MCPcopy
hub / github.com/jackwener/OpenCLI / createProgram

Function createProgram

src/cli.ts:693–3586  ·  view source on GitHub ↗
(BUILTIN_CLIS: string, USER_CLIS: string)

Source from the content-addressed store, hash-verified

691}
692
693export function createProgram(BUILTIN_CLIS: string, USER_CLIS: string): Command {
694 const program = new Command();
695 // enablePositionalOptions: prevents parent from consuming flags meant for subcommands;
696 // prerequisite for passThroughOptions to forward --help/--version to external binaries
697 program
698 .name('opencli')
699 .description('Make any website your CLI. Zero setup. AI-powered.')
700 .version(PKG_VERSION)
701 .option('--profile <name>', 'Chrome profile/context alias for Browser Bridge commands')
702 .enablePositionalOptions();
703
704 // ── Built-in: list ────────────────────────────────────────────────────────
705
706 program
707 .command('list')
708 .description('List all available CLI commands')
709 .option('-f, --format <fmt>', 'Output format: table, json, yaml, md, csv', 'table')
710 .action((opts) => {
711 const registry = getRegistry();
712 const commands = [...new Set(registry.values())].sort((a, b) => fullName(a).localeCompare(fullName(b)));
713 const fmt = opts.format;
714 const isStructured = fmt === 'json' || fmt === 'yaml';
715
716 if (fmt !== 'table') {
717 const rows = isStructured
718 ? commands.map(serializeCommand)
719 : commands.map(c => ({
720 command: fullName(c),
721 site: c.site,
722 name: c.name,
723 aliases: c.aliases?.join(', ') ?? '',
724 description: c.description,
725 access: c.access,
726 strategy: strategyLabel(c),
727 browser: !!c.browser,
728 args: formatArgSummary(c.args),
729 }));
730 renderOutput(rows, {
731 fmt,
732 columns: ['command', 'site', 'name', 'aliases', 'description', 'access', 'strategy', 'browser', 'args',
733 ...(isStructured ? ['columns', 'domain'] : [])],
734 title: 'opencli/list',
735 source: 'opencli list',
736 });
737 return;
738 }
739
740 // Table (default) — grouped by adapter kind (app vs site), then by site name.
741 // classifyAdapter() reads the `domain` field: DNS-style domains are sites;
742 // localhost/loopback endpoints and bare app names are apps.
743 const appsBySite = new Map<string, CliCommand[]>();
744 const sitesBySite = new Map<string, CliCommand[]>();
745 for (const cmd of commands) {
746 const target = classifyAdapter(cmd.domain) === 'app' ? appsBySite : sitesBySite;
747 const g = target.get(cmd.site) ?? [];
748 g.push(cmd);
749 target.set(cmd.site, g);
750 }

Callers 2

cli.test.tsFile · 0.85
runCliFunction · 0.85

Calls 15

connectMethod · 0.95
getRegistryFunction · 0.85
fullNameFunction · 0.85
strategyLabelFunction · 0.85
formatArgSummaryFunction · 0.85
classifyAdapterFunction · 0.85
renderSiteGroupFunction · 0.85
loadExternalClisFunction · 0.85
isBinaryInstalledFunction · 0.85
formatExternalCliLabelFunction · 0.85
renderValidationReportFunction · 0.85
validateClisWithTargetFunction · 0.85

Tested by

no test coverage detected