Repository navigation
feat(terminal): record shell integration (OSC 7 cwd + OSC 133 marks) - #956
Merged
Merged
Conversation
Wire the two escape sequences that TUIs and modern shells use to tell the terminal about state that xterm.js doesn't handle natively: - OSC 7 — shell emits its current working directory on every `cd`. - OSC 133 — FinalTerm / iTerm semantic prompt marks (A/B/C/D with optional exit code on D). Parsing lives in a new pure `shell-integration.ts` helper with 21 unit tests covering URI decoding, Windows UNC / drive-letter paths, all four OSC 133 letters, the `key=value` hint suffix some emitters append, and the ring-buffer cap on recorded marks. Wiring follows the DEC 2031 / OSC 52 pattern from #896 and #952: - Handlers registered per-pane in onPaneCreated, disposed symmetrically in onPaneClosed. - Two new refs (`paneCwdRef`, `paneSemanticMarksRef`) live on TerminalPane and are passed through UseTerminalPaneLifecycleDeps. - Semantic marks record the absolute buffer row (`baseY + cursorY`) so future block-navigation consumers can scroll to them. - A 10 000-entry ring buffer caps per-pane memory. Shipped consumer: the terminal context menu grows a platform-aware "Reveal in Finder / Show in Explorer / Open Folder" item that opens the shell's current directory in the native file manager. The item is hidden when no OSC 7 has been received, consistent with how other terminal emulators surface shell-integration-dependent features. No consumer yet for OSC 133 — recording is cheap and the consumer UX (block-nav keybinds, exit-code gutters) deserves its own design pass.
Merged
6 of 7 tasks
enrick-dev
pushed a commit
to enrick-dev/orca
that referenced
this pull request
Oct 15, 2026
…tablyai#956) Wire the two escape sequences that TUIs and modern shells use to tell the terminal about state that xterm.js doesn't handle natively: - OSC 7 — shell emits its current working directory on every `cd`. - OSC 133 — FinalTerm / iTerm semantic prompt marks (A/B/C/D with optional exit code on D). Parsing lives in a new pure `shell-integration.ts` helper with 21 unit tests covering URI decoding, Windows UNC / drive-letter paths, all four OSC 133 letters, the `key=value` hint suffix some emitters append, and the ring-buffer cap on recorded marks. Wiring follows the DEC 2031 / OSC 52 pattern from stablyai#896 and stablyai#952: - Handlers registered per-pane in onPaneCreated, disposed symmetrically in onPaneClosed. - Two new refs (`paneCwdRef`, `paneSemanticMarksRef`) live on TerminalPane and are passed through UseTerminalPaneLifecycleDeps. - Semantic marks record the absolute buffer row (`baseY + cursorY`) so future block-navigation consumers can scroll to them. - A 10 000-entry ring buffer caps per-pane memory. Shipped consumer: the terminal context menu grows a platform-aware "Reveal in Finder / Show in Explorer / Open Folder" item that opens the shell's current directory in the native file manager. The item is hidden when no OSC 7 has been received, consistent with how other terminal emulators surface shell-integration-dependent features. No consumer yet for OSC 133 — recording is cheap and the consumer UX (block-nav keybinds, exit-code gutters) deserves its own design pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wire the two shell-integration escape sequences that xterm.js does not handle natively, continuing the pattern established by #896 (DEC 2031) and #952 (OSC 52):
cdby a shell whose rc includes aprecmdhook. Recorded per-pane inpaneCwdRef.A= prompt start,B= prompt end,C= command end,D[;code]= done). Recorded per-pane in a capped ring buffer with buffer-row coordinates.Shipped consumer
The terminal context menu grows a platform-aware Reveal in Finder / Show in Explorer / Open Folder item that opens the shell's current directory in the native file manager. The item is hidden when no OSC 7 has been observed, consistent with how iTerm/tmux surface shell-integration-dependent features.
This gives users an immediate reason to enable OSC 7 in their rc and proves the plumbing works end-to-end — the anti-pattern of shipping infrastructure without consumers was explicitly discussed in the design pass.
Recorded-only (no consumer yet)
OSC 133 marks are recorded but no UI surfaces them. Recording is cheap (a push onto a ring buffer), and the consumer UX (block-nav keybinds, exit-code gutters, per-command timing) deserves its own design debate. Landing the recording now means future consumer PRs won't also have to add the parsing.
Design
See
docs/shell-integration-design.mdin the local worktree (gitignored per project convention for*-design.md).Module layout
src/renderer/src/components/terminal-pane/shell-integration.ts— pure parsers (parseOsc7Path,parseOsc133Payload,pushSemanticMark).src/renderer/src/components/terminal-pane/shell-integration.test.ts— 21 unit tests.use-terminal-pane-lifecycle.ts— register/dispose handlers per-pane, populate the two refs.use-terminal-pane-context-menu.ts— exposemenuPaneCwd+onRevealCwdon the menu state.TerminalContextMenu.tsx— render the platform-labeled Reveal item.Memory safety
onPaneClosed.Security / Safety
file://URI only; non-file schemes returnnull. Passed unchanged toshell.showItemInFoldervia the existingshell:openPathIPC (which is read-only — it just selects the directory in the OS file manager).exitCodeorrowin this PR.Known non-goals (explicit)
PaneManager.splitPaneto accept a per-pane cwd override and threading it throughconnectPanePty. Separate design, ~3× this PR's footprint.precmdsnippet manually today. Auto-injection needs rc-file ownership / uninstall semantics / Fish + PowerShell variants — separate design.Testing
pnpm lintpnpm typecheckprintf '\e]7;file://%s%s\a' "$HOSTNAME" "$PWD"to~/.zshrcprecmd, confirm Reveal in Finder opens the current directory