Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f7d28b5
Add terminal CWD and command state model
nedtwigg May 8, 2026
4cbaad3
Tighten terminal-state hot path and dedupe header derivation
nedtwigg May 8, 2026
08d583a
Add terminal shell and CWD state coverage
nedtwigg May 8, 2026
fff09d1
Respect app-sent terminal title overrides
nedtwigg May 8, 2026
3f4d9bc
Add terminal title candidate diagnostics
nedtwigg May 8, 2026
873edf4
Simplify title-candidate state and header helpers
nedtwigg May 8, 2026
4398647
Decode VS Code OSC 633 command payloads
nedtwigg May 8, 2026
00568eb
Keep terminal state after VS Code PTY exit
nedtwigg May 8, 2026
6dc8af2
Restore saved titles on live reconnect
nedtwigg May 8, 2026
1b5f7d5
Resolve pane state before typed fallback
nedtwigg May 8, 2026
0a80262
Avoid duplicating UNC roots in labels
nedtwigg May 8, 2026
1cd99d9
Tighten header title spacing in stories
nedtwigg May 8, 2026
4c34b72
Skip late process CWD updates for disposed panes
nedtwigg May 8, 2026
b9b5996
Reject sentinel labels as user-pinned titles
nedtwigg May 8, 2026
54d1a8a
Tighten the user-input prompt-return heuristic
nedtwigg May 8, 2026
5c34e56
Drop unused options arg from idleLabel
nedtwigg May 8, 2026
b824cbc
Document semantic stripping on pty:replay in adapters
nedtwigg May 8, 2026
cdfe81d
Avoid raw PTY semantic cleanup in VS Code adapter
nedtwigg May 8, 2026
4884ab5
Keep standalone semantic state on PTY exit
nedtwigg May 8, 2026
fa78920
Preserve semantic event timestamp order
nedtwigg May 8, 2026
ba657c5
Resolve process CWDs through PTY ownership
nedtwigg May 8, 2026
8f8dd80
Seed resumed door titles from saved state
nedtwigg May 8, 2026
6770e0e
Restore persisted cwd into semantic state
nedtwigg May 8, 2026
eade30f
Keep semantic state out of adapter kills
nedtwigg May 8, 2026
df2cfb0
Do not persist derived door titles
nedtwigg May 8, 2026
4da4c0f
Drop redundant inline timestamp in parseOscTitle
nedtwigg May 9, 2026
01ab8b2
Document OSC 633;E semicolon truncation contract
nedtwigg May 9, 2026
423947e
Document looksLikeReturnedShellPrompt as best-effort fallback
nedtwigg May 9, 2026
a8d6d54
Align restoreTerminal title type with resumeTerminal
nedtwigg May 9, 2026
85a50f1
Drop dead-state replay parser map in VSCodeAdapter
nedtwigg May 9, 2026
c9170b6
Apply command-start freshness gate to OSC 9 app titles
nedtwigg May 9, 2026
1ad8bb7
Test VSCodeAdapter replay parser and semantic event paths
nedtwigg May 9, 2026
55626fc
Test extension-host to webview semantic event round-trip
nedtwigg May 9, 2026
6b6d0d0
Warn when a rename hits a reserved label
nedtwigg May 9, 2026
096a3d5
Reorganize docs/specs: OSC.md, transport.md, fold notifications into …
nedtwigg May 9, 2026
987c00a
Update AGENTS.md spec list for the docs/specs reorganization
nedtwigg May 9, 2026
b5896bb
Drop already-resolved #3 and #4 from SPEC-CONFLICTS.md
nedtwigg May 9, 2026
da25a4c
Show <idle> for finished panes and drop DerivedHeader.status
nedtwigg May 9, 2026
2aaa16c
Delegate header-label rules from layout.md to terminal-state.md
nedtwigg May 9, 2026
fe09ab4
Drop dead enum values and document live ones in terminal-state
nedtwigg May 9, 2026
8a79062
Drop SPEC-CONFLICTS #6 (disambiguator coverage)
nedtwigg May 9, 2026
0a437c5
Drop SPEC-CONFLICTS #7 (popup channels mismatch)
nedtwigg May 9, 2026
c4fc723
Align resume title-seeding wording across specs
nedtwigg May 9, 2026
9cbb0a4
Define what 'stale' meant for pending command-line clearing
nedtwigg May 9, 2026
1cf31b6
Replace CWD fallback list with a single precedence statement
nedtwigg May 9, 2026
cad20e4
Disambiguate OSC 9 message form from OSC 9;4 progress form
nedtwigg May 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ The primary job of a spec is to be an accurate reference for the current state o

