Piping any command into head panics or errors instead of exiting quietly
open by a73x
Labels: backlog
[claude 2026-08-15] Closing the read end of a pipe — `| head`, `| less` and quit — makes the tool panic. Standard Unix behaviour is to die silently on SIGPIPE.
Three different behaviours for the same event, depending on how the command writes stdout:
```
$ git-collab patch show <id> | head -4
Head: 9cfb8ccf -> main
thread 'main' panicked at library/std/src/io/stdio.rs:1165:9:
failed printing to stdout: Broken pipe (os error 32)
$ echo ${pipestatus[1]}
101
$ git-collab patch diff <id> | head -4
thread 'main' panicked ... Broken pipe (os error 32) # exit 101
$ git-collab refs | head -3
issue, archived 1e821152a2d7 refs/collab/archive/issues/0316...
error: Broken pipe (os error 32) # exit 1
$ git-collab issue list | head -2 # exit 0, silent
```
Cause: the commands that go through `output::emit` swallow the write error (`let _ = writeln!(...)` in src/output.rs:64), so they are already quiet. The ones writing `println!` directly panic, and `refs` propagates the io::Error up to the `error:` reporter.
Note the panic needs output that outlives the reader — `issue list | head -2` looks fine only because the whole listing fits the 64KB pipe buffer before `head` exits. It is the same latent bug.
Expected: exiting 0 (or dying by SIGPIPE) with no output, for every command, however it writes.
Suggested fix: one exit path that treats `ErrorKind::BrokenPipe` as success, and route the direct `println!` sites through `output::emit` so there is one writer rather than three.