Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "srcpack",
"version": "0.1.10",
"version": "0.1.13",
"description": "Zero-config CLI for bundling code into LLM-optimized context files",
"keywords": [
"llm",
Expand Down Expand Up @@ -54,7 +54,8 @@
"files": [
"dist",
"src",
"schema.json"
"LICENSE",
"README.md"
],
"scripts": {
"build": "bun build ./src/cli.ts ./src/index.ts --outdir ./dist --target node && tsc",
Expand Down
7 changes: 4 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ Options:
for (const { name, outfile, result } of outputs) {
const fileCount = result.index.length;
const lineCount = sumLines(result);
const outPath = join(root, outfile);
const outPath = resolve(root, outfile);

const nameCol = name.padEnd(maxNameLen);
const filesCol = formatNumber(fileCount).padStart(maxFilesLen);
Expand All @@ -213,8 +213,9 @@ Options:
} else {
await mkdir(dirname(outPath), { recursive: true });
await writeFile(outPath, result.content);
const displayPath = relative(process.cwd(), outPath);
console.log(
` ${nameCol} ${filesCol} ${plural(fileCount, "file")} ${linesCol} ${plural(lineCount, "line")} → ${outfile}`,
` ${nameCol} ${filesCol} ${plural(fileCount, "file")} ${linesCol} ${plural(lineCount, "line")} → ${displayPath}`,
);
}
}
Expand Down Expand Up @@ -358,7 +359,7 @@ async function handleGdriveUpload(

for (let i = 0; i < toUpload.length; i++) {
const output = toUpload[i]!;
const filePath = join(root, output.outfile);
const filePath = resolve(root, output.outfile);
uploadSpinner.text = `Uploading ${output.name}... (${i + 1}/${toUpload.length})`;
const result = await uploadFile(filePath, uploadConfig);
results.push(result);
Expand Down
38 changes: 36 additions & 2 deletions tests/e2e/cli.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { join } from "node:path";
import { describe, expect, test } from "bun:test";
import { mkdir, rm, writeFile } from "node:fs/promises";
import { join, resolve } from "node:path";
import { tmpdir } from "node:os";
import { describe, expect, test, afterEach } from "bun:test";

const CLI_PATH = join(import.meta.dir, "../../src/cli.ts");
const FIXTURE_PATH = join(import.meta.dir, "../fixtures/sample-project");
Expand Down Expand Up @@ -114,4 +116,36 @@ describe("cli", () => {
expect(result.stderr).toContain("Unknown bundle: unknown");
});
});

describe("absolute outDir with custom root", () => {
const tempRoot = join(tmpdir(), `srcpack-test-${Date.now()}`);
const tempOutDir = join(tmpdir(), `srcpack-out-${Date.now()}`);

afterEach(async () => {
await rm(tempRoot, { recursive: true, force: true });
await rm(tempOutDir, { recursive: true, force: true });
});

test("should write to absolute outDir when root is also specified", async () => {
// Setup: create temp project with config using absolute outDir
await mkdir(join(tempRoot, "src"), { recursive: true });
await writeFile(join(tempRoot, "src/index.ts"), "export const x = 1;");
await writeFile(
join(tempRoot, "srcpack.config.ts"),
`export default {
outDir: ${JSON.stringify(tempOutDir)},
bundles: { app: "src/**/*" },
};`,
);

const result = await runCli([], { cwd: tempRoot });

expect(result.exitCode).toBe(0);
expect(result.stdout).toContain("app");

// Verify file was written to absolute outDir, not joined with root
const outFile = Bun.file(join(tempOutDir, "app.txt"));
expect(await outFile.exists()).toBe(true);
});
});
});