From 3034448ecd4fe3ac401ea0648f52a7fa4f392fdd Mon Sep 17 00:00:00 2001 From: Kevinjohn Gallagher Date: Sun, 19 Jul 2026 23:50:39 +0100 Subject: [PATCH] Report missing Claude projects directory --- .../scripts/lib/claude-session-transfer.mjs | 10 ++++++++-- tests/runtime.test.mjs | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plugins/codex/scripts/lib/claude-session-transfer.mjs b/plugins/codex/scripts/lib/claude-session-transfer.mjs index eea0aeba2..a2b9f10a8 100644 --- a/plugins/codex/scripts/lib/claude-session-transfer.mjs +++ b/plugins/codex/scripts/lib/claude-session-transfer.mjs @@ -29,13 +29,19 @@ export function resolveClaudeSessionPath(cwd, options = {}) { } let source; - let projects; try { source = fs.realpathSync(sourcePath); - projects = fs.realpathSync(CLAUDE_PROJECTS_DIR); } catch { throw new Error(`Claude session file not found: ${sourcePath}`); } + + let projects; + try { + projects = fs.realpathSync(CLAUDE_PROJECTS_DIR); + } catch { + throw new Error(`Claude projects directory not found: ${CLAUDE_PROJECTS_DIR}`); + } + const relative = path.relative(projects, source); if (relative === "" || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) { throw new Error(`Codex can import Claude sessions only from ${CLAUDE_PROJECTS_DIR}: ${source}`); diff --git a/tests/runtime.test.mjs b/tests/runtime.test.mjs index 8f276835b..72e48e781 100644 --- a/tests/runtime.test.mjs +++ b/tests/runtime.test.mjs @@ -327,6 +327,23 @@ test("transfer rejects sources outside the Claude projects directory", () => { assert.match(result.stderr, /only from .*\.claude.*projects/); }); +test("transfer distinguishes a missing Claude projects directory from a missing source", () => { + const home = makeTempDir(); + const repo = path.join(home, "repo"); + const sourcePath = path.join(home, "session.jsonl"); + fs.mkdirSync(repo, { recursive: true }); + fs.writeFileSync(sourcePath, "{}\n", "utf8"); + + const result = run("node", [SCRIPT, "transfer", "--source", sourcePath], { + cwd: repo, + env: { ...process.env, HOME: home } + }); + + assert.notEqual(result.status, 0); + assert.match(result.stderr, /Claude projects directory not found:/); + assert.doesNotMatch(result.stderr, /Claude session file not found:/); +}); + test("task reports the actual Codex auth error when the run is rejected", () => { const repo = makeTempDir(); const binDir = makeTempDir();