skill-codex 0.3.0 → 0.8.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/.claude-plugin/hooks/hooks.json +17 -0
- package/.claude-plugin/marketplace.json +23 -0
- package/.claude-plugin/plugin.json +16 -0
- package/.mcp.json +9 -0
- package/README.md +75 -15
- package/commands/codex-do.md +4 -3
- package/commands/codex-review.md +17 -6
- package/dist/bin/skill-codex.js +1280 -17
- package/dist/bin/skill-codex.js.map +1 -1
- package/dist/index.js +439 -48
- package/dist/index.js.map +1 -1
- package/hooks/post-tool-use-review.mjs +79 -0
- package/package.json +4 -1
- package/skills/codex-bridge/SKILL.md +217 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../bin/skill-codex.ts","../../setup/setup.ts","../../setup/install-mcp.ts","../../src/config/paths.ts","../../src/util/platform.ts","../../src/config/package-root.ts","../../setup/install-commands.ts","../../setup/install-hook.ts","../../setup/verify.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { runSetup, runUninstall } from \"../setup/setup.js\";\nimport { runVerification } from \"../setup/verify.js\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction getVersion(): string {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const pkgPath = path.resolve(__dirname, \"..\", \"package.json\");\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n return pkg.version ?? \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nasync function main(): Promise<void> {\n if (command === \"--help\" || command === \"-h\") {\n const version = getVersion();\n process.stdout.write(`skill-codex v${version}\n\nUsage:\n skill-codex setup Install MCP server, commands, and hook\n skill-codex setup --force Overwrite existing configuration\n skill-codex verify Check installation status\n skill-codex uninstall Show uninstall instructions\n skill-codex --help, -h Show this help message\n skill-codex --version, -v Show version\n`);\n process.exit(0);\n return;\n }\n\n if (command === \"--version\" || command === \"-v\") {\n process.stdout.write(`${getVersion()}\\n`);\n process.exit(0);\n return;\n }\n\n switch (command) {\n case \"setup\": {\n const force = args.includes(\"--force\");\n const success = await runSetup({ force });\n process.exit(success ? 0 : 1);\n break;\n }\n\n case \"verify\": {\n const { results, allPassed } = await runVerification();\n for (const check of results) {\n const icon = check.pass ? \"[ok]\" : \"[!!]\";\n process.stdout.write(`${icon} ${check.name}: ${check.detail}\\n`);\n }\n process.exit(allPassed ? 0 : 1);\n break;\n }\n\n case \"uninstall\": {\n await runUninstall();\n break;\n }\n\n default: {\n const version = getVersion();\n process.stdout.write(`skill-codex v${version}\n\nUsage:\n skill-codex setup Install MCP server, commands, and hook\n skill-codex setup --force Overwrite existing configuration\n skill-codex verify Check installation status\n skill-codex uninstall Show uninstall instructions\n skill-codex --help, -h Show this help message\n skill-codex --version, -v Show version\n`);\n process.exit(command ? 1 : 0);\n }\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { installMcp } from \"./install-mcp.js\";\nimport { installCommands } from \"./install-commands.js\";\nimport { installHook } from \"./install-hook.js\";\nimport { runVerification } from \"./verify.js\";\nimport {\n getGlobalMcpConfigPath,\n getGlobalCommandsDir,\n getClaudeSettingsPath,\n} from \"../src/config/paths.js\";\n\nfunction log(icon: string, message: string): void {\n process.stdout.write(`${icon} ${message}\\n`);\n}\n\nexport async function runSetup(options: { force?: boolean } = {}): Promise<boolean> {\n log(\">>\", \"skill-codex setup\\n\");\n\n // Step 1: Install MCP server\n log(\" \", \"Registering MCP server...\");\n const mcpResult = installMcp({ force: options.force });\n log(mcpResult.installed ? \"[ok]\" : \"[--]\", mcpResult.message);\n\n // Step 2: Install slash commands\n log(\" \", \"Installing slash commands...\");\n const cmdResult = installCommands({ global: true });\n log(cmdResult.installed.length > 0 ? \"[ok]\" : \"[--]\", cmdResult.message);\n\n // Step 3: Install hook\n log(\" \", \"Registering auto-review hook...\");\n const hookResult = installHook();\n log(hookResult.installed ? \"[ok]\" : \"[--]\", hookResult.message);\n\n // Step 4: Verify\n log(\"\\n \", \"Verifying installation...\\n\");\n const verification = await runVerification();\n\n for (const check of verification.results) {\n const icon = check.pass ? \"[ok]\" : \"[!!]\";\n log(` ${icon}`, `${check.name}: ${check.detail}`);\n }\n\n // Summary\n log(\"\", \"\");\n if (verification.allPassed) {\n log(\"[ok]\", \"Setup complete! Restart Claude Code to activate.\\n\");\n log(\" \", \"Available commands:\");\n log(\" \", \" /codex-review - Code review by Codex\");\n log(\" \", \" /codex-do - Delegate a task to Codex\");\n log(\" \", \" /codex-consult - Get a second opinion from Codex\");\n log(\"\", \"\");\n log(\" \", \"Tip: Add .skill-codex.lock to your .gitignore\");\n } else {\n log(\"[!!]\", \"Setup completed with warnings. Fix the issues above and run: npx skill-codex verify\\n\");\n }\n\n return verification.allPassed;\n}\n\nexport async function runUninstall(): Promise<void> {\n log(\">>\", \"skill-codex uninstall\\n\");\n\n // Step 1: Remove MCP server from ~/.claude.json\n const mcpConfigPath = getGlobalMcpConfigPath();\n try {\n const raw = fs.readFileSync(mcpConfigPath, \"utf-8\");\n const config = JSON.parse(raw) as Record<string, unknown>;\n const mcpServers = (config as { mcpServers?: Record<string, unknown> }).mcpServers;\n if (mcpServers && \"skill-codex\" in mcpServers) {\n delete mcpServers[\"skill-codex\"];\n fs.writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n log(\"[ok]\", \"Removed MCP server\");\n } else {\n log(\"[--]\", \"MCP server not found\");\n }\n } catch {\n log(\"[--]\", \"MCP server not found (could not read ~/.claude.json)\");\n }\n\n // Step 2: Remove slash commands from ~/.claude/commands/\n const commandsDir = getGlobalCommandsDir();\n const commandFiles = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n for (const file of commandFiles) {\n const filePath = path.join(commandsDir, file);\n try {\n fs.unlinkSync(filePath);\n log(\"[ok]\", `Removed ${file}`);\n } catch {\n log(\"[--]\", `${file} not found`);\n }\n }\n\n // Step 3: Remove PostToolUse hook from ~/.claude/settings.json\n const settingsPath = getClaudeSettingsPath();\n try {\n const raw = fs.readFileSync(settingsPath, \"utf-8\");\n const settings = JSON.parse(raw) as Record<string, unknown>;\n type HookEntry = { command?: string; hooks?: HookEntry[] };\n type HooksMap = Record<string, HookEntry[]>;\n const hooks = settings.hooks as HooksMap | undefined;\n if (hooks) {\n let removed = false;\n for (const eventType of Object.keys(hooks)) {\n const before = hooks[eventType].length;\n hooks[eventType] = hooks[eventType].filter(\n (entry) => !(entry.command ?? \"\").includes(\"skill-codex\")\n );\n if (hooks[eventType].length < before) removed = true;\n }\n if (removed) {\n fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + \"\\n\", \"utf-8\");\n log(\"[ok]\", \"Removed PostToolUse hook\");\n } else {\n log(\"[--]\", \"PostToolUse hook not found\");\n }\n } else {\n log(\"[--]\", \"PostToolUse hook not found\");\n }\n } catch {\n log(\"[--]\", \"Could not read ~/.claude/settings.json\");\n }\n\n log(\"\", \"\");\n log(\"[ok]\", \"Uninstall complete. Restart Claude Code to apply changes.\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getGlobalMcpConfigPath } from \"../src/config/paths.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\ninterface McpConfig {\n mcpServers?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nfunction getServerEntryPath(): string {\n return path.join(getPackageRoot(), \"dist\", \"index.js\");\n}\n\nexport function installMcp(options: { force?: boolean } = {}): {\n installed: boolean;\n configPath: string;\n message: string;\n} {\n const configPath = getGlobalMcpConfigPath();\n let config: McpConfig = {};\n\n // Read existing config\n if (fs.existsSync(configPath)) {\n try {\n const raw = fs.readFileSync(configPath, \"utf-8\");\n config = JSON.parse(raw) as McpConfig;\n } catch {\n return {\n installed: false,\n configPath,\n message: `Failed to parse ${configPath}. Back it up and try again.`,\n };\n }\n }\n\n // Check if already registered\n const servers = config.mcpServers ?? {};\n if (\"skill-codex\" in servers && !options.force) {\n return {\n installed: false,\n configPath,\n message: \"skill-codex MCP server already registered. Use --force to overwrite.\",\n };\n }\n\n const entryPath = getServerEntryPath();\n\n // Create new config with merged MCP server\n const updatedConfig: McpConfig = {\n ...config,\n mcpServers: {\n ...servers,\n \"skill-codex\": {\n command: \"node\",\n args: [entryPath],\n env: {},\n },\n },\n };\n\n // Ensure directory exists\n const dir = path.dirname(configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write: write to temp file then rename to prevent corruption\n const tmpPath = configPath + \".tmp\";\n fs.writeFileSync(tmpPath, JSON.stringify(updatedConfig, null, 2) + \"\\n\", \"utf-8\");\n fs.renameSync(tmpPath, configPath);\n\n return {\n installed: true,\n configPath,\n message: `MCP server registered in ${configPath}`,\n };\n}\n","import path from \"node:path\";\nimport { getClaudeDir, getHomeDir } from \"../util/platform.js\";\n\nexport function getClaudeSettingsPath(): string {\n return path.join(getClaudeDir(), \"settings.json\");\n}\n\nexport function getGlobalMcpConfigPath(): string {\n return path.join(getHomeDir(), \".claude.json\");\n}\n\nexport function getGlobalCommandsDir(): string {\n return path.join(getClaudeDir(), \"commands\");\n}\n\nexport function getProjectCommandsDir(cwd: string): string {\n return path.join(cwd, \".claude\", \"commands\");\n}\n\nexport function getProjectMcpConfigPath(cwd: string): string {\n return path.join(cwd, \".mcp.json\");\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport type Platform = \"win32\" | \"darwin\" | \"linux\";\n\nexport function getPlatform(): Platform {\n const p = os.platform();\n if (p === \"win32\" || p === \"darwin\" || p === \"linux\") return p;\n return \"linux\"; // default fallback for other unix-like\n}\n\nexport function isWindows(): boolean {\n return getPlatform() === \"win32\";\n}\n\nexport function normalizePath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport function getHomeDir(): string {\n return os.homedir();\n}\n\nexport function getClaudeDir(): string {\n return path.join(getHomeDir(), \".claude\");\n}\n\nexport function getTempDir(): string {\n return os.tmpdir();\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Resolves the package root directory by walking up from the current file\n * until we find package.json. Works both in dev (src/) and after bundling (dist/).\n */\nexport function getPackageRoot(): string {\n const thisFile = new URL(import.meta.url).pathname;\n const normalized = process.platform === \"win32\" && thisFile.startsWith(\"/\")\n ? thisFile.slice(1)\n : thisFile;\n\n let dir = path.dirname(normalized);\n for (let i = 0; i < 10; i++) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n\n // Fallback: assume 2 levels up from dist/bin/\n return path.resolve(path.dirname(normalized), \"..\", \"..\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getGlobalCommandsDir } from \"../src/config/paths.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\nconst COMMAND_FILES = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n\nfunction getCommandsSourceDir(): string {\n return path.join(getPackageRoot(), \"commands\");\n}\n\nexport function installCommands(options: { global?: boolean; projectDir?: string } = {}): {\n installed: string[];\n skipped: string[];\n targetDir: string;\n message: string;\n} {\n const targetDir = options.global !== false\n ? getGlobalCommandsDir()\n : path.join(options.projectDir ?? process.cwd(), \".claude\", \"commands\");\n\n const sourceDir = getCommandsSourceDir();\n\n // Ensure target directory exists\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n const installed: string[] = [];\n const skipped: string[] = [];\n\n for (const file of COMMAND_FILES) {\n const sourcePath = path.join(sourceDir, file);\n const targetPath = path.join(targetDir, file);\n\n if (!fs.existsSync(sourcePath)) {\n skipped.push(file);\n continue;\n }\n\n const sourceContent = fs.readFileSync(sourcePath, \"utf-8\");\n\n // Skip if identical content already exists\n if (fs.existsSync(targetPath)) {\n const existingContent = fs.readFileSync(targetPath, \"utf-8\");\n if (existingContent === sourceContent) {\n skipped.push(file);\n continue;\n }\n }\n\n fs.writeFileSync(targetPath, sourceContent, \"utf-8\");\n installed.push(file);\n }\n\n return {\n installed,\n skipped,\n targetDir,\n message: installed.length > 0\n ? `Installed ${installed.length} command(s) to ${targetDir}`\n : \"All commands already up to date\",\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getClaudeSettingsPath } from \"../src/config/paths.js\";\nimport { isWindows } from \"../src/util/platform.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\ninterface HookCommand {\n type: \"command\";\n command: string;\n}\n\ninterface HookEntry {\n matcher: string;\n hooks: HookCommand[];\n}\n\ninterface ClaudeSettings {\n hooks?: {\n PostToolUse?: HookEntry[];\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\nfunction getHookScriptPath(): string {\n const hooksDir = path.join(getPackageRoot(), \"hooks\");\n return isWindows()\n ? path.join(hooksDir, \"post-tool-use-review.ps1\")\n : path.join(hooksDir, \"post-tool-use-review.sh\");\n}\n\nfunction buildHookCommand(): { command: string; scriptPath: string } | null {\n const scriptPath = getHookScriptPath();\n if (!fs.existsSync(scriptPath)) {\n return null;\n }\n const command = isWindows()\n ? `powershell -ExecutionPolicy Bypass -File \"${scriptPath}\"`\n : `bash \"${scriptPath}\"`;\n return { command, scriptPath };\n}\n\nexport function installHook(): {\n installed: boolean;\n settingsPath: string;\n message: string;\n} {\n const settingsPath = getClaudeSettingsPath();\n let settings: ClaudeSettings = {};\n\n if (fs.existsSync(settingsPath)) {\n try {\n const raw = fs.readFileSync(settingsPath, \"utf-8\");\n settings = JSON.parse(raw) as ClaudeSettings;\n } catch {\n return {\n installed: false,\n settingsPath,\n message: `Failed to parse ${settingsPath}. Back it up and fix manually.`,\n };\n }\n }\n\n const hookResult = buildHookCommand();\n if (!hookResult) {\n return {\n installed: false,\n settingsPath,\n message: \"Hook script not found. Run `npm run build` first.\",\n };\n }\n\n // Correct Claude Code hook format: matcher + hooks array\n const hookEntry: HookEntry = {\n matcher: \"Write|Edit|MultiEdit|NotebookEdit\",\n hooks: [\n {\n type: \"command\",\n command: hookResult.command,\n },\n ],\n };\n\n const existingHooks = settings.hooks?.PostToolUse ?? [];\n\n // Check if already registered (search in nested hooks array)\n const alreadyExists = existingHooks.some((h) =>\n h.hooks?.some((inner) => inner.command.includes(\"skill-codex\")),\n );\n if (alreadyExists) {\n return {\n installed: false,\n settingsPath,\n message: \"skill-codex hook already registered.\",\n };\n }\n\n const updatedSettings: ClaudeSettings = {\n ...settings,\n hooks: {\n ...settings.hooks,\n PostToolUse: [...existingHooks, hookEntry],\n },\n };\n\n const dir = path.dirname(settingsPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write: temp file then rename\n const tmpPath = settingsPath + \".tmp\";\n fs.writeFileSync(tmpPath, JSON.stringify(updatedSettings, null, 2) + \"\\n\", \"utf-8\");\n fs.renameSync(tmpPath, settingsPath);\n\n // Ensure bash script is executable on unix\n if (!isWindows()) {\n const shPath = path.resolve(path.dirname(getHookScriptPath()), \"post-tool-use-review.sh\");\n try {\n fs.chmodSync(shPath, 0o755);\n } catch {\n // Best effort\n }\n }\n\n return {\n installed: true,\n settingsPath,\n message: `PostToolUse hook registered in ${settingsPath}`,\n };\n}\n","import fs from \"node:fs\";\nimport which from \"which\";\nimport { getGlobalMcpConfigPath, getGlobalCommandsDir } from \"../src/config/paths.js\";\n\ninterface CheckResult {\n readonly name: string;\n readonly pass: boolean;\n readonly detail: string;\n}\n\nexport async function runVerification(): Promise<{\n results: CheckResult[];\n allPassed: boolean;\n}> {\n const results: CheckResult[] = [];\n\n // 1. Node.js version\n const nodeVersion = process.versions.node;\n const nodeMajor = parseInt(nodeVersion.split(\".\")[0] ?? \"0\", 10);\n results.push({\n name: \"Node.js >= 18\",\n pass: nodeMajor >= 18,\n detail: `v${nodeVersion}`,\n });\n\n // 2. Codex CLI on PATH\n let codexPath: string | null = null;\n try {\n codexPath = await which(\"codex\");\n results.push({ name: \"Codex CLI found\", pass: true, detail: codexPath });\n } catch {\n results.push({ name: \"Codex CLI found\", pass: false, detail: \"Not found. Run: npm i -g @openai/codex\" });\n }\n\n // 3. MCP server registered\n const mcpPath = getGlobalMcpConfigPath();\n let mcpRegistered = false;\n if (fs.existsSync(mcpPath)) {\n try {\n const raw = fs.readFileSync(mcpPath, \"utf-8\");\n const config = JSON.parse(raw);\n mcpRegistered = \"skill-codex\" in (config.mcpServers ?? {});\n } catch {\n // Parse error\n }\n }\n results.push({\n name: \"MCP server registered\",\n pass: mcpRegistered,\n detail: mcpRegistered ? mcpPath : `Not found in ${mcpPath}`,\n });\n\n // 4. Slash commands installed\n const commandsDir = getGlobalCommandsDir();\n const expectedCommands = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n const missingCommands = expectedCommands.filter(\n (cmd) => !fs.existsSync(`${commandsDir}/${cmd}`),\n );\n results.push({\n name: \"Slash commands installed\",\n pass: missingCommands.length === 0,\n detail: missingCommands.length === 0\n ? `All 3 commands in ${commandsDir}`\n : `Missing: ${missingCommands.join(\", \")}`,\n });\n\n return {\n results,\n allPassed: results.every((r) => r.pass),\n };\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","path","path","path","path","fs","fs","path","path","fs","fs","path","path","fs","command","fs","fs","fs","path","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../../bin/skill-codex.ts","../../setup/setup.ts","../../setup/install-mcp.ts","../../src/config/paths.ts","../../src/util/platform.ts","../../src/config/package-root.ts","../../setup/install-commands.ts","../../setup/install-hook.ts","../../setup/install-skill.ts","../../setup/verify.ts","../../src/server.ts","../../src/tools/codex-exec.ts","../../src/errors/errors.ts","../../src/config/constants.ts","../../src/guards/check-recursion.ts","../../src/guards/check-binary.ts","../../src/guards/check-auth.ts","../../src/runner/sandbox-args.ts","../../src/lock/lock-file.ts","../../src/guards/check-lock.ts","../../src/guards/check-git.ts","../../src/guards/preflight.ts","../../src/runner/exec-runner.ts","../../src/runner/timeout.ts","../../src/util/truncate.ts","../../src/runner/output-parser.ts","../../src/util/text.ts","../../src/runner/progress.ts","../../src/util/live-logger.ts","../../src/runner/retry.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { runSetup, runUninstall } from \"../setup/setup.js\";\nimport { runVerification } from \"../setup/verify.js\";\nimport { startServer } from \"../src/server.js\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\n\nfunction getVersion(): string {\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const pkgPath = path.resolve(__dirname, \"..\", \"package.json\");\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n return pkg.version ?? \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nasync function main(): Promise<void> {\n if (command === \"--help\" || command === \"-h\") {\n const version = getVersion();\n process.stdout.write(`skill-codex v${version}\n\nUsage:\n skill-codex setup Install MCP server, commands, and hook\n skill-codex setup --force Overwrite existing configuration\n skill-codex verify Check installation status\n skill-codex uninstall Show uninstall instructions\n skill-codex --help, -h Show this help message\n skill-codex --version, -v Show version\n`);\n process.exit(0);\n return;\n }\n\n if (command === \"--version\" || command === \"-v\") {\n process.stdout.write(`${getVersion()}\\n`);\n process.exit(0);\n return;\n }\n\n switch (command) {\n case \"setup\": {\n const force = args.includes(\"--force\");\n const success = await runSetup({ force });\n process.exit(success ? 0 : 1);\n break;\n }\n\n case \"verify\": {\n const { results, allPassed } = await runVerification();\n for (const check of results) {\n const icon = check.pass ? \"[ok]\" : \"[!!]\";\n process.stdout.write(`${icon} ${check.name}: ${check.detail}\\n`);\n }\n process.exit(allPassed ? 0 : 1);\n break;\n }\n\n case \"uninstall\": {\n await runUninstall();\n break;\n }\n\n case \"mcp\":\n case \"serve\": {\n // Start the MCP server over stdio. Used by the Claude Code plugin's\n // .mcp.json via `npx -y skill-codex mcp`. Must NOT write to stdout\n // (that's the JSON-RPC channel) or call process.exit — the process\n // stays alive for the stdio transport.\n await startServer();\n break;\n }\n\n default: {\n const version = getVersion();\n process.stdout.write(`skill-codex v${version}\n\nUsage:\n skill-codex setup Install MCP server, commands, and hook\n skill-codex setup --force Overwrite existing configuration\n skill-codex verify Check installation status\n skill-codex uninstall Show uninstall instructions\n skill-codex --help, -h Show this help message\n skill-codex --version, -v Show version\n`);\n process.exit(command ? 1 : 0);\n }\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { installMcp } from \"./install-mcp.js\";\nimport { installCommands } from \"./install-commands.js\";\nimport { installHook } from \"./install-hook.js\";\nimport { installSkill, uninstallSkill } from \"./install-skill.js\";\nimport { runVerification } from \"./verify.js\";\nimport {\n getGlobalMcpConfigPath,\n getGlobalCommandsDir,\n getClaudeSettingsPath,\n} from \"../src/config/paths.js\";\n\nfunction log(icon: string, message: string): void {\n process.stdout.write(`${icon} ${message}\\n`);\n}\n\nexport async function runSetup(options: { force?: boolean } = {}): Promise<boolean> {\n log(\">>\", \"skill-codex setup\\n\");\n\n // Step 1: Install MCP server\n log(\" \", \"Registering MCP server...\");\n const mcpResult = installMcp({ force: options.force });\n log(mcpResult.installed ? \"[ok]\" : \"[--]\", mcpResult.message);\n\n // Step 2: Install slash commands\n log(\" \", \"Installing slash commands...\");\n const cmdResult = installCommands({ global: true });\n log(cmdResult.installed.length > 0 ? \"[ok]\" : \"[--]\", cmdResult.message);\n\n // Step 3: Install hook\n log(\" \", \"Registering auto-review hook...\");\n const hookResult = installHook();\n log(hookResult.installed ? \"[ok]\" : \"[--]\", hookResult.message);\n\n // Step 4: Install Agent Skill (auto-trigger discovery)\n log(\" \", \"Installing agent skill...\");\n const skillResult = installSkill();\n log(skillResult.installed ? \"[ok]\" : \"[--]\", skillResult.message);\n\n // Step 5: Verify\n log(\"\\n \", \"Verifying installation...\\n\");\n const verification = await runVerification();\n\n for (const check of verification.results) {\n const icon = check.pass ? \"[ok]\" : \"[!!]\";\n log(` ${icon}`, `${check.name}: ${check.detail}`);\n }\n\n // Summary\n log(\"\", \"\");\n if (verification.allPassed) {\n log(\"[ok]\", \"Setup complete! Restart Claude Code to activate.\\n\");\n log(\" \", \"Available commands:\");\n log(\" \", \" /codex-review - Code review by Codex\");\n log(\" \", \" /codex-do - Delegate a task to Codex\");\n log(\" \", \" /codex-consult - Get a second opinion from Codex\");\n log(\"\", \"\");\n log(\" \", \"Agent skill installed: codex-bridge (auto-triggers on implementation/review requests)\");\n log(\"\", \"\");\n log(\" \", \"Tip: Add .skill-codex.lock to your .gitignore\");\n } else {\n log(\"[!!]\", \"Setup completed with warnings. Fix the issues above and run: npx skill-codex verify\\n\");\n }\n\n return verification.allPassed;\n}\n\nexport async function runUninstall(): Promise<void> {\n log(\">>\", \"skill-codex uninstall\\n\");\n\n // Step 1: Remove MCP server from ~/.claude.json\n const mcpConfigPath = getGlobalMcpConfigPath();\n try {\n const raw = fs.readFileSync(mcpConfigPath, \"utf-8\");\n const config = JSON.parse(raw) as Record<string, unknown>;\n const mcpServers = (config as { mcpServers?: Record<string, unknown> }).mcpServers;\n if (mcpServers && \"skill-codex\" in mcpServers) {\n delete mcpServers[\"skill-codex\"];\n fs.writeFileSync(mcpConfigPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf-8\");\n log(\"[ok]\", \"Removed MCP server\");\n } else {\n log(\"[--]\", \"MCP server not found\");\n }\n } catch {\n log(\"[--]\", \"MCP server not found (could not read ~/.claude.json)\");\n }\n\n // Step 2: Remove slash commands from ~/.claude/commands/\n const commandsDir = getGlobalCommandsDir();\n const commandFiles = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n for (const file of commandFiles) {\n const filePath = path.join(commandsDir, file);\n try {\n fs.unlinkSync(filePath);\n log(\"[ok]\", `Removed ${file}`);\n } catch {\n log(\"[--]\", `${file} not found`);\n }\n }\n\n // Step 3: Remove agent skill from ~/.claude/skills/codex-bridge\n const skillUninstall = uninstallSkill();\n if (skillUninstall.removed) {\n log(\"[ok]\", `Removed skill: ${skillUninstall.targetDir}`);\n } else {\n log(\"[--]\", \"Agent skill not found\");\n }\n\n // Step 4: Remove PostToolUse hook from ~/.claude/settings.json\n const settingsPath = getClaudeSettingsPath();\n try {\n const raw = fs.readFileSync(settingsPath, \"utf-8\");\n const settings = JSON.parse(raw) as Record<string, unknown>;\n type HookEntry = { command?: string; hooks?: HookEntry[] };\n type HooksMap = Record<string, HookEntry[]>;\n const hooks = settings.hooks as HooksMap | undefined;\n if (hooks) {\n let removed = false;\n for (const eventType of Object.keys(hooks)) {\n const before = hooks[eventType].length;\n hooks[eventType] = hooks[eventType].filter(\n (entry) => !(entry.command ?? \"\").includes(\"skill-codex\")\n );\n if (hooks[eventType].length < before) removed = true;\n }\n if (removed) {\n fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + \"\\n\", \"utf-8\");\n log(\"[ok]\", \"Removed PostToolUse hook\");\n } else {\n log(\"[--]\", \"PostToolUse hook not found\");\n }\n } else {\n log(\"[--]\", \"PostToolUse hook not found\");\n }\n } catch {\n log(\"[--]\", \"Could not read ~/.claude/settings.json\");\n }\n\n log(\"\", \"\");\n log(\"[ok]\", \"Uninstall complete. Restart Claude Code to apply changes.\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getGlobalMcpConfigPath } from \"../src/config/paths.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\ninterface McpConfig {\n mcpServers?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nfunction getServerEntryPath(): string {\n return path.join(getPackageRoot(), \"dist\", \"index.js\");\n}\n\nexport function installMcp(options: { force?: boolean } = {}): {\n installed: boolean;\n configPath: string;\n message: string;\n} {\n const configPath = getGlobalMcpConfigPath();\n let config: McpConfig = {};\n\n // Read existing config\n if (fs.existsSync(configPath)) {\n try {\n const raw = fs.readFileSync(configPath, \"utf-8\");\n config = JSON.parse(raw) as McpConfig;\n } catch {\n return {\n installed: false,\n configPath,\n message: `Failed to parse ${configPath}. Back it up and try again.`,\n };\n }\n }\n\n // Check if already registered\n const servers = config.mcpServers ?? {};\n if (\"skill-codex\" in servers && !options.force) {\n return {\n installed: false,\n configPath,\n message: \"skill-codex MCP server already registered. Use --force to overwrite.\",\n };\n }\n\n const entryPath = getServerEntryPath();\n\n // Create new config with merged MCP server\n const updatedConfig: McpConfig = {\n ...config,\n mcpServers: {\n ...servers,\n \"skill-codex\": {\n command: \"node\",\n args: [entryPath],\n env: {},\n },\n },\n };\n\n // Ensure directory exists\n const dir = path.dirname(configPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write: write to temp file then rename to prevent corruption\n const tmpPath = configPath + \".tmp\";\n fs.writeFileSync(tmpPath, JSON.stringify(updatedConfig, null, 2) + \"\\n\", \"utf-8\");\n fs.renameSync(tmpPath, configPath);\n\n return {\n installed: true,\n configPath,\n message: `MCP server registered in ${configPath}`,\n };\n}\n","import path from \"node:path\";\nimport { getClaudeDir, getHomeDir } from \"../util/platform.js\";\n\nexport function getClaudeSettingsPath(): string {\n return path.join(getClaudeDir(), \"settings.json\");\n}\n\nexport function getGlobalMcpConfigPath(): string {\n return path.join(getHomeDir(), \".claude.json\");\n}\n\nexport function getGlobalCommandsDir(): string {\n return path.join(getClaudeDir(), \"commands\");\n}\n\nexport function getGlobalSkillsDir(): string {\n return path.join(getClaudeDir(), \"skills\");\n}\n\nexport function getProjectCommandsDir(cwd: string): string {\n return path.join(cwd, \".claude\", \"commands\");\n}\n\nexport function getProjectMcpConfigPath(cwd: string): string {\n return path.join(cwd, \".mcp.json\");\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\n\nexport type Platform = \"win32\" | \"darwin\" | \"linux\";\n\nexport function getPlatform(): Platform {\n const p = os.platform();\n if (p === \"win32\" || p === \"darwin\" || p === \"linux\") return p;\n return \"linux\"; // default fallback for other unix-like\n}\n\nexport function isWindows(): boolean {\n return getPlatform() === \"win32\";\n}\n\nexport function normalizePath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport function getHomeDir(): string {\n return os.homedir();\n}\n\nexport function getClaudeDir(): string {\n return path.join(getHomeDir(), \".claude\");\n}\n\nexport function getTempDir(): string {\n return os.tmpdir();\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Resolves the package root directory by walking up from the current file\n * until we find package.json. Works both in dev (src/) and after bundling (dist/).\n */\nexport function getPackageRoot(): string {\n const thisFile = new URL(import.meta.url).pathname;\n const normalized = process.platform === \"win32\" && thisFile.startsWith(\"/\")\n ? thisFile.slice(1)\n : thisFile;\n\n let dir = path.dirname(normalized);\n for (let i = 0; i < 10; i++) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n\n // Fallback: assume 2 levels up from dist/bin/\n return path.resolve(path.dirname(normalized), \"..\", \"..\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getGlobalCommandsDir } from \"../src/config/paths.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\nconst COMMAND_FILES = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n\nfunction getCommandsSourceDir(): string {\n return path.join(getPackageRoot(), \"commands\");\n}\n\nexport function installCommands(options: { global?: boolean; projectDir?: string } = {}): {\n installed: string[];\n skipped: string[];\n targetDir: string;\n message: string;\n} {\n const targetDir = options.global !== false\n ? getGlobalCommandsDir()\n : path.join(options.projectDir ?? process.cwd(), \".claude\", \"commands\");\n\n const sourceDir = getCommandsSourceDir();\n\n // Ensure target directory exists\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n const installed: string[] = [];\n const skipped: string[] = [];\n\n for (const file of COMMAND_FILES) {\n const sourcePath = path.join(sourceDir, file);\n const targetPath = path.join(targetDir, file);\n\n if (!fs.existsSync(sourcePath)) {\n skipped.push(file);\n continue;\n }\n\n const sourceContent = fs.readFileSync(sourcePath, \"utf-8\");\n\n // Skip if identical content already exists\n if (fs.existsSync(targetPath)) {\n const existingContent = fs.readFileSync(targetPath, \"utf-8\");\n if (existingContent === sourceContent) {\n skipped.push(file);\n continue;\n }\n }\n\n fs.writeFileSync(targetPath, sourceContent, \"utf-8\");\n installed.push(file);\n }\n\n return {\n installed,\n skipped,\n targetDir,\n message: installed.length > 0\n ? `Installed ${installed.length} command(s) to ${targetDir}`\n : \"All commands already up to date\",\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getClaudeSettingsPath } from \"../src/config/paths.js\";\nimport { isWindows } from \"../src/util/platform.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\ninterface HookCommand {\n type: \"command\";\n command: string;\n}\n\ninterface HookEntry {\n matcher: string;\n hooks: HookCommand[];\n}\n\ninterface ClaudeSettings {\n hooks?: {\n PostToolUse?: HookEntry[];\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\nfunction getHookScriptPath(): string {\n const hooksDir = path.join(getPackageRoot(), \"hooks\");\n return isWindows()\n ? path.join(hooksDir, \"post-tool-use-review.ps1\")\n : path.join(hooksDir, \"post-tool-use-review.sh\");\n}\n\nfunction buildHookCommand(): { command: string; scriptPath: string } | null {\n const scriptPath = getHookScriptPath();\n if (!fs.existsSync(scriptPath)) {\n return null;\n }\n const command = isWindows()\n ? `powershell -ExecutionPolicy Bypass -File \"${scriptPath}\"`\n : `bash \"${scriptPath}\"`;\n return { command, scriptPath };\n}\n\nexport function installHook(): {\n installed: boolean;\n settingsPath: string;\n message: string;\n} {\n const settingsPath = getClaudeSettingsPath();\n let settings: ClaudeSettings = {};\n\n if (fs.existsSync(settingsPath)) {\n try {\n const raw = fs.readFileSync(settingsPath, \"utf-8\");\n settings = JSON.parse(raw) as ClaudeSettings;\n } catch {\n return {\n installed: false,\n settingsPath,\n message: `Failed to parse ${settingsPath}. Back it up and fix manually.`,\n };\n }\n }\n\n const hookResult = buildHookCommand();\n if (!hookResult) {\n return {\n installed: false,\n settingsPath,\n message: \"Hook script not found. Run `npm run build` first.\",\n };\n }\n\n // Correct Claude Code hook format: matcher + hooks array\n const hookEntry: HookEntry = {\n matcher: \"Write|Edit|MultiEdit|NotebookEdit\",\n hooks: [\n {\n type: \"command\",\n command: hookResult.command,\n },\n ],\n };\n\n const existingHooks = settings.hooks?.PostToolUse ?? [];\n\n // Check if already registered (search in nested hooks array)\n const alreadyExists = existingHooks.some((h) =>\n h.hooks?.some((inner) => inner.command.includes(\"skill-codex\")),\n );\n if (alreadyExists) {\n return {\n installed: false,\n settingsPath,\n message: \"skill-codex hook already registered.\",\n };\n }\n\n const updatedSettings: ClaudeSettings = {\n ...settings,\n hooks: {\n ...settings.hooks,\n PostToolUse: [...existingHooks, hookEntry],\n },\n };\n\n const dir = path.dirname(settingsPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Atomic write: temp file then rename\n const tmpPath = settingsPath + \".tmp\";\n fs.writeFileSync(tmpPath, JSON.stringify(updatedSettings, null, 2) + \"\\n\", \"utf-8\");\n fs.renameSync(tmpPath, settingsPath);\n\n // Ensure bash script is executable on unix\n if (!isWindows()) {\n const shPath = path.resolve(path.dirname(getHookScriptPath()), \"post-tool-use-review.sh\");\n try {\n fs.chmodSync(shPath, 0o755);\n } catch {\n // Best effort\n }\n }\n\n return {\n installed: true,\n settingsPath,\n message: `PostToolUse hook registered in ${settingsPath}`,\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getGlobalSkillsDir } from \"../src/config/paths.js\";\nimport { getPackageRoot } from \"../src/config/package-root.js\";\n\nconst SKILL_NAME = \"codex-bridge\";\n\ninterface InstallSkillResult {\n readonly installed: boolean;\n readonly targetDir: string;\n readonly copiedFiles: readonly string[];\n readonly message: string;\n}\n\nfunction getSkillSourceDir(): string {\n return path.join(getPackageRoot(), \"skills\", SKILL_NAME);\n}\n\nfunction copyDirRecursive(source: string, target: string): readonly string[] {\n const copied: string[] = [];\n\n if (!fs.existsSync(target)) {\n fs.mkdirSync(target, { recursive: true });\n }\n\n const entries = fs.readdirSync(source, { withFileTypes: true });\n for (const entry of entries) {\n const sourcePath = path.join(source, entry.name);\n const targetPath = path.join(target, entry.name);\n\n if (entry.isDirectory()) {\n copied.push(...copyDirRecursive(sourcePath, targetPath));\n } else if (entry.isFile()) {\n const sourceContent = fs.readFileSync(sourcePath);\n let shouldWrite = true;\n if (fs.existsSync(targetPath)) {\n const existing = fs.readFileSync(targetPath);\n shouldWrite = !existing.equals(sourceContent);\n }\n if (shouldWrite) {\n fs.writeFileSync(targetPath, sourceContent);\n copied.push(entry.name);\n }\n }\n }\n\n return copied;\n}\n\nexport function installSkill(): InstallSkillResult {\n const sourceDir = getSkillSourceDir();\n const targetDir = path.join(getGlobalSkillsDir(), SKILL_NAME);\n\n if (!fs.existsSync(sourceDir)) {\n return {\n installed: false,\n targetDir,\n copiedFiles: [],\n message: `Skill source not found at ${sourceDir}`,\n };\n }\n\n const skillFile = path.join(sourceDir, \"SKILL.md\");\n if (!fs.existsSync(skillFile)) {\n return {\n installed: false,\n targetDir,\n copiedFiles: [],\n message: `SKILL.md missing in ${sourceDir}`,\n };\n }\n\n const copied = copyDirRecursive(sourceDir, targetDir);\n\n return {\n installed: true,\n targetDir,\n copiedFiles: copied,\n message: copied.length > 0\n ? `Installed skill '${SKILL_NAME}' to ${targetDir} (${copied.length} file(s))`\n : `Skill '${SKILL_NAME}' already up to date`,\n };\n}\n\nexport function uninstallSkill(): { removed: boolean; targetDir: string } {\n const targetDir = path.join(getGlobalSkillsDir(), SKILL_NAME);\n if (!fs.existsSync(targetDir)) {\n return { removed: false, targetDir };\n }\n fs.rmSync(targetDir, { recursive: true, force: true });\n return { removed: true, targetDir };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport which from \"which\";\nimport {\n getGlobalMcpConfigPath,\n getGlobalCommandsDir,\n getGlobalSkillsDir,\n} from \"../src/config/paths.js\";\n\ninterface CheckResult {\n readonly name: string;\n readonly pass: boolean;\n readonly detail: string;\n}\n\nexport async function runVerification(): Promise<{\n results: CheckResult[];\n allPassed: boolean;\n}> {\n const results: CheckResult[] = [];\n\n // 1. Node.js version\n const nodeVersion = process.versions.node;\n const nodeMajor = parseInt(nodeVersion.split(\".\")[0] ?? \"0\", 10);\n results.push({\n name: \"Node.js >= 18\",\n pass: nodeMajor >= 18,\n detail: `v${nodeVersion}`,\n });\n\n // 2. Codex CLI on PATH\n let codexPath: string | null = null;\n try {\n codexPath = await which(\"codex\");\n results.push({ name: \"Codex CLI found\", pass: true, detail: codexPath });\n } catch {\n results.push({ name: \"Codex CLI found\", pass: false, detail: \"Not found. Run: npm i -g @openai/codex\" });\n }\n\n // 3. MCP server registered\n const mcpPath = getGlobalMcpConfigPath();\n let mcpRegistered = false;\n if (fs.existsSync(mcpPath)) {\n try {\n const raw = fs.readFileSync(mcpPath, \"utf-8\");\n const config = JSON.parse(raw);\n mcpRegistered = \"skill-codex\" in (config.mcpServers ?? {});\n } catch {\n // Parse error\n }\n }\n results.push({\n name: \"MCP server registered\",\n pass: mcpRegistered,\n detail: mcpRegistered ? mcpPath : `Not found in ${mcpPath}`,\n });\n\n // 4. Slash commands installed\n const commandsDir = getGlobalCommandsDir();\n const expectedCommands = [\"codex-review.md\", \"codex-do.md\", \"codex-consult.md\"];\n const missingCommands = expectedCommands.filter(\n (cmd) => !fs.existsSync(`${commandsDir}/${cmd}`),\n );\n results.push({\n name: \"Slash commands installed\",\n pass: missingCommands.length === 0,\n detail: missingCommands.length === 0\n ? `All 3 commands in ${commandsDir}`\n : `Missing: ${missingCommands.join(\", \")}`,\n });\n\n // 5. Agent skill installed\n const skillFile = path.join(getGlobalSkillsDir(), \"codex-bridge\", \"SKILL.md\");\n const skillInstalled = fs.existsSync(skillFile);\n results.push({\n name: \"Agent skill installed\",\n pass: skillInstalled,\n detail: skillInstalled ? skillFile : `Not found at ${skillFile}`,\n });\n\n return {\n results,\n allPassed: results.every((r) => r.pass),\n };\n}\n","import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n TOOL_NAME,\n TOOL_DESCRIPTION,\n TOOL_INPUT_JSON_SCHEMA,\n inputSchema,\n handleCodexExec,\n} from \"./tools/codex-exec.js\";\n\nexport function createServer(cwd: string): Server {\n const server = new Server(\n { name: \"skill-codex\", version: \"0.8.0\" },\n { capabilities: { tools: {} } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: TOOL_NAME,\n description: TOOL_DESCRIPTION,\n inputSchema: TOOL_INPUT_JSON_SCHEMA,\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n if (request.params.name !== TOOL_NAME) {\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${request.params.name}` }],\n isError: true,\n };\n }\n\n const parsed = inputSchema.safeParse(request.params.arguments);\n if (!parsed.success) {\n return {\n content: [\n {\n type: \"text\",\n text: `Invalid input: ${parsed.error.issues.map((i) => i.message).join(\", \")}`,\n },\n ],\n isError: true,\n };\n }\n\n // Stream live progress only if the client requested it (sent a progressToken).\n // MCP requires the `progress` value to monotonically increase per request.\n const progressToken = request.params._meta?.progressToken;\n let progressCounter = 0;\n const onProgress =\n progressToken === undefined\n ? undefined\n : (message: string): void => {\n progressCounter += 1;\n void extra\n .sendNotification({\n method: \"notifications/progress\",\n params: { progressToken, progress: progressCounter, message },\n })\n .catch(() => {\n // never let a dropped notification break the run\n });\n };\n\n return handleCodexExec(parsed.data, cwd, onProgress);\n });\n\n return server;\n}\n\nexport async function startServer(): Promise<void> {\n const cwd = process.cwd();\n const server = createServer(cwd);\n const transport = new StdioServerTransport();\n\n process.stderr.write(\"[skill-codex] MCP server starting...\\n\");\n\n await server.connect(transport);\n\n process.stderr.write(\"[skill-codex] MCP server connected via stdio\\n\");\n\n process.on(\"uncaughtException\", (err) => {\n process.stderr.write(`[skill-codex] Uncaught exception: ${err.message}\\n`);\n });\n\n process.on(\"unhandledRejection\", (reason) => {\n process.stderr.write(`[skill-codex] Unhandled rejection: ${String(reason)}\\n`);\n });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { runPreflight } from \"../guards/preflight.js\";\nimport { execCodex } from \"../runner/exec-runner.js\";\nimport { withRetry } from \"../runner/retry.js\";\nimport { BridgeError } from \"../errors/errors.js\";\nimport type { CodexResult } from \"../runner/output-parser.js\";\n\nexport const TOOL_NAME = \"codex_exec\";\n\nexport const TOOL_DESCRIPTION =\n \"Execute a task using OpenAI Codex CLI. Use for code review, implementation tasks, or getting a second opinion. Codex output is a SUGGESTION — evaluate it critically before applying.\";\n\nexport const inputSchema = z.object({\n prompt: z.string().optional().describe(\"The task description for Codex\"),\n mode: z\n .enum([\"exec\", \"full-auto\"])\n .default(\"exec\")\n .describe(\"exec = read-only with confirmation, full-auto = can write files\"),\n sandbox: z\n .enum([\"read-only\", \"workspace-write\", \"danger-full-access\"])\n .optional()\n .describe(\n \"Explicit Codex sandbox policy; overrides mode. read-only = no writes, workspace-write = write within cwd, danger-full-access = unrestricted (use with care).\",\n ),\n sessionId: z\n .string()\n .regex(/^[A-Za-z0-9_-]{1,128}$/, \"sessionId must be a Codex thread id (letters, digits, '-', '_')\")\n .optional()\n .describe(\n \"Resume a prior Codex session by its thread id (returned in a previous response) so Codex retains context across calls.\",\n ),\n model: z\n .string()\n .regex(/^[A-Za-z0-9._-]{1,64}$/)\n .optional()\n .describe(\n \"Codex model to use (e.g. gpt-5.5, gpt-5.4, gpt-5.4-mini). Omit to use Codex's configured default.\",\n ),\n reasoningEffort: z\n .enum([\"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"])\n .optional()\n .describe(\"How much reasoning effort Codex spends. Omit for the model's default.\"),\n review: z\n .boolean()\n .optional()\n .describe(\n \"Run Codex's native diff-scoped review (`codex exec review`) instead of a freeform prompt. The prompt becomes optional custom review instructions.\",\n ),\n reviewBase: z\n .string()\n .regex(/^[A-Za-z0-9._\\/-]{1,128}$/)\n .optional()\n .describe(\"With review: diff against this base branch (default: uncommitted changes).\"),\n reviewCommit: z\n .string()\n .regex(/^[0-9a-fA-F]{4,64}$/)\n .optional()\n .describe(\"With review: review the changes introduced by this commit SHA.\"),\n cwd: z.string().optional().describe(\"Working directory (defaults to server cwd)\"),\n timeoutMs: z.number().optional().describe(\"Override default timeout in milliseconds\"),\n requireGit: z.boolean().default(false).describe(\"Fail if not inside a git repository\"),\n});\n\nexport type CodexExecInput = z.infer<typeof inputSchema>;\n\n/**\n * JSON Schema advertised to MCP clients in the `tools/list` response. Kept here\n * next to the zod `inputSchema` (the runtime validator) so the two can't drift —\n * a sync test asserts their property sets match. The MCP SDK wants a plain JSON\n * Schema object, so we hand-write it rather than deriving it at runtime.\n */\nexport const TOOL_INPUT_JSON_SCHEMA = {\n type: \"object\" as const,\n properties: {\n prompt: { type: \"string\", description: \"The task description for Codex\" },\n mode: {\n type: \"string\",\n enum: [\"exec\", \"full-auto\"],\n default: \"exec\",\n description: \"exec = read-only, full-auto = can write files\",\n },\n sandbox: {\n type: \"string\",\n enum: [\"read-only\", \"workspace-write\", \"danger-full-access\"],\n description:\n \"Explicit Codex sandbox policy; overrides mode. read-only = no writes, workspace-write = write within cwd, danger-full-access = unrestricted (use with care).\",\n },\n sessionId: {\n type: \"string\",\n pattern: \"^[A-Za-z0-9_-]{1,128}$\",\n description:\n \"Resume a prior Codex session by its thread id (returned in a previous response) so Codex retains context across calls.\",\n },\n model: {\n type: \"string\",\n pattern: \"^[A-Za-z0-9._-]{1,64}$\",\n description:\n \"Codex model to use (e.g. gpt-5.5, gpt-5.4, gpt-5.4-mini). Omit to use Codex's configured default.\",\n },\n reasoningEffort: {\n type: \"string\",\n enum: [\"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"],\n description: \"How much reasoning effort Codex spends. Omit for the model's default.\",\n },\n review: {\n type: \"boolean\",\n description:\n \"Run Codex's native diff-scoped review (`codex exec review`) instead of a freeform prompt. The prompt becomes optional custom review instructions.\",\n },\n reviewBase: {\n type: \"string\",\n pattern: \"^[A-Za-z0-9._\\\\/-]{1,128}$\",\n description: \"With review: diff against this base branch (default: uncommitted changes).\",\n },\n reviewCommit: {\n type: \"string\",\n pattern: \"^[0-9a-fA-F]{4,64}$\",\n description: \"With review: review the changes introduced by this commit SHA.\",\n },\n cwd: { type: \"string\", description: \"Working directory (defaults to server cwd)\" },\n timeoutMs: { type: \"number\", description: \"Override default timeout in milliseconds\" },\n requireGit: {\n type: \"boolean\",\n default: false,\n description: \"Fail if not inside a git repository\",\n },\n },\n required: [],\n};\n\nfunction formatError(err: unknown): string {\n if (err instanceof BridgeError) {\n return `[skill-codex error: ${err.code}] ${err.message}`;\n }\n if (err instanceof Error) {\n return `[skill-codex error] ${err.message}`;\n }\n return `[skill-codex error] Unknown error: ${String(err)}`;\n}\n\nfunction formatRichResponse(\n result: CodexResult,\n input: CodexExecInput,\n cwd: string,\n): string {\n const lines: string[] = [];\n\n // On resume, no --sandbox is sent (the session keeps its original policy), so\n // labelling it with a specific mode would be misleading — show \"resumed\" instead.\n const sandboxLabel = input.sandbox ?? (input.mode === \"full-auto\" ? \"workspace-write\" : \"read-only\");\n const label = input.review ? \"review\" : input.sessionId ? \"resumed\" : sandboxLabel;\n const metaParts: string[] = [label];\n\n if (input.model) {\n metaParts.push(input.model);\n }\n\n if (input.reasoningEffort) {\n metaParts.push(`effort:${input.reasoningEffort}`);\n }\n\n metaParts.push(cwd);\n\n if (typeof result.durationMs === \"number\") {\n metaParts.push(`${(result.durationMs / 1000).toFixed(1)}s`);\n }\n\n if (result.usage) {\n const {\n input_tokens: inp,\n output_tokens: out,\n cached_input_tokens: cached,\n reasoning_output_tokens: reasoning,\n } = result.usage;\n metaParts.push(\n `${inp} tok in${cached > 0 ? ` (${cached} cached)` : \"\"} \\u2192 ${out} out${reasoning > 0 ? ` (+${reasoning} reasoning)` : \"\"}`,\n );\n }\n\n lines.push(`[${metaParts.join(\" \\u2502 \")}]`);\n\n if (result.sessionId) {\n lines.push(` session: ${result.sessionId} (pass as sessionId to continue this conversation)`);\n }\n\n if (result.logPath) {\n lines.push(` live log: ${result.logPath}`);\n }\n\n if (result.activity.length > 0) {\n for (const a of result.activity) {\n if (a.type === \"exec\") {\n lines.push(` ${a.icon} exec: ${a.command} (${a.status})`);\n } else if (a.type === \"read\") {\n lines.push(` \\u25B6 read: ${a.path}`);\n } else if (a.type === \"write\") {\n lines.push(` \\u270E write: ${a.path}`);\n }\n }\n }\n\n lines.push(\"\");\n lines.push(result.content);\n\n return lines.join(\"\\n\");\n}\n\nexport async function handleCodexExec(\n input: CodexExecInput,\n serverCwd: string,\n onProgress?: (message: string) => void,\n): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n const rawCwd = input.cwd ?? serverCwd;\n const cwd = path.resolve(rawCwd);\n\n // Validate cwd is an existing directory (prevent path traversal to arbitrary locations)\n if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {\n return {\n content: [{ type: \"text\", text: `[skill-codex error: INVALID_CWD] cwd is not an existing directory: ${cwd}` }],\n isError: true,\n };\n }\n\n // Reject conflicting/stray options instead of silently ignoring them.\n const optError = (msg: string): { content: Array<{ type: \"text\"; text: string }>; isError: boolean } => ({\n content: [{ type: \"text\", text: `[skill-codex error: INVALID_OPTIONS] ${msg}` }],\n isError: true,\n });\n if (input.review && input.sessionId) return optError(\"review and sessionId are mutually exclusive\");\n if (input.reviewBase && input.reviewCommit) return optError(\"reviewBase and reviewCommit are mutually exclusive\");\n if ((input.reviewBase ?? input.reviewCommit) && !input.review) {\n return optError(\"reviewBase/reviewCommit require review: true\");\n }\n // The codex CLI forbids combining a review scope flag with a PROMPT.\n if (input.review && (input.reviewBase ?? input.reviewCommit) && input.prompt?.trim()) {\n return optError(\n \"a review target (reviewBase/reviewCommit) can't be combined with a prompt — Codex review takes a target OR instructions, not both\",\n );\n }\n\n // `prompt` is optional only for native review (where it's optional custom\n // instructions). Every other call must supply a prompt.\n if (!input.review && !input.prompt?.trim()) {\n return {\n content: [{ type: \"text\", text: \"[skill-codex error: MISSING_PROMPT] prompt is required unless review is set\" }],\n isError: true,\n };\n }\n\n let lockRelease: (() => void) | null = null;\n\n try {\n const { lockHandle } = await runPreflight({\n cwd,\n requireGit: input.requireGit,\n });\n lockRelease = lockHandle?.release ?? null;\n\n const result = await withRetry(() =>\n execCodex({\n prompt: input.prompt ?? \"\",\n cwd,\n mode: input.mode,\n sandbox: input.sandbox,\n sessionId: input.sessionId,\n model: input.model,\n reasoningEffort: input.reasoningEffort,\n review: input.review,\n reviewBase: input.reviewBase,\n reviewCommit: input.reviewCommit,\n timeoutMs: input.timeoutMs,\n onProgress,\n }),\n );\n\n const formatted = formatRichResponse(result, input, cwd);\n return {\n content: [{ type: \"text\", text: formatted }],\n };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: formatError(err) }],\n isError: true,\n };\n } finally {\n lockRelease?.();\n }\n}\n","export class BridgeError extends Error {\n readonly code: string;\n readonly retryable: boolean;\n\n constructor(message: string, code: string, retryable: boolean) {\n super(message);\n this.name = \"BridgeError\";\n this.code = code;\n this.retryable = retryable;\n }\n}\n\nexport class CliNotFoundError extends BridgeError {\n constructor(binary: string = \"codex\") {\n super(\n `${binary} CLI not found on PATH. Install it with: npm i -g @openai/codex`,\n \"CLI_NOT_FOUND\",\n false,\n );\n this.name = \"CliNotFoundError\";\n }\n}\n\nexport class AuthExpiredError extends BridgeError {\n constructor() {\n super(\n \"Codex authentication expired or not found. Run `codex login` to re-authenticate.\",\n \"AUTH_EXPIRED\",\n false,\n );\n this.name = \"AuthExpiredError\";\n }\n}\n\nexport class RecursionLimitError extends BridgeError {\n constructor(depth: number, max: number) {\n super(\n `Maximum bridge nesting depth reached (${depth} >= ${max}). This prevents infinite recursion between Claude and Codex.`,\n \"RECURSION_LIMIT\",\n false,\n );\n this.name = \"RecursionLimitError\";\n }\n}\n\nexport class LockConflictError extends BridgeError {\n constructor(pid: number) {\n super(\n `Another skill-codex instance is running (PID ${pid}). Wait for it to finish or delete the lock file.`,\n \"LOCK_CONFLICT\",\n false,\n );\n this.name = \"LockConflictError\";\n }\n}\n\nexport class TimeoutError extends BridgeError {\n constructor(timeoutMs: number) {\n super(\n `Codex timed out after ${Math.round(timeoutMs / 1000)}s. Increase SKILL_CODEX_TIMEOUT_MS if needed.`,\n \"TIMEOUT\",\n true,\n );\n this.name = \"TimeoutError\";\n }\n}\n\nexport class RateLimitError extends BridgeError {\n constructor() {\n super(\n \"Codex rate limited (429). Will retry with backoff.\",\n \"RATE_LIMIT\",\n true,\n );\n this.name = \"RateLimitError\";\n }\n}\n\nexport class ServerError extends BridgeError {\n constructor(detail: string = \"\") {\n super(\n `Codex server error${detail ? `: ${detail}` : \"\"}. Will retry.`,\n \"SERVER_ERROR\",\n true,\n );\n this.name = \"ServerError\";\n }\n}\n\nexport class NetworkError extends BridgeError {\n constructor(detail: string = \"\") {\n super(\n `Network error connecting to Codex${detail ? `: ${detail}` : \"\"}. Check your connection.`,\n \"NETWORK_ERROR\",\n true,\n );\n this.name = \"NetworkError\";\n }\n}\n\nexport class EmptyOutputError extends BridgeError {\n constructor() {\n super(\n \"Codex returned empty output. This may be a transient issue.\",\n \"EMPTY_OUTPUT\",\n true,\n );\n this.name = \"EmptyOutputError\";\n }\n}\n\nexport class NotGitRepoError extends BridgeError {\n constructor(cwd: string) {\n super(\n `Not a git repository: ${cwd}. This operation requires a git repo.`,\n \"NOT_GIT_REPO\",\n false,\n );\n this.name = \"NotGitRepoError\";\n }\n}\n\nexport class ParseError extends BridgeError {\n constructor(detail: string = \"\") {\n super(\n `Failed to parse Codex output${detail ? `: ${detail}` : \"\"}. The Codex CLI format may have changed — please update skill-codex.`,\n \"PARSE_ERROR\",\n false,\n );\n this.name = \"ParseError\";\n }\n}\n","export const MAX_BRIDGE_DEPTH = 2;\nexport const BRIDGE_DEPTH_ENV = \"SKILL_CODEX_DEPTH\";\n\nexport const DEFAULT_TIMEOUT_MS = 300_000; // 5 minutes (override via SKILL_CODEX_TIMEOUT_MS or per-call timeoutMs)\nexport const TIMEOUT_ENV = \"SKILL_CODEX_TIMEOUT_MS\";\nexport const KILL_GRACE_MS = 5_000;\n\n/** How often to emit a heartbeat progress message during quiet stretches. */\nexport const HEARTBEAT_INTERVAL_MS = 10_000;\n\nexport const MAX_RETRIES = 3;\nexport const MAX_RETRIES_ENV = \"SKILL_CODEX_MAX_RETRIES\";\nexport const RETRY_DELAYS_MS = [1_000, 2_000, 4_000];\nexport const RETRY_CAP_MS = 10_000;\n\nexport const MAX_RESPONSE_CHARS = 80_000;\n\nexport const LOCK_STALE_MS = 900_000; // 15 minutes\nexport const LOCK_FILENAME = \".skill-codex.lock\";\n\n// Live, human-readable per-run log. Codex emits JSONL that the MCP transport\n// buffers until completion; tailing this file shows progress in real time.\n// Defaults to a per-workspace file under the OS temp dir so a run never writes\n// a growing log into the user's working repo. Override with an absolute path\n// via SKILL_CODEX_LOG. The resolved path is printed at run start and returned\n// in the tool response, so it stays discoverable.\nexport const LOG_ENV = \"SKILL_CODEX_LOG\";\n\nexport const TRIVIAL_DIFF_THRESHOLD = 5; // lines\nexport const DOCS_ONLY_EXTENSIONS = [\".md\", \".txt\", \".rst\", \".adoc\"];\nexport const SECURITY_PATH_KEYWORDS = [\"security\", \"auth\", \"crypto\", \"password\", \"secret\", \"token\"];\nexport const FORCE_REVIEW_LINES = 100;\nexport const FORCE_REVIEW_FILES = 3;\n\nexport const CONFIG_ONLY_FILES = [\".gitignore\", \".eslintrc\", \".prettierrc\", \".editorconfig\"];\n\nexport const DEBUG_ENV = \"SKILL_CODEX_DEBUG\";\n\n// Codex's default (\"elevated\") Windows sandbox fails to spawn shells with\n// \"windows sandbox: spawn setup refresh\" on many setups (openai/codex#24098,\n// #24259). The \"unelevated\" sandbox spawns reliably, so we pin to it on Windows.\n// Override with SKILL_CODEX_WINDOWS_SANDBOX=elevated if a machine needs it.\nexport const WINDOWS_SANDBOX_ENV = \"SKILL_CODEX_WINDOWS_SANDBOX\";\nexport const WINDOWS_SANDBOX_DEFAULT = \"unelevated\";\n\nexport const TRANSIENT_PATTERNS = [\n \"rate limit\", \"too many requests\", \"429\",\n \"500\", \"502\", \"503\", \"504\",\n \"internal server error\", \"bad gateway\", \"service unavailable\", \"gateway timeout\",\n \"connection reset\", \"connection refused\",\n \"econnreset\", \"econnrefused\", \"etimedout\",\n \"network error\", \"fetch failed\", \"socket hang up\",\n] as const;\n\nexport const AUTH_ERROR_PATTERNS = [\n \"api key\", \"authentication\", \"unauthorized\", \"401\", \"auth\",\n] as const;\n","import { BRIDGE_DEPTH_ENV, MAX_BRIDGE_DEPTH } from \"../config/constants.js\";\nimport { RecursionLimitError } from \"../errors/errors.js\";\n\nexport function getCurrentDepth(): number {\n return parseInt(process.env[BRIDGE_DEPTH_ENV] ?? \"0\", 10);\n}\n\nexport function getNextDepth(): number {\n return getCurrentDepth() + 1;\n}\n\nexport function checkRecursion(): void {\n const depth = getCurrentDepth();\n if (depth >= MAX_BRIDGE_DEPTH) {\n throw new RecursionLimitError(depth, MAX_BRIDGE_DEPTH);\n }\n}\n","import which from \"which\";\nimport { CliNotFoundError } from \"../errors/errors.js\";\n\nexport interface BinaryCheckResult {\n readonly found: boolean;\n readonly path: string;\n}\n\nlet cachedBinaryPath: string | null = null;\n\nexport function getCachedBinaryPath(): string | null {\n return cachedBinaryPath;\n}\n\nexport function resetBinaryCache(): void {\n cachedBinaryPath = null;\n}\n\nexport async function checkBinary(\n binary: string = \"codex\",\n): Promise<BinaryCheckResult> {\n if (cachedBinaryPath !== null) {\n return { found: true, path: cachedBinaryPath };\n }\n\n try {\n const resolved = await which(binary);\n cachedBinaryPath = resolved;\n return { found: true, path: resolved };\n } catch {\n throw new CliNotFoundError(binary);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { AuthExpiredError, NetworkError, CliNotFoundError } from \"../errors/errors.js\";\nimport { getCachedBinaryPath } from \"./check-binary.js\";\nimport { getSandboxConfigArgs } from \"../runner/sandbox-args.js\";\n\nconst AUTH_CACHE_TTL_MS = 60_000;\n\nlet authCachedAt: number | null = null;\n\nexport function resetAuthCache(): void {\n authCachedAt = null;\n}\n\nexport async function checkAuth(): Promise<void> {\n const now = Date.now();\n\n if (authCachedAt !== null && now - authCachedAt < AUTH_CACHE_TTL_MS) {\n return;\n }\n\n const binary = getCachedBinaryPath() ?? \"codex\";\n\n return new Promise((resolve, reject) => {\n const child = execFile(\n binary,\n [\"exec\", \"--sandbox\", \"read-only\", ...getSandboxConfigArgs(), \"--skip-git-repo-check\", \"--ephemeral\", \"echo ok\"],\n { timeout: 30_000, shell: process.platform === \"win32\" },\n (error, _stdout, stderr) => {\n if (!error) {\n authCachedAt = Date.now();\n resolve();\n return;\n }\n\n const lower = (stderr ?? error.message ?? \"\").toLowerCase();\n\n // Distinguish error types instead of masking everything as auth\n if (error.code === \"ENOENT\" || (error as NodeJS.ErrnoException).code === \"ENOENT\") {\n reject(new CliNotFoundError());\n return;\n }\n\n if (error.killed) {\n reject(new NetworkError(\"Auth check timed out — check your network connection\"));\n return;\n }\n\n if ([\"econnrefused\", \"econnreset\", \"etimedout\", \"network error\", \"fetch failed\"].some((p) => lower.includes(p))) {\n reject(new NetworkError(\"Network error during auth check\"));\n return;\n }\n\n // Default: treat as auth issue\n reject(new AuthExpiredError());\n },\n );\n child.stdin?.end();\n });\n}\n","import { WINDOWS_SANDBOX_ENV, WINDOWS_SANDBOX_DEFAULT } from \"../config/constants.js\";\n\n/**\n * Extra `codex` CLI args needed to make the sandbox usable on the current\n * platform.\n *\n * On Windows, Codex's default elevated sandbox fails to spawn shell processes\n * (\"windows sandbox: spawn setup refresh\" — openai/codex#24098, #24259), which\n * blocks every command the model runs, including read-only ones. Pinning\n * `windows.sandbox=unelevated` restores reliable spawning. The mode can be\n * overridden via SKILL_CODEX_WINDOWS_SANDBOX (e.g. \"elevated\") for machines\n * where the elevated sandbox does work.\n *\n * Returns an empty array on non-Windows platforms, where Codex's native\n * sandbox (Seatbelt/Landlock) is used as-is.\n */\nexport function getSandboxConfigArgs(): readonly string[] {\n if (process.platform !== \"win32\") return [];\n const raw = process.env[WINDOWS_SANDBOX_ENV]?.trim() || WINDOWS_SANDBOX_DEFAULT;\n // Allowlist: Windows spawns via shell:true, so reject anything but a bare mode\n // token to keep a stray env value from injecting extra shell args.\n const mode = /^[a-z-]+$/.test(raw) ? raw : WINDOWS_SANDBOX_DEFAULT;\n return [\"-c\", `windows.sandbox=${mode}`];\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport { LOCK_FILENAME, LOCK_STALE_MS } from \"../config/constants.js\";\nimport { LockConflictError } from \"../errors/errors.js\";\n\ninterface LockData {\n readonly pid: number;\n readonly timestamp: number;\n readonly hostname: string;\n}\n\nexport interface LockHandle {\n readonly release: () => void;\n}\n\nfunction getLockPath(cwd: string): string {\n return path.join(cwd, LOCK_FILENAME);\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isLockStale(data: LockData): boolean {\n const age = Date.now() - data.timestamp;\n if (age > LOCK_STALE_MS) return true;\n if (!isProcessAlive(data.pid)) return true;\n return false;\n}\n\nfunction tryRemoveStaleLock(lockPath: string): boolean {\n try {\n const raw = fs.readFileSync(lockPath, \"utf-8\");\n const data: LockData = JSON.parse(raw);\n if (isLockStale(data)) {\n fs.unlinkSync(lockPath);\n return true;\n }\n throw new LockConflictError(data.pid);\n } catch (err) {\n if (err instanceof LockConflictError) throw err;\n // File disappeared or is unreadable — try to acquire\n try { fs.unlinkSync(lockPath); } catch { /* ignore */ }\n return true;\n }\n}\n\nexport function acquireLock(cwd: string): LockHandle {\n const lockPath = getLockPath(cwd);\n const lockData: LockData = {\n pid: process.pid,\n timestamp: Date.now(),\n hostname: os.hostname(),\n };\n const content = JSON.stringify(lockData, null, 2);\n\n try {\n fs.writeFileSync(lockPath, content, { flag: \"wx\" });\n } catch (err: unknown) {\n const fsErr = err as NodeJS.ErrnoException;\n if (fsErr.code === \"EEXIST\") {\n tryRemoveStaleLock(lockPath);\n // Retry once after stale removal — wrap in try/catch for TOCTOU race\n try {\n fs.writeFileSync(lockPath, content, { flag: \"wx\" });\n } catch (retryErr: unknown) {\n const retryFsErr = retryErr as NodeJS.ErrnoException;\n if (retryFsErr.code === \"EEXIST\") {\n // Another process won the race\n throw new LockConflictError(0);\n }\n throw retryErr;\n }\n } else {\n throw err;\n }\n }\n\n // Signal handlers — stored for removal in release()\n const onExit = (): void => {\n try { fs.unlinkSync(lockPath); } catch { /* ignore */ }\n };\n\n process.on(\"exit\", onExit);\n process.on(\"SIGINT\", onExit);\n process.on(\"SIGTERM\", onExit);\n\n const release = (): void => {\n // Remove signal handlers first to prevent double-cleanup\n process.removeListener(\"exit\", onExit);\n process.removeListener(\"SIGINT\", onExit);\n process.removeListener(\"SIGTERM\", onExit);\n try { fs.unlinkSync(lockPath); } catch { /* ignore */ }\n };\n\n return { release };\n}\n","import { acquireLock, type LockHandle } from \"../lock/lock-file.js\";\n\nexport function checkLock(cwd: string): LockHandle {\n return acquireLock(cwd);\n}\n","import { execFileSync } from \"node:child_process\";\n\nexport interface GitCheckResult {\n readonly isGitRepo: boolean;\n}\n\nexport function checkGit(cwd: string): GitCheckResult {\n try {\n execFileSync(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"], {\n cwd,\n stdio: \"pipe\",\n timeout: 5_000,\n });\n return { isGitRepo: true };\n } catch {\n return { isGitRepo: false };\n }\n}\n","import type { LockHandle } from \"../lock/lock-file.js\";\nimport { NotGitRepoError } from \"../errors/errors.js\";\nimport { checkRecursion } from \"./check-recursion.js\";\nimport { checkBinary } from \"./check-binary.js\";\nimport { checkAuth } from \"./check-auth.js\";\nimport { checkLock } from \"./check-lock.js\";\nimport { checkGit } from \"./check-git.js\";\n\nexport interface PreflightOptions {\n readonly cwd: string;\n readonly requireGit: boolean;\n readonly skipAuth?: boolean;\n readonly skipLock?: boolean;\n}\n\nexport interface PreflightResult {\n readonly lockHandle: LockHandle | null;\n}\n\nexport async function runPreflight(\n options: PreflightOptions,\n): Promise<PreflightResult> {\n // Order: cheapest checks first (fail-fast)\n // 1. Recursion (env read — instant)\n checkRecursion();\n\n // 2. Binary exists (filesystem lookup)\n await checkBinary();\n\n // 3. Auth valid (spawns a quick process)\n // Skipped on Windows: execFile auth check fails due to PowerShell profile\n // errors causing false AuthExpiredError. The real execCodex handles auth.\n if (!options.skipAuth && process.platform !== \"win32\") {\n await checkAuth();\n }\n\n // 4. Lock file (filesystem write)\n let lockHandle: LockHandle | null = null;\n if (!options.skipLock) {\n lockHandle = checkLock(options.cwd);\n }\n\n // 5. Git repo (if required)\n if (options.requireGit) {\n const { isGitRepo } = checkGit(options.cwd);\n if (!isGitRepo) {\n lockHandle?.release();\n throw new NotGitRepoError(options.cwd);\n }\n }\n\n return { lockHandle };\n}\n","import { spawn } from \"node:child_process\";\nimport { StringDecoder } from \"node:string_decoder\";\nimport {\n BRIDGE_DEPTH_ENV,\n DEFAULT_TIMEOUT_MS,\n TIMEOUT_ENV,\n HEARTBEAT_INTERVAL_MS,\n} from \"../config/constants.js\";\nimport { getNextDepth } from \"../guards/check-recursion.js\";\nimport { getCachedBinaryPath } from \"../guards/check-binary.js\";\nimport { getSandboxConfigArgs } from \"./sandbox-args.js\";\nimport { setupTimeout } from \"./timeout.js\";\nimport { parseCodexOutput, type CodexResult } from \"./output-parser.js\";\nimport { formatProgressMessage } from \"./progress.js\";\nimport { createLiveLogger } from \"../util/live-logger.js\";\nimport {\n BridgeError,\n CliNotFoundError,\n AuthExpiredError,\n RateLimitError,\n ServerError,\n NetworkError,\n} from \"../errors/errors.js\";\n\nexport interface ExecParams {\n readonly prompt: string;\n readonly cwd: string;\n readonly mode: \"exec\" | \"full-auto\";\n readonly sandbox?: \"read-only\" | \"workspace-write\" | \"danger-full-access\";\n readonly sessionId?: string;\n readonly model?: string;\n readonly reasoningEffort?: \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n readonly review?: boolean;\n readonly reviewBase?: string;\n readonly reviewCommit?: string;\n readonly timeoutMs?: number;\n /**\n * Optional live-progress sink. Called with a short status line each time\n * Codex emits a meaningful JSONL event, plus a periodic heartbeat during\n * quiet stretches. Used to drive MCP progress notifications so a long run\n * doesn't look frozen. Best-effort — callbacks must not throw.\n */\n readonly onProgress?: (message: string) => void;\n}\n\nfunction getTimeout(override?: number): number {\n if (override !== undefined) return override;\n const envVal = process.env[TIMEOUT_ENV];\n if (envVal) {\n const parsed = parseInt(envVal, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n return DEFAULT_TIMEOUT_MS;\n}\n\nfunction classifyError(exitCode: number, stderr: string): BridgeError {\n const lower = stderr.toLowerCase();\n\n // Check auth errors first but exclude generic \"auth\" in context\n if (lower.includes(\"unauthorized\") || lower.includes(\"401\") || lower.includes(\"api key\")) {\n return new AuthExpiredError();\n }\n if (lower.includes(\"rate limit\") || lower.includes(\"429\") || lower.includes(\"too many requests\")) {\n return new RateLimitError();\n }\n if ([\"500\", \"502\", \"503\", \"504\", \"internal server error\", \"bad gateway\", \"service unavailable\"].some((p) => lower.includes(p))) {\n return new ServerError(stderr.slice(0, 200));\n }\n if ([\"econnreset\", \"econnrefused\", \"etimedout\", \"network error\", \"fetch failed\", \"socket hang up\"].some((p) => lower.includes(p))) {\n return new NetworkError(stderr.slice(0, 200));\n }\n\n return new BridgeError(\n `Codex exited with code ${exitCode}: ${stderr.slice(0, 300)}`,\n \"EXEC_FAILED\",\n false,\n );\n}\n\nexport async function execCodex(params: ExecParams): Promise<CodexResult> {\n // Use cached binary path from checkBinary — throws if not found\n const codexPath = getCachedBinaryPath();\n if (codexPath === null) {\n throw new CliNotFoundError();\n }\n\n return new Promise((resolve, reject) => {\n const timeoutMs = getTimeout(params.timeoutMs);\n let args: string[];\n // Whether to send the prompt over stdin (the `-` sentinel). For native\n // review, the codex CLI forbids combining a scope flag\n // (--uncommitted/--base/--commit) with a PROMPT, so we only pass the prompt\n // when reviewing with custom instructions and no scope flag.\n let sendStdinPrompt: boolean;\n if (params.review) {\n args = [\"exec\", \"review\", \"--json\", \"--skip-git-repo-check\"];\n if (params.reviewBase) {\n args.push(\"--base\", params.reviewBase);\n sendStdinPrompt = false;\n } else if (params.reviewCommit) {\n args.push(\"--commit\", params.reviewCommit);\n sendStdinPrompt = false;\n } else if (params.prompt?.trim()) {\n // Custom review instructions only — review defaults to the working tree.\n sendStdinPrompt = true;\n } else {\n args.push(\"--uncommitted\");\n sendStdinPrompt = false;\n }\n } else if (params.sessionId) {\n // Resume keeps the original session's sandbox policy; `resume` has no --sandbox flag.\n args = [\"exec\", \"resume\", params.sessionId, \"--json\", \"--skip-git-repo-check\"];\n sendStdinPrompt = true;\n } else {\n const sandbox =\n params.sandbox ?? (params.mode === \"full-auto\" ? \"workspace-write\" : \"read-only\");\n args = [\"exec\", \"--json\", \"--skip-git-repo-check\", \"--sandbox\", sandbox];\n sendStdinPrompt = true;\n }\n\n if (params.model) {\n args.push(\"-m\", params.model);\n }\n\n if (params.reasoningEffort) {\n args.push(\"-c\", `model_reasoning_effort=${params.reasoningEffort}`);\n }\n\n // Platform-specific sandbox config (e.g. windows.sandbox=unelevated to work\n // around Codex's broken elevated Windows sandbox). Empty on non-Windows.\n args.push(...getSandboxConfigArgs());\n\n // Prompt passed via stdin to avoid shell injection — NOT as a positional arg\n const stdinPrompt = params.prompt ?? \"\";\n\n // Use \"-\" to tell codex to read the prompt from stdin. Omitted for review\n // runs that use a scope flag, where the CLI rejects a PROMPT.\n if (sendStdinPrompt) {\n args.push(\"-\");\n }\n\n const env = {\n ...process.env,\n [BRIDGE_DEPTH_ENV]: String(getNextDepth()),\n };\n\n // On Windows, npm-installed CLIs are .cmd shims that require a shell to execute.\n const child = spawn(codexPath, args, {\n cwd: params.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n shell: process.platform === \"win32\",\n windowsHide: true,\n });\n\n const { clear: clearTimeout_, promise: timeoutPromise } = setupTimeout(child, timeoutMs);\n\n const startedAt = Date.now();\n\n // Persistent, tail-able per-run log (recovers progress the transport buffers).\n const logger = createLiveLogger({\n cwd: params.cwd,\n mode: params.mode,\n prompt: params.prompt,\n });\n process.stderr.write(`[skill-codex] live log: ${logger.path}\\n`);\n\n // Heartbeat so quiet reasoning stretches still show the run is alive.\n let heartbeat: ReturnType<typeof setInterval> | null = null;\n if (params.onProgress) {\n heartbeat = setInterval(() => {\n const secs = Math.round((Date.now() - startedAt) / 1000);\n params.onProgress?.(`Codex working… ${secs}s elapsed`);\n }, HEARTBEAT_INTERVAL_MS);\n if (typeof heartbeat.unref === \"function\") heartbeat.unref();\n }\n const stopHeartbeat = (): void => {\n if (heartbeat) {\n clearInterval(heartbeat);\n heartbeat = null;\n }\n };\n\n // Incrementally decode stdout: feed the file logger, and emit a progress\n // message per complete JSONL line.\n const decoder = new StringDecoder(\"utf8\");\n let progressBuf = \"\";\n const consumeForProgress = (text: string): void => {\n if (!params.onProgress) return;\n progressBuf += text;\n let idx: number;\n while ((idx = progressBuf.indexOf(\"\\n\")) >= 0) {\n const lineStr = progressBuf.slice(0, idx).trim();\n progressBuf = progressBuf.slice(idx + 1);\n if (!lineStr) continue;\n try {\n const msg = formatProgressMessage(JSON.parse(lineStr));\n if (msg) params.onProgress(msg);\n } catch {\n // non-JSON line — ignore\n }\n }\n };\n\n let logFinished = false;\n const finishLog = (summary: string): void => {\n stopHeartbeat();\n if (logFinished) return;\n logFinished = true;\n try {\n logger.write(decoder.end());\n logger.finish(summary);\n } catch {\n // best-effort\n }\n };\n\n const stdoutChunks: Buffer[] = [];\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n const text = decoder.write(chunk);\n try {\n logger.write(text);\n } catch {\n // best-effort logging\n }\n consumeForProgress(text);\n });\n\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n // Write prompt via stdin then close — safe from shell injection. Skipped\n // for review-with-scope runs that don't pass `-` (the CLI rejects a PROMPT).\n if (sendStdinPrompt) {\n child.stdin?.write(stdinPrompt);\n }\n child.stdin?.end();\n\n const onClose = (exitCode: number | null): void => {\n clearTimeout_();\n finishLog(exitCode === 0 || exitCode === null ? \"ok\" : `exit ${exitCode}`);\n const stdout = Buffer.concat(stdoutChunks).toString();\n\n if (exitCode === 0 || exitCode === null) {\n try {\n const result = parseCodexOutput(stdout);\n resolve({ ...result, logPath: logger.path, durationMs: Date.now() - startedAt });\n } catch (err) {\n reject(err);\n }\n return;\n }\n\n reject(classifyError(exitCode, stderr));\n };\n\n child.on(\"close\", onClose);\n\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n clearTimeout_();\n finishLog(\"spawn error\");\n if (err.code === \"ENOENT\") {\n reject(new CliNotFoundError());\n } else {\n reject(new BridgeError(`Failed to spawn codex: ${err.message}`, \"SPAWN_ERROR\", false));\n }\n });\n\n // Race with timeout\n timeoutPromise.catch((err) => {\n finishLog(\"timeout\");\n reject(err);\n });\n });\n}\n","import type { ChildProcess } from \"node:child_process\";\nimport { KILL_GRACE_MS } from \"../config/constants.js\";\nimport { TimeoutError } from \"../errors/errors.js\";\nimport { isWindows } from \"../util/platform.js\";\n\nexport function setupTimeout(\n child: ChildProcess,\n timeoutMs: number,\n): { clear: () => void; promise: Promise<never> } {\n let timer: ReturnType<typeof setTimeout> | null = null;\n let graceTimer: ReturnType<typeof setTimeout> | null = null;\n\n const promise = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n if (isWindows()) {\n // On Windows, SIGTERM is silently ignored by Node.js — it maps to\n // TerminateProcess regardless of signal name. Call kill() with no\n // argument so the intent is explicit and no grace timer is needed.\n child.kill();\n } else {\n // Phase 1: graceful kill\n child.kill(\"SIGTERM\");\n\n // Phase 2: force kill after grace period\n graceTimer = setTimeout(() => {\n try {\n if (!child.killed) {\n child.kill(\"SIGKILL\");\n }\n } catch {\n // Process may already be gone — ignore\n }\n }, KILL_GRACE_MS);\n }\n\n reject(new TimeoutError(timeoutMs));\n }, timeoutMs);\n });\n\n const clear = (): void => {\n if (timer) clearTimeout(timer);\n if (graceTimer) clearTimeout(graceTimer);\n };\n\n return { clear, promise };\n}\n","import { MAX_RESPONSE_CHARS } from \"../config/constants.js\";\n\nexport function truncateResponse(\n text: string,\n maxChars: number = MAX_RESPONSE_CHARS,\n): string {\n if (text.length <= maxChars) return text;\n\n const omitted = text.length - maxChars;\n return (\n text.slice(0, maxChars) +\n `\\n\\n[Response truncated at ${maxChars} characters. ${omitted} characters omitted.]`\n );\n}\n","import { EmptyOutputError } from \"../errors/errors.js\";\nimport { truncateResponse } from \"../util/truncate.js\";\n\nexport interface ActivityEntry {\n readonly type: \"exec\" | \"read\" | \"write\";\n readonly command?: string;\n readonly path?: string;\n readonly icon: string;\n readonly status: string;\n}\n\nexport interface TokenUsage {\n readonly input_tokens: number;\n readonly cached_input_tokens: number;\n readonly output_tokens: number;\n readonly reasoning_output_tokens: number;\n}\n\nexport interface CodexResult {\n readonly content: string;\n readonly activity: ActivityEntry[];\n readonly usage: TokenUsage | null;\n readonly raw: string;\n readonly sessionId?: string;\n /** Path to the live run log, attached by execCodex. */\n readonly logPath?: string;\n /** Wall-clock duration of the Codex run in ms, attached by execCodex. */\n readonly durationMs?: number;\n}\n\nexport function parseCodexOutput(raw: string): CodexResult {\n if (!raw.trim()) {\n throw new EmptyOutputError();\n }\n\n const lines = raw.split(\"\\n\").filter((line) => line.trim());\n const messages: string[] = [];\n const activity: ActivityEntry[] = [];\n let resultContent: string | null = null;\n let sessionId: string | undefined;\n let usage: TokenUsage | null = null;\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\n\n if (parsed.type === \"thread.started\" && typeof parsed.thread_id === \"string\") {\n sessionId = parsed.thread_id;\n continue;\n }\n\n // Extract token usage from turn.completed events\n if (parsed.type === \"turn.completed\" && parsed.usage) {\n usage = {\n input_tokens: parsed.usage.input_tokens ?? 0,\n cached_input_tokens: parsed.usage.cached_input_tokens ?? 0,\n output_tokens: parsed.usage.output_tokens ?? 0,\n reasoning_output_tokens: parsed.usage.reasoning_output_tokens ?? 0,\n };\n continue;\n }\n\n // Handle result type — takes priority over all other messages\n if (parsed.type === \"result\" && typeof parsed.content === \"string\") {\n resultContent = parsed.content;\n continue;\n }\n\n // Handle standard event format\n if (parsed.type === \"message\" && typeof parsed.content === \"string\") {\n messages.push(parsed.content);\n continue;\n }\n\n // Track command executions\n if (parsed.item?.type === \"command_execution\") {\n const cmd = parsed.item;\n const shortCmd =\n cmd.command?.length > 80\n ? cmd.command.slice(0, 77) + \"...\"\n : cmd.command;\n const statusIcon =\n cmd.status === \"declined\"\n ? \"\\u2718\"\n : cmd.exit_code === 0\n ? \"\\u2714\"\n : cmd.exit_code !== null\n ? \"\\u2718\"\n : \"\\u25B6\";\n const statusLabel =\n cmd.status === \"declined\"\n ? \"blocked\"\n : cmd.status === \"in_progress\"\n ? \"running\"\n : cmd.exit_code === 0\n ? \"ok\"\n : `exit ${cmd.exit_code}`;\n // Only record completed/declined events, not in_progress starts\n if (cmd.status !== \"in_progress\") {\n activity.push({\n type: \"exec\",\n command: shortCmd,\n icon: statusIcon,\n status: statusLabel,\n });\n }\n continue;\n }\n\n // Handle nested item format (Codex JSONL). The current schema emits the\n // final text on `item.completed`; skip `item.started`/`item.updated`\n // partials so streamed chunks aren't double-counted.\n if (\n parsed.item?.type === \"agent_message\" &&\n typeof parsed.item.text === \"string\" &&\n parsed.type !== \"item.started\" &&\n parsed.type !== \"item.updated\"\n ) {\n messages.push(parsed.item.text);\n continue;\n }\n\n // Handle flat legacy format\n if (parsed.itemType === \"agent_message\" && typeof parsed.text === \"string\") {\n messages.push(parsed.text);\n continue;\n }\n\n // Track file reads\n if (parsed.item?.type === \"file_read\") {\n activity.push({\n type: \"read\",\n path: parsed.item.path || \"file\",\n icon: \"\\u25B6\",\n status: \"read\",\n });\n continue;\n }\n\n // Track file writes/edits (legacy item types, retained for back-compat)\n if (parsed.item?.type === \"file_write\" || parsed.item?.type === \"file_edit\") {\n activity.push({\n type: \"write\",\n path: parsed.item.path || \"file\",\n icon: \"\\u270E\",\n status: \"write\",\n });\n continue;\n }\n\n // Current schema collapses file activity into a single `file_change` item.\n // It may carry a top-level `path` or a `changes` array of { path, kind }.\n if (parsed.item?.type === \"file_change\") {\n const changes = Array.isArray(parsed.item.changes) ? parsed.item.changes : null;\n if (changes && changes.length > 0) {\n for (const change of changes) {\n activity.push({\n type: \"write\",\n path: change?.path || \"file\",\n icon: \"\\u270E\",\n status: change?.kind || \"write\",\n });\n }\n } else {\n activity.push({\n type: \"write\",\n path: parsed.item.path || \"file\",\n icon: \"\\u270E\",\n status: \"write\",\n });\n }\n continue;\n }\n } catch {\n // Non-JSON line — could be preamble or status output. Skip.\n }\n }\n\n let agentMessage: string;\n\n if (resultContent !== null) {\n agentMessage = resultContent;\n } else if (messages.length > 0) {\n agentMessage = messages.join(\"\\n\\n\");\n } else {\n // If no structured output found, use the raw text (minus any obvious preamble)\n const substantiveLines = lines.filter(\n (line) =>\n !line.startsWith(\"OpenAI Codex\") &&\n !line.startsWith(\"---\") &&\n !line.startsWith(\"tokens used\"),\n );\n agentMessage = substantiveLines.join(\"\\n\").trim();\n }\n\n if (!agentMessage) {\n throw new EmptyOutputError();\n }\n\n return {\n content: truncateResponse(agentMessage),\n activity,\n usage,\n raw,\n sessionId,\n };\n}\n","/**\n * Collapse all whitespace runs to single spaces, trim, and truncate to `max`\n * characters with an ellipsis. Shared by the live file logger and the MCP\n * progress formatter so a single codex event renders consistently in both.\n */\nexport function oneLine(text: string, max: number): string {\n const collapsed = text.replace(/\\s+/g, \" \").trim();\n return collapsed.length > max ? collapsed.slice(0, max - 1) + \"…\" : collapsed;\n}\n\n/** Last path segment, for compact progress lines. Falls back to the input. */\nexport function baseName(p: string): string {\n if (!p) return \"file\";\n const parts = p.split(/[\\\\/]/).filter(Boolean);\n return parts.length > 0 ? parts[parts.length - 1] : p;\n}\n","import { oneLine, baseName } from \"../util/text.js\";\n\n/**\n * Map a parsed Codex JSONL event to a concise, human-readable status line for\n * MCP `notifications/progress`, or `null` for events that shouldn't surface as\n * progress (turn starts, partial item streams, unknown shapes).\n *\n * Kept pure (no I/O) so it is unit-testable in isolation and reusable by any\n * caller that wants a one-line summary of \"what is Codex doing right now\".\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function formatProgressMessage(evt: any): string | null {\n if (!evt || typeof evt !== \"object\") return null;\n\n const item = evt.item;\n\n if (item?.type === \"command_execution\") {\n const cmd = oneLine(String(item.command ?? \"\"), 60);\n if (item.status === \"in_progress\") return `running: ${cmd}`;\n if (item.status === \"declined\") return `blocked: ${cmd}`;\n if (item.exit_code === 0) return `ran: ${cmd}`;\n return `failed (exit ${String(item.exit_code)}): ${cmd}`;\n }\n\n if (item?.type === \"file_read\") return `reading ${baseName(String(item.path ?? \"file\"))}`;\n\n if (item?.type === \"file_write\" || item?.type === \"file_edit\") {\n return `editing ${baseName(String(item.path ?? \"file\"))}`;\n }\n\n if (item?.type === \"file_change\") {\n const changes = Array.isArray(item.changes) ? item.changes : null;\n if (changes && changes.length > 0) {\n return changes.length === 1\n ? `editing ${baseName(String(changes[0]?.path ?? \"file\"))}`\n : `editing ${changes.length} files`;\n }\n return `editing ${baseName(String(item.path ?? \"file\"))}`;\n }\n\n if (item?.type === \"reasoning\" || evt.type === \"turn.started\") return \"thinking…\";\n\n if (\n item?.type === \"agent_message\" &&\n typeof item.text === \"string\" &&\n evt.type !== \"item.started\" &&\n evt.type !== \"item.updated\"\n ) {\n return \"writing response…\";\n }\n\n return null;\n}\n","import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { LOG_ENV } from \"../config/constants.js\";\nimport { oneLine } from \"./text.js\";\n\nexport interface LiveLoggerOptions {\n readonly cwd: string;\n readonly mode: string;\n readonly prompt: string;\n}\n\nexport interface LiveLogger {\n readonly path: string;\n /** Feed a raw stdout fragment; complete JSONL lines are rendered as they arrive. */\n write(fragment: string): void;\n /** Flush any trailing partial line and write the footer. */\n finish(summary: string): void;\n}\n\n/**\n * Resolve the live-log path:\n * 1. `SKILL_CODEX_LOG` override (absolute path), else\n * 2. a per-workspace file under the OS temp dir — so a run never writes a\n * growing log file into the user's working repo. The filename is the\n * workspace basename plus a short hash of the full path, so the same\n * workspace appends to one tail-able log and distinct workspaces don't\n * collide. The resolved path is printed at run start and returned in the\n * tool response, so it stays discoverable.\n */\nexport function resolveLogPath(cwd: string): string {\n const override = process.env[LOG_ENV];\n if (override && override.trim()) return path.resolve(override.trim());\n const base = path.basename(cwd).replace(/[^a-zA-Z0-9._-]/g, \"_\") || \"run\";\n const hash = createHash(\"sha1\").update(cwd).digest(\"hex\").slice(0, 8);\n return path.join(os.tmpdir(), \"skill-codex\", `${base}-${hash}.log`);\n}\n\n/**\n * Render a parsed Codex JSONL event as zero or more human-readable log lines.\n * Pure (no I/O) so it can be unit-tested in isolation; `createLiveLogger`\n * wraps it with file buffering.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function formatLogLines(evt: any): string[] {\n if (!evt || typeof evt !== \"object\") return [];\n\n const item = evt.item;\n\n if (item?.type === \"command_execution\") {\n if (item.status === \"in_progress\") return [` $ ${oneLine(String(item.command ?? \"\"), 120)}`];\n if (item.status === \"declined\") return [\" ✘ blocked\"];\n if (item.exit_code === 0) return [\" ✔ ok\"];\n return [` ✘ exit ${String(item.exit_code)}`];\n }\n\n if (item?.type === \"file_read\") return [` read ${String(item.path ?? \"file\")}`];\n\n if (item?.type === \"file_write\" || item?.type === \"file_edit\") {\n return [` write ${String(item.path ?? \"file\")}`];\n }\n\n if (item?.type === \"file_change\") {\n const changes = Array.isArray(item.changes) ? item.changes : null;\n if (changes && changes.length > 0) {\n return changes.map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (change: any) => ` write ${String(change?.path ?? \"file\")} (${String(change?.kind ?? \"write\")})`,\n );\n }\n return [` write ${String(item.path ?? \"file\")}`];\n }\n\n if (\n item?.type === \"agent_message\" &&\n typeof item.text === \"string\" &&\n evt.type !== \"item.started\" &&\n evt.type !== \"item.updated\"\n ) {\n return [` msg ${oneLine(item.text, 400)}`];\n }\n\n if (evt.type === \"message\" && typeof evt.content === \"string\") {\n return [` msg ${oneLine(evt.content, 400)}`];\n }\n\n if (evt.type === \"turn.completed\" && evt.usage) {\n const u = evt.usage;\n const reasoning = u.reasoning_output_tokens ?? 0;\n return [\n ` tokens: ${u.input_tokens ?? 0} in → ${u.output_tokens ?? 0} out${reasoning > 0 ? ` (+${reasoning} reasoning)` : \"\"}`,\n ];\n }\n\n return [];\n}\n\n/**\n * Human-readable, append-only log of a single Codex run. Codex emits JSONL on\n * stdout; this tails each event to a file so the user can `tail -f` a run that\n * the MCP transport would otherwise buffer until completion. Best-effort: any\n * filesystem error is swallowed so logging never breaks an actual Codex call.\n */\nexport function createLiveLogger(opts: LiveLoggerOptions): LiveLogger {\n const logPath = resolveLogPath(opts.cwd);\n\n let stream: fs.WriteStream | null = null;\n try {\n fs.mkdirSync(path.dirname(logPath), { recursive: true });\n stream = fs.createWriteStream(logPath, { flags: \"a\" });\n } catch {\n stream = null;\n }\n\n const line = (text: string): void => {\n try {\n stream?.write(text + \"\\n\");\n } catch {\n // best-effort logging — never throw\n }\n };\n\n const startedAt = new Date().toISOString();\n line(\"\");\n line(\"=\".repeat(60));\n line(`> codex ${opts.mode} ${startedAt}`);\n line(` cwd: ${opts.cwd}`);\n line(` task: ${oneLine(opts.prompt, 200)}`);\n line(\"-\".repeat(60));\n\n const handleEvent = (raw: string): void => {\n const trimmed = raw.trim();\n if (!trimmed) return;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let evt: any;\n try {\n evt = JSON.parse(trimmed);\n } catch {\n return; // non-JSON preamble — skip\n }\n for (const l of formatLogLines(evt)) line(l);\n };\n\n let buffer = \"\";\n\n return {\n path: logPath,\n write(fragment: string): void {\n buffer += fragment;\n let idx: number;\n while ((idx = buffer.indexOf(\"\\n\")) >= 0) {\n const lineStr = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 1);\n handleEvent(lineStr);\n }\n },\n finish(summary: string): void {\n if (buffer.trim()) {\n handleEvent(buffer);\n buffer = \"\";\n }\n line(\"-\".repeat(60));\n line(`# done ${new Date().toISOString()} ${summary}`);\n try {\n stream?.end();\n } catch {\n // ignore\n }\n },\n };\n}\n","import { BridgeError } from \"../errors/errors.js\";\nimport { MAX_RETRIES, MAX_RETRIES_ENV, RETRY_DELAYS_MS, RETRY_CAP_MS } from \"../config/constants.js\";\n\nexport interface RetryOptions {\n readonly maxRetries?: number;\n readonly shouldRetry?: (err: Error) => boolean;\n}\n\nfunction getMaxRetries(override?: number): number {\n if (override !== undefined) return override;\n const envVal = process.env[MAX_RETRIES_ENV];\n if (envVal) {\n const parsed = parseInt(envVal, 10);\n if (!isNaN(parsed) && parsed >= 0) return parsed;\n }\n return MAX_RETRIES;\n}\n\nfunction getDelay(attempt: number): number {\n const base = RETRY_DELAYS_MS[attempt] ?? RETRY_CAP_MS;\n const capped = Math.min(base, RETRY_CAP_MS);\n // Add jitter: 50-150% of base delay\n const jitter = 0.5 + Math.random();\n return Math.round(capped * jitter);\n}\n\nfunction defaultShouldRetry(err: Error): boolean {\n return err instanceof BridgeError && err.retryable;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const maxRetries = getMaxRetries(options.maxRetries);\n const shouldRetry = options.shouldRetry ?? defaultShouldRetry;\n\n for (let attempt = 0; ; attempt++) {\n try {\n return await fn();\n } catch (err) {\n const isRetryable = err instanceof Error && shouldRetry(err);\n if (attempt < maxRetries && isRetryable) {\n const delay = getDelay(attempt);\n const errorName = err instanceof Error ? err.constructor.name : \"UnknownError\";\n process.stderr.write(\n `[skill-codex] ${errorName} (attempt ${attempt + 1}/${maxRetries}), retrying in ${delay}ms...\\n`,\n );\n await sleep(delay);\n continue;\n }\n throw err;\n }\n }\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","path","path","path","path","fs","fs","path","path","fs","fs","path","path","fs","command","fs","path","path","fs","fs","path","fs","path","fs","path","fs","path","which","which","fs","path","os","path","fs","os","fs","os","path","path","os","fs","args","path","fs","path","fs"]}
|