Skip to content

cmux NEXT: view a Claude Code or Codex session without taking it over - #21921

Merged
teamleaderleo merged 43 commits into
feat-cmux-nextfrom
leo/acpmux-watch-session
Oct 21, 2026
Merged

teamleaderleo merged 43 commits into
feat-cmux-nextfrom
leo/acpmux-watch-session

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Leo wants to see a Claude Code or Codex session open in cmux NEXT next to the app that runs it, to compare the UI and move over gradually, without cmux taking the session away. This adds a View Only open: cmux NEXT shows the chat and follows the app as it writes, and it never resumes, writes to or locks the original. Take Over is a separate, explicit step. Viewing never blocks starting a session: new chats, harness picks and folders work as before, and the viewer always offers a new chat of its own.

Behavior

  • acpmux watch mode. session/new with adopt.watch: true (Claude Code or Codex) looks up the transcript the way adoption does: ~/.claude/projects/**/<id>.jsonl, or a Codex rollout-…-<id>.jsonl. It does not start the harness. The chat replays the transcript into acpmux history, then reads only new complete lines every 400 ms and shows each prompt and answer as it lands. It stores the file and the byte offset (SessionMeta.watching), so a daemon restart picks up where it stopped. A transcript that is replaced or truncated is read again from the start.
  • Nothing touches the original. The transcript file is opened read-only, and no agent process starts, so there is no --resume, session/load or lock. A prompt is refused with watch.read_only, and web origins cannot use _acpmux/watch_take_over (watch.origin_refused).
  • Take Over. _acpmux/watch_take_over ends the watch. The next prompt resumes the conversation as an ordinary adopted chat. If the transcript was written in the last few minutes, Take Over first answers with the same adopt.live details an adopt does. The page then asks whether to fork the chat (Claude Code only) or open it anyway.
  • Continue in New Chat. The View Only banner offers a way on beside Take Over. For Claude Code, Continue in New Chat forks the conversation into a new chat (claude --resume <id> --fork-session), so the original is only read. For Codex, which cannot be forked while another app runs it, New Chat Here starts a Codex chat in the same folder. The viewed chat stays as it is. An adopt with ifLive: fork now always makes a new chat; before, it could return the chat that already adopted or viewed the conversation. This only adds a button and changes no existing flow, so it has no Debug toggle.
  • Agent pane. Session summaries carry watching: "claude" | "codex". The pane shows "Viewing Claude Code session" with a Take Over button, and the composer is off with "Take over this session to send messages".
  • Entry points, one path. The All chats row menu's View Only (chats.watch), the palette's View Chat Only (agentChat.view) and cmux agent view <chat> all call ChatsOpenCoordinator.watch. That coordinator is the Open Chat path with adopt.watch set. <chat> is an index key (claude-code:<id>, codex:<id>), a transcript path, or a bare session id; a bare id is Claude Code's when its transcript is under ~/.claude/projects, otherwise Codex's. cmux agent view show|ensure|… keep their sidebar-view meaning.

Supporting changes:

  • hub/lifecycle.rs was at the 1000-line limit. Its route check moves to route_switch.rs::check_new_route.
  • cli.rs is at 993 lines. The positional chat for agent view lives in cli/agent_view.rs.
  • server/requests.rs stays under the line limit: adopt and Take Over share one IfLive::parse.
  • CmuxNextApp does not grow (its size cap): ChatOpenSubject moved to CmuxNextAgentPane, and the View Chat Only refusal moved to RefusalStrings.
  • Merged feat-cmux-next at 59d0076. The base this branch started from failed to compile cmux-sdk's home_conversation_live test, and that is fixed upstream.

Validation

