@reliverse/rempts 1.7.28 → 1.7.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +176 -37
  2. package/bin/{components/visual/animate/animate.d.ts → libs/animate/animate-mod.d.ts} +1 -1
  3. package/bin/{components/visual/animate/animate.js → libs/animate/animate-mod.js} +2 -5
  4. package/bin/{components → libs}/anykey/anykey-mod.d.ts +2 -2
  5. package/bin/{components → libs}/anykey/anykey-mod.js +3 -3
  6. package/bin/libs/cancel/cancel.d.ts +45 -0
  7. package/bin/libs/cancel/cancel.js +72 -0
  8. package/bin/libs/confirm/confirm-alias.d.ts +1 -0
  9. package/bin/libs/confirm/confirm-alias.js +2 -0
  10. package/bin/{components/input/confirm-prompt.js → libs/confirm/confirm-mod.js} +1 -1
  11. package/bin/{components → libs}/editor/editor-mod.d.ts +4 -4
  12. package/bin/{components → libs}/editor/editor-mod.js +8 -8
  13. package/bin/{components → libs}/figures/figures-mod.d.ts +2 -3
  14. package/bin/{components → libs}/figures/figures-mod.js +1 -2
  15. package/bin/libs/input/input-alias.d.ts +4 -0
  16. package/bin/libs/input/input-alias.js +4 -0
  17. package/bin/{components/input/input-prompt.js → libs/input/input-mod.js} +2 -2
  18. package/bin/libs/intro/intro-alias.d.ts +2 -0
  19. package/bin/libs/intro/intro-alias.js +3 -0
  20. package/bin/{components/st-end/start.d.ts → libs/intro/intro-mod.d.ts} +4 -1
  21. package/bin/{components/st-end/start.js → libs/intro/intro-mod.js} +35 -21
  22. package/bin/libs/launcher/launcher-alias.d.ts +2 -0
  23. package/bin/libs/launcher/launcher-alias.js +2 -0
  24. package/bin/{components → libs}/launcher/launcher-mod.d.ts +37 -5
  25. package/bin/{components → libs}/launcher/launcher-mod.js +326 -205
  26. package/bin/{components → libs}/launcher/launcher-types.d.ts +15 -18
  27. package/bin/libs/launcher/trpc-orpc-support/completions.d.ts +4 -0
  28. package/bin/libs/launcher/trpc-orpc-support/completions.js +45 -0
  29. package/bin/libs/launcher/trpc-orpc-support/errors.d.ts +11 -0
  30. package/bin/libs/launcher/trpc-orpc-support/errors.js +10 -0
  31. package/bin/libs/launcher/trpc-orpc-support/index.d.ts +34 -0
  32. package/bin/libs/launcher/trpc-orpc-support/index.js +641 -0
  33. package/bin/libs/launcher/trpc-orpc-support/json-schema.d.ts +17 -0
  34. package/bin/libs/launcher/trpc-orpc-support/json-schema.js +168 -0
  35. package/bin/libs/launcher/trpc-orpc-support/json.d.ts +44 -0
  36. package/bin/libs/launcher/trpc-orpc-support/json.js +41 -0
  37. package/bin/libs/launcher/trpc-orpc-support/logging.d.ts +11 -0
  38. package/bin/libs/launcher/trpc-orpc-support/logging.js +26 -0
  39. package/bin/libs/launcher/trpc-orpc-support/parse-procedure.d.ts +2 -0
  40. package/bin/libs/launcher/trpc-orpc-support/parse-procedure.js +486 -0
  41. package/bin/libs/launcher/trpc-orpc-support/prompts.d.ts +18 -0
  42. package/bin/libs/launcher/trpc-orpc-support/prompts.js +534 -0
  43. package/bin/libs/launcher/trpc-orpc-support/standard-schema/contract.d.ts +53 -0
  44. package/bin/libs/launcher/trpc-orpc-support/standard-schema/contract.js +0 -0
  45. package/bin/libs/launcher/trpc-orpc-support/standard-schema/errors.d.ts +9 -0
  46. package/bin/libs/launcher/trpc-orpc-support/standard-schema/errors.js +47 -0
  47. package/bin/libs/launcher/trpc-orpc-support/standard-schema/utils.d.ts +3 -0
  48. package/bin/libs/launcher/trpc-orpc-support/standard-schema/utils.js +6 -0
  49. package/bin/libs/launcher/trpc-orpc-support/trpc-compat.d.ts +71 -0
  50. package/bin/libs/launcher/trpc-orpc-support/trpc-compat.js +11 -0
  51. package/bin/libs/launcher/trpc-orpc-support/types.d.ts +276 -0
  52. package/bin/libs/launcher/trpc-orpc-support/types.js +0 -0
  53. package/bin/libs/launcher/trpc-orpc-support/util.d.ts +9 -0
  54. package/bin/libs/launcher/trpc-orpc-support/util.js +9 -0
  55. package/bin/libs/log/log-alias.d.ts +2 -0
  56. package/bin/libs/log/log-alias.js +2 -0
  57. package/bin/{components → libs}/msg-fmt/logger.js +1 -1
  58. package/bin/libs/multiselect/multiselect-alias.d.ts +1 -0
  59. package/bin/libs/multiselect/multiselect-alias.js +2 -0
  60. package/bin/{components/select → libs/multiselect}/multiselect-prompt.js +1 -1
  61. package/bin/{components → libs}/next-steps/next-steps.d.ts +2 -2
  62. package/bin/{components → libs}/number/number-mod.d.ts +2 -2
  63. package/bin/{components → libs}/number/number-mod.js +1 -4
  64. package/bin/libs/outro/outro-alias.d.ts +2 -0
  65. package/bin/libs/outro/outro-alias.js +3 -0
  66. package/bin/libs/outro/outro-mod.d.ts +8 -0
  67. package/bin/libs/outro/outro-mod.js +55 -0
  68. package/bin/{components → libs}/results/results.d.ts +2 -2
  69. package/bin/libs/select/aliases-alias.d.ts +1 -0
  70. package/bin/libs/select/aliases-alias.js +2 -0
  71. package/bin/{components → libs}/select/select-prompt.d.ts +6 -5
  72. package/bin/{components → libs}/select/select-prompt.js +6 -4
  73. package/bin/{components → libs}/select/toggle-prompt.js +1 -1
  74. package/bin/libs/spinner/spinner-alias.d.ts +1 -0
  75. package/bin/libs/spinner/spinner-alias.js +2 -0
  76. package/bin/libs/spinner/spinner-mod.d.ts +106 -0
  77. package/bin/libs/spinner/spinner-mod.js +265 -0
  78. package/bin/{components → libs}/task/progress.d.ts +1 -1
  79. package/bin/{components → libs}/task/progress.js +1 -1
  80. package/bin/{components/task/spinner.d.ts → libs/task/task-spin.d.ts} +3 -3
  81. package/bin/{components/task/spinner.js → libs/task/task-spin.js} +2 -2
  82. package/bin/{utils → libs/utils}/colorize.d.ts +1 -1
  83. package/bin/{utils → libs/utils}/prevent.d.ts +1 -1
  84. package/bin/{utils → libs/utils}/prevent.js +2 -2
  85. package/bin/{utils → libs/utils}/prompt-end.d.ts +1 -1
  86. package/bin/{utils → libs/utils}/prompt-end.js +2 -2
  87. package/bin/{utils → libs/utils}/stream-text.d.ts +1 -1
  88. package/bin/{utils → libs/utils}/stream-text.js +2 -2
  89. package/bin/{utils → libs/utils}/validate.d.ts +2 -2
  90. package/bin/mod.d.ts +66 -38
  91. package/bin/mod.js +102 -43
  92. package/bin/types.d.ts +36 -36
  93. package/package.json +17 -3
  94. package/bin/components/st-end/end.d.ts +0 -2
  95. package/bin/components/st-end/end.js +0 -42
  96. package/bin/hooks/spinner/spinner-mod.d.ts +0 -64
  97. package/bin/hooks/spinner/spinner-mod.js +0 -74
  98. /package/bin/{components/input/confirm-prompt.d.ts → libs/confirm/confirm-mod.d.ts} +0 -0
  99. /package/bin/{components → libs}/date/date.d.ts +0 -0
  100. /package/bin/{components → libs}/date/date.js +0 -0
  101. /package/bin/{components/input/input-prompt.d.ts → libs/input/input-mod.d.ts} +0 -0
  102. /package/bin/{components → libs}/launcher/launcher-types.js +0 -0
  103. /package/bin/{components → libs}/launcher/run-command.d.ts +0 -0
  104. /package/bin/{components → libs}/launcher/run-command.js +0 -0
  105. /package/bin/{components → libs}/msg-fmt/colors.d.ts +0 -0
  106. /package/bin/{components → libs}/msg-fmt/colors.js +0 -0
  107. /package/bin/{components → libs}/msg-fmt/logger.d.ts +0 -0
  108. /package/bin/{components → libs}/msg-fmt/mapping.d.ts +0 -0
  109. /package/bin/{components → libs}/msg-fmt/mapping.js +0 -0
  110. /package/bin/{components → libs}/msg-fmt/messages.d.ts +0 -0
  111. /package/bin/{components → libs}/msg-fmt/messages.js +0 -0
  112. /package/bin/{components → libs}/msg-fmt/terminal.d.ts +0 -0
  113. /package/bin/{components → libs}/msg-fmt/terminal.js +0 -0
  114. /package/bin/{components → libs}/msg-fmt/variants.d.ts +0 -0
  115. /package/bin/{components → libs}/msg-fmt/variants.js +0 -0
  116. /package/bin/{components/select → libs/multiselect}/multiselect-prompt.d.ts +0 -0
  117. /package/bin/{components → libs}/next-steps/next-steps.js +0 -0
  118. /package/bin/{components → libs}/results/results.js +0 -0
  119. /package/bin/{components → libs}/select/nummultiselect-prompt.d.ts +0 -0
  120. /package/bin/{components → libs}/select/nummultiselect-prompt.js +0 -0
  121. /package/bin/{components → libs}/select/numselect-prompt.d.ts +0 -0
  122. /package/bin/{components → libs}/select/numselect-prompt.js +0 -0
  123. /package/bin/{components → libs}/select/toggle-prompt.d.ts +0 -0
  124. /package/bin/{utils → libs/utils}/colorize.js +0 -0
  125. /package/bin/{utils → libs/utils}/errors.d.ts +0 -0
  126. /package/bin/{utils → libs/utils}/errors.js +0 -0
  127. /package/bin/{utils → libs/utils}/system.d.ts +0 -0
  128. /package/bin/{utils → libs/utils}/system.js +0 -0
  129. /package/bin/{utils → libs/utils}/validate.js +0 -0
  130. /package/bin/{components/visual/ascii-art/ascii-art.d.ts → libs/visual/visual-mod.d.ts} +0 -0
  131. /package/bin/{components/visual/ascii-art/ascii-art.js → libs/visual/visual-mod.js} +0 -0
