@reliverse/rempts 1.7.1 β†’ 1.7.3

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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > @reliverse/rempts is a modern, type-safe toolkit for building delightful cli experiences. it's fast, flexible, and made for developer happiness. file-based commands keep things simpleβ€”no clutter, just clean and easy workflows. this is how cli should feel.
4
4
 
5
- [πŸ’¬ Discord](https://discord.gg/3GawfWfAPe) β€” [πŸ“¦ NPM](https://npmjs.com/package/@reliverse/rempts) β€” [🧠 Docs](https://docs.reliverse.org/reliverse/rempts) β€” [🌐 JSR](https://jsr.io/@reliverse/rempts) β€” [✨ GitHub](https://github.com/reliverse/rempts)
5
+ [sponsor](https://github.com/sponsors/blefnk) β€” [discord](https://discord.gg/Pb8uKbwpsJ) β€” [repo](https://github.com/reliverse/rempts) β€” [npm](https://npmjs.com/@reliverse/rempts)
6
6
 
7
7
  ## Features
8
8
 
@@ -18,7 +18,7 @@
18
18
  - 🚨 Crash-safe (Ctrl+C, SIGINT, errors)
19
19
  - πŸͺ„ Minimal API surface, max expressiveness
20
20
  - πŸ§ͺ Scriptable for testing, stable for production
21
- - πŸ†• Automatic commands creation (via `dler init --cmd my-cool-cmd`)
21
+ - πŸ†• Automatic commands creation (via `dler rempts init --cmd my-cool-cmd`)
22
22
  - 🏞️ No more hacking together `inquirer`, `citty`, `commander`, `chalk`
23
23
 
24
24
  ## Installation
@@ -27,6 +27,14 @@
27
27
  bun add @reliverse/rempts
28
28
  ```
29
29
 
30
+ **Coming soon**:
31
+
32
+ ```bash
33
+ bun i -g @reliverse/dler
34
+ dler rempts init --cmd my-cmd-1
35
+ dler rempts init --cmds
36
+ ```
37
+
30
38
  ## Usage Examples
31
39
 
32
40
  - [Prompts](#prompts)
@@ -130,14 +138,14 @@ await main();
130
138
  ### Terminology
131
139
 
132
140
  - **Launcher/Router**: The main entry point for your CLI. Visit [CLI Launcher (Router)](#cli-launcher-router) section to learn more.
133
- - **Command/Subcommand**: A command is a function that defines the behavior of a CLI.
141
+ - **Command**: A command is a function that defines the inner script launched by the main script where runMain() is used or by some other command.
134
142
  - **Argument**: An argument is a value that is passed to a command.
135
143
  - **Flag**: A flag is a boolean argument that is used to enable or disable a feature.
136
144
  - **Option**: An option is a named argument that is used to configure a command.
137
145
 
138
146
  #### Launcher Usage Example
139
147
 
140
- ‼️ Go to [Usage Examples](#usage-examples) section for a more detailed example.
148
+ **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.
141
149
 
142
150
  ```ts
143
151
  import { relinka } from "@reliverse/relinka";
@@ -156,7 +164,7 @@ const main = defineCommand({
156
164
  onCmdEnd() {
157
165
  relinka("success", "Cleanup");
158
166
  },
159
- subCommands: {
167
+ commands: {
160
168
  build: () => import("./app/build/cmd.js").then((r) => r.default),
161
169
  deploy: () => import("./app/deploy/cmd.js").then((r) => r.default),
162
170
  debug: () => import("./app/debug/cmd.js").then((r) => r.default),
@@ -177,9 +185,9 @@ await runMain(myCommand, {
177
185
  });
178
186
  ```
179
187
 
180
- This flexibility allows you to easily build a rich, multi-command CLI with minimal boilerplate. The launcher even supports nested subcommands, making it simple to construct complex CLI applications.
188
+ This flexibility allows you to easily build a rich, multi-command CLI with minimal boilerplate. The launcher even supports nested commands, making it simple to construct complex CLI applications.
181
189
 
182
- #### File-Based Subcommands
190
+ #### File-Based Commands
183
191
 
184
192
  Drop a `./src/cli/app/add/index.ts` and it's live.
185
193
 
@@ -199,7 +207,7 @@ export default defineCommand({
199
207
  }),
200
208
  },
201
209
  async run({ args }) {
202
- relinka("info", "Adding:", args.name);
210
+ relinka("log", "Adding:", args.name);
203
211
  },
204
212
  });
205
213
  ```
@@ -214,7 +222,7 @@ export default defineCommand({
214
222
  **Hint**:
215
223
 
216
224
  - Install `bun add -D @reliverse/dler`
217
- - Use `dler init --cmd cmd1 cmd2` to init commands for rempts launcher's automatically
225
+ - Use `dler rempts init --cmd cmd1 cmd2` to init commands for rempts launcher's automatically
218
226
 
219
227
  ### Advanced Minimal API
220
228
 
@@ -227,7 +235,7 @@ defineCommand({
227
235
  animals: { type: "array", options: ["cat","dog"] },
228
236
  },
229
237
  async run({ args, raw }) { // or `async run(ctx)`
230
- relinka("info", args.name, args.verbose, args.animals); // or `relinka("info", ctx.args.name, ...);`
238
+ relinka("log", args.name, args.verbose, args.animals); // or `relinka("log", ctx.args.name, ...);`
231
239
  },
232
240
  });
233
241
  ```
@@ -281,7 +289,7 @@ await runMain(defineCommand({}));
281
289
 
282
290
  ```bash
283
291
  bun add -D @reliverse/dler # or: bun i -g @reliverse/dler
284
- bun dler init --cmd my-cmd-1 # or: dler init my-cmd-1 my-cmd-2 --main src/mod.ts
292
+ bun dler rempts init --cmd my-cmd-1 # or: dler rempts init my-cmd-1 my-cmd-2 --main src/mod.ts
285
293
  # * `--main` is optional, default is `./src/mod.ts`
286
294
  # * you can specify multiple commands at once
287
295
  ```
@@ -362,7 +370,7 @@ const main = defineCommand({
362
370
  ],
363
371
  });
364
372
 
365
- relinka("info", "You have selected:", { name, framework });
373
+ relinka("log", "You have selected:", { name, framework });
366
374
  },
367
375
  });
368
376
 
@@ -388,7 +396,7 @@ import {
388
396
  * This command demonstrates the full range of launcher features along with all supported argument types:
389
397
  *
390
398
  * - Global Usage Handling: Automatically processes `--help` and `--version`.
391
- * - File-Based Subcommands: Scans "app" for subcommands (e.g., `init`).
399
+ * - File-Based Commands: Scans "app" for commands (e.g., `init`).
392
400
  * - Comprehensive Argument Parsing: Supports positional, boolean, string, number, and array arguments.
393
401
  * - Interactive Prompts: Uses built-in prompt functions for an engaging CLI experience.
394
402
  */
@@ -397,7 +405,7 @@ const mainCommand = defineCommand({
397
405
  name: "rempts",
398
406
  version: "1.6.0",
399
407
  description:
400
- "An example CLI that supports file-based subcommands and all argument types.",
408
+ "An example CLI that supports file-based commands and all argument types.",
401
409
  },
402
410
  args: {
403
411
  // Positional arguments
@@ -440,10 +448,10 @@ const mainCommand = defineCommand({
440
448
  },
441
449
  async run({ args, raw }) {
442
450
  // Display invocation details and parsed arguments.
443
- relinka("info", "Main command was invoked!");
444
- relinka("info", "Parsed main-command args:", args);
445
- relinka("info", "Raw argv:", raw);
446
- relinka("info", "\nHelp: `rempts --help`, `rempts cmdName --help`");
451
+ relinka("log", "Main command was invoked!");
452
+ relinka("log", "Parsed main-command args:", args);
453
+ relinka("log", "Raw argv:", raw);
454
+ relinka("log", "\nHelp: `rempts --help`, `rempts cmdName --help`");
447
455
 
448
456
  // Begin interactive session with a prompt.
449
457
  await startPrompt({
@@ -467,7 +475,7 @@ const mainCommand = defineCommand({
467
475
  });
468
476
 
469
477
  // Log all gathered input details.
470
- relinka("info", "You have selected:", {
478
+ relinka("log", "You have selected:", {
471
479
  projectName,
472
480
  framework,
473
481
  inputFile: args.inputFile,
@@ -483,7 +491,7 @@ const mainCommand = defineCommand({
483
491
  /**
484
492
  * The `runMain()` function sets up the launcher with several advanced features:
485
493
  *
486
- * - File-Based Subcommands: Enables scanning for subcommands within the "app" directory.
494
+ * - File-Based Commands: Enables scanning for commands within the "app" directory.
487
495
  * - Alias Mapping: Shorthand flags (e.g., `-v`) are mapped to their full names (e.g., `--verbose`).
488
496
  * - Strict Mode & Unknown Flag Warnings: Unknown flags are either warned about or handled via a callback.
489
497
  * - Negated Boolean Support: Allows flags to be negated (e.g., `--no-verbose`).
@@ -491,8 +499,8 @@ const mainCommand = defineCommand({
491
499
  */
492
500
  await runMain(mainCommand, {
493
501
  fileBasedCmds: {
494
- enable: true, // Enables file-based subcommand detection.
495
- cmdsRootPath: "app", // Directory to scan for subcommands.
502
+ enable: true, // Enables file-based command detection.
503
+ cmdsRootPath: "app", // Directory to scan for commands.
496
504
  },
497
505
  alias: {
498
506
  v: "verbose", // Maps shorthand flag -v to --verbose.
@@ -509,10 +517,10 @@ await runMain(mainCommand, {
509
517
 
510
518
  ### CLI Launcher (Router)
511
519
 
512
- Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'s so called "launcher" is a uniquely powerful and ergonomic CLI toolkitβ€”one that helps you build delightful developer experiences with less code and more confidence. The launcher supports both programmatically defined subcommands and file-based routing, so you can structure your CLI however you like. It automatically detects and loads subcommands from your filesystem and provides robust usage and error handling out-of-the-box. The launcher is more than just a command runnerβ€”it's a robust, developer-friendly engine with several advanced features and thoughtful design choices:
520
+ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'s so called "launcher" is a uniquely powerful and ergonomic CLI toolkitβ€”one that helps you build delightful developer experiences with less code and more confidence. The launcher supports both programmatically defined commands and file-based routing, so you can structure your CLI however you like. It automatically detects and loads commands from your filesystem and provides robust usage and error handling out-of-the-box. The launcher is more than just a command runnerβ€”it's a robust, developer-friendly engine with several advanced features and thoughtful design choices:
513
521
 
514
- - **File-Based & Defined Subcommands:**
515
- Use `subCommands` in your command definition or let the launcher automatically load commands from a specified directory.
522
+ - **File-Based & Defined Commands:**
523
+ Use `commands` in your command definition or let the launcher automatically load commands from a specified directory.
516
524
 
517
525
  - **Automatic Command Detection:**
518
526
  The launcher scans your specified `cmdsRootPath` for command files matching common patterns such as:
@@ -539,20 +547,20 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
539
547
  - **Lifecycle Hooks:**
540
548
  You can define optional lifecycle hooks in your main command:
541
549
  - `onLauncherStart` and `onLauncherEnd` (global, called once per CLI process)
542
- - `onCmdStart` and `onCmdEnd` (per-subcommand, called before/after each subcommand, but NOT for the main `run()` handler)
550
+ - `onCmdStart` and `onCmdEnd` (per-command, called before/after each command, but NOT for the main `run()` handler)
543
551
 
544
552
  **Global Hooks:**
545
- - `onLauncherStart`: Called once, before any command/subcommand/run() is executed.
546
- - `onLauncherEnd`: Called once, after all command/subcommand/run() logic is finished (even if an error occurs).
553
+ - `onLauncherStart`: Called once, before any command/run() is executed.
554
+ - `onLauncherEnd`: Called once, after all command/run() logic is finished (even if an error occurs).
547
555
 
548
- **Per-Subcommand Hooks:**
549
- - `onCmdStart`: Called before each subcommand (not for main `run()`).
550
- - `onCmdEnd`: Called after each subcommand (not for main `run()`).
556
+ **Per-Command Hooks:**
557
+ - `onCmdStart`: Called before each command (not for main `run()`).
558
+ - `onCmdEnd`: Called after each command (not for main `run()`).
551
559
 
552
560
  This means:
553
- - If your CLI has multiple subcommands, `onCmdStart` and `onCmdEnd` will be called for each subcommand invocation, not just once for the whole CLI process.
554
- - If your main command has a `run()` handler (and no subcommand is invoked), these hooks are **not** called; use the `run()` handler itself or the global hooks for such logic.
555
- - This allows you to perform setup/teardown logic specific to each subcommand execution.
561
+ - If your CLI has multiple commands, `onCmdStart` and `onCmdEnd` will be called for each command invocation, not just once for the whole CLI process.
562
+ - If your main command has a `run()` handler (and no command is invoked), these hooks are **not** called; use the `run()` handler itself or the global hooks for such logic.
563
+ - This allows you to perform setup/teardown logic specific to each command execution.
556
564
  - If you want logic to run only once for the entire CLI process, use `onLauncherStart` and `onLauncherEnd`.
557
565
 
558
566
  **Example:**
@@ -561,27 +569,29 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
561
569
  const main = defineCommand({
562
570
  onLauncherStart() { relinka('info', 'Global setup (once per process)'); },
563
571
  onLauncherEnd() { relinka('info', 'Global cleanup (once per process)'); },
564
- onCmdStart() { relinka('info', 'Setup for each subcommand'); },
565
- onCmdEnd() { relinka('info', 'Cleanup for each subcommand'); },
566
- subCommands: { ... },
567
- run() { relinka('info', 'Main run handler (no subcommand)'); },
572
+ onCmdStart() { relinka('info', 'Setup for each command'); },
573
+ onCmdEnd() { relinka('info', 'Cleanup for each command'); },
574
+ commands: { ... },
575
+ run() { relinka('info', 'Main run handler (no command)'); },
568
576
  });
569
577
  // onLauncherStart/onLauncherEnd are called once per process
570
- // onCmdStart/onCmdEnd are called for every subcommand (not for main run())
578
+ // onCmdStart/onCmdEnd are called for every command (not for main run())
571
579
  // If you want per-run() logic, use the run() handler or global hooks
572
580
  ```
573
581
 
574
- > **Note:** The legacy `setup` and `cleanup` names are still supported as aliases for per-command hooks, but will be removed in a future major version. Prefer `onCmdStart` and `onCmdEnd` going forward.
582
+ - **Deprecation Notice**
583
+ - The legacy `setup` and `cleanup` names are still supported as aliases for per-command hooks, but will be removed in a future major version. Prefer `onCmdStart` and `onCmdEnd` going forward.
584
+ - The `subCommands` property is deprecated as well. Please use `commands` instead. `subCommands` will be removed in a future major version.
575
585
 
576
586
  - **Dynamic Usage Examples:**
577
- - The launcher inspects your available subcommands and their argument definitions, then prints a plausible example CLI invocation for a random subcommand directly in the help output. This helps users understand real-world usage at a glance.
587
+ - The launcher inspects your available commands and their argument definitions, then prints a plausible example CLI invocation for a random command directly in the help output. This helps users understand real-world usage at a glance.
578
588
 
579
- - **File-Based & Programmatic Subcommands:**
580
- - Both file-based and object subcommands are fully supported. The launcher can introspect their argument definitions and metadata for help, usage, and validation.
581
- - File-based subcommands are auto-discovered from your filesystem, while programmatic subcommands can be defined inline in your main command.
589
+ - **File-Based & Programmatic Commands:**
590
+ - Both file-based and object commands are fully supported. The launcher can introspect their argument definitions and metadata for help, usage, and validation.
591
+ - File-based commands are auto-discovered from your filesystem, while programmatic commands can be defined inline in your main command.
582
592
 
583
593
  - **Context-Aware Help Output:**
584
- - The help/usage output adapts to your CLI's structure, showing available subcommands, their aliases, argument details, and even dynamic usage examples. It also displays global options and context-specific error messages.
594
+ - The help/usage output adapts to your CLI's structure, showing available commands, their aliases, argument details, and even dynamic usage examples. It also displays global options and context-specific error messages.
585
595
 
586
596
  - **Error Handling:**
587
597
  - The launcher provides clear, actionable error messages for missing required arguments, invalid types, unknown commands, and import errors. It always shows relevant usage information to help users recover quickly.
@@ -598,6 +608,92 @@ Finally, a full-featured CLI launcher without the ceremony. `@reliverse/rempts`'
598
608
  - **Prompt-First, Modern UX:**
599
609
  - The launcher integrates tightly with the prompt engine, so you can build interactive, delightful CLIs with minimal effort.
600
610
 
611
+ ### Launcher Programmatic Execution
612
+
613
+ For larger CLIs or when you want to programmatically run commands (e.g.: [prompt demo](./example/prompts/mod.ts), tests, etc), you can organize your commands in a `cmds.ts` file and use the `runCmd` utility.
614
+
615
+ **Pro Tips & Best Practices**:
616
+
617
+ - Install `dler` globally and run `dler rempts init --cmds` to generate a `src/app/cmds.ts` (custom path is supported) file in your project.
618
+ - You can use any name for the `cmds.ts` file and store it anywhere, but `src/app/cmds.ts` is a good convention you can follow.
619
+ - Use the async function pattern for lazy loading if you have many commands or care about startup performance.
620
+ - Use eager loading (const) for small CLIs or demos where simplicity is preferred.
621
+
622
+ **Lazy Loading (Recommended for Most CLIs)**:
623
+
624
+ ```ts
625
+ // example/launcher/app/cmds.ts
626
+
627
+ export async function getCmdHooks() {
628
+ return (await import("./hooks/cmd.js")).default;
629
+ }
630
+
631
+ export async function getCmdFoo() {
632
+ return (await import("./foo/cmd.js")).default;
633
+ }
634
+
635
+ // ...more commands
636
+ ```
637
+
638
+ Usage:
639
+
640
+ ```ts
641
+ // example/prompts/mod.ts
642
+
643
+ import { getCmdHooks } from "@/launcher/app/cmds.js";
644
+ import { runCmd } from "@reliverse/rempts";
645
+
646
+ await runCmd(await getCmdHooks(), ["--flag"]);
647
+ // OR:
648
+ // const hooksCmd = await getCmdHooks();
649
+ // await runCmd(hooksCmd, ["--flag"]);
650
+ ```
651
+
652
+ **Alternative: Eager Loading (All Commands Loaded at Startup)**:
653
+
654
+ ```ts
655
+ // example/launcher/app/cmds.ts
656
+ export const hooksCmd = (await import("./hooks/cmd.js")).default;
657
+ export const fooCmd = (await import("./foo/cmd.js")).default;
658
+ // ...more commands
659
+ ```
660
+
661
+ Usage:
662
+
663
+ ```ts
664
+ import { hooksCmd } from "./cmds.js";
665
+ import { runCmd } from "@reliverse/rempts";
666
+
667
+ await runCmd(hooksCmd, ["--flag"]);
668
+ ```
669
+
670
+ **Programmatic Command Execution with `runCmd`**:
671
+
672
+ The `runCmd` utility lets you run a command's `run()` handler with parsed arguments, outside of the full launcher context. This is useful for demos, tests, or custom flows:
673
+
674
+ ```ts
675
+ import { runCmd } from "@reliverse/rempts";
676
+ import { hooksCmd } from "./cmds.js";
677
+
678
+ await runCmd(hooksCmd, ["--flag"]); // argv as array of strings
679
+ ```
680
+
681
+ Or with lazy loading:
682
+
683
+ ```ts
684
+ const hooksCmd = await getCmdHooks();
685
+ await runCmd(hooksCmd, ["--flag"]);
686
+ ```
687
+
688
+ **Note:** `runCmd` only runs the command's `run()` handler and does not handle subcommands, file-based commands, or global hooks. For full CLI behavior, use `runMain`.
689
+
690
+ **Performance Note:**
691
+
692
+ - Eager loading (`const`) loads all commands at startup, which may impact performance for large CLIs.
693
+ - Lazy loading (`async function`) loads each command only when needed, improving startup time and memory usage.
694
+
695
+ Choose the pattern that best fits your CLI's size and usage!
696
+
601
697
  ## Contributing
602
698
 
603
699
  Bug report? Prompt idea? Want to build the best DX possible?
@@ -27,7 +27,7 @@ export async function runMain<T extends ArgsDef = ArgsDef>(
27
27
  if (!meta?.version) {
28
28
  throw new CLIError("No version specified", "E_NO_VERSION");
29
29
  }
30
- relinka("info", meta.version);
30
+ relinka("log", meta.version);
31
31
  } else {
32
32
  await runCommand(cmd, { rawArgs });
33
33
  }
@@ -12,7 +12,7 @@ export async function showUsage<T extends ArgsDef = ArgsDef>(
12
12
  ) {
13
13
  try {
14
14
  // biome-ignore lint/style/useTemplate: <explanation>
15
- relinka("info", (await renderUsage(cmd, parent)) + "\n");
15
+ relinka("log", (await renderUsage(cmd, parent)) + "\n");
16
16
  } catch (error) {
17
17
  relinka("error", String(error));
18
18
  }
@@ -44,42 +44,50 @@ type CommandMeta = {
44
44
  * 2) A lazy import function returning a Promise that resolves to
45
45
  * { default: Command<any> } or directly to a Command instance.
46
46
  */
47
- type SubCommandSpec = string | (() => Promise<{
47
+ type CommandSpec = string | (() => Promise<{
48
48
  default: Command<any>;
49
49
  } | Command<any>>);
50
- export type SubCommandsMap = Record<string, SubCommandSpec>;
50
+ export type CommandsMap = Record<string, CommandSpec>;
51
51
  type CommandContext<ARGS> = {
52
52
  args: ARGS;
53
53
  raw: string[];
54
54
  };
55
55
  type CommandRun<ARGS> = (ctx: CommandContext<ARGS>) => void | Promise<void>;
56
+ type CommandHook<ARGS> = (ctx: CommandContext<ARGS>) => void | Promise<void>;
56
57
  type DefineCommandOptions<A extends ArgDefinitions = EmptyArgs> = {
57
58
  meta?: CommandMeta;
58
59
  args?: A;
59
60
  run?: CommandRun<InferArgTypes<A>>;
60
- subCommands?: SubCommandsMap;
61
61
  /**
62
- * Called before the command or subcommand runs
62
+ * Object subcommands for this command.
63
63
  */
64
- onCmdStart?: () => void | Promise<void>;
64
+ commands?: CommandsMap;
65
65
  /**
66
- * Called after the command or subcommand finishes
66
+ * @deprecated Use `commands` instead. Will be removed in a future major version.
67
67
  */
68
- onCmdEnd?: () => void | Promise<void>;
68
+ subCommands?: CommandsMap;
69
+ /**
70
+ * Called before the command runs. Receives `{ args, raw }` (parsed args and raw argv).
71
+ */
72
+ onCmdStart?: CommandHook<InferArgTypes<A>>;
73
+ /**
74
+ * Called after the command finishes. Receives `{ args, raw }` (parsed args and raw argv).
75
+ */
76
+ onCmdEnd?: CommandHook<InferArgTypes<A>>;
69
77
  /**
70
78
  * @deprecated Use onCmdStart instead
71
79
  */
72
- setup?: () => void | Promise<void>;
80
+ setup?: CommandHook<InferArgTypes<A>>;
73
81
  /**
74
82
  * @deprecated Use onCmdEnd instead
75
83
  */
76
- cleanup?: () => void | Promise<void>;
84
+ cleanup?: CommandHook<InferArgTypes<A>>;
77
85
  /**
78
- * Called once per CLI process, before any command/subcommand/run() is executed
86
+ * Called once per CLI process, before any command/run() is executed
79
87
  */
80
88
  onLauncherStart?: () => void | Promise<void>;
81
89
  /**
82
- * Called once per CLI process, after all command/subcommand/run() logic is finished
90
+ * Called once per CLI process, after all command/run() logic is finished
83
91
  */
84
92
  onLauncherEnd?: () => void | Promise<void>;
85
93
  };
@@ -87,29 +95,36 @@ export type Command<A extends ArgDefinitions = EmptyArgs> = {
87
95
  meta?: CommandMeta;
88
96
  args: A;
89
97
  run?: CommandRun<InferArgTypes<A>>;
90
- subCommands?: SubCommandsMap;
91
98
  /**
92
- * Called before the command or subcommand runs
99
+ * Object subcommands for this command.
100
+ */
101
+ commands?: CommandsMap;
102
+ /**
103
+ * @deprecated Use `commands` instead. Will be removed in a future major version.
93
104
  */
94
- onCmdStart?: () => void | Promise<void>;
105
+ subCommands?: CommandsMap;
95
106
  /**
96
- * Called after the command or subcommand finishes
107
+ * Called before the command runs. Receives `{ args, raw }` (parsed args and raw argv).
97
108
  */
98
- onCmdEnd?: () => void | Promise<void>;
109
+ onCmdStart?: CommandHook<InferArgTypes<A>>;
110
+ /**
111
+ * Called after the command finishes. Receives `{ args, raw }` (parsed args and raw argv).
112
+ */
113
+ onCmdEnd?: CommandHook<InferArgTypes<A>>;
99
114
  /**
100
115
  * @deprecated Use onCmdStart instead
101
116
  */
102
- setup?: () => void | Promise<void>;
117
+ setup?: CommandHook<InferArgTypes<A>>;
103
118
  /**
104
119
  * @deprecated Use onCmdEnd instead
105
120
  */
106
- cleanup?: () => void | Promise<void>;
121
+ cleanup?: CommandHook<InferArgTypes<A>>;
107
122
  /**
108
- * Called once per CLI process, before any command/subcommand/run() is executed
123
+ * Called once per CLI process, before any command/run() is executed
109
124
  */
110
125
  onLauncherStart?: () => void | Promise<void>;
111
126
  /**
112
- * Called once per CLI process, after all command/subcommand/run() logic is finished
127
+ * Called once per CLI process, after all command/run() logic is finished
113
128
  */
114
129
  onLauncherEnd?: () => void | Promise<void>;
115
130
  };
@@ -152,11 +167,11 @@ export declare function showUsage<A extends ArgDefinitions>(command: Command<A>,
152
167
  /**
153
168
  * Primary entry point to run a command. This function supports:
154
169
  *
155
- * - File-based Subcommands: scanning for subcommands within a given commands root.
156
- * - SubCommands defined within the command object.
170
+ * - File-based Commands: scanning for commands within a given commands root.
171
+ * - Commands defined within the command object.
157
172
  * - Standard flags like --help, --version, and --debug.
158
173
  *
159
- * This function passes along remaining arguments to subcommand runners to ensure
174
+ * This function passes along remaining arguments to command runners to ensure
160
175
  * consistent parsing.
161
176
  */
162
177
  export declare function runMain<A extends ArgDefinitions = EmptyArgs>(command: Command<A>, parserOptions?: ReliArgParserOptions & {
@@ -174,4 +189,14 @@ export declare function runMain<A extends ArgDefinitions = EmptyArgs>(command: C
174
189
  * precise default value validation (e.g., `options: ["a", "b"] as const`).
175
190
  */
176
191
  export declare function defineArgs<A extends ArgDefinitions>(args: A & ValidateArrayDefaults<A>): A;
192
+ /**
193
+ * Programmatically run a command's run() handler with parsed arguments.
194
+ * Does not handle subcommands, file-based commands, or global hooks.
195
+ * Suitable for use in demos, tests, or programmatic invocation.
196
+ *
197
+ * @param command The command definition (from defineCommand)
198
+ * @param argv The argv array to parse (default: [])
199
+ * @param parserOptions Optional reliArgParser options
200
+ */
201
+ export declare function runCmd<A extends ArgDefinitions = EmptyArgs>(command: Command<A>, argv?: string[], parserOptions?: ReliArgParserOptions): Promise<void>;
177
202
  export {};
@@ -50,7 +50,7 @@ function buildExampleArgs(args) {
50
50
  const isDebugMode = process.argv.includes("--debug");
51
51
  function debugLog(...args) {
52
52
  if (isDebugMode) {
53
- relinka("info", "[DEBUG]", ...args);
53
+ relinka("log", "[DEBUG]", ...args);
54
54
  }
55
55
  }
56
56
  function isFlag(str) {
@@ -61,11 +61,15 @@ export function defineCommand(options) {
61
61
  const onCmdEnd = options.onCmdEnd || options.cleanup;
62
62
  const onLauncherStart = options.onLauncherStart;
63
63
  const onLauncherEnd = options.onLauncherEnd;
64
- return {
64
+ let commands = options.commands;
65
+ if (!commands) {
66
+ commands = options.subCommands;
67
+ }
68
+ const cmdObj = {
65
69
  meta: options.meta,
66
70
  args: options.args || {},
67
71
  run: options.run,
68
- subCommands: options.subCommands,
72
+ commands,
69
73
  onCmdStart,
70
74
  onCmdEnd,
71
75
  onLauncherStart,
@@ -74,6 +78,14 @@ export function defineCommand(options) {
74
78
  setup: onCmdStart,
75
79
  cleanup: onCmdEnd
76
80
  };
81
+ Object.defineProperty(cmdObj, "subCommands", {
82
+ get() {
83
+ return this.commands;
84
+ },
85
+ enumerable: false,
86
+ configurable: true
87
+ });
88
+ return cmdObj;
77
89
  }
78
90
  let _cachedDefaultCliName;
79
91
  let _cachedDefaultCliVersion;
@@ -97,7 +109,7 @@ export async function showUsage(command, parserOptions = {}, displayNotFoundMess
97
109
  const { name: fallbackName, version: fallbackVersion } = await getDefaultCliNameAndVersion();
98
110
  const cliName = command.meta?.name || fallbackName;
99
111
  const cliVersion = command.meta?.version || fallbackVersion;
100
- relinka("info", `${cliName}${cliVersion ? ` v${cliVersion}` : ""}`);
112
+ relinka("log", `${cliName}${cliVersion ? ` v${cliVersion}` : ""}`);
101
113
  if (parserOptions.metaSettings?.showDescriptionOnMain) {
102
114
  let description = command.meta?.description;
103
115
  if (!description) {
@@ -173,8 +185,9 @@ export async function showUsage(command, parserOptions = {}, displayNotFoundMess
173
185
  } else {
174
186
  const subCommandNames = [];
175
187
  const subCommandDefs = [];
176
- if (command.subCommands) {
177
- for (const [name, spec] of Object.entries(command.subCommands)) {
188
+ const objectCommands = command.commands;
189
+ if (objectCommands) {
190
+ for (const [name, spec] of Object.entries(objectCommands)) {
178
191
  try {
179
192
  const cmd = await loadSubCommand(spec);
180
193
  if (!cmd?.meta?.hidden) {
@@ -183,7 +196,7 @@ export async function showUsage(command, parserOptions = {}, displayNotFoundMess
183
196
  subCommandDefs.push({ name, def: cmd });
184
197
  }
185
198
  } catch (err) {
186
- debugLog(`Error loading subcommand ${name}:`, err);
199
+ debugLog(`Error loading command ${name}:`, err);
187
200
  }
188
201
  }
189
202
  }
@@ -240,7 +253,7 @@ export async function runMain(command, parserOptions = {}) {
240
253
  if (typeof command.onLauncherStart === "function")
241
254
  await command.onLauncherStart();
242
255
  try {
243
- if (!parserOptions.fileBasedCmds && !command.subCommands) {
256
+ if (!parserOptions.fileBasedCmds && !command.commands) {
244
257
  let callerDir = process.cwd();
245
258
  let callerFile;
246
259
  try {
@@ -289,7 +302,7 @@ This can cause recursion or unexpected behavior.`
289
302
  }
290
303
  const rawArgv = process.argv.slice(2);
291
304
  const autoExit = parserOptions.autoExit !== false;
292
- if (!(parserOptions.fileBasedCmds?.enable || command.subCommands && Object.keys(command.subCommands).length > 0 || command.run)) {
305
+ if (!(parserOptions.fileBasedCmds?.enable || command.commands && Object.keys(command.commands).length > 0 || command.run)) {
293
306
  relinka(
294
307
  "error",
295
308
  "Invalid CLI configuration: No file-based commands, subCommands, or run() handler are defined. This CLI will not do anything.\n\u2502 To fix: add file-based commands (./app), or provide at least one subCommand or a run() handler."
@@ -310,7 +323,7 @@ This can cause recursion or unexpected behavior.`
310
323
  if (checkVersion(rawArgv)) {
311
324
  if (command.meta?.name) {
312
325
  relinka(
313
- "info",
326
+ "log",
314
327
  `${command.meta?.name} ${command.meta?.version ? `v${command.meta?.version}` : ""}`
315
328
  );
316
329
  }
@@ -321,14 +334,17 @@ This can cause recursion or unexpected behavior.`
321
334
  if (fileBasedEnabled && rawArgv.length > 0 && !isFlag(rawArgv[0])) {
322
335
  const [subName, ...subCmdArgv] = rawArgv;
323
336
  try {
337
+ const ctx = getParsedContext(command, rawArgv, parserOptions);
324
338
  if (typeof command.onCmdStart === "function")
325
- await command.onCmdStart();
339
+ await command.onCmdStart(ctx);
326
340
  await runFileBasedSubCmd(
327
341
  subName,
328
342
  subCmdArgv,
329
343
  parserOptions.fileBasedCmds,
330
344
  parserOptions,
331
- command.onCmdEnd
345
+ command.onCmdEnd ? async (_subCtx) => {
346
+ await command.onCmdEnd?.(ctx);
347
+ } : void 0
332
348
  );
333
349
  if (autoExit) process.exit(0);
334
350
  return;
@@ -338,10 +354,10 @@ This can cause recursion or unexpected behavior.`
338
354
  throw err;
339
355
  }
340
356
  }
341
- if (!fileBasedEnabled && command.subCommands && rawArgv.length > 0 && !isFlag(rawArgv[0])) {
357
+ if (!fileBasedEnabled && command.commands && rawArgv.length > 0 && !isFlag(rawArgv[0])) {
342
358
  const [maybeSub, ...subCmdArgv] = rawArgv;
343
359
  let subSpec;
344
- for (const [key, spec] of Object.entries(command.subCommands)) {
360
+ for (const [key, spec] of Object.entries(command.commands)) {
345
361
  if (key === maybeSub) {
346
362
  subSpec = spec;
347
363
  break;
@@ -353,18 +369,21 @@ This can cause recursion or unexpected behavior.`
353
369
  break;
354
370
  }
355
371
  } catch (err) {
356
- debugLog(`Error checking alias for subcommand ${key}:`, err);
372
+ debugLog(`Error checking alias for command ${key}:`, err);
357
373
  }
358
374
  }
359
375
  if (subSpec) {
360
376
  try {
377
+ const ctx = getParsedContext(command, rawArgv, parserOptions);
361
378
  if (typeof command.onCmdStart === "function")
362
- await command.onCmdStart();
379
+ await command.onCmdStart(ctx);
363
380
  await runSubCommand(
364
381
  subSpec,
365
382
  subCmdArgv,
366
383
  parserOptions,
367
- command.onCmdEnd
384
+ command.onCmdEnd ? async (_subCtx) => {
385
+ await command.onCmdEnd?.(ctx);
386
+ } : void 0
368
387
  );
369
388
  if (autoExit) process.exit(0);
370
389
  return;
@@ -461,20 +480,32 @@ Info for this CLI's developer: No valid command directory found, expected: ${exp
461
480
  );
462
481
  }
463
482
  try {
464
- await runCommandWithArgs(subCommand, argv, parserOptions);
483
+ const subCtx = await runCommandWithArgs(
484
+ subCommand,
485
+ argv,
486
+ parserOptions,
487
+ true
488
+ );
489
+ if (typeof parentFinish === "function" && subCtx)
490
+ await parentFinish(subCtx);
465
491
  } finally {
466
- if (typeof parentFinish === "function") await parentFinish();
467
492
  }
468
493
  }
469
494
  async function runSubCommand(spec, argv, parserOptions, parentFinish) {
470
495
  const subCommand = await loadSubCommand(spec);
471
496
  try {
472
- await runCommandWithArgs(subCommand, argv, parserOptions);
497
+ const subCtx = await runCommandWithArgs(
498
+ subCommand,
499
+ argv,
500
+ parserOptions,
501
+ true
502
+ );
503
+ if (typeof parentFinish === "function" && subCtx)
504
+ await parentFinish(subCtx);
473
505
  } finally {
474
- if (typeof parentFinish === "function") await parentFinish();
475
506
  }
476
507
  }
477
- async function runCommandWithArgs(command, argv, parserOptions) {
508
+ async function runCommandWithArgs(command, argv, parserOptions, returnCtx) {
478
509
  const autoExit = parserOptions.autoExit !== false;
479
510
  const booleanKeys = Object.keys(command.args || {}).filter(
480
511
  (k) => command.args[k].type === "boolean"
@@ -556,7 +587,7 @@ async function runCommandWithArgs(command, argv, parserOptions) {
556
587
  if (command.run) {
557
588
  await command.run(ctx);
558
589
  } else {
559
- const isDispatcher = parserOptions.fileBasedCmds?.enable || command.subCommands && Object.keys(command.subCommands).length > 0;
590
+ const isDispatcher = parserOptions.fileBasedCmds?.enable || command.commands && Object.keys(command.commands).length > 0;
560
591
  const noSubcommandArgInCurrentCall = !argv.some((arg) => !isFlag(arg));
561
592
  if (isDispatcher && noSubcommandArgInCurrentCall) {
562
593
  relinka("warn", "Please specify a command");
@@ -580,6 +611,8 @@ ${String(err)}`);
580
611
  if (autoExit) process.exit(1);
581
612
  else throw err;
582
613
  }
614
+ if (returnCtx) return ctx;
615
+ return void 0;
583
616
  }
584
617
  function castArgValue(def, rawVal, argName) {
585
618
  if (rawVal == null) {
@@ -624,3 +657,118 @@ function renderPositional(args) {
624
657
  export function defineArgs(args) {
625
658
  return args;
626
659
  }
660
+ export async function runCmd(command, argv = [], parserOptions = {}) {
661
+ const booleanKeys = Object.keys(command.args || {}).filter(
662
+ (k) => command.args[k].type === "boolean"
663
+ );
664
+ const defaultMap = {};
665
+ for (const [argKey, def] of Object.entries(command.args || {})) {
666
+ if (def.default !== void 0) {
667
+ if (def.type === "array" && typeof def.default === "string") {
668
+ defaultMap[argKey] = [def.default];
669
+ } else {
670
+ defaultMap[argKey] = def.default;
671
+ }
672
+ }
673
+ }
674
+ const mergedParserOptions = {
675
+ ...parserOptions,
676
+ boolean: [...parserOptions.boolean || [], ...booleanKeys],
677
+ defaults: { ...defaultMap, ...parserOptions.defaults || {} }
678
+ };
679
+ const parsed = reliArgParser(argv, mergedParserOptions);
680
+ debugLog("Parsed arguments (runCmd):", parsed);
681
+ const finalArgs = {};
682
+ const positionalKeys = Object.keys(command.args || {}).filter(
683
+ (k) => command.args[k].type === "positional"
684
+ );
685
+ const leftoverPositionals = [...parsed._ || []];
686
+ for (let i = 0; i < positionalKeys.length; i++) {
687
+ const key = positionalKeys[i];
688
+ const def = command.args?.[key];
689
+ const val = leftoverPositionals[i];
690
+ if (val == null && def.required) {
691
+ throw new Error(`Missing required positional argument: <${key}>`);
692
+ }
693
+ finalArgs[key] = val != null ? castArgValue(def, val, key) : def.default;
694
+ }
695
+ const otherKeys = Object.keys(command.args || {}).filter(
696
+ (k) => command.args[k].type !== "positional"
697
+ );
698
+ for (const key of otherKeys) {
699
+ const def = command.args?.[key];
700
+ let rawVal = parsed[key];
701
+ if (def.type === "array" && rawVal !== void 0 && !Array.isArray(rawVal)) {
702
+ rawVal = [rawVal];
703
+ }
704
+ const valueOrDefault = rawVal ?? defaultMap[key];
705
+ if (valueOrDefault == null && def.required) {
706
+ throw new Error(`Missing required argument: --${key}`);
707
+ }
708
+ finalArgs[key] = castArgValue(def, rawVal, key);
709
+ if (def.type === "array" && def.options && finalArgs[key]) {
710
+ const values = finalArgs[key];
711
+ const invalidOptions = values.filter(
712
+ (v) => def.options && !def.options.includes(v)
713
+ );
714
+ if (invalidOptions.length > 0) {
715
+ throw new Error(
716
+ `Invalid choice(s) for --${key}: ${invalidOptions.join(", ")}. Allowed options: ${def.options.join(", ")}`
717
+ );
718
+ }
719
+ }
720
+ }
721
+ const ctx = {
722
+ args: finalArgs,
723
+ raw: argv
724
+ };
725
+ if (typeof command.run === "function") {
726
+ await command.run(ctx);
727
+ } else {
728
+ throw new Error("Command has no run() handler.");
729
+ }
730
+ }
731
+ function getParsedContext(command, argv, parserOptions) {
732
+ const booleanKeys = Object.keys(command.args || {}).filter(
733
+ (k) => command.args[k].type === "boolean"
734
+ );
735
+ const defaultMap = {};
736
+ for (const [argKey, def] of Object.entries(command.args || {})) {
737
+ if (def.default !== void 0) {
738
+ if (def.type === "array" && typeof def.default === "string") {
739
+ defaultMap[argKey] = [def.default];
740
+ } else {
741
+ defaultMap[argKey] = def.default;
742
+ }
743
+ }
744
+ }
745
+ const mergedParserOptions = {
746
+ ...parserOptions,
747
+ boolean: [...parserOptions.boolean || [], ...booleanKeys],
748
+ defaults: { ...defaultMap, ...parserOptions.defaults || {} }
749
+ };
750
+ const parsed = reliArgParser(argv, mergedParserOptions);
751
+ const finalArgs = {};
752
+ const positionalKeys = Object.keys(command.args || {}).filter(
753
+ (k) => command.args[k].type === "positional"
754
+ );
755
+ const leftoverPositionals = [...parsed._ || []];
756
+ for (let i = 0; i < positionalKeys.length; i++) {
757
+ const key = positionalKeys[i];
758
+ const def = command.args?.[key];
759
+ const val = leftoverPositionals[i];
760
+ finalArgs[key] = val != null ? castArgValue(def, val, key) : def.default;
761
+ }
762
+ const otherKeys = Object.keys(command.args || {}).filter(
763
+ (k) => command.args[k].type !== "positional"
764
+ );
765
+ for (const key of otherKeys) {
766
+ const def = command.args?.[key];
767
+ let rawVal = parsed[key];
768
+ if (def.type === "array" && rawVal !== void 0 && !Array.isArray(rawVal)) {
769
+ rawVal = [rawVal];
770
+ }
771
+ finalArgs[key] = castArgValue(def, rawVal, key);
772
+ }
773
+ return { args: finalArgs, raw: argv };
774
+ }
@@ -21,7 +21,10 @@ export const symbols = {
21
21
  step_active: u("\u25C6", "\u2666"),
22
22
  step_error: u("\u{1F5F4}", "x"),
23
23
  info: u("\u2139", "i"),
24
- success: u("\u2705", "\u2713")
24
+ log: u("\u2502", "|"),
25
+ success: u("\u2705", "\u2713"),
26
+ warn: u("\u26A0", "!"),
27
+ error: u("\u274C", "x")
25
28
  };
26
29
  function wrapThenStyle(input, wrap, typographyName, colorName, variantName, borderColor) {
27
30
  if (!input) return "";
@@ -309,8 +312,8 @@ export function msgUndoAll() {
309
312
  }
310
313
  export function printLineBar(text, indent = 2) {
311
314
  if (text === "") {
312
- relinka("info", re.dim("\u2502"));
315
+ relinka("log", re.dim("\u2502"));
313
316
  } else {
314
- relinka("info", `${re.dim("\u2502")}${" ".repeat(indent)}${text}`);
317
+ relinka("log", `${re.dim("\u2502")}${" ".repeat(indent)}${text}`);
315
318
  }
316
319
  }
@@ -86,7 +86,7 @@ function renderPromptUI(params) {
86
86
  uiLineCount++;
87
87
  }
88
88
  if (debug) {
89
- relinka("info", "", { optionsCount: options.length });
89
+ relinka("log", "", { optionsCount: options.length });
90
90
  }
91
91
  return uiLineCount;
92
92
  }
@@ -104,7 +104,7 @@ async function renderPromptUI(params) {
104
104
  uiLineCount++;
105
105
  }
106
106
  if (debug) {
107
- relinka("info", "", { optionsCount: options.length });
107
+ relinka("log", "", { optionsCount: options.length });
108
108
  }
109
109
  return uiLineCount;
110
110
  }
@@ -59,7 +59,7 @@ function renderTogglePrompt(params) {
59
59
  msg({ type: "M_NULL", title: displayString });
60
60
  uiLineCount++;
61
61
  if (debug) {
62
- relinka("info", "", {
62
+ relinka("log", "", {
63
63
  selectedIndex,
64
64
  displayOptions: options
65
65
  });
@@ -50,9 +50,9 @@ export async function startPrompt({
50
50
  }
51
51
  if (clearConsole) {
52
52
  relinka("clear", "");
53
- relinka("info", "");
53
+ relinka("log", "");
54
54
  } else {
55
- relinka("info", "");
55
+ relinka("log", "");
56
56
  }
57
57
  msg({
58
58
  type: "M_START",
@@ -9,5 +9,5 @@ export async function createAsciiArt({
9
9
  relinka("clear", "");
10
10
  }
11
11
  const asciiArt = figlet.textSync(message, { font });
12
- relinka("info", asciiArt);
12
+ relinka("log", asciiArt);
13
13
  }
package/bin/mod.d.ts CHANGED
@@ -4,7 +4,7 @@ export { startEditor } from "./components/editor/editor-mod.js";
4
4
  export { mainSymbols, fallbackSymbols, } from "./components/figures/figures-mod.js";
5
5
  export { confirmPrompt } from "./components/input/confirm-prompt.js";
6
6
  export { inputPrompt } from "./components/input/input-prompt.js";
7
- export type { ArgDefinition, ArgDefinitions, SubCommandsMap, Command, InferArgTypes, FileBasedCmdsOptions, } from "./components/launcher/launcher-mod.js";
7
+ export type { ArgDefinition, ArgDefinitions, CommandsMap, Command, InferArgTypes, FileBasedCmdsOptions, } from "./components/launcher/launcher-mod.js";
8
8
  export { defineCommand, defineArgs, showUsage, runMain, } from "./components/launcher/launcher-mod.js";
9
9
  export { toBaseColor, toSolidColor } from "./components/msg-fmt/colors.js";
10
10
  export { relinkaByRemptsDeprecated, relinkaAsyncByRemptsDeprecated, throwError, } from "./components/msg-fmt/logger.js";
package/bin/types.d.ts CHANGED
@@ -241,7 +241,7 @@ export type RenderParams = {
241
241
  /**
242
242
  * Known symbol names that will have IntelliSense support
243
243
  */
244
- export type SymbolName = "pointer" | "start" | "middle" | "end" | "line" | "corner_top_right" | "step_active" | "step_error" | "info" | "success";
244
+ export type SymbolName = "pointer" | "start" | "middle" | "end" | "line" | "corner_top_right" | "step_active" | "step_error" | "log" | "success" | "info" | "warn" | "error";
245
245
  export type Symbols = Record<SymbolName, string>;
246
246
  export type FmtMsgOptions = {
247
247
  type: MsgType;
@@ -21,14 +21,14 @@ export async function completePrompt(prompt, isCtrlC, _endTitle = "", _endTitleC
21
21
  return value ?? false;
22
22
  }
23
23
  export function renderEndLine() {
24
- const lineLength = getExactTerminalWidth() - 2;
25
- relinka("info", re.dim(symbols.middle));
26
- relinka("info", re.dim(`${symbols.end}${symbols.line.repeat(lineLength)}\u22B1`));
27
- relinka("info", "");
24
+ const lineLength = getExactTerminalWidth() - 6;
25
+ relinka("null", re.dim(symbols.middle));
26
+ relinka("null", re.dim(`${symbols.end}${symbols.line.repeat(lineLength)}\u22B1`));
27
+ relinka("null", "");
28
28
  }
29
29
  export function renderEndLineInput() {
30
- const lineLength = getExactTerminalWidth() - 2;
31
- relinka("info", "");
32
- relinka("info", re.dim(`${symbols.end}${symbols.line.repeat(lineLength)}\u22B1`));
33
- relinka("info", "");
30
+ const lineLength = getExactTerminalWidth() - 6;
31
+ relinka("null", "");
32
+ relinka("null", re.dim(`${symbols.end}${symbols.line.repeat(lineLength)}\u22B1`));
33
+ relinka("null", "");
34
34
  }
package/package.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "dependencies": {
3
3
  "@figliolia/chalk-animation": "^1.0.4",
4
4
  "@reliverse/reliarg": "^1.0.3",
5
- "@reliverse/relico": "^1.1.1",
6
- "@reliverse/relinka": "^1.4.3",
5
+ "@reliverse/relico": "^1.1.2",
6
+ "@reliverse/relinka": "^1.4.5",
7
7
  "@reliverse/runtime": "^1.0.3",
8
8
  "ansi-escapes": "^7.0.0",
9
9
  "c12": "^3.0.3",
@@ -28,7 +28,7 @@
28
28
  "license": "MIT",
29
29
  "name": "@reliverse/rempts",
30
30
  "type": "module",
31
- "version": "1.7.1",
31
+ "version": "1.7.3",
32
32
  "author": "reliverse",
33
33
  "bugs": {
34
34
  "email": "blefnk@gmail.com",
@@ -58,7 +58,7 @@
58
58
  "eslint-plugin-no-relative-import-paths": "^1.6.1",
59
59
  "eslint-plugin-perfectionist": "^4.13.0",
60
60
  "jiti": "^2.4.2",
61
- "knip": "^5.55.1",
61
+ "knip": "^5.56.0",
62
62
  "typescript": "^5.8.3",
63
63
  "typescript-eslint": "^8.32.1",
64
64
  "vitest": "^3.1.3"