Hosted CI only; nothing was built on a Mac.

  • acpmux, tests/hub_integration/watch.rs:
    • a watched Codex chat shows the rollout and what is appended to it;
    • a snapshot of every file under the Codex home is byte-identical before and after;
    • prompts are refused, and no initialize or session/load is recorded;
    • a watched Claude chat shows prompts and answers and settles ended turns;
    • Take Over lets the next prompt run and settles a turn the other app left open.
    • The pane's warm-up and a mode change start no agent on a viewed chat.
    • A Claude turn ends on its text line, not the thinking line before it.
    • Viewing never blocks starting a session: a new chat in the viewed chat's folder runs, and a fork is its own chat while the view goes on (viewing_a_chat_never_blocks_starting_a_new_one).
    • A unit test covers complete-line reading and offsets.
    • Focused run test_filter=watch: 39204810572, in progress.
  • CLI, cli/agent_view.rs: key, path and bare-id mapping, and sidebar view verbs are left alone. Focused run test_filter=agent_view: 39204813047, in progress.
  • Swift AgentChatViewTests: View Only sends watch: true in the adopt handshake, and an ordinary open sends none. chats.watch decodes, and the action takes only Claude Code or Codex keys. These run in this PR's cmux-next checks.
  • Webview, bun:
    • watch-banner.test.tsx: the banner names the app and offers Take Over plus Continue in New Chat (Claude Code) or New Chat Here (Codex);
    • all-chats-view-only.test.tsx: the row menu offers View Only, off for chats acpmux cannot watch, and it calls back with the row's key.
    • tsc --noEmit is clean.
  • The action exports (plans/cmux-next/action-surfaces.json) are left to the autofix bot, which regenerates them on a Mac runner.

Not verified: a live run against a real Claude Code or Codex session in a built app, and the side-by-side capture against the Claude app. That needs a dogfood build (dev-build label) on a machine with those apps signed in.

Limits

  • Claude Code and Codex only; other families are refused.
  • Viewing polls the file (400 ms) instead of using file events.
  • A watched chat shows the transcript's prompts and answers; tool calls and thinking are not mapped yet.
  • A transcript replaced by a longer file is not detected (no inode check), and an old Codex rollout with only unannotated items shows nothing while being followed.
  • The model and mode pickers stay drawn on a viewed chat. acpmux refuses those changes until Take Over, but the controls are not greyed out.
  • A Codex New Chat Here starts without the viewed conversation's context.

Changelog

  • Added: View Only for Claude Code and Codex chats in cmux NEXT (All chats menu, palette, cmux agent view): the chat follows the app that runs it without taking it over, until Take Over.

Context: manaflow-ai/cmuxterm-hq#2503. Related: #21253 (read-only observe of an acpmux session, which complements this one).

No capture: View Only needs a Claude Code or Codex transcript written outside cmux, and a capture slot has none. The banner and the All chats menu row are webview UI, covered by watch-banner.test.tsx and all-chats-view-only.test.tsx.

🤖 Generated with Claude Code

Agent session: cosmic-gray

teamleaderleo and others added 5 commits October 18, 2026 16:56
session/new with _meta.acpmux.adopt.watch finds the conversation as adopt
does but starts no harness: acpmux reads the transcript into history and
follows what the other app appends, writing nothing to it. The chat refuses
prompts (watch.read_only) and its summary carries watching: family, until
_acpmux/watch_take_over ends the watch; that refuses with adopt.live while
the original still runs unless ifLive forks or opens it, and the next prompt
resumes the conversation as for any idle chat. The read position is saved,
so a watch survives a daemon restart. Web connections cannot take over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The composer is off while acpmux shows a Claude Code or Codex chat another app
runs; Take Over asks acpmux to run it, and a chat still live elsewhere asks
whether to fork or open it anyway.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ux-watch-session

# Conflicts:
#	cmux-tui/crates/acpmux/src/hub/lifecycle.rs
…view

One opener for every entrypoint (ChatsOpenCoordinator.watch): the All chats
row menu's View Only (chats.watch), the agentChat.view action, and
`cmux agent view <chat>`, which takes an index key, a transcript path or a
bare session id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 19, 2026 04:41 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Oct 19, 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: 83239171-150c-426d-88e8-31862cd80c22

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
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 951b84b: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr21921 -f ref=leo/acpmux-watch-session -f platform=macos -f backend_mode=local

