goke 6.12.0 → 6.12.2

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.
@@ -973,6 +973,7 @@ describe('space-separated subcommands', () => {
973
973
  let output = '';
974
974
  const cli = goke('mycli', {
975
975
  stdout: { write(data) { output += data; } },
976
+ exit: () => { },
976
977
  });
977
978
  cli.command('mcp login', 'Login to MCP');
978
979
  cli.command('mcp logout', 'Logout from MCP');
@@ -992,8 +993,11 @@ describe('space-separated subcommands', () => {
992
993
  });
993
994
  test('unknown command without prefix does not show filtered help', async () => {
994
995
  let output = '';
996
+ let errOutput = '';
995
997
  const cli = goke('mycli', {
996
998
  stdout: { write(data) { output += data; } },
999
+ stderr: { write(data) { errOutput += data; } },
1000
+ exit: () => { },
997
1001
  });
998
1002
  cli.command('mcp login', 'Login to MCP');
999
1003
  cli.command('build', 'Build project');
@@ -1002,11 +1006,16 @@ describe('space-separated subcommands', () => {
1002
1006
  await cli.parse(['node', 'bin', 'foo'], { run: true });
1003
1007
  // Should not show filtered help since "foo" is not a prefix of any command
1004
1008
  expect(stripAnsi(output)).not.toContain('Available "foo" commands');
1009
+ // Should show error message instead of root help
1010
+ expect(stripAnsi(errOutput)).toContain('Unknown command: foo');
1005
1011
  });
1006
- test('unknown command without prefix outputs root help', async () => {
1007
- let output = '';
1012
+ test('unknown command without prefix outputs error and help', async () => {
1013
+ let errOutput = '';
1014
+ let stdOutput = '';
1008
1015
  const cli = goke('mycli', {
1009
- stdout: { write(data) { output += data; } },
1016
+ stdout: { write(data) { stdOutput += data; } },
1017
+ stderr: { write(data) { errOutput += data; } },
1018
+ exit: () => { },
1010
1019
  });
1011
1020
  cli.command('mcp login', 'Login to MCP');
1012
1021
  cli.command('build', 'Build project');
@@ -1014,10 +1023,11 @@ describe('space-separated subcommands', () => {
1014
1023
  // User types an unknown command that does not match any prefix group
1015
1024
  await cli.parse(['node', 'bin', 'something'], { run: true });
1016
1025
  expect(cli.matchedCommand).toBeUndefined();
1017
- expect(stripAnsi(output)).toContain('Usage:');
1018
- expect(stripAnsi(output)).toContain('$ mycli <command> [options]');
1019
- expect(stripAnsi(output)).toContain('mcp login');
1020
- expect(stripAnsi(output)).toContain('build');
1026
+ expect(stripAnsi(errOutput)).toContain('Unknown command: something');
1027
+ // Should output help so the user can see available commands
1028
+ expect(stripAnsi(stdOutput)).toContain('Usage:');
1029
+ expect(stripAnsi(stdOutput)).toContain('mcp login');
1030
+ expect(stripAnsi(stdOutput)).toContain('build');
1021
1031
  });
1022
1032
  test('no args without default command outputs root help', async () => {
1023
1033
  const stdout = createTestOutputStream();
@@ -1074,6 +1084,19 @@ describe('space-separated subcommands', () => {
1074
1084
  await cli.parse(['node', 'bin', 'deploy'], { run: true });
1075
1085
  expect(receivedScript).toBe('deploy');
1076
1086
  });
1087
+ test('default command WITH positional args alongside other commands', async () => {
1088
+ let defaultScript;
1089
+ let buildRan = false;
1090
+ const cli = gokeTestable('mycli');
1091
+ cli.command('[file]', 'Process a file').action(async (file) => {
1092
+ defaultScript = file;
1093
+ });
1094
+ cli.command('build', 'Build project').action(async () => { buildRan = true; });
1095
+ // Passing an arg that is NOT a known command should route to the default
1096
+ await cli.parse(['node', 'bin', 'readme.md'], { run: true });
1097
+ expect(defaultScript).toBe('readme.md');
1098
+ expect(buildRan).toBe(false);
1099
+ });
1077
1100
  test('default command rejects unknown nonexistent command', async () => {
1078
1101
  let defaultRan = false;
1079
1102
  let unknownFired = false;
@@ -1536,7 +1559,7 @@ describe('stdout/stderr/argv injection', () => {
1536
1559
  });
1537
1560
  test('stdout captures prefix help for unknown subcommands', async () => {
1538
1561
  const stdout = createTestOutputStream();
1539
- const cli = goke('mycli', { stdout });
1562
+ const cli = goke('mycli', { stdout, exit: () => { } });
1540
1563
  cli.command('mcp login', 'Login to MCP');
1541
1564
  cli.command('mcp logout', 'Logout from MCP');
1542
1565
  cli.help();
@@ -1859,7 +1882,7 @@ describe('middleware', () => {
1859
1882
  });
1860
1883
  test('middleware does not run when no command matched', async () => {
1861
1884
  const stdout = createTestOutputStream();
1862
- const cli = goke('mycli', { stdout });
1885
+ const cli = goke('mycli', { stdout, exit: () => { } });
1863
1886
  let middlewareCalled = false;
1864
1887
  cli.use(() => { middlewareCalled = true; });
1865
1888
  cli.help();
@@ -2083,3 +2106,126 @@ describe('getAction()', () => {
2083
2106
  expect(() => cmd.getAction()).toThrow(/No action registered/);
2084
2107
  });
2085
2108
  });
2109
+ describe('command routing with conflicting enum options', () => {
2110
+ test('commands with same option name but different enums route correctly', async () => {
2111
+ const cli = gokeTestable('egaki');
2112
+ let matched = '';
2113
+ cli.command('image <prompt>', 'Generate images')
2114
+ .option('-m, --model [model]', z.enum(['imagen-4', 'dall-e-3']).describe('Image model'))
2115
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2116
+ cli.command('video <prompt>', 'Generate videos')
2117
+ .option('-m, --model [model]', z.enum(['veo-3', 'grok-video']).describe('Video model'))
2118
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2119
+ await cli.parse(['node', 'bin', 'video', 'test', '--model', 'grok-video']);
2120
+ expect(matched).toBe('video:test:grok-video');
2121
+ });
2122
+ test('first-defined command still works with its own enum values', async () => {
2123
+ const cli = gokeTestable('egaki');
2124
+ let matched = '';
2125
+ cli.command('image <prompt>', 'Generate images')
2126
+ .option('-m, --model [model]', z.enum(['imagen-4', 'dall-e-3']).describe('Image model'))
2127
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2128
+ cli.command('video <prompt>', 'Generate videos')
2129
+ .option('-m, --model [model]', z.enum(['veo-3', 'grok-video']).describe('Video model'))
2130
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2131
+ await cli.parse(['node', 'bin', 'image', 'sunset', '--model', 'dall-e-3']);
2132
+ expect(matched).toBe('image:sunset:dall-e-3');
2133
+ });
2134
+ test('parent child command matches before parent <arg>', async () => {
2135
+ const cli = gokeTestable('mycli');
2136
+ let matched = '';
2137
+ cli.command('parent <arg>', 'Parent with positional')
2138
+ .action((arg) => { matched = `parent:${arg}`; });
2139
+ cli.command('parent child', 'Parent child subcommand')
2140
+ .action(() => { matched = 'parent child'; });
2141
+ await cli.parse(['node', 'bin', 'parent', 'child']);
2142
+ expect(matched).toBe('parent child');
2143
+ });
2144
+ test('parent <arg> still works for non-subcommand args', async () => {
2145
+ const cli = gokeTestable('mycli');
2146
+ let matched = '';
2147
+ cli.command('parent <arg>', 'Parent with positional')
2148
+ .action((arg) => { matched = `parent:${arg}`; });
2149
+ cli.command('parent child', 'Parent child subcommand')
2150
+ .action(() => { matched = 'parent child'; });
2151
+ await cli.parse(['node', 'bin', 'parent', 'something']);
2152
+ expect(matched).toBe('parent:something');
2153
+ });
2154
+ test('multi-word commands with same first word and conflicting enums route correctly', async () => {
2155
+ const cli = gokeTestable('egaki');
2156
+ let matched = '';
2157
+ cli.command('image create <prompt>', 'Create image')
2158
+ .option('--model [model]', z.enum(['imagen']).describe('Create model'))
2159
+ .action((prompt, options) => { matched = `create:${prompt}:${options.model}`; });
2160
+ cli.command('image edit <prompt>', 'Edit image')
2161
+ .option('--model [model]', z.enum(['edit-model']).describe('Edit model'))
2162
+ .action((prompt, options) => { matched = `edit:${prompt}:${options.model}`; });
2163
+ await cli.parse(['node', 'bin', 'image', 'edit', 'test', '--model', 'edit-model']);
2164
+ expect(matched).toBe('edit:test:edit-model');
2165
+ });
2166
+ test('aliased command with conflicting enum routes correctly', async () => {
2167
+ const cli = gokeTestable('egaki');
2168
+ let matched = '';
2169
+ cli.command('image <prompt>', 'Generate images')
2170
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2171
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2172
+ cli.command('video <prompt>', 'Generate videos')
2173
+ .alias('v')
2174
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2175
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2176
+ await cli.parse(['node', 'bin', 'v', 'test', '--model', 'veo']);
2177
+ expect(matched).toBe('video:test:veo');
2178
+ });
2179
+ test('global boolean flag before command does not disable routing precheck', async () => {
2180
+ const cli = gokeTestable('egaki');
2181
+ let matched = '';
2182
+ cli.option('--verbose', 'Verbose output');
2183
+ cli.command('image <prompt>', 'Generate images')
2184
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2185
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2186
+ cli.command('video <prompt>', 'Generate videos')
2187
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2188
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2189
+ await cli.parse(['node', 'bin', '--verbose', 'video', 'test', '--model', 'veo']);
2190
+ expect(matched).toBe('video:test:veo');
2191
+ });
2192
+ test('global value option before command keeps routing precheck enabled', async () => {
2193
+ const cli = gokeTestable('egaki');
2194
+ let matched = '';
2195
+ cli.option('--config <path>', z.string().describe('Config path'));
2196
+ cli.command('image <prompt>', 'Generate images')
2197
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2198
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2199
+ cli.command('video <prompt>', 'Generate videos')
2200
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2201
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2202
+ await cli.parse(['node', 'bin', '--config', 'config.json', 'video', 'test', '--model', 'veo']);
2203
+ expect(matched).toBe('video:test:veo');
2204
+ });
2205
+ test('global value option with equals syntax keeps routing precheck enabled', async () => {
2206
+ const cli = gokeTestable('egaki');
2207
+ let matched = '';
2208
+ cli.option('--config <path>', z.string().describe('Config path'));
2209
+ cli.command('image <prompt>', 'Generate images')
2210
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2211
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2212
+ cli.command('video <prompt>', 'Generate videos')
2213
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2214
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2215
+ await cli.parse(['node', 'bin', '--config=config.json', 'video', 'test', '--model', 'veo']);
2216
+ expect(matched).toBe('video:test:veo');
2217
+ });
2218
+ test('global boolean flag with explicit equals value keeps routing precheck enabled', async () => {
2219
+ const cli = gokeTestable('egaki');
2220
+ let matched = '';
2221
+ cli.option('--verbose', 'Verbose output');
2222
+ cli.command('image <prompt>', 'Generate images')
2223
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2224
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}`; });
2225
+ cli.command('video <prompt>', 'Generate videos')
2226
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2227
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}`; });
2228
+ await cli.parse(['node', 'bin', '--verbose=false', 'video', 'test', '--model', 'veo']);
2229
+ expect(matched).toBe('video:test:veo');
2230
+ });
2231
+ });
@@ -291,6 +291,22 @@ describe('generateDocs', () => {
291
291
  const pages = generateDocs({ cli });
292
292
  expect(pages).toEqual([]);
293
293
  });
294
+ test('supports basePath option for links', async () => {
295
+ const cli = gokeTestable('mycli');
296
+ cli.command('deploy', 'Deploy the app');
297
+ cli.command('status', 'Show status');
298
+ const pages = generateDocs({ cli, basePath: '/docs/cli' });
299
+ const index = pages.find((p) => p.slug === 'index');
300
+ expect(index.content).toContain('[\`deploy\`](/docs/cli/deploy.md)');
301
+ expect(index.content).toContain('[\`status\`](/docs/cli/status.md)');
302
+ });
303
+ test('basePath with trailing slash is normalized', async () => {
304
+ const cli = gokeTestable('mycli');
305
+ cli.command('deploy', 'Deploy the app');
306
+ const pages = generateDocs({ cli, basePath: '/docs/cli/' });
307
+ const index = pages.find((p) => p.slug === 'index');
308
+ expect(index.content).toContain('[\`deploy\`](/docs/cli/deploy.md)');
309
+ });
294
310
  test('skips deprecated options', async () => {
295
311
  const cli = gokeTestable('mycli');
296
312
  cli
package/dist/goke.d.ts CHANGED
@@ -698,6 +698,8 @@ interface DocPage {
698
698
  interface GenerateDocsOptions {
699
699
  /** The Goke CLI instance to generate docs from. */
700
700
  cli: Goke<any>;
701
+ /** Base path prefix for links between pages (e.g. "/docs/cli"). Defaults to ".". */
702
+ basePath?: string;
701
703
  }
702
704
  /**
703
705
  * Generate markdown documentation pages for every command in a CLI.
@@ -715,13 +717,13 @@ interface GenerateDocsOptions {
715
717
  * .command('deploy <env>', 'Deploy to an environment')
716
718
  * .option('--force', 'Skip confirmation')
717
719
  *
718
- * const pages = generateDocs({ cli })
720
+ * const pages = generateDocs({ cli, basePath: '/docs/cli' })
719
721
  * for (const page of pages) {
720
722
  * fs.writeFileSync(`docs/${page.slug}.md`, page.content)
721
723
  * }
722
724
  * ```
723
725
  */
724
- declare function generateDocs({ cli }: GenerateDocsOptions): DocPage[];
726
+ declare function generateDocs({ cli, basePath }: GenerateDocsOptions): DocPage[];
725
727
  export type { GokeOutputStream, GokeConsole, GokeOptions, GokeProcess, GokeExecutionContext, GokeExecutionContextOverride, GokeFs, DocPage, GenerateDocsOptions };
726
728
  export { createConsole, Command, GokeProcessExit, openInBrowser, generateDocs };
727
729
  export type { ShellType };
@@ -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":"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"}
package/dist/goke.js CHANGED
@@ -1288,21 +1288,27 @@ class Goke extends EventEmitter {
1288
1288
  const bLength = b.name.split(' ').filter(Boolean).length;
1289
1289
  return bLength - aLength;
1290
1290
  });
1291
- // Search sub-commands mri() can throw coercion errors, catch them
1291
+ // Search sub-commands using two-pass matching:
1292
+ // 1. First pass: parse without schema coercion to find the matching command.
1293
+ // This avoids z.enum() or other schema validation throwing for the wrong
1294
+ // command's options before isMatched() can reject it.
1295
+ // 2. Second pass: re-parse with full coercion for the matched command only.
1292
1296
  try {
1293
1297
  for (const command of sortedCommands) {
1294
- const parsed = this.mri(argv.slice(2), command);
1298
+ const parsed = this.mri(argv.slice(2), command, true);
1295
1299
  const result = command.isMatched(parsed.args);
1296
1300
  if (result.matched) {
1297
1301
  shouldParse = false;
1298
- const matchedCommandName = parsed.args.slice(0, result.consumedArgs).join(' ');
1302
+ // Re-parse with coercion now that we know this is the right command
1303
+ const coerced = this.mri(argv.slice(2), command);
1304
+ const matchedCommandName = coerced.args.slice(0, result.consumedArgs).join(' ');
1299
1305
  const parsedInfo = {
1300
- ...parsed,
1301
- args: parsed.args.slice(result.consumedArgs),
1306
+ ...coerced,
1307
+ args: coerced.args.slice(result.consumedArgs),
1302
1308
  };
1303
1309
  this.setParsedInfo(parsedInfo, command, matchedCommandName);
1304
1310
  this.emit(`command:${matchedCommandName}`, command);
1305
- break; // Stop after first match (greedy matching)
1311
+ break;
1306
1312
  }
1307
1313
  }
1308
1314
  if (shouldParse) {
@@ -1396,9 +1402,11 @@ class Goke extends EventEmitter {
1396
1402
  this.outputHelpForPrefix(firstArg, matchingCommands);
1397
1403
  }
1398
1404
  else {
1399
- // Unknown command with no matching prefix: show root help
1405
+ // Unknown command with no matching prefix: show error + root help
1406
+ this.console.error(`Unknown command: ${this.args.join(' ')}\n`);
1400
1407
  this.outputHelp();
1401
1408
  }
1409
+ this.exit(1);
1402
1410
  }
1403
1411
  }
1404
1412
  if (!this.matchedCommand &&
@@ -1410,7 +1418,9 @@ class Goke extends EventEmitter {
1410
1418
  return parsedArgv;
1411
1419
  }
1412
1420
  mri(argv,
1413
- /** Matched command */ command) {
1421
+ /** Matched command */ command,
1422
+ /** Skip schema coercion (used during command matching to avoid throwing for wrong commands) */
1423
+ skipCoercion) {
1414
1424
  // All added options
1415
1425
  const cliOptions = [
1416
1426
  ...this.globalCommand.options,
@@ -1502,41 +1512,43 @@ class Goke extends EventEmitter {
1502
1512
  if (key !== '_') {
1503
1513
  const keys = key.split('.');
1504
1514
  let value = parsed[key];
1505
- // Apply schema coercion if this option has a schema.
1506
- // When value is boolean `true` and the option takes a value, it's mri's sentinel
1507
- // for "flag present, no value given":
1508
- // - Required options (<...>): preserve `true` so checkOptionValue() throws
1509
- // - Optional options ([...]) with schema AND a default: skip this
1510
- // key entirely so the preset default (written into `options` at
1511
- // the top of this function) survives. This keeps the type-level
1512
- // `HasSchemaDefault` promise honest at runtime.
1513
- // - Optional options ([...]) with schema and NO default: replace
1514
- // `true` with `undefined` so the caller sees "flag present, no value"
1515
- // as `undefined`.
1516
- const schemaInfo = schemaMap.get(key);
1517
- if (schemaInfo && value !== undefined) {
1518
- if (value === true && requiredValueOptions.has(key)) {
1519
- // Keep sentinel for checkOptionValue() to detect
1520
- }
1521
- else if (value === true && optionalValueOptions.has(key)) {
1522
- if (optionsWithDefault.has(key)) {
1523
- // Preserve the preset default — don't overwrite with undefined.
1524
- continue;
1515
+ if (!skipCoercion) {
1516
+ // Apply schema coercion if this option has a schema.
1517
+ // When value is boolean `true` and the option takes a value, it's mri's sentinel
1518
+ // for "flag present, no value given":
1519
+ // - Required options (<...>): preserve `true` so checkOptionValue() throws
1520
+ // - Optional options ([...]) with schema AND a default: skip this
1521
+ // key entirely so the preset default (written into `options` at
1522
+ // the top of this function) survives. This keeps the type-level
1523
+ // `HasSchemaDefault` promise honest at runtime.
1524
+ // - Optional options ([...]) with schema and NO default: replace
1525
+ // `true` with `undefined` so the caller sees "flag present, no value"
1526
+ // as `undefined`.
1527
+ const schemaInfo = schemaMap.get(key);
1528
+ if (schemaInfo && value !== undefined) {
1529
+ if (value === true && requiredValueOptions.has(key)) {
1530
+ // Keep sentinel for checkOptionValue() to detect
1531
+ }
1532
+ else if (value === true && optionalValueOptions.has(key)) {
1533
+ if (optionsWithDefault.has(key)) {
1534
+ // Preserve the preset default — don't overwrite with undefined.
1535
+ continue;
1536
+ }
1537
+ value = undefined;
1538
+ }
1539
+ else {
1540
+ value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName);
1525
1541
  }
1526
- value = undefined;
1527
1542
  }
1528
- else {
1529
- value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName);
1543
+ else if (value === true && optionalValueOptions.has(key)) {
1544
+ // Untyped optional-value flag with no schema: normalize bare `true`
1545
+ // to `''` so callers get a clean `string | undefined` shape. `''`
1546
+ // means "flag passed with no argument", distinct from `undefined`
1547
+ // (flag omitted). This matches the new type inference that treats
1548
+ // `[value]` as `string` instead of `string | boolean`.
1549
+ value = '';
1530
1550
  }
1531
1551
  }
1532
- else if (value === true && optionalValueOptions.has(key)) {
1533
- // Untyped optional-value flag with no schema: normalize bare `true`
1534
- // to `''` so callers get a clean `string | undefined` shape. `''`
1535
- // means "flag passed with no argument", distinct from `undefined`
1536
- // (flag omitted). This matches the new type inference that treats
1537
- // `[value]` as `string` instead of `string | boolean`.
1538
- value = '';
1539
- }
1540
1552
  setDotProp(options, keys, value);
1541
1553
  }
1542
1554
  }
@@ -1649,13 +1661,15 @@ class Goke extends EventEmitter {
1649
1661
  * .command('deploy <env>', 'Deploy to an environment')
1650
1662
  * .option('--force', 'Skip confirmation')
1651
1663
  *
1652
- * const pages = generateDocs({ cli })
1664
+ * const pages = generateDocs({ cli, basePath: '/docs/cli' })
1653
1665
  * for (const page of pages) {
1654
1666
  * fs.writeFileSync(`docs/${page.slug}.md`, page.content)
1655
1667
  * }
1656
1668
  * ```
1657
1669
  */
1658
- function generateDocs({ cli }) {
1670
+ function generateDocs({ cli, basePath = '.' }) {
1671
+ // Normalize: strip trailing slash
1672
+ basePath = basePath.replace(/\/+$/, '') || '.';
1659
1673
  const pages = [];
1660
1674
  // Collect global options (from globalCommand), excluding deprecated
1661
1675
  const globalOptions = cli.globalCommand.options.filter((o) => !o.deprecated);
@@ -1679,7 +1693,7 @@ function generateDocs({ cli }) {
1679
1693
  continue;
1680
1694
  const desc = cmd.description.split('\n')[0].trim();
1681
1695
  const slug = cmd.name.replace(/\s+/g, '-');
1682
- lines.push(`| [\`${cmd.name}\`](./${slug}.md) | ${desc} |`);
1696
+ lines.push(`| [\`${cmd.name}\`](${basePath}/${slug}.md) | ${desc} |`);
1683
1697
  }
1684
1698
  lines.push('');
1685
1699
  if (globalOptions.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goke",
3
- "version": "6.12.0",
3
+ "version": "6.12.2",
4
4
  "type": "module",
5
5
  "description": "Simple yet powerful framework for building command-line apps. Inspired by cac.",
6
6
  "repository": {
@@ -24,7 +24,6 @@
24
24
  "imports": {
25
25
  "#runtime": {
26
26
  "types": "./dist/runtime-node.d.ts",
27
- "development": "./src/runtime-node.ts",
28
27
  "node": "./dist/runtime-node.js",
29
28
  "default": "./dist/runtime-browser.js"
30
29
  }
@@ -1249,6 +1249,7 @@ describe('space-separated subcommands', () => {
1249
1249
  let output = ''
1250
1250
  const cli = goke('mycli', {
1251
1251
  stdout: { write(data) { output += data } },
1252
+ exit: () => {},
1252
1253
  })
1253
1254
 
1254
1255
  cli.command('mcp login', 'Login to MCP')
@@ -1273,8 +1274,11 @@ describe('space-separated subcommands', () => {
1273
1274
 
1274
1275
  test('unknown command without prefix does not show filtered help', async () => {
1275
1276
  let output = ''
1277
+ let errOutput = ''
1276
1278
  const cli = goke('mycli', {
1277
1279
  stdout: { write(data) { output += data } },
1280
+ stderr: { write(data) { errOutput += data } },
1281
+ exit: () => {},
1278
1282
  })
1279
1283
 
1280
1284
  cli.command('mcp login', 'Login to MCP')
@@ -1287,12 +1291,17 @@ describe('space-separated subcommands', () => {
1287
1291
 
1288
1292
  // Should not show filtered help since "foo" is not a prefix of any command
1289
1293
  expect(stripAnsi(output)).not.toContain('Available "foo" commands')
1294
+ // Should show error message instead of root help
1295
+ expect(stripAnsi(errOutput)).toContain('Unknown command: foo')
1290
1296
  })
1291
1297
 
1292
- test('unknown command without prefix outputs root help', async () => {
1293
- let output = ''
1298
+ test('unknown command without prefix outputs error and help', async () => {
1299
+ let errOutput = ''
1300
+ let stdOutput = ''
1294
1301
  const cli = goke('mycli', {
1295
- stdout: { write(data) { output += data } },
1302
+ stdout: { write(data) { stdOutput += data } },
1303
+ stderr: { write(data) { errOutput += data } },
1304
+ exit: () => {},
1296
1305
  })
1297
1306
 
1298
1307
  cli.command('mcp login', 'Login to MCP')
@@ -1304,10 +1313,11 @@ describe('space-separated subcommands', () => {
1304
1313
  await cli.parse(['node', 'bin', 'something'], { run: true })
1305
1314
 
1306
1315
  expect(cli.matchedCommand).toBeUndefined()
1307
- expect(stripAnsi(output)).toContain('Usage:')
1308
- expect(stripAnsi(output)).toContain('$ mycli <command> [options]')
1309
- expect(stripAnsi(output)).toContain('mcp login')
1310
- expect(stripAnsi(output)).toContain('build')
1316
+ expect(stripAnsi(errOutput)).toContain('Unknown command: something')
1317
+ // Should output help so the user can see available commands
1318
+ expect(stripAnsi(stdOutput)).toContain('Usage:')
1319
+ expect(stripAnsi(stdOutput)).toContain('mcp login')
1320
+ expect(stripAnsi(stdOutput)).toContain('build')
1311
1321
  })
1312
1322
 
1313
1323
  test('no args without default command outputs root help', async () => {
@@ -1385,6 +1395,23 @@ describe('space-separated subcommands', () => {
1385
1395
  expect(receivedScript).toBe('deploy')
1386
1396
  })
1387
1397
 
1398
+ test('default command WITH positional args alongside other commands', async () => {
1399
+ let defaultScript: string | undefined
1400
+ let buildRan = false
1401
+ const cli = gokeTestable('mycli')
1402
+
1403
+ cli.command('[file]', 'Process a file').action(async (file) => {
1404
+ defaultScript = file
1405
+ })
1406
+ cli.command('build', 'Build project').action(async () => { buildRan = true })
1407
+
1408
+ // Passing an arg that is NOT a known command should route to the default
1409
+ await cli.parse(['node', 'bin', 'readme.md'], { run: true })
1410
+
1411
+ expect(defaultScript).toBe('readme.md')
1412
+ expect(buildRan).toBe(false)
1413
+ })
1414
+
1388
1415
  test('default command rejects unknown nonexistent command', async () => {
1389
1416
  let defaultRan = false
1390
1417
  let unknownFired = false
@@ -1943,7 +1970,7 @@ describe('stdout/stderr/argv injection', () => {
1943
1970
 
1944
1971
  test('stdout captures prefix help for unknown subcommands', async () => {
1945
1972
  const stdout = createTestOutputStream()
1946
- const cli = goke('mycli', { stdout })
1973
+ const cli = goke('mycli', { stdout, exit: () => {} })
1947
1974
 
1948
1975
  cli.command('mcp login', 'Login to MCP')
1949
1976
  cli.command('mcp logout', 'Logout from MCP')
@@ -2370,7 +2397,7 @@ describe('middleware', () => {
2370
2397
 
2371
2398
  test('middleware does not run when no command matched', async () => {
2372
2399
  const stdout = createTestOutputStream()
2373
- const cli = goke('mycli', { stdout })
2400
+ const cli = goke('mycli', { stdout, exit: () => {} })
2374
2401
  let middlewareCalled = false
2375
2402
 
2376
2403
  cli.use(() => { middlewareCalled = true })
@@ -2665,3 +2692,170 @@ describe('getAction()', () => {
2665
2692
  expect(() => cmd.getAction()).toThrow(/No action registered/)
2666
2693
  })
2667
2694
  })
2695
+
2696
+ describe('command routing with conflicting enum options', () => {
2697
+ test('commands with same option name but different enums route correctly', async () => {
2698
+ const cli = gokeTestable('egaki')
2699
+ let matched = ''
2700
+
2701
+ cli.command('image <prompt>', 'Generate images')
2702
+ .option('-m, --model [model]', z.enum(['imagen-4', 'dall-e-3']).describe('Image model'))
2703
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2704
+
2705
+ cli.command('video <prompt>', 'Generate videos')
2706
+ .option('-m, --model [model]', z.enum(['veo-3', 'grok-video']).describe('Video model'))
2707
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2708
+
2709
+ await cli.parse(['node', 'bin', 'video', 'test', '--model', 'grok-video'])
2710
+ expect(matched).toBe('video:test:grok-video')
2711
+ })
2712
+
2713
+ test('first-defined command still works with its own enum values', async () => {
2714
+ const cli = gokeTestable('egaki')
2715
+ let matched = ''
2716
+
2717
+ cli.command('image <prompt>', 'Generate images')
2718
+ .option('-m, --model [model]', z.enum(['imagen-4', 'dall-e-3']).describe('Image model'))
2719
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2720
+
2721
+ cli.command('video <prompt>', 'Generate videos')
2722
+ .option('-m, --model [model]', z.enum(['veo-3', 'grok-video']).describe('Video model'))
2723
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2724
+
2725
+ await cli.parse(['node', 'bin', 'image', 'sunset', '--model', 'dall-e-3'])
2726
+ expect(matched).toBe('image:sunset:dall-e-3')
2727
+ })
2728
+
2729
+ test('parent child command matches before parent <arg>', async () => {
2730
+ const cli = gokeTestable('mycli')
2731
+ let matched = ''
2732
+
2733
+ cli.command('parent <arg>', 'Parent with positional')
2734
+ .action((arg) => { matched = `parent:${arg}` })
2735
+
2736
+ cli.command('parent child', 'Parent child subcommand')
2737
+ .action(() => { matched = 'parent child' })
2738
+
2739
+ await cli.parse(['node', 'bin', 'parent', 'child'])
2740
+ expect(matched).toBe('parent child')
2741
+ })
2742
+
2743
+ test('parent <arg> still works for non-subcommand args', async () => {
2744
+ const cli = gokeTestable('mycli')
2745
+ let matched = ''
2746
+
2747
+ cli.command('parent <arg>', 'Parent with positional')
2748
+ .action((arg) => { matched = `parent:${arg}` })
2749
+
2750
+ cli.command('parent child', 'Parent child subcommand')
2751
+ .action(() => { matched = 'parent child' })
2752
+
2753
+ await cli.parse(['node', 'bin', 'parent', 'something'])
2754
+ expect(matched).toBe('parent:something')
2755
+ })
2756
+
2757
+ test('multi-word commands with same first word and conflicting enums route correctly', async () => {
2758
+ const cli = gokeTestable('egaki')
2759
+ let matched = ''
2760
+
2761
+ cli.command('image create <prompt>', 'Create image')
2762
+ .option('--model [model]', z.enum(['imagen']).describe('Create model'))
2763
+ .action((prompt, options) => { matched = `create:${prompt}:${options.model}` })
2764
+
2765
+ cli.command('image edit <prompt>', 'Edit image')
2766
+ .option('--model [model]', z.enum(['edit-model']).describe('Edit model'))
2767
+ .action((prompt, options) => { matched = `edit:${prompt}:${options.model}` })
2768
+
2769
+ await cli.parse(['node', 'bin', 'image', 'edit', 'test', '--model', 'edit-model'])
2770
+ expect(matched).toBe('edit:test:edit-model')
2771
+ })
2772
+
2773
+ test('aliased command with conflicting enum routes correctly', async () => {
2774
+ const cli = gokeTestable('egaki')
2775
+ let matched = ''
2776
+
2777
+ cli.command('image <prompt>', 'Generate images')
2778
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2779
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2780
+
2781
+ cli.command('video <prompt>', 'Generate videos')
2782
+ .alias('v')
2783
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2784
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2785
+
2786
+ await cli.parse(['node', 'bin', 'v', 'test', '--model', 'veo'])
2787
+ expect(matched).toBe('video:test:veo')
2788
+ })
2789
+
2790
+ test('global boolean flag before command does not disable routing precheck', async () => {
2791
+ const cli = gokeTestable('egaki')
2792
+ let matched = ''
2793
+
2794
+ cli.option('--verbose', 'Verbose output')
2795
+
2796
+ cli.command('image <prompt>', 'Generate images')
2797
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2798
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2799
+
2800
+ cli.command('video <prompt>', 'Generate videos')
2801
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2802
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2803
+
2804
+ await cli.parse(['node', 'bin', '--verbose', 'video', 'test', '--model', 'veo'])
2805
+ expect(matched).toBe('video:test:veo')
2806
+ })
2807
+
2808
+ test('global value option before command keeps routing precheck enabled', async () => {
2809
+ const cli = gokeTestable('egaki')
2810
+ let matched = ''
2811
+
2812
+ cli.option('--config <path>', z.string().describe('Config path'))
2813
+
2814
+ cli.command('image <prompt>', 'Generate images')
2815
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2816
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2817
+
2818
+ cli.command('video <prompt>', 'Generate videos')
2819
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2820
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2821
+
2822
+ await cli.parse(['node', 'bin', '--config', 'config.json', 'video', 'test', '--model', 'veo'])
2823
+ expect(matched).toBe('video:test:veo')
2824
+ })
2825
+
2826
+ test('global value option with equals syntax keeps routing precheck enabled', async () => {
2827
+ const cli = gokeTestable('egaki')
2828
+ let matched = ''
2829
+
2830
+ cli.option('--config <path>', z.string().describe('Config path'))
2831
+
2832
+ cli.command('image <prompt>', 'Generate images')
2833
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2834
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2835
+
2836
+ cli.command('video <prompt>', 'Generate videos')
2837
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2838
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2839
+
2840
+ await cli.parse(['node', 'bin', '--config=config.json', 'video', 'test', '--model', 'veo'])
2841
+ expect(matched).toBe('video:test:veo')
2842
+ })
2843
+
2844
+ test('global boolean flag with explicit equals value keeps routing precheck enabled', async () => {
2845
+ const cli = gokeTestable('egaki')
2846
+ let matched = ''
2847
+
2848
+ cli.option('--verbose', 'Verbose output')
2849
+
2850
+ cli.command('image <prompt>', 'Generate images')
2851
+ .option('--model [model]', z.enum(['imagen']).describe('Image model'))
2852
+ .action((prompt, options) => { matched = `image:${prompt}:${options.model}` })
2853
+
2854
+ cli.command('video <prompt>', 'Generate videos')
2855
+ .option('--model [model]', z.enum(['veo']).describe('Video model'))
2856
+ .action((prompt, options) => { matched = `video:${prompt}:${options.model}` })
2857
+
2858
+ await cli.parse(['node', 'bin', '--verbose=false', 'video', 'test', '--model', 'veo'])
2859
+ expect(matched).toBe('video:test:veo')
2860
+ })
2861
+ })
@@ -358,6 +358,26 @@ describe('generateDocs', () => {
358
358
  expect(pages).toEqual([])
359
359
  })
360
360
 
361
+ test('supports basePath option for links', async () => {
362
+ const cli = gokeTestable('mycli')
363
+ cli.command('deploy', 'Deploy the app')
364
+ cli.command('status', 'Show status')
365
+
366
+ const pages = generateDocs({ cli, basePath: '/docs/cli' })
367
+ const index = pages.find((p) => p.slug === 'index')!
368
+ expect(index.content).toContain('[\`deploy\`](/docs/cli/deploy.md)')
369
+ expect(index.content).toContain('[\`status\`](/docs/cli/status.md)')
370
+ })
371
+
372
+ test('basePath with trailing slash is normalized', async () => {
373
+ const cli = gokeTestable('mycli')
374
+ cli.command('deploy', 'Deploy the app')
375
+
376
+ const pages = generateDocs({ cli, basePath: '/docs/cli/' })
377
+ const index = pages.find((p) => p.slug === 'index')!
378
+ expect(index.content).toContain('[\`deploy\`](/docs/cli/deploy.md)')
379
+ })
380
+
361
381
  test('skips deprecated options', async () => {
362
382
  const cli = gokeTestable('mycli')
363
383
  cli
package/src/goke.ts CHANGED
@@ -1927,22 +1927,28 @@ class Goke<Opts = {}> extends EventEmitter {
1927
1927
  return bLength - aLength
1928
1928
  })
1929
1929
 
1930
- // Search sub-commands mri() can throw coercion errors, catch them
1930
+ // Search sub-commands using two-pass matching:
1931
+ // 1. First pass: parse without schema coercion to find the matching command.
1932
+ // This avoids z.enum() or other schema validation throwing for the wrong
1933
+ // command's options before isMatched() can reject it.
1934
+ // 2. Second pass: re-parse with full coercion for the matched command only.
1931
1935
  try {
1932
1936
  for (const command of sortedCommands) {
1933
- const parsed = this.mri(argv.slice(2), command)
1937
+ const parsed = this.mri(argv.slice(2), command, true)
1934
1938
 
1935
1939
  const result = command.isMatched(parsed.args as string[])
1936
1940
  if (result.matched) {
1937
1941
  shouldParse = false
1938
- const matchedCommandName = parsed.args.slice(0, result.consumedArgs).join(' ')
1942
+ // Re-parse with coercion now that we know this is the right command
1943
+ const coerced = this.mri(argv.slice(2), command)
1944
+ const matchedCommandName = coerced.args.slice(0, result.consumedArgs).join(' ')
1939
1945
  const parsedInfo = {
1940
- ...parsed,
1941
- args: parsed.args.slice(result.consumedArgs),
1946
+ ...coerced,
1947
+ args: coerced.args.slice(result.consumedArgs),
1942
1948
  }
1943
1949
  this.setParsedInfo(parsedInfo, command, matchedCommandName)
1944
1950
  this.emit(`command:${matchedCommandName}`, command)
1945
- break // Stop after first match (greedy matching)
1951
+ break
1946
1952
  }
1947
1953
  }
1948
1954
 
@@ -2038,9 +2044,11 @@ class Goke<Opts = {}> extends EventEmitter {
2038
2044
  // Show help for commands starting with this prefix
2039
2045
  this.outputHelpForPrefix(firstArg, matchingCommands)
2040
2046
  } else {
2041
- // Unknown command with no matching prefix: show root help
2047
+ // Unknown command with no matching prefix: show error + root help
2048
+ this.console.error(`Unknown command: ${this.args.join(' ')}\n`)
2042
2049
  this.outputHelp()
2043
2050
  }
2051
+ this.exit(1)
2044
2052
  }
2045
2053
  }
2046
2054
 
@@ -2058,7 +2066,9 @@ class Goke<Opts = {}> extends EventEmitter {
2058
2066
 
2059
2067
  private mri(
2060
2068
  argv: string[],
2061
- /** Matched command */ command?: Command
2069
+ /** Matched command */ command?: Command,
2070
+ /** Skip schema coercion (used during command matching to avoid throwing for wrong commands) */
2071
+ skipCoercion?: boolean,
2062
2072
  ): ParsedArgv {
2063
2073
  // All added options
2064
2074
  const cliOptions = [
@@ -2165,37 +2175,39 @@ class Goke<Opts = {}> extends EventEmitter {
2165
2175
  const keys = key.split('.')
2166
2176
  let value = parsed[key]
2167
2177
 
2168
- // Apply schema coercion if this option has a schema.
2169
- // When value is boolean `true` and the option takes a value, it's mri's sentinel
2170
- // for "flag present, no value given":
2171
- // - Required options (<...>): preserve `true` so checkOptionValue() throws
2172
- // - Optional options ([...]) with schema AND a default: skip this
2173
- // key entirely so the preset default (written into `options` at
2174
- // the top of this function) survives. This keeps the type-level
2175
- // `HasSchemaDefault` promise honest at runtime.
2176
- // - Optional options ([...]) with schema and NO default: replace
2177
- // `true` with `undefined` so the caller sees "flag present, no value"
2178
- // as `undefined`.
2179
- const schemaInfo = schemaMap.get(key)
2180
- if (schemaInfo && value !== undefined) {
2181
- if (value === true && requiredValueOptions.has(key)) {
2182
- // Keep sentinel for checkOptionValue() to detect
2183
- } else if (value === true && optionalValueOptions.has(key)) {
2184
- if (optionsWithDefault.has(key)) {
2185
- // Preserve the preset default — don't overwrite with undefined.
2186
- continue
2178
+ if (!skipCoercion) {
2179
+ // Apply schema coercion if this option has a schema.
2180
+ // When value is boolean `true` and the option takes a value, it's mri's sentinel
2181
+ // for "flag present, no value given":
2182
+ // - Required options (<...>): preserve `true` so checkOptionValue() throws
2183
+ // - Optional options ([...]) with schema AND a default: skip this
2184
+ // key entirely so the preset default (written into `options` at
2185
+ // the top of this function) survives. This keeps the type-level
2186
+ // `HasSchemaDefault` promise honest at runtime.
2187
+ // - Optional options ([...]) with schema and NO default: replace
2188
+ // `true` with `undefined` so the caller sees "flag present, no value"
2189
+ // as `undefined`.
2190
+ const schemaInfo = schemaMap.get(key)
2191
+ if (schemaInfo && value !== undefined) {
2192
+ if (value === true && requiredValueOptions.has(key)) {
2193
+ // Keep sentinel for checkOptionValue() to detect
2194
+ } else if (value === true && optionalValueOptions.has(key)) {
2195
+ if (optionsWithDefault.has(key)) {
2196
+ // Preserve the preset default — don't overwrite with undefined.
2197
+ continue
2198
+ }
2199
+ value = undefined
2200
+ } else {
2201
+ value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName)
2187
2202
  }
2188
- value = undefined
2189
- } else {
2190
- value = coerceBySchema(value, schemaInfo.jsonSchema, schemaInfo.optionName)
2203
+ } else if (value === true && optionalValueOptions.has(key)) {
2204
+ // Untyped optional-value flag with no schema: normalize bare `true`
2205
+ // to `''` so callers get a clean `string | undefined` shape. `''`
2206
+ // means "flag passed with no argument", distinct from `undefined`
2207
+ // (flag omitted). This matches the new type inference that treats
2208
+ // `[value]` as `string` instead of `string | boolean`.
2209
+ value = ''
2191
2210
  }
2192
- } else if (value === true && optionalValueOptions.has(key)) {
2193
- // Untyped optional-value flag with no schema: normalize bare `true`
2194
- // to `''` so callers get a clean `string | undefined` shape. `''`
2195
- // means "flag passed with no argument", distinct from `undefined`
2196
- // (flag omitted). This matches the new type inference that treats
2197
- // `[value]` as `string` instead of `string | boolean`.
2198
- value = ''
2199
2211
  }
2200
2212
 
2201
2213
  setDotProp(options, keys, value)
@@ -2314,6 +2326,8 @@ interface DocPage {
2314
2326
  interface GenerateDocsOptions {
2315
2327
  /** The Goke CLI instance to generate docs from. */
2316
2328
  cli: Goke<any>
2329
+ /** Base path prefix for links between pages (e.g. "/docs/cli"). Defaults to ".". */
2330
+ basePath?: string
2317
2331
  }
2318
2332
 
2319
2333
  /**
@@ -2332,13 +2346,15 @@ interface GenerateDocsOptions {
2332
2346
  * .command('deploy <env>', 'Deploy to an environment')
2333
2347
  * .option('--force', 'Skip confirmation')
2334
2348
  *
2335
- * const pages = generateDocs({ cli })
2349
+ * const pages = generateDocs({ cli, basePath: '/docs/cli' })
2336
2350
  * for (const page of pages) {
2337
2351
  * fs.writeFileSync(`docs/${page.slug}.md`, page.content)
2338
2352
  * }
2339
2353
  * ```
2340
2354
  */
2341
- function generateDocs({ cli }: GenerateDocsOptions): DocPage[] {
2355
+ function generateDocs({ cli, basePath = '.' }: GenerateDocsOptions): DocPage[] {
2356
+ // Normalize: strip trailing slash
2357
+ basePath = basePath.replace(/\/+$/, '') || '.'
2342
2358
  const pages: DocPage[] = []
2343
2359
 
2344
2360
  // Collect global options (from globalCommand), excluding deprecated
@@ -2365,7 +2381,7 @@ function generateDocs({ cli }: GenerateDocsOptions): DocPage[] {
2365
2381
  if (cmd.isDefaultCommand) continue
2366
2382
  const desc = cmd.description.split('\n')[0].trim()
2367
2383
  const slug = cmd.name.replace(/\s+/g, '-')
2368
- lines.push(`| [\`${cmd.name}\`](./${slug}.md) | ${desc} |`)
2384
+ lines.push(`| [\`${cmd.name}\`](${basePath}/${slug}.md) | ${desc} |`)
2369
2385
  }
2370
2386
  lines.push('')
2371
2387