padrone 1.4.0 → 1.5.0

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +105 -284
  3. package/dist/{args-CVDbyyzG.mjs → args-D5PNDyNu.mjs} +41 -18
  4. package/dist/args-D5PNDyNu.mjs.map +1 -0
  5. package/dist/chunk-CjcI7cDX.mjs +15 -0
  6. package/dist/codegen/index.d.mts +28 -3
  7. package/dist/codegen/index.d.mts.map +1 -1
  8. package/dist/codegen/index.mjs +169 -19
  9. package/dist/codegen/index.mjs.map +1 -1
  10. package/dist/command-utils-B1D-HqCd.mjs +1117 -0
  11. package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
  12. package/dist/completion.d.mts +1 -1
  13. package/dist/completion.d.mts.map +1 -1
  14. package/dist/completion.mjs +77 -29
  15. package/dist/completion.mjs.map +1 -1
  16. package/dist/docs/index.d.mts +22 -2
  17. package/dist/docs/index.d.mts.map +1 -1
  18. package/dist/docs/index.mjs +94 -7
  19. package/dist/docs/index.mjs.map +1 -1
  20. package/dist/errors-BiVrBgi6.mjs +114 -0
  21. package/dist/errors-BiVrBgi6.mjs.map +1 -0
  22. package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DtHzbP22.d.mts} +34 -5
  23. package/dist/formatter-DtHzbP22.d.mts.map +1 -0
  24. package/dist/help-bbmu9-qd.mjs +735 -0
  25. package/dist/help-bbmu9-qd.mjs.map +1 -0
  26. package/dist/index.d.mts +32 -3
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +493 -265
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/mcp-mLWIdUIu.mjs +379 -0
  31. package/dist/mcp-mLWIdUIu.mjs.map +1 -0
  32. package/dist/serve-B0u43DK7.mjs +404 -0
  33. package/dist/serve-B0u43DK7.mjs.map +1 -0
  34. package/dist/stream-BcC146Ud.mjs +56 -0
  35. package/dist/stream-BcC146Ud.mjs.map +1 -0
  36. package/dist/test.d.mts +1 -1
  37. package/dist/test.mjs +4 -15
  38. package/dist/test.mjs.map +1 -1
  39. package/dist/{types-DjIdJN5G.d.mts → types-Ch8Mk6Qb.d.mts} +310 -62
  40. package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
  41. package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
  42. package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
  43. package/dist/zod.d.mts +32 -0
  44. package/dist/zod.d.mts.map +1 -0
  45. package/dist/zod.mjs +50 -0
  46. package/dist/zod.mjs.map +1 -0
  47. package/package.json +10 -2
  48. package/src/args.ts +68 -40
  49. package/src/cli/docs.ts +1 -7
  50. package/src/cli/doctor.ts +195 -10
  51. package/src/cli/index.ts +1 -1
  52. package/src/cli/init.ts +2 -3
  53. package/src/cli/link.ts +2 -2
  54. package/src/codegen/discovery.ts +80 -28
  55. package/src/codegen/index.ts +2 -1
  56. package/src/codegen/parsers/bash.ts +179 -0
  57. package/src/codegen/schema-to-code.ts +2 -1
  58. package/src/colorizer.ts +126 -13
  59. package/src/command-utils.ts +380 -30
  60. package/src/completion.ts +120 -47
  61. package/src/create.ts +480 -128
  62. package/src/docs/index.ts +122 -8
  63. package/src/formatter.ts +171 -125
  64. package/src/help.ts +45 -12
  65. package/src/index.ts +29 -1
  66. package/src/interactive.ts +45 -4
  67. package/src/mcp.ts +390 -0
  68. package/src/repl-loop.ts +16 -3
  69. package/src/runtime.ts +195 -2
  70. package/src/serve.ts +442 -0
  71. package/src/stream.ts +75 -0
  72. package/src/test.ts +7 -16
  73. package/src/type-utils.ts +28 -4
  74. package/src/types.ts +212 -30
  75. package/src/wrap.ts +23 -25
  76. package/src/zod.ts +50 -0
  77. package/dist/args-CVDbyyzG.mjs.map +0 -1
  78. package/dist/chunk-y_GBKt04.mjs +0 -5
  79. package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
  80. package/dist/help-CcBe91bV.mjs +0 -1254
  81. package/dist/help-CcBe91bV.mjs.map +0 -1
  82. package/dist/types-DjIdJN5G.d.mts.map +0 -1