package/README.md CHANGED
@@ -6,7 +6,8 @@
6
6
 
7
7
  ## Features
8
8
 
9
- - 😘 drop-in alternative to `citty` + built-in prompts
9
+ - 😘 drop-in to libraries like `unjs/citty` and `@clack/prompts`
10
+ - 📝 includes comprehensive set of built-in cli prompts
10
11
  - 📂 file-based commands (app-router style by default)
11
12
  - 🫂 rempts keeps you from fighting with your CLI tool
12
13
  - 🏎️ prompt engine that *feels* modern — and actually is
@@ -58,14 +59,13 @@ All main prompts APIs are available from the package root:
58
59
  ```ts
59
60
  import {
60
61
  // ...prompts
61
- defineCommand, runMain, defineArgs,
62
62
  inputPrompt, selectPrompt, multiselectPrompt, numberPrompt,
63
- confirmPrompt, togglePrompt, spinnerTaskPrompt, progressTaskPrompt,
63
+ confirmPrompt, togglePrompt, taskSpinPrompt, taskProgressPrompt,
64
64
  startPrompt, endPrompt, resultPrompt, nextStepsPrompt,
65
65
  // ...hooks
66
66
  useSpinner,
67
67
  // ...launcher
68
- runMain, defineCommand, defineArgs,
68
+ createCli, defineCommand, defineArgs,
69
69
  // ...types
70
70
  // ...more
71
71
  } from "@reliverse/rempts";
@@ -79,25 +79,32 @@ import {
79
79
 
80
80
  | Prompt | Description |
81
81
  |---------------------------|-----------------------------------------------------------|
82
+ | `useSpinner` | Start/stop spinner |
82
83
  | `inputPrompt` | Single-line input (with mask support, e.g. for passwords) |
83
84
  | `selectPrompt` | Single-choice radio menu |
84
85
  | `multiselectPrompt` | Multi-choice checkbox menu |
85
86
  | `numberPrompt` | Type-safe number input |
86
87
  | `confirmPrompt` | Yes/No toggle |
87
88
  | `togglePrompt` | Custom on/off toggles |
88
- | `progressTaskPrompt` | Progress bar for async tasks |
89
+ | `taskProgressPrompt` | Progress bar for async tasks |
89
90
  | `resultPrompt` | Show results in a styled box |
90
91
  | `nextStepsPrompt` | Show next steps in a styled list |
91
92
  | `startPrompt`/`endPrompt` | Makes CLI start/end flows look nice |
92
- | `spinnerTaskPrompt` | Async loader with spinner (possibly will be deprecated) |
93
+ | `taskSpinPrompt` | Async loader with spinner (possibly will be deprecated) |
93
94
  | `datePrompt` | Date input with format validation |
94
95
  | `anykeyPrompt` | Wait for any keypress |
95
96
 
96
- ### Hooks
97
+ ### Aliases
97
98
 
98
- | Hook | Description |
99
- |--------------|--------------------|
100
- | `useSpinner` | Start/stop spinner |
99
+ To help you migrate from the different CLI frameworks, `@reliverse/rempts` has some aliases for the most popular prompts.
100
+
101
+ | Prompt | Aliases |
102
+ |-----------------------|-----------------|
103
+ | `useSpinner` | `spinner` |
104
+ | `selectPrompt` | `select` |
105
+ | `multiselectPrompt` | `multiselect` |
106
+ | `inputPrompt` | `text`, `input` |
107
+ | `@reliverse/relinka` | `log` |
101
108
 
102
109
  ### Notices
103
110
 
@@ -124,6 +131,23 @@ async function main() {
124
131
  defaultValue: "my-cool-project",
125
132
  });
126
133
 
134
+ const spinner = useSpinner({
135
+ text: "Loading...",
136
+ indicator: "timer", // or "dots"
137
+ frames: ["◒", "◐", "◓", "◑"], // custom frames
138
+ delay: 80, // custom delay
139
+ onCancel: () => {
140
+ console.log("Operation cancelled");
141
+ },
142
+ cancelMessage: "Operation cancelled by user",
143
+ errorMessage: "Operation failed",
144
+ signal: abortController.signal,
145
+ }).start();
146
+
147
+ // The spinner will show:
148
+ // ◒ Loading... [5s]
149
+ // With animated frames and timer
150
+
127
151
  const framework = await selectPrompt({
128
152
  title: "Pick your framework",
129
153
  options: [
@@ -140,8 +164,61 @@ async function main() {
140
164
  await main();
141
165
  ```
