Add @base-org/account-cli package scaffolding#257
Conversation
✅ Heimdall Review Status
|
8996555 to
0b157a4
Compare
Establish the account-cli workspace package with build tooling, entry point, type system, and output formatting — ready for commands to be added incrementally. Made-with: Cursor
0b157a4 to
d907e87
Compare
Vitest exits with code 1 when no test files are found, which caused the Tests job to fail. Add tests for CLIError and the output formatting helpers. Made-with: Cursor
f83df71 to
15925ff
Compare
spencerstock
left a comment
There was a problem hiding this comment.
🔴 Changes requested · 72/100
The scaffolding for @base-org/account-cli is well-structured with clean separation of concerns (commands/core architecture), good test coverage for the error types and output helpers, and proper workspace integration.
However, there is one critical issue: TypeScript's tsc does not preserve the #!/usr/bin/env node shebang from the source file, so dist/index.js will lack it after build. This means the base-account binary entry won't work when the package is installed globally or via npx. A post-build shebang injection step or a switch to a bundler that handles this is needed.
Additionally, the formatOutput function has identical logic in both JSON and non-JSON branches, making the --json flag a no-op for output formatting. The license mismatch with the root package (MIT vs Apache-2.0) and missing LICENSE file should also be resolved before publishing.
Confidence: 72/100 · 🔴 1 critical · 🟡 2 suggestions
🔧 Fix with prompt
A reviewer gave these comments as feedback. Validate them and fix all the ones that need to be fixed.
- [critical] packages/account-cli/src/index.ts:1-1
**critical:** The `#!/usr/bin/env node` shebang is in the TypeScript source, but `tsc` does **not** preserve shebangs when compiling. The `bin` entry in `package.json` points to `./dist/index.js`, which will lack the shebang after build.
When installed via `npm install -g` or run via `npx`, `base-account` will fail to execute (the OS won't know to invoke Node).
**Fix options:**
1. Add a post-build script: `echo '#!/usr/bin/env node' | cat - dist/index.js > temp && mv temp dist/index.js`
2. Switch to a bundler like `tsup` or `esbuild` that preserves/injects shebangs
3. Use a small shell wrapper as the bin entry
- [suggestion] packages/account-cli/src/output/index.test.ts:22-25
**suggestion:** This test only asserts `toHaveBeenCalledOnce()` without verifying the output content for the `json=false` case. Once the human-readable formatter is differentiated from JSON output, this test should assert on the actual format to prevent regressions.
- [suggestion] packages/account-cli/package.json:14-14
**suggestion:** The root `package.json` uses `"license": "MIT"` while this package specifies `"license": "Apache-2.0"`. The `files` array also includes `LICENSE` but no LICENSE file exists in `packages/account-cli/`. Please verify the intended license and add the corresponding LICENSE file, or it will be missing from the published package.
SHA 15925ffc · gemini-3-pro-preview → claude-opus-4-6 · [bot-raiser]
| @@ -0,0 +1,10 @@ | |||
| #!/usr/bin/env node | |||
There was a problem hiding this comment.
[bot-raiser] critical
critical: The #!/usr/bin/env node shebang is in the TypeScript source, but tsc does not preserve shebangs when compiling. The bin entry in package.json points to ./dist/index.js, which will lack the shebang after build.
When installed via npm install -g or run via npx, base-account will fail to execute (the OS won't know to invoke Node).
Fix options:
- Add a post-build script:
echo '#!/usr/bin/env node' | cat - dist/index.js > temp && mv temp dist/index.js - Switch to a bundler like
tsuporesbuildthat preserves/injects shebangs - Use a small shell wrapper as the bin entry
| it('writes output to stdout when json=false', () => { | ||
| formatOutput({ value: 42 }, false); | ||
| expect(stdoutSpy).toHaveBeenCalledOnce(); | ||
| }); |
There was a problem hiding this comment.
suggestion: This test only asserts toHaveBeenCalledOnce() without verifying the output content for the json=false case. Once the human-readable formatter is differentiated from JSON output, this test should assert on the actual format to prevent regressions.
There was a problem hiding this comment.
yup, this PR doesn't have non json formatter yet, this is just a placeholder test cases, will add it in human output formatter PR!
| ], | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, |
There was a problem hiding this comment.
suggestion: The root package.json uses "license": "MIT" while this package specifies "license": "Apache-2.0". The files array also includes LICENSE but no LICENSE file exists in packages/account-cli/. Please verify the intended license and add the corresponding LICENSE file, or it will be missing from the published package.
c9f9bf0 to
a80adbb
Compare
Add postbuild script to prepend #!/usr/bin/env node to dist/index.js since tsc strips shebangs. Align license to MIT to match root package and remove non-existent LICENSE from files array. Made-with: Cursor
a80adbb to
075ebf0
Compare
spencerstock
left a comment
There was a problem hiding this comment.
🟡 Follow-up needed on prior feedback · 77/100 · Re-review
Previous comment assessment:
-
License (Comment 1): Resolved. The
package.jsonnow has"license": "MIT"(matching root), and thefilesarray no longer includesLICENSE, avoiding shipping a missing file. -
Shebang (Comment 2): Resolved. A
postbuildscript was added:printf '#!/usr/bin/env node\n' | cat - dist/index.js > dist/index.tmp && mv dist/index.tmp dist/index.js. This correctly prepends the shebang to the compiled output. -
Test assertion for json=false (Comment 3): Not addressed. The test at line 23-24 of
output/index.test.tsstill only assertstoHaveBeenCalledOnce()without verifying the actual output content for thejson=falsecase. Given that the implementation is still identical for both branches, this is understandable but the test gap remains. -
Identical branches in formatOutput (Comment 4): Not addressed. Lines 4-8 of
output/index.tsstill have identicalif/elsebranches — both emitJSON.stringify(data, null, 2). The human-readable path is indistinguishable from JSON output.
New issue sweep:
- The
postbuildscript usesprintfandcatwhich are POSIX utilities — this will fail on Windows without WSL/Git Bash. For a scaffolding PR this is acceptable but worth noting. - No other regressions or critical new issues found in the changed hunks.
Confidence: 77/100
SHA 075ebf00 · claude-opus-4-6
|
@spencerstock thx! comment 3 and comment 4 is true, this PR is just for scaffolding, I'm leaning towards keeping it as-is for now, as we don't have clear picture on what human output is gonna be like yet. We might import some package to prettify the human output for commands, but will get to it once we start implementing actual commands i think |
There was a problem hiding this comment.
can we name this directory something like utils instead?
Made-with: Cursor
Summary
packages/account-cli/as a new workspace package (@base-org/account-cli) withbin: base-account--jsonglobal flag,CLIErrorclass, andformatOutput/formatErrorhelperscommands/+core/) documented in the README for incremental command additionsTest plan
yarn workspace @base-org/account-cli typecheckpassesyarn workspace @base-org/account-cli buildsucceedsnode packages/account-cli/dist/index.js --helpshows expected outputnpx biome lint packages/account-cli/)Made with Cursor