| 7 | import { collectCommands, findSuggestions, resolveCommand } from './registry' |
| 8 | |
| 9 | export async function run(tree: CommandTree, argv: string[]): Promise<void> { |
| 10 | if (argv.length === 0 || argv[0] === 'help' || argv.includes('--help') || argv.includes('-h')) { |
| 11 | const format = sniffOutputFormat(argv) |
| 12 | // The command/topic path is the leading positional run; stop at the first |
| 13 | // flag so output flags like `-o json` never leak into resolution. |
| 14 | const helpArgv: string[] = [] |
| 15 | |
| 16 | for (const a of argv) { |
| 17 | if (a === 'help' || a === '--help' || a === '-h') |
| 18 | continue |
| 19 | if (a.startsWith('-')) |
| 20 | break |
| 21 | helpArgv.push(a) |
| 22 | } |
| 23 | |
| 24 | if (helpArgv.length > 0) { |
| 25 | const resolved = resolveCommand(tree, helpArgv) |
| 26 | |
| 27 | if (resolved) { |
| 28 | const out = formatHelp(resolved.command, resolved.path.join(' '), format) |
| 29 | process.stdout.write(isStructuredFormat(format) ? out : `${out}\n`) |
| 30 | |
| 31 | return |
| 32 | } |
| 33 | |
| 34 | const first = helpArgv[0] |
| 35 | |
| 36 | if (helpArgv.length === 1 && first !== undefined) { |
| 37 | const topic = findTopic(first) |
| 38 | |
| 39 | if (topic) { |
| 40 | process.stdout.write(formatTopic(topic, format)) |
| 41 | |
| 42 | return |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | // Namespace drill-in: `difyctl auth --help` / `difyctl auth devices --help`. |
| 47 | // Group nodes have no command of their own (no index.ts), so resolveCommand |
| 48 | // misses them; surface their subtree instead of erroring. A strict-prefix |
| 49 | // match over the full-depth command walk keeps this purely derived. |
| 50 | const subtree = collectCommands(tree).filter( |
| 51 | c => c.path.length > helpArgv.length && helpArgv.every((token, i) => c.path[i] === token), |
| 52 | ) |
| 53 | |
| 54 | if (subtree.length > 0) { |
| 55 | process.stdout.write(formatCommandList(subtree, format)) |
| 56 | |
| 57 | return |
| 58 | } |
| 59 | |
| 60 | process.stderr.write(`unknown help topic: ${helpArgv.join(' ')}\n`) |
| 61 | const suggestions = findSuggestions(tree, helpArgv) |
| 62 | |
| 63 | if (suggestions.length > 0) { |
| 64 | process.stderr.write('\nDid you mean:\n') |
| 65 | |
| 66 | for (const s of suggestions.slice(0, 5)) |