Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: npx biome check

- name: Test
run: pnpm test

- name: Publish to npm
run: pnpm -r publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
pull_request:

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 24
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Lint
run: npx biome check

- name: Test
run: pnpm test
135 changes: 77 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,59 @@
# @inquirer-cli

The `@inquirer-cli` suite provides standalone command-line interface (CLI) tools for various prompt types, leveraging the robust functionality of [Inquirer.js](https://github.com/SBoudrias/Inquirer.js). These tools enable developers to incorporate interactive prompts directly into shell scripts or command pipelines without the need to write custom JavaScript code.
Interactive command-line prompts for shell scripts, powered by [Inquirer.js](https://github.com/SBoudrias/Inquirer.js).

## Installation
The `@inquirer-cli` suite lets you add interactive prompts (text input, confirmations, selections, and more) to any shell script - no JavaScript required.

No installation required. Simply do to start the prompt:
## Quick Start

No installation needed. Run any prompt directly with `npx`:

```bash
$ npx -y @inquirer-cli/<prompt-name> [...args]
name=$(npx -y @inquirer-cli/input "What is your name?")
echo "Hello, $name!"
```

> **Note**: The `-y` flag is used with `npx` to skip the installation prompt. This is necessary because the CLI's output is consumed by `$()` in bash, which would otherwise cause the script to freeze.
> **Why `-y`?** The `-y` flag auto-confirms the `npx` install prompt. Without it, the confirmation prompt would interfere when capturing output with `$()`.

Replace `<prompt-name>` with the desired prompt listed in the next section.
## How It Works

## Prompts
Each prompt renders its UI to **stderr** and writes the user's answer to **stdout**. This means you can capture the answer with `$()` while the prompt remains visible in the terminal.

Each prompt type is available as a separate package under the `@inquirer-cli` scope:
Each package corresponds to an Inquirer.js prompt type and is designed to be used independently.
## Prompts

### [`@inquirer-cli/input`](./packages/input/README.md)

> Uses [@inquirer/input](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/input).

Prompts the user for text input.

Example:
Prompts for free-text input.

```bash
name=$(npx -y @inquirer-cli/input -r "What is your name?")
echo "Hello, $name!"
```

### [`@inquirer-cli/number`](./packages/number/README.md)
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-r, --required` | Reject empty input |
| `-h, --help` | Show help |

> Uses [@inquirer/number](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/number).

Requests a numeric input from the user.
### [`@inquirer-cli/number`](./packages/number/README.md)

Ask the user for their age:
Prompts for numeric input.

```bash
age=$(npx -y @inquirer-cli/number -r "Enter your age")
echo "You are $age years old."
```

### [`@inquirer-cli/confirm`](./packages/confirm/README.md)

> Uses [@inquirer/confirm](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/confirm).
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-r, --required` | Reject empty input |
| `-h, --help` | Show help |

Presents a yes/no confirmation to the user.
### [`@inquirer-cli/confirm`](./packages/confirm/README.md)

Confirm an action with the user:
Prompts for a yes/no confirmation. Outputs `true` or `false`.

```bash
if $(npx -y @inquirer-cli/confirm "Do you want to continue?"); then
Expand All @@ -61,79 +63,96 @@ else
fi
```

### [`@inquirer-cli/select`](./packages/select/README.md)

> Uses [@inquirer/select](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/select).
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-y, --yes` | Default to "yes" instead of "no" |
| `-h, --help` | Show help |

Offers a list of options for the user to select one.
### [`@inquirer-cli/select`](./packages/select/README.md)

Let the user choose a fruit:
Prompts the user to pick one option from a list.

```bash
fruit=$(npx "@inquirer-cli/select" -c "Apple" -c "Banana" -c "Cherry" "Pick a fruit")
fruit=$(npx -y @inquirer-cli/select -c Apple -c Banana -c Cherry "Pick a fruit")
echo "You selected: $fruit"
```

### [`@inquirer-cli/checkbox`](./packages/checkbox/README.md)

> Uses [@inquirer/checkbox](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/checkbox).
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-c, --choice <value>` | Add a choice (use multiple times, at least one required) |
| `-r, --required` | Reject empty selection |
| `-h, --help` | Show help |

Allows the user to select multiple options from a list.
### [`@inquirer-cli/checkbox`](./packages/checkbox/README.md)

Allow the user to select multiple options:
Prompts the user to select multiple options from a list. Outputs selected values as a space-separated string.

```bash
choices=$(npx -y @inquirer-cli/checkbox -r "Select your favorite colors" -c "Red" -c "Blue" -c "Green")
colors=$(npx -y @inquirer-cli/checkbox -r "Select your favorite colors" -c Red -c Blue -c Green)
echo "You selected:"
for choice in $choices; do
echo "- $choice"
for color in $colors; do
echo "- $color"
done
```

### [`@inquirer-cli/password`](./packages/password/README.md)

> Uses [@inquirer/password](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/password).
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-c, --choice <value>` | Add a choice (use multiple times, at least one required) |
| `-r, --required` | Require at least one selection |
| `-h, --help` | Show help |

Prompts the user for sensitive information with input masking.
### [`@inquirer-cli/password`](./packages/password/README.md)

Prompt the user for a password:
Prompts for sensitive input with masking.

```bash
password=$(npx -y @inquirer-cli/password -r "Enter your password")
echo "Password received. $password"
secret=$(npx -y @inquirer-cli/password -r "Enter your password")
```

### ~~[`@inquirer-cli/editor`](./packages/editor/README.md)~~ (🚧 NOT SUPPORTED YET)
| Option | Description |
|---|---|
| `<message>` | The prompt message (required) |
| `-r, --required` | Reject empty input |
| `-h, --help` | Show help |

I wished `editor` would work like the following but sadly I couldn't make it work. Any help on this would be appreciated!
### ~~[`@inquirer-cli/editor`](./packages/editor/README.md)~~ (not supported yet)

> Uses [@inquirer/editor](https://github.com/SBoudrias/Inquirer.js/tree/main/packages/editor).
Opens the user's default editor for multi-line input. This package is currently not functional due to technical difficulties. Contributions welcome!

```bash
notes=$(npx -y @inquirer-cli/editor "Write your notes")
echo "Your notes: $notes"
```

## Options
## Full Example

```bash
#!/bin/sh

Each CLI prompt accepts various options to customize its behavior. Common options include:
name=$(npx -y @inquirer-cli/input -r "What is your name?")
age=$(npx -y @inquirer-cli/number -r "How old are you?")
lang=$(npx -y @inquirer-cli/select -c JavaScript -c Python -c Go "Favorite language?")

- `--choices` (or `-c`):
A space-separated list of choices (applicable to `select` and `checkbox` prompts).
if $(npx -y @inquirer-cli/confirm "Save profile?"); then
echo "Saved: $name, age $age, likes $lang"
fi
```

- `--required` (or `-r`):
When set, empty responses will be reprompted (not applicable to `confirm`).
## Requirements

For a full list of options and detailed usage, refer to the documentation of the respective `@inquirer-cli` package.
- Node.js >= 16

## Author

[@ycmjason](https://github.com/ycmjason))
[@ycmjason](https://github.com/ycmjason)

## License

Licensed under the MIT License.
MIT

---

*The `@inquirer-cli` project is an independent initiative and is not affiliated with or endorsed by Inquirer.js.*
*`@inquirer-cli` is an independent project and is not affiliated with or endorsed by Inquirer.js.*
41 changes: 35 additions & 6 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
},
"correctness": {
"noUnusedImports": {
"level": "error",
"fix": "safe"
}
},
"nursery": {
"noFloatingPromises": "error"
}
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
Expand All @@ -19,17 +37,28 @@
"indentWidth": 2,
"lineWidth": 100
},
"json": {
"formatter": {
"enabled": true
}
},
"javascript": {
"formatter": {
"trailingCommas": "all",
"semicolons": "always",
"arrowParentheses": "asNeeded",
"quoteStyle": "single"
}
},
"files": {
"includes": [
"**/*",
"!**/.cache/*",
"!**/.claude/*",
"!**/dist/*",
"!**/node_modules/*",
"!**/output/*",
"!**/*.gen.*"
]
},
"css": {
"parser": {
"tailwindDirectives": true
}
}
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"shell",
"automation"
],
"type": "module",
"license": "MIT",
"author": {
"name": "YCM Jason",
Expand All @@ -24,14 +25,16 @@
"url": "https://github.com/fishballapp/inquirer-cli/issues"
},
"scripts": {
"test": "node --test 'packages/*/index.test.js'",
"check:fix": "biome check --fix",
"version:bump": "pnpm -r exec pnpm version --no-git-tag-version $(npx -y @inquirer-cli/select -c patch -c minor -c major 'Select Version') && pnpm check:fix"
},
"dependencies": {
"minimist": "catalog:"
},
"devDependencies": {
"@biomejs/biome": "^2.2.4"
"@biomejs/biome": "^2.4.7",
"@inquirer-cli/test-helper": "workspace:*"
},
"packageManager": "pnpm@10.16.0+sha512.8066e7b034217b700a9a4dbb3a005061d641ba130a89915213a10b3ca4919c19c037bec8066afdc559b89635fdb806b16ea673f2468fbb28aabfa13c53e3f769"
}
4 changes: 2 additions & 2 deletions packages/checkbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const args = minimist(process.argv.slice(2), {
alias: { choice: 'c', required: 'r' },
});
const message = args._[0];
const choices = [args.choice].flat();
const choices = [args.choice].flat().filter(c => c !== undefined);
const required = args.required;

function showHelp() {
Expand Down Expand Up @@ -42,7 +42,7 @@ if (choices.length === 0) {
process.exit(1);
}

(async () => {
void (async () => {
const answer = await checkbox({ message, choices, required }, { output: process.stderr });
console.log(answer.join(' ')); // Log as a space-separated string
})();
Loading
Loading