skill-codex 0.2.0 → 0.3.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/README.md +8 -5
- package/dist/index.js +76 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# skill-codex
|
|
2
2
|
|
|
3
|
-

|
|
3
|
+
[](https://www.npmjs.com/package/skill-codex)
|
|
4
|
+
[](https://www.npmjs.com/package/skill-codex)
|
|
4
5
|

|
|
5
6
|

|
|
6
7
|

|
|
@@ -31,12 +32,14 @@ Claude Code and Codex CLI have different strengths. Claude excels at reasoning,
|
|
|
31
32
|
## Quick Start
|
|
32
33
|
|
|
33
34
|
```shell
|
|
34
|
-
#
|
|
35
|
+
# Option A: Run directly (no global install)
|
|
35
36
|
npx skill-codex setup
|
|
36
37
|
|
|
37
|
-
#
|
|
38
|
+
# Option B: Install globally, then setup
|
|
39
|
+
npm i -g skill-codex
|
|
40
|
+
skill-codex setup
|
|
38
41
|
|
|
39
|
-
#
|
|
42
|
+
# Restart Claude Code to load the MCP server, then use:
|
|
40
43
|
/codex-review # Review uncommitted changes
|
|
41
44
|
/codex-do "write tests" # Delegate a task to Codex
|
|
42
45
|
/codex-consult "approach?" # Get a second opinion
|
|
@@ -115,7 +118,7 @@ Environment variables (all optional):
|
|
|
115
118
|
| Auth expired | Advises `codex login`, no retry |
|
|
116
119
|
| Network down | Retries 3x with exponential backoff |
|
|
117
120
|
| Rate limited (429) | Retries with backoff + jitter |
|
|
118
|
-
| Codex hangs | Killed after timeout (SIGTERM
|
|
121
|
+
| Codex hangs | Killed after timeout (SIGTERM+SIGKILL on Unix, immediate kill on Windows) |
|
|
119
122
|
| Concurrent runs | Lock file prevents conflicts (stale after 15min) |
|
|
120
123
|
| Recursive calls | `SKILL_CODEX_DEPTH` limit prevents infinite loops |
|
|
121
124
|
| Trivial changes | Smart filter skips auto-review |
|
package/dist/index.js
CHANGED
|
@@ -184,7 +184,7 @@ async function checkAuth() {
|
|
|
184
184
|
const child = execFile(
|
|
185
185
|
binary,
|
|
186
186
|
["exec", "--sandbox", "read-only", "--skip-git-repo-check", "--ephemeral", "echo ok"],
|
|
187
|
-
{ timeout:
|
|
187
|
+
{ timeout: 3e4, shell: process.platform === "win32" },
|
|
188
188
|
(error, _stdout, stderr) => {
|
|
189
189
|
if (!error) {
|
|
190
190
|
authCachedAt = Date.now();
|
|
@@ -322,7 +322,7 @@ function checkGit(cwd) {
|
|
|
322
322
|
async function runPreflight(options) {
|
|
323
323
|
checkRecursion();
|
|
324
324
|
await checkBinary();
|
|
325
|
-
if (!options.skipAuth) {
|
|
325
|
+
if (!options.skipAuth && process.platform !== "win32") {
|
|
326
326
|
await checkAuth();
|
|
327
327
|
}
|
|
328
328
|
let lockHandle = null;
|
|
@@ -399,10 +399,20 @@ function parseCodexOutput(raw) {
|
|
|
399
399
|
}
|
|
400
400
|
const lines = raw.split("\n").filter((line) => line.trim());
|
|
401
401
|
const messages = [];
|
|
402
|
+
const activity = [];
|
|
402
403
|
let resultContent = null;
|
|
404
|
+
let usage = null;
|
|
403
405
|
for (const line of lines) {
|
|
404
406
|
try {
|
|
405
407
|
const parsed = JSON.parse(line);
|
|
408
|
+
if (parsed.type === "turn.completed" && parsed.usage) {
|
|
409
|
+
usage = {
|
|
410
|
+
input_tokens: parsed.usage.input_tokens ?? 0,
|
|
411
|
+
cached_input_tokens: parsed.usage.cached_input_tokens ?? 0,
|
|
412
|
+
output_tokens: parsed.usage.output_tokens ?? 0
|
|
413
|
+
};
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
406
416
|
if (parsed.type === "result" && typeof parsed.content === "string") {
|
|
407
417
|
resultContent = parsed.content;
|
|
408
418
|
continue;
|
|
@@ -411,6 +421,21 @@ function parseCodexOutput(raw) {
|
|
|
411
421
|
messages.push(parsed.content);
|
|
412
422
|
continue;
|
|
413
423
|
}
|
|
424
|
+
if (parsed.item?.type === "command_execution") {
|
|
425
|
+
const cmd = parsed.item;
|
|
426
|
+
const shortCmd = cmd.command?.length > 80 ? cmd.command.slice(0, 77) + "..." : cmd.command;
|
|
427
|
+
const statusIcon = cmd.status === "declined" ? "\u2718" : cmd.exit_code === 0 ? "\u2714" : cmd.exit_code !== null ? "\u2718" : "\u25B6";
|
|
428
|
+
const statusLabel = cmd.status === "declined" ? "blocked" : cmd.status === "in_progress" ? "running" : cmd.exit_code === 0 ? "ok" : `exit ${cmd.exit_code}`;
|
|
429
|
+
if (cmd.status !== "in_progress") {
|
|
430
|
+
activity.push({
|
|
431
|
+
type: "exec",
|
|
432
|
+
command: shortCmd,
|
|
433
|
+
icon: statusIcon,
|
|
434
|
+
status: statusLabel
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
414
439
|
if (parsed.item?.type === "agent_message" && typeof parsed.item.text === "string") {
|
|
415
440
|
messages.push(parsed.item.text);
|
|
416
441
|
continue;
|
|
@@ -419,6 +444,24 @@ function parseCodexOutput(raw) {
|
|
|
419
444
|
messages.push(parsed.text);
|
|
420
445
|
continue;
|
|
421
446
|
}
|
|
447
|
+
if (parsed.item?.type === "file_read") {
|
|
448
|
+
activity.push({
|
|
449
|
+
type: "read",
|
|
450
|
+
path: parsed.item.path || "file",
|
|
451
|
+
icon: "\u25B6",
|
|
452
|
+
status: "read"
|
|
453
|
+
});
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (parsed.item?.type === "file_write" || parsed.item?.type === "file_edit") {
|
|
457
|
+
activity.push({
|
|
458
|
+
type: "write",
|
|
459
|
+
path: parsed.item.path || "file",
|
|
460
|
+
icon: "\u270E",
|
|
461
|
+
status: "write"
|
|
462
|
+
});
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
422
465
|
} catch {
|
|
423
466
|
}
|
|
424
467
|
}
|
|
@@ -438,6 +481,8 @@ function parseCodexOutput(raw) {
|
|
|
438
481
|
}
|
|
439
482
|
return {
|
|
440
483
|
content: truncateResponse(agentMessage),
|
|
484
|
+
activity,
|
|
485
|
+
usage,
|
|
441
486
|
raw
|
|
442
487
|
};
|
|
443
488
|
}
|
|
@@ -495,7 +540,7 @@ async function execCodex(params) {
|
|
|
495
540
|
cwd: params.cwd,
|
|
496
541
|
env,
|
|
497
542
|
stdio: ["pipe", "pipe", "pipe"],
|
|
498
|
-
shell:
|
|
543
|
+
shell: process.platform === "win32",
|
|
499
544
|
windowsHide: true
|
|
500
545
|
});
|
|
501
546
|
const { clear: clearTimeout_, promise: timeoutPromise } = setupTimeout(child, timeoutMs);
|
|
@@ -602,6 +647,32 @@ function formatError(err) {
|
|
|
602
647
|
}
|
|
603
648
|
return `[skill-codex error] Unknown error: ${String(err)}`;
|
|
604
649
|
}
|
|
650
|
+
function formatRichResponse(result, input, cwd) {
|
|
651
|
+
const lines = [];
|
|
652
|
+
const modeLabel = input.mode === "full-auto" ? "full-auto" : "read-only";
|
|
653
|
+
const metaParts = [modeLabel, cwd];
|
|
654
|
+
if (result.usage) {
|
|
655
|
+
const { input_tokens: inp, output_tokens: out, cached_input_tokens: cached } = result.usage;
|
|
656
|
+
metaParts.push(
|
|
657
|
+
`${inp} tok in${cached > 0 ? ` (${cached} cached)` : ""} \u2192 ${out} out`
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
lines.push(`[${metaParts.join(" \u2502 ")}]`);
|
|
661
|
+
if (result.activity.length > 0) {
|
|
662
|
+
for (const a of result.activity) {
|
|
663
|
+
if (a.type === "exec") {
|
|
664
|
+
lines.push(` ${a.icon} exec: ${a.command} (${a.status})`);
|
|
665
|
+
} else if (a.type === "read") {
|
|
666
|
+
lines.push(` \u25B6 read: ${a.path}`);
|
|
667
|
+
} else if (a.type === "write") {
|
|
668
|
+
lines.push(` \u270E write: ${a.path}`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
lines.push("");
|
|
673
|
+
lines.push(result.content);
|
|
674
|
+
return lines.join("\n");
|
|
675
|
+
}
|
|
605
676
|
async function handleCodexExec(input, serverCwd) {
|
|
606
677
|
const rawCwd = input.cwd ?? serverCwd;
|
|
607
678
|
const cwd = path3.resolve(rawCwd);
|
|
@@ -626,8 +697,9 @@ async function handleCodexExec(input, serverCwd) {
|
|
|
626
697
|
timeoutMs: input.timeoutMs
|
|
627
698
|
})
|
|
628
699
|
);
|
|
700
|
+
const formatted = formatRichResponse(result, input, cwd);
|
|
629
701
|
return {
|
|
630
|
-
content: [{ type: "text", text:
|
|
702
|
+
content: [{ type: "text", text: formatted }]
|
|
631
703
|
};
|
|
632
704
|
} catch (err) {
|
|
633
705
|
return {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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/lock/lock-file.ts","../src/guards/check-lock.ts","../src/guards/check-git.ts","../src/guards/preflight.ts","../src/runner/exec-runner.ts","../src/util/platform.ts","../src/runner/timeout.ts","../src/util/truncate.ts","../src/runner/output-parser.ts","../src/runner/retry.ts","../src/index.ts"],"sourcesContent":["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 { TOOL_NAME, TOOL_DESCRIPTION, inputSchema, handleCodexExec } from \"./tools/codex-exec.js\";\n\nexport function createServer(cwd: string): Server {\n const server = new Server(\n { name: \"skill-codex\", version: \"0.2.0\" },\n { capabilities: { tools: {} } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: TOOL_NAME,\n description: TOOL_DESCRIPTION,\n inputSchema: {\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 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: [\"prompt\"],\n },\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\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 return handleCodexExec(parsed.data, cwd);\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\";\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().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 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\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\nexport async function handleCodexExec(\n input: CodexExecInput,\n serverCwd: string,\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 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 timeoutMs: input.timeoutMs,\n }),\n );\n\n return {\n content: [{ type: \"text\", text: result.content }],\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 = 600_000; // 10 minutes\nexport const TIMEOUT_ENV = \"SKILL_CODEX_TIMEOUT_MS\";\nexport const KILL_GRACE_MS = 5_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\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\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\";\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\", \"--skip-git-repo-check\", \"--ephemeral\", \"echo ok\"],\n { timeout: 15_000 },\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 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 if (!options.skipAuth) {\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 { BRIDGE_DEPTH_ENV, DEFAULT_TIMEOUT_MS, TIMEOUT_ENV } from \"../config/constants.js\";\nimport { getNextDepth } from \"../guards/check-recursion.js\";\nimport { getCachedBinaryPath } from \"../guards/check-binary.js\";\nimport { setupTimeout } from \"./timeout.js\";\nimport { parseCodexOutput, type CodexResult } from \"./output-parser.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 timeoutMs?: number;\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 const args: string[] = [\"exec\", \"--json\", \"--skip-git-repo-check\"];\n\n if (params.mode === \"full-auto\") {\n args.push(\"--full-auto\");\n } else {\n args.push(\"--sandbox\", \"read-only\");\n }\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 prompt from stdin\n args.push(\"-\");\n\n const env = {\n ...process.env,\n [BRIDGE_DEPTH_ENV]: String(getNextDepth()),\n };\n\n // shell: false — codexPath is the resolved absolute path, no shell resolution needed\n const child = spawn(codexPath, args, {\n cwd: params.cwd,\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n shell: false,\n windowsHide: true,\n });\n\n const { clear: clearTimeout_, promise: timeoutPromise } = setupTimeout(child, timeoutMs);\n\n const stdoutChunks: Buffer[] = [];\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk);\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\n child.stdin?.write(stdinPrompt);\n child.stdin?.end();\n\n const onClose = (exitCode: number | null): void => {\n clearTimeout_();\n const stdout = Buffer.concat(stdoutChunks).toString();\n\n if (exitCode === 0 || exitCode === null) {\n try {\n const result = parseCodexOutput(stdout);\n resolve(result);\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 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 reject(err);\n });\n });\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 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 CodexResult {\n readonly content: string;\n readonly raw: string;\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 let resultContent: string | null = null;\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\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 // Handle nested item format (Codex JSONL)\n if (parsed.item?.type === \"agent_message\" && typeof parsed.item.text === \"string\") {\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 } 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) => !line.startsWith(\"OpenAI Codex\") && !line.startsWith(\"---\") && !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 raw,\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","import { startServer } from \"./server.js\";\n\nstartServer().catch((err) => {\n process.stderr.write(`[skill-codex] Fatal: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","os","path","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../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/lock/lock-file.ts","../src/guards/check-lock.ts","../src/guards/check-git.ts","../src/guards/preflight.ts","../src/runner/exec-runner.ts","../src/util/platform.ts","../src/runner/timeout.ts","../src/util/truncate.ts","../src/runner/output-parser.ts","../src/runner/retry.ts","../src/index.ts"],"sourcesContent":["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 { TOOL_NAME, TOOL_DESCRIPTION, inputSchema, handleCodexExec } from \"./tools/codex-exec.js\";\n\nexport function createServer(cwd: string): Server {\n const server = new Server(\n { name: \"skill-codex\", version: \"0.2.0\" },\n { capabilities: { tools: {} } },\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: TOOL_NAME,\n description: TOOL_DESCRIPTION,\n inputSchema: {\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 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: [\"prompt\"],\n },\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\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 return handleCodexExec(parsed.data, cwd);\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().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 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\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 const modeLabel = input.mode === \"full-auto\" ? \"full-auto\" : \"read-only\";\n const metaParts: string[] = [modeLabel, cwd];\n\n if (result.usage) {\n const { input_tokens: inp, output_tokens: out, cached_input_tokens: cached } = result.usage;\n metaParts.push(\n `${inp} tok in${cached > 0 ? ` (${cached} cached)` : \"\"} \\u2192 ${out} out`,\n );\n }\n\n lines.push(`[${metaParts.join(\" \\u2502 \")}]`);\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): 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 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 timeoutMs: input.timeoutMs,\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 = 600_000; // 10 minutes\nexport const TIMEOUT_ENV = \"SKILL_CODEX_TIMEOUT_MS\";\nexport const KILL_GRACE_MS = 5_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\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\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\";\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\", \"--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 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 { BRIDGE_DEPTH_ENV, DEFAULT_TIMEOUT_MS, TIMEOUT_ENV } from \"../config/constants.js\";\nimport { getNextDepth } from \"../guards/check-recursion.js\";\nimport { getCachedBinaryPath } from \"../guards/check-binary.js\";\nimport { setupTimeout } from \"./timeout.js\";\nimport { parseCodexOutput, type CodexResult } from \"./output-parser.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 timeoutMs?: number;\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 const args: string[] = [\"exec\", \"--json\", \"--skip-git-repo-check\"];\n\n if (params.mode === \"full-auto\") {\n args.push(\"--full-auto\");\n } else {\n args.push(\"--sandbox\", \"read-only\");\n }\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 prompt from stdin\n args.push(\"-\");\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 stdoutChunks: Buffer[] = [];\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk);\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\n child.stdin?.write(stdinPrompt);\n child.stdin?.end();\n\n const onClose = (exitCode: number | null): void => {\n clearTimeout_();\n const stdout = Buffer.concat(stdoutChunks).toString();\n\n if (exitCode === 0 || exitCode === null) {\n try {\n const result = parseCodexOutput(stdout);\n resolve(result);\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 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 reject(err);\n });\n });\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 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}\n\nexport interface CodexResult {\n readonly content: string;\n readonly activity: ActivityEntry[];\n readonly usage: TokenUsage | null;\n readonly raw: string;\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 usage: TokenUsage | null = null;\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\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 };\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)\n if (parsed.item?.type === \"agent_message\" && typeof parsed.item.text === \"string\") {\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\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 } 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 };\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","import { startServer } from \"./server.js\";\n\nstartServer().catch((err) => {\n process.stderr.write(`[skill-codex] Fatal: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","os","path","path","fs"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skill-codex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Cross-platform Claude Code skill that integrates OpenAI Codex CLI for code review, task delegation, and consultation via MCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"bin": {
|
|
15
|
-
"skill-codex": "
|
|
15
|
+
"skill-codex": "dist/bin/skill-codex.js"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"build": "tsup",
|