Compare commits

..

1 Commits

Author SHA1 Message Date
Dominik Kundel 741dd5104d ci: add pull request workflow for tests and build 2026-03-31 12:52:24 -07:00
11 changed files with 14 additions and 47 deletions
+2 -2
View File
@@ -5,13 +5,13 @@
},
"metadata": {
"description": "Codex plugins to use in Claude Code for delegation and code review.",
"version": "1.0.2"
"version": "1.0.0"
},
"plugins": [
{
"name": "codex",
"description": "Use Codex from Claude Code to review code or delegate tasks.",
"version": "1.0.2",
"version": "1.0.0",
"author": {
"name": "OpenAI"
},
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@openai/codex-plugin-cc",
"version": "1.0.2",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@openai/codex-plugin-cc",
"version": "1.0.2",
"version": "1.0.0",
"license": "Apache-2.0",
"devDependencies": {
"@types/node": "^25.5.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@openai/codex-plugin-cc",
"version": "1.0.2",
"version": "1.0.0",
"private": true,
"type": "module",
"description": "Use Codex from Claude Code to review code or delegate tasks.",
-1
View File
@@ -1,6 +1,5 @@
{
"name": "codex",
"version": "1.0.2",
"description": "Use Codex from Claude Code to review code or delegate tasks.",
"author": {
"name": "OpenAI"
+1 -1
View File
@@ -2,7 +2,7 @@
description: Delegate investigation, an explicit fix request, or follow-up rescue work to the Codex rescue subagent
argument-hint: "[--background|--wait] [--resume|--fresh] [--model <model|spark>] [--effort <none|minimal|low|medium|high|xhigh>] [what Codex should investigate, solve, or continue]"
context: fork
allowed-tools: Bash(node:*), AskUserQuestion
allowed-tools: Bash(node:*)
---
Route this request to the `codex:codex-rescue` subagent.
+3 -18
View File
@@ -14,7 +14,6 @@ import { spawn } from "node:child_process";
import readline from "node:readline";
import { parseBrokerEndpoint } from "./broker-endpoint.mjs";
import { ensureBrokerSession } from "./broker-lifecycle.mjs";
import { terminateProcessTree } from "./process.mjs";
const PLUGIN_MANIFEST_URL = new URL("../../.claude-plugin/plugin.json", import.meta.url);
const PLUGIN_MANIFEST = JSON.parse(fs.readFileSync(PLUGIN_MANIFEST_URL, "utf8"));
@@ -189,9 +188,7 @@ class SpawnedCodexAppServerClient extends AppServerClientBase {
this.proc = spawn("codex", ["app-server"], {
cwd: this.cwd,
env: this.options.env,
stdio: ["pipe", "pipe", "pipe"],
shell: process.platform === "win32",
windowsHide: true
stdio: ["pipe", "pipe", "pipe"]
});
this.proc.stdout.setEncoding("utf8");
@@ -240,20 +237,8 @@ class SpawnedCodexAppServerClient extends AppServerClientBase {
if (this.proc && !this.proc.killed) {
this.proc.stdin.end();
setTimeout(() => {
if (this.proc && !this.proc.killed && this.proc.exitCode === null) {
// On Windows with shell: true, the direct child is cmd.exe.
// Use terminateProcessTree to kill the entire tree including
// the grandchild node process.
if (process.platform === "win32") {
try {
terminateProcessTree(this.proc.pid);
} catch {
// Best-effort cleanup inside an unref'd timer — swallow errors
// to avoid crashing the host process during shutdown.
}
} else {
this.proc.kill("SIGTERM");
}
if (this.proc && !this.proc.killed) {
this.proc.kill("SIGTERM");
}
}, 50).unref?.();
}
+1 -2
View File
@@ -8,8 +8,7 @@ export function runCommand(command, args = [], options = {}) {
encoding: "utf8",
input: options.input,
stdio: options.stdio ?? "pipe",
shell: process.platform === "win32",
windowsHide: true
shell: process.platform === "win32"
});
return {
+1 -3
View File
@@ -2,9 +2,8 @@ import fs from "node:fs";
import path from "node:path";
import test from "node:test";
import assert from "node:assert/strict";
import { fileURLToPath } from "node:url";
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const ROOT = "/Users/dkundel/code/codex-plugin";
const PLUGIN_ROOT = path.join(ROOT, "plugins", "codex");
function read(relativePath) {
@@ -90,7 +89,6 @@ test("rescue command absorbs continue semantics", () => {
const runtimeSkill = read("skills/codex-cli-runtime/SKILL.md");
assert.match(rescue, /The final user-visible response must be Codex's output verbatim/i);
assert.match(rescue, /allowed-tools:\s*Bash\(node:\*\),\s*AskUserQuestion/);
assert.match(rescue, /--background\|--wait/);
assert.match(rescue, /--resume\|--fresh/);
assert.match(rescue, /--model <model\|spark>/);
+1 -11
View File
@@ -1,6 +1,4 @@
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { writeExecutable } from "./helpers.mjs";
@@ -509,19 +507,11 @@ rl.on("line", (line) => {
});
`;
writeExecutable(scriptPath, source);
// On Windows, npm global binaries are invoked via .cmd wrappers.
// Create a codex.cmd so the fake binary is discoverable by spawn with shell: true.
if (process.platform === "win32") {
const cmdWrapper = `@echo off\r\nnode "%~dp0codex" %*\r\n`;
fs.writeFileSync(path.join(binDir, "codex.cmd"), cmdWrapper, { encoding: "utf8" });
}
}
export function buildEnv(binDir) {
const sep = process.platform === "win32" ? ";" : ":";
return {
...process.env,
PATH: `${binDir}${sep}${process.env.PATH}`
PATH: `${binDir}:${process.env.PATH}`
};
}
+1 -4
View File
@@ -1,7 +1,6 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import process from "node:process";
import { spawnSync } from "node:child_process";
export function makeTempDir(prefix = "codex-plugin-test-") {
@@ -17,9 +16,7 @@ export function run(command, args, options = {}) {
cwd: options.cwd,
env: options.env,
encoding: "utf8",
input: options.input,
shell: process.platform === "win32" && !path.isAbsolute(command),
windowsHide: true
input: options.input
});
}
+1 -2
View File
@@ -3,14 +3,13 @@ import path from "node:path";
import test from "node:test";
import assert from "node:assert/strict";
import { spawn } from "node:child_process";
import { fileURLToPath } from "node:url";
import { buildEnv, installFakeCodex } from "./fake-codex-fixture.mjs";
import { initGitRepo, makeTempDir, run } from "./helpers.mjs";
import { loadBrokerSession } from "../plugins/codex/scripts/lib/broker-lifecycle.mjs";
import { resolveStateDir } from "../plugins/codex/scripts/lib/state.mjs";
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const ROOT = "/Users/dkundel/code/codex-plugin";
const PLUGIN_ROOT = path.join(ROOT, "plugins", "codex");
const SCRIPT = path.join(PLUGIN_ROOT, "scripts", "codex-companion.mjs");
const STOP_HOOK = path.join(PLUGIN_ROOT, "scripts", "stop-review-gate-hook.mjs");