Skip to content

feat(cli): stream product frames to a wire debugger behind --debugger - #656

Open
decrypto21 wants to merge 1 commit into
mainfrom
nidish/debugger-cli-flag
Open

feat(cli): stream product frames to a wire debugger behind --debugger#656
decrypto21 wants to merge 1 commit into
mainfrom
nidish/debugger-cli-flag

Conversation

@decrypto21

@decrypto21 decrypto21 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Adds a --debugger flag so the headless truapi-host CLI streams its product frames to the wire debugger.

Why: the debugger only ever sees the browser host. wasm.rs was the sole non-test set_debug_sink caller, so every frame the CLI serves was unobservable, including truapi-host dev and the whole e2e-* family. WsDebugSink already existed and was tested, with no caller outside its own tests.

How: frame_server.rs gains a DebugTappedRuntime that wraps a ProductRuntimeFactory and installs a sink on every runtime it hands out; main.rs resolves the switch into that sink and wraps the factory each host role uses. global = true puts it on pairing-host, signing-host and dev, and TRUAPI_DEBUGGER_URL sets the same thing, which is how a harness attaches without a script change.

  • Wrapping the factory rather than each host role keeps the tap in one place, and none of the roles knows it is being observed.
  • The decorator delegates connection_reset. The trait default would leave product connections alive across a session switch that exists to invalidate them, and nothing in the accept loop reports the omission, so it has a test that fails when the override is removed.
  • The switch resolves in dispatch, before any command binds a port, so a non-loopback or wss:// target aborts on the argument rather than half-way through startup. A loopback URL succeeds with nothing listening, since the sink dials lazily and reconnects.
  • The report names which switch supplied the URL. Two switches resolve to one value, and a stale exported variable beating an explicit flag is otherwise silent.

Implements §9's native enablement path. §9 of the design doc spelled out only the browser rule and said no host wired the native sink up. It now states the native rule too.

Two changes beyond the flag:

  • The CLI declares truapi-server's ws-bridge feature, which is where WsDebugSink lives. Nothing declared it before; the mobile builds pass it on the command line. No new crates enter the tree, but cargo build --workspace now compiles more of truapi-server.
  • Two comments in host_core.rs rested on the CLI installing no sink. The lock-poisoning argument still holds on a narrower basis: not that wasm32 cannot unwind, but that every caller builds a fresh SinkTransport per product_runtime() and installs at most once on it, so previous is always None.

Verified against a live host. scripts/battery.sh --signing-host with TRUAPI_DEBUGGER_URL set and no other change reaches the debugger as 148 ops over 484 frames and 1,003,511 bytes, codecMismatch: false, malformed: 0, truncated: 0. Sorting that capture by duration puts resourceAllocation.request at 53.9s against an 821ms average, which is the kind of tail this exists to make visible. A /frame drill-down returns "kind": "decoded". fmt clean, clippy at zero, 222 crate tests pass.

That run also rewrites explorer/diagnosis-reports/spa/signing-host-cli.md. This branch leaves it alone: its new failures are the run's ephemeral identity, not this change.

@decrypto21
decrypto21 requested a review from a team September 9, 2026 08:41
@decrypto21
decrypto21 force-pushed the nidish/debugger-cli-flag branch from 0935dcc to 429df49 Compare September 9, 2026 12:13
@pgherveou

Copy link
Copy Markdown
Collaborator

can you add some screenshot / recording how how it looks in action?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants