-
Notifications
You must be signed in to change notification settings - Fork 31
feat: atmn precheck with interactive install prompt #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/atmn-v2.1
Are you sure you want to change the base?
Conversation
Add package.json precheck before CLI runs. If atmn is not installed and the terminal is interactive, display a React Ink prompt allowing users to choose between npm, pnpm, or bun for installation. This prevents type errors in autumn.config.ts from missing atmn package. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 files reviewed, 2 comments
| async function main() { | ||
| if (!checkAtmnInstalled() && process.stdout.isTTY) { | ||
| const { waitUntilExit } = render(<InstallPrompt />); | ||
| await waitUntilExit(); | ||
| } | ||
|
|
||
| program.parse(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Precheck runs before flags
main() runs the interactive install precheck before program.parse(), so global flags like --headless (which you set in the preAction hook) are not applied yet. This means atmn --headless ... will still see process.stdout.isTTY as true and can trigger the Ink InstallPrompt, breaking CI/agent usage where --headless is expected to suppress interactivity.
Prompt To Fix With AI
This is a comment left during a code review.
Path: atmn/src/cli.tsx
Line: 455:462
Comment:
**Precheck runs before flags**
`main()` runs the interactive install precheck before `program.parse()`, so global flags like `--headless` (which you set in the `preAction` hook) are not applied yet. This means `atmn --headless ...` will still see `process.stdout.isTTY` as true and can trigger the Ink `InstallPrompt`, breaking CI/agent usage where `--headless` is expected to suppress interactivity.
How can I resolve this? If you propose a fix, please make it concise.| try { | ||
| execSync(commands[item.value], { stdio: "inherit" }); | ||
| setState("success"); | ||
| setTimeout(() => exit(), 500); | ||
| } catch (err) { | ||
| setError( | ||
| err instanceof Error ? err.message : "Installation failed", | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CLI can hang on failure
When execSync(...) throws, you set error but never call exit(), so the Ink renderer in cli.tsx will wait indefinitely on waitUntilExit() with no way to continue unless the user manually terminates the process. The error UI renders, but the process doesn’t exit or return control to program.parse().
Prompt To Fix With AI
This is a comment left during a code review.
Path: atmn/src/views/react/install/InstallPrompt.tsx
Line: 34:42
Comment:
**CLI can hang on failure**
When `execSync(...)` throws, you set `error` but never call `exit()`, so the Ink renderer in `cli.tsx` will wait indefinitely on `waitUntilExit()` with no way to continue unless the user manually terminates the process. The error UI renders, but the process doesn’t exit or return control to `program.parse()`.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 3 files
Confidence score: 2/5
- The precheck in
atmn/src/cli.tsxruns beforeprogram.parse(), so--headlessisn’t honored and CI/agent workflows may unexpectedly prompt for input. - In
atmn/src/views/react/install/InstallPrompt.tsx, the error handler doesn’t callexit(), so failed installs can hang indefinitely andwaitUntilExit()never resolves. - These are high-severity, user-facing CLI workflow breaks, so the change carries elevated risk despite limited scope.
- Pay close attention to
atmn/src/cli.tsxandatmn/src/views/react/install/InstallPrompt.tsx- ensure headless parsing and exit-on-error are handled.
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="atmn/src/views/react/install/InstallPrompt.tsx">
<violation number="1" location="atmn/src/views/react/install/InstallPrompt.tsx:38">
P1: The error handler sets state but never calls `exit()`, causing the CLI to hang indefinitely when installation fails. The `waitUntilExit()` in cli.tsx will never resolve because the Ink app remains running. Add `exit()` after setting the error to allow the process to terminate gracefully.</violation>
</file>
<file name="atmn/src/cli.tsx">
<violation number="1" location="atmn/src/cli.tsx:456">
P1: The interactive precheck runs before `program.parse()`, so CLI flags like `--headless` haven't been processed yet. This breaks CI/agent workflows where `--headless` is expected to suppress interactivity. Consider parsing a minimal flag check first, or checking for `--headless` in `process.argv` before the precheck.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| execSync(commands[item.value], { stdio: "inherit" }); | ||
| setState("success"); | ||
| setTimeout(() => exit(), 500); | ||
| } catch (err) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The error handler sets state but never calls exit(), causing the CLI to hang indefinitely when installation fails. The waitUntilExit() in cli.tsx will never resolve because the Ink app remains running. Add exit() after setting the error to allow the process to terminate gracefully.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At atmn/src/views/react/install/InstallPrompt.tsx, line 38:
<comment>The error handler sets state but never calls `exit()`, causing the CLI to hang indefinitely when installation fails. The `waitUntilExit()` in cli.tsx will never resolve because the Ink app remains running. Add `exit()` after setting the error to allow the process to terminate gracefully.</comment>
<file context>
@@ -0,0 +1,95 @@
+ execSync(commands[item.value], { stdio: "inherit" });
+ setState("success");
+ setTimeout(() => exit(), 500);
+ } catch (err) {
+ setError(
+ err instanceof Error ? err.message : "Installation failed",
</file context>
|
|
||
| program.parse(); | ||
| async function main() { | ||
| if (!checkAtmnInstalled() && process.stdout.isTTY) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: The interactive precheck runs before program.parse(), so CLI flags like --headless haven't been processed yet. This breaks CI/agent workflows where --headless is expected to suppress interactivity. Consider parsing a minimal flag check first, or checking for --headless in process.argv before the precheck.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At atmn/src/cli.tsx, line 456:
<comment>The interactive precheck runs before `program.parse()`, so CLI flags like `--headless` haven't been processed yet. This breaks CI/agent workflows where `--headless` is expected to suppress interactivity. Consider parsing a minimal flag check first, or checking for `--headless` in `process.argv` before the precheck.</comment>
<file context>
@@ -450,4 +452,13 @@ const originalEmit = process.emitWarning as any;
-program.parse();
+async function main() {
+ if (!checkAtmnInstalled() && process.stdout.isTTY) {
+ const { waitUntilExit } = render(<InstallPrompt />);
+ await waitUntilExit();
</file context>
Summary
Implementation
checkAtmnInstalled(): Utility to check if atmn is in package.jsonInstallPrompt: React Ink component with SelectMenu for package manager choiceprogram.parse()in async main() that runs precheck first🤖 Generated with Claude Code
Summary by cubic
Adds a pre-run check to detect if the atmn package is missing and, in interactive terminals, prompts users to install it via npm, pnpm, or bun. This prevents autumn.config.ts type errors and smooths first-time CLI usage.
Written for commit ec8132d. Summary will update on new commits.
Greptile Overview
Greptile Summary
Adds a startup precheck that looks for
atmnin the project’spackage.jsonand, when running interactively, renders an Ink prompt offering to install it via npm/pnpm/bun before continuing with normal CLI parsing.Key changes
checkAtmnInstalled()to detect whetheratmnis listed independencies/devDependencies.InstallPromptUI to installatmninteractively.main()that runs the precheck before callingprogram.parse().Must-fix issues
program.parse(), so--headlesscan’t prevent the interactive prompt.waitUntilExit().Confidence Score: 2/5
--headlesscannot suppress interactivity because the precheck runs before option parsing, and (2) install failure leaves Ink running without exit, hanging the CLI. The rest of the changes are localized and straightforward.Important Files Changed
atmnisn’t in package.json. Issue: precheck runs beforeprogram.parse(), so--headlesscan’t suppress interactivity.checkAtmnInstalled()that checks foratmnin dependencies/devDependencies via cwd package.json; no functional issues found.npm/pnpm/buninstall viaexecSync. Issue: on install failure it sets an error state but never exits, causingwaitUntilExit()to hang.Sequence Diagram
sequenceDiagram participant U as User participant CLI as atmn/src/cli.tsx participant PC as atmn/src/lib/precheck.ts participant Ink as Ink renderer participant IP as InstallPrompt participant PM as Package manager U->>CLI: Run `atmn ...` CLI->>PC: checkAtmnInstalled() alt atmn missing AND stdout is TTY CLI->>Ink: render(<InstallPrompt />) Ink->>IP: mount component IP->>U: show SelectMenu (npm/pnpm/bun) U->>IP: select package manager IP->>PM: execSync("<pm> add/install atmn") alt install succeeds IP-->>Ink: set state=success IP-->>CLI: exit() triggers waitUntilExit resolve CLI->>CLI: program.parse() else install fails IP-->>Ink: set error state Note over CLI,IP: Current code never exits -> CLI awaits waitUntilExit forever end else atmn present OR non-TTY CLI->>CLI: program.parse() endContext used:
dashboard- CLAUDE.md (source)