codex-plugin-cc/plugins/codex/scripts/lib/claude-session-transfer.mjs
2026-06-23 10:26:06 -07:00

45 lines
1.5 KiB
JavaScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { ensureAbsolutePath } from "./fs.mjs";
export const TRANSCRIPT_PATH_ENV = "CODEX_COMPANION_TRANSCRIPT_PATH";
const CLAUDE_PROJECTS_DIR = path.join(os.homedir(), ".claude", "projects");
function resolveUserPath(cwd, value) {
if (value === "~") {
return os.homedir();
}
if (String(value).startsWith("~/")) {
return path.join(os.homedir(), String(value).slice(2));
}
return ensureAbsolutePath(cwd, value);
}
export function resolveClaudeSessionPath(cwd, options = {}) {
const requestedPath = options.source || process.env[TRANSCRIPT_PATH_ENV];
if (!requestedPath) {
throw new Error("Could not identify the current Claude transcript. Retry with --source <path-to-claude-jsonl>.");
}
const sourcePath = resolveUserPath(cwd, requestedPath);
if (path.extname(sourcePath) !== ".jsonl") {
throw new Error(`Claude session source must be a JSONL file: ${sourcePath}`);
}
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}`);
}
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}`);
}
return source;
}