Hot reload every page in Debug and tagged builds (cx-urd.56)

Merged
TE
1mo ago
+6470-14167

Summary

Only the agent pane and the standalone Settings server could hot reload, and neither ran inside the app's page host. Now every page cmux-next hosts hot reloads in a Debug or tagged build: the React pages (apps, changelog, cloud, coderouter, history, icon-picker, keybindings, passwords, settings) and the diff, markdown and code editor viewers.

cd webviews && bun run dev:pages        # one Vite server on http://127.0.0.1:4190/
CMUX_NEXT_PAGES_DEV_URL=http://127.0.0.1:4190/ ./scripts/reload.sh --tag <tag>

How it works:

  • The page keeps its own cmux-page://<id>/ origin. PageSchemeHandler answers each request from the dev server instead of the bundle: the document maps to /<page>/ (or /diff-page.html, /markdown-page.html, /editor-page.html), and every module, the Vite client and dependencies keep their path and query. The host bridge, routing and PageHostTrust are the shipped ones, so the page talks to the real app.
  • Dynamic prefixes (__patch, backdrop, the markdown assets) still come from the page instance. An app page and the agent pane (which has its own override) are never proxied. A reply redirected off the dev server's origin is refused.
  • In dev, the page's CSP adds only the server's HMR socket and its reconnect ping (ws:// and http:// on that host and port). vite.config.pages-dev.ts points the Vite client's socket at the server, because the page's origin isn't the server.
  • PageDevServer reads CMUX_NEXT_PAGES_DEV_URL only when DEBUG is set. The URL must be http on 127.0.0.1 or localhost with an explicit port and no credentials. That loopback rule is now shared: AgentPaneSource.devServerURL calls PageDevServer.loopbackURL. Release ignores the variable.
  • reload.sh forwards the variable. web-dev.sh starts the pages server and prints the launch line. The dev server now serves all nine React pages (it served five), and rewrites href="./" as well as src="./" (Settings links its stylesheet).

Testing

  • PageDevServerTests (new, CmuxNextPagesTests):

    • Release ignores the variable (resolve(..., allowsDevServer: false) is nil with it set).
    • Only loopback http with a port and no credentials is accepted.
    • Each page maps to its dev path; dynamic prefixes, app pages and the agent pane are not proxied.
    • The dev CSP adds only the socket.
    • The scheme handler serves a module from the server with that CSP, and serves the bundle with no server.
    • A cross-origin reply is refused.
  • Red, test commit e801a6f3056 with a stub PageDevServer: cmux-ci run --class light --script scripts/ci/run-swift-testing-suites.sh --arg=Packages/macOS/CmuxNext --red. Result pending.

  • Green, 42a367b9a6f: the same suite runner. Result pending.

  • python3 scripts/verify-local.py --affected origin/feat-cmux-next --swift-changed origin/feat-cmux-next passes except localization, localization-defaults and package-groups, which fail the same way on a clean origin/feat-cmux-next. check-no-godfiles.sh and crash_ratchet.py pass.

  • Not yet checked live: a tagged build running dev:pages with an edit hot reloading in a page. That needs the fleet dev build this PR asks for.

  • Unit tests: dropped on 2026-10-09 under the cmux-next no-unit-tests rule. The real verification is the live HMR check on a tagged build (bead cx-urd.57), which is still open.

Changelog

none

Proof

A developer-only path that Release ignores. A live reload in a tagged build will be added after the fleet dev build.

🤖 Generated with Claude Code


[!NOTE]
Medium Risk
Touches page loading/CSP and release signing workflows; large agent-chat test removal reduces regression coverage unless boundary tests fully replace them.

Overview
Adds Debug-only hot reload for all cmux-next hosted pages via CMUX_NEXT_PAGES_DEV_URL and a new PageDevServer that proxies cmux-page:// requests to a local Vite server (bun run dev:pages), with tightened CSP for HMR and shared loopback URL rules for the agent pane.

WebKit automation now allows scripted right-clicks without stealing the user’s context menu, fixes middle-button and wheel targeting, and registers run.get / run.list in app platform scopes.

CI and release plumbing: removes the standalone agent-session-web and many agent-chat unit tests (preflight still runs bun run test / boundary tests); drops cmux-tui web npm test and speeds daemon tests with a single cargo test pass; cmux-next-dev-daily signs and publishes a rolling cmux NEXT DEV GitHub prerelease from feat-cmux-next Release artifacts; dogfood/NEXT DEV packaging uses always() so later steps don’t block uploads.

Reviewed by Cursor Bugbot for commit fd8fbb50ec4c1c8580268ced9a761e8f88bf8c25. Bugbot is set up for automated code reviews on this repo. Configure here.