What
PR #9 (59c6861 feat: run on Node or Bun — Bun is no longer an install prerequisite) does not hold. On Node v25.9.0, every stpa subcommand that spawns a tool fails:
$ ./stpa run .stpa
(node:59015) Warning: Failed to load the ES module: .../Tools/RenderReport.ts.
Make sure to set "type": "module" in the nearest package.json file or use the .mjs extension.
.../Tools/RenderReport.ts:25
import { readFileSync, existsSync, writeFileSync } from "node:fs";
^^^^^^
SyntaxError: Cannot use import statement outside a module
Only ./stpa --help works, because the launcher never spawns a child. Bun is fine: bun stpa run completes the whole pipeline.
Root cause
The two halves disagree about module system, and fixing one breaks the other:
Tools/*.ts are ESM. The repo has no package.json, so Node resolves .ts as CommonJS and every import is a syntax error. --experimental-strip-types does not change this — it strips types, it does not change module resolution.
- Adding
package.json with {"type":"module"} fixes every tool — and then breaks the launcher, because stpa is CJS:
$ ./stpa run .stpa # with {"type":"module"} present
const { spawnSync } = require("node:child_process");
^
ReferenceError: require is not defined in ES module scope
So a fix needs both halves. Options:
package.json with {"type":"module"} and convert stpa to ESM import (it uses require at lines 24-26), or
- rename the tools to
.mts and leave the launcher alone, or
- keep
stpa CJS by giving it a .cjs extension, or createRequire.
Why CI did not catch it
.github/workflows/ci.yml installs oven-sh/setup-bun@v2, invokes tools as bun Tools/X.ts, and never runs Node at all. It also never exercises ./stpa <subcommand> past --help. The one runtime PR #9 was written to support is the one runtime CI does not test — so the feature shipped green and broken.
Whatever the fix, CI should gain a Node job that runs ./stpa run Examples/ledgerline end-to-end. A claim about a runtime that no job exercises is not a tested claim.
Reproduce
node --version # v25.9.0
./stpa --help # works
node Tools/RenderReport.ts --help # SyntaxError
./stpa run Examples/ledgerline # SyntaxError, no report
bun stpa run Examples/ledgerline # works
Also noticed
Tools/DiscoveryGate.ts:275 writes its template with writeFileSync and no mkdir, so pointing it at a directory with no .stpa/ inside dies with a raw ENOENT stack trace instead of a usable message.
- Several tool usage strings still say
bun ControlInventory.ts, which contradicts the Node-or-Bun claim.
- The committed
Examples/ledgerline/REPORT.html is stale against RenderReport.ts — regenerating it adds 5 lines of .corr CSS that a later commit introduced.
🤖 Generated with Claude Code
What
PR #9 (
59c6861 feat: run on Node or Bun — Bun is no longer an install prerequisite) does not hold. On Node v25.9.0, everystpasubcommand that spawns a tool fails:Only
./stpa --helpworks, because the launcher never spawns a child. Bun is fine:bun stpa runcompletes the whole pipeline.Root cause
The two halves disagree about module system, and fixing one breaks the other:
Tools/*.tsare ESM. The repo has nopackage.json, so Node resolves.tsas CommonJS and everyimportis a syntax error.--experimental-strip-typesdoes not change this — it strips types, it does not change module resolution.package.jsonwith{"type":"module"}fixes every tool — and then breaks the launcher, becausestpais CJS:So a fix needs both halves. Options:
package.jsonwith{"type":"module"}and convertstpato ESMimport(it usesrequireat lines 24-26), or.mtsand leave the launcher alone, orstpaCJS by giving it a.cjsextension, orcreateRequire.Why CI did not catch it
.github/workflows/ci.ymlinstallsoven-sh/setup-bun@v2, invokes tools asbun Tools/X.ts, and never runs Node at all. It also never exercises./stpa <subcommand>past--help. The one runtime PR #9 was written to support is the one runtime CI does not test — so the feature shipped green and broken.Whatever the fix, CI should gain a Node job that runs
./stpa run Examples/ledgerlineend-to-end. A claim about a runtime that no job exercises is not a tested claim.Reproduce
Also noticed
Tools/DiscoveryGate.ts:275writes its template withwriteFileSyncand nomkdir, so pointing it at a directory with no.stpa/inside dies with a raw ENOENT stack trace instead of a usable message.bun ControlInventory.ts, which contradicts the Node-or-Bun claim.Examples/ledgerline/REPORT.htmlis stale againstRenderReport.ts— regenerating it adds 5 lines of.corrCSS that a later commit introduced.🤖 Generated with Claude Code