goke 6.5.2 → 6.6.1

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
@@ -47,7 +47,7 @@ cli.parse()
47
47
  - **JustBash support** — `cli.createJustBashCommand()` exposes your CLI as a sandboxed JustBash command. Same action code, no changes needed.
48
48
  - **Space-separated subcommands** — `git remote add`, `mcp login`, `db migrate` — multi-word commands work out of the box.
49
49
  - **Injected `{ fs, console, process }`** — commands receive a portable runtime context. Swap it in tests, or let JustBash replace it with a sandbox. No global side effects.
50
- - **Zero dependencies** — single file, no runtime deps.
50
+ - **Zero runtime dependencies** — install `goke` without pulling extra runtime packages into your CLI.
51
51
 
52
52
  ## Install
53
53
 
@@ -230,7 +230,9 @@ test('dot-nested options', () => {
230
230
  .option('--scale [level]', 'Scaling level');
231
231
  const { options: options1 } = cli.parse(`node bin --externals.env.prod production --scale`.split(' '));
232
232
  expect(options1.externals).toEqual({ env: { prod: 'production' } });
233
- expect(options1.scale).toEqual(true);
233
+ // Bare `--scale` normalizes to `''` (new uniform string-or-undefined shape
234
+ // for untyped optional-value flags).
235
+ expect(options1.scale).toEqual('');
234
236
  });