142
166
 
167
+ **Available spinner options:**
168
+
169
+ | Option | Description |
170
+ |--------|-------------|
171
+ | `cancelMessage` | The message to display when the spinner is cancelled |
172
+ | `color` | The color of the spinner |
173
+ | `delay` | The delay between frames |
174
+ | `errorMessage` | The message to display when the spinner fails |
175
+ | `failText` | The text to display when the spinner fails |
176
+ | `frames` | The frames to use for the spinner |
177
+ | `hideCursor` | Whether to hide the cursor |
178
+ | `indicator` | The indicator to use for the spinner |
179
+ | `onCancel` | The function to call when the spinner is cancelled |
180
+ | `prefixText` | The text to display before the spinner |
181
+ | `signal` | The signal to use for the spinner |
182
+ | `silent` | Whether to hide the spinner |
183
+ | `spinner` | The spinner to use for the spinner |
184
+ | `successText` | The text to display when the spinner succeeds |
185
+ | `text` | The text to display next to the spinner |
186
+
187
+ **Available indicator options:**
188
+
189
+ | Option | Description |
190
+ |--------|-------------|
191
+ | `timer` | The timer indicator |
192
+ | `dots` | The dots indicator |
193
+
194
+ **Available signal options:**
195
+
196
+ | Option | Description |
197
+ |--------|-------------|
198
+ | `abortController.signal` | The signal to use for the spinner |
199
+
200
+ **Available frames options:**
201
+
202
+ | Option | Description |
203
+ |--------|-------------|
204
+ | `["◒", "◐", "◓", "◑"]` | The frames to use for the spinner |
205
+
206
+ **Available delay options:**
207
+
208
+ | Option | Description |
209
+ |--------|-------------|
210
+ | `80` | The delay between frames |
211
+
212
+ **Available onCancel options:**
213
+
214
+ | Option | Description |
215
+ |--------|-------------|
216
+ | `() => { console.log("Operation cancelled"); }` | The function to call when the spinner is cancelled |
217
+
143
218
  ## Launcher
