cli-kiss 0.2.4 → 0.2.5

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/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ type ReaderOptionKey = (string | {
11
11
  */
12
12
  type ReaderOptionParsing = {
13
13
  consumeShortGroup: boolean;
14
- consumeNextArg: (inlined: string | null, separated: Array<string>, next: string | undefined) => boolean;
14
+ consumeNextArg: (inlined: string | null, separated: Array<string>, nextArg: string | undefined) => boolean;
15
15
  };
16
16
  /**
17
17
  * Result of parsing an option, including its inlined value and any following separated values.
@@ -105,17 +105,17 @@ declare class ReaderArgs {
105
105
 
106
106
  /**
107
107
  * Decodes a raw CLI string into a typed value.
108
- * A pair of a human-readable `content` name (e.g. `"Number"`) and a `decoder` function.
108
+ * A pair of a human-readable `content` name and a `decoder` function.
109
109
  *
110
- * Built-in: {@link typeString}, {@link typeBoolean}, {@link typeNumber},
111
- * {@link typeInteger}, {@link typeDate}, {@link typeUrl}.
112
- * Composite: {@link typeOneOf}, {@link typeMapped}, {@link typeTuple}, {@link typeList}.
110
+ * Built-in: {@link type}, {@link typeBoolean}, {@link typeNumber},
111
+ * {@link typeInteger}, {@link typeDatetime}, {@link typeUrl}.
112
+ * Composite: {@link typeChoice}, {@link typeConverted}, {@link typeTuple}, {@link typeList}.
113
113
  *
114
114
  * @typeParam Value - Type produced by the decoder.
115
115
  */
116
116
  type Type<Value> = {
117
117
  /**
118
- * Human-readable name shown in help and errors (e.g. `"String"`, `"Number"`).
118
+ * Human-readable name shown in help and errors (e.g. `"name"`, `"number"`).
119
119
  */
120
120
  content: string;
121
121
  /**
@@ -133,71 +133,71 @@ type Type<Value> = {
133
133
  *
134
134
  * @example
135
135
  * ```ts
136
- * typeBoolean.decoder("true") // → true
137
- * typeBoolean.decoder("yes") // → true
138
- * typeBoolean.decoder("y") // → true
139
- * typeBoolean.decoder("false") // → false
140
- * typeBoolean.decoder("no") // → false
141
- * typeBoolean.decoder("n") // → false
136
+ * typeBoolean("flag").decoder("true") // → true
137
+ * typeBoolean("flag").decoder("yes") // → true
138
+ * typeBoolean("flag").decoder("y") // → true
139
+ * typeBoolean("flag").decoder("false") // → false
140
+ * typeBoolean("flag").decoder("no") // → false
141
+ * typeBoolean("flag").decoder("n") // → false
142
142
  * ```
143
143
  */
144
- declare const typeBoolean: Type<boolean>;
144
+ declare function typeBoolean(name?: string): Type<boolean>;
145
145
  /**
146
146
  * Parses a date/time string via `Date.parse`.
147
147
  * Accepts any format supported by `Date.parse`, including ISO 8601.
148
148
  *
149
149
  * @example
150
150
  * ```ts
151
- * typeDate.decoder("2024-01-15") // → Date object for 2024-01-15
152
- * typeDate.decoder("2024-01-15T13:45:30Z") // → Date object for 2024-01-15 13:45:30 UTC
153
- * typeDate.decoder("not a date") // throws TypoError
151
+ * typeDatetime("my-datetime").decoder("2024-01-15") // → Date object for 2024-01-15
152
+ * typeDatetime("my-datetime").decoder("2024-01-15T13:45:30Z") // → Date object for 2024-01-15 13:45:30 UTC
153
+ * typeDatetime("my-datetime").decoder("not a date") // throws TypoError
154
154
  * ```
155
155
  */
156
- declare const typeDate: Type<Date>;
156
+ declare function typeDatetime(name?: string): Type<Date>;
157
157
  /**
158
158
  * Parses a string to `number` via `Number()`; `NaN` throws {@link TypoError}.
159
159
  *
160
160
  * @example
161
161
  * ```ts
162
- * typeNumber.decoder("3.14") // → 3.14
163
- * typeNumber.decoder("-1") // → -1
164
- * typeNumber.decoder("hello") // throws TypoError
162
+ * typeNumber("my-number").decoder("3.14") // → 3.14
163
+ * typeNumber("my-number").decoder("-1") // → -1
164
+ * typeNumber("my-number").decoder("hello") // throws TypoError
165
165
  * ```
166
166
  */
167
- declare const typeNumber: Type<number>;
167
+ declare function typeNumber(name?: string): Type<number>;
168
168
  /**
169
169
  * Parses an integer string to `bigint` via `BigInt()`.
170
170
  * Floats and non-numeric strings throw {@link TypoError}.
171
171
  *
172
172
  * @example
173
173
  * ```ts
174
- * typeInteger.decoder("42") // → 42n
175
- * typeInteger.decoder("3.14") // throws TypoError
176
- * typeInteger.decoder("abc") // throws TypoError
174
+ * typeInteger("my-integer").decoder("42") // → 42n
175
+ * typeInteger("my-integer").decoder("3.14") // throws TypoError
176
+ * typeInteger("my-integer").decoder("abc") // throws TypoError
177
177
  * ```
178
178
  */
179
- declare const typeInteger: Type<bigint>;
179
+ declare function typeInteger(name?: string): Type<bigint>;
180
180
  /**
181
181
  * Parses an absolute URL string to a `URL` object.
182
182
  * Relative or malformed URLs throw {@link TypoError}.
183
183
  *
184
184
  * @example
185
185
  * ```ts
186
- * typeUrl.decoder("https://example.com") // → URL { href: "https://example.com/", ... }
187
- * typeUrl.decoder("not-a-url") // throws TypoError
186
+ * typeUrl("my-url").decoder("https://example.com") // → URL { href: "https://example.com/", ... }
187
+ * typeUrl("my-url").decoder("not-a-url") // throws TypoError
188
188
  * ```
189
189
  */
190
- declare const typeUrl: Type<URL>;
190
+ declare function typeUrl(name?: string): Type<URL>;
191
191
  /**
192
- * Identity decoder passes the raw string through unchanged.
193
- *
192
+ * A named type that accepts any string as input.
193
+ * @param name - Name shown in help and errors (e.g. `"my-value"`).
194
194
  * @example
195
195
  * ```ts
196
- * typeString.decoder("hello") // → "hello"
197
- * typeString.decoder("") // → ""
196
+ * type("greeting").decoder("hello") // → "hello"
197
+ * type("greeting").decoder("") // → ""
198
198
  * ```
199
199
  */
200
- declare const typeString: Type<string>;
200
+ declare function type(name?: string): Type<string>;
201
201
  /**
202
202
  * Chains `before`'s decoder with an `after` transformation.
203
203
  * `before` errors are prefixed with `"from: <content>"` for traceability.
@@ -205,45 +205,54 @@ declare const typeString: Type<string>;
205
205
  * @typeParam Before - Intermediate type from `before.decoder`.
206
206
  * @typeParam After - Final type from `after.decoder`.
207
207
  *
208
- * @param before - Base decoder for the raw string.
209
- * @param after - Transformation applied to the decoded value.
210
- * @param after.content - Name for the resulting type (shown in errors).
211
- * @param after.decoder - Converts a `Before` value to `After`.
208
+ * @param name - Name shown in help and errors (e.g. `"my-value"`).
209
+ * @param before - Base type to decode the raw string.
210
+ * @param mapper - Transforms `before`'s output to the final value; errors are wrapped with context.
212
211
  * @returns A {@link Type}`<After>`.
213
212
  *
214
213
  * @example
215
214
  * ```ts
216
- * const typePort = typeMapped(typeNumber, {
217
- * content: "Port",
218
- * decoder: (n) => {
219
- * if (n < 1 || n > 65535) throw new Error("Out of range");
220
- * return n;
221
- * },
215
+ * const typePort = typeConverted("port", typeNumber(), (n) => {
216
+ * if (n < 1 || n > 65535) throw new Error("Out of range");
217
+ * return n;
222
218
  * });
223
219
  * // "--port 8080" → 8080
224
220
  * // "--port 99999" → TypoError: --port: <PORT>: Port: Out of range
225
221
  * ```
226
222
  */
227
- declare function typeMapped<Before, After>(before: Type<Before>, after: {
228
- content: string;
229
- decoder: (value: Before) => After;
230
- }): Type<After>;
223
+ declare function typeConverted<Before, After>(name: string, before: Type<Before>, mapper: (value: Before) => After): Type<After>;
224
+ /**
225
+ * Adds a name to a {@link Type} for clearer error messages and help text.
226
+ *
227
+ * @param name - Name to use for the type.
228
+ * @param type - Base type to name.
229
+ * @returns A {@link Type} with the given name.
230
+ */
231
+ declare function typeRenamed<Value>(type: Type<Value>, name: string): Type<Value>;
232
+ /**
233
+ * Creates a {@link Type} for filesystem paths with optional existence checks.
234
+ * @param checks - Optional checks for path existence and type (file/directory).
235
+ * @returns A {@link Type}`<string>` representing the path.
236
+ */
237
+ declare function typePath(name?: string, checks?: {
238
+ checkSyncExistAs?: "file" | "directory" | "anything";
239
+ }): Type<string>;
231
240
  /**
232
241
  * Creates a {@link Type}`<string>` that only accepts a fixed set of values.
233
242
  * Out-of-set inputs throw {@link TypoError} listing up to 5 valid options.
234
243
  *
235
- * @param content - Name shown in help and errors (e.g. `"Environment"`).
244
+ * @param name - Name shown in help and errors.
236
245
  * @param values - Ordered list of accepted values.
237
246
  * @returns A {@link Type}`<string>`.
238
247
  *
239
248
  * @example
240
249
  * ```ts
241
- * const typeEnv = typeOneOf("Environment", ["dev", "staging", "prod"]);
250
+ * const typeEnv = typeChoice("environment", ["dev", "staging", "prod"]);
242
251
  * typeEnv.decoder("prod") // → "prod"
243
252
  * typeEnv.decoder("unknown") // throws TypoError: Invalid value: "unknown" (expected one of: "dev" | "staging" | "prod")
244
253
  * ```
245
254
  */
246
- declare function typeOneOf<const Value extends string>(content: string, values: Array<Value>): Type<Value>;
255
+ declare function typeChoice<const Value extends string>(name: string, values: Array<Value>, caseSensitive?: boolean): Type<Value>;
247
256
  /**
248
257
  * Splits a delimited string into a typed tuple.
249
258
  * Each part is decoded by the corresponding element type; wrong count or decode failure throws {@link TypoError}.
@@ -256,7 +265,7 @@ declare function typeOneOf<const Value extends string>(content: string, values:
256
265
  *
257
266
  * @example
258
267
  * ```ts
259
- * const typePoint = typeTuple([typeNumber, typeNumber]);
268
+ * const typePoint = typeTuple([typeNumber("x"), typeNumber("y")]);
260
269
  * typePoint.decoder("3.14,2.71") // → [3.14, 2.71]
261
270
  * typePoint.decoder("1,2,3") // → [1, 2]
262
271
  * typePoint.decoder("x,2") // throws TypoError: at 0: Number: Unable to parse: "x"
@@ -282,7 +291,7 @@ declare function typeTuple<const Elements extends Array<any>>(elementTypes: {
282
291
  * typeNumbers.decoder("1,2,3") // → [1, 2, 3]
283
292
  * typeNumbers.decoder("1,x,3") // throws TypoError: at 1: Number: Unable to parse: "x"
284
293
  *
285
- * const typePaths = typeList(typeString, ":");
294
+ * const typePaths = typeList(typePath(), ":");
286
295
  * typePaths.decoder("/usr/bin:/usr/local/bin") // → ["/usr/bin", "/usr/local/bin"]
287
296
  * ```
288
297
  */
@@ -298,6 +307,10 @@ type TypoColor = "darkBlack" | "darkRed" | "darkGreen" | "darkYellow" | "darkBlu
298
307
  * All fields are optional; ignored entirely in `"none"` mode.
299
308
  */
300
309
  type TypoStyle = {
310
+ /**
311
+ * Letter case.
312
+ */
313
+ case?: "upper" | "lower";
301
314
  /**
302
315
  * Foreground (text) color.
303
316
  */
@@ -428,7 +441,7 @@ declare class TypoGrid {
428
441
  * Renders as an array of styled, column-padded strings.
429
442
  *
430
443
  * @param typoSupport - Rendering mode.
431
- * @returns 2-D array of styled strings.
444
+ * @returns Array of styled strings.
432
445
  */
433
446
  computeStyledLines(typoSupport: TypoSupport): Array<string>;
434
447
  }
@@ -477,16 +490,12 @@ declare class TypoSupport {
477
490
  static tty(): TypoSupport;
478
491
  /**
479
492
  * Deterministic textual styling for snapshot tests.
480
- * Style flags appear as suffixes: `{text}@color`, `{text}+` (bold), `{text}-` (dim),
481
- * `{text}*` (italic), `{text}_` (underline), `{text}~` (strikethrough).
482
493
  */
483
494
  static mock(): TypoSupport;
484
495
  /**
485
- * Auto-detects styling mode from the process environment.
486
- * `FORCE_COLOR=0` / `NO_COLOR` → none; `FORCE_COLOR` (truthy) / `isTTY` → tty; else → none.
487
- * Falls back to none if `process` is unavailable.
496
+ * Auto-detects styling mode from the process environment on best-effort basis.
488
497
  */
489
- static inferFromProcess(): TypoSupport;
498
+ static inferFromEnv(): TypoSupport;
490
499
  /**
491
500
  * Applies `typoStyle` to `value` according to the current mode.
492
501
  *
@@ -510,9 +519,12 @@ declare class TypoSupport {
510
519
  type UsageCommand = {
511
520
  /**
512
521
  * Segments of the usage line
513
- * (e.g. `my-cli <POSITIONAL> subcommand <ANOTHER_POSITIONAL>`).
514
522
  */
515
- segments: Array<UsageSegment>;
523
+ segments: Array<{
524
+ positional: string;
525
+ } | {
526
+ subcommand: string;
527
+ }>;
516
528
  /**
517
529
  * Command metadata.
518
530
  */
@@ -530,27 +542,6 @@ type UsageCommand = {
530
542
  */
531
543
  options: Array<UsageOption>;
532
544
  };
533
- /**
534
- * One segment of the usage line.
535
- */
536
- type UsageSegment = {
537
- positional: string;
538
- } | {
539
- subcommand: string;
540
- };
541
- /**
542
- * Usage metadata. Produced by {@link Operation.generateUsage}, consumed when building {@link UsageCommand}.
543
- */
544
- type UsageOperation = {
545
- /**
546
- * Registered options.
547
- */
548
- options: Array<UsageOption>;
549
- /**
550
- * Declared positionals, in order.
551
- */
552
- positionals: Array<UsagePositional>;
553
- };
554
545
  /**
555
546
  * Positional metadata for the `Positionals:` section of help.
556
547
  */
@@ -558,16 +549,15 @@ type UsagePositional = {
558
549
  /**
559
550
  * Help text.
560
551
  */
561
- description: string | undefined;
552
+ description?: string | undefined;
562
553
  /**
563
554
  * Short note shown in parentheses.
564
555
  */
565
- hint: string | undefined;
556
+ hint?: string | undefined;
566
557
  /**
567
558
  * Placeholder label shown in the usage line and the `Positionals:` section.
568
- * Required: `<NAME>`, optional: `[NAME]`, variadic: `[NAME]...`.
569
559
  */
570
- label: Uppercase<string>;
560
+ label: string;
571
561
  };
572
562
  /**
573
563
  * Entry in the `Subcommands:` section.
@@ -580,11 +570,11 @@ type UsageSubcommand = {
580
570
  /**
581
571
  * From {@link CommandInformation.description}.
582
572
  */
583
- description: string | undefined;
573
+ description?: string | undefined;
584
574
  /**
585
575
  * From {@link CommandInformation.hint}.
586
576
  */
587
- hint: string | undefined;
577
+ hint?: string | undefined;
588
578
  };
589
579
  /**
590
580
  * Option metadata for the `Options:` section of help.
@@ -593,27 +583,27 @@ type UsageOption = {
593
583
  /**
594
584
  * Short-form name without `-` (e.g. `"v"`).
595
585
  */
596
- short: string | undefined;
586
+ short?: string | undefined;
597
587
  /**
598
588
  * Long-form name without `--` (e.g. `"verbose"`).
599
589
  */
600
- long: Lowercase<string>;
590
+ long: string;
601
591
  /**
602
- * Extra annotation appended to the option label in help (e.g. `[=no]`, ` [*]`).
592
+ * Value placeholder in help (e.g. `"<FILE>"`).
603
593
  */
604
- annotation: string | undefined;
594
+ label?: string | undefined;
605
595
  /**
606
- * Help text.
596
+ * Extra annotation appended to the option label in help.
607
597
  */
608
- description: string | undefined;
598
+ annotation?: string | undefined;
609
599
  /**
610
- * Short note shown in parentheses.
600
+ * Help text.
611
601
  */
612
- hint: string | undefined;
602
+ description?: string | undefined;
613
603
  /**
614
- * Value placeholder in help (e.g. `"<FILE>"`). `undefined` for flags.
604
+ * Short note shown in parentheses.
615
605
  */
616
- label: Uppercase<string> | undefined;
606
+ hint?: string | undefined;
617
607
  };
618
608
  /**
619
609
  * Converts a {@link UsageCommand} model into an array of styled lines ready to be
@@ -660,7 +650,7 @@ type UsageOption = {
660
650
  * ```
661
651
  */
662
652
  declare function usageToStyledLines(params: {
663
- cliName: Lowercase<string>;
653
+ cliName: string;
664
654
  usage: UsageCommand;
665
655
  typoSupport: TypoSupport;
666
656
  }): string[];
@@ -697,15 +687,15 @@ type OptionDecoder<Value> = {
697
687
  /**
698
688
  * Creates a boolean flag option (`--verbose`, optionally `--flag=no`).
699
689
  *
700
- * Parsing: absent → `false`; `--flag` / `--flag=yes` → `true`; `--flag=no` → `false`;
701
- * specified more than once → {@link TypoError}.
690
+ * Parsing: absent → default value; `--flag` / `--flag=yes` → `true`; `--flag=no` → `false`;
691
+ * specified more than once → throws {@link TypoError}.
702
692
  *
703
693
  * @param definition.long - Long-form name (without `--`).
704
694
  * @param definition.short - Short-form name (without `-`).
705
695
  * @param definition.description - Help text.
706
696
  * @param definition.hint - Short note shown in parentheses.
707
697
  * @param definition.aliases - Additional names.
708
- * @param definition.default - Default when absent. Defaults to `false`.
698
+ * @param definition.default - Default value when absent.
709
699
  * @returns An {@link Option}`<boolean>`.
710
700
  *
711
701
  * @example
@@ -715,15 +705,20 @@ type OptionDecoder<Value> = {
715
705
  * short: "v",
716
706
  * description: "Enable verbose output",
717
707
  * });
708
+ * // Usage:
709
+ * // my-cli → false
710
+ * // my-cli --verbose → true
711
+ * // my-cli --verbose=yes → true
712
+ * // my-cli -v=no → false
718
713
  * ```
719
714
  */
720
715
  declare function optionFlag(definition: {
721
- long: Lowercase<string>;
716
+ long: string;
722
717
  short?: string;
723
718
  description?: string;
724
719
  hint?: string;
725
720
  aliases?: {
726
- longs?: Array<Lowercase<string>>;
721
+ longs?: Array<string>;
727
722
  shorts?: Array<string>;
728
723
  };
729
724
  default?: boolean;
@@ -731,7 +726,7 @@ declare function optionFlag(definition: {
731
726
  /**
732
727
  * Creates an option that accepts exactly one value (e.g. `--output dist/`).
733
728
  *
734
- * Parsing: absent → `default()`; once → decoded with `type`; more than once → {@link TypoError}.
729
+ * Parsing: absent → `defaultValue()`; once → decoded with `type`; more than once → {@link TypoError}.
735
730
  * Value syntax: `--long value`, `--long=value`, `-s value`, `-s=value`, `-svalue`.
736
731
  *
737
732
  * @typeParam Value - Type produced by the decoder.
@@ -741,9 +736,9 @@ declare function optionFlag(definition: {
741
736
  * @param definition.description - Help text.
742
737
  * @param definition.hint - Short note shown in parentheses.
743
738
  * @param definition.aliases - Additional names.
744
- * @param definition.label - Value placeholder in help. Defaults to uppercased `type.content`.
745
739
  * @param definition.type - Decoder for the raw string value.
746
- * @param definition.default - Default when absent. Throw to make the option required.
740
+ * @param definition.valueWhenNotDefined - Default value when the option is not specified at all.
741
+ * @param definition.valueWhenNotInlined - Default value when the option is specified without an inline value (e.g. `--option` or `-o`).
747
742
  * @returns An {@link Option}`<Value>`.
748
743
  *
749
744
  * @example
@@ -751,25 +746,28 @@ declare function optionFlag(definition: {
751
746
  * const outputOption = optionSingleValue({
752
747
  * long: "output",
753
748
  * short: "o",
754
- * type: typeString,
755
- * label: "PATH",
749
+ * type: typePath(),
756
750
  * description: "Output directory",
757
- * default: () => "dist/",
751
+ * valueWhenNotDefined: () => "dist",
758
752
  * });
753
+ * // Usage:
754
+ * // my-cli → "dist"
755
+ * // my-cli --output folder → "folder"
756
+ * // my-cli -o folder → "folder"
759
757
  * ```
760
758
  */
761
759
  declare function optionSingleValue<Value>(definition: {
762
- long: Lowercase<string>;
760
+ long: string;
763
761
  short?: string;
764
762
  description?: string;
765
763
  hint?: string;
766
764
  aliases?: {
767
- longs?: Array<Lowercase<string>>;
765
+ longs?: Array<string>;
768
766
  shorts?: Array<string>;
769
767
  };
770
- label?: Uppercase<string>;
771
768
  type: Type<Value>;
772
- default: () => Value;
769
+ defaultWhenNotDefined: () => Value;
770
+ defaultWhenNotInlined?: () => Value;
773
771
  }): Option<Value>;
774
772
  /**
775
773
  * Creates an option that collects every occurrence into an array (e.g. `--file a.ts --file b.ts`).
@@ -784,7 +782,6 @@ declare function optionSingleValue<Value>(definition: {
784
782
  * @param definition.description - Help text.
785
783
  * @param definition.hint - Short note shown in parentheses.
786
784
  * @param definition.aliases - Additional names.
787
- * @param definition.label - Value placeholder in help. Defaults to uppercased `type.content`.
788
785
  * @param definition.type - Decoder applied to each raw string value.
789
786
  * @returns An {@link Option}`<Array<Value>>`.
790
787
  *
@@ -801,15 +798,14 @@ declare function optionSingleValue<Value>(definition: {
801
798
  * ```
802
799
  */
803
800
  declare function optionRepeatable<Value>(definition: {
804
- long: Lowercase<string>;
801
+ long: string;
805
802
  short?: string;
806
803
  description?: string;
807
804
  hint?: string;
808
805
  aliases?: {
809
- longs?: Array<Lowercase<string>>;
806
+ longs?: Array<string>;
810
807
  shorts?: Array<string>;
811
808
  };
812
- label?: Uppercase<string>;
813
809
  type: Type<Value>;
814
810
  }): Option<Array<Value>>;
815
811
 
@@ -845,41 +841,36 @@ type PositionalDecoder<Value> = {
845
841
  };
846
842
  /**
847
843
  * Creates a required positional — missing token throws {@link TypoError}.
848
- * Label defaults to uppercased `type.content` in angle brackets (e.g. `<STRING>`).
849
844
  *
850
845
  * @typeParam Value - Type produced by the decoder.
851
846
  *
852
847
  * @param definition.description - Help text.
853
848
  * @param definition.hint - Short note shown in parentheses.
854
- * @param definition.label - Label without brackets; defaults to uppercased `type.content`.
855
849
  * @param definition.type - Decoder for the raw token.
856
850
  * @returns A {@link Positional}`<Value>`.
857
851
  *
858
852
  * @example
859
853
  * ```ts
860
854
  * const namePositional = positionalRequired({
861
- * type: typeString,
862
- * label: "NAME",
855
+ * type: type("name"),
863
856
  * description: "The name to greet",
864
857
  * });
865
- * // Parses: my-cli Alice → "Alice"
858
+ * // Usage:
859
+ * // my-cli Alice → "Alice"
866
860
  * ```
867
861
  */
868
862
  declare function positionalRequired<Value>(definition: {
869
863
  description?: string;
870
864
  hint?: string;
871
- label?: Uppercase<string>;
872
865
  type: Type<Value>;
873
866
  }): Positional<Value>;
874
867
  /**
875
868
  * Creates an optional positional — absent token falls back to `default()`.
876
- * Label defaults to uppercased `type.content` in square brackets (e.g. `[STRING]`).
877
869
  *
878
870
  * @typeParam Value - Type produced by the decoder (or the default).
879
871
  *
880
872
  * @param definition.description - Help text.
881
873
  * @param definition.hint - Short note shown in parentheses.
882
- * @param definition.label - Label without brackets; defaults to uppercased `type.content`.
883
874
  * @param definition.type - Decoder for the raw token.
884
875
  * @param definition.default - Value when absent. Throw to make it required.
885
876
  * @returns A {@link Positional}`<Value>`.
@@ -887,51 +878,48 @@ declare function positionalRequired<Value>(definition: {
887
878
  * @example
888
879
  * ```ts
889
880
  * const greeteePositional = positionalOptional({
890
- * type: typeString,
891
- * label: "NAME",
881
+ * type: type("name"),
892
882
  * description: "Name to greet (default: world)",
893
883
  * default: () => "world",
894
884
  * });
895
- * // my-cli → "world"
896
- * // my-cli Alice → "Alice"
885
+ * // Usage:
886
+ * // my-cli → "world"
887
+ * // my-cli Alice → "Alice"
897
888
  * ```
898
889
  */
899
890
  declare function positionalOptional<Value>(definition: {
900
891
  description?: string;
901
892
  hint?: string;
902
- label?: Uppercase<string>;
903
893
  type: Type<Value>;
904
894
  default: () => Value;
905
895
  }): Positional<Value>;
906
896
  /**
907
897
  * Creates a variadic positional that collects zero or more remaining tokens into an array.
908
- * Stops at `endDelimiter` (consumed, not included). Label: `[TYPE]...` notation.
898
+ * Optionally stops at `endDelimiter` (consumed, not included).
909
899
  *
910
900
  * @typeParam Value - Type produced by the decoder for each token.
911
901
  *
912
902
  * @param definition.endDelimiter - Sentinel token that stops collection (consumed, not included).
913
903
  * @param definition.description - Help text.
914
904
  * @param definition.hint - Short note shown in parentheses.
915
- * @param definition.label - Label without brackets; defaults to uppercased `type.content`.
916
905
  * @param definition.type - Decoder applied to each token.
917
906
  * @returns A {@link Positional}`<Array<Value>>`.
918
907
  *
919
908
  * @example
920
909
  * ```ts
921
910
  * const filesPositional = positionalVariadics({
922
- * type: typeString,
923
- * label: "FILE",
911
+ * type: typePath(),
924
912
  * description: "Files to process",
925
913
  * });
926
- * // my-cli a.ts b.ts c.ts → ["a.ts", "b.ts", "c.ts"]
927
- * // my-cli → []
914
+ * // Usage:
915
+ * // my-cli → []
916
+ * // my-cli a.ts b.ts c.ts → ["a.ts", "b.ts", "c.ts"]
928
917
  * ```
929
918
  */
930
919
  declare function positionalVariadics<Value>(definition: {
931
920
  endDelimiter?: string;
932
921
  description?: string;
933
922
  hint?: string;
934
- label?: Uppercase<string>;
935
923
  type: Type<Value>;
936
924
  }): Positional<Array<Value>>;
937
925
 
@@ -948,7 +936,16 @@ type Operation<Context, Result> = {
948
936
  /**
949
937
  * Returns usage metadata without consuming any arguments.
950
938
  */
951
- generateUsage(): UsageOperation;
939
+ generateUsage(): {
940
+ /**
941
+ * Registered options.
942
+ */
943
+ options: Array<UsageOption>;
944
+ /**
945
+ * Declared positionals, in order.
946
+ */
947
+ positionals: Array<UsagePositional>;
948
+ };
952
949
  /**
953
950
  * Consumes args from `readerArgs` and returns an {@link OperationDecoder}.
954
951
  */
@@ -1001,10 +998,10 @@ type OperationInterpreter<Context, Result> = {
1001
998
  * const greetOperation = operation(
1002
999
  * {
1003
1000
  * options: {
1004
- * loud: optionFlag({ long: "loud", description: "Print in uppercase" }),
1001
+ * loud: optionFlag({ long: "loud", description: "Print in uppercase", default: false }),
1005
1002
  * },
1006
1003
  * positionals: [
1007
- * positionalRequired({ type: typeString, label: "NAME", description: "Name to greet" }),
1004
+ * positionalRequired({ type: type("name"), description: "Name to greet" }),
1008
1005
  * ],
1009
1006
  * },
1010
1007
  * async function (_ctx, { options: { loud }, positionals: [name] }) {
@@ -1108,10 +1105,12 @@ type CommandInformation = {
1108
1105
  } | {
1109
1106
  option: {
1110
1107
  long: string;
1111
- value?: string;
1108
+ inlined?: string;
1109
+ separated?: Array<string>;
1112
1110
  } | {
1113
1111
  short: string;
1114
- value?: string;
1112
+ inlined?: string;
1113
+ separated?: Array<string>;
1115
1114
  };
1116
1115
  }>;
1117
1116
  }>;
@@ -1131,7 +1130,7 @@ type CommandInformation = {
1131
1130
  * const greet = command(
1132
1131
  * { description: "Greet a user" },
1133
1132
  * operation(
1134
- * { options: {}, positionals: [positionalRequired({ type: typeString, label: "NAME" })] },
1133
+ * { options: {}, positionals: [positionalRequired({ type: type("name") })] },
1135
1134
  * async (_ctx, { positionals: [name] }) => console.log(`Hello, ${name}!`),
1136
1135
  * ),
1137
1136
  * );
@@ -1163,7 +1162,7 @@ declare function command<Context, Result>(information: CommandInformation, opera
1163
1162
  * ```
1164
1163
  */
1165
1164
  declare function commandWithSubcommands<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommands: {
1166
- [subcommand: Lowercase<string>]: Command<Payload, Result>;
1165
+ [subcommand: string]: Command<Payload, Result>;
1167
1166
  }): Command<Context, Result>;
1168
1167
  /**
1169
1168
  * Chains an {@link Operation} and a {@link Command}: `operation` runs first, its
@@ -1177,18 +1176,6 @@ declare function commandWithSubcommands<Context, Payload, Result>(information: C
1177
1176
  * @param operation - Runs first; output becomes `subcommand`'s context.
1178
1177
  * @param subcommand - Runs after `operation`.
1179
1178
  * @returns A {@link Command} composing both stages.
1180
- *
1181
- * @example
1182
- * ```ts
1183
- * const authenticatedDeploy = commandChained(
1184
- * { description: "Authenticate then deploy" },
1185
- * operation(
1186
- * { options: { token: optionSingleValue({ long: "token", type: typeString, default: () => "" }) }, positionals: [] },
1187
- * async (_ctx, { options: { token } }) => ({ token }),
1188
- * ),
1189
- * command({ description: "Deploy" }, deployOperation),
1190
- * );
1191
- * ```
1192
1179
  */
1193
1180
  declare function commandChained<Context, Payload, Result>(information: CommandInformation, operation: Operation<Context, Payload>, subcommand: Command<Payload, Result>): Command<Context, Result>;
1194
1181
 
@@ -1206,8 +1193,7 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
1206
1193
  * @param cliArgs - Raw arguments, typically `process.argv.slice(2)`.
1207
1194
  * @param context - Forwarded to the handler.
1208
1195
  * @param command - Root {@link Command}.
1209
- * @param options.useTtyColors - Color mode: `true` (always), `false` (never),
1210
- * `"mock"` (snapshot-friendly), `undefined` (auto-detect from env).
1196
+ * @param options.colorSetup - Configures color support; enables `--color` flag if set to `"flag"`.
1211
1197
  * @param options.usageOnHelp - Enables `--help` flag (default `true`).
1212
1198
  * @param options.usageOnError - Prints usage to stderr on parse error (default `true`).
1213
1199
  * @param options.buildVersion - Enables `--version`; prints `<cliName> <buildVersion>`.
@@ -1218,12 +1204,12 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
1218
1204
  *
1219
1205
  * @example
1220
1206
  * ```ts
1221
- * import { runAndExit, command, operation, positionalRequired, typeString } from "cli-kiss";
1207
+ * import { runAndExit, command, operation, positionalRequired, type } from "cli-kiss";
1222
1208
  *
1223
1209
  * const greetCommand = command(
1224
1210
  * { description: "Greet someone" },
1225
1211
  * operation(
1226
- * { options: {}, positionals: [positionalRequired({ type: typeString, label: "NAME" })] },
1212
+ * { options: {}, positionals: [positionalRequired({ type: type("name") })] },
1227
1213
  * async function (_ctx, { positionals: [name] }) {
1228
1214
  * console.log(`Hello, ${name}!`);
1229
1215
  * },
@@ -1235,8 +1221,8 @@ declare function commandChained<Context, Payload, Result>(information: CommandIn
1235
1221
  * });
1236
1222
  * ```
1237
1223
  */
1238
- declare function runAndExit<Context>(cliName: Lowercase<string>, cliArgs: ReadonlyArray<string>, context: Context, command: Command<Context, void>, options?: {
1239
- useTtyColors?: boolean | undefined | "mock";
1224
+ declare function runAndExit<Context>(cliName: string, cliArgs: ReadonlyArray<string>, context: Context, command: Command<Context, void>, options?: {
1225
+ colorSetup?: "flag" | "env" | "always" | "never" | "mock" | undefined;
1240
1226
  usageOnHelp?: boolean | undefined;
1241
1227
  usageOnError?: boolean | undefined;
1242
1228
  buildVersion?: string | undefined;
@@ -1244,4 +1230,4 @@ declare function runAndExit<Context>(cliName: Lowercase<string>, cliArgs: Readon
1244
1230
  onExit?: ((code: number) => never) | undefined;
1245
1231
  }): Promise<never>;
1246
1232
 
1247
- export { type Command, type CommandDecoder, type CommandInformation, type CommandInterpreter, type Operation, type OperationDecoder, type OperationInterpreter, type Option, type OptionDecoder, type Positional, type PositionalDecoder, ReaderArgs, type ReaderOptionKey, type ReaderOptionParsing, type ReaderOptionValue, type ReaderOptions, type ReaderPositionals, type Type, type TypoColor, TypoError, TypoGrid, TypoString, type TypoStyle, TypoSupport, TypoText, type UsageCommand, type UsageOperation, type UsageOption, type UsagePositional, type UsageSegment, type UsageSubcommand, command, commandChained, commandWithSubcommands, operation, optionFlag, optionRepeatable, optionSingleValue, positionalOptional, positionalRequired, positionalVariadics, runAndExit, typeBoolean, typeDate, typeInteger, typeList, typeMapped, typeNumber, typeOneOf, typeString, typeTuple, typeUrl, typoStyleConstants, typoStyleFailure, typoStyleLogic, typoStyleQuote, typoStyleRegularStrong, typoStyleRegularWeaker, typoStyleTitle, typoStyleUserInput, usageToStyledLines };
1233
+ export { type Command, type CommandDecoder, type CommandInformation, type CommandInterpreter, type Operation, type OperationDecoder, type OperationInterpreter, type Option, type OptionDecoder, type Positional, type PositionalDecoder, ReaderArgs, type ReaderOptionKey, type ReaderOptionParsing, type ReaderOptionValue, type ReaderOptions, type ReaderPositionals, type Type, type TypoColor, TypoError, TypoGrid, TypoString, type TypoStyle, TypoSupport, TypoText, type UsageCommand, type UsageOption, type UsagePositional, type UsageSubcommand, command, commandChained, commandWithSubcommands, operation, optionFlag, optionRepeatable, optionSingleValue, positionalOptional, positionalRequired, positionalVariadics, runAndExit, type, typeBoolean, typeChoice, typeConverted, typeDatetime, typeInteger, typeList, typeNumber, typePath, typeRenamed, typeTuple, typeUrl, typoStyleConstants, typoStyleFailure, typoStyleLogic, typoStyleQuote, typoStyleRegularStrong, typoStyleRegularWeaker, typoStyleTitle, typoStyleUserInput, usageToStyledLines };