@visulima/cerebro 3.0.0-alpha.12 → 3.0.0-alpha.13

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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## @visulima/cerebro [3.0.0-alpha.13](https://github.com/visulima/visulima/compare/@visulima/cerebro@3.0.0-alpha.12...@visulima/cerebro@3.0.0-alpha.13) (2026-04-30)
2
+
3
+ ### Features
4
+
5
+ * **cerebro:** longest-prefix parser with option-stop and parent help ([ef1d244](https://github.com/visulima/visulima/commit/ef1d24446462cd5b34598f70715d4987c31b4eff))
6
+
7
+
8
+ ### Dependencies
9
+
10
+ * **@visulima/error:** upgraded to 6.0.0-alpha.14
11
+
1
12
  ## @visulima/cerebro [3.0.0-alpha.12](https://github.com/visulima/visulima/compare/@visulima/cerebro@3.0.0-alpha.11...@visulima/cerebro@3.0.0-alpha.12) (2026-04-28)
2
13
 
3
14
  ### Features
package/LICENSE.md CHANGED
@@ -145,7 +145,7 @@ Repository: git+https://github.com/visulima/visulima.git
145
145
  > > # Bundled types:
146
146
  > > ## ai
147
147
  > > License: Apache-2.0
148
- > > Repository: git+https://github.com/vercel/ai.git
148
+ > > Repository: https://github.com/vercel/ai
149
149
  > >
150
150
  > > > Copyright 2023 Vercel, Inc.
151
151
  > > >
@@ -230,7 +230,7 @@ Repository: git+https://github.com/visulima/visulima.git
230
230
  > > # Bundled types:
231
231
  > > ## ai
232
232
  > > License: Apache-2.0
233
- > > Repository: git+https://github.com/vercel/ai.git
233
+ > > Repository: https://github.com/vercel/ai
234
234
  > >
235
235
  > > > Copyright 2023 Vercel, Inc.
236
236
  > > >
@@ -308,7 +308,7 @@ Repository: git+https://github.com/visulima/visulima.git
308
308
  > # Bundled types:
309
309
  > ## ai
310
310
  > License: Apache-2.0
311
- > Repository: git+https://github.com/vercel/ai.git
311
+ > Repository: https://github.com/vercel/ai
312
312
  >
313
313
  > > Copyright 2023 Vercel, Inc.
314
314
  > >
@@ -1243,7 +1243,7 @@ Repository: git+https://github.com/visulima/visulima.git
1243
1243
  > > # Bundled types:
1244
1244
  > > ## ai
1245
1245
  > > License: Apache-2.0
1246
- > > Repository: git+https://github.com/vercel/ai.git
1246
+ > > Repository: https://github.com/vercel/ai
1247
1247
  > >
1248
1248
  > > > Copyright 2023 Vercel, Inc.
1249
1249
  > > >
@@ -1328,7 +1328,7 @@ Repository: git+https://github.com/visulima/visulima.git
1328
1328
  > > # Bundled types:
1329
1329
  > > ## ai
1330
1330
  > > License: Apache-2.0
1331
- > > Repository: git+https://github.com/vercel/ai.git
1331
+ > > Repository: https://github.com/vercel/ai
1332
1332
  > >
1333
1333
  > > > Copyright 2023 Vercel, Inc.
1334
1334
  > > >
@@ -1406,7 +1406,7 @@ Repository: git+https://github.com/visulima/visulima.git
1406
1406
  > # Bundled types:
1407
1407
  > ## ai
1408
1408
  > License: Apache-2.0
1409
- > Repository: git+https://github.com/vercel/ai.git
1409
+ > Repository: https://github.com/vercel/ai
1410
1410
  >
1411
1411
  > > Copyright 2023 Vercel, Inc.
1412
1412
  > >
@@ -1518,7 +1518,7 @@ Repository: git+https://github.com/visulima/visulima.git
1518
1518
  > > # Bundled types:
1519
1519
  > > ## ai
1520
1520
  > > License: Apache-2.0
1521
- > > Repository: git+https://github.com/vercel/ai.git
1521
+ > > Repository: https://github.com/vercel/ai
1522
1522
  > >
1523
1523
  > > > Copyright 2023 Vercel, Inc.
1524
1524
  > > >
@@ -98,6 +98,51 @@ const printGeneralHelp = (logger, runtime, commands, groupOption) => {
98
98
  )
99
99
  );
100
100
  };
