bridge: stdin EOF after sessions.search writes a clean end whose count claims items it never emitted #112

Closed
opened 2026-10-12 15:02:30 +09:00 by natsukium · 0 comments
Owner

Summary

When the bridge's stdin closes right after a sessions.search request line, the bridge writes a clean end terminal whose count claims matches it never emitted. No item lines appear.

docs/reference/cli.md says closing stdin cancels in-flight operations, so dropping the items may be intended. A clean end with a nonzero count is not: a consumer reads it as a complete result with N matches. Either the items should be emitted before the terminal, or the terminal should be the failing one (canceled) with no claimed count.

Repro

Isolated daemon, a session that printed NEEDLE (the CLI finds 2 matches):

printf '{"v":1,"id":1,"op":"sessions.search","params":{"session":"%s","pattern":"NEEDLE"}}\n' "$ID" | felis bridge
# {"v":1,"id":1,"event":"end","count":2}        <- no item lines; 4 of 4 runs

(printf '{"v":1,"id":1,"op":"sessions.search","params":{"session":"%s","pattern":"NEEDLE"}}\n' "$ID"; sleep 2) | felis bridge
# {"v":1,"id":1,"item":{...,"line_index":1,"text":"NEEDLE"}}
# {"v":1,"id":1,"item":{...,"line_index":0,"text":"sh-5.3$ echo NEEDLE"}}
# {"v":1,"id":1,"event":"end","count":2}

A separate run on the search --source visible branch (one expected match) saw count 1 in some runs and 0 in others, again with no item line, so the count is also racy.

Expected

The terminal after stdin EOF matches what was written: either every item followed by end with that count, or a canceled failing terminal. Which one is right depends on whether EOF should drain or cancel in-flight streams. The doc says cancel, which points to the failing terminal.

Notes

  • Reproduces with the default search (no source param), so it does not depend on search --source visible.
  • sessions.capture likely needs the same check.
## Summary When the bridge's stdin closes right after a `sessions.search` request line, the bridge writes a **clean** `end` terminal whose `count` claims matches it never emitted. No item lines appear. `docs/reference/cli.md` says closing stdin cancels in-flight operations, so dropping the items may be intended. A clean `end` with a nonzero `count` is not: a consumer reads it as a complete result with N matches. Either the items should be emitted before the terminal, or the terminal should be the failing one (`canceled`) with no claimed count. ## Repro Isolated daemon, a session that printed `NEEDLE` (the CLI finds 2 matches): ```sh printf '{"v":1,"id":1,"op":"sessions.search","params":{"session":"%s","pattern":"NEEDLE"}}\n' "$ID" | felis bridge # {"v":1,"id":1,"event":"end","count":2} <- no item lines; 4 of 4 runs (printf '{"v":1,"id":1,"op":"sessions.search","params":{"session":"%s","pattern":"NEEDLE"}}\n' "$ID"; sleep 2) | felis bridge # {"v":1,"id":1,"item":{...,"line_index":1,"text":"NEEDLE"}} # {"v":1,"id":1,"item":{...,"line_index":0,"text":"sh-5.3$ echo NEEDLE"}} # {"v":1,"id":1,"event":"end","count":2} ``` A separate run on the `search --source visible` branch (one expected match) saw `count` 1 in some runs and 0 in others, again with no item line, so the count is also racy. ## Expected The terminal after stdin EOF matches what was written: either every item followed by `end` with that count, or a `canceled` failing terminal. Which one is right depends on whether EOF should drain or cancel in-flight streams. The doc says cancel, which points to the failing terminal. ## Notes - Reproduces with the default search (no `source` param), so it does not depend on `search --source visible`. - `sessions.capture` likely needs the same check.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis#112
No description provided.