Fix background read-screen PTY startup
Fixes #1472.
Summary
- Add runtime regression coverage for a plain background workspace where
read-screenis the first operation requiring a PTY. - Route terminal text reads through
TerminalSurfacedemand-start logic so a background workspace can create its hidden runtime surface without selecting or focusing the workspace. - Preserve the idle background workspace policy: no PTY is created at
workspace.createtime unless there is startup work;read-screenstarts it on demand.
Reproduction
- Classified as a bug from issue #1472. The current code path still let
readTerminalTextBase64readterminalPanel.surface.surfacedirectly while background priming intentionally skipped idle workspaces without deferred startup work. - Local app reproduction/build was not run because this task explicitly forbids
reload.shandxcodebuild; the regression is captured in the first commit as a runtimetests_v2repro.
Test plan
- Not run locally per repo policy and task constraints. CI should run the new
tests_v2/test_background_workspace_read_screen_starts_pty.pycoverage.
Commit structure
991efe189adds the failing regression test first.b4fb5b01aadds the fix separately.
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.
[!NOTE]
Medium Risk
Changes when PTYs spin up for socket reads and could affect idle background workspaces or race with headless startup; mitigated by snapshot path staying existing-only and new regression test.
Overview
Fixes background read-screen failing when a workspace has no PTY yet by demand-starting the hidden runtime surface on socket/API reads, without focusing the workspace.
Adds liveSurfaceForSocketRead on TerminalSurface: if no live Ghostty surface exists and runtime creation is allowed, it bootstraps via the existing headless-window path (same idea as socket writes), with DEBUG timing logs.
TerminalController terminal text reads no longer use terminalPanel.surface directly. A TerminalTextSurfaceAccess split routes surface.read_text / CLI read-screen through socket read (demand-start) while snapshot reads still require an existing surface only. Selection helpers take the resolved ghostty_surface_t after that lookup.
Adds tests_v2/test_background_workspace_read_screen_starts_pty.py to assert a non-focused background workspace can read-screen, then send/send-key, without switching the selected workspace.
Reviewed by Cursor Bugbot for commit 250cd24fe44db0df36ea0b75e3451f97e59e507f. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Fixes #1472 by demand-starting a PTY when read-screen or API surface.read_text runs on a background workspace, creating a hidden runtime surface without changing focus. Also moves surface.read_text to the socket worker with off-main Claude shim prep and stricter param checks.
- Bug Fixes
- Added
TerminalSurface.liveSurfaceForSocketRead(...)to bootstrap a hidden runtime surface for socket/API reads; includes DEBUG timing logs. - Introduced
TerminalTextSurfaceAccesswith.existingvs.socketRead; CLIread-screenand APIsurface.read_textuse.socketRead, while snapshots use.existing. Reads now resolve aghostty_surface_tand only error when creation isn’t allowed. - Registered
surface.read_textin execution policy to run on the socket worker; performs Claude shim prep off-main viaclaudeCommandShimInstallRequestForSocketRead()/finishClaudeCommandShimInstallForSocketRead(...), then delegates to the coordinator. - Tightened socket read validation: reject
lines <= 0forsurface.read_textto avoid invalid reads.
- Added
Summary by CodeRabbit
-
New Features
- Enhanced socket-based terminal text reading capabilities with improved surface access handling for background operations.
-
Tests
- Added regression test verifying
read-screencorrectly functions on unfocused workspaces without interrupting the currently active workspace.
- Added regression test verifying
-
Documentation
- Minor formatting updates to example documentation.