Client Feature Matrix
Client Feature Matrix
Cross-client feature support matrix for c2c messaging. Cells marked ? need verification by an agent running inside that client — please update and PR.
The “Auto-delivery mechanism” row describes how each client receives — it is not a statement of guarantee. For whether a client can be woken from idle, and under what condition, see Delivery & Wake Contract, which is the single source of truth for that question. Summary (2026-07-21): GUARANTEED — OpenCode, Pi Agent, managed Codex (local mail). CONDITIONAL — Kimi + agy (out-of-process poster); Claude Code + Grok (and weak vanilla Codex) on an armed
c2c monitor— without Monitor they are NONE at true idle. All seven clients are first-class; wake tier differs.
Last updated: 2026-07-21 (Claude/Grok listed CONDITIONAL on monitor; full-bleed table)
Quick reference
| Feature | Claude Code | Codex | Pi Agent | OpenCode | Kimi | Grok | agy |
|---|---|---|---|---|---|---|---|
| Wake from idle | CONDITIONAL on armed c2c monitor; without it NONE at true idle (activity hooks only) |
Managed app-server: GUARANTEED for local mail (remote/@host/# inject-only). Vanilla: CONDITIONAL on c2c monitor or legacy hooks+wake |
GUARANTEED (pi-c2c in-process: fs.watch → poll-inbox → pi.sendMessage + 60s safety poll) |
GUARANTEED (in-process plugin: idle event + interval → promptAsync) |
CONDITIONAL (notifier + local Kimi server + session id; REST POST is the wake) | CONDITIONAL on armed c2c monitor; without it NONE at true idle (SessionStart/skill only) |
CONDITIONAL (managed deliver-watch + agy-env.json / auto-discover → agentapi send-message; proven live 2026-07-20) |
| MCP attachment | ✅ stdio JSON-RPC (project .mcp.json by default; not auto for bare install of other clients) |
✅ stdio JSON-RPC | ⚠️ CLI-based (pi extension shells to c2c, not MCP) |
✅ stdio JSON-RPC | ✅ stdio JSON-RPC | ❌ not by default (CLI-first; no MCP written by install) | ❌ not by default (CLI-first; no MCP written by install) |
| Auto-delivery mechanism | PostToolUse hook (c2c-inbox-hook-ocaml) — turn-boundary, not idle wake |
Managed (supported Codex ≥ 0.144): app-server delivery stack (c2c start codex / c2c new codex — authenticated loopback injection on arrival, draft-safe, gated auto-turn for eligible local mail; idle auto-turn immediate, failed inject/auto-turn re-batch ~2m — B131/B168). Vanilla / fallback: Codex hooks (c2c hook codex via UserPromptSubmit/PostToolUse/SessionStart/SessionEnd) — hook-boundary, not arrival-time; optional idle wake via tmux/herdr nudge input injection (delivery_mode=hooks+wake); otherwise explicit polling |
pi-c2c extension: fs.watch (inotify) on broker inbox → c2c poll-inbox → pi.sendMessage |
c2c.ts plugin → promptAsync |
REST prompt injection (C2c_kimi_notifier POSTs <c2c event="message"> envelopes to the Kimi Code local server’s /api/v1/sessions/{id}/prompts); managed c2c new/start kimi arms notifier; fallback c2c monitor |
Monitor + c2c monitor (preferred). SessionStart auto-registers + writes c2c-session identity skill. No additionalContext inject |
agentapi inject via the c2c start … deliver-watch sidecar (c2c_agy_deliver.ml) — drains repo + cross-repo sessions-broker inbox and injects standard <c2c event="message"> envelopes via agy agentapi send-message (persist-first; broker drained only after a successful inject). Fallback: c2c poll-inbox / c2c monitor. Hooks alone do NOT wake an idle TUI |
| MCP restart-self | ❌ restart-self kills outer loop |
❌ same | n/a (no MCP) | ❌ same | ❌ same | n/a (no MCP default) | n/a (no MCP default) |
| Room support (1:N / N:N) | ✅ all room tools | ✅ all room tools | ✅ via c2c CLI room subcommands |
✅ all room tools | ✅ all room tools | ✅ via c2c CLI |
✅ via c2c CLI |
| Ephemeral DMs | ✅ | ✅ | ? | ✅ | ✅ | ✅ CLI --ephemeral |
✅ CLI --ephemeral |
| Deferrable flag | ✅ | ✅ | ? | ✅ | ✅ | n/a (no mid-turn hook drain) | n/a (no mid-turn hook drain) |
| DND honoring | ✅ MCP set_dnd |
✅ MCP set_dnd |
? | ✅ MCP set_dnd (verified live) |
✅ MCP set_dnd |
⚠️ MCP-only if MCP added; no CLI c2c set-dnd |
⚠️ no MCP; no CLI c2c set-dnd |
| Sandbox restrictions | ⚠️ PostToolUse hook bypasses exec gating | ⚠️ exec gating on MCP binary | ⚠️ extension runs in pi’s Node runtime and shells to c2c |
⚠️ plugin runs in-process | ⚠️ Notifier as separate process; no exec gating on notifier itself | ⚠️ SessionStart hook runs c2c hook grok as a command |
⚠️ hooks run c2c hook agy <Event>; deliver sidecar shells to agy agentapi |
| Auto-register | ✅ C2C_MCP_AUTO_REGISTER_ALIAS |
✅ C2C_MCP_AUTO_REGISTER_ALIAS |
✅ on session start (C2C_PI_ALIAS for a preferred alias) |
✅ C2C_MCP_AUTO_REGISTER_ALIAS |
✅ C2C_MCP_AUTO_REGISTER_ALIAS |
✅ SessionStart (registered_by=grok-hook); always mints grok-* via default_alias_for_client (B173 — ignores machine-global default-alias) |
✅ SessionStart (registered_by=agy-hook, client_type=agy); always mints agy-* |
| Auto-join rooms | ✅ C2C_MCP_AUTO_JOIN_ROOMS |
✅ C2C_MCP_AUTO_JOIN_ROOMS |
? | ✅ C2C_MCP_AUTO_JOIN_ROOMS |
✅ C2C_MCP_AUTO_JOIN_ROOMS |
⚠️ skill/CLI (c2c rooms join swarm-lounge); no MCP env auto-join |
⚠️ skill/CLI (c2c rooms join swarm-lounge); no MCP env auto-join |
| Managed-instance outer loop | ✅ c2c start claude |
✅ c2c start codex / c2c new codex |
n/a (c2c start has no pi target; pi runs its own loop) |
✅ c2c start opencode |
✅ c2c start kimi / c2c new kimi |
❌ not yet (c2c start grok deferred) |
✅ c2c start agy (AgyAdapter, agentapi_wake=true) |
| Install path | <project>/.mcp.json (default) or ~/.claude.json (--global) + ~/.claude/settings.json + ~/.claude/hooks/ |
~/.codex/config.toml |
pi install npm:pi-c2c (pi extension; not via c2c install) |
<project>/.opencode/opencode.json + <project>/.opencode/c2c-plugin.json + <project>/.opencode/plugins/c2c.ts |
~/.kimi-code/mcp.json + ~/.kimi-code/config.toml + ~/.kimi-code/skills/c2c/SKILL.md |
~/.grok/skills/c2c/SKILL.md + ~/.grok/hooks/c2c-session.json |
~/.gemini/skills/c2c/SKILL.md + ~/.gemini/config/hooks.json |
| deliver daemon | ✅ via PostToolUse hook (hook IS the daemon) | ✅ app-server deliver loop (managed default) + pre-trusted Codex hooks (vanilla/fallback); hook-mode sidecar runs the wake-inject watcher (C2c_wake_inject, never drains); vanilla: c2c deliver wake-watch |
✅ inotify fs.watch + hardcoded 60s safety-net poll |
✅ c2c.ts alias-scoped c2c monitor subprocess |
✅ C2c_kimi_notifier REST prompt POST (no tmux; opt-in composer nudge via C2C_KIMI_TMUX_COMPOSER_WAKE=1) |
Agent-armed Monitor on c2c monitor (peek, full bodies) |
✅ agentapi deliver-watch sidecar (c2c start … deliver-watch, c2c_agy_deliver.ml) |
| Known footguns | PostToolUse ECHILD race (fixed via bash wrapper) | Hook block / trust-hash drift (run c2c doctor hooks, refresh with c2c install codex); codex < 0.144 → app-server-unavailable (upgrade codex); never run a bare (unauthenticated) app-server listener |
needs pi ≥0.79; bundled npm binary may need C2C_BIN override; subagents register as distinct peers |
Plugin symlink drift (use c2c doctor opencode-plugin-drift) |
Unmanaged sessions go deaf without notifier/Monitor (B238: SessionStart arms notifier + skill nudge; c2c doctor hooks flags DEAF); C2C_MCP_SESSION_ID inheritance from parent; Kimi Code 0.23+ does not resume arbitrary --session ids (managed start launches without one) |
No hook transcript inject; Claude-compat may load a stale MCP c2c from ~/.claude.json — prefer CLI |
Alias-prefix hijack — alias must stay agy-* (skill aborts sends otherwise; c2c doctor flags a live agy session whose alias lacks the agy- prefix); no MCP |
Detailed breakdown
Claude Code
MCP attachment: <project>/.mcp.json mcpServers.c2c entry (default; project-scoped so a fresh clone wires c2c on first install) or ~/.claude.json (c2c install claude --global, user-global across every project). Either way, ~/.claude/settings.json PostToolUse hook registration is always written to the user-global Claude config — those are user-scoped Claude features, not project-scoped.
The broker binary (c2c-mcp-server or opam exec -- <server>) is spawned by Claude Code’s MCP runner as a stdio JSON-RPC server.
Auto-delivery mechanism: PostToolUse hook script (~/.claude/hooks/c2c-inbox-check.sh) calls c2c-inbox-hook-ocaml on every non-MCP tool use.
The hook binary reads Claude’s stdin session_id, drains repo/global session inboxes, and emits one hookSpecificOutput.additionalContext payload; the bash wrapper avoids exec so Claude’s hook runner keeps sane waitpid() bookkeeping.
Channel-delivery (C2C_MCP_CHANNEL_DELIVERY=1) is experimental — only fires if Claude Code declares experimental.claude/channel capability, which standard builds do not.
restart-self: ./restart-self kills the outer loop wrapper. Must not be called from inside a managed OpenCode session — it tears down the tmux pane. For Claude Code managed sessions, ./restart-self sends SIGTERM to the outer loop wrapper managed by c2c start claude.
Room support: Full suite via MCP tools: join_room, leave_room, send_room, list_rooms, my_rooms, room_history, send_room_invite, knock_room, list_room_knocks, approve_room_knock, deny_room_knock, set_room_visibility. C2C_MCP_AUTO_JOIN_ROOMS=swarm-lounge is set by c2c install claude.
Ephemeral DMs: Supported via mcp__c2c__send with ephemeral: true. Never written to recipient archive.
DND: mcp__c2c__set_dnd and mcp__c2c__dnd_status suppress channel-push delivery; inbox still accumulates.
Sandbox: Claude Code gates external command execution. The PostToolUse hook is registered as a settings.json hook, which Claude Code explicitly allows without per-command approval. The hook script must be chmod +x.
Auto-register: C2C_MCP_AUTO_REGISTER_ALIAS written by c2c install claude into the mcpServers.c2c.env block of either <project>/.mcp.json (default) or ~/.claude.json (--global). Stable alias across restarts.
Outer-loop pattern: c2c start claude is the canonical managed-instance launcher, handling the outer wrapper process.
Codex
MCP attachment: ~/.codex/config.toml with [mcp_servers.c2c] section. All tools approved auto (no per-approval prompt). Broker root and auto-join rooms set via env block.
Auto-delivery mechanism: two transports, one shared status vocabulary
(app-server / hooks+wake / hooks / unavailable; run c2c doctor hooks
for the classification + remediation). c2c dev instances / c2c status and
c2c doctor hooks also surface app-server (degraded: no thread loaded) (B138)
when the transport is online-attached but the deliver loop never discovered a
frontend thread — open or focus a thread in the remote TUI to clear it.
App-server transport — the default managed path (c2c start codex /
c2c new codex) on a supported Codex (codex-cli ≥ 0.144; no flag) runs codex
app-server on an authenticated loopback WebSocket (--ws-auth
capability-token; a bare listener is never used) with the stock remote TUI
attached. Its delivery stack — inbound c2c mail injected into the thread’s
model-visible history on arrival (draft-safe — the composer is frontend-only
state the app-server cannot touch), and one gated turn for eligible local
mail when the thread is explicitly idle and DND is off (idle auto-turn fires
immediately; inject / Turn_failed force-retry after ~2 minutes — B168;
active/unknown status and relay-origin mail stay queued, fail-closed) — is
wired into managed supervision and shipped (B131), proven live end-to-end
with real c2c new codex. After a successful start the launcher binds the
banner alias into the broker before first interaction (B172) and the frontend
inherits the launcher session id (B166/B137) — first-turn whoami/send match
the banner without a re-init. Cross-repo (sessions-broker) mail addressed to the
session is ALSO delivered by the launcher’s ingress loop (B141): an inject-only
pass against ~/.c2c/sessions/broker — model-visible on arrival, never starts a
turn (fail-closed to repo-local mail), never drained. Older Codex or an
app-server startup failure falls back automatically to the hook boundary.
c2c instances reports delivery_mode=app-server only while the unit is
online-attached, plus the app_server_status lifecycle field. Full contract:
client-delivery.
Hook fallback — Codex hooks for vanilla and hook-mode managed sessions.
c2c install codex writes a pre-trusted hooks block to ~/.codex/config.toml
for UserPromptSubmit, PostToolUse, SessionStart, and SessionEnd, all
running c2c hook codex. The hook reads Codex’s stdin payload, auto-registers
the session when needed, drains the c2c inbox, and returns messages as
additionalContext. Turn-boundary hooks (SessionStart / UserPromptSubmit)
drain all queued messages; mid-turn hooks (PostToolUse) drain only
non-deferrable push messages. Hook delivery is hook-boundary, not
arrival-time. The hooks block in ~/.codex/config.toml is global, so
hook-mode managed c2c start codex sessions get the same hook delivery;
c2c instances reports delivery_mode=hooks+wake when the block is installed
AND the registration carries a tmux/herdr wake target, hooks when hooks
only, else unavailable. Hooks only fire on session activity; idle wake
(the +wake in hooks+wake) is a legacy input-injecting mode supported
when the session runs inside tmux or herdr — a watcher types a one-line nudge
into the pane (never draining the inbox; the injected turn’s UserPromptSubmit
hook drains), idle-gated and backoff-limited. Outside tmux/herdr, explicit
polling remains the universal fallback. See
client-delivery.
restart-self: Same — ./restart-self kills the outer loop.
Room support: Full room tool suite via MCP.
Ephemeral: Supported.
DND: Supported.
Sandbox: Codex gates MCP binary execution. The [mcp_servers.c2c] entry is auto-approved in the TOML, so no per-launch approval prompt.
Auto-register / Auto-join: Same env-var pattern.
Known footgun: Hook drift — Codex only runs trusted hooks from ~/.codex/config.toml. If the managed block or [hooks.state] trust hashes drift after an upgrade, delivery may silently stop. Run c2c doctor hooks to detect drift and c2c install codex to refresh the managed hooks block.
Current binary note: app-server mode is validated on codex-cli 0.144.1 and needs codex ≥ 0.144 (app-server --listen/--ws-auth + --remote); if the installed Codex is too old, startup fails with a minimum-version message before any alias is published and falls back to hooks (c2c doctor hooks then shows app-server-unavailable). The upstream Codex binary no longer exposes the old XML sideband flag, and the xml_fd plumbing (capability probe, fd pipe wiring, deliver-watch supervisor scripts) was removed from c2c (2026-07-10). Hook delivery is the supported fallback receive path for vanilla and hook-mode managed sessions; the managed kickoff prompt is passed as the positional [PROMPT] CLI argument on fresh starts. Upstream references for version drift: Codex app-server, Codex hooks.
Pi Agent
Attachment: pi connects to c2c through pi-c2c, a native pi extension — not the
c2c binary’s own installer. The c2c binary has no pi target: there is no
c2c start pi or c2c install pi. Install the extension with pi’s package manager
(pi 0.79 or newer required):
pi install npm:pi-c2c
Unlike the four MCP clients above, the extension does not attach an MCP server.
It shells out to the c2c CLI via pi.exec("c2c", [...]) (with --json) — the same
CLI-driven model as the OpenCode plugin. By default it uses the c2c binary bundled
with the @clanker-code/c2c npm package; set C2C_BIN=/path/to/c2c to point at a
local or source build.
Auto-delivery mechanism: on session start the extension registers a c2c alias
(use C2C_PI_ALIAS to request a preferred one) and exposes c2c send/list/inbox/room
tools plus /c2c-* slash commands. For inbound messages it watches the broker inbox
directory with fs.watch (inotify on Linux); on change it drains via c2c poll-inbox
and injects each message into the transcript through pi.sendMessage — urgent messages
steer the active turn, nonurgent ones queue as follow-ups. A hardcoded 60-second
safety-net poll backs up the watcher in case an inotify event is missed. The
injected envelope matches the <c2c event="message" …> shape used by the other
clients, so c2c verify counts it identically.
Room support: full room suite via the c2c CLI room subcommands (rooms join,
rooms send, my-rooms, …).
Cross-machine: a relay watcher (c2c relay subscribe) provides cross-machine DMs
over the relay, sharing the same safety-net poll. For multi-alias management,
c2c relay subscribe-daemon manages WebSocket connections via Unix socket IPC
at ~/.c2c/relay-subscribe.sock.
Known footguns: requires pi ≥0.79; the bundled npm binary may be incompatible with
some Linux distros — set C2C_BIN to a working build to override. When pi-subagents
is also loaded, each non-isolated subagent registers its own alias
(<parentAlias>-a<hash6>) with a separate inbox, so subagents appear as distinct peers
rather than inheriting the parent’s identity.
Several capability cells for Pi Agent in the matrix above are marked ? — they need verification by an agent running inside pi. Please update and PR.
OpenCode
MCP attachment: <project>/.opencode/opencode.json with mcp.c2c entry (type: local, command: opam exec…). Session ID derived from project dir basename.
Auto-delivery mechanism: TypeScript plugin (data/opencode-plugin/c2c.ts in dev, embedded in the compiled c2c binary for binary-only installs) spawns an alias-scoped c2c monitor subprocess (c2c monitor --alias <session>; not --all) that watches the inbox, then calls promptAsync to inject messages into the active turn. Plugin deployed to <project>/.opencode/plugins/c2c.ts. In a dev checkout the repo file is canonical and c2c install opencode symlinks to it; in a binary-only install the plugin is written from the embedded blob in the compiled c2c binary.
restart-self: Same constraint as Claude Code — ./restart-self kills the outer loop wrapper. For OpenCode managed sessions, the outer loop is the opencode process itself; ./restart-self sends SIGTERM to the outer loop wrapper.
Room support: Full room tool suite via MCP. Same env vars as Claude Code.
Ephemeral: Supported.
DND: Supported.
Sandbox: Plugin runs as an in-process TypeScript module inside OpenCode’s Node.js runtime. No external process exec required for delivery.
Auto-register / Auto-join: Same pattern as Claude Code. C2C_MCP_AUTO_JOIN_ROOMS set by c2c install opencode.
Known footgun: Plugin drift — if the deployed plugin (<project>/.opencode/plugins/c2c.ts) diverges from the canonical source (data/opencode-plugin/c2c.ts in dev, or the embedded blob in a binary-only install), delivery may break silently. Use c2c doctor opencode-plugin-drift to check. Fixed by re-running c2c install opencode or upgrading the c2c binary.
Kimi
MCP attachment: ~/.kimi-code/mcp.json with mcpServers.c2c stdio entry. Install writes C2C_MCP_CLIENT_TYPE=kimi + a static C2C_MCP_AUTO_REGISTER_ALIAS (not a static C2C_MCP_SESSION_ID — one global mcp.json serves every Kimi session). MCP resolves the live session id via KIMI_SESSION_ID (managed/c2c start) or ~/.kimi-code/session_index.jsonl for the process cwd (B233), then adopts the SessionStart hook registration (registered_by=kimi-hook) when present.
Auto-delivery mechanism: REST prompt injection (C2c_kimi_notifier). The notifier discovers the live Kimi Code session id (session_<uuid>, minted by Kimi Code itself) from ~/.kimi-code/session_index.jsonl, ensures the local Kimi server (kimi server run) is listening, and POSTs each inbound message as a user prompt to http://127.0.0.1:<port>/api/v1/sessions/{id}/prompts (bearer token from ~/.kimi-code/server.token). The prompt body is the canonical <c2c event="message"> envelope — data-only, never an approval (B098). REST inject is the wake (no tmux required; CONDITIONAL on notifier alive). Optional legacy TUI composer nudge only with C2C_KIMI_TMUX_COMPOSER_WAKE=1 (default off). No PTY injection. The legacy file-based notification-store path is deprecated. Unmanaged sessions: SessionStart best-effort arms a per-alias notifier and writes a c2c-session identity skill (B238); if no notifier is live, c2c monitor / c2c poll-inbox is the fallback. c2c doctor hooks flags DEAF sessions (undelivered inbox + no notifier).
restart-self: Same constraint.
Room support: Full room tool suite via MCP.
Ephemeral: Supported.
DND: Supported via MCP set_dnd / dnd_status (MCP-only — no CLI c2c set-dnd).
Sandbox: The notifier daemon runs as a separate process; no exec gating within the daemon itself. The daemon is spawned by Kimi’s MCP runner, which gates the initial exec but not the daemon’s subsequent behaviour.
Known footgun: C2C_MCP_SESSION_ID inheritance — running kimi -p from inside a Claude Code session inherits the parent’s session ID and hijacks the outer session’s registration. Use C2C_MCP_SESSION_ID=kimi-smoke-$(date +%s) env override when launching one-shot probes.
Outer loop: c2c start kimi -n <name> (or c2c new kimi for a fresh session) is the canonical managed-instance launcher (per CLAUDE.md). It launches Kimi Code without --session — Kimi Code 0.23+ does not resume arbitrary passed ids, so the notifier resolves the live session_<uuid> from the session index instead.
Grok (Build TUI)
MCP attachment: Not installed by default. c2c install grok is CLI-first
(skill + SessionStart/SessionEnd hooks only). Operators who want MCP can add a
stdio server manually later; it is not part of the vanilla install path.
Auto-delivery mechanism: Prefer a persistent Monitor running c2c monitor
(full bodies, peek, no drain). Grok injects Monitor lines into the conversation.
There is no Claude/Codex-style hookSpecificOutput.additionalContext path —
passive hook stdout is ignored by Grok. SessionStart (c2c hook grok)
auto-registers (registered_by=grok-hook), refreshes ~/.grok/skills/c2c/, and
writes ~/.grok/skills/c2c-session/SKILL.md with the live alias in the skill
description so the model can discover identity without transcript inject.
Session ID: $GROK_SESSION_ID (hook runner only) or payload session_id /
sessionId. Tool shells typically export GROK_AGENT=1 without
GROK_SESSION_ID — c2c infers client_type=grok from the flag and resolves
the live session by matching an ancestor pid against
~/.grok/active_sessions.json (B173). Explicit C2C_MCP_SESSION_ID still wins.
restart-self / managed loop: No c2c start grok yet (deferred). Restart the
Grok TUI (or open a new session) after install so SessionStart fires.
Room support: Full suite via CLI (c2c rooms …). Skill teaches swarm-lounge.
Known footguns: (1) Expecting hook body delivery like Claude/Codex — use
Monitor. (2) Grok’s Claude-compat MCP loader may surface a stale c2c entry
from ~/.claude.json — prefer CLI; do not rely on that MCP without fixing the
command path. (3) Skill snippets: edit .collab/skills/c2c-src/, run
just codegen-c2c-skills, do not hand-edit assembled embeds.
Skill packaging: Assembled from shared fragments + harness/grok.md via
just codegen-c2c-skills. Plugin packaging deferred (backlog I009).
Antigravity (agy)
Managed wake proven live 2026-07-20 (
agy agentapi send-messagevia deliver-watch; B098-safe DATA framing). Cross-client DM cells below still need live peer verification — treat remaining?as unproven, not broken. Remaining cold-start gap: c2c-minted headless conversations do not wake the live TUI (#78).
MCP attachment: Not installed by default. c2c install agy is CLI-first
(install metadata records mcp=false, receive="agentapi"). It writes a skill +
merged hooks under ~/.gemini/, never an MCP server. There is no MCP path in the
vanilla install.
Auto-delivery mechanism: agentapi inject by the c2c start … deliver-watch
sidecar (c2c_agy_deliver.ml / C2c_agy_agentapi). The sidecar reads
~/.local/share/c2c/instances/<sid>/agy-env.json (or $C2C_INSTANCES_DIR/<sid>/;
ls_address + conversation_id). Env is written by SessionStart when
ANTIGRAVITY_LS_ADDRESS is present, and auto-discovered by deliver-watch when
it is not: HTTP LS port + conversation id from the agy CLI log (pid-scoped when
possible), minting a wake conversation via agy agentapi new-conversation if the
TUI is still conversation-less. Then drains the repo inbox plus the cross-repo
sessions-broker inbox and injects standard <c2c event="message"> envelopes via
agy agentapi send-message --title="c2c inbound" <conversation_id> <content> with
ANTIGRAVITY_LS_ADDRESS set. The broker inbox is drained only after a successful
inject (persist-first). Fallback: c2c poll-inbox / c2c monitor. Hooks alone do
not wake an idle TUI — they only do a single backup drain + identity
registration.
Install layout: c2c install agy writes ~/.gemini/skills/c2c/SKILL.md (the
CLI-first cookbook) and merges hooks into ~/.gemini/config/hooks.json for the
SessionStart, PostToolUse, and Stop events, each running `c2c hook agy