Skip to content

Conversation

@SirTenzin
Copy link
Member

@SirTenzin SirTenzin commented Feb 8, 2026

Summary

  • Add package.json precheck before CLI runs
  • Display React Ink prompt if atmn is not installed (interactive mode only)
  • Allow users to choose between npm, pnpm, or bun for installation
  • Prevents type errors in autumn.config.ts from missing atmn dependency

Implementation

  • checkAtmnInstalled(): Utility to check if atmn is in package.json
  • InstallPrompt: React Ink component with SelectMenu for package manager choice
  • CLI precheck: Wrapped program.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.

  • New Features
    • checkAtmnInstalled() reads package.json deps/devDeps to verify atmn.
    • Ink InstallPrompt with SelectMenu runs install via npm/pnpm/bun and shows success/error states.
    • CLI wraps program.parse() in an async main() and renders the prompt only when TTY is available.

Written for commit ec8132d. Summary will update on new commits.

Greptile Overview

Greptile Summary

Adds a startup precheck that looks for atmn in the project’s package.json and, when running interactively, renders an Ink prompt offering to install it via npm/pnpm/bun before continuing with normal CLI parsing.

Key changes

  • Improvements: Introduce checkAtmnInstalled() to detect whether atmn is listed in dependencies/devDependencies.
  • Improvements: Add an Ink-based InstallPrompt UI to install atmn interactively.
  • API changes: Wrap CLI startup in an async main() that runs the precheck before calling program.parse().

Must-fix issues

  • Precheck executes before program.parse(), so --headless can’t prevent the interactive prompt.
  • If installation fails, the prompt renders an error but never exits, leaving the CLI stuck awaiting waitUntilExit().

Confidence Score: 2/5

  • This PR has clear functional blockers in headless/CI mode and on install failure paths.
  • Two issues are likely to break real usage: (1) --headless cannot 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.
  • atmn/src/cli.tsx and atmn/src/views/react/install/InstallPrompt.tsx

Important Files Changed

Filename Overview
atmn/src/cli.tsx Adds a pre-run check that renders an Ink install prompt when atmn isn’t in package.json. Issue: precheck runs before program.parse(), so --headless can’t suppress interactivity.
atmn/src/lib/precheck.ts Introduces checkAtmnInstalled() that checks for atmn in dependencies/devDependencies via cwd package.json; no functional issues found.
atmn/src/views/react/install/InstallPrompt.tsx Adds an Ink UI that runs npm/pnpm/bun install via execSync. Issue: on install failure it sets an error state but never exits, causing waitUntilExit() 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()
    end
Loading

Context used:

  • Context from dashboard - CLAUDE.md (source)

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>
@vercel
Copy link

vercel bot commented Feb 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
autumn-ui Error Error Feb 8, 2026 2:30am

Request Review

Copy link

@greptile-apps greptile-apps bot left a 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

Edit Code Review Agent Settings | Greptile

Comment on lines +455 to +462
async function main() {
if (!checkAtmnInstalled() && process.stdout.isTTY) {
const { waitUntilExit } = render(<InstallPrompt />);
await waitUntilExit();
}

program.parse();
}
Copy link

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.

Comment on lines +34 to +42
try {
execSync(commands[item.value], { stdio: "inherit" });
setState("success");
setTimeout(() => exit(), 500);
} catch (err) {
setError(
err instanceof Error ? err.message : "Installation failed",
);
}
Copy link

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.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a 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.tsx runs before program.parse(), so --headless isn’t honored and CI/agent workflows may unexpectedly prompt for input.
  • In atmn/src/views/react/install/InstallPrompt.tsx, the error handler doesn’t call exit(), so failed installs can hang indefinitely and waitUntilExit() 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.tsx and atmn/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) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 8, 2026

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>
Fix with Cubic


program.parse();
async function main() {
if (!checkAtmnInstalled() && process.stdout.isTTY) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 8, 2026

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>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant