Skip to content

feat(tui): report program status with OSC 7501 - #471

Open
yujiachen-y wants to merge 2 commits into
mainfrom
feat/osc7501-program-status
Open

yujiachen-y wants to merge 2 commits into
mainfrom
feat/osc7501-program-status

Conversation

@yujiachen-y

@yujiachen-y yujiachen-y commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Change

Report the interactive TUI's current program state through OSC 7501 revision 0.4, so supporting terminals can distinguish running work, approval/question/login waits, completion and failure without scraping titles or screen content.

The emitter reuses the existing runtime status projection and sends only fixed state, kind and app=mcode metadata on changes. Cancellation/suspension report idle; resume reapplies the current state; done/error survive normal exit. Output is TTY-only and absent from headless exec and ACP, and can be disabled with tui.programStatus: false. Existing title and notification settings are independent. No dependencies, heartbeat, terminal-brand checks, capability round trips or tmux passthrough wrapping are added; the protocol treats each multiplexer pane as its own terminal.

Interaction readback no longer depends on the build-mode status line item. Previously, with the default configuration, a pending permission or question was projected as running, so both the terminal title and OSC 7501 reported working instead of Needs approval / blocked:kind=permission. build-mode now only controls rendering of the [V] line.

Make missing login a recoverable account-derived condition in the existing projection, so authenticating in the same session restores working/completed reports instead of permanently latching an error. The projection derives it once: the [V] line keeps state=error, the title shows Needs login, and OSC 7501 reports blocked:kind=auth. Genuine fatal errors retain their existing behavior and are not downgraded to a login wait.

  • Labels: enhancement, cli, tui.
  • Documentation: updated terminal capability coverage and limitations, the tui.programStatus setting, and the [V] contract note that a login block clears after sign-in.

Validation

  • PASS: default-path regression through createTuiApp without build-mode: a permission prompt sets the title to Needs approval and reports blocked:kind=permission; after approval the question sets Needs input and reports blocked:kind=question. Reverting the readback gate makes this test fail with Working.
  • PASS: login projection through chrome flow ([V] error, Needs login title, blocked:kind=auth, recovery to ready/run/done, fatal error not downgraded), emitted sequences limited to state/kind/app keys, tui.programStatus config loading, and disabled reports.
  • PASS: focused terminal presentation, chrome flow, TUI app, build-mode contract and settings tests (5 files); pnpm typecheck; pnpm lint.
  • PASS: pnpm verify full profile on clean commit 23f3a8e (macOS arm64), all 15 applicable gates. Skipped as not applicable: test:windows, test:release-package.
  • PASS: no merge conflicts with current main.
  • NOT RUN: a manually triggered permission prompt in a real terminal, real Rex/other supporting-terminal UI, Linux/Windows local execution and live-model acceptance. Terminal display remains host-dependent.

Publication and contribution checks

  • I have permission to contribute these changes under the existing licenses applicable to the changed files/packages; imported material and its provenance are identified and existing notices are preserved.
  • No credentials, account data, real user content, internal source history or private review material is included.
  • Added source was reviewed before regenerating release/public-source.json; tests extend existing declared suites.
  • Capability documentation is updated. No shared README content changed. Offline results are not described as live-service acceptance.

Maintainer handoff

Publication scope: one first-party TUI terminal-output module added; no license changes or imported implementation.

Shared-source port: pending.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@yujiachen-y yujiachen-y added enhancement New feature or request tui Interactive terminal UI (TUI) cli Standalone mcode: TUI, headless, ACP and source builds/tooling labels Oct 9, 2026
@1anZhang
1anZhang self-requested a review October 11, 2026 02:26

@hetaoBackend hetaoBackend left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one blocking issue; the rest are smaller points.

Blocking: blocked:permission and blocked:question are not reported with the default configuration.
app.ts wires agentInteraction to interactionFlow.agentReadback(), and agentReadback() returns undefined unless agentStatusEnabled is true. That flag is only set when the status line config lists build-mode, which status-line-config.md documents as not a default and as taking over the whole status line. So in a normal setup a permission prompt or a question reaches the terminal as working, not blocked. Only auth works, because it reads the account directly. The new tests inject agentInteraction straight into the flow, so they do not cover the default createTuiApp path, and docs/tui-capabilities.md currently claims more than the code does. Please decouple the interaction readback from build-mode (or give OSC 7501 its own readback) and add a test through the default path. I read this statically and have not triggered a real permission prompt, so please confirm on a real TUI.

