Summary
The reply guard introduced in v0.17.0 (PR #39) correctly protects against answering dialogs, but has a UX gap when the target pane is busy streaming output: text arrives in the terminal but the submit key is never sent, the draft stays in the compose box, and retry accumulates duplicate text in the pane with no way to submit or clear it from the PWA.
Scenario
- Agent pane (Claude Code) is actively streaming output (working on a response).
- User types a message in Collie's composer and taps Send.
- Guard step 1 —
pane.send_text(text, submit: false) — succeeds: the text lands on the pane's input line.
- Guard step 2 — polling the pane to verify the text appeared on the > prompt input line — fails, because the > prompt is scrolled off/obscured by streaming output.
- Guard step 3 — Enter is withheld. The Collie compose box keeps the draft.
- User taps Send again — steps 3–5 repeat — text accumulates multiple times on the pane's input line with no way to submit it.
Observed behavior
- The terminal mirror confirms the text IS in the pane's input buffer (it appears on the > line).
- The Collie compose box still shows the draft, implying the send "failed."
- Repeated sends type additional copies of the text in the pane but never add a trailing Enter.
- No PWA affordance to: send a bare Enter, clear the pane's input line, or retry the submit without retyping.
Related
What makes this different from related issues
The guard was designed around a dialog-active scenario, where stalling is correct (you don't want to send Enter into a dialog). But the more common trigger (pane busy streaming) has the opposite UX: the text WAS delivered to the pane's input buffer, it just needs Enter to submit it. The guard treats both scenarios identically when it should distinguish them.
Suggested improvements
1. Clear the compose box on verified type regardless of submit outcome
Once send_text returns ok, the text is in the pane. The compose box should clear immediately — the draft was successfully transmitted even if Enter hasn't been sent yet. Keeping the draft is misleading because the user sees it and assumes "it didn't go through," then retries and accumulates.
2. Retry submit standalone
When the guard stalls (text verified, Enter withheld), offer a "Resend Enter" action. The user can tap it later once they visually confirm in the mirror that the prompt is ready. The original text is already in the pane — only the submit key is missing.
3. Pre-check pane state before typing
Before the guard types anything, check if the pane is in a readable state (output settled, > prompt visible). If the pane is streaming, wait for it to settle rather than typing blind.
Workaround (for documentation)
On the Mac/TUI: tap Cmd+K then Enter in the target pane to clear the accumulated text and start fresh.
From the PWA: tap Keys -> send Ctrl+C to cancel a stuck state, then try sending again when the pane is idle.
Environment
- Collie v0.20.2 (bridge
herdr.collie)
- Herdr 0.7.4
- Bridge host: macOS (Apple Silicon), behind tailscale serve
- Harness: Claude Code panes
- Client: Android PWA (installed to home screen)
Summary
The reply guard introduced in v0.17.0 (PR #39) correctly protects against answering dialogs, but has a UX gap when the target pane is busy streaming output: text arrives in the terminal but the submit key is never sent, the draft stays in the compose box, and retry accumulates duplicate text in the pane with no way to submit or clear it from the PWA.
Scenario
pane.send_text(text, submit: false)— succeeds: the text lands on the pane's input line.Observed behavior
Related
What makes this different from related issues
The guard was designed around a dialog-active scenario, where stalling is correct (you don't want to send Enter into a dialog). But the more common trigger (pane busy streaming) has the opposite UX: the text WAS delivered to the pane's input buffer, it just needs Enter to submit it. The guard treats both scenarios identically when it should distinguish them.
Suggested improvements
1. Clear the compose box on verified type regardless of submit outcome
Once
send_textreturns ok, the text is in the pane. The compose box should clear immediately — the draft was successfully transmitted even if Enter hasn't been sent yet. Keeping the draft is misleading because the user sees it and assumes "it didn't go through," then retries and accumulates.2. Retry submit standalone
When the guard stalls (text verified, Enter withheld), offer a "Resend Enter" action. The user can tap it later once they visually confirm in the mirror that the prompt is ready. The original text is already in the pane — only the submit key is missing.
3. Pre-check pane state before typing
Before the guard types anything, check if the pane is in a readable state (output settled, > prompt visible). If the pane is streaming, wait for it to settle rather than typing blind.
Workaround (for documentation)
On the Mac/TUI: tap Cmd+K then Enter in the target pane to clear the accumulated text and start fresh.
From the PWA: tap Keys -> send Ctrl+C to cancel a stuck state, then try sending again when the pane is idle.
Environment
herdr.collie)