144
219
 
220
+ > **Note**: `runMain` is now an alias for `createCli` and is still supported for backward compatibility. The new `createCli` API provides a more intuitive object-based configuration format.
221
+
145
222
  ### Terminology
146
223
 
147
224
  - **Launcher/Router**: The main entry point for your CLI. Visit [CLI Launcher (Router)](#cli-launcher-router) section to learn more.
@@ -152,12 +229,12 @@ await main();
152
229
 
153
230
  #### Launcher Usage Example
154
231
 
155
- **Important**: Ensure your commands don't have `await main();`, `await runMain();`, or something like that — to prevent any unexpected behavior. Only main command should have it.
232
+ **Important**: Ensure your commands don't have `await main();`, `await createCli();`, or something like that — to prevent any unexpected behavior. Only main command should have it.
156
233
 
157
234
  ```ts
158
235
  import { relinka } from "@reliverse/relinka";
159
236
 
160
- import { defineCommand, runMain } from "@reliverse/rempts";
237
+ import { defineCommand, createCli } from "@reliverse/rempts";
161
238
 
162
239
  const main = defineCommand({
163
240
  meta: {
@@ -178,12 +255,20 @@ const main = defineCommand({
178
255
  },
179
256
  });
180
257
 
181
- await runMain(main);
182
- ```
258
+ // New object format (recommended)
259
+ await createCli({
260
+ mainCommand: main,
261
+ fileBased: {
262
+ enable: true,
263
+ cmdsRootPath: "my-cmds", // default is `./app`
264
+ },
265
+ // Optionally disable auto-exit to handle errors manually:
266
+ autoExit: false,
267
+ });
183
268
 
184
- ```ts
185
- await runMain(myCommand, {
186
- fileBasedCmds: {
269
+ // Legacy format (still supported)
270
+ await createCli(main, {
271
+ fileBased: {
187
272
  enable: true,
188
273
  cmdsRootPath: "my-cmds", // default is `./app`
189
274
  },
@@ -299,9 +384,15 @@ bun dev
299
384
  **1 Create a `src/mod.ts` file:**
300
385
 
301
386
  ```ts
302
- import { runMain, defineCommand } from "@reliverse/rempts";
387
+ import { createCli, defineCommand } from "@reliverse/rempts";
388
+
389
+ // New object format (recommended)
390
+ await createCli({
391
+ mainCommand: defineCommand({}),
392
+ });
303
393
 
304
- await runMain(defineCommand({}));
394
+ // Legacy format (still supported)
395
+ await createCli(defineCommand({}));
305
396
  ```
306
397
 
307
398
  **2 Run the following:**
@@ -330,7 +421,7 @@ bun src/mod.ts
330
421
  #### Medium Usage Example
331
422
 
332
423
  ```ts
333
- import { defineCommand, runMain } from "@reliverse/rempts";
424
+ import { defineCommand, createCli } from "@reliverse/rempts";
334
425
 
335
426
  const main = defineCommand({
336
427
  meta: {
@@ -341,7 +432,13 @@ const main = defineCommand({
341
432
  },
342
433
  });
343
434
 
344
- await runMain(main);
435
+ // New object format (recommended)
436
+ await createCli({
437
+ mainCommand: main,
438
+ });
439
+
440
+ // Legacy format (still supported)
441
+ await createCli(main);
345
442
  ```
346
443
 
347
444
  #### Classic Usage Example
@@ -354,7 +451,7 @@ import {
354
451
  inputPrompt,
355
452
  selectPrompt,
356
453
  defineCommand,
357
- runMain
454
+ createCli
358
455
  } from "@reliverse/rempts";
359
456
 
360
457
  const main = defineCommand({
@@ -393,7 +490,13 @@ const main = defineCommand({
393
490
  },
394
491
  });
395
492
 
396
- await runMain(main);
493
+ // New object format (recommended)
494
+ await createCli({
495
+ mainCommand: main,
496
+ });
497
+
498
+ // Legacy format (still supported)
499
+ await createCli(main);
397
500
  ```
398
501
 
399
502
  #### Advanced Usage Example
@@ -508,7 +611,7 @@ const mainCommand = defineCommand({
508
611
  });
509
612
 
510
613
  /**
511
- * The `runMain()` function sets up the launcher with several advanced features:
614
+ * The `createCli()` function sets up the launcher with several advanced features:
512
615
  *
513
616
  * - File-Based Commands: Enables scanning for commands within the "app" directory.
514
617
  * - Alias Mapping: Shorthand flags (e.g., `-v`) are mapped to their full names (e.g., `--verbose`).
@@ -516,8 +619,28 @@ const mainCommand = defineCommand({
516
619
  * - Negated Boolean Support: Allows flags to be negated (e.g., `--no-verbose`).
517
620
  * - Custom Unknown Flag Handler: Provides custom handling for unrecognized flags.
518
621
  */
519
- await runMain(mainCommand, {
520
- fileBasedCmds: {
622
+ // New object format (recommended)
623
+ await createCli({
624
+ mainCommand: mainCommand,
625
+ fileBased: {
626
+ enable: true, // Enables file-based command detection.
627
+ cmdsRootPath: "app", // Directory to scan for commands.
628
+ },
629
+ alias: {
630
+ v: "verbose", // Maps shorthand flag -v to --verbose.
631
+ },
632
+ strict: false, // Do not throw errors for unknown flags.
633
+ warnOnUnknown: false, // Warn when encountering unknown flags.
634
+ negatedBoolean: true, // Support for negated booleans (e.g., --no-verbose).
635
+ // unknown: (flagName) => {
636
+ // relinka("warn", "Unknown flag encountered:", flagName);
637
+ // return false;
638
+ // },
639
+ });
640
+
641
+ // Legacy format (still supported)
642
+ await createCli(mainCommand, {
643
+ fileBased: {
521
644
  enable: true, // Enables file-based command detection.
522
645
  cmdsRootPath: "app", // Directory to scan for commands.
523
646
  },
@@ -558,7 +681,7 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
558
681
  Seamlessly combines positional and named arguments with zero configuration, auto-parsing booleans, strings, numbers, arrays, and even supporting negated flags like `--no-flag`.
559
682
 
560
683
  - **Customizable Behavior:**
561
- Options such as `fileBasedCmds.enable`, `cmdsRootPath`, and `autoExit` allow you to tailor the launcher's behavior. For example, you can choose whether the process should exit automatically on error or allow manual error handling.
684
+ Options such as `fileBased.enable`, `cmdsRootPath`, and `autoExit` allow you to tailor the launcher's behavior. For example, you can choose whether the process should exit automatically on error or allow manual error handling.
562
685
 
563
686
  - **Error Management & Usage Output:**
564
687
  The launcher provides clear error messages for missing required arguments, invalid types, or command import issues, and it automatically displays usage information for your CLI.
@@ -757,7 +880,7 @@ export default defineCommand({
757
880
  Below is a demonstration of how to define and use all supported argument types in rempts: positional, boolean, string, number, and array. This includes example CLI invocations and the resulting parsed output.
758
881
 
759
882
  ```ts
760
- import { defineCommand, runMain } from "@reliverse/rempts";
883
+ import { defineCommand, createCli } from "@reliverse/rempts";
761
884
 
762
885
  const main = defineCommand({
763
886
  meta: {
@@ -801,7 +924,13 @@ const main = defineCommand({
801
924
  },
802
925
  });
803
926
 
804
- await runMain(main);
927
+ // New object format (recommended)
928
+ await createCli({
929
+ mainCommand: main,
930
+ });
931
+
932
+ // Legacy format (still supported)
933
+ await createCli(main);
805
934
  ```
806
935
 
807
936
  ### Example CLI Invocations
@@ -972,13 +1101,7 @@ The validation happens after type casting, so for example with numbers, the inpu
972
1101
 
973
1102
  Bug report? Prompt idea? Want to build the best DX possible?
974
1103
 
975
- You're in the right place:
976
-
977
- - ✨ [Star the repo](https://github.com/reliverse/rempts)
978
- - 💬 [Join the Discord](https://discord.gg/3GawfWfAPe)
979
- - ❤️ [Sponsor @blefnk](https://github.com/sponsors/blefnk)
980
-
981
- > *No classes. No magic. Just clean, composable tools for CLI devs.*
1104
+ You're in the right place! Please help us make the best CLI toolkit possible.
982
1105
 
983
1106
  ### Notices For Contributors
984
1107
 
@@ -1002,6 +1125,10 @@ All APIs are fully typed. See [`src/types.ts`](./src/types.ts) for advanced cust
1002
1125
 
1003
1126
  - [CLI application with the Node.js Readline module](https://dev.to/camptocamp-geo/cli-application-with-the-nodejs-readline-module-48ic)
1004
1127
 
1128
+ ## TODO
1129
+
1130
+ - [ ] migrate to `dler libs` in the future (all main components will be published as separate packages; `@reliverse/rempts` will be a wrapper for all of them)
1131
+
1005
1132
  ## Related
1006
1133
 
1007
1134
  - [`@reliverse/cli`](https://npmjs.com/package/@reliverse/cli) – CLI-first toolkit for fullstack workflows
@@ -1013,6 +1140,18 @@ All APIs are fully typed. See [`src/types.ts`](./src/types.ts) for advanced cust
1013
1140
 
1014
1141
  - [citty](https://github.com/unjs/citty#readme) - launcher design inspiration
1015
1142
 
1143
+ ## Support
1144
+
1145
+ Bug report? Prompt idea? Want to build the best DX possible?
1146
+
1147
+ You're in the right place:
1148
+
1149
+ - ✨ [Star the repo](https://github.com/reliverse/rempts)
1150
+ - 💬 [Join the Discord](https://discord.gg/3GawfWfAPe)
1151
+ - ❤️ [Sponsor @blefnk](https://github.com/sponsors/blefnk)
1152
+
1153
+ > *No classes. No magic. Just clean, composable tools for CLI devs.*
1154
+
1016
1155
  ## License
1017
1156
 
1018
- 💖 MIT © [blefnk (Nazar Kornienko)](https://github.com/blefnk)
1157
+ 💖 MIT (see [LICENSE](./LICENSE) and [LICENCES](./LICENSES)) © [blefnk (Nazar Kornienko)](https://github.com/blefnk)
@@ -1,5 +1,5 @@
1
1
  import { type Animation, type AnimationName } from "@figliolia/chalk-animation";
2
- import type { BorderColorName, ColorName, MsgType, TypographyName } from "../../../types.js";
2
+ import type { BorderColorName, ColorName, MsgType, TypographyName } from "../../types.js";
3
3
  export declare const animationMap: Record<AnimationName, (text: string) => Animation>;
4
4
  export declare function animateText({ title, anim, delay, type, titleColor, titleTypography, border, borderColor, horizontalLineLength, }: {
5
5
  title: string;
@@ -2,11 +2,8 @@ import {
2
2
  ChalkAnimation
3
3
  } from "@figliolia/chalk-animation";
4
4
  import { relinka } from "@reliverse/relinka";
5
- import { msg } from "../../msg-fmt/messages.js";
6
- import {
7
- deleteLastLine,
8
- getTerminalWidth
9
- } from "../../msg-fmt/terminal.js";
5
+ import { msg } from "../msg-fmt/messages.js";
6
+ import { deleteLastLine, getTerminalWidth } from "../msg-fmt/terminal.js";
10
7
  export const animationMap = {
11
8
  rainbow: ChalkAnimation.rainbow,
12
9
  pulse: ChalkAnimation.pulse,
@@ -1,5 +1,5 @@
1
1
  import type { ColorName } from "../../types.js";
2
- type Options = {
2
+ interface Options {
3
3
  ctrlC?: number | false | "reject";
4
4
  preserveLog?: boolean;
5
5
  hideMessage?: boolean;
@@ -7,6 +7,6 @@ type Options = {
7
7
  streamDelay?: number;
8
8
  color?: ColorName;
9
9
  placeholderColor?: ColorName;
10
- };
10
+ }
11
11
  export declare function anykeyPrompt(message?: string, options?: Options): Promise<void>;
12
12
  export {};
@@ -1,8 +1,8 @@
1
1
  import logUpdate from "log-update";
2
2
  import { cursor } from "sisteransi";
3
3
  import { fmt } from "../msg-fmt/messages.js";
4
- import { endPrompt } from "../st-end/end.js";
5
- import { streamText } from "../../utils/stream-text.js";
4
+ import { outroPrompt } from "../outro/outro-mod.js";
5
+ import { streamText } from "../utils/stream-text.js";
6
6
  const DEFAULT_MESSAGE = "Press any key to continue...";
7
7
  const CTRL_C_CODE = 3;
8
8
  const terminal = {
@@ -82,7 +82,7 @@ export async function anykeyPrompt(message = DEFAULT_MESSAGE, options = {}) {
82
82
  };
83
83
  const handleCtrlC = () => {
84
84
  cleanup();
85
- void endPrompt({
85
+ void outroPrompt({
86
86
  title: "\u270B User pressed Ctrl+C, exiting...",
87
87
  titleAnimation: "pulse",
88
88
  titleColor: "redBright",
@@ -0,0 +1,45 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ /**
3
+ * Special value that indicates a cancelled operation
4
+ */
5
+ export declare const CANCEL: unique symbol;
6
+ /**
7
+ * Type for the cancel value
8
+ */
9
+ export type CancelValue = typeof CANCEL;
10
+ export declare const isWindows: boolean;
11
+ /**
12
+ * Sets raw mode on input stream
13
+ */
14
+ export declare function setRawMode(input: Readable, value: boolean): void;
15
+ /**
16
+ * Gets the number of columns in the terminal
17
+ */
18
+ export declare function getColumns(output: Writable): number;
19
+ interface BlockOptions {
20
+ input?: Readable;
21
+ output?: Writable;
22
+ overwrite?: boolean;
23
+ hideCursor?: boolean;
24
+ }
25
+ /**
26
+ * Creates a block for handling input with proper cursor and cleanup
27
+ */
28
+ export declare function block({ input, output, overwrite, hideCursor, }?: BlockOptions): () => void;
29
+ /**
30
+ * Checks if a value represents a cancelled operation
31
+ * @param value - The value to check
32
+ * @returns true if the value represents a cancelled operation
33
+ */
34
+ export declare function isCancel(value: unknown): value is CancelValue;
35
+ /**
36
+ * Handles cancellation of an operation
37
+ * @param message - Optional message to display before exiting
38
+ */
39
+ export declare function cancel(message?: string): never;
40
+ /**
41
+ * Creates a cancel value that can be returned from operations
42
+ * @returns The cancel value
43
+ */
44
+ export declare function createCancel(): CancelValue;
45
+ export {};
@@ -0,0 +1,72 @@
1
+ import { stdin, stdout } from "node:process";
2
+ import * as readline from "node:readline";
3
+ import { ReadStream, WriteStream } from "node:tty";
4
+ import { cursor } from "sisteransi";
5
+ export const CANCEL = Symbol("CANCEL");
6
+ export const isWindows = globalThis.process.platform.startsWith("win");
7
+ export function setRawMode(input, value) {
8
+ const i = input;
9
+ if (i.isTTY) i.setRawMode(value);
10
+ }
11
+ export function getColumns(output) {
12
+ if (output instanceof WriteStream && output.columns) {
13
+ return output.columns;
14
+ }
15
+ return 80;
16
+ }
17
+ export function block({
18
+ input = stdin,
19
+ output = stdout,
20
+ overwrite = true,
21
+ hideCursor = true
22
+ } = {}) {
23
+ const rl = readline.createInterface({
24
+ input,
25
+ output,
26
+ prompt: "",
27
+ tabSize: 1
28
+ });
29
+ readline.emitKeypressEvents(input, rl);
30
+ if (input instanceof ReadStream && input.isTTY) {
31
+ input.setRawMode(true);
32
+ }
33
+ const clear = (data, { name, sequence }) => {
34
+ const str = String(data);
35
+ if (str === "" || name === "c" && sequence === "") {
36
+ if (hideCursor) output.write(cursor.show);
37
+ process.exit(0);
38
+ return;
39
+ }
40
+ if (!overwrite) return;
41
+ const dx = name === "return" ? 0 : -1;
42
+ const dy = name === "return" ? -1 : 0;
43
+ readline.moveCursor(output, dx, dy, () => {
44
+ readline.clearLine(output, 1, () => {
45
+ input.once("keypress", clear);
46
+ });
47
+ });
48
+ };
49
+ if (hideCursor) output.write(cursor.hide);
50
+ input.once("keypress", clear);
51
+ return () => {
52
+ input.off("keypress", clear);
53
+ if (hideCursor) output.write(cursor.show);
54
+ if (input instanceof ReadStream && input.isTTY && !isWindows) {
55
+ input.setRawMode(false);
56
+ }
57
+ rl.terminal = false;
58
+ rl.close();
59
+ };
60
+ }
61
+ export function isCancel(value) {
62
+ return value === CANCEL;
63
+ }
64
+ export function cancel(message) {
65
+ if (message) {
66
+ console.log(message);
67
+ }
68
+ process.exit(0);
69
+ }
70
+ export function createCancel() {
71
+ return CANCEL;
72
+ }
@@ -0,0 +1 @@
1
+ export declare const confirm: any;
@@ -0,0 +1,2 @@
1
+ import { confirmPrompt } from "./confirm-mod.js";
2
+ export const confirm = confirmPrompt;
@@ -3,7 +3,7 @@ import { stdin as input, stdout as output } from "node:process";
3
3
  import readline from "node:readline/promises";
4
4
  import { bar, msg } from "../msg-fmt/messages.js";
5
5
  import { deleteLastLine } from "../msg-fmt/terminal.js";
6
- import { completePrompt } from "../../utils/prompt-end.js";
6
+ import { completePrompt } from "../utils/prompt-end.js";
7
7
  function renderPrompt(params) {
8
8
  const {
9
9
  title,
@@ -1,5 +1,5 @@
1
1
  import type { EditorExitResult } from "../../types.js";
2
- type EditorConfig = {
2
+ interface EditorConfig {
3
3
  syntaxHighlighting?: boolean;
4
4
  theme?: "auto" | "light" | "dark";
5
5
  defaultAllowSaveAs?: boolean;
@@ -7,8 +7,8 @@ type EditorConfig = {
7
7
  defaultAutoCloseOnSave?: boolean;
8
8
  defaultReturnContentOnSave?: boolean;
9
9
  [key: string]: any;
10
- };
11
- type EditorOptions = {
10
+ }
11
+ interface EditorOptions {
12
12
  filename?: string | null;
13
13
  initialContent?: string | null;
14
14
  onSave?: (content: string, filename: string | null) => Promise<string | boolean | undefined> | string | boolean | undefined;
@@ -20,6 +20,6 @@ type EditorOptions = {
20
20
  returnContentOnSave?: boolean;
21
21
  mode?: string;
22
22
  cwd?: string;
23
- };
23
+ }
24
24
  export declare function startEditor(options?: EditorOptions): Promise<EditorExitResult>;
25
25
  export {};
@@ -192,11 +192,11 @@ function renderEditor() {
192
192
  const lineNum = String(fileLineIndex + 1).padStart(3);
193
193
  term(state.theme.lineNumber(`${lineNum} `));
194
194
  const line = state.lines[fileLineIndex];
195
- const displayLine = line.substring(
195
+ const displayLine = line?.substring(
196
196
  state.leftCol,
197
197
  state.leftCol + displayWidth
198
198
  );
199
- const highlightedDisplayLine = applySyntaxHighlighting(displayLine);
199
+ const highlightedDisplayLine = applySyntaxHighlighting(displayLine ?? "");
200
200
  term(highlightedDisplayLine);
201
201
  term.eraseLineAfter();
202
202
  } else {
@@ -237,8 +237,8 @@ function deleteCharBackward() {
237
237
  const currentLine = state.lines.splice(state.cursorY, 1)[0];
238
238
  state.cursorY--;
239
239
  const prevLine = state.lines[state.cursorY];
240
- state.cursorX = prevLine.length;
241
- state.lines[state.cursorY] = prevLine + currentLine;
240
+ state.cursorX = prevLine?.length ?? 0;
241
+ state.lines[state.cursorY] = prevLine + (currentLine ?? "");
242
242
  updateModifiedStatus();
243
243
  }
244
244
  }
@@ -368,7 +368,7 @@ async function confirmAction(promptMessage = "Are you sure? (y/N)") {
368
368
  no: ["n", "N", "ENTER"]
369
369
  }).promise;
370
370
  term.moveTo(1, term.height).eraseLine();
371
- return confirm;
371
+ return confirm ?? false;
372
372
  } catch (_error) {
373
373
  term.moveTo(1, term.height).eraseLine();
374
374
  state.statusMessage = "Cancelled";
@@ -537,7 +537,7 @@ async function findText() {
537
537
  for (let y = state.cursorY; y < state.lines.length; y++) {
538
538
  const line = state.lines[y];
539
539
  const startIdx = y === state.cursorY ? state.cursorX + 1 : 0;
540
- const matchIndex = line.indexOf(termToUse, startIdx);
540
+ const matchIndex = line?.indexOf(termToUse, startIdx) ?? -1;
541
541
  if (matchIndex !== -1) {
542
542
  state.cursorY = y;
543
543
  state.cursorX = matchIndex;
@@ -549,8 +549,8 @@ async function findText() {
549
549
  state.statusMessage = `Search wrapped: ${termToUse}`;
550
550
  for (let y = 0; y <= state.cursorY; y++) {
551
551
  const line = state.lines[y];
552
- const endIdx = y === state.cursorY ? state.cursorX + 1 : line.length;
553
- const matchIndex = line.substring(0, endIdx).indexOf(termToUse);
552
+ const endIdx = y === state.cursorY ? state.cursorX + 1 : line?.length ?? 0;
553
+ const matchIndex = line?.substring(0, endIdx).indexOf(termToUse) ?? -1;
554
554
  if (matchIndex !== -1) {
555
555
  state.cursorY = y;
556
556
  state.cursorX = matchIndex;
@@ -229,7 +229,7 @@ export declare const mainSymbols: {
229
229
  lineSlash: string;
230
230
  };
231
231
  export declare const fallbackSymbols: Record<string, string>;
232
- declare const figures: {
232
+ export declare const figures: Record<string, string> | {
233
233
  tick: string;
234
234
  info: string;
235
235
  warning: string;
@@ -458,5 +458,4 @@ declare const figures: {
458
458
  lineCross: string;
459
459
  lineBackslash: string;
460
460
  lineSlash: string;
461
- } | Record<string, string>;
462
- export default figures;
461
+ };
@@ -282,5 +282,4 @@ export const fallbackSymbols = {
282
282
  ...specialFallbackSymbols
283
283
  };
284
284
  const shouldUseMain = isUnicodeSupported();
285
- const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
286
- export default figures;
285
+ export const figures = shouldUseMain ? mainSymbols : fallbackSymbols;
@@ -0,0 +1,4 @@
1
+ import type { InputPromptOptions } from "../../types.js";
2
+ export declare const input: any;
3
+ export declare const text: any;
4
+ export declare const password: (options: Omit<InputPromptOptions, "mode">) => any;