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.
- package/CHANGELOG.md +79 -0
- package/README.md +105 -284
- package/dist/{args-CVDbyyzG.mjs → args-D5PNDyNu.mjs} +41 -18
- package/dist/args-D5PNDyNu.mjs.map +1 -0
- package/dist/chunk-CjcI7cDX.mjs +15 -0
- package/dist/codegen/index.d.mts +28 -3
- package/dist/codegen/index.d.mts.map +1 -1
- package/dist/codegen/index.mjs +169 -19
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/command-utils-B1D-HqCd.mjs +1117 -0
- package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
- package/dist/completion.d.mts +1 -1
- package/dist/completion.d.mts.map +1 -1
- package/dist/completion.mjs +77 -29
- package/dist/completion.mjs.map +1 -1
- package/dist/docs/index.d.mts +22 -2
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +94 -7
- package/dist/docs/index.mjs.map +1 -1
- package/dist/errors-BiVrBgi6.mjs +114 -0
- package/dist/errors-BiVrBgi6.mjs.map +1 -0
- package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DtHzbP22.d.mts} +34 -5
- package/dist/formatter-DtHzbP22.d.mts.map +1 -0
- package/dist/help-bbmu9-qd.mjs +735 -0
- package/dist/help-bbmu9-qd.mjs.map +1 -0
- package/dist/index.d.mts +32 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +493 -265
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-mLWIdUIu.mjs +379 -0
- package/dist/mcp-mLWIdUIu.mjs.map +1 -0
- package/dist/serve-B0u43DK7.mjs +404 -0
- package/dist/serve-B0u43DK7.mjs.map +1 -0
- package/dist/stream-BcC146Ud.mjs +56 -0
- package/dist/stream-BcC146Ud.mjs.map +1 -0
- package/dist/test.d.mts +1 -1
- package/dist/test.mjs +4 -15
- package/dist/test.mjs.map +1 -1
- package/dist/{types-DjIdJN5G.d.mts → types-Ch8Mk6Qb.d.mts} +310 -62
- package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
- package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
- package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
- package/dist/zod.d.mts +32 -0
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +50 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +10 -2
- package/src/args.ts +68 -40
- package/src/cli/docs.ts +1 -7
- package/src/cli/doctor.ts +195 -10
- package/src/cli/index.ts +1 -1
- package/src/cli/init.ts +2 -3
- package/src/cli/link.ts +2 -2
- package/src/codegen/discovery.ts +80 -28
- package/src/codegen/index.ts +2 -1
- package/src/codegen/parsers/bash.ts +179 -0
- package/src/codegen/schema-to-code.ts +2 -1
- package/src/colorizer.ts +126 -13
- package/src/command-utils.ts +380 -30
- package/src/completion.ts +120 -47
- package/src/create.ts +480 -128
- package/src/docs/index.ts +122 -8
- package/src/formatter.ts +171 -125
- package/src/help.ts +45 -12
- package/src/index.ts +29 -1
- package/src/interactive.ts +45 -4
- package/src/mcp.ts +390 -0
- package/src/repl-loop.ts +16 -3
- package/src/runtime.ts +195 -2
- package/src/serve.ts +442 -0
- package/src/stream.ts +75 -0
- package/src/test.ts +7 -16
- package/src/type-utils.ts +28 -4
- package/src/types.ts +212 -30
- package/src/wrap.ts +23 -25
- package/src/zod.ts +50 -0
- package/dist/args-CVDbyyzG.mjs.map +0 -1
- package/dist/chunk-y_GBKt04.mjs +0 -5
- package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
- package/dist/help-CcBe91bV.mjs +0 -1254
- package/dist/help-CcBe91bV.mjs.map +0 -1
- package/dist/types-DjIdJN5G.d.mts.map +0 -1
package/dist/docs/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as __require } from "../chunk-CjcI7cDX.mjs";
|
|
2
|
+
import { n as getHelpInfo } from "../help-bbmu9-qd.mjs";
|
|
3
|
+
import { d as getCommand } from "../command-utils-B1D-HqCd.mjs";
|
|
2
4
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
5
|
import { dirname, join, resolve } from "node:path";
|
|
4
6
|
//#region src/docs/index.ts
|
|
@@ -122,6 +124,14 @@ function generateMarkdownPage(info, depth, frontmatterFn) {
|
|
|
122
124
|
lines.push(usageParts.join(" "));
|
|
123
125
|
lines.push("```");
|
|
124
126
|
lines.push("");
|
|
127
|
+
if (info.examples?.length) {
|
|
128
|
+
lines.push("## Examples");
|
|
129
|
+
lines.push("");
|
|
130
|
+
lines.push("```");
|
|
131
|
+
for (const ex of info.examples) lines.push(`$ ${ex}`);
|
|
132
|
+
lines.push("```");
|
|
133
|
+
lines.push("");
|
|
134
|
+
}
|
|
125
135
|
if (info.subcommands?.length) {
|
|
126
136
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
127
137
|
if (visibleSubs.length > 0) {
|
|
@@ -170,6 +180,10 @@ function generateHtmlPage(info, depth) {
|
|
|
170
180
|
if (info.usage.hasArguments) usageParts.push("[options]");
|
|
171
181
|
sections.push(" <h2>Usage</h2>");
|
|
172
182
|
sections.push(` <pre><code>${escapeHtml(usageParts.join(" "))}</code></pre>`);
|
|
183
|
+
if (info.examples?.length) {
|
|
184
|
+
sections.push(" <h2>Examples</h2>");
|
|
185
|
+
sections.push(` <pre><code>${info.examples.map((ex) => `$ ${escapeHtml(ex)}`).join("\n")}</code></pre>`);
|
|
186
|
+
}
|
|
173
187
|
if (info.subcommands?.length) {
|
|
174
188
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
175
189
|
if (visibleSubs.length > 0) {
|
|
@@ -249,6 +263,13 @@ function generateManPage(info, _depth, programName) {
|
|
|
249
263
|
lines.push(".SH DESCRIPTION");
|
|
250
264
|
lines.push(escapeMan(info.description));
|
|
251
265
|
}
|
|
266
|
+
if (info.examples?.length) {
|
|
267
|
+
lines.push(".SH EXAMPLES");
|
|
268
|
+
for (const ex of info.examples) {
|
|
269
|
+
lines.push(".PP");
|
|
270
|
+
lines.push(`.nf\n$ ${escapeMan(ex)}\n.fi`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
252
273
|
if (info.subcommands?.length) {
|
|
253
274
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
254
275
|
if (visibleSubs.length > 0) {
|
|
@@ -321,17 +342,13 @@ function generateMarkdownIndex(rootInfo, allInfos) {
|
|
|
321
342
|
}
|
|
322
343
|
return `${lines.join("\n").trimEnd()}\n`;
|
|
323
344
|
}
|
|
324
|
-
function resolveCommand(programOrCommand) {
|
|
325
|
-
if (commandSymbol in programOrCommand) return programOrCommand[commandSymbol];
|
|
326
|
-
return programOrCommand;
|
|
327
|
-
}
|
|
328
345
|
/**
|
|
329
346
|
* Generate documentation for a Padrone CLI program or command tree.
|
|
330
347
|
* Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.
|
|
331
348
|
*/
|
|
332
349
|
function generateDocs(program, options = {}) {
|
|
333
350
|
const { format = "markdown", output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;
|
|
334
|
-
const cmd =
|
|
351
|
+
const cmd = getCommand(program);
|
|
335
352
|
const allInfos = collectAllHelpInfo(cmd, includeHidden);
|
|
336
353
|
const rootInfo = allInfos[0];
|
|
337
354
|
const programName = cmd.name || "program";
|
|
@@ -399,7 +416,77 @@ function generateDocs(program, options = {}) {
|
|
|
399
416
|
}
|
|
400
417
|
return result;
|
|
401
418
|
}
|
|
419
|
+
/**
|
|
420
|
+
* Returns the local man page directory for the given section.
|
|
421
|
+
* Uses `~/.local/share/man/man<section>` (XDG convention).
|
|
422
|
+
*/
|
|
423
|
+
function getManPageDir(section = 1) {
|
|
424
|
+
const { homedir } = __require("node:os");
|
|
425
|
+
const { join: joinPath } = __require("node:path");
|
|
426
|
+
return joinPath(process.env.XDG_DATA_HOME || joinPath(homedir(), ".local", "share"), "man", `man${section}`);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Converts a command name to a man page filename.
|
|
430
|
+
* "myapp" → "myapp.1", "myapp deploy" → "myapp-deploy.1"
|
|
431
|
+
*/
|
|
432
|
+
function manPageFilename(commandName, section = 1) {
|
|
433
|
+
return `${commandName.replace(/\s+/g, "-")}.${section}`;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Installs man pages for a Padrone CLI program into the local man directory.
|
|
437
|
+
* Generates man pages for all commands and writes them to `~/.local/share/man/man1/`.
|
|
438
|
+
*
|
|
439
|
+
* After installation, `man <program>` and `man <program>-<subcommand>` should work
|
|
440
|
+
* (assuming `~/.local/share/man` is in `MANPATH` or `manpath` picks it up).
|
|
441
|
+
*/
|
|
442
|
+
function setupManPages(program) {
|
|
443
|
+
const cmd = getCommand(program);
|
|
444
|
+
const allInfos = collectAllHelpInfo(cmd, false);
|
|
445
|
+
const programName = cmd.name || "program";
|
|
446
|
+
const manDir = getManPageDir(1);
|
|
447
|
+
mkdirSync(manDir, { recursive: true });
|
|
448
|
+
const written = [];
|
|
449
|
+
let updated = false;
|
|
450
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
451
|
+
const info = allInfos[i];
|
|
452
|
+
const depth = i === 0 ? 0 : info.name.split(/\s+/).length;
|
|
453
|
+
const filename = manPageFilename(info.name === "<root>" || !info.name ? programName : info.name);
|
|
454
|
+
const fullPath = join(manDir, filename);
|
|
455
|
+
if (existsSync(fullPath)) updated = true;
|
|
456
|
+
writeFileSync(fullPath, generateManPage(info, depth, programName), "utf-8");
|
|
457
|
+
written.push(filename);
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
dir: manDir,
|
|
461
|
+
written,
|
|
462
|
+
updated
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Removes installed man pages for a Padrone CLI program.
|
|
467
|
+
*/
|
|
468
|
+
function removeManPages(program) {
|
|
469
|
+
const { unlinkSync } = __require("node:fs");
|
|
470
|
+
const cmd = getCommand(program);
|
|
471
|
+
const allInfos = collectAllHelpInfo(cmd, false);
|
|
472
|
+
const programName = cmd.name || "program";
|
|
473
|
+
const manDir = getManPageDir(1);
|
|
474
|
+
const removed = [];
|
|
475
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
476
|
+
const info = allInfos[i];
|
|
477
|
+
const filename = manPageFilename(info.name === "<root>" || !info.name ? programName : info.name);
|
|
478
|
+
const fullPath = join(manDir, filename);
|
|
479
|
+
if (existsSync(fullPath)) {
|
|
480
|
+
unlinkSync(fullPath);
|
|
481
|
+
removed.push(filename);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return {
|
|
485
|
+
dir: manDir,
|
|
486
|
+
removed
|
|
487
|
+
};
|
|
488
|
+
}
|
|
402
489
|
//#endregion
|
|
403
|
-
export { generateDocs };
|
|
490
|
+
export { generateDocs, removeManPages, setupManPages };
|
|
404
491
|
|
|
405
492
|
//# sourceMappingURL=index.mjs.map
|
package/dist/docs/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/docs/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { commandSymbol } from '../command-utils.ts';\nimport type { HelpArgumentInfo, HelpInfo, HelpPositionalInfo, HelpSubcommandInfo } from '../formatter.ts';\nimport { getHelpInfo } from '../help.ts';\nimport type { AnyPadroneCommand } from '../types.ts';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DocsFormat = 'markdown' | 'html' | 'man' | 'json';\n\nexport type DocsOptions = {\n /** Output format. Defaults to 'markdown'. */\n format?: DocsFormat;\n /** Output directory. If not set, docs are returned but not written. */\n output?: string;\n /** Include hidden commands and options. Defaults to false. */\n includeHidden?: boolean;\n /** Frontmatter generator for markdown files (VitePress, Starlight, etc.). */\n frontmatter?: (info: HelpInfo, depth: number) => Record<string, unknown>;\n /** Whether to overwrite existing files. Defaults to true. */\n overwrite?: boolean;\n /** Print what would be written without writing. */\n dryRun?: boolean;\n};\n\nexport type DocsPage = {\n /** File path relative to output directory (e.g., \"deploy.md\", \"index.md\"). */\n path: string;\n /** Generated content for this page. */\n content: string;\n /** The command name this page documents. */\n command: string;\n};\n\nexport type DocsResult = {\n /** All generated pages. */\n pages: DocsPage[];\n /** Files that were written (empty if no output dir). */\n written: string[];\n /** Files that were skipped (already exist, no overwrite). */\n skipped: string[];\n /** Files that failed to write. */\n errors: { file: string; error: Error }[];\n};\n\n// ============================================================================\n// Help Info Collection\n// ============================================================================\n\nfunction collectAllHelpInfo(cmd: AnyPadroneCommand, includeHidden: boolean): HelpInfo[] {\n const info = getHelpInfo(cmd, 'standard');\n const result: HelpInfo[] = [info];\n\n if (cmd.commands) {\n for (const sub of cmd.commands) {\n if (!includeHidden && sub.hidden) continue;\n result.push(...collectAllHelpInfo(sub, includeHidden));\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Markdown Generator\n// ============================================================================\n\nfunction generateFrontmatter(data: Record<string, unknown>): string {\n const lines: string[] = ['---'];\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === 'string') {\n lines.push(`${key}: \"${value.replace(/\"/g, '\\\\\"')}\"`);\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n lines.push(`${key}: ${value}`);\n } else if (Array.isArray(value)) {\n lines.push(`${key}:`);\n for (const item of value) {\n lines.push(` - \"${String(item).replace(/\"/g, '\\\\\"')}\"`);\n }\n }\n }\n lines.push('---');\n return lines.join('\\n');\n}\n\nfunction formatMarkdownPositional(arg: HelpPositionalInfo): string {\n const parts: string[] = [];\n parts.push(`- \\`${arg.name}\\``);\n if (arg.type) parts.push(`*(${arg.type})*`);\n if (arg.optional) parts.push('*(optional)*');\n if (arg.default !== undefined) parts.push(`— default: \\`${String(arg.default)}\\``);\n if (arg.description) parts.push(`— ${arg.description}`);\n return parts.join(' ');\n}\n\nfunction formatMarkdownArgument(arg: HelpArgumentInfo): string[] {\n const lines: string[] = [];\n\n const flagName = `--${arg.name}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `-${f}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `--${a}`).join(', ')}, ` : '';\n const header = `#### \\`${flagStr}${aliasStr}${flagName}\\``;\n lines.push(header);\n lines.push('');\n\n if (arg.description) {\n lines.push(arg.description);\n lines.push('');\n }\n\n const meta: string[] = [];\n if (arg.type && arg.type !== 'boolean') meta.push(`**Type:** \\`${arg.type}\\``);\n if (!arg.optional) meta.push('**Required**');\n if (arg.default !== undefined) meta.push(`**Default:** \\`${String(arg.default)}\\``);\n if (arg.enum) meta.push(`**Choices:** ${arg.enum.map((v) => `\\`${v}\\``).join(', ')}`);\n if (arg.variadic) meta.push('**Repeatable**');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? arg.deprecated : '';\n meta.push(`**Deprecated**${msg ? `: ${msg}` : ''}`);\n }\n\n if (meta.length > 0) {\n lines.push(meta.join(' | '));\n lines.push('');\n }\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`**Environment:** ${envVars.map((v) => `\\`${v}\\``).join(', ')}`);\n lines.push('');\n }\n\n if (arg.configKey) {\n lines.push(`**Config key:** \\`${arg.configKey}\\``);\n lines.push('');\n }\n\n if (arg.examples?.length) {\n lines.push(`**Examples:** ${arg.examples.map((e) => `\\`${typeof e === 'string' ? e : JSON.stringify(e)}\\``).join(', ')}`);\n lines.push('');\n }\n\n return lines;\n}\n\nfunction formatMarkdownSubcommand(sub: HelpSubcommandInfo): string {\n const parts: string[] = [];\n const suffix = sub.hasSubcommands ? ' ...' : '';\n parts.push(`| \\`${sub.name}${suffix}\\``);\n\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n parts.push(`| ${aliases?.length ? aliases.map((a) => `\\`${a}\\``).join(', ') : ''}`);\n\n const desc = sub.title ?? sub.description ?? '';\n parts.push(`| ${desc}`);\n parts.push('|');\n\n return parts.join(' ');\n}\n\nfunction generateMarkdownPage(info: HelpInfo, depth: number, frontmatterFn?: DocsOptions['frontmatter']): string {\n const lines: string[] = [];\n\n if (frontmatterFn) {\n const fm = frontmatterFn(info, depth);\n if (Object.keys(fm).length > 0) {\n lines.push(generateFrontmatter(fm));\n lines.push('');\n }\n }\n\n // Title\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : info.name;\n lines.push(`# ${displayName}`);\n lines.push('');\n\n // Deprecation warning\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? info.deprecated : 'This command is deprecated.';\n lines.push(`> **Deprecated:** ${msg}`);\n lines.push('');\n }\n\n // Description\n if (info.title) {\n lines.push(`> ${info.title}`);\n lines.push('');\n }\n if (info.description) {\n lines.push(info.description);\n lines.push('');\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n lines.push(`**Aliases:** ${realAliases.map((a) => `\\`${a}\\``).join(', ')}`);\n lines.push('');\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n lines.push('## Usage');\n lines.push('');\n lines.push('```');\n lines.push(usageParts.join(' '));\n lines.push('```');\n lines.push('');\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('## Commands');\n lines.push('');\n lines.push('| Command | Aliases | Description |');\n lines.push('| --- | --- | --- |');\n for (const sub of visibleSubs) {\n lines.push(formatMarkdownSubcommand(sub));\n }\n lines.push('');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n lines.push('## Arguments');\n lines.push('');\n for (const arg of info.positionals) {\n lines.push(formatMarkdownPositional(arg));\n }\n lines.push('');\n }\n\n // Options\n if (info.arguments?.length) {\n lines.push('## Options');\n lines.push('');\n for (const arg of info.arguments) {\n lines.push(...formatMarkdownArgument(arg));\n }\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// HTML Generator\n// ============================================================================\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction generateHtmlPage(info: HelpInfo, depth: number): string {\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : escapeHtml(info.name);\n\n const sections: string[] = [];\n\n // Header\n sections.push(`<article class=\"padrone-docs-page\" data-command=\"${escapeHtml(info.name)}\" data-depth=\"${depth}\">`);\n sections.push(` <h1>${displayName}</h1>`);\n\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? escapeHtml(info.deprecated) : 'This command is deprecated.';\n sections.push(` <div class=\"deprecated-warning\"><strong>Deprecated:</strong> ${msg}</div>`);\n }\n\n if (info.title) {\n sections.push(` <p class=\"command-title\">${escapeHtml(info.title)}</p>`);\n }\n if (info.description) {\n sections.push(` <p class=\"command-description\">${escapeHtml(info.description)}</p>`);\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n sections.push(` <p><strong>Aliases:</strong> ${realAliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ')}</p>`);\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n sections.push(' <h2>Usage</h2>');\n sections.push(` <pre><code>${escapeHtml(usageParts.join(' '))}</code></pre>`);\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n sections.push(' <h2>Commands</h2>');\n sections.push(' <table>');\n sections.push(' <thead><tr><th>Command</th><th>Aliases</th><th>Description</th></tr></thead>');\n sections.push(' <tbody>');\n for (const sub of visibleSubs) {\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n const desc = sub.title ?? sub.description ?? '';\n const suffix = sub.hasSubcommands ? ' ...' : '';\n sections.push(\n ` <tr><td><code>${escapeHtml(sub.name + suffix)}</code></td><td>${aliases?.length ? aliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ') : ''}</td><td>${escapeHtml(desc)}</td></tr>`,\n );\n }\n sections.push(' </tbody>');\n sections.push(' </table>');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n sections.push(' <h2>Arguments</h2>');\n sections.push(' <dl>');\n for (const arg of info.positionals) {\n sections.push(\n ` <dt><code>${escapeHtml(arg.name)}</code>${arg.type ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : ''}${arg.optional ? ' <em>(optional)</em>' : ''}</dt>`,\n );\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n if (arg.default !== undefined) sections.push(` <dd>Default: <code>${escapeHtml(String(arg.default))}</code></dd>`);\n }\n sections.push(' </dl>');\n }\n\n // Options\n if (info.arguments?.length) {\n sections.push(' <h2>Options</h2>');\n sections.push(' <dl>');\n for (const arg of info.arguments) {\n const flagName = `--${arg.name}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `-${f}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `--${a}`).join(', ')}, ` : '';\n const typeSpan = arg.type && arg.type !== 'boolean' ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : '';\n sections.push(` <dt><code>${escapeHtml(flagStr + aliasStr + flagName)}</code>${typeSpan}</dt>`);\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n\n const meta: string[] = [];\n if (!arg.optional) meta.push('Required');\n if (arg.default !== undefined) meta.push(`Default: <code>${escapeHtml(String(arg.default))}</code>`);\n if (arg.enum) meta.push(`Choices: ${arg.enum.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}`);\n if (arg.variadic) meta.push('Repeatable');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? escapeHtml(arg.deprecated) : '';\n meta.push(`Deprecated${msg ? `: ${msg}` : ''}`);\n }\n if (meta.length > 0) sections.push(` <dd class=\"meta\">${meta.join(' · ')}</dd>`);\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n sections.push(` <dd>Environment: ${envVars.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}</dd>`);\n }\n if (arg.configKey) {\n sections.push(` <dd>Config key: <code>${escapeHtml(arg.configKey)}</code></dd>`);\n }\n }\n sections.push(' </dl>');\n }\n\n sections.push('</article>');\n return `${sections.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Man Page Generator\n// ============================================================================\n\nfunction escapeMan(text: string): string {\n return text.replace(/\\\\/g, '\\\\\\\\').replace(/-/g, '\\\\-').replace(/'/g, '\\\\(aq');\n}\n\nfunction generateManPage(info: HelpInfo, _depth: number, programName: string): string {\n const commandName = info.name === '<root>' || !info.name ? programName : info.name;\n const manName = commandName.replace(/\\s+/g, '-');\n const lines: string[] = [];\n\n lines.push(`.TH \"${escapeMan(manName.toUpperCase())}\" \"1\" \"\" \"\" \"\"`);\n\n // NAME\n lines.push('.SH NAME');\n const desc = info.title ?? info.description ?? '';\n lines.push(`${escapeMan(manName)}${desc ? ` \\\\- ${escapeMan(desc)}` : ''}`);\n\n // SYNOPSIS\n lines.push('.SH SYNOPSIS');\n const usageParts: string[] = [`\\\\fB${escapeMan(commandName)}\\\\fR`];\n if (info.usage.hasSubcommands) usageParts.push('[\\\\fIcommand\\\\fR]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[\\\\fI${escapeMan(arg.name)}\\\\fR]` : `\\\\fI${escapeMan(arg.name)}\\\\fR`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[\\\\fIoptions\\\\fR]');\n lines.push(usageParts.join(' '));\n\n // DESCRIPTION\n if (info.description) {\n lines.push('.SH DESCRIPTION');\n lines.push(escapeMan(info.description));\n }\n\n // COMMANDS\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('.SH COMMANDS');\n for (const sub of visibleSubs) {\n const suffix = sub.hasSubcommands ? ' ...' : '';\n lines.push(`.TP`);\n lines.push(`\\\\fB${escapeMan(sub.name + suffix)}\\\\fR`);\n const subDesc = sub.title ?? sub.description;\n if (subDesc) lines.push(escapeMan(subDesc));\n }\n }\n }\n\n // ARGUMENTS\n if (info.positionals?.length) {\n lines.push('.SH ARGUMENTS');\n for (const arg of info.positionals) {\n lines.push('.TP');\n lines.push(`\\\\fI${escapeMan(arg.name)}\\\\fR`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.optional) parts.push('(optional)');\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n }\n }\n\n // OPTIONS\n if (info.arguments?.length) {\n lines.push('.SH OPTIONS');\n for (const arg of info.arguments) {\n const flagName = `\\\\-\\\\-${escapeMan(arg.name)}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `\\\\-${escapeMan(f)}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `\\\\-\\\\-${escapeMan(a)}`).join(', ')}, ` : '';\n lines.push('.TP');\n lines.push(`\\\\fB${flagStr}${aliasStr}${flagName}\\\\fR${arg.type ? ` \\\\fI${escapeMan(arg.type)}\\\\fR` : ''}`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (arg.enum) parts.push(`Choices: ${arg.enum.map((v) => escapeMan(v)).join(', ')}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`.br`);\n lines.push(`Environment: ${envVars.map((v) => escapeMan(v)).join(', ')}`);\n }\n }\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Page Path Helpers\n// ============================================================================\n\nfunction commandToPath(info: HelpInfo, ext: string, isRoot: boolean): string {\n if (isRoot) return `index${ext}`;\n // Split on whitespace and replace empty segments (from empty-name default commands) with \"_default\"\n const segments = info.name.split(/\\s+/).map((s) => s || '_default');\n return segments.join('/') + ext;\n}\n\n// ============================================================================\n// Index Page Generators\n// ============================================================================\n\nfunction generateMarkdownIndex(rootInfo: HelpInfo, allInfos: HelpInfo[]): string {\n const lines: string[] = [];\n lines.push(`# ${rootInfo.title ?? rootInfo.name ?? 'CLI'} Reference`);\n lines.push('');\n\n if (rootInfo.description) {\n lines.push(rootInfo.description);\n lines.push('');\n }\n\n if (allInfos.length > 1) {\n lines.push('## Commands');\n lines.push('');\n for (const info of allInfos) {\n const path = commandToPath(info, '.md', info === rootInfo);\n const name = info === rootInfo ? info.name || 'root' : info.name;\n const desc = info.title ?? info.description ?? '';\n lines.push(`- [${name}](${path})${desc ? ` — ${desc}` : ''}`);\n }\n lines.push('');\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\nfunction resolveCommand(programOrCommand: object): AnyPadroneCommand {\n if (commandSymbol in programOrCommand) return (programOrCommand as any)[commandSymbol] as AnyPadroneCommand;\n return programOrCommand as AnyPadroneCommand;\n}\n\n/**\n * Generate documentation for a Padrone CLI program or command tree.\n * Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.\n */\nexport function generateDocs(program: object, options: DocsOptions = {}): DocsResult {\n const { format = 'markdown', output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;\n\n const cmd = resolveCommand(program);\n const allInfos = collectAllHelpInfo(cmd, includeHidden);\n const rootInfo = allInfos[0]!;\n const programName = cmd.name || 'program';\n\n const pages: DocsPage[] = [];\n\n const ext = format === 'markdown' ? '.md' : format === 'html' ? '.html' : format === 'man' ? '.1' : '.json';\n\n for (let i = 0; i < allInfos.length; i++) {\n const info = allInfos[i]!;\n const isRoot = i === 0;\n const depth = isRoot ? 0 : info.name.split(/\\s+/).length;\n const path = commandToPath(info, ext, isRoot);\n\n let content: string;\n switch (format) {\n case 'markdown':\n content = generateMarkdownPage(info, depth, frontmatter);\n break;\n case 'html':\n content = generateHtmlPage(info, depth);\n break;\n case 'man':\n content = generateManPage(info, depth, programName);\n break;\n case 'json':\n content = `${JSON.stringify(info, null, 2)}\\n`;\n break;\n }\n\n pages.push({ path, content, command: info.name });\n }\n\n // Generate index page for markdown (when there are subcommands)\n if (format === 'markdown' && allInfos.length > 1) {\n // Replace the root page with a combined index\n const rootPage = pages[0]!;\n rootPage.content = generateMarkdownIndex(rootInfo, allInfos);\n }\n\n const result: DocsResult = { pages, written: [], skipped: [], errors: [] };\n\n // Write to disk if output dir specified\n if (output) {\n const outDir = resolve(output);\n\n for (const page of pages) {\n const fullPath = join(outDir, page.path);\n\n try {\n if (existsSync(fullPath) && !overwrite) {\n result.skipped.push(page.path);\n continue;\n }\n\n if (dryRun) {\n result.written.push(page.path);\n continue;\n }\n\n const dir = dirname(fullPath);\n mkdirSync(dir, { recursive: true });\n writeFileSync(fullPath, page.content, 'utf-8');\n result.written.push(page.path);\n } catch (err) {\n result.errors.push({\n file: page.path,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/docs/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { getCommand } from '../command-utils.ts';\nimport type { HelpArgumentInfo, HelpInfo, HelpPositionalInfo, HelpSubcommandInfo } from '../formatter.ts';\nimport { getHelpInfo } from '../help.ts';\nimport type { AnyPadroneCommand } from '../types.ts';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type DocsFormat = 'markdown' | 'html' | 'man' | 'json';\n\nexport type DocsOptions = {\n /** Output format. Defaults to 'markdown'. */\n format?: DocsFormat;\n /** Output directory. If not set, docs are returned but not written. */\n output?: string;\n /** Include hidden commands and options. Defaults to false. */\n includeHidden?: boolean;\n /** Frontmatter generator for markdown files (VitePress, Starlight, etc.). */\n frontmatter?: (info: HelpInfo, depth: number) => Record<string, unknown>;\n /** Whether to overwrite existing files. Defaults to true. */\n overwrite?: boolean;\n /** Print what would be written without writing. */\n dryRun?: boolean;\n};\n\nexport type DocsPage = {\n /** File path relative to output directory (e.g., \"deploy.md\", \"index.md\"). */\n path: string;\n /** Generated content for this page. */\n content: string;\n /** The command name this page documents. */\n command: string;\n};\n\nexport type DocsResult = {\n /** All generated pages. */\n pages: DocsPage[];\n /** Files that were written (empty if no output dir). */\n written: string[];\n /** Files that were skipped (already exist, no overwrite). */\n skipped: string[];\n /** Files that failed to write. */\n errors: { file: string; error: Error }[];\n};\n\n// ============================================================================\n// Help Info Collection\n// ============================================================================\n\nfunction collectAllHelpInfo(cmd: AnyPadroneCommand, includeHidden: boolean): HelpInfo[] {\n const info = getHelpInfo(cmd, 'standard');\n const result: HelpInfo[] = [info];\n\n if (cmd.commands) {\n for (const sub of cmd.commands) {\n if (!includeHidden && sub.hidden) continue;\n result.push(...collectAllHelpInfo(sub, includeHidden));\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Markdown Generator\n// ============================================================================\n\nfunction generateFrontmatter(data: Record<string, unknown>): string {\n const lines: string[] = ['---'];\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === 'string') {\n lines.push(`${key}: \"${value.replace(/\"/g, '\\\\\"')}\"`);\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n lines.push(`${key}: ${value}`);\n } else if (Array.isArray(value)) {\n lines.push(`${key}:`);\n for (const item of value) {\n lines.push(` - \"${String(item).replace(/\"/g, '\\\\\"')}\"`);\n }\n }\n }\n lines.push('---');\n return lines.join('\\n');\n}\n\nfunction formatMarkdownPositional(arg: HelpPositionalInfo): string {\n const parts: string[] = [];\n parts.push(`- \\`${arg.name}\\``);\n if (arg.type) parts.push(`*(${arg.type})*`);\n if (arg.optional) parts.push('*(optional)*');\n if (arg.default !== undefined) parts.push(`— default: \\`${String(arg.default)}\\``);\n if (arg.description) parts.push(`— ${arg.description}`);\n return parts.join(' ');\n}\n\nfunction formatMarkdownArgument(arg: HelpArgumentInfo): string[] {\n const lines: string[] = [];\n\n const flagName = `--${arg.name}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `-${f}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `--${a}`).join(', ')}, ` : '';\n const header = `#### \\`${flagStr}${aliasStr}${flagName}\\``;\n lines.push(header);\n lines.push('');\n\n if (arg.description) {\n lines.push(arg.description);\n lines.push('');\n }\n\n const meta: string[] = [];\n if (arg.type && arg.type !== 'boolean') meta.push(`**Type:** \\`${arg.type}\\``);\n if (!arg.optional) meta.push('**Required**');\n if (arg.default !== undefined) meta.push(`**Default:** \\`${String(arg.default)}\\``);\n if (arg.enum) meta.push(`**Choices:** ${arg.enum.map((v) => `\\`${v}\\``).join(', ')}`);\n if (arg.variadic) meta.push('**Repeatable**');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? arg.deprecated : '';\n meta.push(`**Deprecated**${msg ? `: ${msg}` : ''}`);\n }\n\n if (meta.length > 0) {\n lines.push(meta.join(' | '));\n lines.push('');\n }\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`**Environment:** ${envVars.map((v) => `\\`${v}\\``).join(', ')}`);\n lines.push('');\n }\n\n if (arg.configKey) {\n lines.push(`**Config key:** \\`${arg.configKey}\\``);\n lines.push('');\n }\n\n if (arg.examples?.length) {\n lines.push(`**Examples:** ${arg.examples.map((e) => `\\`${typeof e === 'string' ? e : JSON.stringify(e)}\\``).join(', ')}`);\n lines.push('');\n }\n\n return lines;\n}\n\nfunction formatMarkdownSubcommand(sub: HelpSubcommandInfo): string {\n const parts: string[] = [];\n const suffix = sub.hasSubcommands ? ' ...' : '';\n parts.push(`| \\`${sub.name}${suffix}\\``);\n\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n parts.push(`| ${aliases?.length ? aliases.map((a) => `\\`${a}\\``).join(', ') : ''}`);\n\n const desc = sub.title ?? sub.description ?? '';\n parts.push(`| ${desc}`);\n parts.push('|');\n\n return parts.join(' ');\n}\n\nfunction generateMarkdownPage(info: HelpInfo, depth: number, frontmatterFn?: DocsOptions['frontmatter']): string {\n const lines: string[] = [];\n\n if (frontmatterFn) {\n const fm = frontmatterFn(info, depth);\n if (Object.keys(fm).length > 0) {\n lines.push(generateFrontmatter(fm));\n lines.push('');\n }\n }\n\n // Title\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : info.name;\n lines.push(`# ${displayName}`);\n lines.push('');\n\n // Deprecation warning\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? info.deprecated : 'This command is deprecated.';\n lines.push(`> **Deprecated:** ${msg}`);\n lines.push('');\n }\n\n // Description\n if (info.title) {\n lines.push(`> ${info.title}`);\n lines.push('');\n }\n if (info.description) {\n lines.push(info.description);\n lines.push('');\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n lines.push(`**Aliases:** ${realAliases.map((a) => `\\`${a}\\``).join(', ')}`);\n lines.push('');\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n lines.push('## Usage');\n lines.push('');\n lines.push('```');\n lines.push(usageParts.join(' '));\n lines.push('```');\n lines.push('');\n\n // Examples\n if (info.examples?.length) {\n lines.push('## Examples');\n lines.push('');\n lines.push('```');\n for (const ex of info.examples) {\n lines.push(`$ ${ex}`);\n }\n lines.push('```');\n lines.push('');\n }\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('## Commands');\n lines.push('');\n lines.push('| Command | Aliases | Description |');\n lines.push('| --- | --- | --- |');\n for (const sub of visibleSubs) {\n lines.push(formatMarkdownSubcommand(sub));\n }\n lines.push('');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n lines.push('## Arguments');\n lines.push('');\n for (const arg of info.positionals) {\n lines.push(formatMarkdownPositional(arg));\n }\n lines.push('');\n }\n\n // Options\n if (info.arguments?.length) {\n lines.push('## Options');\n lines.push('');\n for (const arg of info.arguments) {\n lines.push(...formatMarkdownArgument(arg));\n }\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// HTML Generator\n// ============================================================================\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction generateHtmlPage(info: HelpInfo, depth: number): string {\n const displayName = info.name === '<root>' || !info.name ? 'CLI Reference' : escapeHtml(info.name);\n\n const sections: string[] = [];\n\n // Header\n sections.push(`<article class=\"padrone-docs-page\" data-command=\"${escapeHtml(info.name)}\" data-depth=\"${depth}\">`);\n sections.push(` <h1>${displayName}</h1>`);\n\n if (info.deprecated) {\n const msg = typeof info.deprecated === 'string' ? escapeHtml(info.deprecated) : 'This command is deprecated.';\n sections.push(` <div class=\"deprecated-warning\"><strong>Deprecated:</strong> ${msg}</div>`);\n }\n\n if (info.title) {\n sections.push(` <p class=\"command-title\">${escapeHtml(info.title)}</p>`);\n }\n if (info.description) {\n sections.push(` <p class=\"command-description\">${escapeHtml(info.description)}</p>`);\n }\n\n // Aliases\n if (info.aliases?.length) {\n const realAliases = info.aliases.filter((a) => a !== '[default]');\n if (realAliases.length > 0) {\n sections.push(` <p><strong>Aliases:</strong> ${realAliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ')}</p>`);\n }\n }\n\n // Usage\n const usageParts: string[] = [info.usage.command];\n if (info.usage.hasSubcommands) usageParts.push('[command]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[${arg.name}]` : `<${arg.name}>`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[options]');\n\n sections.push(' <h2>Usage</h2>');\n sections.push(` <pre><code>${escapeHtml(usageParts.join(' '))}</code></pre>`);\n\n // Examples\n if (info.examples?.length) {\n sections.push(' <h2>Examples</h2>');\n sections.push(` <pre><code>${info.examples.map((ex) => `$ ${escapeHtml(ex)}`).join('\\n')}</code></pre>`);\n }\n\n // Subcommands\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n sections.push(' <h2>Commands</h2>');\n sections.push(' <table>');\n sections.push(' <thead><tr><th>Command</th><th>Aliases</th><th>Description</th></tr></thead>');\n sections.push(' <tbody>');\n for (const sub of visibleSubs) {\n const aliases = sub.aliases?.filter((a) => a !== '[default]');\n const desc = sub.title ?? sub.description ?? '';\n const suffix = sub.hasSubcommands ? ' ...' : '';\n sections.push(\n ` <tr><td><code>${escapeHtml(sub.name + suffix)}</code></td><td>${aliases?.length ? aliases.map((a) => `<code>${escapeHtml(a)}</code>`).join(', ') : ''}</td><td>${escapeHtml(desc)}</td></tr>`,\n );\n }\n sections.push(' </tbody>');\n sections.push(' </table>');\n }\n }\n\n // Positional arguments\n if (info.positionals?.length) {\n sections.push(' <h2>Arguments</h2>');\n sections.push(' <dl>');\n for (const arg of info.positionals) {\n sections.push(\n ` <dt><code>${escapeHtml(arg.name)}</code>${arg.type ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : ''}${arg.optional ? ' <em>(optional)</em>' : ''}</dt>`,\n );\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n if (arg.default !== undefined) sections.push(` <dd>Default: <code>${escapeHtml(String(arg.default))}</code></dd>`);\n }\n sections.push(' </dl>');\n }\n\n // Options\n if (info.arguments?.length) {\n sections.push(' <h2>Options</h2>');\n sections.push(' <dl>');\n for (const arg of info.arguments) {\n const flagName = `--${arg.name}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `-${f}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `--${a}`).join(', ')}, ` : '';\n const typeSpan = arg.type && arg.type !== 'boolean' ? ` <span class=\"type\">${escapeHtml(arg.type)}</span>` : '';\n sections.push(` <dt><code>${escapeHtml(flagStr + aliasStr + flagName)}</code>${typeSpan}</dt>`);\n if (arg.description) sections.push(` <dd>${escapeHtml(arg.description)}</dd>`);\n\n const meta: string[] = [];\n if (!arg.optional) meta.push('Required');\n if (arg.default !== undefined) meta.push(`Default: <code>${escapeHtml(String(arg.default))}</code>`);\n if (arg.enum) meta.push(`Choices: ${arg.enum.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}`);\n if (arg.variadic) meta.push('Repeatable');\n if (arg.deprecated) {\n const msg = typeof arg.deprecated === 'string' ? escapeHtml(arg.deprecated) : '';\n meta.push(`Deprecated${msg ? `: ${msg}` : ''}`);\n }\n if (meta.length > 0) sections.push(` <dd class=\"meta\">${meta.join(' · ')}</dd>`);\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n sections.push(` <dd>Environment: ${envVars.map((v) => `<code>${escapeHtml(v)}</code>`).join(', ')}</dd>`);\n }\n if (arg.configKey) {\n sections.push(` <dd>Config key: <code>${escapeHtml(arg.configKey)}</code></dd>`);\n }\n }\n sections.push(' </dl>');\n }\n\n sections.push('</article>');\n return `${sections.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Man Page Generator (experimental)\n// ============================================================================\n\nfunction escapeMan(text: string): string {\n return text.replace(/\\\\/g, '\\\\\\\\').replace(/-/g, '\\\\-').replace(/'/g, '\\\\(aq');\n}\n\nfunction generateManPage(info: HelpInfo, _depth: number, programName: string): string {\n const commandName = info.name === '<root>' || !info.name ? programName : info.name;\n const manName = commandName.replace(/\\s+/g, '-');\n const lines: string[] = [];\n\n lines.push(`.TH \"${escapeMan(manName.toUpperCase())}\" \"1\" \"\" \"\" \"\"`);\n\n // NAME\n lines.push('.SH NAME');\n const desc = info.title ?? info.description ?? '';\n lines.push(`${escapeMan(manName)}${desc ? ` \\\\- ${escapeMan(desc)}` : ''}`);\n\n // SYNOPSIS\n lines.push('.SH SYNOPSIS');\n const usageParts: string[] = [`\\\\fB${escapeMan(commandName)}\\\\fR`];\n if (info.usage.hasSubcommands) usageParts.push('[\\\\fIcommand\\\\fR]');\n if (info.positionals?.length) {\n for (const arg of info.positionals) {\n usageParts.push(arg.optional ? `[\\\\fI${escapeMan(arg.name)}\\\\fR]` : `\\\\fI${escapeMan(arg.name)}\\\\fR`);\n }\n }\n if (info.usage.hasArguments) usageParts.push('[\\\\fIoptions\\\\fR]');\n lines.push(usageParts.join(' '));\n\n // DESCRIPTION\n if (info.description) {\n lines.push('.SH DESCRIPTION');\n lines.push(escapeMan(info.description));\n }\n\n // EXAMPLES\n if (info.examples?.length) {\n lines.push('.SH EXAMPLES');\n for (const ex of info.examples) {\n lines.push('.PP');\n lines.push(`.nf\\n$ ${escapeMan(ex)}\\n.fi`);\n }\n }\n\n // COMMANDS\n if (info.subcommands?.length) {\n const visibleSubs = info.subcommands.filter((s) => !s.hidden);\n if (visibleSubs.length > 0) {\n lines.push('.SH COMMANDS');\n for (const sub of visibleSubs) {\n const suffix = sub.hasSubcommands ? ' ...' : '';\n lines.push(`.TP`);\n lines.push(`\\\\fB${escapeMan(sub.name + suffix)}\\\\fR`);\n const subDesc = sub.title ?? sub.description;\n if (subDesc) lines.push(escapeMan(subDesc));\n }\n }\n }\n\n // ARGUMENTS\n if (info.positionals?.length) {\n lines.push('.SH ARGUMENTS');\n for (const arg of info.positionals) {\n lines.push('.TP');\n lines.push(`\\\\fI${escapeMan(arg.name)}\\\\fR`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.optional) parts.push('(optional)');\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n }\n }\n\n // OPTIONS\n if (info.arguments?.length) {\n lines.push('.SH OPTIONS');\n for (const arg of info.arguments) {\n const flagName = `\\\\-\\\\-${escapeMan(arg.name)}`;\n const flagStr = arg.flags?.length ? `${arg.flags.map((f) => `\\\\-${escapeMan(f)}`).join(', ')}, ` : '';\n const aliasStr = arg.aliases?.length ? `${arg.aliases.map((a) => `\\\\-\\\\-${escapeMan(a)}`).join(', ')}, ` : '';\n lines.push('.TP');\n lines.push(`\\\\fB${flagStr}${aliasStr}${flagName}\\\\fR${arg.type ? ` \\\\fI${escapeMan(arg.type)}\\\\fR` : ''}`);\n const parts: string[] = [];\n if (arg.description) parts.push(escapeMan(arg.description));\n if (arg.default !== undefined) parts.push(`Default: ${escapeMan(String(arg.default))}`);\n if (arg.enum) parts.push(`Choices: ${arg.enum.map((v) => escapeMan(v)).join(', ')}`);\n if (parts.length > 0) lines.push(parts.join('. '));\n\n if (arg.env) {\n const envVars = typeof arg.env === 'string' ? [arg.env] : arg.env;\n lines.push(`.br`);\n lines.push(`Environment: ${envVars.map((v) => escapeMan(v)).join(', ')}`);\n }\n }\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n\n// ============================================================================\n// Page Path Helpers\n// ============================================================================\n\nfunction commandToPath(info: HelpInfo, ext: string, isRoot: boolean): string {\n if (isRoot) return `index${ext}`;\n // Split on whitespace and replace empty segments (from empty-name default commands) with \"_default\"\n const segments = info.name.split(/\\s+/).map((s) => s || '_default');\n return segments.join('/') + ext;\n}\n\n// ============================================================================\n// Index Page Generators\n// ============================================================================\n\nfunction generateMarkdownIndex(rootInfo: HelpInfo, allInfos: HelpInfo[]): string {\n const lines: string[] = [];\n lines.push(`# ${rootInfo.title ?? rootInfo.name ?? 'CLI'} Reference`);\n lines.push('');\n\n if (rootInfo.description) {\n lines.push(rootInfo.description);\n lines.push('');\n }\n\n if (allInfos.length > 1) {\n lines.push('## Commands');\n lines.push('');\n for (const info of allInfos) {\n const path = commandToPath(info, '.md', info === rootInfo);\n const name = info === rootInfo ? info.name || 'root' : info.name;\n const desc = info.title ?? info.description ?? '';\n lines.push(`- [${name}](${path})${desc ? ` — ${desc}` : ''}`);\n }\n lines.push('');\n }\n\n return `${lines.join('\\n').trimEnd()}\\n`;\n}\n\n// ============================================================================\n// Main Entry Point\n// ============================================================================\n\n/**\n * Generate documentation for a Padrone CLI program or command tree.\n * Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.\n */\nexport function generateDocs(program: object, options: DocsOptions = {}): DocsResult {\n const { format = 'markdown', output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;\n\n const cmd = getCommand(program);\n const allInfos = collectAllHelpInfo(cmd, includeHidden);\n const rootInfo = allInfos[0]!;\n const programName = cmd.name || 'program';\n\n const pages: DocsPage[] = [];\n\n const ext = format === 'markdown' ? '.md' : format === 'html' ? '.html' : format === 'man' ? '.1' : '.json';\n\n for (let i = 0; i < allInfos.length; i++) {\n const info = allInfos[i]!;\n const isRoot = i === 0;\n const depth = isRoot ? 0 : info.name.split(/\\s+/).length;\n const path = commandToPath(info, ext, isRoot);\n\n let content: string;\n switch (format) {\n case 'markdown':\n content = generateMarkdownPage(info, depth, frontmatter);\n break;\n case 'html':\n content = generateHtmlPage(info, depth);\n break;\n case 'man':\n content = generateManPage(info, depth, programName);\n break;\n case 'json':\n content = `${JSON.stringify(info, null, 2)}\\n`;\n break;\n }\n\n pages.push({ path, content, command: info.name });\n }\n\n // Generate index page for markdown (when there are subcommands)\n if (format === 'markdown' && allInfos.length > 1) {\n // Replace the root page with a combined index\n const rootPage = pages[0]!;\n rootPage.content = generateMarkdownIndex(rootInfo, allInfos);\n }\n\n const result: DocsResult = { pages, written: [], skipped: [], errors: [] };\n\n // Write to disk if output dir specified\n if (output) {\n const outDir = resolve(output);\n\n for (const page of pages) {\n const fullPath = join(outDir, page.path);\n\n try {\n if (existsSync(fullPath) && !overwrite) {\n result.skipped.push(page.path);\n continue;\n }\n\n if (dryRun) {\n result.written.push(page.path);\n continue;\n }\n\n const dir = dirname(fullPath);\n mkdirSync(dir, { recursive: true });\n writeFileSync(fullPath, page.content, 'utf-8');\n result.written.push(page.path);\n } catch (err) {\n result.errors.push({\n file: page.path,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n }\n }\n\n return result;\n}\n\n// ============================================================================\n// Man Page Installation\n// ============================================================================\n\nexport type SetupManPagesResult = {\n /** Directory where man pages were written. */\n dir: string;\n /** Man page files that were written. */\n written: string[];\n /** Whether existing pages were overwritten (true) or newly created (false). */\n updated: boolean;\n};\n\n/**\n * Returns the local man page directory for the given section.\n * Uses `~/.local/share/man/man<section>` (XDG convention).\n */\nfunction getManPageDir(section = 1): string {\n const { homedir } = require('node:os') as typeof import('node:os');\n const { join: joinPath } = require('node:path') as typeof import('node:path');\n return joinPath(process.env.XDG_DATA_HOME || joinPath(homedir(), '.local', 'share'), 'man', `man${section}`);\n}\n\n/**\n * Converts a command name to a man page filename.\n * \"myapp\" → \"myapp.1\", \"myapp deploy\" → \"myapp-deploy.1\"\n */\nfunction manPageFilename(commandName: string, section = 1): string {\n return `${commandName.replace(/\\s+/g, '-')}.${section}`;\n}\n\n/**\n * Installs man pages for a Padrone CLI program into the local man directory.\n * Generates man pages for all commands and writes them to `~/.local/share/man/man1/`.\n *\n * After installation, `man <program>` and `man <program>-<subcommand>` should work\n * (assuming `~/.local/share/man` is in `MANPATH` or `manpath` picks it up).\n */\nexport function setupManPages(program: object): SetupManPagesResult {\n const cmd = getCommand(program);\n const allInfos = collectAllHelpInfo(cmd, false);\n const programName = cmd.name || 'program';\n const manDir = getManPageDir(1);\n\n mkdirSync(manDir, { recursive: true });\n\n const written: string[] = [];\n let updated = false;\n\n for (let i = 0; i < allInfos.length; i++) {\n const info = allInfos[i]!;\n const depth = i === 0 ? 0 : info.name.split(/\\s+/).length;\n const commandName = info.name === '<root>' || !info.name ? programName : info.name;\n const filename = manPageFilename(commandName);\n const fullPath = join(manDir, filename);\n\n if (existsSync(fullPath)) updated = true;\n\n const content = generateManPage(info, depth, programName);\n writeFileSync(fullPath, content, 'utf-8');\n written.push(filename);\n }\n\n return { dir: manDir, written, updated };\n}\n\n/**\n * Removes installed man pages for a Padrone CLI program.\n */\nexport function removeManPages(program: object): { dir: string; removed: string[] } {\n const { unlinkSync } = require('node:fs') as typeof import('node:fs');\n const cmd = getCommand(program);\n const allInfos = collectAllHelpInfo(cmd, false);\n const programName = cmd.name || 'program';\n const manDir = getManPageDir(1);\n const removed: string[] = [];\n\n for (let i = 0; i < allInfos.length; i++) {\n const info = allInfos[i]!;\n const commandName = info.name === '<root>' || !info.name ? programName : info.name;\n const filename = manPageFilename(commandName);\n const fullPath = join(manDir, filename);\n\n if (existsSync(fullPath)) {\n unlinkSync(fullPath);\n removed.push(filename);\n }\n }\n\n return { dir: manDir, removed };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
//#region src/errors.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base error class for all Padrone errors.
|
|
4
|
+
* Carries structured metadata for user-friendly formatting and programmatic handling.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* throw new PadroneError('Something went wrong', {
|
|
9
|
+
* exitCode: 1,
|
|
10
|
+
* suggestions: ['Try --help for usage information'],
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
var PadroneError = class extends Error {
|
|
15
|
+
exitCode;
|
|
16
|
+
suggestions;
|
|
17
|
+
command;
|
|
18
|
+
phase;
|
|
19
|
+
constructor(message, options) {
|
|
20
|
+
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
21
|
+
this.name = "PadroneError";
|
|
22
|
+
this.exitCode = options?.exitCode ?? 1;
|
|
23
|
+
this.suggestions = options?.suggestions ?? [];
|
|
24
|
+
this.command = options?.command;
|
|
25
|
+
this.phase = options?.phase;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns a serializable representation of the error,
|
|
29
|
+
* suitable for non-terminal runtimes (web UIs, APIs, etc.).
|
|
30
|
+
*/
|
|
31
|
+
toJSON() {
|
|
32
|
+
return {
|
|
33
|
+
name: this.name,
|
|
34
|
+
message: this.message,
|
|
35
|
+
exitCode: this.exitCode,
|
|
36
|
+
suggestions: this.suggestions,
|
|
37
|
+
command: this.command,
|
|
38
|
+
phase: this.phase
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Thrown when command routing fails — unknown command, unexpected arguments, etc.
|
|
44
|
+
*/
|
|
45
|
+
var RoutingError = class extends PadroneError {
|
|
46
|
+
constructor(message, options) {
|
|
47
|
+
super(message, {
|
|
48
|
+
phase: "parse",
|
|
49
|
+
...options
|
|
50
|
+
});
|
|
51
|
+
this.name = "RoutingError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Thrown when argument or schema validation fails.
|
|
56
|
+
* Carries the structured issues from the schema validator.
|
|
57
|
+
*/
|
|
58
|
+
var ValidationError = class extends PadroneError {
|
|
59
|
+
issues;
|
|
60
|
+
constructor(message, issues, options) {
|
|
61
|
+
super(message, {
|
|
62
|
+
phase: "validate",
|
|
63
|
+
...options
|
|
64
|
+
});
|
|
65
|
+
this.name = "ValidationError";
|
|
66
|
+
this.issues = issues;
|
|
67
|
+
}
|
|
68
|
+
toJSON() {
|
|
69
|
+
return {
|
|
70
|
+
...super.toJSON(),
|
|
71
|
+
issues: this.issues.map((i) => ({
|
|
72
|
+
path: i.path?.map(String),
|
|
73
|
+
message: i.message
|
|
74
|
+
}))
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Thrown when config file loading or validation fails.
|
|
80
|
+
*/
|
|
81
|
+
var ConfigError = class extends PadroneError {
|
|
82
|
+
constructor(message, options) {
|
|
83
|
+
super(message, {
|
|
84
|
+
phase: "config",
|
|
85
|
+
...options
|
|
86
|
+
});
|
|
87
|
+
this.name = "ConfigError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Thrown from user action handlers to surface structured errors with exit codes and suggestions.
|
|
92
|
+
* This is the primary error class users should throw from their command actions.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* throw new ActionError('Missing environment', {
|
|
97
|
+
* exitCode: 1,
|
|
98
|
+
* suggestions: ['Use --env production or --env staging'],
|
|
99
|
+
* });
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
var ActionError = class extends PadroneError {
|
|
103
|
+
constructor(message, options) {
|
|
104
|
+
super(message, {
|
|
105
|
+
phase: "execute",
|
|
106
|
+
...options
|
|
107
|
+
});
|
|
108
|
+
this.name = "ActionError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
//#endregion
|
|
112
|
+
export { ValidationError as a, RoutingError as i, ConfigError as n, PadroneError as r, ActionError as t };
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=errors-BiVrBgi6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-BiVrBgi6.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Structured error hierarchy for Padrone CLI framework.\n *\n * All Padrone errors extend `PadroneError`, which carries an exit code,\n * optional suggestions, and context about which command/phase produced the error.\n * This allows callers to distinguish user errors (bad input) from bugs (unexpected throws)\n * and to present formatted, actionable error messages.\n */\n\nexport type PadroneErrorOptions = {\n /** Process exit code. Defaults to 1. */\n exitCode?: number;\n /** Actionable suggestions shown to the user (e.g. \"Use --env production\"). */\n suggestions?: string[];\n /** The command path that produced the error (e.g. \"deploy staging\"). */\n command?: string;\n /** The phase where the error occurred. */\n phase?: 'parse' | 'validate' | 'execute' | 'config';\n /** Original cause for error chaining. */\n cause?: unknown;\n};\n\n/**\n * Base error class for all Padrone errors.\n * Carries structured metadata for user-friendly formatting and programmatic handling.\n *\n * @example\n * ```ts\n * throw new PadroneError('Something went wrong', {\n * exitCode: 1,\n * suggestions: ['Try --help for usage information'],\n * });\n * ```\n */\nexport class PadroneError extends Error {\n readonly exitCode: number;\n readonly suggestions: string[];\n readonly command?: string;\n readonly phase?: 'parse' | 'validate' | 'execute' | 'config';\n\n constructor(message: string, options?: PadroneErrorOptions) {\n super(message, options?.cause ? { cause: options.cause } : undefined);\n this.name = 'PadroneError';\n this.exitCode = options?.exitCode ?? 1;\n this.suggestions = options?.suggestions ?? [];\n this.command = options?.command;\n this.phase = options?.phase;\n }\n\n /**\n * Returns a serializable representation of the error,\n * suitable for non-terminal runtimes (web UIs, APIs, etc.).\n */\n toJSON(): {\n name: string;\n message: string;\n exitCode: number;\n suggestions: string[];\n command?: string;\n phase?: string;\n } {\n return {\n name: this.name,\n message: this.message,\n exitCode: this.exitCode,\n suggestions: this.suggestions,\n command: this.command,\n phase: this.phase,\n };\n }\n}\n\n/**\n * Thrown when command routing fails — unknown command, unexpected arguments, etc.\n */\nexport class RoutingError extends PadroneError {\n constructor(message: string, options?: PadroneErrorOptions) {\n super(message, { phase: 'parse', ...options });\n this.name = 'RoutingError';\n }\n}\n\n/**\n * Thrown when argument or schema validation fails.\n * Carries the structured issues from the schema validator.\n */\nexport class ValidationError extends PadroneError {\n readonly issues: readonly { path?: PropertyKey[]; message: string }[];\n\n constructor(message: string, issues: readonly { path?: PropertyKey[]; message: string }[], options?: PadroneErrorOptions) {\n super(message, { phase: 'validate', ...options });\n this.name = 'ValidationError';\n this.issues = issues;\n }\n\n override toJSON() {\n return {\n ...super.toJSON(),\n issues: this.issues.map((i) => ({ path: i.path?.map(String), message: i.message })),\n };\n }\n}\n\n/**\n * Thrown when config file loading or validation fails.\n */\nexport class ConfigError extends PadroneError {\n constructor(message: string, options?: PadroneErrorOptions) {\n super(message, { phase: 'config', ...options });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Thrown from user action handlers to surface structured errors with exit codes and suggestions.\n * This is the primary error class users should throw from their command actions.\n *\n * @example\n * ```ts\n * throw new ActionError('Missing environment', {\n * exitCode: 1,\n * suggestions: ['Use --env production or --env staging'],\n * });\n * ```\n */\nexport class ActionError extends PadroneError {\n constructor(message: string, options?: PadroneErrorOptions) {\n super(message, { phase: 'execute', ...options });\n this.name = 'ActionError';\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAkCA,IAAa,eAAb,cAAkC,MAAM;CACtC;CACA;CACA;CACA;CAEA,YAAY,SAAiB,SAA+B;AAC1D,QAAM,SAAS,SAAS,QAAQ,EAAE,OAAO,QAAQ,OAAO,GAAG,KAAA,EAAU;AACrE,OAAK,OAAO;AACZ,OAAK,WAAW,SAAS,YAAY;AACrC,OAAK,cAAc,SAAS,eAAe,EAAE;AAC7C,OAAK,UAAU,SAAS;AACxB,OAAK,QAAQ,SAAS;;;;;;CAOxB,SAOE;AACA,SAAO;GACL,MAAM,KAAK;GACX,SAAS,KAAK;GACd,UAAU,KAAK;GACf,aAAa,KAAK;GAClB,SAAS,KAAK;GACd,OAAO,KAAK;GACb;;;;;;AAOL,IAAa,eAAb,cAAkC,aAAa;CAC7C,YAAY,SAAiB,SAA+B;AAC1D,QAAM,SAAS;GAAE,OAAO;GAAS,GAAG;GAAS,CAAC;AAC9C,OAAK,OAAO;;;;;;;AAQhB,IAAa,kBAAb,cAAqC,aAAa;CAChD;CAEA,YAAY,SAAiB,QAA8D,SAA+B;AACxH,QAAM,SAAS;GAAE,OAAO;GAAY,GAAG;GAAS,CAAC;AACjD,OAAK,OAAO;AACZ,OAAK,SAAS;;CAGhB,SAAkB;AAChB,SAAO;GACL,GAAG,MAAM,QAAQ;GACjB,QAAQ,KAAK,OAAO,KAAK,OAAO;IAAE,MAAM,EAAE,MAAM,IAAI,OAAO;IAAE,SAAS,EAAE;IAAS,EAAE;GACpF;;;;;;AAOL,IAAa,cAAb,cAAiC,aAAa;CAC5C,YAAY,SAAiB,SAA+B;AAC1D,QAAM,SAAS;GAAE,OAAO;GAAU,GAAG;GAAS,CAAC;AAC/C,OAAK,OAAO;;;;;;;;;;;;;;;AAgBhB,IAAa,cAAb,cAAiC,aAAa;CAC5C,YAAY,SAAiB,SAA+B;AAC1D,QAAM,SAAS;GAAE,OAAO;GAAW,GAAG;GAAS,CAAC;AAChD,OAAK,OAAO"}
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
//#region src/colorizer.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Available ANSI styles that can be combined for each color role.
|
|
4
|
+
*/
|
|
5
|
+
type AnsiStyle = 'reset' | 'bold' | 'dim' | 'italic' | 'underline' | 'strikethrough' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray';
|
|
6
|
+
/**
|
|
7
|
+
* Maps each semantic color role to an array of ANSI styles.
|
|
8
|
+
* Partial configs are merged with the default theme.
|
|
9
|
+
*/
|
|
10
|
+
type ColorConfig = {
|
|
11
|
+
command?: AnsiStyle[];
|
|
12
|
+
arg?: AnsiStyle[];
|
|
13
|
+
type?: AnsiStyle[];
|
|
14
|
+
description?: AnsiStyle[];
|
|
15
|
+
label?: AnsiStyle[];
|
|
16
|
+
meta?: AnsiStyle[];
|
|
17
|
+
example?: AnsiStyle[];
|
|
18
|
+
exampleValue?: AnsiStyle[];
|
|
19
|
+
deprecated?: AnsiStyle[];
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Available predefined color themes.
|
|
23
|
+
*/
|
|
24
|
+
type ColorTheme = 'default' | 'ocean' | 'warm' | 'monochrome';
|
|
25
|
+
declare const colorThemes: Record<ColorTheme, Required<ColorConfig>>;
|
|
26
|
+
//#endregion
|
|
1
27
|
//#region src/formatter.d.ts
|
|
2
28
|
type HelpFormat = 'text' | 'ansi' | 'console' | 'markdown' | 'html' | 'json';
|
|
3
29
|
type HelpDetail = 'minimal' | 'standard' | 'full';
|
|
@@ -30,7 +56,8 @@ type HelpArgumentInfo = {
|
|
|
30
56
|
env?: string | string[]; /** Whether this arg is an array type (shown as <type...>) */
|
|
31
57
|
variadic?: boolean; /** Whether this arg is a boolean (shown as --[no-]arg) */
|
|
32
58
|
negatable?: boolean; /** Config file key that maps to this arg */
|
|
33
|
-
configKey?: string;
|
|
59
|
+
configKey?: string; /** Group name for organizing this option under a labeled section in help output */
|
|
60
|
+
group?: string;
|
|
34
61
|
};
|
|
35
62
|
/**
|
|
36
63
|
* Information about a subcommand (minimal info for listing).
|
|
@@ -42,7 +69,8 @@ type HelpSubcommandInfo = {
|
|
|
42
69
|
aliases?: string[];
|
|
43
70
|
deprecated?: boolean | string;
|
|
44
71
|
hidden?: boolean;
|
|
45
|
-
hasSubcommands?: boolean;
|
|
72
|
+
hasSubcommands?: boolean; /** Group name for organizing this command under a labeled section in help output */
|
|
73
|
+
group?: string;
|
|
46
74
|
};
|
|
47
75
|
/**
|
|
48
76
|
* Information about a built-in command/flag entry.
|
|
@@ -76,9 +104,10 @@ type HelpInfo = {
|
|
|
76
104
|
subcommands?: HelpSubcommandInfo[]; /** Positional arguments */
|
|
77
105
|
positionals?: HelpPositionalInfo[]; /** Arguments/flags (only visible ones, hidden filtered out) */
|
|
78
106
|
arguments?: HelpArgumentInfo[]; /** Built-in commands and flags (shown only for root command) */
|
|
79
|
-
builtins?: HelpBuiltinInfo[]; /**
|
|
107
|
+
builtins?: HelpBuiltinInfo[]; /** Command-level usage examples (shown in help output) */
|
|
108
|
+
examples?: string[]; /** Full help info for nested commands (used in 'full' detail mode) */
|
|
80
109
|
nestedCommands?: HelpInfo[];
|
|
81
110
|
};
|
|
82
111
|
//#endregion
|
|
83
|
-
export { HelpFormat as n, HelpInfo as r, HelpDetail as t };
|
|
84
|
-
//# sourceMappingURL=formatter-
|
|
112
|
+
export { ColorConfig as a, AnsiStyle as i, HelpFormat as n, ColorTheme as o, HelpInfo as r, colorThemes as s, HelpDetail as t };
|
|
113
|
+
//# sourceMappingURL=formatter-DtHzbP22.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-DtHzbP22.d.mts","names":[],"sources":["../src/colorizer.ts","../src/formatter.ts"],"mappings":";;AAqBA;;KAAY,SAAA;;;AAoBZ;;KAAY,WAAA;EACV,OAAA,GAAU,SAAA;EACV,GAAA,GAAM,SAAA;EACN,IAAA,GAAO,SAAA;EACP,WAAA,GAAc,SAAA;EACd,KAAA,GAAQ,SAAA;EACR,IAAA,GAAO,SAAA;EACP,OAAA,GAAU,SAAA;EACV,YAAA,GAAe,SAAA;EACf,UAAA,GAAa,SAAA;AAAA;;;;KAsEH,UAAA;AAAA,cAEC,WAAA,EAAa,MAAA,CAAO,UAAA,EAAY,QAAA,CAAS,WAAA;;;KCvH1C,UAAA;AAAA,KACA,UAAA;;;;KASA,kBAAA;EACV,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA;AAAA;;;;KAMU,gBAAA;EACV,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA,aDaA;ECXA,KAAA,aDYA;ECVA,OAAA;EACA,UAAA;EACA,MAAA;EACA,QAAA,cDSO;ECPP,GAAA,sBDQU;ECNV,QAAA,YDOe;ECLf,SAAA,YDMa;ECJb,SAAA,WDIsB;ECFtB,KAAA;AAAA;;;;KAMU,kBAAA;EACV,IAAA;EACA,KAAA;EACA,WAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,cAAA,YD6D8B;EC3D9B,KAAA;AAAA;;;;KAMU,eAAA;EACV,IAAA;EACA,WAAA;EACA,GAAA;IAAQ,IAAA;IAAc,WAAA;EAAA;AAAA;;AApExB;;;KA2EY,QAAA;EA3EU,4DA6EpB,IAAA,UApE4B;EAsE5B,KAAA,WAtE4B;EAwE5B,WAAA,WAtEA;EAwEA,OAAA,aAtEA;EAwEA,UAAA,qBAtEA;EAwEA,MAAA,YAxEI;EA0EJ,KAAA;IACE,OAAA;IACA,cAAA;IACA,cAAA;IACA,YAAA,WAtEF;IAwEE,UAAA;EAAA,GArEF;EAwEA,WAAA,GAAc,kBAAA,IArEd;EAuEA,WAAA,GAAc,kBAAA,IApEd;EAsEA,SAAA,GAAY,gBAAA,IApEZ;EAsEA,QAAA,GAAW,eAAA,IAlEX;EAoEA,QAAA,aAhEA;EAkEA,cAAA,GAAiB,QAAA;AAAA"}
|