235
237
  describe('schema-based options', () => {
236
238
  test('schema coerces string to number', () => {
@@ -334,11 +336,14 @@ describe('no-schema behavior (mri no longer auto-converts)', () => {
334
336
  const { options } = cli.parse('node bin --verbose'.split(' '));
335
337
  expect(options.verbose).toBe(true);
336
338
  });
337
- test('optional value flag returns true when no value given', () => {
339
+ test('optional value flag returns empty string when no value given', () => {
340
+ // Bare `--format` is normalized from the mri `true` sentinel to `''` so
341
+ // callers see a uniform `string | undefined` shape. `''` still lets them
342
+ // distinguish "flag present but no value" from "flag omitted entirely".
338
343
  const cli = goke();
339
344
  cli.option('--format [fmt]', 'Format');
340
345
  const { options } = cli.parse('node bin --format'.split(' '));
341
- expect(options.format).toBe(true);
346
+ expect(options.format).toBe('');
342
347
  });
343
348
  test('optional value flag returns string when value given', () => {
344
349
  const cli = goke();
@@ -545,12 +550,17 @@ describe('regression: oracle-found issues', () => {
545
550
  const { options } = cli.parse('node bin --count'.split(' '));
546
551
  expect(options.count).toBe(undefined);
547
552
  });
548
- test('optional value option without schema preserves true sentinel', () => {
553
+ test('optional value option without schema normalizes bare flag to empty string', () => {
549
554
  const cli = goke();
550
555
  cli.option('--count [count]', 'Count');
551
- // Without schema, original goke behavior: true means "flag present"
556
+ // Untyped optional-value flags uniformly expose `string | undefined`:
557
+ // - `--count` → '' (flag present, no value)
558
+ // - `--count 42` → '42' (flag present, with value)
559
+ // - (omitted) → undefined (flag absent)
560
+ // This lets callers use a single `typeof options.count === 'string'`
561
+ // check and distinguish the three cases via `=== ''` if they need to.
552
562
  const { options } = cli.parse('node bin --count'.split(' '));
553
- expect(options.count).toBe(true);
563
+ expect(options.count).toBe('');
554
564
  });
555
565
  test('optional value option with schema coerces when value given', () => {
556
566
  const cli = goke();
@@ -274,12 +274,16 @@ describe('type-level: command() .action() option inference', () => {
274
274
  expectTypeOf(options.port).toEqualTypeOf();
275
275
  });
276
276
  });
277
- test('untyped optional value options keep raw mri sentinel shapes', () => {
277
+ test('untyped optional value options surface as string | undefined', () => {
278
278
  goke('test')
279
279
  .command('serve', 'Start server')
280
280
  .option('--host [host]', 'Optional host override')
281
281
  .option('--verbose', 'Verbose output')
282
282
  .action((options) => {
283
+ // `[value]` options always resolve to `string | undefined`:
284
+ // - omitted → undefined
285
+ // - `--host` → '' (flag present, no value)
286
+ // - `--host example` → 'example'
283
287
  expectTypeOf(options.host).toEqualTypeOf();
284
288
  expectTypeOf(options.verbose).toEqualTypeOf();
285
289
  });
package/dist/coerce.d.ts CHANGED
@@ -78,13 +78,35 @@ export declare namespace StandardJSONSchemaV1 {
78
78
  /**
79
79
  * Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
80
80
  *
81
- * @internal This is an internal helper used by @goke/mcp to wrap MCP tool schemas.
82
- * Users should pass Zod or other StandardSchema-compatible schemas to `.option()`.
81
+ * Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
82
+ * any consumer that has a hand-written JSON Schema (e.g. an array of strings
83
+ * or a tagged union) and wants goke's `.action()` callback to infer the right
84
+ * option type without reaching for Zod. Pass an explicit `Output` type
85
+ * parameter to tell TypeScript what the coerced value will look like at
86
+ * runtime — goke does not validate the output shape, it just propagates it
87
+ * into the inferred options type for `.action()` callbacks.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * cli
92
+ * .command('diff', 'Show diff')
93
+ * .option(
94
+ * '--filter <glob>',
95
+ * wrapJsonSchema<string[]>({
96
+ * type: 'array',
97
+ * items: { type: 'string' },
98
+ * description: 'Glob pattern (repeatable)',
99
+ * }),
100
+ * )
101
+ * .action((options) => {
102
+ * // options.filter: string[] | undefined
103
+ * })
104
+ * ```
83
105
  *
84
106
  * @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
85
107
  * @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
86
108
  */
87
- export declare function wrapJsonSchema(jsonSchema: Record<string, unknown>): StandardJSONSchemaV1;
109
+ export declare function wrapJsonSchema<Output = unknown>(jsonSchema: Record<string, unknown>): StandardJSONSchemaV1<unknown, Output>;
88
110
  /** Minimal JSON Schema interface — only what we need for CLI coercion. */
89
111
  export interface JsonSchema {
90
112
  type?: string | string[];
@@ -1 +1 @@
1
- {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"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"}
package/dist/coerce.js CHANGED
@@ -50,8 +50,30 @@ export class GokeError extends Error {
50
50
  /**
51
51
  * Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
52
52
  *
53
- * @internal This is an internal helper used by @goke/mcp to wrap MCP tool schemas.
54
- * Users should pass Zod or other StandardSchema-compatible schemas to `.option()`.
53
+ * Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
54
+ * any consumer that has a hand-written JSON Schema (e.g. an array of strings
55
+ * or a tagged union) and wants goke's `.action()` callback to infer the right
56
+ * option type without reaching for Zod. Pass an explicit `Output` type
57
+ * parameter to tell TypeScript what the coerced value will look like at
58
+ * runtime — goke does not validate the output shape, it just propagates it
59
+ * into the inferred options type for `.action()` callbacks.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * cli
64
+ * .command('diff', 'Show diff')
65
+ * .option(
66
+ * '--filter <glob>',
67
+ * wrapJsonSchema<string[]>({
68
+ * type: 'array',
69
+ * items: { type: 'string' },
70
+ * description: 'Glob pattern (repeatable)',
71
+ * }),
72
+ * )
73
+ * .action((options) => {
74
+ * // options.filter: string[] | undefined
75
+ * })
76
+ * ```
55
77
  *
56
78
  * @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
57
79
  * @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
package/dist/goke.d.ts CHANGED
@@ -77,11 +77,15 @@ type OptionEntry<RawName extends string, Schema> = IsOptionalOption<RawName> ext
77
77
  * Infer the raw runtime value shape for an option declared without a schema.
78
78
  *
79
79
  * Required value options (`--port <port>`) always reach actions as strings.
80
- * Optional value options (`--host [host]`) can be strings, the sentinel
81
- * boolean `true` when passed without a value, or `undefined` when omitted.
80
+ * Optional value options (`--host [host]`) reach actions as strings: the
81
+ * empty string `''` when the flag is passed bare (`--host`), the given
82
+ * value when passed with one (`--host example.com`), and `undefined` when
83
+ * the flag is omitted entirely. This lets callers use a single `typeof`
84
+ * check and, if they really care, distinguish "omitted" from "present but
85
+ * empty" via `=== undefined` vs `=== ''`.
82
86
  * Plain flags (`--verbose`) are booleans.
83
87
  */
84
- type UntypedOptionValue<RawName extends string> = RawName extends `${string}<${string}>` ? string : RawName extends `${string}[${string}]` ? string | boolean | undefined : boolean | undefined;
88
+ type UntypedOptionValue<RawName extends string> = RawName extends `${string}<${string}>` ? string : RawName extends `${string}[${string}]` ? string : boolean | undefined;
85
89
  /**
86
90
  * Build the option type entry for a `.option()` call that uses a plain
87
91
  * description (no schema).
@@ -123,6 +127,15 @@ type ExtractCommandArgs<T extends readonly string[]> = T extends readonly [infer
123
127
  * "deploy" → []
124
128
  */
125
129
  type ExtractPositionalArgs<RawName extends string> = ExtractCommandArgs<TokenizeName<RawName>>;
130
+ /**
131
+ * Everything after a literal `--` on the command line is collected into
132
+ * `options['--']` as a string array (empty when `--` is absent). This key
133
+ * is always present at runtime, so it's merged into every action's options
134
+ * type regardless of which options the user declared.
135
+ */
136
+ type DoubleDashOptions = {
137
+ '--': string[];
138
+ };
126
139
  /**
127
140
  * Build the full argument tuple passed to a command's action callback.
128
141
  *
@@ -131,10 +144,13 @@ type ExtractPositionalArgs<RawName extends string> = ExtractCommandArgs<Tokenize
131
144
  * This matches the runtime behavior in Goke.runMatchedCommand(): the action
132
145
  * is called with positional args from the parsed command, then the parsed
133
146
  * options object, then the injected GokeExecutionContext.
147
+ *
148
+ * The options type is always extended with `{ '--': string[] }` because the
149
+ * parser always populates that key (see `Goke.parse()`).
134
150
  */
135
151
  type ActionArgs<RawName extends string, Opts> = [
136
152
  ...ExtractPositionalArgs<RawName>,
137
- Opts,
153
+ Opts & DoubleDashOptions,
138
154
  GokeExecutionContext
139
155
  ];
140
156
  interface CommandArg {
@@ -427,7 +443,7 @@ declare class Goke<Opts = {}> extends EventEmitter {
427
443
  * })
428
444
  * ```
429
445
  */
430
- use(callback: (options: Opts, context: GokeExecutionContext) => void | Promise<void>): this;
446
+ use(callback: (options: Opts & DoubleDashOptions, context: GokeExecutionContext) => void | Promise<void>): this;
431
447
  /**
432
448
  * Show help message when `-h, --help` flags appear.
433
449
  *
@@ -1 +1 @@
1
- {"version":3,"file":"goke.d.ts","sourceRoot":"","sources":["../src/goke.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"goke.d.ts","sourceRoot":"","sources":["../src/goke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAmB,aAAa,EAAW,MAAM,UAAU,CAAA;AAmNhF,cAAM,MAAM;IAwBD,OAAO,EAAE,MAAM;IAvBxB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,8BAA8B;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qEAAqE;IACrE,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAA;IAEpB;;;;;OAKG;gBAEM,OAAO,EAAE,MAAM,EACtB,mBAAmB,CAAC,EAAE,MAAM,GAAG,oBAAoB;IA0CrD,KAAK;CAGN;AAMD;;;GAGG;AACH,KAAK,SAAS,CAAC,CAAC,SAAS,MAAM,IAC7B,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GAC7B,GAAG,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,GACjC,CAAC,CAAA;AAEP;;;;;GAKG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,IAErC,CAAC,SAAS,GAAG,MAAM,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAClE,CAAC,SAAS,GAAG,MAAM,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,GAClE,CAAC,SAAS,GAAG,MAAM,KAAK,MAAM,IAAI,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,GACtD,MAAM,CAAA;AAER;;GAEG;AACH,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,IACpC,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,GAAG,GAAG,KAAK,GACxC,IAAI,CAAA;AAEN;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,IACtB,CAAC,SAAS;IAAE,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAAG,CAAC,GAAG,OAAO,CAAA;AAErG;;;;GAIG;AACH,KAAK,WAAW,CAAC,OAAO,SAAS,MAAM,EAAE,MAAM,IAC7C,gBAAgB,CAAC,OAAO,CAAC,SAAS,IAAI,GAClC;KAAG,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,MAAM,CAAC;CAAE,GACjE;KAAG,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC;CAAE,CAAA;AAEtE;;;;;;;;;;;GAWG;AACH,KAAK,kBAAkB,CAAC,OAAO,SAAS,MAAM,IAC5C,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,GAAG,GAAG,MAAM,GAC/C,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,GAAG,GAAG,MAAM,GAC/C,OAAO,GAAG,SAAS,CAAA;AAErB;;;GAGG;AACH,KAAK,kBAAkB,CAAC,OAAO,SAAS,MAAM,IAC5C,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,GAAG,GAClC;KAAG,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;CAAE,GAClE;KAAG,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC;CAAE,CAAA;AAEzE;;;;GAIG;AACH,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,SAAS,MAAM,EAAE,GAAG,EAAE,IACpE,CAAC,SAAS,GAAG,MAAM,IAAI,IAAI,MAAM,IAAI,EAAE,GACnC,YAAY,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,GAClC,CAAC,SAAS,EAAE,GACV,GAAG,GACH,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAA;AAEnB;;;;;;;;;GASG;AACH,KAAK,cAAc,CAAC,CAAC,SAAS,MAAM,IAClC,CAAC,SAAS,OAAO,MAAM,GAAG,GAAG,MAAM,EAAE,GACrC,CAAC,SAAS,OAAO,MAAM,GAAG,GAAG,MAAM,EAAE,GACrC,CAAC,SAAS,IAAI,MAAM,GAAG,GAAG,MAAM,GAChC,CAAC,SAAS,IAAI,MAAM,GAAG,GAAG,MAAM,GAAG,SAAS,GAC5C,KAAK,CAAA;AAEP;;;GAGG;AACH,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,IACjD,CAAC,SAAS,SAAS,CAAC,MAAM,IAAI,SAAS,MAAM,EAAE,GAAG,MAAM,IAAI,SAAS,MAAM,EAAE,CAAC,GAC1E,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACpC,kBAAkB,CAAC,IAAI,CAAC,GACxB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,GACrD,EAAE,CAAA;AAER;;;;;;;;GAQG;AACH,KAAK,qBAAqB,CAAC,OAAO,SAAS,MAAM,IAC/C,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;AAE3C;;;;;GAKG;AACH,KAAK,iBAAiB,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAE3C;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,CAAC,OAAO,SAAS,MAAM,EAAE,IAAI,IAC1C;IACE,GAAG,qBAAqB,CAAC,OAAO,CAAC;IACjC,IAAI,GAAG,iBAAiB;IACxB,oBAAoB;CACrB,CAAA;AAEH,UAAU,UAAU;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,UAAU,aAAa;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAA;CACnC;AAED,KAAK,YAAY,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,WAAW,EAAE,CAAA;AAErE,KAAK,cAAc,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,MAAM,CAAA;AAExD,cAAM,OAAO,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,IAAI,GAAG,EAAE;IAe7C,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,MAAM;IACnB,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IAjBvB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,UAAU,EAAE,MAAM,EAAE,CAAA;IAEpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB,aAAa,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;IACvC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;gBAGR,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,YAAK,EAC1B,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IASvB,KAAK,CAAC,IAAI,EAAE,MAAM;IAKlB,mBAAmB;IAKnB,wBAAwB;IAKxB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAkB;IAMtD,OAAO,CAAC,OAAO,EAAE,cAAc;IAK/B;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CACJ,aAAa,SAAS,MAAM,EAC5B,CAAC,SAAS,oBAAoB,EAE9B,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,CAAC,GACR,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,CAAC,aAAa,SAAS,MAAM,EACjC,OAAO,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,EAAE,IAAI,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAO7D,KAAK,CAAC,IAAI,EAAE,MAAM;IAKlB,MAAM;IAKN;;;;;;;;;;;;;;OAcG;IACH,MAAM,CACJ,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAC3E,IAAI;IAKP,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;IAuBrE,IAAI,gBAAgB,YAEnB;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM;IAOtB;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAwLlB,UAAU;IAIV,aAAa;IAQb,iBAAiB;IAUjB;;;;OAIG;IACH,mBAAmB;IAkBnB;;OAEG;IACH,gBAAgB;CAwBjB;AAED,cAAM,aAAc,SAAQ,OAAO;gBACrB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;CAG3B;AAsBD;;;GAGG;AACH,UAAU,gBAAgB;IACxB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;GAIG;AACH,UAAU,WAAW;IACnB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC7B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;CAC/B;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,gBAAgB,CAAA;IACxB,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAA;CACjC;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE,WAAW,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,WAAW,CAAA;CACrB;AAED,cAAM,eAAgB,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,CAAA;gBAEA,IAAI,EAAE,MAAM;CAKzB;AAED;;GAEG;AACH,UAAU,WAAW;IACnB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACxC,+EAA+E;IAC/E,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,uDAAuD;IACvD,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,gHAAgH;IAChH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAetF;AAwBD,UAAU,UAAU;IAClB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC3B,OAAO,EAAE;QACP,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;KACjB,CAAA;CACF;AAED,cAAM,IAAI,CAAC,IAAI,GAAG,EAAE,CAAE,SAAQ,YAAY;;IACxC,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAA;IAC7B,6FAA6F;IAC7F,WAAW,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC,CAAA;IACrG,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IACxB;;OAEG;IACH,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;IAE9B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAE3B,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACjD,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,qCAAqC;IACrC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAIrC;;;OAGG;gBACS,IAAI,SAAK,EAAE,OAAO,CAAC,EAAE,WAAW;IAsB5C,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW;IA+B3B,OAAO,CAAC,sBAAsB;IAmBxB,qBAAqB,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;IAIvD;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM;IAKlB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc,SAAS,MAAM,EACnC,OAAO,EAAE,cAAc,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC;IAYhC;;;;;;;;;;;;OAYG;IACH,MAAM,CACJ,OAAO,SAAS,MAAM,EACtB,CAAC,SAAS,oBAAoB,EAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,CAAC,OAAO,SAAS,MAAM,EAC3B,OAAO,EAAE,OAAO,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAO3C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,GAAG,CACD,QAAQ,EAAE,CACR,OAAO,EAAE,IAAI,GAAG,iBAAiB,EACjC,OAAO,EAAE,oBAAoB,KAC1B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACxB,IAAI;IAKP;;;OAGG;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,YAAY;IAO5B;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,SAAkB;IAMtD;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc;IAK/B;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAOlB;;;;OAIG;IACH,UAAU;IAIV;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,YAAY,UAAQ;IAwBrF;;;OAGG;IACH,aAAa;IAIb,OAAO,CAAC,aAAa;IAgBrB,mBAAmB;IAKnB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,KAAK,CACH,IAAI,WAAoB,EACxB;IACE,oDAAoD;IACpD,GAAU,GACX;;KAAK,GACL,UAAU;IA2Ib,OAAO,CAAC,GAAG;IAsIX,iBAAiB;CA0FlB;AAID,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAA;AACrG,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,CAAA;AACjE,eAAe,IAAI,CAAA"}
package/dist/goke.js CHANGED
@@ -1102,7 +1102,9 @@ class Goke extends EventEmitter {
1102
1102
  //
1103
1103
  // When mri returns `true` for value-taking options, it means "flag present, no value given".
1104
1104
  // For required options (<...>), the sentinel is preserved so checkOptionValue() throws.
1105
- // For optional options ([...]) with a schema, we replace `true` with `undefined`.
1105
+ // For optional options ([...]) we want a single, uniform shape: `string`
1106
+ // with `''` meaning "flag present but no value" — callers get clean
1107
+ // `string | undefined` types instead of `string | boolean | undefined`.
1106
1108
  const requiredValueOptions = new Set();
1107
1109
  const optionalValueOptions = new Set();
1108
1110
  for (const cliOption of cliOptions) {
@@ -1127,21 +1129,29 @@ class Goke extends EventEmitter {
1127
1129
  // When value is boolean `true` and the option takes a value, it's mri's sentinel
1128
1130
  // for "flag present, no value given":
1129
1131
  // - Required options (<...>): preserve `true` so checkOptionValue() throws
1130
- // - Optional options ([...]) with schema: replace with `undefined` (no typed value)
1131
- // - Optional options ([...]) without schema: preserve `true` (original goke behavior)
1132
+ // - Optional options ([...]) with schema: replace with `undefined` so
1133
+ // any `.default(...)` on the schema kicks in (e.g. z.number().default(30)
1134
+ // should produce 30, not try to coerce the `''` empty-string sentinel).
1132
1135
  const schemaInfo = schemaMap.get(key);
1133
1136
  if (schemaInfo && value !== undefined) {
1134
1137
  if (value === true && requiredValueOptions.has(key)) {
1135
1138
  // Keep sentinel for checkOptionValue() to detect
1136
1139
  }
1137
1140
  else if (value === true && optionalValueOptions.has(key)) {
1138
- // Optional value not given — schema expects a typed value, so return undefined
1139
1141
  value = undefined;
1140
1142
  }
1141
1143
  else {
1142
1144
  value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName);
1143
1145
  }
1144
1146
  }
1147
+ else if (value === true && optionalValueOptions.has(key)) {
1148
+ // Untyped optional-value flag with no schema: normalize bare `true`
1149
+ // to `''` so callers get a clean `string | undefined` shape. `''`
1150
+ // means "flag passed with no argument", distinct from `undefined`
1151
+ // (flag omitted). This matches the new type inference that treats
1152
+ // `[value]` as `string` instead of `string | boolean`.
1153
+ value = '';
1154
+ }
1145
1155
  setDotProp(options, keys, value);
1146
1156
  }
1147
1157
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goke",
3
- "version": "6.5.2",
3
+ "version": "6.6.1",
4
4
  "type": "module",
5
5
  "description": "Simple yet powerful framework for building command-line apps. Inspired by cac.",
6
6
  "repository": {
@@ -278,7 +278,9 @@ test('dot-nested options', () => {
278
278
  `node bin --externals.env.prod production --scale`.split(' ')
279
279
  )
280
280
  expect(options1.externals).toEqual({ env: { prod: 'production' } })
281
- expect(options1.scale).toEqual(true)
281
+ // Bare `--scale` normalizes to `''` (new uniform string-or-undefined shape
282
+ // for untyped optional-value flags).
283
+ expect(options1.scale).toEqual('')
282
284
  })
283
285
 
284
286
  describe('schema-based options', () => {
@@ -418,11 +420,14 @@ describe('no-schema behavior (mri no longer auto-converts)', () => {
418
420
  expect(options.verbose).toBe(true)
419
421
  })
420
422
 
421
- test('optional value flag returns true when no value given', () => {
423
+ test('optional value flag returns empty string when no value given', () => {
424
+ // Bare `--format` is normalized from the mri `true` sentinel to `''` so
425
+ // callers see a uniform `string | undefined` shape. `''` still lets them
426
+ // distinguish "flag present but no value" from "flag omitted entirely".
422
427
  const cli = goke()
423
428
  cli.option('--format [fmt]', 'Format')
424
429
  const { options } = cli.parse('node bin --format'.split(' '))
425
- expect(options.format).toBe(true)
430
+ expect(options.format).toBe('')
426
431
  })
427
432
 
428
433
  test('optional value flag returns string when value given', () => {
@@ -699,14 +704,19 @@ describe('regression: oracle-found issues', () => {
699
704
  expect(options.count).toBe(undefined)
700
705
  })
701
706
 
702
- test('optional value option without schema preserves true sentinel', () => {
707
+ test('optional value option without schema normalizes bare flag to empty string', () => {
703
708
  const cli = goke()
704
709
 
705
710
  cli.option('--count [count]', 'Count')
706
711
 
707
- // Without schema, original goke behavior: true means "flag present"
712
+ // Untyped optional-value flags uniformly expose `string | undefined`:
713
+ // - `--count` → '' (flag present, no value)
714
+ // - `--count 42` → '42' (flag present, with value)
715
+ // - (omitted) → undefined (flag absent)
716
+ // This lets callers use a single `typeof options.count === 'string'`
717
+ // check and distinguish the three cases via `=== ''` if they need to.
708
718
  const { options } = cli.parse('node bin --count'.split(' '))
709
- expect(options.count).toBe(true)
719
+ expect(options.count).toBe('')
710
720
  })
711
721
 
712
722
  test('optional value option with schema coerces when value given', () => {
@@ -76,6 +76,11 @@ describe('type-level: IsOptionalOption', () => {
76
76
  })
77
77
  })
78
78
 
79
+ // Every action callback's options param is extended with `{ '--': string[] }`
80
+ // because the runtime always populates that key. Use this alias everywhere
81
+ // we used to write `{}` to mean "no user-declared options".
82
+ type Base = { '--': string[] }
83
+
79
84
  describe('type-level: InferSchemaOutput', () => {
80
85
  test('infers output from StandardTypedV1', () => {
81
86
  type Schema = StandardTypedV1<unknown, number>
@@ -177,7 +182,7 @@ describe('type-level: command() .action() positional args inference', () => {
177
182
  goke('test')
178
183
  .command('deploy', 'Deploy the app')
179
184
  .action((options, ctx) => {
180
- expectTypeOf(options).toEqualTypeOf<{}>()
185
+ expectTypeOf(options).toEqualTypeOf<Base>()
181
186
  expectTypeOf(ctx).toEqualTypeOf<GokeExecutionContext>()
182
187
  })
183
188
  })
@@ -187,7 +192,7 @@ describe('type-level: command() .action() positional args inference', () => {
187
192
  .command('get <id>', 'Fetch a resource by id')
188
193
  .action((id, options, ctx) => {
189
194
  expectTypeOf(id).toEqualTypeOf<string>()
190
- expectTypeOf(options).toEqualTypeOf<{}>()
195
+ expectTypeOf(options).toEqualTypeOf<Base>()
191
196
  expectTypeOf(ctx).toEqualTypeOf<GokeExecutionContext>()
192
197
  })
193
198
  })
@@ -198,7 +203,7 @@ describe('type-level: command() .action() positional args inference', () => {
198
203
  .action((input, output, options) => {
199
204
  expectTypeOf(input).toEqualTypeOf<string>()
200
205
  expectTypeOf(output).toEqualTypeOf<string>()
201
- expectTypeOf(options).toEqualTypeOf<{}>()
206
+ expectTypeOf(options).toEqualTypeOf<Base>()
202
207
  })
203
208
  })
204
209
 
@@ -207,7 +212,7 @@ describe('type-level: command() .action() positional args inference', () => {
207
212
  .command('run [script]', 'Run a script')
208
213
  .action((script, options) => {
209
214
  expectTypeOf(script).toEqualTypeOf<string | undefined>()
210
- expectTypeOf(options).toEqualTypeOf<{}>()
215
+ expectTypeOf(options).toEqualTypeOf<Base>()
211
216
  })
212
217
  })
213
218
 
@@ -216,7 +221,7 @@ describe('type-level: command() .action() positional args inference', () => {
216
221
  .command('exec <...args>', 'Run a binary with args')
217
222
  .action((args, options) => {
218
223
  expectTypeOf(args).toEqualTypeOf<string[]>()
219
- expectTypeOf(options).toEqualTypeOf<{}>()
224
+ expectTypeOf(options).toEqualTypeOf<Base>()
220
225
  })
221
226
  })
222
227
 
@@ -225,7 +230,7 @@ describe('type-level: command() .action() positional args inference', () => {
225
230
  .command('run [...rest]', 'Variadic optional')
226
231
  .action((rest, options) => {
227
232
  expectTypeOf(rest).toEqualTypeOf<string[]>()
228
- expectTypeOf(options).toEqualTypeOf<{}>()
233
+ expectTypeOf(options).toEqualTypeOf<Base>()
229
234
  })
230
235
  })
231
236
 
@@ -234,7 +239,7 @@ describe('type-level: command() .action() positional args inference', () => {
234
239
  .command('mcp getNodeXml <id>', 'Get XML for a node')
235
240
  .action((id, options) => {
236
241
  expectTypeOf(id).toEqualTypeOf<string>()
237
- expectTypeOf(options).toEqualTypeOf<{}>()
242
+ expectTypeOf(options).toEqualTypeOf<Base>()
238
243
  })
239
244
  })
240
245
 
@@ -243,7 +248,7 @@ describe('type-level: command() .action() positional args inference', () => {
243
248
  .command('<file>', 'Default command')
244
249
  .action((file, options) => {
245
250
  expectTypeOf(file).toEqualTypeOf<string>()
246
- expectTypeOf(options).toEqualTypeOf<{}>()
251
+ expectTypeOf(options).toEqualTypeOf<Base>()
247
252
  })
248
253
  })
249
254
 
@@ -253,7 +258,7 @@ describe('type-level: command() .action() positional args inference', () => {
253
258
  .action((to, cc, options) => {
254
259
  expectTypeOf(to).toEqualTypeOf<string>()
255
260
  expectTypeOf(cc).toEqualTypeOf<string | undefined>()
256
- expectTypeOf(options).toEqualTypeOf<{}>()
261
+ expectTypeOf(options).toEqualTypeOf<Base>()
257
262
  })
258
263
  })
259
264
  })
@@ -342,13 +347,17 @@ describe('type-level: command() .action() option inference', () => {
342
347
  })
343
348
  })
344
349
 
345
- test('untyped optional value options keep raw mri sentinel shapes', () => {
350
+ test('untyped optional value options surface as string | undefined', () => {
346
351
  goke('test')
347
352
  .command('serve', 'Start server')
348
353
  .option('--host [host]', 'Optional host override')
349
354
  .option('--verbose', 'Verbose output')
350
355
  .action((options) => {
351
- expectTypeOf(options.host).toEqualTypeOf<string | boolean | undefined>()
356
+ // `[value]` options always resolve to `string | undefined`:
357
+ // - omitted → undefined
358
+ // - `--host` → '' (flag present, no value)
359
+ // - `--host example` → 'example'
360
+ expectTypeOf(options.host).toEqualTypeOf<string | undefined>()
352
361
  expectTypeOf(options.verbose).toEqualTypeOf<boolean | undefined>()
353
362
  })
354
363
  })
@@ -369,7 +378,7 @@ describe('type-level: command() .action() option inference', () => {
369
378
  .command('get <id>', 'Fetch resource')
370
379
  .action((id, options, ctx, ...rest) => {
371
380
  expectTypeOf(id).toEqualTypeOf<string>()
372
- expectTypeOf(options).toEqualTypeOf<{}>()
381
+ expectTypeOf(options).toEqualTypeOf<Base>()
373
382
  expectTypeOf(ctx).toEqualTypeOf<GokeExecutionContext>()
374
383
  // No more positional slots — rest should be empty
375
384
  expectTypeOf(rest).toEqualTypeOf<[]>()
package/src/coerce.ts CHANGED
@@ -127,13 +127,37 @@ export declare namespace StandardJSONSchemaV1 {
127
127
  /**
128
128
  * Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
129
129
  *
130
- * @internal This is an internal helper used by @goke/mcp to wrap MCP tool schemas.
131
- * Users should pass Zod or other StandardSchema-compatible schemas to `.option()`.
130
+ * Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
131
+ * any consumer that has a hand-written JSON Schema (e.g. an array of strings
132
+ * or a tagged union) and wants goke's `.action()` callback to infer the right
133
+ * option type without reaching for Zod. Pass an explicit `Output` type
134
+ * parameter to tell TypeScript what the coerced value will look like at
135
+ * runtime — goke does not validate the output shape, it just propagates it
136
+ * into the inferred options type for `.action()` callbacks.
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * cli
141
+ * .command('diff', 'Show diff')
142
+ * .option(
143
+ * '--filter <glob>',
144
+ * wrapJsonSchema<string[]>({
145
+ * type: 'array',
146
+ * items: { type: 'string' },
147
+ * description: 'Glob pattern (repeatable)',
148
+ * }),
149
+ * )
150
+ * .action((options) => {
151
+ * // options.filter: string[] | undefined
152
+ * })
153
+ * ```
132
154
  *
133
155
  * @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
134
156
  * @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
135
157
  */
136
- export function wrapJsonSchema(jsonSchema: Record<string, unknown>): StandardJSONSchemaV1 {
158
+ export function wrapJsonSchema<Output = unknown>(
159
+ jsonSchema: Record<string, unknown>,
160
+ ): StandardJSONSchemaV1<unknown, Output> {
137
161
  return {
138
162
  "~standard": {
139
163
  version: 1,
package/src/goke.ts CHANGED
@@ -352,13 +352,17 @@ type OptionEntry<RawName extends string, Schema> =
352
352
  * Infer the raw runtime value shape for an option declared without a schema.
353
353
  *
354
354
  * Required value options (`--port <port>`) always reach actions as strings.
355
- * Optional value options (`--host [host]`) can be strings, the sentinel
356
- * boolean `true` when passed without a value, or `undefined` when omitted.
355
+ * Optional value options (`--host [host]`) reach actions as strings: the
356
+ * empty string `''` when the flag is passed bare (`--host`), the given
357
+ * value when passed with one (`--host example.com`), and `undefined` when
358
+ * the flag is omitted entirely. This lets callers use a single `typeof`
359
+ * check and, if they really care, distinguish "omitted" from "present but
360
+ * empty" via `=== undefined` vs `=== ''`.
357
361
  * Plain flags (`--verbose`) are booleans.
358
362
  */
359
363
  type UntypedOptionValue<RawName extends string> =
360
364
  RawName extends `${string}<${string}>` ? string :
361
- RawName extends `${string}[${string}]` ? string | boolean | undefined :
365
+ RawName extends `${string}[${string}]` ? string :
362
366
  boolean | undefined
363
367
 
364
368
  /**
@@ -422,6 +426,14 @@ type ExtractCommandArgs<T extends readonly string[]> =
422
426
  type ExtractPositionalArgs<RawName extends string> =
423
427
  ExtractCommandArgs<TokenizeName<RawName>>
424
428
 
429
+ /**
430
+ * Everything after a literal `--` on the command line is collected into
431
+ * `options['--']` as a string array (empty when `--` is absent). This key
432
+ * is always present at runtime, so it's merged into every action's options
433
+ * type regardless of which options the user declared.
434
+ */
435
+ type DoubleDashOptions = { '--': string[] }
436
+
425
437
  /**
426
438
  * Build the full argument tuple passed to a command's action callback.
427
439
  *
@@ -430,9 +442,16 @@ type ExtractPositionalArgs<RawName extends string> =
430
442
  * This matches the runtime behavior in Goke.runMatchedCommand(): the action
431
443
  * is called with positional args from the parsed command, then the parsed
432
444
  * options object, then the injected GokeExecutionContext.
445
+ *
446
+ * The options type is always extended with `{ '--': string[] }` because the
447
+ * parser always populates that key (see `Goke.parse()`).
433
448
  */
434
449
  type ActionArgs<RawName extends string, Opts> =
435
- [...ExtractPositionalArgs<RawName>, Opts, GokeExecutionContext]
450
+ [
451
+ ...ExtractPositionalArgs<RawName>,
452
+ Opts & DoubleDashOptions,
453
+ GokeExecutionContext,
454
+ ]
436
455
 
437
456
  interface CommandArg {
438
457
  required: boolean
@@ -1239,7 +1258,12 @@ class Goke<Opts = {}> extends EventEmitter {
1239
1258
  * })
1240
1259
  * ```
1241
1260
  */
1242
- use(callback: (options: Opts, context: GokeExecutionContext) => void | Promise<void>): this {
1261
+ use(
1262
+ callback: (
1263
+ options: Opts & DoubleDashOptions,
1264
+ context: GokeExecutionContext,
1265
+ ) => void | Promise<void>,
1266
+ ): this {
1243
1267
  this.middlewares.push({ action: callback })
1244
1268
  return this
1245
1269
  }
@@ -1592,7 +1616,9 @@ class Goke<Opts = {}> extends EventEmitter {
1592
1616
  //
1593
1617
  // When mri returns `true` for value-taking options, it means "flag present, no value given".
1594
1618
  // For required options (<...>), the sentinel is preserved so checkOptionValue() throws.
1595
- // For optional options ([...]) with a schema, we replace `true` with `undefined`.
1619
+ // For optional options ([...]) we want a single, uniform shape: `string`
1620
+ // with `''` meaning "flag present but no value" — callers get clean
1621
+ // `string | undefined` types instead of `string | boolean | undefined`.
1596
1622
  const requiredValueOptions = new Set<string>()
1597
1623
  const optionalValueOptions = new Set<string>()
1598
1624
  for (const cliOption of cliOptions) {
@@ -1618,18 +1644,25 @@ class Goke<Opts = {}> extends EventEmitter {
1618
1644
  // When value is boolean `true` and the option takes a value, it's mri's sentinel
1619
1645
  // for "flag present, no value given":
1620
1646
  // - Required options (<...>): preserve `true` so checkOptionValue() throws
1621
- // - Optional options ([...]) with schema: replace with `undefined` (no typed value)
1622
- // - Optional options ([...]) without schema: preserve `true` (original goke behavior)
1647
+ // - Optional options ([...]) with schema: replace with `undefined` so
1648
+ // any `.default(...)` on the schema kicks in (e.g. z.number().default(30)
1649
+ // should produce 30, not try to coerce the `''` empty-string sentinel).
1623
1650
  const schemaInfo = schemaMap.get(key)
1624
1651
  if (schemaInfo && value !== undefined) {
1625
1652
  if (value === true && requiredValueOptions.has(key)) {
1626
1653
  // Keep sentinel for checkOptionValue() to detect
1627
1654
  } else if (value === true && optionalValueOptions.has(key)) {
1628
- // Optional value not given — schema expects a typed value, so return undefined
1629
1655
  value = undefined
1630
1656
  } else {
1631
1657
  value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName)
1632
1658
  }
1659
+ } else if (value === true && optionalValueOptions.has(key)) {
1660
+ // Untyped optional-value flag with no schema: normalize bare `true`
1661
+ // to `''` so callers get a clean `string | undefined` shape. `''`
1662
+ // means "flag passed with no argument", distinct from `undefined`
1663
+ // (flag omitted). This matches the new type inference that treats
1664
+ // `[value]` as `string` instead of `string | boolean`.
1665
+ value = ''
1633
1666
  }
1634
1667
 
1635
1668
  setDotProp(options, keys, value)