padrone 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +94 -0
- package/README.md +105 -284
- package/dist/{args-DFEI7_G_.mjs → args-D5PNDyNu.mjs} +46 -21
- package/dist/args-D5PNDyNu.mjs.map +1 -0
- package/dist/chunk-CjcI7cDX.mjs +15 -0
- package/dist/codegen/index.d.mts +28 -3
- package/dist/codegen/index.d.mts.map +1 -1
- package/dist/codegen/index.mjs +169 -19
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/command-utils-B1D-HqCd.mjs +1117 -0
- package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
- package/dist/completion.d.mts +1 -1
- package/dist/completion.d.mts.map +1 -1
- package/dist/completion.mjs +77 -29
- package/dist/completion.mjs.map +1 -1
- package/dist/docs/index.d.mts +22 -2
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +94 -7
- package/dist/docs/index.mjs.map +1 -1
- package/dist/errors-BiVrBgi6.mjs +114 -0
- package/dist/errors-BiVrBgi6.mjs.map +1 -0
- package/dist/{formatter-XroimS3Q.d.mts → formatter-DtHzbP22.d.mts} +35 -5
- package/dist/formatter-DtHzbP22.d.mts.map +1 -0
- package/dist/help-bbmu9-qd.mjs +735 -0
- package/dist/help-bbmu9-qd.mjs.map +1 -0
- package/dist/index.d.mts +32 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +495 -267
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-mLWIdUIu.mjs +379 -0
- package/dist/mcp-mLWIdUIu.mjs.map +1 -0
- package/dist/serve-B0u43DK7.mjs +404 -0
- package/dist/serve-B0u43DK7.mjs.map +1 -0
- package/dist/stream-BcC146Ud.mjs +56 -0
- package/dist/stream-BcC146Ud.mjs.map +1 -0
- package/dist/test.d.mts +1 -1
- package/dist/test.mjs +4 -15
- package/dist/test.mjs.map +1 -1
- package/dist/{types-BS7RP5Ls.d.mts → types-Ch8Mk6Qb.d.mts} +311 -63
- package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
- package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
- package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
- package/dist/zod.d.mts +32 -0
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +50 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +10 -2
- package/src/args.ts +76 -44
- package/src/cli/docs.ts +1 -7
- package/src/cli/doctor.ts +195 -10
- package/src/cli/index.ts +1 -1
- package/src/cli/init.ts +2 -3
- package/src/cli/link.ts +2 -2
- package/src/codegen/discovery.ts +80 -28
- package/src/codegen/index.ts +2 -1
- package/src/codegen/parsers/bash.ts +179 -0
- package/src/codegen/schema-to-code.ts +2 -1
- package/src/colorizer.ts +126 -13
- package/src/command-utils.ts +401 -23
- package/src/completion.ts +120 -47
- package/src/create.ts +483 -130
- package/src/docs/index.ts +122 -8
- package/src/formatter.ts +173 -125
- package/src/help.ts +46 -12
- package/src/index.ts +29 -1
- package/src/interactive.ts +45 -4
- package/src/mcp.ts +390 -0
- package/src/repl-loop.ts +16 -3
- package/src/runtime.ts +195 -2
- package/src/serve.ts +442 -0
- package/src/stream.ts +75 -0
- package/src/test.ts +7 -16
- package/src/type-utils.ts +28 -4
- package/src/types.ts +212 -30
- package/src/wrap.ts +23 -25
- package/src/zod.ts +50 -0
- package/dist/args-DFEI7_G_.mjs.map +0 -1
- package/dist/chunk-y_GBKt04.mjs +0 -5
- package/dist/formatter-XroimS3Q.d.mts.map +0 -1
- package/dist/help-CgGP7hQU.mjs +0 -1229
- package/dist/help-CgGP7hQU.mjs.map +0 -1
- package/dist/types-BS7RP5Ls.d.mts.map +0 -1
package/src/docs/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { getCommand } from '../command-utils.ts';
|
|
4
4
|
import type { HelpArgumentInfo, HelpInfo, HelpPositionalInfo, HelpSubcommandInfo } from '../formatter.ts';
|
|
5
5
|
import { getHelpInfo } from '../help.ts';
|
|
6
6
|
import type { AnyPadroneCommand } from '../types.ts';
|
|
@@ -220,6 +220,18 @@ function generateMarkdownPage(info: HelpInfo, depth: number, frontmatterFn?: Doc
|
|
|
220
220
|
lines.push('```');
|
|
221
221
|
lines.push('');
|
|
222
222
|
|
|
223
|
+
// Examples
|
|
224
|
+
if (info.examples?.length) {
|
|
225
|
+
lines.push('## Examples');
|
|
226
|
+
lines.push('');
|
|
227
|
+
lines.push('```');
|
|
228
|
+
for (const ex of info.examples) {
|
|
229
|
+
lines.push(`$ ${ex}`);
|
|
230
|
+
}
|
|
231
|
+
lines.push('```');
|
|
232
|
+
lines.push('');
|
|
233
|
+
}
|
|
234
|
+
|
|
223
235
|
// Subcommands
|
|
224
236
|
if (info.subcommands?.length) {
|
|
225
237
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
@@ -307,6 +319,12 @@ function generateHtmlPage(info: HelpInfo, depth: number): string {
|
|
|
307
319
|
sections.push(' <h2>Usage</h2>');
|
|
308
320
|
sections.push(` <pre><code>${escapeHtml(usageParts.join(' '))}</code></pre>`);
|
|
309
321
|
|
|
322
|
+
// Examples
|
|
323
|
+
if (info.examples?.length) {
|
|
324
|
+
sections.push(' <h2>Examples</h2>');
|
|
325
|
+
sections.push(` <pre><code>${info.examples.map((ex) => `$ ${escapeHtml(ex)}`).join('\n')}</code></pre>`);
|
|
326
|
+
}
|
|
327
|
+
|
|
310
328
|
// Subcommands
|
|
311
329
|
if (info.subcommands?.length) {
|
|
312
330
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
@@ -381,7 +399,7 @@ function generateHtmlPage(info: HelpInfo, depth: number): string {
|
|
|
381
399
|
}
|
|
382
400
|
|
|
383
401
|
// ============================================================================
|
|
384
|
-
// Man Page Generator
|
|
402
|
+
// Man Page Generator (experimental)
|
|
385
403
|
// ============================================================================
|
|
386
404
|
|
|
387
405
|
function escapeMan(text: string): string {
|
|
@@ -418,6 +436,15 @@ function generateManPage(info: HelpInfo, _depth: number, programName: string): s
|
|
|
418
436
|
lines.push(escapeMan(info.description));
|
|
419
437
|
}
|
|
420
438
|
|
|
439
|
+
// EXAMPLES
|
|
440
|
+
if (info.examples?.length) {
|
|
441
|
+
lines.push('.SH EXAMPLES');
|
|
442
|
+
for (const ex of info.examples) {
|
|
443
|
+
lines.push('.PP');
|
|
444
|
+
lines.push(`.nf\n$ ${escapeMan(ex)}\n.fi`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
421
448
|
// COMMANDS
|
|
422
449
|
if (info.subcommands?.length) {
|
|
423
450
|
const visibleSubs = info.subcommands.filter((s) => !s.hidden);
|
|
@@ -517,11 +544,6 @@ function generateMarkdownIndex(rootInfo: HelpInfo, allInfos: HelpInfo[]): string
|
|
|
517
544
|
// Main Entry Point
|
|
518
545
|
// ============================================================================
|
|
519
546
|
|
|
520
|
-
function resolveCommand(programOrCommand: object): AnyPadroneCommand {
|
|
521
|
-
if (commandSymbol in programOrCommand) return (programOrCommand as any)[commandSymbol] as AnyPadroneCommand;
|
|
522
|
-
return programOrCommand as AnyPadroneCommand;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
547
|
/**
|
|
526
548
|
* Generate documentation for a Padrone CLI program or command tree.
|
|
527
549
|
* Accepts either a PadroneProgram (from createPadrone()) or a raw AnyPadroneCommand.
|
|
@@ -529,7 +551,7 @@ function resolveCommand(programOrCommand: object): AnyPadroneCommand {
|
|
|
529
551
|
export function generateDocs(program: object, options: DocsOptions = {}): DocsResult {
|
|
530
552
|
const { format = 'markdown', output, includeHidden = false, frontmatter, overwrite = true, dryRun = false } = options;
|
|
531
553
|
|
|
532
|
-
const cmd =
|
|
554
|
+
const cmd = getCommand(program);
|
|
533
555
|
const allInfos = collectAllHelpInfo(cmd, includeHidden);
|
|
534
556
|
const rootInfo = allInfos[0]!;
|
|
535
557
|
const programName = cmd.name || 'program';
|
|
@@ -605,3 +627,95 @@ export function generateDocs(program: object, options: DocsOptions = {}): DocsRe
|
|
|
605
627
|
|
|
606
628
|
return result;
|
|
607
629
|
}
|
|
630
|
+
|
|
631
|
+
// ============================================================================
|
|
632
|
+
// Man Page Installation
|
|
633
|
+
// ============================================================================
|
|
634
|
+
|
|
635
|
+
export type SetupManPagesResult = {
|
|
636
|
+
/** Directory where man pages were written. */
|
|
637
|
+
dir: string;
|
|
638
|
+
/** Man page files that were written. */
|
|
639
|
+
written: string[];
|
|
640
|
+
/** Whether existing pages were overwritten (true) or newly created (false). */
|
|
641
|
+
updated: boolean;
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Returns the local man page directory for the given section.
|
|
646
|
+
* Uses `~/.local/share/man/man<section>` (XDG convention).
|
|
647
|
+
*/
|
|
648
|
+
function getManPageDir(section = 1): string {
|
|
649
|
+
const { homedir } = require('node:os') as typeof import('node:os');
|
|
650
|
+
const { join: joinPath } = require('node:path') as typeof import('node:path');
|
|
651
|
+
return joinPath(process.env.XDG_DATA_HOME || joinPath(homedir(), '.local', 'share'), 'man', `man${section}`);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Converts a command name to a man page filename.
|
|
656
|
+
* "myapp" → "myapp.1", "myapp deploy" → "myapp-deploy.1"
|
|
657
|
+
*/
|
|
658
|
+
function manPageFilename(commandName: string, section = 1): string {
|
|
659
|
+
return `${commandName.replace(/\s+/g, '-')}.${section}`;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Installs man pages for a Padrone CLI program into the local man directory.
|
|
664
|
+
* Generates man pages for all commands and writes them to `~/.local/share/man/man1/`.
|
|
665
|
+
*
|
|
666
|
+
* After installation, `man <program>` and `man <program>-<subcommand>` should work
|
|
667
|
+
* (assuming `~/.local/share/man` is in `MANPATH` or `manpath` picks it up).
|
|
668
|
+
*/
|
|
669
|
+
export function setupManPages(program: object): SetupManPagesResult {
|
|
670
|
+
const cmd = getCommand(program);
|
|
671
|
+
const allInfos = collectAllHelpInfo(cmd, false);
|
|
672
|
+
const programName = cmd.name || 'program';
|
|
673
|
+
const manDir = getManPageDir(1);
|
|
674
|
+
|
|
675
|
+
mkdirSync(manDir, { recursive: true });
|
|
676
|
+
|
|
677
|
+
const written: string[] = [];
|
|
678
|
+
let updated = false;
|
|
679
|
+
|
|
680
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
681
|
+
const info = allInfos[i]!;
|
|
682
|
+
const depth = i === 0 ? 0 : info.name.split(/\s+/).length;
|
|
683
|
+
const commandName = info.name === '<root>' || !info.name ? programName : info.name;
|
|
684
|
+
const filename = manPageFilename(commandName);
|
|
685
|
+
const fullPath = join(manDir, filename);
|
|
686
|
+
|
|
687
|
+
if (existsSync(fullPath)) updated = true;
|
|
688
|
+
|
|
689
|
+
const content = generateManPage(info, depth, programName);
|
|
690
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
691
|
+
written.push(filename);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
return { dir: manDir, written, updated };
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Removes installed man pages for a Padrone CLI program.
|
|
699
|
+
*/
|
|
700
|
+
export function removeManPages(program: object): { dir: string; removed: string[] } {
|
|
701
|
+
const { unlinkSync } = require('node:fs') as typeof import('node:fs');
|
|
702
|
+
const cmd = getCommand(program);
|
|
703
|
+
const allInfos = collectAllHelpInfo(cmd, false);
|
|
704
|
+
const programName = cmd.name || 'program';
|
|
705
|
+
const manDir = getManPageDir(1);
|
|
706
|
+
const removed: string[] = [];
|
|
707
|
+
|
|
708
|
+
for (let i = 0; i < allInfos.length; i++) {
|
|
709
|
+
const info = allInfos[i]!;
|
|
710
|
+
const commandName = info.name === '<root>' || !info.name ? programName : info.name;
|
|
711
|
+
const filename = manPageFilename(commandName);
|
|
712
|
+
const fullPath = join(manDir, filename);
|
|
713
|
+
|
|
714
|
+
if (existsSync(fullPath)) {
|
|
715
|
+
unlinkSync(fullPath);
|
|
716
|
+
removed.push(filename);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
return { dir: manDir, removed };
|
|
721
|
+
}
|