padrone 1.5.0 → 1.7.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 +44 -0
- package/README.md +15 -11
- package/dist/{args-D5PNDyNu.mjs → args-Cnq0nwSM.mjs} +91 -41
- package/dist/args-Cnq0nwSM.mjs.map +1 -0
- package/dist/codegen/index.mjs +4 -4
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/commands-B_gufyR9.mjs +514 -0
- package/dist/commands-B_gufyR9.mjs.map +1 -0
- package/dist/{completion.mjs → completion-BEuflbDO.mjs} +12 -82
- package/dist/completion-BEuflbDO.mjs.map +1 -0
- package/dist/docs/index.d.mts +4 -4
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +10 -12
- package/dist/docs/index.mjs.map +1 -1
- package/dist/{errors-BiVrBgi6.mjs → errors-DA4KzK1M.mjs} +26 -3
- package/dist/errors-DA4KzK1M.mjs.map +1 -0
- package/dist/{formatter-DtHzbP22.d.mts → formatter-DrvhDMrq.d.mts} +3 -3
- package/dist/formatter-DrvhDMrq.d.mts.map +1 -0
- package/dist/{help-bbmu9-qd.mjs → help-BtxLgrF_.mjs} +190 -43
- package/dist/help-BtxLgrF_.mjs.map +1 -0
- package/dist/{types-Ch8Mk6Qb.d.mts → index-D6-7dz0l.d.mts} +634 -745
- package/dist/index-D6-7dz0l.d.mts.map +1 -0
- package/dist/index.d.mts +869 -36
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3884 -1699
- package/dist/index.mjs.map +1 -1
- package/dist/{mcp-mLWIdUIu.mjs → mcp-6-Jw4Bpq.mjs} +13 -15
- package/dist/mcp-6-Jw4Bpq.mjs.map +1 -0
- package/dist/{serve-B0u43DK7.mjs → serve-YVTPzBCl.mjs} +12 -14
- package/dist/serve-YVTPzBCl.mjs.map +1 -0
- package/dist/{stream-BcC146Ud.mjs → stream-DC4H8YTx.mjs} +24 -3
- package/dist/stream-DC4H8YTx.mjs.map +1 -0
- package/dist/test.d.mts +5 -8
- package/dist/test.d.mts.map +1 -1
- package/dist/test.mjs +2 -13
- package/dist/test.mjs.map +1 -1
- package/dist/{update-check-CFX1FV3v.mjs → update-check-CZ2VqjnV.mjs} +16 -17
- package/dist/update-check-CZ2VqjnV.mjs.map +1 -0
- package/dist/zod.d.mts +2 -2
- package/dist/zod.d.mts.map +1 -1
- package/dist/zod.mjs +2 -2
- package/dist/zod.mjs.map +1 -1
- package/package.json +15 -12
- package/src/cli/completions.ts +14 -11
- package/src/cli/docs.ts +13 -10
- package/src/cli/doctor.ts +22 -18
- package/src/cli/index.ts +28 -82
- package/src/cli/init.ts +10 -7
- package/src/cli/link.ts +20 -16
- package/src/cli/wrap.ts +14 -11
- package/src/codegen/schema-to-code.ts +2 -2
- package/src/{args.ts → core/args.ts} +32 -225
- package/src/core/commands.ts +373 -0
- package/src/core/create.ts +301 -0
- package/src/core/default-runtime.ts +239 -0
- package/src/{errors.ts → core/errors.ts} +22 -0
- package/src/core/exec.ts +259 -0
- package/src/core/interceptors.ts +302 -0
- package/src/{parse.ts → core/parse.ts} +36 -89
- package/src/core/program-methods.ts +301 -0
- package/src/core/results.ts +229 -0
- package/src/core/runtime.ts +246 -0
- package/src/core/validate.ts +247 -0
- package/src/docs/index.ts +12 -13
- package/src/extension/auto-output.ts +146 -0
- package/src/extension/color.ts +38 -0
- package/src/extension/completion.ts +49 -0
- package/src/extension/config.ts +262 -0
- package/src/extension/env.ts +101 -0
- package/src/extension/help.ts +192 -0
- package/src/extension/index.ts +44 -0
- package/src/extension/ink.ts +93 -0
- package/src/extension/interactive.ts +106 -0
- package/src/extension/logger.ts +262 -0
- package/src/extension/man.ts +51 -0
- package/src/extension/mcp.ts +52 -0
- package/src/extension/progress-renderer.ts +338 -0
- package/src/extension/progress.ts +299 -0
- package/src/extension/repl.ts +94 -0
- package/src/extension/serve.ts +48 -0
- package/src/extension/signal.ts +87 -0
- package/src/extension/stdin.ts +62 -0
- package/src/extension/suggestions.ts +114 -0
- package/src/extension/timing.ts +81 -0
- package/src/extension/tracing.ts +175 -0
- package/src/extension/update-check.ts +77 -0
- package/src/extension/utils.ts +51 -0
- package/src/extension/version.ts +63 -0
- package/src/{completion.ts → feature/completion.ts} +12 -12
- package/src/{interactive.ts → feature/interactive.ts} +4 -4
- package/src/{mcp.ts → feature/mcp.ts} +12 -15
- package/src/{repl-loop.ts → feature/repl-loop.ts} +10 -13
- package/src/{serve.ts → feature/serve.ts} +11 -15
- package/src/feature/test.ts +262 -0
- package/src/{update-check.ts → feature/update-check.ts} +16 -16
- package/src/{wrap.ts → feature/wrap.ts} +10 -8
- package/src/index.ts +115 -30
- package/src/{formatter.ts → output/formatter.ts} +124 -176
- package/src/{help.ts → output/help.ts} +22 -8
- package/src/output/output-indicator.ts +87 -0
- package/src/output/primitives.ts +335 -0
- package/src/output/styling.ts +221 -0
- package/src/{zod.d.ts → schema/zod.d.ts} +1 -1
- package/src/schema/zod.ts +50 -0
- package/src/test.ts +2 -276
- package/src/types/args-meta.ts +151 -0
- package/src/types/builder.ts +718 -0
- package/src/types/command.ts +157 -0
- package/src/types/index.ts +60 -0
- package/src/types/interceptor.ts +296 -0
- package/src/types/preferences.ts +83 -0
- package/src/types/result.ts +71 -0
- package/src/types/schema.ts +19 -0
- package/src/util/dotenv.ts +244 -0
- package/src/{shell-utils.ts → util/shell-utils.ts} +26 -9
- package/src/{stream.ts → util/stream.ts} +27 -1
- package/src/{type-helpers.ts → util/type-helpers.ts} +23 -16
- package/src/{type-utils.ts → util/type-utils.ts} +71 -33
- package/src/util/utils.ts +51 -0
- package/src/zod.ts +1 -50
- package/dist/args-D5PNDyNu.mjs.map +0 -1
- package/dist/chunk-CjcI7cDX.mjs +0 -15
- package/dist/command-utils-B1D-HqCd.mjs +0 -1117
- package/dist/command-utils-B1D-HqCd.mjs.map +0 -1
- package/dist/completion.d.mts +0 -64
- package/dist/completion.d.mts.map +0 -1
- package/dist/completion.mjs.map +0 -1
- package/dist/errors-BiVrBgi6.mjs.map +0 -1
- package/dist/formatter-DtHzbP22.d.mts.map +0 -1
- package/dist/help-bbmu9-qd.mjs.map +0 -1
- package/dist/mcp-mLWIdUIu.mjs.map +0 -1
- package/dist/serve-B0u43DK7.mjs.map +0 -1
- package/dist/stream-BcC146Ud.mjs.map +0 -1
- package/dist/types-Ch8Mk6Qb.d.mts.map +0 -1
- package/dist/update-check-CFX1FV3v.mjs.map +0 -1
- package/src/command-utils.ts +0 -882
- package/src/create.ts +0 -1829
- package/src/runtime.ts +0 -497
- package/src/types.ts +0 -1291
- package/src/utils.ts +0 -140
- /package/src/{colorizer.ts → output/colorizer.ts} +0 -0
|
@@ -1,75 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/shell-utils.ts
|
|
4
|
-
/**
|
|
5
|
-
* Detects the current shell from environment variables and process info.
|
|
6
|
-
* @returns The detected shell type, or undefined if unknown
|
|
7
|
-
*/
|
|
8
|
-
function detectShell() {
|
|
9
|
-
if (typeof process === "undefined") return void 0;
|
|
10
|
-
const shellEnv = process.env.SHELL || "";
|
|
11
|
-
if (shellEnv.includes("zsh")) return "zsh";
|
|
12
|
-
if (shellEnv.includes("bash")) return "bash";
|
|
13
|
-
if (shellEnv.includes("fish")) return "fish";
|
|
14
|
-
if (process.env.PSModulePath || process.env.POWERSHELL_DISTRIBUTION_CHANNEL) return "powershell";
|
|
15
|
-
try {
|
|
16
|
-
const ppid = process.ppid;
|
|
17
|
-
if (ppid) {
|
|
18
|
-
const { execSync } = __require("node:child_process");
|
|
19
|
-
const processName = execSync(`ps -p ${ppid} -o comm=`, {
|
|
20
|
-
encoding: "utf-8",
|
|
21
|
-
stdio: [
|
|
22
|
-
"pipe",
|
|
23
|
-
"pipe",
|
|
24
|
-
"ignore"
|
|
25
|
-
]
|
|
26
|
-
}).trim();
|
|
27
|
-
if (processName.includes("zsh")) return "zsh";
|
|
28
|
-
if (processName.includes("bash")) return "bash";
|
|
29
|
-
if (processName.includes("fish")) return "fish";
|
|
30
|
-
}
|
|
31
|
-
} catch {}
|
|
32
|
-
}
|
|
33
|
-
function getRcFile(shell, home) {
|
|
34
|
-
const { homedir } = __require("node:os");
|
|
35
|
-
const { join } = __require("node:path");
|
|
36
|
-
const h = home ?? homedir();
|
|
37
|
-
switch (shell) {
|
|
38
|
-
case "bash": return join(h, ".bashrc");
|
|
39
|
-
case "zsh": return join(h, ".zshrc");
|
|
40
|
-
case "fish": return join(h, ".config", "fish", "config.fish");
|
|
41
|
-
case "powershell": return process.env.PROFILE || join(h, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
|
|
42
|
-
default: return null;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function escapeRegExp(str) {
|
|
46
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Writes a snippet to a shell config file using begin/end markers for idempotency.
|
|
50
|
-
* If a block with the same begin marker exists, it is replaced. Otherwise the snippet is appended.
|
|
51
|
-
*/
|
|
52
|
-
function writeToRcFile(rcFile, snippet, beginMarker, endMarker) {
|
|
53
|
-
const { existsSync, mkdirSync, readFileSync, writeFileSync } = __require("node:fs");
|
|
54
|
-
const { dirname } = __require("node:path");
|
|
55
|
-
const existing = existsSync(rcFile) ? readFileSync(rcFile, "utf-8") : "";
|
|
56
|
-
if (existing.includes(beginMarker)) {
|
|
57
|
-
const pattern = new RegExp(`${escapeRegExp(beginMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}`);
|
|
58
|
-
writeFileSync(rcFile, existing.replace(pattern, snippet));
|
|
59
|
-
return {
|
|
60
|
-
file: rcFile,
|
|
61
|
-
updated: true
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
mkdirSync(dirname(rcFile), { recursive: true });
|
|
65
|
-
writeFileSync(rcFile, `${existing}${existing.length > 0 && !existing.endsWith("\n") ? "\n" : ""}\n${snippet}\n`);
|
|
66
|
-
return {
|
|
67
|
-
file: rcFile,
|
|
68
|
-
updated: false
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
//#endregion
|
|
72
|
-
//#region src/completion.ts
|
|
1
|
+
import { a as getJsonSchema, d as detectShell, i as extractSchemaMetadata, m as writeToRcFile, p as getRcFile } from "./args-Cnq0nwSM.mjs";
|
|
2
|
+
//#region src/feature/completion.ts
|
|
73
3
|
/**
|
|
74
4
|
* Collects all commands from a program recursively.
|
|
75
5
|
*/
|
|
@@ -94,7 +24,7 @@ function extractArguments(cmd) {
|
|
|
94
24
|
const { aliases } = extractSchemaMetadata(cmd.argsSchema, argsMeta, cmd.meta?.autoAlias);
|
|
95
25
|
const argToAlias = {};
|
|
96
26
|
for (const [aliasName, argName] of Object.entries(aliases)) if (!argToAlias[argName]) argToAlias[argName] = aliasName;
|
|
97
|
-
const jsonSchema = cmd.argsSchema
|
|
27
|
+
const jsonSchema = getJsonSchema(cmd.argsSchema);
|
|
98
28
|
if (jsonSchema.type === "object" && jsonSchema.properties) for (const [key, prop] of Object.entries(jsonSchema.properties)) {
|
|
99
29
|
const enumValues = prop.enum ?? prop.items?.enum;
|
|
100
30
|
const optMeta = argsMeta?.[key];
|
|
@@ -396,10 +326,10 @@ ${programName} completion powershell >> $PROFILE`;
|
|
|
396
326
|
* Generates the completion output with automatic shell detection.
|
|
397
327
|
* If shell is not specified, detects the current shell and provides instructions.
|
|
398
328
|
*/
|
|
399
|
-
function generateCompletionOutput(program, shell) {
|
|
329
|
+
async function generateCompletionOutput(program, shell) {
|
|
400
330
|
const programName = program.name;
|
|
401
331
|
if (shell) return generateCompletion(program, shell);
|
|
402
|
-
const detectedShell = detectShell();
|
|
332
|
+
const detectedShell = await detectShell();
|
|
403
333
|
if (detectedShell) return `# Detected shell: ${detectedShell}
|
|
404
334
|
#
|
|
405
335
|
${getCompletionInstallInstructions(programName, detectedShell)}
|
|
@@ -428,10 +358,10 @@ ${generateCompletion(program, detectedShell)}`;
|
|
|
428
358
|
* Sets up shell completions by writing an eval snippet to the appropriate shell config file.
|
|
429
359
|
* Uses marker comments for idempotency — re-running replaces the existing block.
|
|
430
360
|
*/
|
|
431
|
-
function setupCompletions(programName, shell) {
|
|
432
|
-
const { existsSync, mkdirSync, writeFileSync } =
|
|
433
|
-
const { join } =
|
|
434
|
-
const { homedir } =
|
|
361
|
+
async function setupCompletions(programName, shell) {
|
|
362
|
+
const { existsSync, mkdirSync, writeFileSync } = await import("node:fs");
|
|
363
|
+
const { join } = await import("node:path");
|
|
364
|
+
const { homedir } = await import("node:os");
|
|
435
365
|
const beginMarker = `###-begin-${programName}-completion-###`;
|
|
436
366
|
const endMarker = `###-end-${programName}-completion-###`;
|
|
437
367
|
const snippet = buildSetupSnippet(programName, shell, beginMarker, endMarker);
|
|
@@ -446,7 +376,7 @@ function setupCompletions(programName, shell) {
|
|
|
446
376
|
updated: existed
|
|
447
377
|
};
|
|
448
378
|
}
|
|
449
|
-
const rcFile = getRcFile(shell);
|
|
379
|
+
const rcFile = await getRcFile(shell);
|
|
450
380
|
if (!rcFile) throw new Error(`Could not determine config file for ${shell}.`);
|
|
451
381
|
return writeToRcFile(rcFile, snippet, beginMarker, endMarker);
|
|
452
382
|
}
|
|
@@ -460,6 +390,6 @@ function buildSetupSnippet(programName, shell, beginMarker, endMarker) {
|
|
|
460
390
|
}
|
|
461
391
|
}
|
|
462
392
|
//#endregion
|
|
463
|
-
export { detectShell,
|
|
393
|
+
export { detectShell, generateCompletionOutput, setupCompletions };
|
|
464
394
|
|
|
465
|
-
//# sourceMappingURL=completion.mjs.map
|
|
395
|
+
//# sourceMappingURL=completion-BEuflbDO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-BEuflbDO.mjs","names":[],"sources":["../src/feature/completion.ts"],"sourcesContent":["import { extractSchemaMetadata, getJsonSchema } from '../core/args.ts';\nimport type { AnyPadroneCommand } from '../types/index.ts';\nimport { detectShell, getRcFile, type ShellType, writeToRcFile } from '../util/shell-utils.ts';\n\nexport { detectShell, escapeRegExp, getRcFile, type ShellType, writeToRcFile } from '../util/shell-utils.ts';\n\n/**\n * Collects all commands from a program recursively.\n */\nfunction collectAllCommands(cmd: AnyPadroneCommand): AnyPadroneCommand[] {\n const result: AnyPadroneCommand[] = [];\n\n if (cmd.commands) {\n for (const subcmd of cmd.commands) {\n if (!subcmd.hidden) {\n result.push(subcmd);\n result.push(...collectAllCommands(subcmd));\n }\n }\n }\n\n return result;\n}\n\ninterface ExtractedArg {\n name: string;\n alias?: string;\n isBoolean: boolean;\n enum?: string[];\n description?: string;\n}\n\n/**\n * Extracts all argument names from a command's schema.\n */\nfunction extractArguments(cmd: AnyPadroneCommand): ExtractedArg[] {\n const argList: ExtractedArg[] = [];\n\n if (!cmd.argsSchema) return argList;\n\n try {\n const argsMeta = cmd.meta?.fields;\n const { aliases } = extractSchemaMetadata(cmd.argsSchema, argsMeta, cmd.meta?.autoAlias);\n\n // Build reverse map: argName → aliasName\n const argToAlias: Record<string, string> = {};\n for (const [aliasName, argName] of Object.entries(aliases)) {\n if (!argToAlias[argName]) argToAlias[argName] = aliasName;\n }\n\n const jsonSchema = getJsonSchema(cmd.argsSchema) as Record<string, any>;\n\n if (jsonSchema.type === 'object' && jsonSchema.properties) {\n for (const [key, prop] of Object.entries(jsonSchema.properties as Record<string, any>)) {\n const enumValues = (prop.enum ?? prop.items?.enum) as string[] | undefined;\n const optMeta = argsMeta?.[key];\n argList.push({\n name: key,\n alias: argToAlias[key],\n isBoolean: prop?.type === 'boolean',\n enum: enumValues,\n description: optMeta?.description ?? prop.description,\n });\n }\n }\n } catch {\n // Ignore schema parsing errors\n }\n\n return argList;\n}\n\n/**\n * Collects unique args across all commands, preserving first-seen enum values.\n */\nfunction collectUniqueArgs(program: AnyPadroneCommand, commands: AnyPadroneCommand[]): Map<string, ExtractedArg> {\n const seen = new Map<string, ExtractedArg>();\n\n for (const cmd of [program, ...commands]) {\n for (const arg of extractArguments(cmd)) {\n if (!seen.has(arg.name)) {\n seen.set(arg.name, arg);\n }\n }\n }\n\n return seen;\n}\n\n/**\n * Generates a Bash completion script for the program.\n */\nexport function generateBashCompletion(program: AnyPadroneCommand): string {\n const programName = program.name;\n const commands = collectAllCommands(program);\n const commandNames = commands.map((c) => c.name).join(' ');\n const uniqueArgs = collectUniqueArgs(program, commands);\n\n // Collect all option names\n const allArguments = new Set<string>();\n allArguments.add('--help');\n allArguments.add('--version');\n\n for (const arg of uniqueArgs.values()) {\n allArguments.add(`--${arg.name}`);\n if (arg.alias) allArguments.add(`--${arg.alias}`);\n }\n\n const argsList = Array.from(allArguments).join(' ');\n\n // Build case branches for options with enum values\n const enumCases: string[] = [];\n for (const arg of uniqueArgs.values()) {\n if (!arg.enum || arg.enum.length === 0) continue;\n const values = arg.enum.join(' ');\n const patterns = [`--${arg.name}`];\n if (arg.alias) patterns.push(`--${arg.alias}`);\n enumCases.push(` ${patterns.join('|')}) COMPREPLY=($(compgen -W \"${values}\" -- \"$cur\")); return 0 ;;`);\n }\n\n const enumBlock =\n enumCases.length > 0\n ? `\n # Complete option values\n case \"$prev\" in\n${enumCases.join('\\n')}\n esac\n\n`\n : '\\n';\n\n return `###-begin-${programName}-completion-###\n#\n# ${programName} command completion script\n#\n# Installation: ${programName} completion >> ~/.bashrc (or ~/.zshrc)\n# Or, maybe: ${programName} completion > /usr/local/etc/bash_completion.d/${programName}\n#\n\nif type complete &>/dev/null; then\n _${programName}_completion() {\n local cur prev words cword\n if type _get_comp_words_by_ref &>/dev/null; then\n _get_comp_words_by_ref -n = -n @ -n : -w words -i cword\n else\n cword=\"$COMP_CWORD\"\n words=(\"\\${COMP_WORDS[@]}\")\n fi\n\n cur=\"\\${words[cword]}\"\n prev=\"\\${words[cword-1]}\"\n\n local commands=\"${commandNames}\"\n local args=\"${argsList}\"\n${enumBlock} # Complete args when current word starts with -\n if [[ \"$cur\" == -* ]]; then\n COMPREPLY=($(compgen -W \"$args\" -- \"$cur\"))\n return 0\n fi\n\n # Complete commands\n COMPREPLY=($(compgen -W \"$commands\" -- \"$cur\"))\n }\n complete -o bashdefault -o default -o nospace -F _${programName}_completion ${programName}\nelif type compdef &>/dev/null; then\n _${programName}_completion() {\n local si=$IFS\n local commands=\"${commandNames}\"\n local args=\"${argsList}\"\n\n if [[ \"\\${words[CURRENT]}\" == -* ]]; then\n compadd -- \\${=args}\n else\n compadd -- \\${=commands}\n fi\n IFS=$si\n }\n compdef _${programName}_completion ${programName}\nelif type compctl &>/dev/null; then\n _${programName}_completion() {\n local commands=\"${commandNames}\"\n local args=\"${argsList}\"\n\n if [[ \"\\${words[CURRENT]}\" == -* ]]; then\n reply=(\\${=args})\n else\n reply=(\\${=commands})\n fi\n }\n compctl -K _${programName}_completion ${programName}\nfi\n###-end-${programName}-completion-###`;\n}\n\n/**\n * Generates a Zsh completion script for the program.\n */\nexport function generateZshCompletion(program: AnyPadroneCommand): string {\n const programName = program.name;\n const commands = collectAllCommands(program);\n\n // Generate command completions with descriptions\n const commandCompletions = commands\n .map((cmd) => {\n const desc = cmd.description || cmd.title || '';\n const escapedDesc = desc.replace(/'/g, \"'\\\\''\").replace(/:/g, '\\\\:');\n return ` '${cmd.name}:${escapedDesc}'`;\n })\n .join('\\n');\n\n // Collect all args with descriptions and enum values\n const argumentCompletions: string[] = [];\n argumentCompletions.push(\" '--help[Show help information]'\");\n argumentCompletions.push(\" '--version[Show version number]'\");\n\n const uniqueArgs = collectUniqueArgs(program, commands);\n\n for (const arg of uniqueArgs.values()) {\n const desc = arg.description || '';\n const escapedDesc = desc.replace(/'/g, \"'\\\\''\").replace(/\\[/g, '\\\\[').replace(/\\]/g, '\\\\]');\n\n // Zsh action spec for enum values: :label:(val1 val2 val3)\n const valueAction = arg.enum?.length ? `: :(${arg.enum.join(' ')})` : '';\n\n if (arg.alias) {\n argumentCompletions.push(` {--${arg.alias},--${arg.name}}'[${escapedDesc}]${valueAction}'`);\n } else {\n argumentCompletions.push(` '--${arg.name}[${escapedDesc}]${valueAction}'`);\n }\n }\n\n return `#compdef ${programName}\n###-begin-${programName}-completion-###\n#\n# ${programName} command completion script for Zsh\n#\n# Installation: ${programName} completion >> ~/.zshrc\n# Or: ${programName} completion > ~/.zsh/completions/_${programName}\n#\n\n_${programName}() {\n local -a commands\n local -a args\n\n commands=(\n${commandCompletions}\n )\n\n args=(\n${argumentCompletions.join('\\n')}\n )\n\n _arguments -s \\\\\n $args \\\\\n '1: :->command' \\\\\n '*::arg:->args'\n\n case \"$state\" in\n command)\n _describe 'command' commands\n ;;\n esac\n}\n\n_${programName}\n###-end-${programName}-completion-###`;\n}\n\n/**\n * Generates a Fish completion script for the program.\n */\nexport function generateFishCompletion(program: AnyPadroneCommand): string {\n const programName = program.name;\n const commands = collectAllCommands(program);\n\n const lines: string[] = [\n `###-begin-${programName}-completion-###`,\n '#',\n `# ${programName} command completion script for Fish`,\n '#',\n `# Installation: ${programName} completion > ~/.config/fish/completions/${programName}.fish`,\n '#',\n '',\n `# Clear existing completions`,\n `complete -c ${programName} -e`,\n '',\n '# Commands',\n ];\n\n for (const cmd of commands) {\n const desc = cmd.description || cmd.title || '';\n const escapedDesc = desc.replace(/'/g, \"\\\\'\");\n lines.push(`complete -c ${programName} -n \"__fish_use_subcommand\" -a \"${cmd.name}\" -d '${escapedDesc}'`);\n }\n\n lines.push('');\n lines.push('# Global arguments');\n lines.push(`complete -c ${programName} -l help -d 'Show help information'`);\n lines.push(`complete -c ${programName} -l version -d 'Show version number'`);\n\n const uniqueArgs = collectUniqueArgs(program, commands);\n\n for (const arg of uniqueArgs.values()) {\n const desc = arg.description || '';\n const escapedDesc = desc.replace(/'/g, \"\\\\'\");\n // Fish: -xa 'val1 val2' provides exclusive value completions\n const valueFlag = arg.enum?.length ? ` -xa '${arg.enum.join(' ')}'` : '';\n\n if (arg.alias) {\n lines.push(`complete -c ${programName} -l ${arg.name} -s ${arg.alias} -d '${escapedDesc}'${valueFlag}`);\n } else {\n lines.push(`complete -c ${programName} -l ${arg.name} -d '${escapedDesc}'${valueFlag}`);\n }\n }\n\n lines.push(`###-end-${programName}-completion-###`);\n\n return lines.join('\\n');\n}\n\n/**\n * Generates a PowerShell completion script for the program.\n */\nexport function generatePowerShellCompletion(program: AnyPadroneCommand): string {\n const programName = program.name;\n const commands = collectAllCommands(program);\n const uniqueArgs = collectUniqueArgs(program, commands);\n\n const commandNames = commands.map((c) => `'${c.name}'`).join(', ');\n\n // Collect all option names\n const argNames: string[] = [\"'--help'\", \"'--version'\"];\n for (const arg of uniqueArgs.values()) {\n argNames.push(`'--${arg.name}'`);\n if (arg.alias) argNames.push(`'--${arg.alias}'`);\n }\n\n // Build switch cases for option value completion\n const enumCases: string[] = [];\n for (const arg of uniqueArgs.values()) {\n if (!arg.enum || arg.enum.length === 0) continue;\n const values = arg.enum.map((v) => `'${v}'`).join(', ');\n const patterns = [`'--${arg.name}'`];\n if (arg.alias) patterns.push(`'--${arg.alias}'`);\n enumCases.push(` ${patterns.join(', ')} { @(${values}) | Where-Object { $_ -like \"$wordToComplete*\" } | ForEach-Object {\n [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)\n }; return }`);\n }\n\n const enumBlock =\n enumCases.length > 0\n ? `\n # Complete option values\n $prevWord = $commandAst.CommandElements | Select-Object -Last 2 | Select-Object -First 1\n switch ($prevWord) {\n${enumCases.join('\\n')}\n }\n\n`\n : '\\n';\n\n return `###-begin-${programName}-completion-###\n#\n# ${programName} command completion script for PowerShell\n#\n# Installation: ${programName} completion >> $PROFILE\n#\n\nRegister-ArgumentCompleter -Native -CommandName ${programName} -ScriptBlock {\n param($wordToComplete, $commandAst, $cursorPosition)\n\n $commands = @(${commandNames})\n $args = @(${argNames.join(', ')})\n${enumBlock} if ($wordToComplete -like '-*') {\n $args | Where-Object { $_ -like \"$wordToComplete*\" } | ForEach-Object {\n [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)\n }\n } else {\n $commands | Where-Object { $_ -like \"$wordToComplete*\" } | ForEach-Object {\n [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)\n }\n }\n}\n###-end-${programName}-completion-###`;\n}\n\n/**\n * Generates a completion script for the specified shell.\n */\nexport function generateCompletion(program: AnyPadroneCommand, shell: ShellType): string {\n switch (shell) {\n case 'bash':\n return generateBashCompletion(program);\n case 'zsh':\n return generateZshCompletion(program);\n case 'fish':\n return generateFishCompletion(program);\n case 'powershell':\n return generatePowerShellCompletion(program);\n default:\n throw new Error(`Unsupported shell: ${shell}`);\n }\n}\n\n/**\n * Gets the installation instructions for a shell completion script.\n */\nexport function getCompletionInstallInstructions(programName: string, shell: ShellType): string {\n switch (shell) {\n case 'bash':\n return `# Add to ~/.bashrc:\n${programName} completion bash >> ~/.bashrc\n\n# Or install system-wide:\n${programName} completion bash > /usr/local/etc/bash_completion.d/${programName}`;\n\n case 'zsh':\n return `# Add to ~/.zshrc:\n${programName} completion zsh >> ~/.zshrc\n\n# Or add to completions directory:\n${programName} completion zsh > ~/.zsh/completions/_${programName}`;\n\n case 'fish':\n return `# Install to Fish completions:\n${programName} completion fish > ~/.config/fish/completions/${programName}.fish`;\n\n case 'powershell':\n return `# Add to PowerShell profile:\n${programName} completion powershell >> $PROFILE`;\n\n default:\n return `# Run: ${programName} completion <shell>\n# Supported shells: bash, zsh, fish, powershell`;\n }\n}\n\n/**\n * Generates the completion output with automatic shell detection.\n * If shell is not specified, detects the current shell and provides instructions.\n */\nexport async function generateCompletionOutput(program: AnyPadroneCommand, shell?: ShellType): Promise<string> {\n const programName = program.name;\n\n if (shell) {\n return generateCompletion(program, shell);\n }\n\n // Auto-detect shell and provide instructions\n const detectedShell = await detectShell();\n\n if (detectedShell) {\n const instructions = getCompletionInstallInstructions(programName, detectedShell);\n const script = generateCompletion(program, detectedShell);\n\n return `# Detected shell: ${detectedShell}\n#\n${instructions}\n#\n# Or evaluate directly (temporary, for current session only):\n# eval \"$(${programName} completion ${detectedShell})\"\n\n${script}`;\n }\n\n // Could not detect shell - provide usage info\n return `# Shell auto-detection failed.\n#\n# Usage: ${programName} completion <shell>\n#\n# Supported shells:\n# bash - Bash completion script\n# zsh - Zsh completion script\n# fish - Fish completion script\n# powershell - PowerShell completion script\n#\n# Example:\n# ${programName} completion bash >> ~/.bashrc\n# ${programName} completion zsh >> ~/.zshrc\n# ${programName} completion fish > ~/.config/fish/completions/${programName}.fish\n# ${programName} completion powershell >> $PROFILE`;\n}\n\nexport interface SetupCompletionsResult {\n /** The file that was written to. */\n file: string;\n /** Whether an existing completion block was replaced (true) or a new one was appended (false). */\n updated: boolean;\n}\n\n/**\n * Sets up shell completions by writing an eval snippet to the appropriate shell config file.\n * Uses marker comments for idempotency — re-running replaces the existing block.\n */\nexport async function setupCompletions(programName: string, shell: ShellType): Promise<SetupCompletionsResult> {\n const { existsSync, mkdirSync, writeFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const { homedir } = await import('node:os');\n\n const beginMarker = `###-begin-${programName}-completion-###`;\n const endMarker = `###-end-${programName}-completion-###`;\n const snippet = buildSetupSnippet(programName, shell, beginMarker, endMarker);\n\n if (shell === 'fish') {\n const completionsDir = join(homedir(), '.config', 'fish', 'completions');\n const filePath = join(completionsDir, `${programName}.fish`);\n mkdirSync(completionsDir, { recursive: true });\n const existed = existsSync(filePath);\n writeFileSync(filePath, `${snippet}\\n`);\n return { file: filePath, updated: existed };\n }\n\n const rcFile = await getRcFile(shell);\n if (!rcFile) {\n throw new Error(`Could not determine config file for ${shell}.`);\n }\n\n return writeToRcFile(rcFile, snippet, beginMarker, endMarker);\n}\n\nfunction buildSetupSnippet(programName: string, shell: ShellType, beginMarker: string, endMarker: string): string {\n const evalCmd = `${programName} completion ${shell}`;\n\n switch (shell) {\n case 'bash':\n case 'zsh':\n return `${beginMarker}\\neval \"$(${evalCmd})\"\\n${endMarker}`;\n case 'fish':\n return `${beginMarker}\\n${evalCmd} | source\\n${endMarker}`;\n case 'powershell':\n return `${beginMarker}\\n${evalCmd} | Invoke-Expression\\n${endMarker}`;\n }\n}\n"],"mappings":"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"}
|
package/dist/docs/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as HelpInfo } from "../formatter-
|
|
1
|
+
import { r as HelpInfo } from "../formatter-DrvhDMrq.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/docs/index.d.ts
|
|
4
4
|
type DocsFormat = 'markdown' | 'html' | 'man' | 'json';
|
|
@@ -41,14 +41,14 @@ type SetupManPagesResult = {
|
|
|
41
41
|
* After installation, `man <program>` and `man <program>-<subcommand>` should work
|
|
42
42
|
* (assuming `~/.local/share/man` is in `MANPATH` or `manpath` picks it up).
|
|
43
43
|
*/
|
|
44
|
-
declare function setupManPages(program: object): SetupManPagesResult
|
|
44
|
+
declare function setupManPages(program: object): Promise<SetupManPagesResult>;
|
|
45
45
|
/**
|
|
46
46
|
* Removes installed man pages for a Padrone CLI program.
|
|
47
47
|
*/
|
|
48
|
-
declare function removeManPages(program: object): {
|
|
48
|
+
declare function removeManPages(program: object): Promise<{
|
|
49
49
|
dir: string;
|
|
50
50
|
removed: string[];
|
|
51
|
-
}
|
|
51
|
+
}>;
|
|
52
52
|
//#endregion
|
|
53
53
|
export { DocsFormat, DocsOptions, DocsPage, DocsResult, SetupManPagesResult, generateDocs, removeManPages, setupManPages };
|
|
54
54
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/docs/index.ts"],"mappings":";;;KAWY,UAAA;AAAA,KAEA,WAAA;EAFA,6CAIV,MAAA,GAAS,UAAA;EAET,MAAA,WANoB;EAQpB,aAAA,YANqB;EAQrB,WAAA,IAAe,IAAA,EAAM,QAAA,EAAU,KAAA,aAAkB,MAAA,mBANxC;EAQT,SAAA,YAFiD;EAIjD,MAAA;AAAA;AAAA,KAGU,QAAA;EAbD,8EAeT,IAAA,UAXA;EAaA,OAAA,UAXqB;EAarB,OAAA;AAAA;AAAA,KAGU,UAAA;EAdV,2BAgBA,KAAA,EAAO,QAAA,IAdD;EAgBN,OAAA,YAbU;EAeV,OAAA;EAEA,MAAA;IAAU,IAAA;IAAc,KAAA,EAAO,KAAA;EAAA;AAAA;;AARjC;;;iBAigBgB,YAAA,CAAa,OAAA,UAAiB,OAAA,GAAS,WAAA,GAAmB,UAAA;AAAA,KAoF9D,mBAAA;EAnlBH,8CAqlBP,GAAA,UAjlBA;EAmlBA,OAAA,YAjlBU;EAmlBV,OAAA;AAAA;;;AA1FF;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/docs/index.ts"],"mappings":";;;KAWY,UAAA;AAAA,KAEA,WAAA;EAFA,6CAIV,MAAA,GAAS,UAAA;EAET,MAAA,WANoB;EAQpB,aAAA,YANqB;EAQrB,WAAA,IAAe,IAAA,EAAM,QAAA,EAAU,KAAA,aAAkB,MAAA,mBANxC;EAQT,SAAA,YAFiD;EAIjD,MAAA;AAAA;AAAA,KAGU,QAAA;EAbD,8EAeT,IAAA,UAXA;EAaA,OAAA,UAXqB;EAarB,OAAA;AAAA;AAAA,KAGU,UAAA;EAdV,2BAgBA,KAAA,EAAO,QAAA,IAdD;EAgBN,OAAA,YAbU;EAeV,OAAA;EAEA,MAAA;IAAU,IAAA;IAAc,KAAA,EAAO,KAAA;EAAA;AAAA;;AARjC;;;iBAigBgB,YAAA,CAAa,OAAA,UAAiB,OAAA,GAAS,WAAA,GAAmB,UAAA;AAAA,KAoF9D,mBAAA;EAnlBH,8CAqlBP,GAAA,UAjlBA;EAmlBA,OAAA,YAjlBU;EAmlBV,OAAA;AAAA;;;AA1FF;;;;;iBAqHsB,aAAA,CAAc,OAAA,WAAkB,OAAA,CAAQ,mBAAA;;;;iBA+BxC,cAAA,CAAe,OAAA,WAAkB,OAAA;EAAU,GAAA;EAAa,OAAA;AAAA"}
|
package/dist/docs/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as getHelpInfo } from "../help-
|
|
3
|
-
import { d as getCommand } from "../command-utils-B1D-HqCd.mjs";
|
|
1
|
+
import { s as getCommand } from "../commands-B_gufyR9.mjs";
|
|
2
|
+
import { n as getHelpInfo } from "../help-BtxLgrF_.mjs";
|
|
4
3
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
5
4
|
import { dirname, join, resolve } from "node:path";
|
|
6
5
|
//#region src/docs/index.ts
|
|
@@ -420,10 +419,9 @@ function generateDocs(program, options = {}) {
|
|
|
420
419
|
* Returns the local man page directory for the given section.
|
|
421
420
|
* Uses `~/.local/share/man/man<section>` (XDG convention).
|
|
422
421
|
*/
|
|
423
|
-
function getManPageDir(section = 1) {
|
|
424
|
-
const { homedir } =
|
|
425
|
-
|
|
426
|
-
return joinPath(process.env.XDG_DATA_HOME || joinPath(homedir(), ".local", "share"), "man", `man${section}`);
|
|
422
|
+
async function getManPageDir(section = 1) {
|
|
423
|
+
const { homedir } = await import("node:os");
|
|
424
|
+
return join(process.env.XDG_DATA_HOME || join(homedir(), ".local", "share"), "man", `man${section}`);
|
|
427
425
|
}
|
|
428
426
|
/**
|
|
429
427
|
* Converts a command name to a man page filename.
|
|
@@ -439,11 +437,11 @@ function manPageFilename(commandName, section = 1) {
|
|
|
439
437
|
* After installation, `man <program>` and `man <program>-<subcommand>` should work
|
|
440
438
|
* (assuming `~/.local/share/man` is in `MANPATH` or `manpath` picks it up).
|
|
441
439
|
*/
|
|
442
|
-
function setupManPages(program) {
|
|
440
|
+
async function setupManPages(program) {
|
|
443
441
|
const cmd = getCommand(program);
|
|
444
442
|
const allInfos = collectAllHelpInfo(cmd, false);
|
|
445
443
|
const programName = cmd.name || "program";
|
|
446
|
-
const manDir = getManPageDir(1);
|
|
444
|
+
const manDir = await getManPageDir(1);
|
|
447
445
|
mkdirSync(manDir, { recursive: true });
|
|
448
446
|
const written = [];
|
|
449
447
|
let updated = false;
|
|
@@ -465,12 +463,12 @@ function setupManPages(program) {
|
|
|
465
463
|
/**
|
|
466
464
|
* Removes installed man pages for a Padrone CLI program.
|
|
467
465
|
*/
|
|
468
|
-
function removeManPages(program) {
|
|
469
|
-
const { unlinkSync } =
|
|
466
|
+
async function removeManPages(program) {
|
|
467
|
+
const { unlinkSync } = await import("node:fs");
|
|
470
468
|
const cmd = getCommand(program);
|
|
471
469
|
const allInfos = collectAllHelpInfo(cmd, false);
|
|
472
470
|
const programName = cmd.name || "program";
|
|
473
|
-
const manDir = getManPageDir(1);
|
|
471
|
+
const manDir = await getManPageDir(1);
|
|
474
472
|
const removed = [];
|
|
475
473
|
for (let i = 0; i < allInfos.length; i++) {
|
|
476
474
|
const info = allInfos[i];
|
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 { 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":";;;;;;AAoDA,SAAS,mBAAmB,KAAwB,eAAoC;CAEtF,MAAM,SAAqB,CADd,YAAY,KAAK,WAAW,CACR;AAEjC,KAAI,IAAI,SACN,MAAK,MAAM,OAAO,IAAI,UAAU;AAC9B,MAAI,CAAC,iBAAiB,IAAI,OAAQ;AAClC,SAAO,KAAK,GAAG,mBAAmB,KAAK,cAAc,CAAC;;AAI1D,QAAO;;AAOT,SAAS,oBAAoB,MAAuC;CAClE,MAAM,QAAkB,CAAC,MAAM;AAC/B,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,CAC7C,KAAI,OAAO,UAAU,SACnB,OAAM,KAAK,GAAG,IAAI,KAAK,MAAM,QAAQ,MAAM,OAAM,CAAC,GAAG;UAC5C,OAAO,UAAU,YAAY,OAAO,UAAU,UACvD,OAAM,KAAK,GAAG,IAAI,IAAI,QAAQ;UACrB,MAAM,QAAQ,MAAM,EAAE;AAC/B,QAAM,KAAK,GAAG,IAAI,GAAG;AACrB,OAAK,MAAM,QAAQ,MACjB,OAAM,KAAK,QAAQ,OAAO,KAAK,CAAC,QAAQ,MAAM,OAAM,CAAC,GAAG;;AAI9D,OAAM,KAAK,MAAM;AACjB,QAAO,MAAM,KAAK,KAAK;;AAGzB,SAAS,yBAAyB,KAAiC;CACjE,MAAM,QAAkB,EAAE;AAC1B,OAAM,KAAK,OAAO,IAAI,KAAK,IAAI;AAC/B,KAAI,IAAI,KAAM,OAAM,KAAK,KAAK,IAAI,KAAK,IAAI;AAC3C,KAAI,IAAI,SAAU,OAAM,KAAK,eAAe;AAC5C,KAAI,IAAI,YAAY,KAAA,EAAW,OAAM,KAAK,gBAAgB,OAAO,IAAI,QAAQ,CAAC,IAAI;AAClF,KAAI,IAAI,YAAa,OAAM,KAAK,KAAK,IAAI,cAAc;AACvD,QAAO,MAAM,KAAK,IAAI;;AAGxB,SAAS,uBAAuB,KAAiC;CAC/D,MAAM,QAAkB,EAAE;CAE1B,MAAM,WAAW,KAAK,IAAI;CAG1B,MAAM,SAAS,UAFC,IAAI,OAAO,SAAS,GAAG,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,KACrE,IAAI,SAAS,SAAS,GAAG,IAAI,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,KAC9C,SAAS;AACvD,OAAM,KAAK,OAAO;AAClB,OAAM,KAAK,GAAG;AAEd,KAAI,IAAI,aAAa;AACnB,QAAM,KAAK,IAAI,YAAY;AAC3B,QAAM,KAAK,GAAG;;CAGhB,MAAM,OAAiB,EAAE;AACzB,KAAI,IAAI,QAAQ,IAAI,SAAS,UAAW,MAAK,KAAK,eAAe,IAAI,KAAK,IAAI;AAC9E,KAAI,CAAC,IAAI,SAAU,MAAK,KAAK,eAAe;AAC5C,KAAI,IAAI,YAAY,KAAA,EAAW,MAAK,KAAK,kBAAkB,OAAO,IAAI,QAAQ,CAAC,IAAI;AACnF,KAAI,IAAI,KAAM,MAAK,KAAK,gBAAgB,IAAI,KAAK,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,GAAG;AACrF,KAAI,IAAI,SAAU,MAAK,KAAK,iBAAiB;AAC7C,KAAI,IAAI,YAAY;EAClB,MAAM,MAAM,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAClE,OAAK,KAAK,iBAAiB,MAAM,KAAK,QAAQ,KAAK;;AAGrD,KAAI,KAAK,SAAS,GAAG;AACnB,QAAM,KAAK,KAAK,KAAK,MAAM,CAAC;AAC5B,QAAM,KAAK,GAAG;;AAGhB,KAAI,IAAI,KAAK;EACX,MAAM,UAAU,OAAO,IAAI,QAAQ,WAAW,CAAC,IAAI,IAAI,GAAG,IAAI;AAC9D,QAAM,KAAK,oBAAoB,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,GAAG;AAC3E,QAAM,KAAK,GAAG;;AAGhB,KAAI,IAAI,WAAW;AACjB,QAAM,KAAK,qBAAqB,IAAI,UAAU,IAAI;AAClD,QAAM,KAAK,GAAG;;AAGhB,KAAI,IAAI,UAAU,QAAQ;AACxB,QAAM,KAAK,iBAAiB,IAAI,SAAS,KAAK,MAAM,KAAK,OAAO,MAAM,WAAW,IAAI,KAAK,UAAU,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG;AACzH,QAAM,KAAK,GAAG;;AAGhB,QAAO;;AAGT,SAAS,yBAAyB,KAAiC;CACjE,MAAM,QAAkB,EAAE;CAC1B,MAAM,SAAS,IAAI,iBAAiB,SAAS;AAC7C,OAAM,KAAK,OAAO,IAAI,OAAO,OAAO,IAAI;CAExC,MAAM,UAAU,IAAI,SAAS,QAAQ,MAAM,MAAM,YAAY;AAC7D,OAAM,KAAK,KAAK,SAAS,SAAS,QAAQ,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,GAAG,KAAK;CAEnF,MAAM,OAAO,IAAI,SAAS,IAAI,eAAe;AAC7C,OAAM,KAAK,KAAK,OAAO;AACvB,OAAM,KAAK,IAAI;AAEf,QAAO,MAAM,KAAK,IAAI;;AAGxB,SAAS,qBAAqB,MAAgB,OAAe,eAAoD;CAC/G,MAAM,QAAkB,EAAE;AAE1B,KAAI,eAAe;EACjB,MAAM,KAAK,cAAc,MAAM,MAAM;AACrC,MAAI,OAAO,KAAK,GAAG,CAAC,SAAS,GAAG;AAC9B,SAAM,KAAK,oBAAoB,GAAG,CAAC;AACnC,SAAM,KAAK,GAAG;;;CAKlB,MAAM,cAAc,KAAK,SAAS,YAAY,CAAC,KAAK,OAAO,kBAAkB,KAAK;AAClF,OAAM,KAAK,KAAK,cAAc;AAC9B,OAAM,KAAK,GAAG;AAGd,KAAI,KAAK,YAAY;EACnB,MAAM,MAAM,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AACpE,QAAM,KAAK,qBAAqB,MAAM;AACtC,QAAM,KAAK,GAAG;;AAIhB,KAAI,KAAK,OAAO;AACd,QAAM,KAAK,KAAK,KAAK,QAAQ;AAC7B,QAAM,KAAK,GAAG;;AAEhB,KAAI,KAAK,aAAa;AACpB,QAAM,KAAK,KAAK,YAAY;AAC5B,QAAM,KAAK,GAAG;;AAIhB,KAAI,KAAK,SAAS,QAAQ;EACxB,MAAM,cAAc,KAAK,QAAQ,QAAQ,MAAM,MAAM,YAAY;AACjE,MAAI,YAAY,SAAS,GAAG;AAC1B,SAAM,KAAK,gBAAgB,YAAY,KAAK,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,GAAG;AAC3E,SAAM,KAAK,GAAG;;;CAKlB,MAAM,aAAuB,CAAC,KAAK,MAAM,QAAQ;AACjD,KAAI,KAAK,MAAM,eAAgB,YAAW,KAAK,YAAY;AAC3D,KAAI,KAAK,aAAa,OACpB,MAAK,MAAM,OAAO,KAAK,YACrB,YAAW,KAAK,IAAI,WAAW,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG;AAGrE,KAAI,KAAK,MAAM,aAAc,YAAW,KAAK,YAAY;AAEzD,OAAM,KAAK,WAAW;AACtB,OAAM,KAAK,GAAG;AACd,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,WAAW,KAAK,IAAI,CAAC;AAChC,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,GAAG;AAGd,KAAI,KAAK,UAAU,QAAQ;AACzB,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,MAAM;AACjB,OAAK,MAAM,MAAM,KAAK,SACpB,OAAM,KAAK,KAAK,KAAK;AAEvB,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,GAAG;;AAIhB,KAAI,KAAK,aAAa,QAAQ;EAC5B,MAAM,cAAc,KAAK,YAAY,QAAQ,MAAM,CAAC,EAAE,OAAO;AAC7D,MAAI,YAAY,SAAS,GAAG;AAC1B,SAAM,KAAK,cAAc;AACzB,SAAM,KAAK,GAAG;AACd,SAAM,KAAK,sCAAsC;AACjD,SAAM,KAAK,sBAAsB;AACjC,QAAK,MAAM,OAAO,YAChB,OAAM,KAAK,yBAAyB,IAAI,CAAC;AAE3C,SAAM,KAAK,GAAG;;;AAKlB,KAAI,KAAK,aAAa,QAAQ;AAC5B,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,GAAG;AACd,OAAK,MAAM,OAAO,KAAK,YACrB,OAAM,KAAK,yBAAyB,IAAI,CAAC;AAE3C,QAAM,KAAK,GAAG;;AAIhB,KAAI,KAAK,WAAW,QAAQ;AAC1B,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,GAAG;AACd,OAAK,MAAM,OAAO,KAAK,UACrB,OAAM,KAAK,GAAG,uBAAuB,IAAI,CAAC;;AAI9C,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;;AAOvC,SAAS,WAAW,MAAsB;AACxC,QAAO,KAAK,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,SAAS;;AAGxG,SAAS,iBAAiB,MAAgB,OAAuB;CAC/D,MAAM,cAAc,KAAK,SAAS,YAAY,CAAC,KAAK,OAAO,kBAAkB,WAAW,KAAK,KAAK;CAElG,MAAM,WAAqB,EAAE;AAG7B,UAAS,KAAK,oDAAoD,WAAW,KAAK,KAAK,CAAC,gBAAgB,MAAM,IAAI;AAClH,UAAS,KAAK,SAAS,YAAY,OAAO;AAE1C,KAAI,KAAK,YAAY;EACnB,MAAM,MAAM,OAAO,KAAK,eAAe,WAAW,WAAW,KAAK,WAAW,GAAG;AAChF,WAAS,KAAK,kEAAkE,IAAI,QAAQ;;AAG9F,KAAI,KAAK,MACP,UAAS,KAAK,8BAA8B,WAAW,KAAK,MAAM,CAAC,MAAM;AAE3E,KAAI,KAAK,YACP,UAAS,KAAK,oCAAoC,WAAW,KAAK,YAAY,CAAC,MAAM;AAIvF,KAAI,KAAK,SAAS,QAAQ;EACxB,MAAM,cAAc,KAAK,QAAQ,QAAQ,MAAM,MAAM,YAAY;AACjE,MAAI,YAAY,SAAS,EACvB,UAAS,KAAK,kCAAkC,YAAY,KAAK,MAAM,SAAS,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,MAAM;;CAK7H,MAAM,aAAuB,CAAC,KAAK,MAAM,QAAQ;AACjD,KAAI,KAAK,MAAM,eAAgB,YAAW,KAAK,YAAY;AAC3D,KAAI,KAAK,aAAa,OACpB,MAAK,MAAM,OAAO,KAAK,YACrB,YAAW,KAAK,IAAI,WAAW,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG;AAGrE,KAAI,KAAK,MAAM,aAAc,YAAW,KAAK,YAAY;AAEzD,UAAS,KAAK,mBAAmB;AACjC,UAAS,KAAK,gBAAgB,WAAW,WAAW,KAAK,IAAI,CAAC,CAAC,eAAe;AAG9E,KAAI,KAAK,UAAU,QAAQ;AACzB,WAAS,KAAK,sBAAsB;AACpC,WAAS,KAAK,gBAAgB,KAAK,SAAS,KAAK,OAAO,KAAK,WAAW,GAAG,GAAG,CAAC,KAAK,KAAK,CAAC,eAAe;;AAI3G,KAAI,KAAK,aAAa,QAAQ;EAC5B,MAAM,cAAc,KAAK,YAAY,QAAQ,MAAM,CAAC,EAAE,OAAO;AAC7D,MAAI,YAAY,SAAS,GAAG;AAC1B,YAAS,KAAK,sBAAsB;AACpC,YAAS,KAAK,YAAY;AAC1B,YAAS,KAAK,mFAAmF;AACjG,YAAS,KAAK,cAAc;AAC5B,QAAK,MAAM,OAAO,aAAa;IAC7B,MAAM,UAAU,IAAI,SAAS,QAAQ,MAAM,MAAM,YAAY;IAC7D,MAAM,OAAO,IAAI,SAAS,IAAI,eAAe;IAC7C,MAAM,SAAS,IAAI,iBAAiB,SAAS;AAC7C,aAAS,KACP,uBAAuB,WAAW,IAAI,OAAO,OAAO,CAAC,kBAAkB,SAAS,SAAS,QAAQ,KAAK,MAAM,SAAS,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,GAAG,GAAG,WAAW,WAAW,KAAK,CAAC,YAC1L;;AAEH,YAAS,KAAK,eAAe;AAC7B,YAAS,KAAK,aAAa;;;AAK/B,KAAI,KAAK,aAAa,QAAQ;AAC5B,WAAS,KAAK,uBAAuB;AACrC,WAAS,KAAK,SAAS;AACvB,OAAK,MAAM,OAAO,KAAK,aAAa;AAClC,YAAS,KACP,iBAAiB,WAAW,IAAI,KAAK,CAAC,SAAS,IAAI,OAAO,uBAAuB,WAAW,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,WAAW,yBAAyB,GAAG,OAClK;AACD,OAAI,IAAI,YAAa,UAAS,KAAK,WAAW,WAAW,IAAI,YAAY,CAAC,OAAO;AACjF,OAAI,IAAI,YAAY,KAAA,EAAW,UAAS,KAAK,0BAA0B,WAAW,OAAO,IAAI,QAAQ,CAAC,CAAC,cAAc;;AAEvH,WAAS,KAAK,UAAU;;AAI1B,KAAI,KAAK,WAAW,QAAQ;AAC1B,WAAS,KAAK,qBAAqB;AACnC,WAAS,KAAK,SAAS;AACvB,OAAK,MAAM,OAAO,KAAK,WAAW;GAChC,MAAM,WAAW,KAAK,IAAI;GAC1B,MAAM,UAAU,IAAI,OAAO,SAAS,GAAG,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM;GACtF,MAAM,WAAW,IAAI,SAAS,SAAS,GAAG,IAAI,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM;GAC5F,MAAM,WAAW,IAAI,QAAQ,IAAI,SAAS,YAAY,uBAAuB,WAAW,IAAI,KAAK,CAAC,WAAW;AAC7G,YAAS,KAAK,iBAAiB,WAAW,UAAU,WAAW,SAAS,CAAC,SAAS,SAAS,OAAO;AAClG,OAAI,IAAI,YAAa,UAAS,KAAK,WAAW,WAAW,IAAI,YAAY,CAAC,OAAO;GAEjF,MAAM,OAAiB,EAAE;AACzB,OAAI,CAAC,IAAI,SAAU,MAAK,KAAK,WAAW;AACxC,OAAI,IAAI,YAAY,KAAA,EAAW,MAAK,KAAK,kBAAkB,WAAW,OAAO,IAAI,QAAQ,CAAC,CAAC,SAAS;AACpG,OAAI,IAAI,KAAM,MAAK,KAAK,YAAY,IAAI,KAAK,KAAK,MAAM,SAAS,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,GAAG;AACtG,OAAI,IAAI,SAAU,MAAK,KAAK,aAAa;AACzC,OAAI,IAAI,YAAY;IAClB,MAAM,MAAM,OAAO,IAAI,eAAe,WAAW,WAAW,IAAI,WAAW,GAAG;AAC9E,SAAK,KAAK,aAAa,MAAM,KAAK,QAAQ,KAAK;;AAEjD,OAAI,KAAK,SAAS,EAAG,UAAS,KAAK,wBAAwB,KAAK,KAAK,MAAM,CAAC,OAAO;AAEnF,OAAI,IAAI,KAAK;IACX,MAAM,UAAU,OAAO,IAAI,QAAQ,WAAW,CAAC,IAAI,IAAI,GAAG,IAAI;AAC9D,aAAS,KAAK,wBAAwB,QAAQ,KAAK,MAAM,SAAS,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,CAAC,OAAO;;AAE9G,OAAI,IAAI,UACN,UAAS,KAAK,6BAA6B,WAAW,IAAI,UAAU,CAAC,cAAc;;AAGvF,WAAS,KAAK,UAAU;;AAG1B,UAAS,KAAK,aAAa;AAC3B,QAAO,GAAG,SAAS,KAAK,KAAK,CAAC;;AAOhC,SAAS,UAAU,MAAsB;AACvC,QAAO,KAAK,QAAQ,OAAO,OAAO,CAAC,QAAQ,MAAM,MAAM,CAAC,QAAQ,MAAM,QAAQ;;AAGhF,SAAS,gBAAgB,MAAgB,QAAgB,aAA6B;CACpF,MAAM,cAAc,KAAK,SAAS,YAAY,CAAC,KAAK,OAAO,cAAc,KAAK;CAC9E,MAAM,UAAU,YAAY,QAAQ,QAAQ,IAAI;CAChD,MAAM,QAAkB,EAAE;AAE1B,OAAM,KAAK,QAAQ,UAAU,QAAQ,aAAa,CAAC,CAAC,gBAAgB;AAGpE,OAAM,KAAK,WAAW;CACtB,MAAM,OAAO,KAAK,SAAS,KAAK,eAAe;AAC/C,OAAM,KAAK,GAAG,UAAU,QAAQ,GAAG,OAAO,QAAQ,UAAU,KAAK,KAAK,KAAK;AAG3E,OAAM,KAAK,eAAe;CAC1B,MAAM,aAAuB,CAAC,OAAO,UAAU,YAAY,CAAC,MAAM;AAClE,KAAI,KAAK,MAAM,eAAgB,YAAW,KAAK,oBAAoB;AACnE,KAAI,KAAK,aAAa,OACpB,MAAK,MAAM,OAAO,KAAK,YACrB,YAAW,KAAK,IAAI,WAAW,QAAQ,UAAU,IAAI,KAAK,CAAC,SAAS,OAAO,UAAU,IAAI,KAAK,CAAC,MAAM;AAGzG,KAAI,KAAK,MAAM,aAAc,YAAW,KAAK,oBAAoB;AACjE,OAAM,KAAK,WAAW,KAAK,IAAI,CAAC;AAGhC,KAAI,KAAK,aAAa;AACpB,QAAM,KAAK,kBAAkB;AAC7B,QAAM,KAAK,UAAU,KAAK,YAAY,CAAC;;AAIzC,KAAI,KAAK,UAAU,QAAQ;AACzB,QAAM,KAAK,eAAe;AAC1B,OAAK,MAAM,MAAM,KAAK,UAAU;AAC9B,SAAM,KAAK,MAAM;AACjB,SAAM,KAAK,UAAU,UAAU,GAAG,CAAC,OAAO;;;AAK9C,KAAI,KAAK,aAAa,QAAQ;EAC5B,MAAM,cAAc,KAAK,YAAY,QAAQ,MAAM,CAAC,EAAE,OAAO;AAC7D,MAAI,YAAY,SAAS,GAAG;AAC1B,SAAM,KAAK,eAAe;AAC1B,QAAK,MAAM,OAAO,aAAa;IAC7B,MAAM,SAAS,IAAI,iBAAiB,SAAS;AAC7C,UAAM,KAAK,MAAM;AACjB,UAAM,KAAK,OAAO,UAAU,IAAI,OAAO,OAAO,CAAC,MAAM;IACrD,MAAM,UAAU,IAAI,SAAS,IAAI;AACjC,QAAI,QAAS,OAAM,KAAK,UAAU,QAAQ,CAAC;;;;AAMjD,KAAI,KAAK,aAAa,QAAQ;AAC5B,QAAM,KAAK,gBAAgB;AAC3B,OAAK,MAAM,OAAO,KAAK,aAAa;AAClC,SAAM,KAAK,MAAM;AACjB,SAAM,KAAK,OAAO,UAAU,IAAI,KAAK,CAAC,MAAM;GAC5C,MAAM,QAAkB,EAAE;AAC1B,OAAI,IAAI,YAAa,OAAM,KAAK,UAAU,IAAI,YAAY,CAAC;AAC3D,OAAI,IAAI,SAAU,OAAM,KAAK,aAAa;AAC1C,OAAI,IAAI,YAAY,KAAA,EAAW,OAAM,KAAK,YAAY,UAAU,OAAO,IAAI,QAAQ,CAAC,GAAG;AACvF,OAAI,MAAM,SAAS,EAAG,OAAM,KAAK,MAAM,KAAK,KAAK,CAAC;;;AAKtD,KAAI,KAAK,WAAW,QAAQ;AAC1B,QAAM,KAAK,cAAc;AACzB,OAAK,MAAM,OAAO,KAAK,WAAW;GAChC,MAAM,WAAW,SAAS,UAAU,IAAI,KAAK;GAC7C,MAAM,UAAU,IAAI,OAAO,SAAS,GAAG,IAAI,MAAM,KAAK,MAAM,MAAM,UAAU,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM;GACnG,MAAM,WAAW,IAAI,SAAS,SAAS,GAAG,IAAI,QAAQ,KAAK,MAAM,SAAS,UAAU,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM;AAC3G,SAAM,KAAK,MAAM;AACjB,SAAM,KAAK,OAAO,UAAU,WAAW,SAAS,MAAM,IAAI,OAAO,QAAQ,UAAU,IAAI,KAAK,CAAC,QAAQ,KAAK;GAC1G,MAAM,QAAkB,EAAE;AAC1B,OAAI,IAAI,YAAa,OAAM,KAAK,UAAU,IAAI,YAAY,CAAC;AAC3D,OAAI,IAAI,YAAY,KAAA,EAAW,OAAM,KAAK,YAAY,UAAU,OAAO,IAAI,QAAQ,CAAC,GAAG;AACvF,OAAI,IAAI,KAAM,OAAM,KAAK,YAAY,IAAI,KAAK,KAAK,MAAM,UAAU,EAAE,CAAC,CAAC,KAAK,KAAK,GAAG;AACpF,OAAI,MAAM,SAAS,EAAG,OAAM,KAAK,MAAM,KAAK,KAAK,CAAC;AAElD,OAAI,IAAI,KAAK;IACX,MAAM,UAAU,OAAO,IAAI,QAAQ,WAAW,CAAC,IAAI,IAAI,GAAG,IAAI;AAC9D,UAAM,KAAK,MAAM;AACjB,UAAM,KAAK,gBAAgB,QAAQ,KAAK,MAAM,UAAU,EAAE,CAAC,CAAC,KAAK,KAAK,GAAG;;;;AAK/E,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC;;AAO7B,SAAS,cAAc,MAAgB,KAAa,QAAyB;AAC3E,KAAI,OAAQ,QAAO,QAAQ;AAG3B,QADiB,KAAK,KAAK,MAAM,MAAM,CAAC,KAAK,MAAM,KAAK,WAAW,CACnD,KAAK,IAAI,GAAG;;AAO9B,SAAS,sBAAsB,UAAoB,UAA8B;CAC/E,MAAM,QAAkB,EAAE;AAC1B,OAAM,KAAK,KAAK,SAAS,SAAS,SAAS,QAAQ,MAAM,YAAY;AACrE,OAAM,KAAK,GAAG;AAEd,KAAI,SAAS,aAAa;AACxB,QAAM,KAAK,SAAS,YAAY;AAChC,QAAM,KAAK,GAAG;;AAGhB,KAAI,SAAS,SAAS,GAAG;AACvB,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,GAAG;AACd,OAAK,MAAM,QAAQ,UAAU;GAC3B,MAAM,OAAO,cAAc,MAAM,OAAO,SAAS,SAAS;GAC1D,MAAM,OAAO,SAAS,WAAW,KAAK,QAAQ,SAAS,KAAK;GAC5D,MAAM,OAAO,KAAK,SAAS,KAAK,eAAe;AAC/C,SAAM,KAAK,MAAM,KAAK,IAAI,KAAK,GAAG,OAAO,MAAM,SAAS,KAAK;;AAE/D,QAAM,KAAK,GAAG;;AAGhB,QAAO,GAAG,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;;;;;;AAWvC,SAAgB,aAAa,SAAiB,UAAuB,EAAE,EAAc;CACnF,MAAM,EAAE,SAAS,YAAY,QAAQ,gBAAgB,OAAO,aAAa,YAAY,MAAM,SAAS,UAAU;CAE9G,MAAM,MAAM,WAAW,QAAQ;CAC/B,MAAM,WAAW,mBAAmB,KAAK,cAAc;CACvD,MAAM,WAAW,SAAS;CAC1B,MAAM,cAAc,IAAI,QAAQ;CAEhC,MAAM,QAAoB,EAAE;CAE5B,MAAM,MAAM,WAAW,aAAa,QAAQ,WAAW,SAAS,UAAU,WAAW,QAAQ,OAAO;AAEpG,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,OAAO,SAAS;EACtB,MAAM,SAAS,MAAM;EACrB,MAAM,QAAQ,SAAS,IAAI,KAAK,KAAK,MAAM,MAAM,CAAC;EAClD,MAAM,OAAO,cAAc,MAAM,KAAK,OAAO;EAE7C,IAAI;AACJ,UAAQ,QAAR;GACE,KAAK;AACH,cAAU,qBAAqB,MAAM,OAAO,YAAY;AACxD;GACF,KAAK;AACH,cAAU,iBAAiB,MAAM,MAAM;AACvC;GACF,KAAK;AACH,cAAU,gBAAgB,MAAM,OAAO,YAAY;AACnD;GACF,KAAK;AACH,cAAU,GAAG,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAC3C;;AAGJ,QAAM,KAAK;GAAE;GAAM;GAAS,SAAS,KAAK;GAAM,CAAC;;AAInD,KAAI,WAAW,cAAc,SAAS,SAAS,GAAG;EAEhD,MAAM,WAAW,MAAM;AACvB,WAAS,UAAU,sBAAsB,UAAU,SAAS;;CAG9D,MAAM,SAAqB;EAAE;EAAO,SAAS,EAAE;EAAE,SAAS,EAAE;EAAE,QAAQ,EAAE;EAAE;AAG1E,KAAI,QAAQ;EACV,MAAM,SAAS,QAAQ,OAAO;AAE9B,OAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,WAAW,KAAK,QAAQ,KAAK,KAAK;AAExC,OAAI;AACF,QAAI,WAAW,SAAS,IAAI,CAAC,WAAW;AACtC,YAAO,QAAQ,KAAK,KAAK,KAAK;AAC9B;;AAGF,QAAI,QAAQ;AACV,YAAO,QAAQ,KAAK,KAAK,KAAK;AAC9B;;AAIF,cADY,QAAQ,SAAS,EACd,EAAE,WAAW,MAAM,CAAC;AACnC,kBAAc,UAAU,KAAK,SAAS,QAAQ;AAC9C,WAAO,QAAQ,KAAK,KAAK,KAAK;YACvB,KAAK;AACZ,WAAO,OAAO,KAAK;KACjB,MAAM,KAAK;KACX,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;KAC3D,CAAC;;;;AAKR,QAAO;;;;;;AAoBT,SAAS,cAAc,UAAU,GAAW;CAC1C,MAAM,EAAE,YAAA,UAAoB,UAAU;CACtC,MAAM,EAAE,MAAM,aAAA,UAAqB,YAAY;AAC/C,QAAO,SAAS,QAAQ,IAAI,iBAAiB,SAAS,SAAS,EAAE,UAAU,QAAQ,EAAE,OAAO,MAAM,UAAU;;;;;;AAO9G,SAAS,gBAAgB,aAAqB,UAAU,GAAW;AACjE,QAAO,GAAG,YAAY,QAAQ,QAAQ,IAAI,CAAC,GAAG;;;;;;;;;AAUhD,SAAgB,cAAc,SAAsC;CAClE,MAAM,MAAM,WAAW,QAAQ;CAC/B,MAAM,WAAW,mBAAmB,KAAK,MAAM;CAC/C,MAAM,cAAc,IAAI,QAAQ;CAChC,MAAM,SAAS,cAAc,EAAE;AAE/B,WAAU,QAAQ,EAAE,WAAW,MAAM,CAAC;CAEtC,MAAM,UAAoB,EAAE;CAC5B,IAAI,UAAU;AAEd,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,OAAO,SAAS;EACtB,MAAM,QAAQ,MAAM,IAAI,IAAI,KAAK,KAAK,MAAM,MAAM,CAAC;EAEnD,MAAM,WAAW,gBADG,KAAK,SAAS,YAAY,CAAC,KAAK,OAAO,cAAc,KAAK,KACjC;EAC7C,MAAM,WAAW,KAAK,QAAQ,SAAS;AAEvC,MAAI,WAAW,SAAS,CAAE,WAAU;AAGpC,gBAAc,UADE,gBAAgB,MAAM,OAAO,YAAY,EACxB,QAAQ;AACzC,UAAQ,KAAK,SAAS;;AAGxB,QAAO;EAAE,KAAK;EAAQ;EAAS;EAAS;;;;;AAM1C,SAAgB,eAAe,SAAqD;CAClF,MAAM,EAAE,eAAA,UAAuB,UAAU;CACzC,MAAM,MAAM,WAAW,QAAQ;CAC/B,MAAM,WAAW,mBAAmB,KAAK,MAAM;CAC/C,MAAM,cAAc,IAAI,QAAQ;CAChC,MAAM,SAAS,cAAc,EAAE;CAC/B,MAAM,UAAoB,EAAE;AAE5B,MAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACxC,MAAM,OAAO,SAAS;EAEtB,MAAM,WAAW,gBADG,KAAK,SAAS,YAAY,CAAC,KAAK,OAAO,cAAc,KAAK,KACjC;EAC7C,MAAM,WAAW,KAAK,QAAQ,SAAS;AAEvC,MAAI,WAAW,SAAS,EAAE;AACxB,cAAW,SAAS;AACpB,WAAQ,KAAK,SAAS;;;AAI1B,QAAO;EAAE,KAAK;EAAQ;EAAS"}
|
|
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 '../core/commands.ts';\nimport type { HelpArgumentInfo, HelpInfo, HelpPositionalInfo, HelpSubcommandInfo } from '../output/formatter.ts';\nimport { getHelpInfo } from '../output/help.ts';\nimport type { AnyPadroneCommand } from '../types/index.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 */\nasync function getManPageDir(section = 1): Promise<string> {\n const { homedir } = await import('node:os');\n return join(process.env.XDG_DATA_HOME || join(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 async function setupManPages(program: object): Promise<SetupManPagesResult> {\n const cmd = getCommand(program);\n const allInfos = collectAllHelpInfo(cmd, false);\n const programName = cmd.name || 'program';\n const manDir = await 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 async function removeManPages(program: object): Promise<{ dir: string; removed: string[] }> {\n const { unlinkSync } = await import('node:fs');\n const cmd = getCommand(program);\n const allInfos = collectAllHelpInfo(cmd, false);\n const programName = cmd.name || 'program';\n const manDir = await 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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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/errors.ts
|
|
1
|
+
//#region src/core/errors.ts
|
|
2
2
|
/**
|
|
3
3
|
* Base error class for all Padrone errors.
|
|
4
4
|
* Carries structured metadata for user-friendly formatting and programmatic handling.
|
|
@@ -108,7 +108,30 @@ var ActionError = class extends PadroneError {
|
|
|
108
108
|
this.name = "ActionError";
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Thrown when command execution is interrupted by a process signal (SIGINT, SIGTERM, SIGHUP).
|
|
113
|
+
* Carries the signal name and the conventional exit code (128 + signal number).
|
|
114
|
+
*/
|
|
115
|
+
var SignalError = class extends PadroneError {
|
|
116
|
+
signal;
|
|
117
|
+
constructor(signal, options) {
|
|
118
|
+
super(`Process interrupted by ${signal}`, {
|
|
119
|
+
exitCode: signalExitCode(signal),
|
|
120
|
+
cause: options?.cause
|
|
121
|
+
});
|
|
122
|
+
this.name = "SignalError";
|
|
123
|
+
this.signal = signal;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
/** Maps a signal name to its conventional exit code (128 + signal number). */
|
|
127
|
+
function signalExitCode(signal) {
|
|
128
|
+
return {
|
|
129
|
+
SIGINT: 130,
|
|
130
|
+
SIGTERM: 143,
|
|
131
|
+
SIGHUP: 129
|
|
132
|
+
}[signal] ?? 1;
|
|
133
|
+
}
|
|
111
134
|
//#endregion
|
|
112
|
-
export {
|
|
135
|
+
export { SignalError as a, RoutingError as i, ConfigError as n, ValidationError as o, PadroneError as r, signalExitCode as s, ActionError as t };
|
|
113
136
|
|
|
114
|
-
//# sourceMappingURL=errors-
|
|
137
|
+
//# sourceMappingURL=errors-DA4KzK1M.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-DA4KzK1M.mjs","names":[],"sources":["../src/core/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\nimport type { PadroneSignal } from './runtime.ts';\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\n/**\n * Thrown when command execution is interrupted by a process signal (SIGINT, SIGTERM, SIGHUP).\n * Carries the signal name and the conventional exit code (128 + signal number).\n */\nexport class SignalError extends PadroneError {\n readonly signal: PadroneSignal;\n\n constructor(signal: PadroneSignal, options?: { cause?: unknown }) {\n super(`Process interrupted by ${signal}`, { exitCode: signalExitCode(signal), cause: options?.cause });\n this.name = 'SignalError';\n this.signal = signal;\n }\n}\n\n/** Maps a signal name to its conventional exit code (128 + signal number). */\nexport function signalExitCode(signal: PadroneSignal): number {\n const codes: Record<string, number> = { SIGINT: 130, SIGTERM: 143, SIGHUP: 129 };\n return codes[signal] ?? 1;\n}\n"],"mappings":";;;;;;;;;;;;;AAoCA,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;;;;;;;AAQhB,IAAa,cAAb,cAAiC,aAAa;CAC5C;CAEA,YAAY,QAAuB,SAA+B;AAChE,QAAM,0BAA0B,UAAU;GAAE,UAAU,eAAe,OAAO;GAAE,OAAO,SAAS;GAAO,CAAC;AACtG,OAAK,OAAO;AACZ,OAAK,SAAS;;;;AAKlB,SAAgB,eAAe,QAA+B;AAE5D,QADsC;EAAE,QAAQ;EAAK,SAAS;EAAK,QAAQ;EAAK,CACnE,WAAW"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/colorizer.d.ts
|
|
1
|
+
//#region src/output/colorizer.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* Available ANSI styles that can be combined for each color role.
|
|
4
4
|
*/
|
|
@@ -24,7 +24,7 @@ type ColorConfig = {
|
|
|
24
24
|
type ColorTheme = 'default' | 'ocean' | 'warm' | 'monochrome';
|
|
25
25
|
declare const colorThemes: Record<ColorTheme, Required<ColorConfig>>;
|
|
26
26
|
//#endregion
|
|
27
|
-
//#region src/formatter.d.ts
|
|
27
|
+
//#region src/output/formatter.d.ts
|
|
28
28
|
type HelpFormat = 'text' | 'ansi' | 'console' | 'markdown' | 'html' | 'json';
|
|
29
29
|
type HelpDetail = 'minimal' | 'standard' | 'full';
|
|
30
30
|
/**
|
|
@@ -110,4 +110,4 @@ type HelpInfo = {
|
|
|
110
110
|
};
|
|
111
111
|
//#endregion
|
|
112
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-
|
|
113
|
+
//# sourceMappingURL=formatter-DrvhDMrq.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter-DrvhDMrq.d.mts","names":[],"sources":["../src/output/colorizer.ts","../src/output/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;;;KCxG1C,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,aDFA;ECIA,KAAA,aDHA;ECKA,OAAA;EACA,UAAA;EACA,MAAA;EACA,QAAA,cDNO;ECQP,GAAA,sBDPU;ECSV,QAAA,YDRe;ECUf,SAAA,YDTa;ECWb,SAAA,WDXsB;ECatB,KAAA;AAAA;;;;KAMU,kBAAA;EACV,IAAA;EACA,KAAA;EACA,WAAA;EACA,OAAA;EACA,UAAA;EACA,MAAA;EACA,cAAA,YD8C8B;EC5C9B,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"}
|