- **`docs/specs/ontology.md`** — Canonical vocabulary for Session states, layers (Process / Registry / View / Link / Activity / Snapshot), transition verbs, and the Liskov contract on Registry APIs. Read this first. Other specs defer to it when naming a state or a verb.
- **`docs/specs/layout.md`** — Tiling layout, pane/door containers, dockview configuration, modes (passthrough/command), keyboard shortcuts, selection overlay, spatial navigation, minimize/reattach, inline rename, session lifecycle, session persistence, and theming. Read this when touching: `Wall.tsx`, `Baseboard.tsx`, `Door.tsx`, `TerminalPane.tsx`, `spatial-nav.ts`, `layout-snapshot.ts`, `terminal-registry.ts`, `session-save.ts`, `session-restore.ts`, `reconnect.ts`, `index.css`, `theme.css`, or any keyboard/navigation/mode behavior.
- **`docs/specs/alert.md`** — Activity monitoring state machine, alert trigger/clearing rules, attention model, TODO lifecycle (soft/hard), bell button visual states and interaction, door alert indicators, and hardening (a11y, motion, i18n, overflow). Read this when touching: `activity-monitor.ts`, `alert-manager.ts`, the alert bell or TODO pill in `Wall.tsx` (TerminalPaneHeader), alert indicators in `Door.tsx`, or the `a`/`t` keyboard shortcuts. Layout.md defers to this spec for all alert/TODO behavior.
- **`docs/specs/iTerm2.md`** — iTerm2-compatible identity, terminal notification protocols (`OSC 9`, `OSC 99`, `OSC 777`), and `OSC 9;4` progress arming, including how protocol signals force or cock the alert/TODO system. Read this when touching PTY environment identity, terminal device/version reports, OSC parsing, `AlertManager` protocol notification/progress paths, `ActivityState` metadata, or TODO notification preview UI.
- **`docs/specs/vscode.md`** — VS Code extension architecture: hosting modes (WebviewView + WebviewPanel), PTY lifecycle and buffering, message protocol between webview and extension host, session persistence flow, reconnection protocol, theme integration, CSP, build pipeline, and invariants (save-before-kill ordering, PTY ownership, alert state merging). Read this when touching: `extension.ts`, `webview-view-provider.ts`, `message-router.ts`, `message-types.ts`, `pty-manager.ts`, `pty-host.js`, `session-state.ts`, `webview-html.ts`, `vscode-adapter.ts`, or `pty-core.js`.
- **`docs/specs/alert.md`** — Activity monitoring state machine, alert trigger/clearing rules, attention model, TODO lifecycle, bell button visual states and interaction, door alert indicators, hardening (a11y, motion, i18n, overflow), notification protocols (`OSC 9` / `OSC 9;4` / `OSC 99` / `OSC 777` / `BEL`), the `ActivityNotification` model, notification text handling and security, and the notification preview/detail UI. Read this when touching: `activity-monitor.ts`, `alert-manager.ts`, `AlertManager` notification/progress paths, the alert bell or TODO pill in `Wall.tsx` (TerminalPaneHeader), alert indicators in `Door.tsx`, the `a`/`t` keyboard shortcuts, or TODO notification preview UI. Layout.md defers to this spec for all alert/TODO behavior.
- **`docs/specs/terminal-state.md`** — Terminal semantic state for CWD, shell prompt/editing/running/finished lifecycle, command runs, terminal title fallback, normalized semantic OSC events (`OSC 7`, `OSC 9;9`, `OSC 133`, `OSC 633`, `OSC 1337`, `OSC 0/2`), title-candidate diagnostics, header derivation, and grouping keys. Read this when touching `terminal-state.ts`, `terminal-state-store.ts`, semantic event parsing in `terminal-protocol.ts`, adapter semantic event forwarding, or derived pane/door labels.
- **`docs/specs/OSC.md`** — Registry of every supported OSC sequence with pointers to the spec defining its behavior (alert.md or terminal-state.md), the canonical parsing-location and `pty:data` strip semantics, iTerm2 self-identification (env vars, `CSI > q` response, fail-inertly rule), and known-unimplemented iTerm2 sequences. Read this when touching: OSC parsing at the PTY data boundary, the iTerm2 identity env vars (`TERM_PROGRAM`, `LC_TERMINAL`), or adding support for a new OSC sequence.
- **`docs/specs/transport.md`** — Adapter-agnostic protocol shared across VS Code, standalone, and fake adapters: PTY lifecycle (decoupled from webview), `replayChunks`/`scrollbackChunks` buffering, reconnection sequence (`mouseterm:init` → `pty:list` + `pty:replay`), the full webview ↔ host message protocol, persisted-session types, and universal invariants (shell login args, scrollback trailing newline, replay drop-replies-only). Read this when touching: `pty-manager.ts`, `pty-host.js`, `pty-core.js`, `message-router.ts`, `message-types.ts`, `vscode-adapter.ts`, `fake-adapter.ts`, `reconnect.ts`, `session-save.ts`, `session-restore.ts`, `session-types.ts`, or any code crossing the webview/host boundary.
- **`docs/specs/vscode.md`** — VS Code-specific layer: hosting modes (WebviewView + WebviewPanel), extension manifest, VS Code persistence flow (`workspaceState`, `vscode.setState`, `WebviewPanelSerializer`, deactivate ordering, `mergeAlertStates` rule, `retainContextWhenHidden`), theme integration (`--vscode-*` → `--color-*` with the runtime resolver), CSP, build pipeline, and dream-architecture commands. The transport protocol it speaks (PTY lifecycle, message protocol, persisted-session types) lives in `transport.md`. Read this when touching: `extension.ts`, `webview-view-provider.ts`, `session-state.ts`, `webview-html.ts`, the theme resolver/observer in `terminal-theme.ts`, or VS Code commands and context keys.
- **`docs/specs/tutorial.md`** — Playground tutorial on the website: 3-pane layout, interactive `tut` TUI runner with three sections (keyboard navigation, alerts/TODOs, copy/paste), per-item detection wired to `WallEvent` / activity store / mouse-selection store, single-key `mouseterm-tut-v3` localStorage scheme, theme picker, and FakePtyAdapter extensions (`sendOutput`, `pumpActivity`, `setInputHandler`). Read this when touching: `website/src/pages/Playground.tsx`, `website/src/lib/tut-runner.ts`, `website/src/lib/tut-detector.ts`, `website/src/lib/tutorial-state.ts`, `website/src/lib/tut-items.ts`, `website/src/lib/tutorial-shell.ts`, `lib/src/components/ThemePicker.tsx`, `lib/src/lib/themes/`, `lib/src/lib/platform/fake-scenarios.ts` (tutorial scenarios), the `WallEvent` union, or the `onApiReady`/`onEvent`/`initialPaneIds` props on Wall.
- **`docs/specs/theme.md`** — Theme system: two-layer CSS variable strategy, theme data model, conversion pipeline, bundled themes, localStorage store, shared ThemePicker component, standalone AppBar picker, runtime OpenVSX installer. Read this when touching: `lib/src/lib/themes/`, `lib/src/components/ThemePicker.tsx`, `lib/src/theme.css`, `lib/scripts/bundle-themes.mjs`, `standalone/src/AppBar.tsx` (theme picker), `standalone/src/main.tsx` (theme restore), or `website/src/components/SiteHeader.tsx` (themeAware mode).
- **`docs/specs/mouse-and-clipboard.md`** — Terminal-owned text selection, copy (Raw / Rewrapped), bracketed paste, smart URL/path extension, mouse-reporting override UI (icon + banner), and the state matrix for which layer owns mouse events. Read this when touching: `lib/src/lib/mouse-selection.ts`, `lib/src/lib/mouse-mode-observer.ts`, `lib/src/lib/clipboard.ts`, `lib/src/lib/rewrap.ts`, `lib/src/lib/selection-text.ts`, `lib/src/lib/smart-token.ts`, `lib/src/components/SelectionOverlay.tsx`, `lib/src/components/SelectionPopup.tsx`, the mouse icon / override banner / Cmd+C-V handling in `lib/src/components/Wall.tsx`, or the parser hooks + mouse listeners in `lib/src/lib/terminal-registry.ts`.
Expand Down
99 changes: 99 additions & 0 deletions docs/specs/OSC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# OSC Sequence Registry

