Resolve the real site running state when resuming code sessions headlessly - #4096
Merged
Conversation
…essly Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
📊 Performance Test ResultsComparing 2da0d55 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
bcotrim
approved these changes
Jul 7, 2026
bcotrim
left a comment
Contributor
There was a problem hiding this comment.
@shaunandrews — while reviewing this we found the same bug hiding in two more entry points, so the fix moved one level down and got broader:
- Before: the resume command resolved the running state itself — fixing only the desktop/headless path.
- Now:
runAgentTurnasks the daemon right before building the context banner, every turn. One guard covers all entry points — desktop headless resume (the original STU-2001), interactivestudio code sessions resume(session replay hardcodedrunning: false), andstudio code --path(flag never set) — plus mid-session changes (stop/start a site from another terminal and the next turn reflects it).
Simple test plan (needs a built CLI: npm run cli:build):
- Start a local site in Studio.
studio code→ pick the running site → send "just reply ok, don't use tools" → exit.studio code sessions resume latest→ first message: "Without using any tools, is my active site running?" → should say running (on trunk it says stopped).- Stop the site, send the same question again → should say stopped.
- Desktop is still covered by the original testing instructions in the PR description.
- Unit tests:
npm test -- apps/cli/commands/ai
Pushed the fix and approved so we can merge this as CI goes green
Merged
1 task
bcotrim
pushed a commit
that referenced
this pull request
Jul 11, 2026
…headless runs can exit (#4175) ## Related issues - Fixes [STU-2040](https://linear.app/a8c/issue/STU-2040/headless-code-sessions-never-exit-after-turncompleted-leaving-desktop) - Related to [STU-2001](https://linear.app/a8c/issue/STU-2001/agent-always-sees-local-sites-as-stopped-in-desktop-studio-code) / #4096 ## How AI was used in this PR Claude Code applied the fix, verified it end-to-end in both directions (fixed build exits, unfixed build hangs), and drafted this PR. I reviewed and directed the work. ## Proposed Changes Since #4096, every headless `studio code … --json` turn on a local site leaves the CLI process alive after it reports `turn.completed`. The per-turn site running-state check opens a connection to the process-manager daemon and never closes it, and that open socket keeps the process from exiting. The desktop app feels this the most: each turn forks a headless `code sessions resume` child and treats the child's exit as the end of the turn. Because the child never exits, the session appears stuck in the working state forever — the stop button and the sidebar agent-activity indicator never clear — and an orphaned node process piles up for every turn taken on a running-or-stopped local site. The fix closes the daemon connection as soon as the running-state check completes, the same way every other daemon consumer in the CLI already does. The connection is a singleton, so anything later in the turn that needs the daemon (like the WP-CLI tool) reconnects transparently. ## Testing Instructions 1. `npm run cli:build` 2. Run a headless turn against a local site: `node apps/cli/dist/cli/main.mjs code --json --path ~/Studio/<site> "Reply with only the word OK."` 3. The process should exit on its own a moment after the `turn.completed` event (on trunk it hangs indefinitely and must be killed). 4. In the desktop app, take a turn in a Studio Code session on a local site and confirm the working indicator clears when the turn finishes. 5. Tests: `npm test -- apps/cli/commands/ai/sessions/tests/resume.test.ts apps/cli/commands/ai/tests/index.test.ts` ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
shaunandrews
added a commit
that referenced
this pull request
Jul 17, 2026
The STU-2001 fix (#4096) asks the daemon whether the active site is running before every turn, but never disconnected. The open socket kept the headless --json child alive after turn.completed, so the desktop never saw run.exited and sessions stayed stuck in the working state (stop button + sidebar activity indicator).
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.
Related issues
How AI was used in this PR
Claude Code investigated the root cause, wrote the fix and tests, and drafted this PR. I reviewed and directed the work.
Proposed Changes
In desktop Studio Code sessions, the agent's per-turn context banner always described the active local site as
(stopped), no matter its actual state. The agent would then defensively callsite_startbefore WP-CLI or other site operations — wasting a tool call every turn and confusing users whose site was clearly already running.The cause: every desktop turn runs
studio code sessions resume --json, which hydrates the active site from the session's event log. That log carries no running state, and the missing flag defaulted to "stopped". Now the headless resume path asks the daemon whether the site is actually up before dispatching the turn, so the agent sees the truth: no more redundantsite_startcalls, and the agent can correctly warn when the site really is stopped.Sites missing from the CLI config are still treated as stopped, and remote (WordPress.com) sites skip the check since running state doesn't apply to them.
Testing Instructions
(stopped)and it would often callsite_startfirst; now the context shows(running)and it goes straight to the WP-CLI call.(stopped).npm test -- apps/cli/commands/ai/sessions/tests/resume.test.tsPre-merge Checklist
🤖 Generated with Claude Code