@@ -0,0 +1,735 @@
1
+ import { a as extractSchemaMetadata, c as parsePositionalConfig, l as parseStdinConfig, n as camelToKebab, t as JSON_SCHEMA_OPTS } from "./args-D5PNDyNu.mjs";
2
+ import { L as getRootCommand, u as findCommandByName } from "./command-utils-B1D-HqCd.mjs";
3
+ //#region src/colorizer.ts
4
+ const ansiCodes = {
5
+ reset: "\x1B[0m",
6
+ bold: "\x1B[1m",
7
+ dim: "\x1B[2m",
8
+ italic: "\x1B[3m",
9
+ underline: "\x1B[4m",
10
+ strikethrough: "\x1B[9m",
11
+ red: "\x1B[31m",
12
+ green: "\x1B[32m",
13
+ yellow: "\x1B[33m",
14
+ blue: "\x1B[34m",
15
+ magenta: "\x1B[35m",
16
+ cyan: "\x1B[36m",
17
+ white: "\x1B[37m",
18
+ gray: "\x1B[90m"
19
+ };
20
+ const defaultTheme = {
21
+ command: ["cyan", "bold"],
22
+ arg: ["green"],
23
+ type: ["yellow"],
24
+ description: ["dim"],
25
+ label: ["bold"],
26
+ meta: ["gray"],
27
+ example: ["underline"],
28
+ exampleValue: ["italic"],
29
+ deprecated: ["strikethrough", "gray"]
30
+ };
31
+ const colorThemes = {
32
+ default: defaultTheme,
33
+ ocean: {
34
+ command: ["blue", "bold"],
35
+ arg: ["cyan"],
36
+ type: ["green"],
37
+ description: ["dim"],
38
+ label: ["bold"],
39
+ meta: ["gray"],
40
+ example: ["underline", "cyan"],
41
+ exampleValue: ["italic"],
42
+ deprecated: ["strikethrough", "gray"]
43
+ },
44
+ warm: {
45
+ command: ["yellow", "bold"],
46
+ arg: ["red"],
47
+ type: ["magenta"],
48
+ description: ["dim"],
49
+ label: ["bold"],
50
+ meta: ["gray"],
51
+ example: ["underline", "yellow"],
52
+ exampleValue: ["italic"],
53
+ deprecated: ["strikethrough", "gray"]
54
+ },
55
+ monochrome: {
56
+ command: ["bold"],
57
+ arg: ["underline"],
58
+ type: ["dim"],
59
+ description: ["dim"],
60
+ label: ["bold"],
61
+ meta: ["dim"],
62
+ example: ["underline"],
63
+ exampleValue: ["italic"],
64
+ deprecated: ["strikethrough", "dim"]
65
+ }
66
+ };
67
+ function makeStyleFn(styles) {
68
+ const prefix = styles.map((s) => ansiCodes[s]).join("");
69
+ return (text) => `${prefix}${text}${ansiCodes.reset}`;
70
+ }
71
+ function resolveConfig(config) {
72
+ if (!config) return defaultTheme;
73
+ if (typeof config === "string") return colorThemes[config] ?? defaultTheme;
74
+ return {
75
+ ...defaultTheme,
76
+ ...config
77
+ };
78
+ }
79
+ function createColorizer(config) {
80
+ const resolved = resolveConfig(config);
81
+ return {
82
+ command: makeStyleFn(resolved.command),
83
+ arg: makeStyleFn(resolved.arg),
84
+ type: makeStyleFn(resolved.type),
85
+ description: makeStyleFn(resolved.description),
86
+ label: makeStyleFn(resolved.label),
87
+ meta: makeStyleFn(resolved.meta),
88
+ example: makeStyleFn(resolved.example),
89
+ exampleValue: makeStyleFn(resolved.exampleValue),
90
+ deprecated: makeStyleFn(resolved.deprecated)
91
+ };
92
+ }
93
+ //#endregion
94
+ //#region src/formatter.ts
95
+ function createTextStyler() {
96
+ return {
97
+ command: (text) => text,
98
+ arg: (text) => text,
99
+ type: (text) => text,
100
+ description: (text) => text,
101
+ label: (text) => text,
102
+ section: (text) => text,
103
+ meta: (text) => text,
104
+ example: (text) => text,
105
+ exampleValue: (text) => text,
106
+ deprecated: (text) => text
107
+ };
108
+ }
109
+ function createAnsiStyler(theme) {
110
+ const colorizer = createColorizer(theme);
111
+ return {
112
+ command: colorizer.command,
113
+ arg: colorizer.arg,
114
+ type: colorizer.type,
115
+ description: colorizer.description,
116
+ label: colorizer.label,
117
+ section: colorizer.label,
118
+ meta: colorizer.meta,
119
+ example: colorizer.example,
120
+ exampleValue: colorizer.exampleValue,
121
+ deprecated: colorizer.deprecated
122
+ };
123
+ }
124
+ function createConsoleStyler(theme) {
125
+ return createAnsiStyler(theme);
126
+ }
127
+ function createMarkdownStyler() {
128
+ return {
129
+ command: (text) => `**${text}**`,
130
+ arg: (text) => `\`${text}\``,
131
+ type: (text) => `\`${text}\``,
132
+ description: (text) => text,
133
+ label: (text) => `**${text}**`,
134
+ section: (text) => `### ${text}`,
135
+ meta: (text) => `*${text}*`,
136
+ example: (text) => `**${text}**`,
137
+ exampleValue: (text) => `\`${text}\``,
138
+ deprecated: (text) => `~~${text}~~`
139
+ };
140
+ }
141
+ function escapeHtml(text) {
142
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
143
+ }
144
+ function createHtmlStyler() {
145
+ return {
146
+ command: (text) => `<strong style="color: #00bcd4;">${escapeHtml(text)}</strong>`,
147
+ arg: (text) => `<code style="color: #4caf50;">${escapeHtml(text)}</code>`,
148
+ type: (text) => `<code style="color: #ff9800;">${escapeHtml(text)}</code>`,
149
+ description: (text) => `<span style="color: #666;">${escapeHtml(text)}</span>`,
150
+ label: (text) => `<strong>${escapeHtml(text)}</strong>`,
151
+ section: (text) => `<h3>${escapeHtml(text)}</h3>`,
152
+ meta: (text) => `<span style="color: #999;">${escapeHtml(text)}</span>`,
153
+ example: (text) => `<strong style="text-decoration: underline;">${escapeHtml(text)}</strong>`,
154
+ exampleValue: (text) => `<em>${escapeHtml(text)}</em>`,
155
+ deprecated: (text) => `<del style="color: #999;">${escapeHtml(text)}</del>`
156
+ };
157
+ }
158
+ function createTextLayout() {
159
+ return {
160
+ newline: "\n",
161
+ indent: (level) => " ".repeat(level),
162
+ join: (parts) => parts.filter(Boolean).join(" ")
163
+ };
164
+ }
165
+ function createMarkdownLayout() {
166
+ return {
167
+ newline: "\n\n",
168
+ indent: (level) => {
169
+ if (level === 0) return "";
170
+ if (level === 1) return " ";
171
+ return " ";
172
+ },
173
+ join: (parts) => parts.filter(Boolean).join(" ")
174
+ };
175
+ }
176
+ function createHtmlLayout() {
177
+ return {
178
+ newline: "<br>",
179
+ indent: (level) => "&nbsp;&nbsp;".repeat(level),
180
+ join: (parts) => parts.filter(Boolean).join(" "),
181
+ wrapDocument: (content) => `<div style="font-family: monospace; line-height: 1.6;">${content}</div>`
182
+ };
183
+ }
184
+ /**
185
+ * Creates a formatter that uses the given styler and layout configuration.
186
+ */
187
+ function createGenericFormatter(styler, layout, showAllBuiltins) {
188
+ const { newline, indent, join, wrapDocument } = layout;
189
+ function formatUsageSection(info) {
190
+ const usageParts = [styler.command(info.usage.command), info.usage.hasSubcommands ? styler.meta("[command]") : ""];
191
+ if (info.positionals && info.positionals.length > 0) for (const arg of info.positionals) {
192
+ const name = arg.name.startsWith("...") ? `${arg.name}` : arg.name;
193
+ usageParts.push(styler.meta(arg.optional ? `[${name}]` : `<${name}>`));
194
+ }
195
+ if (info.usage.hasArguments) usageParts.push(styler.meta("[options]"));
196
+ return [`${styler.label("Usage:")} ${join(usageParts)}`];
197
+ }
198
+ function formatSubcommandsSection(info) {
199
+ const lines = [];
200
+ const subcommands = info.subcommands;
201
+ const subcommandSuffix = (c) => c.hasSubcommands ? " <subcommand>" : "";
202
+ const formatAliasParts = (c) => {
203
+ if (!c.aliases?.length) return {
204
+ plain: "",
205
+ styled: ""
206
+ };
207
+ const realAliases = c.aliases.filter((a) => a !== "[default]");
208
+ const hasDefault = c.aliases.some((a) => a === "[default]");
209
+ const parts = [];
210
+ const styledParts = [];
211
+ if (realAliases.length) {
212
+ parts.push(`(${realAliases.join(", ")})`);
213
+ styledParts.push(`(${realAliases.join(", ")})`);
214
+ }
215
+ if (hasDefault) {
216
+ parts.push("[default]");
217
+ styledParts.push(styler.meta("[default]"));
218
+ }
219
+ return {
220
+ plain: parts.length ? ` ${parts.join(" ")}` : "",
221
+ styled: styledParts.length ? ` ${styledParts.join(" ")}` : ""
222
+ };
223
+ };
224
+ const maxNameLength = Math.max(...subcommands.map((c) => {
225
+ return (c.name + subcommandSuffix(c) + formatAliasParts(c).plain).length;
226
+ }));
227
+ const grouped = Object.groupBy(subcommands, (c) => c.group ?? "");
228
+ const renderSubcommands = (cmds) => {
229
+ for (const subCmd of cmds) {
230
+ const aliasParts = formatAliasParts(subCmd);
231
+ const suffix = subcommandSuffix(subCmd);
232
+ const commandDisplay = subCmd.name + suffix + aliasParts.plain;
233
+ const padding = " ".repeat(Math.max(0, maxNameLength - commandDisplay.length + 2));
234
+ const isDeprecated = !!subCmd.deprecated;
235
+ const isDefaultEntry = subCmd.name === "[default]";
236
+ const lineParts = [isDeprecated ? styler.deprecated(commandDisplay) : (isDefaultEntry ? styler.meta(subCmd.name) : styler.command(subCmd.name)) + (suffix ? styler.meta(suffix) : "") + aliasParts.styled, padding];
237
+ const displayText = subCmd.title ?? subCmd.description;
238
+ if (displayText) lineParts.push(isDeprecated ? styler.deprecated(displayText) : styler.description(displayText));
239
+ if (isDeprecated) {
240
+ const deprecatedMeta = typeof subCmd.deprecated === "string" ? styler.meta(` (deprecated: ${subCmd.deprecated})`) : styler.meta(" (deprecated)");
241
+ lineParts.push(deprecatedMeta);
242
+ }
243
+ lines.push(indent(1) + lineParts.join(""));
244
+ }
245
+ };
246
+ for (const [key, items] of Object.entries(grouped)) {
247
+ if (lines.length > 0) lines.push("");
248
+ lines.push(styler.section(key ? `${key}:` : "Commands:"));
249
+ renderSubcommands(items);
250
+ }
251
+ if (!info.builtins?.length) {
252
+ lines.push("");
253
+ lines.push(styler.meta(`Run "${info.name} [command] --help" for more information on a command.`));
254
+ }
255
+ return lines;
256
+ }
257
+ function formatPositionalsSection(info) {
258
+ const lines = [];
259
+ const args = info.positionals;
260
+ lines.push(styler.section("Arguments:"));
261
+ const maxNameLength = Math.min(32, Math.max(...args.map((a) => a.name.length)));
262
+ for (const arg of args) {
263
+ const padding = " ".repeat(Math.max(2, maxNameLength - arg.name.length + 2));
264
+ const descParts = [];
265
+ if (arg.description) descParts.push(styler.description(arg.description));
266
+ if (info.usage.stdinField === arg.name) descParts.push(styler.meta("(stdin)"));
267
+ if (arg.enum) descParts.push(styler.meta(`(choices: ${arg.enum.join(", ")})`));
268
+ if (arg.default !== void 0) descParts.push(styler.meta(`(default: ${String(arg.default)})`));
269
+ lines.push(indent(1) + styler.arg(arg.name) + padding + join(descParts));
270
+ }
271
+ return lines;
272
+ }
273
+ function formatArgumentsSection(info) {
274
+ const lines = [];
275
+ const argList = info.arguments || [];
276
+ const hasDefault = (value) => {
277
+ if (value === void 0) return false;
278
+ if (value === "") return false;
279
+ if (Array.isArray(value) && value.length === 0) return false;
280
+ return true;
281
+ };
282
+ const argColumns = argList.map((arg) => {
283
+ const kebab = camelToKebab(arg.name);
284
+ const primaryName = kebab && arg.aliases?.includes(kebab) ? kebab : arg.name;
285
+ const remainingAliases = arg.aliases?.filter((a) => a !== primaryName);
286
+ return {
287
+ flagsPlain: arg.flags?.length ? arg.flags.map((f) => `-${f}`).join(", ") : "",
288
+ namesPlain: [`--${primaryName}`, ...remainingAliases?.map((a) => `--${a}`) || []].join(", "),
289
+ typePlain: arg.type && arg.type !== "boolean" ? arg.optional ? `[${arg.type}]` : `<${arg.type}>` : "",
290
+ isDeprecated: !!arg.deprecated,
291
+ arg
292
+ };
293
+ });
294
+ const maxFlagsWidth = Math.min(12, Math.max(0, ...argColumns.map((c) => c.flagsPlain.length)));
295
+ const maxNamesWidth = Math.min(32, Math.max(0, ...argColumns.map((c) => c.namesPlain.length)));
296
+ const maxTypeWidth = Math.min(16, Math.max(0, ...argColumns.map((c) => c.typePlain.length)));
297
+ const hasAnyFlags = maxFlagsWidth > 0;
298
+ const grouped = Object.groupBy(argColumns, (c) => c.arg.group ?? "");
299
+ const renderArgColumns = (columns) => {
300
+ for (const { flagsPlain, namesPlain, typePlain, isDeprecated, arg } of columns) {
301
+ const parts = [];
302
+ if (hasAnyFlags) {
303
+ const styledFlags = isDeprecated ? flagsPlain ? styler.deprecated(flagsPlain) : "" : flagsPlain ? styler.arg(flagsPlain) : "";
304
+ const flagsPadding = " ".repeat(Math.max(0, maxFlagsWidth - flagsPlain.length));
305
+ const separator = flagsPlain ? ", " : " ";
306
+ parts.push(styledFlags + flagsPadding + separator);
307
+ }
308
+ const styledNames = isDeprecated ? styler.deprecated(namesPlain) : styler.arg(namesPlain);
309
+ const namesPadding = " ".repeat(Math.max(2, maxNamesWidth - namesPlain.length + 2));
310
+ parts.push(styledNames + namesPadding);
311
+ if (maxTypeWidth > 0) {
312
+ const styledType = typePlain ? styler.type(typePlain) : "";
313
+ const typePadding = " ".repeat(Math.max(2, maxTypeWidth - typePlain.length + 2));
314
+ parts.push(styledType + typePadding);
315
+ }
316
+ const descParts = [];
317
+ if (arg.description) descParts.push(isDeprecated ? styler.deprecated(arg.description) : styler.description(arg.description));
318
+ lines.push(indent(1) + parts.join("") + join(descParts));
319
+ const line2Parts = [];
320
+ if (isDeprecated && typeof arg.deprecated !== "string") line2Parts.push(styler.meta("(deprecated)"));
321
+ if (hasDefault(arg.default)) line2Parts.push(styler.meta(`(default: ${String(arg.default)})`));
322
+ if (arg.enum) line2Parts.push(styler.meta(`(choices: ${arg.enum.join(", ")})`));
323
+ if (line2Parts.length > 0) lines.push(indent(3) + join(line2Parts));
324
+ const line3Parts = [];
325
+ if (isDeprecated && typeof arg.deprecated === "string") line3Parts.push(styler.meta(`(deprecated: ${arg.deprecated})`));
326
+ if (arg.examples && arg.examples.length > 0) {
327
+ const exampleValues = arg.examples.map((example) => typeof example === "string" ? example : JSON.stringify(example)).join(", ");
328
+ line3Parts.push(styler.example("Example:"), styler.exampleValue(exampleValues));
329
+ }
330
+ if (line3Parts.length > 0) lines.push(indent(3) + join(line3Parts));
331
+ const line4Parts = [];
332
+ if (info.usage.stdinField === arg.name) line4Parts.push(styler.meta("(stdin)"));
333
+ if (arg.env) {
334
+ const envVars = typeof arg.env === "string" ? [arg.env] : arg.env;
335
+ line4Parts.push(styler.example("Env:"), styler.exampleValue(envVars.join(", ")));
336
+ }
337
+ if (arg.configKey) line4Parts.push(styler.example("Config:"), styler.exampleValue(arg.configKey));
338
+ if (line4Parts.length > 0) lines.push(indent(3) + join(line4Parts));
339
+ }
340
+ };
341
+ for (const [key, items] of Object.entries(grouped)) {
342
+ if (lines.length > 0) lines.push("");
343
+ lines.push(styler.section(key ? `${key}:` : "Options:"));
344
+ renderArgColumns(items);
345
+ }
346
+ return lines;
347
+ }
348
+ function formatBuiltinsSection(info) {
349
+ const lines = [];
350
+ const builtins = info.builtins;
351
+ if (!showAllBuiltins) {
352
+ lines.push(`${styler.label("Global:")} ${styler.meta([
353
+ "help [command]",
354
+ "version",
355
+ "[command] --repl"
356
+ ].join(", "))}`);
357
+ const hint = info.usage.hasSubcommands ? `Run "${info.name} [command] --help" for more information. Use "--all" for all global commands.` : `Use "${info.name} help --all" for more information on global commands.`;
358
+ lines.push(styler.meta(hint));
359
+ return lines;
360
+ }
361
+ lines.push(styler.section("Global:"));
362
+ const allLengths = [];
363
+ for (const entry of builtins) {
364
+ allLengths.push(entry.name.length);
365
+ if (entry.sub) for (const sub of entry.sub) allLengths.push(sub.name.length + 2);
366
+ }
367
+ const maxLen = Math.max(...allLengths);
368
+ for (const entry of builtins) {
369
+ const padding = " ".repeat(Math.max(2, maxLen - entry.name.length + 2));
370
+ const parts = [styler.command(entry.name)];
371
+ if (entry.description) parts.push(padding + styler.description(entry.description));
372
+ lines.push(indent(1) + parts.join(""));
373
+ if (entry.sub) for (const sub of entry.sub) {
374
+ const subPadding = " ".repeat(Math.max(2, maxLen - sub.name.length));
375
+ const subParts = [styler.arg(sub.name)];
376
+ if (sub.description) subParts.push(subPadding + styler.description(sub.description));
377
+ lines.push(indent(2) + subParts.join(""));
378
+ }
379
+ }
380
+ return lines;
381
+ }
382
+ return { format(info) {
383
+ const lines = [];
384
+ if (info.deprecated) {
385
+ const deprecationMessage = typeof info.deprecated === "string" ? `⚠️ This command is deprecated: ${info.deprecated}` : "⚠️ This command is deprecated";
386
+ lines.push(styler.deprecated(deprecationMessage));
387
+ lines.push("");
388
+ }
389
+ lines.push(...formatUsageSection(info));
390
+ lines.push("");
391
+ if (info.title) {
392
+ lines.push(styler.label(info.title));
393
+ lines.push("");
394
+ }
395
+ if (info.aliases && info.aliases.length > 0) {
396
+ lines.push(styler.meta(`Aliases: ${info.aliases.join(", ")}`));
397
+ lines.push("");
398
+ }
399
+ if (info.description) {
400
+ lines.push(styler.description(info.description));
401
+ lines.push("");
402
+ }
403
+ if (info.examples && info.examples.length > 0) {
404
+ lines.push(styler.section("Examples:"));
405
+ for (const ex of info.examples) lines.push(indent(1) + styler.meta("$ ") + styler.exampleValue(ex));
406
+ lines.push("");
407
+ }
408
+ if (info.subcommands && info.subcommands.length > 0) {
409
+ lines.push(...formatSubcommandsSection(info));
410
+ lines.push("");
411
+ }
412
+ if (info.positionals && info.positionals.length > 0) {
413
+ lines.push(...formatPositionalsSection(info));
414
+ lines.push("");
415
+ }
416
+ if (info.arguments && info.arguments.length > 0) {
417
+ lines.push(...formatArgumentsSection(info));
418
+ lines.push("");
419
+ }
420
+ if (info.builtins && info.builtins.length > 0) {
421
+ lines.push(...formatBuiltinsSection(info));
422
+ lines.push("");
423
+ }
424
+ if (info.arguments?.some((arg) => arg.negatable && arg.default === true)) {
425
+ lines.push(styler.meta("Boolean options can be negated with --no-<option>."));
426
+ lines.push("");
427
+ }
428
+ if (info.nestedCommands?.length) {
429
+ lines.push(styler.section("Subcommand Details:"));
430
+ lines.push("");
431
+ for (const nestedCmd of info.nestedCommands) {
432
+ lines.push(styler.meta("─".repeat(60)));
433
+ lines.push(this.format(nestedCmd));
434
+ }
435
+ }
436
+ const result = lines.join(newline);
437
+ return wrapDocument ? wrapDocument(result) : result;
438
+ } };
439
+ }
440
+ function createJsonFormatter() {
441
+ return { format(info) {
442
+ return JSON.stringify(info, null, 2);
443
+ } };
444
+ }
445
+ function shouldUseAnsi() {
446
+ if (typeof process === "undefined") return false;
447
+ if (process.env.NO_COLOR) return false;
448
+ if (process.env.CI) return false;
449
+ if (process.stdout && typeof process.stdout.isTTY === "boolean") return process.stdout.isTTY;
450
+ return false;
451
+ }
452
+ /**
453
+ * Creates a minimal formatter that outputs just a single-line usage string.
454
+ */
455
+ function createMinimalFormatter() {
456
+ return { format(info) {
457
+ const parts = [info.usage.command];
458
+ if (info.usage.hasSubcommands) parts.push("[command]");
459
+ if (info.positionals && info.positionals.length > 0) for (const arg of info.positionals) {
460
+ const name = arg.name.startsWith("...") ? `${arg.name}` : arg.name;
461
+ parts.push(arg.optional ? `[${name}]` : `<${name}>`);
462
+ }
463
+ if (info.usage.hasArguments) parts.push("[options]");
464
+ return parts.join(" ");
465
+ } };
466
+ }
467
+ function createFormatter(format, detail = "standard", theme, all) {
468
+ if (detail === "minimal") return createMinimalFormatter();
469
+ if (format === "json") return createJsonFormatter();
470
+ if (format === "ansi" || format === "auto" && shouldUseAnsi()) return createGenericFormatter(createAnsiStyler(theme), createTextLayout(), all);
471
+ if (format === "console") return createGenericFormatter(createConsoleStyler(theme), createTextLayout(), all);
472
+ if (format === "markdown") return createGenericFormatter(createMarkdownStyler(), createMarkdownLayout(), all);
473
+ if (format === "html") return createGenericFormatter(createHtmlStyler(), createHtmlLayout(), all);
474
+ return createGenericFormatter(createTextStyler(), createTextLayout(), all);
475
+ }
476
+ //#endregion
477
+ //#region src/help.ts
478
+ /**
479
+ * Extract positional arguments info from schema based on meta.positional config.
480
+ */
481
+ function extractPositionalArgsInfo(schema, meta) {
482
+ const args = [];
483
+ const positionalNames = /* @__PURE__ */ new Set();
484
+ if (!schema || !meta?.positional || meta.positional.length === 0) return {
485
+ args,
486
+ positionalNames
487
+ };
488
+ const positionalConfig = parsePositionalConfig(meta.positional);
489
+ try {
490
+ const jsonSchema = schema["~standard"].jsonSchema.input(JSON_SCHEMA_OPTS);
491
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
492
+ const properties = jsonSchema.properties;
493
+ const required = jsonSchema.required || [];
494
+ for (const { name, variadic } of positionalConfig) {
495
+ const prop = properties[name];
496
+ if (!prop) continue;
497
+ positionalNames.add(name);
498
+ const optMeta = meta.fields?.[name];
499
+ args.push({
500
+ name: variadic ? `...${name}` : name,
501
+ description: optMeta?.description ?? prop.description,
502
+ optional: !required.includes(name),
503
+ default: prop.default,
504
+ type: variadic ? `array<${prop.items?.type || "string"}>` : prop.type,
505
+ enum: prop.enum ?? prop.items?.enum
506
+ });
507
+ }
508
+ }
509
+ } catch {}
510
+ return {
511
+ args,
512
+ positionalNames
513
+ };
514
+ }
515
+ function extractArgsInfo(schema, meta, positionalNames) {
516
+ const result = [];
517
+ if (!schema) return result;
518
+ if (!schema["~standard"].vendor.includes("zod")) return result;
519
+ const argsMeta = meta?.fields;
520
+ try {
521
+ const jsonSchema = schema["~standard"].jsonSchema.input(JSON_SCHEMA_OPTS);
522
+ if (jsonSchema.type === "object" && jsonSchema.properties) {
523
+ const properties = jsonSchema.properties;
524
+ const required = jsonSchema.required || [];
525
+ const propertyNames = new Set(Object.keys(properties));
526
+ const hasExplicitNegation = (key) => {
527
+ const camelNegated = `no${key.charAt(0).toUpperCase()}${key.slice(1)}`;
528
+ if (propertyNames.has(camelNegated)) return true;
529
+ const kebabNegated = `no-${key}`;
530
+ if (propertyNames.has(kebabNegated)) return true;
531
+ return false;
532
+ };
533
+ const isNegationOf = (key) => {
534
+ if (key.startsWith("no") && key.length > 2 && key[2] === key[2]?.toUpperCase()) {
535
+ const positiveKey = key.charAt(2).toLowerCase() + key.slice(3);
536
+ if (propertyNames.has(positiveKey)) return true;
537
+ }
538
+ if (key.startsWith("no-")) {
539
+ const positiveKey = key.slice(3);
540
+ if (propertyNames.has(positiveKey)) return true;
541
+ }
542
+ return false;
543
+ };
544
+ for (const [key, prop] of Object.entries(properties)) {
545
+ if (positionalNames?.has(key)) continue;
546
+ const isOptional = !required.includes(key);
547
+ const enumValues = prop.enum ?? prop.items?.enum;
548
+ const optMeta = argsMeta?.[key];
549
+ const propType = prop.type;
550
+ const isNegatable = propType === "boolean" && !hasExplicitNegation(key) && !isNegationOf(key);
551
+ result.push({
552
+ name: key,
553
+ description: optMeta?.description ?? prop.description,
554
+ optional: isOptional,
555
+ default: prop.default,
556
+ type: propType === "array" ? `${prop.items?.type || "string"}[]` : propType,
557
+ enum: enumValues,
558
+ deprecated: optMeta?.deprecated ?? prop?.deprecated,
559
+ hidden: optMeta?.hidden ?? prop?.hidden,
560
+ examples: optMeta?.examples ?? prop?.examples,
561
+ variadic: propType === "array",
562
+ negatable: isNegatable,
563
+ group: optMeta?.group
564
+ });
565
+ }
566
+ }
567
+ } catch {}
568
+ return result;
569
+ }
570
+ /**
571
+ * Builds a comprehensive HelpInfo structure from a command.
572
+ * This is the single source of truth that all formatters use.
573
+ * @param cmd - The command to build help info for
574
+ * @param detail - The level of detail ('minimal', 'standard', or 'full')
575
+ */
576
+ function getHelpInfo(cmd, detail = "standard", all) {
577
+ const rootCmd = getRootCommand(cmd);
578
+ const isDefaultCommand = cmd.parent && (!cmd.name || cmd.aliases?.includes(""));
579
+ const nonEmptyAliases = cmd.aliases?.filter(Boolean);
580
+ const commandName = cmd.path || cmd.name || nonEmptyAliases?.[0] || (cmd.parent ? "[default]" : "program");
581
+ const remainingAliases = !cmd.name && nonEmptyAliases?.length ? nonEmptyAliases.slice(1) : nonEmptyAliases ?? [];
582
+ const displayAliases = isDefaultCommand ? [...remainingAliases, "[default]"] : nonEmptyAliases;
583
+ const { args: positionalArgs, positionalNames } = cmd.argsSchema ? extractPositionalArgsInfo(cmd.argsSchema, cmd.meta) : {
584
+ args: [],
585
+ positionalNames: /* @__PURE__ */ new Set()
586
+ };
587
+ const hasPositionals = positionalArgs.length > 0;
588
+ const helpInfo = {
589
+ name: commandName,
590
+ title: cmd.title,
591
+ description: cmd.description,
592
+ examples: cmd.examples,
593
+ aliases: displayAliases,
594
+ deprecated: cmd.deprecated,
595
+ hidden: cmd.hidden,
596
+ usage: {
597
+ command: rootCmd === cmd ? commandName : `${rootCmd.name} ${commandName}`,
598
+ hasSubcommands: !!(cmd.commands && cmd.commands.length > 0),
599
+ hasPositionals,
600
+ hasArguments: false,
601
+ stdinField: cmd.meta?.stdin ? parseStdinConfig(cmd.meta.stdin) : void 0
602
+ }
603
+ };
604
+ if (cmd.commands && cmd.commands.length > 0) {
605
+ const visibleCommands = detail === "full" ? cmd.commands : cmd.commands.filter((c) => !c.hidden);
606
+ helpInfo.subcommands = [...cmd.action ? [{
607
+ name: "[default]",
608
+ title: cmd.title,
609
+ description: cmd.description
610
+ }] : [], ...visibleCommands.flatMap((c) => {
611
+ const isDefault = !c.name || c.aliases?.includes("");
612
+ const nonEmptyAliases = c.aliases?.filter(Boolean);
613
+ const displayName = c.name || nonEmptyAliases?.[0] || "[default]";
614
+ const remainingAliases = !c.name && nonEmptyAliases?.length ? nonEmptyAliases.slice(1) : nonEmptyAliases ?? [];
615
+ const displayAliases = isDefault && displayName !== "[default]" ? [...remainingAliases, "[default]"] : isDefault ? remainingAliases : nonEmptyAliases;
616
+ const hasSubcommands = !!(c.commands && c.commands.length > 0);
617
+ const hasDefaultHandler = c.action || c.commands?.some((sub) => !sub.name || sub.aliases?.includes(""));
618
+ if (hasSubcommands && hasDefaultHandler) {
619
+ const defaultSub = !c.action ? c.commands?.find((sub) => !sub.name || sub.aliases?.includes("")) : void 0;
620
+ const hasDefaultSubInfo = defaultSub && (defaultSub.title || defaultSub.description);
621
+ return [{
622
+ name: displayName,
623
+ title: hasDefaultSubInfo ? defaultSub.title : c.title,
624
+ description: hasDefaultSubInfo ? defaultSub.description : c.description,
625
+ aliases: displayAliases?.length ? displayAliases : void 0,
626
+ deprecated: c.deprecated,
627
+ hidden: c.hidden,
628
+ group: c.group
629
+ }, {
630
+ name: displayName,
631
+ title: c.title,
632
+ description: c.description,
633
+ deprecated: c.deprecated,
634
+ hidden: c.hidden,
635
+ hasSubcommands: true,
636
+ group: c.group
637
+ }];
638
+ }
639
+ return [{
640
+ name: displayName,
641
+ title: c.title,
642
+ description: c.description,
643
+ aliases: displayAliases?.length ? displayAliases : void 0,
644
+ deprecated: c.deprecated,
645
+ hidden: c.hidden,
646
+ hasSubcommands,
647
+ group: c.group
648
+ }];
649
+ })];
650
+ if (detail === "full") helpInfo.nestedCommands = visibleCommands.map((c) => getHelpInfo(c, "full"));
651
+ }
652
+ if (hasPositionals) helpInfo.positionals = positionalArgs;
653
+ if (cmd.argsSchema) {
654
+ const argsInfo = extractArgsInfo(cmd.argsSchema, cmd.meta, positionalNames);
655
+ const argMap = Object.fromEntries(argsInfo.map((arg) => [arg.name, arg]));
656
+ const { flags, aliases } = extractSchemaMetadata(cmd.argsSchema, cmd.meta?.fields, cmd.meta?.autoAlias);
657
+ for (const [flag, name] of Object.entries(flags)) {
658
+ const arg = argMap[name];
659
+ if (!arg) continue;
660
+ arg.flags = [...arg.flags || [], flag];
661
+ }
662
+ for (const [alias, name] of Object.entries(aliases)) {
663
+ const arg = argMap[name];
664
+ if (!arg) continue;
665
+ arg.aliases = [...arg.aliases || [], alias];
666
+ }
667
+ const visibleArgs = argsInfo.filter((arg) => !arg.hidden);
668
+ if (visibleArgs.length > 0) {
669
+ helpInfo.arguments = visibleArgs;
670
+ helpInfo.usage.hasArguments = true;
671
+ }
672
+ }
673
+ if (!cmd.parent || all) {
674
+ const builtins = [];
675
+ if (!findCommandByName("help", rootCmd.commands)) builtins.push({
676
+ name: "help [command], -h, --help",
677
+ description: "Show help for a command",
678
+ sub: [
679
+ {
680
+ name: "--all",
681
+ description: "Show all global commands and flags"
682
+ },
683
+ {
684
+ name: "--detail <level>",
685
+ description: "Detail level (minimal, standard, full)"
686
+ },
687
+ {
688
+ name: "--format <format>",
689
+ description: "Output format (text, ansi, json, markdown, html)"
690
+ }
691
+ ]
692
+ });
693
+ if (!findCommandByName("version", rootCmd.commands)) builtins.push({
694
+ name: "version, -v, --version",
695
+ description: "Show version information"
696
+ });
697
+ if (!findCommandByName("completion", rootCmd.commands)) builtins.push({
698
+ name: "completion [shell]",
699
+ description: "Generate shell completions (bash, zsh, fish, powershell)"
700
+ });
701
+ if (!findCommandByName("man", rootCmd.commands)) builtins.push({
702
+ name: "man",
703
+ description: "Show or install man pages (--setup to install, --remove to uninstall) (experimental)"
704
+ });
705
+ builtins.push({
706
+ name: "[command] --repl",
707
+ description: "Start interactive REPL scoped to a command"
708
+ });
709
+ if (!findCommandByName("mcp", rootCmd.commands)) builtins.push({
710
+ name: "mcp [http|stdio]",
711
+ description: "Start a Model Context Protocol server to expose commands as AI tools (experimental)",
712
+ sub: [{
713
+ name: "--port <port>",
714
+ description: "HTTP port (default: 3000)"
715
+ }, {
716
+ name: "--host <host>",
717
+ description: "HTTP host (default: 127.0.0.1)"
718
+ }]
719
+ });
720
+ builtins.push({
721
+ name: "--color [theme], --no-color",
722
+ description: "Set color theme (default, ocean, warm, monochrome) or disable colors"
723
+ });
724
+ if (builtins.length > 0) helpInfo.builtins = builtins;
725
+ }
726
+ return helpInfo;
727
+ }
728
+ function generateHelp(rootCommand, commandObj = rootCommand, prefs) {
729
+ const helpInfo = getHelpInfo(commandObj, prefs?.detail, prefs?.all);
730
+ return createFormatter(prefs?.format ?? "auto", prefs?.detail, prefs?.theme, prefs?.all).format(helpInfo);
731
+ }
732
+ //#endregion
733
+ export { getHelpInfo as n, colorThemes as r, generateHelp as t };
734
+
735
+ //# sourceMappingURL=help-bbmu9-qd.mjs.map