cmux-next: wire explicit read-only remote agent observation

Merged
TE
15d ago
+207-14

Problem

The server-side agent-session-observe-v1 capability (on feat-cmux-next via #21386) is not yet consumable by the macOS remote agent viewer. Without an explicit client mode, a viewer could accidentally use writable attach semantics.

Change

This branch now carries only the observer client. The server half is already on base via #21386 (#21253 was closed for that reason). The base merge at 4438f6cadb36 dropped the unrelated work this branch had picked up: sidebar priority projection, motion debug menu, window snapshot encoding, agent-chat orchestration gallery, Codex voice capability negotiation, and new-tab fixes. Those commits are still in the branch history.

  • add an explicit .observe mode on AgentSessionAttachClient with its own capability handshake (agent-session-observe-v1) and its own agent-session-observe verb; a daemon without it refuses, and there is no fallback to writable attach;
  • an observing client refuses start and trust locally;
  • propagate observe mode through AgentTabRemoteHost / AgentTabRemoteClient (isReadOnly) and RemoteAcpmuxWire;
  • RemoteAcpmuxWire refuses session/prompt, session/cancel and _acpmux/permission_respond locally with agent_session.read_only, while record, permission and session-changed pushes stay visible;
  • add DaemonCapabilities.agentSessionObserve to the optional list and to plans/cmux-next/daemon-capabilities.json; update plans/cmux-next/remote-agent-attach.md;
  • tests: RemoteAcpmuxObserverTests (wire refusals, pushes still flow) and AgentSessionAttachClientObserverTests (mode capability/command, no start).

Selected chats can opt into AgentTabRemoteHost(mode: .observe) in a follow-up; nothing uses .observe yet, so default behavior is unchanged.

No capture: no visible UI change (observe mode is a client protocol mode; no selected chat opts in yet)

Validation (at 4438f6cadb36)

  • swiftc -parse on every changed Swift file;
  • check-daemon-capabilities-fresh.py and check-app-capability-references.py pass;
  • check-concurrency.sh ok; crash_ratchet.py reports the same hits on the pure base tree (base reds, none from this diff);
  • the Swift compile and tests run on CI (never on this Mac).

Agent session: cosmic-gray