Skip to content

feat: OSC 7501 program status - #405

Merged
arzafran merged 8 commits into
mainfrom
feat/osc7501-program-status
Oct 7, 2026
Merged

arzafran merged 8 commits into
mainfrom
feat/osc7501-program-status

Conversation

@arzafran

@arzafran arzafran commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

What this does

Programs running in a Programa terminal can now tell us what they are doing (working, done, waiting on you, failed) with the OSC 7501 Program Status Protocol. Programa shows it in the sidebar and notifies you when a pane you aren't looking at finishes, fails or needs you. Because the report travels inside the terminal output, it also works over SSH and in containers, where our socket hooks can't reach. Our own Claude Code, Codex and OpenCode hooks send it too.

Summary

Review in this order:

  1. ghostty bump (fork branch osc7501-program-status): backport of libghostty-vt: program status protocol (OSC 7501) ghostty-org/ghostty#14560 plus a GHOSTTY_ACTION_PROGRAM_STATUS action. The fork also clears records on RIS, signals the OSC 133;A prompt, and answers the OSC 7501 ; ? query, which upstream's full-app path does not.
  2. Sources/ProgramStatus.swift: report parser and per-terminal record store (256 records, clear-subtree, prompt drops working/blocked, done/error survive).
  3. Sources/GhosttyApp+ProgramStatus.swift: callback copies the bytes, hops to main, projects the root record into agent presence as source program, notifies waiters and posts notifications per state transition.
  4. Sources/Workspace+SidebarTelemetry.swift: authority. Program beats hooks beats screen inference, but only while the program is working or blocked; a resting done/error record yields to a hook that reports activity.
  5. Socket: program_status on surface.list / system.tree (state, kind, progress, app, has_message, updated_at), surface.wait gains program_state. agent_state keeps its values (done/error read as idle). Record msg/title never go over the socket, including through notification text, per the spec.
  6. CLI/CLI+ProgramStatusEmitter.swift: hooks write one ≤512-byte sequence to the tty, only when PROGRAMA_SURFACE_ID is set and not inside tmux.
  7. Sidebar check/stop icons for done/error, localized notification text (en, ja), docs in docs/program-status.md and docs/socket-api.md.

f41dfac312 pins the GhosttyKit checksum. The release token got a 403 on the fork, so that framework was built locally with CI's flags and published by hand.

Not in this PR: OSC 9;4 progress is not mapped into 7501 records; child records are stored but not shown.

Test Plan

  • Fork: zig build test -Dtest-filter=OSC passes (parser and header-sync tests)
  • CI green on 9d4167a2b3, including tests_v2/test_program_status_osc7501.py (10 cases) in socket-integration-tests
  • Release arm64 build succeeds
  • By hand: in a pane you are not looking at, run printf '\e]7501;state=done:msg=SGVsbG8=\e\\'; expect a check icon in the sidebar and one "Done" notification
  • By hand: run Claude Code in a Programa pane; the sidebar shows working, then done when it stops

@arzafran
arzafran marked this pull request as ready for review October 7, 2026 18:33
@arzafran
arzafran merged commit c66fae7 into main Oct 7, 2026
14 checks passed
@arzafran
arzafran deleted the feat/osc7501-program-status branch October 7, 2026 19:13
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.

1 participant