> Single registry of OSC sequences MouseTerm parses. Behavioral details live in `docs/specs/alert.md` (notifications) and `docs/specs/terminal-state.md` (CWD, prompt/command, title fallback). This file also documents iTerm2 self-identification because the same identity is what causes most of these sequences to be emitted at us.

## Goal

MouseTerm parses a small set of OSC (Operating System Command) escape sequences from PTY output to drive alerts, terminal state, and titles. This document is the index — every supported OSC has one row in the table below pointing to the spec that defines its full behavior.

## Parsing location

OSC sequences are introduced by `ESC ]` and terminated by either `BEL` (`\x07`) or `ST` (`ESC \`). A `BEL` that terminates an OSC is part of that OSC sequence, not a standalone bell notification. Both terminators are accepted across all supported sequences, and the parser handles split chunks across PTY reads.

Supported OSCs are parsed at the PTY data boundary in the platform adapter:

- VS Code: in the extension host (`message-router.ts` / `pty-manager.ts`), before `pty:data` is forwarded to the webview.
- Standalone and fake adapters: in the frontend adapter, before xterm.js sees the bytes.

After parsing, supported sequences are consumed and not re-emitted. The platform sends two streams to the webview:

- `pty:data` — terminal output with supported OSCs already parsed/stripped. Feeds xterm.js.
- `terminal:semanticEvents` — normalized semantic events parsed in the platform (CWD, prompt/command boundaries, titles). Feeds `TerminalPaneState`.
- Notification-derived state is delivered through `AlertManager` calls / `alert:state` messages, not through `pty:data`.

For replay (`pty:replay`), the webview re-parses semantic OSCs from the buffered raw stream during reconstruction. Replay must not re-fire alerts, activity-monitor events, or protocol notifications: saved scrollback may contain raw OSC sequences, but replay filtering suppresses all protocol side effects so a resumed Session does not re-ring on every reload.

The parser also classifies each PTY data chunk for activity-monitor purposes:

- A chunk that contains only notification/progress OSCs after parsing must not be fed to the activity monitor's `onData()` as generic meaningful output.
- A chunk that contains visible output plus notification/progress OSCs still counts visible output as activity.

Unknown OSC sequences pass through to xterm.js unchanged (and are then ignored by xterm.js if it does not recognize them — see the iTerm2-identity fail-inertly rule below).

## Supported OSCs

| Sequence | Purpose | Spec |
|---|---|---|
| `BEL` (standalone, outside an OSC) | Generic terminal-bell notification | [alert.md](alert.md#standalone-bel) |
| `OSC 0 ; <title> ST` | Window/icon title | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 2 ; <title> ST` | Window title | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 7 ; file://host/path ST` | CWD (xterm-style URI) | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 9 ; <message> ST` | iTerm2 legacy notification | [alert.md](alert.md#osc-9) |
| `OSC 9 ; 4 ; <state> [; <progress>] ST` | iTerm2 progress | [alert.md](alert.md#osc-94-progress) |
| `OSC 9 ; 9 ; <cwd> ST` | CWD (Windows Terminal / ConEmu) | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 99 ; <metadata> ; <payload> ST` | kitty desktop notification | [alert.md](alert.md#osc-99) |
| `OSC 133 ; A/B/C/D [...] ST` | Prompt/command boundaries | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 633 ; A/B/C/D ST` | VS Code prompt/command boundaries | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 633 ; E ; <commandline> [; <nonce>] ST` | VS Code command line | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 633 ; P ; Cwd=<cwd> ST` | CWD (VS Code) | [terminal-state.md](terminal-state.md#supported-osc-inputs) |
| `OSC 777 ; notify ; <title> ; <body> ST` | rxvt/WezTerm notification | [alert.md](alert.md#osc-777) |
| `OSC 1337 ; CurrentDir=<cwd> ST` | CWD (iTerm2 compatibility) | [terminal-state.md](terminal-state.md#supported-osc-inputs) |

## iTerm2 identity

MouseTerm reports an iTerm2-compatible identity so that tools (shells, build systems, agent clients) emit the iTerm2-style escape codes that this spec set supports.

Environment for spawned PTYs:

| Variable | Value |
|---|---|
| `TERM_PROGRAM` | `iTerm.app` |
| `TERM_PROGRAM_VERSION` | MouseTerm's chosen iTerm2 compatibility version, not the package version |
| `LC_TERMINAL` | `iTerm2` only if needed by real-world shell integrations |
| `LC_TERMINAL_VERSION` | same compatibility version as `TERM_PROGRAM_VERSION` |

Device/version query:

- On `CSI > q`, respond with `DCS > | iTerm2 [version] ST`, matching iTerm2's extended device attributes response shape.
- Use a single compatibility version across env and device responses.
- Do not advertise feature-specific support until the relevant behavior exists.

Because this identity can cause tools to emit more iTerm2 escape codes than MouseTerm implements, **unsupported escape codes must fail inertly**: consume or ignore them without visible terminal garbage, privilege escalation, clipboard access, file access, or focus stealing.

## Known-unimplemented iTerm2 sequences

MouseTerm intentionally does not implement the following iTerm2 OSC sequences. They must fail inertly per the rule above.

| Sequence | Purpose | Reason for non-support |
|---|---|---|
| `OSC 1337 ; SetMark` | Pin a navigable scrollback mark | No mark UI in MouseTerm. |
| `OSC 1337 ; CursorShape=...` | Cursor shape override | Cursor shape comes from MouseTerm settings, not the PTY. |
| `OSC 1337 ; SetBadgeFormat=...` | Display a badge string in the terminal | No badge UI. |
| `OSC 1337 ; ClearScrollback` | Clear scrollback buffer | xterm.js handles native clear-screen sequences. |
| `OSC 1337 ; CopyToClipboard=...` / `EndCopy` | Programmatic clipboard write | Security: untrusted PTY output cannot write the user's clipboard. See `docs/specs/mouse-and-clipboard.md`. |
| `OSC 1337 ; RequestUpload=...` | Begin file upload from terminal | No file-transfer protocol. |
| `OSC 1337 ; File=...` | Inline image protocol | No inline-image rendering. |
| `OSC 1337 ; SetUserVar=...` | Set a per-tab user variable | No user-variable surface. |
| `OSC 50 ; <font> ST` | Set font dynamically | Font is host-controlled. |
| `OSC 52 ; <selection> ; <data> ST` | Programmatic clipboard write | Security: same rationale as `CopyToClipboard`. |

This list is non-exhaustive. Any iTerm2 OSC not in the [Supported OSCs](#supported-oscs) table is ignored.

## References

- iTerm2 proprietary escape codes: https://iterm2.com/documentation-escape-codes.html
- xterm control sequences (OSC 0 / 2 / 7): https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
- VS Code shell integration sequences (OSC 633): https://code.visualstudio.com/docs/terminal/shell-integration
- Windows Terminal CWD OSC 9;9: https://learn.microsoft.com/en-us/windows/terminal/tutorials/new-tab-same-directory
- kitty desktop notifications (OSC 99): https://sw.kovidgoyal.net/kitty/desktop-notifications/
- WezTerm escape sequences (OSC 777): https://wezterm.org/escape-sequences.html
Loading
Loading