@mclawnet/agent 0.6.34 → 0.6.36
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.
- package/cli.js +75 -7
- package/dist/__tests__/bootstrap-deps.test.d.ts +2 -0
- package/dist/__tests__/bootstrap-deps.test.d.ts.map +1 -0
- package/dist/__tests__/collect-manifest.test.d.ts +2 -0
- package/dist/__tests__/collect-manifest.test.d.ts.map +1 -0
- package/dist/__tests__/hub-connection-on-activity.test.d.ts +2 -0
- package/dist/__tests__/hub-connection-on-activity.test.d.ts.map +1 -0
- package/dist/__tests__/hub-connection-wake-watch.test.d.ts +2 -0
- package/dist/__tests__/hub-connection-wake-watch.test.d.ts.map +1 -0
- package/dist/__tests__/ideas-rest-client.test.d.ts +2 -0
- package/dist/__tests__/ideas-rest-client.test.d.ts.map +1 -0
- package/dist/__tests__/legacy-claude-execute-compat.test.d.ts +2 -0
- package/dist/__tests__/legacy-claude-execute-compat.test.d.ts.map +1 -0
- package/dist/__tests__/no-adapter-cycle.test.d.ts +2 -0
- package/dist/__tests__/no-adapter-cycle.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-env-defaults.test.d.ts +2 -0
- package/dist/__tests__/runtime-env-defaults.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-exit-reason.test.d.ts +2 -0
- package/dist/__tests__/session-manager-exit-reason.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-merge.test.d.ts +2 -0
- package/dist/__tests__/session-manager-merge.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager-sticky.test.d.ts +2 -0
- package/dist/__tests__/session-manager-sticky.test.d.ts.map +1 -0
- package/dist/__tests__/session-protocol-dispatch.test.d.ts +2 -0
- package/dist/__tests__/session-protocol-dispatch.test.d.ts.map +1 -0
- package/dist/__tests__/worktree-bridge.test.d.ts +2 -0
- package/dist/__tests__/worktree-bridge.test.d.ts.map +1 -0
- package/dist/backend-adapter.d.ts +6 -232
- package/dist/backend-adapter.d.ts.map +1 -1
- package/dist/backend-factory-AFF6I7YF.js +11 -0
- package/dist/backend-factory.d.ts +23 -1
- package/dist/backend-factory.d.ts.map +1 -1
- package/dist/bootstrap-deps.d.ts +84 -0
- package/dist/bootstrap-deps.d.ts.map +1 -0
- package/dist/bootstrap-deps.js +173 -0
- package/dist/bootstrap-deps.js.map +1 -0
- package/dist/{chunk-PJ5M6Q36.js → chunk-376QZ7JB.js} +2 -2
- package/dist/chunk-376QZ7JB.js.map +1 -0
- package/dist/{chunk-2JDX6XFD.js → chunk-GOCWMRBB.js} +1817 -298
- package/dist/chunk-GOCWMRBB.js.map +1 -0
- package/dist/{chunk-M2CDVPQF.js → chunk-JH6RGJBQ.js} +2 -2
- package/dist/{chunk-MFXF77LG.js → chunk-VAEFJLPL.js} +25 -3
- package/dist/chunk-VAEFJLPL.js.map +1 -0
- package/dist/{dist-VLBO5CT3.js → dist-NWVHAP5R.js} +330 -23
- package/dist/dist-NWVHAP5R.js.map +1 -0
- package/dist/errors.d.ts +20 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/hub-connection.d.ts +25 -1
- package/dist/hub-connection.d.ts.map +1 -1
- package/dist/ideas-rest-client.d.ts +25 -0
- package/dist/ideas-rest-client.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/{linux-IHA4O633.js → linux-MBU6ERXL.js} +3 -3
- package/dist/{macos-G4VK2253.js → macos-I2DUWFUH.js} +3 -3
- package/dist/projects-handler.d.ts +146 -1
- package/dist/projects-handler.d.ts.map +1 -1
- package/dist/runtime-env-defaults.d.ts +18 -0
- package/dist/runtime-env-defaults.d.ts.map +1 -0
- package/dist/service/index.js +5 -5
- package/dist/session-manager.d.ts +59 -0
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +3 -2
- package/dist/{windows-P6U3JLUZ.js → windows-PEJ3KOLC.js} +3 -3
- package/dist/worktree-bridge.d.ts +51 -0
- package/dist/worktree-bridge.d.ts.map +1 -0
- package/package.json +10 -8
- package/dist/backend-factory-RUYUBJVF.js +0 -9
- package/dist/chunk-2JDX6XFD.js.map +0 -1
- package/dist/chunk-MFXF77LG.js.map +0 -1
- package/dist/chunk-PJ5M6Q36.js.map +0 -1
- package/dist/dist-VLBO5CT3.js.map +0 -1
- /package/dist/{backend-factory-RUYUBJVF.js.map → backend-factory-AFF6I7YF.js.map} +0 -0
- /package/dist/{chunk-M2CDVPQF.js.map → chunk-JH6RGJBQ.js.map} +0 -0
- /package/dist/{linux-IHA4O633.js.map → linux-MBU6ERXL.js.map} +0 -0
- /package/dist/{macos-G4VK2253.js.map → macos-I2DUWFUH.js.map} +0 -0
- /package/dist/{windows-P6U3JLUZ.js.map → windows-PEJ3KOLC.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/backend-factory.ts"],"sourcesContent":["import type { BackendAdapter } from \"./backend-adapter.js\";\n\nexport type BackendKind = \"claude\" | \"codex\";\n\nconst cache = new Map<BackendKind, BackendAdapter>();\n\nexport function __resetBackendFactoryCache(): void {\n cache.clear();\n}\n\nexport interface BackendFactoryContext {\n /** Role instance / template name — surfaces in error messages so users know\n * which role is misconfigured when its backend package fails to load. */\n roleName?: string;\n}\n\n/**\n * Resolve a BackendAdapter for the given backend kind.\n *\n * - \"claude\" / undefined → @mclawnet/claude-adapter (back-compat default).\n * - \"codex\" → @mclawnet/codex-adapter via dynamic import so the codex bundle\n * isn't pulled into claude-only deployments.\n *\n * Results are cached per kind; subsequent calls return the same instance.\n */\nexport async function createBackendAdapter(\n kind: BackendKind | undefined,\n ctx: BackendFactoryContext = {},\n): Promise<BackendAdapter> {\n const resolved: BackendKind = kind ?? \"claude\";\n const cached = cache.get(resolved);\n if (cached) return cached;\n\n let adapter: BackendAdapter;\n if (resolved === \"claude\") {\n try {\n // Type-erased dynamic import: claude-adapter has a type-only ref back\n // to @mclawnet/agent, so resolving its types here would create a\n // tsc-time cycle. Both adapters are built AFTER agent, so the dist\n // files only exist at runtime.\n const mod = (await import(\"@mclawnet/claude-adapter\" as string)) as {\n ClaudeCodeAdapter: new () => BackendAdapter;\n };\n adapter = new mod.ClaudeCodeAdapter();\n } catch (err) {\n throw rethrowWithRole(\n err,\n ctx.roleName,\n \"failed to load @mclawnet/claude-adapter\",\n );\n }\n } else if (resolved === \"codex\") {\n try {\n const mod = (await import(\"@mclawnet/codex-adapter\" as string)) as {\n CodexAdapter: new () => BackendAdapter;\n };\n adapter = new mod.CodexAdapter();\n } catch (err) {\n throw rethrowWithRole(\n err,\n ctx.roleName,\n \"failed to load @mclawnet/codex-adapter (is codex CLI installed?)\",\n );\n }\n } else {\n throw new Error(`unknown backend kind: ${resolved}`);\n }\n\n cache.set(resolved, adapter);\n return adapter;\n}\n\nfunction rethrowWithRole(err: unknown, roleName: string | undefined, prefix: string): Error {\n const base = err instanceof Error ? err.message : String(err);\n const tag = roleName ? ` [role=${roleName}]` : \"\";\n return new Error(`${prefix}${tag}: ${base}`);\n}\n"],"mappings":";AAIA,IAAM,QAAQ,oBAAI,IAAiC;AAE5C,SAAS,6BAAmC;AACjD,QAAM,MAAM;AACd;AAiBA,eAAsB,qBACpB,MACA,MAA6B,CAAC,GACL;AACzB,QAAM,WAAwB,QAAQ;AACtC,QAAM,SAAS,MAAM,IAAI,QAAQ;AACjC,MAAI,OAAQ,QAAO;AAEnB,MAAI;AACJ,MAAI,aAAa,UAAU;AACzB,QAAI;AAKF,YAAM,MAAO,MAAM,OAAO,0BAAoC;AAG9D,gBAAU,IAAI,IAAI,kBAAkB;AAAA,IACtC,SAAS,KAAK;AACZ,YAAM;AAAA,QACJ;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,aAAa,SAAS;AAC/B,QAAI;AACF,YAAM,MAAO,MAAM,OAAO,oBAAmC;AAG7D,gBAAU,IAAI,IAAI,aAAa;AAAA,IACjC,SAAS,KAAK;AACZ,YAAM;AAAA,QACJ;AAAA,QACA,IAAI;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,IAAI,MAAM,yBAAyB,QAAQ,EAAE;AAAA,EACrD;AAEA,QAAM,IAAI,UAAU,OAAO;AAC3B,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAc,UAA8B,QAAuB;AAC1F,QAAM,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC5D,QAAM,MAAM,WAAW,UAAU,QAAQ,MAAM;AAC/C,SAAO,IAAI,MAAM,GAAG,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;AAC7C;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, hostname } from \"node:os\";\nimport type { BackendType } from \"@mclawnet/shared\";\nimport { createLogger } from \"@mclawnet/logger\";\n\nconst log = createLogger({ module: \"config\" });\n\nexport interface EmbeddingConfig {\n /** Embedding provider mode: auto / openai / ollama / hash */\n provider?: string;\n /** OpenAI-compatible API base URL (e.g. http://localhost:4141/v1 for copilot proxy) */\n openaiBaseUrl?: string;\n /** OpenAI API key (use \"dummy\" for copilot proxy) */\n openaiApiKey?: string;\n /** OpenAI embedding model name */\n openaiModel?: string;\n /** Ollama server URL */\n ollamaUrl?: string;\n /** Ollama embedding model name */\n ollamaModel?: string;\n}\n\nexport interface AgentConfig {\n hubUrl: string;\n token: string;\n name: string;\n backendType: BackendType;\n embedding?: EmbeddingConfig;\n}\n\nconst CONFIG_DIR = join(homedir(), \".clawnet\");\nconst SETTINGS_FILE = join(CONFIG_DIR, \"settings.json\");\n\nconst DEFAULT_HUB_URL = process.env.CLAWNET_DEFAULT_HUB_URL || \"wss://mclaw.work/ws/agent\";\n\nconst DEFAULTS: AgentConfig = {\n hubUrl: DEFAULT_HUB_URL,\n token: \"\",\n name: hostname(),\n backendType: \"claude-code\",\n};\n\n/** Ensure hubUrl uses ws(s):// protocol and ends with /ws/agent */\nfunction normalizeHubUrl(url: string): string {\n // Convert http(s):// to ws(s)://\n url = url.replace(/^https:\\/\\//, \"wss://\").replace(/^http:\\/\\//, \"ws://\");\n // Default to wss:// if no protocol\n if (!/^wss?:\\/\\//.test(url)) url = \"wss://\" + url;\n if (url.endsWith(\"/ws/agent\")) return url;\n return url.replace(/\\/+$/, \"\") + \"/ws/agent\";\n}\n\n/**\n * Map structured embedding config to CLAWNET_* env vars.\n * Only sets vars that are not already defined in process.env.\n */\nfunction applyEmbeddingConfig(embedding: EmbeddingConfig): void {\n const mapping: Array<[keyof EmbeddingConfig, string]> = [\n [\"provider\", \"CLAWNET_EMBEDDING_PROVIDER\"],\n [\"openaiBaseUrl\", \"CLAWNET_OPENAI_BASE_URL\"],\n [\"openaiApiKey\", \"CLAWNET_OPENAI_API_KEY\"],\n [\"openaiModel\", \"CLAWNET_OPENAI_EMBEDDING_MODEL\"],\n [\"ollamaUrl\", \"CLAWNET_OLLAMA_URL\"],\n [\"ollamaModel\", \"CLAWNET_OLLAMA_MODEL\"],\n ];\n\n for (const [configKey, envKey] of mapping) {\n const value = embedding[configKey];\n if (value !== undefined && process.env[envKey] === undefined) {\n process.env[envKey] = value;\n }\n }\n}\n\n/** Load config: CLI opts > env vars > settings file > defaults */\nexport function loadConfig(cliOpts: Partial<AgentConfig> = {}): AgentConfig {\n let fileConfig: Partial<AgentConfig> = {};\n\n log.info({ path: SETTINGS_FILE }, \"loading config\");\n\n if (existsSync(SETTINGS_FILE)) {\n try {\n fileConfig = JSON.parse(readFileSync(SETTINGS_FILE, \"utf-8\"));\n log.info(\n { hubUrl: fileConfig.hubUrl, hasToken: !!fileConfig.token, name: fileConfig.name },\n \"settings.json loaded\"\n );\n } catch (e) {\n log.warn({ err: e }, \"failed to parse settings.json\");\n }\n } else {\n log.warn(\"settings.json not found\");\n }\n\n // Apply structured embedding config to process.env\n if (fileConfig.embedding) {\n applyEmbeddingConfig(fileConfig.embedding);\n }\n\n const hubUrl =\n cliOpts.hubUrl ??\n process.env.CLAWNET_HUB_URL ??\n fileConfig.hubUrl ??\n DEFAULTS.hubUrl;\n\n const resolved = {\n hubUrl: normalizeHubUrl(hubUrl),\n token:\n cliOpts.token ??\n process.env.CLAWNET_TOKEN ??\n fileConfig.token ??\n DEFAULTS.token,\n name:\n cliOpts.name ??\n process.env.CLAWNET_NAME ??\n fileConfig.name ??\n DEFAULTS.name,\n backendType:\n (cliOpts.backendType as BackendType) ??\n (process.env.CLAWNET_BACKEND_TYPE as BackendType) ??\n (fileConfig.backendType as BackendType) ??\n DEFAULTS.backendType,\n embedding: fileConfig.embedding,\n };\n\n log.info(\n {\n hubUrl: resolved.hubUrl,\n hubUrlSource: cliOpts.hubUrl ? \"cli\" : process.env.CLAWNET_HUB_URL ? \"env\" : fileConfig.hubUrl ? \"file\" : \"default\",\n tokenSource: cliOpts.token ? \"cli\" : process.env.CLAWNET_TOKEN ? \"env\" : fileConfig.token ? \"file\" : \"default\",\n hasToken: !!resolved.token,\n },\n \"config resolved\"\n );\n\n return resolved;\n}\n\n/** Save config to ~/.clawnet/settings.json */\nexport function saveConfig(config: Partial<AgentConfig>): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n\n let existing: Partial<AgentConfig> = {};\n if (existsSync(SETTINGS_FILE)) {\n try {\n existing = JSON.parse(readFileSync(SETTINGS_FILE, \"utf-8\"));\n } catch {\n // ignore\n }\n }\n\n const merged = { ...existing, ...config };\n writeFileSync(SETTINGS_FILE, JSON.stringify(merged, null, 2) + \"\\n\");\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../codex-adapter/src/codex-adapter.ts","../../codex-adapter/src/codex-spawn-args.ts","../../codex-adapter/src/json-rpc-client.ts","../../codex-adapter/src/permission-mapper.ts","../../codex-adapter/src/output-mapper.ts"],"sourcesContent":["import { spawn, type ChildProcess } from \"node:child_process\";\nimport { EventEmitter } from \"node:events\";\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { buildCodexSpawnArgs, cleanupBriefingFile, type McpServerConfig } from \"./codex-spawn-args.js\";\nimport type {\n BackendAdapter,\n BackendProcess,\n BackendOutput,\n PermissionDecision,\n PermissionRequest,\n SpawnOptions,\n} from \"@mclawnet/agent\";\nimport { createLogger, preview } from \"@mclawnet/logger\";\nimport { JsonRpcClient } from \"./json-rpc-client.js\";\nimport {\n buildApprovalReply,\n parseApprovalRequest,\n type ApprovalWireFamily,\n} from \"./permission-mapper.js\";\nimport { mapCodexFrame } from \"./output-mapper.js\";\n\nconst log = createLogger({ module: \"codex-adapter\" });\n\nconst CLAWNET_CLIENT_INFO = {\n name: \"clawnet\",\n version: \"0.1.0\",\n title: \"ClawNet Agent\",\n};\n\n/**\n * Per-process state wrapper. Holds the JSON-RPC client + pending approval\n * resolvers so `respondToPermission` can find the right server-initiated\n * request id to reply to.\n */\nexport class CodexProcess extends EventEmitter implements BackendProcess {\n readonly id: string;\n readonly workDir: string;\n pid?: number;\n proc?: ChildProcess;\n private killed = false;\n /** callId → JSON-RPC server-request id we still owe a result to. */\n pendingApprovals = new Map<string, number>();\n /** callId → originating wire family (drives v2/legacy/mcp reply shape). */\n approvalMethods = new Map<string, ApprovalWireFamily>();\n /** Monotonic counter for approval resolver keys. */\n private nextResolverKey = 1;\n /** Resolver registered by the rpc client for each pending approval. */\n approvalResolvers = new Map<number, (reply: Record<string, string>) => void>();\n rpc?: JsonRpcClient;\n backendSessionId?: string;\n /**\n * Thread id to resume on agent restart. When set, handshake() sends\n * `thread/resume { threadId }` instead of `thread/start { cwd }`.\n * Set from SpawnOptions.resumeId in CodexAdapter.spawn(). Must NOT be\n * passed as `--resume` CLI flag — app-server rejects it.\n */\n resumeId?: string;\n /** True once `initialize` round-trip + `thread/start` (or `thread/resume`) have completed. */\n handshakeComplete = false;\n /** Inputs queued by send() while the handshake is still in flight. */\n pendingInputs: string[] = [];\n /** Temp file for briefing injection; cleaned up on kill(). */\n briefingFile?: string;\n /**\n * Set by CodexAdapter.spawn() so handshake() can surface real process-exit\n * info if the codex CLI died (e.g. arg parse error). Without this, a dead\n * process leads to a generic \"handshake timeout\" instead of the actual\n * \"error: unexpected argument …\" stderr message.\n *\n * Default returns (null, \"\") for tests that construct CodexProcess\n * directly without going through spawn() (e.g. attachRpc mock pipes).\n * spawn() overrides these with real getters wired to the child process.\n */\n getExitInfo: () => { code: number | null; signal: string | null } | null = () => null;\n getStderr: () => string = () => \"\";\n\n /** Allocate a resolver key. Monotonic; never reused. */\n allocResolverKey(): number {\n return this.nextResolverKey++;\n }\n\n constructor(sessionId: string, workDir: string, proc?: ChildProcess) {\n super();\n this.id = sessionId;\n this.workDir = workDir;\n this.proc = proc;\n this.pid = proc?.pid;\n }\n\n async kill(): Promise<void> {\n this.killed = true;\n // Drain any pending approval bookkeeping so long-running hubs don't leak\n // entries on aborted sessions. Resolve any outstanding RPC promise with a\n // \"cancel\"-equivalent so callers awaiting `respondToPermission` never hang.\n for (const [, resolver] of this.approvalResolvers) {\n try {\n resolver({ decision: \"abort\" });\n } catch {\n // ignore\n }\n }\n this.pendingApprovals.clear();\n this.approvalMethods.clear();\n this.approvalResolvers.clear();\n this.pendingInputs.length = 0;\n if (this.briefingFile) {\n cleanupBriefingFile(this.briefingFile);\n this.briefingFile = undefined;\n }\n if (this.proc && !this.proc.killed) {\n try {\n this.proc.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n }\n }\n\n isAlive(): boolean {\n if (this.killed) return false;\n if (!this.proc) return true;\n return !this.proc.killed && this.proc.exitCode === null;\n }\n}\n\nexport interface CodexAdapterOptions {\n /** Override path to the codex binary. Default: lookup in PATH. */\n codexBin?: string;\n /**\n * Max time to wait for codex handshake (initialize + thread/start|resume)\n * to complete before emitting an error. Default: 15s. Used to detect the\n * case where the codex process dies mid-handshake (CLI parse error,\n * crash) — without this, pendingInputs stack up forever and the swarm\n * silently stalls.\n */\n handshakeTimeoutMs?: number;\n}\n\n/**\n * CodexAdapter — BackendAdapter wrapping `codex app-server --listen stdio://`.\n *\n * M3.S3 scope: spawn/stop/send/onOutput plus the permission flow\n * (`onPermissionRequest` / `respondToPermission`). Resume + token-budget +\n * MCP plumbing land in follow-up slices.\n */\nexport class CodexAdapter implements BackendAdapter {\n readonly type = \"codex\";\n private codexBin: string;\n private handshakeTimeoutMs: number;\n\n constructor(options?: CodexAdapterOptions) {\n this.codexBin = options?.codexBin ?? \"codex\";\n // Precedence: explicit constructor option > env var > 15s default. The\n // env var (CLAWNET_CODEX_HANDSHAKE_TIMEOUT_MS) is the escape hatch for\n // slow CI / cold-start machines where 15s isn't enough and the user\n // can't easily inject a CodexAdapterOptions override.\n const envTimeout = Number(process.env.CLAWNET_CODEX_HANDSHAKE_TIMEOUT_MS);\n this.handshakeTimeoutMs =\n options?.handshakeTimeoutMs ??\n (Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : 15000);\n }\n\n async spawn(options: SpawnOptions): Promise<CodexProcess> {\n let cwd = options.workDir || process.cwd();\n if (!existsSync(cwd)) cwd = homedir();\n\n // Build args with MCP + briefing injection\n const mcpServer = this.buildMcpServerConfig(options);\n const { args, briefingFile } = buildCodexSpawnArgs({\n sessionId: options.sessionId,\n resumeId: options.resumeId,\n systemPrompt: options.systemPrompt,\n mcpServer,\n sandbox: options.sandbox,\n });\n\n log.info(\n { sessionId: options.sessionId, bin: this.codexBin, args, cwd, resumeId: options.resumeId },\n \"codex spawn: forking app-server\",\n );\n const proc = spawn(this.codexBin, args, {\n cwd,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: process.env,\n windowsHide: true,\n });\n // Capture exit state into a closure so handshake() can surface it if\n // initialize / thread RPC times out. Without this guard a dead codex\n // (e.g. CLI arg parse error → ~600ms after spawn) would leave the\n // adapter waiting handshakeTimeoutMs (default 15s) with a generic\n // \"handshake timeout\" message. With it, we report exit code + stderr.\n const stderrChunks: string[] = [];\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString(\"utf8\").trim();\n if (text) {\n stderrChunks.push(text);\n log.warn({ sessionId: options.sessionId, stderr: text }, \"codex stderr\");\n }\n });\n let exitInfo: { code: number | null; signal: string | null } | null = null;\n proc.on(\"exit\", (code, signal) => {\n // \"Clean\" exits: code 0 (normal completion) or signal SIGTERM (we\n // asked it to stop via kill()). Anything else — non-zero code, OR\n // a different signal like SIGKILL / SIGSEGV / SIGABRT — is unclean\n // and worth a warn so monitoring/dashboards can flag it.\n const isClean = code === 0 || signal === \"SIGTERM\";\n const level = isClean ? \"debug\" : \"warn\";\n log[level]({ sessionId: options.sessionId, code, signal }, \"codex process exited\");\n if (!exitInfo) exitInfo = { code, signal };\n });\n\n await new Promise<void>((resolve, reject) => {\n const t = setTimeout(() => resolve(), 2000);\n proc.on(\"error\", (err) => {\n clearTimeout(t);\n reject(new Error(`Failed to spawn codex CLI: ${err.message}`));\n });\n proc.on(\"spawn\", () => {\n clearTimeout(t);\n log.debug({ sessionId: options.sessionId, pid: proc.pid }, \"codex spawn: process started\");\n resolve();\n });\n });\n\n const cp = new CodexProcess(options.sessionId, cwd, proc);\n cp.briefingFile = briefingFile;\n cp.resumeId = options.resumeId;\n // Expose process-exit signal to handshake so a timeout can report the\n // real cause instead of a generic \"timeout\".\n cp.getExitInfo = () => exitInfo;\n cp.getStderr = () => stderrChunks.join(\"\\n\").slice(0, 800);\n this.wireRpc(cp);\n return cp;\n }\n\n private buildMcpServerConfig(options: SpawnOptions): McpServerConfig | undefined {\n // Resolve clawnet-mcp-server path. Primary: Node's native module\n // resolution (handles npm flat, npm nested, pnpm symlinks, yarn classic\n // — wherever node would `require()` the package from). Fallback:\n // monorepo-relative path for dev where the package isn't \"installed\".\n let serverPath: string | undefined;\n try {\n const require = createRequire(import.meta.url);\n serverPath = require.resolve(\"@mclawnet/mcp-server/dist/server.js\");\n } catch {\n const devPath = join(\n import.meta.dirname ?? __dirname,\n \"../../mcp-server/dist/server.js\",\n );\n if (existsSync(devPath)) serverPath = devPath;\n }\n if (!serverPath) {\n log.warn(\n { pkg: \"@mclawnet/mcp-server\" },\n \"codex: clawnet-mcp-server not resolvable, codex role will lack MCP tools\",\n );\n return undefined;\n }\n const env: Record<string, string> = {};\n if (options.workDir) env.CLAWNET_WORK_DIR = options.workDir;\n // mcp-server's server.ts:28 explicitly documents: CLAWNET_HOME is the\n // user home (NO `.clawnet` suffix) — the server appends `.clawnet`\n // itself via projectRoot(). Passing `~/.clawnet` here would yield\n // `~/.clawnet/.clawnet/...` (double append) and break inbox/task layout.\n const home = process.env.CLAWNET_HOME ?? homedir();\n env.CLAWNET_HOME = home;\n return { command: \"node\", args: [serverPath], env };\n }\n\n /**\n * Bind a CodexProcess to a JSON-RPC duplex. Public so tests can inject a\n * mocked stdin/stdout pair without spawning a real subprocess.\n *\n * Drives the v2 handshake automatically: `initialize` → `thread/start`.\n * Once `thread/start` resolves, `cp.backendSessionId` is set and a\n * `session_started` event fires so the agent's hub bridge can persist it.\n */\n attachRpc(\n cp: CodexProcess,\n stdin: NodeJS.WritableStream,\n stdout: NodeJS.ReadableStream,\n ): void {\n const rpc = new JsonRpcClient({\n stdin: stdin as never,\n stdout: stdout as never,\n onRequest: (method, params) => this.handleServerRequest(cp, method, params),\n onNotification: (method, params) => this.handleNotification(cp, method, params),\n onMalformedLine: (line, err) =>\n log.warn(\n { sessionId: cp.id, err: err.message, linePreview: line.slice(0, 200) },\n \"codex stdout: non-JSON line ignored\",\n ),\n });\n cp.rpc = rpc;\n void this.handshake(cp);\n }\n\n private async handshake(cp: CodexProcess): Promise<void> {\n if (!cp.rpc) return;\n const rpc = cp.rpc;\n const resumeId = cp.resumeId;\n log.info(\n { sessionId: cp.id, workDir: cp.workDir, resumeId },\n \"codex handshake: start\",\n );\n\n // Wrap the whole handshake in a timeout so a dead codex process (e.g.\n // killed by `--resume` CLI parse error, segfault, etc.) doesn't leave\n // pendingInputs queued forever. Without this guard the swarm silently\n // stalls — the user sees no error, just nothing happens.\n //\n // raceSettled is declared up here (before the IIFE) so the handshake\n // success path can also check it. If timeout/death wins the race,\n // handshakeAttempt may still complete later — without this guard it\n // would mutate cp.backendSessionId, emit session_started, and flush\n // pendingInputs against a process the caller already considers dead.\n let raceSettled = false;\n const handshakeAttempt = (async () => {\n await rpc.request(\"initialize\", { clientInfo: CLAWNET_CLIENT_INFO });\n log.info({ sessionId: cp.id }, \"codex handshake: initialize ok\");\n\n // Branch on resumeId — `codex app-server` rejects `--resume` CLI flag,\n // so resume MUST happen at the JSON-RPC layer via `thread/resume`.\n // `thread/start` on a resumed codex returns a NEW threadId (losing\n // conversation continuity), which is why we have to branch here.\n let threadId: string | undefined;\n if (resumeId) {\n const resumed = (await rpc.request(\"thread/resume\", { threadId: resumeId })) as\n | { thread?: { id?: string }; threadId?: string }\n | undefined;\n // Don't silently fall back to the input resumeId — if codex ever\n // migrates the thread id (the protocol allows it) we'd persist a\n // stale id and break the next restart. Treat absent thread id as a\n // protocol error so the caller sees it and can re-spawn fresh.\n threadId = resumed?.thread?.id ?? resumed?.threadId;\n } else {\n // v2 `thread/start` returns { thread: { id, sessionId, ... }, ... }.\n // The resumable identifier is `thread.id` — `sessionId` here is the\n // tree-id shared by forked threads, not what `thread/resume` wants.\n const started = (await rpc.request(\"thread/start\", { cwd: cp.workDir })) as\n | { thread?: { id?: string }; threadId?: string }\n | undefined;\n threadId = started?.thread?.id ?? started?.threadId;\n }\n\n if (!threadId) {\n throw new Error(\n `codex handshake: ${resumeId ? \"thread/resume\" : \"thread/start\"} returned no threadId`,\n );\n }\n // Race lost (timeout/death already won) → don't mutate state, don't\n // emit session_started, don't flush queued inputs. The handshake\n // error has already been reported via cp.emit(\"error\") in the\n // catch-block below.\n if (raceSettled) {\n log.warn(\n { sessionId: cp.id, threadId },\n \"codex handshake resolved AFTER race already lost — discarding result\",\n );\n return;\n }\n cp.backendSessionId = threadId;\n cp.handshakeComplete = true;\n log.info(\n { sessionId: cp.id, threadId, queuedInputs: cp.pendingInputs.length },\n \"codex handshake: complete, flushing queued inputs\",\n );\n cp.emit(\"session_started\", { backendSessionId: threadId });\n // Flush any inputs that arrived while the handshake was in flight.\n const queued = cp.pendingInputs.splice(0);\n for (const input of queued) {\n this.dispatchTurn(cp, input);\n }\n })();\n // Attach a no-op catch so handshakeAttempt rejecting AFTER losing the\n // race (timeout or death already won) doesn't bubble as an unhandled\n // promise rejection — node --unhandled-rejections=strict would crash.\n // The real error already surfaced via cp.emit(\"error\") above.\n handshakeAttempt.catch(() => {});\n\n let timeoutHandle: NodeJS.Timeout | undefined;\n let exitPollHandle: NodeJS.Timeout | undefined;\n // raceSettled is checked by the death-poll loop and the handshake\n // success path. clearTimeout in finally{} alone is insufficient:\n // poll() may be mid-execution when finally runs, scheduling the next\n // setTimeout before clear; the success path could likewise resolve a\n // late RPC after the race has been decided.\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutHandle = setTimeout(() => {\n reject(\n new Error(\n `codex handshake timeout after ${this.handshakeTimeoutMs}ms (process may have died)`,\n ),\n );\n }, this.handshakeTimeoutMs);\n });\n\n // Process-death detector: poll exitInfo every 100ms; if codex exits\n // mid-handshake (e.g. CLI parse error), reject early with the real\n // stderr instead of waiting handshakeTimeoutMs (15s default) for the\n // generic timeout message.\n const deathPromise = new Promise<never>((_, reject) => {\n const poll = () => {\n if (raceSettled) return; // race already over — stop recursing\n const exit = cp.getExitInfo();\n if (exit) {\n const stderr = cp.getStderr();\n reject(\n new Error(\n `codex process died during handshake ` +\n `(code=${exit.code}, signal=${exit.signal}). ` +\n `stderr: ${stderr || \"(empty)\"}`,\n ),\n );\n return;\n }\n exitPollHandle = setTimeout(poll, 100);\n };\n poll();\n });\n\n try {\n await Promise.race([handshakeAttempt, timeoutPromise, deathPromise]);\n } catch (err) {\n log.error({ err, sessionId: cp.id }, \"codex v2 handshake failed\");\n cp.emit(\"error\", err);\n } finally {\n raceSettled = true;\n if (timeoutHandle) clearTimeout(timeoutHandle);\n if (exitPollHandle) clearTimeout(exitPollHandle);\n }\n }\n\n private wireRpc(cp: CodexProcess) {\n const proc = cp.proc;\n if (proc?.stdin && proc?.stdout) {\n this.attachRpc(cp, proc.stdin, proc.stdout);\n }\n }\n\n private handleServerRequest(\n cp: CodexProcess,\n method: string,\n params: unknown,\n ): Promise<unknown> {\n const parsed = parseApprovalRequest(method, params);\n if (!parsed) {\n log.warn({ method }, \"codex server-request: unrecognized method\");\n return Promise.resolve({ decision: \"denied\" });\n }\n const { req, wireFamily } = parsed;\n return new Promise((resolve) => {\n const resolverKey = cp.allocResolverKey();\n cp.pendingApprovals.set(req.callId, resolverKey);\n cp.approvalMethods.set(req.callId, wireFamily);\n cp.approvalResolvers.set(resolverKey, (reply) => {\n resolve(reply);\n });\n cp.emit(\"permission_request\", req);\n });\n }\n\n private handleNotification(cp: CodexProcess, method: string, params: unknown) {\n // v2 thread lifecycle\n if (method === \"thread/started\") {\n // codex emits this as a *notification* during normal turns too; the\n // primary session_started signal comes from thread/start's RPC result\n // (see handshake()). Suppress the duplicate here so onSessionStarted\n // listeners only fire once.\n return;\n }\n if (method === \"error\") {\n // Surface codex-side errors prominently — without this they degrade to\n // a `{kind:\"raw\"}` envelope and get lost in the agent's debug stream.\n log.warn({ sessionId: cp.id, params }, \"codex error notification\");\n }\n if (method === \"turn/completed\" || method === \"thread/turnComplete\" || method === \"turn/complete\") {\n log.info({ sessionId: cp.id, method }, \"codex turn complete\");\n // Token usage is delivered via the separate\n // `thread/tokenUsageUpdated` notification — the `turn` payload here\n // does NOT carry a `usage` field per the v2 schema.\n cp.emit(\"turn_complete\", {\n backendSessionId: cp.backendSessionId,\n });\n return;\n }\n if (method === \"turn/started\") {\n log.info({ sessionId: cp.id }, \"codex turn started\");\n return;\n }\n const out: BackendOutput = mapCodexFrame({ method, params });\n this.logBackendOutput(cp.id, method, out);\n cp.emit(\"output\", out);\n }\n\n /**\n * Selective notification logging. The previous catch-all `log.debug(\"codex\n * notification\")` fired for every streaming `item/agentMessage/delta` chunk\n * (many per turn), drowning the actually useful events. Instead, log only\n * structural events at INFO and surface unrecognised methods as WARN so the\n * `{kind:\"raw\"}` degradation isn't silent.\n */\n private logBackendOutput(sessionId: string, method: string, out: BackendOutput): void {\n // Streaming text deltas — too high-frequency to log per-chunk.\n if (method === \"item/agentMessage/delta\") return;\n // Other token-usage / progress notifications without a structural meaning.\n if (method === \"thread/tokenUsageUpdated\") return;\n\n switch (out.kind) {\n case \"tool_use\":\n log.info(\n { sessionId, callId: out.callId, tool: out.toolName, input: preview(out.input, 120) },\n \"codex tool_use\",\n );\n return;\n case \"tool_result\":\n log.info(\n { sessionId, callId: out.callId, isError: out.isError, output: preview(out.output, 120) },\n \"codex tool_result\",\n );\n return;\n case \"assistant_text\":\n log.debug(\n { sessionId, len: out.text.length, text: preview(out.text, 120) },\n \"codex assistant_text\",\n );\n return;\n case \"raw\":\n log.warn({ sessionId, method, payload: preview(out.payload, 200) }, \"codex unhandled frame\");\n return;\n }\n }\n\n async stop(process: BackendProcess): Promise<void> {\n await process.kill();\n }\n\n send(process: BackendProcess, input: string): void {\n if (!(process instanceof CodexProcess)) {\n log.warn(\n { sessionId: (process as { id?: string })?.id, len: input.length },\n \"codex send: not a CodexProcess — input dropped\",\n );\n return;\n }\n if (!process.rpc) {\n log.warn({ sessionId: process.id, len: input.length }, \"codex send: no rpc — input dropped\");\n return;\n }\n if (!process.backendSessionId) {\n // Handshake still in flight: queue the input and let `handshake()`\n // flush it once `thread/start` resolves. This avoids silent drops when\n // a hub author moves from claude-adapter (no handshake) to codex.\n process.pendingInputs.push(input);\n log.info(\n { sessionId: process.id, queueDepth: process.pendingInputs.length, len: input.length },\n \"codex send: handshake pending, queued\",\n );\n return;\n }\n log.info(\n { sessionId: process.id, threadId: process.backendSessionId, len: input.length },\n \"codex send: dispatching turn/start\",\n );\n this.dispatchTurn(process, input);\n }\n\n private dispatchTurn(process: CodexProcess, input: string): void {\n if (!process.rpc || !process.backendSessionId) return;\n // codex v2: turn/start is a *request* (server returns a result when the\n // turn is queued). We fire-and-forget here because the agent loop reacts\n // to async `turn/completed` / `item/...` notifications, not to the\n // request's result envelope.\n void process.rpc\n .request(\"turn/start\", {\n threadId: process.backendSessionId,\n input: [{ type: \"text\", text: input }],\n })\n .then(() => {\n log.info(\n { sessionId: process.id, threadId: process.backendSessionId },\n \"codex turn/start: accepted by server\",\n );\n })\n .catch((err: Error) => {\n log.warn({ err, sessionId: process.id }, \"turn/start failed\");\n process.emit(\"error\", err);\n });\n }\n\n onOutput(process: BackendProcess, handler: (msg: unknown) => void): void {\n if (process instanceof CodexProcess) process.on(\"output\", handler);\n }\n\n onPermissionRequest(\n process: BackendProcess,\n handler: (req: PermissionRequest) => void,\n ): void {\n if (process instanceof CodexProcess) process.on(\"permission_request\", handler);\n }\n\n async respondToPermission(\n process: BackendProcess,\n decision: PermissionDecision,\n ): Promise<void> {\n if (!(process instanceof CodexProcess)) return;\n const key = process.pendingApprovals.get(decision.callId);\n if (key === undefined) {\n log.warn({ callId: decision.callId }, \"respondToPermission: no pending approval\");\n return;\n }\n const family = process.approvalMethods.get(decision.callId) ?? \"legacy\";\n const resolver = process.approvalResolvers.get(key);\n process.pendingApprovals.delete(decision.callId);\n process.approvalMethods.delete(decision.callId);\n process.approvalResolvers.delete(key);\n const reply = buildApprovalReply(family, decision.decision);\n resolver?.(reply);\n }\n\n onTurnComplete(\n process: BackendProcess,\n handler: (info: { backendSessionId?: string }) => void,\n ): void {\n if (process instanceof CodexProcess) process.on(\"turn_complete\", handler);\n }\n\n onSessionStarted(\n process: BackendProcess,\n handler: (info: { backendSessionId: string }) => void,\n ): void {\n if (process instanceof CodexProcess) process.on(\"session_started\", handler);\n }\n\n onError(process: BackendProcess, handler: (err: Error) => void): void {\n if (process instanceof CodexProcess) process.on(\"error\", handler);\n }\n\n onExit(process: BackendProcess, handler: (code: number | null) => void): void {\n if (process instanceof CodexProcess) process.on(\"exit\", handler);\n }\n}\n","/**\n * codex-spawn-args — construct CLI args for `codex app-server` with\n * per-spawn MCP server + briefing injection.\n *\n * Extracted from CodexAdapter.spawn() so it can be unit-tested without\n * spawning a real child process.\n */\nimport { writeFileSync, unlinkSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { randomUUID } from \"node:crypto\";\nimport { DEFAULT_SANDBOX, type SandboxLevel } from \"@mclawnet/shared\";\n\nexport interface McpServerConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\nexport interface CodexSpawnArgsOptions {\n sessionId: string;\n resumeId?: string;\n systemPrompt?: string;\n mcpServer?: McpServerConfig;\n /**\n * Per-role sandbox level. Maps to codex's `sandbox_mode` config key:\n * - \"read-only\" → `read-only`\n * - \"workspace-write\" → `workspace-write` (default)\n * - \"full-access\" → `danger-full-access` (codex's internal name; we\n * expose the friendlier label upstream)\n * Undefined falls back to \"workspace-write\" so existing callers see no\n * behavior change.\n */\n sandbox?: SandboxLevel;\n}\n\nexport interface CodexSpawnArgsResult {\n args: string[];\n briefingFile?: string;\n}\n\nfunction escapeToml(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nexport function buildCodexSpawnArgs(options: CodexSpawnArgsOptions): CodexSpawnArgsResult {\n const args: string[] = [\"app-server\"];\n let briefingFile: string | undefined;\n\n // NOTE: `--resume <id>` is NOT a valid `codex app-server` flag. It only\n // exists on `codex` interactive / `codex exec`. Passing it to app-server\n // makes the CLI exit with \"error: unexpected argument '--resume' found\",\n // and the calling spawn() doesn't notice the immediate exit, so all\n // JSON-RPC traffic hangs. Resume is implemented at the protocol layer\n // by sending `thread/resume { threadId }` from CodexAdapter.handshake()\n // when CodexProcess.resumeId is set. `options.resumeId` is kept on the\n // CodexProcess for the handshake to read; we do NOT add it to args.\n void options.resumeId;\n\n // Non-interactive runtime policy: swarm roles run unattended, so MCP tool\n // calls must not be gated on a user-facing approval prompt. Without\n // `approval_policy=\"never\"`, codex defaults to `on-request` and rejects\n // every MCP tool call with \"user rejected MCP tool call\" because there's\n // no elicitation handler wired on the client side. `workspace-write`\n // matches the role's workDir as the writable root (analogous to claude-\n // adapter's `--permission-mode bypassPermissions` + workspace boundary).\n args.push(\"-c\", 'approval_policy=\"never\"');\n // Map ClawNet's abstract sandbox level to codex's mode name. We expose\n // \"full-access\" to users for readability; codex's internal mode is\n // named \"danger-full-access\". Default (undefined) → DEFAULT_SANDBOX\n // from @mclawnet/shared so existing swarms keep current behavior.\n const sandboxLevel: SandboxLevel = options.sandbox ?? DEFAULT_SANDBOX;\n const codexSandboxMode =\n sandboxLevel === \"read-only\"\n ? \"read-only\"\n : sandboxLevel === \"full-access\"\n ? \"danger-full-access\"\n : \"workspace-write\";\n args.push(\"-c\", `sandbox_mode=\"${codexSandboxMode}\"`);\n\n // Layer 1: MCP server injection via -c flags\n if (options.mcpServer) {\n const { command, args: serverArgs, env } = options.mcpServer;\n args.push(\"-c\", `mcp_servers.clawnet-mcp.command=\"${escapeToml(command)}\"`);\n if (serverArgs && serverArgs.length > 0) {\n const argsToml = \"[\" + serverArgs.map((a) => `\"${escapeToml(a)}\"`).join(\", \") + \"]\";\n args.push(\"-c\", `mcp_servers.clawnet-mcp.args=${argsToml}`);\n }\n if (env) {\n for (const [key, value] of Object.entries(env)) {\n args.push(\"-c\", `mcp_servers.clawnet-mcp.env.${key}=\"${escapeToml(value)}\"`);\n }\n }\n // CRITICAL: per-server tool approval mode. Without this codex still\n // elicits each MCP tool call (even with global approval_policy=\"never\"\n // which only covers shell exec). The elicitation has no client-side\n // handler, so every MCP tool call returns \"user rejected MCP tool call\"\n // in 0s. \"approve\" silently approves all tool calls — required for\n // unattended swarm-role execution. (Valid values are \"prompt\" and\n // \"approve\"; \"auto\" is NOT accepted by codex 0.134.)\n args.push(\"-c\", 'mcp_servers.clawnet-mcp.default_tools_approval_mode=\"approve\"');\n }\n\n // Layer 2: Briefing injection via temp file + model_instructions_file\n if (options.systemPrompt) {\n briefingFile = join(tmpdir(), `clawnet-briefing-${options.sessionId}-${randomUUID().slice(0, 8)}.md`);\n writeFileSync(briefingFile, options.systemPrompt, { encoding: \"utf-8\", mode: 0o600 });\n args.push(\"-c\", `model_instructions_file=\"${escapeToml(briefingFile)}\"`);\n }\n\n return { args, briefingFile };\n}\n\nexport function cleanupBriefingFile(filePath: string): void {\n try {\n unlinkSync(filePath);\n } catch {\n // ignore — file may already be gone\n }\n}\n","import type { Writable, Readable } from \"node:stream\";\n\nexport interface JsonRpcClientOptions {\n stdin: Writable;\n stdout: Readable;\n onRequest?: (method: string, params: unknown) => Promise<unknown> | unknown;\n onNotification?: (method: string, params: unknown) => void;\n onMalformedLine?: (line: string, err: Error) => void;\n}\n\ninterface JsonRpcPending {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n}\n\n/**\n * Minimal JSON-RPC 2.0 client over NDJSON stdio.\n *\n * Half of the duplex: client-initiated `request()` returns a Promise tied to\n * the response by id. Server-initiated requests (codex approval callbacks)\n * are dispatched to `onRequest` and the resolved value is written back as a\n * `result` envelope.\n */\nexport class JsonRpcClient {\n private stdin: Writable;\n private buffer = \"\";\n private nextId = 1;\n private pending = new Map<number, JsonRpcPending>();\n private onRequest?: JsonRpcClientOptions[\"onRequest\"];\n private onNotification?: JsonRpcClientOptions[\"onNotification\"];\n private onMalformedLine?: JsonRpcClientOptions[\"onMalformedLine\"];\n\n constructor(opts: JsonRpcClientOptions) {\n this.stdin = opts.stdin;\n this.onRequest = opts.onRequest;\n this.onNotification = opts.onNotification;\n this.onMalformedLine = opts.onMalformedLine;\n opts.stdout.on(\"data\", (chunk: Buffer) => this.feed(chunk.toString(\"utf-8\")));\n }\n\n request(method: string, params: unknown): Promise<unknown> {\n const id = this.nextId++;\n const frame = { jsonrpc: \"2.0\", id, method, params };\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n this.stdin.write(JSON.stringify(frame) + \"\\n\");\n });\n }\n\n notify(method: string, params: unknown): void {\n this.stdin.write(JSON.stringify({ jsonrpc: \"2.0\", method, params }) + \"\\n\");\n }\n\n private feed(s: string) {\n this.buffer += s;\n let nl: number;\n while ((nl = this.buffer.indexOf(\"\\n\")) >= 0) {\n const line = this.buffer.slice(0, nl).trim();\n this.buffer = this.buffer.slice(nl + 1);\n if (!line) continue;\n this.dispatch(line);\n }\n }\n\n private dispatch(line: string) {\n let msg: {\n id?: number;\n method?: string;\n params?: unknown;\n result?: unknown;\n error?: { code: number; message: string };\n };\n try {\n msg = JSON.parse(line);\n } catch (err) {\n this.onMalformedLine?.(line, err as Error);\n return;\n }\n if (typeof msg.id === \"number\" && (msg.result !== undefined || msg.error !== undefined)) {\n const pending = this.pending.get(msg.id);\n if (!pending) return;\n this.pending.delete(msg.id);\n if (msg.error) pending.reject(new Error(msg.error.message));\n else pending.resolve(msg.result);\n return;\n }\n if (msg.method && typeof msg.id === \"number\") {\n // server-initiated request\n const id = msg.id;\n const method = msg.method;\n const params = msg.params;\n void Promise.resolve(this.onRequest?.(method, params))\n .then((result) => {\n this.stdin.write(JSON.stringify({ jsonrpc: \"2.0\", id, result }) + \"\\n\");\n })\n .catch((err: Error) => {\n this.stdin.write(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n error: { code: -32000, message: err.message },\n }) + \"\\n\",\n );\n });\n return;\n }\n if (msg.method) {\n this.onNotification?.(msg.method, msg.params);\n }\n }\n}\n","import type { PermissionDecision, PermissionRequest } from \"@mclawnet/agent\";\n\n/**\n * Three coexisting decision-wire families codex app-server speaks:\n * - \"legacy\" → ReviewDecision (approved/approved_for_session/denied/abort)\n * - \"v2\" → CommandExecutionApprovalDecision / FileChangeApprovalDecision\n * (accept/acceptForSession/decline/cancel)\n * - \"mcp\" → McpServerElicitationAction\n * ({ action: \"accept\" | \"decline\" | \"cancel\" })\n *\n * `parseApprovalRequest` returns the family so `respondToPermission` can pick\n * the right wire without re-deriving it from a brittle method-name prefix.\n */\nexport type ApprovalWireFamily = \"legacy\" | \"v2\" | \"mcp\";\n\nexport type ReviewDecisionWire =\n | \"approved\"\n | \"approved_for_session\"\n | \"denied\"\n | \"abort\";\n\nexport function decisionToWire(d: PermissionDecision[\"decision\"]): ReviewDecisionWire {\n switch (d) {\n case \"allow\":\n return \"approved\";\n case \"allow_session\":\n return \"approved_for_session\";\n case \"deny\":\n return \"denied\";\n case \"abort\":\n return \"abort\";\n default: {\n const _exhaustive: never = d;\n return _exhaustive;\n }\n }\n}\n\n/**\n * v2 CommandExecutionApprovalDecision / FileChangeApprovalDecision wire enum.\n * Used by codex app-server >= 0.134 for `item/.../requestApproval` flows.\n */\nexport type V2DecisionWire = \"accept\" | \"acceptForSession\" | \"decline\" | \"cancel\";\n\nexport function decisionToV2Wire(d: PermissionDecision[\"decision\"]): V2DecisionWire {\n switch (d) {\n case \"allow\":\n return \"accept\";\n case \"allow_session\":\n return \"acceptForSession\";\n case \"deny\":\n return \"decline\";\n case \"abort\":\n return \"cancel\";\n default: {\n const _exhaustive: never = d;\n return _exhaustive;\n }\n }\n}\n\n/**\n * MCP elicitation action enum (RMCP CreateElicitationResult). Note: \"session\"\n * scope isn't part of the MCP spec — `allow_session` degrades to \"accept\".\n */\nexport type McpElicitationAction = \"accept\" | \"decline\" | \"cancel\";\n\nexport function decisionToMcpAction(d: PermissionDecision[\"decision\"]): McpElicitationAction {\n switch (d) {\n case \"allow\":\n case \"allow_session\":\n return \"accept\";\n case \"deny\":\n return \"decline\";\n case \"abort\":\n return \"cancel\";\n default: {\n const _exhaustive: never = d;\n return _exhaustive;\n }\n }\n}\n\n/** @deprecated kept only for back-compat with M3.S5 test seam; prefer the\n * wire family returned by `parseApprovalRequest`. */\nexport function isV2ApprovalMethod(method: string): boolean {\n return method.startsWith(\"item/\");\n}\n\n/**\n * Build the wire-shaped reply body for a given decision + family.\n * - legacy → `{ decision: \"approved\" | ... }`\n * - v2 → `{ decision: \"accept\" | ... }`\n * - mcp → `{ action: \"accept\" | ... }`\n */\nexport function buildApprovalReply(\n family: ApprovalWireFamily,\n decision: PermissionDecision[\"decision\"],\n): Record<string, string> {\n switch (family) {\n case \"legacy\":\n return { decision: decisionToWire(decision) };\n case \"v2\":\n return { decision: decisionToV2Wire(decision) };\n case \"mcp\":\n return { action: decisionToMcpAction(decision) };\n default: {\n const _exhaustive: never = family;\n return _exhaustive;\n }\n }\n}\n\nexport interface ParsedApprovalRequest {\n req: PermissionRequest;\n wireFamily: ApprovalWireFamily;\n}\n\n/**\n * Map a codex JSON-RPC approval request to our backend-neutral\n * PermissionRequest. Covers both legacy (`execCommandApproval`,\n * `applyPatchApproval`) and v2 (`item/commandExecution/requestApproval`,\n * `item/fileChange/requestApproval`) shapes, plus MCP elicitation.\n *\n * Returns null when the method is not a recognized approval channel — the\n * adapter forwards such frames as raw output instead.\n */\nexport function parseApprovalRequest(\n method: string,\n params: unknown,\n): ParsedApprovalRequest | null {\n const p = (params ?? {}) as Record<string, unknown>;\n const callId = (p.callId as string | undefined) ?? (p.itemId as string | undefined);\n if (!callId) return null;\n const reason = p.reason as string | undefined;\n const cwd = p.cwd as string | undefined;\n\n if (method === \"execCommandApproval\") {\n return {\n req: {\n callId,\n toolName: \"shell\",\n input: { command: p.command, cwd },\n meta: { backend: \"codex\", reason, cwd },\n },\n wireFamily: \"legacy\",\n };\n }\n if (method === \"item/commandExecution/requestApproval\") {\n return {\n req: {\n callId,\n toolName: \"shell\",\n input: { command: p.command, cwd },\n meta: { backend: \"codex\", reason, cwd },\n },\n wireFamily: \"v2\",\n };\n }\n if (method === \"applyPatchApproval\") {\n return {\n req: {\n callId,\n toolName: \"apply_patch\",\n input: { fileChanges: p.fileChanges },\n meta: { backend: \"codex\", reason, cwd },\n },\n wireFamily: \"legacy\",\n };\n }\n if (method === \"item/fileChange/requestApproval\") {\n return {\n req: {\n callId,\n toolName: \"apply_patch\",\n input: { fileChanges: p.fileChanges },\n meta: { backend: \"codex\", reason, cwd },\n },\n wireFamily: \"v2\",\n };\n }\n if (method === \"mcpServer/elicitation/request\") {\n return {\n req: {\n callId,\n toolName: (p.serverName as string | undefined) ?? \"mcp\",\n input: { message: p.message, meta: p._meta },\n meta: { backend: \"codex\", reason },\n },\n wireFamily: \"mcp\",\n };\n }\n return null;\n}\n","import type { BackendOutput } from \"@mclawnet/agent\";\n\n/**\n * Map a single codex JSON-RPC notification frame to a backend-neutral\n * BackendOutput envelope. Unknown methods degrade to `{ kind: \"raw\" }` so\n * the agent main loop can still see them (e.g. for debug logging) without\n * the adapter pretending to understand every codex frame.\n *\n * Covers both v2 (`item/agentMessage/delta`, `item/started`, `item/completed`)\n * and legacy (`thread/message`, `thread/toolUse`) frame names.\n */\nexport function mapCodexFrame(frame: {\n method: string;\n params?: unknown;\n}): BackendOutput {\n const params = (frame.params ?? {}) as Record<string, unknown>;\n switch (frame.method) {\n // ── v2 frames (real codex app-server v2 protocol) ─────────────────\n case \"item/agentMessage/delta\": {\n const delta = params.delta;\n if (typeof delta === \"string\") {\n return { kind: \"assistant_text\", text: delta };\n }\n break;\n }\n case \"item/completed\": {\n const item = params.item as\n | {\n type?: string;\n text?: string;\n id?: string;\n // commandExecution\n command?: string;\n aggregatedOutput?: string | null;\n exitCode?: number | null;\n status?: string;\n // fileChange\n changes?: unknown;\n // mcpToolCall\n server?: string;\n tool?: string;\n arguments?: unknown;\n result?: unknown;\n error?: unknown;\n }\n | undefined;\n if (item?.type === \"agentMessage\" && typeof item.text === \"string\") {\n return { kind: \"assistant_text\", text: item.text };\n }\n if (item?.type === \"commandExecution\") {\n // CommandExecutionStatus = \"inProgress\" | \"completed\" | \"failed\" | \"declined\"\n const failed = item.status === \"failed\" || item.status === \"declined\";\n const badExit = typeof item.exitCode === \"number\" && item.exitCode !== 0;\n return {\n kind: \"tool_result\",\n callId: String(item.id ?? \"\"),\n output: item.aggregatedOutput ?? null,\n isError: failed || badExit,\n };\n }\n if (item?.type === \"fileChange\") {\n // PatchApplyStatus shares the CommandExecutionStatus enum shape.\n const failed = item.status === \"failed\" || item.status === \"declined\";\n return {\n kind: \"tool_result\",\n callId: String(item.id ?? \"\"),\n output: { changes: item.changes },\n isError: failed,\n };\n }\n if (item?.type === \"mcpToolCall\") {\n // McpToolCallStatus = \"inProgress\" | \"completed\" | \"failed\"\n const failed = item.status === \"failed\" || item.error != null;\n return {\n kind: \"tool_result\",\n callId: String(item.id ?? \"\"),\n output: failed ? item.error : item.result,\n isError: failed,\n };\n }\n break;\n }\n case \"item/started\": {\n const item = params.item as\n | { type?: string; id?: string; command?: string; name?: string; input?: unknown }\n | undefined;\n if (item?.type === \"commandExecution\") {\n return {\n kind: \"tool_use\",\n callId: String(item.id ?? \"\"),\n toolName: \"shell\",\n input: { command: item.command },\n };\n }\n if (item?.type === \"mcpToolCall\") {\n return {\n kind: \"tool_use\",\n callId: String(item.id ?? \"\"),\n toolName: String(item.name ?? \"mcp\"),\n input: item.input,\n };\n }\n break;\n }\n\n // ── legacy frame names (kept for back-compat with older codex / tests) ──\n case \"thread/message\": {\n const role = params.role as string | undefined;\n const content = params.content as Array<{ type: string; text?: string }> | undefined;\n if (role === \"assistant\" && content) {\n const text = content\n .filter((c) => c.type === \"text\" && typeof c.text === \"string\")\n .map((c) => c.text!)\n .join(\"\");\n return { kind: \"assistant_text\", text };\n }\n break;\n }\n case \"thread/toolUse\":\n return {\n kind: \"tool_use\",\n callId: String(params.callId ?? \"\"),\n toolName: String(params.name ?? \"\"),\n input: params.input,\n };\n case \"thread/toolResult\":\n return {\n kind: \"tool_result\",\n callId: String(params.callId ?? \"\"),\n output: params.output,\n isError: Boolean(params.isError),\n };\n }\n return { kind: \"raw\", backend: \"codex\", payload: frame };\n}\n"],"mappings":"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","names":["join","require","join","process"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|