Gallery before/after for 951b84b: 16 states rendered, 0 images differ, 1409 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 39596681782 -R manaflow-ai/cmux -n gallery-advisory-21921-951b84b7cd7e492f0cf67ea6830d23d8eb0642ed (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/standard Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/typing-in-dock Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/typing-in-dock Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/long-title Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/long-title Apple System Colors unchanged 0% own App.tsx
agent-pane.history/chats Apple System Colors Light unchanged 0% own HistoryScreen.tsx
agent-pane.history/chats Apple System Colors unchanged 0% own HistoryScreen.tsx
agent-pane.history/selected Apple System Colors Light unchanged 0% own HistoryScreen.tsx
agent-pane.history/selected Apple System Colors unchanged 0% own HistoryScreen.tsx
agent-pane.new-tab/empty Apple System Colors Light unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/empty Apple System Colors unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/model-picker-open Apple System Colors Light unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/model-picker-open Apple System Colors unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/reasoning-chip Apple System Colors Light unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/reasoning-chip Apple System Colors unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/reasoning-chip-stage Apple System Colors Light unchanged 0% own AllChatsList.tsx
agent-pane.new-tab/reasoning-chip-stage Apple System Colors unchanged 0% own AllChatsList.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Not verified: macOS jobs did not run: compile and app tests were skipped on 951b84b7cd; ci-status is green without them.

CI passes on 951b84b7cd (run 39596682235 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

CI fast guards passes on 951b84b7cd (run). This covers only the fast guards, not CI: CI's result is ci-status.

Tour of 951b84b7cd (run): no media. The tour job failed before the tour ran (build or setup); the run log has the output.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

CI fast guards failed on eb98beeb2c (https://github.com/manaflow-ai/cmux/actions/runs/39210599140). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally. This comment is updated in place on each push.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-886tm created for this PR by the cmux coordinator.

@blacksmith-sh

This comment has been minimized.

@teamleaderleo

teamleaderleo commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator Author

Visual preview of b246cef: in the maintainers' private review feed.

…e allows Take Over

Review fixes for the watch PR:
- child_for refuses a watched chat, so the pane's warm-up, a mode or model
  pick, or a fork never resumes the original conversation before Take Over.
- The pane transport allows _acpmux/watch_take_over (it was default-denied).
- The open watched turn is kept in the session meta: a daemon restart goes on
  with it instead of marking it failed, and Take Over settles it.
- A Claude turn ends on its text line, not the thinking line before it.
- A cut file is followed from its end (no duplicated history); a line over
  4 MiB is skipped instead of stalling the watch; answer pieces read as
  paragraphs; a purged or closed chat's meta is not written back.
- adopt.watch with ifLive fork is refused; Take Over's live choice shows only
  on its chat.
- cli.rs keeps mod app unix-only.
- CmuxNextApp does not grow: ChatOpenSubject moves to CmuxNextAgentPane and
  the refusal to RefusalStrings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 19, 2026 04:57 — with GitHub Actions Inactive
…nder 1000 lines

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 19, 2026 05:02 — with GitHub Actions Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

A review subagent read fbfaa67. Its findings and what ca3028d and 52c3ed9 did about each:

Blocking

  1. The pane transport refused _acpmux/watch_take_over. It is default deny, so Take Over could never reach acpmux. Fixed: it is now in AcpmuxPaneMethods.requests and sessionScoped, with its params in knownParams. The allowlist header asks for the protocol/origin lead's (ad349) review of list changes. This one is session-scoped, takes only sessionId and ifLive, and is refused for web origins in acpmux (watch.origin_refused).
  2. Something could start the agent on the watched conversation before Take Over. Three paths reached child_for: the pane's warm-up (_acpmux/warm), a mode, model or effort pick, and a Codex fork. That would --resume or session/load the original. Fixed: child_for refuses a watched chat with watch.read_only, so every lazy start is covered. New test: warming_or_changing_mode_starts_no_agent_on_a_watched_chat.
  3. cli.rs dropped #[cfg(unix)] from mod app, which would break the Windows build. Fixed.

Medium
4. A Claude turn ended on the thinking line, so its answer landed after turn_end. Fixed: a turn now ends only on an assistant line with text, and stop_sequence counts as an end. The new test a_claude_turn_ends_with_its_text_and_take_over_settles_an_open_one covers it.
5. A daemon restart marked an open watched turn failed. Fixed: the open turn is kept in Watching.open, and mark_unknown_outcomes skips watched chats.
6. Take Over left the open turn unsettled. Fixed: watch_take_over now ends it (same test).
7. A line over 4 MiB stalled the watch. Fixed: such a line is skipped, and its tail fails to parse and is dropped.

Low

  • 8 (a purged chat's meta was rewritten): fixed. The meta is not saved if the chat was purged, closed or taken over.
  • 9 (a cut file duplicated history): fixed. A shorter file is followed from its end. A file replaced by a longer one is still not detected (no inode check); that is listed under Limits.
  • 10 (answer pieces ran together): fixed. Pieces after the first start a new paragraph.
  • 11 (an old Codex rollout with only unannotated items shows nothing while streaming): not changed. Those rollouts are older than the format the watch maps; listed under Limits.
  • 12 (adopt.watch with ifLive: fork): now refused.
  • 13 (liveTakeOver could show on another chat): fixed. It is scoped to the chat that asked. Mode and model pickers stay drawn on a watched chat, but acpmux now refuses those changes (see 2).
  • 14 (dedupe ignores watch): left as is. View Only on a chat already open reveals that tab; Open on a watched chat reveals the View Only tab, where Take Over is one click.

Also fixed after the first CI run:

  • server/requests.rs was over the 1000-line limit. One IfLive::parse is now shared by adopt and Take Over.
  • The CmuxNextApp size cap failed. ChatOpenSubject moved to CmuxNextAgentPane and the refusal to RefusalStrings, so CmuxNextApp is now 4 code lines smaller than on the base.
  • A11y lint failed on role="status" on a div; the attribute is removed.

Leo 2026-10-19: viewing is an extra option, never a gate. The View Only
banner offers Continue in New Chat, which forks a Claude Code session into
a new chat, and for Codex (which cannot be forked while another app runs it)
New Chat Here in its folder. An adopt with ifLive fork no longer returns the
chat that already adopts or views the conversation. New test: a new chat in
the viewed chat's folder runs, and a fork is its own chat while the view goes on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 19, 2026 05:29 — with GitHub Actions Inactive
Open on a Claude Code or Codex chat another app runs shows it View Only
(Debug toggle agent.openOutsideChatsViewOnly, default on); other harnesses
open as before. The composer stays on: sending takes the chat over first,
and while the other app still runs it the pane asks how and keeps the message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo and others added 3 commits October 18, 2026 23:03
A profile is named freely (fakecodex, claude-work, a subrouter account), so
the open route must not read the family off the profile's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
_acpmux/chat_open's adopt plan says the chat's family (claude, codex,
opencode); the open route watches a Claude Code or Codex chat by that, so a
profile named claude-work or a subrouter account still opens View Only.
A daemon without the field falls back to the profile's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…watch-session

# Conflicts:
#	webviews/src/agent-session/acpmux/generated/strings.json
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 19, 2026 06:11 — with GitHub Actions Inactive
teamleaderleo and others added 2 commits October 18, 2026 23:13
…eo/acpmux-watch-reply-takes-over

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneTunables.swift
- regenerated plans/cmux-next/action-surfaces.json
- regenerated plans/cmux-next/actions.md
- regenerated schemas/defaults/cmux-next.json
- vp fmt webviews/src/agent-session/acpmux/replyHref.ts
- vp fmt webviews/src/pages/markdown/links.ts
- vp fmt webviews/test/markdown-cmux-app-links.test.ts

Autofix-Run: https://github.com/manaflow-ai/cmux/actions/runs/39208471588
@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 11:32 — with GitHub Actions Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (claude-opus review subagent): BLOCK at f776fe7

I read the diff against feat-cmux-next at the merge base 92c12bc and the commits since the last review (ce2fc4c4..f776fe76: 21eb2b9, the base merge 83edbc2, f776fe7). I built nothing locally. The earlier blocker is fixed and the base merge is clean. One new red belongs to this PR, and it is a one-line fix.

Blocking

  1. fast gates fails on this PR's own line. The web lint step (vp check) reports a formatting issue in exactly one file, webviews/src/agent-session/acpmux/App.tsx. The cause is the PR's line at App.tsx:6769:
    if (snapshot.sessionId && surfaceRef.current !== "quick" && !projectDraft && !snapshot.summary?.watching) {
    
    It is 121 columns, and config/vite-plus/check.ts sets printWidth: 120. I ran oxfmt with printWidth: 120 on a scratch copy of the file at this head. The only change it makes is to break that condition over four lines. Nothing else in the file moves. The gate itself says this red is not base's: it marks the crash ratchet as "already red on the base" and does not say that about web lint. Fix: run vp check --fix in webviews/, or wrap the condition by hand.

Checked and right

  • Earlier blocker (action-surfaces.json): fixed. Against base, plans/cmux-next/action-surfaces.json adds exactly one hunk, the agentChat.view entry (+28, -0). Every other line matches base. The file parses. chief.openSubagent is present (actions[1029]). The workspaceGroup.moveToSpace, workspace.moveToSpace and workspace.duplicateToSpace context-menu entries are kind: "choices". The new entry sits after agentChat.copyIdentifier, the same place AgentChatViewActionCatalog takes in ActionCatalog.swift. action export areas and generated drift pass on this head. cmux-next generated files and action exports (Mac) were still running when I checked.
  • Should-fix 2 from the last review: applied correctly. hub/watch.rs:254-255 now reads let (_, env) = self.harness_env(&meta).await; and then self.harness_homes().with_env(&[&env]), as fork.rs and aside.rs do. harness_env layers the profile env and the preset env, then applies chat_store. So a store set by a profile is now the one checked for a live holder. meta is an owned clone, so no lock is held across the .await.
  • The last base merge did not regress anything:
    • The only conflict resolution in 83edbc2 was in hub/mod.rs. Against base, that file keeps all of base's new modules and fields (composers, forum, is_permission_ask) and adds only the PR's mod watch, the start_watch restart loop and the mark_unknown_outcomes skip.
    • Per-file numstat (all files except .xcstrings) for the PR against its base is identical before and after the merge, apart from action-surfaces.json, which changed on purpose. So the merge reverted nothing.
    • .xcstrings, compared key by key against base: ActionCatalog +2 (action.agentChat.view, argument.agentChat.key), Refusals +1 (handlers.refusal.notAWatchableChat), webview Localizable +6 (watch.*, newTab.viewOnly). No base key is removed or changed, base's key order is kept, and every added key has the same 21 languages as base. All three diffs are pure insertions. f776fe7 undid the reorder the merge had made in the webview catalog.
    • Generated files: the PR does not touch ci-target-graph.json, settings-schema.json, docs/mdm/* or sources.sha256. The protocol outputs it does change (acpmux-protocol.json, acpmux-schema.json, protocol/generated/methods.ts and types.ts) are its own inputs, and acpmux-protocol:check passes.
    • tests/test-execution.toml now equals base. f776fe7 dropped the test_guard_hooks_from_base.py entry that the merge had added. That test came from base (cmux guards: run merge guard hooks from the feat-cmux-next tip #23316), and base does not register it either, so the entry was not this PR's to carry.
    • The branch merges cleanly with today's base tip e0a42bf (git merge-tree).
  • The Rust side still type-checks on paper after the merge. Every SessionMeta and SessionSummary literal sets watching (fork.rs:172, resolve.rs:322, views.rs:298). The test helpers in startup_load.rs and stats.rs build SessionMeta through serde, and watching is #[serde(default)]. build acpmux x86_64-pc-windows-gnu and rustfmt pass on this head.

Not this PR's reds

  • cmux-next checks: its only red step is "Companion workflows". Three test_cmux_next_pr_autofix_settings.py cases fail because scripts/cmux-next/base-autofix-repair.sh is missing. In the same job, the convention ERROR is in HomeThoughtHeadline.swift and the FIRST-TURN-COST failure is about Chief. The PR touches none of these files.
  • web / react-apps-check (2): the failure is agent-pane-scrollbar-full-height.test.ts:441, where a composer that grows and shrinks ends 20 px off. The last review also saw it on an earlier head. The PR's App.tsx changes only act when summary.watching is set, and this test never sets it.

Should fix (not blocking, carried over)

  1. The comment above blocked= (App.tsx:6893-6895) still says the composer is blocked "while the chat only shows a session another app runs", but blocked does not look at watching. Either reword the comment, or make blocked look at watching.
  2. Still no test reaches adopt.live on Take Over, now through the profile-env path. Suggested test: a profile whose env sets CLAUDE_CONFIG_DIR to a temp dir, plus a sessions/x.json there with the test's own pid. Take Over without ifLive should then refuse with adopt.live. Also still open: watch.origin_refused, resuming a watch after a restart, and the poll-cost and race items from earlier reviews.

Once item 1 is wrapped and fast gates passes, this is a SHIP from me without another code pass.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 11:49 — with GitHub Actions Inactive
# Conflicts:
#	cmux-tui/crates/acpmux/src/server/change_kind.rs
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 11:51 — with GitHub Actions Inactive
@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 11:55 — with GitHub Actions Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (claude-opus review subagent): SHIP at 397c459

I read the changes since my BLOCK at f776fe7: c40a7f2, and the base merges 09a8c2d and 397c459. I also read the whole PR against its merge base 76f7e42. I built nothing locally.

The blocker is fixed

  • c40a7f2 wraps the View Only send condition at App.tsx:6769 over four lines.
  • I ran oxfmt with printWidth: 120 on scratch copies of App.tsx, WatchBanner.tsx, direct.ts and model.ts at this head, and it leaves all four unchanged.
  • fast gates now passes on this head.

The merges are right

  • server/change_kind.rs: the resolution keeps every base kind, including "git" and "subsession". It adds only the PR's "watch_started" and "watch_taken_over" to the same pass-through arm. Nothing is dropped or duplicated.
  • plans/cmux-next/action-surfaces.json: +28/-0 against base. The only addition is the agentChat.view entry, and every base line is kept. The file parses: 1135 actions, chief.openSubagent present, and the moveToSpace / duplicateToSpace choices entries unchanged. action export areas and generated drift pass.
  • The PR has the same shape as before the merges. Its per-file numstat against base equals the one at f776fe7 against its own base, except App.tsx, which grows by the 5-line wrap (+30/-3 instead of +25/-3). So neither merge reverted base content or brought in a new file.
  • .xcstrings: compared key by key against base, all three catalogs are pure insertions. ActionCatalog adds 2 keys, Refusals 1 and webview Localizable 6. No base key is removed or changed, and base's key order is kept.
  • Other files: tests/test-execution.toml is identical to base. The PR carries no ci-target-graph.json, settings-schema.json, docs/mdm/* or sources.sha256 changes.
  • Base tip: the branch merges cleanly with today's base tip 7052345.

Still open (not blocking, carried over)

  • The comment above blocked= in App.tsx says the composer is blocked while watching, but blocked does not look at watching.
  • No test yet reaches adopt.live on Take Over through a profile's CLAUDE_CONFIG_DIR. watch.origin_refused and resuming a watch after a restart are also untested.

CI at this head when I posted

77 passed, 0 failed, 19 pending. cmux-next generated files, action exports (Mac), cmux-next checks and the react-apps-check shards were still queued or running. On f776fe7, the reds in cmux-next checks (Companion workflows) and react-apps-check (2) (agent-pane-scrollbar-full-height.test.ts:441) were not this PR's. Any new red in generated files would be.

@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 12:04 — with GitHub Actions Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (claude-opus review subagent): SHIP at 951b84b

The only commit since my SHIP at 397c459 is the base merge 951b84b (second parent 80f4317). I compared it against base and built nothing locally.

The merge only brings in base

  • Same files as base: the merge changes 71 files, and that list matches exactly the files base changed between the two merge bases (76f7e42 → 80f4317).
  • No base content reverted: the PR's per-file numstat against its new merge base is identical to the one at 397c459, at +2693/-69 over 63 files. So every file the PR doesn't touch now equals base.
  • plans/cmux-next/action-surfaces.json: still +28/-0 against base. The only addition is agentChat.view.
  • .xcstrings: compared key by key against base, ActionCatalog +2, Refusals +1 and webview Localizable +6. No base key is removed or changed, and base's key order is kept. The other catalogs the merge touched (AppStoreActions, HistoryActions, RemoteActions, History, MiscHandlers, Cloud) come from base and now equal base.
  • tests/test-execution.toml: identical to base.
  • Generated files: the PR carries no ci-target-graph.json, settings-schema.json, docs/mdm/* or sources.sha256 changes.
  • Base tip: the branch merges cleanly with today's base tip 979915a.

CI at this head when I posted

No failed checks: 69 passed, 2 neutral, 50 skipped, 7 still running or queued. The ones not finished are cmux-next generated files, action exports (Mac), cmux-next fast tier, cmux-next swift test, cmux-next Release compile (Xcode 26), build x86_64-pc-windows-gnu and Tour the app. So there is nothing to attribute yet. A red in generated files or action exports would be this PR's. On earlier heads, cmux-next checks (Companion workflows) and react-apps-check (2) (agent-pane-scrollbar-full-height.test.ts:441) failed for reasons outside this PR, and both pass on this head.

Still open (not blocking, carried over)

  • The comment above blocked= in App.tsx says the composer is blocked while watching, but blocked does not look at watching.
  • No test yet reaches adopt.live on Take Over through a profile's CLAUDE_CONFIG_DIR. watch.origin_refused and resuming a watch after a restart are also untested.

@teamleaderleo
teamleaderleo merged commit 3690aaa into feat-cmux-next Oct 21, 2026
@teamleaderleo
teamleaderleo deleted the leo/acpmux-watch-session branch October 21, 2026 13:38
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…t as the Swift host does (base red)

The macOS host's AcpmuxPaneMethods lists two pane methods policy.json lacks:
- _acpmux/attachment (#20411): requests, knownParams [sessionId, id]
- _acpmux/watch_take_over (#21921): requests, sessionScoped,
  knownParams [sessionId, ifLive]
so tests/swift.rs (the_requests_are_the_macos_hosts,
the_known_params_are_the_macos_hosts) fail on feat-cmux-next and are
skipped in scripts/ci/cmux-tui-base-red.tsv (cx-c0wvp). Add both to
policy.json as Swift has them and drop the two skips. The
typescript.rs skip stays, with its reason brought up to date.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15df4-118f-7020-8a15-dbb7b04d4092&host=cosmic-gray
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…t as the Swift host does (base red) (#23447)

The macOS host's AcpmuxPaneMethods lists two pane methods policy.json lacks:
- _acpmux/attachment (#20411): requests, knownParams [sessionId, id]
- _acpmux/watch_take_over (#21921): requests, sessionScoped,
  knownParams [sessionId, ifLive]
so tests/swift.rs (the_requests_are_the_macos_hosts,
the_known_params_are_the_macos_hosts) fail on feat-cmux-next and are
skipped in scripts/ci/cmux-tui-base-red.tsv (cx-c0wvp). Add both to
policy.json as Swift has them and drop the two skips. The
typescript.rs skip stays, with its reason brought up to date.


Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15df4-118f-7020-8a15-dbb7b04d4092&host=cosmic-gray

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

This branch was previously deployed

4 inactive deployments
ci-routing-agent — 951b84b7 Deployed Oct 21, 2026 by github-actions[bot]
artifacts — 951b84b7 Deployed Oct 21, 2026 by teamleaderleo
sentry-dsyms — 951b84b7 Deployed Oct 21, 2026 by teamleaderleo
cmux-tui-merge-tree — 951b84b7 Deployed Oct 21, 2026 by teamleaderleo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant