diff --git a/plugins/codex/scripts/lib/git.mjs b/plugins/codex/scripts/lib/git.mjs index 1c0529a..9b3b765 100644 --- a/plugins/codex/scripts/lib/git.mjs +++ b/plugins/codex/scripts/lib/git.mjs @@ -133,9 +133,12 @@ function formatSection(title, body) { return [`## ${title}`, "", body.trim() ? body.trim() : "(none)", ""].join("\n"); } -function formatUntrackedFile(cwd, relativePath) { +export function formatUntrackedFile(cwd, relativePath) { const absolutePath = path.join(cwd, relativePath); const stat = fs.statSync(absolutePath); + if (stat.isDirectory()) { + return `### ${relativePath}\n(skipped: directory)`; + } if (stat.size > MAX_UNTRACKED_BYTES) { return `### ${relativePath}\n(skipped: ${stat.size} bytes exceeds ${MAX_UNTRACKED_BYTES} byte limit)`; } diff --git a/tests/git.test.mjs b/tests/git.test.mjs index 7ea1a04..af923f3 100644 --- a/tests/git.test.mjs +++ b/tests/git.test.mjs @@ -3,7 +3,7 @@ import path from "node:path"; import test from "node:test"; import assert from "node:assert/strict"; -import { collectReviewContext, resolveReviewTarget } from "../plugins/codex/scripts/lib/git.mjs"; +import { collectReviewContext, formatUntrackedFile, resolveReviewTarget } from "../plugins/codex/scripts/lib/git.mjs"; import { initGitRepo, makeTempDir, run } from "./helpers.mjs"; test("resolveReviewTarget prefers working tree when repo is dirty", () => { @@ -68,3 +68,13 @@ test("resolveReviewTarget requires an explicit base when no default branch can b /Unable to detect the repository default branch\. Pass --base or use --scope working-tree\./ ); }); + +test("formatUntrackedFile skips directories instead of throwing EISDIR", () => { + const cwd = makeTempDir(); + fs.mkdirSync(path.join(cwd, "some-dir")); + + const result = formatUntrackedFile(cwd, "some-dir"); + + assert.match(result, /skipped: directory/); + assert.match(result, /some-dir/); +});