feat(run): spawn codex in a lane's tmux pane
This commit is contained in:
@@ -214,4 +214,88 @@ describe("pty-run", () => {
|
||||
assert.equal(retrieved.promptPreview, "the live prompt");
|
||||
assert.equal(retrieved.status, "running");
|
||||
});
|
||||
|
||||
function captureNewSession(fn) {
|
||||
const calls = [];
|
||||
tmux.__setExecImpl((args) => {
|
||||
calls.push(args);
|
||||
if (args[0] === "has-session") {
|
||||
const e = new Error("no such session");
|
||||
e.status = 1;
|
||||
throw e;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
fn();
|
||||
return calls.find((c) => c[0] === "new-session");
|
||||
}
|
||||
|
||||
it("spawnRun builds a codex argv for a codex lane", () => {
|
||||
const call = captureNewSession(() =>
|
||||
pty.spawnRun({
|
||||
laneId: 7,
|
||||
cwd: "/tmp/repo",
|
||||
tool: "codex",
|
||||
model: "gpt-5.1-codex",
|
||||
sandbox: "workspace-write",
|
||||
approval: "on-request",
|
||||
effort: "high",
|
||||
initialPrompt: "hello",
|
||||
})
|
||||
);
|
||||
const argv = call.slice(7);
|
||||
assert.deepEqual(argv, [
|
||||
"codex",
|
||||
"-m",
|
||||
"gpt-5.1-codex",
|
||||
"-s",
|
||||
"workspace-write",
|
||||
"-a",
|
||||
"on-request",
|
||||
"-c",
|
||||
"model_reasoning_effort=high",
|
||||
"hello",
|
||||
]);
|
||||
});
|
||||
|
||||
it("spawnRun puts codex resume first, as a subcommand", () => {
|
||||
const withId = captureNewSession(() =>
|
||||
pty.spawnRun({
|
||||
laneId: 8,
|
||||
cwd: "/tmp/repo",
|
||||
tool: "codex",
|
||||
resumeSessionId: "0199aaaa-bbbb-cccc-dddd-eeeeffff0000",
|
||||
})
|
||||
);
|
||||
assert.deepEqual(withId.slice(7, 10), [
|
||||
"codex",
|
||||
"resume",
|
||||
"0199aaaa-bbbb-cccc-dddd-eeeeffff0000",
|
||||
]);
|
||||
|
||||
tmux.__reset();
|
||||
const last = captureNewSession(() =>
|
||||
pty.spawnRun({ laneId: 9, cwd: "/tmp/repo", tool: "codex", resumeLast: true })
|
||||
);
|
||||
assert.deepEqual(last.slice(7, 10), ["codex", "resume", "--last"]);
|
||||
});
|
||||
|
||||
it("spawnRun rejects a codex sandbox/approval outside the allowlist", () => {
|
||||
tmux.__setExecImpl(() => "");
|
||||
assert.throws(
|
||||
() => pty.spawnRun({ laneId: 10, cwd: "/tmp/repo", tool: "codex", sandbox: "rm -rf" }),
|
||||
(err) => err.code === "EBADSANDBOX"
|
||||
);
|
||||
assert.throws(
|
||||
() => pty.spawnRun({ laneId: 10, cwd: "/tmp/repo", tool: "codex", approval: "always" }),
|
||||
(err) => err.code === "EBADAPPROVAL"
|
||||
);
|
||||
});
|
||||
|
||||
it("spawnRun never emits codex bypass flags", () => {
|
||||
const call = captureNewSession(() =>
|
||||
pty.spawnRun({ laneId: 11, cwd: "/tmp/repo", tool: "codex", sandbox: "danger-full-access" })
|
||||
);
|
||||
assert.ok(!call.some((a) => String(a).startsWith("--dangerously-bypass")));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user