gstack/extension
Garry Tan 0aed7f8ecf
feat(sidebar): forceRestart via /pty-restart + pagehide /pty-dispose
Closes the Commit 2 loop: server-side lease + restart routes shipped in
25ef24e9; this commit wires the extension client to use them. End-to-end
result — clicking Restart now actually kills the server's PTY before
opening a new WS (zero race window), and closing the sidebar / quitting
the browser disposes the PTY immediately instead of letting it linger
for the upcoming 60s detach window.

sidepanel-terminal.js:
  * mintSession callers read the v1.44 4-tuple (sessionId + attachToken)
    from /pty-session, with a backward-compat fallback to ptySessionToken
    so a partially-updated extension still works against a fresh server
    for one minor release.
  * Eager spawn via {type:"start"} text frame replaces the legacy
    `TextEncoder().encode("\n")` newline hack. Pre-v1.44, the lazy-binary-
    spawn pattern made forceRestart look stuck until the user typed —
    now claude boots before the prompt renders.
  * forceRestart() rewritten as an async one-transaction handler:
      1. close current WS with code 4001 (intentional-restart)
      2. POST /pty-restart with priorSessionId so the server can scope
         the dispose, then mint fresh sessionId + lease + attachToken
         in the same response
      3. Open new WS with the returned attachToken, send {type:"start"}
         immediately for eager spawn
      4. On 401: sticky-abort the auto-connect loop (no spam)
      5. On 503 / network failure: fall back to patient autoconnect
  * currentSessionId tracked and exposed on window.gstackPtySession so
    sidepanel.js's pagehide handler can sendBeacon the dispose.

sidepanel.js:
  * New pagehide handler fires navigator.sendBeacon('/pty-dispose',
    {sessionId, authToken}) on tab close, panel close, browser quit,
    or extension reload. sendBeacon-compatible: auth token rides in
    the body since sendBeacon can't set custom headers (server route
    accepts body-auth per 25ef24e9).
  * try/catch around the entire body so a sendBeacon failure can't
    interfere with the browser's unload sequence — the 60s detach
    window from Commit 3 catches anything we miss.

There's bounded duplication between connect() and forceRestart() (~70
lines of WS attach/handler wiring). Extracting a shared helper is a
clean follow-up but out of scope for the v1.44 ship — both paths are
exercised by the same e2e test.

Test (browse/test/sidepanel-restart-dispose.test.ts):
  * 9 static-grep tripwires pinning the 4-tuple parse, eager spawn,
    close-code 4001 contract, /pty-restart wire shape, sticky-abort
    401 path, sessionId window plumbing, sendBeacon body contract,
    and the best-effort try/catch around pagehide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 23:19:25 -07:00
..
icons feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
background.js feat: gstack browser sidebar = interactive Claude Code REPL with live tab awareness (v1.14.0.0) (#1216) 2026-04-25 22:52:15 -07:00
content.css feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
content.js refactor: AI slop reduction with cross-model quality review (v0.16.3.0) (#941) 2026-04-10 17:13:15 -10:00
inspector.css feat: sidebar CSS inspector + per-tab agents (v0.13.9.0) (#650) 2026-03-30 12:51:05 -06:00
inspector.js refactor: AI slop reduction with cross-model quality review (v0.16.3.0) (#941) 2026-04-10 17:13:15 -10:00
manifest.json v1.32.0.0 fix wave: 7 community PRs + 5 gate-eval hardenings (#1431) 2026-05-11 12:16:26 -07:00
popup.html feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
popup.js feat: headed mode + sidebar agent + Chrome extension (v0.12.0) (#517) 2026-03-26 11:15:24 -06:00
sidepanel-terminal.js feat(sidebar): forceRestart via /pty-restart + pagehide /pty-dispose 2026-05-23 23:19:25 -07:00
sidepanel.css v1.30.0.0 fix wave: 21 community PRs + Windows CI extension + codex flag-semantics smoke (#1391) 2026-05-09 08:06:47 -07:00
sidepanel.html feat: gstack browser sidebar = interactive Claude Code REPL with live tab awareness (v1.14.0.0) (#1216) 2026-04-25 22:52:15 -07:00
sidepanel.js feat(sidebar): forceRestart via /pty-restart + pagehide /pty-dispose 2026-05-23 23:19:25 -07:00