Skip to content

chore(deps): replace inquirer with @inquirer/select#1136

Open
ikeyan wants to merge 3 commits intoOpenAPITools:masterfrom
ikeyan:inquirer-select
Open

chore(deps): replace inquirer with @inquirer/select#1136
ikeyan wants to merge 3 commits intoOpenAPITools:masterfrom
ikeyan:inquirer-select

Conversation

@ikeyan
Copy link

@ikeyan ikeyan commented Feb 16, 2026

Supersedes #819, #969, #1048.
Replaces dependency inquirer with @inquirer/select.
(Since Node >=16 is supported, we cannot upgrade inquirer or @inquirer/select further.)

There are differences in their behavior:

  • When Ctrl+C is pressed:
    • inquirer did not handle Ctrl+C, so the process naturally exits 0.
    • @inquirer/select throws Error: User force closed the prompt with ....
      • I explicitly catch them and process.exit(0).
  • Hint:
    • inquirer shows (Use arrow keys) on the right of the prompt until the user hits any key and, when necessary, (Move up and down to reveal more choices) at the bottom.
    • @inquirer/select shows:
      • When the options fit the pageSize, (Use arrow keys) on the right of the prompt until the user hits any key
      • Otherwise,(Use arrow keys to reveal more choices) at the bottom of the options
    • I think the new behavior is better.
  • Separators:
    • inquirer automatically dims the separator.
    • @inquirer/select shows the separator without styling.
      • I explicitly dim the separator text.

Bug Fixes in UIService#list

While migrating, I fixed several legacy issues in the pageSize calculation:

  1. Prompt visibility: Fixed a bug where the prompt would fail to display if the choices did not contain any Separator.
  2. Excessive shrinking: Fixed an issue where the pageSize became unnecessarily small when multiple Separator instances were present.
  3. Optimized calculation:
    • Old: process.stdout.rows - separatorCount - 1
    • New: Math.max(1, process.stdout.rows - 2)
    • This ensures a consistent and usable number of visible items regardless of the number of separators.

Manual testing

Old

old.mov
  • npx tsx ./src/manual-test-ui-service-list l 0,80
    • select one
    • Ctrl+C, echo $?
  • npx tsx ./src/manual-test-ui-service-list l 45,80
  • npx tsx ./src/manual-test-ui-service-list t 80
    • select one
    • Ctrl+C, echo $?

New

2026-02-16.22.48.06.mov
  • npx tsx ./src/manual-test-ui-service-list l 0,80
    • select one
    • Ctrl+C, echo $?
  • npx tsx ./src/manual-test-ui-service-list l 45,80
  • npx tsx ./src/manual-test-ui-service-list t 80
    • select one
    • Ctrl+C, echo $?
  • npx tsx ./src/manual-test-ui-service-list l 1,5
  • npx tsx ./src/manual-test-ui-service-list t 5

Script

apps/generator-cli/src/manual-test-ui-service-list.ts:

import { styleText } from 'util';
import { UIService } from './app/services/ui.service';

let Separator: typeof import('@inquirer/select').Separator;
try {
  Separator = require('inquirer').Separator;
} catch {
  Separator = require('@inquirer/select').Separator;
}

const fillRange = <T>(n: number, mapper: (i: number) => T) => Array.from({ length: n }, (_, i) => mapper(i));

async function testList(arg: string) {
  const ui = new UIService();

  // Parse command line arguments: "separatorCount,itemCount" (e.g., "4,80", ",80", or omitted)
  // Default: "0,5"
  const [separatorStr = '0', itemStr = '5'] = arg.split(',');
  const separatorCount = separatorStr ? parseInt(separatorStr, 10) : 0;
  const itemCount = itemStr ? parseInt(itemStr, 10) : 5;

  const options = {
    name: 'test',
    message: 'Select one option for manual UIService#list verification:',
    choices: [
      ...fillRange(separatorCount, () => new Separator(styleText('dim', '--- separator ---'))),
      ...fillRange(itemCount, (i) => ({ name: `Choice ${i + 1}`, value: `choice${i + 1}` })),
    ],
  };
  const selected = await ui.list<string>(options);

  console.log(`Selected value: ${selected}`);
}

async function testTable(arg: string) {
  const ui = new UIService();

  // Parse command line arguments: "itemCount" (e.g., "10")
  // Default: "5"
  const itemCount = arg ? parseInt(arg, 10) : 5;

  const rows = fillRange(itemCount, (i) => ({
    value: { id: i + 1, name: `Item ${i + 1}` },
    short: `item${i + 1}`,
    row: {
      '☐': i % 3 === 0 ? '☒' : '☐',
      id: `${i + 1}`,
      name: `Item ${i + 1}`,
      status: i % 2 === 0 ? styleText('green', 'active') : styleText('red', 'inactive'),
      type: i % 3 === 0 ? 'premium' : 'standard',
    },
  }));

  const options = {
    name: 'test',
    message: 'Select one option for manual UIService#table verification:',
    rows,
  };
  const selected = await ui.table(options);

  console.log(`Selected value:`, selected);
}

async function main() {
  const command = process.argv[2] || 'list';
  const argument = process.argv[3] || '';

  if (command === 'list' || command === 'l') {
    await testList(argument || '0,5');
  } else if (command === 'table' || command === 't') {
    await testTable(argument || '5');
  } else {
    console.error(`Unknown command: ${command}`);
    console.error('Usage:');
    console.error('  (list|l) [separatorCount,itemCount]  - Test UIService#list (default: 0,5)');
    console.error('  (table|t) [itemCount]                - Test UIService#table (default: 5)');
    process.exit(1);
  }
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Summary by cubic

Replace inquirer with @inquirer/select to simplify prompts and improve UX. Ctrl+C now exits cleanly (code 0), choices show a checkmark with clearer hints, and table headers/separators are dimmed with stable paging.

  • Bug Fixes

    • Prompt renders even with no separators.
    • Prevented page shrinking with many separators.
    • Consistent pageSize: Math.max(1, process.stdout.rows - 2).
    • Updated VersionManagerController and its unit test to match the new UIService API (no name field on list/table).
  • Dependencies

    • Removed inquirer and @types/inquirer.
    • Added @inquirer/select@^1.3.3.

Written for commit 5244f82. Summary will update on new commits.

Copy link
Contributor

@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.

1 issue found across 4 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/generator-cli/src/app/services/ui.service.ts">

<violation number="1" location="apps/generator-cli/src/app/services/ui.service.ts:5">
P2: util.styleText is only available in Node >=20.12.0, but this package declares support for Node >=16. Using styleText will crash on Node 16–20.11 at runtime.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

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