acpmux: one typed protocol registry; generated web types and drift checks (hq#2025, no bead)

Merged
TE
22d ago
+3992-110

Summary

First step of a typed acpmux protocol (plan: manaflow-ai/cmuxterm-hq#2025; T3 Code's packages/contracts is the model). Rust is the source of truth, and the web gets generated types plus a typed request, with drift checks on both sides.

  • Registry (cmux-tui/crates/acpmux/src/protocol/).
    • Names all 121 methods and notifications acpmux serves or sends (ACP, _acpmux/*, catalog.*, chats, transfer), with their kind.
    • Typed so far: _acpmux/sessions, _acpmux/permission_respond, _acpmux/permission_groups, _acpmux/permission_group_respond, _acpmux/permission_chat_revoke, and the _acpmux/session_changed and _acpmux/permission_pending notifications.
    • Every other method is declared as any JSON until it is typed.
  • The daemon builds from the types.
    • Hub::session_summary builds SessionSummary, and permission groups build PermissionGroup.
    • Reviewed for wire equivalence against the old json! output; no key, null or number changes.
    • One fix: a non-UTF-8 cwd is now lossy instead of a json! panic.
  • IR. spec/acpmux-protocol.json holds JSON Schema 2020-12 from schemars.
  • Web.
    • webviews/scripts/acpmux-protocol-codegen.ts generates agent-session/acpmux/protocol/generated/: one type per schema, plus AcpmuxRequests, AcpmuxNotifications and ACPMUX_METHODS.
    • protocol/client.ts adds typedRequest and isNotification.
    • The permission group client, permission_respond, and the session_changed and permission_pending handlers now use them, and the hand-written permission types alias the generated ones.
  • Drift checks.
    • Rust: protocol_ir_is_current fails on a stale IR (bless with ACPMUX_PROTOCOL_BLESS=1).
    • Rust: protocol_registry_names_every_served_method fails when rpc::method or a server literal names a method the registry lacks.
    • Web: bun run check now ends with acpmux-protocol:check, which fails on stale generated TS.

Follow-ups in hq#2025: type the rest (attach, detach, view, events, watch, then everything else); serve the IR from _acpmux/schema and retire the hand-written docs/acpmux-schema.json; Swift Codable.

Changelog

none

Verification

All of this ran on the private Linux builder, on the merged head (base 93d4ef26af52):

  • cargo test --locked -p acpmux --lib protocol_: 3 passed.
  • cargo clippy --locked -p acpmux --all-targets -- -D warnings: clean.
  • bun run check in webviews: green, including the new drift check and the typecheck of 1318 files.
  • bun test src/agent-session/acpmux/protocol: 4 pass.
  • Two non-browser permission and queue tests pass. The chromium tests were skipped on the builder (no browser installed there), so CI runs them.

The crash ratchet is ok.

No UI change.

🤖 Generated with Claude Code


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


Summary by cubic

Turns acpmux into a typed protocol: one Rust registry names every method and notification, and the web gets generated types plus a typed request from it.

  • Typed so far: sessions, permission group, respond, and revoke, plus the session_changed and permission_pending notifications; the rest are any JSON.
  • The daemon builds SessionSummary and PermissionGroup from the types; a non-UTF-8 cwd is now lossy instead of a json! panic.
  • The session summary carries the lane fields (lane, inputSince, lastTurn.detail) and chat tools (tools, toolsMutable); the workspace field was dropped again with the branch's last merge.
  • spec/acpmux-protocol.json holds the JSON Schema 2020-12 IR; codegen lives beside the pane protocol codegen, outside the pane sources, so pane-english does not scan its developer-facing errors.
  • Web views get generated types plus typedRequest and isNotification helpers.
  • Drift checks fail on a stale IR or generated web types, and when the dispatcher serves a method the registry lacks (bless with ACPMUX_PROTOCOL_BLESS=1); they caught offer_session, offer_respond, prompt_withdraw, the tools, stats, bookmark, and process methods, now registered as untyped requests.
  • Follow-ups: type the rest of the methods, serve the IR from _acpmux/schema, add Swift Codable.

<pull_request_end>