@leo000001/codex-mcp 2.1.3 → 2.1.5

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/session/manager.ts","../src/app-server/client.ts","../src/app-server/protocol.ts","../src/app-server/lifecycle.ts","../src/app-server/codex-bin.ts","../src/utils/codex-executable.ts","../src/types.ts","../src/utils/cwd.ts","../src/utils/redact.ts","../src/utils/files.ts","../src/utils/config.ts","../src/tools/codex.ts","../src/tools/codex-reply.ts","../src/tools/codex-session.ts","../src/tools/codex-check.ts","../src/resources/register-resources.ts","../src/utils/stdio-guard.ts","../src/app-server/detect.ts","../src/app-server/exec-client.ts"],"sourcesContent":["/**\n * codex-mcp — MCP server entry point\n *\n * Starts the MCP server with stdio transport.\n * Spawns codex app-server child processes for each session,\n * or falls back to codex exec --json when app-server is unavailable.\n */\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\nimport type { ICodexClient } from \"./app-server/client-interface.js\";\nimport { AppServerClient } from \"./app-server/client.js\";\nimport { detectClientMode } from \"./app-server/detect.js\";\nimport { ExecClient } from \"./app-server/exec-client.js\";\nimport { runStdioPreflight } from \"./utils/stdio-guard.js\";\nimport {\n checkDefaultCodexExecutableAvailability,\n getDefaultCodexExecutable,\n} from \"./utils/codex-executable.js\";\n\nasync function main(): Promise<void> {\n const preflight = runStdioPreflight();\n for (const note of preflight.notes) {\n console.error(`[stdio] ${note}`);\n }\n if (preflight.riskLevel === \"elevated\") {\n console.error(`[stdio] Elevated stdout contamination risk detected (mode=${preflight.mode}).`);\n for (const reason of preflight.riskReasons) {\n console.error(`[stdio] Reason: ${reason}`);\n }\n for (const suggestion of preflight.suggestions) {\n console.error(`[stdio] Suggestion: ${suggestion}`);\n }\n }\n if (preflight.shouldBlock) {\n throw new Error(\n \"STDIO preflight failed in strict mode due to blocking stdout contamination risk\"\n );\n }\n\n // Resolve and validate the codex executable before starting the server.\n // Throws immediately if env vars are misconfigured (e.g. both set, or path missing).\n checkDefaultCodexExecutableAvailability();\n const executable = getDefaultCodexExecutable();\n const clientMode = await detectClientMode(executable.command, executable.isPath);\n console.error(`[codex-mcp] client mode: ${clientMode} (binary: ${executable.command})`);\n const createClient = (): ICodexClient =>\n clientMode === \"exec\" ? new ExecClient() : new AppServerClient();\n\n const serverCwd = process.cwd();\n const server = createServer(serverCwd, {\n createClient,\n clientMode,\n });\n const transport = new StdioServerTransport();\n\n let closing = false;\n const shutdown = async () => {\n if (closing) return;\n closing = true;\n try {\n await server.close();\n } catch {\n // Ignore close errors during shutdown\n }\n process.exitCode = 0;\n const exitTimer = setTimeout(() => process.exit(0), 100);\n exitTimer.unref();\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n // Windows commonly emits SIGBREAK (Ctrl+Break / console close scenarios).\n process.on(\"SIGBREAK\", shutdown);\n\n await server.connect(transport);\n console.error(`codex-mcp server started (cwd: ${serverCwd})`);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal error:\", err);\n process.exit(1);\n});\n","/**\n * MCP Server definition — registers tools and handles requests.\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { SessionManager, type SessionManagerOptions } from \"./session/manager.js\";\nimport { executeCodex } from \"./tools/codex.js\";\nimport { executeCodexReply } from \"./tools/codex-reply.js\";\nimport { executeCodexSession } from \"./tools/codex-session.js\";\nimport { executeCodexCheck } from \"./tools/codex-check.js\";\nimport { registerResources } from \"./resources/register-resources.js\";\nimport {\n APPROVAL_POLICIES,\n SANDBOX_MODES,\n PERSONALITIES,\n EFFORT_LEVELS,\n SUMMARY_MODES,\n SESSION_ACTIONS,\n CHECK_ACTIONS,\n RESPONSE_MODES,\n ALL_DECISIONS,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n DEFAULT_EFFORT_LEVEL,\n ErrorCode,\n} from \"./types.js\";\nimport { redactPaths } from \"./utils/redact.js\";\n\ndeclare const __PKG_VERSION__: string;\nconst SERVER_VERSION = typeof __PKG_VERSION__ !== \"undefined\" ? __PKG_VERSION__ : \"0.0.0-dev\";\n\nfunction formatErrorMessage(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n const m = /^Error \\[([A-Z_]+)\\]:\\s*(.*)$/.exec(message);\n if (m) {\n const [, code, rest] = m;\n if (code === ErrorCode.INTERNAL) {\n return `Error [${ErrorCode.INTERNAL}]: ${redactPaths(rest)}`;\n }\n return message;\n }\n return `Error [${ErrorCode.INTERNAL}]: ${redactPaths(message)}`;\n}\n\nfunction toStructuredContent(value: unknown): Record<string, unknown> {\n // MCP structuredContent is object-shaped; wrap non-object payloads for compatibility.\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return { value };\n}\n\nexport function createServer(\n serverCwd: string,\n options?: SessionManagerOptions & { clientMode?: string }\n): McpServer {\n const sessionManager = new SessionManager(options);\n\n const server = new McpServer({\n name: \"codex-mcp\",\n version: SERVER_VERSION,\n });\n\n // Read-only MCP resources (helpful docs / metadata)\n registerResources(server, {\n version: SERVER_VERSION,\n sessionManager,\n clientMode: options?.clientMode,\n });\n\n const publicSessionInfoSchema = z.object({\n sessionId: z.string(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]),\n createdAt: z.string(),\n lastActiveAt: z.string(),\n cancelledAt: z.string().optional(),\n cancelledReason: z.string().optional(),\n model: z.string().optional(),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional(),\n sandbox: z.enum(SANDBOX_MODES).optional(),\n pendingRequestCount: z.number().int(),\n });\n\n const errorOutputShape = {\n error: z.string().optional(),\n isError: z.boolean().optional(),\n };\n\n const sessionStartOutputShape = {\n sessionId: z.string().optional(),\n threadId: z.string().optional(),\n status: z.enum([\"running\", \"idle\"]).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n ...errorOutputShape,\n };\n\n const codexCheckPollOptionsSchema = z\n .object({\n includeEvents: z\n .boolean()\n .optional()\n .describe(\"Default: true. Include events[] in response.\"),\n includeActions: z\n .boolean()\n .optional()\n .describe(\"Default: true. Include actions[] in response.\"),\n includeResult: z.boolean().optional().describe(\"Default: true. Include result in response.\"),\n maxBytes: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Default: unlimited. Best-effort response payload cap in bytes.\"),\n })\n .optional()\n .describe(\"Optional poll shaping controls.\");\n\n const codexCheckInputSchema = z\n .object({\n action: z.enum(CHECK_ACTIONS),\n sessionId: z.string().describe(\"Target session ID\"),\n cursor: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\"Event cursor (default: session last consumed cursor).\"),\n maxEvents: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\n `Max events. Default: poll=${POLL_DEFAULT_MAX_EVENTS} (min ${POLL_MIN_MAX_EVENTS}), respond_*=${RESPOND_DEFAULT_MAX_EVENTS}.`\n ),\n responseMode: z\n .enum(RESPONSE_MODES)\n .optional()\n .describe(\"Response mode. Default: minimal. Options: minimal/delta_compact/full.\"),\n pollOptions: codexCheckPollOptionsSchema,\n // respond_permission\n requestId: z.string().optional().describe(\"Request ID from actions[]\"),\n decision: z\n .enum(ALL_DECISIONS)\n .optional()\n .describe(\n \"Approval decision for respond_permission. acceptWithExecpolicyAmendment requires execpolicy_amendment; applyNetworkPolicyAmendment requires network_policy_amendment.\"\n ),\n execpolicy_amendment: z\n .array(z.string())\n .optional()\n .describe(\"For acceptWithExecpolicyAmendment only\"),\n network_policy_amendment: z\n .object({\n action: z.enum([\"allow\", \"deny\"]),\n host: z.string().min(1),\n })\n .optional()\n .describe(\"For applyNetworkPolicyAmendment only\"),\n denyMessage: z.string().optional().describe(\"Deny reason (not sent to agent)\"),\n // respond_user_input\n answers: z\n .record(\n z.string(),\n z.object({\n answers: z.array(z.string()),\n })\n )\n .optional()\n .describe(\"question-id -> answers map (id from actions[] user_input request).\"),\n })\n .superRefine((value, ctx) => {\n const addIssue = (path: string, message: string) => {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [path],\n message,\n });\n };\n\n switch (value.action) {\n case \"poll\": {\n if (value.maxEvents !== undefined && value.maxEvents < POLL_MIN_MAX_EVENTS) {\n addIssue(\n \"maxEvents\",\n `poll requires maxEvents >= ${POLL_MIN_MAX_EVENTS} to avoid no-op loops.`\n );\n }\n if (value.requestId !== undefined) {\n addIssue(\"requestId\", \"requestId is only allowed for respond_* actions.\");\n }\n if (value.decision !== undefined) {\n addIssue(\"decision\", \"decision is only allowed for action='respond_permission'.\");\n }\n if (value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.denyMessage !== undefined) {\n addIssue(\"denyMessage\", \"denyMessage is only allowed for action='respond_permission'.\");\n }\n if (value.answers !== undefined) {\n addIssue(\"answers\", \"answers is only allowed for action='respond_user_input'.\");\n }\n break;\n }\n case \"respond_permission\": {\n if (!value.requestId) {\n addIssue(\"requestId\", \"requestId is required for action='respond_permission'.\");\n }\n if (!value.decision) {\n addIssue(\"decision\", \"decision is required for action='respond_permission'.\");\n }\n if (value.answers !== undefined) {\n addIssue(\"answers\", \"answers is only allowed for action='respond_user_input'.\");\n }\n const needsExecpolicy = value.decision === \"acceptWithExecpolicyAmendment\";\n const needsNetworkPolicy = value.decision === \"applyNetworkPolicyAmendment\";\n if (\n needsExecpolicy &&\n (!value.execpolicy_amendment || value.execpolicy_amendment.length === 0)\n ) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is required and must be non-empty when decision='acceptWithExecpolicyAmendment'.\"\n );\n }\n if (!needsExecpolicy && value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed when decision='acceptWithExecpolicyAmendment'.\"\n );\n }\n\n if (needsNetworkPolicy && !value.network_policy_amendment) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is required when decision='applyNetworkPolicyAmendment'.\"\n );\n }\n if (!needsNetworkPolicy && value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed when decision='applyNetworkPolicyAmendment'.\"\n );\n }\n break;\n }\n case \"respond_user_input\": {\n if (!value.requestId) {\n addIssue(\"requestId\", \"requestId is required for action='respond_user_input'.\");\n }\n if (!value.answers) {\n addIssue(\"answers\", \"answers is required for action='respond_user_input'.\");\n }\n if (value.decision !== undefined) {\n addIssue(\"decision\", \"decision is only allowed for action='respond_permission'.\");\n }\n if (value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.denyMessage !== undefined) {\n addIssue(\"denyMessage\", \"denyMessage is only allowed for action='respond_permission'.\");\n }\n break;\n }\n }\n });\n\n // ── Tool 1: codex — Start a new Codex agent session ──────────────\n\n server.registerTool(\n \"codex\",\n {\n title: \"Start Codex Session\",\n description:\n \"Start session asynchronously and return `{ sessionId, threadId, status, pollInterval }`. Use `pollInterval` as a minimum hint: `running` >=120000ms (increase for long tasks), `waiting_approval` ~=1000ms.\",\n inputSchema: {\n prompt: z.string().describe(\"Task or question\"),\n approvalPolicy: z\n .enum(APPROVAL_POLICIES)\n .describe(\"Required enum: untrusted/on-failure/on-request/never.\"),\n sandbox: z\n .enum(SANDBOX_MODES)\n .describe(\"Required enum: read-only/workspace-write/danger-full-access.\"),\n effort: z\n .enum(EFFORT_LEVELS)\n .default(DEFAULT_EFFORT_LEVEL)\n .describe(\"Reasoning effort (default: low).\"),\n cwd: z.string().optional().describe(\"Working directory (default: server cwd).\"),\n model: z.string().optional().describe(\"Model override (default: config.toml)\"),\n profile: z.string().optional().describe(\"Profile name (default: CLI default profile).\"),\n advanced: z\n .object({\n baseInstructions: z.string().optional().describe(\"Replace system instructions.\"),\n developerInstructions: z.string().optional().describe(\"Extra developer instructions.\"),\n personality: z\n .enum(PERSONALITIES)\n .optional()\n .describe(\"Personality (default: config.toml).\"),\n summary: z\n .enum(SUMMARY_MODES)\n .optional()\n .describe(\"Summary mode (default: config.toml).\"),\n config: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Override config values.\"),\n ephemeral: z.boolean().optional().describe(\"Do not persist thread (default: false).\"),\n outputSchema: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Structured output schema.\"),\n images: z.array(z.string()).optional().describe(\"Local image paths.\"),\n approvalTimeoutMs: z\n .number()\n .int()\n .positive()\n .default(DEFAULT_APPROVAL_TIMEOUT_MS)\n .optional()\n .describe(`Auto-decline timeout in ms (default: ${DEFAULT_APPROVAL_TIMEOUT_MS})`),\n })\n .optional()\n .describe(\"Advanced settings.\"),\n },\n outputSchema: sessionStartOutputShape,\n annotations: {\n title: \"Start Codex Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async (args) => {\n try {\n const result = await executeCodex(args, sessionManager, serverCwd);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError: false,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // ── Tool 2: codex_reply — Continue an existing session ───────────\n\n server.registerTool(\n \"codex_reply\",\n {\n title: \"Continue Codex Session\",\n description:\n \"Continue existing session. Allowed in `idle`/`error`; otherwise `SESSION_BUSY`. Returns immediately. Use `pollInterval` as a minimum hint: `running` >=120000ms, `waiting_approval` ~=1000ms.\",\n inputSchema: {\n sessionId: z.string().describe(\"Session ID from codex tool\"),\n prompt: z.string().describe(\"Follow-up message\"),\n model: z.string().optional().describe(\"Override model.\"),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional().describe(\"Override approval policy.\"),\n effort: z.enum(EFFORT_LEVELS).optional().describe(\"Override effort.\"),\n summary: z.enum(SUMMARY_MODES).optional().describe(\"Override summary.\"),\n personality: z.enum(PERSONALITIES).optional().describe(\"Override personality.\"),\n sandbox: z.enum(SANDBOX_MODES).optional().describe(\"Override sandbox.\"),\n cwd: z.string().optional().describe(\"Override cwd.\"),\n outputSchema: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Structured output schema override (top-level in codex_reply).\"),\n },\n outputSchema: sessionStartOutputShape,\n annotations: {\n title: \"Continue Codex Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async (args) => {\n try {\n const result = await executeCodexReply(args, sessionManager);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError: false,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // ── Tool 3: codex_session — Manage sessions ──────────────────────\n\n server.registerTool(\n \"codex_session\",\n {\n title: \"Manage Sessions\",\n description: `Session actions: list, get, cancel, interrupt, fork, clean_background_terminals.\n\n- list: sessions in memory.\n- get: details. includeSensitive defaults to false; true adds threadId/cwd/profile/config.\n- cancel: terminal.\n- interrupt: stop current turn.\n- fork: clone current thread into a new session; source remains unchanged.\n- clean_background_terminals: ask app-server to clean stale background terminals for this thread.`,\n inputSchema: {\n action: z.enum(SESSION_ACTIONS),\n sessionId: z\n .string()\n .optional()\n .describe(\"Required for get/cancel/interrupt/fork/clean_background_terminals\"),\n includeSensitive: z\n .boolean()\n .default(false)\n .optional()\n .describe(\"Include cwd/config/threadId/profile in get (default: false)\"),\n },\n outputSchema: {\n sessions: z.array(publicSessionInfoSchema).optional(),\n sessionId: z.string().optional(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]).optional(),\n createdAt: z.string().optional(),\n lastActiveAt: z.string().optional(),\n cancelledAt: z.string().optional(),\n cancelledReason: z.string().optional(),\n model: z.string().optional(),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional(),\n sandbox: z.enum(SANDBOX_MODES).optional(),\n pendingRequestCount: z.number().int().optional(),\n threadId: z.string().optional(),\n cwd: z.string().optional(),\n profile: z.string().optional(),\n config: z.record(z.string(), z.unknown()).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n success: z.boolean().optional(),\n message: z.string().optional(),\n ...errorOutputShape,\n },\n annotations: {\n title: \"Manage Sessions\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async (args) => {\n try {\n const result = await executeCodexSession(args, sessionManager);\n const isError =\n typeof (result as { isError?: boolean }).isError === \"boolean\"\n ? (result as { isError: boolean }).isError\n : false;\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // ── Tool 4: codex_check — Poll events + respond to requests ──────\n\n server.registerTool(\n \"codex_check\",\n {\n title: \"Poll & Respond\",\n description: `Poll session for events or respond to approval/input requests.\n\nPOLLING FREQUENCY: Do NOT poll every turn. Codex tasks take minutes, not seconds.\n- Treat pollInterval as a minimum hint, not a fixed schedule.\n- \"running\": sleep at least 2 minutes between polls; increase for complex tasks. Do NOT high-frequency poll — it wastes tokens and provides no benefit.\n- \"waiting_approval\": poll about every 1000ms and respond quickly to actions[].\n- When status is \"idle\"/\"error\"/\"cancelled\": stop polling, the session is done.\n- Adapt interval based on task complexity and whether the previous poll returned new events.\n\npoll: events since cursor. Default maxEvents=${POLL_DEFAULT_MAX_EVENTS}.\n\nrespond_permission: approval decision. Default maxEvents=${RESPOND_DEFAULT_MAX_EVENTS} (compact ACK).\n\nrespond_user_input: user-input answers. Default maxEvents=${RESPOND_DEFAULT_MAX_EVENTS} (compact ACK).\n\nevents[].type is coarse-grained; details are in events[].data.method.\ncursor omitted => use session last cursor. cursorResetTo => reset and continue.`,\n inputSchema: codexCheckInputSchema,\n outputSchema: {\n sessionId: z.string().optional(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n events: z\n .array(\n z.object({\n id: z.number().int(),\n type: z.enum([\n \"output\",\n \"progress\",\n \"approval_request\",\n \"approval_result\",\n \"result\",\n \"error\",\n ]),\n data: z.unknown(),\n timestamp: z.string(),\n })\n )\n .optional(),\n nextCursor: z.number().int().optional(),\n cursorResetTo: z.number().int().optional(),\n actions: z\n .array(\n z.object({\n type: z.enum([\"approval\", \"user_input\"]),\n requestId: z.string(),\n kind: z.enum([\"command\", \"fileChange\", \"user_input\"]),\n params: z.unknown(),\n itemId: z.string(),\n reason: z.string().optional(),\n approvalId: z.string().optional(),\n commandActions: z.array(z.unknown()).nullable().optional(),\n proposedExecpolicyAmendment: z.array(z.string()).nullable().optional(),\n createdAt: z.string(),\n })\n )\n .optional(),\n result: z\n .object({\n turnId: z.string(),\n output: z.string().optional(),\n structuredOutput: z.unknown().optional(),\n turn: z.unknown().optional(),\n status: z.string().optional(),\n turnError: z.unknown().optional(),\n error: z.string().optional(),\n completedAt: z.string(),\n })\n .optional(),\n compatWarnings: z.array(z.string()).optional(),\n truncated: z.boolean().optional(),\n truncatedFields: z.array(z.string()).optional(),\n ...errorOutputShape,\n },\n annotations: {\n title: \"Poll & Respond\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async (args) => {\n try {\n const result = executeCodexCheck(args, sessionManager);\n const isError =\n typeof (result as { isError?: boolean }).isError === \"boolean\"\n ? (result as { isError: boolean }).isError\n : false;\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // Cleanup on server close\n const originalClose = server.close.bind(server);\n server.close = async () => {\n sessionManager.destroy();\n await originalClose();\n };\n\n return server;\n}\n","/**\n * SessionManager — manages Codex session lifecycle, event buffering, and approval flow.\n */\nimport { randomUUID } from \"crypto\";\nimport { AppServerClient } from \"../app-server/client.js\";\nimport type { ICodexClient } from \"../app-server/client-interface.js\";\nimport type { AppServerSpawnOptions } from \"../app-server/lifecycle.js\";\nimport { resolveAndValidateCwd } from \"../utils/cwd.js\";\nimport { redactPaths } from \"../utils/redact.js\";\nimport { resolveAndValidateFilePath } from \"../utils/files.js\";\nimport {\n type RequestId,\n type CommandApprovalParams,\n type CommandApprovalResponse,\n type FileChangeApprovalResponse,\n type UserInputRequestResponse,\n type DynamicToolCallResponse,\n type LegacyApprovalResponse,\n type TurnStartParams,\n type UserInput,\n Methods,\n toSandboxPolicy,\n} from \"../app-server/protocol.js\";\nimport {\n type ApprovalPolicy,\n type EffortLevel,\n type Personality,\n type SessionInfo,\n type SessionStatus,\n type SandboxMode,\n type SummaryMode,\n type PublicSessionInfo,\n type SensitiveSessionInfo,\n type SessionEventType,\n type EventBuffer,\n type PendingRequest,\n type SessionStartResult,\n type CheckResult,\n type ResponseMode,\n type PollOptions,\n type NetworkPolicyAmendment,\n ErrorCode,\n COMMAND_DECISIONS,\n FILE_CHANGE_DECISIONS,\n DEFAULT_POLL_INTERVAL,\n WAITING_APPROVAL_POLL_INTERVAL,\n DEFAULT_MAX_EVENTS,\n DEFAULT_EVENT_BUFFER_SIZE,\n DEFAULT_EVENT_BUFFER_HARD_SIZE,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n DEFAULT_IDLE_CLEANUP_MS,\n DEFAULT_RUNNING_CLEANUP_MS,\n DEFAULT_TERMINAL_CLEANUP_MS,\n CLEANUP_INTERVAL_MS,\n} from \"../types.js\";\n\nconst COALESCED_PROGRESS_DELTA_METHODS = new Set<string>([\n Methods.COMMAND_OUTPUT_DELTA,\n Methods.FILE_CHANGE_OUTPUT_DELTA,\n Methods.REASONING_TEXT_DELTA,\n Methods.REASONING_SUMMARY_DELTA,\n]);\n// Guard against unbounded in-memory string growth when app-server emits hot delta streams.\nconst MAX_COALESCED_DELTA_CHARS = 16_384;\nconst AUTH_REFRESH_UNSUPPORTED_CODE = -32000;\nconst AUTH_REFRESH_UNSUPPORTED_MESSAGE =\n \"account/chatgptAuthTokens/refresh unsupported: codex-mcp does not manage external ChatGPT auth tokens\";\nconst AUTH_REFRESH_TERMINAL_MESSAGE =\n \"account/chatgptAuthTokens/refresh unsupported: session is terminal\";\n\n// ── Shell noise filtering ────────────────────────────────────────────\n// On Windows, PowerShell profile output (oh-my-posh, PSReadLine, etc.) leaks\n// into every command execution, wasting tokens in MCP client contexts.\n// These patterns are stripped from COMMAND_OUTPUT_DELTA events before they\n// enter the event buffer. Disable with CODEX_MCP_DISABLE_NOISE_FILTER=1.\nconst NOISE_FILTER_ENABLED = process.env.CODEX_MCP_DISABLE_NOISE_FILTER !== \"1\";\nconst WINDOWS_TERMINAL_INTEGRATION_PREFIX = `${String.fromCharCode(0x1b)}]633;`;\n\nconst SHELL_NOISE_LINE_PATTERNS: RegExp[] = [\n // oh-my-posh migration / update prompts\n /oh-my-posh/i,\n // PSReadLine configuration errors\n /PSReadLine/i,\n /Set-PSReadLineOption/i,\n // PowerShell module auto-import warnings\n /^WARNING:\\s/,\n // PowerShell profile loading messages\n /Loading personal and system profiles/i,\n // conda/mamba init noise that leaks through profiles\n /^(\\(base\\)|\\(conda\\))/,\n // Common \"new version available\" nag lines from profile tools\n /A new version of .+ is available/i,\n];\n\n/**\n * Strip known shell profile noise lines from a command output delta.\n * Returns the cleaned string, or empty string if everything was noise.\n */\nfunction stripShellNoise(delta: string): string {\n if (!NOISE_FILTER_ENABLED) return delta;\n const lines = delta.split(\"\\n\");\n const cleaned = lines.filter(\n (line) =>\n !line.includes(WINDOWS_TERMINAL_INTEGRATION_PREFIX) &&\n !SHELL_NOISE_LINE_PATTERNS.some((re) => re.test(line))\n );\n // Preserve original trailing newline structure\n if (cleaned.length === 0) return \"\";\n return cleaned.join(\"\\n\");\n}\n\nexport interface SessionManagerOptions {\n /** Inject client factory (for tests or to select exec mode). */\n createClient?: () => ICodexClient;\n /** Disable background cleanup timer (useful for tests). */\n disableCleanup?: boolean;\n}\n\nexport interface PollQueryOptions {\n responseMode?: ResponseMode;\n pollOptions?: PollOptions;\n}\n\nexport class SessionManager {\n private sessions = new Map<string, SessionInfo>();\n private clients = new Map<string, ICodexClient>();\n private cancellationInFlight = new Map<string, Promise<void>>();\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n private createClient: () => ICodexClient;\n\n constructor(options: SessionManagerOptions = {}) {\n this.createClient = options.createClient ?? (() => new AppServerClient());\n\n if (!options.disableCleanup) {\n this.cleanupTimer = setInterval(() => this.cleanupSessions(), CLEANUP_INTERVAL_MS);\n if (this.cleanupTimer.unref) this.cleanupTimer.unref();\n }\n }\n\n // ── Session Creation ─────────────────────────────────────────────\n\n async createSession(\n prompt: string,\n cwd: string,\n spawnOpts: AppServerSpawnOptions,\n effort: EffortLevel,\n advanced?: {\n baseInstructions?: string;\n developerInstructions?: string;\n personality?: Personality;\n ephemeral?: boolean;\n config?: Record<string, unknown>;\n images?: string[];\n outputSchema?: Record<string, unknown>;\n summary?: SummaryMode;\n approvalTimeoutMs?: number;\n }\n ): Promise<SessionStartResult> {\n const sessionId = `sess_${randomUUID().slice(0, 12)}`;\n const client = this.createClient();\n\n // Create session record\n const now = new Date().toISOString();\n const approvalTimeoutMs = advanced?.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MS;\n\n const resolvedImages = advanced?.images\n ? advanced.images.map((p) => resolveAndValidateFilePath(p, cwd, \"image\"))\n : undefined;\n const session: SessionInfo = {\n sessionId,\n status: \"running\",\n lastEventCursor: 0,\n createdAt: now,\n lastActiveAt: now,\n approvalTimeoutMs,\n cwd,\n model: spawnOpts.model,\n profile: spawnOpts.profile,\n approvalPolicy: spawnOpts.approvalPolicy,\n sandbox: spawnOpts.sandbox,\n config: spawnOpts.config,\n eventBuffer: createEventBuffer(),\n pendingRequests: new Map(),\n };\n\n this.sessions.set(sessionId, session);\n this.clients.set(sessionId, client);\n\n try {\n // Register event handlers before start to prevent unhandled \"error\" events\n this.registerHandlers(sessionId, client, approvalTimeoutMs);\n\n // Start app-server subprocess\n await client.start(spawnOpts);\n\n // Start thread\n const threadStartResult = await client.threadStart({\n cwd,\n model: spawnOpts.model,\n approvalPolicy: spawnOpts.approvalPolicy,\n sandbox: spawnOpts.sandbox,\n personality: advanced?.personality,\n ephemeral: advanced?.ephemeral,\n baseInstructions: advanced?.baseInstructions,\n developerInstructions: advanced?.developerInstructions,\n config: advanced?.config,\n });\n const threadId = extractThreadId(threadStartResult);\n session.threadId = threadId;\n\n // Build input array\n const input: UserInput[] = [{ type: \"text\", text: prompt }];\n if (resolvedImages) {\n for (const imagePath of resolvedImages) {\n input.push({ type: \"localImage\", path: imagePath });\n }\n }\n\n // Start first turn\n const turnStartResult = await client.turnStart({\n threadId,\n input,\n effort,\n summary: advanced?.summary,\n outputSchema: advanced?.outputSchema,\n });\n\n // Best-effort: seed activeTurnId from response if present (notifications are authoritative)\n const startedTurnId = extractTurnId(turnStartResult);\n if (startedTurnId) session.activeTurnId = startedTurnId;\n\n return {\n sessionId,\n threadId,\n status: \"running\",\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n } catch (err) {\n session.status = \"error\";\n pushEvent(session.eventBuffer, \"error\", {\n message: redactPaths(err instanceof Error ? err.message : String(err)),\n });\n await client.destroy();\n this.clients.delete(sessionId);\n this.sessions.delete(sessionId);\n throw err;\n }\n }\n\n // ── Session Reply ────────────────────────────────────────────────\n\n async replyToSession(\n sessionId: string,\n prompt: string,\n overrides?: {\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n effort?: EffortLevel;\n summary?: SummaryMode;\n personality?: Personality;\n sandbox?: SandboxMode;\n cwd?: string;\n outputSchema?: Record<string, unknown>;\n }\n ): Promise<SessionStartResult> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status === \"cancelled\") {\n throw new Error(\n `Error [${ErrorCode.CANCELLED}]: Session '${sessionId}' has been cancelled and cannot be resumed`\n );\n }\n if (session.status !== \"idle\" && session.status !== \"error\") {\n throw new Error(\n `Error [${ErrorCode.SESSION_BUSY}]: Session '${sessionId}' is ${session.status}, expected idle or error`\n );\n }\n if (!session.threadId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Session '${sessionId}' has no threadId, cannot reply`\n );\n }\n\n // Clear stale result/error events so the new turn starts clean\n clearTerminalEvents(session.eventBuffer);\n\n session.status = \"running\";\n session.lastActiveAt = new Date().toISOString();\n\n const input: UserInput[] = [{ type: \"text\", text: prompt }];\n\n const resolvedCwd = overrides?.cwd\n ? resolveAndValidateCwd(overrides.cwd, session.cwd)\n : undefined;\n\n const turnParams: TurnStartParams = {\n threadId: session.threadId,\n input,\n model: overrides?.model,\n approvalPolicy: overrides?.approvalPolicy,\n effort: overrides?.effort,\n summary: overrides?.summary,\n personality: overrides?.personality,\n cwd: resolvedCwd,\n outputSchema: overrides?.outputSchema,\n };\n\n // Map sandbox string to protocol object\n if (overrides?.sandbox) {\n turnParams.sandboxPolicy = toSandboxPolicy(overrides.sandbox);\n }\n\n try {\n const turnStartResult = await client.turnStart(turnParams);\n const startedTurnId = extractTurnId(turnStartResult);\n if (startedTurnId) session.activeTurnId = startedTurnId;\n\n // Only persist cwd/sandbox overrides if the client actually supports them\n // on this turn. ExecClient in resume mode does not support -s/-p/-C, so\n // persisting those values would cause session metadata to drift from reality.\n const canOverride = client.supportsTurnOverrides;\n if (resolvedCwd && canOverride) session.cwd = resolvedCwd;\n if (overrides?.model) session.model = overrides.model;\n if (overrides?.approvalPolicy) {\n session.approvalPolicy = overrides.approvalPolicy as ApprovalPolicy;\n }\n if (overrides?.sandbox && canOverride) {\n session.sandbox = overrides.sandbox as SandboxMode;\n }\n } catch (err) {\n session.status = \"error\";\n pushEvent(session.eventBuffer, \"error\", {\n message: redactPaths(\n `Failed to start turn: ${err instanceof Error ? err.message : String(err)}`\n ),\n });\n throw err;\n }\n\n return {\n sessionId,\n threadId: session.threadId,\n status: \"running\",\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n }\n\n // ── Session Management ───────────────────────────────────────────\n\n listSessions(): PublicSessionInfo[] {\n return Array.from(this.sessions.values()).map(toPublicInfo);\n }\n\n /**\n * Count currently active sessions for lightweight runtime observability.\n * \"Active\" here means the session can still be interacted with.\n */\n getActiveSessionCount(): number {\n let count = 0;\n for (const session of this.sessions.values()) {\n if (\n session.status === \"running\" ||\n session.status === \"waiting_approval\" ||\n session.status === \"idle\"\n ) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Best-effort effective default model observed from recent sessions.\n * Returns null when no model can be inferred from in-memory state.\n */\n getObservedDefaultModel(): string | null {\n let latestModel: string | null = null;\n let latestTs = Number.NEGATIVE_INFINITY;\n\n for (const session of this.sessions.values()) {\n if (session.status === \"cancelled\") continue;\n if (typeof session.model !== \"string\" || session.model.length === 0) continue;\n\n const ts = Date.parse(session.lastActiveAt);\n const comparableTs = Number.isFinite(ts) ? ts : Number.NEGATIVE_INFINITY;\n if (comparableTs >= latestTs) {\n latestTs = comparableTs;\n latestModel = session.model;\n }\n }\n\n return latestModel;\n }\n\n getSession(\n sessionId: string,\n includeSensitive = false\n ): PublicSessionInfo | SensitiveSessionInfo {\n const session = this.getSessionOrThrow(sessionId);\n return includeSensitive ? toSensitiveInfo(session) : toPublicInfo(session);\n }\n\n async cancelSession(sessionId: string, reason?: string): Promise<void> {\n const existing = this.cancellationInFlight.get(sessionId);\n if (existing) {\n await existing;\n return;\n }\n\n const cancellation = this.performCancelSession(sessionId, reason);\n this.cancellationInFlight.set(sessionId, cancellation);\n try {\n await cancellation;\n } finally {\n this.cancellationInFlight.delete(sessionId);\n }\n }\n\n private async performCancelSession(sessionId: string, reason?: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n\n // Idempotent: already cancelled\n if (session.status === \"cancelled\") return;\n\n const client = this.clients.get(sessionId);\n\n session.status = \"cancelled\";\n const now = new Date().toISOString();\n session.cancelledAt = now;\n session.lastActiveAt = now;\n session.cancelledReason = reason ?? \"Cancelled by user\";\n\n // Resolve and clear all pending requests (avoid leaving hanging server-initiated requests)\n for (const [reqId, req] of session.pendingRequests) {\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n if (!req.resolved && req.respond) {\n req.resolved = true;\n try {\n if (req.kind === \"command\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"fileChange\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"user_input\") req.respond({ answers: {} });\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to respond pending request during cancel: session=${sessionId} request=${reqId} kind=${req.kind} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n session.pendingRequests.delete(reqId);\n }\n\n pushEvent(\n session.eventBuffer,\n \"progress\",\n { message: \"Session cancelled\", cancelledReason: session.cancelledReason },\n true\n );\n\n const cancelledTurnId = session.activeTurnId ?? \"\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: cancelledTurnId,\n status: \"cancelled\",\n error: session.cancelledReason,\n completedAt: new Date().toISOString(),\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n { status: \"cancelled\", reason: session.cancelledReason, turnId: cancelledTurnId },\n true\n );\n\n if (client) {\n await client.destroy();\n this.clients.delete(sessionId);\n }\n }\n\n async interruptSession(sessionId: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status !== \"running\" && session.status !== \"waiting_approval\") {\n throw new Error(\n `Error [${ErrorCode.SESSION_NOT_RUNNING}]: Cannot interrupt session in ${session.status} state`\n );\n }\n\n if (!session.threadId || !session.activeTurnId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Missing threadId or activeTurnId for interrupt`\n );\n }\n\n await client.turnInterrupt({\n threadId: session.threadId,\n turnId: session.activeTurnId,\n });\n }\n\n async cleanBackgroundTerminals(sessionId: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status === \"cancelled\") {\n throw new Error(\n `Error [${ErrorCode.CANCELLED}]: Session '${sessionId}' has been cancelled and cannot be cleaned`\n );\n }\n if (!session.threadId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Session '${sessionId}' has no threadId, cannot clean background terminals`\n );\n }\n\n await client.threadBackgroundTerminalsClean({ threadId: session.threadId });\n session.lastActiveAt = new Date().toISOString();\n pushEvent(\n session.eventBuffer,\n \"progress\",\n {\n method: Methods.THREAD_BACKGROUND_TERMINALS_CLEAN,\n threadId: session.threadId,\n status: \"requested\",\n },\n true\n );\n }\n\n async forkSession(sessionId: string): Promise<SessionStartResult> {\n const session = this.getSessionOrThrow(sessionId);\n const originalClient = this.getClientOrThrow(sessionId);\n\n if (!session.threadId) {\n throw new Error(`Error [${ErrorCode.INTERNAL}]: No threadId to fork`);\n }\n\n // Fork the thread on the ORIGINAL client (which holds the thread state)\n const forkResult = await originalClient.threadFork({ threadId: session.threadId });\n const forkedThreadId = extractThreadId(forkResult);\n\n // Create new session with its own app-server process\n const newSessionId = `sess_${randomUUID().slice(0, 12)}`;\n const newClient = this.createClient();\n const now = new Date().toISOString();\n\n const newSession: SessionInfo = {\n sessionId: newSessionId,\n status: \"idle\",\n lastEventCursor: 0,\n createdAt: now,\n lastActiveAt: now,\n approvalTimeoutMs: session.approvalTimeoutMs,\n cwd: session.cwd,\n model: session.model,\n profile: session.profile,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n config: session.config,\n eventBuffer: createEventBuffer(),\n pendingRequests: new Map(),\n };\n\n this.sessions.set(newSessionId, newSession);\n this.clients.set(newSessionId, newClient);\n\n try {\n // Register handlers before start to prevent unhandled \"error\" events\n this.registerHandlers(newSessionId, newClient, newSession.approvalTimeoutMs);\n\n // Start new app-server subprocess\n await newClient.start({\n profile: session.profile,\n model: session.model,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n config: session.config,\n });\n\n // Resume the forked thread on the new process\n await newClient.threadResume({ threadId: forkedThreadId });\n newSession.threadId = forkedThreadId;\n\n return {\n sessionId: newSessionId,\n threadId: forkedThreadId,\n status: \"idle\" as const,\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n } catch (err) {\n const errorMessage = redactPaths(err instanceof Error ? err.message : String(err));\n console.error(\n `[codex-mcp] forkSession failed after thread/fork created thread=${forkedThreadId}. The app-server protocol does not currently expose a guaranteed thread-delete RPC, so manual cleanup may be required.`\n );\n newSession.status = \"error\";\n try {\n await newClient.destroy();\n } catch (destroyErr) {\n console.error(\n `[codex-mcp] Failed to destroy forked app-server client after resume failure: session=${newSessionId} error=${destroyErr instanceof Error ? destroyErr.message : String(destroyErr)}`\n );\n }\n this.clients.delete(newSessionId);\n this.sessions.delete(newSessionId);\n throw new Error(\n `Error [${ErrorCode.THREAD_FORK_RESUME_FAILED}]: Failed to resume forked thread '${forkedThreadId}' in new app-server process: ${errorMessage}`\n );\n }\n }\n\n // ── Event Polling ────────────────────────────────────────────────\n\n pollEvents(\n sessionId: string,\n cursor?: number,\n maxEvents = DEFAULT_MAX_EVENTS,\n options: PollQueryOptions = {}\n ): CheckResult {\n const session = this.getSessionOrThrow(sessionId);\n const buf = session.eventBuffer;\n const responseMode = options.responseMode ?? \"full\";\n const pollOptions = options.pollOptions;\n const includeEvents = pollOptions?.includeEvents ?? true;\n const includeActions = pollOptions?.includeActions ?? true;\n const includeResult = pollOptions?.includeResult ?? true;\n const maxBytes = pollOptions?.maxBytes;\n const effectiveCursor = cursor ?? session.lastEventCursor;\n\n // Find events with id >= cursor\n let events = includeEvents ? buf.events.filter((e) => e.id >= effectiveCursor) : [];\n let cursorResetTo: number | undefined;\n\n // Check if cursor is stale (events were evicted)\n if (includeEvents && buf.events.length > 0) {\n const earliest = buf.events[0].id;\n if (earliest > effectiveCursor) {\n cursorResetTo = earliest;\n events = buf.events;\n }\n }\n const cursorFloor = cursorResetTo ?? effectiveCursor;\n\n // Limit events\n if (events.length > maxEvents) {\n events = events.slice(0, maxEvents);\n }\n\n let nextCursor = clampCursorToLatest(\n events.length > 0 ? events[events.length - 1].id + 1 : cursorFloor,\n buf.nextId\n );\n\n // Collect pending actions\n const actions: CheckResult[\"actions\"] = [];\n if (includeActions) {\n for (const [, req] of session.pendingRequests) {\n if (!req.resolved) {\n actions.push({\n type: req.kind === \"user_input\" ? \"user_input\" : \"approval\",\n requestId: req.requestId,\n kind: req.kind,\n params: req.params,\n itemId: req.itemId,\n reason: req.reason,\n approvalId: req.approvalId,\n commandActions: req.commandActions,\n proposedExecpolicyAmendment: req.proposedExecpolicyAmendment,\n availableDecisions: req.availableDecisions,\n proposedNetworkPolicyAmendments: req.proposedNetworkPolicyAmendments,\n additionalPermissions: req.additionalPermissions,\n networkApprovalContext: req.networkApprovalContext,\n createdAt: req.createdAt,\n });\n }\n }\n }\n\n const result: CheckResult = {\n sessionId,\n status: session.status,\n pollInterval: pollIntervalForStatus(session.status),\n events: events.map((event) => serializeEventForMode(event, responseMode)),\n nextCursor,\n cursorResetTo,\n actions: actions.length > 0 ? actions : undefined,\n result:\n includeResult &&\n (session.status === \"idle\" || session.status === \"error\" || session.status === \"cancelled\")\n ? session.lastResult\n : undefined,\n };\n\n if (typeof maxBytes === \"number\") {\n const normalizedMaxBytes = Math.max(1, Math.floor(maxBytes));\n const hasAnyPayload =\n result.events.length > 0 ||\n typeof result.actions !== \"undefined\" ||\n typeof result.result !== \"undefined\";\n if (hasAnyPayload && payloadByteSize(result) > normalizedMaxBytes) {\n const truncatedFields: string[] = [];\n\n if (result.events.length > 0) {\n while (result.events.length > 0 && payloadByteSize(result) > normalizedMaxBytes) {\n result.events.pop();\n }\n nextCursor = clampCursorToLatest(\n result.events.length > 0\n ? result.events[result.events.length - 1]!.id + 1\n : cursorFloor,\n buf.nextId\n );\n result.nextCursor = nextCursor;\n truncatedFields.push(\"events\");\n }\n\n if (typeof result.result !== \"undefined\" && payloadByteSize(result) > normalizedMaxBytes) {\n result.result = undefined;\n truncatedFields.push(\"result\");\n }\n\n if (typeof result.actions !== \"undefined\" && payloadByteSize(result) > normalizedMaxBytes) {\n if (session.status === \"waiting_approval\") {\n result.actions = compactActionsForBudget(result.actions);\n while (result.actions.length > 1 && payloadByteSize(result) > normalizedMaxBytes) {\n result.actions.pop();\n }\n if (payloadByteSize(result) > normalizedMaxBytes) {\n result.actions = compactActionsToMinimum(result.actions);\n }\n truncatedFields.push(\"actions\");\n }\n\n if (\n typeof result.actions !== \"undefined\" &&\n payloadByteSize(result) > normalizedMaxBytes\n ) {\n result.actions = undefined;\n truncatedFields.push(\"actions\");\n }\n }\n\n if (truncatedFields.length > 0) {\n result.truncated = true;\n result.truncatedFields = Array.from(new Set(truncatedFields));\n addCompatWarningWithinBudget(\n result,\n `Response truncated to respect pollOptions.maxBytes=${normalizedMaxBytes}.`,\n maxBytes\n );\n }\n }\n }\n\n if (includeEvents) {\n session.lastEventCursor = persistMonotonicCursor(\n session.lastEventCursor,\n result.nextCursor,\n buf.nextId\n );\n }\n\n return result;\n }\n\n /**\n * Monotonic polling helper for respond_* flows.\n * Uses max(providedCursor, session.lastEventCursor) to avoid replaying\n * already-consumed history when clients send stale/default cursors.\n */\n pollEventsMonotonic(\n sessionId: string,\n cursor?: number,\n maxEvents = DEFAULT_MAX_EVENTS,\n options: PollQueryOptions = {}\n ): CheckResult {\n const session = this.getSessionOrThrow(sessionId);\n const sessionCursor = session.lastEventCursor;\n const staleCursor = typeof cursor === \"number\" && cursor < sessionCursor;\n const effectiveCursor =\n typeof cursor === \"number\" ? Math.max(cursor, sessionCursor) : undefined;\n const result = this.pollEvents(sessionId, effectiveCursor, maxEvents, options);\n if (staleCursor) {\n addCompatWarningWithinBudget(\n result,\n `Provided cursor ${cursor} is stale; used session cursor ${sessionCursor}.`,\n options.pollOptions?.maxBytes\n );\n }\n return result;\n }\n\n // ── Approval Response ────────────────────────────────────────────\n\n resolveApproval(\n sessionId: string,\n requestId: string,\n decision: string,\n extra?: {\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n denyMessage?: string;\n }\n ): void {\n const session = this.getSessionOrThrow(sessionId);\n const req = session.pendingRequests.get(requestId);\n\n if (!req || req.resolved) {\n throw new Error(\n `Error [${ErrorCode.REQUEST_NOT_FOUND}]: Request '${requestId}' not found or already resolved`\n );\n }\n\n // Validate decision by kind (avoid sending invalid protocol payloads)\n if (req.kind === \"command\") {\n const available = parseAvailableDecisionSet(req.availableDecisions);\n if (available && !available.has(decision)) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Decision '${decision}' is not available for this approval prompt`\n );\n }\n\n // Backward-compat: object-form decisions must be explicitly advertised by newer CLIs.\n if (!available && decision === \"applyNetworkPolicyAmendment\") {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Decision '${decision}' is not supported by this Codex CLI version (missing availableDecisions)`\n );\n }\n if (!COMMAND_DECISIONS.includes(decision as (typeof COMMAND_DECISIONS)[number])) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Invalid command decision '${decision}'`\n );\n }\n if (\n decision === \"acceptWithExecpolicyAmendment\" &&\n (!extra?.execpolicy_amendment || extra.execpolicy_amendment.length === 0)\n ) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`\n );\n }\n\n if (\n decision !== \"acceptWithExecpolicyAmendment\" &&\n extra?.execpolicy_amendment !== undefined\n ) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment is only valid for acceptWithExecpolicyAmendment`\n );\n }\n\n if (decision === \"applyNetworkPolicyAmendment\") {\n const amendment = extra?.network_policy_amendment;\n if (!amendment) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`\n );\n }\n if (amendment.action !== \"allow\" && amendment.action !== \"deny\") {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.action must be 'allow' or 'deny'`\n );\n }\n if (!amendment.host) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.host required for applyNetworkPolicyAmendment`\n );\n }\n } else if (extra?.network_policy_amendment !== undefined) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment is only valid for applyNetworkPolicyAmendment`\n );\n }\n } else if (req.kind === \"fileChange\") {\n if (!FILE_CHANGE_DECISIONS.includes(decision as (typeof FILE_CHANGE_DECISIONS)[number])) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Invalid fileChange decision '${decision}'`\n );\n }\n } else {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Request '${requestId}' is not an approval request`\n );\n }\n\n // Build protocol response\n let response: unknown;\n if (req.kind === \"command\") {\n response = buildCommandApprovalResponse(decision, {\n execpolicy_amendment: extra?.execpolicy_amendment,\n network_policy_amendment: extra?.network_policy_amendment,\n });\n } else if (req.kind === \"fileChange\") {\n response = { decision } as FileChangeApprovalResponse;\n }\n\n if (!response) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Failed to build approval response for request '${requestId}'`\n );\n }\n\n sendPendingRequestResponseOrThrow(req, response, sessionId, requestId);\n\n req.resolved = true;\n req.decision = decision;\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n\n // Push approval_result event\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: req.kind,\n approvalId: req.approvalId,\n decision,\n denyMessage: extra?.denyMessage,\n },\n true\n );\n\n // Remove resolved request to prevent unbounded growth\n session.pendingRequests.delete(requestId);\n\n // Restore status if no more pending requests\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n }\n\n // ── User Input Response ──────────────────────────────────────────\n\n resolveUserInput(\n sessionId: string,\n requestId: string,\n answers: Record<string, { answers: string[] }>\n ): void {\n const session = this.getSessionOrThrow(sessionId);\n const req = session.pendingRequests.get(requestId);\n\n if (!req || req.resolved || req.kind !== \"user_input\") {\n throw new Error(\n `Error [${ErrorCode.REQUEST_NOT_FOUND}]: User input request '${requestId}' not found`\n );\n }\n\n sendPendingRequestResponseOrThrow(\n req,\n { answers } as UserInputRequestResponse,\n sessionId,\n requestId\n );\n\n req.resolved = true;\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"user_input\",\n approvalId: req.approvalId,\n answers,\n },\n true\n );\n\n session.pendingRequests.delete(requestId);\n\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n }\n\n // ── Cleanup ──────────────────────────────────────────────────────\n\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n this.cancellationInFlight.clear();\n\n // Clear all pending request timers\n for (const [, session] of this.sessions) {\n clearSessionPendingRequests(session);\n }\n\n for (const [id, client] of this.clients) {\n client.destroy().catch((err) => {\n console.error(\n `[codex-mcp] Failed to destroy app-server client during manager.destroy(): session=${id} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n this.clients.delete(id);\n }\n this.sessions.clear();\n }\n\n // ── Private ──────────────────────────────────────────────────────\n\n private getSessionOrThrow(sessionId: string): SessionInfo {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Error [${ErrorCode.SESSION_NOT_FOUND}]: Session '${sessionId}' not found`);\n }\n return session;\n }\n\n private getClientOrThrow(sessionId: string): ICodexClient {\n const client = this.clients.get(sessionId);\n if (!client) {\n throw new Error(\n `Error [${ErrorCode.SESSION_NOT_FOUND}]: No client for session '${sessionId}'`\n );\n }\n return client;\n }\n\n private registerHandlers(\n sessionId: string,\n client: ICodexClient,\n approvalTimeoutMs = DEFAULT_APPROVAL_TIMEOUT_MS\n ): void {\n const session = this.sessions.get(sessionId)!;\n\n // Handle notifications\n client.onNotification((method, params) => {\n session.lastActiveAt = new Date().toISOString();\n const p = params as Record<string, unknown>;\n\n switch (method) {\n case Methods.THREAD_STARTED: {\n const thread = isRecord(p.thread) ? p.thread : undefined;\n // Update session.threadId if the notification provides a real thread ID\n // (e.g. ExecClient returns a synthetic ID from threadStart(), then the\n // real ID arrives via the thread.started JSONL event).\n const notifiedThreadId =\n normalizeOptionalString(p.threadId) ?? normalizeOptionalString(thread?.id);\n if (notifiedThreadId && notifiedThreadId !== session.threadId) {\n session.threadId = notifiedThreadId;\n }\n pushEvent(session.eventBuffer, \"progress\", {\n method,\n ...p,\n threadId: notifiedThreadId,\n status: normalizeOptionalString(thread?.status),\n });\n break;\n }\n\n case Methods.THREAD_ARCHIVED:\n case Methods.THREAD_UNARCHIVED:\n case Methods.THREAD_NAME_UPDATED:\n case Methods.THREAD_TOKEN_USAGE_UPDATED:\n case Methods.FUZZY_FILE_SEARCH_SESSION_UPDATED:\n case Methods.FUZZY_FILE_SEARCH_SESSION_COMPLETED:\n case Methods.WINDOWS_WORLD_WRITABLE_WARNING:\n case Methods.ACCOUNT_LOGIN_COMPLETED:\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n break;\n\n case Methods.TURN_STARTED:\n if (session.status === \"cancelled\") break;\n {\n const turnObj = p.turn as Record<string, unknown> | undefined;\n const status = normalizeOptionalString(turnObj?.status);\n session.activeTurnId = normalizeOptionalString(turnObj?.id);\n pushEvent(session.eventBuffer, \"progress\", {\n method,\n ...p,\n turnId: session.activeTurnId,\n status,\n });\n }\n break;\n\n case Methods.TURN_COMPLETED: {\n if (session.status === \"cancelled\") break;\n const turnObj = p.turn as Record<string, unknown> | undefined;\n const completedTurnId = (turnObj?.id as string | undefined) ?? session.activeTurnId ?? \"\";\n session.status = \"idle\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: completedTurnId,\n output: turnObj?.output as string | undefined,\n structuredOutput: turnObj?.structuredOutput,\n turn: p.turn,\n status: turnObj?.status as string | undefined,\n turnError: turnObj?.error,\n completedAt: new Date().toISOString(),\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n {\n method,\n ...p,\n turnId: completedTurnId,\n status: normalizeOptionalString(turnObj?.status),\n },\n true\n );\n break;\n }\n\n case Methods.ERROR: {\n if (session.status === \"cancelled\") break;\n const willRetry = p.willRetry as boolean;\n if (!willRetry) {\n session.status = \"error\";\n }\n {\n const data: Record<string, unknown> = { method, ...p };\n if (typeof data.message === \"string\") data.message = redactPaths(data.message);\n if (typeof data.error === \"string\") data.error = redactPaths(data.error);\n if (willRetry) {\n pushEvent(\n session.eventBuffer,\n \"progress\",\n {\n ...data,\n method: \"codex-mcp/reconnect\",\n sourceMethod: method,\n phase: \"retrying\",\n },\n true\n );\n } else {\n pushEvent(session.eventBuffer, \"error\", data, true);\n }\n }\n break;\n }\n\n case Methods.AGENT_MESSAGE_DELTA:\n pushEvent(session.eventBuffer, \"output\", { method, delta: p.delta, itemId: p.itemId });\n break;\n\n case Methods.ITEM_STARTED:\n case Methods.ITEM_COMPLETED:\n case Methods.RAW_RESPONSE_ITEM_COMPLETED:\n {\n const item = p.item as Record<string, unknown> | undefined;\n const itemType = item && typeof item.type === \"string\" ? item.type : undefined;\n const status = normalizeOptionalString(item?.status);\n // Keep user/agent message-like items as output; everything else is progress.\n const eventType: SessionEventType =\n itemType === \"agentMessage\" || itemType === \"userMessage\" ? \"output\" : \"progress\";\n pushEvent(session.eventBuffer, eventType, {\n method,\n ...p,\n item: p.item,\n status,\n });\n }\n break;\n\n case Methods.COMMAND_OUTPUT_DELTA: {\n // Filter known shell profile noise (PowerShell oh-my-posh, PSReadLine, etc.)\n if (typeof p.delta === \"string\") {\n const cleaned = stripShellNoise(p.delta);\n if (cleaned.length === 0) break; // entire delta was noise, skip event\n pushEvent(session.eventBuffer, \"progress\", { method, ...p, delta: cleaned });\n } else {\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n }\n break;\n }\n case Methods.COMMAND_TERMINAL_INTERACTION:\n case Methods.FILE_CHANGE_OUTPUT_DELTA:\n case Methods.REASONING_TEXT_DELTA:\n case Methods.REASONING_SUMMARY_DELTA:\n case Methods.REASONING_SUMMARY_PART_ADDED:\n case Methods.PLAN_DELTA:\n case Methods.MCP_TOOL_PROGRESS:\n case Methods.TURN_DIFF_UPDATED:\n case Methods.TURN_PLAN_UPDATED:\n case Methods.MODEL_REROUTED:\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n break;\n\n default:\n // Ignore other notifications (account, config, etc.)\n break;\n }\n });\n\n // Handle server-initiated requests\n client.onServerRequest((id: RequestId, method: string, params: unknown) => {\n // Do not transition terminal sessions back to waiting_approval.\n if (session.status === \"cancelled\" || session.status === \"error\") {\n respondToTerminalSessionRequest(client, id, method);\n return;\n }\n\n session.lastActiveAt = new Date().toISOString();\n const p = params as Record<string, unknown>;\n\n switch (method) {\n case Methods.COMMAND_APPROVAL: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const approvalParams = params as CommandApprovalParams & Record<string, unknown>;\n const reason = normalizeOptionalString(approvalParams.reason);\n const approvalId = normalizeOptionalString(approvalParams.approvalId);\n const commandActions = Array.isArray(approvalParams.commandActions)\n ? approvalParams.commandActions\n : null;\n const proposedExecpolicyAmendment = normalizeStringArrayOrNull(\n approvalParams.proposedExecpolicyAmendment\n );\n const availableDecisions = Array.isArray(approvalParams.availableDecisions)\n ? (approvalParams.availableDecisions as unknown[])\n : null;\n const proposedNetworkPolicyAmendments = Array.isArray(\n approvalParams.proposedNetworkPolicyAmendments\n )\n ? (approvalParams.proposedNetworkPolicyAmendments as unknown[])\n : null;\n const additionalPermissions =\n \"additionalPermissions\" in approvalParams\n ? (approvalParams.additionalPermissions as unknown)\n : undefined;\n const networkApprovalContext =\n \"networkApprovalContext\" in approvalParams\n ? (approvalParams.networkApprovalContext as unknown)\n : undefined;\n const pending: PendingRequest = {\n requestId,\n kind: \"command\",\n params,\n itemId: normalizeOptionalString(approvalParams.itemId) ?? \"\",\n threadId: normalizeOptionalString(approvalParams.threadId) ?? \"\",\n turnId: normalizeOptionalString(approvalParams.turnId) ?? \"\",\n reason,\n approvalId,\n commandActions,\n proposedExecpolicyAmendment,\n availableDecisions,\n proposedNetworkPolicyAmendments,\n additionalPermissions,\n networkApprovalContext,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n // Timeout\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n pending.decision = \"decline\";\n try {\n client.respondToServer(id, { decision: \"decline\" } as CommandApprovalResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-decline command approval timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"command\",\n approvalId,\n decision: \"decline\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"command\",\n itemId: approvalParams.itemId,\n approvalId,\n command: approvalParams.command,\n cwd: approvalParams.cwd,\n reason,\n commandActions,\n proposedExecpolicyAmendment,\n availableDecisions,\n proposedNetworkPolicyAmendments,\n additionalPermissions,\n networkApprovalContext,\n },\n true\n );\n break;\n }\n\n case Methods.FILE_CHANGE_APPROVAL: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const reason = normalizeOptionalString(p.reason);\n const pending: PendingRequest = {\n requestId,\n kind: \"fileChange\",\n params,\n itemId: p.itemId as string,\n threadId: p.threadId as string,\n turnId: p.turnId as string,\n reason,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n pending.decision = \"decline\";\n try {\n client.respondToServer(id, { decision: \"decline\" } as FileChangeApprovalResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-decline file-change approval timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"fileChange\",\n decision: \"decline\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"fileChange\",\n itemId: p.itemId,\n reason,\n },\n true\n );\n break;\n }\n\n case Methods.USER_INPUT_REQUEST: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const pending: PendingRequest = {\n requestId,\n kind: \"user_input\",\n params,\n itemId: p.itemId as string,\n threadId: p.threadId as string,\n turnId: p.turnId as string,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n try {\n client.respondToServer(id, { answers: {} } as UserInputRequestResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-answer user-input timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"user_input\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"user_input\",\n questions: p.questions,\n },\n true\n );\n break;\n }\n\n case Methods.DYNAMIC_TOOL_CALL:\n // Auto-reject: codex-mcp doesn't support dynamic tool calls\n client.respondToServer(id, {\n success: false,\n contentItems: [{ type: \"inputText\", text: \"Not supported by codex-mcp\" }],\n } as DynamicToolCallResponse);\n break;\n\n case Methods.AUTH_TOKEN_REFRESH:\n client.respondErrorToServer(\n id,\n AUTH_REFRESH_UNSUPPORTED_CODE,\n AUTH_REFRESH_UNSUPPORTED_MESSAGE\n );\n break;\n\n case Methods.LEGACY_PATCH_APPROVAL:\n case Methods.LEGACY_EXEC_APPROVAL:\n client.respondToServer(id, { decision: \"denied\" } as LegacyApprovalResponse);\n console.error(`[codex-mcp] Legacy approval request received: ${method}`);\n break;\n\n default:\n client.respondErrorToServer(id, -32601, `Unhandled server request: ${method}`);\n break;\n }\n });\n\n // Handle subprocess exit\n client.on(\"exit\", (code: number | null) => {\n clearSessionPendingRequests(session);\n if (session.status === \"running\" || session.status === \"waiting_approval\") {\n session.status = \"error\";\n const message = `app-server exited unexpectedly (code: ${code})`;\n setTerminalErrorResult(session, message);\n pushEvent(\n session.eventBuffer,\n \"error\",\n {\n message,\n },\n true\n );\n }\n });\n\n // Handle subprocess spawn errors (must listen to prevent uncaught exception)\n client.on(\"error\", (err: Error) => {\n clearSessionPendingRequests(session);\n if (session.status === \"running\" || session.status === \"waiting_approval\") {\n session.status = \"error\";\n const message = redactPaths(`app-server error: ${err.message}`);\n setTerminalErrorResult(session, message);\n pushEvent(\n session.eventBuffer,\n \"error\",\n {\n message,\n },\n true\n );\n }\n });\n }\n\n private cleanupSessions(): void {\n const now = Date.now();\n for (const [id, session] of this.sessions) {\n const lastActive = new Date(session.lastActiveAt).getTime();\n if (Number.isNaN(lastActive)) {\n // Invalid timestamp — clean up immediately\n this.requestCancellation(id, \"Invalid timestamp\");\n continue;\n }\n const age = now - lastActive;\n\n if (session.status === \"idle\" && age > DEFAULT_IDLE_CLEANUP_MS) {\n this.requestCancellation(id, \"Idle timeout\");\n } else if (session.status === \"waiting_approval\" && age > DEFAULT_RUNNING_CLEANUP_MS) {\n this.requestCancellation(id, \"Approval timeout\");\n } else if (session.status === \"running\" && age > DEFAULT_RUNNING_CLEANUP_MS) {\n this.requestCancellation(id, \"Running timeout\");\n } else if (\n (session.status === \"cancelled\" || session.status === \"error\") &&\n age > DEFAULT_TERMINAL_CLEANUP_MS\n ) {\n this.clients\n .get(id)\n ?.destroy()\n .catch((err) => {\n console.error(\n `[codex-mcp] Failed to destroy app-server client during cleanup: session=${id} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n this.clients.delete(id);\n this.sessions.delete(id);\n }\n }\n }\n\n private requestCancellation(sessionId: string, reason: string): void {\n if (this.cancellationInFlight.has(sessionId)) return;\n this.cancelSession(sessionId, reason).catch((err) => {\n console.error(\n `[codex-mcp] Failed to cancel session during cleanup: session=${sessionId} reason=${reason} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction pollIntervalForStatus(status: SessionStatus): number | undefined {\n if (status === \"waiting_approval\") return WAITING_APPROVAL_POLL_INTERVAL;\n if (status === \"running\") return DEFAULT_POLL_INTERVAL;\n return undefined; // terminal states don't need polling\n}\n\nfunction createEventBuffer(): EventBuffer {\n return {\n events: [],\n maxSize: DEFAULT_EVENT_BUFFER_SIZE,\n hardMaxSize: DEFAULT_EVENT_BUFFER_HARD_SIZE,\n nextId: 0,\n };\n}\n\n/** Clear stale result/error events when transitioning idle/error → running */\nfunction clearTerminalEvents(buf: EventBuffer): void {\n buf.events = buf.events.filter((e) => e.type !== \"result\" && e.type !== \"error\");\n}\n\nfunction clearSessionPendingRequests(session: SessionInfo): void {\n const entries = Array.from(session.pendingRequests.entries());\n session.pendingRequests.clear();\n for (const [, req] of entries) {\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n req.resolved = true;\n }\n}\n\nfunction setTerminalErrorResult(session: SessionInfo, message: string): void {\n const completedAt = new Date().toISOString();\n const failedTurnId = session.activeTurnId ?? \"\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: failedTurnId,\n status: \"error\",\n error: message,\n completedAt,\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n {\n status: \"error\",\n turnId: failedTurnId,\n error: message,\n completedAt,\n },\n true\n );\n}\n\nfunction createUnrefTimeout(handler: () => void, timeoutMs: number): ReturnType<typeof setTimeout> {\n const timer = setTimeout(handler, timeoutMs);\n if (typeof (timer as { unref?: () => void }).unref === \"function\") {\n (timer as { unref: () => void }).unref();\n }\n return timer;\n}\n\nfunction respondToTerminalSessionRequest(\n client: ICodexClient,\n id: RequestId,\n method: string\n): void {\n switch (method) {\n case Methods.COMMAND_APPROVAL:\n case Methods.FILE_CHANGE_APPROVAL:\n client.respondToServer(id, { decision: \"cancel\" });\n break;\n case Methods.USER_INPUT_REQUEST:\n client.respondToServer(id, { answers: {} } as UserInputRequestResponse);\n break;\n case Methods.DYNAMIC_TOOL_CALL:\n client.respondToServer(id, {\n success: false,\n contentItems: [{ type: \"inputText\", text: \"Session is terminal\" }],\n } as DynamicToolCallResponse);\n break;\n case Methods.AUTH_TOKEN_REFRESH:\n client.respondErrorToServer(id, AUTH_REFRESH_UNSUPPORTED_CODE, AUTH_REFRESH_TERMINAL_MESSAGE);\n break;\n case Methods.LEGACY_PATCH_APPROVAL:\n case Methods.LEGACY_EXEC_APPROVAL:\n client.respondToServer(id, { decision: \"denied\" } as LegacyApprovalResponse);\n break;\n default:\n client.respondErrorToServer(id, -32601, `Unhandled server request: ${method}`);\n break;\n }\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction normalizeStringArrayOrNull(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null;\n const normalized = value.filter((entry): entry is string => typeof entry === \"string\");\n return normalized;\n}\n\nfunction sendPendingRequestResponseOrThrow(\n req: PendingRequest,\n response: unknown,\n sessionId: string,\n requestId: string\n): void {\n if (!req.respond) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Missing response handler for request '${requestId}'`\n );\n }\n try {\n req.respond(response);\n } catch (err) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Failed to send response: session=${sessionId} request=${requestId} kind=${req.kind} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\nfunction compactActionsForBudget(\n actions: NonNullable<CheckResult[\"actions\"]>\n): NonNullable<CheckResult[\"actions\"]> {\n return actions.map((action) => ({\n type: action.type,\n requestId: action.requestId,\n kind: action.kind,\n params: compactActionParamsForBudget(action),\n itemId: action.itemId,\n createdAt: action.createdAt,\n commandActions: action.commandActions,\n proposedExecpolicyAmendment: action.proposedExecpolicyAmendment,\n availableDecisions: action.availableDecisions,\n additionalPermissions: action.additionalPermissions,\n networkApprovalContext: action.networkApprovalContext,\n proposedNetworkPolicyAmendments: action.proposedNetworkPolicyAmendments,\n }));\n}\n\nfunction compactActionParamsForBudget(\n action: NonNullable<CheckResult[\"actions\"]>[number]\n): unknown {\n if (action.kind !== \"user_input\" || !isRecord(action.params)) {\n return undefined;\n }\n\n const rawQuestions = action.params.questions;\n if (!Array.isArray(rawQuestions)) {\n return undefined;\n }\n\n const compactQuestions: Array<{ id: string }> = [];\n for (const entry of rawQuestions) {\n if (!isRecord(entry)) continue;\n const id = typeof entry.id === \"string\" ? entry.id : undefined;\n if (id) {\n compactQuestions.push({ id });\n }\n }\n\n return compactQuestions.length > 0 ? { questions: compactQuestions } : undefined;\n}\n\nfunction compactActionsToMinimum(\n actions: NonNullable<CheckResult[\"actions\"]>\n): NonNullable<CheckResult[\"actions\"]> {\n if (actions.length === 0) return actions;\n const first = actions[0]!;\n return [\n {\n type: first.type,\n requestId: first.requestId,\n kind: first.kind,\n params: undefined,\n itemId: first.itemId,\n createdAt: first.createdAt,\n commandActions: first.commandActions,\n proposedExecpolicyAmendment: first.proposedExecpolicyAmendment,\n availableDecisions: first.availableDecisions,\n additionalPermissions: first.additionalPermissions,\n networkApprovalContext: first.networkApprovalContext,\n proposedNetworkPolicyAmendments: first.proposedNetworkPolicyAmendments,\n },\n ];\n}\n\nfunction clampCursorToLatest(cursor: number, latestCursor: number): number {\n return Math.max(0, Math.min(cursor, latestCursor));\n}\n\nfunction persistMonotonicCursor(\n previousCursor: number,\n nextCursor: number,\n latestCursor: number\n): number {\n const boundedCursor = clampCursorToLatest(nextCursor, latestCursor);\n return Math.max(previousCursor, boundedCursor);\n}\n\nfunction pushEvent(buf: EventBuffer, type: SessionEventType, data: unknown, pinned = false): void {\n if (tryCoalesceProgressDelta(buf, type, data, pinned)) return;\n\n buf.events.push({\n id: buf.nextId++,\n type,\n data,\n timestamp: new Date().toISOString(),\n pinned,\n });\n evictEvents(buf);\n}\n\nfunction serializeEventForMode(\n event: { id: number; type: SessionEventType; data: unknown; timestamp: string },\n mode: ResponseMode\n): { id: number; type: SessionEventType; data: unknown; timestamp: string } {\n if (mode === \"full\") {\n return { id: event.id, type: event.type, data: event.data, timestamp: event.timestamp };\n }\n const minimal = mode === \"minimal\";\n return {\n id: event.id,\n type: event.type,\n data: compactEventData(event.data, minimal),\n timestamp: event.timestamp,\n };\n}\n\nfunction compactEventData(data: unknown, minimal: boolean): unknown {\n if (!isRecord(data)) return data;\n\n const compact: Record<string, unknown> = {};\n if (typeof data.method === \"string\") {\n compact.method = data.method;\n }\n\n const preferredKeys = minimal\n ? [\n \"delta\",\n \"message\",\n \"error\",\n \"status\",\n \"phase\",\n \"itemId\",\n \"turnId\",\n \"requestId\",\n \"kind\",\n \"decision\",\n \"timeout\",\n \"willRetry\",\n \"retryCount\",\n \"maxRetries\",\n ]\n : [\n \"delta\",\n \"message\",\n \"error\",\n \"status\",\n \"phase\",\n \"itemId\",\n \"turnId\",\n \"requestId\",\n \"kind\",\n \"decision\",\n \"timeout\",\n \"willRetry\",\n \"retryCount\",\n \"maxRetries\",\n \"reason\",\n \"command\",\n \"cwd\",\n \"sourceMethod\",\n ];\n\n for (const key of preferredKeys) {\n if (key in data) {\n compact[key] = data[key];\n }\n }\n\n if (typeof compact.delta === \"string\") {\n const limit = minimal ? 256 : 2048;\n if (compact.delta.length > limit) {\n compact.delta = compact.delta.slice(0, limit);\n compact.deltaTruncated = true;\n }\n }\n\n if (Object.keys(compact).length === 0) {\n return minimal ? { summary: \"omitted for minimal response mode\" } : { ...data };\n }\n\n return compact;\n}\n\nfunction payloadByteSize(value: unknown): number {\n return Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nfunction addCompatWarning(result: CheckResult, warning: string): void {\n if (!result.compatWarnings) {\n result.compatWarnings = [];\n }\n result.compatWarnings.push(warning);\n}\n\nfunction addCompatWarningWithinBudget(\n result: CheckResult,\n warning: string,\n maxBytes?: number\n): void {\n const previousWarnings = result.compatWarnings ? [...result.compatWarnings] : undefined;\n addCompatWarning(result, warning);\n\n if (typeof maxBytes !== \"number\") {\n return;\n }\n\n const normalizedMaxBytes = Math.max(1, Math.floor(maxBytes));\n if (payloadByteSize(result) <= normalizedMaxBytes) {\n return;\n }\n\n if (!previousWarnings || previousWarnings.length === 0) {\n result.compatWarnings = undefined;\n return;\n }\n result.compatWarnings = previousWarnings;\n}\n\nfunction tryCoalesceProgressDelta(\n buf: EventBuffer,\n type: SessionEventType,\n data: unknown,\n pinned: boolean\n): boolean {\n if (type !== \"progress\" || pinned || buf.events.length === 0) return false;\n if (!isRecord(data)) return false;\n\n const method = data.method;\n const delta = data.delta;\n const itemId = data.itemId;\n const turnId = data.turnId;\n const itemKey = typeof itemId === \"string\" ? itemId : \"\";\n const turnKey = typeof turnId === \"string\" ? turnId : \"\";\n if (\n typeof method !== \"string\" ||\n !COALESCED_PROGRESS_DELTA_METHODS.has(method) ||\n typeof delta !== \"string\"\n ) {\n return false;\n }\n // Keep coalescing scoped to a stable stream key (itemId or turnId).\n if (itemKey.length === 0 && turnKey.length === 0) return false;\n\n const last = buf.events[buf.events.length - 1];\n if (last.type !== \"progress\" || last.pinned || !isRecord(last.data)) return false;\n\n const lastMethod = last.data.method;\n const lastItemId = last.data.itemId;\n const lastTurnId = last.data.turnId;\n const lastDelta = last.data.delta;\n const lastItemKey = typeof lastItemId === \"string\" ? lastItemId : \"\";\n const lastTurnKey = typeof lastTurnId === \"string\" ? lastTurnId : \"\";\n if (\n lastMethod !== method ||\n lastItemKey !== itemKey ||\n lastTurnKey !== turnKey ||\n typeof lastDelta !== \"string\"\n ) {\n return false;\n }\n\n if (lastDelta.length + delta.length > MAX_COALESCED_DELTA_CHARS) return false;\n\n last.data = {\n ...last.data,\n delta: `${lastDelta}${delta}`,\n };\n last.timestamp = new Date().toISOString();\n return true;\n}\n\nfunction evictEvents(buf: EventBuffer): void {\n // Soft limit: evict oldest unpinned\n while (buf.events.length > buf.maxSize) {\n const idx = buf.events.findIndex((e) => !e.pinned);\n if (idx === -1) break;\n buf.events.splice(idx, 1);\n }\n\n // If still over soft limit (all pinned): evict old approval_result events first.\n while (buf.events.length > buf.maxSize) {\n const idx = buf.events.findIndex((e) => e.type === \"approval_result\");\n if (idx === -1) break;\n buf.events.splice(idx, 1);\n }\n\n if (buf.events.length <= buf.hardMaxSize) return;\n\n // Hard limit: select evictions in one pass to avoid O(n^2) repeated scans.\n const overflow = buf.events.length - buf.hardMaxSize;\n const approvalResultIdx: number[] = [];\n const nonPinnedIdx: number[] = [];\n const pinnedNonCriticalIdx: number[] = [];\n const criticalPinnedIdx: number[] = [];\n\n for (let i = 0; i < buf.events.length; i++) {\n const event = buf.events[i];\n if (event.type === \"approval_result\") {\n approvalResultIdx.push(i);\n } else if (!event.pinned) {\n nonPinnedIdx.push(i);\n } else if (!isHardPinnedCriticalType(event.type)) {\n pinnedNonCriticalIdx.push(i);\n } else {\n criticalPinnedIdx.push(i);\n }\n }\n\n const drop = new Set<number>();\n const take = (indices: number[]) => {\n for (const idx of indices) {\n if (drop.size >= overflow) break;\n drop.add(idx);\n }\n };\n\n take(approvalResultIdx);\n take(nonPinnedIdx);\n take(pinnedNonCriticalIdx);\n const beforeCritical = drop.size;\n take(criticalPinnedIdx);\n\n if (drop.size > beforeCritical) {\n console.error(\n \"[codex-mcp] Event buffer hard limit exceeded with only critical pinned events; evicting oldest event.\"\n );\n }\n\n if (drop.size === 0) return;\n buf.events = buf.events.filter((_, idx) => !drop.has(idx));\n}\n\nfunction isHardPinnedCriticalType(type: SessionEventType): boolean {\n return type === \"approval_request\" || type === \"result\" || type === \"error\";\n}\n\nfunction toPublicInfo(session: SessionInfo): PublicSessionInfo {\n return {\n sessionId: session.sessionId,\n status: session.status,\n createdAt: session.createdAt,\n lastActiveAt: session.lastActiveAt,\n cancelledAt: session.cancelledAt,\n cancelledReason: session.cancelledReason,\n model: session.model,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n pendingRequestCount: Array.from(session.pendingRequests.values()).filter((r) => !r.resolved)\n .length,\n };\n}\n\nfunction toSensitiveInfo(session: SessionInfo): SensitiveSessionInfo {\n return {\n ...toPublicInfo(session),\n threadId: session.threadId,\n cwd: session.cwd,\n profile: session.profile,\n config: session.config,\n };\n}\n\nfunction buildCommandApprovalResponse(\n decision: string,\n extra?: {\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n }\n): CommandApprovalResponse {\n if (decision === \"acceptWithExecpolicyAmendment\") {\n const execpolicy_amendment = extra?.execpolicy_amendment;\n if (!execpolicy_amendment || execpolicy_amendment.length === 0) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`\n );\n }\n return {\n decision: {\n acceptWithExecpolicyAmendment: {\n execpolicy_amendment,\n },\n },\n };\n }\n\n if (decision === \"applyNetworkPolicyAmendment\") {\n const amendment = extra?.network_policy_amendment;\n if (!amendment) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`\n );\n }\n return {\n decision: {\n applyNetworkPolicyAmendment: {\n network_policy_amendment: amendment,\n },\n },\n };\n }\n return { decision: decision as \"accept\" | \"acceptForSession\" | \"decline\" | \"cancel\" };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction parseAvailableDecisionSet(available: unknown[] | null | undefined): Set<string> | null {\n if (!Array.isArray(available) || available.length === 0) return null;\n const set = new Set<string>();\n for (const entry of available) {\n if (typeof entry === \"string\") {\n set.add(entry);\n continue;\n }\n if (isRecord(entry)) {\n if (\"acceptWithExecpolicyAmendment\" in entry) set.add(\"acceptWithExecpolicyAmendment\");\n if (\"applyNetworkPolicyAmendment\" in entry) set.add(\"applyNetworkPolicyAmendment\");\n }\n }\n return set.size > 0 ? set : null;\n}\n\n/**\n * Extract thread id from either v1 ({threadId}) or v2 ({thread:{id}}) responses.\n * threadId is mandatory for session correctness, so invalid shape throws.\n */\nfunction extractThreadId(result: unknown): string {\n if (!isRecord(result)) {\n throw new Error(`Error [${ErrorCode.INTERNAL}]: Invalid thread response: expected object`);\n }\n\n const direct = result.threadId;\n if (typeof direct === \"string\" && direct.length > 0) return direct;\n\n const thread = result.thread;\n if (isRecord(thread) && typeof thread.id === \"string\" && thread.id.length > 0) return thread.id;\n\n throw new Error(`Error [${ErrorCode.INTERNAL}]: Invalid thread response: missing thread id`);\n}\n\n/**\n * Extract turn id from either v1 ({turnId}) or v2 ({turn:{id}}) responses.\n * turnId is optional because turn/started notifications are authoritative.\n */\nfunction extractTurnId(result: unknown): string | undefined {\n if (!isRecord(result)) return undefined;\n\n const direct = result.turnId;\n if (typeof direct === \"string\" && direct.length > 0) return direct;\n\n const turn = result.turn;\n if (isRecord(turn) && typeof turn.id === \"string\" && turn.id.length > 0) return turn.id;\n\n return undefined;\n}\n","/**\n * AppServerClient — JSON-RPC client for codex app-server subprocess.\n *\n * Manages a single codex app-server child process via stdio.\n * Handles request/response correlation, notifications, and server-initiated requests.\n */\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { EventEmitter } from \"events\";\nimport { StringDecoder } from \"string_decoder\";\nimport {\n type RequestId,\n type JsonRpcRequest,\n type JsonRpcResponse,\n type JsonRpcNotification,\n type JsonRpcMessage,\n type InitializeParams,\n type InitializeResult,\n type ThreadStartParams,\n type ThreadStartResult,\n type ThreadForkParams,\n type ThreadForkResult,\n type ThreadResumeParams,\n type ThreadResumeResult,\n type ThreadBackgroundTerminalsCleanParams,\n type TurnStartParams,\n type TurnStartResult,\n type TurnInterruptParams,\n Methods,\n} from \"./protocol.js\";\nimport { buildAppServerArgs, type AppServerSpawnOptions } from \"./lifecycle.js\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\nimport { getDefaultCodexExecutable } from \"../utils/codex-executable.js\";\nimport { ErrorCode } from \"../types.js\";\nimport type { ICodexClient } from \"./client-interface.js\";\n\ndeclare const __PKG_VERSION__: string;\nconst CLIENT_VERSION = typeof __PKG_VERSION__ !== \"undefined\" ? __PKG_VERSION__ : \"0.0.0-dev\";\n\nconst DEFAULT_REQUEST_TIMEOUT = 30_000;\nconst STARTUP_REQUEST_TIMEOUT = 90_000;\nconst MAX_WRITE_QUEUE_BYTES = 5 * 1024 * 1024; // 5MB\n\ninterface PendingRpcRequest {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\ntype NotificationHandler = (method: string, params: unknown) => void;\ntype ServerRequestHandler = (id: RequestId, method: string, params: unknown) => void;\n\nexport class AppServerClient extends EventEmitter implements ICodexClient {\n private process: ChildProcess | null = null;\n private nextId = 1;\n private pending = new Map<RequestId, PendingRpcRequest>();\n private buffer = \"\";\n private decoder = new StringDecoder(\"utf8\");\n private _destroyed = false;\n private lastFailure: Error | null = null;\n private backpressure = false;\n private writeQueue: string[] = [];\n private queuedBytes = 0;\n private spawnedViaCmd = false;\n private spawnedDetached = false;\n\n private notificationHandler: NotificationHandler | null = null;\n private serverRequestHandler: ServerRequestHandler | null = null;\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n get supportsTurnOverrides(): boolean {\n return true;\n }\n\n /**\n * Spawn codex app-server and perform initialization handshake.\n */\n async start(opts: AppServerSpawnOptions): Promise<InitializeResult> {\n const args = buildAppServerArgs(opts);\n const env = { ...process.env };\n const stdio: [\"pipe\", \"pipe\", \"pipe\"] = [\"pipe\", \"pipe\", \"pipe\"];\n\n const exe = getDefaultCodexExecutable();\n const invocation = resolveCodexInvocation(args, {\n codexCommand: exe.command,\n codexIsPath: exe.isPath,\n });\n this.spawnedViaCmd = invocation.spawnedViaCmd;\n this.spawnedDetached = process.platform !== \"win32\";\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio,\n env,\n detached: this.spawnedDetached,\n windowsHide: process.platform === \"win32\",\n });\n this.process = proc;\n\n proc.stdout!.on(\"data\", (chunk: Buffer) => this.onData(chunk));\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n console.error(`[app-server stderr] ${chunk.toString().trimEnd()}`);\n });\n proc.stdin?.on(\"drain\", () => this.flushWriteQueue());\n proc.stdin?.on(\"error\", (err) => {\n this.lastFailure = err instanceof Error ? err : new Error(String(err));\n this.failAllPending(this.lastFailure);\n });\n proc.stdin?.on(\"close\", () => {\n this.lastFailure ??= new Error(\"app-server stdin closed\");\n this.failAllPending(this.lastFailure);\n });\n proc.on(\"exit\", (code, signal) => {\n this.lastFailure ??= new Error(\n `app-server exited (code: ${code}, signal: ${signal ?? \"null\"})`\n );\n this.failAllPending(this.lastFailure);\n if (!this._destroyed) {\n this.emit(\"exit\", code, signal);\n }\n });\n proc.on(\"error\", (err) => {\n this.lastFailure = err instanceof Error ? err : new Error(String(err));\n this.failAllPending(this.lastFailure);\n this.emit(\"error\", err);\n });\n\n // Initialize handshake\n const result = await this.request<InitializeResult>(Methods.INITIALIZE, {\n clientInfo: { name: \"codex-mcp\", version: CLIENT_VERSION },\n } satisfies InitializeParams);\n\n return result;\n }\n\n /**\n * Register handler for server notifications.\n */\n onNotification(handler: NotificationHandler): void {\n this.notificationHandler = handler;\n }\n\n /**\n * Register handler for server-initiated requests (approvals, user input, etc.).\n */\n onServerRequest(handler: ServerRequestHandler): void {\n this.serverRequestHandler = handler;\n }\n\n /**\n * Send a JSON-RPC response to a server-initiated request.\n */\n respondToServer(id: RequestId, result: unknown): void {\n try {\n this.send({ jsonrpc: \"2.0\", id, result } as JsonRpcResponse);\n } catch (err) {\n console.error(\n `[app-server] Failed to send JSON-RPC response for server request id=${String(id)}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n /**\n * Send a JSON-RPC error response to a server-initiated request.\n */\n respondErrorToServer(id: RequestId, code: number, message: string): void {\n try {\n this.send({ jsonrpc: \"2.0\", id, error: { code, message } } as JsonRpcResponse);\n } catch (err) {\n console.error(\n `[app-server] Failed to send JSON-RPC error response for server request id=${String(id)}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // ── High-level protocol methods ────────────────────────────────\n\n async threadStart(\n params: ThreadStartParams,\n timeout = STARTUP_REQUEST_TIMEOUT\n ): Promise<ThreadStartResult> {\n return this.request<ThreadStartResult>(Methods.THREAD_START, params, timeout);\n }\n\n async threadFork(params: ThreadForkParams): Promise<ThreadForkResult> {\n return this.request<ThreadForkResult>(Methods.THREAD_FORK, params);\n }\n\n async threadResume(params: ThreadResumeParams): Promise<ThreadResumeResult> {\n return this.request<ThreadResumeResult>(Methods.THREAD_RESUME, params);\n }\n\n async threadBackgroundTerminalsClean(\n params: ThreadBackgroundTerminalsCleanParams\n ): Promise<Record<string, never>> {\n return this.request<Record<string, never>>(Methods.THREAD_BACKGROUND_TERMINALS_CLEAN, params);\n }\n\n async turnStart(\n params: TurnStartParams,\n timeout = STARTUP_REQUEST_TIMEOUT\n ): Promise<TurnStartResult> {\n return this.request<TurnStartResult>(Methods.TURN_START, params, timeout);\n }\n\n async turnInterrupt(params: TurnInterruptParams): Promise<void> {\n await this.request<void>(Methods.TURN_INTERRUPT, params);\n }\n\n // ── Low-level JSON-RPC ─────────────────────────────────────────\n\n private request<T>(\n method: string,\n params?: unknown,\n timeout = DEFAULT_REQUEST_TIMEOUT\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (this._destroyed) {\n reject(new Error(\"Client destroyed\"));\n return;\n }\n if (!this.process?.stdin?.writable) {\n reject(this.lastFailure ?? new Error(\"app-server is not running (stdin not writable)\"));\n return;\n }\n\n const id = this.nextId++;\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`Request ${method} timed out after ${timeout}ms`));\n }, timeout);\n if (timer.unref) timer.unref();\n\n this.pending.set(id, {\n resolve: resolve as (result: unknown) => void,\n reject,\n timer,\n });\n\n try {\n this.send({ jsonrpc: \"2.0\", id, method, params } as JsonRpcRequest);\n } catch (err) {\n const pending = this.pending.get(id);\n if (pending) {\n this.pending.delete(id);\n clearTimeout(pending.timer);\n }\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n private send(msg: JsonRpcMessage): void {\n if (!this.process?.stdin) throw new Error(\"app-server process not started\");\n if (!this.process.stdin.writable) throw new Error(\"app-server stdin not writable\");\n const payload = JSON.stringify(msg) + \"\\n\";\n this.enqueueWrite(payload);\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += this.decoder.write(chunk);\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n // Fast path: app-server should emit JSON per line; ignore any non-JSON noise safely.\n if (trimmed[0] !== \"{\" && trimmed[0] !== \"[\") {\n continue;\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (Array.isArray(parsed)) {\n for (const item of parsed) {\n if (item && typeof item === \"object\") {\n this.handleMessage(item as JsonRpcMessage);\n }\n }\n } else if (parsed && typeof parsed === \"object\") {\n this.handleMessage(parsed as JsonRpcMessage);\n }\n } catch {\n const error = new Error(\n `Error [${ErrorCode.PROTOCOL_PARSE_ERROR}]: app-server protocol error: failed to parse JSON line: ${trimmed.slice(0, 200)}`\n );\n console.error(`[app-server] ${error.message}`);\n this.lastFailure ??= error;\n this.failAllPending(error);\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after protocol parse error: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n }\n }\n }\n\n private enqueueWrite(payload: string): void {\n if (!this.process?.stdin?.writable) throw new Error(\"app-server stdin not writable\");\n\n if (this.backpressure || this.writeQueue.length > 0) {\n if (this.queuedBytes + payload.length > MAX_WRITE_QUEUE_BYTES) {\n const error = new Error(\n `Error [${ErrorCode.WRITE_QUEUE_DROPPED}]: app-server stdin backpressure: write queue exceeded limit`\n );\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after write queue overflow: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n throw error;\n }\n this.writeQueue.push(payload);\n this.queuedBytes += payload.length;\n return;\n }\n\n try {\n const ok = this.process.stdin.write(payload);\n if (!ok) this.backpressure = true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.lastFailure = error;\n this.failAllPending(error);\n throw error;\n }\n }\n\n private flushWriteQueue(): void {\n if (!this.process?.stdin?.writable) {\n const dropped = this.dropQueuedWrites(\"stdin is not writable while flushing\");\n if (dropped) {\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after dropping queued writes: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n }\n return;\n }\n this.backpressure = false;\n while (this.writeQueue.length > 0 && !this.backpressure) {\n const next = this.writeQueue.shift()!;\n this.queuedBytes -= next.length;\n try {\n const ok = this.process.stdin.write(next);\n if (!ok) this.backpressure = true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n return;\n }\n }\n }\n\n private dropQueuedWrites(reason: string): boolean {\n if (this.writeQueue.length === 0) return false;\n const error = new Error(`Error [${ErrorCode.WRITE_QUEUE_DROPPED}]: ${reason}`);\n console.error(\n `[app-server] Dropping ${this.writeQueue.length} queued writes (${this.queuedBytes} bytes): ${reason}`\n );\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n return true;\n }\n\n private handleMessage(msg: JsonRpcMessage): void {\n // Response to our request\n if (\"id\" in msg && (\"result\" in msg || \"error\" in msg)) {\n const resp = msg as JsonRpcResponse;\n const pending = this.pending.get(resp.id);\n if (pending) {\n this.pending.delete(resp.id);\n clearTimeout(pending.timer);\n if (resp.error) {\n pending.reject(new Error(`RPC error ${resp.error.code}: ${resp.error.message}`));\n } else {\n pending.resolve(resp.result);\n }\n }\n return;\n }\n\n // Server-initiated request (has id + method, no result/error)\n if (\"id\" in msg && \"method\" in msg) {\n const req = msg as JsonRpcRequest;\n if (this.serverRequestHandler) {\n this.serverRequestHandler(req.id, req.method, req.params);\n } else {\n // No handler — respond with error to avoid hanging\n this.respondErrorToServer(req.id, -32601, `Method not handled: ${req.method}`);\n }\n return;\n }\n\n // Notification (no id)\n if (\"method\" in msg && !(\"id\" in msg)) {\n const notif = msg as JsonRpcNotification;\n if (this.notificationHandler) {\n this.notificationHandler(notif.method, notif.params);\n }\n return;\n }\n }\n\n private failAllPending(error: Error): void {\n if (this.pending.size === 0) return;\n const entries = Array.from(this.pending.entries());\n this.pending.clear();\n for (const [, pending] of entries) {\n clearTimeout(pending.timer);\n pending.reject(error);\n }\n }\n\n /**\n * Gracefully destroy the client and kill the subprocess.\n */\n async destroy(): Promise<void> {\n if (this._destroyed) return;\n this._destroyed = true;\n\n // Reject all pending requests\n this.failAllPending(new Error(\"Client destroyed\"));\n\n // Kill subprocess\n if (this.process && !this.process.killed) {\n const alreadyExited = this.process.exitCode !== null;\n this.process.stdin?.end();\n this.terminate(\"SIGTERM\");\n\n // Force kill after 5s\n const forceKill = setTimeout(() => {\n if (this.process && !this.process.killed) {\n if (process.platform === \"win32\" && this.process.pid) {\n try {\n spawn(\"taskkill\", [\"/PID\", String(this.process.pid), \"/T\", \"/F\"], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } catch (err) {\n console.error(\n `[app-server] Failed to force-kill app-server via taskkill: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n } else {\n this.terminate(\"SIGKILL\");\n }\n }\n }, 5000);\n forceKill.unref();\n\n if (!alreadyExited) {\n await new Promise<void>((resolve) => {\n this.process!.on(\"exit\", () => {\n clearTimeout(forceKill);\n resolve();\n });\n // Resolve anyway after timeout\n const fallback = setTimeout(resolve, 6000);\n fallback.unref();\n });\n }\n }\n\n this.process = null;\n this.removeAllListeners();\n }\n\n private terminate(signal: NodeJS.Signals): void {\n if (!this.process) return;\n\n // On POSIX, kill the whole process group when detached to avoid orphan children.\n if (process.platform !== \"win32\" && this.spawnedDetached && this.process.pid) {\n try {\n process.kill(-this.process.pid, signal);\n return;\n } catch (err) {\n console.error(\n `[app-server] Failed to kill detached process group with ${signal}, falling back to direct kill: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n try {\n this.process.kill(signal);\n } catch (err) {\n console.error(\n `[app-server] Failed to send ${signal} to app-server process: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n}\n","/**\n * codex app-server JSON-RPC protocol types\n *\n * Derived from `codex app-server generate-json-schema`.\n * Wire format for stdio communication with codex app-server subprocess.\n */\n\n// ── JSON-RPC Base ──────────────────────────────────────────────────\n\nexport type RequestId = string | number;\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id: RequestId;\n method: string;\n params?: unknown;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: RequestId;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nexport interface JsonRpcNotification {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n}\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\n// ── Initialize ─────────────────────────────────────────────────────\n\nexport interface InitializeParams {\n clientInfo: { name: string; version: string; title?: string };\n capabilities?: {\n experimentalApi?: boolean;\n optOutNotificationMethods?: string[];\n };\n}\n\nexport interface InitializeResult {\n userAgent: string;\n}\n\n// ── Shared enums / aliases ─────────────────────────────────────────\n\nexport type ApprovalPolicy = \"untrusted\" | \"on-failure\" | \"on-request\" | \"never\";\nexport type SandboxMode = \"read-only\" | \"workspace-write\" | \"danger-full-access\";\nexport type Personality = \"none\" | \"friendly\" | \"pragmatic\";\nexport type ReasoningEffort = \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\nexport type ReasoningSummary = \"auto\" | \"concise\" | \"detailed\" | \"none\";\n\n// ── Thread Management ──────────────────────────────────────────────\n\nexport interface DynamicToolSpec {\n name: string;\n description: string;\n inputSchema: unknown;\n}\n\n/** thread/start — all fields optional */\nexport interface ThreadStartParams {\n cwd?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n approvalPolicy?: ApprovalPolicy | null;\n /**\n * v2 schema: sandbox mode string enum (\"read-only\" | \"workspace-write\" | \"danger-full-access\")\n * (Not the SandboxPolicy object used by turn/start's sandboxPolicy.)\n */\n sandbox?: SandboxMode | null;\n personality?: Personality | null;\n ephemeral?: boolean | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n config?: Record<string, unknown> | null;\n dynamicTools?: DynamicToolSpec[] | null;\n experimentalRawEvents?: boolean;\n mockExperimentalField?: string | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadStartResultV1 {\n threadId: string;\n}\nexport interface ThreadStartResultV2 {\n thread: { id: string };\n}\nexport type ThreadStartResult = ThreadStartResultV1 | ThreadStartResultV2;\n\nexport interface ThreadForkParams {\n threadId: string;\n approvalPolicy?: ApprovalPolicy | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n sandbox?: SandboxMode | null;\n cwd?: string | null;\n config?: Record<string, unknown> | null;\n path?: string | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadForkResultV1 {\n threadId: string;\n}\nexport interface ThreadForkResultV2 {\n thread: { id: string };\n}\nexport type ThreadForkResult = ThreadForkResultV1 | ThreadForkResultV2;\n\nexport interface ThreadResumeParams {\n threadId: string;\n approvalPolicy?: ApprovalPolicy | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n sandbox?: SandboxMode | null;\n personality?: Personality | null;\n cwd?: string | null;\n config?: Record<string, unknown> | null;\n path?: string | null;\n history?: unknown[] | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadResumeResultV1 {\n threadId: string;\n}\nexport interface ThreadResumeResultV2 {\n thread: { id: string };\n}\nexport type ThreadResumeResult = ThreadResumeResultV1 | ThreadResumeResultV2;\n\nexport interface ThreadBackgroundTerminalsCleanParams {\n threadId: string;\n}\n\n// ── SandboxPolicy ──────────────────────────────────────────────────\n\nexport type ReadOnlyAccess =\n | {\n type: \"restricted\";\n includePlatformDefaults?: boolean;\n readableRoots?: string[];\n }\n | { type: \"fullAccess\" };\n\nexport type SandboxPolicy =\n | { type: \"dangerFullAccess\" }\n | { type: \"readOnly\"; access?: ReadOnlyAccess }\n | { type: \"externalSandbox\"; networkAccess?: \"restricted\" | \"enabled\" }\n | {\n type: \"workspaceWrite\";\n writableRoots?: string[];\n readOnlyAccess?: ReadOnlyAccess;\n networkAccess?: boolean;\n excludeSlashTmp?: boolean;\n excludeTmpdirEnvVar?: boolean;\n };\n\n/** Map user-facing sandbox mode string to protocol SandboxPolicy */\nexport function toSandboxPolicy(mode: SandboxMode | string): SandboxPolicy | undefined {\n switch (mode) {\n case \"read-only\":\n return { type: \"readOnly\" };\n case \"workspace-write\":\n return { type: \"workspaceWrite\" };\n case \"danger-full-access\":\n return { type: \"dangerFullAccess\" };\n default:\n return undefined;\n }\n}\n\n// ── Turn Management ────────────────────────────────────────────────\n\nexport interface TextElement {\n byteRange: { start: number; end: number };\n placeholder?: string | null;\n}\n\nexport type UserInput =\n | { type: \"text\"; text: string; text_elements?: TextElement[] }\n | { type: \"image\"; url: string }\n | { type: \"localImage\"; path: string }\n | { type: \"skill\"; name: string; path: string }\n | { type: \"mention\"; name: string; path: string };\n\nexport interface CollaborationMode {\n mode: \"plan\" | \"default\";\n settings: {\n model: string;\n developer_instructions?: string | null;\n reasoning_effort?: ReasoningEffort | null;\n };\n}\n\nexport interface TurnStartParams {\n threadId: string;\n input: UserInput[];\n model?: string | null;\n approvalPolicy?: ApprovalPolicy | null;\n sandboxPolicy?: SandboxPolicy | null;\n personality?: Personality | null;\n effort?: ReasoningEffort | null;\n summary?: ReasoningSummary | null;\n cwd?: string | null;\n outputSchema?: Record<string, unknown>;\n collaborationMode?: CollaborationMode | null;\n}\n\nexport interface TurnStartResultV1 {\n turnId: string;\n}\nexport interface TurnStartResultV2 {\n turn: { id: string };\n}\nexport type TurnStartResult = TurnStartResultV1 | TurnStartResultV2;\n\nexport interface TurnInterruptParams {\n threadId: string;\n turnId: string;\n}\n\nexport interface TurnSteerParams {\n threadId: string;\n expectedTurnId: string;\n input: UserInput[];\n}\n\n// ── Approval Requests (server → client) ────────────────────────────\n\nexport interface CommandApprovalParams {\n /**\n * Optional per-callback approval id.\n * Present for subcommand approvals (execve intercept), null/absent for regular approvals.\n */\n approvalId?: string | null;\n itemId: string;\n threadId: string;\n turnId: string;\n command?: string | null;\n cwd?: string | null;\n reason?: string | null;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n\n // Added in codex-cli 0.106.x: richer approval contexts.\n additionalPermissions?: unknown;\n availableDecisions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown;\n}\n\nexport type CommandApprovalDecision =\n | \"accept\"\n | \"acceptForSession\"\n | { acceptWithExecpolicyAmendment: { execpolicy_amendment: string[] } }\n | {\n applyNetworkPolicyAmendment: {\n network_policy_amendment: { action: \"allow\" | \"deny\"; host: string };\n };\n }\n | \"decline\"\n | \"cancel\";\n\nexport interface CommandApprovalResponse {\n decision: CommandApprovalDecision;\n}\n\nexport interface FileChangeApprovalParams {\n itemId: string;\n threadId: string;\n turnId: string;\n grantRoot?: string | null;\n reason?: string | null;\n}\n\nexport type FileChangeApprovalDecision = \"accept\" | \"acceptForSession\" | \"decline\" | \"cancel\";\n\nexport interface FileChangeApprovalResponse {\n decision: FileChangeApprovalDecision;\n}\n\n// ── User Input Request (server → client) ───────────────────────────\n\nexport interface UserInputRequestParams {\n itemId: string;\n threadId: string;\n turnId: string;\n questions: Array<{\n id: string;\n header: string;\n question: string;\n isOther?: boolean;\n isSecret?: boolean;\n options?: Array<{ label: string; description: string }> | null;\n }>;\n}\n\nexport interface UserInputRequestResponse {\n answers: Record<string, { answers: string[] }>;\n}\n\n// ── Dynamic Tool Call (server → client) ────────────────────────────\n\nexport interface DynamicToolCallParams {\n threadId: string;\n turnId: string;\n callId: string;\n tool: string;\n arguments: unknown;\n}\n\nexport interface DynamicToolCallResponse {\n success: boolean;\n contentItems: Array<\n { type: \"inputText\"; text: string } | { type: \"inputImage\"; imageUrl: string }\n >;\n}\n\n// ── Auth Refresh Request (server → client) ─────────────────────────\n\nexport interface ChatgptAuthTokensRefreshParams {\n reason: \"unauthorized\";\n previousAccountId?: string | null;\n}\n\nexport interface ChatgptAuthTokensRefreshResponse {\n accessToken: string;\n chatgptAccountId: string;\n chatgptPlanType?: string | null;\n}\n\n// ── Event Notification Params ──────────────────────────────────────\n\nexport interface DeltaNotificationParams {\n threadId: string;\n turnId: string;\n itemId: string;\n delta: string;\n}\n\nexport interface ReasoningDeltaParams {\n threadId: string;\n turnId: string;\n itemId: string;\n contentIndex: number;\n delta: string;\n}\n\nexport interface ItemNotificationParams {\n threadId: string;\n turnId: string;\n item: unknown;\n}\n\nexport interface ThreadStateNotificationParams {\n threadId: string;\n}\n\nexport interface TurnNotificationParams {\n threadId: string;\n turn: unknown;\n}\n\nexport interface ErrorNotificationParams {\n threadId: string;\n turnId: string;\n error: unknown;\n willRetry: boolean;\n}\n\n// ── Legacy Approval (deprecated) ───────────────────────────────────\n\nexport interface LegacyApprovalResponse {\n decision:\n | \"approved\"\n | \"approved_for_session\"\n | \"denied\"\n | \"abort\"\n | { approved_execpolicy_amendment: { proposed_execpolicy_amendment: string[] } };\n}\n\n// ── Protocol Method Constants ──────────────────────────────────────\n\nexport const Methods = {\n // Client → Server\n INITIALIZE: \"initialize\",\n THREAD_START: \"thread/start\",\n THREAD_RESUME: \"thread/resume\",\n THREAD_FORK: \"thread/fork\",\n THREAD_BACKGROUND_TERMINALS_CLEAN: \"thread/backgroundTerminals/clean\",\n TURN_START: \"turn/start\",\n TURN_INTERRUPT: \"turn/interrupt\",\n TURN_STEER: \"turn/steer\",\n\n // Server → Client requests\n COMMAND_APPROVAL: \"item/commandExecution/requestApproval\",\n FILE_CHANGE_APPROVAL: \"item/fileChange/requestApproval\",\n USER_INPUT_REQUEST: \"item/tool/requestUserInput\",\n DYNAMIC_TOOL_CALL: \"item/tool/call\",\n AUTH_TOKEN_REFRESH: \"account/chatgptAuthTokens/refresh\",\n LEGACY_PATCH_APPROVAL: \"applyPatchApproval\",\n LEGACY_EXEC_APPROVAL: \"execCommandApproval\",\n\n // Server → Client notifications\n ERROR: \"error\",\n THREAD_STARTED: \"thread/started\",\n THREAD_ARCHIVED: \"thread/archived\",\n THREAD_UNARCHIVED: \"thread/unarchived\",\n THREAD_NAME_UPDATED: \"thread/name/updated\",\n THREAD_TOKEN_USAGE_UPDATED: \"thread/tokenUsage/updated\",\n TURN_STARTED: \"turn/started\",\n TURN_COMPLETED: \"turn/completed\",\n TURN_DIFF_UPDATED: \"turn/diff/updated\",\n TURN_PLAN_UPDATED: \"turn/plan/updated\",\n ITEM_STARTED: \"item/started\",\n ITEM_COMPLETED: \"item/completed\",\n RAW_RESPONSE_ITEM_COMPLETED: \"rawResponseItem/completed\",\n AGENT_MESSAGE_DELTA: \"item/agentMessage/delta\",\n COMMAND_OUTPUT_DELTA: \"item/commandExecution/outputDelta\",\n COMMAND_TERMINAL_INTERACTION: \"item/commandExecution/terminalInteraction\",\n FILE_CHANGE_OUTPUT_DELTA: \"item/fileChange/outputDelta\",\n REASONING_TEXT_DELTA: \"item/reasoning/textDelta\",\n REASONING_SUMMARY_DELTA: \"item/reasoning/summaryTextDelta\",\n REASONING_SUMMARY_PART_ADDED: \"item/reasoning/summaryPartAdded\",\n PLAN_DELTA: \"item/plan/delta\",\n MCP_TOOL_PROGRESS: \"item/mcpToolCall/progress\",\n MODEL_REROUTED: \"model/rerouted\",\n FUZZY_FILE_SEARCH_SESSION_UPDATED: \"fuzzyFileSearch/sessionUpdated\",\n FUZZY_FILE_SEARCH_SESSION_COMPLETED: \"fuzzyFileSearch/sessionCompleted\",\n WINDOWS_WORLD_WRITABLE_WARNING: \"windows/worldWritableWarning\",\n ACCOUNT_LOGIN_COMPLETED: \"account/login/completed\",\n SESSION_CONFIGURED: \"sessionConfigured\",\n} as const;\n","/**\n * Build codex app-server spawn arguments from tool parameters.\n */\nimport type { ApprovalPolicy, SandboxMode } from \"../types.js\";\n\nexport interface AppServerSpawnOptions {\n profile?: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n config?: Record<string, unknown>;\n}\n\nexport function buildAppServerArgs(opts: AppServerSpawnOptions): string[] {\n const args: string[] = [\"app-server\"];\n\n if (opts.profile) {\n args.push(\"-p\", opts.profile);\n }\n if (opts.model) {\n args.push(\"-c\", `model=${opts.model}`);\n }\n if (opts.approvalPolicy) {\n args.push(\"-c\", `approval_policy=${opts.approvalPolicy}`);\n }\n if (opts.sandbox) {\n args.push(\"-c\", `sandbox_mode=${opts.sandbox}`);\n }\n if (opts.config) {\n for (const [key, value] of Object.entries(opts.config)) {\n // Use raw value for primitives, JSON for objects/arrays\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n }\n\n return args;\n}\n","/**\n * Resolve how to spawn the `codex` CLI across platforms.\n *\n * Goal: avoid going through a shell on Windows when possible (npm `.cmd` shims are shell-parsed),\n * while keeping \"zero-config local integration\" (PATH + ~/.codex/config.toml).\n *\n * The command name is configurable via the `codexCommand` field in `ResolverDeps`.\n * When `codexIsPath` is true, the value is treated as a direct filesystem path\n * and PATH resolution is skipped.\n */\nimport { existsSync, readFileSync } from \"fs\";\nimport path from \"path\";\n\nexport interface CodexInvocation {\n cmd: string;\n args: string[];\n /** True when spawning via `cmd.exe` (fallback path). */\n spawnedViaCmd: boolean;\n}\n\ntype ResolverDeps = {\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n exists?: (p: string) => boolean;\n readFile?: (p: string) => string;\n /** The codex command name or filesystem path. Defaults to \"codex\". */\n codexCommand?: string;\n /** True when `codexCommand` is a filesystem path (not a bare command name). */\n codexIsPath?: boolean;\n};\n\nexport function resolveCodexInvocation(\n codexArgs: string[],\n deps: ResolverDeps = {}\n): CodexInvocation {\n const platform = deps.platform ?? process.platform;\n const env = deps.env ?? process.env;\n const exists = deps.exists ?? existsSync;\n const readFile = deps.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n const pathApi = platform === \"win32\" ? path.win32 : path.posix;\n const delimiter = platform === \"win32\" ? \";\" : \":\";\n const codexCommand = deps.codexCommand ?? \"codex\";\n const codexIsPath = deps.codexIsPath ?? false;\n\n // ── Direct path mode ────────────────────────────────────────────\n // When an explicit filesystem path is provided, use it directly.\n // On Windows, .cmd/.bat files cannot be spawned directly — wrap via cmd.exe.\n if (codexIsPath) {\n if (\n platform === \"win32\" &&\n (codexCommand.toLowerCase().endsWith(\".cmd\") || codexCommand.toLowerCase().endsWith(\".bat\"))\n ) {\n const comspec = env.ComSpec || env.COMSPEC || \"cmd.exe\";\n return {\n cmd: comspec,\n args: [\"/d\", \"/s\", \"/c\", codexCommand, ...codexArgs],\n spawnedViaCmd: true,\n };\n }\n return { cmd: codexCommand, args: codexArgs, spawnedViaCmd: false };\n }\n\n // ── Non-Windows: bare command ───────────────────────────────────\n if (platform !== \"win32\") {\n return { cmd: codexCommand, args: codexArgs, spawnedViaCmd: false };\n }\n\n // ── Windows: try to resolve from PATH ───────────────────────────\n const shim = findOnPath(codexCommand, env, exists, pathApi, delimiter, [\".exe\", \".cmd\", \".bat\"]);\n if (shim && shim.toLowerCase().endsWith(\".exe\")) {\n return { cmd: shim, args: codexArgs, spawnedViaCmd: false };\n }\n\n if (shim && (shim.toLowerCase().endsWith(\".cmd\") || shim.toLowerCase().endsWith(\".bat\"))) {\n const script = tryResolveNodeScriptFromShim(shim, codexCommand, exists, readFile, pathApi);\n if (script) {\n return { cmd: process.execPath, args: [script, ...codexArgs], spawnedViaCmd: false };\n }\n }\n\n // Last resort: spawn via cmd.exe. Keep arguments as separate tokens to avoid nested-quote issues\n // when Node builds the final CreateProcess command line.\n const comspec = env.ComSpec || env.COMSPEC || \"cmd.exe\";\n return {\n cmd: comspec,\n args: [\"/d\", \"/s\", \"/c\", codexCommand, ...codexArgs],\n spawnedViaCmd: true,\n };\n}\n\nexport function findOnPath(\n base: string,\n env: NodeJS.ProcessEnv,\n exists: (p: string) => boolean,\n pathApi: typeof path.posix | typeof path.win32,\n delimiter: string,\n exts: string[]\n): string | undefined {\n const pathEnv = env.PATH || env.Path || env.path || \"\";\n const dirs = pathEnv\n .split(delimiter)\n .map((d) => stripSurroundingQuotes(d.trim()))\n .filter(Boolean);\n\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = pathApi.join(dir, `${base}${ext}`);\n if (exists(candidate)) return candidate;\n }\n const raw = pathApi.join(dir, base);\n if (exists(raw)) return raw;\n }\n return undefined;\n}\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction tryResolveNodeScriptFromShim(\n shimPath: string,\n codexCommand: string,\n exists: (p: string) => boolean,\n readFile: (p: string) => string,\n pathApi: typeof path.posix | typeof path.win32\n): string | undefined {\n let contents: string;\n try {\n contents = readFile(shimPath);\n } catch {\n return undefined;\n }\n\n // npm `.cmd` shims typically contain a quoted script path ending in `.js` / `.cjs` / `.mjs`.\n const matches: string[] = [];\n const re = /\"([^\"]+\\.(?:m?js|cjs))\"/gi;\n for (;;) {\n const m = re.exec(contents);\n if (!m) break;\n matches.push(m[1]);\n }\n if (matches.length === 0) return undefined;\n\n // Escape the command name for use in regex matching\n const escapedCommand = codexCommand.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const baseNameRe = new RegExp(escapedCommand, \"i\");\n const pathRe = new RegExp(\n `@openai\\\\\\\\${escapedCommand}|\\\\\\\\${escapedCommand}\\\\\\\\|\\\\/${escapedCommand}\\\\/`,\n \"i\"\n );\n\n const preferred =\n matches.find((m) => baseNameRe.test(pathApi.basename(m))) ??\n matches.find((m) => pathRe.test(m)) ??\n matches[matches.length - 1];\n\n const shimDir = pathApi.dirname(shimPath);\n const dp0 = shimDir.endsWith(pathApi.sep) ? shimDir : shimDir + pathApi.sep;\n let resolved = preferred.replace(/%~dp0/gi, dp0).replace(/%dp0%/gi, dp0);\n resolved = resolved.replace(/\\//g, \"\\\\\");\n\n const abs = pathApi.isAbsolute(resolved)\n ? pathApi.normalize(resolved)\n : pathApi.resolve(shimDir, resolved);\n if (!exists(abs)) return undefined;\n return abs;\n}\n","/**\n * Resolve which `codex` executable to use.\n *\n * Resolution priority (mirrors claude-code-mcp's claude-executable.ts):\n * 1. CODEX_MCP_PATH — absolute/relative filesystem path\n * 2. CODEX_MCP_COMMAND — bare command name resolved from PATH\n * 3. Auto-detect: try \"codex\", then \"codex-internal\" on PATH\n * 4. Fall back to \"codex\" (let spawn fail with a clear error later)\n *\n * CODEX_MCP_PATH and CODEX_MCP_COMMAND are mutually exclusive.\n */\nimport { accessSync, constants, existsSync, statSync } from \"fs\";\nimport path from \"path\";\n\n// ── Env var names ─────────────────────────────────────────────────\nexport const CODEX_MCP_COMMAND = \"CODEX_MCP_COMMAND\";\nexport const CODEX_MCP_PATH = \"CODEX_MCP_PATH\";\n\n// ── Auto-detection candidates (tried in order) ───────────────────\nexport const AUTO_CODEX_COMMANDS = [\"codex\", \"codex-internal\"] as const;\n\n// ── Types ─────────────────────────────────────────────────────────\nexport type CodexExecutableSource = \"env_path\" | \"env_command\" | \"auto_detect\" | \"default\";\n\nexport interface CodexExecutableInfo {\n /** The command name or filesystem path to use */\n command: string;\n /** True when `command` is a filesystem path (not a bare name) */\n isPath: boolean;\n /** How the value was determined */\n source: CodexExecutableSource;\n}\n\n// ── Module state ──────────────────────────────────────────────────\nlet _resolved: CodexExecutableInfo | undefined;\n\n// ── PATH helpers ──────────────────────────────────────────────────\n\nconst WINDOWS_SUPPORTED_EXTENSIONS = [\".com\", \".exe\", \".bat\", \".cmd\"] as const;\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction normalizeMaybeQuotedToken(raw: string): string {\n return stripSurroundingQuotes(raw.trim());\n}\n\nfunction normalizeWindowsExtension(value: string): string | undefined {\n const trimmed = stripSurroundingQuotes(value.trim());\n if (!trimmed) return undefined;\n return trimmed.startsWith(\".\") ? trimmed.toLowerCase() : `.${trimmed.toLowerCase()}`;\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n const stat = statSync(candidate);\n if (!stat.isFile()) return false;\n if (process.platform === \"win32\") return true;\n accessSync(candidate, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getPathEntries(env: NodeJS.ProcessEnv): string[] {\n const pathEnv = env.PATH || env.Path || env.path || \"\";\n return pathEnv\n .split(process.platform === \"win32\" ? \";\" : \":\")\n .map((entry) => stripSurroundingQuotes(entry.trim()))\n .filter(Boolean);\n}\n\nfunction getPathExtensions(env: NodeJS.ProcessEnv): string[] {\n if (process.platform !== \"win32\") return [\"\"];\n const configured =\n env.PATHEXT ?? env.Pathext ?? env.pathext ?? process.env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\";\n const configuredExts = configured\n .split(\";\")\n .map((entry) => normalizeWindowsExtension(entry))\n .filter((entry): entry is string => Boolean(entry));\n const merged = configuredExts.filter((ext) =>\n WINDOWS_SUPPORTED_EXTENSIONS.includes(ext as never)\n );\n for (const ext of WINDOWS_SUPPORTED_EXTENSIONS) {\n if (!merged.includes(ext)) merged.push(ext);\n }\n return Array.from(new Set(merged));\n}\n\nfunction commandExistsOnPath(command: string, env: NodeJS.ProcessEnv): boolean {\n const dirs = getPathEntries(env);\n const ext = process.platform === \"win32\" ? path.extname(command) : \"\";\n const names =\n process.platform === \"win32\"\n ? Array.from(\n new Set(\n ext\n ? [command]\n : [...getPathExtensions(env).map((suffix) => `${command}${suffix}`), command]\n )\n )\n : [command];\n\n for (const dir of dirs) {\n for (const name of names) {\n const candidate = path.join(dir, name);\n if (isExecutableFile(candidate)) return true;\n }\n }\n return false;\n}\n\nfunction looksLikePath(value: string): boolean {\n return value.includes(\"/\") || value.includes(\"\\\\\");\n}\n\n// ── Core resolution ───────────────────────────────────────────────\n\nexport function resolveDefaultCodexExecutable(\n env: NodeJS.ProcessEnv = process.env\n): CodexExecutableInfo {\n const envPathRaw = env[CODEX_MCP_PATH]?.trim();\n const envCommandRaw = env[CODEX_MCP_COMMAND]?.trim();\n const envPath = envPathRaw ? normalizeMaybeQuotedToken(envPathRaw) : undefined;\n const envCommand = envCommandRaw ? normalizeMaybeQuotedToken(envCommandRaw) : undefined;\n\n // Mutually exclusive\n if (envPath && envCommand) {\n throw new Error(\n `Cannot set both ${CODEX_MCP_PATH} and ${CODEX_MCP_COMMAND}. Use one or the other.`\n );\n }\n\n // 1. Explicit filesystem path\n if (envPath) {\n const resolvedPath = path.resolve(envPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`${CODEX_MCP_PATH}=\"${envPath}\" — file does not exist.`);\n }\n if (!isExecutableFile(resolvedPath)) {\n throw new Error(`${CODEX_MCP_PATH}=\"${envPath}\" — not an executable file.`);\n }\n return { command: resolvedPath, isPath: true, source: \"env_path\" };\n }\n\n // 2. Explicit bare command name\n if (envCommand) {\n if (looksLikePath(envCommand)) {\n throw new Error(\n `${CODEX_MCP_COMMAND}=\"${envCommand}\" looks like a path. Use ${CODEX_MCP_PATH} for filesystem paths.`\n );\n }\n if (!commandExistsOnPath(envCommand, env)) {\n throw new Error(`${CODEX_MCP_COMMAND}=\"${envCommand}\" was not found in PATH.`);\n }\n return { command: envCommand, isPath: false, source: \"env_command\" };\n }\n\n // 3. Auto-detect from PATH\n for (const candidate of AUTO_CODEX_COMMANDS) {\n if (commandExistsOnPath(candidate, env)) {\n return { command: candidate, isPath: false, source: \"auto_detect\" };\n }\n }\n\n // 4. Fall back to \"codex\" — let spawn surface a clear \"not found\" error later\n return { command: \"codex\", isPath: false, source: \"default\" };\n}\n\n// ── Public API ────────────────────────────────────────────────────\n\n/**\n * Resolve and cache the default codex executable info.\n * Safe to call multiple times — resolution runs only once.\n */\nexport function getDefaultCodexExecutable(): CodexExecutableInfo {\n if (!_resolved) {\n _resolved = resolveDefaultCodexExecutable();\n }\n return _resolved;\n}\n\n/**\n * Startup check — resolves the executable and logs the result.\n * Throws on misconfiguration (mutually exclusive env vars, missing path).\n */\nexport function checkDefaultCodexExecutableAvailability(): void {\n const info = getDefaultCodexExecutable();\n const label = info.isPath ? \"path\" : \"command\";\n switch (info.source) {\n case \"env_path\":\n console.error(`[codex-executable] Using ${CODEX_MCP_PATH}: ${info.command}`);\n break;\n case \"env_command\":\n console.error(`[codex-executable] Using ${CODEX_MCP_COMMAND}: ${info.command}`);\n break;\n case \"auto_detect\":\n console.error(`[codex-executable] Auto-detected ${label}: ${info.command}`);\n break;\n case \"default\":\n console.error(\n `[codex-executable] No codex found on PATH; falling back to \"${info.command}\". ` +\n `Set ${CODEX_MCP_COMMAND} or ${CODEX_MCP_PATH} to configure.`\n );\n break;\n }\n}\n\n/** Reset cached state (for testing). */\nexport function _resetForTesting(): void {\n _resolved = undefined;\n}\n","/**\n * Type definitions for codex-mcp\n *\n * Shared constants are defined as tuples so both Zod schemas and\n * TypeScript types can derive from the same source of truth.\n */\n\n// ── Constants ──────────────────────────────────────────────────────\n\nexport const APPROVAL_POLICIES = [\"untrusted\", \"on-failure\", \"on-request\", \"never\"] as const;\nexport type ApprovalPolicy = (typeof APPROVAL_POLICIES)[number];\n\nexport const SANDBOX_MODES = [\"read-only\", \"workspace-write\", \"danger-full-access\"] as const;\nexport type SandboxMode = (typeof SANDBOX_MODES)[number];\n\nexport const PERSONALITIES = [\"none\", \"friendly\", \"pragmatic\"] as const;\nexport type Personality = (typeof PERSONALITIES)[number];\n\nexport const EFFORT_LEVELS = [\"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\nexport type EffortLevel = (typeof EFFORT_LEVELS)[number];\n\nexport const SUMMARY_MODES = [\"auto\", \"concise\", \"detailed\", \"none\"] as const;\nexport type SummaryMode = (typeof SUMMARY_MODES)[number];\n\nexport const SESSION_ACTIONS = [\n \"list\",\n \"get\",\n \"cancel\",\n \"interrupt\",\n \"fork\",\n \"clean_background_terminals\",\n] as const;\nexport type SessionAction = (typeof SESSION_ACTIONS)[number];\n\nexport const CHECK_ACTIONS = [\"poll\", \"respond_permission\", \"respond_user_input\"] as const;\nexport type CheckAction = (typeof CHECK_ACTIONS)[number];\n\nexport const RESPONSE_MODES = [\"minimal\", \"delta_compact\", \"full\"] as const;\nexport type ResponseMode = (typeof RESPONSE_MODES)[number];\n\nexport interface PollOptions {\n includeEvents?: boolean;\n includeActions?: boolean;\n includeResult?: boolean;\n maxBytes?: number;\n}\n\nexport const APPROVAL_TYPES = [\"command\", \"fileChange\"] as const;\nexport type ApprovalType = (typeof APPROVAL_TYPES)[number];\n\nexport const COMMAND_DECISIONS = [\n \"accept\",\n \"acceptForSession\",\n \"acceptWithExecpolicyAmendment\",\n \"applyNetworkPolicyAmendment\",\n \"decline\",\n \"cancel\",\n] as const;\nexport type CommandDecision = (typeof COMMAND_DECISIONS)[number];\n\nexport const FILE_CHANGE_DECISIONS = [\"accept\", \"acceptForSession\", \"decline\", \"cancel\"] as const;\nexport type FileChangeDecision = (typeof FILE_CHANGE_DECISIONS)[number];\n\nexport const ALL_DECISIONS = [\n \"accept\",\n \"acceptForSession\",\n \"acceptWithExecpolicyAmendment\",\n \"applyNetworkPolicyAmendment\",\n \"decline\",\n \"cancel\",\n] as const;\nexport type ApprovalDecision = (typeof ALL_DECISIONS)[number];\n\nexport interface NetworkPolicyAmendment {\n action: \"allow\" | \"deny\";\n host: string;\n}\n\n// ── Session Types ──────────────────────────────────────────────────\n\nexport type SessionStatus = \"running\" | \"idle\" | \"waiting_approval\" | \"error\" | \"cancelled\";\n\nexport type SessionEventType =\n | \"output\"\n | \"progress\"\n | \"approval_request\"\n | \"approval_result\"\n | \"result\"\n | \"error\";\n\nexport interface SessionEvent {\n id: number;\n type: SessionEventType;\n data: unknown;\n timestamp: string;\n pinned: boolean;\n}\n\nexport interface EventBuffer {\n events: SessionEvent[];\n maxSize: number;\n hardMaxSize: number;\n nextId: number;\n}\n\n/** Pending approval/user-input request */\nexport interface PendingRequest {\n requestId: string;\n /** \"command\" | \"fileChange\" | \"user_input\" */\n kind: ApprovalType | \"user_input\";\n /** Raw params from app-server */\n params: unknown;\n /** itemId from app-server (for correlation) */\n itemId: string;\n threadId: string;\n turnId: string;\n reason?: string;\n approvalId?: string;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n availableDecisions?: unknown[] | null;\n additionalPermissions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown[] | null;\n createdAt: string;\n resolved: boolean;\n decision?: string;\n timeoutHandle?: ReturnType<typeof setTimeout>;\n /** JSON-RPC response resolver */\n respond?: (result: unknown) => void;\n}\n\n/** Internal session info (full) */\nexport interface SessionInfo {\n sessionId: string;\n threadId?: string;\n activeTurnId?: string;\n /** Most recent poll cursor consumed by this session. */\n lastEventCursor: number;\n status: SessionStatus;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n approvalTimeoutMs?: number;\n cwd: string;\n model?: string;\n profile?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n config?: Record<string, unknown>;\n eventBuffer: EventBuffer;\n pendingRequests: Map<string, PendingRequest>;\n lastResult?: TurnResult;\n}\n\n/** Public session info (redacted) */\nexport interface PublicSessionInfo {\n sessionId: string;\n status: SessionStatus;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n pendingRequestCount: number;\n}\n\n/** Sensitive session info */\nexport interface SensitiveSessionInfo extends PublicSessionInfo {\n threadId?: string;\n cwd: string;\n profile?: string;\n config?: Record<string, unknown>;\n}\n\n// ── Result Types ───────────────────────────────────────────────────\n\nexport interface TurnResult {\n turnId: string;\n output?: string;\n structuredOutput?: unknown;\n /** Raw turn object from app-server notifications/responses (shape depends on schema version). */\n turn?: unknown;\n /** Turn status string if available (e.g. \"completed\" | \"failed\" | \"interrupted\"). */\n status?: string;\n /** Raw turn error object if available. */\n turnError?: unknown;\n error?: string;\n completedAt: string;\n}\n\nexport interface SessionStartResult {\n sessionId: string;\n threadId: string;\n status: \"running\" | \"idle\";\n pollInterval: number;\n}\n\nexport interface CheckResult {\n sessionId: string;\n status: SessionStatus;\n pollInterval?: number;\n events: Array<{\n id: number;\n type: SessionEventType;\n data: unknown;\n timestamp: string;\n }>;\n nextCursor: number;\n cursorResetTo?: number;\n actions?: Array<{\n type: \"approval\" | \"user_input\";\n requestId: string;\n kind: \"command\" | \"fileChange\" | \"user_input\";\n params: unknown;\n itemId: string;\n reason?: string;\n approvalId?: string;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n availableDecisions?: unknown[] | null;\n additionalPermissions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown[] | null;\n createdAt: string;\n }>;\n result?: TurnResult;\n compatWarnings?: string[];\n truncated?: boolean;\n truncatedFields?: string[];\n}\n\n// ── Error Types ────────────────────────────────────────────────────\n\nexport enum ErrorCode {\n INVALID_ARGUMENT = \"INVALID_ARGUMENT\",\n SESSION_NOT_FOUND = \"SESSION_NOT_FOUND\",\n SESSION_BUSY = \"SESSION_BUSY\",\n SESSION_NOT_RUNNING = \"SESSION_NOT_RUNNING\",\n REQUEST_NOT_FOUND = \"REQUEST_NOT_FOUND\",\n TIMEOUT = \"TIMEOUT\",\n CANCELLED = \"CANCELLED\",\n APP_SERVER_START_FAILED = \"APP_SERVER_START_FAILED\",\n THREAD_FORK_RESUME_FAILED = \"THREAD_FORK_RESUME_FAILED\",\n PROTOCOL_PARSE_ERROR = \"PROTOCOL_PARSE_ERROR\",\n WRITE_QUEUE_DROPPED = \"WRITE_QUEUE_DROPPED\",\n EXEC_NOT_SUPPORTED = \"EXEC_NOT_SUPPORTED\",\n INTERNAL = \"INTERNAL\",\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\nexport const DEFAULT_EFFORT_LEVEL: EffortLevel = \"low\";\n/**\n * Minimum recommended polling interval (ms) when session status is \"running\".\n * MCP callers should treat this as a floor and can wait longer for larger tasks.\n */\nexport const DEFAULT_POLL_INTERVAL = 120_000;\n/**\n * Polling interval (ms) while waiting for approval/user-input actions.\n * Kept short so callers can unblock pending actions before approval timeout.\n */\nexport const WAITING_APPROVAL_POLL_INTERVAL = 1000;\n/** Public codex_check default for action=\"poll\" when maxEvents is omitted. */\nexport const POLL_DEFAULT_MAX_EVENTS = 1;\n/** Public codex_check lower bound for action=\"poll\" to avoid no-op loops. */\nexport const POLL_MIN_MAX_EVENTS = 1;\n/** Public codex_check default for action=\"respond_*\" when maxEvents is omitted. */\nexport const RESPOND_DEFAULT_MAX_EVENTS = 0;\n/**\n * Internal SessionManager fallback for direct poll helpers.\n * Not used as codex_check external default.\n */\nexport const DEFAULT_MAX_EVENTS = 200;\nexport const DEFAULT_EVENT_BUFFER_SIZE = 1000;\nexport const DEFAULT_EVENT_BUFFER_HARD_SIZE = 2000;\nexport const DEFAULT_APPROVAL_TIMEOUT_MS = 60_000;\nexport const DEFAULT_IDLE_CLEANUP_MS = 30 * 60 * 1000;\nexport const DEFAULT_RUNNING_CLEANUP_MS = 4 * 60 * 60 * 1000;\nexport const DEFAULT_TERMINAL_CLEANUP_MS = 5 * 60 * 1000;\nexport const CLEANUP_INTERVAL_MS = 60_000;\n","/**\n * cwd resolution + validation helpers.\n *\n * - Resolves relative paths against a provided base (not process.cwd()).\n * - Ensures the resolved path exists and is a directory.\n */\nimport { existsSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { ErrorCode } from \"../types.js\";\n\nexport function resolveAndValidateCwd(inputCwd: string | undefined, baseCwd: string): string {\n const candidate = inputCwd ?? baseCwd;\n const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(baseCwd, candidate);\n\n if (!existsSync(resolved)) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cwd does not exist: ${resolved}`);\n }\n\n try {\n const stat = statSync(resolved);\n if (!stat.isDirectory()) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cwd is not a directory: ${resolved}`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes(`Error [${ErrorCode.INVALID_ARGUMENT}]`)) {\n throw err;\n }\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cannot access cwd: ${resolved}`);\n }\n\n return resolved;\n}\n","/**\n * Redaction helpers for user-facing text.\n *\n * Goal: avoid leaking full local file paths in errors/events (spawn failures often include them).\n */\n\nexport function redactPaths(message: string): string {\n const uncPath = /(^|[\\s'\"(])\\\\\\\\[^\\s\\\\/:]+\\\\[^\\s:]+(?:\\\\[^\\s:]+)*/g;\n const windowsPath = /\\b[A-Za-z]:\\\\[^\\s:]+/g;\n const posixPath = /(^|[\\s'\"(])\\/[^\\s:'\")]+/g;\n return message\n .replace(uncPath, (_m, prefix: string) => `${prefix}<path>`)\n .replace(windowsPath, \"<path>\")\n .replace(posixPath, (_m, prefix: string) => `${prefix}<path>`);\n}\n","/**\n * File path resolution + validation helpers.\n */\nimport { existsSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { ErrorCode } from \"../types.js\";\n\nexport function resolveAndValidateFilePath(\n inputPath: string,\n baseDir: string,\n label = \"path\"\n): string {\n const resolved = path.isAbsolute(inputPath) ? inputPath : path.resolve(baseDir, inputPath);\n\n if (!existsSync(resolved)) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: ${label} does not exist: ${resolved}`);\n }\n\n try {\n const stat = statSync(resolved);\n if (!stat.isFile()) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: ${label} is not a file: ${resolved}`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes(`Error [${ErrorCode.INVALID_ARGUMENT}]`)) {\n throw err;\n }\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cannot access ${label}: ${resolved}`);\n }\n\n return resolved;\n}\n","/**\n * Configuration helpers for codex-mcp.\n */\nimport type { AppServerSpawnOptions } from \"../app-server/lifecycle.js\";\nimport type {\n ApprovalPolicy,\n EffortLevel,\n Personality,\n SandboxMode,\n SummaryMode,\n} from \"../types.js\";\n\nexport interface CodexToolParams {\n prompt: string;\n cwd?: string;\n model?: string;\n profile?: string;\n approvalPolicy: ApprovalPolicy;\n sandbox: SandboxMode;\n effort?: EffortLevel;\n advanced?: {\n baseInstructions?: string;\n developerInstructions?: string;\n personality?: Personality;\n summary?: SummaryMode;\n config?: Record<string, unknown>;\n ephemeral?: boolean;\n outputSchema?: Record<string, unknown>;\n images?: string[];\n approvalTimeoutMs?: number;\n };\n}\n\nexport function extractSpawnOptions(params: CodexToolParams): AppServerSpawnOptions {\n return {\n profile: params.profile,\n model: params.model,\n approvalPolicy: params.approvalPolicy,\n sandbox: params.sandbox,\n config: params.advanced?.config,\n };\n}\n","/**\n * codex tool — start a new Codex agent session.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport { DEFAULT_EFFORT_LEVEL, type SessionStartResult } from \"../types.js\";\nimport type { CodexToolParams } from \"../utils/config.js\";\nimport { extractSpawnOptions } from \"../utils/config.js\";\nimport { resolveAndValidateCwd } from \"../utils/cwd.js\";\n\nexport async function executeCodex(\n args: CodexToolParams,\n sessionManager: SessionManager,\n serverCwd: string\n): Promise<SessionStartResult> {\n const cwd = resolveAndValidateCwd(args.cwd, serverCwd);\n const spawnOpts = extractSpawnOptions(args);\n const effort = args.effort ?? DEFAULT_EFFORT_LEVEL;\n\n return sessionManager.createSession(args.prompt, cwd, spawnOpts, effort, args.advanced);\n}\n","/**\n * codex_reply tool — continue an existing session.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport type {\n ApprovalPolicy,\n EffortLevel,\n Personality,\n SandboxMode,\n SessionStartResult,\n SummaryMode,\n} from \"../types.js\";\n\nexport interface CodexReplyParams {\n sessionId: string;\n prompt: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n effort?: EffortLevel;\n summary?: SummaryMode;\n personality?: Personality;\n sandbox?: SandboxMode;\n cwd?: string;\n outputSchema?: Record<string, unknown>;\n}\n\nexport async function executeCodexReply(\n args: CodexReplyParams,\n sessionManager: SessionManager\n): Promise<SessionStartResult> {\n return sessionManager.replyToSession(args.sessionId, args.prompt, {\n model: args.model,\n approvalPolicy: args.approvalPolicy,\n effort: args.effort,\n summary: args.summary,\n personality: args.personality,\n sandbox: args.sandbox,\n cwd: args.cwd,\n outputSchema: args.outputSchema,\n });\n}\n","/**\n * codex_session tool — manage sessions (list/get/cancel/interrupt/fork/clean_background_terminals).\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport { ErrorCode, type SessionAction } from \"../types.js\";\n\nexport interface CodexSessionParams {\n action: SessionAction;\n sessionId?: string;\n includeSensitive?: boolean;\n}\n\nexport async function executeCodexSession(\n args: CodexSessionParams,\n sessionManager: SessionManager\n): Promise<unknown> {\n switch (args.action) {\n case \"list\":\n return { sessions: sessionManager.listSessions() };\n\n case \"get\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'get'`,\n isError: true,\n };\n }\n return sessionManager.getSession(args.sessionId, args.includeSensitive);\n\n case \"cancel\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'cancel'`,\n isError: true,\n };\n }\n await sessionManager.cancelSession(args.sessionId);\n return { success: true, message: `Session ${args.sessionId} cancelled` };\n\n case \"interrupt\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'interrupt'`,\n isError: true,\n };\n }\n await sessionManager.interruptSession(args.sessionId);\n return { success: true, message: `Session ${args.sessionId} interrupted` };\n\n case \"fork\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'fork'`,\n isError: true,\n };\n }\n return await sessionManager.forkSession(args.sessionId);\n\n case \"clean_background_terminals\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'clean_background_terminals'`,\n isError: true,\n };\n }\n await sessionManager.cleanBackgroundTerminals(args.sessionId);\n return {\n success: true,\n message: `Background terminals cleaned for session ${args.sessionId}`,\n };\n\n default:\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown action '${args.action}'`,\n isError: true,\n };\n }\n}\n","/**\n * codex_check tool — poll events + respond to approvals/user input.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport {\n ALL_DECISIONS,\n ErrorCode,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n type NetworkPolicyAmendment,\n type ApprovalDecision,\n type CheckAction,\n type CheckResult,\n type PollOptions,\n type ResponseMode,\n} from \"../types.js\";\n\nexport interface CodexCheckParams {\n action: CheckAction;\n sessionId: string;\n // poll params\n cursor?: number;\n maxEvents?: number;\n // respond_permission params\n requestId?: string;\n decision?: ApprovalDecision;\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n denyMessage?: string;\n // respond_user_input params\n answers?: Record<string, { answers: string[] }>;\n responseMode?: ResponseMode;\n pollOptions?: PollOptions;\n}\n\nexport function executeCodexCheck(\n args: CodexCheckParams,\n sessionManager: SessionManager\n): CheckResult | { error: string; isError: true } {\n const responseMode = args.responseMode ?? \"minimal\";\n const pollOptions = args.pollOptions;\n\n switch (args.action) {\n case \"poll\": {\n if (\n args.requestId !== undefined ||\n args.decision !== undefined ||\n args.execpolicy_amendment !== undefined ||\n args.network_policy_amendment !== undefined ||\n args.denyMessage !== undefined ||\n args.answers !== undefined\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId/decision/execpolicy_amendment/network_policy_amendment/denyMessage/answers are only valid for respond_* actions`,\n isError: true,\n };\n }\n // Default to a single incremental event for lightweight polling.\n // Polling with maxEvents=0 can cause no-op loops in some clients, so\n // enforce a minimum of 1 for poll.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(POLL_MIN_MAX_EVENTS, Math.floor(args.maxEvents))\n : POLL_DEFAULT_MAX_EVENTS;\n return sessionManager.pollEvents(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n });\n }\n\n case \"respond_permission\": {\n if (!args.requestId || !args.decision) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId and decision required for respond_permission`,\n isError: true,\n };\n }\n if (args.answers !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: answers is only valid for respond_user_input`,\n isError: true,\n };\n }\n if (args.decision === \"acceptWithExecpolicyAmendment\") {\n if (!args.execpolicy_amendment || args.execpolicy_amendment.length === 0) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`,\n isError: true,\n };\n }\n } else if (args.execpolicy_amendment !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment is only valid with decision='acceptWithExecpolicyAmendment'`,\n isError: true,\n };\n }\n\n if (args.decision === \"applyNetworkPolicyAmendment\") {\n if (!args.network_policy_amendment) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`,\n isError: true,\n };\n }\n if (\n args.network_policy_amendment.action !== \"allow\" &&\n args.network_policy_amendment.action !== \"deny\"\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.action must be 'allow' or 'deny'`,\n isError: true,\n };\n }\n if (!args.network_policy_amendment.host) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.host required for applyNetworkPolicyAmendment`,\n isError: true,\n };\n }\n } else if (args.network_policy_amendment !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment is only valid with decision='applyNetworkPolicyAmendment'`,\n isError: true,\n };\n }\n if (!ALL_DECISIONS.includes(args.decision)) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown decision '${args.decision}'`,\n isError: true,\n };\n }\n try {\n sessionManager.resolveApproval(args.sessionId, args.requestId, args.decision, {\n execpolicy_amendment: args.execpolicy_amendment,\n network_policy_amendment: args.network_policy_amendment,\n denyMessage: args.denyMessage,\n });\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { error: message, isError: true };\n }\n // For respond_* actions:\n // - use monotonic cursor progression to avoid replay when some MCP hosts\n // send stale/default cursor values.\n // - default to compact ACK (maxEvents=0) to avoid returning large event\n // payloads on approval/user-input responses.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(0, Math.floor(args.maxEvents))\n : RESPOND_DEFAULT_MAX_EVENTS;\n return sessionManager.pollEventsMonotonic(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n });\n }\n\n case \"respond_user_input\": {\n if (!args.requestId || !args.answers) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId and answers required for respond_user_input`,\n isError: true,\n };\n }\n if (\n args.decision !== undefined ||\n args.execpolicy_amendment !== undefined ||\n args.network_policy_amendment !== undefined ||\n args.denyMessage !== undefined\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: decision/execpolicy_amendment/network_policy_amendment/denyMessage are only valid for respond_permission`,\n isError: true,\n };\n }\n try {\n sessionManager.resolveUserInput(args.sessionId, args.requestId, args.answers);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { error: message, isError: true };\n }\n // For respond_* actions:\n // - use monotonic cursor progression to avoid replay when some MCP hosts\n // send stale/default cursor values.\n // - default to compact ACK (maxEvents=0) to avoid returning large event\n // payloads on approval/user-input responses.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(0, Math.floor(args.maxEvents))\n : RESPOND_DEFAULT_MAX_EVENTS;\n return sessionManager.pollEventsMonotonic(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n });\n }\n\n default:\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown action '${args.action}'`,\n isError: true,\n };\n }\n}\n","import { spawnSync } from \"child_process\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { SessionManager } from \"../session/manager.js\";\nimport {\n APPROVAL_POLICIES,\n SANDBOX_MODES,\n EFFORT_LEVELS,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n DEFAULT_IDLE_CLEANUP_MS,\n DEFAULT_RUNNING_CLEANUP_MS,\n DEFAULT_TERMINAL_CLEANUP_MS,\n ErrorCode,\n} from \"../types.js\";\nimport { resolveStdioMode } from \"../utils/stdio-guard.js\";\n\nconst RESOURCE_SCHEME = \"codex-mcp\";\n\nexport const RESOURCE_URIS = {\n serverInfo: `${RESOURCE_SCHEME}:///server-info`,\n compatReport: `${RESOURCE_SCHEME}:///compat-report`,\n config: `${RESOURCE_SCHEME}:///config`,\n gotchas: `${RESOURCE_SCHEME}:///gotchas`,\n quickstart: `${RESOURCE_SCHEME}:///quickstart`,\n errors: `${RESOURCE_SCHEME}:///errors`,\n} as const;\n\ntype RuntimeMetadataProvider = Pick<\n SessionManager,\n \"getActiveSessionCount\" | \"getObservedDefaultModel\"\n>;\n\ninterface ResourceCatalogEntry {\n key: keyof typeof RESOURCE_URIS;\n name: string;\n title: string;\n description: string;\n mimeType: string;\n}\n\nconst RESOURCE_CATALOG: ResourceCatalogEntry[] = [\n {\n key: \"serverInfo\",\n name: \"server_info\",\n title: \"Server Info\",\n description: \"Server metadata and runtime capabilities\",\n mimeType: \"application/json\",\n },\n {\n key: \"compatReport\",\n name: \"compat_report\",\n title: \"Compat Report\",\n description: \"Cross-backend compatibility capability report\",\n mimeType: \"application/json\",\n },\n {\n key: \"config\",\n name: \"config\",\n title: \"Config Guide\",\n description: \"Parameter guide and config.toml mapping\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"gotchas\",\n name: \"gotchas\",\n title: \"Gotchas\",\n description: \"Practical limits and common issues\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"quickstart\",\n name: \"quickstart\",\n title: \"Quickstart\",\n description: \"Minimal end-to-end workflow\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"errors\",\n name: \"errors\",\n title: \"Errors\",\n description: \"Error code reference and recovery hints\",\n mimeType: \"text/markdown\",\n },\n];\n\nconst ERROR_CODE_HINTS: Record<ErrorCode, string> = {\n [ErrorCode.INVALID_ARGUMENT]: \"Input shape/value mismatch. Fix payload and retry.\",\n [ErrorCode.SESSION_NOT_FOUND]: \"Unknown sessionId or already cleaned up.\",\n [ErrorCode.SESSION_BUSY]: \"Session is running or waiting approval. Poll until idle/error.\",\n [ErrorCode.SESSION_NOT_RUNNING]: \"Action requires running/waiting_approval session.\",\n [ErrorCode.REQUEST_NOT_FOUND]: \"requestId was resolved, stale, or never existed.\",\n [ErrorCode.TIMEOUT]: \"Operation timed out. Retry or use a longer timeout where supported.\",\n [ErrorCode.CANCELLED]: \"Session was cancelled and cannot be resumed.\",\n [ErrorCode.APP_SERVER_START_FAILED]: \"codex app-server failed to boot. Check CLI install/path.\",\n [ErrorCode.THREAD_FORK_RESUME_FAILED]:\n \"Forked thread could not resume in new process. Retry fork from current source session.\",\n [ErrorCode.PROTOCOL_PARSE_ERROR]:\n \"Non-JSON or malformed app-server line. Check shell/profile noise and transport health.\",\n [ErrorCode.WRITE_QUEUE_DROPPED]:\n \"stdin backpressure overflow. Reduce burst size and re-run in smaller turns.\",\n [ErrorCode.EXEC_NOT_SUPPORTED]:\n \"Operation not supported in exec mode. Features like threadFork and threadResume require app-server mode.\",\n [ErrorCode.INTERNAL]: \"Unexpected server-side failure. Inspect logs and retry safely.\",\n};\n\nfunction asTextResource(uri: URL, text: string, mimeType: string): ReadResourceResult {\n return {\n contents: [\n {\n uri: uri.toString(),\n text,\n mimeType,\n },\n ],\n };\n}\n\nfunction detectCodexCliVersion(timeoutMs = 1500): string | null {\n try {\n const run = spawnSync(\"codex\", [\"--version\"], {\n encoding: \"utf8\",\n timeout: timeoutMs,\n windowsHide: true,\n });\n const combined = `${run.stdout ?? \"\"}\\n${run.stderr ?? \"\"}`.trim();\n if (!combined) return null;\n const versionToken = combined.match(/v?\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?/);\n if (!versionToken) return combined.split(/\\s+/)[0] ?? null;\n return versionToken[0].replace(/^v/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction msToMinutes(ms: number): number {\n return Math.floor(ms / 60_000);\n}\n\nfunction buildConfigGuideText(): string {\n return [\n \"## Top-level parameters (`codex`)\",\n \"\",\n \"- Required: `prompt`, `approvalPolicy`, `sandbox`.\",\n \"- Optional: `effort` (default `low`), `cwd` (default server cwd), `model` (default config.toml), `profile` (default CLI profile), `advanced`.\",\n \"- Prefer passing `cwd` explicitly to avoid accidental server-cwd execution.\",\n \"\",\n \"## `advanced.*` guide\",\n \"\",\n \"- `advanced.baseInstructions`: replace default system instructions for this session (default: unchanged).\",\n \"- `advanced.developerInstructions`: append extra developer instructions (default: none).\",\n \"- `advanced.personality`: optional personality preset (default: config.toml).\",\n \"- `advanced.summary`: summary verbosity preset for turn output (default: config.toml).\",\n \"- `advanced.ephemeral`: do not persist thread state remotely (default `false`).\",\n \"- `advanced.images`: local image file paths on the same host as codex-mcp (default: none).\",\n `- \\`advanced.approvalTimeoutMs\\`: auto-decline timeout for approval/user-input requests (default \\`${DEFAULT_APPROVAL_TIMEOUT_MS}\\` ms).`,\n \"- `advanced.outputSchema`: JSON Schema for structured output from `codex` turns (default: none).\",\n \"\",\n \"## `advanced.config` mapping\",\n \"\",\n \"Forwarded as `-c key=value` flags to `codex app-server`.\",\n \"Primitives use `String(value)`; objects/arrays use `JSON.stringify(value)`.\",\n \"\",\n \"Prefer dedicated top-level params when available:\",\n \"\",\n \"- `codex.model` -> `-c model=...`\",\n \"- `codex.approvalPolicy` -> `-c approval_policy=...`\",\n \"- `codex.sandbox` -> `-c sandbox_mode=...`\",\n \"- `codex.effort` -> turn-level reasoning effort (do not encode in `advanced.config`)\",\n \"- `codex.profile` -> `-p ...`\",\n \"\",\n \"## `codex_reply` differences\",\n \"\",\n \"- `codex_reply.outputSchema` is top-level.\",\n \"- `codex.outputSchema` lives under `advanced.outputSchema`.\",\n \"- `codex_reply` can override `model`, `approvalPolicy`, `sandbox`, `effort`, `summary`, `personality`, and `cwd`.\",\n \"- `codex_reply` only works when session state is `idle` or `error`; otherwise returns `SESSION_BUSY`.\",\n \"- All `codex_reply` override fields default to no override when omitted.\",\n \"\",\n \"## Override persistence (`codex_reply`)\",\n \"\",\n \"- `model`, `approvalPolicy`, `sandbox`, and `cwd` update in-memory session defaults for later turns.\",\n \"- `effort`, `summary`, `personality`, and `outputSchema` apply to the submitted turn payload.\",\n \"\",\n \"## Version compatibility note\",\n \"\",\n \"Available `advanced.config` keys depend on installed Codex CLI version.\",\n \"To inspect your local CLI version, read `codex-mcp:///server-info` (`codexCliVersion`).\",\n \"\",\n \"## Other tool defaults (quick reference)\",\n \"\",\n \"- `codex_session.includeSensitive`: default `false`.\",\n `- \\`codex_check.poll.maxEvents\\`: default \\`${POLL_DEFAULT_MAX_EVENTS}\\` (minimum \\`${POLL_MIN_MAX_EVENTS}\\`).`,\n `- \\`codex_check.respond_*.maxEvents\\`: default \\`${RESPOND_DEFAULT_MAX_EVENTS}\\`.`,\n \"- `codex_check.responseMode`: default `minimal` (`minimal` / `delta_compact` / `full`).\",\n \"- `codex_check.pollOptions.includeEvents`: default `true`.\",\n \"- `codex_check.pollOptions.includeActions`: default `true`.\",\n \"- `codex_check.pollOptions.includeResult`: default `true`.\",\n \"- `codex_check.pollOptions.maxBytes`: default unlimited.\",\n \"- `codex_check.cursor`: default is session last consumed cursor when omitted.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildGotchasText(): string {\n return [\n \"## Polling and cursors\",\n \"\",\n '- Sessions are async. Poll `codex_check(action=\"poll\")` until status is `idle`/`error`/`cancelled`.',\n \"- Store `nextCursor` and pass it back to avoid replay.\",\n `- Poll default is \\`maxEvents=${POLL_DEFAULT_MAX_EVENTS}\\` (authoritative: tool schema / constants).`,\n `- Poll enforces minimum \\`maxEvents=${POLL_MIN_MAX_EVENTS}\\`; sending \\`0\\` is normalized to \\`${POLL_MIN_MAX_EVENTS}\\`.`,\n `- \\`respond_permission\\` and \\`respond_user_input\\` default to compact ACK with \\`maxEvents=${RESPOND_DEFAULT_MAX_EVENTS}\\`.`,\n \"- Default response mode is `minimal`; use `full` if you need full raw event payloads.\",\n \"- respond_* uses monotonic cursor handling: `max(cursor, sessionLastCursor)`.\",\n \"- If `cursorResetTo` is present, your cursor is stale (old events were evicted); restart from that value.\",\n \"- **Poll frequency guidance**: Adapt poll interval to task complexity and previous poll results. For `running` sessions, start at 2 minutes and increase for long tasks. Only poll frequently (~1s) when `waiting_approval`. Do NOT high-frequency poll — it wastes tokens and provides no benefit.\",\n \"\",\n \"## Approval behavior\",\n \"\",\n `- Pending approvals/user-input auto-decline after \\`approvalTimeoutMs\\` (default ${DEFAULT_APPROVAL_TIMEOUT_MS} ms).`,\n \"- `untrusted` behavior is enforced by Codex CLI backend and may auto-allow some low-risk commands.\",\n \"- Do not assume every read-only command will always require approval across CLI versions.\",\n `- **Timeout vs polling conflict**: The recommended polling interval for \\`running\\` status is >=120 seconds, but the default approval timeout is ${DEFAULT_APPROVAL_TIMEOUT_MS / 1000} seconds. If a session transitions to \\`waiting_approval\\` between polls, the approval will auto-decline before the client can respond. Set \\`advanced.approvalTimeoutMs\\` to at least 300000 (5 minutes) when using \\`untrusted\\` or \\`on-request\\` policies.`,\n \"\",\n \"## Event model\",\n \"\",\n \"- Top-level `events[].type` is one of: `output`, `progress`, `approval_request`, `approval_result`, `result`, `error`.\",\n \"- Fine-grained stream semantics are in `events[].data.method` (for example command output delta, reasoning delta, turn updates).\",\n '- Retryable interruptions surface as `progress` with `method=\"codex-mcp/reconnect\"` and include retry fields.',\n \"- During reconnect/retry, continue polling normally; if retries stop (`willRetry=false`), session transitions to error path.\",\n \"\",\n \"## Windows shell/profile issues\",\n \"\",\n \"- On Windows wrappers, prefer `pwsh -NoProfile` to avoid profile/banner stdout noise.\",\n \"- Profile noise can affect both MCP handshake and agent-internal command turns.\",\n \"- For mojibake, enforce UTF-8 shell output (`chcp 65001`, `$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()`).\",\n \"- Prefer host-native absolute paths for `cwd` and file args (Windows example: `D:\\\\\\\\Lab\\\\\\\\codex-mcp`).\",\n \"\",\n \"## Lifecycle and cleanup\",\n \"\",\n `- Idle sessions are auto-cleaned after ${msToMinutes(DEFAULT_IDLE_CLEANUP_MS)} minutes.`,\n `- Running/waiting sessions are auto-cleaned after ${msToMinutes(DEFAULT_RUNNING_CLEANUP_MS)} minutes.`,\n `- Error/cancelled sessions are retained for about ${msToMinutes(DEFAULT_TERMINAL_CLEANUP_MS)} minutes, then removed.`,\n \"- Session state is in-memory. Restarting codex-mcp drops all existing sessions.\",\n \"\",\n \"## Capacity\",\n \"\",\n \"- codex-mcp does not hard-code a strict concurrent-session cap.\",\n \"- Practical limit depends on machine resources and child-process load.\",\n \"\",\n \"## Exec fallback mode\",\n \"\",\n \"- When the codex binary does not support `app-server`, codex-mcp falls back to `exec` mode (`codex exec --json`).\",\n \"- Check `codex-mcp:///server-info` `clientMode` field to detect which mode is active.\",\n \"- **Exec mode supports multi-turn**: first turn uses `codex exec`, subsequent turns use `codex exec resume <threadId>` for context continuity.\",\n \"- **Exec mode limitations**: no approval/user-input interactions, `threadFork`/`threadResume` throw `EXEC_NOT_SUPPORTED`. `sandbox`/`profile`/`cwd`/`outputSchema` overrides only apply on the first turn (exec resume does not support `-s`/`-p`/`-C`/`--output-schema`).\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildQuickstartText(): string {\n return [\n \"## Minimal flow\",\n \"\",\n \"1. Start session (`codex`)\",\n \"\",\n \"```json\",\n \"{\",\n ' \"prompt\": \"List files and summarize repository purpose.\",',\n ' \"approvalPolicy\": \"on-request\",',\n ' \"sandbox\": \"workspace-write\",',\n ' \"effort\": \"low\",',\n ' \"cwd\": \"D:\\\\\\\\Lab\\\\\\\\codex-mcp\"',\n \"}\",\n \"```\",\n \"\",\n \"Typical start result:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"sessionId\": \"sess_abc123\",',\n ' \"threadId\": \"thread_xyz\",',\n ' \"status\": \"running\",',\n ' \"pollInterval\": 120000',\n \"}\",\n \"```\",\n \"\",\n \"2. Poll incrementally (`codex_check`)\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"poll\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"cursor\": 0,',\n ' \"maxEvents\": 10',\n \"}\",\n \"```\",\n \"\",\n \"- Use `pollInterval` as a minimum delay: `running` >=120000ms (and usually longer for big tasks).\",\n \"- `waiting_approval` is the exception: poll/answer around 1000ms to avoid timeout.\",\n `- When using \\`untrusted\\` or \\`on-request\\` policies, set \\`advanced.approvalTimeoutMs\\` to at least 300000 to prevent approvals from expiring between polling intervals.`,\n \"\",\n \"3. If `actions[]` contains an approval request, respond:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"respond_permission\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"requestId\": \"req_123\",',\n ' \"decision\": \"acceptForSession\"',\n \"}\",\n \"```\",\n \"\",\n \"4. If `actions[]` contains a user-input request, respond:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"respond_user_input\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"requestId\": \"req_456\",',\n ' \"answers\": {',\n ' \"question-id\": {',\n ' \"answers\": [\"Option A\"]',\n \" }\",\n \" }\",\n \"}\",\n \"```\",\n \"\",\n \"5. Continue polling until terminal status (`idle`, `error`, or `cancelled`), respecting the >=2 minute interval while `running`.\",\n \"\",\n \"## Cursor notes\",\n \"\",\n \"- Omit `cursor` to continue from session last consumed cursor.\",\n `- Omit \\`maxEvents\\`: defaults are poll=${POLL_DEFAULT_MAX_EVENTS}, respond_*=${RESPOND_DEFAULT_MAX_EVENTS}.`,\n \"- Omit `responseMode`: default is `minimal`.\",\n \"- Use returned `nextCursor` for the next call.\",\n \"- If `cursorResetTo` appears, reset to that value and continue.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildErrorsText(): string {\n const lines: string[] = [\n \"## Error format\",\n \"\",\n \"Tool failures use: `Error [CODE]: message`\",\n \"\",\n \"## Codes\",\n \"\",\n ];\n\n for (const code of Object.values(ErrorCode)) {\n lines.push(`- \\`${code}\\`: ${ERROR_CODE_HINTS[code]}`);\n }\n\n lines.push(\"\");\n lines.push(\"## Recovery basics\");\n lines.push(\"\");\n lines.push(\"- `INVALID_ARGUMENT`: fix payload fields/enums and retry.\");\n lines.push(\"- `SESSION_BUSY`: poll until terminal/idle before issuing incompatible action.\");\n lines.push(\"- `REQUEST_NOT_FOUND`: re-poll and use latest `actions[].requestId`.\");\n lines.push(\"- `PROTOCOL_PARSE_ERROR`: remove shell/profile stdout noise and restart session.\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nfunction buildCompatReport(\n deps: { version: string; sessionManager: RuntimeMetadataProvider },\n codexCliVersion: string | null\n): string {\n const runtimeWarnings: string[] = [];\n if (!codexCliVersion) {\n runtimeWarnings.push(\"Unable to detect local codex CLI version from PATH.\");\n }\n return JSON.stringify(\n {\n schemaVersion: \"1.0.0\",\n features: {\n respondPermission: true,\n respondApprovalAlias: false,\n respondUserInput: true,\n sessionInterrupt: true,\n responseModeMinimal: true,\n responseModeDeltaCompact: true,\n responseModeFull: true,\n pollOptionsBase: true,\n maxBytesTruncation: true,\n compatWarnings: true,\n diskResume: false,\n dynamicTools: false,\n toolPermissionControl: false,\n },\n recommendedSettings: {\n codexCheck: {\n responseMode: \"minimal\",\n pollOptions: {\n includeEvents: true,\n includeActions: true,\n includeResult: true,\n },\n },\n },\n toolCounts: {\n core: 4,\n },\n runtimeWarnings,\n detectedMismatches: [],\n runtime: {\n codexMcpVersion: deps.version,\n codexCliVersion,\n activeSessions: deps.sessionManager.getActiveSessionCount(),\n },\n },\n null,\n 2\n );\n}\n\nexport function registerResources(\n server: Pick<McpServer, \"registerResource\">,\n deps: { version: string; sessionManager: RuntimeMetadataProvider; clientMode?: string }\n): void {\n let codexCliVersionCache: string | null | undefined;\n const getCodexCliVersion = (): string | null => {\n if (codexCliVersionCache !== undefined) return codexCliVersionCache;\n codexCliVersionCache = detectCodexCliVersion();\n return codexCliVersionCache;\n };\n\n const byKey = new Map(RESOURCE_CATALOG.map((entry) => [entry.key, entry]));\n\n const serverInfoMeta = byKey.get(\"serverInfo\")!;\n const serverInfoUri = new URL(RESOURCE_URIS.serverInfo);\n server.registerResource(\n serverInfoMeta.name,\n serverInfoUri.toString(),\n {\n title: serverInfoMeta.title,\n description: serverInfoMeta.description,\n mimeType: serverInfoMeta.mimeType,\n },\n () => {\n const observedModel = deps.sessionManager.getObservedDefaultModel();\n return asTextResource(\n serverInfoUri,\n JSON.stringify(\n {\n name: \"codex-mcp\",\n version: deps.version,\n codexCliVersion: getCodexCliVersion(),\n clientMode: deps.clientMode ?? \"app-server\",\n node: process.version,\n platform: process.platform,\n arch: process.arch,\n stdioMode: resolveStdioMode().mode,\n supportedApprovalPolicies: APPROVAL_POLICIES,\n supportedSandboxModes: SANDBOX_MODES,\n supportedEffortLevels: EFFORT_LEVELS,\n activeSessions: deps.sessionManager.getActiveSessionCount(),\n defaultModel: observedModel,\n defaultModelSource: observedModel ? \"session-default\" : \"unknown\",\n resources: RESOURCE_CATALOG.map((entry) => ({\n uri: RESOURCE_URIS[entry.key],\n title: entry.title,\n mimeType: entry.mimeType,\n description: entry.description,\n })),\n },\n null,\n 2\n ),\n \"application/json\"\n );\n }\n );\n\n const compatReportMeta = byKey.get(\"compatReport\")!;\n const compatReportUri = new URL(RESOURCE_URIS.compatReport);\n server.registerResource(\n compatReportMeta.name,\n compatReportUri.toString(),\n {\n title: compatReportMeta.title,\n description: compatReportMeta.description,\n mimeType: compatReportMeta.mimeType,\n },\n () =>\n asTextResource(\n compatReportUri,\n buildCompatReport(deps, getCodexCliVersion()),\n \"application/json\"\n )\n );\n\n const configMeta = byKey.get(\"config\")!;\n const configUri = new URL(RESOURCE_URIS.config);\n server.registerResource(\n configMeta.name,\n configUri.toString(),\n {\n title: configMeta.title,\n description: configMeta.description,\n mimeType: configMeta.mimeType,\n },\n () => asTextResource(configUri, buildConfigGuideText(), \"text/markdown\")\n );\n\n const gotchasMeta = byKey.get(\"gotchas\")!;\n const gotchasUri = new URL(RESOURCE_URIS.gotchas);\n server.registerResource(\n gotchasMeta.name,\n gotchasUri.toString(),\n {\n title: gotchasMeta.title,\n description: gotchasMeta.description,\n mimeType: gotchasMeta.mimeType,\n },\n () => asTextResource(gotchasUri, buildGotchasText(), \"text/markdown\")\n );\n\n const quickstartMeta = byKey.get(\"quickstart\")!;\n const quickstartUri = new URL(RESOURCE_URIS.quickstart);\n server.registerResource(\n quickstartMeta.name,\n quickstartUri.toString(),\n {\n title: quickstartMeta.title,\n description: quickstartMeta.description,\n mimeType: quickstartMeta.mimeType,\n },\n () => asTextResource(quickstartUri, buildQuickstartText(), \"text/markdown\")\n );\n\n const errorsMeta = byKey.get(\"errors\")!;\n const errorsUri = new URL(RESOURCE_URIS.errors);\n server.registerResource(\n errorsMeta.name,\n errorsUri.toString(),\n {\n title: errorsMeta.title,\n description: errorsMeta.description,\n mimeType: errorsMeta.mimeType,\n },\n () => asTextResource(errorsUri, buildErrorsText(), \"text/markdown\")\n );\n}\n","/**\n * STDIO preflight guard.\n *\n * Purpose:\n * - Detect elevated risk of stdout contamination before MCP stdio handshake.\n * - Support caller-selected behavior via CODEX_MCP_STDIO_MODE.\n */\n\nexport const STDIO_MODES = [\"auto\", \"strict\", \"off\"] as const;\nexport type StdioMode = (typeof STDIO_MODES)[number];\n\nexport interface StdioModeResolution {\n mode: StdioMode;\n source: \"default\" | \"env\" | \"env_invalid\";\n invalidRaw?: string;\n}\n\nexport interface StdioPreflightOptions {\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n stdinIsTTY?: boolean;\n stdoutIsTTY?: boolean;\n}\n\nexport interface StdioPreflightResult {\n mode: StdioMode;\n modeSource: StdioModeResolution[\"source\"];\n invalidMode?: string;\n riskLevel: \"low\" | \"elevated\";\n riskReasons: string[];\n blockingReasons: string[];\n notes: string[];\n suggestions: string[];\n shouldBlock: boolean;\n}\n\nexport function resolveStdioMode(env: NodeJS.ProcessEnv = process.env): StdioModeResolution {\n const raw = env.CODEX_MCP_STDIO_MODE;\n if (raw === undefined) {\n return { mode: \"auto\", source: \"default\" };\n }\n\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"\") {\n return { mode: \"auto\", source: \"default\" };\n }\n\n if ((STDIO_MODES as readonly string[]).includes(normalized)) {\n return { mode: normalized as StdioMode, source: \"env\" };\n }\n\n return { mode: \"auto\", source: \"env_invalid\", invalidRaw: raw };\n}\n\nexport function runStdioPreflight(opts: StdioPreflightOptions = {}): StdioPreflightResult {\n const platform = opts.platform ?? process.platform;\n const env = opts.env ?? process.env;\n const stdinIsTTY = opts.stdinIsTTY ?? Boolean(process.stdin.isTTY);\n const stdoutIsTTY = opts.stdoutIsTTY ?? Boolean(process.stdout.isTTY);\n\n const modeResolution = resolveStdioMode(env);\n const notes: string[] = [];\n const riskReasons: string[] = [];\n\n if (modeResolution.source === \"env_invalid\" && modeResolution.invalidRaw) {\n notes.push(\n `Invalid CODEX_MCP_STDIO_MODE='${modeResolution.invalidRaw}'. Falling back to 'auto'.`\n );\n }\n\n // In \"off\" mode, guard is intentionally disabled.\n if (modeResolution.mode === \"off\") {\n return {\n mode: modeResolution.mode,\n modeSource: modeResolution.source,\n invalidMode: modeResolution.invalidRaw,\n riskLevel: \"low\",\n riskReasons: [],\n blockingReasons: [],\n notes,\n suggestions: [],\n shouldBlock: false,\n };\n }\n\n const blockingReasons: string[] = [];\n\n if (platform === \"win32\" && looksLikePowerShell(env)) {\n riskReasons.push(\n \"PowerShell environment detected on Windows; shell profiles can print banner text to stdout.\"\n );\n }\n\n if (stdinIsTTY || stdoutIsTTY) {\n const ttyRisk =\n \"STDIO appears attached to a terminal (TTY). MCP clients should launch codex-mcp with piped stdio.\";\n notes.push(ttyRisk);\n riskReasons.push(ttyRisk);\n blockingReasons.push(ttyRisk);\n }\n\n const riskLevel: StdioPreflightResult[\"riskLevel\"] = riskReasons.length > 0 ? \"elevated\" : \"low\";\n const shouldBlock = modeResolution.mode === \"strict\" && blockingReasons.length > 0;\n\n return {\n mode: modeResolution.mode,\n modeSource: modeResolution.source,\n invalidMode: modeResolution.invalidRaw,\n riskLevel,\n riskReasons,\n blockingReasons,\n notes,\n suggestions: riskReasons.length > 0 ? buildFixSuggestions(platform) : [],\n shouldBlock,\n };\n}\n\nfunction looksLikePowerShell(env: NodeJS.ProcessEnv): boolean {\n return Boolean(\n env.POWERSHELL_DISTRIBUTION_CHANNEL ||\n env.PSModulePath ||\n env.PSExecutionPolicyPreference ||\n env.PSModuleAnalysisCachePath\n );\n}\n\nfunction buildFixSuggestions(platform: NodeJS.Platform): string[] {\n const generic = [\n \"Prefer direct MCP config launch: command='npx', args=['-y', '@leo000001/codex-mcp']\",\n \"Keep server stdout strictly JSON-RPC; route diagnostics to stderr only.\",\n \"codex-mcp cannot sanitize shell/profile stdout once emitted before MCP handshake.\",\n ];\n\n if (platform === \"win32\") {\n return [\n 'If shell wrapping is required, use: pwsh -NoProfile -Command \"npx -y @leo000001/codex-mcp\"',\n \"Disable noisy PowerShell profile output (oh-my-posh banners, startup prompts, etc.).\",\n ...generic,\n ];\n }\n\n return generic;\n}\n","/**\n * Detect whether the codex binary supports app-server mode.\n *\n * Falls back to exec mode when app-server is unavailable.\n * Can be overridden via CODEX_MCP_MODE env var.\n */\nimport { spawn } from \"child_process\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\n\nexport type ClientMode = \"app-server\" | \"exec\";\n\nconst DETECTION_TIMEOUT_MS = 5_000;\n\n/**\n * Detect whether the codex binary supports app-server mode.\n *\n * 1. If CODEX_MCP_MODE is set, use it directly.\n * 2. Otherwise probe `<binary> app-server --help` with a timeout.\n */\nexport async function detectClientMode(\n codexCommand: string,\n codexIsPath = false,\n env: NodeJS.ProcessEnv = process.env\n): Promise<ClientMode> {\n const override = env.CODEX_MCP_MODE;\n if (override === \"app-server\" || override === \"exec\") {\n return override;\n }\n\n try {\n const supported = await probeAppServer(codexCommand, codexIsPath, env);\n return supported ? \"app-server\" : \"exec\";\n } catch {\n return \"exec\";\n }\n}\n\n/**\n * Probe whether `<binary> app-server --help` succeeds.\n */\nfunction probeAppServer(\n codexCommand: string,\n codexIsPath: boolean,\n env: NodeJS.ProcessEnv\n): Promise<boolean> {\n return new Promise((resolve) => {\n const invocation = resolveCodexInvocation([\"app-server\", \"--help\"], {\n env,\n codexCommand,\n codexIsPath,\n });\n\n let settled = false;\n const settle = (result: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n\n let stdout = \"\";\n let stderr = \"\";\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env,\n windowsHide: true,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n proc.on(\"error\", () => {\n // ENOENT or other spawn failure\n settle(false);\n });\n\n proc.on(\"exit\", (code) => {\n if (code === 0) {\n settle(true);\n } else {\n // Check if stderr/stdout suggests \"unknown subcommand\"\n const combined = (stdout + stderr).toLowerCase();\n const isUnknown =\n combined.includes(\"unknown\") ||\n combined.includes(\"unrecognized\") ||\n combined.includes(\"not found\") ||\n combined.includes(\"no such subcommand\");\n settle(!isUnknown && combined.includes(\"app-server\"));\n }\n });\n\n const timer = setTimeout(() => {\n try {\n proc.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n settle(false);\n }, DETECTION_TIMEOUT_MS);\n if (timer.unref) timer.unref();\n });\n}\n","/**\n * ExecClient — codex exec --json based client.\n *\n * Fallback for codex variants that don't support app-server.\n * Spawns `codex exec \"<prompt>\" --json --skip-git-repo-check` per turn\n * and transforms JSONL stdout events into the app-server notification format\n * that SessionManager expects.\n */\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { writeFileSync, mkdtempSync } from \"fs\";\nimport { EventEmitter } from \"events\";\nimport { randomUUID } from \"crypto\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { StringDecoder } from \"string_decoder\";\nimport type { ICodexClient } from \"./client-interface.js\";\nimport type { AppServerSpawnOptions } from \"./lifecycle.js\";\nimport {\n type RequestId,\n type InitializeResult,\n type ThreadStartParams,\n type ThreadStartResult,\n type ThreadForkParams,\n type ThreadForkResult,\n type ThreadResumeParams,\n type ThreadResumeResult,\n type ThreadBackgroundTerminalsCleanParams,\n type TurnStartParams,\n type TurnStartResult,\n type TurnInterruptParams,\n type SandboxPolicy,\n Methods,\n} from \"./protocol.js\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\nimport { ErrorCode } from \"../types.js\";\nimport { getDefaultCodexExecutable } from \"../utils/codex-executable.js\";\n\ntype NotificationHandler = (method: string, params: unknown) => void;\ntype ServerRequestHandler = (id: RequestId, method: string, params: unknown) => void;\n\nconst FORCE_KILL_TIMEOUT_MS = 5_000;\n\n/**\n * Convert snake_case item type from exec JSONL to camelCase used by app-server protocol.\n */\nfunction camelCaseItemType(snakeType: string): string {\n return snakeType.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n/**\n * Deep-transform item object: convert `type` field from snake_case to camelCase.\n */\nfunction transformItem(item: Record<string, unknown>): Record<string, unknown> {\n const result = { ...item };\n if (typeof result.type === \"string\") {\n result.type = camelCaseItemType(result.type);\n }\n return result;\n}\n\n/**\n * Detect whether an exec `{\"type\":\"error\"}` event is a transient/retryable error\n * (e.g. \"Reconnecting... n/5\") vs a terminal failure.\n */\nfunction isRetryableError(event: Record<string, unknown>): boolean {\n const msg = typeof event.message === \"string\" ? event.message : \"\";\n return /reconnect/i.test(msg) || /\\d+\\/\\d+/.test(msg);\n}\n\n/**\n * Reverse-map SandboxPolicy object back to sandbox mode string for -s flag.\n */\nfunction sandboxPolicyToMode(policy: SandboxPolicy): string | undefined {\n switch (policy.type) {\n case \"readOnly\":\n return \"read-only\";\n case \"workspaceWrite\":\n return \"workspace-write\";\n case \"dangerFullAccess\":\n return \"danger-full-access\";\n case \"externalSandbox\":\n // externalSandbox has no direct CLI equivalent; log and return undefined\n // so the caller falls back to thread/spawn-level sandbox.\n console.error(\n `[exec-client] SandboxPolicy type \"externalSandbox\" cannot be mapped to exec -s flag; using thread-level sandbox`\n );\n return undefined;\n default:\n return undefined;\n }\n}\n\n/**\n * Map exec JSONL event type (snake_case) to app-server notification method.\n * Covers all events from codex-schema/EventMsg.json that have corresponding\n * app-server notification methods in SessionManager.registerHandlers().\n */\nconst EXEC_EVENT_TO_METHOD: Record<string, string> = {\n // Agent message deltas\n agent_message_delta: Methods.AGENT_MESSAGE_DELTA,\n agent_message_content_delta: Methods.AGENT_MESSAGE_DELTA,\n\n // Command execution\n exec_command_output_delta: Methods.COMMAND_OUTPUT_DELTA,\n command_output_delta: Methods.COMMAND_OUTPUT_DELTA,\n terminal_interaction: Methods.COMMAND_TERMINAL_INTERACTION,\n\n // File changes\n file_change_output_delta: Methods.FILE_CHANGE_OUTPUT_DELTA,\n\n // Reasoning\n reasoning_content_delta: Methods.REASONING_TEXT_DELTA,\n reasoning_raw_content_delta: Methods.REASONING_TEXT_DELTA,\n agent_reasoning_delta: Methods.REASONING_TEXT_DELTA,\n agent_reasoning_raw_content_delta: Methods.REASONING_TEXT_DELTA,\n reasoning_summary_delta: Methods.REASONING_SUMMARY_DELTA,\n agent_reasoning_section_break: Methods.REASONING_SUMMARY_PART_ADDED,\n\n // Plan\n plan_delta: Methods.PLAN_DELTA,\n plan_update: Methods.TURN_PLAN_UPDATED,\n\n // Turn-level\n turn_diff: Methods.TURN_DIFF_UPDATED,\n diff_update: Methods.TURN_DIFF_UPDATED,\n\n // MCP\n mcp_tool_call_begin: Methods.MCP_TOOL_PROGRESS,\n mcp_tool_call_end: Methods.MCP_TOOL_PROGRESS,\n mcp_startup_update: Methods.MCP_TOOL_PROGRESS,\n mcp_startup_complete: Methods.MCP_TOOL_PROGRESS,\n\n // Model routing\n model_reroute: Methods.MODEL_REROUTED,\n\n // Thread/session events\n thread_name_updated: Methods.THREAD_NAME_UPDATED,\n token_count: Methods.THREAD_TOKEN_USAGE_UPDATED,\n session_configured: Methods.SESSION_CONFIGURED,\n\n // Item lifecycle (in case exec emits these outside the dot-notation variants)\n item_started: Methods.ITEM_STARTED,\n item_completed: Methods.ITEM_COMPLETED,\n raw_response_item: Methods.RAW_RESPONSE_ITEM_COMPLETED,\n\n // Stream errors — map to error method so retryable detection can handle it\n stream_error: Methods.ERROR,\n\n // Legacy turn lifecycle (v1 wire format used by older CLIs)\n // These are critical for exec fallback since it targets CLIs without app-server.\n task_started: Methods.TURN_STARTED,\n task_complete: Methods.TURN_COMPLETED,\n turn_aborted: Methods.TURN_COMPLETED,\n};\n\nexport class ExecClient extends EventEmitter implements ICodexClient {\n private _destroyed = false;\n private process: ChildProcess | null = null;\n private spawnOpts: AppServerSpawnOptions | null = null;\n\n // Thread/turn state\n private threadId: string | null = null;\n /** Real thread ID from CLI (received via thread.started event). Used for exec resume. */\n private realThreadId: string | null = null;\n private turnId: string | null = null;\n private turnCount = 0;\n private threadStartParams: ThreadStartParams | null = null;\n private lastAgentMessageText = \"\";\n private turnCompleted = false;\n\n // Handlers\n private notificationHandler: NotificationHandler | null = null;\n private serverRequestHandler: ServerRequestHandler | null = null;\n\n // Stdout buffer for JSONL parsing\n private buffer = \"\";\n private decoder = new StringDecoder(\"utf8\");\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n get supportsTurnOverrides(): boolean {\n // After the first turn, exec resume does not support -s/-p/-C overrides\n return this.turnCount <= 1 || this.realThreadId == null;\n }\n\n async start(opts: AppServerSpawnOptions): Promise<InitializeResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n this.spawnOpts = opts;\n return { userAgent: \"codex-exec\" };\n }\n\n async threadStart(params: ThreadStartParams): Promise<ThreadStartResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n this.threadStartParams = params;\n this.threadId = `exec_thread_${randomUUID().slice(0, 12)}`;\n return { thread: { id: this.threadId } };\n }\n\n async threadFork(_params: ThreadForkParams): Promise<ThreadForkResult> {\n throw new Error(\n `Error [${ErrorCode.EXEC_NOT_SUPPORTED}]: threadFork is not supported in exec mode`\n );\n }\n\n async threadResume(_params: ThreadResumeParams): Promise<ThreadResumeResult> {\n throw new Error(\n `Error [${ErrorCode.EXEC_NOT_SUPPORTED}]: threadResume is not supported in exec mode`\n );\n }\n\n async threadBackgroundTerminalsClean(\n _params: ThreadBackgroundTerminalsCleanParams\n ): Promise<Record<string, never>> {\n return {};\n }\n\n async turnStart(params: TurnStartParams): Promise<TurnStartResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n if (!this.threadId) throw new Error(\"No thread started\");\n\n // Kill any previous turn subprocess\n this.killProcess();\n\n this.turnCount++;\n this.turnId = `exec_turn_${randomUUID().slice(0, 12)}`;\n this.lastAgentMessageText = \"\";\n this.turnCompleted = false;\n this.buffer = \"\";\n this.decoder = new StringDecoder(\"utf8\");\n\n // Extract prompt text from input array\n const prompt = params.input\n .filter((i): i is { type: \"text\"; text: string } => i.type === \"text\")\n .map((i) => i.text)\n .join(\"\\n\");\n\n // Extract image paths\n const images = params.input\n .filter((i): i is { type: \"localImage\"; path: string } => i.type === \"localImage\")\n .map((i) => i.path);\n\n // First turn: codex exec \"<prompt>\" ...\n // Subsequent turns: codex exec resume <threadId> \"<prompt>\" ... (multi-turn context)\n const isResume = this.turnCount > 1 && this.realThreadId != null;\n if (this.turnCount > 1 && !this.realThreadId) {\n // CLI didn't provide a thread ID (e.g. older CLI without thread.started event).\n // Fall back to fresh exec but warn — multi-turn context will be lost.\n console.error(\n \"[exec-client] No realThreadId available for resume; falling back to fresh exec (context will be lost)\"\n );\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error:\n \"exec mode: multi-turn context unavailable (CLI did not provide thread ID). This turn runs without prior context.\",\n willRetry: true, // non-terminal: session continues, just without context\n });\n }\n const args = isResume\n ? this.buildResumeArgs(prompt, params, images)\n : this.buildExecArgs(prompt, params, images);\n const executable = getDefaultCodexExecutable();\n const invocation = resolveCodexInvocation(args, {\n codexCommand: executable.command,\n codexIsPath: executable.isPath,\n });\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n detached: process.platform !== \"win32\",\n windowsHide: process.platform === \"win32\",\n });\n this.process = proc;\n\n // Close stdin immediately — exec reads prompt from args\n proc.stdin?.end();\n\n proc.stdout!.on(\"data\", (chunk: Buffer) => this.onData(chunk));\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n console.error(`[exec-client stderr] ${chunk.toString().trimEnd()}`);\n });\n\n proc.on(\"error\", (err) => {\n if (!this._destroyed) {\n this.emit(\"error\", err);\n }\n });\n\n proc.on(\"exit\", (code, signal) => {\n // If turn wasn't completed via JSONL event, synthesize completion\n if (this.turnId && !this._destroyed && !this.turnCompleted) {\n if (code !== 0 && code !== null) {\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: { message: `exec process exited with code ${code}` },\n willRetry: false,\n });\n }\n }\n if (!this._destroyed) {\n this.emit(\"exit\", code, signal);\n }\n this.process = null;\n });\n\n const turnId = this.turnId;\n return { turn: { id: turnId } };\n }\n\n async turnInterrupt(_params: TurnInterruptParams): Promise<void> {\n this.killProcess();\n }\n\n onNotification(handler: NotificationHandler): void {\n this.notificationHandler = handler;\n }\n\n onServerRequest(handler: ServerRequestHandler): void {\n this.serverRequestHandler = handler;\n }\n\n respondToServer(_id: RequestId, _result: unknown): void {\n // No-op: exec mode has no server-initiated requests\n }\n\n respondErrorToServer(_id: RequestId, _code: number, _message: string): void {\n // No-op: exec mode has no server-initiated requests\n }\n\n async destroy(): Promise<void> {\n if (this._destroyed) return;\n this._destroyed = true;\n\n const proc = this.process;\n if (proc && !proc.killed) {\n const alreadyExited = proc.exitCode !== null;\n proc.stdin?.end();\n this.killProcess();\n\n // Force kill after timeout (matches AppServerClient behavior)\n const forceKill = setTimeout(() => {\n if (proc && !proc.killed && proc.exitCode === null) {\n if (process.platform === \"win32\" && proc.pid) {\n try {\n spawn(\"taskkill\", [\"/PID\", String(proc.pid), \"/T\", \"/F\"], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } catch {\n // ignore\n }\n } else {\n try {\n if (proc.pid) process.kill(-proc.pid, \"SIGKILL\");\n else proc.kill(\"SIGKILL\");\n } catch {\n // ignore\n }\n }\n }\n }, FORCE_KILL_TIMEOUT_MS);\n forceKill.unref();\n\n if (!alreadyExited) {\n await new Promise<void>((resolve) => {\n proc.on(\"exit\", () => {\n clearTimeout(forceKill);\n resolve();\n });\n const fallback = setTimeout(resolve, FORCE_KILL_TIMEOUT_MS + 1000);\n fallback.unref();\n });\n }\n }\n\n this.process = null;\n this.removeAllListeners();\n }\n\n // ── Private helpers ─────────────────────────────────────────────\n\n /**\n * Build args for the first turn: `codex exec \"<prompt>\" --json --skip-git-repo-check [flags]`.\n * No --ephemeral so the session persists for subsequent resume turns.\n */\n private buildExecArgs(prompt: string, params: TurnStartParams, images: string[]): string[] {\n const args: string[] = [\"exec\", prompt, \"--json\", \"--skip-git-repo-check\"];\n\n // Model\n const model = params.model ?? this.threadStartParams?.model ?? this.spawnOpts?.model;\n if (model) args.push(\"-m\", model);\n\n // Sandbox (first turn only — exec resume does not support -s)\n let effectiveSandbox: string | undefined;\n if (params.sandboxPolicy) {\n effectiveSandbox = sandboxPolicyToMode(params.sandboxPolicy);\n }\n if (!effectiveSandbox) {\n effectiveSandbox = this.threadStartParams?.sandbox ?? this.spawnOpts?.sandbox;\n }\n if (effectiveSandbox) args.push(\"-s\", effectiveSandbox);\n\n // Profile (first turn only — exec resume does not support -p)\n if (this.spawnOpts?.profile) args.push(\"-p\", this.spawnOpts.profile);\n\n // CWD (first turn only — exec resume does not support -C)\n const cwd = params.cwd ?? this.threadStartParams?.cwd;\n if (cwd) args.push(\"-C\", cwd);\n\n // Images\n for (const img of images) args.push(\"-i\", img);\n\n // Approval policy via config override (precise, doesn't affect sandbox)\n const approvalPolicy =\n params.approvalPolicy ??\n this.threadStartParams?.approvalPolicy ??\n this.spawnOpts?.approvalPolicy;\n if (approvalPolicy) args.push(\"-c\", `approval_policy=${approvalPolicy}`);\n\n // Output schema (exec supports --output-schema <file>; write to temp file)\n if (params.outputSchema && Object.keys(params.outputSchema).length > 0) {\n try {\n const tmpDir = mkdtempSync(join(tmpdir(), \"codex-mcp-schema-\"));\n const schemaPath = join(tmpDir, \"output-schema.json\");\n writeFileSync(schemaPath, JSON.stringify(params.outputSchema));\n args.push(\"--output-schema\", schemaPath);\n } catch (err) {\n console.error(\n `[exec-client] Failed to write output schema to temp file: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // Config overrides\n const configs: Record<string, unknown> = {\n ...this.spawnOpts?.config,\n ...this.threadStartParams?.config,\n };\n for (const [key, value] of Object.entries(configs)) {\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n\n return args;\n }\n\n /**\n * Build args for subsequent turns: `codex exec resume <threadId> \"<prompt>\" --json [flags]`.\n * Resumes the persisted session for multi-turn context continuity.\n * Note: exec resume only supports -m, -c, -i, --json, --skip-git-repo-check.\n * -s, -p, -C are NOT supported and inherit from the first turn's session.\n */\n private buildResumeArgs(prompt: string, params: TurnStartParams, images: string[]): string[] {\n const args: string[] = [\n \"exec\",\n \"resume\",\n this.realThreadId!,\n prompt,\n \"--json\",\n \"--skip-git-repo-check\",\n ];\n\n // Warn about unsupported overrides in resume mode\n if (params.sandboxPolicy) {\n console.error(\n \"[exec-client] sandbox override ignored in resume mode (exec resume does not support -s)\"\n );\n }\n if (params.cwd) {\n console.error(\n \"[exec-client] cwd override ignored in resume mode (exec resume does not support -C)\"\n );\n }\n if (params.outputSchema && Object.keys(params.outputSchema).length > 0) {\n console.error(\n \"[exec-client] outputSchema ignored in resume mode (exec resume does not support --output-schema)\"\n );\n }\n\n // Model override (supported in resume)\n const model = params.model ?? this.threadStartParams?.model ?? this.spawnOpts?.model;\n if (model) args.push(\"-m\", model);\n\n // Images (supported in resume)\n for (const img of images) args.push(\"-i\", img);\n\n // Approval policy via config override (supported in resume via -c)\n const approvalPolicy =\n params.approvalPolicy ??\n this.threadStartParams?.approvalPolicy ??\n this.spawnOpts?.approvalPolicy;\n if (approvalPolicy) args.push(\"-c\", `approval_policy=${approvalPolicy}`);\n\n // Config overrides (supported in resume via -c)\n const configs: Record<string, unknown> = {\n ...this.spawnOpts?.config,\n ...this.threadStartParams?.config,\n };\n for (const [key, value] of Object.entries(configs)) {\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n\n return args;\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += this.decoder.write(chunk);\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed[0] !== \"{\") continue;\n\n try {\n const event = JSON.parse(trimmed) as Record<string, unknown>;\n this.handleExecEvent(event);\n } catch {\n console.error(`[exec-client] Failed to parse JSONL: ${trimmed.slice(0, 200)}`);\n }\n }\n }\n\n /**\n * Transform exec JSONL event into app-server notification and dispatch.\n */\n private handleExecEvent(event: Record<string, unknown>): void {\n const type = event.type as string;\n\n // Handle structured lifecycle events first (dot-notation from exec --json)\n switch (type) {\n case \"thread.started\": {\n const cliThreadId = event.thread_id as string | undefined;\n if (cliThreadId) {\n this.threadId = cliThreadId;\n this.realThreadId = cliThreadId;\n }\n this.emitNotification(Methods.THREAD_STARTED, {\n thread: { id: this.threadId },\n });\n return;\n }\n\n case \"turn.started\":\n this.emitNotification(Methods.TURN_STARTED, {\n turn: { id: this.turnId, status: \"inProgress\" },\n });\n return;\n\n case \"item.started\": {\n const item = event.item as Record<string, unknown> | undefined;\n if (item) {\n this.emitNotification(Methods.ITEM_STARTED, {\n threadId: this.threadId,\n turnId: this.turnId,\n item: transformItem(item),\n });\n }\n return;\n }\n\n case \"item.completed\": {\n const item = event.item as Record<string, unknown> | undefined;\n if (item) {\n const transformed = transformItem(item);\n if (transformed.type === \"agentMessage\" && typeof transformed.text === \"string\") {\n this.lastAgentMessageText = transformed.text;\n }\n this.emitNotification(Methods.ITEM_COMPLETED, {\n threadId: this.threadId,\n turnId: this.turnId,\n item: transformed,\n });\n }\n return;\n }\n\n case \"turn.completed\": {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"completed\",\n output: this.lastAgentMessageText || undefined,\n usage: event.usage,\n },\n });\n this.turnId = null;\n return;\n }\n\n case \"turn.failed\": {\n const turnId = this.turnId ?? \"\";\n const error = event.error as Record<string, unknown> | undefined;\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"failed\",\n error: error ?? { message: \"Turn failed\" },\n },\n });\n this.turnId = null;\n return;\n }\n\n case \"error\": {\n const willRetry = isRetryableError(event);\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: event.message ?? event.error,\n willRetry,\n });\n return;\n }\n\n default:\n break;\n }\n\n // Map snake_case event types to app-server notification methods\n const mappedMethod = EXEC_EVENT_TO_METHOD[type];\n if (mappedMethod) {\n // Legacy turn lifecycle events need turn object synthesis\n if (type === \"task_started\") {\n const turnId = (event.turn_id as string) ?? this.turnId;\n if (turnId) this.turnId = turnId;\n this.emitNotification(Methods.TURN_STARTED, {\n turn: { id: this.turnId, status: \"inProgress\" },\n });\n } else if (type === \"task_complete\") {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"completed\",\n output: this.lastAgentMessageText || undefined,\n },\n });\n this.turnId = null;\n } else if (type === \"turn_aborted\") {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"cancelled\",\n error: event.reason ?? { message: \"Turn aborted\" },\n },\n });\n this.turnId = null;\n } else if (mappedMethod === Methods.ERROR) {\n // For stream_error, apply retryable detection\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: event.message ?? event.error ?? type,\n willRetry: isRetryableError(event),\n });\n } else {\n this.emitNotification(mappedMethod, {\n threadId: this.threadId,\n turnId: this.turnId,\n ...event,\n });\n }\n return;\n }\n\n // Unmapped events: log but don't emit to avoid silent drops in manager.\n // The manager's default branch ignores unknown methods, so emitting them\n // would be misleading. Logging ensures visibility during debugging.\n console.error(`[exec-client] Unmapped exec event type: ${type}`);\n }\n\n private emitNotification(method: string, params: unknown): void {\n if (this.notificationHandler) {\n this.notificationHandler(method, params);\n }\n }\n\n private killProcess(): void {\n if (!this.process || this.process.killed) return;\n\n if (process.platform !== \"win32\" && this.process.pid) {\n try {\n process.kill(-this.process.pid, \"SIGTERM\");\n return;\n } catch {\n // Fall through to direct kill\n }\n }\n\n try {\n this.process.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n }\n}\n"],"mappings":"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","names":["comspec","existsSync","path","stripSurroundingQuotes","ErrorCode","existsSync","statSync","path","path","existsSync","statSync","existsSync","statSync","path","path","existsSync","statSync","path","spawn","spawn","spawn","EventEmitter","randomUUID","StringDecoder","EventEmitter","StringDecoder","randomUUID","spawn"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/session/manager.ts","../src/app-server/client.ts","../src/app-server/protocol.ts","../src/app-server/lifecycle.ts","../src/app-server/codex-bin.ts","../src/utils/codex-executable.ts","../src/types.ts","../src/utils/cwd.ts","../src/utils/redact.ts","../src/utils/files.ts","../src/utils/config.ts","../src/utils/execution.ts","../src/tools/codex.ts","../src/tools/codex-reply.ts","../src/tools/codex-session.ts","../src/tools/codex-check.ts","../src/tools/codex-setup.ts","../src/app-server/detect.ts","../src/resources/register-resources.ts","../src/utils/stdio-guard.ts","../src/app-server/exec-client.ts","../src/session/persistence.ts","../src/persistence/atomic-writer.ts","../src/persistence/lockfile.ts","../src/persistence/event-log.ts","../src/persistence/recovery-scanner.ts","../src/persistence/retention.ts","../src/session/orphan-reaper.ts","../src/utils/stdin-shutdown.ts"],"sourcesContent":["/**\n * codex-mcp — MCP server entry point\n *\n * Starts the MCP server with stdio transport.\n * Spawns codex app-server child processes for each session,\n * or falls back to codex exec --json when app-server is unavailable.\n */\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\nimport type { ICodexClient } from \"./app-server/client-interface.js\";\nimport { AppServerClient } from \"./app-server/client.js\";\nimport { detectClientMode } from \"./app-server/detect.js\";\nimport { ExecClient } from \"./app-server/exec-client.js\";\nimport { runStdioPreflight } from \"./utils/stdio-guard.js\";\nimport {\n checkDefaultCodexExecutableAvailability,\n getDefaultCodexExecutable,\n} from \"./utils/codex-executable.js\";\nimport { SessionPersistence } from \"./session/persistence.js\";\nimport { reapOrphanProcesses } from \"./session/orphan-reaper.js\";\nimport { decideStdinShutdown } from \"./utils/stdin-shutdown.js\";\n\nconst STDIN_SHUTDOWN_CHECK_MS = 750;\nconst STDIN_SHUTDOWN_MAX_WAIT_MS = process.platform === \"win32\" ? 15_000 : 10_000;\n\nasync function main(): Promise<void> {\n const preflight = runStdioPreflight();\n for (const note of preflight.notes) {\n console.error(`[stdio] ${note}`);\n }\n if (preflight.riskLevel === \"elevated\") {\n console.error(`[stdio] Elevated stdout contamination risk detected (mode=${preflight.mode}).`);\n for (const reason of preflight.riskReasons) {\n console.error(`[stdio] Reason: ${reason}`);\n }\n for (const suggestion of preflight.suggestions) {\n console.error(`[stdio] Suggestion: ${suggestion}`);\n }\n }\n if (preflight.shouldBlock) {\n throw new Error(\n \"STDIO preflight failed in strict mode due to blocking stdout contamination risk\"\n );\n }\n\n // Resolve and validate the codex executable before starting the server.\n // Throws immediately if env vars are misconfigured (e.g. both set, or path missing).\n checkDefaultCodexExecutableAvailability();\n const executable = getDefaultCodexExecutable();\n const clientMode = await detectClientMode(executable.command, executable.isPath);\n console.error(`[codex-mcp] client mode: ${clientMode} (binary: ${executable.command})`);\n const createClient = (): ICodexClient =>\n clientMode === \"exec\" ? new ExecClient() : new AppServerClient();\n\n // Initialize disk persistence\n const persistence = new SessionPersistence();\n try {\n persistence.acquireLock();\n console.error(\"[codex-mcp] STATE_DIR lock acquired\");\n } catch (err) {\n console.error(\"[codex-mcp] WARNING: Failed to acquire STATE_DIR lock:\", err);\n }\n\n // Recover sessions from disk and prune old ones\n const recovered = persistence.recoverSessions();\n if (recovered.length > 0) {\n console.error(`[codex-mcp] Recovered ${recovered.length} session(s) from disk`);\n }\n const pruned = persistence.prune();\n if (pruned > 0) {\n console.error(`[codex-mcp] Pruned ${pruned} old session(s)`);\n }\n\n // Reap any orphaned child processes from the previous server run.\n const reaped = await reapOrphanProcesses(recovered);\n if (reaped.reaped > 0) console.error(`[codex-mcp] Reaped ${reaped.reaped} orphan process(es)`);\n\n const serverCwd = process.cwd();\n const ctx = createServer(serverCwd, {\n createClient,\n clientMode,\n persistence,\n });\n const server = ctx.server;\n const sessionManager = ctx.sessionManager;\n\n // Ingest recovered sessions into the in-memory session manager\n if (recovered.length > 0) {\n sessionManager.ingestRecovered(recovered);\n }\n\n const transport = new StdioServerTransport();\n\n // ── Graceful shutdown state ────────────────────────────────────────\n let closing = false;\n let lastExitCode = 0;\n let stdinClosedAt: number | undefined;\n let stdinClosedReason: \"end\" | \"close\" | undefined;\n let stdinShutdownTimer: ReturnType<typeof setTimeout> | undefined;\n\n const onStdinEnd = () => handleStdinTerminated(\"end\");\n const onStdinClose = () => handleStdinTerminated(\"close\");\n\n const clearStdinShutdownTimer = () => {\n if (stdinShutdownTimer) {\n clearTimeout(stdinShutdownTimer);\n stdinShutdownTimer = undefined;\n }\n };\n\n function hasActiveSessions(): boolean {\n return sessionManager\n .listSessions()\n .some((s) => s.status === \"running\" || s.status === \"waiting_approval\");\n }\n\n const shutdown = async (reason = \"unknown\") => {\n if (closing) return;\n closing = true;\n clearStdinShutdownTimer();\n // Remove stdin listeners to avoid re-entrant calls\n if (typeof process.stdin.off === \"function\") {\n process.stdin.off(\"error\", handleStdinError);\n process.stdin.off(\"end\", onStdinEnd);\n process.stdin.off(\"close\", onStdinClose);\n }\n\n // Set a hard force-exit timer in case cleanup hangs\n const forceExitMs = process.platform === \"win32\" ? 10_000 : 5_000;\n const forceExitTimer = setTimeout(() => process.exit(lastExitCode), forceExitMs);\n if (forceExitTimer.unref) forceExitTimer.unref();\n\n const activeSessions = sessionManager.listSessions();\n const runningCount = activeSessions.filter(\n (s) => s.status === \"running\" || s.status === \"waiting_approval\"\n ).length;\n\n console.error(\n `[codex-mcp] shutdown triggered (reason=${reason}, activeSessions=${runningCount}, total=${activeSessions.length})`\n );\n\n try {\n if (server.isConnected()) {\n await server.sendLoggingMessage({\n level: \"info\",\n data: {\n event: \"server_stopping\",\n reason,\n activeSessions: runningCount,\n totalSessions: activeSessions.length,\n },\n });\n }\n } catch {\n // ignore — client may not support logging notifications\n }\n\n try {\n // Flush persistence and release lock before server close\n persistence.flushAll();\n persistence.releaseLockIfHeld();\n } catch {\n // best-effort\n }\n\n try {\n await server.close();\n } catch {\n // Ignore close errors during shutdown\n }\n\n persistence.destroy();\n process.exitCode = lastExitCode;\n\n try {\n await new Promise<void>((resolve) => process.stderr.write(\"\", () => resolve()));\n } catch {\n // ignore stderr flush errors\n } finally {\n clearTimeout(forceExitTimer);\n }\n };\n\n function handleStdinError(error: Error) {\n console.error(\"[codex-mcp] stdin error:\", error);\n lastExitCode = 1;\n void shutdown(\"stdin_error\");\n }\n\n const evaluateStdinTermination = () => {\n if (closing || stdinClosedAt === undefined) return;\n\n const stdinUnavailable =\n process.stdin.destroyed || process.stdin.readableEnded || !process.stdin.readable;\n const elapsedMs = Date.now() - stdinClosedAt;\n const active = hasActiveSessions();\n const connected = server.isConnected();\n\n const decision = decideStdinShutdown({\n stdinUnavailable,\n elapsedMs,\n maxWaitMs: STDIN_SHUTDOWN_MAX_WAIT_MS,\n hasActiveSessions: active,\n isConnected: connected,\n });\n\n if (decision === \"clear\") {\n // Stdin stream recovered — drop this shutdown attempt.\n stdinClosedAt = undefined;\n stdinClosedReason = undefined;\n return;\n }\n if (decision === \"shutdown_now\") {\n console.error(\"[codex-mcp] stdin closed with no active sessions — shutting down\");\n void shutdown(`stdin_${stdinClosedReason ?? \"closed\"}`);\n return;\n }\n if (decision === \"shutdown_timeout\") {\n console.error(\n `[codex-mcp] stdin closed and drain period (${STDIN_SHUTDOWN_MAX_WAIT_MS}ms) elapsed — forcing shutdown`\n );\n void shutdown(`stdin_${stdinClosedReason ?? \"closed\"}_timeout`);\n return;\n }\n // decision === \"reschedule\": keep waiting\n if (active) {\n console.error(\n `[codex-mcp] stdin closed; ${sessionManager.getActiveSessionCount()} active session(s) — waiting up to ${STDIN_SHUTDOWN_MAX_WAIT_MS}ms (elapsed: ${elapsedMs}ms)`\n );\n }\n stdinShutdownTimer = setTimeout(evaluateStdinTermination, STDIN_SHUTDOWN_CHECK_MS);\n if (stdinShutdownTimer.unref) stdinShutdownTimer.unref();\n };\n\n function handleStdinTerminated(event: \"end\" | \"close\") {\n if (closing) return;\n if (stdinClosedAt === undefined) {\n stdinClosedAt = Date.now();\n stdinClosedReason = event;\n console.error(`[codex-mcp] stdin ${event} observed — entering guarded shutdown checks`);\n }\n clearStdinShutdownTimer();\n stdinShutdownTimer = setTimeout(evaluateStdinTermination, STDIN_SHUTDOWN_CHECK_MS);\n if (stdinShutdownTimer.unref) stdinShutdownTimer.unref();\n }\n\n const handleUnexpectedError = (error: unknown) => {\n console.error(\"[codex-mcp] Unhandled runtime error:\", error);\n lastExitCode = 1;\n void shutdown(\"runtime_error\");\n };\n\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n // Windows: Ctrl+Break / console close scenarios.\n process.on(\"SIGBREAK\", () => void shutdown(\"SIGBREAK\"));\n process.on(\"beforeExit\", () => {\n // Do not eagerly shutdown while transport still appears connected.\n if (!server.isConnected()) {\n void shutdown(\"beforeExit\");\n }\n });\n process.on(\"uncaughtException\", handleUnexpectedError);\n process.on(\"unhandledRejection\", handleUnexpectedError);\n\n // Keep stdin alive so the MCP stdio transport continues to receive frames.\n if (typeof process.stdin.resume === \"function\") {\n process.stdin.resume();\n }\n process.stdin.on(\"error\", handleStdinError);\n // Guarded shutdown: some clients can transiently trigger stdio close-like signals.\n // We only exit after checking connection/session state.\n process.stdin.on(\"end\", onStdinEnd);\n process.stdin.on(\"close\", onStdinClose);\n\n await server.connect(transport);\n console.error(`codex-mcp server started (cwd: ${serverCwd})`);\n}\n\nmain().catch((err) => {\n console.error(\"Fatal error:\", err);\n process.exit(1);\n});\n","/**\n * MCP Server definition — registers tools and handles requests.\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { SessionManager, type SessionManagerOptions } from \"./session/manager.js\";\nimport { executeCodex } from \"./tools/codex.js\";\nimport { executeCodexReply } from \"./tools/codex-reply.js\";\nimport { executeCodexSession } from \"./tools/codex-session.js\";\nimport { executeCodexCheck } from \"./tools/codex-check.js\";\nimport { executeCodexSetup } from \"./tools/codex-setup.js\";\nimport { registerResources } from \"./resources/register-resources.js\";\nimport {\n APPROVAL_POLICIES,\n SANDBOX_MODES,\n PERSONALITIES,\n EFFORT_LEVELS,\n SUMMARY_MODES,\n SESSION_ACTIONS,\n CHECK_ACTIONS,\n RESPONSE_MODES,\n ALL_DECISIONS,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n DEFAULT_EFFORT_LEVEL,\n ErrorCode,\n} from \"./types.js\";\nimport { redactPaths } from \"./utils/redact.js\";\n\ndeclare const __PKG_VERSION__: string;\nconst SERVER_VERSION = typeof __PKG_VERSION__ !== \"undefined\" ? __PKG_VERSION__ : \"0.0.0-dev\";\n\nfunction formatErrorMessage(err: unknown): string {\n const message = err instanceof Error ? err.message : String(err);\n const m = /^Error \\[([A-Z_]+)\\]:\\s*(.*)$/.exec(message);\n if (m) {\n const [, code, rest] = m;\n if (code === ErrorCode.INTERNAL) {\n return `Error [${ErrorCode.INTERNAL}]: ${redactPaths(rest)}`;\n }\n return message;\n }\n return `Error [${ErrorCode.INTERNAL}]: ${redactPaths(message)}`;\n}\n\nfunction toStructuredContent(value: unknown): Record<string, unknown> {\n // MCP structuredContent is object-shaped; wrap non-object payloads for compatibility.\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return { value };\n}\n\nexport interface ServerContext {\n server: McpServer;\n sessionManager: SessionManager;\n}\n\nexport function createServer(\n serverCwd: string,\n options?: SessionManagerOptions & { clientMode?: string }\n): ServerContext {\n const sessionManager = new SessionManager(options);\n\n const server = new McpServer({\n name: \"codex-mcp\",\n version: SERVER_VERSION,\n });\n\n // Read-only MCP resources (helpful docs / metadata)\n registerResources(server, {\n version: SERVER_VERSION,\n sessionManager,\n clientMode: options?.clientMode,\n });\n\n const publicSessionInfoSchema = z.object({\n sessionId: z.string(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]),\n createdAt: z.string(),\n lastActiveAt: z.string(),\n cancelledAt: z.string().optional(),\n cancelledReason: z.string().optional(),\n model: z.string().optional(),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional(),\n sandbox: z.enum(SANDBOX_MODES).optional(),\n pendingRequestCount: z.number().int(),\n });\n\n const errorOutputShape = {\n error: z.string().optional(),\n isError: z.boolean().optional(),\n };\n\n const executionInfoSchema = z.object({\n requested: z.enum([\"background\", \"foreground\"]),\n effective: z.enum([\"background\", \"foreground\"]),\n waitForResultMs: z.number().int().positive().optional(),\n fallbackReason: z.enum([\"wait_for_result_timeout\", \"interactive_poll_required\"]).optional(),\n });\n\n const interactionStateSchema = z.enum([\"working\", \"waiting_input\", \"finished\"]);\n const nextActionSchema = z.enum([\"poll\", \"respond_permission\", \"respond_user_input\", \"none\"]);\n\n const setupResultShape = {\n ready: z.boolean(),\n cwd: z.string(),\n executable: z.object({\n ok: z.boolean(),\n source: z.string(),\n command: z.string().optional(),\n isPath: z.boolean().optional(),\n detail: z.string(),\n }),\n auth: z.object({\n ok: z.boolean(),\n state: z.enum([\"authenticated\", \"unauthenticated\", \"unknown\"]),\n detail: z.string(),\n }),\n runtime: z.object({\n sameMachineRequired: z.boolean(),\n clientMode: z.enum([\"app-server\", \"exec\"]).optional(),\n stateDir: z.string(),\n }),\n projectContext: z.object({\n hasUserConfig: z.boolean(),\n hasProjectConfig: z.boolean(),\n }),\n warnings: z.array(z.string()),\n nextSteps: z.array(z.string()),\n };\n\n const sessionStartOutputShape = {\n sessionId: z.string().optional(),\n threadId: z.string().optional(),\n status: z.enum([\"running\", \"waiting_approval\", \"idle\", \"error\", \"cancelled\"]).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n result: z\n .unknown()\n .optional()\n .describe(\"Final result when waitForResult is set and session completed.\"),\n completedAt: z\n .string()\n .optional()\n .describe(\"ISO timestamp when the session completed (only when waitForResult succeeded).\"),\n execution: executionInfoSchema.optional(),\n interactionState: interactionStateSchema.optional(),\n recommendedNextAction: nextActionSchema.optional(),\n ...errorOutputShape,\n };\n\n const codexCheckPollOptionsSchema = z\n .object({\n includeEvents: z\n .boolean()\n .optional()\n .describe(\"Default: true. Include events[] in response.\"),\n includeActions: z\n .boolean()\n .optional()\n .describe(\"Default: true. Include actions[] in response.\"),\n includeResult: z.boolean().optional().describe(\"Default: true. Include result in response.\"),\n maxBytes: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Default: unlimited. Best-effort response payload cap in bytes.\"),\n waitMs: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\n \"Long-poll: block up to this many ms for new events (max 120000). Omit or 0 for immediate return.\"\n ),\n })\n .optional()\n .describe(\"Optional poll shaping controls.\");\n\n const codexCheckInputSchema = z\n .object({\n action: z.enum(CHECK_ACTIONS),\n sessionId: z.string().describe(\"Target session ID\"),\n cursor: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\"Event cursor (default: session last consumed cursor).\"),\n maxEvents: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\n `Max events. Default: poll=${POLL_DEFAULT_MAX_EVENTS} (min ${POLL_MIN_MAX_EVENTS}), respond_*=${RESPOND_DEFAULT_MAX_EVENTS}.`\n ),\n responseMode: z\n .enum(RESPONSE_MODES)\n .optional()\n .describe(\"Response mode. Default: minimal. Options: minimal/delta_compact/full.\"),\n pollOptions: codexCheckPollOptionsSchema,\n // respond_permission\n requestId: z.string().optional().describe(\"Request ID from actions[]\"),\n decision: z\n .enum(ALL_DECISIONS)\n .optional()\n .describe(\n \"Approval decision for respond_permission. acceptWithExecpolicyAmendment requires execpolicy_amendment; applyNetworkPolicyAmendment requires network_policy_amendment.\"\n ),\n execpolicy_amendment: z\n .array(z.string())\n .optional()\n .describe(\"For acceptWithExecpolicyAmendment only\"),\n network_policy_amendment: z\n .object({\n action: z.enum([\"allow\", \"deny\"]),\n host: z.string().min(1),\n })\n .optional()\n .describe(\"For applyNetworkPolicyAmendment only\"),\n denyMessage: z.string().optional().describe(\"Deny reason (not sent to agent)\"),\n // respond_user_input\n answers: z\n .record(\n z.string(),\n z.object({\n answers: z.array(z.string()),\n })\n )\n .optional()\n .describe(\"question-id -> answers map (id from actions[] user_input request).\"),\n })\n .superRefine((value, ctx) => {\n const addIssue = (path: string, message: string) => {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [path],\n message,\n });\n };\n\n switch (value.action) {\n case \"poll\": {\n if (value.maxEvents !== undefined && value.maxEvents < POLL_MIN_MAX_EVENTS) {\n addIssue(\n \"maxEvents\",\n `poll requires maxEvents >= ${POLL_MIN_MAX_EVENTS} to avoid no-op loops.`\n );\n }\n if (value.requestId !== undefined) {\n addIssue(\"requestId\", \"requestId is only allowed for respond_* actions.\");\n }\n if (value.decision !== undefined) {\n addIssue(\"decision\", \"decision is only allowed for action='respond_permission'.\");\n }\n if (value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.denyMessage !== undefined) {\n addIssue(\"denyMessage\", \"denyMessage is only allowed for action='respond_permission'.\");\n }\n if (value.answers !== undefined) {\n addIssue(\"answers\", \"answers is only allowed for action='respond_user_input'.\");\n }\n break;\n }\n case \"respond_permission\": {\n if (!value.requestId) {\n addIssue(\"requestId\", \"requestId is required for action='respond_permission'.\");\n }\n if (!value.decision) {\n addIssue(\"decision\", \"decision is required for action='respond_permission'.\");\n }\n if (value.answers !== undefined) {\n addIssue(\"answers\", \"answers is only allowed for action='respond_user_input'.\");\n }\n const needsExecpolicy = value.decision === \"acceptWithExecpolicyAmendment\";\n const needsNetworkPolicy = value.decision === \"applyNetworkPolicyAmendment\";\n if (\n needsExecpolicy &&\n (!value.execpolicy_amendment || value.execpolicy_amendment.length === 0)\n ) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is required and must be non-empty when decision='acceptWithExecpolicyAmendment'.\"\n );\n }\n if (!needsExecpolicy && value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed when decision='acceptWithExecpolicyAmendment'.\"\n );\n }\n\n if (needsNetworkPolicy && !value.network_policy_amendment) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is required when decision='applyNetworkPolicyAmendment'.\"\n );\n }\n if (!needsNetworkPolicy && value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed when decision='applyNetworkPolicyAmendment'.\"\n );\n }\n break;\n }\n case \"respond_user_input\": {\n if (!value.requestId) {\n addIssue(\"requestId\", \"requestId is required for action='respond_user_input'.\");\n }\n if (!value.answers) {\n addIssue(\"answers\", \"answers is required for action='respond_user_input'.\");\n }\n if (value.decision !== undefined) {\n addIssue(\"decision\", \"decision is only allowed for action='respond_permission'.\");\n }\n if (value.execpolicy_amendment !== undefined) {\n addIssue(\n \"execpolicy_amendment\",\n \"execpolicy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.network_policy_amendment !== undefined) {\n addIssue(\n \"network_policy_amendment\",\n \"network_policy_amendment is only allowed for action='respond_permission'.\"\n );\n }\n if (value.denyMessage !== undefined) {\n addIssue(\"denyMessage\", \"denyMessage is only allowed for action='respond_permission'.\");\n }\n break;\n }\n }\n });\n\n // ── Tool 1: codex — Start a new Codex agent session ──────────────\n\n server.registerTool(\n \"codex\",\n {\n title: \"Start Codex Session\",\n description:\n \"Start session asynchronously and return `{ sessionId, threadId, status, pollInterval }`. Use `pollInterval` as a minimum hint: `running` >=120000ms (increase for long tasks), `waiting_approval` ~=1000ms.\",\n inputSchema: {\n prompt: z.string().describe(\"Task or question\"),\n approvalPolicy: z\n .enum(APPROVAL_POLICIES)\n .describe(\"Required enum: untrusted/on-failure/on-request/never.\"),\n sandbox: z\n .enum(SANDBOX_MODES)\n .describe(\"Required enum: read-only/workspace-write/danger-full-access.\"),\n effort: z\n .enum(EFFORT_LEVELS)\n .default(DEFAULT_EFFORT_LEVEL)\n .describe(\"Reasoning effort (default: low).\"),\n cwd: z.string().optional().describe(\"Working directory (default: server cwd).\"),\n model: z.string().optional().describe(\"Model override (default: config.toml)\"),\n profile: z.string().optional().describe(\"Profile name (default: CLI default profile).\"),\n advanced: z\n .object({\n baseInstructions: z.string().optional().describe(\"Replace system instructions.\"),\n developerInstructions: z.string().optional().describe(\"Extra developer instructions.\"),\n personality: z\n .enum(PERSONALITIES)\n .optional()\n .describe(\"Personality (default: config.toml).\"),\n summary: z\n .enum(SUMMARY_MODES)\n .optional()\n .describe(\"Summary mode (default: config.toml).\"),\n config: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Override config values.\"),\n ephemeral: z.boolean().optional().describe(\"Do not persist thread (default: false).\"),\n outputSchema: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Structured output schema.\"),\n images: z.array(z.string()).optional().describe(\"Local image paths.\"),\n approvalTimeoutMs: z\n .number()\n .int()\n .positive()\n .default(DEFAULT_APPROVAL_TIMEOUT_MS)\n .optional()\n .describe(`Auto-decline timeout in ms (default: ${DEFAULT_APPROVAL_TIMEOUT_MS})`),\n waitForResult: z\n .number()\n .int()\n .positive()\n .max(300000)\n .optional()\n .describe(\n \"Block up to this many ms for session completion (max 300000). Falls back to sessionId for polling if not done in time. Only use with approvalPolicy on-failure/never.\"\n ),\n })\n .optional()\n .describe(\"Advanced settings.\"),\n },\n outputSchema: sessionStartOutputShape,\n annotations: {\n title: \"Start Codex Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async (args, extra) => {\n try {\n const result = await executeCodex(args, sessionManager, serverCwd, extra.signal);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError: false,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // ── Tool 2: codex_reply — Continue an existing session ───────────\n\n server.registerTool(\n \"codex_reply\",\n {\n title: \"Continue Codex Session\",\n description:\n \"Continue existing session. Allowed in `idle`/`error`; otherwise `SESSION_BUSY`. Returns immediately. Use `pollInterval` as a minimum hint: `running` >=120000ms, `waiting_approval` ~=1000ms.\",\n inputSchema: {\n sessionId: z.string().describe(\"Session ID from codex tool\"),\n prompt: z.string().describe(\"Follow-up message\"),\n model: z.string().optional().describe(\"Override model.\"),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional().describe(\"Override approval policy.\"),\n effort: z.enum(EFFORT_LEVELS).optional().describe(\"Override effort.\"),\n summary: z.enum(SUMMARY_MODES).optional().describe(\"Override summary.\"),\n personality: z.enum(PERSONALITIES).optional().describe(\"Override personality.\"),\n sandbox: z.enum(SANDBOX_MODES).optional().describe(\"Override sandbox.\"),\n cwd: z.string().optional().describe(\"Override cwd.\"),\n outputSchema: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Structured output schema override (top-level in codex_reply).\"),\n waitForResult: z\n .number()\n .int()\n .positive()\n .max(300000)\n .optional()\n .describe(\n \"Wait up to this many ms for the reply turn to complete and return the result directly. Max 300000 (5 min). If the turn does not finish in time or enters interactive approval/user-input flow, returns session metadata for polling.\"\n ),\n },\n outputSchema: sessionStartOutputShape,\n annotations: {\n title: \"Continue Codex Session\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: true,\n },\n },\n async (args, extra) => {\n try {\n const result = await executeCodexReply(args, sessionManager, extra.signal);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError: false,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n server.registerTool(\n \"codex_setup\",\n {\n title: \"Codex Setup\",\n description:\n \"Run local readiness checks for codex-mcp: executable resolution, login status, detected backend mode, and project config. Use this before starting a session when setup is uncertain.\",\n inputSchema: {\n cwd: z\n .string()\n .optional()\n .describe(\"Optional cwd to inspect for project-local Codex config. Default: server cwd.\"),\n },\n outputSchema: setupResultShape,\n annotations: {\n title: \"Codex Setup\",\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n async (args) => {\n const result = await executeCodexSetup(args, serverCwd);\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError: false,\n };\n }\n );\n\n // ── Tool 4: codex_session — Manage sessions ──────────────────────\n\n server.registerTool(\n \"codex_session\",\n {\n title: \"Manage Sessions\",\n description: `Session actions: list, get, cancel, interrupt, fork, clean_background_terminals.\n\n- list: sessions in memory.\n- get: details. includeSensitive defaults to false; true adds threadId/cwd/profile/config.\n- cancel: terminal.\n- interrupt: stop current turn.\n- fork: clone current thread into a new session; source remains unchanged.\n- clean_background_terminals: ask app-server to clean stale background terminals for this thread.`,\n inputSchema: {\n action: z.enum(SESSION_ACTIONS),\n sessionId: z\n .string()\n .optional()\n .describe(\"Required for get/cancel/interrupt/fork/clean_background_terminals\"),\n includeSensitive: z\n .boolean()\n .default(false)\n .optional()\n .describe(\"Include cwd/config/threadId/profile in get (default: false)\"),\n },\n outputSchema: {\n sessions: z.array(publicSessionInfoSchema).optional(),\n sessionId: z.string().optional(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]).optional(),\n createdAt: z.string().optional(),\n lastActiveAt: z.string().optional(),\n cancelledAt: z.string().optional(),\n cancelledReason: z.string().optional(),\n model: z.string().optional(),\n approvalPolicy: z.enum(APPROVAL_POLICIES).optional(),\n sandbox: z.enum(SANDBOX_MODES).optional(),\n pendingRequestCount: z.number().int().optional(),\n threadId: z.string().optional(),\n cwd: z.string().optional(),\n profile: z.string().optional(),\n config: z.record(z.string(), z.unknown()).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n success: z.boolean().optional(),\n message: z.string().optional(),\n ...errorOutputShape,\n },\n annotations: {\n title: \"Manage Sessions\",\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async (args) => {\n try {\n const result = await executeCodexSession(args, sessionManager);\n const isError =\n typeof (result as { isError?: boolean }).isError === \"boolean\"\n ? (result as { isError: boolean }).isError\n : false;\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // ── Tool 5: codex_check — Poll events + respond to requests ──────\n\n server.registerTool(\n \"codex_check\",\n {\n title: \"Poll & Respond\",\n description: `Poll session for events or respond to approval/input requests. Use pollInterval as a minimum hint; stop polling on terminal status (idle/error/cancelled). See codex-mcp:///gotchas for poll frequency guidance.\n\npoll: events since cursor. Default maxEvents=${POLL_DEFAULT_MAX_EVENTS}.\nrespond_permission: approval decision. Default maxEvents=${RESPOND_DEFAULT_MAX_EVENTS} (compact ACK).\nrespond_user_input: user-input answers. Default maxEvents=${RESPOND_DEFAULT_MAX_EVENTS} (compact ACK).`,\n inputSchema: codexCheckInputSchema,\n outputSchema: {\n sessionId: z.string().optional(),\n status: z.enum([\"running\", \"idle\", \"waiting_approval\", \"error\", \"cancelled\"]).optional(),\n pollInterval: z\n .number()\n .int()\n .optional()\n .describe(\n \"Recommended minimum delay before next poll (ms): running >=120000, waiting_approval ~=1000.\"\n ),\n interactionState: interactionStateSchema.optional(),\n recommendedNextAction: nextActionSchema.optional(),\n events: z\n .array(\n z.object({\n id: z.number().int(),\n type: z.enum([\n \"output\",\n \"progress\",\n \"approval_request\",\n \"approval_result\",\n \"result\",\n \"error\",\n ]),\n data: z.unknown(),\n timestamp: z.string(),\n })\n )\n .optional(),\n nextCursor: z.number().int().optional(),\n cursorResetTo: z.number().int().optional(),\n actions: z\n .array(\n z.object({\n type: z.enum([\"approval\", \"user_input\"]),\n requestId: z.string(),\n kind: z.enum([\"command\", \"fileChange\", \"user_input\"]),\n params: z.unknown(),\n itemId: z.string(),\n reason: z.string().optional(),\n approvalId: z.string().optional(),\n commandActions: z.array(z.unknown()).nullable().optional(),\n proposedExecpolicyAmendment: z.array(z.string()).nullable().optional(),\n createdAt: z.string(),\n })\n )\n .optional(),\n result: z\n .object({\n turnId: z.string(),\n output: z.string().optional(),\n structuredOutput: z.unknown().optional(),\n turn: z.unknown().optional(),\n status: z.string().optional(),\n turnError: z.unknown().optional(),\n error: z.string().optional(),\n completedAt: z.string(),\n })\n .optional(),\n compatWarnings: z.array(z.string()).optional(),\n truncated: z.boolean().optional(),\n truncatedFields: z.array(z.string()).optional(),\n ...errorOutputShape,\n },\n annotations: {\n title: \"Poll & Respond\",\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n async (args, extra) => {\n try {\n const result = await executeCodexCheck(args, sessionManager, extra.signal);\n const isError =\n typeof (result as { isError?: boolean }).isError === \"boolean\"\n ? (result as { isError: boolean }).isError\n : false;\n return {\n content: [{ type: \"text\" as const, text: JSON.stringify(result, null, 2) }],\n structuredContent: toStructuredContent(result),\n isError,\n };\n } catch (err: unknown) {\n const message = formatErrorMessage(err);\n return {\n content: [{ type: \"text\" as const, text: message }],\n structuredContent: { error: message, isError: true },\n isError: true,\n };\n }\n }\n );\n\n // Cleanup on server close\n const originalClose = server.close.bind(server);\n server.close = async () => {\n sessionManager.destroy();\n await originalClose();\n };\n\n return { server, sessionManager };\n}\n","/**\n * SessionManager — manages Codex session lifecycle, event buffering, and approval flow.\n */\nimport { randomUUID } from \"crypto\";\nimport { AppServerClient } from \"../app-server/client.js\";\nimport type { ICodexClient } from \"../app-server/client-interface.js\";\nimport type { AppServerSpawnOptions } from \"../app-server/lifecycle.js\";\nimport { resolveAndValidateCwd } from \"../utils/cwd.js\";\nimport { redactPaths } from \"../utils/redact.js\";\nimport { resolveAndValidateFilePath } from \"../utils/files.js\";\nimport {\n type RequestId,\n type CommandApprovalParams,\n type CommandApprovalResponse,\n type FileChangeApprovalResponse,\n type UserInputRequestResponse,\n type DynamicToolCallResponse,\n type LegacyApprovalResponse,\n type TurnStartParams,\n type UserInput,\n Methods,\n toSandboxPolicy,\n} from \"../app-server/protocol.js\";\nimport {\n type ApprovalPolicy,\n type EffortLevel,\n type Personality,\n type SessionInfo,\n type SessionStatus,\n type SandboxMode,\n type SummaryMode,\n type PublicSessionInfo,\n type SensitiveSessionInfo,\n type SessionEventType,\n type EventBuffer,\n type PendingRequest,\n type SessionStartResult,\n type CheckResult,\n type TurnResult,\n type ResponseMode,\n type PollOptions,\n type NetworkPolicyAmendment,\n ErrorCode,\n COMMAND_DECISIONS,\n FILE_CHANGE_DECISIONS,\n DEFAULT_POLL_INTERVAL,\n WAITING_APPROVAL_POLL_INTERVAL,\n DEFAULT_MAX_EVENTS,\n DEFAULT_EVENT_BUFFER_SIZE,\n DEFAULT_EVENT_BUFFER_HARD_SIZE,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n DEFAULT_IDLE_CLEANUP_MS,\n DEFAULT_RUNNING_CLEANUP_MS,\n DEFAULT_TERMINAL_CLEANUP_MS,\n CLEANUP_INTERVAL_MS,\n} from \"../types.js\";\n\nconst COALESCED_PROGRESS_DELTA_METHODS = new Set<string>([\n Methods.COMMAND_OUTPUT_DELTA,\n Methods.FILE_CHANGE_OUTPUT_DELTA,\n Methods.REASONING_TEXT_DELTA,\n Methods.REASONING_SUMMARY_DELTA,\n]);\n// Guard against unbounded in-memory string growth when app-server emits hot delta streams.\nconst MAX_COALESCED_DELTA_CHARS = 16_384;\nconst AUTH_REFRESH_UNSUPPORTED_CODE = -32000;\nconst AUTH_REFRESH_UNSUPPORTED_MESSAGE =\n \"account/chatgptAuthTokens/refresh unsupported: codex-mcp does not manage external ChatGPT auth tokens\";\nconst AUTH_REFRESH_TERMINAL_MESSAGE =\n \"account/chatgptAuthTokens/refresh unsupported: session is terminal\";\n\n// ── Shell noise filtering ────────────────────────────────────────────\n// On Windows, PowerShell profile output (oh-my-posh, PSReadLine, etc.) leaks\n// into every command execution, wasting tokens in MCP client contexts.\n// These patterns are stripped from COMMAND_OUTPUT_DELTA events before they\n// enter the event buffer. Disable with CODEX_MCP_DISABLE_NOISE_FILTER=1.\nconst NOISE_FILTER_ENABLED = process.env.CODEX_MCP_DISABLE_NOISE_FILTER !== \"1\";\nconst WINDOWS_TERMINAL_INTEGRATION_PREFIX = `${String.fromCharCode(0x1b)}]633;`;\n\nconst SHELL_NOISE_LINE_PATTERNS: RegExp[] = [\n // oh-my-posh migration / update prompts\n /oh-my-posh/i,\n // PSReadLine configuration errors\n /PSReadLine/i,\n /Set-PSReadLineOption/i,\n // PowerShell module auto-import warnings\n /^WARNING:\\s/,\n // PowerShell profile loading messages\n /Loading personal and system profiles/i,\n // conda/mamba init noise that leaks through profiles\n /^(\\(base\\)|\\(conda\\))/,\n // Common \"new version available\" nag lines from profile tools\n /A new version of .+ is available/i,\n];\n\n/**\n * Strip known shell profile noise lines from a command output delta.\n * Returns the cleaned string, or empty string if everything was noise.\n */\nfunction stripShellNoise(delta: string): string {\n if (!NOISE_FILTER_ENABLED) return delta;\n const lines = delta.split(\"\\n\");\n const cleaned = lines.filter(\n (line) =>\n !line.includes(WINDOWS_TERMINAL_INTEGRATION_PREFIX) &&\n !SHELL_NOISE_LINE_PATTERNS.some((re) => re.test(line))\n );\n // Preserve original trailing newline structure\n if (cleaned.length === 0) return \"\";\n return cleaned.join(\"\\n\");\n}\n\nexport interface SessionManagerOptions {\n /** Inject client factory (for tests or to select exec mode). */\n createClient?: () => ICodexClient;\n /** Disable background cleanup timer (useful for tests). */\n disableCleanup?: boolean;\n /** Disk persistence adapter (optional). */\n persistence?: import(\"./persistence.js\").SessionPersistence;\n}\n\nexport interface PollQueryOptions {\n responseMode?: ResponseMode;\n pollOptions?: PollOptions;\n}\n\nconst MAX_WAITERS_PER_SESSION = 4;\nconst MAX_WAIT_MS = 120_000;\n\nexport class SessionManager {\n private sessions = new Map<string, SessionInfo>();\n private clients = new Map<string, ICodexClient>();\n private cancellationInFlight = new Map<string, Promise<void>>();\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n private createClient: () => ICodexClient;\n /** Optional disk persistence adapter. */\n readonly persistence: import(\"./persistence.js\").SessionPersistence | null;\n /** Track last persisted status to avoid redundant writes. */\n private lastPersistedStatus = new Map<string, string>();\n /** Sessions for which a TTL warning event has already been emitted this cycle. */\n private ttlWarningEmitted = new Set<string>();\n /** Long-poll notifiers: set of resolve callbacks waiting for any change in a session. */\n private sessionNotifiers = new Map<string, Set<() => void>>();\n\n constructor(options: SessionManagerOptions = {}) {\n this.createClient = options.createClient ?? (() => new AppServerClient());\n this.persistence = options.persistence ?? null;\n\n if (!options.disableCleanup) {\n this.cleanupTimer = setInterval(() => this.cleanupSessions(), CLEANUP_INTERVAL_MS);\n if (this.cleanupTimer.unref) this.cleanupTimer.unref();\n }\n }\n\n /**\n * Ingest recovered sessions from disk into the in-memory session store.\n * Marks previously-running sessions as error, preserves completed results.\n */\n ingestRecovered(\n recovered: import(\"../persistence/recovery-scanner.js\").RecoveredSession[]\n ): void {\n for (const rec of recovered) {\n if (this.sessions.has(rec.sessionId)) continue; // skip duplicates\n const VALID_STATUSES: Set<string> = new Set([\n \"running\",\n \"idle\",\n \"waiting_approval\",\n \"error\",\n \"cancelled\",\n ]);\n const wasActive = rec.meta.status === \"running\" || rec.meta.status === \"waiting_approval\";\n // Validate status from disk — unknown statuses default to \"error\"\n const resolvedStatus: SessionStatus = wasActive\n ? \"error\"\n : VALID_STATUSES.has(rec.meta.status)\n ? (rec.meta.status as SessionStatus)\n : \"error\";\n const now = new Date().toISOString();\n const session: SessionInfo = {\n sessionId: rec.meta.sessionId,\n threadId: rec.meta.threadId as string | undefined,\n status: resolvedStatus,\n lastEventCursor: 0,\n createdAt: rec.meta.createdAt,\n lastActiveAt: now,\n cancelledAt: rec.meta.cancelledAt,\n cancelledReason: wasActive\n ? \"Server restarted while session was active\"\n : rec.meta.cancelledReason,\n cwd: rec.meta.cwd ?? \".\",\n model: rec.meta.model as string | undefined,\n approvalPolicy: rec.meta.approvalPolicy as ApprovalPolicy | undefined,\n sandbox: rec.meta.sandbox as SandboxMode | undefined,\n eventBuffer: createEventBuffer(),\n pendingRequests: new Map(),\n lastResult: rec.result as TurnResult | undefined,\n };\n this.sessions.set(rec.sessionId, session);\n // Resume event log sequence numbering\n if (rec.lastSeq >= 0) {\n this.persistence?.setEventLogNextSeq(rec.sessionId, rec.lastSeq + 1);\n }\n // Persist the updated status if it changed\n if (wasActive) {\n this.persistSessionIfChanged(session);\n }\n }\n }\n\n /**\n * Best-effort persist session metadata to disk when status changes.\n * Deduplicates writes if status hasn't changed since last persist.\n */\n private persistSessionIfChanged(session: SessionInfo): void {\n if (!this.persistence) return;\n const lastStatus = this.lastPersistedStatus.get(session.sessionId);\n if (lastStatus === session.status) return;\n try {\n this.persistence.writeSessionMeta(session);\n this.lastPersistedStatus.set(session.sessionId, session.status);\n } catch {\n /* best-effort */\n }\n }\n\n /**\n * Best-effort persist result to disk.\n */\n private persistResult(session: SessionInfo): void {\n if (!this.persistence || !session.lastResult) return;\n try {\n this.persistence.writeResult(session.sessionId, session.lastResult);\n } catch {\n /* best-effort */\n }\n }\n\n // ── Session Creation ─────────────────────────────────────────────\n\n async createSession(\n prompt: string,\n cwd: string,\n spawnOpts: AppServerSpawnOptions,\n effort: EffortLevel,\n advanced?: {\n baseInstructions?: string;\n developerInstructions?: string;\n personality?: Personality;\n ephemeral?: boolean;\n config?: Record<string, unknown>;\n images?: string[];\n outputSchema?: Record<string, unknown>;\n summary?: SummaryMode;\n approvalTimeoutMs?: number;\n }\n ): Promise<SessionStartResult> {\n const sessionId = `sess_${randomUUID().slice(0, 12)}`;\n const client = this.createClient();\n\n // Create session record\n const now = new Date().toISOString();\n const approvalTimeoutMs = advanced?.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MS;\n\n const resolvedImages = advanced?.images\n ? advanced.images.map((p) => resolveAndValidateFilePath(p, cwd, \"image\"))\n : undefined;\n const session: SessionInfo = {\n sessionId,\n status: \"running\",\n lastEventCursor: 0,\n createdAt: now,\n lastActiveAt: now,\n approvalTimeoutMs,\n cwd,\n model: spawnOpts.model,\n profile: spawnOpts.profile,\n approvalPolicy: spawnOpts.approvalPolicy,\n sandbox: spawnOpts.sandbox,\n config: spawnOpts.config,\n eventBuffer: createEventBuffer(),\n pendingRequests: new Map(),\n };\n\n this.sessions.set(sessionId, session);\n this.clients.set(sessionId, client);\n\n // Persist session metadata to disk\n try {\n this.persistence?.writeSessionMeta(session);\n } catch {\n /* best-effort */\n }\n\n try {\n // Register event handlers before start to prevent unhandled \"error\" events\n this.registerHandlers(sessionId, client, approvalTimeoutMs);\n\n // Start app-server subprocess\n await client.start(spawnOpts);\n\n // Persist PID info for orphan detection on next startup.\n if (client.childPid !== undefined) {\n try {\n this.persistence?.writePidInfo(sessionId, client.childPid, spawnOpts.model);\n } catch {\n /* best-effort */\n }\n }\n\n // Start thread\n const threadStartResult = await client.threadStart({\n cwd,\n model: spawnOpts.model,\n approvalPolicy: spawnOpts.approvalPolicy,\n sandbox: spawnOpts.sandbox,\n personality: advanced?.personality,\n ephemeral: advanced?.ephemeral,\n baseInstructions: advanced?.baseInstructions,\n developerInstructions: advanced?.developerInstructions,\n config: advanced?.config,\n });\n const threadId = extractThreadId(threadStartResult);\n session.threadId = threadId;\n\n // Build input array\n const input: UserInput[] = [{ type: \"text\", text: prompt }];\n if (resolvedImages) {\n for (const imagePath of resolvedImages) {\n input.push({ type: \"localImage\", path: imagePath });\n }\n }\n\n // Start first turn\n const turnStartResult = await client.turnStart({\n threadId,\n input,\n effort,\n summary: advanced?.summary,\n outputSchema: advanced?.outputSchema,\n });\n\n // Best-effort: seed activeTurnId from response if present (notifications are authoritative)\n const startedTurnId = extractTurnId(turnStartResult);\n if (startedTurnId) session.activeTurnId = startedTurnId;\n\n return {\n sessionId,\n threadId,\n status: \"running\",\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n } catch (err) {\n session.status = \"error\";\n pushEvent(session.eventBuffer, \"error\", {\n message: redactPaths(err instanceof Error ? err.message : String(err)),\n });\n await client.destroy();\n this.clients.delete(sessionId);\n this.sessions.delete(sessionId);\n throw err;\n }\n }\n\n // ── Session Reply ────────────────────────────────────────────────\n\n async replyToSession(\n sessionId: string,\n prompt: string,\n overrides?: {\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n effort?: EffortLevel;\n summary?: SummaryMode;\n personality?: Personality;\n sandbox?: SandboxMode;\n cwd?: string;\n outputSchema?: Record<string, unknown>;\n }\n ): Promise<SessionStartResult> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status === \"cancelled\") {\n throw new Error(\n `Error [${ErrorCode.CANCELLED}]: Session '${sessionId}' has been cancelled and cannot be resumed`\n );\n }\n if (session.status !== \"idle\" && session.status !== \"error\") {\n throw new Error(\n `Error [${ErrorCode.SESSION_BUSY}]: Session '${sessionId}' is ${session.status}, expected idle or error`\n );\n }\n if (!session.threadId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Session '${sessionId}' has no threadId, cannot reply`\n );\n }\n\n // Clear stale result/error events so the new turn starts clean\n clearTerminalEvents(session.eventBuffer);\n\n session.status = \"running\";\n session.lastActiveAt = new Date().toISOString();\n this.persistSessionIfChanged(session);\n\n const input: UserInput[] = [{ type: \"text\", text: prompt }];\n\n const resolvedCwd = overrides?.cwd\n ? resolveAndValidateCwd(overrides.cwd, session.cwd)\n : undefined;\n\n const turnParams: TurnStartParams = {\n threadId: session.threadId,\n input,\n model: overrides?.model,\n approvalPolicy: overrides?.approvalPolicy,\n effort: overrides?.effort,\n summary: overrides?.summary,\n personality: overrides?.personality,\n cwd: resolvedCwd,\n outputSchema: overrides?.outputSchema,\n };\n\n // Map sandbox string to protocol object\n if (overrides?.sandbox) {\n turnParams.sandboxPolicy = toSandboxPolicy(overrides.sandbox);\n }\n\n try {\n const turnStartResult = await client.turnStart(turnParams);\n const startedTurnId = extractTurnId(turnStartResult);\n if (startedTurnId) session.activeTurnId = startedTurnId;\n\n // Only persist cwd/sandbox overrides if the client actually supports them\n // on this turn. ExecClient in resume mode does not support -s/-p/-C, so\n // persisting those values would cause session metadata to drift from reality.\n const canOverride = client.supportsTurnOverrides;\n if (resolvedCwd && canOverride) session.cwd = resolvedCwd;\n if (overrides?.model) session.model = overrides.model;\n if (overrides?.approvalPolicy) {\n session.approvalPolicy = overrides.approvalPolicy as ApprovalPolicy;\n }\n if (overrides?.sandbox && canOverride) {\n session.sandbox = overrides.sandbox as SandboxMode;\n }\n } catch (err) {\n session.status = \"error\";\n pushEvent(session.eventBuffer, \"error\", {\n message: redactPaths(\n `Failed to start turn: ${err instanceof Error ? err.message : String(err)}`\n ),\n });\n throw err;\n }\n\n return {\n sessionId,\n threadId: session.threadId,\n status: \"running\",\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n }\n\n // ── Session Management ───────────────────────────────────────────\n\n listSessions(): PublicSessionInfo[] {\n return Array.from(this.sessions.values()).map(toPublicInfo);\n }\n\n /**\n * Count currently active sessions for lightweight runtime observability.\n * \"Active\" here means the session can still be interacted with.\n */\n getActiveSessionCount(): number {\n let count = 0;\n for (const session of this.sessions.values()) {\n if (\n session.status === \"running\" ||\n session.status === \"waiting_approval\" ||\n session.status === \"idle\"\n ) {\n count++;\n }\n }\n return count;\n }\n\n /**\n * Best-effort effective default model observed from recent sessions.\n * Returns null when no model can be inferred from in-memory state.\n */\n getObservedDefaultModel(): string | null {\n let latestModel: string | null = null;\n let latestTs = Number.NEGATIVE_INFINITY;\n\n for (const session of this.sessions.values()) {\n if (session.status === \"cancelled\") continue;\n if (typeof session.model !== \"string\" || session.model.length === 0) continue;\n\n const ts = Date.parse(session.lastActiveAt);\n const comparableTs = Number.isFinite(ts) ? ts : Number.NEGATIVE_INFINITY;\n if (comparableTs >= latestTs) {\n latestTs = comparableTs;\n latestModel = session.model;\n }\n }\n\n return latestModel;\n }\n\n getSession(\n sessionId: string,\n includeSensitive = false\n ): PublicSessionInfo | SensitiveSessionInfo {\n const session = this.getSessionOrThrow(sessionId);\n return includeSensitive ? toSensitiveInfo(session) : toPublicInfo(session);\n }\n\n getLastResult(sessionId: string): TurnResult | undefined {\n return this.getSessionOrThrow(sessionId).lastResult;\n }\n\n getPendingActionTypes(sessionId: string): Array<\"approval\" | \"user_input\"> {\n const session = this.getSessionOrThrow(sessionId);\n const actionTypes = new Set<\"approval\" | \"user_input\">();\n for (const req of session.pendingRequests.values()) {\n if (req.resolved) continue;\n actionTypes.add(req.kind === \"user_input\" ? \"user_input\" : \"approval\");\n }\n return Array.from(actionTypes);\n }\n\n async cancelSession(sessionId: string, reason?: string): Promise<void> {\n const existing = this.cancellationInFlight.get(sessionId);\n if (existing) {\n await existing;\n return;\n }\n\n const cancellation = this.performCancelSession(sessionId, reason);\n this.cancellationInFlight.set(sessionId, cancellation);\n try {\n await cancellation;\n } finally {\n this.cancellationInFlight.delete(sessionId);\n }\n }\n\n private async performCancelSession(sessionId: string, reason?: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n\n // Idempotent: already cancelled\n if (session.status === \"cancelled\") return;\n\n const client = this.clients.get(sessionId);\n\n session.status = \"cancelled\";\n const now = new Date().toISOString();\n session.cancelledAt = now;\n session.lastActiveAt = now;\n session.cancelledReason = reason ?? \"Cancelled by user\";\n\n // Persist cancelled status to disk\n this.persistSessionIfChanged(session);\n\n // Resolve and clear all pending requests (avoid leaving hanging server-initiated requests)\n for (const [reqId, req] of session.pendingRequests) {\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n if (!req.resolved && req.respond) {\n req.resolved = true;\n try {\n if (req.kind === \"command\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"fileChange\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"user_input\") req.respond({ answers: {} });\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to respond pending request during cancel: session=${sessionId} request=${reqId} kind=${req.kind} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n session.pendingRequests.delete(reqId);\n }\n\n pushEvent(\n session.eventBuffer,\n \"progress\",\n { message: \"Session cancelled\", cancelledReason: session.cancelledReason },\n true\n );\n\n const cancelledTurnId = session.activeTurnId ?? \"\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: cancelledTurnId,\n status: \"cancelled\",\n error: session.cancelledReason,\n completedAt: new Date().toISOString(),\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n { status: \"cancelled\", reason: session.cancelledReason, turnId: cancelledTurnId },\n true\n );\n // Wake long-poll waiters so they see the cancellation immediately\n this.notifyWaiters(sessionId);\n\n if (client) {\n await client.destroy();\n this.clients.delete(sessionId);\n }\n }\n\n async interruptSession(sessionId: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status !== \"running\" && session.status !== \"waiting_approval\") {\n throw new Error(\n `Error [${ErrorCode.SESSION_NOT_RUNNING}]: Cannot interrupt session in ${session.status} state`\n );\n }\n\n if (!session.threadId || !session.activeTurnId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Missing threadId or activeTurnId for interrupt`\n );\n }\n\n await client.turnInterrupt({\n threadId: session.threadId,\n turnId: session.activeTurnId,\n });\n }\n\n async cleanBackgroundTerminals(sessionId: string): Promise<void> {\n const session = this.getSessionOrThrow(sessionId);\n const client = this.getClientOrThrow(sessionId);\n\n if (session.status === \"cancelled\") {\n throw new Error(\n `Error [${ErrorCode.CANCELLED}]: Session '${sessionId}' has been cancelled and cannot be cleaned`\n );\n }\n if (!session.threadId) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Session '${sessionId}' has no threadId, cannot clean background terminals`\n );\n }\n\n await client.threadBackgroundTerminalsClean({ threadId: session.threadId });\n session.lastActiveAt = new Date().toISOString();\n pushEvent(\n session.eventBuffer,\n \"progress\",\n {\n method: Methods.THREAD_BACKGROUND_TERMINALS_CLEAN,\n threadId: session.threadId,\n status: \"requested\",\n },\n true\n );\n }\n\n async forkSession(sessionId: string): Promise<SessionStartResult> {\n const session = this.getSessionOrThrow(sessionId);\n const originalClient = this.getClientOrThrow(sessionId);\n\n if (!session.threadId) {\n throw new Error(`Error [${ErrorCode.INTERNAL}]: No threadId to fork`);\n }\n\n // Fork the thread on the ORIGINAL client (which holds the thread state)\n const forkResult = await originalClient.threadFork({ threadId: session.threadId });\n const forkedThreadId = extractThreadId(forkResult);\n\n // Create new session with its own app-server process\n const newSessionId = `sess_${randomUUID().slice(0, 12)}`;\n const newClient = this.createClient();\n const now = new Date().toISOString();\n\n const newSession: SessionInfo = {\n sessionId: newSessionId,\n status: \"idle\",\n lastEventCursor: 0,\n createdAt: now,\n lastActiveAt: now,\n approvalTimeoutMs: session.approvalTimeoutMs,\n cwd: session.cwd,\n model: session.model,\n profile: session.profile,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n config: session.config,\n eventBuffer: createEventBuffer(),\n pendingRequests: new Map(),\n };\n\n this.sessions.set(newSessionId, newSession);\n this.clients.set(newSessionId, newClient);\n\n try {\n // Register handlers before start to prevent unhandled \"error\" events\n this.registerHandlers(newSessionId, newClient, newSession.approvalTimeoutMs);\n\n // Start new app-server subprocess\n await newClient.start({\n profile: session.profile,\n model: session.model,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n config: session.config,\n });\n\n // Resume the forked thread on the new process\n await newClient.threadResume({ threadId: forkedThreadId });\n newSession.threadId = forkedThreadId;\n\n return {\n sessionId: newSessionId,\n threadId: forkedThreadId,\n status: \"idle\" as const,\n pollInterval: DEFAULT_POLL_INTERVAL,\n };\n } catch (err) {\n const errorMessage = redactPaths(err instanceof Error ? err.message : String(err));\n console.error(\n `[codex-mcp] forkSession failed after thread/fork created thread=${forkedThreadId}. The app-server protocol does not currently expose a guaranteed thread-delete RPC, so manual cleanup may be required.`\n );\n newSession.status = \"error\";\n try {\n await newClient.destroy();\n } catch (destroyErr) {\n console.error(\n `[codex-mcp] Failed to destroy forked app-server client after resume failure: session=${newSessionId} error=${destroyErr instanceof Error ? destroyErr.message : String(destroyErr)}`\n );\n }\n this.clients.delete(newSessionId);\n this.sessions.delete(newSessionId);\n throw new Error(\n `Error [${ErrorCode.THREAD_FORK_RESUME_FAILED}]: Failed to resume forked thread '${forkedThreadId}' in new app-server process: ${errorMessage}`\n );\n }\n }\n\n // ── Long-poll support ────────────────────────────────────────────\n\n /**\n * Wait until a new event is pushed, a new pending request arrives, a status\n * change occurs, or `timeoutMs` elapses (whichever comes first).\n *\n * Rejects with an error when more than MAX_WAITERS_PER_SESSION concurrent\n * waiters are already queued for the same session.\n */\n waitForChange(sessionId: string, timeoutMs: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n resolve();\n return;\n }\n\n let notifiers = this.sessionNotifiers.get(sessionId);\n if (!notifiers) {\n notifiers = new Set();\n this.sessionNotifiers.set(sessionId, notifiers);\n }\n if (notifiers.size >= MAX_WAITERS_PER_SESSION) {\n reject(\n new Error(\n `[codex-mcp] Too many concurrent long-poll waiters for session '${sessionId}' (max ${MAX_WAITERS_PER_SESSION})`\n )\n );\n return;\n }\n\n const clampedMs = Math.min(Math.max(0, timeoutMs), MAX_WAIT_MS);\n\n const done = (): void => {\n notifiers!.delete(notifyFn);\n if (notifiers!.size === 0) this.sessionNotifiers.delete(sessionId);\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", onAbort);\n resolve();\n };\n\n const notifyFn = done;\n const timer = setTimeout(done, clampedMs);\n if (timer.unref) timer.unref();\n\n const onAbort = (): void => done();\n if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n\n notifiers.add(notifyFn);\n });\n }\n\n /** Resolve all waiters for a session immediately (called on any state change). */\n private notifyWaiters(sessionId: string): void {\n const notifiers = this.sessionNotifiers.get(sessionId);\n if (!notifiers || notifiers.size === 0) return;\n // Snapshot to avoid mutation issues during iteration\n for (const fn of Array.from(notifiers)) {\n fn();\n }\n }\n\n // ── Event Polling ────────────────────────────────────────────────\n\n pollEvents(\n sessionId: string,\n cursor?: number,\n maxEvents = DEFAULT_MAX_EVENTS,\n options: PollQueryOptions = {}\n ): CheckResult {\n const session = this.getSessionOrThrow(sessionId);\n const buf = session.eventBuffer;\n const responseMode = options.responseMode ?? \"full\";\n const pollOptions = options.pollOptions;\n const includeEvents = pollOptions?.includeEvents ?? true;\n const includeActions = pollOptions?.includeActions ?? true;\n const includeResult = pollOptions?.includeResult ?? true;\n const maxBytes = pollOptions?.maxBytes;\n const effectiveCursor = cursor ?? session.lastEventCursor;\n\n // Find events with id >= cursor\n let events = includeEvents ? buf.events.filter((e) => e.id >= effectiveCursor) : [];\n let cursorResetTo: number | undefined;\n\n // Check if cursor is stale (events were evicted)\n if (includeEvents && buf.events.length > 0) {\n const earliest = buf.events[0].id;\n if (earliest > effectiveCursor) {\n cursorResetTo = earliest;\n events = buf.events;\n }\n }\n const cursorFloor = cursorResetTo ?? effectiveCursor;\n\n // Limit events\n if (events.length > maxEvents) {\n events = events.slice(0, maxEvents);\n }\n\n let nextCursor = clampCursorToLatest(\n events.length > 0 ? events[events.length - 1].id + 1 : cursorFloor,\n buf.nextId\n );\n\n // Collect pending actions\n const actions: CheckResult[\"actions\"] = [];\n if (includeActions) {\n for (const [, req] of session.pendingRequests) {\n if (!req.resolved) {\n actions.push({\n type: req.kind === \"user_input\" ? \"user_input\" : \"approval\",\n requestId: req.requestId,\n kind: req.kind,\n params: req.params,\n itemId: req.itemId,\n reason: req.reason,\n approvalId: req.approvalId,\n commandActions: req.commandActions,\n proposedExecpolicyAmendment: req.proposedExecpolicyAmendment,\n availableDecisions: req.availableDecisions,\n proposedNetworkPolicyAmendments: req.proposedNetworkPolicyAmendments,\n additionalPermissions: req.additionalPermissions,\n networkApprovalContext: req.networkApprovalContext,\n createdAt: req.createdAt,\n });\n }\n }\n }\n\n const result: CheckResult = {\n sessionId,\n status: session.status,\n pollInterval: pollIntervalForStatus(session.status),\n events: events.map((event) => serializeEventForMode(event, responseMode)),\n nextCursor,\n cursorResetTo,\n actions: actions.length > 0 ? actions : undefined,\n result:\n includeResult &&\n (session.status === \"idle\" || session.status === \"error\" || session.status === \"cancelled\")\n ? session.lastResult\n : undefined,\n };\n\n if (typeof maxBytes === \"number\") {\n const normalizedMaxBytes = Math.max(1, Math.floor(maxBytes));\n const hasAnyPayload =\n result.events.length > 0 ||\n typeof result.actions !== \"undefined\" ||\n typeof result.result !== \"undefined\";\n if (hasAnyPayload && payloadByteSize(result) > normalizedMaxBytes) {\n const truncatedFields: string[] = [];\n\n if (result.events.length > 0) {\n while (result.events.length > 0 && payloadByteSize(result) > normalizedMaxBytes) {\n result.events.pop();\n }\n nextCursor = clampCursorToLatest(\n result.events.length > 0\n ? result.events[result.events.length - 1]!.id + 1\n : cursorFloor,\n buf.nextId\n );\n result.nextCursor = nextCursor;\n truncatedFields.push(\"events\");\n }\n\n if (typeof result.result !== \"undefined\" && payloadByteSize(result) > normalizedMaxBytes) {\n result.result = undefined;\n truncatedFields.push(\"result\");\n }\n\n if (typeof result.actions !== \"undefined\" && payloadByteSize(result) > normalizedMaxBytes) {\n if (session.status === \"waiting_approval\") {\n result.actions = compactActionsForBudget(result.actions);\n while (result.actions.length > 1 && payloadByteSize(result) > normalizedMaxBytes) {\n result.actions.pop();\n }\n if (payloadByteSize(result) > normalizedMaxBytes) {\n result.actions = compactActionsToMinimum(result.actions);\n }\n truncatedFields.push(\"actions\");\n }\n\n if (\n typeof result.actions !== \"undefined\" &&\n payloadByteSize(result) > normalizedMaxBytes\n ) {\n result.actions = undefined;\n truncatedFields.push(\"actions\");\n }\n }\n\n if (truncatedFields.length > 0) {\n result.truncated = true;\n result.truncatedFields = Array.from(new Set(truncatedFields));\n addCompatWarningWithinBudget(\n result,\n `Response truncated to respect pollOptions.maxBytes=${normalizedMaxBytes}.`,\n maxBytes\n );\n }\n }\n }\n\n if (includeEvents) {\n session.lastEventCursor = persistMonotonicCursor(\n session.lastEventCursor,\n result.nextCursor,\n buf.nextId\n );\n }\n\n return result;\n }\n\n /**\n * Monotonic polling helper for respond_* flows.\n * Uses max(providedCursor, session.lastEventCursor) to avoid replaying\n * already-consumed history when clients send stale/default cursors.\n */\n pollEventsMonotonic(\n sessionId: string,\n cursor?: number,\n maxEvents = DEFAULT_MAX_EVENTS,\n options: PollQueryOptions = {}\n ): CheckResult {\n const session = this.getSessionOrThrow(sessionId);\n const sessionCursor = session.lastEventCursor;\n const staleCursor = typeof cursor === \"number\" && cursor < sessionCursor;\n const effectiveCursor =\n typeof cursor === \"number\" ? Math.max(cursor, sessionCursor) : undefined;\n const result = this.pollEvents(sessionId, effectiveCursor, maxEvents, options);\n if (staleCursor) {\n addCompatWarningWithinBudget(\n result,\n `Provided cursor ${cursor} is stale; used session cursor ${sessionCursor}.`,\n options.pollOptions?.maxBytes\n );\n }\n return result;\n }\n\n // ── Approval Response ────────────────────────────────────────────\n\n resolveApproval(\n sessionId: string,\n requestId: string,\n decision: string,\n extra?: {\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n denyMessage?: string;\n }\n ): void {\n const session = this.getSessionOrThrow(sessionId);\n const req = session.pendingRequests.get(requestId);\n\n if (!req || req.resolved) {\n throw new Error(\n `Error [${ErrorCode.REQUEST_NOT_FOUND}]: Request '${requestId}' not found or already resolved`\n );\n }\n\n // Validate decision by kind (avoid sending invalid protocol payloads)\n if (req.kind === \"command\") {\n const available = parseAvailableDecisionSet(req.availableDecisions);\n if (available && !available.has(decision)) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Decision '${decision}' is not available for this approval prompt`\n );\n }\n\n // Backward-compat: object-form decisions must be explicitly advertised by newer CLIs.\n if (!available && decision === \"applyNetworkPolicyAmendment\") {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Decision '${decision}' is not supported by this Codex CLI version (missing availableDecisions)`\n );\n }\n if (!COMMAND_DECISIONS.includes(decision as (typeof COMMAND_DECISIONS)[number])) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Invalid command decision '${decision}'`\n );\n }\n if (\n decision === \"acceptWithExecpolicyAmendment\" &&\n (!extra?.execpolicy_amendment || extra.execpolicy_amendment.length === 0)\n ) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`\n );\n }\n\n if (\n decision !== \"acceptWithExecpolicyAmendment\" &&\n extra?.execpolicy_amendment !== undefined\n ) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment is only valid for acceptWithExecpolicyAmendment`\n );\n }\n\n if (decision === \"applyNetworkPolicyAmendment\") {\n const amendment = extra?.network_policy_amendment;\n if (!amendment) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`\n );\n }\n if (amendment.action !== \"allow\" && amendment.action !== \"deny\") {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.action must be 'allow' or 'deny'`\n );\n }\n if (!amendment.host) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.host required for applyNetworkPolicyAmendment`\n );\n }\n } else if (extra?.network_policy_amendment !== undefined) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment is only valid for applyNetworkPolicyAmendment`\n );\n }\n } else if (req.kind === \"fileChange\") {\n if (!FILE_CHANGE_DECISIONS.includes(decision as (typeof FILE_CHANGE_DECISIONS)[number])) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Invalid fileChange decision '${decision}'`\n );\n }\n } else {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: Request '${requestId}' is not an approval request`\n );\n }\n\n // Build protocol response\n let response: unknown;\n if (req.kind === \"command\") {\n response = buildCommandApprovalResponse(decision, {\n execpolicy_amendment: extra?.execpolicy_amendment,\n network_policy_amendment: extra?.network_policy_amendment,\n });\n } else if (req.kind === \"fileChange\") {\n response = { decision } as FileChangeApprovalResponse;\n }\n\n if (!response) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Failed to build approval response for request '${requestId}'`\n );\n }\n\n // Mark as resolved while sending to avoid duplicate timeout/response races.\n req.resolved = true;\n req.decision = decision;\n try {\n sendPendingRequestResponseOrThrow(req, response, sessionId, requestId);\n } catch (error) {\n req.resolved = false;\n req.decision = undefined;\n session.pendingRequests.set(requestId, req);\n if (session.status !== \"cancelled\") {\n session.status = \"waiting_approval\";\n }\n throw error;\n }\n\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n\n // Push approval_result event\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: req.kind,\n approvalId: req.approvalId,\n decision,\n denyMessage: extra?.denyMessage,\n },\n true\n );\n\n // Remove resolved request to prevent unbounded growth\n session.pendingRequests.delete(requestId);\n\n // Restore status if no more pending requests\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n\n // Wake any long-poll waiters so they see the status transition\n this.notifyWaiters(sessionId);\n }\n\n // ── User Input Response ──────────────────────────────────────────\n\n resolveUserInput(\n sessionId: string,\n requestId: string,\n answers: Record<string, { answers: string[] }>\n ): void {\n const session = this.getSessionOrThrow(sessionId);\n const req = session.pendingRequests.get(requestId);\n\n if (!req || req.resolved || req.kind !== \"user_input\") {\n throw new Error(\n `Error [${ErrorCode.REQUEST_NOT_FOUND}]: User input request '${requestId}' not found`\n );\n }\n\n req.resolved = true;\n try {\n sendPendingRequestResponseOrThrow(\n req,\n { answers } as UserInputRequestResponse,\n sessionId,\n requestId\n );\n } catch (error) {\n req.resolved = false;\n session.pendingRequests.set(requestId, req);\n if (session.status !== \"cancelled\") {\n session.status = \"waiting_approval\";\n }\n throw error;\n }\n\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"user_input\",\n approvalId: req.approvalId,\n answers,\n },\n true\n );\n\n session.pendingRequests.delete(requestId);\n\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n\n // Wake any long-poll waiters so they see the status transition\n this.notifyWaiters(sessionId);\n }\n\n // ── Cleanup ──────────────────────────────────────────────────────\n\n destroy(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n this.cancellationInFlight.clear();\n\n // Clear all pending request timers\n for (const [, session] of this.sessions) {\n clearSessionPendingRequests(session);\n }\n\n for (const [id, client] of this.clients) {\n client.destroy().catch((err) => {\n console.error(\n `[codex-mcp] Failed to destroy app-server client during manager.destroy(): session=${id} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n this.clients.delete(id);\n }\n this.sessions.clear();\n }\n\n // ── Private ──────────────────────────────────────────────────────\n\n private getSessionOrThrow(sessionId: string): SessionInfo {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Error [${ErrorCode.SESSION_NOT_FOUND}]: Session '${sessionId}' not found`);\n }\n return session;\n }\n\n private getClientOrThrow(sessionId: string): ICodexClient {\n const client = this.clients.get(sessionId);\n if (!client) {\n throw new Error(\n `Error [${ErrorCode.SESSION_NOT_FOUND}]: No client for session '${sessionId}'`\n );\n }\n return client;\n }\n\n private registerHandlers(\n sessionId: string,\n client: ICodexClient,\n approvalTimeoutMs = DEFAULT_APPROVAL_TIMEOUT_MS\n ): void {\n const session = this.sessions.get(sessionId)!;\n\n // Handle notifications\n client.onNotification((method, params) => {\n session.lastActiveAt = new Date().toISOString();\n const p = params as Record<string, unknown>;\n\n switch (method) {\n case Methods.THREAD_STARTED: {\n const thread = isRecord(p.thread) ? p.thread : undefined;\n // Update session.threadId if the notification provides a real thread ID\n // (e.g. ExecClient returns a synthetic ID from threadStart(), then the\n // real ID arrives via the thread.started JSONL event).\n const notifiedThreadId =\n normalizeOptionalString(p.threadId) ?? normalizeOptionalString(thread?.id);\n if (notifiedThreadId && notifiedThreadId !== session.threadId) {\n session.threadId = notifiedThreadId;\n }\n pushEvent(session.eventBuffer, \"progress\", {\n method,\n ...p,\n threadId: notifiedThreadId,\n status: normalizeOptionalString(thread?.status),\n });\n break;\n }\n\n case Methods.THREAD_ARCHIVED:\n case Methods.THREAD_UNARCHIVED:\n case Methods.THREAD_NAME_UPDATED:\n case Methods.THREAD_TOKEN_USAGE_UPDATED:\n case Methods.FUZZY_FILE_SEARCH_SESSION_UPDATED:\n case Methods.FUZZY_FILE_SEARCH_SESSION_COMPLETED:\n case Methods.WINDOWS_WORLD_WRITABLE_WARNING:\n case Methods.ACCOUNT_LOGIN_COMPLETED:\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n break;\n\n case Methods.TURN_STARTED:\n if (session.status === \"cancelled\") break;\n {\n const turnObj = p.turn as Record<string, unknown> | undefined;\n const status = normalizeOptionalString(turnObj?.status);\n session.activeTurnId = normalizeOptionalString(turnObj?.id);\n pushEvent(session.eventBuffer, \"progress\", {\n method,\n ...p,\n turnId: session.activeTurnId,\n status,\n });\n }\n break;\n\n case Methods.TURN_COMPLETED: {\n if (session.status === \"cancelled\") break;\n const turnObj = p.turn as Record<string, unknown> | undefined;\n const completedTurnId = (turnObj?.id as string | undefined) ?? session.activeTurnId ?? \"\";\n session.status = \"idle\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: completedTurnId,\n output: turnObj?.output as string | undefined,\n structuredOutput: turnObj?.structuredOutput,\n turn: p.turn,\n status: turnObj?.status as string | undefined,\n turnError: turnObj?.error,\n completedAt: new Date().toISOString(),\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n {\n method,\n ...p,\n turnId: completedTurnId,\n status: normalizeOptionalString(turnObj?.status),\n },\n true\n );\n // Persist idle status + result to disk\n this.persistSessionIfChanged(session);\n this.persistResult(session);\n break;\n }\n\n case Methods.ERROR: {\n if (session.status === \"cancelled\") break;\n const willRetry = p.willRetry as boolean;\n if (!willRetry) {\n session.status = \"error\";\n }\n {\n const data: Record<string, unknown> = { method, ...p };\n if (typeof data.message === \"string\") data.message = redactPaths(data.message);\n if (typeof data.error === \"string\") data.error = redactPaths(data.error);\n if (willRetry) {\n pushEvent(\n session.eventBuffer,\n \"progress\",\n {\n ...data,\n method: \"codex-mcp/reconnect\",\n sourceMethod: method,\n phase: \"retrying\",\n },\n true\n );\n } else {\n pushEvent(session.eventBuffer, \"error\", data, true);\n // Persist error status to disk\n this.persistSessionIfChanged(session);\n }\n }\n break;\n }\n\n case Methods.AGENT_MESSAGE_DELTA:\n pushEvent(session.eventBuffer, \"output\", { method, delta: p.delta, itemId: p.itemId });\n break;\n\n case Methods.ITEM_STARTED:\n case Methods.ITEM_COMPLETED:\n case Methods.RAW_RESPONSE_ITEM_COMPLETED:\n {\n const item = p.item as Record<string, unknown> | undefined;\n const itemType = item && typeof item.type === \"string\" ? item.type : undefined;\n const status = normalizeOptionalString(item?.status);\n // Keep user/agent message-like items as output; everything else is progress.\n const eventType: SessionEventType =\n itemType === \"agentMessage\" || itemType === \"userMessage\" ? \"output\" : \"progress\";\n pushEvent(session.eventBuffer, eventType, {\n method,\n ...p,\n item: p.item,\n status,\n });\n }\n break;\n\n case Methods.COMMAND_OUTPUT_DELTA: {\n // Filter known shell profile noise (PowerShell oh-my-posh, PSReadLine, etc.)\n if (typeof p.delta === \"string\") {\n const cleaned = stripShellNoise(p.delta);\n if (cleaned.length === 0) break; // entire delta was noise, skip event\n pushEvent(session.eventBuffer, \"progress\", { method, ...p, delta: cleaned });\n } else {\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n }\n break;\n }\n case Methods.COMMAND_TERMINAL_INTERACTION:\n case Methods.FILE_CHANGE_OUTPUT_DELTA:\n case Methods.REASONING_TEXT_DELTA:\n case Methods.REASONING_SUMMARY_DELTA:\n case Methods.REASONING_SUMMARY_PART_ADDED:\n case Methods.PLAN_DELTA:\n case Methods.MCP_TOOL_PROGRESS:\n case Methods.TURN_DIFF_UPDATED:\n case Methods.TURN_PLAN_UPDATED:\n case Methods.MODEL_REROUTED:\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\n break;\n\n default:\n // Ignore other notifications (account, config, etc.)\n break;\n }\n // Wake any long-poll waiters after every notification\n this.notifyWaiters(sessionId);\n });\n\n // Handle server-initiated requests\n client.onServerRequest((id: RequestId, method: string, params: unknown) => {\n // Do not transition terminal sessions back to waiting_approval.\n if (session.status === \"cancelled\" || session.status === \"error\") {\n respondToTerminalSessionRequest(client, id, method);\n return;\n }\n\n session.lastActiveAt = new Date().toISOString();\n const p = params as Record<string, unknown>;\n\n switch (method) {\n case Methods.COMMAND_APPROVAL: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const approvalParams = params as CommandApprovalParams & Record<string, unknown>;\n const reason = normalizeOptionalString(approvalParams.reason);\n const approvalId = normalizeOptionalString(approvalParams.approvalId);\n const commandActions = Array.isArray(approvalParams.commandActions)\n ? approvalParams.commandActions\n : null;\n const proposedExecpolicyAmendment = normalizeStringArrayOrNull(\n approvalParams.proposedExecpolicyAmendment\n );\n const availableDecisions = Array.isArray(approvalParams.availableDecisions)\n ? (approvalParams.availableDecisions as unknown[])\n : null;\n const proposedNetworkPolicyAmendments = Array.isArray(\n approvalParams.proposedNetworkPolicyAmendments\n )\n ? (approvalParams.proposedNetworkPolicyAmendments as unknown[])\n : null;\n const additionalPermissions =\n \"additionalPermissions\" in approvalParams\n ? (approvalParams.additionalPermissions as unknown)\n : undefined;\n const networkApprovalContext =\n \"networkApprovalContext\" in approvalParams\n ? (approvalParams.networkApprovalContext as unknown)\n : undefined;\n const pending: PendingRequest = {\n requestId,\n kind: \"command\",\n params,\n itemId: normalizeOptionalString(approvalParams.itemId) ?? \"\",\n threadId: normalizeOptionalString(approvalParams.threadId) ?? \"\",\n turnId: normalizeOptionalString(approvalParams.turnId) ?? \"\",\n reason,\n approvalId,\n commandActions,\n proposedExecpolicyAmendment,\n availableDecisions,\n proposedNetworkPolicyAmendments,\n additionalPermissions,\n networkApprovalContext,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n // Timeout\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n pending.decision = \"decline\";\n try {\n client.respondToServer(id, { decision: \"decline\" } as CommandApprovalResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-decline command approval timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"command\",\n approvalId,\n decision: \"decline\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n this.notifyWaiters(sessionId);\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"command\",\n itemId: approvalParams.itemId,\n approvalId,\n command: approvalParams.command,\n cwd: approvalParams.cwd,\n reason,\n commandActions,\n proposedExecpolicyAmendment,\n availableDecisions,\n proposedNetworkPolicyAmendments,\n additionalPermissions,\n networkApprovalContext,\n },\n true\n );\n break;\n }\n\n case Methods.FILE_CHANGE_APPROVAL: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const reason = normalizeOptionalString(p.reason);\n const pending: PendingRequest = {\n requestId,\n kind: \"fileChange\",\n params,\n itemId: p.itemId as string,\n threadId: p.threadId as string,\n turnId: p.turnId as string,\n reason,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n pending.decision = \"decline\";\n try {\n client.respondToServer(id, { decision: \"decline\" } as FileChangeApprovalResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-decline file-change approval timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"fileChange\",\n decision: \"decline\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n this.notifyWaiters(sessionId);\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"fileChange\",\n itemId: p.itemId,\n reason,\n },\n true\n );\n break;\n }\n\n case Methods.USER_INPUT_REQUEST: {\n const requestId = `req_${randomUUID().slice(0, 8)}`;\n const pending: PendingRequest = {\n requestId,\n kind: \"user_input\",\n params,\n itemId: p.itemId as string,\n threadId: p.threadId as string,\n turnId: p.turnId as string,\n createdAt: new Date().toISOString(),\n resolved: false,\n respond: (result) => client.respondToServer(id, result),\n };\n\n pending.timeoutHandle = createUnrefTimeout(() => {\n if (!pending.resolved) {\n pending.resolved = true;\n try {\n client.respondToServer(id, { answers: {} } as UserInputRequestResponse);\n } catch (err) {\n console.error(\n `[codex-mcp] Failed to auto-answer user-input timeout: session=${sessionId} request=${requestId} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n pushEvent(\n session.eventBuffer,\n \"approval_result\",\n {\n requestId,\n kind: \"user_input\",\n timeout: true,\n },\n true\n );\n session.pendingRequests.delete(requestId);\n if (session.pendingRequests.size === 0 && session.status === \"waiting_approval\") {\n session.status = \"running\";\n }\n this.notifyWaiters(sessionId);\n }\n }, approvalTimeoutMs);\n\n session.pendingRequests.set(requestId, pending);\n session.status = \"waiting_approval\";\n pushEvent(\n session.eventBuffer,\n \"approval_request\",\n {\n requestId,\n kind: \"user_input\",\n questions: p.questions,\n },\n true\n );\n break;\n }\n\n case Methods.DYNAMIC_TOOL_CALL:\n // Auto-reject: codex-mcp doesn't support dynamic tool calls\n client.respondToServer(id, {\n success: false,\n contentItems: [{ type: \"inputText\", text: \"Not supported by codex-mcp\" }],\n } as DynamicToolCallResponse);\n break;\n\n case Methods.AUTH_TOKEN_REFRESH:\n client.respondErrorToServer(\n id,\n AUTH_REFRESH_UNSUPPORTED_CODE,\n AUTH_REFRESH_UNSUPPORTED_MESSAGE\n );\n break;\n\n case Methods.LEGACY_PATCH_APPROVAL:\n case Methods.LEGACY_EXEC_APPROVAL:\n client.respondToServer(id, { decision: \"denied\" } as LegacyApprovalResponse);\n console.error(`[codex-mcp] Legacy approval request received: ${method}`);\n break;\n\n default:\n client.respondErrorToServer(id, -32601, `Unhandled server request: ${method}`);\n break;\n }\n // Wake any long-poll waiters after every server-initiated request (new pending approval)\n this.notifyWaiters(sessionId);\n });\n\n // Handle subprocess exit\n client.on(\"exit\", (code: number | null) => {\n clearSessionPendingRequests(session);\n if (session.status === \"running\" || session.status === \"waiting_approval\") {\n session.status = \"error\";\n const message = `app-server exited unexpectedly (code: ${code})`;\n setTerminalErrorResult(session, message);\n pushEvent(\n session.eventBuffer,\n \"error\",\n {\n message,\n },\n true\n );\n this.persistSessionIfChanged(session);\n this.persistResult(session);\n this.notifyWaiters(sessionId);\n }\n });\n\n // Handle subprocess spawn errors (must listen to prevent uncaught exception)\n client.on(\"error\", (err: Error) => {\n clearSessionPendingRequests(session);\n if (session.status === \"running\" || session.status === \"waiting_approval\") {\n session.status = \"error\";\n const message = redactPaths(`app-server error: ${err.message}`);\n setTerminalErrorResult(session, message);\n pushEvent(\n session.eventBuffer,\n \"error\",\n {\n message,\n },\n true\n );\n this.persistSessionIfChanged(session);\n this.persistResult(session);\n this.notifyWaiters(sessionId);\n }\n });\n }\n\n private cleanupSessions(): void {\n const now = Date.now();\n const TTL_WARNING_THRESHOLD_MS = 60_000;\n for (const [id, session] of this.sessions) {\n const lastActive = new Date(session.lastActiveAt).getTime();\n if (Number.isNaN(lastActive)) {\n // Invalid timestamp — clean up immediately\n this.ttlWarningEmitted.delete(id);\n this.requestCancellation(id, \"Invalid timestamp\");\n continue;\n }\n const age = now - lastActive;\n\n if (session.status === \"idle\" && age > DEFAULT_IDLE_CLEANUP_MS) {\n this.ttlWarningEmitted.delete(id);\n this.requestCancellation(id, \"Idle timeout\");\n } else if (session.status === \"waiting_approval\" && age > DEFAULT_RUNNING_CLEANUP_MS) {\n this.ttlWarningEmitted.delete(id);\n this.requestCancellation(id, \"Approval timeout\");\n } else if (session.status === \"running\" && age > DEFAULT_RUNNING_CLEANUP_MS) {\n this.ttlWarningEmitted.delete(id);\n this.requestCancellation(id, \"Running timeout\");\n } else if (\n (session.status === \"cancelled\" || session.status === \"error\") &&\n age > DEFAULT_TERMINAL_CLEANUP_MS\n ) {\n this.ttlWarningEmitted.delete(id);\n this.clients\n .get(id)\n ?.destroy()\n .catch((err) => {\n console.error(\n `[codex-mcp] Failed to destroy app-server client during cleanup: session=${id} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n this.clients.delete(id);\n this.sessions.delete(id);\n this.lastPersistedStatus.delete(id);\n this.ttlWarningEmitted.delete(id);\n } else {\n // Check if this session is within the TTL warning window.\n let ttlMs: number | undefined;\n if (session.status === \"idle\") {\n ttlMs = DEFAULT_IDLE_CLEANUP_MS;\n } else if (session.status === \"running\" || session.status === \"waiting_approval\") {\n ttlMs = DEFAULT_RUNNING_CLEANUP_MS;\n }\n if (ttlMs !== undefined && !this.ttlWarningEmitted.has(id)) {\n const timeUntilExpiry = ttlMs - age;\n if (timeUntilExpiry <= TTL_WARNING_THRESHOLD_MS && timeUntilExpiry > 0) {\n this.ttlWarningEmitted.add(id);\n pushEvent(session.eventBuffer, \"progress\", {\n method: \"codex-mcp/ttl_warning\",\n type: \"ttl_warning\",\n ttlRemainingMs: timeUntilExpiry,\n sessionId: id,\n });\n }\n }\n }\n }\n }\n\n private requestCancellation(sessionId: string, reason: string): void {\n if (this.cancellationInFlight.has(sessionId)) return;\n this.cancelSession(sessionId, reason).catch((err) => {\n console.error(\n `[codex-mcp] Failed to cancel session during cleanup: session=${sessionId} reason=${reason} error=${err instanceof Error ? err.message : String(err)}`\n );\n });\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction pollIntervalForStatus(status: SessionStatus): number | undefined {\n if (status === \"waiting_approval\") return WAITING_APPROVAL_POLL_INTERVAL;\n if (status === \"running\") return DEFAULT_POLL_INTERVAL;\n return undefined; // terminal states don't need polling\n}\n\nfunction createEventBuffer(): EventBuffer {\n return {\n events: [],\n maxSize: DEFAULT_EVENT_BUFFER_SIZE,\n hardMaxSize: DEFAULT_EVENT_BUFFER_HARD_SIZE,\n nextId: 0,\n };\n}\n\n/** Clear stale result/error events when transitioning idle/error → running */\nfunction clearTerminalEvents(buf: EventBuffer): void {\n buf.events = buf.events.filter((e) => e.type !== \"result\" && e.type !== \"error\");\n}\n\nfunction clearSessionPendingRequests(session: SessionInfo): void {\n const entries = Array.from(session.pendingRequests.entries());\n session.pendingRequests.clear();\n for (const [, req] of entries) {\n if (req.timeoutHandle) clearTimeout(req.timeoutHandle);\n // Best-effort: send cancel response so the backend isn't left waiting.\n if (!req.resolved && req.respond) {\n try {\n if (req.kind === \"command\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"fileChange\") req.respond({ decision: \"cancel\" });\n else if (req.kind === \"user_input\") req.respond({ answers: {} });\n } catch {\n // Client already exited — response delivery is best-effort\n }\n }\n req.resolved = true;\n }\n}\n\nfunction setTerminalErrorResult(session: SessionInfo, message: string): void {\n const completedAt = new Date().toISOString();\n const failedTurnId = session.activeTurnId ?? \"\";\n session.activeTurnId = undefined;\n session.lastResult = {\n turnId: failedTurnId,\n status: \"error\",\n error: message,\n completedAt,\n };\n pushEvent(\n session.eventBuffer,\n \"result\",\n {\n status: \"error\",\n turnId: failedTurnId,\n error: message,\n completedAt,\n },\n true\n );\n}\n\nfunction createUnrefTimeout(handler: () => void, timeoutMs: number): ReturnType<typeof setTimeout> {\n const timer = setTimeout(handler, timeoutMs);\n if (typeof (timer as { unref?: () => void }).unref === \"function\") {\n (timer as { unref: () => void }).unref();\n }\n return timer;\n}\n\nfunction respondToTerminalSessionRequest(\n client: ICodexClient,\n id: RequestId,\n method: string\n): void {\n switch (method) {\n case Methods.COMMAND_APPROVAL:\n case Methods.FILE_CHANGE_APPROVAL:\n client.respondToServer(id, { decision: \"cancel\" });\n break;\n case Methods.USER_INPUT_REQUEST:\n client.respondToServer(id, { answers: {} } as UserInputRequestResponse);\n break;\n case Methods.DYNAMIC_TOOL_CALL:\n client.respondToServer(id, {\n success: false,\n contentItems: [{ type: \"inputText\", text: \"Session is terminal\" }],\n } as DynamicToolCallResponse);\n break;\n case Methods.AUTH_TOKEN_REFRESH:\n client.respondErrorToServer(id, AUTH_REFRESH_UNSUPPORTED_CODE, AUTH_REFRESH_TERMINAL_MESSAGE);\n break;\n case Methods.LEGACY_PATCH_APPROVAL:\n case Methods.LEGACY_EXEC_APPROVAL:\n client.respondToServer(id, { decision: \"denied\" } as LegacyApprovalResponse);\n break;\n default:\n client.respondErrorToServer(id, -32601, `Unhandled server request: ${method}`);\n break;\n }\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction normalizeStringArrayOrNull(value: unknown): string[] | null {\n if (!Array.isArray(value)) return null;\n const normalized = value.filter((entry): entry is string => typeof entry === \"string\");\n return normalized;\n}\n\nfunction sendPendingRequestResponseOrThrow(\n req: PendingRequest,\n response: unknown,\n sessionId: string,\n requestId: string\n): void {\n if (!req.respond) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Missing response handler for request '${requestId}'`\n );\n }\n try {\n req.respond(response);\n } catch (err) {\n throw new Error(\n `Error [${ErrorCode.INTERNAL}]: Failed to send response: session=${sessionId} request=${requestId} kind=${req.kind} error=${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\nfunction compactActionsForBudget(\n actions: NonNullable<CheckResult[\"actions\"]>\n): NonNullable<CheckResult[\"actions\"]> {\n return actions.map((action) => ({\n type: action.type,\n requestId: action.requestId,\n kind: action.kind,\n params: compactActionParamsForBudget(action),\n itemId: action.itemId,\n createdAt: action.createdAt,\n commandActions: action.commandActions,\n proposedExecpolicyAmendment: action.proposedExecpolicyAmendment,\n availableDecisions: action.availableDecisions,\n additionalPermissions: action.additionalPermissions,\n networkApprovalContext: action.networkApprovalContext,\n proposedNetworkPolicyAmendments: action.proposedNetworkPolicyAmendments,\n }));\n}\n\nfunction compactActionParamsForBudget(\n action: NonNullable<CheckResult[\"actions\"]>[number]\n): unknown {\n if (action.kind !== \"user_input\" || !isRecord(action.params)) {\n return undefined;\n }\n\n const rawQuestions = action.params.questions;\n if (!Array.isArray(rawQuestions)) {\n return undefined;\n }\n\n const compactQuestions: Array<{ id: string }> = [];\n for (const entry of rawQuestions) {\n if (!isRecord(entry)) continue;\n const id = typeof entry.id === \"string\" ? entry.id : undefined;\n if (id) {\n compactQuestions.push({ id });\n }\n }\n\n return compactQuestions.length > 0 ? { questions: compactQuestions } : undefined;\n}\n\nfunction compactActionsToMinimum(\n actions: NonNullable<CheckResult[\"actions\"]>\n): NonNullable<CheckResult[\"actions\"]> {\n if (actions.length === 0) return actions;\n const first = actions[0]!;\n return [\n {\n type: first.type,\n requestId: first.requestId,\n kind: first.kind,\n params: undefined,\n itemId: first.itemId,\n createdAt: first.createdAt,\n commandActions: first.commandActions,\n proposedExecpolicyAmendment: first.proposedExecpolicyAmendment,\n availableDecisions: first.availableDecisions,\n additionalPermissions: first.additionalPermissions,\n networkApprovalContext: first.networkApprovalContext,\n proposedNetworkPolicyAmendments: first.proposedNetworkPolicyAmendments,\n },\n ];\n}\n\nfunction clampCursorToLatest(cursor: number, latestCursor: number): number {\n return Math.max(0, Math.min(cursor, latestCursor));\n}\n\nfunction persistMonotonicCursor(\n previousCursor: number,\n nextCursor: number,\n latestCursor: number\n): number {\n const boundedCursor = clampCursorToLatest(nextCursor, latestCursor);\n return Math.max(previousCursor, boundedCursor);\n}\n\nfunction pushEvent(buf: EventBuffer, type: SessionEventType, data: unknown, pinned = false): void {\n if (tryCoalesceProgressDelta(buf, type, data, pinned)) return;\n\n buf.events.push({\n id: buf.nextId++,\n type,\n data,\n timestamp: new Date().toISOString(),\n pinned,\n });\n evictEvents(buf);\n}\n\nfunction serializeEventForMode(\n event: { id: number; type: SessionEventType; data: unknown; timestamp: string },\n mode: ResponseMode\n): { id: number; type: SessionEventType; data: unknown; timestamp: string } {\n if (mode === \"full\") {\n return { id: event.id, type: event.type, data: event.data, timestamp: event.timestamp };\n }\n const minimal = mode === \"minimal\";\n return {\n id: event.id,\n type: event.type,\n data: compactEventData(event.data, minimal),\n timestamp: event.timestamp,\n };\n}\n\nfunction compactEventData(data: unknown, minimal: boolean): unknown {\n if (!isRecord(data)) return data;\n\n const compact: Record<string, unknown> = {};\n if (typeof data.method === \"string\") {\n compact.method = data.method;\n }\n\n const preferredKeys = minimal\n ? [\n \"delta\",\n \"message\",\n \"error\",\n \"status\",\n \"phase\",\n \"itemId\",\n \"turnId\",\n \"requestId\",\n \"kind\",\n \"decision\",\n \"timeout\",\n \"willRetry\",\n \"retryCount\",\n \"maxRetries\",\n ]\n : [\n \"delta\",\n \"message\",\n \"error\",\n \"status\",\n \"phase\",\n \"itemId\",\n \"turnId\",\n \"requestId\",\n \"kind\",\n \"decision\",\n \"timeout\",\n \"willRetry\",\n \"retryCount\",\n \"maxRetries\",\n \"reason\",\n \"command\",\n \"cwd\",\n \"sourceMethod\",\n ];\n\n for (const key of preferredKeys) {\n if (key in data) {\n compact[key] = data[key];\n }\n }\n\n if (typeof compact.delta === \"string\") {\n const limit = minimal ? 256 : 2048;\n if (compact.delta.length > limit) {\n compact.delta = compact.delta.slice(0, limit);\n compact.deltaTruncated = true;\n }\n }\n\n if (Object.keys(compact).length === 0) {\n return minimal ? { summary: \"omitted for minimal response mode\" } : { ...data };\n }\n\n return compact;\n}\n\nfunction payloadByteSize(value: unknown): number {\n return Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nfunction addCompatWarning(result: CheckResult, warning: string): void {\n if (!result.compatWarnings) {\n result.compatWarnings = [];\n }\n result.compatWarnings.push(warning);\n}\n\nfunction addCompatWarningWithinBudget(\n result: CheckResult,\n warning: string,\n maxBytes?: number\n): void {\n const previousWarnings = result.compatWarnings ? [...result.compatWarnings] : undefined;\n addCompatWarning(result, warning);\n\n if (typeof maxBytes !== \"number\") {\n return;\n }\n\n const normalizedMaxBytes = Math.max(1, Math.floor(maxBytes));\n if (payloadByteSize(result) <= normalizedMaxBytes) {\n return;\n }\n\n if (!previousWarnings || previousWarnings.length === 0) {\n result.compatWarnings = undefined;\n return;\n }\n result.compatWarnings = previousWarnings;\n}\n\nfunction tryCoalesceProgressDelta(\n buf: EventBuffer,\n type: SessionEventType,\n data: unknown,\n pinned: boolean\n): boolean {\n if (type !== \"progress\" || pinned || buf.events.length === 0) return false;\n if (!isRecord(data)) return false;\n\n const method = data.method;\n const delta = data.delta;\n const itemId = data.itemId;\n const turnId = data.turnId;\n const itemKey = typeof itemId === \"string\" ? itemId : \"\";\n const turnKey = typeof turnId === \"string\" ? turnId : \"\";\n if (\n typeof method !== \"string\" ||\n !COALESCED_PROGRESS_DELTA_METHODS.has(method) ||\n typeof delta !== \"string\"\n ) {\n return false;\n }\n // Keep coalescing scoped to a stable stream key (itemId or turnId).\n if (itemKey.length === 0 && turnKey.length === 0) return false;\n\n const last = buf.events[buf.events.length - 1];\n if (last.type !== \"progress\" || last.pinned || !isRecord(last.data)) return false;\n\n const lastMethod = last.data.method;\n const lastItemId = last.data.itemId;\n const lastTurnId = last.data.turnId;\n const lastDelta = last.data.delta;\n const lastItemKey = typeof lastItemId === \"string\" ? lastItemId : \"\";\n const lastTurnKey = typeof lastTurnId === \"string\" ? lastTurnId : \"\";\n if (\n lastMethod !== method ||\n lastItemKey !== itemKey ||\n lastTurnKey !== turnKey ||\n typeof lastDelta !== \"string\"\n ) {\n return false;\n }\n\n if (lastDelta.length + delta.length > MAX_COALESCED_DELTA_CHARS) return false;\n\n last.data = {\n ...last.data,\n delta: `${lastDelta}${delta}`,\n };\n last.timestamp = new Date().toISOString();\n return true;\n}\n\nfunction evictEvents(buf: EventBuffer): void {\n // Soft limit: evict in a single pass to avoid O(n²) repeated findIndex+splice.\n if (buf.events.length > buf.maxSize) {\n const overflow = buf.events.length - buf.maxSize;\n const unpinnedIdx: number[] = [];\n const approvalResultIdx: number[] = [];\n for (let i = 0; i < buf.events.length; i++) {\n const event = buf.events[i];\n if (!event.pinned) unpinnedIdx.push(i);\n else if (event.type === \"approval_result\") approvalResultIdx.push(i);\n }\n\n const drop = new Set<number>();\n for (const idx of unpinnedIdx) {\n if (drop.size >= overflow) break;\n drop.add(idx);\n }\n for (const idx of approvalResultIdx) {\n if (drop.size >= overflow) break;\n drop.add(idx);\n }\n\n if (drop.size > 0) {\n buf.events = buf.events.filter((_, idx) => !drop.has(idx));\n }\n }\n\n if (buf.events.length <= buf.hardMaxSize) return;\n\n // Hard limit: select evictions in one pass to avoid O(n^2) repeated scans.\n const overflow = buf.events.length - buf.hardMaxSize;\n const approvalResultIdx: number[] = [];\n const nonPinnedIdx: number[] = [];\n const pinnedNonCriticalIdx: number[] = [];\n const criticalPinnedIdx: number[] = [];\n\n for (let i = 0; i < buf.events.length; i++) {\n const event = buf.events[i];\n if (event.type === \"approval_result\") {\n approvalResultIdx.push(i);\n } else if (!event.pinned) {\n nonPinnedIdx.push(i);\n } else if (!isHardPinnedCriticalType(event.type)) {\n pinnedNonCriticalIdx.push(i);\n } else {\n criticalPinnedIdx.push(i);\n }\n }\n\n const drop = new Set<number>();\n const take = (indices: number[]) => {\n for (const idx of indices) {\n if (drop.size >= overflow) break;\n drop.add(idx);\n }\n };\n\n take(approvalResultIdx);\n take(nonPinnedIdx);\n take(pinnedNonCriticalIdx);\n const beforeCritical = drop.size;\n take(criticalPinnedIdx);\n\n if (drop.size > beforeCritical) {\n console.error(\n \"[codex-mcp] Event buffer hard limit exceeded with only critical pinned events; evicting oldest event.\"\n );\n }\n\n if (drop.size === 0) return;\n buf.events = buf.events.filter((_, idx) => !drop.has(idx));\n}\n\nfunction isHardPinnedCriticalType(type: SessionEventType): boolean {\n return type === \"approval_request\" || type === \"result\" || type === \"error\";\n}\n\nfunction toPublicInfo(session: SessionInfo): PublicSessionInfo {\n return {\n sessionId: session.sessionId,\n status: session.status,\n createdAt: session.createdAt,\n lastActiveAt: session.lastActiveAt,\n cancelledAt: session.cancelledAt,\n cancelledReason: session.cancelledReason,\n model: session.model,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n pendingRequestCount: Array.from(session.pendingRequests.values()).filter((r) => !r.resolved)\n .length,\n };\n}\n\nfunction toSensitiveInfo(session: SessionInfo): SensitiveSessionInfo {\n return {\n ...toPublicInfo(session),\n threadId: session.threadId,\n cwd: session.cwd,\n profile: session.profile,\n config: session.config,\n };\n}\n\nfunction buildCommandApprovalResponse(\n decision: string,\n extra?: {\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n }\n): CommandApprovalResponse {\n if (decision === \"acceptWithExecpolicyAmendment\") {\n const execpolicy_amendment = extra?.execpolicy_amendment;\n if (!execpolicy_amendment || execpolicy_amendment.length === 0) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`\n );\n }\n return {\n decision: {\n acceptWithExecpolicyAmendment: {\n execpolicy_amendment,\n },\n },\n };\n }\n\n if (decision === \"applyNetworkPolicyAmendment\") {\n const amendment = extra?.network_policy_amendment;\n if (!amendment) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`\n );\n }\n return {\n decision: {\n applyNetworkPolicyAmendment: {\n network_policy_amendment: amendment,\n },\n },\n };\n }\n return { decision: decision as \"accept\" | \"acceptForSession\" | \"decline\" | \"cancel\" };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction parseAvailableDecisionSet(available: unknown[] | null | undefined): Set<string> | null {\n if (!Array.isArray(available) || available.length === 0) return null;\n const set = new Set<string>();\n for (const entry of available) {\n if (typeof entry === \"string\") {\n set.add(entry);\n continue;\n }\n if (isRecord(entry)) {\n if (\"acceptWithExecpolicyAmendment\" in entry) set.add(\"acceptWithExecpolicyAmendment\");\n if (\"applyNetworkPolicyAmendment\" in entry) set.add(\"applyNetworkPolicyAmendment\");\n }\n }\n return set.size > 0 ? set : null;\n}\n\n/**\n * Extract thread id from either v1 ({threadId}) or v2 ({thread:{id}}) responses.\n * threadId is mandatory for session correctness, so invalid shape throws.\n */\nfunction extractThreadId(result: unknown): string {\n if (!isRecord(result)) {\n throw new Error(`Error [${ErrorCode.INTERNAL}]: Invalid thread response: expected object`);\n }\n\n const direct = result.threadId;\n if (typeof direct === \"string\" && direct.length > 0) return direct;\n\n const thread = result.thread;\n if (isRecord(thread) && typeof thread.id === \"string\" && thread.id.length > 0) return thread.id;\n\n throw new Error(`Error [${ErrorCode.INTERNAL}]: Invalid thread response: missing thread id`);\n}\n\n/**\n * Extract turn id from either v1 ({turnId}) or v2 ({turn:{id}}) responses.\n * turnId is optional because turn/started notifications are authoritative.\n */\nfunction extractTurnId(result: unknown): string | undefined {\n if (!isRecord(result)) return undefined;\n\n const direct = result.turnId;\n if (typeof direct === \"string\" && direct.length > 0) return direct;\n\n const turn = result.turn;\n if (isRecord(turn) && typeof turn.id === \"string\" && turn.id.length > 0) return turn.id;\n\n return undefined;\n}\n","/**\n * AppServerClient — JSON-RPC client for codex app-server subprocess.\n *\n * Manages a single codex app-server child process via stdio.\n * Handles request/response correlation, notifications, and server-initiated requests.\n */\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { EventEmitter } from \"events\";\nimport { StringDecoder } from \"string_decoder\";\nimport {\n type RequestId,\n type JsonRpcRequest,\n type JsonRpcResponse,\n type JsonRpcNotification,\n type JsonRpcMessage,\n type InitializeParams,\n type InitializeResult,\n type ThreadStartParams,\n type ThreadStartResult,\n type ThreadForkParams,\n type ThreadForkResult,\n type ThreadResumeParams,\n type ThreadResumeResult,\n type ThreadBackgroundTerminalsCleanParams,\n type TurnStartParams,\n type TurnStartResult,\n type TurnInterruptParams,\n Methods,\n} from \"./protocol.js\";\nimport { buildAppServerArgs, type AppServerSpawnOptions } from \"./lifecycle.js\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\nimport { getDefaultCodexExecutable } from \"../utils/codex-executable.js\";\nimport { ErrorCode } from \"../types.js\";\nimport type { ICodexClient } from \"./client-interface.js\";\n\ndeclare const __PKG_VERSION__: string;\nconst CLIENT_VERSION = typeof __PKG_VERSION__ !== \"undefined\" ? __PKG_VERSION__ : \"0.0.0-dev\";\n\nconst DEFAULT_REQUEST_TIMEOUT = 30_000;\nconst STARTUP_REQUEST_TIMEOUT = 90_000;\nconst MAX_WRITE_QUEUE_BYTES = 5 * 1024 * 1024; // 5MB\n\ninterface PendingRpcRequest {\n resolve: (result: unknown) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\ntype NotificationHandler = (method: string, params: unknown) => void;\ntype ServerRequestHandler = (id: RequestId, method: string, params: unknown) => void;\n\nexport class AppServerClient extends EventEmitter implements ICodexClient {\n private process: ChildProcess | null = null;\n private nextId = 1;\n private pending = new Map<RequestId, PendingRpcRequest>();\n private buffer = \"\";\n private decoder = new StringDecoder(\"utf8\");\n private _destroyed = false;\n private lastFailure: Error | null = null;\n private backpressure = false;\n private writeQueue: string[] = [];\n private queuedBytes = 0;\n private spawnedViaCmd = false;\n private spawnedDetached = false;\n\n private notificationHandler: NotificationHandler | null = null;\n private serverRequestHandler: ServerRequestHandler | null = null;\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n get supportsTurnOverrides(): boolean {\n return true;\n }\n\n get childPid(): number | undefined {\n return this.process?.pid ?? undefined;\n }\n\n /**\n * Spawn codex app-server and perform initialization handshake.\n */\n async start(opts: AppServerSpawnOptions): Promise<InitializeResult> {\n const args = buildAppServerArgs(opts);\n const env = { ...process.env };\n const stdio: [\"pipe\", \"pipe\", \"pipe\"] = [\"pipe\", \"pipe\", \"pipe\"];\n\n const exe = getDefaultCodexExecutable();\n const invocation = resolveCodexInvocation(args, {\n codexCommand: exe.command,\n codexIsPath: exe.isPath,\n });\n this.spawnedViaCmd = invocation.spawnedViaCmd;\n this.spawnedDetached = process.platform !== \"win32\";\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio,\n env,\n detached: this.spawnedDetached,\n windowsHide: process.platform === \"win32\",\n });\n this.process = proc;\n\n proc.stdout!.on(\"data\", (chunk: Buffer) => this.onData(chunk));\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n console.error(`[app-server stderr] ${chunk.toString().trimEnd()}`);\n });\n proc.stdin?.on(\"drain\", () => this.flushWriteQueue());\n proc.stdin?.on(\"error\", (err) => {\n this.lastFailure = err instanceof Error ? err : new Error(String(err));\n this.failAllPending(this.lastFailure);\n });\n proc.stdin?.on(\"close\", () => {\n this.lastFailure ??= new Error(\"app-server stdin closed\");\n this.failAllPending(this.lastFailure);\n });\n proc.on(\"exit\", (code, signal) => {\n this.lastFailure ??= new Error(\n `app-server exited (code: ${code}, signal: ${signal ?? \"null\"})`\n );\n this.failAllPending(this.lastFailure);\n if (!this._destroyed) {\n this.emit(\"exit\", code, signal);\n }\n });\n proc.on(\"error\", (err) => {\n this.lastFailure = err instanceof Error ? err : new Error(String(err));\n this.failAllPending(this.lastFailure);\n this.emit(\"error\", err);\n });\n\n // Initialize handshake\n const result = await this.request<InitializeResult>(Methods.INITIALIZE, {\n clientInfo: { name: \"codex-mcp\", version: CLIENT_VERSION },\n } satisfies InitializeParams);\n\n return result;\n }\n\n /**\n * Register handler for server notifications.\n */\n onNotification(handler: NotificationHandler): void {\n this.notificationHandler = handler;\n }\n\n /**\n * Register handler for server-initiated requests (approvals, user input, etc.).\n */\n onServerRequest(handler: ServerRequestHandler): void {\n this.serverRequestHandler = handler;\n }\n\n /**\n * Send a JSON-RPC response to a server-initiated request.\n */\n respondToServer(id: RequestId, result: unknown): void {\n try {\n this.send({ jsonrpc: \"2.0\", id, result } as JsonRpcResponse);\n } catch (err) {\n console.error(\n `[app-server] Failed to send JSON-RPC response for server request id=${String(id)}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n /**\n * Send a JSON-RPC error response to a server-initiated request.\n */\n respondErrorToServer(id: RequestId, code: number, message: string): void {\n try {\n this.send({ jsonrpc: \"2.0\", id, error: { code, message } } as JsonRpcResponse);\n } catch (err) {\n console.error(\n `[app-server] Failed to send JSON-RPC error response for server request id=${String(id)}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // ── High-level protocol methods ────────────────────────────────\n\n async threadStart(\n params: ThreadStartParams,\n timeout = STARTUP_REQUEST_TIMEOUT\n ): Promise<ThreadStartResult> {\n return this.request<ThreadStartResult>(Methods.THREAD_START, params, timeout);\n }\n\n async threadFork(params: ThreadForkParams): Promise<ThreadForkResult> {\n return this.request<ThreadForkResult>(Methods.THREAD_FORK, params);\n }\n\n async threadResume(params: ThreadResumeParams): Promise<ThreadResumeResult> {\n return this.request<ThreadResumeResult>(Methods.THREAD_RESUME, params);\n }\n\n async threadBackgroundTerminalsClean(\n params: ThreadBackgroundTerminalsCleanParams\n ): Promise<Record<string, never>> {\n return this.request<Record<string, never>>(Methods.THREAD_BACKGROUND_TERMINALS_CLEAN, params);\n }\n\n async turnStart(\n params: TurnStartParams,\n timeout = STARTUP_REQUEST_TIMEOUT\n ): Promise<TurnStartResult> {\n return this.request<TurnStartResult>(Methods.TURN_START, params, timeout);\n }\n\n async turnInterrupt(params: TurnInterruptParams): Promise<void> {\n await this.request<void>(Methods.TURN_INTERRUPT, params);\n }\n\n // ── Low-level JSON-RPC ─────────────────────────────────────────\n\n private request<T>(\n method: string,\n params?: unknown,\n timeout = DEFAULT_REQUEST_TIMEOUT\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n if (this._destroyed) {\n reject(new Error(\"Client destroyed\"));\n return;\n }\n if (!this.process?.stdin?.writable) {\n reject(this.lastFailure ?? new Error(\"app-server is not running (stdin not writable)\"));\n return;\n }\n\n const id = this.nextId++;\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`Request ${method} timed out after ${timeout}ms`));\n }, timeout);\n if (timer.unref) timer.unref();\n\n this.pending.set(id, {\n resolve: resolve as (result: unknown) => void,\n reject,\n timer,\n });\n\n try {\n this.send({ jsonrpc: \"2.0\", id, method, params } as JsonRpcRequest);\n } catch (err) {\n const pending = this.pending.get(id);\n if (pending) {\n this.pending.delete(id);\n clearTimeout(pending.timer);\n }\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n private send(msg: JsonRpcMessage): void {\n if (!this.process?.stdin) throw new Error(\"app-server process not started\");\n if (!this.process.stdin.writable) throw new Error(\"app-server stdin not writable\");\n const payload = JSON.stringify(msg) + \"\\n\";\n this.enqueueWrite(payload);\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += this.decoder.write(chunk);\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n // Fast path: app-server should emit JSON per line; ignore any non-JSON noise safely.\n if (trimmed[0] !== \"{\" && trimmed[0] !== \"[\") {\n continue;\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (Array.isArray(parsed)) {\n for (const item of parsed) {\n if (item && typeof item === \"object\") {\n this.handleMessage(item as JsonRpcMessage);\n }\n }\n } else if (parsed && typeof parsed === \"object\") {\n this.handleMessage(parsed as JsonRpcMessage);\n }\n } catch {\n const error = new Error(\n `Error [${ErrorCode.PROTOCOL_PARSE_ERROR}]: app-server protocol error: failed to parse JSON line: ${trimmed.slice(0, 200)}`\n );\n console.error(`[app-server] ${error.message}`);\n this.lastFailure ??= error;\n this.failAllPending(error);\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after protocol parse error: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n }\n }\n }\n\n private enqueueWrite(payload: string): void {\n if (!this.process?.stdin?.writable) throw new Error(\"app-server stdin not writable\");\n\n if (this.backpressure || this.writeQueue.length > 0) {\n if (this.queuedBytes + payload.length > MAX_WRITE_QUEUE_BYTES) {\n const error = new Error(\n `Error [${ErrorCode.WRITE_QUEUE_DROPPED}]: app-server stdin backpressure: write queue exceeded limit`\n );\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after write queue overflow: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n throw error;\n }\n this.writeQueue.push(payload);\n this.queuedBytes += payload.length;\n return;\n }\n\n try {\n const ok = this.process.stdin.write(payload);\n if (!ok) this.backpressure = true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.lastFailure = error;\n this.failAllPending(error);\n throw error;\n }\n }\n\n private flushWriteQueue(): void {\n if (!this.process?.stdin?.writable) {\n const dropped = this.dropQueuedWrites(\"stdin is not writable while flushing\");\n if (dropped) {\n try {\n this.terminate(\"SIGTERM\");\n } catch (terminateErr) {\n console.error(\n `[app-server] Failed to terminate app-server after dropping queued writes: ${terminateErr instanceof Error ? terminateErr.message : String(terminateErr)}`\n );\n }\n }\n return;\n }\n this.backpressure = false;\n while (this.writeQueue.length > 0 && !this.backpressure) {\n const next = this.writeQueue.shift()!;\n this.queuedBytes -= next.length;\n try {\n const ok = this.process.stdin.write(next);\n if (!ok) this.backpressure = true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n return;\n }\n }\n }\n\n private dropQueuedWrites(reason: string): boolean {\n if (this.writeQueue.length === 0) return false;\n const error = new Error(`Error [${ErrorCode.WRITE_QUEUE_DROPPED}]: ${reason}`);\n console.error(\n `[app-server] Dropping ${this.writeQueue.length} queued writes (${this.queuedBytes} bytes): ${reason}`\n );\n this.lastFailure = error;\n this.failAllPending(error);\n this.writeQueue = [];\n this.queuedBytes = 0;\n return true;\n }\n\n private handleMessage(msg: JsonRpcMessage): void {\n // Response to our request\n if (\"id\" in msg && (\"result\" in msg || \"error\" in msg)) {\n const resp = msg as JsonRpcResponse;\n const pending = this.pending.get(resp.id);\n if (pending) {\n this.pending.delete(resp.id);\n clearTimeout(pending.timer);\n if (resp.error) {\n pending.reject(new Error(`RPC error ${resp.error.code}: ${resp.error.message}`));\n } else {\n pending.resolve(resp.result);\n }\n }\n return;\n }\n\n // Server-initiated request (has id + method, no result/error)\n if (\"id\" in msg && \"method\" in msg) {\n const req = msg as JsonRpcRequest;\n if (this.serverRequestHandler) {\n this.serverRequestHandler(req.id, req.method, req.params);\n } else {\n // No handler — respond with error to avoid hanging\n this.respondErrorToServer(req.id, -32601, `Method not handled: ${req.method}`);\n }\n return;\n }\n\n // Notification (no id)\n if (\"method\" in msg && !(\"id\" in msg)) {\n const notif = msg as JsonRpcNotification;\n if (this.notificationHandler) {\n this.notificationHandler(notif.method, notif.params);\n }\n return;\n }\n }\n\n private failAllPending(error: Error): void {\n if (this.pending.size === 0) return;\n const entries = Array.from(this.pending.entries());\n this.pending.clear();\n for (const [, pending] of entries) {\n clearTimeout(pending.timer);\n pending.reject(error);\n }\n }\n\n /**\n * Gracefully destroy the client and kill the subprocess.\n */\n async destroy(): Promise<void> {\n if (this._destroyed) return;\n this._destroyed = true;\n\n // Reject all pending requests\n this.failAllPending(new Error(\"Client destroyed\"));\n\n // Kill subprocess\n if (this.process && !this.process.killed) {\n const alreadyExited = this.process.exitCode !== null;\n this.process.stdin?.end();\n this.terminate(\"SIGTERM\");\n\n // Force kill after 5s\n const forceKill = setTimeout(() => {\n if (this.process && !this.process.killed) {\n if (process.platform === \"win32\" && this.process.pid) {\n try {\n spawn(\"taskkill\", [\"/PID\", String(this.process.pid), \"/T\", \"/F\"], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } catch (err) {\n console.error(\n `[app-server] Failed to force-kill app-server via taskkill: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n } else {\n this.terminate(\"SIGKILL\");\n }\n }\n }, 5000);\n forceKill.unref();\n\n if (!alreadyExited) {\n await new Promise<void>((resolve) => {\n this.process!.on(\"exit\", () => {\n clearTimeout(forceKill);\n resolve();\n });\n // Resolve anyway after timeout\n const fallback = setTimeout(resolve, 6000);\n fallback.unref();\n });\n }\n }\n\n this.process = null;\n this.removeAllListeners();\n }\n\n private terminate(signal: NodeJS.Signals): void {\n if (!this.process) return;\n\n // On POSIX, kill the whole process group when detached to avoid orphan children.\n if (process.platform !== \"win32\" && this.spawnedDetached && this.process.pid) {\n try {\n process.kill(-this.process.pid, signal);\n return;\n } catch (err) {\n console.error(\n `[app-server] Failed to kill detached process group with ${signal}, falling back to direct kill: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n try {\n this.process.kill(signal);\n } catch (err) {\n console.error(\n `[app-server] Failed to send ${signal} to app-server process: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n}\n","/**\n * codex app-server JSON-RPC protocol types\n *\n * Derived from `codex app-server generate-json-schema`.\n * Wire format for stdio communication with codex app-server subprocess.\n */\n\n// ── JSON-RPC Base ──────────────────────────────────────────────────\n\nexport type RequestId = string | number;\n\nexport interface JsonRpcRequest {\n jsonrpc: \"2.0\";\n id: RequestId;\n method: string;\n params?: unknown;\n}\n\nexport interface JsonRpcResponse {\n jsonrpc: \"2.0\";\n id: RequestId;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nexport interface JsonRpcNotification {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n}\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcResponse | JsonRpcNotification;\n\n// ── Initialize ─────────────────────────────────────────────────────\n\nexport interface InitializeParams {\n clientInfo: { name: string; version: string; title?: string };\n capabilities?: {\n experimentalApi?: boolean;\n optOutNotificationMethods?: string[];\n };\n}\n\nexport interface InitializeResult {\n userAgent: string;\n}\n\n// ── Shared enums / aliases ─────────────────────────────────────────\n\nexport type ApprovalPolicy = \"untrusted\" | \"on-failure\" | \"on-request\" | \"never\";\nexport type SandboxMode = \"read-only\" | \"workspace-write\" | \"danger-full-access\";\nexport type Personality = \"none\" | \"friendly\" | \"pragmatic\";\nexport type ReasoningEffort = \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\nexport type ReasoningSummary = \"auto\" | \"concise\" | \"detailed\" | \"none\";\n\n// ── Thread Management ──────────────────────────────────────────────\n\nexport interface DynamicToolSpec {\n name: string;\n description: string;\n inputSchema: unknown;\n}\n\n/** thread/start — all fields optional */\nexport interface ThreadStartParams {\n cwd?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n approvalPolicy?: ApprovalPolicy | null;\n /**\n * v2 schema: sandbox mode string enum (\"read-only\" | \"workspace-write\" | \"danger-full-access\")\n * (Not the SandboxPolicy object used by turn/start's sandboxPolicy.)\n */\n sandbox?: SandboxMode | null;\n personality?: Personality | null;\n ephemeral?: boolean | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n config?: Record<string, unknown> | null;\n dynamicTools?: DynamicToolSpec[] | null;\n experimentalRawEvents?: boolean;\n mockExperimentalField?: string | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadStartResultV1 {\n threadId: string;\n}\nexport interface ThreadStartResultV2 {\n thread: { id: string };\n}\nexport type ThreadStartResult = ThreadStartResultV1 | ThreadStartResultV2;\n\nexport interface ThreadForkParams {\n threadId: string;\n approvalPolicy?: ApprovalPolicy | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n sandbox?: SandboxMode | null;\n cwd?: string | null;\n config?: Record<string, unknown> | null;\n path?: string | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadForkResultV1 {\n threadId: string;\n}\nexport interface ThreadForkResultV2 {\n thread: { id: string };\n}\nexport type ThreadForkResult = ThreadForkResultV1 | ThreadForkResultV2;\n\nexport interface ThreadResumeParams {\n threadId: string;\n approvalPolicy?: ApprovalPolicy | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n sandbox?: SandboxMode | null;\n personality?: Personality | null;\n cwd?: string | null;\n config?: Record<string, unknown> | null;\n path?: string | null;\n history?: unknown[] | null;\n persistExtendedHistory?: boolean;\n}\n\nexport interface ThreadResumeResultV1 {\n threadId: string;\n}\nexport interface ThreadResumeResultV2 {\n thread: { id: string };\n}\nexport type ThreadResumeResult = ThreadResumeResultV1 | ThreadResumeResultV2;\n\nexport interface ThreadBackgroundTerminalsCleanParams {\n threadId: string;\n}\n\n// ── SandboxPolicy ──────────────────────────────────────────────────\n\nexport type ReadOnlyAccess =\n | {\n type: \"restricted\";\n includePlatformDefaults?: boolean;\n readableRoots?: string[];\n }\n | { type: \"fullAccess\" };\n\nexport type SandboxPolicy =\n | { type: \"dangerFullAccess\" }\n | { type: \"readOnly\"; access?: ReadOnlyAccess }\n | { type: \"externalSandbox\"; networkAccess?: \"restricted\" | \"enabled\" }\n | {\n type: \"workspaceWrite\";\n writableRoots?: string[];\n readOnlyAccess?: ReadOnlyAccess;\n networkAccess?: boolean;\n excludeSlashTmp?: boolean;\n excludeTmpdirEnvVar?: boolean;\n };\n\n/** Map user-facing sandbox mode string to protocol SandboxPolicy */\nexport function toSandboxPolicy(mode: SandboxMode | string): SandboxPolicy | undefined {\n switch (mode) {\n case \"read-only\":\n return { type: \"readOnly\" };\n case \"workspace-write\":\n return { type: \"workspaceWrite\" };\n case \"danger-full-access\":\n return { type: \"dangerFullAccess\" };\n default:\n return undefined;\n }\n}\n\n// ── Turn Management ────────────────────────────────────────────────\n\nexport interface TextElement {\n byteRange: { start: number; end: number };\n placeholder?: string | null;\n}\n\nexport type UserInput =\n | { type: \"text\"; text: string; text_elements?: TextElement[] }\n | { type: \"image\"; url: string }\n | { type: \"localImage\"; path: string }\n | { type: \"skill\"; name: string; path: string }\n | { type: \"mention\"; name: string; path: string };\n\nexport interface CollaborationMode {\n mode: \"plan\" | \"default\";\n settings: {\n model: string;\n developer_instructions?: string | null;\n reasoning_effort?: ReasoningEffort | null;\n };\n}\n\nexport interface TurnStartParams {\n threadId: string;\n input: UserInput[];\n model?: string | null;\n approvalPolicy?: ApprovalPolicy | null;\n sandboxPolicy?: SandboxPolicy | null;\n personality?: Personality | null;\n effort?: ReasoningEffort | null;\n summary?: ReasoningSummary | null;\n cwd?: string | null;\n outputSchema?: Record<string, unknown>;\n collaborationMode?: CollaborationMode | null;\n}\n\nexport interface TurnStartResultV1 {\n turnId: string;\n}\nexport interface TurnStartResultV2 {\n turn: { id: string };\n}\nexport type TurnStartResult = TurnStartResultV1 | TurnStartResultV2;\n\nexport interface TurnInterruptParams {\n threadId: string;\n turnId: string;\n}\n\nexport interface TurnSteerParams {\n threadId: string;\n expectedTurnId: string;\n input: UserInput[];\n}\n\n// ── Approval Requests (server → client) ────────────────────────────\n\nexport interface CommandApprovalParams {\n /**\n * Optional per-callback approval id.\n * Present for subcommand approvals (execve intercept), null/absent for regular approvals.\n */\n approvalId?: string | null;\n itemId: string;\n threadId: string;\n turnId: string;\n command?: string | null;\n cwd?: string | null;\n reason?: string | null;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n\n // Added in codex-cli 0.106.x: richer approval contexts.\n additionalPermissions?: unknown;\n availableDecisions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown;\n}\n\nexport type CommandApprovalDecision =\n | \"accept\"\n | \"acceptForSession\"\n | { acceptWithExecpolicyAmendment: { execpolicy_amendment: string[] } }\n | {\n applyNetworkPolicyAmendment: {\n network_policy_amendment: { action: \"allow\" | \"deny\"; host: string };\n };\n }\n | \"decline\"\n | \"cancel\";\n\nexport interface CommandApprovalResponse {\n decision: CommandApprovalDecision;\n}\n\nexport interface FileChangeApprovalParams {\n itemId: string;\n threadId: string;\n turnId: string;\n grantRoot?: string | null;\n reason?: string | null;\n}\n\nexport type FileChangeApprovalDecision = \"accept\" | \"acceptForSession\" | \"decline\" | \"cancel\";\n\nexport interface FileChangeApprovalResponse {\n decision: FileChangeApprovalDecision;\n}\n\n// ── User Input Request (server → client) ───────────────────────────\n\nexport interface UserInputRequestParams {\n itemId: string;\n threadId: string;\n turnId: string;\n questions: Array<{\n id: string;\n header: string;\n question: string;\n isOther?: boolean;\n isSecret?: boolean;\n options?: Array<{ label: string; description: string }> | null;\n }>;\n}\n\nexport interface UserInputRequestResponse {\n answers: Record<string, { answers: string[] }>;\n}\n\n// ── Dynamic Tool Call (server → client) ────────────────────────────\n\nexport interface DynamicToolCallParams {\n threadId: string;\n turnId: string;\n callId: string;\n tool: string;\n arguments: unknown;\n}\n\nexport interface DynamicToolCallResponse {\n success: boolean;\n contentItems: Array<\n { type: \"inputText\"; text: string } | { type: \"inputImage\"; imageUrl: string }\n >;\n}\n\n// ── Auth Refresh Request (server → client) ─────────────────────────\n\nexport interface ChatgptAuthTokensRefreshParams {\n reason: \"unauthorized\";\n previousAccountId?: string | null;\n}\n\nexport interface ChatgptAuthTokensRefreshResponse {\n accessToken: string;\n chatgptAccountId: string;\n chatgptPlanType?: string | null;\n}\n\n// ── Event Notification Params ──────────────────────────────────────\n\nexport interface DeltaNotificationParams {\n threadId: string;\n turnId: string;\n itemId: string;\n delta: string;\n}\n\nexport interface ReasoningDeltaParams {\n threadId: string;\n turnId: string;\n itemId: string;\n contentIndex: number;\n delta: string;\n}\n\nexport interface ItemNotificationParams {\n threadId: string;\n turnId: string;\n item: unknown;\n}\n\nexport interface ThreadStateNotificationParams {\n threadId: string;\n}\n\nexport interface TurnNotificationParams {\n threadId: string;\n turn: unknown;\n}\n\nexport interface ErrorNotificationParams {\n threadId: string;\n turnId: string;\n error: unknown;\n willRetry: boolean;\n}\n\n// ── Legacy Approval (deprecated) ───────────────────────────────────\n\nexport interface LegacyApprovalResponse {\n decision:\n | \"approved\"\n | \"approved_for_session\"\n | \"denied\"\n | \"abort\"\n | { approved_execpolicy_amendment: { proposed_execpolicy_amendment: string[] } };\n}\n\n// ── Protocol Method Constants ──────────────────────────────────────\n\nexport const Methods = {\n // Client → Server\n INITIALIZE: \"initialize\",\n THREAD_START: \"thread/start\",\n THREAD_RESUME: \"thread/resume\",\n THREAD_FORK: \"thread/fork\",\n THREAD_BACKGROUND_TERMINALS_CLEAN: \"thread/backgroundTerminals/clean\",\n TURN_START: \"turn/start\",\n TURN_INTERRUPT: \"turn/interrupt\",\n TURN_STEER: \"turn/steer\",\n\n // Server → Client requests\n COMMAND_APPROVAL: \"item/commandExecution/requestApproval\",\n FILE_CHANGE_APPROVAL: \"item/fileChange/requestApproval\",\n USER_INPUT_REQUEST: \"item/tool/requestUserInput\",\n DYNAMIC_TOOL_CALL: \"item/tool/call\",\n AUTH_TOKEN_REFRESH: \"account/chatgptAuthTokens/refresh\",\n LEGACY_PATCH_APPROVAL: \"applyPatchApproval\",\n LEGACY_EXEC_APPROVAL: \"execCommandApproval\",\n\n // Server → Client notifications\n ERROR: \"error\",\n THREAD_STARTED: \"thread/started\",\n THREAD_ARCHIVED: \"thread/archived\",\n THREAD_UNARCHIVED: \"thread/unarchived\",\n THREAD_NAME_UPDATED: \"thread/name/updated\",\n THREAD_TOKEN_USAGE_UPDATED: \"thread/tokenUsage/updated\",\n TURN_STARTED: \"turn/started\",\n TURN_COMPLETED: \"turn/completed\",\n TURN_DIFF_UPDATED: \"turn/diff/updated\",\n TURN_PLAN_UPDATED: \"turn/plan/updated\",\n ITEM_STARTED: \"item/started\",\n ITEM_COMPLETED: \"item/completed\",\n RAW_RESPONSE_ITEM_COMPLETED: \"rawResponseItem/completed\",\n AGENT_MESSAGE_DELTA: \"item/agentMessage/delta\",\n COMMAND_OUTPUT_DELTA: \"item/commandExecution/outputDelta\",\n COMMAND_TERMINAL_INTERACTION: \"item/commandExecution/terminalInteraction\",\n FILE_CHANGE_OUTPUT_DELTA: \"item/fileChange/outputDelta\",\n REASONING_TEXT_DELTA: \"item/reasoning/textDelta\",\n REASONING_SUMMARY_DELTA: \"item/reasoning/summaryTextDelta\",\n REASONING_SUMMARY_PART_ADDED: \"item/reasoning/summaryPartAdded\",\n PLAN_DELTA: \"item/plan/delta\",\n MCP_TOOL_PROGRESS: \"item/mcpToolCall/progress\",\n MODEL_REROUTED: \"model/rerouted\",\n FUZZY_FILE_SEARCH_SESSION_UPDATED: \"fuzzyFileSearch/sessionUpdated\",\n FUZZY_FILE_SEARCH_SESSION_COMPLETED: \"fuzzyFileSearch/sessionCompleted\",\n WINDOWS_WORLD_WRITABLE_WARNING: \"windows/worldWritableWarning\",\n ACCOUNT_LOGIN_COMPLETED: \"account/login/completed\",\n SESSION_CONFIGURED: \"sessionConfigured\",\n} as const;\n","/**\n * Build codex app-server spawn arguments from tool parameters.\n */\nimport type { ApprovalPolicy, SandboxMode } from \"../types.js\";\n\nexport interface AppServerSpawnOptions {\n profile?: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n config?: Record<string, unknown>;\n}\n\nexport function buildAppServerArgs(opts: AppServerSpawnOptions): string[] {\n const args: string[] = [\"app-server\"];\n\n if (opts.profile) {\n args.push(\"-p\", opts.profile);\n }\n if (opts.model) {\n args.push(\"-c\", `model=${opts.model}`);\n }\n if (opts.approvalPolicy) {\n args.push(\"-c\", `approval_policy=${opts.approvalPolicy}`);\n }\n if (opts.sandbox) {\n args.push(\"-c\", `sandbox_mode=${opts.sandbox}`);\n }\n if (opts.config) {\n for (const [key, value] of Object.entries(opts.config)) {\n // Use raw value for primitives, JSON for objects/arrays\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n }\n\n return args;\n}\n","/**\n * Resolve how to spawn the `codex` CLI across platforms.\n *\n * Goal: avoid going through a shell on Windows when possible (npm `.cmd` shims are shell-parsed),\n * while keeping \"zero-config local integration\" (PATH + ~/.codex/config.toml).\n *\n * The command name is configurable via the `codexCommand` field in `ResolverDeps`.\n * When `codexIsPath` is true, the value is treated as a direct filesystem path\n * and PATH resolution is skipped.\n */\nimport { existsSync, readFileSync } from \"fs\";\nimport path from \"path\";\n\nexport interface CodexInvocation {\n cmd: string;\n args: string[];\n /** True when spawning via `cmd.exe` (fallback path). */\n spawnedViaCmd: boolean;\n}\n\ntype ResolverDeps = {\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n exists?: (p: string) => boolean;\n readFile?: (p: string) => string;\n /** The codex command name or filesystem path. Defaults to \"codex\". */\n codexCommand?: string;\n /** True when `codexCommand` is a filesystem path (not a bare command name). */\n codexIsPath?: boolean;\n};\n\nexport function resolveCodexInvocation(\n codexArgs: string[],\n deps: ResolverDeps = {}\n): CodexInvocation {\n const platform = deps.platform ?? process.platform;\n const env = deps.env ?? process.env;\n const exists = deps.exists ?? existsSync;\n const readFile = deps.readFile ?? ((p: string) => readFileSync(p, \"utf8\"));\n const pathApi = platform === \"win32\" ? path.win32 : path.posix;\n const delimiter = platform === \"win32\" ? \";\" : \":\";\n const codexCommand = deps.codexCommand ?? \"codex\";\n const codexIsPath = deps.codexIsPath ?? false;\n\n // ── Direct path mode ────────────────────────────────────────────\n // When an explicit filesystem path is provided, use it directly.\n // On Windows, .cmd/.bat files cannot be spawned directly — wrap via cmd.exe.\n if (codexIsPath) {\n if (\n platform === \"win32\" &&\n (codexCommand.toLowerCase().endsWith(\".cmd\") || codexCommand.toLowerCase().endsWith(\".bat\"))\n ) {\n const comspec = env.ComSpec || env.COMSPEC || \"cmd.exe\";\n return {\n cmd: comspec,\n args: [\"/d\", \"/s\", \"/c\", codexCommand, ...codexArgs],\n spawnedViaCmd: true,\n };\n }\n return { cmd: codexCommand, args: codexArgs, spawnedViaCmd: false };\n }\n\n // ── Non-Windows: bare command ───────────────────────────────────\n if (platform !== \"win32\") {\n return { cmd: codexCommand, args: codexArgs, spawnedViaCmd: false };\n }\n\n // ── Windows: try to resolve from PATH ───────────────────────────\n const shim = findOnPath(codexCommand, env, exists, pathApi, delimiter, [\".exe\", \".cmd\", \".bat\"]);\n if (shim && shim.toLowerCase().endsWith(\".exe\")) {\n return { cmd: shim, args: codexArgs, spawnedViaCmd: false };\n }\n\n if (shim && (shim.toLowerCase().endsWith(\".cmd\") || shim.toLowerCase().endsWith(\".bat\"))) {\n const script = tryResolveNodeScriptFromShim(shim, codexCommand, exists, readFile, pathApi);\n if (script) {\n return { cmd: process.execPath, args: [script, ...codexArgs], spawnedViaCmd: false };\n }\n }\n\n // Last resort: spawn via cmd.exe. Keep arguments as separate tokens to avoid nested-quote issues\n // when Node builds the final CreateProcess command line.\n const comspec = env.ComSpec || env.COMSPEC || \"cmd.exe\";\n return {\n cmd: comspec,\n args: [\"/d\", \"/s\", \"/c\", codexCommand, ...codexArgs],\n spawnedViaCmd: true,\n };\n}\n\nexport function findOnPath(\n base: string,\n env: NodeJS.ProcessEnv,\n exists: (p: string) => boolean,\n pathApi: typeof path.posix | typeof path.win32,\n delimiter: string,\n exts: string[]\n): string | undefined {\n const pathEnv = env.PATH || env.Path || env.path || \"\";\n const dirs = pathEnv\n .split(delimiter)\n .map((d) => stripSurroundingQuotes(d.trim()))\n .filter(Boolean);\n\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = pathApi.join(dir, `${base}${ext}`);\n if (exists(candidate)) return candidate;\n }\n const raw = pathApi.join(dir, base);\n if (exists(raw)) return raw;\n }\n return undefined;\n}\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction tryResolveNodeScriptFromShim(\n shimPath: string,\n codexCommand: string,\n exists: (p: string) => boolean,\n readFile: (p: string) => string,\n pathApi: typeof path.posix | typeof path.win32\n): string | undefined {\n let contents: string;\n try {\n contents = readFile(shimPath);\n } catch {\n return undefined;\n }\n\n // npm `.cmd` shims typically contain a quoted script path ending in `.js` / `.cjs` / `.mjs`.\n const matches: string[] = [];\n const re = /\"([^\"]+\\.(?:m?js|cjs))\"/gi;\n for (;;) {\n const m = re.exec(contents);\n if (!m) break;\n matches.push(m[1]);\n }\n if (matches.length === 0) return undefined;\n\n // Escape the command name for use in regex matching\n const escapedCommand = codexCommand.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const baseNameRe = new RegExp(escapedCommand, \"i\");\n const pathRe = new RegExp(\n `@openai\\\\\\\\${escapedCommand}|\\\\\\\\${escapedCommand}\\\\\\\\|\\\\/${escapedCommand}\\\\/`,\n \"i\"\n );\n\n const preferred =\n matches.find((m) => baseNameRe.test(pathApi.basename(m))) ??\n matches.find((m) => pathRe.test(m)) ??\n matches[matches.length - 1];\n\n const shimDir = pathApi.dirname(shimPath);\n const dp0 = shimDir.endsWith(pathApi.sep) ? shimDir : shimDir + pathApi.sep;\n let resolved = preferred.replace(/%~dp0/gi, dp0).replace(/%dp0%/gi, dp0);\n resolved = resolved.replace(/\\//g, \"\\\\\");\n\n const abs = pathApi.isAbsolute(resolved)\n ? pathApi.normalize(resolved)\n : pathApi.resolve(shimDir, resolved);\n if (!exists(abs)) return undefined;\n return abs;\n}\n","/**\n * Resolve which `codex` executable to use.\n *\n * Resolution priority (mirrors claude-code-mcp's claude-executable.ts):\n * 1. CODEX_MCP_PATH — absolute/relative filesystem path\n * 2. CODEX_MCP_COMMAND — bare command name resolved from PATH\n * 3. Auto-detect: try \"codex\", then \"codex-internal\" on PATH\n * 4. Fall back to \"codex\" (let spawn fail with a clear error later)\n *\n * CODEX_MCP_PATH and CODEX_MCP_COMMAND are mutually exclusive.\n */\nimport { accessSync, constants, existsSync, statSync } from \"fs\";\nimport path from \"path\";\n\n// ── Env var names ─────────────────────────────────────────────────\nexport const CODEX_MCP_COMMAND = \"CODEX_MCP_COMMAND\";\nexport const CODEX_MCP_PATH = \"CODEX_MCP_PATH\";\n\n// ── Auto-detection candidates (tried in order) ───────────────────\nexport const AUTO_CODEX_COMMANDS = [\"codex\", \"codex-internal\"] as const;\n\n// ── Types ─────────────────────────────────────────────────────────\nexport type CodexExecutableSource = \"env_path\" | \"env_command\" | \"auto_detect\" | \"default\";\n\nexport interface CodexExecutableInfo {\n /** The command name or filesystem path to use */\n command: string;\n /** True when `command` is a filesystem path (not a bare name) */\n isPath: boolean;\n /** How the value was determined */\n source: CodexExecutableSource;\n}\n\n// ── Module state ──────────────────────────────────────────────────\nlet _resolved: CodexExecutableInfo | undefined;\n\n// ── PATH helpers ──────────────────────────────────────────────────\n\nconst WINDOWS_SUPPORTED_EXTENSIONS = [\".com\", \".exe\", \".bat\", \".cmd\"] as const;\n\nfunction stripSurroundingQuotes(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction normalizeMaybeQuotedToken(raw: string): string {\n return stripSurroundingQuotes(raw.trim());\n}\n\nfunction normalizeWindowsExtension(value: string): string | undefined {\n const trimmed = stripSurroundingQuotes(value.trim());\n if (!trimmed) return undefined;\n return trimmed.startsWith(\".\") ? trimmed.toLowerCase() : `.${trimmed.toLowerCase()}`;\n}\n\nfunction isExecutableFile(candidate: string): boolean {\n try {\n const stat = statSync(candidate);\n if (!stat.isFile()) return false;\n if (process.platform === \"win32\") return true;\n accessSync(candidate, constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getPathEntries(env: NodeJS.ProcessEnv): string[] {\n const pathEnv = env.PATH || env.Path || env.path || \"\";\n return pathEnv\n .split(process.platform === \"win32\" ? \";\" : \":\")\n .map((entry) => stripSurroundingQuotes(entry.trim()))\n .filter(Boolean);\n}\n\nfunction getPathExtensions(env: NodeJS.ProcessEnv): string[] {\n if (process.platform !== \"win32\") return [\"\"];\n const configured =\n env.PATHEXT ?? env.Pathext ?? env.pathext ?? process.env.PATHEXT ?? \".COM;.EXE;.BAT;.CMD\";\n const configuredExts = configured\n .split(\";\")\n .map((entry) => normalizeWindowsExtension(entry))\n .filter((entry): entry is string => Boolean(entry));\n const merged = configuredExts.filter((ext) =>\n WINDOWS_SUPPORTED_EXTENSIONS.includes(ext as never)\n );\n for (const ext of WINDOWS_SUPPORTED_EXTENSIONS) {\n if (!merged.includes(ext)) merged.push(ext);\n }\n return Array.from(new Set(merged));\n}\n\nfunction commandExistsOnPath(command: string, env: NodeJS.ProcessEnv): boolean {\n const dirs = getPathEntries(env);\n const ext = process.platform === \"win32\" ? path.extname(command) : \"\";\n const names =\n process.platform === \"win32\"\n ? Array.from(\n new Set(\n ext\n ? [command]\n : [...getPathExtensions(env).map((suffix) => `${command}${suffix}`), command]\n )\n )\n : [command];\n\n for (const dir of dirs) {\n for (const name of names) {\n const candidate = path.join(dir, name);\n if (isExecutableFile(candidate)) return true;\n }\n }\n return false;\n}\n\nfunction looksLikePath(value: string): boolean {\n return value.includes(\"/\") || value.includes(\"\\\\\");\n}\n\n// ── Core resolution ───────────────────────────────────────────────\n\nexport function resolveDefaultCodexExecutable(\n env: NodeJS.ProcessEnv = process.env\n): CodexExecutableInfo {\n const envPathRaw = env[CODEX_MCP_PATH]?.trim();\n const envCommandRaw = env[CODEX_MCP_COMMAND]?.trim();\n const envPath = envPathRaw ? normalizeMaybeQuotedToken(envPathRaw) : undefined;\n const envCommand = envCommandRaw ? normalizeMaybeQuotedToken(envCommandRaw) : undefined;\n\n // Mutually exclusive\n if (envPath && envCommand) {\n throw new Error(\n `Cannot set both ${CODEX_MCP_PATH} and ${CODEX_MCP_COMMAND}. Use one or the other.`\n );\n }\n\n // 1. Explicit filesystem path\n if (envPath) {\n const resolvedPath = path.resolve(envPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`${CODEX_MCP_PATH}=\"${envPath}\" — file does not exist.`);\n }\n if (!isExecutableFile(resolvedPath)) {\n throw new Error(`${CODEX_MCP_PATH}=\"${envPath}\" — not an executable file.`);\n }\n return { command: resolvedPath, isPath: true, source: \"env_path\" };\n }\n\n // 2. Explicit bare command name\n if (envCommand) {\n if (looksLikePath(envCommand)) {\n throw new Error(\n `${CODEX_MCP_COMMAND}=\"${envCommand}\" looks like a path. Use ${CODEX_MCP_PATH} for filesystem paths.`\n );\n }\n if (!commandExistsOnPath(envCommand, env)) {\n throw new Error(`${CODEX_MCP_COMMAND}=\"${envCommand}\" was not found in PATH.`);\n }\n return { command: envCommand, isPath: false, source: \"env_command\" };\n }\n\n // 3. Auto-detect from PATH\n for (const candidate of AUTO_CODEX_COMMANDS) {\n if (commandExistsOnPath(candidate, env)) {\n return { command: candidate, isPath: false, source: \"auto_detect\" };\n }\n }\n\n // 4. Fall back to \"codex\" — let spawn surface a clear \"not found\" error later\n return { command: \"codex\", isPath: false, source: \"default\" };\n}\n\n// ── Public API ────────────────────────────────────────────────────\n\n/**\n * Resolve and cache the default codex executable info.\n * Safe to call multiple times — resolution runs only once.\n */\nexport function getDefaultCodexExecutable(): CodexExecutableInfo {\n if (!_resolved) {\n _resolved = resolveDefaultCodexExecutable();\n }\n return _resolved;\n}\n\n/**\n * Startup check — resolves the executable and logs the result.\n * Throws on misconfiguration (mutually exclusive env vars, missing path).\n */\nexport function checkDefaultCodexExecutableAvailability(): void {\n const info = getDefaultCodexExecutable();\n const label = info.isPath ? \"path\" : \"command\";\n switch (info.source) {\n case \"env_path\":\n console.error(`[codex-executable] Using ${CODEX_MCP_PATH}: ${info.command}`);\n break;\n case \"env_command\":\n console.error(`[codex-executable] Using ${CODEX_MCP_COMMAND}: ${info.command}`);\n break;\n case \"auto_detect\":\n console.error(`[codex-executable] Auto-detected ${label}: ${info.command}`);\n break;\n case \"default\":\n console.error(\n `[codex-executable] No codex found on PATH; falling back to \"${info.command}\". ` +\n `Set ${CODEX_MCP_COMMAND} or ${CODEX_MCP_PATH} to configure.`\n );\n break;\n }\n}\n\n/** Reset cached state (for testing). */\nexport function _resetForTesting(): void {\n _resolved = undefined;\n}\n","/**\n * Type definitions for codex-mcp\n *\n * Shared constants are defined as tuples so both Zod schemas and\n * TypeScript types can derive from the same source of truth.\n */\n\n// ── Constants ──────────────────────────────────────────────────────\n\nexport const APPROVAL_POLICIES = [\"untrusted\", \"on-failure\", \"on-request\", \"never\"] as const;\nexport type ApprovalPolicy = (typeof APPROVAL_POLICIES)[number];\n\nexport const SANDBOX_MODES = [\"read-only\", \"workspace-write\", \"danger-full-access\"] as const;\nexport type SandboxMode = (typeof SANDBOX_MODES)[number];\n\nexport const PERSONALITIES = [\"none\", \"friendly\", \"pragmatic\"] as const;\nexport type Personality = (typeof PERSONALITIES)[number];\n\nexport const EFFORT_LEVELS = [\"none\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"] as const;\nexport type EffortLevel = (typeof EFFORT_LEVELS)[number];\n\nexport const SUMMARY_MODES = [\"auto\", \"concise\", \"detailed\", \"none\"] as const;\nexport type SummaryMode = (typeof SUMMARY_MODES)[number];\n\nexport const SESSION_ACTIONS = [\n \"list\",\n \"get\",\n \"cancel\",\n \"interrupt\",\n \"fork\",\n \"clean_background_terminals\",\n] as const;\nexport type SessionAction = (typeof SESSION_ACTIONS)[number];\n\nexport const CHECK_ACTIONS = [\"poll\", \"respond_permission\", \"respond_user_input\"] as const;\nexport type CheckAction = (typeof CHECK_ACTIONS)[number];\n\nexport const RESPONSE_MODES = [\"minimal\", \"delta_compact\", \"full\"] as const;\nexport type ResponseMode = (typeof RESPONSE_MODES)[number];\n\nexport interface PollOptions {\n includeEvents?: boolean;\n includeActions?: boolean;\n includeResult?: boolean;\n maxBytes?: number;\n /** Long-poll: wait up to this many ms for new events before returning. Max 120000. */\n waitMs?: number;\n}\n\nexport const APPROVAL_TYPES = [\"command\", \"fileChange\"] as const;\nexport type ApprovalType = (typeof APPROVAL_TYPES)[number];\n\nexport const COMMAND_DECISIONS = [\n \"accept\",\n \"acceptForSession\",\n \"acceptWithExecpolicyAmendment\",\n \"applyNetworkPolicyAmendment\",\n \"decline\",\n \"cancel\",\n] as const;\nexport type CommandDecision = (typeof COMMAND_DECISIONS)[number];\n\nexport const FILE_CHANGE_DECISIONS = [\"accept\", \"acceptForSession\", \"decline\", \"cancel\"] as const;\nexport type FileChangeDecision = (typeof FILE_CHANGE_DECISIONS)[number];\n\nexport const ALL_DECISIONS = [\n \"accept\",\n \"acceptForSession\",\n \"acceptWithExecpolicyAmendment\",\n \"applyNetworkPolicyAmendment\",\n \"decline\",\n \"cancel\",\n] as const;\nexport type ApprovalDecision = (typeof ALL_DECISIONS)[number];\n\nexport interface NetworkPolicyAmendment {\n action: \"allow\" | \"deny\";\n host: string;\n}\n\n// ── Session Types ──────────────────────────────────────────────────\n\nexport type SessionStatus = \"running\" | \"idle\" | \"waiting_approval\" | \"error\" | \"cancelled\";\n\nexport type InteractionState = \"working\" | \"waiting_input\" | \"finished\";\n\nexport type RecommendedNextAction = \"poll\" | \"respond_permission\" | \"respond_user_input\" | \"none\";\n\nexport type ExecutionMode = \"background\" | \"foreground\";\n\nexport type ExecutionFallbackReason = \"wait_for_result_timeout\" | \"interactive_poll_required\";\n\nexport interface ExecutionInfo {\n requested: ExecutionMode;\n effective: ExecutionMode;\n waitForResultMs?: number;\n fallbackReason?: ExecutionFallbackReason;\n}\n\nexport type SessionEventType =\n | \"output\"\n | \"progress\"\n | \"approval_request\"\n | \"approval_result\"\n | \"result\"\n | \"error\";\n\nexport interface SessionEvent {\n id: number;\n type: SessionEventType;\n data: unknown;\n timestamp: string;\n pinned: boolean;\n}\n\nexport interface EventBuffer {\n events: SessionEvent[];\n maxSize: number;\n hardMaxSize: number;\n nextId: number;\n}\n\n/** Pending approval/user-input request */\nexport interface PendingRequest {\n requestId: string;\n /** \"command\" | \"fileChange\" | \"user_input\" */\n kind: ApprovalType | \"user_input\";\n /** Raw params from app-server */\n params: unknown;\n /** itemId from app-server (for correlation) */\n itemId: string;\n threadId: string;\n turnId: string;\n reason?: string;\n approvalId?: string;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n availableDecisions?: unknown[] | null;\n additionalPermissions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown[] | null;\n createdAt: string;\n resolved: boolean;\n decision?: string;\n timeoutHandle?: ReturnType<typeof setTimeout>;\n /** JSON-RPC response resolver */\n respond?: (result: unknown) => void;\n}\n\n/** Internal session info (full) */\nexport interface SessionInfo {\n sessionId: string;\n threadId?: string;\n activeTurnId?: string;\n /** Most recent poll cursor consumed by this session. */\n lastEventCursor: number;\n status: SessionStatus;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n approvalTimeoutMs?: number;\n cwd: string;\n model?: string;\n profile?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n config?: Record<string, unknown>;\n eventBuffer: EventBuffer;\n pendingRequests: Map<string, PendingRequest>;\n lastResult?: TurnResult;\n}\n\n/** Public session info (redacted) */\nexport interface PublicSessionInfo {\n sessionId: string;\n status: SessionStatus;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n sandbox?: SandboxMode;\n pendingRequestCount: number;\n}\n\n/** Sensitive session info */\nexport interface SensitiveSessionInfo extends PublicSessionInfo {\n threadId?: string;\n cwd: string;\n profile?: string;\n config?: Record<string, unknown>;\n}\n\n// ── Result Types ───────────────────────────────────────────────────\n\nexport interface TurnResult {\n turnId: string;\n output?: string;\n structuredOutput?: unknown;\n /** Raw turn object from app-server notifications/responses (shape depends on schema version). */\n turn?: unknown;\n /** Turn status string if available (e.g. \"completed\" | \"failed\" | \"interrupted\"). */\n status?: string;\n /** Raw turn error object if available. */\n turnError?: unknown;\n error?: string;\n completedAt: string;\n}\n\nexport interface SessionStartResult {\n sessionId: string;\n threadId: string;\n status: \"running\" | \"idle\";\n pollInterval: number;\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n}\n\nexport interface CheckResult {\n sessionId: string;\n status: SessionStatus;\n pollInterval?: number;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n events: Array<{\n id: number;\n type: SessionEventType;\n data: unknown;\n timestamp: string;\n }>;\n nextCursor: number;\n cursorResetTo?: number;\n actions?: Array<{\n type: \"approval\" | \"user_input\";\n requestId: string;\n kind: \"command\" | \"fileChange\" | \"user_input\";\n params: unknown;\n itemId: string;\n reason?: string;\n approvalId?: string;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n availableDecisions?: unknown[] | null;\n additionalPermissions?: unknown;\n networkApprovalContext?: unknown;\n proposedNetworkPolicyAmendments?: unknown[] | null;\n createdAt: string;\n }>;\n result?: TurnResult;\n compatWarnings?: string[];\n truncated?: boolean;\n truncatedFields?: string[];\n}\n\n// ── Error Types ────────────────────────────────────────────────────\n\nexport enum ErrorCode {\n INVALID_ARGUMENT = \"INVALID_ARGUMENT\",\n SESSION_NOT_FOUND = \"SESSION_NOT_FOUND\",\n SESSION_BUSY = \"SESSION_BUSY\",\n SESSION_NOT_RUNNING = \"SESSION_NOT_RUNNING\",\n REQUEST_NOT_FOUND = \"REQUEST_NOT_FOUND\",\n TIMEOUT = \"TIMEOUT\",\n CANCELLED = \"CANCELLED\",\n APP_SERVER_START_FAILED = \"APP_SERVER_START_FAILED\",\n THREAD_FORK_RESUME_FAILED = \"THREAD_FORK_RESUME_FAILED\",\n PROTOCOL_PARSE_ERROR = \"PROTOCOL_PARSE_ERROR\",\n WRITE_QUEUE_DROPPED = \"WRITE_QUEUE_DROPPED\",\n EXEC_NOT_SUPPORTED = \"EXEC_NOT_SUPPORTED\",\n INTERNAL = \"INTERNAL\",\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\nexport const DEFAULT_EFFORT_LEVEL: EffortLevel = \"low\";\n/**\n * Minimum recommended polling interval (ms) when session status is \"running\".\n * MCP callers should treat this as a floor and can wait longer for larger tasks.\n */\nexport const DEFAULT_POLL_INTERVAL = 120_000;\n/**\n * Polling interval (ms) while waiting for approval/user-input actions.\n * Kept short so callers can unblock pending actions before approval timeout.\n */\nexport const WAITING_APPROVAL_POLL_INTERVAL = 1000;\n/** Public codex_check default for action=\"poll\" when maxEvents is omitted. */\nexport const POLL_DEFAULT_MAX_EVENTS = 1;\n/** Public codex_check lower bound for action=\"poll\" to avoid no-op loops. */\nexport const POLL_MIN_MAX_EVENTS = 1;\n/** Public codex_check default for action=\"respond_*\" when maxEvents is omitted. */\nexport const RESPOND_DEFAULT_MAX_EVENTS = 0;\n/**\n * Internal SessionManager fallback for direct poll helpers.\n * Not used as codex_check external default.\n */\nexport const DEFAULT_MAX_EVENTS = 200;\nexport const DEFAULT_EVENT_BUFFER_SIZE = 1000;\nexport const DEFAULT_EVENT_BUFFER_HARD_SIZE = 2000;\nexport const DEFAULT_APPROVAL_TIMEOUT_MS = 60_000;\nexport const DEFAULT_IDLE_CLEANUP_MS = 30 * 60 * 1000;\nexport const DEFAULT_RUNNING_CLEANUP_MS = 4 * 60 * 60 * 1000;\nexport const DEFAULT_TERMINAL_CLEANUP_MS = 5 * 60 * 1000;\nexport const CLEANUP_INTERVAL_MS = 60_000;\n","/**\n * cwd resolution + validation helpers.\n *\n * - Resolves relative paths against a provided base (not process.cwd()).\n * - Ensures the resolved path exists and is a directory.\n */\nimport { existsSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { ErrorCode } from \"../types.js\";\n\nexport function resolveAndValidateCwd(inputCwd: string | undefined, baseCwd: string): string {\n const candidate = inputCwd ?? baseCwd;\n const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(baseCwd, candidate);\n\n if (!existsSync(resolved)) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cwd does not exist: ${resolved}`);\n }\n\n try {\n const stat = statSync(resolved);\n if (!stat.isDirectory()) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cwd is not a directory: ${resolved}`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes(`Error [${ErrorCode.INVALID_ARGUMENT}]`)) {\n throw err;\n }\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cannot access cwd: ${resolved}`);\n }\n\n return resolved;\n}\n","/**\n * Redaction helpers for user-facing text.\n *\n * Goal: avoid leaking full local file paths in errors/events (spawn failures often include them).\n */\n\nexport function redactPaths(message: string): string {\n const uncPath = /(^|[\\s'\"(])\\\\\\\\[^\\s\\\\/:]+\\\\[^\\s:]+(?:\\\\[^\\s:]+)*/g;\n const windowsPath = /\\b[A-Za-z]:\\\\[^\\s:]+/g;\n const posixPath = /(^|[\\s'\"(])\\/[^\\s:'\")]*\\/[^\\s:'\")]+/g;\n return message\n .replace(uncPath, (_m, prefix: string) => `${prefix}<path>`)\n .replace(windowsPath, \"<path>\")\n .replace(posixPath, (_m, prefix: string) => `${prefix}<path>`);\n}\n","/**\n * File path resolution + validation helpers.\n */\nimport { existsSync, statSync } from \"fs\";\nimport path from \"path\";\nimport { ErrorCode } from \"../types.js\";\n\nexport function resolveAndValidateFilePath(\n inputPath: string,\n baseDir: string,\n label = \"path\"\n): string {\n const resolved = path.isAbsolute(inputPath) ? inputPath : path.resolve(baseDir, inputPath);\n\n if (!existsSync(resolved)) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: ${label} does not exist: ${resolved}`);\n }\n\n try {\n const stat = statSync(resolved);\n if (!stat.isFile()) {\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: ${label} is not a file: ${resolved}`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes(`Error [${ErrorCode.INVALID_ARGUMENT}]`)) {\n throw err;\n }\n throw new Error(`Error [${ErrorCode.INVALID_ARGUMENT}]: cannot access ${label}: ${resolved}`);\n }\n\n return resolved;\n}\n","/**\n * Configuration helpers for codex-mcp.\n */\nimport type { AppServerSpawnOptions } from \"../app-server/lifecycle.js\";\nimport type {\n ApprovalPolicy,\n EffortLevel,\n Personality,\n SandboxMode,\n SummaryMode,\n} from \"../types.js\";\n\nexport interface CodexToolParams {\n prompt: string;\n cwd?: string;\n model?: string;\n profile?: string;\n approvalPolicy: ApprovalPolicy;\n sandbox: SandboxMode;\n effort?: EffortLevel;\n advanced?: {\n baseInstructions?: string;\n developerInstructions?: string;\n personality?: Personality;\n summary?: SummaryMode;\n config?: Record<string, unknown>;\n ephemeral?: boolean;\n outputSchema?: Record<string, unknown>;\n images?: string[];\n approvalTimeoutMs?: number;\n waitForResult?: number;\n };\n}\n\nexport function extractSpawnOptions(params: CodexToolParams): AppServerSpawnOptions {\n return {\n profile: params.profile,\n model: params.model,\n approvalPolicy: params.approvalPolicy,\n sandbox: params.sandbox,\n config: params.advanced?.config,\n };\n}\n","import type {\n CheckResult,\n ExecutionFallbackReason,\n ExecutionInfo,\n InteractionState,\n RecommendedNextAction,\n SessionStatus,\n} from \"../types.js\";\nimport type { SessionManager } from \"../session/manager.js\";\n\nconst TERMINAL_STATUSES = new Set<SessionStatus>([\"idle\", \"error\", \"cancelled\"]);\n\nexport function interactionStateForStatus(status: SessionStatus): InteractionState {\n if (status === \"waiting_approval\") return \"waiting_input\";\n if (TERMINAL_STATUSES.has(status)) return \"finished\";\n return \"working\";\n}\n\nexport function recommendedNextActionForStatus(\n status: SessionStatus,\n actionTypes: Array<\"approval\" | \"user_input\"> = []\n): RecommendedNextAction {\n if (status === \"waiting_approval\") {\n if (actionTypes.includes(\"user_input\")) return \"respond_user_input\";\n if (actionTypes.includes(\"approval\")) return \"respond_permission\";\n }\n if (TERMINAL_STATUSES.has(status)) return \"none\";\n return \"poll\";\n}\n\nexport function buildExecutionInfo(\n waitForResultMs: number | undefined,\n status: SessionStatus,\n fallbackReason?: ExecutionFallbackReason\n): ExecutionInfo {\n const requested = waitForResultMs && waitForResultMs > 0 ? \"foreground\" : \"background\";\n const effective =\n requested === \"foreground\" && TERMINAL_STATUSES.has(status) ? \"foreground\" : \"background\";\n return {\n requested,\n effective,\n waitForResultMs: waitForResultMs && waitForResultMs > 0 ? waitForResultMs : undefined,\n fallbackReason: effective === \"background\" ? fallbackReason : undefined,\n };\n}\n\nexport async function waitForCodexSessionForegroundResult(\n sessionManager: SessionManager,\n sessionId: string,\n waitForResultMs: number,\n signal?: AbortSignal\n): Promise<{\n status: SessionStatus;\n result?: CheckResult[\"result\"];\n completedAt?: string;\n pendingActionTypes?: Array<\"approval\" | \"user_input\">;\n fallbackReason?: ExecutionFallbackReason;\n}> {\n const deadline = Date.now() + Math.min(waitForResultMs, 300_000);\n\n while (Date.now() < deadline) {\n let status: SessionStatus;\n try {\n status = sessionManager.getSession(sessionId).status;\n } catch {\n status = \"error\";\n }\n\n if (TERMINAL_STATUSES.has(status)) {\n const finalResult = sessionManager.getLastResult(sessionId);\n return {\n status,\n result: finalResult,\n completedAt: finalResult?.completedAt ?? new Date().toISOString(),\n };\n }\n\n if (status === \"waiting_approval\") {\n return {\n status,\n pendingActionTypes: sessionManager.getPendingActionTypes(sessionId),\n fallbackReason: \"interactive_poll_required\",\n };\n }\n\n const remainingMs = Math.min(deadline - Date.now(), 5_000);\n if (remainingMs <= 0) break;\n try {\n await sessionManager.waitForChange(sessionId, remainingMs, signal);\n } catch {\n break;\n }\n }\n\n let status: SessionStatus = \"running\";\n try {\n status = sessionManager.getSession(sessionId).status;\n } catch {\n status = \"error\";\n }\n return { status, fallbackReason: \"wait_for_result_timeout\" };\n}\n","/**\n * codex tool — start a new Codex agent session.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport type {\n ExecutionInfo,\n InteractionState,\n RecommendedNextAction,\n SessionStatus,\n SessionStartResult,\n TurnResult,\n} from \"../types.js\";\nimport { DEFAULT_EFFORT_LEVEL, WAITING_APPROVAL_POLL_INTERVAL } from \"../types.js\";\nimport type { CodexToolParams } from \"../utils/config.js\";\nimport { extractSpawnOptions } from \"../utils/config.js\";\nimport { resolveAndValidateCwd } from \"../utils/cwd.js\";\nimport {\n buildExecutionInfo,\n interactionStateForStatus,\n recommendedNextActionForStatus,\n waitForCodexSessionForegroundResult,\n} from \"../utils/execution.js\";\n\nexport type CodexCompletedResult = {\n sessionId: string;\n threadId: string;\n result: TurnResult | undefined;\n status: SessionStatus;\n completedAt?: string;\n pollInterval?: number;\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n};\n\nexport async function executeCodex(\n args: CodexToolParams,\n sessionManager: SessionManager,\n serverCwd: string,\n requestSignal?: AbortSignal\n): Promise<SessionStartResult | CodexCompletedResult> {\n const cwd = resolveAndValidateCwd(args.cwd, serverCwd);\n const spawnOpts = extractSpawnOptions(args);\n const effort = args.effort ?? DEFAULT_EFFORT_LEVEL;\n\n const startResult = await sessionManager.createSession(\n args.prompt,\n cwd,\n spawnOpts,\n effort,\n args.advanced\n );\n\n const waitMs = args.advanced?.waitForResult;\n const baseResult: SessionStartResult & {\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n } = {\n ...startResult,\n execution: buildExecutionInfo(waitMs, \"running\"),\n interactionState: interactionStateForStatus(\"running\"),\n recommendedNextAction: recommendedNextActionForStatus(\"running\"),\n };\n\n if (!waitMs || waitMs <= 0) return baseResult;\n\n const foreground = await waitForCodexSessionForegroundResult(\n sessionManager,\n startResult.sessionId,\n waitMs,\n requestSignal\n );\n return {\n sessionId: startResult.sessionId,\n threadId: startResult.threadId,\n result: foreground.result,\n status: foreground.status,\n completedAt: foreground.completedAt,\n pollInterval:\n foreground.status === \"waiting_approval\"\n ? WAITING_APPROVAL_POLL_INTERVAL\n : foreground.status === \"running\"\n ? startResult.pollInterval\n : undefined,\n execution: buildExecutionInfo(waitMs, foreground.status, foreground.fallbackReason),\n interactionState: interactionStateForStatus(foreground.status),\n recommendedNextAction: recommendedNextActionForStatus(\n foreground.status,\n foreground.pendingActionTypes ?? []\n ),\n };\n}\n","/**\n * codex_reply tool — continue an existing session.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport type {\n ApprovalPolicy,\n ExecutionInfo,\n EffortLevel,\n InteractionState,\n Personality,\n RecommendedNextAction,\n SandboxMode,\n SessionStatus,\n SessionStartResult,\n SummaryMode,\n} from \"../types.js\";\nimport { WAITING_APPROVAL_POLL_INTERVAL } from \"../types.js\";\nimport {\n buildExecutionInfo,\n interactionStateForStatus,\n recommendedNextActionForStatus,\n waitForCodexSessionForegroundResult,\n} from \"../utils/execution.js\";\n\nexport interface CodexReplyParams {\n sessionId: string;\n prompt: string;\n model?: string;\n approvalPolicy?: ApprovalPolicy;\n effort?: EffortLevel;\n summary?: SummaryMode;\n personality?: Personality;\n sandbox?: SandboxMode;\n cwd?: string;\n outputSchema?: Record<string, unknown>;\n waitForResult?: number;\n}\n\nexport type CodexReplyResult =\n | (SessionStartResult & {\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n })\n | {\n sessionId: string;\n threadId: string;\n status: SessionStatus;\n pollInterval?: number;\n result?: import(\"../types.js\").TurnResult;\n completedAt?: string;\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n };\n\nexport async function executeCodexReply(\n args: CodexReplyParams,\n sessionManager: SessionManager,\n requestSignal?: AbortSignal\n): Promise<CodexReplyResult> {\n const startResult = await sessionManager.replyToSession(args.sessionId, args.prompt, {\n model: args.model,\n approvalPolicy: args.approvalPolicy,\n effort: args.effort,\n summary: args.summary,\n personality: args.personality,\n sandbox: args.sandbox,\n cwd: args.cwd,\n outputSchema: args.outputSchema,\n });\n\n const waitMs = args.waitForResult;\n const baseResult: SessionStartResult & {\n execution?: ExecutionInfo;\n interactionState?: InteractionState;\n recommendedNextAction?: RecommendedNextAction;\n } = {\n ...startResult,\n execution: buildExecutionInfo(waitMs, \"running\"),\n interactionState: interactionStateForStatus(\"running\"),\n recommendedNextAction: recommendedNextActionForStatus(\"running\"),\n };\n\n if (!waitMs || waitMs <= 0) {\n return baseResult;\n }\n\n const foreground = await waitForCodexSessionForegroundResult(\n sessionManager,\n startResult.sessionId,\n waitMs,\n requestSignal\n );\n return {\n sessionId: startResult.sessionId,\n threadId: startResult.threadId,\n status: foreground.status,\n pollInterval:\n foreground.status === \"waiting_approval\"\n ? WAITING_APPROVAL_POLL_INTERVAL\n : foreground.status === \"running\"\n ? startResult.pollInterval\n : undefined,\n result: foreground.result,\n completedAt: foreground.completedAt,\n execution: buildExecutionInfo(waitMs, foreground.status, foreground.fallbackReason),\n interactionState: interactionStateForStatus(foreground.status),\n recommendedNextAction: recommendedNextActionForStatus(\n foreground.status,\n foreground.pendingActionTypes ?? []\n ),\n };\n}\n","/**\n * codex_session tool — manage sessions (list/get/cancel/interrupt/fork/clean_background_terminals).\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport { ErrorCode, type SessionAction } from \"../types.js\";\n\nexport interface CodexSessionParams {\n action: SessionAction;\n sessionId?: string;\n includeSensitive?: boolean;\n}\n\nexport async function executeCodexSession(\n args: CodexSessionParams,\n sessionManager: SessionManager\n): Promise<unknown> {\n switch (args.action) {\n case \"list\":\n return { sessions: sessionManager.listSessions() };\n\n case \"get\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'get'`,\n isError: true,\n };\n }\n return sessionManager.getSession(args.sessionId, args.includeSensitive);\n\n case \"cancel\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'cancel'`,\n isError: true,\n };\n }\n await sessionManager.cancelSession(args.sessionId);\n return { success: true, message: `Session ${args.sessionId} cancelled` };\n\n case \"interrupt\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'interrupt'`,\n isError: true,\n };\n }\n await sessionManager.interruptSession(args.sessionId);\n return { success: true, message: `Session ${args.sessionId} interrupted` };\n\n case \"fork\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'fork'`,\n isError: true,\n };\n }\n return await sessionManager.forkSession(args.sessionId);\n\n case \"clean_background_terminals\":\n if (!args.sessionId) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: sessionId required for 'clean_background_terminals'`,\n isError: true,\n };\n }\n await sessionManager.cleanBackgroundTerminals(args.sessionId);\n return {\n success: true,\n message: `Background terminals cleaned for session ${args.sessionId}`,\n };\n\n default:\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown action '${args.action}'`,\n isError: true,\n };\n }\n}\n","/**\n * codex_check tool — poll events + respond to approvals/user input.\n */\nimport type { SessionManager } from \"../session/manager.js\";\nimport {\n ALL_DECISIONS,\n ErrorCode,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n type NetworkPolicyAmendment,\n type ApprovalDecision,\n type CheckAction,\n type CheckResult,\n type PollOptions,\n type ResponseMode,\n} from \"../types.js\";\nimport { interactionStateForStatus, recommendedNextActionForStatus } from \"../utils/execution.js\";\n\nexport interface CodexCheckParams {\n action: CheckAction;\n sessionId: string;\n // poll params\n cursor?: number;\n maxEvents?: number;\n // respond_permission params\n requestId?: string;\n decision?: ApprovalDecision;\n execpolicy_amendment?: string[];\n network_policy_amendment?: NetworkPolicyAmendment;\n denyMessage?: string;\n // respond_user_input params\n answers?: Record<string, { answers: string[] }>;\n responseMode?: ResponseMode;\n pollOptions?: PollOptions;\n}\n\nexport type CodexCheckReturn =\n | CheckResult\n | { error: string; isError: true }\n | Promise<CheckResult | { error: string; isError: true }>;\n\nexport function executeCodexCheck(\n args: CodexCheckParams,\n sessionManager: SessionManager,\n requestSignal?: AbortSignal\n): CodexCheckReturn {\n const responseMode = args.responseMode ?? \"minimal\";\n const pollOptions = args.pollOptions;\n\n switch (args.action) {\n case \"poll\": {\n if (\n args.requestId !== undefined ||\n args.decision !== undefined ||\n args.execpolicy_amendment !== undefined ||\n args.network_policy_amendment !== undefined ||\n args.denyMessage !== undefined ||\n args.answers !== undefined\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId/decision/execpolicy_amendment/network_policy_amendment/denyMessage/answers are only valid for respond_* actions`,\n isError: true,\n };\n }\n // Default to a single incremental event for lightweight polling.\n // Polling with maxEvents=0 can cause no-op loops in some clients, so\n // enforce a minimum of 1 for poll.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(POLL_MIN_MAX_EVENTS, Math.floor(args.maxEvents))\n : POLL_DEFAULT_MAX_EVENTS;\n\n // Long-poll: if no events are immediately available and waitMs is requested, wait.\n const waitMs = pollOptions?.waitMs;\n if (typeof waitMs === \"number\" && waitMs > 0) {\n const firstCheck = sessionManager.pollEvents(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n });\n const hasData =\n firstCheck.events.length > 0 ||\n (firstCheck.actions !== undefined && firstCheck.actions.length > 0) ||\n firstCheck.result !== undefined;\n if (!hasData) {\n const clampedWait = Math.min(waitMs, 120_000);\n return sessionManager\n .waitForChange(args.sessionId, clampedWait, requestSignal)\n .catch(() => undefined)\n .then(() =>\n enrichCheckResult(\n sessionManager,\n sessionManager.pollEvents(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n })\n )\n );\n }\n return enrichCheckResult(sessionManager, firstCheck);\n }\n\n return enrichCheckResult(\n sessionManager,\n sessionManager.pollEvents(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n })\n );\n }\n\n case \"respond_permission\": {\n if (!args.requestId || !args.decision) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId and decision required for respond_permission`,\n isError: true,\n };\n }\n if (args.answers !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: answers is only valid for respond_user_input`,\n isError: true,\n };\n }\n if (args.decision === \"acceptWithExecpolicyAmendment\") {\n if (!args.execpolicy_amendment || args.execpolicy_amendment.length === 0) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment required for acceptWithExecpolicyAmendment`,\n isError: true,\n };\n }\n } else if (args.execpolicy_amendment !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicy_amendment is only valid with decision='acceptWithExecpolicyAmendment'`,\n isError: true,\n };\n }\n\n if (args.decision === \"applyNetworkPolicyAmendment\") {\n if (!args.network_policy_amendment) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment required for applyNetworkPolicyAmendment`,\n isError: true,\n };\n }\n if (\n args.network_policy_amendment.action !== \"allow\" &&\n args.network_policy_amendment.action !== \"deny\"\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.action must be 'allow' or 'deny'`,\n isError: true,\n };\n }\n if (!args.network_policy_amendment.host) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment.host required for applyNetworkPolicyAmendment`,\n isError: true,\n };\n }\n } else if (args.network_policy_amendment !== undefined) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: network_policy_amendment is only valid with decision='applyNetworkPolicyAmendment'`,\n isError: true,\n };\n }\n if (!ALL_DECISIONS.includes(args.decision)) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown decision '${args.decision}'`,\n isError: true,\n };\n }\n try {\n sessionManager.resolveApproval(args.sessionId, args.requestId, args.decision, {\n execpolicy_amendment: args.execpolicy_amendment,\n network_policy_amendment: args.network_policy_amendment,\n denyMessage: args.denyMessage,\n });\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { error: message, isError: true };\n }\n // For respond_* actions:\n // - use monotonic cursor progression to avoid replay when some MCP hosts\n // send stale/default cursor values.\n // - default to compact ACK (maxEvents=0) to avoid returning large event\n // payloads on approval/user-input responses.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(0, Math.floor(args.maxEvents))\n : RESPOND_DEFAULT_MAX_EVENTS;\n return enrichCheckResult(\n sessionManager,\n sessionManager.pollEventsMonotonic(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n })\n );\n }\n\n case \"respond_user_input\": {\n if (!args.requestId || !args.answers) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId and answers required for respond_user_input`,\n isError: true,\n };\n }\n if (\n args.decision !== undefined ||\n args.execpolicy_amendment !== undefined ||\n args.network_policy_amendment !== undefined ||\n args.denyMessage !== undefined\n ) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: decision/execpolicy_amendment/network_policy_amendment/denyMessage are only valid for respond_permission`,\n isError: true,\n };\n }\n try {\n sessionManager.resolveUserInput(args.sessionId, args.requestId, args.answers);\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { error: message, isError: true };\n }\n // For respond_* actions:\n // - use monotonic cursor progression to avoid replay when some MCP hosts\n // send stale/default cursor values.\n // - default to compact ACK (maxEvents=0) to avoid returning large event\n // payloads on approval/user-input responses.\n const maxEvents =\n typeof args.maxEvents === \"number\"\n ? Math.max(0, Math.floor(args.maxEvents))\n : RESPOND_DEFAULT_MAX_EVENTS;\n return enrichCheckResult(\n sessionManager,\n sessionManager.pollEventsMonotonic(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n })\n );\n }\n\n default:\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: Unknown action '${args.action}'`,\n isError: true,\n };\n }\n}\n\nfunction enrichCheckResult(sessionManager: SessionManager, result: CheckResult): CheckResult {\n const actionTypes =\n result.status === \"waiting_approval\"\n ? sessionManager.getPendingActionTypes(result.sessionId)\n : [];\n return {\n ...result,\n interactionState: interactionStateForStatus(result.status),\n recommendedNextAction: recommendedNextActionForStatus(result.status, actionTypes),\n };\n}\n","import { spawnSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { homedir } from \"os\";\nimport path from \"path\";\nimport { detectClientMode, type ClientMode } from \"../app-server/detect.js\";\nimport { resolveCodexInvocation } from \"../app-server/codex-bin.js\";\nimport {\n resolveDefaultCodexExecutable,\n type CodexExecutableInfo,\n} from \"../utils/codex-executable.js\";\n\nexport interface CodexSetupInput {\n cwd?: string;\n}\n\ntype AuthState = \"authenticated\" | \"unauthenticated\" | \"unknown\";\n\nexport interface CodexSetupResult {\n ready: boolean;\n cwd: string;\n executable: {\n ok: boolean;\n source: CodexExecutableInfo[\"source\"] | \"error\";\n command?: string;\n isPath?: boolean;\n detail: string;\n };\n auth: {\n ok: boolean;\n state: AuthState;\n detail: string;\n };\n runtime: {\n sameMachineRequired: true;\n clientMode?: ClientMode;\n stateDir: string;\n };\n projectContext: {\n hasUserConfig: boolean;\n hasProjectConfig: boolean;\n };\n warnings: string[];\n nextSteps: string[];\n}\n\nfunction classifyAuthResult(status: number | null, combined: string): AuthState {\n if (status === 0) return \"authenticated\";\n if (/(not (logged|authenticated)|login required|run\\s+codex\\s+login)/i.test(combined)) {\n return \"unauthenticated\";\n }\n return \"unknown\";\n}\n\nfunction resolveCodexStateDir(): string {\n const configured = process.env.CODEX_MCP_STATE_DIR?.trim();\n return configured && configured !== \"\" ? configured : path.join(homedir(), \".codex-mcp\", \"state\");\n}\n\nfunction probeCodexAuth(info: CodexExecutableInfo): CodexSetupResult[\"auth\"] {\n const invocation = resolveCodexInvocation([\"login\", \"status\"], {\n codexCommand: info.command,\n codexIsPath: info.isPath,\n });\n const run = spawnSync(invocation.cmd, invocation.args, {\n encoding: \"utf8\",\n timeout: 5000,\n windowsHide: true,\n });\n const combined = `${run.stdout ?? \"\"}\\n${run.stderr ?? \"\"}`.trim();\n if (run.error) {\n return {\n ok: false,\n state: \"unknown\",\n detail: `Failed to probe auth status: ${run.error.message}`,\n };\n }\n const state = classifyAuthResult(run.status, combined);\n return {\n ok: state !== \"unauthenticated\",\n state,\n detail: combined || (state === \"authenticated\" ? \"Authenticated.\" : \"Auth status unknown.\"),\n };\n}\n\nexport async function executeCodexSetup(\n input: CodexSetupInput | undefined,\n serverCwd: string\n): Promise<CodexSetupResult> {\n const cwd = input?.cwd && input.cwd.trim() !== \"\" ? input.cwd : serverCwd;\n const warnings: string[] = [];\n const nextSteps: string[] = [];\n\n let executable: CodexSetupResult[\"executable\"];\n let auth: CodexSetupResult[\"auth\"];\n let clientMode: ClientMode | undefined;\n\n try {\n const info = resolveDefaultCodexExecutable();\n const available = info.source !== \"default\";\n executable = {\n ok: available,\n source: info.source,\n command: info.command,\n isPath: info.isPath,\n detail:\n info.source === \"default\"\n ? \"No codex executable was auto-detected; the server would fall back to `codex` and let process spawn fail later.\"\n : `Codex resolves via ${info.source}.`,\n };\n\n if (available) {\n auth = probeCodexAuth(info);\n clientMode = await detectClientMode(info.command, info.isPath);\n } else {\n auth = {\n ok: false,\n state: \"unknown\",\n detail: \"Auth status not checked because no codex executable was detected.\",\n };\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n executable = {\n ok: false,\n source: \"error\",\n detail: message,\n };\n auth = {\n ok: false,\n state: \"unknown\",\n detail: \"Auth status not checked because executable resolution failed.\",\n };\n }\n\n const projectContext = {\n hasUserConfig: existsSync(path.join(homedir(), \".codex\", \"config.toml\")),\n hasProjectConfig: existsSync(path.join(cwd, \".codex\", \"config.toml\")),\n };\n\n if (!executable.ok) {\n warnings.push(executable.detail);\n nextSteps.push(\n \"Install Codex or fix CODEX_MCP_COMMAND / CODEX_MCP_PATH so the executable can be resolved.\"\n );\n }\n if (auth.state === \"unauthenticated\") {\n warnings.push(auth.detail);\n nextSteps.push(\"Run `codex login` and rerun `codex_setup`.\");\n } else if (auth.state === \"unknown\") {\n warnings.push(auth.detail);\n nextSteps.push(\n \"Verify Codex authentication explicitly (for example with `codex login status`) before relying on this environment.\"\n );\n }\n if (!projectContext.hasUserConfig && !projectContext.hasProjectConfig) {\n warnings.push(\"No Codex config.toml was found in ~/.codex or this project.\");\n }\n if (clientMode === \"exec\") {\n warnings.push(\n \"Codex app-server support was not detected; codex-mcp would run in exec fallback mode with fewer capabilities.\"\n );\n }\n\n return {\n ready: executable.ok && auth.ok,\n cwd,\n executable,\n auth,\n runtime: {\n sameMachineRequired: true,\n clientMode,\n stateDir: resolveCodexStateDir(),\n },\n projectContext,\n warnings,\n nextSteps,\n };\n}\n","/**\n * Detect whether the codex binary supports app-server mode.\n *\n * Falls back to exec mode when app-server is unavailable.\n * Can be overridden via CODEX_MCP_MODE env var.\n */\nimport { spawn } from \"child_process\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\n\nexport type ClientMode = \"app-server\" | \"exec\";\n\nconst DETECTION_TIMEOUT_MS = 5_000;\n\n/**\n * Detect whether the codex binary supports app-server mode.\n *\n * 1. If CODEX_MCP_MODE is set, use it directly.\n * 2. Otherwise probe `<binary> app-server --help` with a timeout.\n */\nexport async function detectClientMode(\n codexCommand: string,\n codexIsPath = false,\n env: NodeJS.ProcessEnv = process.env\n): Promise<ClientMode> {\n const override = env.CODEX_MCP_MODE;\n if (override === \"app-server\" || override === \"exec\") {\n return override;\n }\n\n try {\n const supported = await probeAppServer(codexCommand, codexIsPath, env);\n return supported ? \"app-server\" : \"exec\";\n } catch {\n return \"exec\";\n }\n}\n\n/**\n * Probe whether `<binary> app-server --help` succeeds.\n */\nfunction probeAppServer(\n codexCommand: string,\n codexIsPath: boolean,\n env: NodeJS.ProcessEnv\n): Promise<boolean> {\n return new Promise((resolve) => {\n const invocation = resolveCodexInvocation([\"app-server\", \"--help\"], {\n env,\n codexCommand,\n codexIsPath,\n });\n\n let settled = false;\n const settle = (result: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(result);\n };\n\n let stdout = \"\";\n let stderr = \"\";\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env,\n windowsHide: true,\n });\n\n proc.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n proc.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n proc.on(\"error\", () => {\n // ENOENT or other spawn failure\n settle(false);\n });\n\n proc.on(\"exit\", (code) => {\n if (code === 0) {\n settle(true);\n } else {\n // Check if stderr/stdout suggests \"unknown subcommand\"\n const combined = (stdout + stderr).toLowerCase();\n const isUnknown =\n combined.includes(\"unknown\") ||\n combined.includes(\"unrecognized\") ||\n combined.includes(\"not found\") ||\n combined.includes(\"no such subcommand\");\n settle(!isUnknown && combined.includes(\"app-server\"));\n }\n });\n\n const timer = setTimeout(() => {\n try {\n proc.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n // Force kill after grace period if still alive\n const forceKill = setTimeout(() => {\n try {\n if (!proc.killed && proc.exitCode === null) {\n proc.kill(\"SIGKILL\");\n }\n } catch {\n /* ignore */\n }\n }, 2000);\n if (forceKill.unref) forceKill.unref();\n settle(false);\n }, DETECTION_TIMEOUT_MS);\n if (timer.unref) timer.unref();\n });\n}\n","import { spawnSync } from \"child_process\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ReadResourceResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { SessionManager } from \"../session/manager.js\";\nimport {\n APPROVAL_POLICIES,\n SANDBOX_MODES,\n EFFORT_LEVELS,\n DEFAULT_APPROVAL_TIMEOUT_MS,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\n DEFAULT_IDLE_CLEANUP_MS,\n DEFAULT_RUNNING_CLEANUP_MS,\n DEFAULT_TERMINAL_CLEANUP_MS,\n ErrorCode,\n} from \"../types.js\";\nimport { resolveStdioMode } from \"../utils/stdio-guard.js\";\nimport { getDefaultCodexExecutable } from \"../utils/codex-executable.js\";\n\nconst RESOURCE_SCHEME = \"codex-mcp\";\n\nexport const RESOURCE_URIS = {\n serverInfo: `${RESOURCE_SCHEME}:///server-info`,\n compatReport: `${RESOURCE_SCHEME}:///compat-report`,\n config: `${RESOURCE_SCHEME}:///config`,\n gotchas: `${RESOURCE_SCHEME}:///gotchas`,\n quickstart: `${RESOURCE_SCHEME}:///quickstart`,\n errors: `${RESOURCE_SCHEME}:///errors`,\n delegationGuide: `${RESOURCE_SCHEME}:///delegation-guide`,\n} as const;\n\ntype RuntimeMetadataProvider = Pick<\n SessionManager,\n \"getActiveSessionCount\" | \"getObservedDefaultModel\"\n>;\n\ninterface ResourceCatalogEntry {\n key: keyof typeof RESOURCE_URIS;\n name: string;\n title: string;\n description: string;\n mimeType: string;\n}\n\nconst RESOURCE_CATALOG: ResourceCatalogEntry[] = [\n {\n key: \"serverInfo\",\n name: \"server_info\",\n title: \"Server Info\",\n description: \"Server metadata and runtime capabilities\",\n mimeType: \"application/json\",\n },\n {\n key: \"compatReport\",\n name: \"compat_report\",\n title: \"Compat Report\",\n description: \"Cross-backend compatibility capability report\",\n mimeType: \"application/json\",\n },\n {\n key: \"config\",\n name: \"config\",\n title: \"Config Guide\",\n description: \"Parameter guide and config.toml mapping\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"gotchas\",\n name: \"gotchas\",\n title: \"Gotchas\",\n description: \"Practical limits and common issues\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"quickstart\",\n name: \"quickstart\",\n title: \"Quickstart\",\n description: \"Minimal end-to-end workflow\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"errors\",\n name: \"errors\",\n title: \"Errors\",\n description: \"Error code reference and recovery hints\",\n mimeType: \"text/markdown\",\n },\n {\n key: \"delegationGuide\",\n name: \"delegation_guide\",\n title: \"Delegation Guide\",\n description: \"Best practices for delegating tasks to Codex\",\n mimeType: \"text/markdown\",\n },\n];\n\nconst ERROR_CODE_HINTS: Record<ErrorCode, string> = {\n [ErrorCode.INVALID_ARGUMENT]: \"Input shape/value mismatch. Fix payload and retry.\",\n [ErrorCode.SESSION_NOT_FOUND]: \"Unknown sessionId or already cleaned up.\",\n [ErrorCode.SESSION_BUSY]: \"Session is running or waiting approval. Poll until idle/error.\",\n [ErrorCode.SESSION_NOT_RUNNING]: \"Action requires running/waiting_approval session.\",\n [ErrorCode.REQUEST_NOT_FOUND]: \"requestId was resolved, stale, or never existed.\",\n [ErrorCode.TIMEOUT]: \"Operation timed out. Retry or use a longer timeout where supported.\",\n [ErrorCode.CANCELLED]: \"Session was cancelled and cannot be resumed.\",\n [ErrorCode.APP_SERVER_START_FAILED]: \"codex app-server failed to boot. Check CLI install/path.\",\n [ErrorCode.THREAD_FORK_RESUME_FAILED]:\n \"Forked thread could not resume in new process. Retry fork from current source session.\",\n [ErrorCode.PROTOCOL_PARSE_ERROR]:\n \"Non-JSON or malformed app-server line. Check shell/profile noise and transport health.\",\n [ErrorCode.WRITE_QUEUE_DROPPED]:\n \"stdin backpressure overflow. Reduce burst size and re-run in smaller turns.\",\n [ErrorCode.EXEC_NOT_SUPPORTED]:\n \"Operation not supported in exec mode. Features like threadFork and threadResume require app-server mode.\",\n [ErrorCode.INTERNAL]: \"Unexpected server-side failure. Inspect logs and retry safely.\",\n};\n\nfunction asTextResource(uri: URL, text: string, mimeType: string): ReadResourceResult {\n return {\n contents: [\n {\n uri: uri.toString(),\n text,\n mimeType,\n },\n ],\n };\n}\n\nfunction detectCodexCliVersion(timeoutMs = 1500): string | null {\n try {\n const executable = getDefaultCodexExecutable();\n const run = spawnSync(executable.command, [\"--version\"], {\n encoding: \"utf8\",\n timeout: timeoutMs,\n windowsHide: true,\n });\n const combined = `${run.stdout ?? \"\"}\\n${run.stderr ?? \"\"}`.trim();\n if (!combined) return null;\n const versionToken = combined.match(/v?\\d+\\.\\d+\\.\\d+(?:[-+][0-9A-Za-z.-]+)?/);\n if (!versionToken) return combined.split(/\\s+/)[0] ?? null;\n return versionToken[0].replace(/^v/, \"\");\n } catch {\n return null;\n }\n}\n\nfunction msToMinutes(ms: number): number {\n return Math.floor(ms / 60_000);\n}\n\nfunction buildConfigGuideText(): string {\n return [\n \"## Top-level parameters (`codex`)\",\n \"\",\n \"- Required: `prompt`, `approvalPolicy`, `sandbox`.\",\n \"- Optional: `effort` (default `low`), `cwd` (default server cwd), `model` (default config.toml), `profile` (default CLI profile), `advanced`.\",\n \"- Prefer passing `cwd` explicitly to avoid accidental server-cwd execution.\",\n \"\",\n \"## `advanced.*` guide\",\n \"\",\n \"- `advanced.baseInstructions`: replace default system instructions for this session (default: unchanged).\",\n \"- `advanced.developerInstructions`: append extra developer instructions (default: none).\",\n \"- `advanced.personality`: optional personality preset (default: config.toml).\",\n \"- `advanced.summary`: summary verbosity preset for turn output (default: config.toml).\",\n \"- `advanced.ephemeral`: do not persist thread state remotely (default `false`).\",\n \"- `advanced.images`: local image file paths on the same host as codex-mcp (default: none).\",\n `- \\`advanced.approvalTimeoutMs\\`: auto-decline timeout for approval/user-input requests (default \\`${DEFAULT_APPROVAL_TIMEOUT_MS}\\` ms).`,\n \"- `advanced.outputSchema`: JSON Schema for structured output from `codex` turns (default: none).\",\n \"\",\n \"## `advanced.config` mapping\",\n \"\",\n \"Forwarded as `-c key=value` flags to `codex app-server`.\",\n \"Primitives use `String(value)`; objects/arrays use `JSON.stringify(value)`.\",\n \"\",\n \"Prefer dedicated top-level params when available:\",\n \"\",\n \"- `codex.model` -> `-c model=...`\",\n \"- `codex.approvalPolicy` -> `-c approval_policy=...`\",\n \"- `codex.sandbox` -> `-c sandbox_mode=...`\",\n \"- `codex.effort` -> turn-level reasoning effort (do not encode in `advanced.config`)\",\n \"- `codex.profile` -> `-p ...`\",\n \"\",\n \"## `codex_reply` differences\",\n \"\",\n \"- `codex_reply.outputSchema` is top-level.\",\n \"- `codex.outputSchema` lives under `advanced.outputSchema`.\",\n \"- `codex_reply` can override `model`, `approvalPolicy`, `sandbox`, `effort`, `summary`, `personality`, and `cwd`.\",\n \"- `codex_reply` only works when session state is `idle` or `error`; otherwise returns `SESSION_BUSY`.\",\n \"- All `codex_reply` override fields default to no override when omitted.\",\n \"\",\n \"## Override persistence (`codex_reply`)\",\n \"\",\n \"- `model`, `approvalPolicy`, `sandbox`, and `cwd` update in-memory session defaults for later turns.\",\n \"- `effort`, `summary`, `personality`, and `outputSchema` apply to the submitted turn payload.\",\n \"\",\n \"## Version compatibility note\",\n \"\",\n \"Available `advanced.config` keys depend on installed Codex CLI version.\",\n \"To inspect your local CLI version, read `codex-mcp:///server-info` (`codexCliVersion`).\",\n \"\",\n \"## Other tool defaults (quick reference)\",\n \"\",\n \"- `codex_session.includeSensitive`: default `false`.\",\n `- \\`codex_check.poll.maxEvents\\`: default \\`${POLL_DEFAULT_MAX_EVENTS}\\` (minimum \\`${POLL_MIN_MAX_EVENTS}\\`).`,\n `- \\`codex_check.respond_*.maxEvents\\`: default \\`${RESPOND_DEFAULT_MAX_EVENTS}\\`.`,\n \"- `codex_check.responseMode`: default `minimal` (`minimal` / `delta_compact` / `full`).\",\n \"- `codex_check.pollOptions.includeEvents`: default `true`.\",\n \"- `codex_check.pollOptions.includeActions`: default `true`.\",\n \"- `codex_check.pollOptions.includeResult`: default `true`.\",\n \"- `codex_check.pollOptions.maxBytes`: default unlimited.\",\n \"- `codex_check.cursor`: default is session last consumed cursor when omitted.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildGotchasText(): string {\n return [\n \"## Polling and cursors\",\n \"\",\n '- Sessions are async. Poll `codex_check(action=\"poll\")` until status is `idle`/`error`/`cancelled`.',\n \"- Store `nextCursor` and pass it back to avoid replay.\",\n `- Poll default is \\`maxEvents=${POLL_DEFAULT_MAX_EVENTS}\\` (authoritative: tool schema / constants).`,\n `- Poll enforces minimum \\`maxEvents=${POLL_MIN_MAX_EVENTS}\\`; sending \\`0\\` is normalized to \\`${POLL_MIN_MAX_EVENTS}\\`.`,\n `- \\`respond_permission\\` and \\`respond_user_input\\` default to compact ACK with \\`maxEvents=${RESPOND_DEFAULT_MAX_EVENTS}\\`.`,\n \"- Default response mode is `minimal`; use `full` if you need full raw event payloads.\",\n \"- respond_* uses monotonic cursor handling: `max(cursor, sessionLastCursor)`.\",\n \"- If `cursorResetTo` is present, your cursor is stale (old events were evicted); restart from that value.\",\n \"- **Poll frequency guidance**: Adapt poll interval to task complexity and previous poll results. For `running` sessions, start at 2 minutes and increase for long tasks. Only poll frequently (~1s) when `waiting_approval`. Do NOT high-frequency poll — it wastes tokens and provides no benefit.\",\n \"\",\n \"## Approval behavior\",\n \"\",\n `- Pending approvals/user-input auto-decline after \\`approvalTimeoutMs\\` (default ${DEFAULT_APPROVAL_TIMEOUT_MS} ms).`,\n \"- `untrusted` behavior is enforced by Codex CLI backend and may auto-allow some low-risk commands.\",\n \"- Do not assume every read-only command will always require approval across CLI versions.\",\n `- **Timeout vs polling conflict**: The recommended polling interval for \\`running\\` status is >=120 seconds, but the default approval timeout is ${DEFAULT_APPROVAL_TIMEOUT_MS / 1000} seconds. If a session transitions to \\`waiting_approval\\` between polls, the approval will auto-decline before the client can respond. Set \\`advanced.approvalTimeoutMs\\` to at least 300000 (5 minutes) when using \\`untrusted\\` or \\`on-request\\` policies.`,\n \"\",\n \"## Event model\",\n \"\",\n \"- Top-level `events[].type` is one of: `output`, `progress`, `approval_request`, `approval_result`, `result`, `error`.\",\n \"- Fine-grained stream semantics are in `events[].data.method` (for example command output delta, reasoning delta, turn updates).\",\n '- Retryable interruptions surface as `progress` with `method=\"codex-mcp/reconnect\"` and include retry fields.',\n \"- During reconnect/retry, continue polling normally; if retries stop (`willRetry=false`), session transitions to error path.\",\n \"\",\n \"## Windows shell/profile issues\",\n \"\",\n \"- On Windows wrappers, prefer `pwsh -NoProfile` to avoid profile/banner stdout noise.\",\n \"- Profile noise can affect both MCP handshake and agent-internal command turns.\",\n \"- For mojibake, enforce UTF-8 shell output (`chcp 65001`, `$OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()`).\",\n \"- Prefer host-native absolute paths for `cwd` and file args (Windows example: `D:\\\\\\\\Lab\\\\\\\\codex-mcp`).\",\n \"\",\n \"## Lifecycle and cleanup\",\n \"\",\n `- Idle sessions are auto-cleaned after ${msToMinutes(DEFAULT_IDLE_CLEANUP_MS)} minutes.`,\n `- Running/waiting sessions are auto-cleaned after ${msToMinutes(DEFAULT_RUNNING_CLEANUP_MS)} minutes.`,\n `- Error/cancelled sessions are retained for about ${msToMinutes(DEFAULT_TERMINAL_CLEANUP_MS)} minutes, then removed.`,\n \"- Session state is in-memory. Restarting codex-mcp drops all existing sessions.\",\n \"\",\n \"## Capacity\",\n \"\",\n \"- codex-mcp does not hard-code a strict concurrent-session cap.\",\n \"- Practical limit depends on machine resources and child-process load.\",\n \"\",\n \"## Exec fallback mode\",\n \"\",\n \"- When the codex binary does not support `app-server`, codex-mcp falls back to `exec` mode (`codex exec --json`).\",\n \"- Check `codex-mcp:///server-info` `clientMode` field to detect which mode is active.\",\n \"- **Exec mode supports multi-turn**: first turn uses `codex exec`, subsequent turns use `codex exec resume <threadId>` for context continuity.\",\n \"- **Exec mode limitations**: no approval/user-input interactions, `threadFork`/`threadResume` throw `EXEC_NOT_SUPPORTED`. `sandbox`/`profile`/`cwd`/`outputSchema` overrides only apply on the first turn (exec resume does not support `-s`/`-p`/`-C`/`--output-schema`).\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildQuickstartText(): string {\n return [\n \"## Minimal flow\",\n \"\",\n \"0. Optional but recommended: run `codex_setup` first to verify the local Codex CLI, login state, and backend mode.\",\n \"\",\n \"1. Start session (`codex`)\",\n \"\",\n \"```json\",\n \"{\",\n ' \"prompt\": \"List files and summarize repository purpose.\",',\n ' \"approvalPolicy\": \"on-request\",',\n ' \"sandbox\": \"workspace-write\",',\n ' \"effort\": \"low\",',\n ' \"cwd\": \"D:\\\\\\\\Lab\\\\\\\\codex-mcp\"',\n \"}\",\n \"```\",\n \"\",\n \"Typical start result:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"sessionId\": \"sess_abc123\",',\n ' \"threadId\": \"thread_xyz\",',\n ' \"status\": \"running\",',\n ' \"pollInterval\": 120000',\n \"}\",\n \"```\",\n \"\",\n \"2. Poll incrementally (`codex_check`)\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"poll\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"cursor\": 0,',\n ' \"maxEvents\": 10',\n \"}\",\n \"```\",\n \"\",\n \"- Use `pollInterval` as a minimum delay: `running` >=120000ms (and usually longer for big tasks).\",\n \"- `waiting_approval` is the exception: poll/answer around 1000ms to avoid timeout.\",\n `- When using \\`untrusted\\` or \\`on-request\\` policies, set \\`advanced.approvalTimeoutMs\\` to at least 300000 to prevent approvals from expiring between polling intervals.`,\n \"\",\n \"3. If `actions[]` contains an approval request, respond:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"respond_permission\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"requestId\": \"req_123\",',\n ' \"decision\": \"acceptForSession\"',\n \"}\",\n \"```\",\n \"\",\n \"4. If `actions[]` contains a user-input request, respond:\",\n \"\",\n \"```json\",\n \"{\",\n ' \"action\": \"respond_user_input\",',\n ' \"sessionId\": \"sess_abc123\",',\n ' \"requestId\": \"req_456\",',\n ' \"answers\": {',\n ' \"question-id\": {',\n ' \"answers\": [\"Option A\"]',\n \" }\",\n \" }\",\n \"}\",\n \"```\",\n \"\",\n \"5. Continue polling until terminal status (`idle`, `error`, or `cancelled`), respecting the >=2 minute interval while `running`.\",\n \"\",\n \"## Cursor notes\",\n \"\",\n \"- Omit `cursor` to continue from session last consumed cursor.\",\n `- Omit \\`maxEvents\\`: defaults are poll=${POLL_DEFAULT_MAX_EVENTS}, respond_*=${RESPOND_DEFAULT_MAX_EVENTS}.`,\n \"- Omit `responseMode`: default is `minimal`.\",\n \"- Use returned `nextCursor` for the next call.\",\n \"- If `cursorResetTo` appears, reset to that value and continue.\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildErrorsText(): string {\n const lines: string[] = [\n \"## Error format\",\n \"\",\n \"Tool failures use: `Error [CODE]: message`\",\n \"\",\n \"## Codes\",\n \"\",\n ];\n\n for (const code of Object.values(ErrorCode)) {\n lines.push(`- \\`${code}\\`: ${ERROR_CODE_HINTS[code]}`);\n }\n\n lines.push(\"\");\n lines.push(\"## Recovery basics\");\n lines.push(\"\");\n lines.push(\"- `INVALID_ARGUMENT`: fix payload fields/enums and retry.\");\n lines.push(\"- `SESSION_BUSY`: poll until terminal/idle before issuing incompatible action.\");\n lines.push(\"- `REQUEST_NOT_FOUND`: re-poll and use latest `actions[].requestId`.\");\n lines.push(\"- `PROTOCOL_PARSE_ERROR`: remove shell/profile stdout noise and restart session.\");\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nfunction buildDelegationGuideText(): string {\n return [\n \"# Codex Delegation Guide\",\n \"\",\n \"## When to delegate\",\n \"- Bug investigation or fix that benefits from a second opinion\",\n \"- Code review (use read-only sandbox)\",\n \"- Refactoring or migration tasks with clear scope\",\n \"- Tasks where the calling agent is stuck or wants parallel work\",\n \"\",\n \"## Permission combinations by task type\",\n \"\",\n \"| Task | approvalPolicy | sandbox | Notes |\",\n \"|------|---------------|---------|-------|\",\n \"| Code review / analysis | `never` | `read-only` | Safe: sandbox blocks writes, no approval needed |\",\n \"| Quick bug fix | `on-failure` | `workspace-write` | Auto-approves unless error; good with `waitForResult` |\",\n \"| Feature implementation | `on-failure` | `workspace-write` | Async mode recommended for longer tasks |\",\n \"| Sensitive refactor | `on-request` | `workspace-write` | Codex asks before each action; requires active polling |\",\n \"| Full autonomy | `never` | `workspace-write` | No guardrails — only for well-scoped, trusted tasks |\",\n \"| Network access needed | `on-failure` | `danger-full-access` | Rare; avoid unless genuinely required |\",\n \"\",\n \"**Key rule:** `read-only` sandbox already prevents writes, so `approvalPolicy: 'never'` is safe with it. Avoid `untrusted` + `read-only` — every read command triggers approval for no safety gain.\",\n \"\",\n \"## Quick mode: `waitForResult`\",\n \"For short tasks (< 2 min), set `advanced.waitForResult` to get the final result in a single tool call:\",\n \"```json\",\n '{ \"prompt\": \"Fix the null check in auth.ts\", \"approvalPolicy\": \"on-failure\", \"sandbox\": \"workspace-write\", \"effort\": \"medium\", \"advanced\": { \"waitForResult\": 120000 } }',\n \"```\",\n \"If the task finishes within the timeout, the result is returned directly. Otherwise the response falls back to polling metadata (including `sessionId` and `threadId`).\",\n \"\",\n \"**Constraint:** `waitForResult` blocks your tool call. If the task hits `waiting_approval`, you cannot respond — the timeout will always expire. Only use with `approvalPolicy: 'on-failure'` or `'never'`.\",\n \"\",\n \"## Async mode: poll loop\",\n 'For long tasks, omit `waitForResult`. Use `codex_check(action=\"poll\", pollOptions={ waitMs: 30000 })` with long-polling to avoid empty polls.',\n \"\",\n \"## Effort selection\",\n \"- `low` (default): quick questions, lookups, simple edits\",\n \"- `medium`: multi-file changes, moderate reasoning\",\n \"- `high`/`xhigh`: complex architecture decisions, large refactors\",\n \"\",\n \"## Troubleshooting\",\n \"\",\n \"**Tool call hangs:** Likely `waitForResult` + approval conflict; cancel and retry with `on-failure`/`never`. See `codex-mcp:///gotchas`.\",\n \"\",\n \"**Empty polls:** Use `pollOptions.waitMs` for long-polling; stop when status is terminal. See `codex-mcp:///gotchas`.\",\n \"\",\n \"**Session not found after restart:** Previously-running sessions surface as `status: 'error'` with restart reason. See `codex-mcp:///gotchas`.\",\n \"\",\n \"**Approval timeout:** Default is 60s; infrequent polling causes silent auto-decline. See `codex-mcp:///gotchas`.\",\n \"\",\n \"## Security notes\",\n \"- `sandbox: 'read-only'` is the strongest isolation — blocks all writes regardless of approval policy\",\n \"- `approvalPolicy: 'never'` + `sandbox: 'workspace-write'` gives the agent full write access with no human oversight — use only for well-defined, low-risk tasks\",\n \"- `danger-full-access` allows network and system access — treat as root-equivalent\",\n \"- Persisted session data (events, results) may contain code snippets and file paths — stored in `~/.codex-mcp/state/`\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction buildCompatReport(\n deps: { version: string; sessionManager: RuntimeMetadataProvider },\n codexCliVersion: string | null\n): string {\n const runtimeWarnings: string[] = [];\n if (!codexCliVersion) {\n runtimeWarnings.push(\"Unable to detect local codex CLI version from PATH.\");\n }\n return JSON.stringify(\n {\n schemaVersion: \"1.0.0\",\n features: {\n respondPermission: true,\n respondApprovalAlias: false,\n respondUserInput: true,\n sessionInterrupt: true,\n responseModeMinimal: true,\n responseModeDeltaCompact: true,\n responseModeFull: true,\n pollOptionsBase: true,\n maxBytesTruncation: true,\n compatWarnings: true,\n diskResume: false,\n dynamicTools: false,\n toolPermissionControl: false,\n },\n recommendedSettings: {\n codexCheck: {\n responseMode: \"minimal\",\n pollOptions: {\n includeEvents: true,\n includeActions: true,\n includeResult: true,\n },\n },\n },\n toolCounts: {\n core: 5,\n },\n runtimeWarnings,\n detectedMismatches: [],\n runtime: {\n codexMcpVersion: deps.version,\n codexCliVersion,\n activeSessions: deps.sessionManager.getActiveSessionCount(),\n },\n },\n null,\n 2\n );\n}\n\nexport function registerResources(\n server: Pick<McpServer, \"registerResource\">,\n deps: { version: string; sessionManager: RuntimeMetadataProvider; clientMode?: string }\n): void {\n let codexCliVersionCache: string | null | undefined;\n const getCodexCliVersion = (): string | null => {\n if (codexCliVersionCache !== undefined) return codexCliVersionCache;\n codexCliVersionCache = detectCodexCliVersion();\n return codexCliVersionCache;\n };\n\n const byKey = new Map(RESOURCE_CATALOG.map((entry) => [entry.key, entry]));\n\n const serverInfoMeta = byKey.get(\"serverInfo\")!;\n const serverInfoUri = new URL(RESOURCE_URIS.serverInfo);\n server.registerResource(\n serverInfoMeta.name,\n serverInfoUri.toString(),\n {\n title: serverInfoMeta.title,\n description: serverInfoMeta.description,\n mimeType: serverInfoMeta.mimeType,\n },\n () => {\n const observedModel = deps.sessionManager.getObservedDefaultModel();\n return asTextResource(\n serverInfoUri,\n JSON.stringify(\n {\n name: \"codex-mcp\",\n version: deps.version,\n codexCliVersion: getCodexCliVersion(),\n clientMode: deps.clientMode ?? \"app-server\",\n node: process.version,\n platform: process.platform,\n arch: process.arch,\n stdioMode: resolveStdioMode().mode,\n supportedApprovalPolicies: APPROVAL_POLICIES,\n supportedSandboxModes: SANDBOX_MODES,\n supportedEffortLevels: EFFORT_LEVELS,\n activeSessions: deps.sessionManager.getActiveSessionCount(),\n defaultModel: observedModel,\n defaultModelSource: observedModel ? \"session-default\" : \"unknown\",\n resources: RESOURCE_CATALOG.map((entry) => ({\n uri: RESOURCE_URIS[entry.key],\n title: entry.title,\n mimeType: entry.mimeType,\n description: entry.description,\n })),\n },\n null,\n 2\n ),\n \"application/json\"\n );\n }\n );\n\n const compatReportMeta = byKey.get(\"compatReport\")!;\n const compatReportUri = new URL(RESOURCE_URIS.compatReport);\n server.registerResource(\n compatReportMeta.name,\n compatReportUri.toString(),\n {\n title: compatReportMeta.title,\n description: compatReportMeta.description,\n mimeType: compatReportMeta.mimeType,\n },\n () =>\n asTextResource(\n compatReportUri,\n buildCompatReport(deps, getCodexCliVersion()),\n \"application/json\"\n )\n );\n\n const configMeta = byKey.get(\"config\")!;\n const configUri = new URL(RESOURCE_URIS.config);\n server.registerResource(\n configMeta.name,\n configUri.toString(),\n {\n title: configMeta.title,\n description: configMeta.description,\n mimeType: configMeta.mimeType,\n },\n () => asTextResource(configUri, buildConfigGuideText(), \"text/markdown\")\n );\n\n const gotchasMeta = byKey.get(\"gotchas\")!;\n const gotchasUri = new URL(RESOURCE_URIS.gotchas);\n server.registerResource(\n gotchasMeta.name,\n gotchasUri.toString(),\n {\n title: gotchasMeta.title,\n description: gotchasMeta.description,\n mimeType: gotchasMeta.mimeType,\n },\n () => asTextResource(gotchasUri, buildGotchasText(), \"text/markdown\")\n );\n\n const quickstartMeta = byKey.get(\"quickstart\")!;\n const quickstartUri = new URL(RESOURCE_URIS.quickstart);\n server.registerResource(\n quickstartMeta.name,\n quickstartUri.toString(),\n {\n title: quickstartMeta.title,\n description: quickstartMeta.description,\n mimeType: quickstartMeta.mimeType,\n },\n () => asTextResource(quickstartUri, buildQuickstartText(), \"text/markdown\")\n );\n\n const errorsMeta = byKey.get(\"errors\")!;\n const errorsUri = new URL(RESOURCE_URIS.errors);\n server.registerResource(\n errorsMeta.name,\n errorsUri.toString(),\n {\n title: errorsMeta.title,\n description: errorsMeta.description,\n mimeType: errorsMeta.mimeType,\n },\n () => asTextResource(errorsUri, buildErrorsText(), \"text/markdown\")\n );\n\n const delegationGuideMeta = byKey.get(\"delegationGuide\")!;\n const delegationGuideUri = new URL(RESOURCE_URIS.delegationGuide);\n server.registerResource(\n delegationGuideMeta.name,\n delegationGuideUri.toString(),\n {\n title: delegationGuideMeta.title,\n description: delegationGuideMeta.description,\n mimeType: delegationGuideMeta.mimeType,\n },\n () => asTextResource(delegationGuideUri, buildDelegationGuideText(), \"text/markdown\")\n );\n}\n","/**\n * STDIO preflight guard.\n *\n * Purpose:\n * - Detect elevated risk of stdout contamination before MCP stdio handshake.\n * - Support caller-selected behavior via CODEX_MCP_STDIO_MODE.\n */\n\nexport const STDIO_MODES = [\"auto\", \"strict\", \"off\"] as const;\nexport type StdioMode = (typeof STDIO_MODES)[number];\n\nexport interface StdioModeResolution {\n mode: StdioMode;\n source: \"default\" | \"env\" | \"env_invalid\";\n invalidRaw?: string;\n}\n\nexport interface StdioPreflightOptions {\n platform?: NodeJS.Platform;\n env?: NodeJS.ProcessEnv;\n stdinIsTTY?: boolean;\n stdoutIsTTY?: boolean;\n}\n\nexport interface StdioPreflightResult {\n mode: StdioMode;\n modeSource: StdioModeResolution[\"source\"];\n invalidMode?: string;\n riskLevel: \"low\" | \"elevated\";\n riskReasons: string[];\n blockingReasons: string[];\n notes: string[];\n suggestions: string[];\n shouldBlock: boolean;\n}\n\nexport function resolveStdioMode(env: NodeJS.ProcessEnv = process.env): StdioModeResolution {\n const raw = env.CODEX_MCP_STDIO_MODE;\n if (raw === undefined) {\n return { mode: \"auto\", source: \"default\" };\n }\n\n const normalized = raw.trim().toLowerCase();\n if (normalized === \"\") {\n return { mode: \"auto\", source: \"default\" };\n }\n\n if ((STDIO_MODES as readonly string[]).includes(normalized)) {\n return { mode: normalized as StdioMode, source: \"env\" };\n }\n\n return { mode: \"auto\", source: \"env_invalid\", invalidRaw: raw };\n}\n\nexport function runStdioPreflight(opts: StdioPreflightOptions = {}): StdioPreflightResult {\n const platform = opts.platform ?? process.platform;\n const env = opts.env ?? process.env;\n const stdinIsTTY = opts.stdinIsTTY ?? Boolean(process.stdin.isTTY);\n const stdoutIsTTY = opts.stdoutIsTTY ?? Boolean(process.stdout.isTTY);\n\n const modeResolution = resolveStdioMode(env);\n const notes: string[] = [];\n const riskReasons: string[] = [];\n\n if (modeResolution.source === \"env_invalid\" && modeResolution.invalidRaw) {\n notes.push(\n `Invalid CODEX_MCP_STDIO_MODE='${modeResolution.invalidRaw}'. Falling back to 'auto'.`\n );\n }\n\n // In \"off\" mode, guard is intentionally disabled.\n if (modeResolution.mode === \"off\") {\n return {\n mode: modeResolution.mode,\n modeSource: modeResolution.source,\n invalidMode: modeResolution.invalidRaw,\n riskLevel: \"low\",\n riskReasons: [],\n blockingReasons: [],\n notes,\n suggestions: [],\n shouldBlock: false,\n };\n }\n\n const blockingReasons: string[] = [];\n\n if (platform === \"win32\" && looksLikePowerShell(env)) {\n riskReasons.push(\n \"PowerShell environment detected on Windows; shell profiles can print banner text to stdout.\"\n );\n }\n\n if (stdinIsTTY || stdoutIsTTY) {\n const ttyRisk =\n \"STDIO appears attached to a terminal (TTY). MCP clients should launch codex-mcp with piped stdio.\";\n notes.push(ttyRisk);\n riskReasons.push(ttyRisk);\n blockingReasons.push(ttyRisk);\n }\n\n const riskLevel: StdioPreflightResult[\"riskLevel\"] = riskReasons.length > 0 ? \"elevated\" : \"low\";\n const shouldBlock = modeResolution.mode === \"strict\" && blockingReasons.length > 0;\n\n return {\n mode: modeResolution.mode,\n modeSource: modeResolution.source,\n invalidMode: modeResolution.invalidRaw,\n riskLevel,\n riskReasons,\n blockingReasons,\n notes,\n suggestions: riskReasons.length > 0 ? buildFixSuggestions(platform) : [],\n shouldBlock,\n };\n}\n\nfunction looksLikePowerShell(env: NodeJS.ProcessEnv): boolean {\n return Boolean(\n env.POWERSHELL_DISTRIBUTION_CHANNEL ||\n env.PSModulePath ||\n env.PSExecutionPolicyPreference ||\n env.PSModuleAnalysisCachePath\n );\n}\n\nfunction buildFixSuggestions(platform: NodeJS.Platform): string[] {\n const generic = [\n \"Prefer direct MCP config launch: command='npx', args=['-y', '@leo000001/codex-mcp']\",\n \"Keep server stdout strictly JSON-RPC; route diagnostics to stderr only.\",\n \"codex-mcp cannot sanitize shell/profile stdout once emitted before MCP handshake.\",\n ];\n\n if (platform === \"win32\") {\n return [\n 'If shell wrapping is required, use: pwsh -NoProfile -Command \"npx -y @leo000001/codex-mcp\"',\n \"Disable noisy PowerShell profile output (oh-my-posh banners, startup prompts, etc.).\",\n ...generic,\n ];\n }\n\n return generic;\n}\n","/**\n * ExecClient — codex exec --json based client.\n *\n * Fallback for codex variants that don't support app-server.\n * Spawns `codex exec \"<prompt>\" --json --skip-git-repo-check` per turn\n * and transforms JSONL stdout events into the app-server notification format\n * that SessionManager expects.\n */\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { writeFileSync, mkdtempSync, rmSync } from \"fs\";\nimport { EventEmitter } from \"events\";\nimport { randomUUID } from \"crypto\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { StringDecoder } from \"string_decoder\";\nimport type { ICodexClient } from \"./client-interface.js\";\nimport type { AppServerSpawnOptions } from \"./lifecycle.js\";\nimport {\n type RequestId,\n type InitializeResult,\n type ThreadStartParams,\n type ThreadStartResult,\n type ThreadForkParams,\n type ThreadForkResult,\n type ThreadResumeParams,\n type ThreadResumeResult,\n type ThreadBackgroundTerminalsCleanParams,\n type TurnStartParams,\n type TurnStartResult,\n type TurnInterruptParams,\n type SandboxPolicy,\n Methods,\n} from \"./protocol.js\";\nimport { resolveCodexInvocation } from \"./codex-bin.js\";\nimport { ErrorCode } from \"../types.js\";\nimport { getDefaultCodexExecutable } from \"../utils/codex-executable.js\";\n\ntype NotificationHandler = (method: string, params: unknown) => void;\ntype ServerRequestHandler = (id: RequestId, method: string, params: unknown) => void;\n\nconst FORCE_KILL_TIMEOUT_MS = 5_000;\n\n/**\n * Convert snake_case item type from exec JSONL to camelCase used by app-server protocol.\n */\nfunction camelCaseItemType(snakeType: string): string {\n return snakeType.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase());\n}\n\n/**\n * Deep-transform item object: convert `type` field from snake_case to camelCase.\n */\nfunction transformItem(item: Record<string, unknown>): Record<string, unknown> {\n const result = { ...item };\n if (typeof result.type === \"string\") {\n result.type = camelCaseItemType(result.type);\n }\n return result;\n}\n\n/**\n * Detect whether an exec `{\"type\":\"error\"}` event is a transient/retryable error\n * (e.g. \"Reconnecting... n/5\") vs a terminal failure.\n */\nfunction isRetryableError(event: Record<string, unknown>): boolean {\n const msg = typeof event.message === \"string\" ? event.message : \"\";\n return /reconnect/i.test(msg) || /\\d+\\/\\d+/.test(msg);\n}\n\n/**\n * Reverse-map SandboxPolicy object back to sandbox mode string for -s flag.\n */\nfunction sandboxPolicyToMode(policy: SandboxPolicy): string | undefined {\n switch (policy.type) {\n case \"readOnly\":\n return \"read-only\";\n case \"workspaceWrite\":\n return \"workspace-write\";\n case \"dangerFullAccess\":\n return \"danger-full-access\";\n case \"externalSandbox\":\n // externalSandbox has no direct CLI equivalent; log and return undefined\n // so the caller falls back to thread/spawn-level sandbox.\n console.error(\n `[exec-client] SandboxPolicy type \"externalSandbox\" cannot be mapped to exec -s flag; using thread-level sandbox`\n );\n return undefined;\n default:\n return undefined;\n }\n}\n\n/**\n * Map exec JSONL event type (snake_case) to app-server notification method.\n * Covers all events from codex-schema/EventMsg.json that have corresponding\n * app-server notification methods in SessionManager.registerHandlers().\n */\nconst EXEC_EVENT_TO_METHOD: Record<string, string> = {\n // Agent message deltas\n agent_message_delta: Methods.AGENT_MESSAGE_DELTA,\n agent_message_content_delta: Methods.AGENT_MESSAGE_DELTA,\n\n // Command execution\n exec_command_output_delta: Methods.COMMAND_OUTPUT_DELTA,\n command_output_delta: Methods.COMMAND_OUTPUT_DELTA,\n terminal_interaction: Methods.COMMAND_TERMINAL_INTERACTION,\n\n // File changes\n file_change_output_delta: Methods.FILE_CHANGE_OUTPUT_DELTA,\n\n // Reasoning\n reasoning_content_delta: Methods.REASONING_TEXT_DELTA,\n reasoning_raw_content_delta: Methods.REASONING_TEXT_DELTA,\n agent_reasoning_delta: Methods.REASONING_TEXT_DELTA,\n agent_reasoning_raw_content_delta: Methods.REASONING_TEXT_DELTA,\n reasoning_summary_delta: Methods.REASONING_SUMMARY_DELTA,\n agent_reasoning_section_break: Methods.REASONING_SUMMARY_PART_ADDED,\n\n // Plan\n plan_delta: Methods.PLAN_DELTA,\n plan_update: Methods.TURN_PLAN_UPDATED,\n\n // Turn-level\n turn_diff: Methods.TURN_DIFF_UPDATED,\n diff_update: Methods.TURN_DIFF_UPDATED,\n\n // MCP\n mcp_tool_call_begin: Methods.MCP_TOOL_PROGRESS,\n mcp_tool_call_end: Methods.MCP_TOOL_PROGRESS,\n mcp_startup_update: Methods.MCP_TOOL_PROGRESS,\n mcp_startup_complete: Methods.MCP_TOOL_PROGRESS,\n\n // Model routing\n model_reroute: Methods.MODEL_REROUTED,\n\n // Thread/session events\n thread_name_updated: Methods.THREAD_NAME_UPDATED,\n token_count: Methods.THREAD_TOKEN_USAGE_UPDATED,\n session_configured: Methods.SESSION_CONFIGURED,\n\n // Item lifecycle (in case exec emits these outside the dot-notation variants)\n item_started: Methods.ITEM_STARTED,\n item_completed: Methods.ITEM_COMPLETED,\n raw_response_item: Methods.RAW_RESPONSE_ITEM_COMPLETED,\n\n // Stream errors — map to error method so retryable detection can handle it\n stream_error: Methods.ERROR,\n\n // Legacy turn lifecycle (v1 wire format used by older CLIs)\n // These are critical for exec fallback since it targets CLIs without app-server.\n task_started: Methods.TURN_STARTED,\n task_complete: Methods.TURN_COMPLETED,\n turn_aborted: Methods.TURN_COMPLETED,\n};\n\nexport class ExecClient extends EventEmitter implements ICodexClient {\n private _destroyed = false;\n private process: ChildProcess | null = null;\n private spawnOpts: AppServerSpawnOptions | null = null;\n\n // Thread/turn state\n private threadId: string | null = null;\n /** Real thread ID from CLI (received via thread.started event). Used for exec resume. */\n private realThreadId: string | null = null;\n private turnId: string | null = null;\n private turnCount = 0;\n private threadStartParams: ThreadStartParams | null = null;\n private lastAgentMessageText = \"\";\n private turnCompleted = false;\n private schemaTmpDirs: string[] = [];\n\n // Handlers\n private notificationHandler: NotificationHandler | null = null;\n private serverRequestHandler: ServerRequestHandler | null = null;\n\n // Stdout buffer for JSONL parsing\n private buffer = \"\";\n private decoder = new StringDecoder(\"utf8\");\n\n get destroyed(): boolean {\n return this._destroyed;\n }\n\n get supportsTurnOverrides(): boolean {\n // After the first turn, exec resume does not support -s/-p/-C overrides\n return this.turnCount <= 1 || this.realThreadId == null;\n }\n\n get childPid(): number | undefined {\n return this.process?.pid ?? undefined;\n }\n\n async start(opts: AppServerSpawnOptions): Promise<InitializeResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n this.spawnOpts = opts;\n return { userAgent: \"codex-exec\" };\n }\n\n async threadStart(params: ThreadStartParams): Promise<ThreadStartResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n this.threadStartParams = params;\n this.threadId = `exec_thread_${randomUUID().slice(0, 12)}`;\n return { thread: { id: this.threadId } };\n }\n\n async threadFork(_params: ThreadForkParams): Promise<ThreadForkResult> {\n throw new Error(\n `Error [${ErrorCode.EXEC_NOT_SUPPORTED}]: threadFork is not supported in exec mode`\n );\n }\n\n async threadResume(_params: ThreadResumeParams): Promise<ThreadResumeResult> {\n throw new Error(\n `Error [${ErrorCode.EXEC_NOT_SUPPORTED}]: threadResume is not supported in exec mode`\n );\n }\n\n async threadBackgroundTerminalsClean(\n _params: ThreadBackgroundTerminalsCleanParams\n ): Promise<Record<string, never>> {\n return {};\n }\n\n async turnStart(params: TurnStartParams): Promise<TurnStartResult> {\n if (this._destroyed) throw new Error(\"Client destroyed\");\n if (!this.threadId) throw new Error(\"No thread started\");\n\n // Kill any previous turn subprocess\n this.killProcess();\n\n this.turnCount++;\n this.turnId = `exec_turn_${randomUUID().slice(0, 12)}`;\n this.lastAgentMessageText = \"\";\n this.turnCompleted = false;\n this.buffer = \"\";\n this.decoder = new StringDecoder(\"utf8\");\n\n // Extract prompt text from input array\n const prompt = params.input\n .filter((i): i is { type: \"text\"; text: string } => i.type === \"text\")\n .map((i) => i.text)\n .join(\"\\n\");\n\n // Extract image paths\n const images = params.input\n .filter((i): i is { type: \"localImage\"; path: string } => i.type === \"localImage\")\n .map((i) => i.path);\n\n // First turn: codex exec \"<prompt>\" ...\n // Subsequent turns: codex exec resume <threadId> \"<prompt>\" ... (multi-turn context)\n const isResume = this.turnCount > 1 && this.realThreadId != null;\n if (this.turnCount > 1 && !this.realThreadId) {\n // CLI didn't provide a thread ID (e.g. older CLI without thread.started event).\n // Fall back to fresh exec but warn — multi-turn context will be lost.\n console.error(\n \"[exec-client] No realThreadId available for resume; falling back to fresh exec (context will be lost)\"\n );\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error:\n \"exec mode: multi-turn context unavailable (CLI did not provide thread ID). This turn runs without prior context.\",\n willRetry: true, // non-terminal: session continues, just without context\n });\n }\n const args = isResume\n ? this.buildResumeArgs(prompt, params, images)\n : this.buildExecArgs(prompt, params, images);\n const executable = getDefaultCodexExecutable();\n const invocation = resolveCodexInvocation(args, {\n codexCommand: executable.command,\n codexIsPath: executable.isPath,\n });\n\n const proc = spawn(invocation.cmd, invocation.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env },\n detached: process.platform !== \"win32\",\n windowsHide: process.platform === \"win32\",\n });\n this.process = proc;\n\n // Close stdin immediately — exec reads prompt from args\n proc.stdin?.end();\n\n proc.stdout!.on(\"data\", (chunk: Buffer) => this.onData(chunk));\n proc.stderr!.on(\"data\", (chunk: Buffer) => {\n console.error(`[exec-client stderr] ${chunk.toString().trimEnd()}`);\n });\n\n proc.on(\"error\", (err) => {\n if (!this._destroyed) {\n this.emit(\"error\", err);\n }\n });\n\n proc.on(\"exit\", (code, signal) => {\n // If turn wasn't completed via JSONL event, synthesize completion\n if (this.turnId && !this._destroyed && !this.turnCompleted) {\n this.turnCompleted = true;\n if (code !== 0 && code !== null) {\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: { message: `exec process exited with code ${code}` },\n willRetry: false,\n });\n }\n // Synthesize TURN_COMPLETED so SessionManager transitions out of \"running\"\n const turnId = this.turnId ?? \"\";\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: code === 0 ? \"completed\" : \"failed\",\n output: this.lastAgentMessageText || undefined,\n ...(code !== 0 && code !== null\n ? { error: { message: `exec process exited with code ${code}` } }\n : signal\n ? { error: { message: `exec process killed by signal ${signal}` } }\n : {}),\n },\n });\n this.turnId = null;\n }\n if (!this._destroyed) {\n this.emit(\"exit\", code, signal);\n }\n this.process = null;\n });\n\n const turnId = this.turnId;\n return { turn: { id: turnId } };\n }\n\n async turnInterrupt(_params: TurnInterruptParams): Promise<void> {\n this.killProcess();\n }\n\n onNotification(handler: NotificationHandler): void {\n this.notificationHandler = handler;\n }\n\n onServerRequest(handler: ServerRequestHandler): void {\n this.serverRequestHandler = handler;\n }\n\n respondToServer(_id: RequestId, _result: unknown): void {\n // No-op: exec mode has no server-initiated requests\n }\n\n respondErrorToServer(_id: RequestId, _code: number, _message: string): void {\n // No-op: exec mode has no server-initiated requests\n }\n\n async destroy(): Promise<void> {\n if (this._destroyed) return;\n this._destroyed = true;\n\n const proc = this.process;\n if (proc && !proc.killed) {\n const alreadyExited = proc.exitCode !== null;\n proc.stdin?.end();\n this.killProcess();\n\n // Force kill after timeout (matches AppServerClient behavior)\n const forceKill = setTimeout(() => {\n if (proc && !proc.killed && proc.exitCode === null) {\n if (process.platform === \"win32\" && proc.pid) {\n try {\n spawn(\"taskkill\", [\"/PID\", String(proc.pid), \"/T\", \"/F\"], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } catch {\n // ignore\n }\n } else {\n try {\n if (proc.pid) process.kill(-proc.pid, \"SIGKILL\");\n else proc.kill(\"SIGKILL\");\n } catch {\n // ignore\n }\n }\n }\n }, FORCE_KILL_TIMEOUT_MS);\n forceKill.unref();\n\n if (!alreadyExited) {\n await new Promise<void>((resolve) => {\n proc.on(\"exit\", () => {\n clearTimeout(forceKill);\n resolve();\n });\n const fallback = setTimeout(resolve, FORCE_KILL_TIMEOUT_MS + 1000);\n fallback.unref();\n });\n }\n }\n\n this.process = null;\n this.removeAllListeners();\n\n // Clean up temp schema directories\n for (const dir of this.schemaTmpDirs) {\n try {\n rmSync(dir, { recursive: true, force: true });\n } catch {\n /* ignore */\n }\n }\n this.schemaTmpDirs = [];\n }\n\n // ── Private helpers ─────────────────────────────────────────────\n\n /**\n * Build args for the first turn: `codex exec \"<prompt>\" --json --skip-git-repo-check [flags]`.\n * No --ephemeral so the session persists for subsequent resume turns.\n */\n private buildExecArgs(prompt: string, params: TurnStartParams, images: string[]): string[] {\n const args: string[] = [\"exec\", prompt, \"--json\", \"--skip-git-repo-check\"];\n\n // Model\n const model = params.model ?? this.threadStartParams?.model ?? this.spawnOpts?.model;\n if (model) args.push(\"-m\", model);\n\n // Sandbox (first turn only — exec resume does not support -s)\n let effectiveSandbox: string | undefined;\n if (params.sandboxPolicy) {\n effectiveSandbox = sandboxPolicyToMode(params.sandboxPolicy);\n }\n if (!effectiveSandbox) {\n effectiveSandbox = this.threadStartParams?.sandbox ?? this.spawnOpts?.sandbox;\n }\n if (effectiveSandbox) args.push(\"-s\", effectiveSandbox);\n\n // Profile (first turn only — exec resume does not support -p)\n if (this.spawnOpts?.profile) args.push(\"-p\", this.spawnOpts.profile);\n\n // CWD (first turn only — exec resume does not support -C)\n const cwd = params.cwd ?? this.threadStartParams?.cwd;\n if (cwd) args.push(\"-C\", cwd);\n\n // Images\n for (const img of images) args.push(\"-i\", img);\n\n // Approval policy via config override (precise, doesn't affect sandbox)\n const approvalPolicy =\n params.approvalPolicy ??\n this.threadStartParams?.approvalPolicy ??\n this.spawnOpts?.approvalPolicy;\n if (approvalPolicy) args.push(\"-c\", `approval_policy=${approvalPolicy}`);\n\n // Output schema (exec supports --output-schema <file>; write to temp file)\n if (params.outputSchema && Object.keys(params.outputSchema).length > 0) {\n try {\n const tmpDir = mkdtempSync(join(tmpdir(), \"codex-mcp-schema-\"));\n this.schemaTmpDirs.push(tmpDir);\n const schemaPath = join(tmpDir, \"output-schema.json\");\n writeFileSync(schemaPath, JSON.stringify(params.outputSchema));\n args.push(\"--output-schema\", schemaPath);\n } catch (err) {\n console.error(\n `[exec-client] Failed to write output schema to temp file: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // Config overrides\n const configs: Record<string, unknown> = {\n ...this.spawnOpts?.config,\n ...this.threadStartParams?.config,\n };\n for (const [key, value] of Object.entries(configs)) {\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n\n return args;\n }\n\n /**\n * Build args for subsequent turns: `codex exec resume <threadId> \"<prompt>\" --json [flags]`.\n * Resumes the persisted session for multi-turn context continuity.\n * Note: exec resume only supports -m, -c, -i, --json, --skip-git-repo-check.\n * -s, -p, -C are NOT supported and inherit from the first turn's session.\n */\n private buildResumeArgs(prompt: string, params: TurnStartParams, images: string[]): string[] {\n const args: string[] = [\n \"exec\",\n \"resume\",\n this.realThreadId!,\n prompt,\n \"--json\",\n \"--skip-git-repo-check\",\n ];\n\n // Warn about unsupported overrides in resume mode\n if (params.sandboxPolicy) {\n console.error(\n \"[exec-client] sandbox override ignored in resume mode (exec resume does not support -s)\"\n );\n }\n if (params.cwd) {\n console.error(\n \"[exec-client] cwd override ignored in resume mode (exec resume does not support -C)\"\n );\n }\n if (params.outputSchema && Object.keys(params.outputSchema).length > 0) {\n console.error(\n \"[exec-client] outputSchema ignored in resume mode (exec resume does not support --output-schema)\"\n );\n }\n\n // Model override (supported in resume)\n const model = params.model ?? this.threadStartParams?.model ?? this.spawnOpts?.model;\n if (model) args.push(\"-m\", model);\n\n // Images (supported in resume)\n for (const img of images) args.push(\"-i\", img);\n\n // Approval policy via config override (supported in resume via -c)\n const approvalPolicy =\n params.approvalPolicy ??\n this.threadStartParams?.approvalPolicy ??\n this.spawnOpts?.approvalPolicy;\n if (approvalPolicy) args.push(\"-c\", `approval_policy=${approvalPolicy}`);\n\n // Config overrides (supported in resume via -c)\n const configs: Record<string, unknown> = {\n ...this.spawnOpts?.config,\n ...this.threadStartParams?.config,\n };\n for (const [key, value] of Object.entries(configs)) {\n const serialized =\n typeof value === \"object\" && value !== null ? JSON.stringify(value) : String(value);\n args.push(\"-c\", `${key}=${serialized}`);\n }\n\n return args;\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += this.decoder.write(chunk);\n const lines = this.buffer.split(\"\\n\");\n this.buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed[0] !== \"{\") continue;\n\n try {\n const event = JSON.parse(trimmed) as Record<string, unknown>;\n this.handleExecEvent(event);\n } catch {\n console.error(`[exec-client] Failed to parse JSONL: ${trimmed.slice(0, 200)}`);\n }\n }\n }\n\n /**\n * Transform exec JSONL event into app-server notification and dispatch.\n */\n private handleExecEvent(event: Record<string, unknown>): void {\n const type = event.type as string;\n\n // Handle structured lifecycle events first (dot-notation from exec --json)\n switch (type) {\n case \"thread.started\": {\n const cliThreadId = (event.thread_id ?? event.threadId) as string | undefined;\n if (cliThreadId) {\n this.threadId = cliThreadId;\n this.realThreadId = cliThreadId;\n }\n this.emitNotification(Methods.THREAD_STARTED, {\n thread: { id: this.threadId },\n });\n return;\n }\n\n case \"turn.started\":\n this.emitNotification(Methods.TURN_STARTED, {\n turn: { id: this.turnId, status: \"inProgress\" },\n });\n return;\n\n case \"item.started\": {\n const item = event.item as Record<string, unknown> | undefined;\n if (item) {\n this.emitNotification(Methods.ITEM_STARTED, {\n threadId: this.threadId,\n turnId: this.turnId,\n item: transformItem(item),\n });\n }\n return;\n }\n\n case \"item.completed\": {\n const item = event.item as Record<string, unknown> | undefined;\n if (item) {\n const transformed = transformItem(item);\n if (transformed.type === \"agentMessage\" && typeof transformed.text === \"string\") {\n this.lastAgentMessageText = transformed.text;\n }\n this.emitNotification(Methods.ITEM_COMPLETED, {\n threadId: this.threadId,\n turnId: this.turnId,\n item: transformed,\n });\n }\n return;\n }\n\n case \"turn.completed\": {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"completed\",\n output: this.lastAgentMessageText || undefined,\n usage: event.usage,\n },\n });\n this.turnId = null;\n return;\n }\n\n case \"turn.failed\": {\n const turnId = this.turnId ?? \"\";\n const error = event.error as Record<string, unknown> | undefined;\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"failed\",\n error: error ?? { message: \"Turn failed\" },\n },\n });\n this.turnId = null;\n return;\n }\n\n case \"error\": {\n const willRetry = isRetryableError(event);\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: event.message ?? event.error,\n willRetry,\n });\n return;\n }\n\n default:\n break;\n }\n\n // Map snake_case event types to app-server notification methods\n const mappedMethod = EXEC_EVENT_TO_METHOD[type];\n if (mappedMethod) {\n // Legacy turn lifecycle events need turn object synthesis\n if (type === \"task_started\") {\n const turnId = (event.turn_id as string) ?? this.turnId;\n if (turnId) this.turnId = turnId;\n this.emitNotification(Methods.TURN_STARTED, {\n turn: { id: this.turnId, status: \"inProgress\" },\n });\n } else if (type === \"task_complete\") {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"completed\",\n output: this.lastAgentMessageText || undefined,\n },\n });\n this.turnId = null;\n } else if (type === \"turn_aborted\") {\n const turnId = this.turnId ?? \"\";\n this.turnCompleted = true;\n this.emitNotification(Methods.TURN_COMPLETED, {\n threadId: this.threadId,\n turn: {\n id: turnId,\n status: \"cancelled\",\n error: event.reason ?? { message: \"Turn aborted\" },\n },\n });\n this.turnId = null;\n } else if (mappedMethod === Methods.ERROR) {\n // For stream_error, apply retryable detection\n this.emitNotification(Methods.ERROR, {\n threadId: this.threadId,\n turnId: this.turnId,\n error: event.message ?? event.error ?? type,\n willRetry: isRetryableError(event),\n });\n } else {\n this.emitNotification(mappedMethod, {\n threadId: this.threadId,\n turnId: this.turnId,\n ...event,\n });\n }\n return;\n }\n\n // Unmapped events: log but don't emit to avoid silent drops in manager.\n // The manager's default branch ignores unknown methods, so emitting them\n // would be misleading. Logging ensures visibility during debugging.\n console.error(`[exec-client] Unmapped exec event type: ${type}`);\n }\n\n private emitNotification(method: string, params: unknown): void {\n if (this.notificationHandler) {\n this.notificationHandler(method, params);\n }\n }\n\n private killProcess(): void {\n if (!this.process || this.process.killed) return;\n\n if (process.platform !== \"win32\" && this.process.pid) {\n try {\n process.kill(-this.process.pid, \"SIGTERM\");\n return;\n } catch {\n // Fall through to direct kill\n }\n }\n\n try {\n this.process.kill(\"SIGTERM\");\n } catch {\n // ignore\n }\n }\n}\n","/**\n * SessionPersistence — disk persistence adapter for codex-mcp sessions.\n *\n * Uses shared primitives (atomic writer, event log, recovery scanner, retention)\n * to persist session state across MCP server restarts.\n */\nimport { join } from \"node:path\";\nimport { mkdirSync, existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\n\nimport {\n atomicWriteJson,\n acquireLock,\n EventLog,\n type EventCriticality,\n scanRecoverableSessions,\n pruneSessionDirs,\n SCHEMA_VERSION,\n type RecoveredSession,\n type RetentionPolicy,\n} from \"../persistence/index.js\";\n\nimport type { SessionInfo, SessionEventType } from \"../types.js\";\n\n// ── Types ────────────────────────────────────────────────────────────\n\nexport interface PersistedSessionMeta {\n schemaVersion: number;\n sessionId: string;\n status: string;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n threadId?: string;\n model?: string;\n cwd?: string;\n approvalPolicy?: string;\n sandbox?: string;\n profile?: string;\n}\n\nexport interface PidInfo {\n pid: number;\n spawnedAt: string;\n command?: string;\n}\n\n// ── Critical event types that require immediate flush ────────────────\n\nconst CRITICAL_EVENT_TYPES = new Set<SessionEventType>([\n \"approval_request\",\n \"approval_result\",\n \"result\",\n \"error\",\n]);\n\nfunction eventCriticality(type: SessionEventType): EventCriticality {\n return CRITICAL_EVENT_TYPES.has(type) ? \"critical\" : \"normal\";\n}\n\n// ── SessionPersistence ───────────────────────────────────────────────\n\nexport class SessionPersistence {\n private readonly stateDir: string;\n private readonly sessionsDir: string;\n private releaseLock: (() => void) | null = null;\n private eventLogs = new Map<string, EventLog>();\n\n constructor(stateDir?: string) {\n this.stateDir =\n stateDir ?? process.env.CODEX_MCP_STATE_DIR ?? join(homedir(), \".codex-mcp\", \"state\");\n this.sessionsDir = join(this.stateDir, \"sessions\");\n mkdirSync(this.sessionsDir, { recursive: true });\n }\n\n /** Acquire the STATE_DIR lock. Call once at startup. */\n acquireLock(): void {\n this.releaseLock = acquireLock(join(this.stateDir, \".lock\"));\n }\n\n /** Release the lock. Call on shutdown. */\n releaseLockIfHeld(): void {\n if (this.releaseLock) {\n this.releaseLock();\n this.releaseLock = null;\n }\n }\n\n // ── Write operations ────────────────────────────────────────────\n\n /** Persist session metadata (called on create and status changes). */\n writeSessionMeta(session: SessionInfo): void {\n const meta: PersistedSessionMeta = {\n schemaVersion: SCHEMA_VERSION,\n sessionId: session.sessionId,\n status: session.status,\n createdAt: session.createdAt,\n lastActiveAt: session.lastActiveAt,\n cancelledAt: session.cancelledAt,\n cancelledReason: session.cancelledReason,\n threadId: session.threadId,\n model: session.model,\n cwd: session.cwd,\n approvalPolicy: session.approvalPolicy,\n sandbox: session.sandbox,\n profile: session.profile,\n };\n const dir = join(this.sessionsDir, session.sessionId);\n atomicWriteJson(join(dir, \"meta.json\"), meta);\n }\n\n /** Persist PID info for orphan detection. */\n writePidInfo(sessionId: string, pid: number, command?: string): void {\n const info: PidInfo = {\n pid,\n spawnedAt: new Date().toISOString(),\n command,\n };\n const dir = join(this.sessionsDir, sessionId);\n mkdirSync(dir, { recursive: true });\n atomicWriteJson(join(dir, \"pid.json\"), info);\n }\n\n /** Append an event to the session's event log. */\n appendEvent(sessionId: string, type: SessionEventType, data: unknown): void {\n let log = this.eventLogs.get(sessionId);\n if (!log) {\n const dir = join(this.sessionsDir, sessionId);\n mkdirSync(dir, { recursive: true });\n log = new EventLog({ filePath: join(dir, \"events.jsonl\") });\n this.eventLogs.set(sessionId, log);\n }\n log.append({ type, data, timestamp: new Date().toISOString() }, eventCriticality(type));\n }\n\n /** Set the next sequence number for a recovered session's event log. */\n setEventLogNextSeq(sessionId: string, seq: number): void {\n let log = this.eventLogs.get(sessionId);\n if (!log) {\n const dir = join(this.sessionsDir, sessionId);\n mkdirSync(dir, { recursive: true });\n log = new EventLog({ filePath: join(dir, \"events.jsonl\") });\n this.eventLogs.set(sessionId, log);\n }\n log.setNextSeq(seq);\n }\n\n /** Persist the final result. */\n writeResult(sessionId: string, result: unknown): void {\n const dir = join(this.sessionsDir, sessionId);\n mkdirSync(dir, { recursive: true });\n atomicWriteJson(join(dir, \"result.json\"), result);\n }\n\n // ── Read / Recovery ─────────────────────────────────────────────\n\n /** Scan and recover sessions from disk. */\n recoverSessions(maxEvents?: number): RecoveredSession[] {\n return scanRecoverableSessions(this.sessionsDir, maxEvents);\n }\n\n /** Apply retention policy. Returns number of sessions pruned. */\n prune(policy?: RetentionPolicy): number {\n return pruneSessionDirs(this.sessionsDir, policy);\n }\n\n // ── Lifecycle ───────────────────────────────────────────────────\n\n /** Flush all event logs synchronously (call on shutdown). */\n flushAll(): void {\n for (const log of this.eventLogs.values()) {\n log.flushSync();\n }\n }\n\n /** Destroy a single session's event log. */\n destroySessionLog(sessionId: string): void {\n const log = this.eventLogs.get(sessionId);\n if (log) {\n log.destroy();\n this.eventLogs.delete(sessionId);\n }\n }\n\n /** Clean up: flush all logs, release lock. */\n destroy(): void {\n for (const log of this.eventLogs.values()) {\n log.destroy();\n }\n this.eventLogs.clear();\n this.releaseLockIfHeld();\n }\n\n /** Check if a session directory exists on disk. */\n hasSessionOnDisk(sessionId: string): boolean {\n return existsSync(join(this.sessionsDir, sessionId, \"meta.json\"));\n }\n}\n","/**\n * Atomic JSON file writer — write to .tmp then rename to avoid torn writes.\n */\nimport { writeFileSync, renameSync, mkdirSync, unlinkSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\n\n/**\n * Atomically write a JSON-serializable value to `filePath`.\n * Writes to a sibling `.tmp` file first, then renames.\n * On crash between write and rename, only the .tmp is left (caller can ignore/clean).\n */\nexport function atomicWriteJson(filePath: string, data: unknown): void {\n const dir = dirname(filePath);\n mkdirSync(dir, { recursive: true });\n const tmpPath = join(dir, `.tmp-${randomBytes(6).toString(\"hex\")}`);\n try {\n writeFileSync(tmpPath, JSON.stringify(data, null, 2) + \"\\n\", \"utf-8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n // Best-effort cleanup of the temp file\n try {\n unlinkSync(tmpPath);\n } catch {\n // ignore\n }\n throw err;\n }\n}\n","/**\n * Simple PID-based lockfile for single-writer STATE_DIR protection.\n *\n * Uses `O_EXCL` for atomic creation. Stale locks (dead PID) are automatically reclaimed.\n */\nimport {\n openSync,\n closeSync,\n readFileSync,\n writeFileSync,\n unlinkSync,\n mkdirSync,\n constants,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\n\ninterface LockContent {\n pid: number;\n startedAt: string;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Acquire a lockfile at `lockPath`. Returns a release function.\n * Throws if another live process holds the lock.\n */\nexport function acquireLock(lockPath: string): () => void {\n mkdirSync(dirname(lockPath), { recursive: true });\n\n // Check for existing lock\n try {\n const raw = readFileSync(lockPath, \"utf-8\");\n const existing: LockContent = JSON.parse(raw);\n if (isPidAlive(existing.pid) && existing.pid !== process.pid) {\n throw new Error(\n `STATE_DIR is locked by another process (pid=${existing.pid}, started=${existing.startedAt}). ` +\n `If this is stale, delete ${lockPath}`\n );\n }\n // Stale lock from a dead process — reclaim it\n unlinkSync(lockPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n if ((err as Error).message?.includes(\"STATE_DIR is locked\")) throw err;\n // Parse error — the file may be mid-write by another process.\n // Do NOT blindly unlink (could delete a valid lock being written).\n // Instead, warn and let O_EXCL below fail naturally if the file exists.\n console.error(\n `[lockfile] Existing lock at ${lockPath} is unreadable — will attempt O_EXCL create`\n );\n }\n }\n\n // Write our lock\n const content: LockContent = {\n pid: process.pid,\n startedAt: new Date().toISOString(),\n };\n let fd: number | undefined;\n try {\n fd = openSync(lockPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);\n writeFileSync(fd, JSON.stringify(content) + \"\\n\", \"utf-8\");\n closeSync(fd);\n fd = undefined;\n } catch (err) {\n if (fd !== undefined) {\n try {\n closeSync(fd);\n } catch {\n /* ignore */\n }\n }\n if ((err as NodeJS.ErrnoException).code === \"EEXIST\") {\n // Another process owns this lockfile — do NOT delete it\n throw new Error(\n `Failed to acquire STATE_DIR lock at ${lockPath} — race with another process`\n );\n }\n // We may have partially created the file — clean up\n try {\n unlinkSync(lockPath);\n } catch {\n /* ignore */\n }\n throw err;\n }\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n try {\n unlinkSync(lockPath);\n } catch {\n // ignore — may already be gone\n }\n };\n}\n","/**\n * Append-only JSONL event log with tiered flush strategy.\n *\n * - Noisy events (progress/output deltas): batched and flushed every `batchIntervalMs` (default 100ms)\n * - Critical events (permission, result, error, status change): flushed immediately\n * - Shutdown: force flush of all buffered events\n *\n * Each line is `{ seq, ...event }\\n` to enable torn-tail detection on recovery.\n */\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/** Event criticality — determines flush strategy */\nexport type EventCriticality = \"normal\" | \"critical\";\n\ninterface PendingWrite {\n line: string;\n}\n\nexport interface EventLogOptions {\n /** Path to the JSONL file */\n filePath: string;\n /** Batch interval for normal events in ms (default: 100) */\n batchIntervalMs?: number;\n}\n\nexport class EventLog {\n private readonly filePath: string;\n private readonly batchIntervalMs: number;\n private buffer: PendingWrite[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private nextSeq = 0;\n private destroyed = false;\n\n constructor(opts: EventLogOptions) {\n this.filePath = opts.filePath;\n this.batchIntervalMs = opts.batchIntervalMs ?? 100;\n mkdirSync(dirname(this.filePath), { recursive: true });\n }\n\n /**\n * Append an event to the log.\n * @param event - Arbitrary JSON-serializable event data\n * @param criticality - \"critical\" forces immediate flush; \"normal\" batches\n */\n append(event: unknown, criticality: EventCriticality = \"normal\"): number {\n if (this.destroyed) return -1;\n const seq = this.nextSeq++;\n const line = JSON.stringify({ seq, ...(event as Record<string, unknown>) }) + \"\\n\";\n this.buffer.push({ line });\n\n if (criticality === \"critical\") {\n this.flushSync();\n } else if (!this.flushTimer) {\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n this.flushSync();\n }, this.batchIntervalMs);\n // Don't block process exit for a timer\n if (this.flushTimer.unref) this.flushTimer.unref();\n }\n return seq;\n }\n\n /** Set the next sequence number (used during recovery to continue from last known seq). */\n setNextSeq(seq: number): void {\n this.nextSeq = seq;\n }\n\n /** Synchronously flush all buffered writes to disk. */\n flushSync(): void {\n if (this.buffer.length === 0) return;\n const chunk = this.buffer.map((w) => w.line).join(\"\");\n this.buffer = [];\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n try {\n appendFileSync(this.filePath, chunk, \"utf-8\");\n } catch (err) {\n // Log but don't throw — persistence is best-effort\n console.error(`[event-log] Failed to flush to ${this.filePath}:`, err);\n }\n }\n\n /** Destroy the log, flushing any remaining events. */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.flushSync();\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n }\n}\n","/**\n * Recovery scanner — scans STATE_DIR/sessions/ on startup to recover persisted sessions.\n *\n * - Reads meta.json for session metadata\n * - Detects torn tails in events.jsonl (incomplete last line)\n * - Reads result.json if present\n * - Returns recovered sessions for the SessionManager to ingest\n */\nimport { readdirSync, readFileSync, existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport const SCHEMA_VERSION = 1;\n\nexport interface RecoveredSessionMeta {\n schemaVersion: number;\n sessionId: string;\n status: string;\n createdAt: string;\n lastActiveAt: string;\n cancelledAt?: string;\n cancelledReason?: string;\n /** codex-mcp specific */\n threadId?: string;\n model?: string;\n cwd?: string;\n /** Arbitrary extra fields from the MCP-specific adapter */\n [key: string]: unknown;\n}\n\nexport interface RecoveredPidInfo {\n pid: number;\n spawnedAt: string;\n command?: string;\n}\n\nexport interface RecoveredSession {\n sessionId: string;\n meta: RecoveredSessionMeta;\n /** Parsed events from events.jsonl (valid lines only, torn tail discarded) */\n events: Array<{ seq: number; [key: string]: unknown }>;\n /** Highest sequence number found in events */\n lastSeq: number;\n /** Result from result.json if present */\n result: unknown | null;\n /** PID info from pid.json if present */\n pidInfo: RecoveredPidInfo | null;\n /** Path to the session directory */\n sessionDir: string;\n}\n\n/**\n * Parse events.jsonl, discarding any torn tail (incomplete last line).\n * Returns valid events sorted by seq.\n */\nfunction parseEventsJsonl(filePath: string): Array<{ seq: number; [key: string]: unknown }> {\n if (!existsSync(filePath)) return [];\n const raw = readFileSync(filePath, \"utf-8\");\n const lines = raw.split(\"\\n\");\n const events: Array<{ seq: number; [key: string]: unknown }> = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const parsed = JSON.parse(trimmed);\n if (typeof parsed.seq === \"number\") {\n events.push(parsed);\n }\n } catch {\n // Torn tail or corrupt line — discard this and all subsequent lines\n break;\n }\n }\n return events.sort((a, b) => a.seq - b.seq);\n}\n\nfunction readJsonSafe<T>(filePath: string): T | null {\n if (!existsSync(filePath)) return null;\n try {\n return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Scan `sessionsDir` for persisted sessions and return recovered metadata.\n *\n * @param sessionsDir - Path to STATE_DIR/sessions/\n * @param maxEvents - Max events to load per session (default: 500, from tail)\n */\nexport function scanRecoverableSessions(sessionsDir: string, maxEvents = 500): RecoveredSession[] {\n if (!existsSync(sessionsDir)) return [];\n\n const results: RecoveredSession[] = [];\n let entries: string[];\n try {\n entries = readdirSync(sessionsDir);\n } catch {\n return [];\n }\n\n for (const entry of entries) {\n const sessionDir = join(sessionsDir, entry);\n try {\n if (!statSync(sessionDir).isDirectory()) continue;\n } catch {\n continue;\n }\n\n const meta = readJsonSafe<RecoveredSessionMeta>(join(sessionDir, \"meta.json\"));\n if (!meta || !meta.sessionId) continue;\n\n // Schema version check\n if (meta.schemaVersion !== undefined && meta.schemaVersion > SCHEMA_VERSION) {\n console.error(\n `[recovery] Skipping session ${meta.sessionId}: schema version ${meta.schemaVersion} > ${SCHEMA_VERSION}`\n );\n continue;\n }\n\n let events = parseEventsJsonl(join(sessionDir, \"events.jsonl\"));\n // Keep only the tail\n if (events.length > maxEvents) {\n events = events.slice(-maxEvents);\n }\n const lastSeq = events.length > 0 ? events[events.length - 1]!.seq : -1;\n\n const result = readJsonSafe<unknown>(join(sessionDir, \"result.json\"));\n const pidInfo = readJsonSafe<RecoveredPidInfo>(join(sessionDir, \"pid.json\"));\n\n results.push({\n sessionId: meta.sessionId,\n meta,\n events,\n lastSeq,\n result,\n pidInfo,\n sessionDir,\n });\n }\n\n return results;\n}\n","/**\n * Retention policy — prune old session directories by age, count, and disk size.\n */\nimport { readdirSync, rmSync, statSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface RetentionPolicy {\n /** Maximum age in milliseconds (default: 7 days) */\n maxAgeMs?: number;\n /** Maximum number of retained sessions (default: 200) */\n maxCount?: number;\n /** Maximum total disk size in bytes (default: 500 MB) */\n maxDiskBytes?: number;\n}\n\nconst DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\nconst DEFAULT_MAX_COUNT = 200;\nconst DEFAULT_MAX_DISK_BYTES = 500 * 1024 * 1024; // 500 MB\n\ninterface SessionDirInfo {\n path: string;\n sessionId: string;\n lastActiveAt: number; // epoch ms\n diskBytes: number;\n}\n\nfunction getDirSize(dirPath: string): number {\n let total = 0;\n try {\n for (const entry of readdirSync(dirPath)) {\n try {\n const st = statSync(join(dirPath, entry));\n total += st.isFile() ? st.size : 0;\n } catch {\n // skip\n }\n }\n } catch {\n // skip\n }\n return total;\n}\n\n/**\n * Apply retention policy to `sessionsDir`, removing oldest sessions first.\n * Returns the number of sessions pruned.\n */\nexport function pruneSessionDirs(sessionsDir: string, policy?: RetentionPolicy): number {\n const maxAgeMs = policy?.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n const maxCount = policy?.maxCount ?? DEFAULT_MAX_COUNT;\n const maxDiskBytes = policy?.maxDiskBytes ?? DEFAULT_MAX_DISK_BYTES;\n\n let entries: string[];\n try {\n entries = readdirSync(sessionsDir);\n } catch {\n return 0;\n }\n\n // Collect info\n const now = Date.now();\n const dirs: SessionDirInfo[] = [];\n for (const entry of entries) {\n const dirPath = join(sessionsDir, entry);\n try {\n if (!statSync(dirPath).isDirectory()) continue;\n } catch {\n continue;\n }\n\n let lastActiveAt = 0;\n try {\n const meta = JSON.parse(readFileSync(join(dirPath, \"meta.json\"), \"utf-8\"));\n lastActiveAt = new Date(meta.lastActiveAt || meta.createdAt || 0).getTime();\n } catch {\n // Use directory mtime as fallback\n try {\n lastActiveAt = statSync(dirPath).mtimeMs;\n } catch {\n lastActiveAt = 0;\n }\n }\n\n dirs.push({\n path: dirPath,\n sessionId: entry,\n lastActiveAt,\n diskBytes: getDirSize(dirPath),\n });\n }\n\n // Sort oldest first\n dirs.sort((a, b) => a.lastActiveAt - b.lastActiveAt);\n\n const toRemove = new Set<string>();\n\n // 1. Age-based pruning\n for (const dir of dirs) {\n if (now - dir.lastActiveAt > maxAgeMs) {\n toRemove.add(dir.path);\n }\n }\n\n // 2. Count-based pruning (remove oldest until count <= maxCount)\n const remaining = dirs.filter((d) => !toRemove.has(d.path));\n if (remaining.length > maxCount) {\n const excess = remaining.length - maxCount;\n for (let i = 0; i < excess; i++) {\n toRemove.add(remaining[i]!.path);\n }\n }\n\n // 3. Size-based pruning (remove oldest until total size <= maxDiskBytes)\n const afterCountPrune = dirs.filter((d) => !toRemove.has(d.path));\n let totalSize = afterCountPrune.reduce((sum, d) => sum + d.diskBytes, 0);\n for (const dir of afterCountPrune) {\n if (totalSize <= maxDiskBytes) break;\n toRemove.add(dir.path);\n totalSize -= dir.diskBytes;\n }\n\n // Execute removal\n let pruned = 0;\n for (const dirPath of toRemove) {\n try {\n rmSync(dirPath, { recursive: true, force: true });\n pruned++;\n } catch (err) {\n console.error(`[retention] Failed to remove ${dirPath}:`, err);\n }\n }\n\n return pruned;\n}\n","/**\n * orphan-reaper — reaps orphaned codex child processes left over from a\n * previous server run.\n *\n * On startup the recovery scanner surfaces sessions that still have a\n * pid.json file. This module verifies whether each such process is still\n * running and, if so, whether it genuinely belongs to the previous server\n * invocation (guards against PID reuse). Confirmed orphans are terminated\n * gracefully (SIGTERM / taskkill) with a 5-second window, then forcefully\n * killed if still alive.\n */\nimport { execSync, spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport type { RecoveredSession } from \"../persistence/index.js\";\n\nexport interface ReapSummary {\n reaped: number;\n alreadyDead: number;\n skipped: number;\n}\n\n// ── Liveness check ───────────────────────────────────────────────────\n\n/**\n * Return true if a process with the given PID appears to be running.\n * Uses `process.kill(pid, 0)` which throws when the process does not exist.\n */\nfunction isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n// ── Start-time helpers ───────────────────────────────────────────────\n\n/**\n * On Windows: query WMI for the process creation time.\n * WMIC returns dates in the form \"YYYYMMDDHHmmss.ffffff+ZZZ\".\n * We extract just the 14-digit prefix and convert to an ISO string.\n * Returns null on any error (process gone, access denied, wmic absent).\n */\nfunction getWindowsCreationTimeMs(pid: number): number | null {\n try {\n const raw = execSync(`wmic process where \"ProcessId=${pid}\" get CreationDate /value`, {\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 5000,\n }).toString();\n const match = raw.match(/CreationDate=(\\d{14})/);\n if (!match || !match[1]) return null;\n const s = match[1];\n const iso = `${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}T${s.slice(8, 10)}:${s.slice(10, 12)}:${s.slice(12, 14)}.000Z`;\n const ms = new Date(iso).getTime();\n return isNaN(ms) ? null : ms;\n } catch {\n return null;\n }\n}\n\n/**\n * On Linux: read /proc/{pid}/stat and return the starttime field (field 22,\n * 0-indexed) as a raw tick string suitable for identity comparison.\n * Returns null when /proc is unavailable.\n */\nfunction getProcStatStartTick(pid: number): string | null {\n try {\n const stat = readFileSync(`/proc/${pid}/stat`, \"utf-8\");\n // The second field is the comm (executable name) enclosed in parentheses\n // and may contain spaces, so we split after the closing ')'.\n const afterComm = stat.slice(stat.lastIndexOf(\")\") + 1).trim();\n const fields = afterComm.split(\" \");\n // After stripping \"state\" and the next fields, starttime is at index 19\n // of afterComm fields (which corresponds to field 22 of the full stat).\n const starttime = fields[19];\n return starttime ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * On macOS / BSDs (and Linux fallback): use `ps -p PID -o lstart=` to get\n * a human-readable start timestamp. Returns null on failure.\n */\nfunction getPsLstart(pid: number): number | null {\n try {\n const output = execSync(`ps -p ${pid} -o lstart=`, {\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 5000,\n })\n .toString()\n .trim();\n if (!output) return null;\n const ms = new Date(output).getTime();\n return isNaN(ms) ? null : ms;\n } catch {\n return null;\n }\n}\n\n// ── Identity verification ─────────────────────────────────────────────\n\n/**\n * Verify that the running process with the given PID is (likely) the same\n * process that was spawned by the previous server instance.\n *\n * The comparison is best-effort. When we cannot determine the start time\n * we conservatively return false (do NOT kill) to avoid hitting a reused PID.\n *\n * @param pid Process ID to inspect.\n * @param spawnedAt ISO timestamp stored in pid.json at spawn time.\n */\nfunction isOrphan(pid: number, spawnedAt: string): boolean {\n const storedMs = new Date(spawnedAt).getTime();\n if (isNaN(storedMs)) return false; // Cannot parse → skip.\n\n if (process.platform === \"win32\") {\n const procMs = getWindowsCreationTimeMs(pid);\n if (procMs === null) return false;\n // Allow 5-second slop for clock skew / WMIC rounding.\n return Math.abs(procMs - storedMs) < 5000;\n }\n\n // Linux: prefer /proc/{pid}/stat tick comparison.\n // We store the tick at reaper-check time and compare with what was stored\n // previously — actually we don't store ticks, so instead we cross-check by\n // also trying ps lstart.\n const lstartMs = getPsLstart(pid);\n if (lstartMs !== null) {\n return Math.abs(lstartMs - storedMs) < 5000;\n }\n\n // Fallback: if we have a /proc tick but cannot convert it to wall time,\n // we use a heuristic: trust the PID is an orphan when the stored spawnedAt\n // is within the last 24 hours (processes spawned further back almost\n // certainly hit a reboot or enough PID cycling to be harmless).\n const tick = getProcStatStartTick(pid);\n if (tick !== null) {\n const ageMs = Date.now() - storedMs;\n return ageMs > 0 && ageMs < 24 * 60 * 60 * 1000;\n }\n\n // No information — conservatively skip.\n return false;\n}\n\n// ── Signal helpers ───────────────────────────────────────────────────\n\nfunction sendGraceful(pid: number): void {\n try {\n if (process.platform === \"win32\") {\n spawn(\"taskkill\", [\"/PID\", String(pid)], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } else {\n process.kill(pid, \"SIGTERM\");\n }\n } catch {\n // Already gone.\n }\n}\n\nfunction sendForce(pid: number): void {\n try {\n if (process.platform === \"win32\") {\n spawn(\"taskkill\", [\"/PID\", String(pid), \"/F\"], {\n stdio: \"ignore\",\n windowsHide: true,\n });\n } else {\n process.kill(pid, \"SIGKILL\");\n }\n } catch {\n // Already gone.\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const t = setTimeout(resolve, ms);\n if (t.unref) t.unref();\n });\n}\n\n// ── Public API ───────────────────────────────────────────────────────\n\n/**\n * Reap any orphaned processes referenced by the recovered sessions.\n *\n * For each session that has a `pidInfo` field:\n * 1. Check if the PID is alive.\n * 2. If alive, verify it is the same process (not a reused PID).\n * 3. If confirmed orphan: graceful terminate → 5 s wait → force kill.\n * 4. Otherwise: count as already-dead or skipped.\n *\n * @param recovered Sessions returned by the recovery scanner.\n * @returns Summary of { reaped, alreadyDead, skipped }.\n */\nexport async function reapOrphanProcesses(recovered: RecoveredSession[]): Promise<ReapSummary> {\n const summary: ReapSummary = { reaped: 0, alreadyDead: 0, skipped: 0 };\n\n const candidates = recovered.filter((s) => s.pidInfo !== null);\n if (candidates.length === 0) return summary;\n\n const reapPromises = candidates.map(async (session) => {\n const { pid, spawnedAt } = session.pidInfo!;\n\n if (!isAlive(pid)) {\n summary.alreadyDead++;\n return;\n }\n\n if (!isOrphan(pid, spawnedAt)) {\n // PID is live but does not match the stored identity → reused PID.\n console.error(\n `[orphan-reaper] PID ${pid} (session ${session.sessionId}) is alive` +\n ` but does not match stored spawn time — likely a reused PID. Skipping.`\n );\n summary.skipped++;\n return;\n }\n\n // Re-verify identity immediately before sending signal (close TOCTOU window).\n if (!isAlive(pid) || !isOrphan(pid, spawnedAt)) {\n summary.skipped++;\n return;\n }\n\n // Confirmed orphan — attempt graceful termination.\n console.error(\n `[orphan-reaper] Sending graceful terminate to orphan PID ${pid}` +\n ` (session ${session.sessionId}).`\n );\n sendGraceful(pid);\n\n // Poll for up to 5 seconds.\n const deadline = Date.now() + 5000;\n while (isAlive(pid) && Date.now() < deadline) {\n await sleep(250);\n }\n\n if (isAlive(pid)) {\n console.error(\n `[orphan-reaper] PID ${pid} did not exit after graceful terminate — force killing.`\n );\n sendForce(pid);\n // Give the OS a moment to act.\n await sleep(500);\n }\n\n summary.reaped++;\n });\n\n await Promise.all(reapPromises);\n return summary;\n}\n","export type StdinShutdownDecision = \"clear\" | \"shutdown_now\" | \"shutdown_timeout\" | \"reschedule\";\n\nexport function decideStdinShutdown(params: {\n stdinUnavailable: boolean;\n elapsedMs: number;\n maxWaitMs: number;\n hasActiveSessions: boolean;\n isConnected: boolean;\n}): StdinShutdownDecision {\n if (!params.stdinUnavailable) return \"clear\";\n\n // Important safety guard:\n // when transport still reports connected, treat stdin end/close as potentially\n // transient and keep serving instead of forcing process shutdown.\n if (params.isConnected) return \"reschedule\";\n\n if (!params.hasActiveSessions) return \"shutdown_now\";\n if (params.elapsedMs >= params.maxWaitMs) return \"shutdown_timeout\";\n return \"reschedule\";\n}\n"],"mappings":"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","names":["comspec","existsSync","path","stripSurroundingQuotes","ErrorCode","existsSync","statSync","path","path","existsSync","statSync","existsSync","statSync","path","path","existsSync","statSync","overflow","approvalResultIdx","drop","status","existsSync","path","spawn","spawn","path","existsSync","spawnSync","spawnSync","path","spawn","EventEmitter","randomUUID","StringDecoder","EventEmitter","StringDecoder","randomUUID","spawn","turnId","join","mkdirSync","existsSync","homedir","writeFileSync","join","readFileSync","writeFileSync","unlinkSync","mkdirSync","constants","dirname","mkdirSync","dirname","readFileSync","existsSync","statSync","join","readdirSync","rmSync","statSync","readFileSync","join","join","homedir","mkdirSync","existsSync","spawn","readFileSync"]}