Skip to content

feat(web): F4 dormant terminal panes — keep the socket open, buffer instead of re-streaming (WI-128) - #674

Closed
thedancingdeveloper wants to merge 1 commit into
feat/terminal-attach-d6-vt-spikefrom
feat/terminal-attach-f4-dormant-panes
Closed

thedancingdeveloper wants to merge 1 commit into
feat/terminal-attach-d6-vt-spikefrom
feat/terminal-attach-f4-dormant-panes

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Contributor

Eighth PR of the terminal-attach-budget initiative (WI-121). Stacked on #673 (D6); all land on feat/terminal-attach-budget.

What this does (F4 / WI-128)

Switching away from a terminal parked its socket (closed it); returning reattached and re-streamed everything produced while away (bounded by F1, but still a re-stream — the switch-away flood). F4 keeps the socket open for inactive panes and stops writing to xterm — output buffers into the in-memory ring — so returning renders the buffered delta with no reattach and no re-stream.

  • terminalDormancy.ts (pure, unit-tested) — a per-document budget of MAX_DORMANT_SOCKETS (4), most-recently-active kept, the rest evicted to parking; and planDormantResume() deciding delta-write vs reset+tail on return.
  • Terminal.tsx state machineactive | dormant | parked. A dormant pane has an open socket, buffers, and shows no "Suspended" banner (e.g. the unfocused half of a split keeps its screen). suspend() goes dormant if the budget allows and the pane is past its snapshot, else parks. activate() resumes a live dormant socket in place with a synchronous catch-up (flip the flag before any write, so live frames queue in order — no gap), or reconnects if the socket died while dormant (a mobile OS reclaim). Preserves the no-second-socket invariant and the cache-load initial-connect path; releases the slot on park and unmount.
  • Docs — USER_GUIDE (dormant vs Suspended) and ENGINE.md (client note: dormant panes are extra broadcast subscribers, bounded).

Tests

  • terminalDormancy.test.ts — budget, MRU eviction, release, and the resume plan. The shared registry is reset between tests in setup.ts.

Verification & the one gap

  • pnpm typecheck clean; pnpm vitest947 passed (9 new); pnpm build bundles.
  • ⚠️ Live acceptance still owed. The core socket-lifecycle change is unit-tested and typechecks, but the switch-away-under-load behavior (symptom 1: no reset, replay ≤ budget on return) is H3's live spec (WI-124) against a real stack — which an agent session cannot reach. Please review this against the live spec / a dev stack before merging. The plan sequences F4's acceptance on H3-live for exactly this reason.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UtEFLJAhLiq4NfZCN2vuBb

Switching away from a terminal parked its socket (closed it); returning
reattached and re-streamed everything produced while away (bounded by F1, but
still a re-stream, and the source of the switch-away flood). F4 keeps the socket
open for inactive panes and stops writing to xterm — output buffers into the
in-memory ring — so returning renders the buffered delta with no reattach.

- terminalDormancy.ts (pure, unit-tested): a per-document budget of
  MAX_DORMANT_SOCKETS (4), most-recently-active kept, the rest evicted to
  parking; and planDormantResume() deciding delta-write vs reset+tail on return.
- Terminal.tsx state machine: active | dormant (socket open, buffering, no
  "Suspended" banner — e.g. the unfocused half of a split) | parked (socket
  closed, "Suspended"). suspend() goes dormant if the budget allows and the pane
  is past its snapshot, else parks; activate() resumes a live dormant socket in
  place with a SYNCHRONOUS catch-up (flip the flag before any write so live
  frames queue in order — no gap), or reconnects if the socket died while
  dormant (mobile OS reclaim). Preserves the no-second-socket invariant and the
  cache-load initial-connect path; releases the slot on park and unmount.
- Docs: USER_GUIDE (dormant vs Suspended) and ENGINE.md (client note: dormant
  panes are extra broadcast subscribers, bounded).

Tests: terminalDormancy.test.ts (budget, MRU eviction, release, resume plan);
the setup resets the shared registry between tests.

Verification: pnpm typecheck clean; pnpm vitest 947 passed (9 new); pnpm build
bundles. LIVE ACCEPTANCE STILL OWED: the switch-away-under-load symptom-1
assertion is H3's live spec (WI-124) against a real stack — not reachable from
an agent session — so review this against that before merge. WI-128.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UtEFLJAhLiq4NfZCN2vuBb
@thedancingdeveloper

Copy link
Copy Markdown
Contributor Author

Cleanup: superseded by the single promotion PR #676. All of this work is already integrated into feat/terminal-attach-budget and is reviewable there per-commit (each commit is one initiative item with a full message). Closing to keep the initiative to one PR; the commit is preserved.

@thedancingdeveloper
thedancingdeveloper deleted the feat/terminal-attach-f4-dormant-panes branch September 9, 2026 20:59
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