{"id":30956079,"url":"https://github.com/TopCli/prompts","last_synced_at":"2025-09-11T12:07:08.190Z","repository":{"id":114215386,"uuid":"609995317","full_name":"TopCli/prompts","owner":"TopCli","description":"Node.js user prompt library for command-line interfaces.","archived":false,"fork":false,"pushed_at":"2025-09-02T15:58:28.000Z","size":614,"stargazers_count":33,"open_issues_count":3,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-09-03T01:41:44.174Z","etag":null,"topics":["cli","nodejs","prompt","prompts"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TopCli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-03-05T20:53:52.000Z","updated_at":"2025-09-02T15:58:32.000Z","dependencies_parsed_at":"2023-10-03T02:11:23.005Z","dependency_job_id":"21237b3a-c733-452b-b97e-b20574b44848","html_url":"https://github.com/TopCli/prompts","commit_stats":{"total_commits":108,"total_committers":9,"mean_commits":12.0,"dds":"0.41666666666666663","last_synced_commit":"507a335e51337898097e9473c48e11d4a9daa9c7"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/TopCli/prompts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TopCli%2Fprompts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TopCli%2Fprompts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TopCli%2Fprompts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TopCli%2Fprompts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TopCli","download_url":"https://codeload.github.com/TopCli/prompts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TopCli%2Fprompts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274632627,"owners_count":25321251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-11T02:00:13.660Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","nodejs","prompt","prompts"],"created_at":"2025-09-11T12:03:54.639Z","updated_at":"2025-09-11T12:07:08.180Z","avatar_url":"https://github.com/TopCli.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./public/banner.png\" alt=\"@topcli/prompts\"\u003e\n\n  ![version](https://img.shields.io/badge/dynamic/json.svg?style=for-the-badge\u0026url=https://raw.githubusercontent.com/TopCli/prompts/main/package.json\u0026query=$.version\u0026label=Version)\n  [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg?style=for-the-badge)](https://github.com/TopCli/prompts/commit-activity)\n  [![isc](https://img.shields.io/badge/License-ISC-blue.svg?style=for-the-badge)](https://github.com/TopCli/prompts/blob/main/LICENSE)\n  [![scorecard](https://api.securityscorecards.dev/projects/github.com/TopCli/prompts/badge?style=for-the-badge)](https://ossf.github.io/scorecard-visualizer/#/projects/github.com/TopCli/prompts)\n  ![build](https://img.shields.io/github/actions/workflow/status/TopCli/prompts/node.js.yml?style=for-the-badge)\n\n  \u003cimg src=\"./public/topcli.gif\" alt=\"demo\"\u003e\n\u003c/div\u003e\n\n## Requirements\n- [Node.js](https://nodejs.org/en/) v20 or higher\n\n## Getting Started\n\nThis package is available in the Node Package Repository and can be easily installed with [npm](https://docs.npmjs.com/getting-started/what-is-npm) or [yarn](https://yarnpkg.com).\n\n```bash\n$ npm i @topcli/prompts\n# or\n$ yarn add @topcli/prompts\n```\n\n## Usage exemple\n\nYou can locally run `node ./demo.js`\n\n```js\nimport { question, confirm, select, multiselect } from \"@topcli/prompts\";\n\nconst kTestRunner = [\"node\", \"tap\", \"tape\", \"vitest\", \"mocha\", \"ava\"];\n\nconst name = await question(\"Project name ?\", { defaultValue: \"foo\" });\nconst runner = await select(\"Choose a test runner\", { choices: kTestRunner, maxVisible: 5 });\nconst isCLI = await confirm(\"Your project is a CLI ?\", { initial: true });\nconst os = await multiselect(\"Choose OS\", {\n  choices: [\"linux\", \"mac\", \"windows\"],\n  preSelectedChoices: [\"linux\"]\n});\n\nconsole.log(name, runner, isCLI, os);\n```\n\n## API\n\n### `question()`\n\n```ts\nquestion(message: string, options?: PromptOptions): Promise\u003cstring\u003e\n```\n\nSimple prompt, similar to `rl.question()` with an improved UI.\n\nUse `options.defaultValue` to set a default value.\n\nUse `options.secure` if you need to hide both input and answer. You can provide either a **boolean** or an **object** which allows to configure a `placeholder` such as `*`.\n\nUse `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).\n\nUse `options.validators` to handle user input.\n\nUse `options.skip` to skip prompt. It will return `options.defaultValue` if given, `\"\"` otherwise.\n\n**Example**\n\n```js\nconst packageName = await question('Package name', {\n  validators: [\n    {\n      validate: (value) =\u003e {\n        if (fs.existsSync(path.join(process.cwd(), value))) {\n          return `Folder ${value} already exists`;\n        }\n      }\n    }\n  ]\n});\n```\n\n**This package provide some validators for common usage**\n\n- required\n\n```js\nimport { question, required } from \"@topcli/prompts\";\n\nconst name = await question(\"What's your name ?\", {\n  validators: [required()]\n});\n```\n\n### `select()`\n\n```ts\nselect\u003cT extends string\u003e(message: string, options: SelectOptions\u003cT\u003e): Promise\u003cT\u003e\n```\n\nScrollable select depending `maxVisible` (default `8`).\n\nUse `options.ignoreValues` to skip result render \u0026 clear lines after a selected one.\n\nUse `options.validators` to handle user input.\n\nUse `options.autocomplete` to allow filtered choices. This can be useful for a large list of choices.\n\nUse `options.caseSensitive` to make autocomplete filters case sensitive. Default `false`\n\nUse `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).\n\nUse `options.skip` to skip prompt. It will return the first choice.\n\n### `multiselect()`\n\n```ts\nmultiselect\u003cT extends string\u003e(message: string, options: MultiselectOptions\u003cT\u003e): Promise\u003cT[]\u003e\n```\n\nScrollable multiselect depending `options.maxVisible` (default `8`).\u003cbr\u003e\nUse `options.preSelectedChoices` to pre-select choices.\n\nUse `options.validators` to handle user input.\n\nUse `options.showHint: false` to disable hint (this option is truthy by default).\n\nUse `options.autocomplete` to allow filtered choices. This can be useful for a large list of choices.\n\nUse `options.caseSensitive` to make autocomplete filters case sensitive. Default `false`.\n\nUse `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).\n\nUse `options.skip` to skip prompt. It will return `options.preSelectedChoices` if given, `[]` otherwise.\n\n### `confirm()`\n\n```ts\nconfirm(message: string, options?: ConfirmOptions): Promise\u003cboolean\u003e\n```\n\nBoolean prompt, default to `options.initial` (`false`).\n\n\u003e [!TIP]\n\u003e You can answer pressing \u003ckbd\u003eY\u003c/kbd\u003e or \u003ckbd\u003eN\u003c/kbd\u003e\n\nUse `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).\n\nUse `options.skip` to skip prompt. It will return `options.initial` (`false` by default)\n\n### `PromptAgent`\n\nThe `PromptAgent` class allows to programmatically set the next answers for any prompt function, this can be useful for testing.\n\n```ts\nconst agent = PromptAgent.agent();\nagent.nextAnswer(\"John\");\n\nconst input = await question(\"What's your name?\");\nassert.equal(input, \"John\");\n```\n\n\u003e [!WARNING]\n\u003e Answers set with `PromptAgent` will **bypass** any logical \u0026 validation rules.\n\u003e Examples:\n\u003e - When using `question()`, `validators` functions will not be executed.\n\u003e - When using `select()`, the answer can be different from the available choices.\n\u003e - When using `confirm()`, the answer can be any type other than boolean.\n\u003e - etc\u003cbr\u003e\n\u003e **Use with caution**\n\n## Errors\n\n### `AbortError`\n\n```ts\nexport class AbortError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = \"AbortError\";\n  }\n}\n```\n\n## Interfaces\n\n```ts\ntype Stdin = NodeJS.ReadStream \u0026 {\n  fd: 0;\n};\n\ntype Stdout = NodeJS.WriteStream \u0026 {\n  fd: 1;\n}\n\nexport interface AbstractPromptOptions {\n  stdin?: Stdin;\n  stdout?: Stdout;\n  message: string;\n  skip?: boolean;\n  signal?: AbortSignal;\n}\n\nexport interface PromptValidator\u003cT extends string | string[]\u003e {\n  validate: (input: T) =\u003e boolean;\n}\n\nexport interface QuestionOptions extends SharedOptions {\n  defaultValue?: string;\n  validators?: PromptValidator\u003cstring\u003e[];\n  secure?: boolean;\n}\n\nexport interface Choice\u003cT = any\u003e {\n  value: T;\n  label: string;\n  description?: string;\n}\n\nexport interface SelectOptions\u003cT extends string\u003e extends AbstractPromptOptions {\n  choices: (Choice\u003cT\u003e | T)[];\n  maxVisible?: number;\n  ignoreValues?: (T | number | boolean)[];\n  validators?: PromptValidator\u003cstring\u003e[];\n  autocomplete?: boolean;\n  caseSensitive?: boolean;\n}\n\nexport interface MultiselectOptions\u003cT extends string\u003e extends AbstractPromptOptions {\n  choices: (Choice\u003cT\u003e | T)[];\n  maxVisible?: number;\n  preSelectedChoices?: (Choice\u003cT\u003e | T)[];\n  validators?: PromptValidator\u003cstring[]\u003e[];\n  autocomplete?: boolean;\n  caseSensitive?: boolean;\n  showHint?: boolean;\n}\n\nexport interface ConfirmOptions extends AbstractPromptOptions {\n  initial?: boolean;\n}\n```\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\nOpen an issue if you want to provide feedback such as bug reports or enchancements.\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/PierreDemailly\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/39910767?v=4?s=100\" width=\"100px;\" alt=\"PierreDemailly\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003ePierreDemailly\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=PierreDemailly\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=PierreDemailly\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://www.linkedin.com/in/thomas-gentilhomme/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/4438263?v=4?s=100\" width=\"100px;\" alt=\"Gentilhomme\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGentilhomme\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/pulls?q=is%3Apr+reviewed-by%3Afraxken\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=fraxken\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=fraxken\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://tonygo.dev\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/22824417?v=4?s=100\" width=\"100px;\" alt=\"Tony Gorez\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTony Gorez\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/pulls?q=is%3Apr+reviewed-by%3Atony-go\" title=\"Reviewed Pull Requests\"\u003e👀\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://sofiand.github.io/portfolio-client/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/39944043?v=4?s=100\" width=\"100px;\" alt=\"Yefis\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eYefis\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=SofianD\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=SofianD\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://justie.dev\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/7118300?v=4?s=100\" width=\"100px;\" alt=\"Ben\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBen\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=JUSTIVE\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-JUSTIVE\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/ncukondo\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/17022138?v=4?s=100\" width=\"100px;\" alt=\"Takeshi Kondo\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTakeshi Kondo\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#maintenance-ncukondo\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/FredGuiou\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/99122562?v=4?s=100\" width=\"100px;\" alt=\"FredGuiou\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eFredGuiou\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=FredGuiou\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=FredGuiou\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=FredGuiou\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/noxify\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/521777?v=4?s=100\" width=\"100px;\" alt=\"Marcus Reinhardt\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMarcus Reinhardt\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=noxify\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=noxify\" title=\"Tests\"\u003e⚠️\u003c/a\u003e \u003ca href=\"https://github.com/TopCli/prompts/commits?author=noxify\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/ItsHarper\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/10224994?v=4?s=100\" width=\"100px;\" alt=\"Harper Andrews\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eHarper Andrews\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TopCli/prompts/commits?author=ItsHarper\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTopCli%2Fprompts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTopCli%2Fprompts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTopCli%2Fprompts/lists"}