Skip to content

Commit 182af25

Browse files
authored
chore: fix monorepo edge case (#26)
* chore: fix monorepo edge case * Update index.test.ts
1 parent 608ccfc commit 182af25

2 files changed

Lines changed: 67 additions & 7 deletions

File tree

src/index.test.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ const runCLI = async (args: string = "") => {
1111
return execAsync(`ts-node ${cliPath} ${args}`);
1212
};
1313

14+
// New helper to run CLI with specific environment variables
15+
const runCLIWithEnv = async (args: string = "", env: Record<string, string> = {}) => {
16+
const cliPath = path.resolve(__dirname, "index.ts");
17+
const envVars = Object.entries(env)
18+
.map(([key, value]) => `${key}="${value}"`)
19+
.join(" ");
20+
return execAsync(`${envVars} ts-node ${cliPath} ${args}`);
21+
};
22+
1423
describe("AI Digest CLI", () => {
1524
afterAll(async () => {
1625
// Remove the created .md files after all tests complete
@@ -319,4 +328,44 @@ describe("AI Digest CLI", () => {
319328
await fs.rm(tempDir2, { recursive: true, force: true });
320329
}
321330
}, 15000);
322-
});
331+
332+
// New test for working directory behavior
333+
it("should respect INIT_CWD when different from process.cwd()", async () => {
334+
// Create a temporary directory structure
335+
const tempRootDir = await fs.mkdtemp(path.join(os.tmpdir(), "ai-digest-wd-test-"));
336+
const subDir = path.join(tempRootDir, "subdir");
337+
await fs.mkdir(subDir);
338+
339+
// Create test files
340+
await fs.writeFile(path.join(tempRootDir, "root-file.txt"), "Root file content");
341+
342+
try {
343+
// Run with INIT_CWD set to subdirectory but cwd unchanged
344+
const env = { INIT_CWD: subDir };
345+
346+
// Use the tempRootDir as input to have files to process
347+
const { stdout } = await runCLIWithEnv(`--input ${tempRootDir}`, env);
348+
349+
// Verify the file was created in the subdirectory (INIT_CWD)
350+
const subDirOutputPath = path.join(subDir, "codebase.md");
351+
const fileExists = await fs
352+
.access(subDirOutputPath)
353+
.then(() => true)
354+
.catch(() => false);
355+
356+
expect(fileExists).toBe(true);
357+
358+
// Verify content includes the root file
359+
const content = await fs.readFile(subDirOutputPath, "utf-8");
360+
expect(content).toContain("root-file.txt");
361+
expect(content).toContain("Root file content");
362+
363+
// Clean up the output file
364+
await fs.unlink(subDirOutputPath).catch(() => {});
365+
366+
} finally {
367+
// Clean up the test directories
368+
await fs.rm(tempRootDir, { recursive: true, force: true });
369+
}
370+
}, 15000);
371+
});

src/index.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ type IgnoreInstance = ReturnType<typeof ignore>;
2525

2626
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB in bytes
2727

28+
function getActualWorkingDirectory() {
29+
// INIT_CWD is set by npm/npx to the directory from which the command was invoked
30+
// This is more reliable than process.cwd() when running via npx
31+
if (process.env.INIT_CWD) {
32+
return process.env.INIT_CWD;
33+
}
34+
35+
return process.cwd();
36+
}
37+
2838
// Simple debounce function to avoid multiple rebuilds when many files change at once
2939
function debounce<F extends (...args: any[]) => any>(
3040
func: F,
@@ -193,7 +203,7 @@ async function watchFiles(
193203
// Ignore the output file
194204
const outputAbsPath = path.isAbsolute(outputFile)
195205
? outputFile
196-
: path.join(process.cwd(), outputFile);
206+
: path.join(getActualWorkingDirectory(), outputFile);
197207
if (filePath === outputAbsPath) {
198208
return true;
199209
}
@@ -453,7 +463,7 @@ async function aggregateFiles(
453463
454464
const outputAbsPath = path.isAbsolute(outputFile)
455465
? outputFile
456-
: path.join(process.cwd(), outputFile);
466+
: path.join(getActualWorkingDirectory(), outputFile);
457467
458468
if (
459469
fullPath === outputAbsPath ||
@@ -503,7 +513,7 @@ async function aggregateFiles(
503513
}
504514
}
505515

506-
await fs.mkdir(path.dirname(outputFile), { recursive: true });
516+
await fs.mkdir(path.dirname(path.resolve(getActualWorkingDirectory(), outputFile)), { recursive: true });
507517

508518
// Write to a temporary file first to prevent partial writes during SIGINT
509519
const tempFile = `${outputFile}.temp`;
@@ -600,7 +610,7 @@ program
600610
.option(
601611
"-i, --input <directories...>",
602612
"Input directories (multiple allowed)",
603-
[process.cwd()]
613+
[getActualWorkingDirectory()] // Fix: Use getActualWorkingDirectory() instead of process.cwd()
604614
)
605615
.option("-o, --output <file>", "Output file name", "codebase.md")
606616
.option("--no-default-ignores", "Disable default ignore patterns")
@@ -613,9 +623,10 @@ program
613623
.option("--watch", "Watch for file changes and rebuild automatically")
614624
.action(async (options) => {
615625
const inputDirs = options.input.map((dir: string) => path.resolve(dir));
626+
// Fix: Use getActualWorkingDirectory() instead of process.cwd()
616627
const outputFile = path.isAbsolute(options.output)
617628
? options.output
618-
: path.join(process.cwd(), options.output);
629+
: path.join(getActualWorkingDirectory(), options.output);
619630

620631
if (options.watch) {
621632
// Run in watch mode
@@ -641,4 +652,4 @@ program
641652
}
642653
});
643654

644-
program.parse(process.argv);
655+
program.parse(process.argv);

0 commit comments

Comments
 (0)