Skip to content

cmux-next agent pane: Vite dev server in Debug builds, and ~/.config/cmux/agent-pane hot reload - #16433

Merged
teamleaderleo merged 6 commits into
feat-cmux-nextfrom
feat-cmux-next-agent-pane-devloop
Oct 1, 2026
Merged

teamleaderleo merged 6 commits into
feat-cmux-nextfrom
feat-cmux-next-agent-pane-devloop

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Changing the agent pane's React code used to mean rebuilding the bundle and the app. Now a Debug or tagged build can load the pane from a local Vite dev server, so TypeScript edits show up in the running app in about a second:

cd webviews && bun run dev:agent-pane          # 127.0.0.1:4176
CMUX_NEXT_AGENT_PANE_DEV_URL=http://127.0.0.1:4176/ ./scripts/reload.sh --tag <tag>

Dev server mode:

  • Resolving the page: AgentPaneSource.resolve(environment:bundledPage:allowsDevServer:) accepts only an http URL on 127.0.0.1 or localhost, with an explicit port and no credentials. Anything else falls back to the bundled page.
  • Trust: the bridge, navigation policy and crash reload all go through AgentPaneSource, so the pane trusts only the dev server's exact scheme, host and port.
  • Release: AgentTabStore passes allowsDevServer: true only under #if DEBUG, so Release still loads nothing but the bundled file.
  • Handshake: endpoint, token and session still come from Swift through ready, so the dev page talks to the real acpmux daemon.
  • Tagged launches: scripts/reload.sh forwards the variable through its env -i launch.
  • Web side: webviews/vite.config.acpmux-pane.mjs and a dev index.html with a dev CSP. The README has the full loop.