101
+ const findChildren = (commands, parentPath) => {
102
+ const matches = [];
103
+ for (const cmd of commands.values()) {
104
+ if (cmd.hidden) {
105
+ continue;
106
+ }
107
+ const commandPath = cmd.commandPath ?? [];
108
+ if (commandPath.length !== parentPath.length) {
109
+ continue;
110
+ }
111
+ let isMatch = true;
112
+ for (let index = 0; index < parentPath.length; index += 1) {
113
+ if (commandPath[index] !== parentPath[index]) {
114
+ isMatch = false;
115
+ break;
116
+ }
117
+ }
118
+ if (isMatch) {
119
+ matches.push(cmd);
120
+ }
121
+ }
122
+ return matches;
123
+ };
124
+ const printParentHelp = (logger, runtime, parentPath, children) => {
125
+ const parentDisplay = parentPath.join(" ");
126
+ const usageGroups = [
127
+ {
128
+ content: `${cyan(runtime.getCliName())} ${green(parentDisplay)} ${green("<subcommand>")} [positional arguments] ${yellow("[options]")}`,
129
+ header: inverse.cyan(" Usage ")
130
+ },
131
+ {
132
+ content: children.map((child) => {
133
+ const fullPath = [...child.commandPath ?? [], child.name].join(" ");
134
+ return [green(fullPath), child.description ?? ""];
135
+ }),
136
+ header: inverse.green(" Subcommands ")
137
+ },
138
+ { header: inverse.yellow(" Global Options "), optionList: runtime.getGlobalOptions() },
139
+ {
140
+ content: `Run "${cyan(runtime.getCliName())} ${green(`${parentDisplay} <subcommand>`)} ${yellow("--help")}" for help with a specific subcommand.`,
141
+ raw: true
142
+ }
143
+ ];
144
+ (logger.raw ?? logger.log)(commandLineUsage(usageGroups));
145
+ };
101
146
  const printCommandHelp = (logger, runtime, commands, name) => {
102
147
  let command = commands.get(name);
103
148
  if (!command) {
@@ -110,6 +155,12 @@ const printCommandHelp = (logger, runtime, commands, name) => {
110
155
  }
111
156
  }
112
157
  if (!command) {
158
+ const parentPath = name.split(" ").filter(Boolean);
159
+ const children = parentPath.length > 0 ? findChildren(commands, parentPath) : [];
160
+ if (children.length > 0) {
161
+ printParentHelp(logger, runtime, parentPath, children);
162
+ return;
163
+ }
113
164
  logger.error(`Command "${name}" not found`);
114
165
  return;
115
166
  }
@@ -159,6 +210,17 @@ const printCommandHelp = (logger, runtime, commands, name) => {
159
210
  header: "Examples"
160
211
  });
161
212
  }
213
+ const ownPath = [...command.commandPath ?? [], command.name];
214
+ const ownChildren = findChildren(commands, ownPath);
215
+ if (ownChildren.length > 0) {
216
+ usageGroups.push({
217
+ content: ownChildren.map((child) => {
218
+ const fullPath = [...child.commandPath ?? [], child.name].join(" ");
219
+ return [green(fullPath), child.description ?? ""];
220
+ }),
221
+ header: inverse.green(" Subcommands ")
222
+ });
223
+ }
162
224
  (logger.raw ?? logger.log)(commandLineUsage(usageGroups));
163
225
  };
164
226
  class HelpCommand {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Cli } from './packem_shared/Cerebro-f9jDcQQy.js';
1
+ import { Cli } from './packem_shared/Cerebro-C1h3DXwy.js';
2
2
  export { VERBOSITY_DEBUG, VERBOSITY_NORMAL, VERBOSITY_QUIET, VERBOSITY_VERBOSE } from './packem_shared/VERBOSITY_QUIET-Dp46zlLW.js';
3
3
  export { lazyNamed } from './packem_shared/lazyNamed-B278Tf9_.js';
4
4
  export { VisulimaError } from './packem_shared/VisulimaError-DA7QsCxH.js';
@@ -1531,18 +1531,21 @@ const parseNestedCommand = (availableCommands, argv) => {
1531
1531
  return { argv: [], commandPath: void 0 };
1532
1532
  }
1533
1533
  const pathKeyParts = [];
1534
+ let bestMatch;
1534
1535
  for (let depth = 1; depth <= argv.length; depth += 1) {
1535
1536
  const argument = argv[depth - 1];
1536
- if (argument === void 0) {
1537
+ if (argument === void 0 || argument.startsWith("-")) {
1537
1538
  break;
1538
1539
  }
1539
1540
  pathKeyParts.push(argument);
1540
1541
  const pathKey = pathKeyParts.join(" ");
1541
1542
  if (availableCommands.has(pathKey)) {
1542
- const remainingArgv = argv.slice(depth);
1543
- return { argv: remainingArgv, commandPath: [...pathKeyParts] };
1543
+ bestMatch = { commandPath: [...pathKeyParts], depth };
1544
1544
  }
1545
1545
  }
1546
+ if (bestMatch) {
1547
+ return { argv: argv.slice(bestMatch.depth), commandPath: bestMatch.commandPath };
1548
+ }
1546
1549
  return { argv, commandPath: void 0 };
1547
1550
  };
1548
1551
  const getCommandPathKey = (commandPath) => commandPath.join(" ");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/cerebro",
3
- "version": "3.0.0-alpha.12",
3
+ "version": "3.0.0-alpha.13",
4
4
  "description": "A delightful toolkit for building cross-runtime CLIs for Node.js, Deno, and Bun.",
5
5
  "keywords": [
6
6
  "ansi",
@@ -116,7 +116,7 @@
116
116
  "fastest-levenshtein": "^1.0.16"
117
117
  },
118
118
  "peerDependencies": {
119
- "@bomb.sh/tab": "0.0.14",
119
+ "@bomb.sh/tab": "0.0.15",
120
120
  "@visulima/boxen": "3.0.0-alpha.10",
121
121
  "@visulima/find-cache-dir": "3.0.0-alpha.9",
122
122
  "@visulima/pail": "4.0.0-alpha.12",