Skip to content

apps/ui: auto-refresh site preview as the agent edits#3235

Merged
youknowriad merged 2 commits intotrunkfrom
claude/naughty-mahavira-9d3f10
Apr 24, 2026
Merged

apps/ui: auto-refresh site preview as the agent edits#3235
youknowriad merged 2 commits intotrunkfrom
claude/naughty-mahavira-9d3f10

Conversation

@youknowriad
Copy link
Copy Markdown
Contributor

Related issues

  • Related to the agent coding-session experience: the site preview next to each session was static, so users had to click refresh to see what the agent just did.

How AI was used in this PR

Authored with Claude Code. The model drove the implementation end-to-end (architecture discussion → MCP tool design → renderer wiring → tests). I reviewed and steered at each step — asked for a detailed architecture of the most-reliable option, had it gate the tools for standalone CLI after I noticed the noisy tool-call messages, and flagged follow-ups rather than bundling them. Verification (typecheck, lint, 110 unit tests) was run locally.

Proposed Changes

  • New MCP tools (apps/cli/ai/tools.ts): preview_navigate(path) and preview_reload() — the agent calls these as a side effect of its editing loop. Handlers emitEvent({ type: 'preview.command', ... }) and return synchronously.
  • Event pipeline: added a preview.command variant to JsonEvent (tools/common/ai/json-events.ts). Events ride the existing CLI→main→renderer ai-agent-event channel — no new IPC surface.
  • Renderer subscriber (apps/ui/src/components/site-preview/index.tsx): SitePreview now takes a sessionId, subscribes to connector.onAgentEvent, filters for matching preview.commands, and drives the iframe via currentPath + a reloadNonce. The nonce is baked into the iframe key so reloads force a remount — more reliable than iframe.contentWindow.location.reload() across self-signed certs / custom-domain boundaries.
  • Session wiring (apps/ui/src/components/session-view/index.tsx): passes sessionId to SitePreview.
  • Standalone-CLI gating (apps/cli/ai/agent.ts, apps/cli/ai/tools.ts, apps/cli/ai/system-prompt.ts): enablePreviewSteering is derived from typeof process.send === 'function' (the same signal emitEvent uses to pick IPC vs stdout). When the CLI runs standalone — not forked by the desktop app — the preview tools are filtered out of the MCP server and omitted from the system prompt, so the model never sees them and the terminal transcript doesn't show noisy "Reload preview" / "Navigate preview" entries.
  • Display names + details (tools/common/ai/tools.ts): so the desktop transcript renders Navigate preview /about/ nicely.
  • System-prompt guidance: a new "Keep the preview in sync with your work" section (only emitted when preview-steering is enabled) nudges the model to call preview_reload after editing theme/CSS/homepage and preview_navigate after editing a specific page/post/template.
  • Tests: 5 new cases in apps/cli/ai/tests/tools.test.ts covering navigate normalization, empty-path fallback, reload emission, and the gating behavior (with and without enablePreviewSteering).

What isn't here yet

  • No fallback reload on turn.completed. If the agent forgets to call the tools, nothing updates the preview. Intentionally left as a follow-up — want to see how good model compliance is on the system-prompt guidance first before layering a belt-and-suspenders reload in run-manager.
  • No replay on session reopen. Preview commands are transient (not persisted in the JSONL); reopening a preview starts at `/`. The agent will re-navigate on its next relevant edit.
  • Remote WP.com sites: explicitly excluded in the system prompt; the preview drawer only shows for local environments anyway.

Testing Instructions

  1. Pull this branch and run `npm start`.
  2. In a coding session with a local site, open the preview drawer (top-right icon in session header).
  3. Ask the agent to edit the front page of the theme — verify the preview reloads automatically after the edit.
  4. Ask it to edit a specific page (e.g. "add a heading to the About page") — verify the preview navigates to `/about/` and reloads.
  5. Close and reopen the drawer mid-session — verify it starts at `/` and will re-navigate on the next agent edit.
  6. Standalone CLI: run `node apps/cli/dist/cli/main.mjs code` in a terminal, start a session, edit something. Verify no `Reload preview` / `Navigate preview` messages appear in the transcript.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?
  • Tests pass (`npm test` — all 110 affected tests green).
  • Lint/format clean on modified files.

Adds two MCP tools (preview_navigate, preview_reload) the agent calls
after editing a page, template, or theme so the Studio site-preview
iframe updates in sync with the work. Commands flow from the CLI child
process through the existing ai-agent-event IPC stream to the renderer,
where SitePreview subscribes (scoped by sessionId) and remounts the
iframe. Tools are gated on a forked-by-desktop signal so plain CLI runs
neither see nor mention preview-steering tools.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented Apr 24, 2026

📊 Performance Test Results

Comparing dc458ab vs trunk

app-size

Metric trunk dc458ab Diff Change
App Size (Mac) 1440.82 MB 1440.82 MB +0.00 MB ⚪ 0.0%

site-editor

Metric trunk dc458ab Diff Change
load 1740 ms 1831 ms +91 ms 🔴 5.2%

site-startup

Metric trunk dc458ab Diff Change
siteCreation 8078 ms 8094 ms +16 ms ⚪ 0.0%
siteStartup 4949 ms 4937 ms 12 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

Array.prototype.includes narrows on the element type, which fails
against the broader studioToolDefinitions union. Switch to a Set of
tool names so the filter doesn't depend on the narrower subtype.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@youknowriad youknowriad merged commit b73d401 into trunk Apr 24, 2026
10 checks passed
@youknowriad youknowriad deleted the claude/naughty-mahavira-9d3f10 branch April 24, 2026 15:33
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.

2 participants