baa-conductor


baa-conductor / packages / codex-exec / src
im_wower  ·  2026-03-22

index.test.js

  1import assert from "node:assert/strict";
  2import { chmod, mkdtemp, rm, writeFile } from "node:fs/promises";
  3import { tmpdir } from "node:os";
  4import { join } from "node:path";
  5import test from "node:test";
  6
  7import { runCodexExec } from "../dist/index.js";
  8
  9async function createFakeCodexCli() {
 10  const directoryPath = await mkdtemp(join(tmpdir(), "baa-codex-exec-cli-"));
 11  const cliPath = join(directoryPath, "codex");
 12  const source = `#!/usr/bin/env node
 13import { writeFileSync } from "node:fs";
 14
 15const args = process.argv.slice(2);
 16const delayMs = Number(process.env.FAKE_CODEX_DELAY_MS ?? "0");
 17const exitCode = Number(process.env.FAKE_CODEX_EXIT_CODE ?? "0");
 18const stderr = process.env.FAKE_CODEX_STDERR ?? "";
 19const stdout = process.env.FAKE_CODEX_STDOUT ?? "";
 20const outputLastMessageIndex = args.indexOf("--output-last-message");
 21const outputLastMessagePath =
 22  outputLastMessageIndex === -1 ? null : args[outputLastMessageIndex + 1];
 23
 24if (delayMs > 0) {
 25  await new Promise((resolve) => setTimeout(resolve, delayMs));
 26}
 27
 28if (outputLastMessagePath) {
 29  writeFileSync(
 30    outputLastMessagePath,
 31    process.env.FAKE_CODEX_LAST_MESSAGE ?? "fake final message\\n"
 32  );
 33}
 34
 35if (stdout !== "") {
 36  process.stdout.write(stdout);
 37} else if (args.includes("--json")) {
 38  process.stdout.write(
 39    JSON.stringify({
 40      type: "started",
 41      payload: {
 42        args,
 43        cwd: process.cwd(),
 44        prompt: args.at(-1) ?? null
 45      }
 46    }) + "\\n"
 47  );
 48  process.stdout.write(JSON.stringify({ type: "completed" }) + "\\n");
 49} else {
 50  process.stdout.write("plain stdout\\n");
 51}
 52
 53if (stderr !== "") {
 54  process.stderr.write(stderr);
 55}
 56
 57process.exit(exitCode);
 58`;
 59
 60  await writeFile(cliPath, source, "utf8");
 61  await chmod(cliPath, 0o755);
 62
 63  return {
 64    cliPath,
 65    directoryPath
 66  };
 67}
 68
 69async function createWorkspace() {
 70  return await mkdtemp(join(tmpdir(), "baa-codex-exec-workspace-"));
 71}
 72
 73test("runCodexExec executes a one-shot fallback worker request and returns structured output", async (t) => {
 74  const fakeCli = await createFakeCodexCli();
 75  const workspacePath = await createWorkspace();
 76
 77  t.after(async () => {
 78    await rm(fakeCli.directoryPath, { force: true, recursive: true });
 79    await rm(workspacePath, { force: true, recursive: true });
 80  });
 81
 82  const response = await runCodexExec({
 83    purpose: "fallback-worker",
 84    prompt: "Summarize the current diff.",
 85    cwd: workspacePath,
 86    cliPath: fakeCli.cliPath,
 87    timeoutMs: 1_000,
 88    model: "gpt-5.4",
 89    profile: "worker",
 90    sandbox: "read-only",
 91    skipGitRepoCheck: true,
 92    json: true,
 93    ephemeral: true,
 94    config: ['model_reasoning_effort="medium"'],
 95    additionalWritableDirectories: [join(workspacePath, "artifacts")],
 96    images: [join(workspacePath, "diagram.png")],
 97    env: {
 98      FAKE_CODEX_LAST_MESSAGE: "worker completed\n",
 99      FAKE_CODEX_STDERR: "simulated warning\n"
100    }
101  });
102
103  assert.equal(response.ok, true);
104  assert.deepEqual(response.invocation.args, [
105    "exec",
106    "--cd",
107    workspacePath,
108    "--color",
109    "never",
110    "--model",
111    "gpt-5.4",
112    "--profile",
113    "worker",
114    "--sandbox",
115    "read-only",
116    "--skip-git-repo-check",
117    "--json",
118    "--ephemeral",
119    "--config",
120    'model_reasoning_effort="medium"',
121    "--add-dir",
122    join(workspacePath, "artifacts"),
123    "--image",
124    join(workspacePath, "diagram.png"),
125    "Summarize the current diff."
126  ]);
127  assert.equal(response.result.exitCode, 0);
128  assert.equal(response.result.timedOut, false);
129  assert.equal(response.result.lastMessage, "worker completed\n");
130  assert.equal(response.result.stderr, "simulated warning\n");
131  assert.equal(response.result.jsonParseErrors.length, 0);
132  assert.equal(response.result.jsonEvents?.length, 2);
133  assert.equal(response.result.jsonEvents?.[0].type, "started");
134  assert.equal(response.result.jsonEvents?.[0].payload.prompt, "Summarize the current diff.");
135  assert.equal(
136    response.result.jsonEvents?.[0].payload.args.includes("--output-last-message"),
137    true
138  );
139});
140
141test("runCodexExec reports non-zero exits without dropping stdout or stderr", async (t) => {
142  const fakeCli = await createFakeCodexCli();
143  const workspacePath = await createWorkspace();
144
145  t.after(async () => {
146    await rm(fakeCli.directoryPath, { force: true, recursive: true });
147    await rm(workspacePath, { force: true, recursive: true });
148  });
149
150  const response = await runCodexExec({
151    purpose: "simple-worker",
152    prompt: "Return an error.",
153    cwd: workspacePath,
154    cliPath: fakeCli.cliPath,
155    timeoutMs: 1_000,
156    env: {
157      FAKE_CODEX_EXIT_CODE: "17",
158      FAKE_CODEX_STDERR: "fatal\n"
159    }
160  });
161
162  assert.equal(response.ok, false);
163  assert.equal(response.error.code, "CODEX_EXEC_EXIT_NON_ZERO");
164  assert.equal(response.invocation?.purpose, "simple-worker");
165  assert.equal(response.result?.exitCode, 17);
166  assert.equal(response.result?.timedOut, false);
167  assert.equal(response.result?.stderr, "fatal\n");
168  assert.equal(response.result?.stdout, "plain stdout\n");
169});
170
171test("runCodexExec reports timeouts for hung fallback processes", async (t) => {
172  const fakeCli = await createFakeCodexCli();
173  const workspacePath = await createWorkspace();
174
175  t.after(async () => {
176    await rm(fakeCli.directoryPath, { force: true, recursive: true });
177    await rm(workspacePath, { force: true, recursive: true });
178  });
179
180  const response = await runCodexExec({
181    purpose: "fallback-worker",
182    prompt: "Sleep too long.",
183    cwd: workspacePath,
184    cliPath: fakeCli.cliPath,
185    timeoutMs: 50,
186    env: {
187      FAKE_CODEX_DELAY_MS: "5000"
188    }
189  });
190
191  assert.equal(response.ok, false);
192  assert.equal(response.error.code, "CODEX_EXEC_TIMEOUT");
193  assert.equal(response.result?.timedOut, true);
194  assert.equal(response.result?.exitCode, null);
195  assert.equal(response.result?.signal, "SIGTERM");
196});
197
198test("runCodexExec rejects stdin-style prompts because the fallback adapter is one-shot only", async () => {
199  const response = await runCodexExec({
200    prompt: "-"
201  });
202
203  assert.equal(response.ok, false);
204  assert.equal(response.error.code, "CODEX_EXEC_INVALID_INPUT");
205});