Customization hot reload (ported from #16042):

  • theme.css, layout.json and registry.js in ~/.config/cmux/agent-pane/ are watched with ConfigFileWatcher and pushed into every open agent pane. The directory follows CMUX_NEXT_CONFIG_FILE.
  • feat: add React acpmux agent pane #16042 bug fixed: a missing file no longer drops the whole push. A deleted theme.css clears the style, and an invalid layout.json is ignored.
  • registry.js: it is evaluated by the host as its own script instead of the page's eval, which the bundled page's CSP blocks.
  • Trust: registry.js runs with page privileges, including access to the daemon token, the same trust as in feat: add React acpmux agent pane #16042, since it's the user's own config file. Any local process on the dev port would also receive the token; the README says so.

Follows #16231.## Verification

  • Swift: new suites AgentPaneSourceTests (including releaseIgnoresTheDevServerOverride) and AgentPaneCustomizationTests, plus updated AgentPaneNavigationTests. They're meant to fail at ba855a4 (stubs) and pass at head. registryWithDeclarationsReplaysInTheSamePage was added at b3a745f, after review found that replaying registry.js as a global script throws on top-level const/class. The system jsc confirms the semantics: the raw script registers once and then throws SyntaxError, while the function-wrapped form from 86b8e98 registers on both runs. Not run yet: this Mac doesn't build cmux, and the cmux-next swift test lane is currently red for unrelated reasons, so the red and green results are unproven.
  • Fleet build: nx-devloop-v1 at b4e16a2 is running. Dogfooding follows: New Agent Chat with the dev server, edit a row component, and a hot-reload of theme.css.
  • webviews: bun run test (254 pass), typecheck and lint:ci pass. build-agent-pane-web.sh --check and build-webviews-app.sh --check pass, so neither build picks up the new dev entry. bun run dev:agent-pane served all 24 modules with 200.
  • Lints: namespace lint (no baseline entries), check-concurrency, no-godfiles, crash-safety, module-resources, l10n and motion pass.
  • reload.sh: test_reload_local_backend_mode.sh, test_reload_build_only_keeps_tagged_app.sh, test_reload_shared_derived_data.sh, test_reload_tag_lock.py and test_ci_reload_build_cache_keys.py pass.

Changelog

none

🤖 Generated with Claude Code

https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Debug and tagged builds can now load the agent pane from a local Vite dev server so TypeScript edits hot-reload in the running app, and customization files in ~/.config/cmux/agent-pane/ hot-reload into open panes. Release builds still load only the bundled page.

Dev server

  • Set CMUX_NEXT_AGENT_PANE_DEV_URL=http://127.0.0.1:4176/ with bun run dev:agent-pane; reload.sh forwards the variable, and only Debug builds honor it.
  • The URL must be http on 127.0.0.1 or localhost with an explicit port, and the pane's bridge, navigation, and crash reload trust only that exact origin.
  • The handshake still comes from Swift, so the dev page talks to the real acpmux daemon; the README warns that any local process on the dev port would also receive the daemon token.

Customization hot reload

  • theme.css, layout.json, and registry.js next to cmux.json (so CMUX_NEXT_CONFIG_FILE moves them) are watched and pushed to every open pane.
  • registry.js is evaluated as its own host script, bypassing the bundled page's CSP that blocked the previous eval; each replay runs in a fresh function scope so top-level const, let, and class declarations don't collide, and a broken registry no longer stops the theme.
  • A missing file no longer drops the whole push: deleting theme.css clears the style, and an invalid layout.json is ignored.

Written for commit 0f720a9. Summary will update on new commits.

Review in cubic

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 11fdb438-73dd-42ce-af65-d2d6f61fe938

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 18 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/src/agent-session/acpmux/README.md">

<violation number="1" location="webviews/src/agent-session/acpmux/README.md:7">
P2: This says a missing or invalid layout is skipped, but the host sends `{}` to `configure` instead. Document that behavior or avoid calling `configure` when no valid layout exists.</violation>

<violation number="2" location="webviews/src/agent-session/acpmux/README.md:7">
P2: This describes `registry.js` as a host script without warning that it runs in the pane's page context and can access the daemon token. State that it is trusted code so users do not run untrusted registry scripts.</violation>
</file>

<file name="Packages/macOS/CmuxNext/Tests/CmuxNextAgentPaneTests/AgentPaneCustomizationTests.swift">

<violation number="1" location="Packages/macOS/CmuxNext/Tests/CmuxNextAgentPaneTests/AgentPaneCustomizationTests.swift:96">
P2: The injection marker is never observed: `run(_:)` returns only `calls`, so `window.pwned = 1` can execute while these assertions still pass. Make the payload append a marker to `calls` so the existing count assertion detects execution.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Rows are measured before paint with [Pretext](https://github.com/chenglou/pretext) using the named `Helvetica Neue` font. Prepared markdown blocks are cached by row id, content version, and text. Layout stores exact tops and heights in typed arrays and finds the visible range with binary search. React mounts only that range; row components are memoized by id and content version, so a streaming update replaces one row.

User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components; Swift watches the files and replays them to the page.
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This says a missing or invalid layout is skipped, but the host sends {} to configure instead. Document that behavior or avoid calling configure when no valid layout exists.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/README.md, line 7:

<comment>This says a missing or invalid layout is skipped, but the host sends `{}` to `configure` instead. Document that behavior or avoid calling `configure` when no valid layout exists.</comment>

<file context>
@@ -4,6 +4,17 @@ Swift is the WKWebView host only. On `ready`, the versioned host bridge returns
 Rows are measured before paint with [Pretext](https://github.com/chenglou/pretext) using the named `Helvetica Neue` font. Prepared markdown blocks are cached by row id, content version, and text. Layout stores exact tops and heights in typed arrays and finds the visible range with binary search. React mounts only that range; row components are memoized by id and content version, so a streaming update replaces one row.
 
-User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components; Swift watches the files and replays them to the page.
+User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.
 
 The virtualized DOM cannot provide selection or find across rows that are unmounted. The v1 pane keeps cmux find in the host, which can ask the direct client to page and mount a matching row in a future action. The preview harness is the iteration path: `cd webviews && bun run preview:dev` for Vite hot reload, or `bun run preview:build`, which writes static files to `webviews/dist/acpmux-agent-session-preview/`.
</file context>
Suggested change
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` in the page context, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and passes the layout to the registry's `configure` as `{}` when `layout.json` is missing or invalid. Missing or unreadable files do not block other updates.

Rows are measured before paint with [Pretext](https://github.com/chenglou/pretext) using the named `Helvetica Neue` font. Prepared markdown blocks are cached by row id, content version, and text. Layout stores exact tops and heights in typed arrays and finds the visible range with binary search. React mounts only that range; row components are memoized by id and content version, so a streaming update replaces one row.

User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components; Swift watches the files and replays them to the page.
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This describes registry.js as a host script without warning that it runs in the pane's page context and can access the daemon token. State that it is trusted code so users do not run untrusted registry scripts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/README.md, line 7:

<comment>This describes `registry.js` as a host script without warning that it runs in the pane's page context and can access the daemon token. State that it is trusted code so users do not run untrusted registry scripts.</comment>

<file context>
@@ -4,6 +4,17 @@ Swift is the WKWebView host only. On `ready`, the versioned host bridge returns
 Rows are measured before paint with [Pretext](https://github.com/chenglou/pretext) using the named `Helvetica Neue` font. Prepared markdown blocks are cached by row id, content version, and text. Layout stores exact tops and heights in typed arrays and finds the visible range with binary search. React mounts only that range; row components are memoized by id and content version, so a streaming update replaces one row.
 
-User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components; Swift watches the files and replays them to the page.
+User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.
 
 The virtualized DOM cannot provide selection or find across rows that are unmounted. The v1 pane keeps cmux find in the host, which can ask the direct client to page and mount a matching row in a future action. The preview harness is the iteration path: `cd webviews && bun run preview:dev` for Vite hot reload, or `bun run preview:build`, which writes static files to `webviews/dist/acpmux-agent-session-preview/`.
</file context>
Suggested change
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` as host script, separately so a broken registry cannot stop the theme, then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and hands `layout.json` to the registry's `configure`. A file that is missing or invalid is skipped and the others still apply.
User customization files live in `~/.config/cmux/agent-pane/`: `theme.css`, `layout.json`, and `registry.js`. Registry components must provide a static `measure(row, width)` function returning a Pretext-based height. Components without it use post-mount measurement and scroll anchoring. `registry.js` can register or replace message, tool, edited-files, permission, and composer-chip components. cmux-next watches the directory (next to `cmux.json`, so `CMUX_NEXT_CONFIG_FILE` moves it) and pushes changes to open panes: it evaluates `registry.js` in the page context, where it can access the daemon token, so only trusted scripts should be used; a broken registry cannot stop the theme. It then calls `applyCustomization({themeCSS, layout})`, which replaces the user stylesheet (an empty one after `theme.css` is deleted) and passes the layout to the registry's `configure` as `{}` when `layout.json` is missing or invalid. Missing or unreadable files do not block other updates.

}

@Test func themeTextCannotEscapeTheCall() throws {
let hostile = #"a::after { content: "\"}); window.pwned = 1; //" }"# + "\n</script>\u{2028}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The injection marker is never observed: run(_:) returns only calls, so window.pwned = 1 can execute while these assertions still pass. Make the payload append a marker to calls so the existing count assertion detects execution.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At Packages/macOS/CmuxNext/Tests/CmuxNextAgentPaneTests/AgentPaneCustomizationTests.swift, line 96:

<comment>The injection marker is never observed: `run(_:)` returns only `calls`, so `window.pwned = 1` can execute while these assertions still pass. Make the payload append a marker to `calls` so the existing count assertion detects execution.</comment>

<file context>
@@ -0,0 +1,111 @@
+    }
+
+    @Test func themeTextCannotEscapeTheCall() throws {
+        let hostile = #"a::after { content: "\"}); window.pwned = 1; //" }"# + "\n</script>\u{2028}"
+        let customization = AgentPaneCustomization(themeCSS: hostile)
+        let calls = try run(customization)
</file context>
Suggested change
let hostile = #"a::after { content: "\"}); window.pwned = 1; //" }"# + "\n</script>\u{2028}"
let hostile = #"a::after { content: "\"}); calls.push("injected"); //" }"# + "\n</script>\u{2028}"

teamleaderleo and others added 3 commits October 1, 2026 14:13
The pane's page now comes from an AgentPaneSource (the bundled file, or a
loopback Vite dev server), and AgentPaneCustomization carries the
~/.config/cmux/agent-pane/ files to the page. Both are stubs here: the
dev-server override is ignored, its origin is never trusted, and the
customization reads and pushes nothing, so the new suites fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
A Debug or tagged build launched with
CMUX_NEXT_AGENT_PANE_DEV_URL=http://127.0.0.1:<port>/ loads the pane from
that loopback dev server (bun run dev:agent-pane, port 4176) instead of
the bundled page, so TypeScript edits hot-reload in the running app. The
handshake still comes from Swift, so the dev page talks to the real
acpmux daemon.

AgentPaneSource.resolve takes allowsDevServer, which the App sets only
under #if DEBUG: Release loads the bundled file whatever the environment
says. The override must be http on 127.0.0.1 or localhost with an
explicit port and no credentials; anything else keeps the bundled page.
Navigation and the handshake trust only that exact origin. reload.sh
forwards the variable into the tagged launch environment, and the pane
README documents the loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
Ports #16042's customization hot reload. AgentPaneCustomizationWatcher
watches theme.css, layout.json and registry.js next to cmux.json (so
CMUX_NEXT_CONFIG_FILE moves them) with ConfigFileWatcher, reads them off
the main actor, drops unchanged results, and sets the value on every
agent pane; new panes get the current value. It runs while any agent tab
has a view.

AgentPaneView pushes a change at once, and replays it after a load and
when the page asks for the handshake (its bridge and registry exist by
then). registry.js is evaluated as its own host script, since the bundled
CSP has no unsafe-eval, so a broken registry no longer stops the theme;
then applyCustomization({themeCSS, layout}) runs. A missing file is
skipped instead of failing the push, a deleted theme.css sends "" and
clears the style, and layout.json must be a JSON object. The page hands
layout to the registry's configure. The bundled page is rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
@teamleaderleo
teamleaderleo force-pushed the feat-cmux-next-agent-pane-devloop branch from b4e16a2 to f772804 Compare October 1, 2026 18:13
teamleaderleo and others added 2 commits October 1, 2026 14:18
…clarations

The pane re-evaluates registry.js on every load, handshake and file
change. As a global classic script, a second run of a file with a
top-level const, let or class throws a SyntaxError (duplicate variable)
before registering anything. Checked in the system jsc: the raw script
registers once and then throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
Each replay of registry.js now runs it inside a fresh function, as
#16042's indirect eval did, so top-level const, let and class
declarations don't collide with the previous run. The README says the
file is replayed and should be idempotent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RYQHfug1ZVQDp4eWgwVUtD
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Subagent review at f772804: REQUEST_CHANGES. Release safety and dev-origin trust check out. The blocker: registry.js was re-evaluated as a global classic script on every load, handshake and file change, so a file with top-level const, let or class threw a SyntaxError on its second run. Fixed in b3a745f (test) and 86b8e98 (function-scope wrapper plus a README note about idempotence). A fresh review of the new head follows.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Subagent review at 86b8e98: APPROVE.

  • registry.js fix: checked in jsc, including a trailing // comment and a syntax error contained to its own script. The new test is a valid red→green discriminator.
  • Release: the #if DEBUG gate holds, and trust is the exact origin only.
  • Swift: the code reads compile-clean; the tests haven't been run.

Non-blocking:

  • the dead (0, eval) path in applyCustomization;
  • layout: {} is sent on every push;
  • the first push before page load is wasted;
  • the Swift red/green results still need recording once the swift test lane works.

…ext-agent-pane-devloop

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/Resources/agent-pane/index.html
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Merging. 0f720a9 is the approved head 86b8e98 with feat-cmux-next (#16426) merged in. The only conflict was the generated agent-pane/index.html, rebuilt with --check passing, and webviews tests (269 pass), typecheck and lint pass. Release compile, iOS and web checks are green. cmux-next swift test is the lane's existing debt (cx-next-swift-tests), so this PR's new Swift tests still have no recorded result; they need one once that lane runs. Dogfood results are in the body.

@teamleaderleo
teamleaderleo merged commit 076ee70 into feat-cmux-next Oct 1, 2026
51 of 52 checks passed
@teamleaderleo
teamleaderleo deleted the feat-cmux-next-agent-pane-devloop branch October 1, 2026 18:42
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.

1 participant