Something went wrong. Try again.
presents omp as codex for use with chatgpt remote
Something went wrong. Try again.
7.6 kB · 204 lines
JavaScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205import test from "node:test";import assert from "node:assert/strict";import fs from "node:fs/promises";import os from "node:os";import path from "node:path";import { execFile } from "node:child_process";import { promisify } from "node:util";import { detectVcs, createIsolatedWorkspace, cleanupWorkspace, getVcsInfo, adaptWorktreeSpawnCommand } from "../src/workspace.mjs";import { CodexAppServer } from "../src/app-server.mjs";import { MockBackendFactory } from "../src/backend/mock.mjs";
const exec = promisify(execFile);
test("detectVcs returns none for plain directory", async () => { const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "plain-dir-")); try { const vcs = await detectVcs(tmp); assert.equal(vcs.type, "none"); assert.equal(vcs.root, tmp); } finally { await fs.rm(tmp, { recursive: true, force: true }); }});
test("detectVcs and createIsolatedWorkspace handle git repositories", async () => { const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "git-repo-")); const wsBase = await fs.mkdtemp(path.join(os.tmpdir(), "git-ws-base-")); try { await exec("git", ["init", tmp]); await exec("git", ["-C", tmp, "config", "user.name", "Test"]); await exec("git", ["-C", tmp, "config", "user.email", "test@example.com"]); await exec("git", ["-C", tmp, "config", "commit.gpgsign", "false"]); await fs.writeFile(path.join(tmp, "file.txt"), "hello"); await exec("git", ["-C", tmp, "add", "file.txt"]); await exec("git", ["-C", tmp, "commit", "-m", "init"]);
const vcs = await detectVcs(tmp); assert.equal(vcs.type, "git");
const info = await getVcsInfo(tmp); assert.ok(info); assert.ok(info.sha);
const ws = await createIsolatedWorkspace({ threadId: "test_thread_git", sourceCwd: tmp, isolationMode: "git", baseDir: wsBase, });
assert.equal(ws.isolated, true); assert.equal(ws.type, "git"); assert.ok(ws.cwd.startsWith(wsBase));
// Verify worktree has the file const content = await fs.readFile(path.join(ws.cwd, "file.txt"), "utf8"); assert.equal(content, "hello");
// Clean up await cleanupWorkspace(ws); const exists = await fs.access(ws.cwd).then(() => true).catch(() => false); assert.equal(exists, false); } finally { await fs.rm(tmp, { recursive: true, force: true }); await fs.rm(wsBase, { recursive: true, force: true }); }});
test("detectVcs and createIsolatedWorkspace handle jj repositories", async () => { let jjAvailable = false; try { await exec("jj", ["--version"]); jjAvailable = true; } catch {}
if (!jjAvailable) return;
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "jj-repo-")); const wsBase = await fs.mkdtemp(path.join(os.tmpdir(), "jj-ws-base-")); try { await exec("jj", ["git", "init", tmp]); await fs.writeFile(path.join(tmp, "jj_file.txt"), "hello jj");
const vcs = await detectVcs(tmp); assert.equal(vcs.type, "jj"); const info = await getVcsInfo(tmp); assert.ok(info); assert.ok(info.sha);
const ws = await createIsolatedWorkspace({ threadId: "test_thread_jj", sourceCwd: tmp, isolationMode: "jj", baseDir: wsBase, });
assert.equal(ws.isolated, true); assert.equal(ws.type, "jj"); assert.ok(ws.cwd.startsWith(wsBase));
// Clean up await cleanupWorkspace(ws); const exists = await fs.access(ws.cwd).then(() => true).catch(() => false); assert.equal(exists, false); } finally { await fs.rm(tmp, { recursive: true, force: true }); await fs.rm(wsBase, { recursive: true, force: true }); }});
test("CodexAppServer creates isolated workspace on thread/start with isolation", async () => { const tmp = await fs.mkdtemp(path.join(os.tmpdir(), "appserver-ws-")); const stateFile = path.join(tmp, "state.json"); const repoDir = path.join(tmp, "repo"); await fs.mkdir(repoDir); await exec("git", ["init", repoDir]); await exec("git", ["-C", repoDir, "config", "user.name", "Test"]); await exec("git", ["-C", repoDir, "config", "user.email", "test@example.com"]); await exec("git", ["-C", repoDir, "config", "commit.gpgsign", "false"]); await fs.writeFile(path.join(repoDir, "test.txt"), "base"); await exec("git", ["-C", repoDir, "add", "test.txt"]); await exec("git", ["-C", repoDir, "commit", "-m", "initial"]);
const server = new CodexAppServer({ backendFactory: new MockBackendFactory(), stateFile, cwd: repoDir, }); const messages = []; const peer = server.createPeer((msg) => messages.push(msg)); await server.handle(peer, { id: 1, method: "initialize", params: { clientInfo: { name: "test", version: "1" } } }); await server.handle(peer, { method: "initialized", params: {} });
await server.handle(peer, { id: 2, method: "thread/start", params: { cwd: repoDir, workspaceIsolation: "git", }, });
const startRes = messages.find((m) => m.id === 2); const thread = startRes.result.thread; assert.ok(thread); assert.ok(thread.workspace); assert.equal(thread.workspace.isolated, true); assert.equal(thread.workspace.type, "git"); assert.notEqual(thread.cwd, repoDir); // List threads with repoDir should match the isolated thread await server.handle(peer, { id: 3, method: "thread/list", params: { cwd: repoDir }, }); const listRes = messages.find((m) => m.id === 3); assert.equal(listRes.result.data.length, 1); assert.equal(listRes.result.data[0].id, thread.id);
// Hooks list with cwds array await server.handle(peer, { id: 4, method: "hooks/list", params: { cwds: [repoDir, thread.workspace.cwd] }, }); const hooksRes = messages.find((m) => m.id === 4); assert.equal(hooksRes.result.data.length, 2); assert.equal(hooksRes.result.data[0].cwd, path.resolve(repoDir));
// Delete thread cleans up workspace const wsPath = thread.workspace.cwd; await server.handle(peer, { id: 5, method: "thread/delete", params: { threadId: thread.id } }); const exists = await fs.access(wsPath).then(() => true).catch(() => false); assert.equal(exists, false);
await fs.rm(tmp, { recursive: true, force: true });});
test("adaptWorktreeSpawnCommand wraps worktree creation and removal scripts", () => { const createCmd = ["/bin/sh", "-lc", 'git_root="."\nworktree_git_root="wt"\ngit worktree add --detach "$worktree_git_root" "$starting_ref"']; const adaptedCreate = adaptWorktreeSpawnCommand(createCmd, {}); assert.equal(adaptedCreate[0], "/bin/sh"); assert.ok(adaptedCreate[2].includes("jj workspace add")); assert.ok(adaptedCreate[2].includes("_real_git"));
// Direct git worktree array commands are wrapped through /bin/sh const directCmd = ["git", "-C", "/path/to/repo", "worktree", "add", "--detach", "/tmp/wt", "HEAD"]; const adaptedDirect = adaptWorktreeSpawnCommand(directCmd, {}); assert.equal(adaptedDirect[0], "/bin/sh"); assert.equal(adaptedDirect[1], "-c"); assert.ok(adaptedDirect[2].includes("jj workspace add")); assert.equal(adaptedDirect[3], "git"); assert.equal(adaptedDirect[4], "-C"); assert.equal(adaptedDirect[5], "/path/to/repo");
// Regular commands are completely untouched const normalCmd = ["/bin/sh", "-lc", "cargo build --release"]; const untouched = adaptWorktreeSpawnCommand(normalCmd, {}); assert.equal(untouched[2], "cargo build --release");
const normalBin = ["cargo", "build", "--release"]; const untouchedBin = adaptWorktreeSpawnCommand(normalBin, {}); assert.deepEqual(untouchedBin, normalBin);});