Summary
In the default interactive mode, hookdeck listen renders a fully "live"-looking TUI before it has connected, and shows no distinct state while connecting or after failing. The only difference between connected and not-connected is the presence or absence of one line in the status bar — and absence is not a signal a user reads.
Reproduce
hookdeck listen 3030 <source> --ws-base ws://127.0.0.1:9 # under a real terminal
The full TUI appears immediately:
●── HOOKDECK CLI ──●
Listening on 1 source • 1 connection • [i] Collapse
Requests to → https://hkdk.events/…
Forwards to → http://localhost:3030/
The status bar is blank — no Connecting…, no spinner, no error. It looks live for roughly 40 seconds while nothing is connected. Only after 10 failed attempts does it tear down the alt-screen and print the real error.
On success the same layout appears with ● Connected. Waiting for events... in the status bar.
Why this matters
This is the inverse of the bug the v2.6.0 release exists to fix. #376 was piped output under-reporting readiness: the tunnel was live and the CLI never said so, and the reporter concluded their websocket was broken. This is interactive output over-reporting it: the CLI looks connected when it is not.
A user hitting this would reasonably file the same ticket from the other direction — "the CLI says it's listening but nothing arrives". Given the release is specifically about making readiness trustworthy, leaving the default mode able to assert readiness before it exists undercuts the fix.
Suggested fix
Show a distinct pending state in the status bar from the first frame (Connecting…), replaced by Connected. on success and by a visible failure state on error, rather than leaving it empty. Readiness should be affirmative in every mode, not inferred from the absence of text.
Testing
Acceptance-level: run listen against an unreachable --ws-base under a pty and assert the pending state is present before the failure, and that the success path shows Connected.. The existing listen acceptance tests already drive a real connection, so the success half has a home.
Related
Filed by Claude on Phil's behalf, from release-candidate testing.
Summary
In the default interactive mode,
hookdeck listenrenders a fully "live"-looking TUI before it has connected, and shows no distinct state while connecting or after failing. The only difference between connected and not-connected is the presence or absence of one line in the status bar — and absence is not a signal a user reads.Reproduce
The full TUI appears immediately:
The status bar is blank — no
Connecting…, no spinner, no error. It looks live for roughly 40 seconds while nothing is connected. Only after 10 failed attempts does it tear down the alt-screen and print the real error.On success the same layout appears with
● Connected. Waiting for events...in the status bar.Why this matters
This is the inverse of the bug the v2.6.0 release exists to fix. #376 was piped output under-reporting readiness: the tunnel was live and the CLI never said so, and the reporter concluded their websocket was broken. This is interactive output over-reporting it: the CLI looks connected when it is not.
A user hitting this would reasonably file the same ticket from the other direction — "the CLI says it's listening but nothing arrives". Given the release is specifically about making readiness trustworthy, leaving the default mode able to assert readiness before it exists undercuts the fix.
Suggested fix
Show a distinct pending state in the status bar from the first frame (
Connecting…), replaced byConnected.on success and by a visible failure state on error, rather than leaving it empty. Readiness should be affirmative in every mode, not inferred from the absence of text.Testing
Acceptance-level: run
listenagainst an unreachable--ws-baseunder a pty and assert the pending state is present before the failure, and that the success path showsConnected.. The existinglistenacceptance tests already drive a real connection, so the success half has a home.Related
listennot naming why it gave up (fixed)Filed by Claude on Phil's behalf, from release-candidate testing.