fix: ship a node-runtime CLI to actually fix stdout truncation (#20)#23
Merged
Merged
Conversation
v2.5.1 removed all process.exit() calls but the truncation persisted: the real cause is the `#!/usr/bin/env bun` shebang. Bun drops queued stdout writes on exit even without an explicit process.exit. Direct proof: the same bundled dist/cli.js produces 10385 bytes piped under node and 512 bytes piped under bun. Changes: - Shebang `bun` -> `node`; tsup already emits plain ESM with no bun-specific runtime APIs, so no behavioral change beyond the fix. - engines.bun -> engines.node ">=20". Bun stays as a dev dependency for TS execution, build, and tests; end users only need node. - Add `program.exitOverride()` in cli.ts so commander's --help, --version, and parse-error paths don't call process.exit and race the pipe drain. The CommanderError exit code is forwarded via process.exitCode in the top-level catch. - New regression suite `pipe-truncation.test.ts` spawns the built dist/cli.js under its real shebang and counts bytes received via a real pipe (`cli | cat`). The v2.5.1 fix passed because the error payload fit in one 512-byte pipe buffer; this test uses `--help` (~649 bytes) so the regression would now be caught. - CI workflows: build before tests so the new integration suite has dist/cli.js to exercise. - CLAUDE.md: document the runtime split (bun for dev, node for ship) and the commander.exitOverride() requirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
v2.5.1 removed
process.exit()calls but issue #20 reproduced anyway. Root cause is the#!/usr/bin/env bunshebang — bun drops queued stdout writes on exit even without an explicitprocess.exit(). The same bundleddist/cli.js:node: 10385 bytes piped ✅bun(current shebang): 512 bytes piped ❌This PR:
#!/usr/bin/env node(tsup emits plain ESM; no bun-runtime APIs in the bundle).engines.bun, addsengines.node: ">=20". Bun remains a dev dependency for TS execution, build, and tests.program.exitOverride()so commander's--help,--version, and parse-error paths don't callprocess.exitand race the pipe drain. TheCommanderError.exitCodeis forwarded viaprocess.exitCode.src/lib/__tests__/pipe-truncation.test.ts, an end-to-end regression suite that spawns the builtdist/cli.jsunder its real shebang and counts bytes received through a realcli | catpipe. The v2.5.1 test passed because the error payload fit in one 512-byte pipe buffer — this one uses--help(~649 bytes) so the regression would now be caught.dist/cli.jsto exercise.exitOverride()requirement.Test plan
bun run typecheckcleanbun run lintcleanbun run test(vitest) — 24/24 passbun test(bun native, mirrors CI) — 24/24 passdist/cli.js inbox list 2>/dev/null | cat | wc -c→ 10385 (was 512)dist/cli.js --help | cat | wc -c→ 649 (was 512)🤖 Generated with Claude Code