Dep: replace inquirer with existing node:readline for all interactive prompts#368
Dep: replace inquirer with existing node:readline for all interactive prompts#368
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR replaces inquirer-based interactive prompts with lightweight node:readline utilities to reduce dependency surface area while preserving existing “confirm” and “select from list” UX in the CLI.
Changes:
- Introduces
promptForSelection()(numbered list prompt) and migratesInteractiveHelperselection flows to it. - Extends
promptForConfirmation()with adefaultValueparameter (and updates “Did you mean?” flows to default to “yes” on Enter). - Removes now-dead inquirer/readline-restore helper code and updates tests/docs/config accordingly.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/utils/prompt-selection.ts |
New readline-based numbered selection prompt utility. |
src/utils/prompt-confirmation.ts |
Adds defaultValue behavior + suffix updates for confirmation prompts. |
src/services/interactive-helper.ts |
Migrates account/app/key selection to promptForSelection(). |
src/hooks/command_not_found/did-you-mean.ts |
Uses promptForConfirmation(..., true) for interactive “Did you mean?” confirmation. |
src/base-topic-command.ts |
Uses promptForConfirmation(..., true) for “Did you mean?” confirmation on topic commands. |
src/utils/readline-helper.ts |
Deletes inquirer-specific readline restoration helper. |
src/hooks/command_not_found/prompt-utils.ts |
Deletes dead prompt helper utilities. |
test/unit/utils/prompt-selection.test.ts |
Adds unit tests for promptForSelection(). |
test/unit/utils/prompt-confirmation.test.ts |
Adds tests for defaultValue + suffix behavior. |
test/unit/services/interactive-helper.test.ts |
Updates tests to mock promptForSelection() instead of inquirer. |
test/unit/hooks/interactive-did-you-mean.test.ts |
Updates tests to mock promptForConfirmation() and removes readline-restore assertions. |
test/unit/commands/did-you-mean.test.ts |
Updates expected prompt formatting from (Y/n) to [Y/n]. |
package.json |
Removes inquirer, @inquirer/prompts, and @types/inquirer. |
pnpm-lock.yaml |
Lockfile updates after dependency removals. |
docs/Interactive-REPL.md |
Updates docs to reference node:readline over inquirer. |
AGENTS.md |
Updates guidance to use promptForConfirmation() for destructive confirmations. |
.github/dependabot.yml |
Removes inquirer-specific ignore rule. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
6f1d2f7 to
92cf223
Compare
…ilities Address PR #368 review comments: add settled/finish guard pattern to prevent Promise hangs on Ctrl+C/EOF in both promptForConfirmation and promptForSelection, early-return null for empty choices, and enforce strict integer validation (/^\d+$/) to reject partial numeric input like "2abc" or "2.5".
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 17 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
src/utils/readline-helper.ts:48
- In strict TS mode,
process.stdin.isRawis typically typed asboolean | undefined, andsetRawModemay not exist unless stdin is a TTY. As written,stdin.setRawMode(isRaw)can fail type-checking (and can throw at runtime ifsetRawModeis missing). Consider guarding withtypeof stdin.setRawMode === "function"and passing a definite boolean (e.g.,stdin.setRawMode(Boolean(isRaw))orstdin.setRawMode(isRaw ?? false)).
// Restore terminal settings
if (stdin.isTTY) {
stdin.setRawMode(isRaw);
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…eadline Replace all inquirer-based prompts with native node:readline utilities. Add defaultValue parameter to promptForConfirmation() for "Did you mean?" flows. Create promptForSelection() utility for interactive list selection. Delete dead code (PromptHelper class, InteractiveHelper.confirm()). Removes ~44 transitive packages from node_modules.
…ilities Address PR #368 review comments: add settled/finish guard pattern to prevent Promise hangs on Ctrl+C/EOF in both promptForConfirmation and promptForSelection, early-return null for empty choices, and enforce strict integer validation (/^\d+$/) to reject partial numeric input like "2abc" or "2.5".
68d5d88 to
b0c1d70
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 18 changed files in this pull request and generated 5 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)
test/unit/hooks/interactive-did-you-mean.test.ts:67
promptForConfirmationis avi.fn()module mock, butafterEachonly callsvi.restoreAllMocks(), which doesn't clear the call history ofvi.fnmocks. This file readsvi.mocked(promptForConfirmation).mock.calls[0], so earlier calls from previous tests can shift indexes and make assertions unreliable. Clear/reset the mock inbeforeEach/afterEach(e.g.vi.mocked(promptForConfirmation).mockClear()orvi.clearAllMocks()alongside restoring spies).
// Reset promptForConfirmation mock to auto-confirm
vi.mocked(promptForConfirmation).mockResolvedValue(true);
});
afterEach(function () {
process.env = originalEnv;
vi.restoreAllMocks();
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| afterEach(function () { | ||
| vi.restoreAllMocks(); | ||
| }); |
| /** | ||
| * Helper function to safely run inquirer prompts in interactive mode | ||
| * Returns the interactive REPL's readline interface if one is registered on | ||
| * `globalThis.__ablyInteractiveReadline`, otherwise `null`. The interactive | ||
| * command (`src/commands/interactive.ts`) sets this global when the REPL is | ||
| * active so that nested prompts can pause and restore its state. | ||
| */ | ||
| export function getInteractiveReadline(): readline.Interface | null { | ||
| const value = (globalThis as Record<string, unknown>) | ||
| .__ablyInteractiveReadline; | ||
| return (value as readline.Interface | null | undefined) ?? null; | ||
| } |
The project targets Node 22+ which has a mature
node:readlinemodule. Inquirer pulled in ~15-20 transitivedependencies (
rxjs,ansi-escapes,cli-cursor,mute-stream, etc.) adding supply chain surface and ~3-5 MB tonode_modules for features we don't need (password input, checkboxes, editor prompts). All prompt use cases
(confirmation + list selection) are well served by
node:readlineSummary
inquirer,@inquirer/prompts, and@types/inquirerdependencies (~44 transitive packages eliminated)defaultValueparameter topromptForConfirmation()to preserve Enter-as-yes behavior for "Did you mean?"prompts
promptForSelection()utility (src/utils/prompt-selection.ts) — numbered-list selector usingnode:readline, replacing inquirer's arrow-key list promptInteractiveHelper.selectAccount/selectApp/selectKeyto usepromptForSelection()base-topic-command.tsanddid-you-mean.tshook topromptForConfirmation()prompt-utils.ts(entire file),InteractiveHelper.confirm(),readline-helper.tsTODO
inquirerdependency ( will mostly beswitchcommands )node:readline, check changes behaviour, make sure operational consistency is preserved.