Repository navigation
fix(cli): never prompt or auto-install when nobody is at the terminal - #6617
Conversation
56d0e1c to
6e43f2d
Compare
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits
The prompt wrapper, confirmationRequired() and the auto-install gate look right, and the publish/upgrade contract cases pass locally. One blocker comes from #6616 and surfaces here: people in Cursor or Windsurf terminals, and in Replit shells, count as unattended. That makes "Behavior for a person at a terminal is unchanged" false (inline). Fixing isUnattended() in #6616 clears it.
— Genesis
6e43f2d to
975d2c9
Compare
The base branch was changed.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Edit accuracy: accurate 271 (base branch 271), smooth 129 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
publish and upgrade called the confirmation prompt with no terminal check.
With stdin from /dev/null, publish exited 13; with an open pipe it hung.
Unattended and without --yes, both now exit 2 before doing any work, and
stderr names --yes (upgrade also names --check).
All prompts and spinners now go through ui/prompts.ts, the only module allowed
to import @clack/prompts (a lint rule and a contract test enforce it). Its
confirm, select, text and password refuse to prompt in an unattended run, and
its spinner prints only the final line, on stderr. init, feedback, catalog and
cloud delete decide whether to ask with isUnattended() instead of a TTY check
of their own.
The background auto-install no longer starts in an unattended run, and the
update notice ("Run: npm install -g ...") is not shown while an install for
that version is pending. CI now counts as set for any value but "false" or "0".
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ugh isAgentDriven Attendance now reads isAgentDriven(), so that is what the catalog tests stub to stay independent of the agent running the suite. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
975d2c9 to
49624ea
Compare
There was a problem hiding this comment.
Verdict: APPROVE · re-approval after the rebase onto main · 975d2c9 → 49624ea
The patch is byte-identical (git diff d02c0e7 975d2c9 = git diff origin/main 49624ea), and none of main's newer CLI commits (#6618, #6627) touch prompts or clack. CI on this head passed. The non-required CLI: npx shim (windows-latest) job hit its 10-minute install timeout and passed on rerun.
— Genesis
What
Second of four stacked PRs (base: #6616). Fixes the two P0 findings for agent and CI runs:
publishandupgradecalled the confirmation prompt with no terminal check. With stdin from/dev/null,publishexited 13 after drawing a half prompt; with an open pipe it hung. Unattended and without--yes, both now exit 2 before doing any work, with the explanation on stderr naming--yes(upgradealso names--check).Update available ... Run: npm install -g ...notice is no longer shown while an install for that version is pending, or in an unattended run.Why
An agent that runs
hyperframes publishshould get a fast, clear "pass --yes" instead of a hang or an exit 13. An agent session should not install software in the background.Related work
Stack: #6616 (factory,
isUnattended()) → this PR → help and nags → JSON envelope.How
packages/cli/src/ui/prompts.tsis the only module allowed to import@clack/prompts. A lint rule (no-restricted-imports) bans static imports elsewhere, and the contract test also fails on a dynamicimport("@clack/prompts")outside it. All 18 files that used clack now import the wrapper, a mechanical swap.confirm,select,textandpasswordthrow a usage error (exit 2) whenisUnattended(), so no future command can prompt without a terminal even if it forgets to check. Itsspinnerprints only the final message, as a plain line on stderr, when unattended.confirmationRequired(command, hint)is the shared "pass --yes" error.init,feedback,catalogandcloud deletenow decide whether to ask withisUnattended()instead of their own TTY checks.autoUpdate.ts:isAutoInstallDisabled()includesisUnattended().updateCheck.ts: the notice is suppressed when unattended or whenpendingUpdateis for the advertised version;CIis read with the sharedisCI()(any value butfalseor0).HYPERFRAMES_NO_UPDATE_CHECK,HYPERFRAMES_NO_AUTO_INSTALLandNO_COLORkeep working as before.Behavior for a person at a terminal is unchanged: prompts, spinners and the auto-install work as before.
Test plan
ui/prompts.test.ts; contract test cases forpublishandupgradewithout--yesand for the clack import rule;autoUpdate.test.ts(unattended skips the install),updateCheck.test.ts(no notice when unattended or while an install is pending). Tests that drive prompts or spinners now mock attendance explicitly, so they pass the same way inside an agent and in CI.CI=trueenvironment for the touched filestypecheck,oxlint,oxfmt --check,fallow audit, comment ratchet passdocs/packages/cli.mdx, publish and upgrade flag notesManual run of the built CLI in a project directory,
CLAUDECODE=1, stdin from/dev/null:🤖 Generated with Claude Code