@leo000001/codex-mcp 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/CODE_OF_CONDUCT.md +26 -0
- package/CONTRIBUTING.md +43 -0
- package/LICENSE +21 -0
- package/README.md +354 -0
- package/SECURITY.md +28 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3168 -0
- package/dist/index.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +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/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"],"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 */\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createServer } from \"./server.js\";\nimport { runStdioPreflight } from \"./utils/stdio-guard.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 const serverCwd = process.cwd();\n const server = createServer(serverCwd);\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 } 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(serverCwd: string): McpServer {\n const sessionManager = new SessionManager();\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, { version: SERVER_VERSION, sessionManager });\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 // ── 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.\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 inputSchema: {\n action: z.enum(SESSION_ACTIONS),\n sessionId: z.string().optional().describe(\"Required for get/cancel/interrupt/fork\"),\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\": never poll faster than 120000ms (2 minutes); use longer intervals for longer tasks.\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\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_approval: deprecated alias for respond_permission.\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: {\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: 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\n .boolean()\n .optional()\n .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 includeTools: z\n .boolean()\n .optional()\n .describe(\"Default: false. Reserved for future dynamic tool metadata support.\"),\n })\n .optional()\n .describe(\"Optional poll shaping controls.\"),\n // respond_permission/respond_approval\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/respond_approval. acceptWithExecpolicyAmendment requires execpolicyAmendment.\"\n ),\n execpolicyAmendment: z\n .array(z.string())\n .optional()\n .describe(\"For acceptWithExecpolicyAmendment 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(\"questionId -> answers map (questionId from actions[] user_input request).\"),\n },\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.string(),\n params: z.unknown(),\n itemId: z.string(),\n reason: z.string().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 { 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 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 SessionInfo,\n type SessionStatus,\n type SandboxMode,\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 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;\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 AppServerClient factory (for tests). */\n createClient?: () => AppServerClient;\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, AppServerClient>();\n private cancellationInFlight = new Map<string, Promise<void>>();\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n private createClient: () => AppServerClient;\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: string,\n advanced?: {\n baseInstructions?: string;\n developerInstructions?: string;\n personality?: string;\n ephemeral?: boolean;\n config?: Record<string, unknown>;\n images?: string[];\n outputSchema?: Record<string, unknown>;\n summary?: string;\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?: string;\n effort?: string;\n summary?: string;\n personality?: string;\n sandbox?: string;\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 if (resolvedCwd) 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) {\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 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 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 (pollOptions?.includeTools === true) {\n addCompatWarningWithinBudget(\n result,\n \"pollOptions.includeTools is not yet supported by codex-mcp; returning no tool metadata.\",\n maxBytes\n );\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 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?: { execpolicyAmendment?: string[]; denyMessage?: string }\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 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?.execpolicyAmendment || extra.execpolicyAmendment.length === 0)\n ) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicyAmendment required for acceptWithExecpolicyAmendment`\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, extra?.execpolicyAmendment);\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 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 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): AppServerClient {\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: AppServerClient,\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.TURN_STARTED:\n if (session.status === \"cancelled\") break;\n session.activeTurnId =\n ((p.turn as Record<string, unknown>)?.id as string | undefined) ??\n (typeof p.turnId === \"string\" ? p.turnId : undefined);\n pushEvent(session.eventBuffer, \"progress\", { method, ...p });\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 =\n (typeof p.turnId === \"string\" ? p.turnId : undefined) ??\n (turnObj?.id as string | undefined) ??\n session.activeTurnId ??\n \"\";\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(session.eventBuffer, \"result\", { method, ...p }, true);\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_COMPLETED:\n {\n const item = p.item as Record<string, unknown> | undefined;\n const itemType = item && typeof item.type === \"string\" ? item.type : undefined;\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, { method, item: p.item });\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.FILE_CHANGE_OUTPUT_DELTA:\n case Methods.REASONING_TEXT_DELTA:\n case Methods.REASONING_SUMMARY_DELTA:\n case Methods.PLAN_DELTA:\n case Methods.MCP_TOOL_PROGRESS:\n case Methods.ITEM_STARTED:\n case Methods.TURN_DIFF_UPDATED:\n case Methods.TURN_PLAN_UPDATED:\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 reason = normalizeOptionalString(p.reason);\n const pending: PendingRequest = {\n requestId,\n kind: \"command\",\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 // 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 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 command: p.command,\n cwd: p.cwd,\n reason,\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(id, -32601, \"Auth token refresh not supported by codex-mcp\");\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: AppServerClient,\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, -32601, \"Session is terminal\");\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 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 }));\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<{ questionId: string }> = [];\n for (const entry of rawQuestions) {\n if (isRecord(entry) && typeof entry.questionId === \"string\") {\n compactQuestions.push({ questionId: entry.questionId });\n }\n }\n\n return compactQuestions.length > 0 ? { questions: compactQuestions } : undefined;\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 execpolicyAmendment?: string[]\n): CommandApprovalResponse {\n if (decision === \"acceptWithExecpolicyAmendment\") {\n if (!execpolicyAmendment || execpolicyAmendment.length === 0) {\n throw new Error(\n `Error [${ErrorCode.INVALID_ARGUMENT}]: execpolicyAmendment required for acceptWithExecpolicyAmendment`\n );\n }\n return {\n decision: {\n acceptWithExecpolicyAmendment: {\n execpolicy_amendment: execpolicyAmendment,\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\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 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 { ErrorCode } from \"../types.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 {\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 /**\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 invocation = resolveCodexInvocation(args);\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 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// ── Thread Management ──────────────────────────────────────────────\n\n/** thread/start — all fields optional */\nexport interface ThreadStartParams {\n cwd?: string | null;\n model?: string | null;\n modelProvider?: string | null;\n approvalPolicy?: string | 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?: string | null;\n personality?: string | null;\n ephemeral?: boolean | null;\n baseInstructions?: string | null;\n developerInstructions?: string | null;\n config?: Record<string, unknown> | null;\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}\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}\n\nexport interface ThreadResumeResultV1 {\n threadId: string;\n}\nexport interface ThreadResumeResultV2 {\n thread: { id: string };\n}\nexport type ThreadResumeResult = ThreadResumeResultV1 | ThreadResumeResultV2;\n\n// ── SandboxPolicy ──────────────────────────────────────────────────\n\nexport type SandboxPolicy =\n | { type: \"readOnly\" }\n | { type: \"workspaceWrite\" }\n | { type: \"dangerFullAccess\" }\n | { type: \"externalSandbox\" };\n\n/** Map user-facing sandbox mode string to protocol SandboxPolicy */\nexport function toSandboxPolicy(mode: 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 UserInput {\n type: \"text\" | \"image\" | \"localImage\" | \"skill\" | \"mention\";\n text?: string;\n url?: string;\n path?: string;\n name?: string;\n}\n\nexport interface TurnStartParams {\n threadId: string;\n input: UserInput[];\n model?: string | null;\n approvalPolicy?: string | null;\n sandboxPolicy?: SandboxPolicy | null;\n personality?: string | null;\n effort?: string | null;\n summary?: string | null;\n cwd?: string | null;\n outputSchema?: Record<string, unknown>;\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\n// ── Approval Requests (server → client) ────────────────────────────\n\nexport interface CommandApprovalParams {\n itemId: string;\n threadId: string;\n turnId: string;\n command?: string | null;\n cwd?: string;\n reason?: string | null;\n commandActions?: unknown[] | null;\n proposedExecpolicyAmendment?: string[] | null;\n}\n\nexport type CommandApprovalDecision =\n | \"accept\"\n | \"acceptForSession\"\n | { acceptWithExecpolicyAmendment: { execpolicy_amendment: string[] } }\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 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// ── 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 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 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 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 AGENT_MESSAGE_DELTA: \"item/agentMessage/delta\",\n COMMAND_OUTPUT_DELTA: \"item/commandExecution/outputDelta\",\n FILE_CHANGE_OUTPUT_DELTA: \"item/fileChange/outputDelta\",\n REASONING_TEXT_DELTA: \"item/reasoning/textDelta\",\n REASONING_SUMMARY_DELTA: \"item/reasoning/summaryTextDelta\",\n PLAN_DELTA: \"item/plan/delta\",\n MCP_TOOL_PROGRESS: \"item/mcpToolCall/progress\",\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 */\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};\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\n if (platform !== \"win32\") {\n return { cmd: \"codex\", args: codexArgs, spawnedViaCmd: false };\n }\n\n const shim = findOnPath(\"codex\", 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, 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 { cmd: comspec, args: [\"/d\", \"/s\", \"/c\", \"codex\", ...codexArgs], spawnedViaCmd: true };\n}\n\nfunction 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 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 const preferred =\n matches.find((m) => /codex/i.test(pathApi.basename(m))) ??\n matches.find((m) => /@openai\\\\codex|\\\\codex\\\\|\\/codex\\//i.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 * 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 = [\"list\", \"get\", \"cancel\", \"interrupt\", \"fork\"] as const;\nexport type SessionAction = (typeof SESSION_ACTIONS)[number];\n\nexport const CHECK_ACTIONS = [\n \"poll\",\n \"respond_permission\",\n \"respond_approval\",\n \"respond_user_input\",\n] 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 /** Reserved for future dynamic-tools support. */\n includeTools?: boolean;\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 \"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 \"decline\",\n \"cancel\",\n] as const;\nexport type ApprovalDecision = (typeof ALL_DECISIONS)[number];\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 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: string;\n params: unknown;\n itemId: string;\n reason?: string;\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 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 { ApprovalPolicy, EffortLevel, SandboxMode } 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?: string;\n summary?: string;\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 { SessionStartResult } from \"../types.js\";\n\nexport interface CodexReplyParams {\n sessionId: string;\n prompt: string;\n model?: string;\n approvalPolicy?: string;\n effort?: string;\n summary?: string;\n personality?: string;\n sandbox?: string;\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).\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 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 ErrorCode,\n POLL_DEFAULT_MAX_EVENTS,\n POLL_MIN_MAX_EVENTS,\n RESPOND_DEFAULT_MAX_EVENTS,\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_approval params\n requestId?: string;\n decision?: string;\n execpolicyAmendment?: string[];\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 // 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, 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 case \"respond_approval\": {\n if (!args.requestId || !args.decision) {\n return {\n error: `Error [${ErrorCode.INVALID_ARGUMENT}]: requestId and decision required for respond_permission/respond_approval`,\n isError: true,\n };\n }\n try {\n sessionManager.resolveApproval(args.sessionId, args.requestId, args.decision, {\n execpolicyAmendment: args.execpolicyAmendment,\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 = args.maxEvents ?? RESPOND_DEFAULT_MAX_EVENTS;\n const result = sessionManager.pollEventsMonotonic(args.sessionId, args.cursor, maxEvents, {\n responseMode,\n pollOptions,\n });\n if (args.action === \"respond_approval\") {\n return addWarning(\n result,\n \"Action 'respond_approval' is deprecated, use 'respond_permission'.\",\n pollOptions?.maxBytes\n );\n }\n return result;\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 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 = args.maxEvents ?? 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\nfunction addWarning(result: CheckResult, warning: string, maxBytes?: number): CheckResult {\n if (!result.compatWarnings) result.compatWarnings = [];\n result.compatWarnings.push(warning);\n\n if (typeof maxBytes !== \"number\") {\n return result;\n }\n\n const normalizedMaxBytes = Math.max(1, Math.floor(maxBytes));\n if (Buffer.byteLength(JSON.stringify(result), \"utf8\") <= normalizedMaxBytes) {\n return result;\n }\n\n // Keep pollOptions.maxBytes behavior stable by dropping only the warning we appended.\n if (result.compatWarnings.length > 1) {\n result.compatWarnings.pop();\n } else {\n result.compatWarnings = undefined;\n }\n\n return result;\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.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 \"- `respond_approval` is a deprecated alias for `respond_permission`.\",\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 \"\",\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 \"\",\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 ].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 \"\",\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: true,\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 }\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 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"],"mappings":"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","names":["ErrorCode","existsSync","path","path","existsSync","existsSync","statSync","path","path","existsSync","statSync"]}
|