Smaller points

  1. The spec is now at revision 0.4 (2026-10-10). The 0.3 to 0.4 change only affects feature-detection replies and removes terminfo, so it does not change behavior here, but the docs reference and link could be updated.
  2. There is no way to turn the sequence off. An env var or config switch would help for terminals that do not ignore unknown OSC cleanly. In tmux the sequence is silently dropped, since there is no DCS passthrough like wrapForTmuxPassthrough in the notification code.
  3. Missing login is computed in two places: the status store returns error while chrome-flow.ts maps it to auth, so the title and notifications see error while the terminal sees blocked:auth. Deriving auth in the status projection would keep them consistent.
  4. Tests: the same-session login recovery change in status-store.ts has no unit test, and there is no assertion that the emitted sequence contains only state, kind and app.
  5. Nit: the report === undefined check in update is unreachable.

The write path, de-duplication, exit handling, no content leakage and spec syntax all look right to me. Not verified: a real supporting terminal such as Rex, screen, Linux and Windows.

Interaction readback was gated on the build-mode status line item, so with
the default configuration a pending permission or question was reported as
working in both the terminal title and OSC 7501. The readback now always
feeds the status projection; build-mode only controls rendering the [V] line.

Missing login is derived once in the status projection as an error with
loginRequired, so the [V] line keeps state=error while the title shows
"Needs login" and OSC 7501 reports blocked:kind=auth from the same fact.

Add tui.programStatus (default true) to disable OSC 7501 reports, document
why reports are not wrapped for tmux passthrough, and reference protocol
revision 0.4.
@yujiachen-y

Copy link
Copy Markdown
Collaborator Author

@hetaoBackend Thanks for the careful review. Addressed in 23f3a8e:

Blocking: permission/question with the default configuration. Confirmed. A manual run in Ghostty showed Working in the title during an approval prompt, which matches your static reading. The gate predates this PR: it was already hiding the documented Needs approval title by default, and OSC 7501 inherited it. The build-mode gate is removed from agentReadback() and the submission tracking, so interaction state always feeds the status projection, and build-mode now only controls whether the [V] line is rendered. A new createTuiApp test without build-mode asserts Needs approval + blocked:kind=permission, then Needs input + blocked:kind=question. With the gate restored, the test fails with Working.

Smaller points

  1. Docs and comments now reference revision 0.4.
  2. Added tui.programStatus: false (default true), following the existing tui.showTips pattern. tmux passthrough is intentionally omitted: the spec defines a terminal as each window, tab, split or pane, "implemented by whatever emulates it". Wrapping would attach one pane's state to the whole outer window and let panes overwrite each other, so the multiplexer needs to implement the protocol itself. The docs now say this explicitly.
  3. Login is now derived once in the status projection, as error with loginRequired. The [V] line keeps state=error, while the title (Needs login) and OSC 7501 (blocked:kind=auth) both read the same fact. A sticky fatal error takes precedence and is not downgraded to a login wait. One small correction: notifications are event-driven and never read this status, so only the title disagreed. I also updated the [V] contract note, since a login block now clears after sign-in instead of persisting until session reset.
  4. Added coverage for the login sequence ([V] error, title, auth report, recovery to ready/run/done, fatal precedence), for emitted keys being limited to state/kind/app, and for config loading and disabled reports.
  5. I kept the report === undefined guard. Types make it unreachable, but the existing test exercises it at runtime. Without it, an unexpected value would write a malformed state=undefined report, and the guard degrades silently instead.

pnpm verify full profile passed on clean 23f3a8e (15 gates, macOS arm64). Still not verified: Rex or another supporting terminal, Linux and Windows.

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

Labels

cli Standalone mcode: TUI, headless, ACP and source builds/tooling enhancement New feature or request tui Interactive terminal UI (TUI)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants