fix(thread-ledger): restore the os import the ledger split dropped

`main` resolves the default turn-summary path through `os.homedir()`,
and the entry point's rewritten import block did not carry `node:os`.
Every `ledger declare` without TURN_SUMMARY_PATH set threw
`ReferenceError: os is not defined`.

The suite never saw it: the declare tests exercise `declareText`, which
is pure, so the CLI branch that builds the fallback path had no test at
all. It has one now — the CLI run as a process, with HOME pointed at a
temp directory and the env var unset, asserting the file lands at
`$HOME/.claude/turn-summary.txt`. It fails on the broken import and
passes on the fix.

ADVANCES #188

Claude-Session: https://claude.ai/code/session_014CUXJh1hKmW4ccUwRQ1Ep1
This commit is contained in:
pando-ramet
2026-09-04 14:10:20 +00:00
parent c2e15fff7c
commit 949e04afc1
2 changed files with 24 additions and 0 deletions
+1
View File
@@ -19,6 +19,7 @@
// Node builtins only. Pushes with plain git; no forge API, no MCP.
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";
+23
View File
@@ -360,6 +360,29 @@ describe("declare", () => {
}
});
it("writes to the default path when nothing names one", () => {
// The CLI's own resolution, run as a process: `declareText` is pure
// and never reaches it, so the branch that builds the fallback path
// had no test and a missing import broke it silently (#188).
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "declare-home-"));
try {
const result = spawnSync(
process.execPath,
[path.join(SKILL, "ledger.mjs"), "declare", "--reviews", "none"],
{
encoding: "utf8",
env: { ...process.env, HOME: dir, TURN_SUMMARY_PATH: undefined },
},
);
assert.equal(result.status, 0, result.stderr);
const written = path.join(dir, ".claude", "turn-summary.txt");
assert.ok(fs.existsSync(written), `nothing at ${written}`);
assert.match(fs.readFileSync(written, "utf8"), /^reviews: none$/m);
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
});
it("writes the two core lines even when empty", () => {
const text = declareText({ reviews: "none" });
assert.equal(text, "tickets: \nreviews: none\n");