cross-agent-teams-mcp 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +296 -0
  3. package/README.zh-CN.md +306 -0
  4. package/dist/channel-cli.d.ts +18 -0
  5. package/dist/channel-cli.js +358 -0
  6. package/dist/channel-cli.js.map +1 -0
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.js +4585 -0
  9. package/dist/cli.js.map +1 -0
  10. package/package.json +62 -0
  11. package/src/channel/auto-daemon.ts +130 -0
  12. package/src/channel/daemon-client.ts +155 -0
  13. package/src/channel/proxy.ts +28 -0
  14. package/src/channel-cli.ts +122 -0
  15. package/src/cli.ts +136 -0
  16. package/src/daemon/auth.ts +17 -0
  17. package/src/daemon/channel-wake-fanout.ts +39 -0
  18. package/src/daemon/channel-wake-send.ts +38 -0
  19. package/src/daemon/cleanup.ts +38 -0
  20. package/src/daemon/errors.ts +18 -0
  21. package/src/daemon/pid.ts +33 -0
  22. package/src/daemon/port.ts +16 -0
  23. package/src/daemon/runtime-identity.ts +238 -0
  24. package/src/daemon/server.ts +64 -0
  25. package/src/daemon/shutdown.ts +12 -0
  26. package/src/daemon/sse-fanout.ts +96 -0
  27. package/src/daemon/tmux-cli.ts +61 -0
  28. package/src/daemon/tmux-pane-detect.ts +276 -0
  29. package/src/lib/client-kind.ts +1 -0
  30. package/src/lib/default-team.ts +18 -0
  31. package/src/lib/delivery-spec.ts +172 -0
  32. package/src/lib/schema-diff.ts +79 -0
  33. package/src/mcp/agent-public-row.ts +52 -0
  34. package/src/mcp/auto-bind-channel.ts +106 -0
  35. package/src/mcp/auto-bind-codex-pane.ts +170 -0
  36. package/src/mcp/auto-poke-fanout.ts +129 -0
  37. package/src/mcp/bind-channel.ts +39 -0
  38. package/src/mcp/bind-runtime-identity.ts +43 -0
  39. package/src/mcp/broadcast-to-role.ts +127 -0
  40. package/src/mcp/broadcast.ts +115 -0
  41. package/src/mcp/codex-appserver-dispatch.ts +169 -0
  42. package/src/mcp/codex-appserver-rpc.ts +227 -0
  43. package/src/mcp/codex-pane-pre-register-repo.ts +57 -0
  44. package/src/mcp/delivery-status.ts +114 -0
  45. package/src/mcp/diff-contracts.ts +25 -0
  46. package/src/mcp/echo.ts +8 -0
  47. package/src/mcp/fanout-with-retry.ts +56 -0
  48. package/src/mcp/get-contract.ts +24 -0
  49. package/src/mcp/get-inbox.ts +57 -0
  50. package/src/mcp/identity.ts +8 -0
  51. package/src/mcp/pending-contract-events.ts +36 -0
  52. package/src/mcp/poke-guard.ts +32 -0
  53. package/src/mcp/poke-retry.ts +159 -0
  54. package/src/mcp/poke.ts +190 -0
  55. package/src/mcp/pre-register-codex-pane.ts +65 -0
  56. package/src/mcp/register-agent.ts +84 -0
  57. package/src/mcp/register-codex-self.ts +276 -0
  58. package/src/mcp/register-contract.ts +60 -0
  59. package/src/mcp/send-message.ts +159 -0
  60. package/src/mcp/subscribe-channel-wake.ts +31 -0
  61. package/src/mcp/subscribe-contract.ts +24 -0
  62. package/src/mcp/task-add.ts +37 -0
  63. package/src/mcp/task-claim.ts +54 -0
  64. package/src/mcp/task-complete.ts +36 -0
  65. package/src/mcp/task-list.ts +33 -0
  66. package/src/mcp/tools.ts +1240 -0
  67. package/src/mcp/transport-dispatch.ts +171 -0
  68. package/src/mcp/transport.ts +204 -0
  69. package/src/mcp/unregister-self.ts +46 -0
  70. package/src/storage/agents-repo.ts +328 -0
  71. package/src/storage/db.ts +13 -0
  72. package/src/storage/events-outbox.ts +44 -0
  73. package/src/storage/schema.ts +180 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/daemon/server.ts","../src/storage/db.ts","../src/storage/schema.ts","../src/daemon/auth.ts","../src/mcp/transport.ts","../src/mcp/echo.ts","../src/mcp/tools.ts","../src/storage/agents-repo.ts","../src/lib/delivery-spec.ts","../src/storage/events-outbox.ts","../src/lib/default-team.ts","../src/mcp/register-agent.ts","../src/mcp/send-message.ts","../src/daemon/tmux-cli.ts","../src/mcp/poke-guard.ts","../src/mcp/poke-retry.ts","../src/mcp/auto-poke-fanout.ts","../src/mcp/delivery-status.ts","../src/mcp/fanout-with-retry.ts","../src/mcp/broadcast.ts","../src/mcp/broadcast-to-role.ts","../src/mcp/get-inbox.ts","../src/mcp/task-add.ts","../src/mcp/task-claim.ts","../src/mcp/task-complete.ts","../src/mcp/task-list.ts","../src/lib/schema-diff.ts","../src/mcp/register-contract.ts","../src/mcp/subscribe-contract.ts","../src/mcp/get-contract.ts","../src/mcp/diff-contracts.ts","../src/mcp/pending-contract-events.ts","../src/mcp/poke.ts","../src/daemon/channel-wake-send.ts","../src/mcp/codex-appserver-rpc.ts","../src/mcp/codex-appserver-dispatch.ts","../src/mcp/transport-dispatch.ts","../src/daemon/errors.ts","../src/mcp/subscribe-channel-wake.ts","../src/mcp/bind-channel.ts","../src/mcp/auto-bind-channel.ts","../src/daemon/runtime-identity.ts","../src/mcp/bind-runtime-identity.ts","../src/mcp/register-codex-self.ts","../src/mcp/unregister-self.ts","../src/mcp/agent-public-row.ts","../src/daemon/tmux-pane-detect.ts","../src/mcp/codex-pane-pre-register-repo.ts","../src/mcp/pre-register-codex-pane.ts","../src/mcp/auto-bind-codex-pane.ts","../src/daemon/cleanup.ts","../src/daemon/sse-fanout.ts","../src/daemon/channel-wake-fanout.ts","../src/daemon/pid.ts","../src/daemon/shutdown.ts","../src/daemon/port.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { startServer } from './daemon/server.js'\nimport { wireShutdown } from './daemon/shutdown.js'\nimport { acquirePidFile } from './daemon/pid.js'\nimport { selectPort } from './daemon/port.js'\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\n\nfunction parseArg(name: string, def?: string): string | undefined {\n const i = process.argv.indexOf(name)\n return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : def\n}\n\nfunction defaultHome(): string {\n return process.env.CROSS_AGENT_TEAMS_MCP_HOME ?? join(homedir(), '.cross-agent-teams-mcp')\n}\n\nasync function runDaemon(): Promise<void> {\n const home = defaultHome()\n const pidPath = parseArg('--pid-file', join(home, 'daemon.pid'))!\n const dbPath = parseArg('--db', join(home, 'data.db'))!\n const token = parseArg('--token')\n const requested = Number(parseArg('--port', '9100'))\n const port = requested === 0 ? 0 : await selectPort([requested, requested + 1, requested + 2])\n const r = acquirePidFile(pidPath, port || requested)\n if (!r.ok) { console.error('daemon already running pid=' + r.pid); process.exit(1) }\n const started = await startServer({ dbPath, token, port })\n wireShutdown(started.app, pidPath)\n console.log(`listening on ${started.host}:${started.port}`)\n}\n\nfunction resolveDaemonPort(explicit: string | undefined): number | undefined {\n if (explicit !== undefined) {\n const n = Number(explicit)\n if (Number.isInteger(n) && n > 0) return n\n return undefined\n }\n const pidPath = parseArg('--pid-file', join(defaultHome(), 'daemon.pid'))!\n if (!existsSync(pidPath)) return undefined\n try {\n const parsed = JSON.parse(readFileSync(pidPath, 'utf8')) as { port?: number }\n if (typeof parsed.port === 'number' && parsed.port > 0) return parsed.port\n } catch { /* ignore corrupt pid file */ }\n return undefined\n}\n\nasync function runPreRegisterCodexPane(): Promise<void> {\n const pane = parseArg('--pane')\n const agentId = parseArg('--agent-id')\n const ttlRaw = parseArg('--ttl')\n const tokenExplicit = parseArg('--token')\n const portExplicit = parseArg('--port')\n\n if (!pane || !agentId) {\n console.error('usage: cross-agent-teams-mcp pre-register-codex-pane --pane <pane_id> --agent-id <uuid> [--ttl <seconds>] [--port <n>] [--token <t>]')\n process.exit(2)\n }\n\n const port = resolveDaemonPort(portExplicit)\n if (!port) {\n console.error('{\"ok\":false,\"error\":\"daemon_port_unresolved\",\"detail\":\"pass --port or start the daemon so the pid file is present\"}')\n process.exit(1)\n }\n\n const token = tokenExplicit ?? process.env.CROSS_AGENT_TEAMS_MCP_TOKEN\n const host = process.env.CROSS_AGENT_TEAMS_MCP_HOST ?? '127.0.0.1'\n const base = new URL(`http://${host}:${port}/mcp`)\n\n const requestInit: RequestInit | undefined = token\n ? { headers: { Authorization: `Bearer ${token}` } }\n : undefined\n\n const transport = new StreamableHTTPClientTransport(base, {\n requestInit,\n })\n const client = new Client({ name: 'cross-agent-teams-mcp-cli', version: '0.1.0' })\n\n try {\n await client.connect(transport)\n const args: Record<string, unknown> = {\n pane_id: pane,\n xats_agent_id: agentId,\n }\n if (ttlRaw !== undefined) {\n const ttl = Number(ttlRaw)\n if (!Number.isInteger(ttl) || ttl <= 0) {\n console.error('{\"ok\":false,\"error\":\"invalid_ttl\"}')\n process.exit(2)\n }\n args.ttl_seconds = ttl\n }\n const resp = await client.callTool({\n name: 'pre_register_codex_pane',\n arguments: args,\n })\n const content = (resp as { content?: Array<{ text?: string }> }).content\n const text = content?.[0]?.text ?? ''\n let parsed: unknown\n try { parsed = JSON.parse(text) } catch { parsed = { raw: text } }\n const obj = (parsed ?? {}) as Record<string, unknown>\n if (obj.ok === true) {\n console.log(JSON.stringify(obj))\n process.exit(0)\n }\n console.error(JSON.stringify(obj))\n process.exit(1)\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error)\n console.error(JSON.stringify({ ok: false, error: 'cli_failed', detail: msg }))\n process.exit(1)\n } finally {\n try { await transport.close() } catch { /* best-effort */ }\n try { await client.close() } catch { /* best-effort */ }\n }\n}\n\nasync function main(): Promise<void> {\n const cmd = process.argv[2]\n if (cmd === 'daemon') {\n await runDaemon()\n return\n }\n if (cmd === 'pre-register-codex-pane') {\n await runPreRegisterCodexPane()\n return\n }\n console.error('usage: cross-agent-teams-mcp <daemon|pre-register-codex-pane> [options]')\n process.exit(2)\n}\n\nmain().catch((e) => { console.error(e?.message ?? e); process.exit(1) })\n\nexport {}\n","import Fastify, { type FastifyInstance } from 'fastify'\nimport { openDb } from '../storage/db.js'\nimport { applySchema } from '../storage/schema.js'\nimport { makeAuthHook } from './auth.js'\nimport { mountMcp } from '../mcp/transport.js'\nimport { runCleanup } from './cleanup.js'\nimport { SseFanout } from './sse-fanout.js'\nimport { ChannelWakeFanout } from './channel-wake-fanout.js'\nimport { clearAllRetries } from '../mcp/poke-retry.js'\n\nexport interface ServerOpts {\n dbPath: string\n token?: string\n cleanupIntervalMs?: number\n fanout?: SseFanout\n channelWakeFanout?: ChannelWakeFanout\n}\nexport interface StartOpts extends ServerOpts { port: number; host?: string }\n\nconst DEFAULT_KEEP_ALIVE_TIMEOUT_MS = 120_000\n\nfunction parsePositiveInt(raw: string | undefined, fallback: number): number {\n const n = Number(raw)\n return Number.isInteger(n) && n > 0 ? n : fallback\n}\n\nexport async function buildServer(opts: ServerOpts): Promise<FastifyInstance> {\n const keepAliveTimeout = parsePositiveInt(process.env.KEEP_ALIVE_TIMEOUT_MS, DEFAULT_KEEP_ALIVE_TIMEOUT_MS)\n const app = Fastify({ logger: false, keepAliveTimeout })\n app.server.headersTimeout = keepAliveTimeout + 1000\n const db = openDb(opts.dbPath)\n applySchema(db)\n const startedAt = Date.now()\n const version = '0.1.0'\n const fanout = opts.fanout ?? new SseFanout()\n const channelWakeFanout = opts.channelWakeFanout ?? new ChannelWakeFanout()\n app.addHook('onRequest', makeAuthHook(opts.token))\n app.get('/health', async () => ({ ok: true, version, uptime_seconds: Math.floor((Date.now() - startedAt) / 1000) }))\n mountMcp(app, db, fanout, channelWakeFanout)\n\n const cleanupIntervalMs = opts.cleanupIntervalMs\n ?? Number(process.env.CLEANUP_INTERVAL_MS ?? 60 * 60 * 1000)\n const interval = setInterval(() => {\n try { runCleanup(db) } catch { /* best-effort */ }\n }, cleanupIntervalMs)\n if (typeof interval.unref === 'function') interval.unref()\n\n app.addHook('onClose', async () => {\n clearInterval(interval)\n clearAllRetries()\n fanout.stopAll()\n db.close()\n })\n return app\n}\n\nexport async function startServer(opts: StartOpts): Promise<{ app: FastifyInstance; port: number; host: string }> {\n const app = await buildServer(opts)\n const host = opts.host ?? '127.0.0.1'\n await app.listen({ port: opts.port, host })\n const addr = app.server.address()\n const port = addr && typeof addr === 'object' ? addr.port : opts.port\n return { app, port, host }\n}\n","import Database from 'better-sqlite3'\nimport { mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nexport function openDb(path: string): Database.Database {\n mkdirSync(dirname(path), { recursive: true })\n const db = new Database(path)\n db.pragma('journal_mode = WAL')\n db.pragma('busy_timeout = 5000')\n db.pragma('synchronous = NORMAL')\n db.pragma('foreign_keys = ON')\n return db\n}\n","import type Database from 'better-sqlite3'\n\nconst DDL = [\n `CREATE TABLE IF NOT EXISTS events (\n event_id INTEGER PRIMARY KEY AUTOINCREMENT,\n from_team TEXT NOT NULL,\n to_team TEXT NOT NULL,\n event_type TEXT NOT NULL,\n actor_agent_id TEXT,\n payload TEXT NOT NULL,\n created_at TEXT NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS idx_events_from_team_eventid ON events(from_team, event_id)`,\n `CREATE INDEX IF NOT EXISTS idx_events_to_team_eventid ON events(to_team, event_id)`,\n `CREATE TABLE IF NOT EXISTS agents (\n agent_id TEXT PRIMARY KEY,\n client TEXT,\n client_name TEXT,\n team TEXT NOT NULL,\n role TEXT NOT NULL,\n name TEXT NOT NULL,\n model TEXT,\n registered_at TEXT NOT NULL,\n last_seen_at TEXT NOT NULL,\n last_processed_event_id INTEGER NOT NULL DEFAULT 0,\n tmux_pane_id TEXT,\n claude_ui_pid INTEGER,\n runtime_ui_pid INTEGER,\n runtime_tty TEXT,\n runtime_verification_mode TEXT,\n runtime_bound_at TEXT,\n channel_session_id TEXT,\n delivery_kind TEXT NOT NULL DEFAULT 'none',\n delivery_payload TEXT\n )`,\n `CREATE UNIQUE INDEX IF NOT EXISTS agents_identity_idx ON agents(team, name)`,\n `CREATE TABLE IF NOT EXISTS messages (\n id TEXT PRIMARY KEY,\n event_id INTEGER NOT NULL REFERENCES events(event_id),\n from_team TEXT NOT NULL,\n to_team TEXT NOT NULL,\n from_agent_id TEXT NOT NULL,\n to_agent_id TEXT,\n to_role TEXT,\n subject TEXT,\n body TEXT NOT NULL,\n need_reply INTEGER NOT NULL DEFAULT 1,\n sent_at TEXT NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS message_delivery_status (\n message_id TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n wake_status TEXT NOT NULL CHECK(wake_status IN ('delivered','retrying','skipped','failed')),\n skip_reason TEXT,\n retry_attempts INTEGER NOT NULL DEFAULT 0,\n updated_at TEXT NOT NULL,\n delivered_at TEXT,\n PRIMARY KEY (message_id, agent_id)\n )`,\n `CREATE INDEX IF NOT EXISTS idx_message_delivery_status_message ON message_delivery_status(message_id)`,\n `CREATE TABLE IF NOT EXISTS tasks (\n id TEXT PRIMARY KEY,\n team TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL CHECK(status IN ('pending','in_progress','completed')),\n depends_on TEXT NOT NULL,\n claimed_by TEXT,\n claimed_at TEXT,\n completed_at TEXT,\n result TEXT,\n created_at TEXT NOT NULL\n )`,\n `CREATE TABLE IF NOT EXISTS contracts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n team TEXT NOT NULL,\n name TEXT NOT NULL,\n version INTEGER NOT NULL,\n format TEXT NOT NULL CHECK(format='jsonschema'),\n schema TEXT NOT NULL,\n note TEXT,\n registered_by TEXT NOT NULL,\n registered_at TEXT NOT NULL,\n UNIQUE(team, name, version)\n )`,\n `CREATE TABLE IF NOT EXISTS contract_subscriptions (\n agent_id TEXT NOT NULL,\n team TEXT NOT NULL,\n contract_name TEXT NOT NULL,\n subscribed_at TEXT NOT NULL,\n PRIMARY KEY (agent_id, team, contract_name)\n )`,\n `CREATE TABLE IF NOT EXISTS codex_pane_pre_registrations (\n pane_id TEXT PRIMARY KEY,\n xats_agent_id TEXT NOT NULL,\n expires_at TEXT NOT NULL\n )`\n]\n\nfunction migrateAgentsDeliveryColumns(db: Database.Database): void {\n const tableExists = db\n .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='agents'`)\n .get() as { name: string } | undefined\n if (!tableExists) return\n const cols = db.pragma('table_info(agents)') as Array<{ name: string }>\n const existing = new Set(cols.map(c => c.name))\n const needClient = !existing.has('client')\n const needClientName = !existing.has('client_name')\n const needKind = !existing.has('delivery_kind')\n const needPayload = !existing.has('delivery_payload')\n const needRuntimeUiPid = !existing.has('runtime_ui_pid')\n const needRuntimeTty = !existing.has('runtime_tty')\n const needRuntimeVerificationMode = !existing.has('runtime_verification_mode')\n const needRuntimeBoundAt = !existing.has('runtime_bound_at')\n const needClaudeUiPid = !existing.has('claude_ui_pid')\n if (\n !needClient &&\n !needClientName &&\n !needKind &&\n !needPayload &&\n !needRuntimeUiPid &&\n !needRuntimeTty &&\n !needRuntimeVerificationMode &&\n !needRuntimeBoundAt &&\n !needClaudeUiPid\n ) return\n const tx = db.transaction(() => {\n if (needClient) {\n db.exec(`ALTER TABLE agents ADD COLUMN client TEXT`)\n }\n if (needClientName) {\n db.exec(`ALTER TABLE agents ADD COLUMN client_name TEXT`)\n }\n if (needKind) {\n db.exec(`ALTER TABLE agents ADD COLUMN delivery_kind TEXT NOT NULL DEFAULT 'none'`)\n }\n if (needPayload) {\n db.exec(`ALTER TABLE agents ADD COLUMN delivery_payload TEXT`)\n }\n if (needRuntimeUiPid) {\n db.exec(`ALTER TABLE agents ADD COLUMN runtime_ui_pid INTEGER`)\n }\n if (needRuntimeTty) {\n db.exec(`ALTER TABLE agents ADD COLUMN runtime_tty TEXT`)\n }\n if (needRuntimeVerificationMode) {\n db.exec(`ALTER TABLE agents ADD COLUMN runtime_verification_mode TEXT`)\n }\n if (needRuntimeBoundAt) {\n db.exec(`ALTER TABLE agents ADD COLUMN runtime_bound_at TEXT`)\n }\n if (needClaudeUiPid) {\n db.exec(`ALTER TABLE agents ADD COLUMN claude_ui_pid INTEGER`)\n }\n if (needKind || needPayload) {\n db.exec(`UPDATE agents\n SET delivery_kind = 'claude-channel',\n delivery_payload = json_object('channel_session_id', channel_session_id)\n WHERE channel_session_id IS NOT NULL AND delivery_kind = 'none'`)\n }\n })\n tx()\n}\n\nfunction migrateMessagesNeedReplyColumn(db: Database.Database): void {\n const tableExists = db\n .prepare(`SELECT name FROM sqlite_master WHERE type='table' AND name='messages'`)\n .get() as { name: string } | undefined\n if (!tableExists) return\n const cols = db.pragma('table_info(messages)') as Array<{ name: string }>\n const existing = new Set(cols.map(c => c.name))\n if (existing.has('need_reply')) return\n db.exec(`ALTER TABLE messages ADD COLUMN need_reply INTEGER NOT NULL DEFAULT 1`)\n}\n\nexport function applySchema(db: Database.Database): void {\n for (const sql of DDL) db.exec(sql)\n migrateAgentsDeliveryColumns(db)\n migrateMessagesNeedReplyColumn(db)\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify'\n\nexport function extractToken(req: FastifyRequest): string | undefined {\n const h = req.headers['authorization']\n if (typeof h === 'string' && h.startsWith('Bearer ')) return h.slice(7)\n const q = (req.query as Record<string, unknown> | undefined)?.token\n return typeof q === 'string' ? q : undefined\n}\n\nexport function makeAuthHook(expected: string | undefined) {\n return async (req: FastifyRequest, reply: FastifyReply) => {\n if (req.url.startsWith('/health')) return\n if (!expected) return\n const got = extractToken(req)\n if (got !== expected) return reply.code(401).send({ error: 'invalid_token' })\n }\n}\n","import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'\nimport type Database from 'better-sqlite3'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { randomUUID, createHash } from 'node:crypto'\nimport { echoSchema, echoHandler } from './echo.js'\nimport { registerBusinessTools, type AgentIdHolder } from './tools.js'\nimport type { SseFanout, SseSink } from '../daemon/sse-fanout.js'\nimport type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\n\ninterface Session {\n transport: StreamableHTTPServerTransport\n server: McpServer\n sessionId: string\n agentIdHolder: AgentIdHolder\n clientInfo?: {\n name?: string\n version?: string\n }\n}\n\nexport function mountMcp(\n app: FastifyInstance,\n db: Database.Database,\n fanout: SseFanout,\n channelWakeFanout?: ChannelWakeFanout\n): void {\n const sessions = new Map<string, Session>()\n // Once register_agent succeeds for a session id, pin the owning Authorization hash.\n // A later register_agent presenting a different Authorization triggers HTTP 409.\n const sessionOwners = new Map<string, string>()\n\n function createSession(): Session {\n const server = new McpServer(\n { name: 'cross-agent-teams-mcp', version: '0.1.0' },\n {\n instructions:\n 'xats 是 cross-agent-teams 的缩写. 当用户或其他 agent 提到 xats 时, 指的是本 MCP server (cross-agent-teams-mcp) 及其跨 agent 协作工具 (register_agent, send_message, task_* 等). 用户说\"注册到 xats\"或\"注册到 cross-agent-teams\"时, 表示注册到本 MCP 服务, xats 和 cross-agent-teams 不是 team 名, 不要把它们传给 team. 不要把单独的常用词\"注册\"默认劫持为本工具; 只有当前上下文已经在讨论 cross-agent-teams 注册时才可续接. 注册时 (register_agent / register_claude_self) 如果用户未显式指定 team, 默认传 project_dir=当前工作目录 (cwd), daemon 会用它的 basename 作为 team 默认值; 都不传时回落 default.'\n + ' Codex clients: if your tool shell env has CODEX_THREAD_ID set (codex 0.124.0+ exports it), pass its value as `thread_id` and prefer `register_codex_self` over `register_agent`. Do NOT attempt to discover or pass `ui_pid` from codex — the launcher\\'s `pre_register_codex_pane` pre-reg flow handles tmux pane binding automatically; supplying `ui_pid` manually disables that auto-bind path.'\n }\n )\n const agentIdHolder: AgentIdHolder = { current: undefined }\n server.registerTool('echo', { title: 'Echo', description: 'Return the input', inputSchema: echoSchema }, echoHandler as any)\n\n let sessionIdForCaller: string | undefined\n // `caller()` returns the session id before register_agent succeeds (to serve as\n // a stable connection_id), and the bound agent_id after register succeeds.\n const getCallerAgentId = (): string | undefined =>\n agentIdHolder.current ?? sessionIdForCaller\n\n const sink: SseSink = {\n send(msg: Record<string, unknown>): void {\n const payload = {\n jsonrpc: '2.0' as const,\n method: 'notifications/contract_event',\n params: msg\n }\n void transport.send(payload).catch(() => { /* no active GET stream yet */ })\n },\n sendHeartbeat(): void {\n void transport.send({\n jsonrpc: '2.0' as const,\n method: 'notifications/heartbeat',\n params: {}\n }).catch(() => { /* no active GET stream yet */ })\n },\n close(): void { /* transport.onclose handles lifecycle */ }\n }\n\n const onRegisterSuccess = (agent_id: string, team: string): void => {\n // Detach any prior sink registered under this agent_id (e.g. from a previous\n // session that reused the same identity) before attaching the new one.\n try { fanout.detach(agent_id) } catch { /* ignore */ }\n // If this session had previously bound a different agent_id (e.g. role change\n // mid-session), detach that too.\n if (agentIdHolder.current && agentIdHolder.current !== agent_id) {\n try { fanout.detach(agentIdHolder.current) } catch { /* ignore */ }\n }\n fanout.attach(agent_id, team, sink)\n agentIdHolder.current = agent_id\n }\n\n const onUnregisterSuccess = (agent_id: string): void => {\n try { fanout.detach(agent_id) } catch { /* ignore */ }\n if (sessionIdForCaller && channelWakeFanout) {\n try { channelWakeFanout.detachBySession(sessionIdForCaller) } catch { /* ignore */ }\n }\n if (agentIdHolder.current === agent_id) agentIdHolder.current = undefined\n }\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (sid: string) => {\n sessionIdForCaller = sid\n sessions.set(sid, { transport, server, sessionId: sid, agentIdHolder, clientInfo: undefined })\n }\n })\n transport.onclose = () => {\n if (agentIdHolder.current) {\n try { fanout.detach(agentIdHolder.current) } catch { /* ignore */ }\n }\n if (transport.sessionId && channelWakeFanout) {\n try { channelWakeFanout.detachBySession(transport.sessionId) } catch { /* ignore */ }\n }\n if (transport.sessionId) {\n sessions.delete(transport.sessionId)\n sessionOwners.delete(transport.sessionId)\n }\n }\n registerBusinessTools(\n server,\n db,\n getCallerAgentId,\n fanout,\n onRegisterSuccess,\n () => sessionIdForCaller,\n channelWakeFanout,\n () => transport,\n () => {\n const sid = sessionIdForCaller\n if (!sid) return undefined\n return sessions.get(sid)?.clientInfo\n },\n onUnregisterSuccess\n )\n server.connect(transport)\n return { transport, server, sessionId: '', agentIdHolder }\n }\n\n function authHashFor(req: FastifyRequest): string | null {\n const raw = req.headers['authorization']\n if (typeof raw !== 'string') return null\n const trimmed = raw.trim()\n if (trimmed.length === 0) return null\n return createHash('sha256').update(trimmed).digest('hex')\n }\n\n interface ToolsCallBody {\n method?: string\n params?: { name?: string; arguments?: Record<string, unknown> }\n }\n\n app.post('/mcp', async (req: FastifyRequest, reply: FastifyReply) => {\n const sid = req.headers['mcp-session-id'] as string | undefined\n const body = req.body as ToolsCallBody | undefined\n const isInit = body?.method === 'initialize'\n let session = sid ? sessions.get(sid) : undefined\n if (!session && !isInit) { return reply.code(400).send({ error: 'unknown_session' }) }\n\n // register_agent presenting a different Authorization header than the one that\n // first claimed this session id -> agent_id_collision (HTTP 409). Absence of\n // an Authorization header disables collision enforcement per spec.\n if (session && body?.method === 'tools/call' && body.params?.name === 'register_agent') {\n const authHash = authHashFor(req)\n if (authHash !== null) {\n const owner = sessionOwners.get(session.sessionId)\n if (owner && owner !== authHash) {\n return reply.code(409).send({ error: 'agent_id_collision' })\n }\n if (!owner) sessionOwners.set(session.sessionId, authHash)\n }\n }\n\n // Spoofed from_agent_id on tools/call -> 403. Compare against the session's\n // currently bound agent_id (post register_agent), NOT the raw MCP session id.\n if (session && body?.method === 'tools/call') {\n const claimed = body.params?.arguments?.from_agent_id\n if (typeof claimed === 'string') {\n const current = session.agentIdHolder.current\n if (current === undefined || claimed !== current) {\n return reply.code(403).send({ error: 'identity_mismatch' })\n }\n }\n }\n\n if (!session) { session = createSession() }\n if (body?.method === 'initialize') {\n const params = body.params as { clientInfo?: { name?: unknown; version?: unknown } } | undefined\n const clientInfo = params?.clientInfo\n session.clientInfo = {\n name: typeof clientInfo?.name === 'string' ? clientInfo.name : undefined,\n version: typeof clientInfo?.version === 'string' ? clientInfo.version : undefined,\n }\n }\n await session.transport.handleRequest(req.raw, reply.raw, body)\n return reply\n })\n\n app.get('/mcp', async (req: FastifyRequest, reply: FastifyReply) => {\n const sid = req.headers['mcp-session-id'] as string | undefined\n const session = sid ? sessions.get(sid) : undefined\n if (!session) return reply.code(400).send({ error: 'unknown_session' })\n await session.transport.handleRequest(req.raw, reply.raw)\n return reply\n })\n\n app.delete('/mcp', async (req: FastifyRequest, reply: FastifyReply) => {\n const sid = req.headers['mcp-session-id'] as string | undefined\n const session = sid ? sessions.get(sid) : undefined\n if (!session) return reply.code(400).send({ error: 'unknown_session' })\n await session.transport.handleRequest(req.raw, reply.raw)\n return reply\n })\n}\n","import { z } from 'zod'\n\nexport const echoSchema = { msg: z.string() }\n\nexport async function echoHandler(args: { msg: string }): Promise<{ content: Array<{ type: 'text'; text: string }> }> {\n const out = { msg: args.msg, echoed_at: new Date().toISOString() }\n return { content: [{ type: 'text', text: JSON.stringify(out) }] }\n}\n","import type Database from 'better-sqlite3'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { AgentsRepo } from '../storage/agents-repo.js'\nimport { EventsOutbox } from '../storage/events-outbox.js'\nimport { RegisterAgentService } from './register-agent.js'\nimport { SendMessageService } from './send-message.js'\nimport { BroadcastService } from './broadcast.js'\nimport { BroadcastToRoleService } from './broadcast-to-role.js'\nimport { GetInboxService } from './get-inbox.js'\nimport { TaskAddService } from './task-add.js'\nimport { TaskClaimService } from './task-claim.js'\nimport { TaskCompleteService } from './task-complete.js'\nimport { TaskListService } from './task-list.js'\nimport { RegisterContractService } from './register-contract.js'\nimport { SubscribeContractService } from './subscribe-contract.js'\nimport { GetContractService } from './get-contract.js'\nimport { DiffContractsService } from './diff-contracts.js'\nimport { PendingContractEventsService } from './pending-contract-events.js'\nimport { GetDeliveryStatusService } from './delivery-status.js'\nimport { poke } from './poke.js'\nimport { wrapStorage } from '../daemon/errors.js'\nimport type { SseFanout } from '../daemon/sse-fanout.js'\nimport type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\nimport { SubscribeChannelWakeService } from './subscribe-channel-wake.js'\nimport { BindChannelService } from './bind-channel.js'\nimport { AutoBindChannelService } from './auto-bind-channel.js'\nimport { BindRuntimeIdentityService } from './bind-runtime-identity.js'\nimport { RegisterCodexSelfService } from './register-codex-self.js'\nimport { UnregisterSelfService } from './unregister-self.js'\nimport { toPublicAgentRow } from './agent-public-row.js'\nimport { detectTmuxPane } from '../daemon/tmux-pane-detect.js'\nimport { bindRuntimeIdentity } from '../daemon/runtime-identity.js'\nimport type { DetectAgentKind } from '../daemon/tmux-pane-detect.js'\nimport type { ClientKind } from '../lib/client-kind.js'\nimport { CodexPanePreRegRepo } from './codex-pane-pre-register-repo.js'\nimport {\n PreRegisterCodexPaneService,\n preRegisterCodexPaneInputSchema,\n} from './pre-register-codex-pane.js'\nimport { autoBindCodexPane } from './auto-bind-codex-pane.js'\n\nexport interface AgentIdHolder { current: string | undefined }\n\ntype TextContent = { content: Array<{ type: 'text'; text: string }> }\n\nfunction toText(value: unknown): TextContent {\n return { content: [{ type: 'text', text: JSON.stringify(value) }] }\n}\n\nconst deliverySchema = z.object({\n kind: z.string(),\n}).passthrough()\n\nconst clientSchema = z.enum(['codex', 'claude-code', 'opencode', 'custom'])\n\nconst detectTmuxPaneSchema = z.object({\n agent: z.enum(['codex', 'claude-code', 'opencode', 'custom']),\n cwd: z.string().optional(),\n tty: z.string().optional(),\n title_contains: z.string().optional(),\n process_pattern: z.string().optional(),\n})\n\nconst detectTmuxPaneArgsSchema = detectTmuxPaneSchema.superRefine((value, ctx) => {\n if (value.agent === 'custom' && (!value.process_pattern || value.process_pattern.trim().length === 0)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['process_pattern'],\n message: 'process_pattern is required when agent=custom',\n })\n }\n})\n\nconst bindRuntimeIdentitySchema = z.object({\n agent: z.enum(['codex', 'claude-code', 'opencode', 'custom']),\n ui_pid: z.number().int().positive().optional(),\n ui_tty: z.string().optional(),\n tmux_pane_id: z.string().min(1).optional(),\n process_pattern: z.string().optional(),\n})\n\nconst bindRuntimeIdentityArgsSchema = bindRuntimeIdentitySchema.superRefine((value, ctx) => {\n if (value.agent === 'custom' && (!value.process_pattern || value.process_pattern.trim().length === 0)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['process_pattern'],\n message: 'process_pattern is required when agent=custom',\n })\n }\n const hasPid = value.ui_pid !== undefined\n const hasTtyPair =\n value.ui_tty !== undefined &&\n value.ui_tty.trim().length > 0 &&\n value.tmux_pane_id !== undefined &&\n value.tmux_pane_id.trim().length > 0\n if (!hasPid && !hasTtyPair) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'provide ui_pid, or ui_tty together with tmux_pane_id',\n })\n }\n})\n\nconst SEND_MESSAGE_DESC = [\n 'Private 1→1 message to another agent by name. By default auto-poke=true with quiet-guard (auto_poke:false opts out), and need_reply=true.',\n 'Set need_reply:false for FYI/no-response-needed messages; recipients see need_reply in get_inbox.',\n 'to_agent_name is the target\\'s `name` within its team; this is the preferred addressing form. For UUID-based sends use send_message_by_id.',\n 'For multi-recipient use broadcast (same-team) or broadcast_to_role (same-team, by role).',\n '除非用户明确指定 to_team, 不要跨 team 沟通 (explicitly set to_team only when user asks).',\n 'Reports poked, poke_skip_reasons (no_pane, guard_failed, tmux_unavailable, self); on guard_failed daemon retries at 30s/180s/600s (retry_scheduled, retry_delays_s); stops early on poked.',\n 'Auto-poke injects only a SHORT wake-up hint (新邮件 from <sender>, 请调 get_inbox 查看), NOT the body — read bodies via get_inbox.',\n 'Delivery is NOT filtered by online/idle (unlike broadcast\\'s 5 min idle skip) — offline targets still receive the mailbox row.'\n].join(' ')\n\nconst SEND_MESSAGE_BY_ID_DESC = [\n 'Private 1→1 message to another agent by agent_id (UUID). Use this when you already hold the target\\'s agent_id; prefer send_message (by name) otherwise.',\n 'Same-team only: the recipient must belong to the caller\\'s team. For cross-team sends use send_message with to_team.',\n 'By default auto-poke=true with quiet-guard (auto_poke:false opts out), and need_reply=true. Set need_reply:false for FYI/no-response-needed messages.',\n 'Reports poked, poke_skip_reasons (no_pane, guard_failed, tmux_unavailable, self); on guard_failed daemon retries at 30s/180s/600s (retry_scheduled, retry_delays_s); stops early on poked.',\n 'Auto-poke injects only a SHORT wake-up hint (新邮件 from <sender>, 请调 get_inbox 查看), NOT the body — read bodies via get_inbox.',\n 'Delivery is NOT filtered by online/idle — offline targets still receive the mailbox row.'\n].join(' ')\n\nconst BROADCAST_DESC = [\n 'Same-team broadcast to every other agent in the caller team.',\n 'Auto-poke default true (quiet-guard + 30s/180s/600s retry; reports poked, poke_skip_reasons, retry_scheduled, retry_delays_s). auto_poke:false opts out.',\n 'For role filter use broadcast_to_role. For cross-team 1→1 use send_message({to_team}).',\n 'Auto-poke injects only a SHORT wake-up hint (新邮件 from <sender>, 请调 get_inbox 查看) — never the body. Read via get_inbox.',\n 'Skips agents idle > 5 min (offline).'\n].join(' ')\n\nconst BROADCAST_TO_ROLE_DESC = [\n 'Same-team broadcast filtered by role. Strictly same-team — no cross-team variant.',\n 'For cross-team private 1→1 use send_message({to_team}).',\n 'Auto-poke default true with quiet-guard + 30s/180s/600s retry (auto_poke:false opts out); injects only a SHORT wake-up hint, not the message body. Recipients read via get_inbox.',\n 'Returns unknown_recipient when no same-team agent matches to_role.'\n].join(' ')\n\nfunction suppressTmuxHint(\n args: { delivery?: { kind?: string } }\n): boolean {\n return args.delivery?.kind !== undefined && args.delivery.kind !== 'none'\n}\n\nfunction defaultClaudeSelfModel(\n clientInfo: SessionClientInfo | undefined\n): string {\n const raw = `${clientInfo?.name ?? ''} ${clientInfo?.version ?? ''}`.trim()\n if (/claude/i.test(raw)) return raw\n return 'claude-code'\n}\n\nexport function buildAutoPokeHint(\n row: { name?: string | null } | undefined,\n fromAgentId: string\n): string {\n const dn = row?.name\n const sender = typeof dn === 'string' && dn.length > 0\n ? `${dn} (${fromAgentId})`\n : fromAgentId.slice(0, 8)\n return `新邮件 from ${sender}, 请调 get_inbox 查看`\n}\n\nexport function createAutoPokeImpl(\n db: Database.Database,\n _agents: AgentsRepo,\n channelWakeFanout?: ChannelWakeFanout\n): import('./auto-poke-fanout.js').AutoPokeFn {\n return async (args) => {\n const row = db\n .prepare('SELECT name FROM agents WHERE agent_id=?')\n .get(args.fromAgentId) as { name: string | null } | undefined\n const hint = buildAutoPokeHint(row, args.fromAgentId)\n const res = await poke(\n { db, callerAgentId: args.fromAgentId, allowCrossTeam: true, channelWakeFanout },\n { target_agent_id: args.targetAgentId, prompt: hint }\n )\n if ('ok' in res && res.ok) return { ok: true }\n const err = (res as { error?: string }).error\n if (err === 'tmux_unavailable') return { ok: false, reason: 'tmux_unavailable' }\n if (err === 'tmux_pane_not_set') return { ok: false, reason: 'no_pane' }\n if (err === 'no_transport_available') return { ok: false, reason: 'no_pane' }\n if (err === 'self_poke_denied') return { ok: false, reason: 'self' }\n return { ok: false, reason: 'guard_failed' }\n }\n}\n\nexport interface RegisterSuccessHook {\n (agent_id: string, team: string): void\n}\n\nexport interface UnregisterSuccessHook {\n (agent_id: string): void\n}\n\nexport interface TransportLike {\n send(msg: Record<string, unknown>): Promise<void> | void\n}\n\nexport interface SessionClientInfo {\n name?: string\n version?: string\n}\n\nfunction inferRuntimeAgentKind(\n args: { client?: ClientKind; delivery?: { kind?: string }; model: string },\n clientInfo: SessionClientInfo | undefined\n): DetectAgentKind | undefined {\n if (args.client === 'custom') return undefined\n if (args.client) return args.client\n if (args.delivery?.kind === 'codex-appserver') return 'codex'\n\n const raw = `${clientInfo?.name ?? ''} ${clientInfo?.version ?? ''} ${args.model}`.toLowerCase()\n if (raw.includes('codex')) return 'codex'\n if (raw.includes('gpt-')) return 'codex'\n if (raw.includes('claude')) return 'claude-code'\n if (raw.includes('opus') || raw.includes('sonnet')) return 'claude-code'\n if (raw.includes('opencode')) return 'opencode'\n return undefined\n}\n\nexport function registerBusinessTools(\n server: McpServer,\n db: Database.Database,\n getCallerAgentId: () => string | undefined,\n fanout?: SseFanout,\n onRegisterSuccess?: RegisterSuccessHook,\n getSessionId?: () => string | undefined,\n channelWakeFanout?: ChannelWakeFanout,\n getTransport?: () => TransportLike,\n getSessionClientInfo?: () => SessionClientInfo | undefined,\n onUnregisterSuccess?: UnregisterSuccessHook\n): void {\n const agents = new AgentsRepo(db)\n const events = new EventsOutbox(db)\n const registerSvc = new RegisterAgentService(db)\n const bindRuntimeIdentitySvc = new BindRuntimeIdentityService(db)\n const registerCodexSelfSvc = new RegisterCodexSelfService(registerSvc)\n const unregisterSelfSvc = new UnregisterSelfService(db, agents)\n\n const autoPokeImpl = createAutoPokeImpl(db, agents, channelWakeFanout)\n\n const sendSvc = new SendMessageService(db, agents, events, { poke: autoPokeImpl })\n const broadcastSvc = new BroadcastService(db, agents, { poke: autoPokeImpl })\n const broadcastToRoleSvc = new BroadcastToRoleService(db, agents, events, { poke: autoPokeImpl })\n const inboxSvc = new GetInboxService(db, agents)\n const deliveryStatusSvc = new GetDeliveryStatusService(db)\n const taskAddSvc = new TaskAddService(db, agents, events)\n const taskClaimSvc = new TaskClaimService(db, agents, events)\n const taskCompleteSvc = new TaskCompleteService(db, agents, events)\n const taskListSvc = new TaskListService(db, agents)\n const regContractSvc = new RegisterContractService(db, agents, events)\n const subContractSvc = new SubscribeContractService(db, agents)\n const getContractSvc = new GetContractService(db, agents)\n const diffContractsSvc = new DiffContractsService(db, agents)\n const pendingEventsSvc = new PendingContractEventsService(db, agents)\n const codexPanePreRegRepo = new CodexPanePreRegRepo(db)\n const preRegisterCodexPaneSvc = new PreRegisterCodexPaneService(codexPanePreRegRepo)\n\n function caller(): string | undefined { return getCallerAgentId() }\n\n async function run(fn: () => unknown): Promise<TextContent> {\n const out = await wrapStorage(() => fn())\n touchIfRegistered()\n return toText(out)\n }\n\n function touchIfRegistered(): void {\n const c = caller()\n if (!c) return\n try {\n if (agents.findById(c)) agents.touch(c)\n } catch { /* best-effort */ }\n }\n\n function requireAgent(): string | { error: 'unknown_agent' } {\n const c = caller()\n if (!c) return { error: 'unknown_agent' }\n const row = agents.findById(c)\n if (!row) return { error: 'unknown_agent' }\n return c\n }\n\n async function autoBindRuntimeIdentity(\n args: {\n client?: ClientKind\n model: string\n delivery?: { kind?: string }\n ui_pid?: number\n },\n callerAgentId: string\n ): Promise<boolean> {\n const inferredAgent = inferRuntimeAgentKind(args, getSessionClientInfo?.())\n if (!inferredAgent) return false\n\n if (args.ui_pid !== undefined) {\n const boundByPid = await bindRuntimeIdentitySvc.bind({\n callerAgentId,\n agent: inferredAgent,\n ui_pid: args.ui_pid,\n })\n return 'ok' in boundByPid && boundByPid.ok\n }\n\n if (inferredAgent === 'codex') {\n const auto = await autoBindCodexPane({\n callerAgentId,\n repo: codexPanePreRegRepo,\n bindRuntimeIdentitySvc,\n })\n if (auto) return true\n }\n\n const detected = await detectTmuxPane({ agent: inferredAgent })\n if (!('ok' in detected) || !detected.ok) return false\n\n const bound = await bindRuntimeIdentitySvc.bind({\n callerAgentId,\n agent: inferredAgent,\n ui_tty: detected.pane.tty,\n tmux_pane_id: detected.pane.pane_id,\n })\n return 'ok' in bound && bound.ok\n }\n\n async function preflightUiPidClient(\n args: {\n client?: ClientKind\n model: string\n delivery?: { kind?: string }\n ui_pid?: number\n }\n ): Promise<\n | undefined\n | {\n error: 'ui_pid_client_mismatch'\n detail: string\n }\n > {\n if (args.ui_pid === undefined) return undefined\n const inferredAgent = inferRuntimeAgentKind(args, getSessionClientInfo?.())\n if (!inferredAgent) return undefined\n\n const validated = await bindRuntimeIdentity({\n agent: inferredAgent,\n ui_pid: args.ui_pid,\n })\n if (!('error' in validated) || validated.error !== 'agent_process_mismatch') {\n return undefined\n }\n\n return {\n error: 'ui_pid_client_mismatch',\n detail:\n `ui_pid ${args.ui_pid} does not belong to client=\\\"${inferredAgent}\\\". ` +\n 'Pass the runtime kind for the process behind ui_pid; for example, use client=\"opencode\" when ui_pid points at an opencode process.',\n }\n }\n\n const registerAgentInputSchema = z.object({\n model: z.string(),\n name: z.string().min(1).refine(v => v.trim().length > 0, { message: 'name must not be empty' }),\n role: z.string().optional(),\n team: z.string().optional(),\n project_dir: z.string().min(1).optional(),\n client: clientSchema,\n client_name: z.string().min(1).optional(),\n ui_pid: z.number().int().positive().optional().describe(\n 'STRONGLY RECOMMENDED. Visible agent UI process pid (e.g. Claude Code CLI pid — `$PPID` from a Bash tool call inside Claude Code). Enables one-shot pid → tty → pane binding at registration; without it, tmux-based cross-agent poke delivery typically stays off.'\n ),\n channel_session_id: z.string().min(1).optional(),\n thread_id: z.string().min(1).refine(v => v.trim().length > 0, { message: 'thread_id must not be empty' }).optional(),\n ws_url: z.string().optional(),\n auth_token_ref: z.string().min(1).optional(),\n claude_ui_pid: z.number().int().positive().optional().describe(\n \"Internal field for the cross-agent-teams-mcp channel proxy. Stores the proxy's parent Claude Code UI pid (`process.ppid`) so that Claude Code hosts registering in the same lineage can auto-bind their claude-channel delivery. Only valid when role='__channel_proxy__'; rejected otherwise.\"\n ),\n delivery: deliverySchema.optional(),\n }).strict()\n\n const registerAgentArgsSchema = registerAgentInputSchema.superRefine((value, ctx) => {\n const hasCodexFields =\n value.thread_id !== undefined ||\n value.ws_url !== undefined ||\n value.auth_token_ref !== undefined\n if (hasCodexFields && value.client !== 'codex') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['client'],\n message: 'client=codex is required when thread_id, ws_url, or auth_token_ref is provided',\n })\n }\n if (value.channel_session_id !== undefined && value.client !== 'claude-code') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['client'],\n message: 'client=claude-code is required when channel_session_id is provided',\n })\n }\n if (value.client_name !== undefined && value.client !== 'custom') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['client_name'],\n message: 'client_name is only allowed when client=custom',\n })\n }\n if (value.claude_ui_pid !== undefined && value.role !== '__channel_proxy__') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['claude_ui_pid'],\n message: \"claude_ui_pid is only allowed when role='__channel_proxy__'\",\n })\n }\n })\n\n const registerClaudeSelfInputSchema = z.object({\n name: z.string().min(1).refine(v => v.trim().length > 0, { message: 'name must not be empty' }),\n model: z.string().optional(),\n role: z.string().optional(),\n team: z.string().optional(),\n project_dir: z.string().min(1).optional(),\n ui_pid: z.number().int().positive().optional().describe(\n 'STRONGLY RECOMMENDED. The Claude Code CLI pid (obtainable as `$PPID` from a Bash tool call inside Claude Code). Enables one-shot pid → tty → pane binding at registration; without it, tmux-based cross-agent poke delivery typically stays off until a separate `bind_runtime_identity(...)` call.'\n ),\n channel_session_id: z.string().min(1).optional(),\n }).strict()\n\n const registerCodexSelfInputSchema = z.object({\n name: z.string().min(1).refine(v => v.trim().length > 0, { message: 'name must not be empty' }),\n model: z.string().optional(),\n role: z.string().optional(),\n team: z.string().optional(),\n project_dir: z.string().min(1).optional(),\n thread_id: z.string().min(1).refine(v => v.trim().length > 0, { message: 'thread_id must not be empty' }).optional(),\n ws_url: z.string().min(1).optional(),\n auth_token_ref: z.string().min(1).optional(),\n }).strict()\n\n async function executeRegister(\n args: {\n client?: ClientKind\n client_name?: string\n model: string\n name: string\n role?: string\n team?: string\n project_dir?: string\n ui_pid?: number\n channel_session_id?: string\n thread_id?: string\n ws_url?: string\n auth_token_ref?: string\n claude_ui_pid?: number\n delivery?: { kind: string; [key: string]: unknown }\n }\n ): Promise<unknown> {\n let nativeDeliveryBound = suppressTmuxHint(args)\n let autoBoundChannelCsid: string | undefined\n const bindChannelSvc = channelWakeFanout\n ? new BindChannelService(db, channelWakeFanout)\n : undefined\n const autoBindChannelSvc = channelWakeFanout\n ? new AutoBindChannelService(db, channelWakeFanout)\n : undefined\n const connectionId = getSessionId?.() ?? caller()\n if (!connectionId) return { error: 'unknown_agent' }\n const uiPidClientError = await preflightUiPidClient(args)\n if (uiPidClientError) return uiPidClientError\n if (\n args.client === 'claude-code' &&\n args.channel_session_id !== undefined &&\n args.ui_pid !== undefined &&\n autoBindChannelSvc\n ) {\n const proxyLookup = autoBindChannelSvc.lookup({\n ui_pid: args.ui_pid,\n })\n if (\n proxyLookup.ok &&\n proxyLookup.channel_session_id !== args.channel_session_id\n ) {\n return {\n error: 'channel_session_id_ui_pid_mismatch',\n detail: {\n ui_pid_matched_csid: proxyLookup.channel_session_id,\n supplied_csid: args.channel_session_id,\n },\n }\n }\n }\n const hasCodexTransportFields =\n args.thread_id !== undefined ||\n args.ws_url !== undefined ||\n args.auth_token_ref !== undefined\n const res =\n args.client === 'codex' &&\n args.delivery === undefined &&\n hasCodexTransportFields\n ? await registerCodexSelfSvc.register({\n connection_id: connectionId,\n name: args.name,\n model: args.model,\n role: args.role,\n team: args.team,\n project_dir: args.project_dir,\n thread_id: args.thread_id,\n ws_url: args.ws_url,\n auth_token_ref: args.auth_token_ref,\n })\n : registerSvc.register({\n connection_id: connectionId,\n client: args.client,\n client_name: args.client_name,\n model: args.model,\n name: args.name,\n role: args.role,\n team: args.team,\n project_dir: args.project_dir,\n delivery: args.delivery,\n claude_ui_pid: args.claude_ui_pid,\n runtime_ui_pid:\n args.client === 'claude-code' ? args.ui_pid : undefined,\n })\n if ('thread_id' in res && 'agent_id' in res) {\n nativeDeliveryBound = true\n }\n if ('agent_id' in res) {\n if (onRegisterSuccess) {\n try { onRegisterSuccess(res.agent_id, res.team) } catch { /* best-effort */ }\n } else if (fanout) {\n try { fanout.rebind(res.agent_id, res.team) } catch { /* best-effort */ }\n }\n if (args.client === 'claude-code' && args.channel_session_id !== undefined) {\n const channelBind = bindChannelSvc\n ? bindChannelSvc.bind({\n callerAgentId: res.agent_id,\n channel_session_id: args.channel_session_id,\n })\n : { error: 'unknown_channel_session' as const }\n if ('ok' in channelBind && channelBind.ok) {\n nativeDeliveryBound = true\n } else {\n return channelBind\n }\n }\n if (\n args.client === 'claude-code' &&\n args.channel_session_id === undefined &&\n args.ui_pid !== undefined &&\n autoBindChannelSvc\n ) {\n const autoBind = autoBindChannelSvc.run({\n callerAgentId: res.agent_id,\n ui_pid: args.ui_pid,\n })\n if (autoBind.ok) {\n autoBoundChannelCsid = autoBind.channel_session_id\n nativeDeliveryBound = true\n }\n }\n const autoBound = await autoBindRuntimeIdentity(args, res.agent_id)\n const envelope = autoBoundChannelCsid !== undefined\n ? { ...res, channel_session_id: autoBoundChannelCsid }\n : res\n if (autoBound) return envelope\n if (!nativeDeliveryBound) {\n return {\n ...envelope,\n hint: \"No usable tmux_pane_id is bound yet — automatic runtime binding did not converge for this session, so cross-agent poke delivery via tmux is still off. Call `bind_runtime_identity(...)` to bind explicitly, or use `detect_tmux_pane(...)` for debugging. Claude Code users who loaded the cross-agent-teams-mcp channel plugin can also route pokes via channel_session_id — that path does not require tmux binding.\"\n }\n }\n return envelope\n }\n return res\n }\n\n function releaseRegisteredState(agentId: string): void {\n const connectionId = getSessionId?.()\n if (connectionId) registerSvc.releaseConnection(agentId, connectionId)\n if (onUnregisterSuccess) {\n try { onUnregisterSuccess(agentId) } catch { /* best-effort */ }\n return\n }\n if (fanout) {\n try { fanout.detach(agentId) } catch { /* best-effort */ }\n }\n }\n\n // pre_register_codex_pane — callable by launchers before any agent row exists\n server.registerTool(\n 'pre_register_codex_pane',\n {\n title: 'Pre-register codex tmux pane',\n description: [\n 'Pre-register a pending tmux-pane claim so the launcher can claim a tmux pane before starting codex.',\n 'The launcher should call this with `$TMUX_PANE` and a freshly generated UUID, then `exec codex --remote ... -c xats.agent_id=\"\\\\\"<uuid>\\\\\"\"`.',\n 'When the codex agent later calls `register_agent({client:\"codex\"})` without `ui_pid`, the daemon uses the pending row to resolve the correct UI pid and auto-bind the pane.',\n 'Callable without a prior `register_agent` — launchers have no agent identity yet.',\n 'TTL defaults to 120 seconds and is capped at 600; pending rows are garbage-collected opportunistically.',\n ].join(' '),\n inputSchema: preRegisterCodexPaneInputSchema,\n },\n async (args: unknown) => run(async () => preRegisterCodexPaneSvc.register(args))\n )\n\n // register_agent — bootstrap: callable before an agents row exists for this session\n server.registerTool(\n 'detect_tmux_pane',\n {\n title: 'Detect tmux pane',\n description: [\n 'Detect the tmux pane that is actually hosting a coding agent UI, even when the shell calling tools lives in a different pane.',\n 'The detector scans tmux panes globally, maps each pane to its tty, then inspects real tty processes instead of trusting `$TMUX_PANE` or tmux focus state alone.',\n 'Use `agent` to pick a built-in matcher for Codex, Claude Code, or opencode.',\n 'Optional `cwd`, `tty`, and `title_contains` narrow the search and make cross-directory multi-agent sessions much more reliable.',\n 'Returns either a single best pane, or an ambiguity/not-found result with candidates for debugging.'\n ].join(' '),\n inputSchema: detectTmuxPaneSchema,\n },\n async (args: {\n agent: 'codex' | 'claude-code' | 'opencode' | 'custom'\n cwd?: string\n tty?: string\n title_contains?: string\n process_pattern?: string\n }) => run(async () => {\n const parsed = detectTmuxPaneArgsSchema.safeParse(args)\n if (!parsed.success) {\n return {\n error: 'invalid_arguments' as const,\n detail: parsed.error.issues.map(issue => issue.message).join('; '),\n }\n }\n return detectTmuxPane({\n agent: parsed.data.agent,\n cwd: parsed.data.cwd,\n tty: parsed.data.tty,\n title_contains: parsed.data.title_contains,\n process_pattern: parsed.data.process_pattern,\n })\n })\n )\n\n server.registerTool(\n 'register_agent',\n {\n title: 'Register agent',\n description: [\n 'Register this session as an agent in a team.',\n 'This is the unified registration entry point.',\n 'Calling this tool again with the same `(team, name, role)` identity reuses the existing',\n '`agent_id` and refreshes `tmux_pane_id` and `model`; no duplicate row is created.',\n 'Callers MUST pass `client` explicitly.',\n 'Use `client=\"custom\"` for unsupported agent harnesses; optionally provide `client_name` for observability.',\n 'Claude Code sessions can pass `client=\"claude-code\"` together with `channel_session_id` to bind channel delivery through this same tool. PREFERRED: pass only `ui_pid` (from `$PPID`) and let the daemon auto-bind channel delivery — do not pass `channel_session_id` explicitly on register. When BOTH `ui_pid` AND `channel_session_id` are supplied, the daemon runs a consistency check against the caller `ui_pid`\\'s live channel proxy; if the proxy\\'s csid does not match the supplied `channel_session_id`, the call is rejected with `channel_session_id_ui_pid_mismatch` before any agent row is written. Use `bind_channel` for low-level rebind after registration instead of supplying csid here.',\n 'Codex sessions can pass `client=\"codex\"` together with `thread_id` to register Codex app-server delivery through this same tool.',\n 'Codex clients SHOULD prefer `register_codex_self` instead — it is the codex-specific convenience entry point. Do NOT pass `ui_pid` from codex agents: the launcher\\'s `pre_register_codex_pane` pre-reg flow handles tmux pane binding, and supplying `ui_pid` from codex disables that auto-bind path.',\n 'Requests such as \"register to xats\" or \"register to cross-agent-teams\" refer to this MCP service, not to the `team` field; do not set `team` to `xats` or `cross-agent-teams` from those phrases.',\n 'Do not treat the bare word \"register\" as a request for this tool unless the current conversation is already about cross-agent-teams registration.',\n 'When the end user has not explicitly specified `team`, callers should pass `project_dir` as the current working directory so the daemon derives a project-scoped default team from its basename; if omitted, it falls back to `default`.',\n '`client` must describe the runtime behind `ui_pid`, not merely the current MCP caller. For example, if `ui_pid` points at an opencode process, pass `client=\"opencode\"` even when the registration request is issued from Claude Code.',\n 'STRONGLY RECOMMENDED: pass `ui_pid` unless it is truly unobtainable. Without it, automatic runtime binding usually fails to converge and tmux-based cross-agent poke delivery stays off until a separate `bind_runtime_identity(...)` call. From Claude Code, `$PPID` inside a Bash tool call is the `claude` CLI pid; for Codex/opencode/other harnesses, discover the UI pid from the host harness. With `ui_pid` the daemon binds via verified pid → tty → pane evidence in one shot.',\n 'After registration, the daemon best-effort attempts runtime binding for recognized local clients so tmux-based poke delivery can come up without a second tool call.',\n 'If automatic runtime binding does not converge, call `bind_runtime_identity(...)` explicitly so the daemon can verify and persist your pane binding.',\n '`detect_tmux_pane(...)` remains available as a debugging aid for ambiguous or missing matches, but it does not write registry state by itself.',\n 'When registration still has no usable `tmux_pane_id`, tmux-based poke delivery stays unavailable until automatic or explicit runtime binding succeeds.'\n ].join(' '),\n inputSchema: registerAgentInputSchema\n },\n async (args: {\n client: ClientKind\n client_name?: string\n model: string; name: string; role?: string; team?: string;\n project_dir?: string;\n ui_pid?: number;\n channel_session_id?: string\n thread_id?: string\n ws_url?: string\n auth_token_ref?: string\n claude_ui_pid?: number\n delivery?: { kind: string; [key: string]: unknown }\n }) => {\n return run(async () => executeRegister(registerAgentArgsSchema.parse(args)))\n }\n )\n\n server.registerTool(\n 'register_claude_self',\n {\n title: 'Register Claude Code session',\n description: [\n 'Register the current Claude Code MCP session as an agent.',\n 'Prefer this helper inside Claude Code when you want to avoid session-mismatch issues caused by external HTTP or curl registration.',\n 'This tool always writes on the caller\\'s current MCP session, so follow-up tools like get_inbox use the same identity immediately.',\n 'AUTO-BIND: when `ui_pid` is supplied AND `channel_session_id` is omitted, the daemon best-effort looks up a live `__channel_proxy__` row whose `claude_ui_pid` matches the caller `ui_pid` and auto-binds `delivery.kind=\\\"claude-channel\\\"` to the proxy\\'s current csid. On success the response includes `channel_session_id`. No match → delivery stays `none` (no error surfaced). This makes `ui_pid` sufficient for channel delivery — the LLM does not need to read or pass csid explicitly.',\n 'If `channel_session_id` is supplied explicitly, the explicit value wins and auto-bind is skipped (identical semantics to `bind_channel`).',\n 'When BOTH `ui_pid` AND `channel_session_id` are supplied, the daemon runs a consistency check: it looks up the live `__channel_proxy__` row matching the caller `ui_pid` and team, and if that proxy\\'s persisted csid differs from the supplied `channel_session_id`, the call is rejected with `channel_session_id_ui_pid_mismatch` BEFORE any agent row is written. Prefer ui_pid-only registration (no `channel_session_id`) to avoid this class of stale-csid drift.',\n 'Requests such as \"register to xats\" or \"register to cross-agent-teams\" refer to this MCP service, not to the `team` field; do not set `team` to `xats` or `cross-agent-teams` from those phrases.',\n 'Do not treat the bare word \"register\" as a request for this tool unless the current conversation is already about cross-agent-teams registration.',\n 'When the end user has not explicitly specified `team`, callers should pass `project_dir` as the current working directory so the daemon derives a project-scoped default team from its basename; if omitted, it falls back to `default`.',\n 'STRONGLY RECOMMENDED: pass `ui_pid` (the Claude Code CLI pid — obtainable as `$PPID` from a Bash tool call). Without it, both channel auto-bind AND automatic tmux runtime binding stay off until a separate `bind_runtime_identity(...)` call. With `ui_pid` the daemon can auto-bind the channel delivery AND verify pid → tty → pane evidence in one shot.',\n 'model is optional here; when omitted it falls back to a Claude-specific default.'\n ].join(' '),\n inputSchema: registerClaudeSelfInputSchema\n },\n async (args: {\n name: string\n model?: string\n role?: string\n team?: string\n project_dir?: string\n ui_pid?: number\n channel_session_id?: string\n }) => run(async () => executeRegister({\n client: 'claude-code',\n name: args.name,\n model: args.model ?? defaultClaudeSelfModel(getSessionClientInfo?.()),\n role: args.role,\n team: args.team,\n project_dir: args.project_dir,\n ui_pid: args.ui_pid,\n channel_session_id: args.channel_session_id,\n }))\n )\n\n server.registerTool(\n 'register_codex_self',\n {\n title: 'Register codex MCP session',\n description: [\n 'Register the current codex MCP session as an agent bound to `codex-appserver` delivery.',\n 'Prefer this helper inside codex over the generic `register_agent` — it locks `client=\"codex\"` and keeps the input surface minimal.',\n 'THREAD_ID: read `$CODEX_THREAD_ID` from your tool shell environment (codex 0.124.0+ exports it for every MCP tool subprocess) and pass its value as `thread_id`. When `thread_id` is omitted, the daemon returns the existing `thread_id_required` envelope listing resumable thread_ids as a candidate fallback.',\n 'DO NOT pass `ui_pid`: this tool\\'s schema rejects it outright. UI pid discovery and tmux pane binding are handled automatically by the launcher\\'s `pre_register_codex_pane` pre-reg flow — passing `ui_pid` would silently disable that auto-bind path.',\n 'The daemon connects to `ws_url` (default `ws://127.0.0.1:8799`, env override `CROSS_AGENT_TEAMS_CODEX_WS_URL`), runs the codex `initialize` + `thread/resume` handshake, and writes `delivery.kind=\"codex-appserver\"`.',\n 'Requests such as \"register to xats\" or \"register to cross-agent-teams\" refer to this MCP service, not to the `team` field; do not set `team` to `xats` or `cross-agent-teams` from those phrases.',\n 'When the end user has not explicitly specified `team`, callers should pass `project_dir` as the current working directory so the daemon derives a project-scoped default team from its basename; if omitted, it falls back to `default`.',\n 'model is optional here; when omitted it falls back to `gpt`.',\n ].join(' '),\n inputSchema: registerCodexSelfInputSchema,\n },\n async (args: {\n name: string\n model?: string\n role?: string\n team?: string\n project_dir?: string\n thread_id?: string\n ws_url?: string\n auth_token_ref?: string\n }) => run(async () => executeRegister({\n client: 'codex',\n name: args.name,\n model: args.model ?? 'gpt',\n role: args.role,\n team: args.team,\n project_dir: args.project_dir,\n thread_id: args.thread_id,\n // Ensure the codex-appserver path is always taken even when thread_id is\n // omitted: callers of register_codex_self expect the thread_id_required\n // candidate-list fallback, not a plain delivery=none registration.\n // RegisterCodexSelfService resolves the empty string to env/default ws_url.\n ws_url: args.ws_url ?? '',\n auth_token_ref: args.auth_token_ref,\n }))\n )\n\n server.registerTool(\n 'unregister_self',\n {\n title: 'Unregister current agent',\n description: [\n 'Remove the caller session\\'s current agent registration.',\n 'This tool only unregisters the currently bound agent identity; it does not delete other agents.',\n 'If the caller still owns any in-progress task, it returns `tasks_in_progress` and leaves all state unchanged.',\n 'On success it deletes the agent row, removes the caller\\'s contract subscriptions, and immediately releases the current MCP session back to an unregistered state.'\n ].join(' '),\n inputSchema: z.object({}).strict()\n },\n async () => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n const result = await wrapStorage(() => unregisterSelfSvc.unregister({ caller: who }))\n if (\n typeof result === 'object' &&\n result !== null &&\n 'ok' in result &&\n result.ok === true &&\n 'agent_id' in result &&\n typeof result.agent_id === 'string'\n ) {\n releaseRegisteredState(result.agent_id)\n return toText(result)\n }\n touchIfRegistered()\n return toText(result)\n }\n )\n\n // list_agents\n server.registerTool(\n 'list_agents',\n {\n title: 'List agents',\n description: 'List agents in the caller\\'s team',\n inputSchema: {}\n },\n async () => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n const row = agents.findById(who)!\n return run(() => ({\n agents: agents.list({ team: row.team }).map(toPublicAgentRow),\n }))\n }\n )\n\n // send_message (by name)\n server.registerTool(\n 'send_message',\n {\n title: 'Send message',\n description: SEND_MESSAGE_DESC,\n inputSchema: z.object({\n to_agent_name: z.string().min(1),\n to_team: z.string().min(1).optional(),\n subject: z.string().optional(),\n body: z.string().min(1),\n auto_poke: z.boolean().optional(),\n need_reply: z.boolean().optional()\n }).strict()\n },\n async (args: {\n to_agent_name: string\n to_team?: string\n subject?: string\n body: string\n auto_poke?: boolean\n need_reply?: boolean\n }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => sendSvc.send({ from: who, ...args }))\n }\n )\n\n // send_message_by_id (by UUID)\n server.registerTool(\n 'send_message_by_id',\n {\n title: 'Send message by id',\n description: SEND_MESSAGE_BY_ID_DESC,\n inputSchema: z.object({\n to_agent_id: z.string().min(1),\n subject: z.string().optional(),\n body: z.string().min(1),\n auto_poke: z.boolean().optional(),\n need_reply: z.boolean().optional()\n }).strict()\n },\n async (args: {\n to_agent_id: string\n subject?: string\n body: string\n auto_poke?: boolean\n need_reply?: boolean\n }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => sendSvc.send({ from: who, ...args }))\n }\n )\n\n // broadcast\n server.registerTool(\n 'broadcast',\n {\n title: 'Broadcast message',\n description: BROADCAST_DESC,\n inputSchema: {\n subject: z.string().optional(),\n body: z.string(),\n auto_poke: z.boolean().optional()\n }\n },\n async (args: { subject?: string; body: string; auto_poke?: boolean }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => broadcastSvc.broadcast({ from: who, ...args }))\n }\n )\n\n // broadcast_to_role\n server.registerTool(\n 'broadcast_to_role',\n {\n title: 'Broadcast to role',\n description: BROADCAST_TO_ROLE_DESC,\n inputSchema: z.object({\n to_role: z.string().min(1),\n subject: z.string().optional(),\n body: z.string().min(1),\n auto_poke: z.boolean().optional()\n }).strict()\n },\n async (args: { to_role: string; subject?: string; body: string; auto_poke?: boolean }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => broadcastToRoleSvc.broadcast({ from: who, ...args }))\n }\n )\n\n // get_inbox\n server.registerTool(\n 'get_inbox',\n {\n title: 'Get inbox',\n description: 'Return messages addressed to caller after since_event_id',\n inputSchema: {\n since_event_id: z.number().int().optional(),\n limit: z.number().int().optional()\n }\n },\n async (args: { since_event_id?: number; limit?: number }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => inboxSvc.get({ caller: who, ...args }))\n }\n )\n\n // get_delivery_status\n server.registerTool(\n 'get_delivery_status',\n {\n title: 'Get delivery status',\n description: [\n 'Return wake-hint delivery status for a message sent by caller.',\n 'Status describes auto-poke delivery only; mailbox persistence is already complete.',\n 'Only the original sender can read a message delivery status.'\n ].join(' '),\n inputSchema: {\n message_id: z.string()\n }\n },\n async (args: { message_id: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => deliveryStatusSvc.get({ caller: who, ...args }))\n }\n )\n\n // task_add\n server.registerTool(\n 'task_add',\n {\n title: 'Add task',\n description: [\n \"Add a new task to the team's task list. Any team member can claim it via `task_claim`\",\n 'on their next turn. The task will sit in the pending queue until someone pulls `task_list`.',\n '`task_add` itself does not wake or target any specific agent; use normal mailbox messaging',\n 'when coordination is needed, then inspect that message with `get_delivery_status`.'\n ].join(' '),\n inputSchema: {\n title: z.string(),\n description: z.string().optional(),\n depends_on: z.array(z.string()).optional()\n }\n },\n async (args: { title: string; description?: string; depends_on?: string[] }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => taskAddSvc.add({ caller: who, ...args }))\n }\n )\n\n // task_claim\n server.registerTool(\n 'task_claim',\n {\n title: 'Claim task',\n description: 'Claim a pending task as caller',\n inputSchema: { task_id: z.string() }\n },\n async (args: { task_id: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => taskClaimSvc.claim({ caller: who, task_id: args.task_id }))\n }\n )\n\n // task_complete\n server.registerTool(\n 'task_complete',\n {\n title: 'Complete task',\n description: 'Mark the caller\\'s in-progress task as completed',\n inputSchema: {\n task_id: z.string(),\n result: z.string().optional()\n }\n },\n async (args: { task_id: string; result?: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => taskCompleteSvc.complete({ caller: who, ...args }))\n }\n )\n\n // task_list\n server.registerTool(\n 'task_list',\n {\n title: 'List tasks',\n description: 'List tasks in the caller\\'s team, optionally filtered by status',\n inputSchema: {\n status: z.enum(['pending', 'in_progress', 'completed']).optional()\n }\n },\n async (args: { status?: 'pending' | 'in_progress' | 'completed' }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => taskListSvc.list({ caller: who, status: args.status }))\n }\n )\n\n // register_contract\n server.registerTool(\n 'register_contract',\n {\n title: 'Register contract',\n description: 'Register or upgrade a contract version',\n inputSchema: {\n name: z.string(),\n schema: z.record(z.unknown()),\n format: z.literal('jsonschema').optional(),\n note: z.string().optional()\n }\n },\n async (args: { name: string; schema: Record<string, unknown>; format?: 'jsonschema'; note?: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => {\n const res = regContractSvc.register({ caller: who, ...args })\n if ('version' in res && res._meta && fanout) {\n try {\n fanout.emitContractEvent(db, {\n to_team: res._meta.team,\n contract_name: res.name,\n version: res.version,\n event_id: res._meta.event_id,\n diff: res._meta.diff\n })\n } catch { /* push failure does not roll back event */ }\n }\n if ('version' in res) {\n const { _meta: _omit, ...publicRes } = res\n return publicRes\n }\n return res\n })\n }\n )\n\n // subscribe_contract\n server.registerTool(\n 'subscribe_contract',\n {\n title: 'Subscribe contract',\n description: 'Subscribe the caller to a contract name\\'s updates',\n inputSchema: { name: z.string() }\n },\n async (args: { name: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => subContractSvc.subscribe({ caller: who, name: args.name }))\n }\n )\n\n // get_contract\n server.registerTool(\n 'get_contract',\n {\n title: 'Get contract',\n description: 'Fetch a contract version (latest by default)',\n inputSchema: {\n name: z.string(),\n version: z.number().int().optional()\n }\n },\n async (args: { name: string; version?: number }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => getContractSvc.get({ caller: who, ...args }))\n }\n )\n\n // diff_contracts\n server.registerTool(\n 'diff_contracts',\n {\n title: 'Diff contracts',\n description: 'Compute diff between two versions of a contract',\n inputSchema: {\n name: z.string(),\n from_version: z.number().int(),\n to_version: z.number().int()\n }\n },\n async (args: { name: string; from_version: number; to_version: number }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => diffContractsSvc.diff({ caller: who, ...args }))\n }\n )\n\n // bind_channel — self-binding: caller (Claude host) writes its own channel_session_id\n if (channelWakeFanout) {\n const bindSvc = new BindChannelService(db, channelWakeFanout)\n server.registerTool(\n 'bind_channel',\n {\n title: 'Bind channel_session_id to caller',\n description: [\n 'Low-level rebind tool for Claude channel delivery.',\n 'Bind the caller session\\'s agent row to a channel_session_id produced by the cross-agent-teams-mcp channel proxy.',\n 'Most callers should prefer `register_agent({ client: \"claude-code\", channel_session_id, ... })` on the unified registration path.',\n 'Call this when you need to rebind an already-registered row after the proxy announces a new csid.',\n 'Rejects proxy callers (role=__channel_proxy__).',\n 'Rejects unknown csid (no live proxy sink attached).'\n ].join(' '),\n inputSchema: {\n channel_session_id: z.string().min(1)\n }\n },\n async (args: { channel_session_id: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => bindSvc.bind({\n callerAgentId: who,\n channel_session_id: args.channel_session_id\n }))\n }\n )\n }\n\n server.registerTool(\n 'bind_runtime_identity',\n {\n title: 'Bind runtime identity to caller',\n description: [\n 'Bind the caller session\\'s agent row to a verified tmux runtime identity.',\n 'Pass `agent` to choose the built-in process matcher (`codex`, `claude-code`, `opencode`), or use `custom` together with `process_pattern`.',\n 'Prefer passing `ui_pid` for the visible agent UI process; the daemon verifies pid → tty → pane before persisting `tmux_pane_id`.',\n 'If `ui_pid` is unavailable, pass `ui_tty` together with `tmux_pane_id` for a weaker but still verified binding path.',\n 'This tool writes registry state; `detect_tmux_pane` is for debugging only.'\n ].join(' '),\n inputSchema: bindRuntimeIdentitySchema,\n },\n async (args: {\n agent: 'codex' | 'claude-code' | 'opencode' | 'custom'\n ui_pid?: number\n ui_tty?: string\n tmux_pane_id?: string\n process_pattern?: string\n }) => {\n const parsed = bindRuntimeIdentityArgsSchema.safeParse(args)\n if (!parsed.success) {\n return toText({\n error: 'invalid_arguments',\n detail: parsed.error.issues.map(issue => issue.message).join('; '),\n })\n }\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => bindRuntimeIdentitySvc.bind({\n callerAgentId: who,\n agent: parsed.data.agent,\n ui_pid: parsed.data.ui_pid,\n ui_tty: parsed.data.ui_tty,\n tmux_pane_id: parsed.data.tmux_pane_id,\n process_pattern: parsed.data.process_pattern,\n }))\n }\n )\n\n // subscribe_channel_wake — reserved for channel proxies (role=__channel_proxy__)\n if (channelWakeFanout) {\n const subscribeSvc = new SubscribeChannelWakeService(db, channelWakeFanout)\n server.registerTool(\n 'subscribe_channel_wake',\n {\n title: 'Subscribe channel wake',\n description: [\n 'Internal tool reserved for the cross-agent-teams-mcp channel proxy.',\n 'Attaches the caller\\'s MCP session notification sink to a channel_session_id so the',\n 'daemon can emit notifications/channel_wake to it. Requires role=__channel_proxy__.'\n ].join(' '),\n inputSchema: { channel_session_id: z.string().min(1) }\n },\n async (args: { channel_session_id: string }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n const sid = getSessionId?.()\n if (!sid) return toText({ error: 'unknown_session' })\n const sink = (payload: unknown) => {\n const t = getTransport?.()\n if (!t) return\n try {\n void Promise.resolve(t.send(payload as Record<string, unknown>)).catch(() => { /* best-effort */ })\n } catch { /* best-effort */ }\n }\n return run(() => subscribeSvc.subscribe({\n callerAgentId: who,\n channel_session_id: args.channel_session_id,\n sessionId: sid,\n sink\n }))\n }\n )\n }\n\n // pending_contract_events\n server.registerTool(\n 'pending_contract_events',\n {\n title: 'Pending contract events',\n description: 'Poll contract_registered events not yet seen',\n inputSchema: {\n since_event_id: z.number().int().optional(),\n limit: z.number().int().optional()\n }\n },\n async (args: { since_event_id?: number; limit?: number }) => {\n const who = requireAgent()\n if (typeof who !== 'string') return toText(who)\n return run(() => pendingEventsSvc.poll({ caller: who, ...args }))\n }\n )\n}\n","import type Database from 'better-sqlite3'\nimport { randomUUID } from 'node:crypto'\nimport {\n parseDeliveryRow,\n serializeDelivery,\n type DeliverySpec,\n type DeliveryRow,\n} from '../lib/delivery-spec.js'\nimport type { ClientKind } from '../lib/client-kind.js'\n\nexport interface RegisterInput {\n client?: ClientKind\n client_name?: string\n model: string\n name: string\n role?: string\n team?: string\n tmux_pane_id?: string\n delivery?: DeliverySpec\n claude_ui_pid?: number\n runtime_ui_pid?: number\n}\n\nexport interface AgentRow {\n agent_id: string\n client: ClientKind | null\n client_name: string | null\n team: string\n role: string\n name: string\n model: string | null\n tmux_pane_id: string | null\n delivery: DeliverySpec\n channel_session_id: string | null\n last_seen_at: string\n}\n\nexport interface AgentListRow extends AgentRow {\n online: boolean\n}\n\nexport const ONLINE_MS = 5 * 60 * 1000\n\ntype DbAgentRow = {\n agent_id: string\n client: ClientKind | null\n client_name: string | null\n team: string\n role: string\n name: string\n model: string | null\n tmux_pane_id: string | null\n last_seen_at: string\n} & DeliveryRow\n\nfunction toAgentRow(row: DbAgentRow): AgentRow {\n const delivery = parseDeliveryRow(row)\n return {\n agent_id: row.agent_id,\n client: row.client,\n client_name: row.client_name,\n team: row.team,\n role: row.role,\n name: row.name,\n model: row.model,\n tmux_pane_id: row.tmux_pane_id,\n delivery,\n channel_session_id:\n delivery.kind === 'claude-channel' ? delivery.channel_session_id : null,\n last_seen_at: row.last_seen_at,\n }\n}\n\nexport class AgentsRepo {\n constructor(private db: Database.Database) {}\n\n findByIdentity(args: { team: string; name: string }): { agent_id: string } | undefined {\n return this.db.prepare(\n `SELECT agent_id FROM agents WHERE team=? AND name=?`\n ).get(args.team, args.name) as { agent_id: string } | undefined\n }\n\n register(input: RegisterInput): {\n agent_id: string\n team: string\n } {\n const team = input.team ?? 'default'\n const role = input.role ?? 'default'\n const name = input.name\n const now = new Date().toISOString()\n const newId = randomUUID()\n const delivery = input.delivery ?? { kind: 'none' }\n const serialized = serializeDelivery(delivery)\n const preserveExistingDelivery = input.delivery === undefined ? 1 : 0\n const tx = this.db.transaction(() => {\n this.writeAgentRow({\n newId,\n input,\n team,\n role,\n name,\n now,\n serialized,\n preserveExistingDelivery,\n })\n const rebindCsid =\n role === '__channel_proxy__' &&\n input.claude_ui_pid !== undefined &&\n delivery.kind === 'claude-channel'\n ? delivery.channel_session_id\n : undefined\n if (rebindCsid !== undefined) {\n this.reactiveRebindHosts({\n team,\n claude_ui_pid: input.claude_ui_pid!,\n new_csid: rebindCsid,\n })\n }\n })\n tx()\n const row = this.db.prepare(`SELECT agent_id FROM agents WHERE team=? AND name=?`).get(team, name) as { agent_id: string }\n return { agent_id: row.agent_id, team }\n }\n\n private writeAgentRow(args: {\n newId: string\n input: RegisterInput\n team: string\n role: string\n name: string\n now: string\n serialized: ReturnType<typeof serializeDelivery>\n preserveExistingDelivery: number\n }): void {\n const { newId, input, team, role, name, now, serialized, preserveExistingDelivery } = args\n this.db.prepare(\n `INSERT INTO agents (\n agent_id, client, client_name, team, role, name, model, registered_at, last_seen_at,\n tmux_pane_id, claude_ui_pid, runtime_ui_pid, delivery_kind, delivery_payload\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (team, name) DO UPDATE SET\n client = excluded.client,\n client_name = excluded.client_name,\n role = excluded.role,\n model = excluded.model,\n last_seen_at = excluded.last_seen_at,\n tmux_pane_id = COALESCE(excluded.tmux_pane_id, tmux_pane_id),\n claude_ui_pid = COALESCE(excluded.claude_ui_pid, claude_ui_pid),\n runtime_ui_pid = COALESCE(excluded.runtime_ui_pid, runtime_ui_pid),\n delivery_kind = CASE\n WHEN ? THEN delivery_kind\n ELSE excluded.delivery_kind\n END,\n delivery_payload = CASE\n WHEN ? THEN delivery_payload\n ELSE excluded.delivery_payload\n END`\n ).run(\n newId,\n input.client ?? null,\n input.client_name ?? null,\n team,\n role,\n name,\n input.model,\n now,\n now,\n input.tmux_pane_id ?? null,\n input.claude_ui_pid ?? null,\n input.runtime_ui_pid ?? null,\n serialized.delivery_kind,\n serialized.delivery_payload,\n preserveExistingDelivery,\n preserveExistingDelivery,\n )\n }\n\n private reactiveRebindHosts(args: {\n team: string\n claude_ui_pid: number\n new_csid: string\n }): void {\n this.db.prepare(\n `UPDATE agents\n SET delivery_kind = 'claude-channel',\n delivery_payload = json_object('channel_session_id', ?)\n WHERE role != '__channel_proxy__'\n AND runtime_ui_pid IS NOT NULL\n AND runtime_ui_pid = ?\n AND team = ?\n AND (\n delivery_kind = 'none'\n OR (delivery_kind = 'claude-channel'\n AND json_extract(delivery_payload,'$.channel_session_id') != ?)\n )`\n ).run(args.new_csid, args.claude_ui_pid, args.team, args.new_csid)\n }\n\n setDelivery(agent_id: string, spec: DeliverySpec): void {\n const serialized = serializeDelivery(spec)\n this.db.prepare(\n `UPDATE agents\n SET delivery_kind=?, delivery_payload=?\n WHERE agent_id=?`\n ).run(serialized.delivery_kind, serialized.delivery_payload, agent_id)\n }\n\n setClient(agent_id: string, client: ClientKind, client_name?: string | null): void {\n this.db.prepare(\n `UPDATE agents\n SET client=?,\n client_name=?\n WHERE agent_id=?`\n ).run(client, client_name ?? null, agent_id)\n }\n\n setRuntimeBinding(\n agent_id: string,\n args: {\n tmux_pane_id: string\n runtime_ui_pid: number | null\n runtime_tty: string\n runtime_verification_mode: string\n runtime_bound_at?: string\n }\n ): void {\n this.db.prepare(\n `UPDATE agents\n SET tmux_pane_id=?,\n runtime_ui_pid=?,\n runtime_tty=?,\n runtime_verification_mode=?,\n runtime_bound_at=?\n WHERE agent_id=?`\n ).run(\n args.tmux_pane_id,\n args.runtime_ui_pid,\n args.runtime_tty,\n args.runtime_verification_mode,\n args.runtime_bound_at ?? new Date().toISOString(),\n agent_id\n )\n }\n\n list(args: { team: string }): AgentListRow[] {\n const rows = this.db.prepare(\n `SELECT\n agent_id,\n client,\n client_name,\n team,\n role,\n name,\n model,\n tmux_pane_id,\n delivery_kind,\n delivery_payload,\n last_seen_at\n FROM agents\n WHERE team=?\n ORDER BY registered_at ASC`\n ).all(args.team) as DbAgentRow[]\n const nowMs = Date.now()\n return rows.map((row) => {\n const agent = toAgentRow(row)\n return {\n ...agent,\n online: nowMs - new Date(agent.last_seen_at).getTime() < ONLINE_MS,\n }\n })\n }\n\n touch(agent_id: string): void {\n this.db.prepare(`UPDATE agents SET last_seen_at=? WHERE agent_id=?`).run(new Date().toISOString(), agent_id)\n }\n\n listClaimedInProgressTaskIds(args: { agent_id: string; team: string }): string[] {\n const rows = this.db.prepare(\n `SELECT id\n FROM tasks\n WHERE team=? AND claimed_by=? AND status='in_progress'\n ORDER BY id ASC`\n ).all(args.team, args.agent_id) as Array<{ id: string }>\n return rows.map((row) => row.id)\n }\n\n deleteContractSubscriptions(args: { agent_id: string; team: string }): number {\n const result = this.db.prepare(\n `DELETE FROM contract_subscriptions\n WHERE agent_id=? AND team=?`\n ).run(args.agent_id, args.team)\n return result.changes\n }\n\n deleteById(agent_id: string): boolean {\n const result = this.db.prepare(\n `DELETE FROM agents\n WHERE agent_id=?`\n ).run(agent_id)\n return result.changes === 1\n }\n\n getById(agent_id: string): AgentRow | undefined {\n const row = this.db.prepare(\n `SELECT\n agent_id,\n client,\n client_name,\n team,\n role,\n name,\n model,\n tmux_pane_id,\n delivery_kind,\n delivery_payload,\n last_seen_at\n FROM agents\n WHERE agent_id=?`\n ).get(agent_id) as DbAgentRow | undefined\n if (!row) return undefined\n return toAgentRow(row)\n }\n\n findById(agent_id: string): AgentRow | undefined {\n return this.getById(agent_id)\n }\n}\n","export type DeliveryNone = {\n kind: 'none';\n};\n\nexport type DeliveryClaudeChannel = {\n kind: 'claude-channel';\n channel_session_id: string;\n};\n\nexport type DeliveryCodexAppserver = {\n kind: 'codex-appserver';\n thread_id: string;\n ws_url: string;\n auth_token_ref?: string;\n};\n\nexport type DeliverySpec =\n | DeliveryNone\n | DeliveryClaudeChannel\n | DeliveryCodexAppserver;\n\nexport type DeliveryKind = DeliverySpec['kind'];\n\nexport const DELIVERY_KINDS: readonly DeliveryKind[] = [\n 'none',\n 'claude-channel',\n 'codex-appserver',\n] as const;\n\nexport type DeliveryRow = {\n delivery_kind: string;\n delivery_payload: string | null;\n};\n\nexport function parseDeliveryRow(row: DeliveryRow): DeliverySpec {\n const kind = row.delivery_kind;\n if (kind === 'none') {\n return { kind: 'none' };\n }\n if (!(DELIVERY_KINDS as readonly string[]).includes(kind)) {\n throw new Error('corrupt_delivery_payload');\n }\n let payload: unknown;\n try {\n payload = row.delivery_payload == null ? {} : JSON.parse(row.delivery_payload);\n } catch {\n throw new Error('corrupt_delivery_payload');\n }\n if (typeof payload !== 'object' || payload === null) {\n throw new Error('corrupt_delivery_payload');\n }\n const record = payload as Record<string, unknown>;\n if (kind === 'claude-channel') {\n const csid = record.channel_session_id;\n if (typeof csid !== 'string' || csid.length === 0) {\n throw new Error('corrupt_delivery_payload');\n }\n return { kind: 'claude-channel', channel_session_id: csid };\n }\n if (kind === 'codex-appserver') {\n const threadId = record.thread_id;\n if (typeof threadId !== 'string' || threadId.length === 0) {\n throw new Error('corrupt_delivery_payload');\n }\n const wsUrl = record.ws_url;\n if (typeof wsUrl !== 'string' || wsUrl.length === 0) {\n throw new Error('corrupt_delivery_payload');\n }\n const hasAuthTokenRef = Object.prototype.hasOwnProperty.call(record, 'auth_token_ref');\n if (hasAuthTokenRef) {\n const authTokenRef = record.auth_token_ref;\n if (typeof authTokenRef !== 'string' || authTokenRef.length === 0) {\n throw new Error('corrupt_delivery_payload');\n }\n return {\n kind: 'codex-appserver',\n thread_id: threadId,\n ws_url: wsUrl,\n auth_token_ref: authTokenRef,\n };\n }\n return { kind: 'codex-appserver', thread_id: threadId, ws_url: wsUrl };\n }\n throw new Error('corrupt_delivery_payload');\n}\n\nexport function serializeDelivery(spec: DeliverySpec): DeliveryRow {\n if (spec.kind === 'none') {\n return { delivery_kind: 'none', delivery_payload: null };\n }\n const { kind, ...rest } = spec;\n return {\n delivery_kind: kind,\n delivery_payload: JSON.stringify(rest),\n };\n}\n\nexport type DeliveryValidationReason =\n | 'unknown_kind'\n | 'missing_channel_session_id'\n | 'invalid_thread_id'\n | 'invalid_ws_url'\n | 'invalid_auth_token_ref';\n\nexport type ValidateDeliveryResult =\n | { ok: DeliverySpec }\n | { error: 'invalid_delivery'; reason: DeliveryValidationReason };\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nfunction readTrimmedString(\n input: Record<string, unknown>,\n key: string\n): string | undefined {\n const value = input[key];\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : '';\n}\n\nexport function validateDeliveryForWrite(input: unknown): ValidateDeliveryResult {\n if (typeof input !== 'object' || input === null) {\n return { error: 'invalid_delivery', reason: 'unknown_kind' };\n }\n const record = input as Record<string, unknown>;\n const kind = record.kind;\n if (kind === 'none') {\n return { ok: { kind: 'none' } };\n }\n if (kind === 'claude-channel') {\n const csid = readTrimmedString(record, 'channel_session_id');\n if (csid === undefined || csid.length === 0) {\n return { error: 'invalid_delivery', reason: 'missing_channel_session_id' };\n }\n return { ok: { kind: 'claude-channel', channel_session_id: csid } };\n }\n if (kind === 'codex-appserver') {\n const threadId = readTrimmedString(record, 'thread_id');\n if (threadId === undefined || threadId.length === 0 || !UUID_RE.test(threadId)) {\n return { error: 'invalid_delivery', reason: 'invalid_thread_id' };\n }\n\n const wsUrl = readTrimmedString(record, 'ws_url');\n if (wsUrl === undefined || wsUrl.length === 0) {\n return { error: 'invalid_delivery', reason: 'invalid_ws_url' };\n }\n try {\n const parsed = new URL(wsUrl);\n if (parsed.protocol !== 'ws:' && parsed.protocol !== 'wss:') {\n return { error: 'invalid_delivery', reason: 'invalid_ws_url' };\n }\n } catch {\n return { error: 'invalid_delivery', reason: 'invalid_ws_url' };\n }\n\n const authTokenRef = readTrimmedString(record, 'auth_token_ref');\n if (authTokenRef === '') {\n return { error: 'invalid_delivery', reason: 'invalid_auth_token_ref' };\n }\n\n return {\n ok: {\n kind: 'codex-appserver',\n thread_id: threadId,\n ws_url: wsUrl,\n ...(authTokenRef === undefined ? {} : { auth_token_ref: authTokenRef }),\n },\n };\n }\n return { error: 'invalid_delivery', reason: 'unknown_kind' };\n}\n","import type Database from 'better-sqlite3'\n\nexport interface EventRow {\n event_id: number\n from_team: string\n to_team: string\n event_type: string\n actor_agent_id: string | null\n payload: string\n created_at: string\n}\n\nexport class EventsOutbox {\n constructor(private db: Database.Database) {}\n\n append(args: {\n from_team: string\n to_team: string\n event_type: string\n actor_agent_id?: string | null\n payload: unknown\n }): number {\n const stmt = this.db.prepare(\n `INSERT INTO events (from_team, to_team, event_type, actor_agent_id, payload, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`\n )\n const info = stmt.run(\n args.from_team,\n args.to_team,\n args.event_type,\n args.actor_agent_id ?? null,\n JSON.stringify(args.payload),\n new Date().toISOString()\n )\n return Number(info.lastInsertRowid)\n }\n\n since(args: { team: string; since_event_id: number; limit?: number }): EventRow[] {\n const limit = Math.min(args.limit ?? 100, 500)\n return this.db.prepare(\n `SELECT * FROM events WHERE to_team = ? AND event_id > ? ORDER BY event_id ASC LIMIT ?`\n ).all(args.team, args.since_event_id, limit) as EventRow[]\n }\n}\n","import { basename } from 'node:path'\n\nexport interface DeriveDefaultTeamInput {\n team?: string\n project_dir?: string\n}\n\nexport function deriveDefaultTeam(input: DeriveDefaultTeamInput): string {\n const explicitTeam = input.team?.trim()\n if (explicitTeam) return explicitTeam\n\n if (input.project_dir !== undefined) {\n const projectTeam = basename(input.project_dir).trim().toLowerCase()\n if (projectTeam) return projectTeam\n }\n\n return 'default'\n}\n","import type Database from 'better-sqlite3'\nimport {\n validateDeliveryForWrite,\n type DeliveryValidationReason,\n} from '../lib/delivery-spec.js'\nimport type { ClientKind } from '../lib/client-kind.js'\nimport { deriveDefaultTeam } from '../lib/default-team.js'\nimport { AgentsRepo } from '../storage/agents-repo.js'\n\nexport { deriveDefaultTeam } from '../lib/default-team.js'\n\nexport interface RegisterInput {\n connection_id: string\n client?: ClientKind\n client_name?: string\n model: string\n name: string\n role?: string\n team?: string\n project_dir?: string\n tmux_pane_id?: string\n delivery?: unknown\n claude_ui_pid?: number\n runtime_ui_pid?: number\n}\n\nexport type RegisterResult =\n | { agent_id: string; team: string }\n | { error: 'agent_id_collision' }\n | { error: 'invalid_delivery'; reason: DeliveryValidationReason }\n | { error: 'claude_ui_pid_requires_channel_proxy' }\n\nfunction identityKey(team: string, name: string): string {\n return `${team}\\u0000${name}`\n}\n\nexport class RegisterAgentService {\n private readonly repo: AgentsRepo\n private readonly connections = new Map<string, string>()\n\n constructor(db: Database.Database) { this.repo = new AgentsRepo(db) }\n\n register(input: RegisterInput): RegisterResult {\n const validated =\n input.delivery === undefined\n ? undefined\n : validateDeliveryForWrite(input.delivery)\n if (validated && 'error' in validated) return validated\n\n const role = input.role ?? 'default'\n if (input.claude_ui_pid !== undefined && role !== '__channel_proxy__') {\n return { error: 'claude_ui_pid_requires_channel_proxy' }\n }\n\n const team = deriveDefaultTeam({\n team: input.team,\n project_dir: input.project_dir,\n })\n const key = identityKey(team, input.name)\n const bound = this.connections.get(key)\n if (bound && bound !== input.connection_id) return { error: 'agent_id_collision' }\n this.connections.set(key, input.connection_id)\n return this.repo.register({\n client: input.client,\n client_name: input.client_name,\n model: input.model,\n name: input.name,\n role,\n team,\n tmux_pane_id: input.tmux_pane_id,\n delivery: validated?.ok,\n claude_ui_pid: input.claude_ui_pid,\n runtime_ui_pid: input.runtime_ui_pid,\n })\n }\n\n releaseConnection(agent_id: string, connection_id: string): void {\n // Release by connection_id — scan and unbind any identity key mapped to this connection.\n for (const [k, cid] of this.connections) {\n if (cid === connection_id) this.connections.delete(k)\n }\n void agent_id\n }\n}\n","import type Database from 'better-sqlite3'\nimport { randomUUID } from 'node:crypto'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\nimport type { AutoPokeSkipReason, FanoutDeps } from './auto-poke-fanout.js'\nimport { parseDeliveryRow, type DeliverySpec } from '../lib/delivery-spec.js'\nimport { runFanoutWithRetry } from './fanout-with-retry.js'\nimport { recordInitialDeliveryStatuses } from './delivery-status.js'\n\nexport type { AutoPokeFn, AutoPokeSkipReason } from './auto-poke-fanout.js'\n\nexport type SendMessageDeps = FanoutDeps\n\nexport interface SendInput {\n from: string\n to_agent_id?: string\n to_agent_name?: string\n to_team?: string\n subject?: string\n body: string\n auto_poke?: boolean\n need_reply?: boolean\n}\n\ninterface SuccessResult {\n message_id: string\n event_id: number\n recipients: string[]\n poked: boolean\n poke_skip_reasons?: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n retry_scheduled: boolean\n retry_delays_s?: number[]\n}\n\nexport type SendResult =\n | SuccessResult\n | { error: 'unknown_recipient' }\n | { error: 'ambiguous_recipient' }\n | { error: 'missing_recipient' }\n\ninterface RecipientPokeRow {\n agent_id: string\n tmux_pane_id: string | null\n delivery: DeliverySpec\n}\n\ninterface RecipientLookupRow {\n agent_id: string\n team: string\n tmux_pane_id: string | null\n delivery_kind: string\n delivery_payload: string | null\n}\n\nexport class SendMessageService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox,\n private deps: SendMessageDeps = {}\n ) {}\n\n async send(input: SendInput): Promise<SendResult> {\n const hasId = typeof input.to_agent_id === 'string' && input.to_agent_id.length > 0\n const hasName = typeof input.to_agent_name === 'string' && input.to_agent_name.length > 0\n if (!hasId && !hasName) return { error: 'missing_recipient' }\n if (hasId && hasName) return { error: 'ambiguous_recipient' }\n const fromRow = this.agents.findById(input.from)\n if (!fromRow) return { error: 'unknown_recipient' }\n const fromTeam = fromRow.team\n const toTeam = input.to_team ?? fromTeam\n\n let resolvedId: string\n if (hasId) {\n resolvedId = input.to_agent_id!\n } else {\n const hit = this.agents.findByIdentity({ team: toTeam, name: input.to_agent_name! })\n if (!hit) return { error: 'unknown_recipient' }\n resolvedId = hit.agent_id\n }\n\n const rcpt = this.db.prepare(\n `SELECT\n agent_id,\n team,\n tmux_pane_id,\n delivery_kind,\n delivery_payload\n FROM agents\n WHERE agent_id=?`\n )\n .get(resolvedId) as RecipientLookupRow | undefined\n if (!rcpt || rcpt.team !== toTeam) return { error: 'unknown_recipient' }\n const recipientRow: RecipientPokeRow = {\n agent_id: rcpt.agent_id,\n tmux_pane_id: rcpt.tmux_pane_id,\n delivery: parseDeliveryRow(rcpt),\n }\n\n const baseResult = this.insert({ fromTeam, toTeam, from: input.from, toAgentId: rcpt.agent_id, input })\n\n const autoPokeEnabled = input.auto_poke !== false\n if (!autoPokeEnabled) {\n recordInitialDeliveryStatuses(this.db, {\n messageId: baseResult.message_id,\n recipients: [rcpt.agent_id],\n delivered: new Set(),\n skipped: [],\n autoPokeDisabled: true,\n })\n return { ...baseResult, poked: false, retry_scheduled: false }\n }\n\n const envelope = await runFanoutWithRetry({\n db: this.db,\n team: toTeam,\n fromAgentId: input.from,\n recipients: [recipientRow],\n body: input.body,\n deps: this.deps,\n messageId: baseResult.message_id,\n sentAt: baseResult.sent_at\n })\n return {\n message_id: baseResult.message_id,\n event_id: baseResult.event_id,\n recipients: baseResult.recipients,\n ...envelope\n }\n }\n\n private insert(args: {\n fromTeam: string; toTeam: string; from: string; toAgentId: string; input: SendInput\n }): { message_id: string; event_id: number; recipients: string[]; sent_at: string } {\n const tx = this.db.transaction(() => {\n const needReply = args.input.need_reply !== false ? 1 : 0\n const event_id = this.events.append({\n from_team: args.fromTeam, to_team: args.toTeam,\n event_type: 'message_sent', actor_agent_id: args.from,\n payload: {\n recipients: [args.toAgentId],\n subject: args.input.subject ?? null,\n need_reply: needReply === 1,\n }\n })\n const sent_at = new Date().toISOString()\n const id = randomUUID()\n this.db.prepare(\n `INSERT INTO messages (id, event_id, from_team, to_team, from_agent_id, to_agent_id, to_role, subject, body, need_reply, sent_at)\n VALUES (?,?,?,?,?,?,?,?,?,?,?)`\n ).run(id, event_id, args.fromTeam, args.toTeam, args.from,\n args.toAgentId,\n null, args.input.subject ?? null, args.input.body, needReply, sent_at)\n return { message_id: id, event_id, sent_at }\n })\n const { message_id, event_id, sent_at } = tx()\n return { message_id, event_id, recipients: [args.toAgentId], sent_at }\n }\n}\n","import { execFile, spawn } from 'node:child_process'\nimport { promisify } from 'node:util'\n\nconst pExecFile = promisify(execFile)\n\nlet _isTmuxAvailable: boolean | null = null\n\nexport async function isTmuxAvailable(): Promise<boolean> {\n if (_isTmuxAvailable !== null) return _isTmuxAvailable\n try {\n await pExecFile('tmux', ['-V'])\n _isTmuxAvailable = true\n } catch {\n _isTmuxAvailable = false\n }\n return _isTmuxAvailable\n}\n\nconst TMUX_CAPTURE_TIMEOUT_MS = 5_000\n\nexport async function capturePaneTail(paneId: string, lines = 8): Promise<string> {\n const { stdout } = await pExecFile(\n 'tmux',\n ['capture-pane', '-t', paneId, '-p', '-S', `-${lines}`],\n { timeout: TMUX_CAPTURE_TIMEOUT_MS }\n )\n return stdout\n}\n\nexport function loadBuffer(bufferName: string, prompt: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('tmux', ['load-buffer', '-b', bufferName, '-'])\n let stderr = ''\n child.on('error', reject)\n if (child.stderr) {\n child.stderr.on('data', (b: Buffer) => { stderr += b.toString('utf8') })\n }\n child.on('close', (code: number) => {\n if (code === 0) resolve()\n else reject(new Error(`load-buffer exit ${code}: ${stderr}`))\n })\n child.stdin.write(Buffer.from(prompt, 'utf8'))\n child.stdin.end()\n })\n}\n\nexport async function pasteBuffer(bufferName: string, paneId: string): Promise<void> {\n await pExecFile('tmux', ['paste-buffer', '-b', bufferName, '-t', paneId, '-p', '-d'])\n}\n\nexport async function sendEnter(paneId: string): Promise<void> {\n await pExecFile('tmux', ['send-keys', '-t', paneId, 'Enter'])\n}\n\nexport function _resetTmuxAvailableCache(): void {\n _isTmuxAvailable = null\n}\n\nexport function _setTmuxAvailableForTest(value: boolean): void {\n _isTmuxAvailable = value\n}\n","import { capturePaneTail as _capture } from '../daemon/tmux-cli.js'\n\nconst DEFAULT_QUIET_MS = 2000\nconst GUARD_TAIL_LINES = 8\n\ntype CaptureFn = (paneId: string, lines?: number) => Promise<string>\n\nlet _captureImpl: CaptureFn = _capture\n\nexport function __setCapturePaneTail(fn: CaptureFn): void {\n _captureImpl = fn\n}\n\nexport function __resetCapturePaneTail(): void {\n _captureImpl = _capture\n}\n\nexport function resolveQuietMs(opt?: number): number {\n if (typeof opt === 'number' && Number.isInteger(opt) && opt > 0) return opt\n const raw = process.env.POKE_QUIET_MS\n if (raw === undefined) return DEFAULT_QUIET_MS\n const n = Number(raw)\n return Number.isInteger(n) && n > 0 ? n : DEFAULT_QUIET_MS\n}\n\nexport async function runQuietGuard(paneId: string, quietMs?: number): Promise<'pass' | 'fail'> {\n const ms = resolveQuietMs(quietMs)\n const before = await _captureImpl(paneId, GUARD_TAIL_LINES)\n await new Promise(r => setTimeout(r, ms))\n const after = await _captureImpl(paneId, GUARD_TAIL_LINES)\n return before === after ? 'pass' : 'fail'\n}\n","export const RETRY_DELAYS_MS = [30_000, 180_000, 600_000] as const\nexport const RETRY_DELAYS_S = [30, 180, 600] as const\n\nexport interface RetryPokeArgs {\n team: string\n fromAgentId: string\n targetAgentId: string\n paneId: string\n body: string\n}\n\nexport interface RetryAgentLookup {\n agent_id: string\n tmux_pane_id: string | null\n last_seen_at: string\n}\n\nexport interface RetryContext {\n agentId: string\n messageId: string\n fromAgentId: string\n body: string\n team: string\n sentAt: string\n paneId: string\n paneGuardFn: (paneId: string) => Promise<'pass' | 'fail'>\n pokeFn: (args: RetryPokeArgs) => Promise<void>\n lookupAgentFn: (agentId: string) => RetryAgentLookup | undefined\n updateStatusFn?: (args: {\n agentId: string\n wake_status: 'delivered' | 'retrying' | 'skipped' | 'failed'\n skip_reason?: 'guard_failed' | 'no_pane' | 'recipient_active' | 'retry_exhausted' | null\n retry_attempts?: number\n delivered_at?: string | null\n }) => void\n}\n\ninterface RetryEntry {\n timer?: ReturnType<typeof setTimeout>\n attempt: number\n ctx: RetryContext\n}\n\nconst retryMap = new Map<string, RetryEntry>()\n\nfunction keyOf(ctx: RetryContext): string {\n return `${ctx.messageId}:${ctx.agentId}`\n}\n\n// Retry tick resolves the recipient via ctx.lookupAgentFn (caller-provided), which is team-agnostic; cross-team retries are supported.\nexport function scheduleRetry(ctx: RetryContext): void {\n const key = keyOf(ctx)\n cancelRetry(key)\n retryMap.set(key, { attempt: 0, ctx })\n enqueueNext(key)\n}\n\nfunction enqueueNext(key: string): void {\n const entry = retryMap.get(key)\n if (!entry) return\n if (entry.attempt >= RETRY_DELAYS_MS.length) {\n retryMap.delete(key)\n return\n }\n const delay = RETRY_DELAYS_MS[entry.attempt]\n entry.timer = setTimeout(() => { void tick(key) }, delay)\n}\n\nasync function tick(key: string): Promise<void> {\n const entry = retryMap.get(key)\n if (!entry) return\n const { ctx } = entry\n try {\n const agent = ctx.lookupAgentFn(ctx.agentId)\n if (!agent || !agent.tmux_pane_id) {\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'failed',\n skip_reason: 'no_pane',\n retry_attempts: entry.attempt,\n })\n retryMap.delete(key)\n return\n }\n if (new Date(agent.last_seen_at).getTime() > new Date(ctx.sentAt).getTime()) {\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'skipped',\n skip_reason: 'recipient_active',\n retry_attempts: entry.attempt,\n })\n retryMap.delete(key)\n return\n }\n const guard = await ctx.paneGuardFn(agent.tmux_pane_id)\n if (guard === 'pass') {\n await ctx.pokeFn({\n team: ctx.team,\n fromAgentId: ctx.fromAgentId,\n targetAgentId: ctx.agentId,\n paneId: agent.tmux_pane_id,\n body: ctx.body\n })\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'delivered',\n skip_reason: null,\n retry_attempts: entry.attempt + 1,\n delivered_at: new Date().toISOString(),\n })\n retryMap.delete(key)\n return\n }\n entry.attempt += 1\n if (entry.attempt >= RETRY_DELAYS_MS.length) {\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'failed',\n skip_reason: 'retry_exhausted',\n retry_attempts: entry.attempt,\n })\n retryMap.delete(key)\n return\n }\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'retrying',\n skip_reason: 'guard_failed',\n retry_attempts: entry.attempt,\n })\n enqueueNext(key)\n } catch {\n ctx.updateStatusFn?.({\n agentId: ctx.agentId,\n wake_status: 'failed',\n skip_reason: 'retry_exhausted',\n retry_attempts: entry.attempt,\n })\n retryMap.delete(key)\n }\n}\n\nexport function cancelRetry(key: string): void {\n const entry = retryMap.get(key)\n if (!entry) return\n if (entry.timer) clearTimeout(entry.timer)\n retryMap.delete(key)\n}\n\nexport function clearAllRetries(): void {\n for (const [, v] of retryMap) if (v.timer) clearTimeout(v.timer)\n retryMap.clear()\n}\n\nexport function __peekRetryMap(): Map<string, { attempt: number; ctx: RetryContext }> {\n const view = new Map<string, { attempt: number; ctx: RetryContext }>()\n for (const [k, v] of retryMap) view.set(k, { attempt: v.attempt, ctx: v.ctx })\n return view\n}\n","import { runQuietGuard } from './poke-guard.js'\nimport { isTmuxAvailable } from '../daemon/tmux-cli.js'\nimport { scheduleRetry as defaultScheduleRetry, type RetryAgentLookup, type RetryContext } from './poke-retry.js'\nimport type { DeliverySpec } from '../lib/delivery-spec.js'\n\nexport type AutoPokeSkipReason = 'no_pane' | 'guard_failed' | 'tmux_unavailable' | 'self'\n\nexport interface AutoPokeArgs {\n team: string\n fromAgentId: string\n targetAgentId: string\n paneId: string | null\n body: string\n}\n\nexport type AutoPokeFn = (args: AutoPokeArgs) => Promise<{ ok: true } | { ok: false; reason?: AutoPokeSkipReason }>\n\nexport interface AutoPokeRecipient {\n agent_id: string\n tmux_pane_id: string | null\n delivery?: DeliverySpec\n}\n\nexport interface FanoutDeps {\n poke?: AutoPokeFn\n tmuxAvailable?: () => Promise<boolean>\n}\n\nexport interface RetryScheduleCtx {\n messageId: string\n sentAt: string\n lookupAgentFn: (agentId: string) => RetryAgentLookup | undefined\n scheduleRetryFn?: (ctx: RetryContext) => void\n updateStatusFn?: RetryContext['updateStatusFn']\n}\n\nexport interface FanoutResult {\n poked: boolean\n skipReasons: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n deliveredAgentIds: string[]\n retryScheduledCount: number\n}\n\nfunction hasNonTmuxTransport(recipient: AutoPokeRecipient): boolean {\n return recipient.delivery !== undefined && recipient.delivery.kind !== 'none'\n}\n\n// Recipients are supplied by the caller; no team filter is applied here, so cross-team fan-out works transparently.\nexport async function fanoutAutoPoke(args: {\n team: string\n fromAgentId: string\n recipients: AutoPokeRecipient[]\n body: string\n deps: FanoutDeps\n retry?: RetryScheduleCtx\n}): Promise<FanoutResult> {\n const pokeFn = args.deps.poke\n const tmuxAvail = args.deps.tmuxAvailable ?? isTmuxAvailable\n\n const results = await Promise.all(args.recipients.map(async (r) => {\n try {\n const nonTmuxTransport = hasNonTmuxTransport(r)\n if (r.agent_id === args.fromAgentId) {\n return { agent_id: r.agent_id, poked: false, reason: 'self' as AutoPokeSkipReason, paneId: null as string | null }\n }\n if (!nonTmuxTransport && !r.tmux_pane_id) {\n return { agent_id: r.agent_id, poked: false, reason: 'no_pane' as AutoPokeSkipReason, paneId: null }\n }\n if (!nonTmuxTransport && !(await tmuxAvail())) {\n return { agent_id: r.agent_id, poked: false, reason: 'tmux_unavailable' as AutoPokeSkipReason, paneId: r.tmux_pane_id }\n }\n if (!pokeFn) {\n return { agent_id: r.agent_id, poked: false, reason: 'tmux_unavailable' as AutoPokeSkipReason, paneId: r.tmux_pane_id }\n }\n if (!nonTmuxTransport) {\n const guard = await runQuietGuard(r.tmux_pane_id!)\n if (guard === 'fail') {\n return { agent_id: r.agent_id, poked: false, reason: 'guard_failed' as AutoPokeSkipReason, paneId: r.tmux_pane_id }\n }\n }\n const out = await pokeFn({\n team: args.team,\n fromAgentId: args.fromAgentId,\n targetAgentId: r.agent_id,\n paneId: r.tmux_pane_id,\n body: args.body\n })\n if (out.ok) return { agent_id: r.agent_id, poked: true, reason: undefined, paneId: r.tmux_pane_id }\n return {\n agent_id: r.agent_id,\n poked: false,\n reason: (out.reason ?? 'guard_failed') as AutoPokeSkipReason,\n paneId: r.tmux_pane_id\n }\n } catch {\n return { agent_id: r.agent_id, poked: false, reason: 'guard_failed' as AutoPokeSkipReason, paneId: r.tmux_pane_id }\n }\n }))\n\n let retryScheduledCount = 0\n if (args.retry && pokeFn) {\n const scheduleFn = args.retry.scheduleRetryFn ?? defaultScheduleRetry\n for (const res of results) {\n if (!res.poked && res.reason === 'guard_failed' && res.paneId) {\n scheduleFn({\n agentId: res.agent_id,\n messageId: args.retry.messageId,\n fromAgentId: args.fromAgentId,\n body: args.body,\n team: args.team,\n sentAt: args.retry.sentAt,\n paneId: res.paneId,\n paneGuardFn: runQuietGuard,\n pokeFn: async (pokeArgs) => { await pokeFn(pokeArgs) },\n lookupAgentFn: args.retry.lookupAgentFn,\n updateStatusFn: args.retry.updateStatusFn\n })\n retryScheduledCount += 1\n }\n }\n }\n\n const poked = results.some(x => x.poked)\n const skipReasons = results\n .filter(x => !x.poked && x.reason !== undefined)\n .map(x => ({ agent_id: x.agent_id, reason: x.reason as AutoPokeSkipReason }))\n const deliveredAgentIds = results.filter(x => x.poked).map(x => x.agent_id)\n return { poked, skipReasons, deliveredAgentIds, retryScheduledCount }\n}\n","import type Database from 'better-sqlite3'\nimport type { AutoPokeSkipReason } from './auto-poke-fanout.js'\n\nexport type WakeStatus = 'delivered' | 'retrying' | 'skipped' | 'failed'\nexport type DeliverySkipReason =\n | AutoPokeSkipReason\n | 'auto_poke_disabled'\n | 'recipient_active'\n | 'retry_exhausted'\n\nexport interface DeliveryStatusRow {\n agent_id: string\n wake_status: WakeStatus\n skip_reason: DeliverySkipReason | null\n retry_attempts: number\n updated_at: string\n delivered_at: string | null\n}\n\nexport function recordInitialDeliveryStatuses(\n db: Database.Database,\n args: {\n messageId: string\n recipients: string[]\n delivered: Set<string>\n skipped: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n autoPokeDisabled?: boolean\n }\n): void {\n const now = new Date().toISOString()\n const skipped = new Map(args.skipped.map(x => [x.agent_id, x.reason]))\n const stmt = db.prepare(\n `INSERT INTO message_delivery_status\n (message_id, agent_id, wake_status, skip_reason, retry_attempts, updated_at, delivered_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(message_id, agent_id) DO UPDATE SET\n wake_status=excluded.wake_status,\n skip_reason=excluded.skip_reason,\n retry_attempts=excluded.retry_attempts,\n updated_at=excluded.updated_at,\n delivered_at=excluded.delivered_at`\n )\n const tx = db.transaction(() => {\n for (const agentId of args.recipients) {\n const reason = args.autoPokeDisabled ? 'auto_poke_disabled' : skipped.get(agentId)\n const delivered = args.delivered.has(agentId)\n const status: WakeStatus = delivered\n ? 'delivered'\n : reason === 'guard_failed' ? 'retrying' : 'skipped'\n stmt.run(\n args.messageId,\n agentId,\n status,\n delivered ? null : reason,\n 0,\n now,\n delivered ? now : null\n )\n }\n })\n tx()\n}\n\nexport function updateDeliveryStatus(\n db: Database.Database,\n messageId: string,\n agentId: string,\n args: {\n wake_status: WakeStatus\n skip_reason?: DeliverySkipReason | null\n retry_attempts?: number\n delivered_at?: string | null\n }\n): void {\n const now = new Date().toISOString()\n db.prepare(\n `UPDATE message_delivery_status\n SET wake_status=?,\n skip_reason=?,\n retry_attempts=COALESCE(?, retry_attempts),\n updated_at=?,\n delivered_at=?\n WHERE message_id=? AND agent_id=?`\n ).run(\n args.wake_status,\n args.skip_reason ?? null,\n args.retry_attempts ?? null,\n now,\n args.delivered_at === undefined ? null : args.delivered_at,\n messageId,\n agentId\n )\n}\n\nexport class GetDeliveryStatusService {\n constructor(private db: Database.Database) {}\n\n get(args: { caller: string; message_id: string }):\n | { message_id: string; statuses: DeliveryStatusRow[] }\n | { error: 'unknown_message' } {\n const owned = this.db.prepare(\n `SELECT 1 AS ok FROM messages WHERE id=? AND from_agent_id=? LIMIT 1`\n ).get(args.message_id, args.caller) as { ok: number } | undefined\n if (!owned) return { error: 'unknown_message' }\n\n const rows = this.db.prepare(\n `SELECT agent_id, wake_status, skip_reason, retry_attempts, updated_at, delivered_at\n FROM message_delivery_status\n WHERE message_id=?\n ORDER BY agent_id ASC`\n ).all(args.message_id) as DeliveryStatusRow[]\n return { message_id: args.message_id, statuses: rows }\n }\n}\n","import type Database from 'better-sqlite3'\nimport { fanoutAutoPoke, type AutoPokeRecipient, type AutoPokeSkipReason, type FanoutDeps } from './auto-poke-fanout.js'\nimport { RETRY_DELAYS_S } from './poke-retry.js'\nimport { recordInitialDeliveryStatuses, updateDeliveryStatus } from './delivery-status.js'\n\nexport interface FanoutResultEnvelope {\n poked: boolean\n poke_skip_reasons?: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n retry_scheduled: boolean\n retry_delays_s?: number[]\n}\n\n// Shared fan-out + retry wiring used by both BroadcastService (all-team) and BroadcastToRoleService (same-team role-scoped).\n// Same recipient-lookup SQL (agent_id-only, team-agnostic) keeps cross-team retry behaviour consistent.\nexport async function runFanoutWithRetry(args: {\n db: Database.Database\n team: string\n fromAgentId: string\n recipients: AutoPokeRecipient[]\n body: string\n deps: FanoutDeps\n messageId: string\n sentAt: string\n}): Promise<FanoutResultEnvelope> {\n const { db } = args\n const fanout = await fanoutAutoPoke({\n team: args.team,\n fromAgentId: args.fromAgentId,\n recipients: args.recipients,\n body: args.body,\n deps: args.deps,\n retry: {\n messageId: args.messageId,\n sentAt: args.sentAt,\n lookupAgentFn: (agentId: string) => db.prepare(\n 'SELECT agent_id, tmux_pane_id, last_seen_at FROM agents WHERE agent_id=?'\n ).get(agentId) as { agent_id: string; tmux_pane_id: string | null; last_seen_at: string } | undefined,\n updateStatusFn: (status) => {\n updateDeliveryStatus(db, args.messageId, status.agentId, status)\n }\n }\n })\n recordInitialDeliveryStatuses(db, {\n messageId: args.messageId,\n recipients: args.recipients.map(r => r.agent_id),\n delivered: new Set(fanout.deliveredAgentIds),\n skipped: fanout.skipReasons\n })\n const retry_scheduled = fanout.retryScheduledCount > 0\n return {\n poked: fanout.poked,\n poke_skip_reasons: fanout.skipReasons,\n retry_scheduled,\n ...(retry_scheduled ? { retry_delays_s: [...RETRY_DELAYS_S] } : {})\n }\n}\n","import type Database from 'better-sqlite3'\nimport { randomUUID } from 'node:crypto'\nimport { ONLINE_MS, type AgentsRepo } from '../storage/agents-repo.js'\nimport type { AutoPokeSkipReason, FanoutDeps } from './auto-poke-fanout.js'\nimport { runFanoutWithRetry } from './fanout-with-retry.js'\nimport { parseDeliveryRow } from '../lib/delivery-spec.js'\nimport { recordInitialDeliveryStatuses } from './delivery-status.js'\n\nexport type BroadcastDeps = FanoutDeps\n\nexport interface BroadcastInput {\n from: string\n body: string\n subject?: string\n auto_poke?: boolean\n}\n\ninterface SuccessResult {\n message_id: string\n event_id: number\n recipients: string[]\n poked: boolean\n poke_skip_reasons?: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n retry_scheduled: boolean\n retry_delays_s?: number[]\n}\n\nexport type BroadcastResult = SuccessResult | { error: 'unknown_recipient' }\n\nexport class BroadcastService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private deps: BroadcastDeps = {}\n ) {}\n\n async broadcast(input: BroadcastInput): Promise<BroadcastResult> {\n const fromRow = this.agents.findById(input.from)\n if (!fromRow) return { error: 'unknown_recipient' }\n const cutoffIso = new Date(Date.now() - ONLINE_MS).toISOString()\n const rawRows = this.db.prepare(\n `SELECT\n agent_id,\n tmux_pane_id,\n delivery_kind,\n delivery_payload\n FROM agents\n WHERE team=? AND agent_id != ? AND last_seen_at > ?`\n ).all(fromRow.team, input.from, cutoffIso) as Array<{\n agent_id: string\n tmux_pane_id: string | null\n delivery_kind: string\n delivery_payload: string | null\n }>\n const rows = rawRows.map((row) => ({\n agent_id: row.agent_id,\n tmux_pane_id: row.tmux_pane_id,\n delivery: parseDeliveryRow(row),\n }))\n if (rows.length === 0) return { error: 'unknown_recipient' }\n const recipients = rows.map(r => r.agent_id)\n const baseId = randomUUID()\n const inserted = this.insertBroadcast(fromRow.team, input.from, recipients, input.body, input.subject, baseId)\n\n if (input.auto_poke === false) {\n recordInitialDeliveryStatuses(this.db, {\n messageId: inserted.message_id,\n recipients,\n delivered: new Set(),\n skipped: [],\n autoPokeDisabled: true,\n })\n return { ...inserted, recipients, poked: false, retry_scheduled: false }\n }\n\n const envelope = await runFanoutWithRetry({\n db: this.db,\n team: fromRow.team,\n fromAgentId: input.from,\n recipients: rows,\n body: input.body,\n deps: this.deps,\n messageId: inserted.message_id,\n sentAt: inserted.sent_at\n })\n return {\n message_id: inserted.message_id,\n event_id: inserted.event_id,\n recipients,\n ...envelope\n }\n }\n\n private insertBroadcast(team: string, from: string, recipients: string[], body: string,\n subject: string | undefined, baseId: string): { message_id: string; event_id: number; sent_at: string } {\n const tx = this.db.transaction(() => {\n const event_id = Number(this.db.prepare(\n `INSERT INTO events (from_team, to_team, event_type, actor_agent_id, payload, created_at) VALUES (?,?,?,?,?,?)`\n ).run(team, team, 'message_sent', from,\n JSON.stringify({ to_role: '*broadcast*', recipients, subject: subject ?? null }),\n new Date().toISOString()).lastInsertRowid)\n const sent_at = new Date().toISOString()\n const insert = this.db.prepare(\n `INSERT INTO messages (id, event_id, from_team, to_team, from_agent_id, to_agent_id, to_role, subject, body, need_reply, sent_at)\n VALUES (?,?,?,?,?,?,?,?,?,?,?)`\n )\n for (let i = 0; i < recipients.length; i++) {\n const id = i === 0 ? baseId : `${baseId}-${i}`\n insert.run(id, event_id, team, team, from, recipients[i], '*broadcast*', subject ?? null, body, 0, sent_at)\n }\n return { message_id: baseId, event_id, sent_at }\n })\n return tx()\n }\n}\n","import type Database from 'better-sqlite3'\nimport { randomUUID } from 'node:crypto'\nimport { ONLINE_MS, type AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\nimport type { FanoutDeps, AutoPokeSkipReason } from './auto-poke-fanout.js'\nimport { runFanoutWithRetry } from './fanout-with-retry.js'\nimport { parseDeliveryRow } from '../lib/delivery-spec.js'\nimport { recordInitialDeliveryStatuses } from './delivery-status.js'\n\nexport type BroadcastToRoleDeps = FanoutDeps\n\nexport interface BroadcastToRoleInput {\n from: string\n to_role: string\n body: string\n subject?: string\n auto_poke?: boolean\n}\n\ninterface SuccessResult {\n message_id: string\n event_id: number\n recipients: string[]\n poked: boolean\n poke_skip_reasons?: Array<{ agent_id: string; reason: AutoPokeSkipReason }>\n retry_scheduled: boolean\n retry_delays_s?: number[]\n}\n\nexport type BroadcastToRoleResult = SuccessResult | { error: 'unknown_recipient' }\n\nexport class BroadcastToRoleService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox,\n private deps: BroadcastToRoleDeps = {}\n ) {}\n\n async broadcast(input: BroadcastToRoleInput): Promise<BroadcastToRoleResult> {\n const fromRow = this.agents.findById(input.from)\n if (!fromRow) return { error: 'unknown_recipient' }\n const cutoffIso = new Date(Date.now() - ONLINE_MS).toISOString()\n const rawRows = this.db.prepare(\n `SELECT\n agent_id,\n tmux_pane_id,\n delivery_kind,\n delivery_payload\n FROM agents\n WHERE team=? AND role=? AND agent_id != ? AND last_seen_at > ?`\n ).all(fromRow.team, input.to_role, input.from, cutoffIso) as Array<{\n agent_id: string\n tmux_pane_id: string | null\n delivery_kind: string\n delivery_payload: string | null\n }>\n const rows = rawRows.map((row) => ({\n agent_id: row.agent_id,\n tmux_pane_id: row.tmux_pane_id,\n delivery: parseDeliveryRow(row),\n }))\n if (rows.length === 0) return { error: 'unknown_recipient' }\n\n const recipients = rows.map(r => r.agent_id)\n const baseId = randomUUID()\n const inserted = this.insert(fromRow.team, input, recipients, baseId)\n\n if (input.auto_poke === false) {\n recordInitialDeliveryStatuses(this.db, {\n messageId: inserted.message_id,\n recipients,\n delivered: new Set(),\n skipped: [],\n autoPokeDisabled: true,\n })\n return {\n message_id: inserted.message_id,\n event_id: inserted.event_id,\n recipients,\n poked: false,\n retry_scheduled: false\n }\n }\n\n const envelope = await runFanoutWithRetry({\n db: this.db,\n team: fromRow.team,\n fromAgentId: input.from,\n recipients: rows,\n body: input.body,\n deps: this.deps,\n messageId: inserted.message_id,\n sentAt: inserted.sent_at\n })\n return {\n message_id: inserted.message_id,\n event_id: inserted.event_id,\n recipients,\n ...envelope\n }\n }\n\n private insert(team: string, input: BroadcastToRoleInput, recipients: string[], baseId: string):\n { message_id: string; event_id: number; sent_at: string } {\n const tx = this.db.transaction(() => {\n const event_id = this.events.append({\n from_team: team,\n to_team: team,\n event_type: 'message_sent',\n actor_agent_id: input.from,\n payload: { to_role: input.to_role, recipients, subject: input.subject ?? null }\n })\n const sent_at = new Date().toISOString()\n const stmt = this.db.prepare(\n `INSERT INTO messages (id, event_id, from_team, to_team, from_agent_id, to_agent_id, to_role, subject, body, need_reply, sent_at)\n VALUES (?,?,?,?,?,?,?,?,?,?,?)`\n )\n for (let i = 0; i < recipients.length; i++) {\n const id = i === 0 ? baseId : `${baseId}-${i}`\n stmt.run(id, event_id, team, team, input.from, recipients[i], input.to_role, input.subject ?? null, input.body, 0, sent_at)\n }\n return { message_id: baseId, event_id, sent_at }\n })\n return tx()\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport interface InboxMessage {\n id: string\n event_id: number\n from_team: string\n to_team: string\n from_agent_id: string\n from_role: string | null\n to_agent_id: string | null\n to_role: string | null\n subject: string | null\n body: string\n need_reply: boolean\n sent_at: string\n}\n\nexport interface InboxResult {\n messages: InboxMessage[]\n has_more: boolean\n last_event_id: number\n}\n\nexport class GetInboxService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n get(args: { caller: string; since_event_id?: number; limit?: number }): InboxResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { messages: [], has_more: false, last_event_id: args.since_event_id ?? 0 }\n const callerTeam = caller.team\n const callerRole = this.db.prepare('SELECT role FROM agents WHERE agent_id=?')\n .get(args.caller) as { role: string } | undefined\n const limit = Math.min(args.limit ?? 50, 200)\n const since = args.since_event_id ?? 0\n const rows = this.db.prepare(\n `SELECT m.id, m.event_id, m.from_team, m.to_team, m.from_agent_id, m.to_agent_id, m.to_role, m.subject, m.body, m.need_reply, m.sent_at,\n a.role as from_role\n FROM messages m\n LEFT JOIN agents a ON a.agent_id = m.from_agent_id\n WHERE m.to_team = ?\n AND m.event_id > ?\n AND ( m.to_agent_id = ? OR (m.to_role IS NOT NULL AND m.to_role = ?) )\n ORDER BY m.event_id ASC\n LIMIT ?`\n ).all(callerTeam, since, args.caller, callerRole?.role ?? '__none__', limit + 1) as Array<\n Omit<InboxMessage, 'need_reply'> & { need_reply: number }\n >\n const has_more = rows.length > limit\n const trimmed = (has_more ? rows.slice(0, limit) : rows).map(row => ({\n ...row,\n need_reply: row.need_reply === 1,\n }))\n const last_event_id = trimmed.length > 0 ? trimmed[trimmed.length - 1].event_id : since\n return { messages: trimmed, has_more, last_event_id }\n }\n}\n","import type Database from 'better-sqlite3'\nimport { randomUUID } from 'node:crypto'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\n\nexport type AddResult = { task_id: string } | { error: 'unknown_agent' }\n\nexport class TaskAddService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox\n ) {}\n\n add(args: { caller: string; title: string; description?: string; depends_on?: string[] }): AddResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const id = randomUUID()\n const depends_on = JSON.stringify(args.depends_on ?? [])\n const created_at = new Date().toISOString()\n const tx = this.db.transaction(() => {\n this.db.prepare(\n `INSERT INTO tasks (id, team, title, description, status, depends_on, created_at)\n VALUES (?,?,?,?, 'pending', ?, ?)`\n ).run(id, caller.team, args.title, args.description ?? null, depends_on, created_at)\n this.events.append({\n from_team: caller.team,\n to_team: caller.team,\n event_type: 'task_added',\n actor_agent_id: args.caller,\n payload: { task_id: id, title: args.title }\n })\n })\n tx()\n return { task_id: id }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\n\nexport type ClaimResult =\n | { ok: true }\n | { error: 'already_claimed'; owner: string }\n | { error: 'dependencies_pending' }\n | { error: 'unknown_task' }\n | { error: 'unknown_agent' }\n\nexport class TaskClaimService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox\n ) {}\n\n claim(args: { caller: string; task_id: string }): ClaimResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const row = this.db.prepare(\n `SELECT status, claimed_by, depends_on FROM tasks WHERE id=? AND team=?`\n ).get(args.task_id, caller.team) as\n { status: string; claimed_by: string | null; depends_on: string } | undefined\n if (!row) return { error: 'unknown_task' }\n if (row.status !== 'pending') {\n if (row.claimed_by) return { error: 'already_claimed', owner: row.claimed_by }\n return { error: 'already_claimed', owner: '' }\n }\n const deps = JSON.parse(row.depends_on) as string[]\n if (deps.length > 0) {\n const pending = this.db.prepare(\n `SELECT COUNT(*) as c FROM tasks WHERE id IN (${deps.map(() => '?').join(',')}) AND team=? AND status != 'completed'`\n ).get(...deps, caller.team) as { c: number }\n if (pending.c > 0) return { error: 'dependencies_pending' }\n }\n const upd = this.db.prepare(\n `UPDATE tasks SET status='in_progress', claimed_by=?, claimed_at=?\n WHERE id=? AND team=? AND status='pending'`\n ).run(args.caller, new Date().toISOString(), args.task_id, caller.team)\n if (upd.changes !== 1) {\n const post = this.db.prepare(`SELECT claimed_by FROM tasks WHERE id=?`).get(args.task_id) as\n { claimed_by: string | null } | undefined\n return { error: 'already_claimed', owner: post?.claimed_by ?? '' }\n }\n this.events.append({\n from_team: caller.team, to_team: caller.team,\n event_type: 'task_claimed', actor_agent_id: args.caller,\n payload: { task_id: args.task_id }\n })\n return { ok: true }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\n\nexport type CompleteResult =\n | { ok: true }\n | { error: 'not_owner' | 'invalid_status' | 'unknown_task' | 'unknown_agent' }\n\nexport class TaskCompleteService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox\n ) {}\n\n complete(args: { caller: string; task_id: string; result?: string }): CompleteResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const row = this.db.prepare(`SELECT status, claimed_by FROM tasks WHERE id=? AND team=?`)\n .get(args.task_id, caller.team) as { status: string; claimed_by: string | null } | undefined\n if (!row) return { error: 'unknown_task' }\n if (row.status !== 'in_progress') return { error: 'invalid_status' }\n if (row.claimed_by !== args.caller) return { error: 'not_owner' }\n const upd = this.db.prepare(\n `UPDATE tasks SET status='completed', completed_at=?, result=?\n WHERE id=? AND team=? AND claimed_by=? AND status='in_progress'`\n ).run(new Date().toISOString(), args.result ?? null, args.task_id, caller.team, args.caller)\n if (upd.changes !== 1) return { error: 'invalid_status' }\n this.events.append({\n from_team: caller.team, to_team: caller.team,\n event_type: 'task_completed', actor_agent_id: args.caller,\n payload: { task_id: args.task_id, result: args.result ?? null }\n })\n return { ok: true }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport interface TaskRow {\n id: string\n team: string\n title: string\n description: string | null\n status: 'pending' | 'in_progress' | 'completed'\n depends_on: string[]\n claimed_by: string | null\n claimed_at: string | null\n completed_at: string | null\n result: string | null\n created_at: string\n}\n\nexport class TaskListService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n list(args: { caller: string; status?: 'pending' | 'in_progress' | 'completed' }): { tasks: TaskRow[] } {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { tasks: [] }\n const sql = args.status\n ? `SELECT * FROM tasks WHERE team=? AND status=? ORDER BY created_at ASC`\n : `SELECT * FROM tasks WHERE team=? ORDER BY created_at ASC`\n const rows = (args.status\n ? this.db.prepare(sql).all(caller.team, args.status)\n : this.db.prepare(sql).all(caller.team)) as Array<TaskRow & { depends_on: string }>\n const tasks = rows.map(r => ({ ...r, depends_on: JSON.parse(r.depends_on as unknown as string) as string[] }))\n return { tasks }\n }\n}\n","export interface ContractDiff {\n added_fields: Array<{ path: string; type_summary: string }>\n removed_fields: Array<{ path: string; type_summary: string }>\n changed_fields: Array<{\n path: string\n from: { type?: string; required?: boolean; enum?: unknown[]; raw: unknown }\n to: { type?: string; required?: boolean; enum?: unknown[]; raw: unknown }\n }>\n breaking: boolean\n}\n\ntype Schema = Record<string, unknown> & {\n type?: string\n properties?: Record<string, Schema>\n required?: string[]\n enum?: unknown[]\n}\n\nfunction typeSummary(s: Schema | undefined): string {\n if (!s) return 'unknown'\n if (typeof s.type === 'string') return s.type\n return 'unknown'\n}\n\nfunction isRequired(parent: Schema, key: string): boolean {\n return Array.isArray(parent.required) && parent.required.includes(key)\n}\n\nfunction walk(\n fromParent: Schema, toParent: Schema, basePath: string,\n added: ContractDiff['added_fields'], removed: ContractDiff['removed_fields'], changed: ContractDiff['changed_fields']\n): void {\n const fp = fromParent.properties ?? {}\n const tp = toParent.properties ?? {}\n const keys = new Set<string>([...Object.keys(fp), ...Object.keys(tp)])\n for (const key of keys) {\n const path = `${basePath}/properties/${key}`\n const fromChild = fp[key]\n const toChild = tp[key]\n if (fromChild && !toChild) {\n removed.push({ path, type_summary: typeSummary(fromChild) })\n continue\n }\n if (!fromChild && toChild) {\n added.push({ path, type_summary: typeSummary(toChild) })\n continue\n }\n if (fromChild && toChild) {\n const fromType = typeof fromChild.type === 'string' ? fromChild.type : undefined\n const toType = typeof toChild.type === 'string' ? toChild.type : undefined\n const fromReq = isRequired(fromParent, key)\n const toReq = isRequired(toParent, key)\n const typeDiff = fromType !== toType\n const reqDiff = fromReq !== toReq\n if (typeDiff || reqDiff) {\n changed.push({\n path,\n from: { type: fromType, required: fromReq, enum: fromChild.enum, raw: fromChild },\n to: { type: toType, required: toReq, enum: toChild.enum, raw: toChild }\n })\n }\n if (toChild.type === 'object' || fromChild.type === 'object') {\n walk(fromChild, toChild, path, added, removed, changed)\n }\n }\n }\n}\n\nexport function diffSchema(from: Schema, to: Schema): ContractDiff {\n const added: ContractDiff['added_fields'] = []\n const removed: ContractDiff['removed_fields'] = []\n const changed: ContractDiff['changed_fields'] = []\n walk(from, to, '', added, removed, changed)\n const breaking =\n removed.length > 0 ||\n changed.some(c => c.from.required === false && c.to.required === true) ||\n changed.some(c => !!c.from.type && !!c.to.type && c.from.type !== c.to.type)\n return { added_fields: added, removed_fields: removed, changed_fields: changed, breaking }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport type { EventsOutbox } from '../storage/events-outbox.js'\nimport { diffSchema, type ContractDiff } from '../lib/schema-diff.js'\n\nexport interface RegisterContractMeta {\n team: string\n event_id: number\n diff: ContractDiff | null\n}\n\nexport type RegisterContractResult =\n | { name: string; version: number; diff?: ContractDiff; _meta?: RegisterContractMeta }\n | { error: 'unknown_agent' | 'invalid_format' }\n\nexport class RegisterContractService {\n constructor(\n private db: Database.Database,\n private agents: AgentsRepo,\n private events: EventsOutbox\n ) {}\n\n register(args: {\n caller: string; name: string; schema: Record<string, unknown>;\n format?: 'jsonschema'; note?: string\n }): RegisterContractResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const format = args.format ?? 'jsonschema'\n if (format !== 'jsonschema') return { error: 'invalid_format' }\n\n // better-sqlite3's .transaction() wraps BEGIN DEFERRED by default. We need IMMEDIATE\n // so multiple writers serialize cleanly. Use a raw BEGIN IMMEDIATE.\n const txFn = this.db.transaction((): RegisterContractResult => {\n const prev = this.db.prepare(\n `SELECT schema, version FROM contracts WHERE team=? AND name=? ORDER BY version DESC LIMIT 1`\n ).get(caller.team, args.name) as { schema: string; version: number } | undefined\n const version = prev ? prev.version + 1 : 1\n const now = new Date().toISOString()\n this.db.prepare(\n `INSERT INTO contracts (team, name, version, format, schema, note, registered_by, registered_at)\n VALUES (?,?,?,?,?,?,?,?)`\n ).run(caller.team, args.name, version, format, JSON.stringify(args.schema), args.note ?? null, args.caller, now)\n let diff: ContractDiff | undefined\n if (prev) diff = diffSchema(JSON.parse(prev.schema), args.schema as any)\n const event_id = this.events.append({\n from_team: caller.team,\n to_team: caller.team,\n event_type: 'contract_registered',\n actor_agent_id: args.caller,\n payload: { name: args.name, version, diff: diff ?? null }\n })\n const meta: RegisterContractMeta = { team: caller.team, event_id, diff: diff ?? null }\n return prev\n ? { name: args.name, version, diff: diff!, _meta: meta }\n : { name: args.name, version, _meta: meta }\n })\n return txFn.immediate()\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport type SubscribeResult =\n | { ok: true; current_version: number | null }\n | { error: 'unknown_agent' }\n\nexport class SubscribeContractService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n subscribe(args: { caller: string; name: string }): SubscribeResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n this.db.prepare(\n `INSERT INTO contract_subscriptions (agent_id, team, contract_name, subscribed_at)\n VALUES (?,?,?,?)\n ON CONFLICT(agent_id, team, contract_name) DO UPDATE SET subscribed_at=excluded.subscribed_at`\n ).run(args.caller, caller.team, args.name, new Date().toISOString())\n const latest = this.db.prepare(\n 'SELECT MAX(version) AS v FROM contracts WHERE team=? AND name=?'\n ).get(caller.team, args.name) as { v: number | null }\n return { ok: true, current_version: latest.v ?? null }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport type GetContractResult =\n | { name: string; version: number; schema: Record<string, unknown>; format: string; note: string | null; registered_at: string }\n | { error: 'unknown_contract' | 'unknown_version' | 'unknown_agent' }\n\nexport class GetContractService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n get(args: { caller: string; name: string; version?: number }): GetContractResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const row = args.version\n ? this.db.prepare('SELECT * FROM contracts WHERE team=? AND name=? AND version=?').get(caller.team, args.name, args.version)\n : this.db.prepare('SELECT * FROM contracts WHERE team=? AND name=? ORDER BY version DESC LIMIT 1').get(caller.team, args.name)\n if (!row) {\n const exists = this.db.prepare('SELECT 1 FROM contracts WHERE team=? AND name=? LIMIT 1').get(caller.team, args.name)\n return exists ? { error: 'unknown_version' } : { error: 'unknown_contract' }\n }\n const r = row as { name: string; version: number; schema: string; format: string; note: string | null; registered_at: string }\n return { name: r.name, version: r.version, schema: JSON.parse(r.schema), format: r.format, note: r.note, registered_at: r.registered_at }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\nimport { diffSchema, type ContractDiff } from '../lib/schema-diff.js'\n\nexport type DiffContractsResult =\n | ContractDiff\n | { error: 'unknown_contract' | 'unknown_version' | 'unknown_agent' }\n\nexport class DiffContractsService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n diff(args: { caller: string; name: string; from_version: number; to_version: number }): DiffContractsResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n const from = this.db.prepare('SELECT schema FROM contracts WHERE team=? AND name=? AND version=?')\n .get(caller.team, args.name, args.from_version) as { schema: string } | undefined\n const to = this.db.prepare('SELECT schema FROM contracts WHERE team=? AND name=? AND version=?')\n .get(caller.team, args.name, args.to_version) as { schema: string } | undefined\n if (!from || !to) {\n const exists = this.db.prepare('SELECT 1 FROM contracts WHERE team=? AND name=? LIMIT 1').get(caller.team, args.name)\n return exists ? { error: 'unknown_version' } : { error: 'unknown_contract' }\n }\n return diffSchema(JSON.parse(from.schema), JSON.parse(to.schema))\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport interface ContractEventOut {\n event_id: number\n contract_name: string\n version: number\n diff: unknown | null\n registered_at: string\n}\n\nexport class PendingContractEventsService {\n constructor(private db: Database.Database, private agents: AgentsRepo) {}\n\n poll(args: { caller: string; since_event_id?: number; limit?: number }): {\n events: ContractEventOut[]; has_more: boolean; last_event_id: number\n } {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { events: [], has_more: false, last_event_id: args.since_event_id ?? 0 }\n const limit = Math.min(args.limit ?? 100, 500)\n const since = args.since_event_id ?? 0\n const rows = this.db.prepare(\n `SELECT event_id, payload, created_at FROM events\n WHERE to_team=? AND event_type='contract_registered' AND event_id > ?\n ORDER BY event_id ASC LIMIT ?`\n ).all(caller.team, since, limit + 1) as Array<{ event_id: number; payload: string; created_at: string }>\n const has_more = rows.length > limit\n const trimmed = has_more ? rows.slice(0, limit) : rows\n const events = trimmed.map(r => {\n const p = JSON.parse(r.payload) as { name: string; version: number; diff: unknown | null }\n return { event_id: r.event_id, contract_name: p.name, version: p.version, diff: p.diff, registered_at: r.created_at }\n })\n const last_event_id = trimmed.length > 0 ? trimmed[trimmed.length - 1].event_id : since\n return { events, has_more, last_event_id }\n }\n}\n","import type Database from 'better-sqlite3'\nimport { randomBytes } from 'node:crypto'\nimport { parseDeliveryRow, type DeliverySpec } from '../lib/delivery-spec.js'\nimport {\n isTmuxAvailable,\n capturePaneTail,\n loadBuffer,\n pasteBuffer,\n sendEnter\n} from '../daemon/tmux-cli.js'\nimport type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\nimport { dispatchPoke, type TmuxPokeResult } from './transport-dispatch.js'\n\n// allowCrossTeam is for internal auto-poke callers only; MCP tool entry MUST NOT pass it.\nexport interface PokeDeps {\n db: Database.Database\n callerAgentId: string | null\n allowCrossTeam?: boolean\n channelWakeFanout?: ChannelWakeFanout\n}\n\nexport interface PokeInput {\n target_agent_id: string\n prompt: string\n}\n\nexport type PokeResult =\n | {\n ok: true\n transport_used: 'claude-channel'\n channel_session_id: string\n }\n | {\n ok: true\n transport_used: 'tmux-poke'\n pane_id: string\n pane_tail_before: string\n pane_tail_after: string\n }\n | {\n ok: true\n transport_used: 'codex-appserver'\n thread_id: string\n }\n | {\n error: string\n detail?: unknown\n transport_used?: 'tmux-poke' | 'codex-appserver'\n }\n\ninterface TargetRow {\n agent_id: string\n client: import('../lib/client-kind.js').ClientKind | null\n team: string\n tmux_pane_id: string | null\n delivery_kind: string\n delivery_payload: string | null\n}\n\nexport const PROMPT_MAX_BYTES = 8192\nexport const PASTE_SETTLE_MS = 400\nexport const TAIL_LINES = 8\n\ntype TmuxStage = 'capture_before' | 'load_buffer' | 'paste_buffer' | 'send_keys' | 'capture_after'\n\ninterface StageError {\n stage: TmuxStage\n cause: unknown\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nfunction errorMessage(cause: unknown): string {\n if (cause && typeof cause === 'object') {\n const err = cause as { stderr?: string | Buffer; message?: string }\n if (err.stderr) {\n const s = typeof err.stderr === 'string' ? err.stderr : err.stderr.toString('utf8')\n if (s.length > 0) return s\n }\n if (err.message) return err.message\n }\n return String(cause)\n}\n\nexport function classifyTmuxError(err: StageError): { error: string; detail: unknown } {\n const msg = errorMessage(err.cause)\n const lower = msg.toLowerCase()\n if (lower.includes(\"can't find pane\") || lower.includes('pane not found') || lower.includes('no such pane')) {\n return { error: 'pane_dead', detail: msg }\n }\n return { error: 'tmux_cmd_failed', detail: { stage: err.stage, stderr: msg } }\n}\n\nasync function runStage<T>(stage: TmuxStage, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn()\n } catch (cause) {\n throw { stage, cause } as StageError\n }\n}\n\nasync function tmuxPokeImpl(args: { pane_id: string; content: string }): Promise<TmuxPokeResult> {\n if (!(await isTmuxAvailable())) {\n return { error: 'tmux_unavailable', detail: 'tmux binary not available on PATH' }\n }\n const bufName = `poke-${randomBytes(3).toString('hex')}`\n try {\n const pane_tail_before = await runStage('capture_before', () => capturePaneTail(args.pane_id, TAIL_LINES))\n await runStage('load_buffer', () => loadBuffer(bufName, args.content))\n await runStage('paste_buffer', () => pasteBuffer(bufName, args.pane_id))\n await delay(PASTE_SETTLE_MS)\n await runStage('send_keys', () => sendEnter(args.pane_id))\n await delay(PASTE_SETTLE_MS)\n const pane_tail_after = await runStage('capture_after', () => capturePaneTail(args.pane_id, TAIL_LINES))\n return { ok: true, pane_tail_before, pane_tail_after }\n } catch (e) {\n return classifyTmuxError(e as StageError)\n }\n}\n\nexport async function poke(deps: PokeDeps, input: PokeInput): Promise<PokeResult> {\n if (!deps.callerAgentId) return { error: 'unknown_agent' }\n\n const promptLen = Buffer.byteLength(input.prompt, 'utf8')\n if (promptLen > PROMPT_MAX_BYTES) {\n return { error: 'prompt_too_long', detail: { max: PROMPT_MAX_BYTES, got: promptLen } }\n }\n\n const target = deps.db\n .prepare(\n `SELECT\n agent_id,\n client,\n team,\n tmux_pane_id,\n delivery_kind,\n delivery_payload\n FROM agents\n WHERE agent_id = ?`\n )\n .get(input.target_agent_id) as TargetRow | undefined\n if (!target) return { error: 'unknown_target' }\n\n if (target.agent_id === deps.callerAgentId) return { error: 'self_poke_denied' }\n\n const callerRow = deps.db\n .prepare(`SELECT team FROM agents WHERE agent_id = ?`)\n .get(deps.callerAgentId) as { team: string } | undefined\n if (!callerRow) return { error: 'unknown_agent' }\n if (callerRow.team !== target.team && !deps.allowCrossTeam) {\n return { error: 'cross_team_denied' }\n }\n\n // Legacy callers may not have ChannelWakeFanout. Keep the historical tmux-only\n // fallback for plain targets, but still allow non-tmux transports that are\n // fully described by the target row itself.\n const fanout = deps.channelWakeFanout\n const delivery = parseDeliveryRow(target) as DeliverySpec\n if (!fanout) {\n if (delivery.kind === 'codex-appserver') {\n return dispatchPoke(\n { tmuxPoke: tmuxPokeImpl },\n { client: target.client, delivery, tmux_pane_id: target.tmux_pane_id },\n { content: input.prompt, meta: {} }\n )\n }\n\n // Legacy tmux-only path preserved when no fanout supplied by caller.\n if (!target.tmux_pane_id) return { error: 'tmux_pane_not_set' }\n const tr = await tmuxPokeImpl({ pane_id: target.tmux_pane_id, content: input.prompt })\n if ('ok' in tr && tr.ok) {\n return {\n ok: true,\n transport_used: 'tmux-poke',\n pane_id: target.tmux_pane_id,\n pane_tail_before: tr.pane_tail_before,\n pane_tail_after: tr.pane_tail_after\n }\n }\n return { ...(tr as { error: string; detail?: unknown }), transport_used: 'tmux-poke' }\n }\n\n return dispatchPoke(\n { channelWakeFanout: fanout, tmuxPoke: tmuxPokeImpl },\n { client: target.client, delivery, tmux_pane_id: target.tmux_pane_id },\n { content: input.prompt, meta: {} }\n )\n}\n","import type { ChannelWakeFanout } from './channel-wake-fanout.js'\n\nconst META_KEY_RE = /^[A-Za-z0-9_]+$/\n\nexport interface ChannelWakeInput {\n content: string\n meta: Record<string, string>\n}\n\nexport type SendChannelWakeResult =\n | { ok: true }\n | { ok: false; reason: 'no_subscriber' }\n\nfunction sanitizeMeta(meta: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(meta)) {\n if (META_KEY_RE.test(k)) out[k] = v\n }\n return out\n}\n\nexport function sendChannelWake(\n fanout: ChannelWakeFanout,\n channel_session_id: string,\n input: ChannelWakeInput\n): SendChannelWakeResult {\n if (!fanout.has(channel_session_id)) return { ok: false, reason: 'no_subscriber' }\n const payload = {\n jsonrpc: '2.0' as const,\n method: 'notifications/channel_wake' as const,\n params: {\n content: input.content,\n meta: sanitizeMeta(input.meta)\n }\n }\n fanout.send(channel_session_id, payload)\n return { ok: true }\n}\n","type Json = unknown\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0'\n id: number\n method: string\n params: Json\n}\n\ninterface JsonRpcNotification {\n jsonrpc: '2.0'\n method: string\n params?: Json\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: '2.0'\n id: number\n result?: Json\n error?: { code: number; message: string; data?: Json }\n}\n\ntype MessageEventLike = { data: unknown }\ntype ErrorEventLike = { error?: unknown; message?: string }\ntype CloseEventLike = { code?: number; reason?: string }\n\nexport interface WebSocketLike {\n addEventListener(\n type: 'open' | 'message' | 'error' | 'close',\n listener: (event: unknown) => void\n ): void\n removeEventListener?(\n type: 'open' | 'message' | 'error' | 'close',\n listener: (event: unknown) => void\n ): void\n send(data: string): void\n close(): void\n}\n\nexport interface CodexWebSocketFactoryArgs {\n url: string\n headers?: Record<string, string>\n}\n\nexport type CodexWebSocketFactory = (\n args: CodexWebSocketFactoryArgs\n) => WebSocketLike\n\ntype PendingResolver = {\n resolve: (value: JsonRpcResponse) => void\n reject: (reason?: unknown) => void\n}\n\nexport function defaultWebSocketFactory(\n args: CodexWebSocketFactoryArgs\n): WebSocketLike {\n const ctor = globalThis.WebSocket as unknown as new (\n url: string,\n options?: { headers?: Record<string, string> }\n ) => WebSocketLike\n return new ctor(\n args.url,\n args.headers === undefined ? undefined : { headers: args.headers }\n )\n}\n\nexport function describeError(error: unknown): string {\n if (error instanceof Error && error.message.length > 0) return error.message\n if (typeof error === 'string' && error.length > 0) return error\n if (error && typeof error === 'object') {\n const record = error as Record<string, unknown>\n const message = record.message\n if (typeof message === 'string' && message.length > 0) return message\n const reason = record.reason\n if (typeof reason === 'string' && reason.length > 0) return reason\n }\n return String(error)\n}\n\nfunction closeDetail(event: CloseEventLike): string {\n const code = typeof event.code === 'number' ? event.code : 'unknown'\n const reason = typeof event.reason === 'string' && event.reason.length > 0\n ? event.reason\n : 'socket_closed'\n return `close ${code}: ${reason}`\n}\n\nfunction decodeMessageData(data: unknown): string {\n if (typeof data === 'string') return data\n if (data instanceof ArrayBuffer) {\n return new TextDecoder().decode(new Uint8Array(data))\n }\n if (ArrayBuffer.isView(data)) {\n return new TextDecoder().decode(data)\n }\n return String(data)\n}\n\nexport function safeClose(ws: WebSocketLike): void {\n try {\n ws.close()\n } catch {\n return\n }\n}\n\nexport function resolveAuthToken(\n authTokenRef: string | undefined,\n env: NodeJS.ProcessEnv\n): { ok: string | undefined } | { error: 'missing_auth_token'; detail: { ref: string } } {\n if (authTokenRef === undefined) return { ok: undefined }\n const token = env[authTokenRef]?.trim()\n if (!token) {\n return {\n error: 'missing_auth_token',\n detail: { ref: authTokenRef },\n }\n }\n return { ok: token }\n}\n\nexport class JsonRpcSocketClient {\n private nextId = 1\n private readonly pending = new Map<number, PendingResolver>()\n private openState:\n | { kind: 'pending'; promise: Promise<void> }\n | { kind: 'open' }\n | { kind: 'failed'; error: unknown }\n\n constructor(private readonly ws: WebSocketLike) {\n this.openState = {\n kind: 'pending',\n promise: new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup()\n this.openState = { kind: 'open' }\n resolve()\n }\n const onError = (event: unknown) => {\n cleanup()\n const detail = event as ErrorEventLike\n const error = detail.error ?? detail.message ?? 'websocket_error'\n this.openState = { kind: 'failed', error }\n reject(error)\n }\n const onClose = (event: unknown) => {\n cleanup()\n const closeEvent = event as CloseEventLike\n const error = closeDetail(closeEvent)\n this.openState = { kind: 'failed', error }\n reject(error)\n }\n const cleanup = () => {\n this.ws.removeEventListener?.('open', onOpen)\n this.ws.removeEventListener?.('error', onError)\n this.ws.removeEventListener?.('close', onClose)\n }\n this.ws.addEventListener('open', onOpen)\n this.ws.addEventListener('error', onError)\n this.ws.addEventListener('close', onClose)\n }),\n }\n\n this.ws.addEventListener('message', (event) => {\n let message: JsonRpcResponse\n try {\n message = JSON.parse(decodeMessageData((event as MessageEventLike).data))\n } catch {\n return\n }\n if (typeof message.id !== 'number') return\n const pending = this.pending.get(message.id)\n if (!pending) return\n this.pending.delete(message.id)\n pending.resolve(message)\n })\n\n this.ws.addEventListener('error', (event) => {\n if (this.openState.kind !== 'open') return\n const detail = event as ErrorEventLike\n const error = detail.error ?? detail.message ?? 'websocket_error'\n this.rejectAll(error)\n })\n\n this.ws.addEventListener('close', (event) => {\n if (this.openState.kind !== 'open') return\n this.rejectAll(closeDetail(event as CloseEventLike))\n })\n }\n\n async waitForOpen(): Promise<void> {\n if (this.openState.kind === 'open') return\n if (this.openState.kind === 'failed') throw this.openState.error\n await this.openState.promise\n }\n\n request(method: string, params: Json): Promise<JsonRpcResponse> {\n const id = this.nextId++\n const request: JsonRpcRequest = { jsonrpc: '2.0', id, method, params }\n return new Promise<JsonRpcResponse>((resolve, reject) => {\n this.pending.set(id, { resolve, reject })\n try {\n this.ws.send(JSON.stringify(request))\n } catch (error) {\n this.pending.delete(id)\n reject(error)\n }\n })\n }\n\n notify(method: string, params?: Json): void {\n const notification: JsonRpcNotification = {\n jsonrpc: '2.0',\n method,\n ...(params === undefined ? {} : { params }),\n }\n this.ws.send(JSON.stringify(notification))\n }\n\n private rejectAll(error: unknown): void {\n const pending = [...this.pending.values()]\n this.pending.clear()\n for (const entry of pending) {\n entry.reject(error)\n }\n }\n}\n","import type { DeliveryCodexAppserver } from '../lib/delivery-spec.js'\nimport {\n JsonRpcSocketClient,\n defaultWebSocketFactory,\n describeError,\n resolveAuthToken,\n safeClose,\n type CodexWebSocketFactory,\n type JsonRpcResponse,\n type WebSocketLike,\n} from './codex-appserver-rpc.js'\nexport type { WebSocketLike } from './codex-appserver-rpc.js'\n\ntype Json = unknown\n\nexport interface CodexAppserverDispatchDeps {\n env?: NodeJS.ProcessEnv\n webSocketFactory?: CodexWebSocketFactory\n}\n\nexport type CodexAppserverDispatchResult =\n | {\n ok: true\n transport_used: 'codex-appserver'\n thread_id: string\n }\n | {\n error:\n | 'missing_auth_token'\n | 'codex_connect_failed'\n | 'codex_initialize_failed'\n | 'codex_resume_failed'\n | 'codex_turn_start_failed'\n detail?: unknown\n transport_used?: 'codex-appserver'\n }\n\nasync function requestStep(\n client: JsonRpcSocketClient,\n method: string,\n params: Json\n): Promise<\n | { ok: JsonRpcResponse }\n | {\n error:\n | 'codex_initialize_failed'\n | 'codex_resume_failed'\n | 'codex_turn_start_failed'\n detail: unknown\n }\n> {\n try {\n const response = await client.request(method, params)\n if (response.error) {\n const mappedError =\n method === 'initialize'\n ? 'codex_initialize_failed'\n : method === 'thread/resume'\n ? 'codex_resume_failed'\n : 'codex_turn_start_failed'\n return { error: mappedError, detail: response.error }\n }\n return { ok: response }\n } catch (error) {\n const mappedError =\n method === 'initialize'\n ? 'codex_initialize_failed'\n : method === 'thread/resume'\n ? 'codex_resume_failed'\n : 'codex_turn_start_failed'\n return { error: mappedError, detail: describeError(error) }\n }\n}\n\nexport async function dispatchCodexAppserverPoke(\n input: {\n delivery: DeliveryCodexAppserver\n content: string\n },\n deps: CodexAppserverDispatchDeps = {}\n): Promise<CodexAppserverDispatchResult> {\n const authToken = resolveAuthToken(\n input.delivery.auth_token_ref,\n deps.env ?? process.env\n )\n if ('error' in authToken) return authToken\n\n const headers = authToken.ok === undefined\n ? undefined\n : { Authorization: `Bearer ${authToken.ok}` }\n\n let ws: WebSocketLike\n try {\n ws = (deps.webSocketFactory ?? defaultWebSocketFactory)({\n url: input.delivery.ws_url,\n headers,\n })\n } catch (error) {\n return {\n error: 'codex_connect_failed',\n detail: describeError(error),\n transport_used: 'codex-appserver',\n }\n }\n\n const client = new JsonRpcSocketClient(ws)\n try {\n await client.waitForOpen()\n\n const init = await requestStep(client, 'initialize', {\n clientInfo: {\n name: 'cross-agent-teams-mcp',\n title: null,\n version: '0.1.0',\n },\n capabilities: {\n experimentalApi: true,\n optOutNotificationMethods: null,\n },\n })\n if ('error' in init) {\n return {\n error: init.error,\n detail: init.detail,\n transport_used: 'codex-appserver',\n }\n }\n\n client.notify('initialized')\n\n const resume = await requestStep(client, 'thread/resume', {\n threadId: input.delivery.thread_id,\n persistExtendedHistory: false,\n })\n if ('error' in resume) {\n return {\n error: resume.error,\n detail: resume.detail,\n transport_used: 'codex-appserver',\n }\n }\n\n const turnStart = await requestStep(client, 'turn/start', {\n threadId: input.delivery.thread_id,\n input: [{ type: 'text', text: input.content, text_elements: [] }],\n })\n if ('error' in turnStart) {\n return {\n error: turnStart.error,\n detail: turnStart.detail,\n transport_used: 'codex-appserver',\n }\n }\n\n return {\n ok: true,\n transport_used: 'codex-appserver',\n thread_id: input.delivery.thread_id,\n }\n } catch (error) {\n return {\n error: 'codex_connect_failed',\n detail: describeError(error),\n transport_used: 'codex-appserver',\n }\n } finally {\n safeClose(ws)\n }\n}\n","import type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\nimport { sendChannelWake } from '../daemon/channel-wake-send.js'\nimport type { ClientKind } from '../lib/client-kind.js'\nimport type { DeliverySpec } from '../lib/delivery-spec.js'\nimport {\n dispatchCodexAppserverPoke,\n type CodexAppserverDispatchResult,\n} from './codex-appserver-dispatch.js'\n\nexport interface DispatchDeps {\n channelWakeFanout?: ChannelWakeFanout\n tmuxPoke: (args: { pane_id: string; content: string }) => Promise<TmuxPokeResult>\n codexAppserverDispatch?: (args: {\n delivery: Extract<DeliverySpec, { kind: 'codex-appserver' }>\n content: string\n }) => Promise<CodexAppserverDispatchResult>\n}\n\nexport type TmuxPokeResult =\n | { ok: true; pane_tail_before: string; pane_tail_after: string }\n | { error: string; detail?: unknown }\n\nexport interface TargetRow {\n client: ClientKind | null\n delivery: DeliverySpec\n tmux_pane_id: string | null\n}\n\nexport interface DispatchInput {\n content: string\n meta: Record<string, string>\n}\n\nexport type DispatchResult =\n | {\n ok: true\n transport_used: 'claude-channel'\n channel_session_id: string\n }\n | {\n ok: true\n transport_used: 'tmux-poke'\n pane_id: string\n pane_tail_before: string\n pane_tail_after: string\n }\n | {\n ok: true\n transport_used: 'codex-appserver'\n thread_id: string\n }\n | {\n error: string\n detail?: unknown\n transport_used?: 'tmux-poke' | 'codex-appserver'\n }\n\nexport async function dispatchPoke(\n deps: DispatchDeps,\n target: TargetRow,\n input: DispatchInput\n): Promise<DispatchResult> {\n const client = resolveClient(target)\n if (client === 'claude-code') return dispatchClaude(deps, target, input)\n if (client === 'codex') return dispatchCodex(deps, target, input)\n return dispatchUnknown(deps, target, input)\n}\n\nfunction resolveClient(target: TargetRow): ClientKind | null {\n if (target.client) return target.client\n if (target.delivery.kind === 'claude-channel') return 'claude-code'\n if (target.delivery.kind === 'codex-appserver') return 'codex'\n return null\n}\n\nasync function dispatchTmux(\n deps: DispatchDeps,\n paneId: string,\n content: string\n): Promise<DispatchResult> {\n const tmuxResult = await deps.tmuxPoke({ pane_id: paneId, content })\n if ('ok' in tmuxResult && tmuxResult.ok) {\n return {\n ok: true,\n transport_used: 'tmux-poke',\n pane_id: paneId,\n pane_tail_before: tmuxResult.pane_tail_before,\n pane_tail_after: tmuxResult.pane_tail_after,\n }\n }\n return {\n ...(tmuxResult as { error: string; detail?: unknown }),\n transport_used: 'tmux-poke',\n }\n}\n\nasync function dispatchClaude(\n deps: DispatchDeps,\n target: TargetRow,\n input: DispatchInput\n): Promise<DispatchResult> {\n const paneId = target.tmux_pane_id\n const channelSubscribed =\n target.delivery.kind === 'claude-channel' &&\n (deps.channelWakeFanout?.has(target.delivery.channel_session_id) ?? false)\n\n if (target.delivery.kind === 'claude-channel' && channelSubscribed && deps.channelWakeFanout) {\n const result = sendChannelWake(\n deps.channelWakeFanout,\n target.delivery.channel_session_id,\n input\n )\n if (result.ok) {\n return {\n ok: true,\n transport_used: 'claude-channel',\n channel_session_id: target.delivery.channel_session_id,\n }\n }\n }\n\n if (paneId) return dispatchTmux(deps, paneId, input.content)\n return {\n error: 'no_transport_available',\n detail: {\n channel_subscribed: channelSubscribed,\n tmux_pane_set: false,\n },\n }\n}\n\nasync function dispatchCodex(\n deps: DispatchDeps,\n target: TargetRow,\n input: DispatchInput\n): Promise<DispatchResult> {\n const paneId = target.tmux_pane_id\n if (target.delivery.kind === 'codex-appserver') {\n const result = await (deps.codexAppserverDispatch ?? dispatchCodexAppserverPoke)({\n delivery: target.delivery,\n content: input.content,\n })\n if ('ok' in result && result.ok) return result\n if (paneId) return dispatchTmux(deps, paneId, input.content)\n return result\n }\n if (paneId) return dispatchTmux(deps, paneId, input.content)\n return {\n error: 'no_transport_available',\n detail: {\n codex_bound: false,\n tmux_pane_set: false,\n },\n }\n}\n\nasync function dispatchUnknown(\n deps: DispatchDeps,\n target: TargetRow,\n input: DispatchInput\n): Promise<DispatchResult> {\n const paneId = target.tmux_pane_id\n if (paneId) return dispatchTmux(deps, paneId, input.content)\n return {\n error: 'no_transport_available',\n detail: {\n channel_subscribed: false,\n tmux_pane_set: false,\n },\n }\n}\n","const STORAGE_CODES = new Set(['SQLITE_FULL','SQLITE_BUSY','SQLITE_IOERR','SQLITE_LOCKED','SQLITE_READONLY'])\n\nexport function isStorageError(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false\n const anyErr = err as { name?: string; code?: string }\n if (anyErr.name === 'SqliteError') return true\n if (anyErr.code && STORAGE_CODES.has(anyErr.code)) return true\n return false\n}\n\nexport async function wrapStorage<T>(fn: () => Promise<T> | T): Promise<T | { error: 'storage_unavailable' }> {\n try {\n return await fn()\n } catch (err) {\n if (isStorageError(err)) return { error: 'storage_unavailable' }\n throw err\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { ChannelWakeFanout, ChannelWakeSink } from '../daemon/channel-wake-fanout.js'\n\nexport const CHANNEL_PROXY_ROLE = '__channel_proxy__'\n\nexport interface SubscribeInput {\n callerAgentId: string\n channel_session_id: string\n sessionId: string\n sink: ChannelWakeSink\n}\n\nexport type SubscribeResult =\n | { ok: true }\n | { error: 'unknown_agent' | 'forbidden_role' | 'invalid_channel_session_id' }\n\nexport class SubscribeChannelWakeService {\n constructor(private readonly db: Database.Database, private readonly fanout: ChannelWakeFanout) {}\n\n subscribe(input: SubscribeInput): SubscribeResult {\n const csid = input.channel_session_id?.trim()\n if (!csid) return { error: 'invalid_channel_session_id' }\n const row = this.db\n .prepare(`SELECT role FROM agents WHERE agent_id=?`)\n .get(input.callerAgentId) as { role: string } | undefined\n if (!row) return { error: 'unknown_agent' }\n if (row.role !== CHANNEL_PROXY_ROLE) return { error: 'forbidden_role' }\n this.fanout.attach(csid, input.sink, input.sessionId)\n return { ok: true }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\nimport { AgentsRepo } from '../storage/agents-repo.js'\nimport { CHANNEL_PROXY_ROLE } from './subscribe-channel-wake.js'\n\nexport interface BindInput {\n callerAgentId: string\n channel_session_id: string\n}\n\nexport type BindResult =\n | { ok: true }\n | { error: 'unknown_agent' | 'forbidden_role' | 'invalid_channel_session_id' | 'unknown_channel_session' }\n\nexport class BindChannelService {\n private readonly repo: AgentsRepo\n\n constructor(\n db: Database.Database,\n private readonly fanout: ChannelWakeFanout\n ) {\n this.repo = new AgentsRepo(db)\n }\n\n bind(input: BindInput): BindResult {\n const csid = input.channel_session_id?.trim()\n if (!csid) return { error: 'invalid_channel_session_id' }\n const caller = this.repo.getById(input.callerAgentId)\n if (!caller) return { error: 'unknown_agent' }\n if (caller.role === CHANNEL_PROXY_ROLE) return { error: 'forbidden_role' }\n if (!this.fanout.has(csid)) return { error: 'unknown_channel_session' }\n this.repo.setClient(input.callerAgentId, 'claude-code')\n this.repo.setDelivery(input.callerAgentId, {\n kind: 'claude-channel',\n channel_session_id: csid,\n })\n return { ok: true }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { ChannelWakeFanout } from '../daemon/channel-wake-fanout.js'\nimport { CHANNEL_PROXY_ROLE } from './subscribe-channel-wake.js'\n\nconst LIVE_WINDOW_MS = 5 * 60 * 1000\n\nexport interface AutoBindInput {\n callerAgentId: string\n ui_pid: number\n}\n\nexport interface LookupInput {\n ui_pid: number\n}\n\nexport interface AutoBindSuccess {\n ok: true\n channel_session_id: string\n}\n\nexport interface AutoBindMiss {\n ok: false\n reason: 'no_proxy_row' | 'proxy_payload_corrupt' | 'sink_not_live'\n}\n\nexport type AutoBindResult = AutoBindSuccess | AutoBindMiss\n\nexport interface LookupSuccess {\n ok: true\n channel_session_id: string\n}\n\nexport interface LookupMiss {\n ok: false\n reason: 'no_proxy_row' | 'proxy_payload_corrupt'\n}\n\nexport type LookupResult = LookupSuccess | LookupMiss\n\ninterface ProxyRow {\n delivery_payload: string | null\n}\n\n/**\n * Best-effort: match a live __channel_proxy__ row keyed on claude_ui_pid, and\n * write the caller's delivery to that proxy's csid. Failure returns `ok:false`\n * with a reason — the caller treats this as \"no auto-bind performed\" and leaves\n * existing delivery unchanged.\n */\nexport class AutoBindChannelService {\n constructor(\n private readonly db: Database.Database,\n private readonly fanout: ChannelWakeFanout\n ) {}\n\n lookup(input: LookupInput): LookupResult {\n return this.findLiveProxyCsid(input)\n }\n\n run(input: AutoBindInput): AutoBindResult {\n const found = this.findLiveProxyCsid({ ui_pid: input.ui_pid })\n if (!found.ok) return found\n const csid = found.channel_session_id\n if (!this.fanout.has(csid)) return { ok: false, reason: 'sink_not_live' }\n this.db\n .prepare(\n `UPDATE agents\n SET delivery_kind = 'claude-channel',\n delivery_payload = json_object('channel_session_id', ?)\n WHERE agent_id = ?`\n )\n .run(csid, input.callerAgentId)\n return { ok: true, channel_session_id: csid }\n }\n\n private findLiveProxyCsid(input: LookupInput): LookupResult {\n const cutoff = new Date(Date.now() - LIVE_WINDOW_MS).toISOString()\n const row = this.db\n .prepare(\n `SELECT delivery_payload\n FROM agents\n WHERE role = ?\n AND claude_ui_pid = ?\n AND last_seen_at > ?\n ORDER BY last_seen_at DESC\n LIMIT 1`\n )\n .get(CHANNEL_PROXY_ROLE, input.ui_pid, cutoff) as ProxyRow | undefined\n if (!row) return { ok: false, reason: 'no_proxy_row' }\n const csid = extractCsid(row.delivery_payload)\n if (!csid) return { ok: false, reason: 'proxy_payload_corrupt' }\n return { ok: true, channel_session_id: csid }\n }\n}\n\nfunction extractCsid(payload: string | null): string | null {\n if (payload === null) return null\n try {\n const parsed = JSON.parse(payload) as Record<string, unknown>\n const csid = parsed.channel_session_id\n if (typeof csid !== 'string' || csid.length === 0) return null\n return csid\n } catch {\n return null\n }\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { DetectAgentKind } from './tmux-pane-detect.js'\n\nconst TMUX_LIST_TIMEOUT_MS = 3_000\nconst PS_LIST_TIMEOUT_MS = 3_000\n\nexport interface BindRuntimeIdentityInput {\n agent: DetectAgentKind\n ui_pid?: number\n ui_tty?: string\n tmux_pane_id?: string\n process_pattern?: string\n}\n\nexport type BindRuntimeIdentityResult =\n | {\n ok: true\n tmux_pane_id: string\n verification_mode: 'verified_pid_tty_pane' | 'verified_tty_pane'\n tty: string\n ui_pid?: number\n }\n | { error: 'invalid_runtime_identity' }\n | { error: 'invalid_process_pattern' }\n | { error: 'invalid_ui_pid' }\n | { error: 'pid_not_found' }\n | { error: 'pid_has_no_tty' }\n | { error: 'agent_process_mismatch' }\n | { error: 'invalid_ui_tty' }\n | { error: 'tmux_unavailable'; detail: string }\n | { error: 'tmux_pane_not_found' }\n | { error: 'pid_pane_tty_mismatch'; detail: { pid_tty: string; pane_tty: string } }\n | { error: 'tty_maps_to_no_agent_process' }\n | { error: 'ambiguous_tty_match'; candidates: Array<{ pane_id: string; tty: string }> }\n\nexport interface BindRuntimeIdentityDeps {\n execFile?: typeof execFile\n}\n\ninterface PaneRow {\n pane_id: string\n tty: string\n}\n\nfunction normalizeTty(raw: string | undefined): string | undefined {\n const value = raw?.trim()\n if (!value) return undefined\n const normalized = value.replace(/^\\/dev\\//, '')\n if (!normalized || normalized === '?') return undefined\n return normalized\n}\n\nfunction commandPattern(args: BindRuntimeIdentityInput): RegExp | null {\n if (args.agent === 'custom') {\n const raw = args.process_pattern?.trim()\n if (!raw) return null\n return new RegExp(raw, 'i')\n }\n if (args.agent === 'codex') {\n return /(^|[\\s/])(codex|codex-aarch64-a)([\\s]|$)/i\n }\n if (args.agent === 'claude-code') {\n return /(^|[\\s/])claude([\\s]|$)/i\n }\n return /(^|[\\s/])opencode([\\s]|$)/i\n}\n\nasync function listPanes(execLike: typeof execFile): Promise<PaneRow[]> {\n const exec = promisify(execLike)\n const { stdout } = await exec(\n 'tmux',\n ['list-panes', '-a', '-F', '#{pane_id}\\t#{pane_tty}'],\n { timeout: TMUX_LIST_TIMEOUT_MS }\n )\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n .map((line) => {\n const [pane_id, pane_tty] = line.split('\\t')\n return {\n pane_id,\n tty: normalizeTty(pane_tty) ?? '',\n }\n })\n}\n\nasync function readPidInfo(\n execLike: typeof execFile,\n pid: number\n): Promise<{ found: boolean; tty?: string; command?: string }> {\n const exec = promisify(execLike)\n try {\n const { stdout } = await exec(\n 'ps',\n ['-p', String(pid), '-o', 'tty=,command='],\n { timeout: PS_LIST_TIMEOUT_MS }\n )\n const line = stdout\n .split('\\n')\n .map(value => value.trim())\n .find(Boolean)\n if (!line) return { found: false }\n const match = line.match(/^(\\S+)\\s+(.*)$/)\n if (!match) return { found: false }\n return {\n found: true,\n tty: normalizeTty(match[1]),\n command: match[2]?.trim(),\n }\n } catch {\n return { found: false }\n }\n}\n\nasync function ttyProcesses(\n execLike: typeof execFile,\n tty: string\n): Promise<string[]> {\n const exec = promisify(execLike)\n const { stdout } = await exec(\n 'ps',\n ['-t', tty, '-o', 'pid=,ppid=,stat=,command='],\n { timeout: PS_LIST_TIMEOUT_MS }\n )\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n}\n\nfunction matchAgentProcess(\n agent: DetectAgentKind,\n lines: string[],\n pattern: RegExp\n): boolean {\n return lines.some((line) => {\n if (isHelperProcess(agent, line)) return false\n return pattern.test(line)\n })\n}\n\nfunction isHelperProcess(agent: DetectAgentKind, command: string): boolean {\n if (agent !== 'codex') return false\n return /codex\\s+app-server/i.test(command) ||\n /Codex Computer Use\\.app/i.test(command) ||\n /SkyComputerUseClient/i.test(command)\n}\n\nexport async function bindRuntimeIdentity(\n input: BindRuntimeIdentityInput,\n deps: BindRuntimeIdentityDeps = {}\n): Promise<BindRuntimeIdentityResult> {\n const execLike = deps.execFile ?? execFile\n const pattern = commandPattern(input)\n if (!pattern) return { error: 'invalid_process_pattern' }\n\n let panes: PaneRow[]\n try {\n panes = await listPanes(execLike)\n } catch (error) {\n return {\n error: 'tmux_unavailable',\n detail: error instanceof Error ? error.message : String(error),\n }\n }\n\n if (input.ui_pid !== undefined) {\n if (!Number.isInteger(input.ui_pid) || input.ui_pid <= 0) {\n return { error: 'invalid_ui_pid' }\n }\n const pidInfo = await readPidInfo(execLike, input.ui_pid)\n if (!pidInfo.found) return { error: 'pid_not_found' }\n if (\n !pidInfo.command ||\n isHelperProcess(input.agent, pidInfo.command) ||\n !pattern.test(pidInfo.command)\n ) {\n return { error: 'agent_process_mismatch' }\n }\n if (!pidInfo.tty) return { error: 'pid_has_no_tty' }\n const candidates = panes.filter(pane => pane.tty === pidInfo.tty)\n if (candidates.length === 0) return { error: 'tmux_pane_not_found' }\n if (candidates.length > 1) {\n return {\n error: 'ambiguous_tty_match',\n candidates: candidates.map(candidate => ({\n pane_id: candidate.pane_id,\n tty: candidate.tty,\n })),\n }\n }\n const candidate = candidates[0]\n const explicitPane = input.tmux_pane_id?.trim()\n if (explicitPane && explicitPane !== candidate.pane_id) {\n return {\n error: 'pid_pane_tty_mismatch',\n detail: {\n pid_tty: pidInfo.tty,\n pane_tty: candidate.tty,\n },\n }\n }\n return {\n ok: true,\n tmux_pane_id: candidate.pane_id,\n verification_mode: 'verified_pid_tty_pane',\n tty: pidInfo.tty,\n ui_pid: input.ui_pid,\n }\n }\n\n const tty = normalizeTty(input.ui_tty)\n const paneId = input.tmux_pane_id?.trim()\n if (!tty || !paneId) return { error: 'invalid_runtime_identity' }\n const pane = panes.find(candidate => candidate.pane_id === paneId)\n if (!pane) return { error: 'tmux_pane_not_found' }\n if (pane.tty !== tty) {\n return {\n error: 'pid_pane_tty_mismatch',\n detail: {\n pid_tty: tty,\n pane_tty: pane.tty,\n },\n }\n }\n const processes = await ttyProcesses(execLike, tty)\n if (!matchAgentProcess(input.agent, processes, pattern)) {\n return { error: 'tty_maps_to_no_agent_process' }\n }\n return {\n ok: true,\n tmux_pane_id: paneId,\n verification_mode: 'verified_tty_pane',\n tty,\n }\n}\n","import type Database from 'better-sqlite3'\nimport {\n bindRuntimeIdentity,\n type BindRuntimeIdentityInput,\n type BindRuntimeIdentityResult,\n} from '../daemon/runtime-identity.js'\nimport { AgentsRepo } from '../storage/agents-repo.js'\n\nexport interface BindRuntimeIdentityServiceInput extends BindRuntimeIdentityInput {\n callerAgentId: string\n}\n\nexport type BindRuntimeIdentityServiceResult =\n | ({ ok: true } & Omit<Extract<BindRuntimeIdentityResult, { ok: true }>, 'ok'>)\n | Extract<BindRuntimeIdentityResult, { error: string }>\n | { error: 'unknown_agent' }\n\nexport class BindRuntimeIdentityService {\n private readonly repo: AgentsRepo\n\n constructor(db: Database.Database) {\n this.repo = new AgentsRepo(db)\n }\n\n async bind(\n input: BindRuntimeIdentityServiceInput\n ): Promise<BindRuntimeIdentityServiceResult> {\n const caller = this.repo.getById(input.callerAgentId)\n if (!caller) return { error: 'unknown_agent' }\n\n const result = await bindRuntimeIdentity(input)\n if (!('ok' in result) || !result.ok) return result\n\n this.repo.setRuntimeBinding(input.callerAgentId, {\n tmux_pane_id: result.tmux_pane_id,\n runtime_ui_pid: result.ui_pid ?? null,\n runtime_tty: result.tty,\n runtime_verification_mode: result.verification_mode,\n })\n\n return result\n }\n}\n","import { RegisterAgentService } from './register-agent.js'\nimport {\n JsonRpcSocketClient,\n defaultWebSocketFactory,\n describeError,\n resolveAuthToken,\n safeClose,\n type CodexWebSocketFactory,\n type JsonRpcResponse,\n} from './codex-appserver-rpc.js'\n\nexport interface RegisterCodexSelfInput {\n connection_id: string\n name: string\n model?: string\n role?: string\n team?: string\n project_dir?: string\n ws_url?: string\n auth_token_ref?: string\n thread_id?: string\n tmux_pane_id?: string\n cwd?: string\n tty?: string\n title_contains?: string\n}\n\nexport type RegisterCodexSelfResult =\n | {\n agent_id: string\n team: string\n thread_id: string\n ws_url: string\n }\n | { error: 'agent_id_collision' }\n | { error: 'invalid_delivery'; reason: string }\n | { error: 'claude_ui_pid_requires_channel_proxy' }\n | { error: 'missing_auth_token'; detail: { ref: string } }\n | { error: 'unsupported_client'; detail: { expected: 'codex'; reason: 'codex_appserver_unreachable' | 'codex_protocol_unavailable'; ws_url: string; cause?: unknown } }\n | { error: 'codex_connect_failed'; detail?: unknown }\n | { error: 'codex_initialize_failed'; detail?: unknown }\n | { error: 'codex_loaded_list_failed'; detail?: unknown }\n | { error: 'no_loaded_threads'; detail?: unknown }\n | { error: 'thread_id_required'; detail: { ws_url: string; thread_ids: string[] } }\n | { error: 'codex_resume_failed'; detail?: unknown }\n\nexport interface RegisterCodexSelfDeps {\n env?: NodeJS.ProcessEnv\n webSocketFactory?: CodexWebSocketFactory\n}\n\ntype RpcErrorCode =\n | 'codex_initialize_failed'\n | 'codex_loaded_list_failed'\n | 'codex_resume_failed'\n\nconst DEFAULT_CODEX_WS_URL = 'ws://127.0.0.1:8799'\n\nasync function requestStep(\n client: JsonRpcSocketClient,\n method: string,\n params: unknown,\n errorCode: RpcErrorCode\n): Promise<{ ok: JsonRpcResponse } | { error: RpcErrorCode; detail: unknown }> {\n try {\n const response = await client.request(method, params)\n if (response.error) return { error: errorCode, detail: response.error }\n return { ok: response }\n } catch (error) {\n return { error: errorCode, detail: describeError(error) }\n }\n}\n\nfunction resolveWsUrl(\n input: RegisterCodexSelfInput,\n env: NodeJS.ProcessEnv\n): string {\n const explicit = input.ws_url?.trim()\n if (explicit) return explicit\n const fromEnv = env.CROSS_AGENT_TEAMS_CODEX_WS_URL?.trim()\n if (fromEnv) return fromEnv\n return DEFAULT_CODEX_WS_URL\n}\n\nfunction extractThreadIds(response: JsonRpcResponse): string[] {\n const result = response.result as { data?: unknown } | undefined\n if (!result || !Array.isArray(result.data)) return []\n return result.data.filter((value): value is string => typeof value === 'string')\n}\n\nfunction trimToUndefined(value: string | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed : undefined\n}\n\nexport class RegisterCodexSelfService {\n constructor(\n private readonly registerSvc: RegisterAgentService,\n private readonly deps: RegisterCodexSelfDeps = {}\n ) {}\n\n async register(\n input: RegisterCodexSelfInput\n ): Promise<RegisterCodexSelfResult> {\n const env = this.deps.env ?? process.env\n const wsUrl = resolveWsUrl(input, env)\n const token = resolveAuthToken(input.auth_token_ref, env)\n if ('error' in token) return token\n const headers = token.ok === undefined\n ? undefined\n : { Authorization: `Bearer ${token.ok}` }\n\n let ws\n try {\n ws = (this.deps.webSocketFactory ?? defaultWebSocketFactory)({\n url: wsUrl,\n headers,\n })\n } catch (error) {\n return {\n error: 'unsupported_client',\n detail: {\n expected: 'codex',\n reason: 'codex_appserver_unreachable',\n ws_url: wsUrl,\n cause: describeError(error),\n },\n }\n }\n\n const client = new JsonRpcSocketClient(ws)\n try {\n await client.waitForOpen()\n\n const init = await requestStep(\n client,\n 'initialize',\n {\n clientInfo: {\n name: 'cross-agent-teams-mcp',\n title: null,\n version: '0.1.0',\n },\n capabilities: {\n experimentalApi: true,\n optOutNotificationMethods: null,\n },\n },\n 'codex_initialize_failed'\n )\n if ('error' in init) {\n return {\n error: 'unsupported_client',\n detail: {\n expected: 'codex',\n reason: 'codex_protocol_unavailable',\n ws_url: wsUrl,\n cause: init.detail,\n },\n }\n }\n\n client.notify('initialized')\n\n const explicitThreadId = trimToUndefined(input.thread_id)\n let threadId = explicitThreadId\n\n if (!threadId) {\n const list = await requestStep(\n client,\n 'thread/loaded/list',\n { cursor: null, limit: 20 },\n 'codex_loaded_list_failed'\n )\n if ('error' in list) return list\n\n const threadIds = extractThreadIds(list.ok)\n if (threadIds.length === 0) {\n return {\n error: 'no_loaded_threads',\n detail: { ws_url: wsUrl },\n }\n }\n\n const liveThreadIds: string[] = []\n const failures: Array<{ thread_id: string; detail: unknown }> = []\n for (const candidateThreadId of threadIds) {\n const resume = await requestStep(\n client,\n 'thread/resume',\n {\n threadId: candidateThreadId,\n persistExtendedHistory: false,\n },\n 'codex_resume_failed'\n )\n if ('error' in resume) {\n failures.push({ thread_id: candidateThreadId, detail: resume.detail })\n continue\n }\n liveThreadIds.push(candidateThreadId)\n }\n\n if (liveThreadIds.length === 0) {\n return {\n error: 'codex_resume_failed',\n detail: failures,\n }\n }\n\n return {\n error: 'thread_id_required',\n detail: {\n ws_url: wsUrl,\n thread_ids: liveThreadIds,\n },\n }\n }\n\n const resume = await requestStep(\n client,\n 'thread/resume',\n {\n threadId,\n persistExtendedHistory: false,\n },\n 'codex_resume_failed'\n )\n if ('error' in resume) {\n return {\n error: 'codex_resume_failed',\n detail: { thread_id: threadId, cause: resume.detail },\n }\n }\n\n const tmuxPaneId = trimToUndefined(input.tmux_pane_id)\n\n const result = this.registerSvc.register({\n connection_id: input.connection_id,\n client: 'codex',\n model: input.model ?? 'codex',\n name: input.name,\n role: input.role,\n team: input.team,\n project_dir: input.project_dir,\n tmux_pane_id: tmuxPaneId,\n delivery: {\n kind: 'codex-appserver',\n thread_id: threadId,\n ws_url: wsUrl,\n ...(input.auth_token_ref === undefined\n ? {}\n : { auth_token_ref: input.auth_token_ref }),\n },\n })\n if ('error' in result) return result\n return {\n ...result,\n thread_id: threadId,\n ws_url: wsUrl,\n }\n } catch (error) {\n return {\n error: 'unsupported_client',\n detail: {\n expected: 'codex',\n reason: 'codex_appserver_unreachable',\n ws_url: wsUrl,\n cause: describeError(error),\n },\n }\n } finally {\n safeClose(ws)\n }\n }\n}\n","import type Database from 'better-sqlite3'\nimport type { AgentsRepo } from '../storage/agents-repo.js'\n\nexport type UnregisterSelfResult =\n | { ok: true; team: string; name: string; agent_id: string }\n | { error: 'unknown_agent' }\n | { error: 'tasks_in_progress'; task_ids: string[] }\n\nexport class UnregisterSelfService {\n constructor(\n private readonly db: Database.Database,\n private readonly agents: AgentsRepo\n ) {}\n\n unregister(args: { caller: string }): UnregisterSelfResult {\n const caller = this.agents.findById(args.caller)\n if (!caller) return { error: 'unknown_agent' }\n\n const task_ids = this.agents.listClaimedInProgressTaskIds({\n agent_id: caller.agent_id,\n team: caller.team,\n })\n if (task_ids.length > 0) {\n return { error: 'tasks_in_progress', task_ids }\n }\n\n let removed = false\n const tx = this.db.transaction(() => {\n removed = this.agents.deleteById(caller.agent_id)\n if (!removed) return\n this.agents.deleteContractSubscriptions({\n agent_id: caller.agent_id,\n team: caller.team,\n })\n })\n tx()\n\n if (!removed) return { error: 'unknown_agent' }\n return {\n ok: true,\n team: caller.team,\n name: caller.name,\n agent_id: caller.agent_id,\n }\n }\n}\n","import type { AgentListRow } from '../storage/agents-repo.js'\nimport type { DeliverySpec } from '../lib/delivery-spec.js'\n\nexport type PublicDelivery =\n | { kind: 'none' }\n | { kind: 'codex-appserver' }\n | { kind: 'claude-channel'; channel_session_id: string }\n\nexport interface PublicAgentListRow {\n agent_id: string\n client: AgentListRow['client']\n client_name: AgentListRow['client_name']\n team: string\n role: string\n name: string\n model: string | null\n tmux_pane_id: string | null\n delivery: PublicDelivery\n channel_session_id: string | null\n last_seen_at: string\n online: boolean\n}\n\nfunction projectDelivery(delivery: DeliverySpec): PublicDelivery {\n if (delivery.kind === 'claude-channel') {\n return {\n kind: 'claude-channel',\n channel_session_id: delivery.channel_session_id,\n }\n }\n return { kind: delivery.kind }\n}\n\nexport function toPublicAgentRow(row: AgentListRow): PublicAgentListRow {\n return {\n agent_id: row.agent_id,\n client: row.client,\n client_name: row.client_name,\n team: row.team,\n role: row.role,\n name: row.name,\n model: row.model,\n tmux_pane_id: row.tmux_pane_id,\n delivery: projectDelivery(row.delivery),\n channel_session_id:\n row.delivery.kind === 'claude-channel'\n ? row.delivery.channel_session_id\n : null,\n last_seen_at: row.last_seen_at,\n online: row.online,\n }\n}\n","import { execFile } from 'node:child_process'\nimport { normalize, sep } from 'node:path'\nimport { promisify } from 'node:util'\n\nconst pExecFile = promisify(execFile)\n\nexport type DetectAgentKind = 'codex' | 'claude-code' | 'opencode' | 'custom'\n\nexport interface DetectTmuxPaneInput {\n agent: DetectAgentKind\n cwd?: string\n tty?: string\n title_contains?: string\n process_pattern?: string\n}\n\nexport interface DetectTmuxPaneCandidate {\n pane_id: string\n session_name: string\n window_index: number\n pane_index: number\n active: boolean\n tty: string\n current_path: string\n current_command: string\n title: string\n matched_processes: string[]\n score: number\n}\n\nexport type DetectTmuxPaneResult =\n | { ok: true; pane: DetectTmuxPaneCandidate; candidates: DetectTmuxPaneCandidate[] }\n | { error: 'not_found'; candidates: [] }\n | { error: 'ambiguous_match'; candidates: DetectTmuxPaneCandidate[] }\n | { error: 'tmux_unavailable'; detail: string }\n\nexport interface DetectTmuxPaneDeps {\n execFile?: typeof execFile\n}\n\ninterface PaneRow {\n pane_id: string\n session_name: string\n window_index: number\n pane_index: number\n active: boolean\n tty: string\n current_path: string\n current_command: string\n title: string\n}\n\nconst TMUX_LIST_TIMEOUT_MS = 3_000\nconst PS_LIST_TIMEOUT_MS = 3_000\n\nfunction normalizeTty(raw: string | undefined): string | undefined {\n const value = raw?.trim()\n if (!value) return undefined\n return value.replace(/^\\/dev\\//, '')\n}\n\nfunction normalizePath(raw: string | undefined): string | undefined {\n const value = raw?.trim()\n if (!value) return undefined\n return normalize(value)\n}\n\nfunction pathRelated(candidatePath: string, inputPath: string): 'exact' | 'ancestor' | 'descendant' | 'none' {\n const candidate = normalize(candidatePath)\n const input = normalize(inputPath)\n if (candidate === input) return 'exact'\n if (candidate.startsWith(`${input}${sep}`)) return 'descendant'\n if (input.startsWith(`${candidate}${sep}`)) return 'ancestor'\n return 'none'\n}\n\nfunction commandPattern(args: DetectTmuxPaneInput): RegExp {\n if (args.agent === 'custom') {\n const raw = args.process_pattern?.trim()\n if (!raw) throw new Error('process_pattern is required when agent=custom')\n return new RegExp(raw, 'i')\n }\n if (args.agent === 'codex') {\n return /(^|[\\s/])(codex|codex-aarch64-a)([\\s]|$)/i\n }\n if (args.agent === 'claude-code') {\n return /(^|[\\s/])claude([\\s]|$)/i\n }\n return /(^|[\\s/])opencode([\\s]|$)/i\n}\n\nfunction commandHintScore(agent: DetectAgentKind, command: string): number {\n if (agent === 'codex' && /codex/i.test(command)) return 6\n if (agent === 'opencode' && /opencode/i.test(command)) return 6\n if (agent === 'claude-code' && /^(\\d+\\.)+\\d+$/.test(command)) return 4\n return 0\n}\n\nfunction isHelperProcess(agent: DetectAgentKind, command: string): boolean {\n if (agent !== 'codex') return false\n return /codex\\s+app-server/i.test(command) ||\n /Codex Computer Use\\.app/i.test(command) ||\n /SkyComputerUseClient/i.test(command)\n}\n\nfunction parsePaneRows(stdout: string): PaneRow[] {\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n .map((line) => {\n const [\n pane_id,\n session_name,\n window_index,\n pane_index,\n pane_active,\n pane_tty,\n pane_current_path,\n pane_current_command,\n pane_title,\n ] = line.split('\\t')\n return {\n pane_id,\n session_name,\n window_index: Number(window_index),\n pane_index: Number(pane_index),\n active: pane_active === '1',\n tty: normalizeTty(pane_tty) ?? '',\n current_path: pane_current_path ?? '',\n current_command: pane_current_command ?? '',\n title: pane_title ?? '',\n }\n })\n }\n\nasync function listPanes(execLike: typeof execFile): Promise<PaneRow[]> {\n const exec = promisify(execLike)\n const { stdout } = await exec(\n 'tmux',\n [\n 'list-panes',\n '-a',\n '-F',\n '#{pane_id}\\t#{session_name}\\t#{window_index}\\t#{pane_index}\\t#{pane_active}\\t#{pane_tty}\\t#{pane_current_path}\\t#{pane_current_command}\\t#{pane_title}',\n ],\n { timeout: TMUX_LIST_TIMEOUT_MS }\n )\n return parsePaneRows(stdout)\n}\n\nasync function ttyProcesses(execLike: typeof execFile, tty: string): Promise<string[]> {\n const exec = promisify(execLike)\n const { stdout } = await exec(\n 'ps',\n ['-t', tty, '-o', 'pid=,ppid=,stat=,command='],\n { timeout: PS_LIST_TIMEOUT_MS }\n )\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n}\n\nfunction collectCandidates(\n panes: PaneRow[],\n ttyMap: Map<string, string[]>,\n input: DetectTmuxPaneInput\n): DetectTmuxPaneCandidate[] {\n const ttyFilter = normalizeTty(input.tty)\n const cwdFilter = normalizePath(input.cwd)\n const titleFilter = input.title_contains?.trim().toLowerCase()\n const pattern = commandPattern(input)\n const candidates: DetectTmuxPaneCandidate[] = []\n\n for (const pane of panes) {\n if (ttyFilter && pane.tty !== ttyFilter) continue\n if (cwdFilter) {\n const relation = pathRelated(pane.current_path, cwdFilter)\n if (relation === 'none') continue\n }\n if (titleFilter && !pane.title.toLowerCase().includes(titleFilter)) continue\n\n const matched_processes = (ttyMap.get(pane.tty) ?? []).filter((line) => {\n if (isHelperProcess(input.agent, line)) return false\n return pattern.test(line)\n })\n if (matched_processes.length === 0) continue\n\n let score = matched_processes.length * 10\n if (pane.active) score += 3\n score += commandHintScore(input.agent, pane.current_command)\n if (ttyFilter) score += 100\n if (cwdFilter) {\n const relation = pathRelated(pane.current_path, cwdFilter)\n if (relation === 'exact') score += 60\n else if (relation === 'descendant') score += 45\n else if (relation === 'ancestor') score += 30\n }\n if (titleFilter) score += 15\n\n candidates.push({\n pane_id: pane.pane_id,\n session_name: pane.session_name,\n window_index: pane.window_index,\n pane_index: pane.pane_index,\n active: pane.active,\n tty: pane.tty,\n current_path: pane.current_path,\n current_command: pane.current_command,\n title: pane.title,\n matched_processes,\n score,\n })\n }\n\n return candidates.sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score\n if (a.pane_id < b.pane_id) return -1\n if (a.pane_id > b.pane_id) return 1\n return 0\n })\n}\n\nexport async function detectTmuxPane(\n input: DetectTmuxPaneInput,\n deps: DetectTmuxPaneDeps = {}\n): Promise<DetectTmuxPaneResult> {\n const execLike = deps.execFile ?? execFile\n let panes: PaneRow[]\n try {\n panes = await listPanes(execLike)\n } catch (error) {\n return {\n error: 'tmux_unavailable',\n detail: error instanceof Error ? error.message : String(error),\n }\n }\n\n const ttyMap = new Map<string, string[]>()\n for (const pane of panes) {\n if (!pane.tty || ttyMap.has(pane.tty)) continue\n try {\n ttyMap.set(pane.tty, await ttyProcesses(execLike, pane.tty))\n } catch {\n ttyMap.set(pane.tty, [])\n }\n }\n\n let candidates: DetectTmuxPaneCandidate[]\n try {\n candidates = collectCandidates(panes, ttyMap, input)\n } catch (error) {\n return {\n error: 'not_found',\n candidates: [],\n }\n }\n\n if (candidates.length === 0) return { error: 'not_found', candidates: [] }\n\n const topScore = candidates[0].score\n const top = candidates.filter(candidate => candidate.score === topScore)\n if (top.length > 1) {\n return {\n error: 'ambiguous_match',\n candidates,\n }\n }\n\n return {\n ok: true,\n pane: candidates[0],\n candidates,\n }\n}\n","import type Database from 'better-sqlite3'\n\nexport interface CodexPanePreRegRow {\n pane_id: string\n xats_agent_id: string\n expires_at: string\n}\n\nexport interface UpsertInput {\n pane_id: string\n xats_agent_id: string\n expires_at: string\n}\n\nexport class CodexPanePreRegRepo {\n constructor(private readonly db: Database.Database) {}\n\n upsert(input: UpsertInput): void {\n this.db\n .prepare(\n `INSERT INTO codex_pane_pre_registrations (pane_id, xats_agent_id, expires_at)\n VALUES (?, ?, ?)\n ON CONFLICT(pane_id) DO UPDATE SET\n xats_agent_id = excluded.xats_agent_id,\n expires_at = excluded.expires_at`\n )\n .run(input.pane_id, input.xats_agent_id, input.expires_at)\n }\n\n listUnexpired(now: string): CodexPanePreRegRow[] {\n return this.db\n .prepare(\n `SELECT pane_id, xats_agent_id, expires_at\n FROM codex_pane_pre_registrations\n WHERE expires_at > ?`\n )\n .all(now) as CodexPanePreRegRow[]\n }\n\n takeByPaneId(pane_id: string): CodexPanePreRegRow | undefined {\n const row = this.db\n .prepare(\n `DELETE FROM codex_pane_pre_registrations\n WHERE pane_id = ?\n RETURNING pane_id, xats_agent_id, expires_at`\n )\n .get(pane_id) as CodexPanePreRegRow | undefined\n return row\n }\n\n deleteExpired(now: string): number {\n const res = this.db\n .prepare(`DELETE FROM codex_pane_pre_registrations WHERE expires_at <= ?`)\n .run(now)\n return res.changes\n }\n}\n","import { z } from 'zod'\nimport type { CodexPanePreRegRepo } from './codex-pane-pre-register-repo.js'\n\nexport const preRegisterCodexPaneInputSchema = z\n .object({\n pane_id: z\n .string()\n .min(1)\n .refine(v => v.startsWith('%'), {\n message: 'pane_id must be a tmux pane id starting with \"%\"',\n }),\n xats_agent_id: z.string().min(1),\n ttl_seconds: z.number().int().positive().optional(),\n })\n .strict()\n\nexport type PreRegisterCodexPaneInput = z.infer<typeof preRegisterCodexPaneInputSchema>\n\nexport type PreRegisterCodexPaneResult =\n | { ok: true; expires_at: string }\n | { error: 'invalid_arguments'; detail: string }\n\nconst DEFAULT_TTL_SECONDS = 120\nconst MIN_TTL_SECONDS = 1\nconst MAX_TTL_SECONDS = 600\n\nfunction clampTtl(ttl: number | undefined): number {\n const raw = ttl ?? DEFAULT_TTL_SECONDS\n if (raw < MIN_TTL_SECONDS) return MIN_TTL_SECONDS\n if (raw > MAX_TTL_SECONDS) return MAX_TTL_SECONDS\n return raw\n}\n\nexport class PreRegisterCodexPaneService {\n constructor(\n private readonly repo: CodexPanePreRegRepo,\n private readonly now: () => Date = () => new Date()\n ) {}\n\n register(args: unknown): PreRegisterCodexPaneResult {\n const parsed = preRegisterCodexPaneInputSchema.safeParse(args)\n if (!parsed.success) {\n return {\n error: 'invalid_arguments',\n detail: parsed.error.issues\n .map(issue => {\n const path = issue.path.join('.')\n return path ? `${path}: ${issue.message}` : issue.message\n })\n .join('; '),\n }\n }\n\n const now = this.now()\n const ttl = clampTtl(parsed.data.ttl_seconds)\n const expires_at = new Date(now.getTime() + ttl * 1000).toISOString()\n this.repo.deleteExpired(now.toISOString())\n this.repo.upsert({\n pane_id: parsed.data.pane_id,\n xats_agent_id: parsed.data.xats_agent_id,\n expires_at,\n })\n return { ok: true, expires_at }\n }\n}\n","import { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport type { CodexPanePreRegRepo, CodexPanePreRegRow } from './codex-pane-pre-register-repo.js'\nimport type { BindRuntimeIdentityService } from './bind-runtime-identity.js'\n\nconst TMUX_LIST_TIMEOUT_MS = 3_000\nconst PS_LIST_TIMEOUT_MS = 3_000\n\nexport interface PaneTtyEntry {\n pane_id: string\n tty: string\n}\n\nexport interface AutoBindCodexPaneDeps {\n listPanes?: () => Promise<PaneTtyEntry[]>\n ttyProcesses?: (tty: string) => Promise<string[]>\n now?: () => Date\n}\n\nexport interface AutoBindCodexPaneInput {\n callerAgentId: string\n repo: CodexPanePreRegRepo\n bindRuntimeIdentitySvc: BindRuntimeIdentityService\n}\n\nfunction normalizeTty(raw: string | undefined): string | undefined {\n const value = raw?.trim()\n if (!value) return undefined\n const normalized = value.replace(/^\\/dev\\//, '')\n if (!normalized || normalized === '?') return undefined\n return normalized\n}\n\nasync function defaultListPanes(): Promise<PaneTtyEntry[]> {\n const exec = promisify(execFile)\n const { stdout } = await exec(\n 'tmux',\n ['list-panes', '-a', '-F', '#{pane_id}\\t#{pane_tty}'],\n { timeout: TMUX_LIST_TIMEOUT_MS }\n )\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n .map(line => {\n const [pane_id, pane_tty] = line.split('\\t')\n return {\n pane_id,\n tty: normalizeTty(pane_tty) ?? '',\n }\n })\n}\n\nasync function defaultTtyProcesses(tty: string): Promise<string[]> {\n const exec = promisify(execFile)\n const { stdout } = await exec(\n 'ps',\n ['-t', tty, '-o', 'pid=,ppid=,stat=,command='],\n { timeout: PS_LIST_TIMEOUT_MS }\n )\n return stdout\n .split('\\n')\n .map(line => line.trimEnd())\n .filter(Boolean)\n}\n\nfunction parsePid(line: string): number | undefined {\n const match = line.trim().match(/^(\\d+)\\s/)\n if (!match) return undefined\n const pid = Number(match[1])\n if (!Number.isInteger(pid) || pid <= 0) return undefined\n return pid\n}\n\nfunction isCodexRemoteProcess(line: string): boolean {\n if (!/codex/i.test(line)) return false\n if (/codex\\s+app-server/i.test(line)) return false\n return /codex(?:-aarch64-a)?\\s+.*--remote/i.test(line) || /codex(?:-aarch64-a)?\\s+--remote/i.test(line)\n}\n\nfunction argvContainsUuid(line: string, uuid: string): boolean {\n return line.includes(`xats.agent_id=\"${uuid}\"`)\n}\n\ninterface Candidate {\n row: CodexPanePreRegRow\n pane_id: string\n ui_pid: number\n}\n\n/**\n * Scan pending pre-regs, look up tmux panes and their processes, and bind\n * the caller agent row when exactly one pre-reg maps to a live codex --remote\n * process whose argv contains the stored UUID.\n *\n * Returns true only when bind + consume succeeded. Any error path returns\n * false without propagating.\n */\n// Test hook: allows integration tests to override the tmux/ps probes that\n// would otherwise need a real tmux session. Production paths pass `deps`\n// explicitly; when they do not, we fall through to these overrides, then to\n// the real child_process-backed defaults.\nexport const __testOverrides: AutoBindCodexPaneDeps = {}\n\nexport async function autoBindCodexPane(\n input: AutoBindCodexPaneInput,\n deps: AutoBindCodexPaneDeps = {}\n): Promise<boolean> {\n const listPanes = deps.listPanes ?? __testOverrides.listPanes ?? defaultListPanes\n const ttyProcesses = deps.ttyProcesses ?? __testOverrides.ttyProcesses ?? defaultTtyProcesses\n const now = deps.now ?? __testOverrides.now ?? (() => new Date())\n\n try {\n const nowIso = now().toISOString()\n input.repo.deleteExpired(nowIso)\n const pending = input.repo.listUnexpired(nowIso)\n if (pending.length === 0) return false\n\n let panes: PaneTtyEntry[]\n try {\n panes = await listPanes()\n } catch {\n return false\n }\n\n const paneIndex = new Map<string, PaneTtyEntry>()\n for (const pane of panes) {\n if (pane.pane_id) paneIndex.set(pane.pane_id, pane)\n }\n\n const ttyProcessCache = new Map<string, string[]>()\n const candidates: Candidate[] = []\n\n for (const row of pending) {\n const pane = paneIndex.get(row.pane_id)\n if (!pane || !pane.tty) continue\n let procs = ttyProcessCache.get(pane.tty)\n if (procs === undefined) {\n try {\n procs = await ttyProcesses(pane.tty)\n } catch {\n procs = []\n }\n ttyProcessCache.set(pane.tty, procs)\n }\n const matching = procs.filter(line =>\n isCodexRemoteProcess(line) && argvContainsUuid(line, row.xats_agent_id)\n )\n if (matching.length !== 1) continue\n const pid = parsePid(matching[0])\n if (pid === undefined) continue\n candidates.push({ row, pane_id: pane.pane_id, ui_pid: pid })\n }\n\n if (candidates.length !== 1) return false\n\n const chosen = candidates[0]\n const bindResult = await input.bindRuntimeIdentitySvc.bind({\n callerAgentId: input.callerAgentId,\n agent: 'codex',\n ui_pid: chosen.ui_pid,\n })\n if (!('ok' in bindResult) || !bindResult.ok) return false\n\n input.repo.takeByPaneId(chosen.pane_id)\n return true\n } catch {\n return false\n }\n}\n","import type Database from 'better-sqlite3'\n\nexport interface CleanupOpts {\n maxAgeDays?: number\n onlineWindowMs?: number\n now?: Date\n}\n\n// Online cursor floor per destination team: an agent in team T with recent last_seen_at\n// advances team T's inbox cursor. Events older than 7 days that target team T can be\n// dropped once T's min cursor has moved past their event_id.\nconst DELETE_AGED_EVENTS_SQL = `\n WITH online_cursor AS (\n SELECT team AS to_team, MIN(last_processed_event_id) AS min_cursor\n FROM agents\n WHERE last_seen_at >= :cutoffOnline\n GROUP BY team\n )\n DELETE FROM events\n WHERE created_at < :ageCutoff\n AND (\n events.to_team NOT IN (SELECT to_team FROM online_cursor)\n OR events.event_id < (\n SELECT min_cursor FROM online_cursor WHERE online_cursor.to_team = events.to_team\n )\n )\n`\n\nexport function runCleanup(db: Database.Database, opts: CleanupOpts = {}): { deleted: number } {\n const now = opts.now ?? new Date()\n const maxAgeDays = opts.maxAgeDays ?? 7\n const onlineWindowMs = opts.onlineWindowMs ?? 5 * 60 * 1000\n const ageCutoff = new Date(now.getTime() - maxAgeDays * 86400 * 1000).toISOString()\n const cutoffOnline = new Date(now.getTime() - onlineWindowMs).toISOString()\n\n const info = db.prepare(DELETE_AGED_EVENTS_SQL).run({ ageCutoff, cutoffOnline })\n return { deleted: Number(info.changes) }\n}\n","import type Database from 'better-sqlite3'\n\nexport interface SseSink {\n send(msg: Record<string, unknown>): void\n sendHeartbeat(): void\n close(): void\n}\n\ninterface Session { agent_id: string; team: string; sink: SseSink }\n\nconst DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000\n\nfunction resolveHeartbeatIntervalMs(opt?: number): number {\n if (typeof opt === 'number' && opt > 0) return opt\n const n = Number(process.env.HEARTBEAT_INTERVAL_MS)\n return Number.isInteger(n) && n > 0 ? n : DEFAULT_HEARTBEAT_INTERVAL_MS\n}\n\nexport class SseFanout {\n private sessions = new Map<string, Session>()\n private heartbeatTimer: ReturnType<typeof setInterval> | undefined\n private readonly heartbeatIntervalMs: number\n\n constructor(opts: { heartbeatIntervalMs?: number } = {}) {\n this.heartbeatIntervalMs = resolveHeartbeatIntervalMs(opts.heartbeatIntervalMs)\n }\n\n attach(agent_id: string, team: string, sink: SseSink): void {\n const prior = this.sessions.get(agent_id)\n if (prior && prior.sink !== sink) {\n try { prior.sink.close() } catch { /* ignore */ }\n }\n const wasEmpty = this.sessions.size === 0\n this.sessions.set(agent_id, { agent_id, team, sink })\n if (wasEmpty) this.startHeartbeat()\n }\n\n rebind(agent_id: string, team: string): void {\n const s = this.sessions.get(agent_id)\n if (!s) return\n this.sessions.set(agent_id, { agent_id, team, sink: s.sink })\n }\n\n detach(agent_id: string): void {\n const s = this.sessions.get(agent_id)\n if (s) { try { s.sink.close() } catch { /* ignore */ } this.sessions.delete(agent_id) }\n if (this.sessions.size === 0) this.stopHeartbeat()\n }\n\n stopAll(): void {\n this.stopHeartbeat()\n for (const s of this.sessions.values()) { try { s.sink.close() } catch { /* ignore */ } }\n this.sessions.clear()\n }\n\n peek(): Array<{ agent_id: string; team: string }> {\n return Array.from(this.sessions.values()).map(s => ({ agent_id: s.agent_id, team: s.team }))\n }\n\n emitContractEvent(\n db: Database.Database,\n args: { to_team: string; contract_name: string; version: number; event_id: number; diff: unknown | null }\n ): void {\n const subs = db.prepare(\n `SELECT agent_id FROM contract_subscriptions WHERE team=? AND contract_name=?`\n ).all(args.to_team, args.contract_name) as Array<{ agent_id: string }>\n const subscribedSet = new Set(subs.map(s => s.agent_id))\n for (const session of this.sessions.values()) {\n if (session.team !== args.to_team) continue\n if (!subscribedSet.has(session.agent_id)) continue\n try {\n session.sink.send({\n type: 'contract_event',\n event_id: args.event_id,\n contract_name: args.contract_name,\n version: args.version,\n diff: args.diff\n })\n } catch { /* broken sink; swallow */ }\n }\n }\n\n private startHeartbeat(): void {\n if (this.heartbeatTimer) return\n this.heartbeatTimer = setInterval(() => {\n for (const s of this.sessions.values()) {\n try { s.sink.sendHeartbeat() } catch { /* ignore */ }\n }\n }, this.heartbeatIntervalMs)\n if (typeof this.heartbeatTimer.unref === 'function') this.heartbeatTimer.unref()\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = undefined }\n }\n}\n","export type ChannelWakeSink = (payload: unknown) => void\n\ninterface Entry {\n sessionId: string\n sink: ChannelWakeSink\n}\n\nexport class ChannelWakeFanout {\n private readonly entries = new Map<string, Entry>()\n\n attach(channel_session_id: string, sink: ChannelWakeSink, sessionId: string): void {\n this.entries.set(channel_session_id, { sessionId, sink })\n }\n\n detach(channel_session_id: string): void {\n this.entries.delete(channel_session_id)\n }\n\n detachBySession(sessionId: string): void {\n for (const [csid, entry] of this.entries) {\n if (entry.sessionId === sessionId) this.entries.delete(csid)\n }\n }\n\n send(channel_session_id: string, payload: unknown): boolean {\n const entry = this.entries.get(channel_session_id)\n if (!entry) return false\n try {\n entry.sink(payload)\n } catch {\n // sink failure is the caller's concern; swallow to preserve map state\n }\n return true\n }\n\n has(channel_session_id: string): boolean {\n return this.entries.has(channel_session_id)\n }\n}\n","import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\n\nexport type AcquireResult =\n | { ok: true }\n | { ok: false; reason: 'already_running'; pid: number; port: number }\n\nfunction isAlive(pid: number): boolean {\n try { process.kill(pid, 0); return true } catch (e) {\n const err = e as NodeJS.ErrnoException\n // EPERM means the process exists but we lack permission to signal it; still alive.\n if (err.code === 'EPERM') return true\n return false\n }\n}\n\nexport function acquirePidFile(path: string, port: number): AcquireResult {\n mkdirSync(dirname(path), { recursive: true })\n if (existsSync(path)) {\n try {\n const prev = JSON.parse(readFileSync(path, 'utf8')) as { pid: number; port: number }\n if (isAlive(prev.pid) && prev.pid !== process.pid) {\n return { ok: false, reason: 'already_running', pid: prev.pid, port: prev.port }\n }\n } catch { /* corrupt file, overwrite */ }\n }\n writeFileSync(path, JSON.stringify({ pid: process.pid, port }))\n return { ok: true }\n}\n\nexport function releasePidFile(path: string): void {\n if (existsSync(path)) rmSync(path, { force: true })\n}\n","import type { FastifyInstance } from 'fastify'\nimport { releasePidFile } from './pid.js'\n\nexport function wireShutdown(app: FastifyInstance, pidPath: string): void {\n const handler = async (_signal: NodeJS.Signals) => {\n try { await app.close() } catch { /* ignore */ }\n releasePidFile(pidPath)\n process.exit(0)\n }\n process.once('SIGTERM', handler)\n process.once('SIGINT', handler)\n}\n","import { createServer } from 'node:net'\n\nfunction tryBind(port: number, host: string): Promise<boolean> {\n return new Promise(resolve => {\n const s = createServer()\n s.once('error', () => resolve(false))\n s.listen(port, host, () => s.close(() => resolve(true)))\n })\n}\n\nexport async function selectPort(candidates: number[], host = '127.0.0.1'): Promise<number> {\n for (const p of candidates) {\n if (await tryBind(p, host)) return p\n }\n throw new Error(`ports ${candidates[0]}-${candidates[candidates.length - 1]} unavailable`)\n}\n"],"mappings":"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","names":["existsSync","readFileSync","randomUUID","z","randomUUID","delay","event_id","sent_at","randomUUID","randomUUID","randomUUID","randomUUID","randomUUID","randomUUID","execFile","promisify","pane","candidate","requestStep","resume","execFile","promisify","pExecFile","TMUX_LIST_TIMEOUT_MS","PS_LIST_TIMEOUT_MS","normalizeTty","commandPattern","isHelperProcess","listPanes","ttyProcesses","z","execFile","promisify","TMUX_LIST_TIMEOUT_MS","PS_LIST_TIMEOUT_MS","normalizeTty","listPanes","ttyProcesses","z","randomUUID","mkdirSync","dirname","existsSync","readFileSync"]}