@crafter/cli-tree 0.1.2 → 0.2.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/dist/{chunk-dnq2rnr7.js → chunk-9pnqbn7b.js} +224 -3
- package/dist/{chunk-dnq2rnr7.js.map → chunk-9pnqbn7b.js.map} +7 -4
- package/dist/cli.js +351 -20
- package/dist/cli.js.map +3 -3
- package/dist/miner/activity.d.ts +21 -0
- package/dist/miner/cross-cli.d.ts +55 -0
- package/dist/miner/index.d.ts +6 -2
- package/dist/miner/index.js +14 -2
- package/dist/miner/index.js.map +1 -1
- package/dist/miner/sparkline.d.ts +14 -0
- package/package.json +1 -1
- package/skill/SKILL.md +69 -8
- package/src/cli.ts +401 -21
- package/src/miner/activity.ts +71 -0
- package/src/miner/cross-cli.ts +216 -0
- package/src/miner/index.ts +28 -1
- package/src/miner/sparkline.ts +31 -0
package/dist/cli.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/cli.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"#!/usr/bin/env bun\nimport { parseHelpRecursive, parseHelp } from \"./parse\";\nimport { printTree, treeToString, treeToHtml } from \"./index\";\nimport type { TreeOptions } from \"./types\";\nimport { parseWorkflow, validateWorkflow, flowToAnsi, flowToString, flowToHtml } from \"./flow\";\nimport type { FlowRenderOptions } from \"./flow/types\";\nimport { mineCli, minedToFlowWorkflow } from \"./miner\";\nimport { runArchaeology, NullDelegate } from \"./archaeology\";\n\nconst args = process.argv.slice(2);\nconst subcommand = args[0];\n\nconst HELP_SUBCOMMANDS = new Set([\"flow\", \"mine\", \"archaeology\"]);\nconst isHelpFlag = args.includes(\"--help\") || args.includes(\"-h\");\n\nif (!subcommand || (isHelpFlag && !HELP_SUBCOMMANDS.has(subcommand ?? \"\"))) {\n\tprintMainHelp();\n\tprocess.exit(0);\n}\n\nif (isHelpFlag) {\n\tif (subcommand === \"flow\") printFlowHelp();\n\telse if (subcommand === \"mine\") printMineHelp();\n\telse if (subcommand === \"archaeology\") printArchaeologyHelp();\n\telse printMainHelp();\n\tprocess.exit(0);\n}\n\nif (subcommand === \"flow\") {\n\tawait runFlow(args.slice(1));\n} else if (subcommand === \"mine\") {\n\tawait runMine(args.slice(1));\n} else if (subcommand === \"archaeology\") {\n\tawait runArchaeologyCmd(args.slice(1));\n} else {\n\tawait runTree(args);\n}\n\nfunction printMainHelp() {\n\tconsole.log(`\n clitree — Visualize and explore any CLI\n\n Usage:\n clitree <binary> [options] Render command tree from --help\n clitree flow <file> [options] Render a workflow YAML as a DAG\n clitree mine <binary> [options] Mine shell history for workflows\n clitree archaeology <binary> [options] Full analysis: tree + mining + (LLM)\n\n Examples:\n clitree docker # basic tree\n clitree mine git # \"what workflows do I repeat with git?\"\n clitree archaeology bun # tree + mining + LLM archaeology\n\n Subcommands:\n tree Parse --help output (default; passing a binary name invokes this)\n flow Render a workflow YAML file as an ASCII DAG\n mine Discover workflows from your shell history\n archaeology Run full analysis (tree + mine + LLM proposals when available)\n\n Help for a subcommand: clitree <subcommand> --help\n`);\n}\n\nfunction printMineHelp() {\n\tconsole.log(`\n clitree mine — Mine your shell history for CLI workflows\n\n Usage:\n clitree mine <binary> [options]\n\n Examples:\n clitree mine git\n clitree mine docker --min-support 5 --with-flow\n clitree mine bun --format json > bun-flows.json\n clitree mine git --no-color | tee report.txt\n\n Options:\n --min-support <n> Minimum occurrences to count as a workflow (default: 3)\n --history-path <p> Custom shell history path (default: ~/.zsh_history)\n --format <fmt> Output format: ansi (default), json\n --max-paths <n> Max workflows to show (default: 10)\n --with-flow Always render the top workflow as an ASCII DAG\n --no-flow Never render the DAG (overrides auto-detect)\n --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)\n -h, --help Show this help\n\n By default, the top workflow is rendered as a DAG only when it has 3+ steps.\n Use --with-flow to force it on even for 2-step chains, or --no-flow to skip.\n`);\n}\n\nfunction printArchaeologyHelp() {\n\tconsole.log(`\n clitree archaeology — Full CLI analysis: tree + mining + LLM archaeology\n\n Usage:\n clitree archaeology <binary> [options]\n\n When run from the command line without a delegate, only the deterministic\n phases run (help parsing + shell history mining). LLM archaeology requires\n running inside the clitree skill (see ./skill/SKILL.md).\n\n Examples:\n clitree archaeology git # help + history\n clitree archaeology docker --no-cache # bypass cache\n clitree archaeology bun --format json # JSON output\n\n Options:\n --no-cache Skip cache, always re-run\n --max-depth <n> Max --help recursion depth (default: 2)\n --format <fmt> Output format: ansi (default), json\n --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)\n -h, --help Show this help\n`);\n}\n\nfunction printFlowHelp() {\n\tconsole.log(`\n cli-tree flow — Render a CLI workflow YAML as a DAG\n\n Usage:\n cli-tree flow <file> [options]\n\n Examples:\n cli-tree flow workflows/git-pr-flow.yml\n cli-tree flow my-workflow.yml --format html > flow.html\n cli-tree flow workflows/docker-deploy.yml --compact --no-color\n\n Options:\n --compact Hide description and legend\n --no-color Disable colors\n --format <fmt> Output format: ansi (default), string, html\n --no-validate Skip validation\n -h, --help Show this help\n`);\n}\n\nasync function runTree(args: string[]) {\n\tconst opts: TreeOptions = {\n\t\tcolor: true,\n\t\tshowFlags: true,\n\t\tshowArgs: true,\n\t\tshowDescriptions: true,\n\t\tshowTypes: true,\n\t\tshowDefaults: true,\n\t\tcompact: false,\n\t};\n\n\tlet depth = 2;\n\tlet format: \"ansi\" | \"string\" | \"html\" | \"json\" = \"ansi\";\n\tlet stdinName: string | null = null;\n\tlet binary: string | null = null;\n\n\topts.color = shouldUseColor(args);\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--depth\" && args[i + 1]) {\n\t\t\tdepth = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--compact\") {\n\t\t\topts.compact = true;\n\t\t\topts.showDescriptions = false;\n\t\t} else if (arg === \"--no-flags\") {\n\t\t\topts.showFlags = false;\n\t\t} else if (arg === \"--no-args\") {\n\t\t\topts.showArgs = false;\n\t\t} else if (arg === \"--no-color\") {\n\t\t\topts.color = false;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"string\" | \"html\" | \"json\";\n\t\t} else if (arg === \"--stdin\" && args[i + 1]) {\n\t\t\tstdinName = args[++i]!;\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\ttry {\n\t\tlet tree;\n\t\tif (stdinName) {\n\t\t\tconst input = await readStdin();\n\t\t\ttree = parseHelp(stdinName, input);\n\t\t} else if (binary) {\n\t\t\ttree = await parseHelpRecursive(binary, [], depth);\n\t\t} else {\n\t\t\tconsole.error(\"Error: provide a binary name or use --stdin <name>\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify(tree, null, 2));\n\t\t} else if (format === \"html\") {\n\t\t\tconsole.log(treeToHtml(tree, opts));\n\t\t} else if (format === \"string\") {\n\t\t\tconsole.log(treeToString(tree, opts));\n\t\t} else {\n\t\t\tprintTree(tree, opts);\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function runFlow(args: string[]) {\n\tconst opts: FlowRenderOptions = {\n\t\tcolor: true,\n\t\tshowDescriptions: true,\n\t\tshowCommands: true,\n\t\tcompact: false,\n\t};\n\n\tlet format: \"ansi\" | \"string\" | \"html\" = \"ansi\";\n\tlet file: string | null = null;\n\tlet skipValidate = false;\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--compact\") {\n\t\t\topts.compact = true;\n\t\t\topts.showDescriptions = false;\n\t\t} else if (arg === \"--no-color\") {\n\t\t\topts.color = false;\n\t\t} else if (arg === \"--no-validate\") {\n\t\t\tskipValidate = true;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"string\" | \"html\";\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tfile = arg;\n\t\t}\n\t}\n\n\tif (!file) {\n\t\tconsole.error(\"Error: provide a workflow YAML file\");\n\t\tconsole.error(\"Run 'cli-tree flow --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tconst text = await Bun.file(file).text();\n\t\tconst workflow = parseWorkflow(text);\n\n\t\tif (!skipValidate) {\n\t\t\tconst result = validateWorkflow(workflow);\n\t\t\tfor (const err of result.errors) {\n\t\t\t\tconst prefix = err.severity === \"error\" ? \"\\x1b[31m✗\" : \"\\x1b[33m⚠\";\n\t\t\t\tconst reset = \"\\x1b[0m\";\n\t\t\t\tconst location = err.node ? ` [${err.node}]` : err.edge ? ` [${err.edge.from}→${err.edge.to}]` : \"\";\n\t\t\t\tconsole.error(`${prefix}${location} ${err.message}${reset}`);\n\t\t\t}\n\t\t\tif (!result.valid) process.exit(1);\n\t\t}\n\n\t\tif (format === \"html\") {\n\t\t\tconsole.log(flowToHtml(workflow, opts));\n\t\t} else if (format === \"string\") {\n\t\t\tconsole.log(flowToString(workflow, opts));\n\t\t} else {\n\t\t\tconsole.log(flowToAnsi(workflow, opts));\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk as Buffer);\n\t}\n\treturn Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nfunction shouldUseColor(args: string[]): boolean {\n\tif (args.includes(\"--no-color\")) return false;\n\tif (process.env.NO_COLOR) return false;\n\tif (process.env.FORCE_COLOR) return true;\n\treturn !!process.stdout.isTTY;\n}\n\nfunction makeColors(enabled: boolean) {\n\tif (!enabled) {\n\t\treturn { reset: \"\", bold: \"\", dim: \"\", cyan: \"\", green: \"\", yellow: \"\", red: \"\", magenta: \"\", gray: \"\" };\n\t}\n\treturn {\n\t\treset: \"\\x1b[0m\",\n\t\tbold: \"\\x1b[1m\",\n\t\tdim: \"\\x1b[2m\",\n\t\tcyan: \"\\x1b[36m\",\n\t\tgreen: \"\\x1b[32m\",\n\t\tyellow: \"\\x1b[33m\",\n\t\tred: \"\\x1b[31m\",\n\t\tmagenta: \"\\x1b[35m\",\n\t\tgray: \"\\x1b[90m\",\n\t};\n}\n\nasync function runMine(args: string[]) {\n\tlet binary: string | null = null;\n\tlet minSupport = 3;\n\tlet historyPath: string | undefined;\n\tlet format: \"ansi\" | \"json\" = \"ansi\";\n\tlet maxPaths = 10;\n\tlet withFlow: \"auto\" | \"on\" | \"off\" = \"auto\";\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--min-support\" && args[i + 1]) {\n\t\t\tminSupport = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--history-path\" && args[i + 1]) {\n\t\t\thistoryPath = args[++i]!;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"json\";\n\t\t} else if (arg === \"--max-paths\" && args[i + 1]) {\n\t\t\tmaxPaths = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--with-flow\" || arg === \"--flow\") {\n\t\t\twithFlow = \"on\";\n\t\t} else if (arg === \"--no-flow\") {\n\t\t\twithFlow = \"off\";\n\t\t} else if (arg !== \"--no-color\" && !arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\tif (!binary) {\n\t\tconsole.error(\"Error: provide a binary name\");\n\t\tconsole.error(\"Run 'clitree mine --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tconst result = await mineCli(binary, { minSupport, historyPath });\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\treturn;\n\t\t}\n\n\t\tconst C = makeColors(shouldUseColor(args));\n\n\t\tconsole.log(`\\n${C.bold}${C.magenta}${binary}${C.reset} ${C.gray}— shell history analysis${C.reset}\\n`);\n\t\tconsole.log(`${C.bold}Usage:${C.reset}`);\n\t\tconsole.log(` ${C.dim}Invocations:${C.reset} ${C.cyan}${result.stats.totalInvocations}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Subcommands:${C.reset} ${C.cyan}${result.stats.uniqueSubcommands}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Sessions:${C.reset} ${C.cyan}${result.sessionsAnalyzed}${C.reset}\\n`);\n\n\t\tif (result.stats.topSubcommands.length > 0) {\n\t\t\tconsole.log(`${C.bold}Top subcommands:${C.reset}`);\n\t\t\tconst max = result.stats.topSubcommands[0]!.count;\n\t\t\tfor (const { subcommand, count } of result.stats.topSubcommands.slice(0, 5)) {\n\t\t\t\tconst bar = \"█\".repeat(Math.max(1, Math.round((count / max) * 30)));\n\t\t\t\tconsole.log(` ${C.green}${subcommand.padEnd(20)}${C.reset} ${C.cyan}${bar}${C.reset} ${C.dim}${count}${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\tif (result.workflows.length > 0) {\n\t\t\tconsole.log(`${C.bold}Discovered workflows:${C.reset}`);\n\t\t\tfor (const wf of result.workflows.slice(0, maxPaths)) {\n\t\t\t\tconst chain = wf.path[0]!.map(p => `${C.green}${p}${C.reset}`).join(` ${C.gray}→${C.reset} `);\n\t\t\t\tconsole.log(` ${chain} ${C.dim}(${wf.support}×)${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\tif (result.suggestions.length > 0) {\n\t\t\tconsole.log(`${C.bold}${C.yellow}💡 Skill suggestions:${C.reset}`);\n\t\t\tfor (const s of result.suggestions.slice(0, 3)) {\n\t\t\t\tconst badge =\n\t\t\t\t\ts.priority === \"high\"\n\t\t\t\t\t\t? `${C.green}[HIGH]${C.reset}`\n\t\t\t\t\t\t: s.priority === \"medium\"\n\t\t\t\t\t\t\t? `${C.yellow}[MED]${C.reset}`\n\t\t\t\t\t\t\t: `${C.dim}[LOW]${C.reset}`;\n\t\t\t\tconsole.log(`\\n ${badge} ${C.bold}/${s.name}${C.reset} — ${s.description}`);\n\t\t\t\tconsole.log(` ${C.dim}${s.reason}${C.reset}`);\n\t\t\t\tconsole.log(` ${C.dim}${s.commands.join(\" && \")}${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\t// Pick the top workflow worth visualizing as a DAG.\n\t\t// In \"auto\" mode, prefer the highest-support workflow with 3+ steps —\n\t\t// 2-step chains are more readable as text than as boxed diagrams.\n\t\t// In \"on\" mode, render whatever is the top regardless of length.\n\t\t// In \"off\" mode, skip.\n\t\tif (withFlow !== \"off\") {\n\t\t\tconst minSteps = withFlow === \"on\" ? 2 : 3;\n\t\t\tconst topForFlow = pickWorkflowForFlow(result.workflows, minSteps);\n\t\t\tif (topForFlow) {\n\t\t\t\tconst flowWorkflow = minedToFlowWorkflow(topForFlow);\n\t\t\t\tconst rendered = shouldUseColor(args) ? flowToAnsi(flowWorkflow) : flowToString(flowWorkflow);\n\t\t\t\tconsole.log(`${C.bold}Top workflow (visualized):${C.reset}`);\n\t\t\t\tconsole.log(rendered);\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nfunction pickWorkflowForFlow<T extends { path: string[][]; support: number }>(\n\tworkflows: T[],\n\tminSteps = 3,\n): T | null {\n\tfor (const wf of workflows) {\n\t\tconst len = wf.path[0]?.length ?? 0;\n\t\tif (len >= minSteps) return wf;\n\t}\n\treturn null;\n}\n\nasync function runArchaeologyCmd(args: string[]) {\n\tlet binary: string | null = null;\n\tlet skipCache = false;\n\tlet maxDepth = 2;\n\tlet format: \"ansi\" | \"json\" = \"ansi\";\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--no-cache\") {\n\t\t\tskipCache = true;\n\t\t} else if (arg === \"--max-depth\" && args[i + 1]) {\n\t\t\tmaxDepth = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"json\";\n\t\t} else if (arg !== \"--no-color\" && !arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\tif (!binary) {\n\t\tconsole.error(\"Error: provide a binary name\");\n\t\tconsole.error(\"Run 'clitree archaeology --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\tconst C = makeColors(shouldUseColor(args));\n\n\ttry {\n\t\tconsole.error(`${C.dim}⚠ LLM archaeology requires running inside the clitree skill.${C.reset}`);\n\t\tconsole.error(`${C.dim} Running deterministic phases only (help + history mining).${C.reset}`);\n\t\tconsole.error(\"\");\n\n\t\tconst [arch, mine] = await Promise.all([\n\t\t\trunArchaeology(binary, new NullDelegate(), { skipCache, maxHelpDepth: maxDepth }),\n\t\t\tmineCli(binary, { minSupport: 3 }).catch(() => null),\n\t\t]);\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify({ archaeology: arch, mining: mine }, null, 2));\n\t\t\treturn;\n\t\t}\n\n\t\tconsole.log(`${C.bold}${C.magenta}${binary}${C.reset}`);\n\t\tif (arch.tree.description) {\n\t\t\tconsole.log(`${C.gray}${arch.tree.description}${C.reset}`);\n\t\t}\n\t\tconsole.log();\n\n\t\tconsole.log(`${C.bold}Tree:${C.reset}`);\n\t\tconsole.log(` ${C.dim}Commands:${C.reset} ${C.cyan}${arch.stats.helpCommands}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Cached:${C.reset} ${arch.fromCache ? `${C.green}yes${C.reset}` : `${C.dim}no${C.reset}`}`);\n\t\tconsole.log();\n\n\t\tif (mine) {\n\t\t\tconsole.log(`${C.bold}Usage from shell history:${C.reset}`);\n\t\t\tconsole.log(` ${C.dim}Invocations:${C.reset} ${C.cyan}${mine.stats.totalInvocations}${C.reset}`);\n\t\t\tconsole.log(` ${C.dim}Subcommands:${C.reset} ${C.cyan}${mine.stats.uniqueSubcommands}${C.reset}`);\n\n\t\t\tif (mine.workflows.length > 0) {\n\t\t\t\tconsole.log(`\\n${C.bold}Workflows you repeat:${C.reset}`);\n\t\t\t\tfor (const wf of mine.workflows.slice(0, 5)) {\n\t\t\t\t\tconst chain = wf.path[0]!.map(p => `${C.green}${p}${C.reset}`).join(` ${C.gray}→${C.reset} `);\n\t\t\t\t\tconsole.log(` ${chain} ${C.dim}(${wf.support}×)${C.reset}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mine.suggestions.length > 0) {\n\t\t\t\tconsole.log(`\\n${C.bold}${C.yellow}💡 Skill suggestions:${C.reset}`);\n\t\t\t\tfor (const s of mine.suggestions.slice(0, 3)) {\n\t\t\t\t\tconsole.log(` ${C.bold}/${s.name}${C.reset} — ${s.description}`);\n\t\t\t\t\tconsole.log(` ${C.dim}${s.reason}${C.reset}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log();\n\t\tconsole.log(`${C.dim}Install the clitree skill for full LLM archaeology:${C.reset}`);\n\t\tconsole.log(`${C.dim} bash ./skill/install.sh${C.reset}`);\n\t\tconsole.log();\n\t} catch (err: any) {\n\t\tconsole.error(`${C.red}Error: ${err.message}${C.reset}`);\n\t\tprocess.exit(1);\n\t}\n}\n"
|
|
5
|
+
"#!/usr/bin/env bun\nimport { parseHelpRecursive, parseHelp } from \"./parse\";\nimport { printTree, treeToString, treeToHtml } from \"./index\";\nimport type { TreeOptions } from \"./types\";\nimport { parseWorkflow, validateWorkflow, flowToAnsi, flowToString, flowToHtml } from \"./flow\";\nimport type { FlowRenderOptions } from \"./flow/types\";\nimport {\n\tmineCli,\n\tminedToFlowWorkflow,\n\tmineCrossCli,\n\tcrossCliToFlowWorkflow,\n\tsparkline,\n\tlabeledSparkline,\n\tformatTimeRange,\n} from \"./miner\";\nimport { runArchaeology, NullDelegate } from \"./archaeology\";\n\nconst args = process.argv.slice(2);\nconst subcommand = args[0];\n\nconst HELP_SUBCOMMANDS = new Set([\"flow\", \"mine\", \"archaeology\", \"safe-help\", \"cross\"]);\nconst isHelpFlag = args.includes(\"--help\") || args.includes(\"-h\");\n\nif (!subcommand || (isHelpFlag && !HELP_SUBCOMMANDS.has(subcommand ?? \"\"))) {\n\tprintMainHelp();\n\tprocess.exit(0);\n}\n\nif (isHelpFlag) {\n\tif (subcommand === \"flow\") printFlowHelp();\n\telse if (subcommand === \"mine\") printMineHelp();\n\telse if (subcommand === \"archaeology\") printArchaeologyHelp();\n\telse if (subcommand === \"safe-help\") printSafeHelpHelp();\n\telse if (subcommand === \"cross\") printCrossHelp();\n\telse printMainHelp();\n\tprocess.exit(0);\n}\n\nif (subcommand === \"flow\") {\n\tawait runFlow(args.slice(1));\n} else if (subcommand === \"mine\") {\n\tawait runMine(args.slice(1));\n} else if (subcommand === \"archaeology\") {\n\tawait runArchaeologyCmd(args.slice(1));\n} else if (subcommand === \"safe-help\") {\n\tawait runSafeHelp(args.slice(1));\n} else if (subcommand === \"cross\") {\n\tawait runCross(args.slice(1));\n} else {\n\tawait runTree(args);\n}\n\nfunction printMainHelp() {\n\tconsole.log(`\n clitree — Visualize and explore any CLI\n\n Usage:\n clitree <binary> [options] Render command tree from --help\n clitree flow <file> [options] Render a workflow YAML as a DAG\n clitree mine <binary> [options] Mine shell history for workflows\n clitree cross [options] Detect cross-CLI workflows (git + gh, docker + kubectl)\n clitree archaeology <binary> [options] Full analysis: tree + mining + (LLM)\n clitree safe-help <binary> [sub...] Fetch clean help for any CLI (no pager, no overstriking)\n\n Examples:\n clitree docker # basic tree\n clitree mine git # \"what workflows do I repeat with git?\"\n clitree cross # cross-CLI flows across your history\n clitree archaeology bun # tree + mining + LLM archaeology\n clitree safe-help git commit # avoid the git man-page pager trap\n\n Subcommands:\n tree Parse --help output (default; passing a binary name invokes this)\n flow Render a workflow YAML file as an ASCII DAG\n mine Discover workflows from your shell history (single CLI)\n cross Discover workflows that span multiple CLIs (e.g. git → gh)\n archaeology Run full analysis (tree + mine + LLM proposals when available)\n safe-help Return inline help for any CLI, handling pager/overstrike edge cases\n\n Help for a subcommand: clitree <subcommand> --help\n`);\n}\n\nfunction printCrossHelp() {\n\tconsole.log(`\n clitree cross — Mine cross-CLI workflows from your shell history\n\n Usage:\n clitree cross [options]\n\n This is mineCli's bigger sibling. Instead of filtering history to a single\n binary, it looks at every command in a session and finds sequences that weave\n between tools — e.g.:\n\n git push → gh pr create\n docker build → docker push → kubectl apply\n bun test → git commit → git push\n\n These patterns are invisible to 'clitree mine <cli>' because they cross boundaries.\n\n Examples:\n clitree cross # top 10 cross-CLI workflows\n clitree cross --top-k 5 # just the top 5\n clitree cross --only git,gh,docker # restrict to a set of CLIs\n clitree cross --format json # raw data\n\n Options:\n --top-k <n> Max workflows to return (default: 10)\n --min-support <n> Minimum occurrences (default: 3)\n --min-path-length <n> Minimum chain length (default: 2)\n --max-path-length <n> Maximum chain length (default: 5)\n --min-distinct-clis <n> Require at least this many distinct CLIs (default: 2)\n --only <csv> Whitelist: only include these CLIs (comma-separated)\n --format <fmt> ansi (default) or json\n --no-color Disable ANSI colors\n --no-flow Skip DAG rendering of the top workflow\n -h, --help Show this help\n`);\n}\n\nfunction printSafeHelpHelp() {\n\tconsole.log(`\n clitree safe-help — Fetch clean help output for any CLI\n\n Usage:\n clitree safe-help <binary> [subcommand...] [options]\n\n Why this exists:\n Running '<cli> --help' directly is a minefield on agents and scripts:\n - 'git commit --help' opens a pager in a TTY and hangs\n - Piping 'git <sub> --help' returns nroff with overstrike (ffiixxuupp)\n - Some CLIs use 'help <sub>' instead of '<sub> --help'\n - macOS man pages emit \\\\b sequences that need col -bx\n\n safe-help tries the right variants in order, cleans overstrikes, and\n returns plain text every time.\n\n Strategy (in order):\n 1. <cli> <sub> -h — short inline help\n 2. <cli> <sub> --help — long help (captured, overstrike-stripped)\n 3. <cli> help <sub> — alternate syntax\n 4. MANPAGER=cat man <cli>-<sub> | col -bx — final man fallback\n\n Examples:\n clitree safe-help git commit\n clitree safe-help docker run\n clitree safe-help kubectl get pods\n clitree safe-help bun install\n\n Options:\n --no-color Disable ANSI codes (auto-detects non-TTY)\n -h, --help Show this help\n`);\n}\n\nfunction printMineHelp() {\n\tconsole.log(`\n clitree mine — Mine your shell history for CLI workflows\n\n Usage:\n clitree mine <binary> [options]\n\n Examples:\n clitree mine git\n clitree mine git --top-k 3 # render top 3 workflows as DAGs\n clitree mine docker --min-support 5 --with-flow\n clitree mine bun --format json > bun-flows.json\n clitree mine git --no-color | tee report.txt\n clitree mine git --no-activity # skip temporal sparklines\n\n Options:\n --min-support <n> Minimum occurrences to count as a workflow (default: 3)\n --history-path <p> Custom shell history path (default: ~/.zsh_history)\n --format <fmt> Output format: ansi (default), json\n --max-paths <n> Max workflows to show in text list (default: 10)\n --top-k <n> Render top N workflows as DAGs (default: 1)\n --with-flow Include 2-step workflows in DAG rendering\n --no-flow Skip DAG rendering entirely\n --no-activity Skip hour/day/30-day activity sparklines\n --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)\n -h, --help Show this help\n\n By default, the top 3+ step workflow is rendered as a DAG.\n --top-k bumps that to N distinct workflows stacked on top of each other.\n`);\n}\n\nfunction printArchaeologyHelp() {\n\tconsole.log(`\n clitree archaeology — Full CLI analysis: tree + mining + LLM archaeology\n\n Usage:\n clitree archaeology <binary> [options]\n\n When run from the command line without a delegate, only the deterministic\n phases run (help parsing + shell history mining). LLM archaeology requires\n running inside the clitree skill (see ./skill/SKILL.md).\n\n Examples:\n clitree archaeology git # help + history\n clitree archaeology docker --no-cache # bypass cache\n clitree archaeology bun --format json # JSON output\n\n Options:\n --no-cache Skip cache, always re-run\n --max-depth <n> Max --help recursion depth (default: 2)\n --format <fmt> Output format: ansi (default), json\n --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)\n -h, --help Show this help\n`);\n}\n\nfunction printFlowHelp() {\n\tconsole.log(`\n cli-tree flow — Render a CLI workflow YAML as a DAG\n\n Usage:\n cli-tree flow <file> [options]\n\n Examples:\n cli-tree flow workflows/git-pr-flow.yml\n cli-tree flow my-workflow.yml --format html > flow.html\n cli-tree flow workflows/docker-deploy.yml --compact --no-color\n\n Options:\n --compact Hide description and legend\n --no-color Disable colors\n --format <fmt> Output format: ansi (default), string, html\n --no-validate Skip validation\n -h, --help Show this help\n`);\n}\n\nasync function runTree(args: string[]) {\n\tconst opts: TreeOptions = {\n\t\tcolor: true,\n\t\tshowFlags: true,\n\t\tshowArgs: true,\n\t\tshowDescriptions: true,\n\t\tshowTypes: true,\n\t\tshowDefaults: true,\n\t\tcompact: false,\n\t};\n\n\tlet depth = 2;\n\tlet format: \"ansi\" | \"string\" | \"html\" | \"json\" = \"ansi\";\n\tlet stdinName: string | null = null;\n\tlet binary: string | null = null;\n\n\topts.color = shouldUseColor(args);\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--depth\" && args[i + 1]) {\n\t\t\tdepth = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--compact\") {\n\t\t\topts.compact = true;\n\t\t\topts.showDescriptions = false;\n\t\t} else if (arg === \"--no-flags\") {\n\t\t\topts.showFlags = false;\n\t\t} else if (arg === \"--no-args\") {\n\t\t\topts.showArgs = false;\n\t\t} else if (arg === \"--no-color\") {\n\t\t\topts.color = false;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"string\" | \"html\" | \"json\";\n\t\t} else if (arg === \"--stdin\" && args[i + 1]) {\n\t\t\tstdinName = args[++i]!;\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\ttry {\n\t\tlet tree;\n\t\tif (stdinName) {\n\t\t\tconst input = await readStdin();\n\t\t\ttree = parseHelp(stdinName, input);\n\t\t} else if (binary) {\n\t\t\ttree = await parseHelpRecursive(binary, [], depth);\n\t\t} else {\n\t\t\tconsole.error(\"Error: provide a binary name or use --stdin <name>\");\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify(tree, null, 2));\n\t\t} else if (format === \"html\") {\n\t\t\tconsole.log(treeToHtml(tree, opts));\n\t\t} else if (format === \"string\") {\n\t\t\tconsole.log(treeToString(tree, opts));\n\t\t} else {\n\t\t\tprintTree(tree, opts);\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function runFlow(args: string[]) {\n\tconst opts: FlowRenderOptions = {\n\t\tcolor: true,\n\t\tshowDescriptions: true,\n\t\tshowCommands: true,\n\t\tcompact: false,\n\t};\n\n\tlet format: \"ansi\" | \"string\" | \"html\" = \"ansi\";\n\tlet file: string | null = null;\n\tlet skipValidate = false;\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--compact\") {\n\t\t\topts.compact = true;\n\t\t\topts.showDescriptions = false;\n\t\t} else if (arg === \"--no-color\") {\n\t\t\topts.color = false;\n\t\t} else if (arg === \"--no-validate\") {\n\t\t\tskipValidate = true;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"string\" | \"html\";\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tfile = arg;\n\t\t}\n\t}\n\n\tif (!file) {\n\t\tconsole.error(\"Error: provide a workflow YAML file\");\n\t\tconsole.error(\"Run 'cli-tree flow --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tconst text = await Bun.file(file).text();\n\t\tconst workflow = parseWorkflow(text);\n\n\t\tif (!skipValidate) {\n\t\t\tconst result = validateWorkflow(workflow);\n\t\t\tfor (const err of result.errors) {\n\t\t\t\tconst prefix = err.severity === \"error\" ? \"\\x1b[31m✗\" : \"\\x1b[33m⚠\";\n\t\t\t\tconst reset = \"\\x1b[0m\";\n\t\t\t\tconst location = err.node ? ` [${err.node}]` : err.edge ? ` [${err.edge.from}→${err.edge.to}]` : \"\";\n\t\t\t\tconsole.error(`${prefix}${location} ${err.message}${reset}`);\n\t\t\t}\n\t\t\tif (!result.valid) process.exit(1);\n\t\t}\n\n\t\tif (format === \"html\") {\n\t\t\tconsole.log(flowToHtml(workflow, opts));\n\t\t} else if (format === \"string\") {\n\t\t\tconsole.log(flowToString(workflow, opts));\n\t\t} else {\n\t\t\tconsole.log(flowToAnsi(workflow, opts));\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk as Buffer);\n\t}\n\treturn Buffer.concat(chunks).toString(\"utf-8\");\n}\n\nfunction stripOverstrike(text: string): string {\n\t// Strip nroff bold via char\\bchar, underline via _\\bchar, and stray control chars.\n\t// This is what `col -bx` does.\n\treturn text\n\t\t.replace(/(.)\\b\\1/g, \"$1\")\n\t\t.replace(/_\\b(.)/g, \"$1\")\n\t\t.replace(/\\b/g, \"\")\n\t\t.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, \"\");\n}\n\nfunction looksLikeHelp(text: string): boolean {\n\tif (!text.trim()) return false;\n\tif (text.length < 40) return false;\n\tconst firstChunk = text.slice(0, 200).toLowerCase();\n\t// Error messages from unknown subcommands or unsupported flags\n\tif (/(unknown|invalid|no such|not a \\w+ command|flag needs an argument|unrecognized)/.test(firstChunk)) {\n\t\treturn false;\n\t}\n\t// \"Run '... --help' for more information\" is a hint, not the help itself\n\tif (/run '.+' for more information/.test(firstChunk)) return false;\n\treturn true;\n}\n\nasync function tryHelpVariant(binary: string, argv: string[], timeoutMs = 5000): Promise<string | null> {\n\ttry {\n\t\tconst proc = Bun.spawn([binary, ...argv], {\n\t\t\tstdout: \"pipe\",\n\t\t\tstderr: \"pipe\",\n\t\t\tenv: { ...process.env, PAGER: \"cat\", MANPAGER: \"cat\", GIT_PAGER: \"cat\" },\n\t\t});\n\n\t\tconst timer = setTimeout(() => proc.kill(), timeoutMs);\n\n\t\tconst [stdout, stderr] = await Promise.all([\n\t\t\tnew Response(proc.stdout).text(),\n\t\t\tnew Response(proc.stderr).text(),\n\t\t]);\n\t\tclearTimeout(timer);\n\t\tawait proc.exited;\n\n\t\tconst combined = stdout || stderr;\n\t\tif (!looksLikeHelp(combined)) return null;\n\t\treturn stripOverstrike(combined);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function tryManPage(binary: string, subPath: string[], timeoutMs = 5000): Promise<string | null> {\n\t// Try 'man binary-sub' (git-commit), then 'man binary sub' as a fallback.\n\tconst candidates = [\n\t\tsubPath.length > 0 ? [`${binary}-${subPath.join(\"-\")}`] : [binary],\n\t\t[binary, ...subPath],\n\t];\n\n\tfor (const args of candidates) {\n\t\ttry {\n\t\t\tconst proc = Bun.spawn([\"man\", ...args], {\n\t\t\t\tstdout: \"pipe\",\n\t\t\t\tstderr: \"pipe\",\n\t\t\t\tenv: { ...process.env, MANPAGER: \"cat\", PAGER: \"cat\" },\n\t\t\t});\n\n\t\t\tconst timer = setTimeout(() => proc.kill(), timeoutMs);\n\t\t\tconst [stdout] = await Promise.all([\n\t\t\t\tnew Response(proc.stdout).text(),\n\t\t\t\tnew Response(proc.stderr).text(),\n\t\t\t]);\n\t\t\tclearTimeout(timer);\n\t\t\tawait proc.exited;\n\n\t\t\tif (looksLikeHelp(stdout)) return stripOverstrike(stdout);\n\t\t} catch {}\n\t}\n\treturn null;\n}\n\nasync function runSafeHelp(args: string[]) {\n\tlet binary: string | null = null;\n\tconst subPath: string[] = [];\n\n\tfor (const arg of args) {\n\t\tif (arg === \"--no-color\" || arg === \"--help\" || arg === \"-h\") continue;\n\t\tif (!binary) {\n\t\t\tbinary = arg;\n\t\t} else {\n\t\t\tsubPath.push(arg);\n\t\t}\n\t}\n\n\tif (!binary) {\n\t\tconsole.error(\"Error: provide a binary name\");\n\t\tconsole.error(\"Run 'clitree safe-help --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\t// Strategy in order of preference:\n\t// 1. `<cli> <sub> -h` — short inline help, no pager\n\t// 2. `<cli> <sub> --help` — long form, overstrike-stripped\n\t// 3. `<cli> help <sub>` — alternate syntax (git, go, bun)\n\t// 4. `man <cli>-<sub>` or `man <cli> <sub>` — final fallback\n\tconst variants: Array<{ label: string; args: string[] }> = [\n\t\t{ label: \"short help (-h)\", args: [...subPath, \"-h\"] },\n\t\t{ label: \"long help (--help)\", args: [...subPath, \"--help\"] },\n\t];\n\n\tif (subPath.length > 0) {\n\t\tvariants.push({ label: \"help subcommand\", args: [\"help\", ...subPath] });\n\t}\n\n\tfor (const variant of variants) {\n\t\tconst output = await tryHelpVariant(binary, variant.args);\n\t\tif (output) {\n\t\t\tprocess.stdout.write(output);\n\t\t\tif (!output.endsWith(\"\\n\")) process.stdout.write(\"\\n\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Last resort: man page\n\tconst manOutput = await tryManPage(binary, subPath);\n\tif (manOutput) {\n\t\tprocess.stdout.write(manOutput);\n\t\tif (!manOutput.endsWith(\"\\n\")) process.stdout.write(\"\\n\");\n\t\treturn;\n\t}\n\n\tconsole.error(`Error: could not fetch help for ${binary} ${subPath.join(\" \")}`);\n\tconsole.error(\"Tried: -h, --help, help subcommand, and man page.\");\n\tprocess.exit(1);\n}\n\nfunction shouldUseColor(args: string[]): boolean {\n\tif (args.includes(\"--no-color\")) return false;\n\tif (process.env.NO_COLOR) return false;\n\tif (process.env.FORCE_COLOR) return true;\n\treturn !!process.stdout.isTTY;\n}\n\nfunction makeColors(enabled: boolean) {\n\tif (!enabled) {\n\t\treturn { reset: \"\", bold: \"\", dim: \"\", cyan: \"\", green: \"\", yellow: \"\", red: \"\", magenta: \"\", gray: \"\" };\n\t}\n\treturn {\n\t\treset: \"\\x1b[0m\",\n\t\tbold: \"\\x1b[1m\",\n\t\tdim: \"\\x1b[2m\",\n\t\tcyan: \"\\x1b[36m\",\n\t\tgreen: \"\\x1b[32m\",\n\t\tyellow: \"\\x1b[33m\",\n\t\tred: \"\\x1b[31m\",\n\t\tmagenta: \"\\x1b[35m\",\n\t\tgray: \"\\x1b[90m\",\n\t};\n}\n\nasync function runMine(args: string[]) {\n\tlet binary: string | null = null;\n\tlet minSupport = 3;\n\tlet historyPath: string | undefined;\n\tlet format: \"ansi\" | \"json\" = \"ansi\";\n\tlet maxPaths = 10;\n\tlet withFlow: \"auto\" | \"on\" | \"off\" = \"auto\";\n\tlet topK = 1;\n\tlet showActivity = true;\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--min-support\" && args[i + 1]) {\n\t\t\tminSupport = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--history-path\" && args[i + 1]) {\n\t\t\thistoryPath = args[++i]!;\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"json\";\n\t\t} else if (arg === \"--max-paths\" && args[i + 1]) {\n\t\t\tmaxPaths = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--top-k\" && args[i + 1]) {\n\t\t\ttopK = Number.parseInt(args[++i]!, 10);\n\t\t\tif (withFlow === \"auto\") withFlow = \"on\";\n\t\t} else if (arg === \"--with-flow\" || arg === \"--flow\") {\n\t\t\twithFlow = \"on\";\n\t\t} else if (arg === \"--no-flow\") {\n\t\t\twithFlow = \"off\";\n\t\t} else if (arg === \"--no-activity\") {\n\t\t\tshowActivity = false;\n\t\t} else if (arg !== \"--no-color\" && !arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\tif (!binary) {\n\t\tconsole.error(\"Error: provide a binary name\");\n\t\tconsole.error(\"Run 'clitree mine --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\ttry {\n\t\tconst result = await mineCli(binary, { minSupport, historyPath });\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\treturn;\n\t\t}\n\n\t\tconst C = makeColors(shouldUseColor(args));\n\n\t\tconsole.log(`\\n${C.bold}${C.magenta}${binary}${C.reset} ${C.gray}— shell history analysis${C.reset}\\n`);\n\t\tconsole.log(`${C.bold}Usage:${C.reset}`);\n\t\tconsole.log(` ${C.dim}Invocations:${C.reset} ${C.cyan}${result.stats.totalInvocations}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Subcommands:${C.reset} ${C.cyan}${result.stats.uniqueSubcommands}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Sessions:${C.reset} ${C.cyan}${result.sessionsAnalyzed}${C.reset}\\n`);\n\n\t\tif (result.stats.topSubcommands.length > 0) {\n\t\t\tconsole.log(`${C.bold}Top subcommands:${C.reset}`);\n\t\t\tconst max = result.stats.topSubcommands[0]!.count;\n\t\t\tfor (const { subcommand, count } of result.stats.topSubcommands.slice(0, 5)) {\n\t\t\t\tconst bar = \"█\".repeat(Math.max(1, Math.round((count / max) * 30)));\n\t\t\t\tconsole.log(` ${C.green}${subcommand.padEnd(20)}${C.reset} ${C.cyan}${bar}${C.reset} ${C.dim}${count}${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\tif (showActivity && result.activity.total > 0) {\n\t\t\trenderActivitySection(result.activity, C);\n\t\t}\n\n\t\tif (result.workflows.length > 0) {\n\t\t\tconsole.log(`${C.bold}Discovered workflows:${C.reset}`);\n\t\t\tfor (const wf of result.workflows.slice(0, maxPaths)) {\n\t\t\t\tconst chain = wf.path[0]!.map(p => `${C.green}${p}${C.reset}`).join(` ${C.gray}→${C.reset} `);\n\t\t\t\tconsole.log(` ${chain} ${C.dim}(${wf.support}×)${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\tif (result.suggestions.length > 0) {\n\t\t\tconsole.log(`${C.bold}${C.yellow}💡 Skill suggestions:${C.reset}`);\n\t\t\tfor (const s of result.suggestions.slice(0, 3)) {\n\t\t\t\tconst badge =\n\t\t\t\t\ts.priority === \"high\"\n\t\t\t\t\t\t? `${C.green}[HIGH]${C.reset}`\n\t\t\t\t\t\t: s.priority === \"medium\"\n\t\t\t\t\t\t\t? `${C.yellow}[MED]${C.reset}`\n\t\t\t\t\t\t\t: `${C.dim}[LOW]${C.reset}`;\n\t\t\t\tconsole.log(`\\n ${badge} ${C.bold}/${s.name}${C.reset} — ${s.description}`);\n\t\t\t\tconsole.log(` ${C.dim}${s.reason}${C.reset}`);\n\t\t\t\tconsole.log(` ${C.dim}${s.commands.join(\" && \")}${C.reset}`);\n\t\t\t}\n\t\t\tconsole.log();\n\t\t}\n\n\t\t// Pick the top-K workflows worth visualizing as DAGs.\n\t\t// Auto mode renders only the first 3+ step workflow.\n\t\t// `--top-k N` renders up to N distinct workflows (skipping shorter 2-step ones by default).\n\t\tif (withFlow !== \"off\") {\n\t\t\tconst minSteps = withFlow === \"on\" ? 2 : 3;\n\t\t\tconst topK_effective = Math.max(1, topK);\n\t\t\tconst candidates = pickWorkflowsForFlow(result.workflows, minSteps, topK_effective);\n\n\t\t\tif (candidates.length > 0) {\n\t\t\t\tconst header = candidates.length === 1 ? \"Top workflow (visualized):\" : `Top ${candidates.length} workflows (visualized):`;\n\t\t\t\tconsole.log(`${C.bold}${header}${C.reset}`);\n\t\t\t\tfor (let i = 0; i < candidates.length; i++) {\n\t\t\t\t\tif (i > 0) console.log(`${C.gray}${\"─\".repeat(60)}${C.reset}`);\n\t\t\t\t\tconst flowWorkflow = minedToFlowWorkflow(candidates[i]!);\n\t\t\t\t\tconst rendered = shouldUseColor(args) ? flowToAnsi(flowWorkflow) : flowToString(flowWorkflow);\n\t\t\t\t\tconsole.log(rendered);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nfunction renderActivitySection(\n\tactivity: { hourOfDay: number[]; dayOfWeek: number[]; last30Days: number[]; firstSeen: number; lastSeen: number; total: number },\n\tC: ReturnType<typeof makeColors>,\n) {\n\t// Only show if we have timestamp data\n\tif (activity.firstSeen === 0) return;\n\n\tconst dayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\tconsole.log(`${C.bold}Activity:${C.reset}`);\n\n\tconst range = formatTimeRange(activity.firstSeen, activity.lastSeen);\n\tconsole.log(` ${C.dim}Tracked over:${C.reset} ${C.cyan}${range}${C.reset}`);\n\n\t// Hour-of-day sparkline (24 chars wide)\n\tconst hourSpark = sparkline(activity.hourOfDay);\n\tconsole.log(` ${C.dim}Hour of day: ${C.reset}${C.cyan}${hourSpark}${C.reset} ${C.dim}(0h → 23h)${C.reset}`);\n\n\t// Day-of-week mini bars\n\tconst dowMax = Math.max(...activity.dayOfWeek);\n\tif (dowMax > 0) {\n\t\tconsole.log(` ${C.dim}Day of week:${C.reset}`);\n\t\tfor (let i = 0; i < 7; i++) {\n\t\t\tconst count = activity.dayOfWeek[i]!;\n\t\t\tconst barLen = dowMax > 0 ? Math.round((count / dowMax) * 20) : 0;\n\t\t\tconst bar = \"█\".repeat(Math.max(count > 0 ? 1 : 0, barLen));\n\t\t\tconsole.log(` ${C.gray}${dayNames[i]}${C.reset} ${C.cyan}${bar}${C.reset} ${C.dim}${count}${C.reset}`);\n\t\t}\n\t}\n\n\t// Last 30 days sparkline\n\tif (activity.last30Days.some(v => v > 0)) {\n\t\tconst monthSpark = sparkline(activity.last30Days);\n\t\tconsole.log(` ${C.dim}Last 30 days:${C.reset} ${C.cyan}${monthSpark}${C.reset} ${C.dim}(30d ago → today)${C.reset}`);\n\t}\n\tconsole.log();\n}\n\nfunction pickWorkflowForFlow<T extends { path: string[][]; support: number }>(\n\tworkflows: T[],\n\tminSteps = 3,\n): T | null {\n\tconst picked = pickWorkflowsForFlow(workflows, minSteps, 1);\n\treturn picked[0] ?? null;\n}\n\nfunction pickWorkflowsForFlow<T extends { path: string[][]; support: number }>(\n\tworkflows: T[],\n\tminSteps: number,\n\ttopK: number,\n): T[] {\n\tconst result: T[] = [];\n\tconst signatures = new Set<string>();\n\tfor (const wf of workflows) {\n\t\tconst len = wf.path[0]?.length ?? 0;\n\t\tif (len < minSteps) continue;\n\t\tconst sig = wf.path[0]!.join(\" → \");\n\t\tif (signatures.has(sig)) continue;\n\t\tsignatures.add(sig);\n\t\tresult.push(wf);\n\t\tif (result.length >= topK) break;\n\t}\n\treturn result;\n}\n\nasync function runCross(args: string[]) {\n\tlet format: \"ansi\" | \"json\" = \"ansi\";\n\tlet topK = 10;\n\tlet minSupport = 3;\n\tlet minPathLength = 2;\n\tlet maxPathLength = 5;\n\tlet minDistinctCLIs = 2;\n\tlet onlyList: string[] = [];\n\tlet withFlow = true;\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--top-k\" && args[i + 1]) {\n\t\t\ttopK = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--min-support\" && args[i + 1]) {\n\t\t\tminSupport = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--min-path-length\" && args[i + 1]) {\n\t\t\tminPathLength = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--max-path-length\" && args[i + 1]) {\n\t\t\tmaxPathLength = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--min-distinct-clis\" && args[i + 1]) {\n\t\t\tminDistinctCLIs = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--only\" && args[i + 1]) {\n\t\t\tonlyList = args[++i]!.split(\",\").map(s => s.trim()).filter(Boolean);\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"json\";\n\t\t} else if (arg === \"--no-flow\") {\n\t\t\twithFlow = false;\n\t\t}\n\t}\n\n\ttry {\n\t\tconst result = await mineCrossCli({\n\t\t\ttopK,\n\t\t\tminSupport,\n\t\t\tminPathLength,\n\t\t\tmaxPathLength,\n\t\t\tminDistinctCLIs,\n\t\t\tallowedCLIs: onlyList.length > 0 ? onlyList : undefined,\n\t\t});\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\treturn;\n\t\t}\n\n\t\tconst C = makeColors(shouldUseColor(args));\n\n\t\tconsole.log(`\\n${C.bold}${C.magenta}cross-CLI workflow analysis${C.reset}\\n`);\n\t\tconsole.log(`${C.bold}Scope:${C.reset}`);\n\t\tconsole.log(` ${C.dim}Sessions analyzed:${C.reset} ${C.cyan}${result.sessionsAnalyzed}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Distinct CLIs:${C.reset} ${C.cyan}${result.distinctCLIs.length}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Transitions:${C.reset} ${C.cyan}${result.totalTransitions}${C.reset}\\n`);\n\n\t\tif (result.workflows.length === 0) {\n\t\t\tconsole.log(`${C.dim}No cross-CLI workflows found. Try lowering --min-support or --min-distinct-clis.${C.reset}\\n`);\n\t\t\treturn;\n\t\t}\n\n\t\tconsole.log(`${C.bold}Cross-CLI workflows (top ${result.workflows.length}):${C.reset}`);\n\t\tfor (let i = 0; i < result.workflows.length; i++) {\n\t\t\tconst wf = result.workflows[i]!;\n\t\t\tconst chain = wf.path\n\t\t\t\t.map(s => `${C.green}${s.cli}${C.reset} ${C.cyan}${s.subcommand}${C.reset}`)\n\t\t\t\t.join(` ${C.gray}→${C.reset} `);\n\t\t\tconsole.log(` ${C.dim}${(i + 1).toString().padStart(2)}.${C.reset} ${chain}`);\n\t\t\tconsole.log(` ${C.dim}seen ${wf.support}×, ${wf.uniqueCLIs} distinct CLIs${C.reset}`);\n\t\t}\n\t\tconsole.log();\n\n\t\tif (withFlow && result.workflows.length > 0) {\n\t\t\tconst top = result.workflows[0]!;\n\t\t\tconst flowWorkflow = crossCliToFlowWorkflow(top);\n\t\t\tconst rendered = shouldUseColor(args) ? flowToAnsi(flowWorkflow) : flowToString(flowWorkflow);\n\t\t\tconsole.log(`${C.bold}Top cross-CLI workflow (visualized):${C.reset}`);\n\t\t\tconsole.log(rendered);\n\t\t\tconsole.log();\n\t\t}\n\t} catch (err: any) {\n\t\tconsole.error(`Error: ${err.message}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nasync function runArchaeologyCmd(args: string[]) {\n\tlet binary: string | null = null;\n\tlet skipCache = false;\n\tlet maxDepth = 2;\n\tlet format: \"ansi\" | \"json\" = \"ansi\";\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i]!;\n\t\tif (arg === \"--no-cache\") {\n\t\t\tskipCache = true;\n\t\t} else if (arg === \"--max-depth\" && args[i + 1]) {\n\t\t\tmaxDepth = Number.parseInt(args[++i]!, 10);\n\t\t} else if (arg === \"--format\" && args[i + 1]) {\n\t\t\tformat = args[++i] as \"ansi\" | \"json\";\n\t\t} else if (arg !== \"--no-color\" && !arg.startsWith(\"-\")) {\n\t\t\tbinary = arg;\n\t\t}\n\t}\n\n\tif (!binary) {\n\t\tconsole.error(\"Error: provide a binary name\");\n\t\tconsole.error(\"Run 'clitree archaeology --help' for usage\");\n\t\tprocess.exit(1);\n\t}\n\n\tconst C = makeColors(shouldUseColor(args));\n\n\ttry {\n\t\tconsole.error(`${C.dim}⚠ LLM archaeology requires running inside the clitree skill.${C.reset}`);\n\t\tconsole.error(`${C.dim} Running deterministic phases only (help + history mining).${C.reset}`);\n\t\tconsole.error(\"\");\n\n\t\tconst [arch, mine] = await Promise.all([\n\t\t\trunArchaeology(binary, new NullDelegate(), { skipCache, maxHelpDepth: maxDepth }),\n\t\t\tmineCli(binary, { minSupport: 3 }).catch(() => null),\n\t\t]);\n\n\t\tif (format === \"json\") {\n\t\t\tconsole.log(JSON.stringify({ archaeology: arch, mining: mine }, null, 2));\n\t\t\treturn;\n\t\t}\n\n\t\tconsole.log(`${C.bold}${C.magenta}${binary}${C.reset}`);\n\t\tif (arch.tree.description) {\n\t\t\tconsole.log(`${C.gray}${arch.tree.description}${C.reset}`);\n\t\t}\n\t\tconsole.log();\n\n\t\tconsole.log(`${C.bold}Tree:${C.reset}`);\n\t\tconsole.log(` ${C.dim}Commands:${C.reset} ${C.cyan}${arch.stats.helpCommands}${C.reset}`);\n\t\tconsole.log(` ${C.dim}Cached:${C.reset} ${arch.fromCache ? `${C.green}yes${C.reset}` : `${C.dim}no${C.reset}`}`);\n\t\tconsole.log();\n\n\t\tif (mine) {\n\t\t\tconsole.log(`${C.bold}Usage from shell history:${C.reset}`);\n\t\t\tconsole.log(` ${C.dim}Invocations:${C.reset} ${C.cyan}${mine.stats.totalInvocations}${C.reset}`);\n\t\t\tconsole.log(` ${C.dim}Subcommands:${C.reset} ${C.cyan}${mine.stats.uniqueSubcommands}${C.reset}`);\n\n\t\t\tif (mine.workflows.length > 0) {\n\t\t\t\tconsole.log(`\\n${C.bold}Workflows you repeat:${C.reset}`);\n\t\t\t\tfor (const wf of mine.workflows.slice(0, 5)) {\n\t\t\t\t\tconst chain = wf.path[0]!.map(p => `${C.green}${p}${C.reset}`).join(` ${C.gray}→${C.reset} `);\n\t\t\t\t\tconsole.log(` ${chain} ${C.dim}(${wf.support}×)${C.reset}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mine.suggestions.length > 0) {\n\t\t\t\tconsole.log(`\\n${C.bold}${C.yellow}💡 Skill suggestions:${C.reset}`);\n\t\t\t\tfor (const s of mine.suggestions.slice(0, 3)) {\n\t\t\t\t\tconsole.log(` ${C.bold}/${s.name}${C.reset} — ${s.description}`);\n\t\t\t\t\tconsole.log(` ${C.dim}${s.reason}${C.reset}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconsole.log();\n\t\tconsole.log(`${C.dim}Install the clitree skill for full LLM archaeology:${C.reset}`);\n\t\tconsole.log(`${C.dim} bash ./skill/install.sh${C.reset}`);\n\t\tconsole.log();\n\t} catch (err: any) {\n\t\tconsole.error(`${C.red}Error: ${err.message}${C.reset}`);\n\t\tprocess.exit(1);\n\t}\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "36C7EC67BF0C8B9764756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HistoryEntry } from "./types";
|
|
2
|
+
export interface ActivityProfile {
|
|
3
|
+
/** Total invocations considered */
|
|
4
|
+
total: number;
|
|
5
|
+
/** Count per hour of day (0-23) */
|
|
6
|
+
hourOfDay: number[];
|
|
7
|
+
/** Count per day of week (0=Sun, 6=Sat) */
|
|
8
|
+
dayOfWeek: number[];
|
|
9
|
+
/** Count per day over the last N days (most recent last) */
|
|
10
|
+
last30Days: number[];
|
|
11
|
+
/** The earliest timestamp observed (unix seconds) */
|
|
12
|
+
firstSeen: number;
|
|
13
|
+
/** The latest timestamp observed (unix seconds) */
|
|
14
|
+
lastSeen: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compute temporal activity histograms from a list of history entries.
|
|
18
|
+
* Assumes entries have unix-second timestamps; entries with timestamp 0 are ignored.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeActivity(entries: HistoryEntry[], now?: Date): ActivityProfile;
|
|
21
|
+
export declare function formatTimeRange(firstSeen: number, lastSeen: number): string;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface CrossCliStep {
|
|
2
|
+
cli: string;
|
|
3
|
+
subcommand: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CrossCliWorkflow {
|
|
6
|
+
path: CrossCliStep[];
|
|
7
|
+
support: number;
|
|
8
|
+
signature: string;
|
|
9
|
+
uniqueCLIs: number;
|
|
10
|
+
}
|
|
11
|
+
export interface CrossCliOptions {
|
|
12
|
+
historyPath?: string;
|
|
13
|
+
sessionGapMinutes?: number;
|
|
14
|
+
minSupport?: number;
|
|
15
|
+
minPathLength?: number;
|
|
16
|
+
maxPathLength?: number;
|
|
17
|
+
topK?: number;
|
|
18
|
+
/** Only include workflows that cross at least this many distinct CLIs */
|
|
19
|
+
minDistinctCLIs?: number;
|
|
20
|
+
/** If non-empty, only consider entries whose cli[0] is in this set */
|
|
21
|
+
allowedCLIs?: string[];
|
|
22
|
+
/** Ignore CLIs that add noise (ls, cd, etc.) */
|
|
23
|
+
ignoreCLIs?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface CrossCliResult {
|
|
26
|
+
workflows: CrossCliWorkflow[];
|
|
27
|
+
sessionsAnalyzed: number;
|
|
28
|
+
distinctCLIs: string[];
|
|
29
|
+
totalTransitions: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Mine workflows that cross multiple CLIs. Unlike `mineCli`, this does NOT filter
|
|
33
|
+
* to a single binary up front. It looks at every command in a session and detects
|
|
34
|
+
* recurring sequences that weave between tools — e.g. `git push → gh pr create`,
|
|
35
|
+
* `docker build → docker push → kubectl apply`, `bun test → git commit → git push`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function mineCrossCli(options?: CrossCliOptions): Promise<CrossCliResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Convert a CrossCliWorkflow into a Workflow suitable for the flow renderer.
|
|
40
|
+
* Each node is labeled with "<cli> <sub>" so the DAG makes the cross-CLI nature obvious.
|
|
41
|
+
*/
|
|
42
|
+
export declare function crossCliToFlowWorkflow(workflow: CrossCliWorkflow): {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
cli: string;
|
|
46
|
+
nodes: {
|
|
47
|
+
id: string;
|
|
48
|
+
command: string[];
|
|
49
|
+
label: string;
|
|
50
|
+
}[];
|
|
51
|
+
edges: {
|
|
52
|
+
from: string;
|
|
53
|
+
to: string;
|
|
54
|
+
}[];
|
|
55
|
+
};
|
package/dist/miner/index.d.ts
CHANGED
|
@@ -5,9 +5,12 @@ import { extractPaths, clusterIntoWorkflows } from "./workflows";
|
|
|
5
5
|
import { computeStats } from "./stats";
|
|
6
6
|
import { suggestSkills, type SkillSuggestion } from "./suggest";
|
|
7
7
|
import { minedToFlowWorkflow } from "./to-flow";
|
|
8
|
+
import { computeActivity, formatTimeRange, type ActivityProfile } from "./activity";
|
|
9
|
+
import { sparkline, labeledSparkline } from "./sparkline";
|
|
10
|
+
import { mineCrossCli, crossCliToFlowWorkflow, type CrossCliOptions, type CrossCliResult, type CrossCliWorkflow, type CrossCliStep } from "./cross-cli";
|
|
8
11
|
import type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions } from "./types";
|
|
9
|
-
export type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion };
|
|
10
|
-
export { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat, segmentSessions, filterByCli, buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, minedToFlowWorkflow, };
|
|
12
|
+
export type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion, ActivityProfile, CrossCliOptions, CrossCliResult, CrossCliWorkflow, CrossCliStep, };
|
|
13
|
+
export { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat, segmentSessions, filterByCli, buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, minedToFlowWorkflow, computeActivity, formatTimeRange, sparkline, labeledSparkline, mineCrossCli, crossCliToFlowWorkflow, };
|
|
11
14
|
export interface MineResult {
|
|
12
15
|
cli: string;
|
|
13
16
|
stats: CliUsageStats;
|
|
@@ -15,5 +18,6 @@ export interface MineResult {
|
|
|
15
18
|
workflows: MinedWorkflow[];
|
|
16
19
|
suggestions: SkillSuggestion[];
|
|
17
20
|
sessionsAnalyzed: number;
|
|
21
|
+
activity: ActivityProfile;
|
|
18
22
|
}
|
|
19
23
|
export declare function mineCli(cli: string, options?: MineOptions): Promise<MineResult>;
|
package/dist/miner/index.js
CHANGED
|
@@ -1,40 +1,52 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildTransitions,
|
|
3
3
|
clusterIntoWorkflows,
|
|
4
|
+
computeActivity,
|
|
4
5
|
computeStats,
|
|
6
|
+
crossCliToFlowWorkflow,
|
|
5
7
|
defaultHistoryPath,
|
|
6
8
|
detectHistoryFormat,
|
|
7
9
|
extractPaths,
|
|
8
10
|
extractSubcommand,
|
|
9
11
|
extractSubcommandPath,
|
|
10
12
|
filterByCli,
|
|
13
|
+
formatTimeRange,
|
|
14
|
+
labeledSparkline,
|
|
11
15
|
mineCli,
|
|
16
|
+
mineCrossCli,
|
|
12
17
|
minedToFlowWorkflow,
|
|
13
18
|
normalizeTransitions,
|
|
14
19
|
parseHistory,
|
|
15
20
|
readHistoryFile,
|
|
16
21
|
segmentSessions,
|
|
22
|
+
sparkline,
|
|
17
23
|
suggestSkills,
|
|
18
24
|
tokenize
|
|
19
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-9pnqbn7b.js";
|
|
20
26
|
export {
|
|
21
27
|
tokenize,
|
|
22
28
|
suggestSkills,
|
|
29
|
+
sparkline,
|
|
23
30
|
segmentSessions,
|
|
24
31
|
readHistoryFile,
|
|
25
32
|
parseHistory,
|
|
26
33
|
normalizeTransitions,
|
|
27
34
|
minedToFlowWorkflow,
|
|
35
|
+
mineCrossCli,
|
|
28
36
|
mineCli,
|
|
37
|
+
labeledSparkline,
|
|
38
|
+
formatTimeRange,
|
|
29
39
|
filterByCli,
|
|
30
40
|
extractSubcommandPath,
|
|
31
41
|
extractSubcommand,
|
|
32
42
|
extractPaths,
|
|
33
43
|
detectHistoryFormat,
|
|
34
44
|
defaultHistoryPath,
|
|
45
|
+
crossCliToFlowWorkflow,
|
|
35
46
|
computeStats,
|
|
47
|
+
computeActivity,
|
|
36
48
|
clusterIntoWorkflows,
|
|
37
49
|
buildTransitions
|
|
38
50
|
};
|
|
39
51
|
|
|
40
|
-
//# debugId=
|
|
52
|
+
//# debugId=3F080486405E782764756E2164756E21
|
package/dist/miner/index.js.map
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Unicode sparkline for a numeric array.
|
|
3
|
+
*
|
|
4
|
+
* We could depend on @crafter/charts for this, but keeping zero deps means
|
|
5
|
+
* clitree stays as a single focused package. The logic is trivial: bucket each
|
|
6
|
+
* value into one of 8 block characters (▁▂▃▄▅▆▇█).
|
|
7
|
+
*/
|
|
8
|
+
export declare function sparkline(data: number[], opts?: {
|
|
9
|
+
empty?: string;
|
|
10
|
+
}): string;
|
|
11
|
+
/**
|
|
12
|
+
* Render a labeled row like "Mon ▁▃▅█▇▅▃▂" — used for day-of-week activity.
|
|
13
|
+
*/
|
|
14
|
+
export declare function labeledSparkline(label: string, data: number[], labelWidth?: number): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crafter/cli-tree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Explore and map any CLI tool deeply. Parse --help trees, mine shell history for repeated workflows, surface hidden flags via LLM archaeology, and suggest new agent skills from your usage patterns.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/skill/SKILL.md
CHANGED
|
@@ -87,7 +87,15 @@ Read the result. You get:
|
|
|
87
87
|
$CLITREE mine "$TARGET_BINARY"
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
This prints a
|
|
90
|
+
This prints a single rich block containing **three visualizations at once**:
|
|
91
|
+
|
|
92
|
+
1. **ASCII bar charts** for the user's top subcommands (ranked with Unicode `██` bars)
|
|
93
|
+
2. **A ranked workflow list** with frequency counts (`add → commit → push (64×)`)
|
|
94
|
+
3. **An ASCII DAG** of the top non-trivial workflow — boxed nodes with arrows, rendered with the same engine as the bundled workflow YAMLs
|
|
95
|
+
|
|
96
|
+
**Capture this entire block — you'll paste it verbatim inside a fenced code block in the `## Your usage` section of the final report.** Do not re-type any part of it. The bars, the workflow list, and the DAG are all value-dense visuals that don't translate well to prose.
|
|
97
|
+
|
|
98
|
+
The DAG auto-renders when the top workflow has 3+ steps. Pass `--with-flow` to force it on for 2-step chains, or `--no-flow` to skip it entirely.
|
|
91
99
|
|
|
92
100
|
Three scenarios from the invocation count:
|
|
93
101
|
|
|
@@ -116,24 +124,77 @@ For detailed prompt templates that help you think through each category systemat
|
|
|
116
124
|
|
|
117
125
|
## Phase 4 — Validate every proposal
|
|
118
126
|
|
|
119
|
-
This is the step that separates archaeology from hallucination. For each flag you propose, verify it exists
|
|
127
|
+
This is the step that separates archaeology from hallucination. For each flag you propose, verify it exists.
|
|
128
|
+
|
|
129
|
+
### The right way to query help
|
|
130
|
+
|
|
131
|
+
**Short help vs long help matters.** Most CLIs have two help outputs:
|
|
132
|
+
|
|
133
|
+
- `<cli> <sub> -h` → **short inline help** (fast, plain text, no pager)
|
|
134
|
+
- `<cli> <sub> --help` → **long help / man page** (slow, may open a pager, often has overstrike formatting)
|
|
135
|
+
|
|
136
|
+
For **git specifically**, `git <cmd> --help` is equivalent to `man git-<cmd>`, which:
|
|
137
|
+
- Opens a pager in a TTY (hangs the agent)
|
|
138
|
+
- Pipes raw `nroff` output with overstrike sequences (`\b`) in a non-TTY — you get `ffiixxuupp` instead of `fixup`
|
|
139
|
+
|
|
140
|
+
**Always prefer `-h` first.** Fall back to `--help` only if `-h` doesn't exist for that CLI.
|
|
141
|
+
|
|
142
|
+
### Recommended validation patterns
|
|
143
|
+
|
|
144
|
+
**The easy way — use the `safe-help` subcommand.** It tries `-h`, `--help`, `help <sub>`, and man pages in order, strips overstrike formatting, kills pagers, and returns clean text every time:
|
|
120
145
|
|
|
121
146
|
```bash
|
|
122
|
-
#
|
|
123
|
-
|
|
147
|
+
# Fetch clean help for any CLI subcommand
|
|
148
|
+
$CLITREE safe-help git commit | grep -E -- "--fixup|--amend|--no-verify"
|
|
149
|
+
$CLITREE safe-help docker run | grep -E -- "--gpus|--platform"
|
|
150
|
+
$CLITREE safe-help kubectl get | grep -E -- "--selector|--output"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Always prefer `safe-help` over raw `--help`.** It handles:
|
|
154
|
+
- `git <cmd> --help` opening a man pager and hanging
|
|
155
|
+
- macOS nroff overstriking (`ffiixxuupp` → `fixup`)
|
|
156
|
+
- CLIs where `-h` isn't supported (like docker subcommands)
|
|
157
|
+
- CLIs where the help lives under `help <sub>` syntax (like git's own internal convention)
|
|
158
|
+
|
|
159
|
+
**If you must call the binary directly** (e.g. the user's CLI isn't mainstream), follow this precedence:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Pattern 1 (preferred): short help, inline, no pager
|
|
163
|
+
"$TARGET_BINARY" "$SUBCOMMAND" -h 2>&1 | grep -E -- "--<flag>|-<short>\b"
|
|
124
164
|
|
|
125
|
-
#
|
|
126
|
-
man "
|
|
165
|
+
# Pattern 2 (git-safe): force man page through col to strip overstrikes
|
|
166
|
+
MANPAGER=cat PAGER=cat man "git-$SUBCOMMAND" 2>/dev/null | col -bx | grep -E -- "--<flag>|-<short>\b"
|
|
167
|
+
|
|
168
|
+
# Pattern 3 (fallback): man for non-git binaries
|
|
169
|
+
MANPAGER=cat PAGER=cat man "$TARGET_BINARY" 2>/dev/null | col -bx | grep -E -- "--<flag>|-<short>\b"
|
|
127
170
|
```
|
|
128
171
|
|
|
172
|
+
**Key details:**
|
|
173
|
+
- `--` before the pattern tells grep the rest isn't options (otherwise `-S` in the pattern breaks grep)
|
|
174
|
+
- `col -bx` strips overstrike/bold formatting → no more `ffiixxuupp`
|
|
175
|
+
- `MANPAGER=cat PAGER=cat` prevents pagers from opening in edge cases
|
|
176
|
+
- `2>&1` captures stderr so grep sees error messages too
|
|
177
|
+
|
|
178
|
+
### What to do with each result
|
|
179
|
+
|
|
129
180
|
Mark each finding:
|
|
130
|
-
- **`verified`** — appears in
|
|
131
|
-
- **`verified-by-man`** — not in help, but man confirms
|
|
181
|
+
- **`verified`** — appears in `<cli> <sub> -h`
|
|
182
|
+
- **`verified-by-man`** — not in short help, but man confirms after `col -bx`
|
|
132
183
|
- **`unconfirmed`** — neither confirms; keep only if you're highly confident AND can explain the evidence (e.g. "shown in docker/docker#12345")
|
|
133
184
|
- **`rejected`** — fail to validate → drop it silently, never include in final output
|
|
134
185
|
|
|
135
186
|
Better to surface 3 verified flags than 10 unconfirmed ones. **Your credibility is built on rejection rate.** When you mark something unconfirmed, explain why you still believe it.
|
|
136
187
|
|
|
188
|
+
### Pitfalls observed in the wild
|
|
189
|
+
|
|
190
|
+
- **`git commit --help` opens a man page**, not inline help. Use `git commit -h` instead.
|
|
191
|
+
- **`docker --help` pipes fine**, but `docker run --help` is long and truncates at tty width if piped through `head`.
|
|
192
|
+
- **`kubectl <sub> --help`** is safe and inline — no pager issues.
|
|
193
|
+
- **`bun <sub> --help`** is safe and inline.
|
|
194
|
+
- **`pnpm <sub> --help`** is safe and inline.
|
|
195
|
+
- **BSD/macOS `man` overstrikes bold text with `\b`.** Always pipe through `col -bx` when parsing man output.
|
|
196
|
+
- **Never paste raw man output into the report.** If you see `ffiixxuupp`, that's overstriking — filter it first or use `-h` instead.
|
|
197
|
+
|
|
137
198
|
## Phase 5 — Render the report
|
|
138
199
|
|
|
139
200
|
Produce this exact structure. Consistency matters — the user learns the shape and scans it quickly on future runs.
|