A CLI's exit codes and version output are contracts — scripts and CI wrap corecoder-ts and depend on them. The TS port silently regressed three of them against the Python original and its own engines claim:
Error vs interrupt exit codes were collapsed — the Python original exits 1 on error and 130 on ^C; the TS port returned 130 for both. Any wrapper that checks $? can't tell a crash from a user cancel.
Version was hardcoded — src/cli.ts shipped const VERSION = '0.1.0' while package.json is the real source of truth; every release bump risks --version drifting.
npm test breaks on the declared Node floor — node --test dist/tests/*.test.js relies on the test runner expanding globs, which only landed in Node 21. On Node 18/20 — which engines claims to support — and on Windows cmd (which never expands), the literal pattern is passed through and the run fails.
Changes
Distinct exit codes (src/cli.ts)
runTurn now reports whether a null result was a cancellation (aborted) or a failure.
New exported turnExitCode(): 0 success, 130 ^C interrupt, 1 error — matching the Python original (KeyboardInterrupt -> 130, Exception -> 1) and POSIX convention (128 + SIGINT).
Version from package.json (src/cli.ts)
VERSION (now exported) is read at runtime via createRequire relative to the module file — works both in the repo (dist/src/cli.js -> ../../package.json) and in a published tarball (same layout). A unit test pins it to package.json so drift fails CI.
Cross-version test runner (scripts/run-tests.mjs, package.json)
New small runner resolves dist/tests/*.test.js itself and passes explicit paths to node --test — identical behavior on Node 18–24 and every shell, and new test files are picked up automatically (no script edits on adding a test).
Tests (tests/cli.test.ts, 2 new)
turnExitCode: 0 / 130 / 1 matrix
VERSION equals package.json version
All 26 tests pass (npm test via the new runner); --version prints corecoder-ts 0.1.0; demo exits 0.
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
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.
Why this is core
A CLI's exit codes and version output are contracts — scripts and CI wrap corecoder-ts and depend on them. The TS port silently regressed three of them against the Python original and its own engines claim:
Changes
Distinct exit codes (src/cli.ts)
Version from package.json (src/cli.ts)
Cross-version test runner (scripts/run-tests.mjs, package.json)
Tests (tests/cli.test.ts, 2 new)
All 26 tests pass (npm test via the new runner); --version prints corecoder-ts 0.1.0; demo exits 0.