@crafter/cli-tree 0.1.1 → 0.1.3

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.
@@ -401,6 +401,29 @@ function generateReason(frequency, path, stats) {
401
401
  return `Detected ${frequency} times in your shell history`;
402
402
  }
403
403
 
404
+ // src/miner/to-flow.ts
405
+ function minedToFlowWorkflow(mined, occurrences) {
406
+ const path = mined.path[0] ?? [];
407
+ const label = path.join(" → ");
408
+ const freq = occurrences ?? mined.support;
409
+ const nodes = path.map((sub, idx) => ({
410
+ id: `n${idx}`,
411
+ command: [mined.cli, sub],
412
+ label: sub
413
+ }));
414
+ const edges = [];
415
+ for (let i = 0;i < nodes.length - 1; i++) {
416
+ edges.push({ from: nodes[i].id, to: nodes[i + 1].id });
417
+ }
418
+ return {
419
+ name: label,
420
+ description: `Seen ${freq}× in your shell history`,
421
+ cli: mined.cli,
422
+ nodes,
423
+ edges
424
+ };
425
+ }
426
+
404
427
  // src/miner/index.ts
405
428
  async function mineCli(cli, options = {}) {
406
429
  const path = options.historyPath ?? defaultHistoryPath();
@@ -429,6 +452,6 @@ async function mineCli(cli, options = {}) {
429
452
  };
430
453
  }
431
454
 
432
- export { readHistoryFile, detectHistoryFormat, parseHistory, tokenize, defaultHistoryPath, segmentSessions, filterByCli, extractSubcommand, extractSubcommandPath, buildTransitions, normalizeTransitions, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, mineCli };
455
+ export { readHistoryFile, detectHistoryFormat, parseHistory, tokenize, defaultHistoryPath, segmentSessions, filterByCli, extractSubcommand, extractSubcommandPath, buildTransitions, normalizeTransitions, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, minedToFlowWorkflow, mineCli };
433
456
 
434
- //# debugId=83F3B582B342B95E64756E2164756E21
457
+ //# debugId=9D659A5F2CF096F164756E2164756E21
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/miner/history.ts", "../src/miner/sessions.ts", "../src/miner/transitions.ts", "../src/miner/workflows.ts", "../src/miner/stats.ts", "../src/miner/suggest.ts", "../src/miner/index.ts"],
3
+ "sources": ["../src/miner/history.ts", "../src/miner/sessions.ts", "../src/miner/transitions.ts", "../src/miner/workflows.ts", "../src/miner/stats.ts", "../src/miner/suggest.ts", "../src/miner/to-flow.ts", "../src/miner/index.ts"],
4
4
  "sourcesContent": [
5
5
  "import type { HistoryEntry } from \"./types\";\n\nexport async function readHistoryFile(path: string): Promise<string> {\n\treturn await Bun.file(path).text();\n}\n\nexport function detectHistoryFormat(text: string): \"zsh-extended\" | \"bash\" | \"fish\" | \"unknown\" {\n\tconst firstNonEmpty = text.split(\"\\n\").find(l => l.trim().length > 0);\n\tif (!firstNonEmpty) return \"unknown\";\n\tif (/^: \\d+:\\d+;/.test(firstNonEmpty)) return \"zsh-extended\";\n\tif (/^- cmd: /.test(firstNonEmpty)) return \"fish\";\n\treturn \"bash\";\n}\n\nexport function parseHistory(text: string): HistoryEntry[] {\n\tconst format = detectHistoryFormat(text);\n\tswitch (format) {\n\t\tcase \"zsh-extended\":\n\t\t\treturn parseZshExtended(text);\n\t\tcase \"fish\":\n\t\t\treturn parseFishHistory(text);\n\t\tcase \"bash\":\n\t\tdefault:\n\t\t\treturn parseBashHistory(text);\n\t}\n}\n\nfunction parseZshExtended(text: string): HistoryEntry[] {\n\tconst entries: HistoryEntry[] = [];\n\tconst lines = text.split(\"\\n\");\n\n\tlet pending: { timestamp: number; cmd: string } | null = null;\n\n\tfor (const rawLine of lines) {\n\t\tconst match = rawLine.match(/^: (\\d+):\\d+;(.*)$/);\n\t\tif (match) {\n\t\t\tif (pending) {\n\t\t\t\tentries.push(buildEntry(pending.timestamp, pending.cmd));\n\t\t\t}\n\t\t\tpending = { timestamp: Number.parseInt(match[1]!, 10), cmd: match[2]! };\n\t\t} else if (pending) {\n\t\t\tpending.cmd += \"\\n\" + rawLine;\n\t\t}\n\t}\n\n\tif (pending) {\n\t\tentries.push(buildEntry(pending.timestamp, pending.cmd));\n\t}\n\n\treturn entries.filter(e => e.argv.length > 0);\n}\n\nfunction parseBashHistory(text: string): HistoryEntry[] {\n\tconst entries: HistoryEntry[] = [];\n\tconst lines = text.split(\"\\n\");\n\tlet currentTimestamp = 0;\n\n\tfor (const line of lines) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\n\t\tif (/^#\\d+$/.test(trimmed)) {\n\t\t\tcurrentTimestamp = Number.parseInt(trimmed.slice(1), 10);\n\t\t\tcontinue;\n\t\t}\n\n\t\tentries.push(buildEntry(currentTimestamp, trimmed));\n\t}\n\n\treturn entries.filter(e => e.argv.length > 0);\n}\n\nfunction parseFishHistory(text: string): HistoryEntry[] {\n\tconst entries: HistoryEntry[] = [];\n\tconst blocks = text.split(/\\n(?=- cmd: )/);\n\n\tfor (const block of blocks) {\n\t\tconst cmdMatch = block.match(/- cmd: (.*)/);\n\t\tconst whenMatch = block.match(/when: (\\d+)/);\n\t\tif (!cmdMatch) continue;\n\t\tconst timestamp = whenMatch ? Number.parseInt(whenMatch[1]!, 10) : 0;\n\t\tentries.push(buildEntry(timestamp, cmdMatch[1]!));\n\t}\n\n\treturn entries.filter(e => e.argv.length > 0);\n}\n\nfunction buildEntry(timestamp: number, rawCmd: string): HistoryEntry {\n\tconst cleaned = stripContinuations(rawCmd).trim();\n\tconst argv = tokenize(cleaned);\n\treturn { timestamp, raw: cleaned, argv };\n}\n\nfunction stripContinuations(cmd: string): string {\n\treturn cmd.replace(/\\\\\\n/g, \" \").replace(/\\n\\s*/g, \" \");\n}\n\nexport function tokenize(cmd: string): string[] {\n\tconst tokens: string[] = [];\n\tlet current = \"\";\n\tlet inSingle = false;\n\tlet inDouble = false;\n\tlet escape = false;\n\n\tfor (let i = 0; i < cmd.length; i++) {\n\t\tconst ch = cmd[i]!;\n\t\tif (escape) {\n\t\t\tcurrent += ch;\n\t\t\tescape = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"\\\\\" && !inSingle) {\n\t\t\tescape = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"'\" && !inDouble) {\n\t\t\tinSingle = !inSingle;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === '\"' && !inSingle) {\n\t\t\tinDouble = !inDouble;\n\t\t\tcontinue;\n\t\t}\n\t\tif (/\\s/.test(ch) && !inSingle && !inDouble) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif ((ch === \"|\" || ch === \";\" || ch === \"&\") && !inSingle && !inDouble) {\n\t\t\tif (current) {\n\t\t\t\ttokens.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t\treturn tokens;\n\t\t}\n\t\tcurrent += ch;\n\t}\n\n\tif (current) tokens.push(current);\n\treturn tokens;\n}\n\nexport function defaultHistoryPath(): string | null {\n\tconst home = process.env.HOME ?? \"\";\n\tif (!home) return null;\n\n\tconst candidates = [\n\t\t`${home}/.zsh_history`,\n\t\t`${home}/.bash_history`,\n\t\t`${home}/.config/fish/fish_history`,\n\t];\n\n\treturn candidates[0] ?? null;\n}\n",
6
6
  "import type { HistoryEntry, Session } from \"./types\";\n\nexport function segmentSessions(entries: HistoryEntry[], gapMinutes = 10): Session[] {\n\tif (entries.length === 0) return [];\n\n\tconst sorted = [...entries].sort((a, b) => a.timestamp - b.timestamp);\n\tconst gapSeconds = gapMinutes * 60;\n\tconst sessions: Session[] = [];\n\n\tlet current: HistoryEntry[] = [sorted[0]!];\n\tlet sessionStart = sorted[0]!.timestamp;\n\tlet lastTimestamp = sorted[0]!.timestamp;\n\n\tfor (let i = 1; i < sorted.length; i++) {\n\t\tconst entry = sorted[i]!;\n\t\tconst gap = entry.timestamp - lastTimestamp;\n\n\t\tif (gap > gapSeconds) {\n\t\t\tsessions.push({ start: sessionStart, end: lastTimestamp, entries: current });\n\t\t\tcurrent = [entry];\n\t\t\tsessionStart = entry.timestamp;\n\t\t} else {\n\t\t\tcurrent.push(entry);\n\t\t}\n\t\tlastTimestamp = entry.timestamp;\n\t}\n\n\tsessions.push({ start: sessionStart, end: lastTimestamp, entries: current });\n\treturn sessions;\n}\n\nexport function filterByCli(sessions: Session[], cli: string): Session[] {\n\treturn sessions\n\t\t.map(session => ({\n\t\t\t...session,\n\t\t\tentries: session.entries.filter(e => e.argv[0] === cli),\n\t\t}))\n\t\t.filter(s => s.entries.length > 0);\n}\n",
@@ -8,9 +8,10 @@
8
8
  "import type { Session, MinedWorkflow } from \"./types\";\nimport { extractSubcommand } from \"./transitions\";\n\nexport interface PathCluster {\n\tsignature: string;\n\tpath: string[];\n\toccurrences: number;\n}\n\nexport function extractPaths(\n\tsessions: Session[],\n\tminLength = 2,\n\tmaxLength = 7,\n): PathCluster[] {\n\tconst pathCounts = new Map<string, { path: string[]; count: number }>();\n\n\tfor (const session of sessions) {\n\t\tconst subcommands = session.entries.map(extractSubcommand);\n\t\tconst dedupedConsecutive = dedupeConsecutive(subcommands);\n\n\t\tfor (let start = 0; start < dedupedConsecutive.length; start++) {\n\t\t\tconst maxEnd = Math.min(start + maxLength, dedupedConsecutive.length);\n\t\t\tfor (let end = start + minLength; end <= maxEnd; end++) {\n\t\t\t\tconst slice = dedupedConsecutive.slice(start, end);\n\t\t\t\tconst sig = slice.join(\" → \");\n\t\t\t\tconst existing = pathCounts.get(sig);\n\t\t\t\tif (existing) {\n\t\t\t\t\texisting.count += 1;\n\t\t\t\t} else {\n\t\t\t\t\tpathCounts.set(sig, { path: slice, count: 1 });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(pathCounts.entries())\n\t\t.map(([signature, { path, count }]) => ({\n\t\t\tsignature,\n\t\t\tpath,\n\t\t\toccurrences: count,\n\t\t}))\n\t\t.sort((a, b) => {\n\t\t\tif (b.occurrences !== a.occurrences) return b.occurrences - a.occurrences;\n\t\t\treturn b.path.length - a.path.length;\n\t\t});\n}\n\nexport function clusterIntoWorkflows(\n\tclusters: PathCluster[],\n\tcli: string,\n\toptions: { minSupport?: number; topK?: number } = {},\n): MinedWorkflow[] {\n\tconst minSupport = options.minSupport ?? 2;\n\tconst topK = options.topK ?? 10;\n\n\tconst filtered = clusters.filter(c => c.occurrences >= minSupport);\n\tconst deduped = removeSubPaths(filtered);\n\n\tconst totalOccurrences = clusters.reduce((sum, c) => sum + c.occurrences, 0) || 1;\n\n\treturn deduped.slice(0, topK).map(cluster => ({\n\t\tname: cluster.path.join(\"-\"),\n\t\tcli,\n\t\tpath: [cluster.path],\n\t\tsupport: cluster.occurrences,\n\t\tconfidence: cluster.occurrences / totalOccurrences,\n\t\tsource: \"history\" as const,\n\t}));\n}\n\nfunction dedupeConsecutive(items: string[]): string[] {\n\tconst result: string[] = [];\n\tfor (const item of items) {\n\t\tif (result.length === 0 || result[result.length - 1] !== item) {\n\t\t\tresult.push(item);\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction removeSubPaths(clusters: PathCluster[]): PathCluster[] {\n\tconst sortedByLength = [...clusters].sort((a, b) => b.path.length - a.path.length);\n\tconst kept: PathCluster[] = [];\n\n\tfor (const cluster of sortedByLength) {\n\t\tconst sig = cluster.signature;\n\t\tconst alreadyCoveredBy = kept.find(k =>\n\t\t\tk.signature.includes(sig) && k.occurrences >= cluster.occurrences * 0.8,\n\t\t);\n\t\tif (!alreadyCoveredBy) {\n\t\t\tkept.push(cluster);\n\t\t}\n\t}\n\n\treturn kept.sort((a, b) => b.occurrences - a.occurrences);\n}\n",
9
9
  "import type { HistoryEntry, CliUsageStats, Session } from \"./types\";\nimport { extractSubcommand } from \"./transitions\";\n\nexport function computeStats(entries: HistoryEntry[], sessions: Session[], cli: string): CliUsageStats {\n\tconst cliEntries = entries.filter(e => e.argv[0] === cli);\n\tconst cliSessions = sessions.filter(s => s.entries.some(e => e.argv[0] === cli));\n\n\tconst subcommandCounts = new Map<string, number>();\n\tconst flagCounts = new Map<string, number>();\n\n\tfor (const entry of cliEntries) {\n\t\tconst sub = extractSubcommand(entry);\n\t\tsubcommandCounts.set(sub, (subcommandCounts.get(sub) ?? 0) + 1);\n\n\t\tfor (const arg of entry.argv.slice(1)) {\n\t\t\tif (arg.startsWith(\"--\")) {\n\t\t\t\tconst flag = arg.split(\"=\")[0]!;\n\t\t\t\tflagCounts.set(flag, (flagCounts.get(flag) ?? 0) + 1);\n\t\t\t} else if (arg.startsWith(\"-\") && arg.length === 2) {\n\t\t\t\tflagCounts.set(arg, (flagCounts.get(arg) ?? 0) + 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst topSubcommands = Array.from(subcommandCounts.entries())\n\t\t.map(([subcommand, count]) => ({ subcommand, count }))\n\t\t.sort((a, b) => b.count - a.count)\n\t\t.slice(0, 10);\n\n\tconst topFlags = Array.from(flagCounts.entries())\n\t\t.map(([flag, count]) => ({ flag, count }))\n\t\t.sort((a, b) => b.count - a.count)\n\t\t.slice(0, 10);\n\n\treturn {\n\t\tcli,\n\t\ttotalInvocations: cliEntries.length,\n\t\tuniqueSubcommands: subcommandCounts.size,\n\t\ttopSubcommands,\n\t\ttopFlags,\n\t\tsessionCount: cliSessions.length,\n\t};\n}\n",
10
10
  "import type { MinedWorkflow, CliUsageStats } from \"./types\";\n\nexport interface SkillSuggestion {\n\tname: string;\n\tdescription: string;\n\tcli: string;\n\tcommands: string[];\n\tfrequency: number;\n\treason: string;\n\tpriority: \"high\" | \"medium\" | \"low\";\n}\n\nexport function suggestSkills(\n\tworkflows: MinedWorkflow[],\n\tstats: CliUsageStats,\n): SkillSuggestion[] {\n\tconst suggestions: SkillSuggestion[] = [];\n\n\tfor (const wf of workflows) {\n\t\tconst path = wf.path[0] ?? [];\n\t\tif (path.length < 2) continue;\n\n\t\tconst suggestion = workflowToSuggestion(wf, stats);\n\t\tif (suggestion) suggestions.push(suggestion);\n\t}\n\n\treturn suggestions.sort((a, b) => {\n\t\tconst priorityOrder = { high: 0, medium: 1, low: 2 };\n\t\tif (priorityOrder[a.priority] !== priorityOrder[b.priority]) {\n\t\t\treturn priorityOrder[a.priority] - priorityOrder[b.priority];\n\t\t}\n\t\treturn b.frequency - a.frequency;\n\t});\n}\n\nfunction workflowToSuggestion(wf: MinedWorkflow, stats: CliUsageStats): SkillSuggestion | null {\n\tconst path = wf.path[0] ?? [];\n\tif (path.length < 2) return null;\n\n\tconst commands = path.map(sub => `${wf.cli} ${sub}`);\n\tconst frequency = wf.support;\n\n\tconst priority = scorePriority(frequency, path.length, stats.totalInvocations);\n\n\tconst name = generateSkillName(wf.cli, path);\n\tconst description = generateDescription(wf.cli, path);\n\tconst reason = generateReason(frequency, path, stats);\n\n\treturn { name, description, cli: wf.cli, commands, frequency, reason, priority };\n}\n\nfunction scorePriority(frequency: number, pathLength: number, totalInvocations: number): \"high\" | \"medium\" | \"low\" {\n\tconst ratio = frequency / totalInvocations;\n\tconst score = frequency * pathLength * (ratio + 0.1);\n\n\tif (score > 50) return \"high\";\n\tif (score > 15) return \"medium\";\n\treturn \"low\";\n}\n\nfunction generateSkillName(cli: string, path: string[]): string {\n\tconst knownPatterns: Record<string, string> = {\n\t\t\"add,commit\": \"ship\",\n\t\t\"add,commit,push\": \"ship\",\n\t\t\"commit,push\": \"push-latest\",\n\t\t\"install,dev\": \"start\",\n\t\t\"install,run\": \"start\",\n\t\t\"login,publish\": \"release\",\n\t\t\"publish,tag\": \"release\",\n\t\t\"checkout,pull\": \"sync\",\n\t\t\"fetch,pull\": \"sync\",\n\t\t\"build,push\": \"deploy\",\n\t\t\"build,run\": \"test-build\",\n\t\t\"compose,compose\": \"compose-iterate\",\n\t};\n\n\tconst key = path.join(\",\");\n\tif (knownPatterns[key]) return knownPatterns[key]!;\n\n\treturn path.join(\"-\");\n}\n\nfunction generateDescription(cli: string, path: string[]): string {\n\treturn `Run ${cli} ${path.join(\", then \")} as one command`;\n}\n\nfunction generateReason(frequency: number, path: string[], stats: CliUsageStats): string {\n\tconst ratio = frequency / stats.totalInvocations;\n\tconst pct = (ratio * 100).toFixed(0);\n\n\tif (ratio > 0.1) {\n\t\treturn `You run this exact sequence ${frequency} times (${pct}% of all your ${stats.cli} usage)`;\n\t}\n\tif (frequency >= 50) {\n\t\treturn `You run this exact sequence ${frequency} times — that's a lot of repetition`;\n\t}\n\tif (frequency >= 20) {\n\t\treturn `You run this exact sequence ${frequency} times`;\n\t}\n\treturn `Detected ${frequency} times in your shell history`;\n}\n",
11
- "import { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat } from \"./history\";\nimport { segmentSessions, filterByCli } from \"./sessions\";\nimport { buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath } from \"./transitions\";\nimport { extractPaths, clusterIntoWorkflows } from \"./workflows\";\nimport { computeStats } from \"./stats\";\nimport { suggestSkills, type SkillSuggestion } from \"./suggest\";\nimport type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions } from \"./types\";\n\nexport type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion };\nexport {\n\tparseHistory,\n\treadHistoryFile,\n\tdefaultHistoryPath,\n\ttokenize,\n\tdetectHistoryFormat,\n\tsegmentSessions,\n\tfilterByCli,\n\tbuildTransitions,\n\tnormalizeTransitions,\n\textractSubcommand,\n\textractSubcommandPath,\n\textractPaths,\n\tclusterIntoWorkflows,\n\tcomputeStats,\n\tsuggestSkills,\n};\n\nexport interface MineResult {\n\tcli: string;\n\tstats: CliUsageStats;\n\ttransitions: Transition[];\n\tworkflows: MinedWorkflow[];\n\tsuggestions: SkillSuggestion[];\n\tsessionsAnalyzed: number;\n}\n\nexport async function mineCli(cli: string, options: MineOptions = {}): Promise<MineResult> {\n\tconst path = options.historyPath ?? defaultHistoryPath();\n\tif (!path) {\n\t\tthrow new Error(\"Could not determine shell history path. Pass historyPath explicitly.\");\n\t}\n\n\tconst text = await readHistoryFile(path);\n\tconst entries = parseHistory(text);\n\tconst allSessions = segmentSessions(entries, options.sessionGapMinutes ?? 10);\n\tconst cliSessions = filterByCli(allSessions, cli);\n\n\tconst stats = computeStats(entries, allSessions, cli);\n\n\tconst rawTransitions = buildTransitions(cliSessions);\n\tconst transitions = normalizeTransitions(\n\t\trawTransitions,\n\t\toptions.minSupport ?? 3,\n\t\toptions.minConfidence ?? 0.2,\n\t);\n\n\tconst paths = extractPaths(\n\t\tcliSessions,\n\t\toptions.minPathLength ?? 2,\n\t\toptions.maxPathLength ?? 6,\n\t);\n\tconst workflows = clusterIntoWorkflows(paths, cli, {\n\t\tminSupport: options.minSupport ?? 3,\n\t});\n\n\tconst suggestions = suggestSkills(workflows, stats);\n\n\treturn {\n\t\tcli,\n\t\tstats,\n\t\ttransitions,\n\t\tworkflows,\n\t\tsuggestions,\n\t\tsessionsAnalyzed: cliSessions.length,\n\t};\n}\n"
11
+ "import type { Workflow } from \"../flow/types\";\nimport type { MinedWorkflow } from \"./types\";\n\n/**\n * Convert a MinedWorkflow (discovered from shell history) into a Workflow\n * that the flow renderer can visualize as an ASCII DAG.\n *\n * The mined workflow is a linear path like [\"add\", \"commit\", \"push\"] with\n * a frequency count. We turn it into a linear Workflow with one node per\n * step and edges in order matching the shape of the handcrafted YAML\n * workflows in workflows/.\n */\nexport function minedToFlowWorkflow(mined: MinedWorkflow, occurrences?: number): Workflow {\n\tconst path = mined.path[0] ?? [];\n\tconst label = path.join(\" → \");\n\tconst freq = occurrences ?? mined.support;\n\n\tconst nodes = path.map((sub, idx) => ({\n\t\tid: `n${idx}`,\n\t\tcommand: [mined.cli, sub],\n\t\tlabel: sub,\n\t}));\n\n\tconst edges = [];\n\tfor (let i = 0; i < nodes.length - 1; i++) {\n\t\tedges.push({ from: nodes[i]!.id, to: nodes[i + 1]!.id });\n\t}\n\n\treturn {\n\t\tname: label,\n\t\tdescription: `Seen ${freq}× in your shell history`,\n\t\tcli: mined.cli,\n\t\tnodes,\n\t\tedges,\n\t};\n}\n",
12
+ "import { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat } from \"./history\";\nimport { segmentSessions, filterByCli } from \"./sessions\";\nimport { buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath } from \"./transitions\";\nimport { extractPaths, clusterIntoWorkflows } from \"./workflows\";\nimport { computeStats } from \"./stats\";\nimport { suggestSkills, type SkillSuggestion } from \"./suggest\";\nimport { minedToFlowWorkflow } from \"./to-flow\";\nimport type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions } from \"./types\";\n\nexport type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion };\nexport {\n\tparseHistory,\n\treadHistoryFile,\n\tdefaultHistoryPath,\n\ttokenize,\n\tdetectHistoryFormat,\n\tsegmentSessions,\n\tfilterByCli,\n\tbuildTransitions,\n\tnormalizeTransitions,\n\textractSubcommand,\n\textractSubcommandPath,\n\textractPaths,\n\tclusterIntoWorkflows,\n\tcomputeStats,\n\tsuggestSkills,\n\tminedToFlowWorkflow,\n};\n\nexport interface MineResult {\n\tcli: string;\n\tstats: CliUsageStats;\n\ttransitions: Transition[];\n\tworkflows: MinedWorkflow[];\n\tsuggestions: SkillSuggestion[];\n\tsessionsAnalyzed: number;\n}\n\nexport async function mineCli(cli: string, options: MineOptions = {}): Promise<MineResult> {\n\tconst path = options.historyPath ?? defaultHistoryPath();\n\tif (!path) {\n\t\tthrow new Error(\"Could not determine shell history path. Pass historyPath explicitly.\");\n\t}\n\n\tconst text = await readHistoryFile(path);\n\tconst entries = parseHistory(text);\n\tconst allSessions = segmentSessions(entries, options.sessionGapMinutes ?? 10);\n\tconst cliSessions = filterByCli(allSessions, cli);\n\n\tconst stats = computeStats(entries, allSessions, cli);\n\n\tconst rawTransitions = buildTransitions(cliSessions);\n\tconst transitions = normalizeTransitions(\n\t\trawTransitions,\n\t\toptions.minSupport ?? 3,\n\t\toptions.minConfidence ?? 0.2,\n\t);\n\n\tconst paths = extractPaths(\n\t\tcliSessions,\n\t\toptions.minPathLength ?? 2,\n\t\toptions.maxPathLength ?? 6,\n\t);\n\tconst workflows = clusterIntoWorkflows(paths, cli, {\n\t\tminSupport: options.minSupport ?? 3,\n\t});\n\n\tconst suggestions = suggestSkills(workflows, stats);\n\n\treturn {\n\t\tcli,\n\t\tstats,\n\t\ttransitions,\n\t\tworkflows,\n\t\tsuggestions,\n\t\tsessionsAnalyzed: cliSessions.length,\n\t};\n}\n"
12
13
  ],
13
- "mappings": "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",
14
- "debugId": "83F3B582B342B95E64756E2164756E21",
14
+ "mappings": "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",
15
+ "debugId": "9D659A5F2CF096F164756E2164756E21",
15
16
  "names": []
16
17
  }
package/dist/cli.js CHANGED
@@ -5,8 +5,9 @@ import {
5
5
  treeToString
6
6
  } from "./chunk-v5w3w6bd.js";
7
7
  import {
8
- mineCli
9
- } from "./chunk-57gtsvhb.js";
8
+ mineCli,
9
+ minedToFlowWorkflow
10
+ } from "./chunk-dnq2rnr7.js";
10
11
  import {
11
12
  NullDelegate,
12
13
  runArchaeology
@@ -27,7 +28,7 @@ import"./chunk-q4se2rwe.js";
27
28
  // src/cli.ts
28
29
  var args = process.argv.slice(2);
29
30
  var subcommand = args[0];
30
- var HELP_SUBCOMMANDS = new Set(["flow", "mine", "archaeology"]);
31
+ var HELP_SUBCOMMANDS = new Set(["flow", "mine", "archaeology", "safe-help"]);
31
32
  var isHelpFlag = args.includes("--help") || args.includes("-h");
32
33
  if (!subcommand || isHelpFlag && !HELP_SUBCOMMANDS.has(subcommand ?? "")) {
33
34
  printMainHelp();
@@ -40,6 +41,8 @@ if (isHelpFlag) {
40
41
  printMineHelp();
41
42
  else if (subcommand === "archaeology")
42
43
  printArchaeologyHelp();
44
+ else if (subcommand === "safe-help")
45
+ printSafeHelpHelp();
43
46
  else
44
47
  printMainHelp();
45
48
  process.exit(0);
@@ -50,6 +53,8 @@ if (subcommand === "flow") {
50
53
  await runMine(args.slice(1));
51
54
  } else if (subcommand === "archaeology") {
52
55
  await runArchaeologyCmd(args.slice(1));
56
+ } else if (subcommand === "safe-help") {
57
+ await runSafeHelp(args.slice(1));
53
58
  } else {
54
59
  await runTree(args);
55
60
  }
@@ -62,21 +67,58 @@ function printMainHelp() {
62
67
  clitree flow <file> [options] Render a workflow YAML as a DAG
63
68
  clitree mine <binary> [options] Mine shell history for workflows
64
69
  clitree archaeology <binary> [options] Full analysis: tree + mining + (LLM)
70
+ clitree safe-help <binary> [sub...] Fetch clean help for any CLI (no pager, no overstriking)
65
71
 
66
72
  Examples:
67
73
  clitree docker # basic tree
68
74
  clitree mine git # "what workflows do I repeat with git?"
69
75
  clitree archaeology bun # tree + mining + LLM archaeology
76
+ clitree safe-help git commit # avoid the git man-page pager trap
70
77
 
71
78
  Subcommands:
72
79
  tree Parse --help output (default; passing a binary name invokes this)
73
80
  flow Render a workflow YAML file as an ASCII DAG
74
81
  mine Discover workflows from your shell history
75
82
  archaeology Run full analysis (tree + mine + LLM proposals when available)
83
+ safe-help Return inline help for any CLI, handling pager/overstrike edge cases
76
84
 
77
85
  Help for a subcommand: clitree <subcommand> --help
78
86
  `);
79
87
  }
88
+ function printSafeHelpHelp() {
89
+ console.log(`
90
+ clitree safe-help — Fetch clean help output for any CLI
91
+
92
+ Usage:
93
+ clitree safe-help <binary> [subcommand...] [options]
94
+
95
+ Why this exists:
96
+ Running '<cli> --help' directly is a minefield on agents and scripts:
97
+ - 'git commit --help' opens a pager in a TTY and hangs
98
+ - Piping 'git <sub> --help' returns nroff with overstrike (ffiixxuupp)
99
+ - Some CLIs use 'help <sub>' instead of '<sub> --help'
100
+ - macOS man pages emit \\b sequences that need col -bx
101
+
102
+ safe-help tries the right variants in order, cleans overstrikes, and
103
+ returns plain text every time.
104
+
105
+ Strategy (in order):
106
+ 1. <cli> <sub> -h — short inline help
107
+ 2. <cli> <sub> --help — long help (captured, overstrike-stripped)
108
+ 3. <cli> help <sub> — alternate syntax
109
+ 4. MANPAGER=cat man <cli>-<sub> | col -bx — final man fallback
110
+
111
+ Examples:
112
+ clitree safe-help git commit
113
+ clitree safe-help docker run
114
+ clitree safe-help kubectl get pods
115
+ clitree safe-help bun install
116
+
117
+ Options:
118
+ --no-color Disable ANSI codes (auto-detects non-TTY)
119
+ -h, --help Show this help
120
+ `);
121
+ }
80
122
  function printMineHelp() {
81
123
  console.log(`
82
124
  clitree mine — Mine your shell history for CLI workflows
@@ -86,7 +128,7 @@ function printMineHelp() {
86
128
 
87
129
  Examples:
88
130
  clitree mine git
89
- clitree mine docker --min-support 5
131
+ clitree mine docker --min-support 5 --with-flow
90
132
  clitree mine bun --format json > bun-flows.json
91
133
  clitree mine git --no-color | tee report.txt
92
134
 
@@ -95,8 +137,13 @@ function printMineHelp() {
95
137
  --history-path <p> Custom shell history path (default: ~/.zsh_history)
96
138
  --format <fmt> Output format: ansi (default), json
97
139
  --max-paths <n> Max workflows to show (default: 10)
140
+ --with-flow Always render the top workflow as an ASCII DAG
141
+ --no-flow Never render the DAG (overrides auto-detect)
98
142
  --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)
99
143
  -h, --help Show this help
144
+
145
+ By default, the top workflow is rendered as a DAG only when it has 3+ steps.
146
+ Use --with-flow to force it on even for 2-step chains, or --no-flow to skip.
100
147
  `);
101
148
  }
102
149
  function printArchaeologyHelp() {
@@ -267,6 +314,117 @@ async function readStdin() {
267
314
  }
268
315
  return Buffer.concat(chunks).toString("utf-8");
269
316
  }
317
+ function stripOverstrike(text) {
318
+ return text.replace(/(.)\b\1/g, "$1").replace(/_\b(.)/g, "$1").replace(/\b/g, "").replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
319
+ }
320
+ function looksLikeHelp(text) {
321
+ if (!text.trim())
322
+ return false;
323
+ if (text.length < 40)
324
+ return false;
325
+ const firstChunk = text.slice(0, 200).toLowerCase();
326
+ if (/(unknown|invalid|no such|not a \w+ command|flag needs an argument|unrecognized)/.test(firstChunk)) {
327
+ return false;
328
+ }
329
+ if (/run '.+' for more information/.test(firstChunk))
330
+ return false;
331
+ return true;
332
+ }
333
+ async function tryHelpVariant(binary, argv, timeoutMs = 5000) {
334
+ try {
335
+ const proc = Bun.spawn([binary, ...argv], {
336
+ stdout: "pipe",
337
+ stderr: "pipe",
338
+ env: { ...process.env, PAGER: "cat", MANPAGER: "cat", GIT_PAGER: "cat" }
339
+ });
340
+ const timer = setTimeout(() => proc.kill(), timeoutMs);
341
+ const [stdout, stderr] = await Promise.all([
342
+ new Response(proc.stdout).text(),
343
+ new Response(proc.stderr).text()
344
+ ]);
345
+ clearTimeout(timer);
346
+ await proc.exited;
347
+ const combined = stdout || stderr;
348
+ if (!looksLikeHelp(combined))
349
+ return null;
350
+ return stripOverstrike(combined);
351
+ } catch {
352
+ return null;
353
+ }
354
+ }
355
+ async function tryManPage(binary, subPath, timeoutMs = 5000) {
356
+ const candidates = [
357
+ subPath.length > 0 ? [`${binary}-${subPath.join("-")}`] : [binary],
358
+ [binary, ...subPath]
359
+ ];
360
+ for (const args2 of candidates) {
361
+ try {
362
+ const proc = Bun.spawn(["man", ...args2], {
363
+ stdout: "pipe",
364
+ stderr: "pipe",
365
+ env: { ...process.env, MANPAGER: "cat", PAGER: "cat" }
366
+ });
367
+ const timer = setTimeout(() => proc.kill(), timeoutMs);
368
+ const [stdout] = await Promise.all([
369
+ new Response(proc.stdout).text(),
370
+ new Response(proc.stderr).text()
371
+ ]);
372
+ clearTimeout(timer);
373
+ await proc.exited;
374
+ if (looksLikeHelp(stdout))
375
+ return stripOverstrike(stdout);
376
+ } catch {}
377
+ }
378
+ return null;
379
+ }
380
+ async function runSafeHelp(args2) {
381
+ let binary = null;
382
+ const subPath = [];
383
+ for (const arg of args2) {
384
+ if (arg === "--no-color" || arg === "--help" || arg === "-h")
385
+ continue;
386
+ if (!binary) {
387
+ binary = arg;
388
+ } else {
389
+ subPath.push(arg);
390
+ }
391
+ }
392
+ if (!binary) {
393
+ console.error("Error: provide a binary name");
394
+ console.error("Run 'clitree safe-help --help' for usage");
395
+ process.exit(1);
396
+ }
397
+ const variants = [
398
+ { label: "short help (-h)", args: [...subPath, "-h"] },
399
+ { label: "long help (--help)", args: [...subPath, "--help"] }
400
+ ];
401
+ if (subPath.length > 0) {
402
+ variants.push({ label: "help subcommand", args: ["help", ...subPath] });
403
+ }
404
+ for (const variant of variants) {
405
+ const output = await tryHelpVariant(binary, variant.args);
406
+ if (output) {
407
+ process.stdout.write(output);
408
+ if (!output.endsWith(`
409
+ `))
410
+ process.stdout.write(`
411
+ `);
412
+ return;
413
+ }
414
+ }
415
+ const manOutput = await tryManPage(binary, subPath);
416
+ if (manOutput) {
417
+ process.stdout.write(manOutput);
418
+ if (!manOutput.endsWith(`
419
+ `))
420
+ process.stdout.write(`
421
+ `);
422
+ return;
423
+ }
424
+ console.error(`Error: could not fetch help for ${binary} ${subPath.join(" ")}`);
425
+ console.error("Tried: -h, --help, help subcommand, and man page.");
426
+ process.exit(1);
427
+ }
270
428
  function shouldUseColor(args2) {
271
429
  if (args2.includes("--no-color"))
272
430
  return false;
@@ -298,6 +456,7 @@ async function runMine(args2) {
298
456
  let historyPath;
299
457
  let format = "ansi";
300
458
  let maxPaths = 10;
459
+ let withFlow = "auto";
301
460
  for (let i = 0;i < args2.length; i++) {
302
461
  const arg = args2[i];
303
462
  if (arg === "--min-support" && args2[i + 1]) {
@@ -308,6 +467,10 @@ async function runMine(args2) {
308
467
  format = args2[++i];
309
468
  } else if (arg === "--max-paths" && args2[i + 1]) {
310
469
  maxPaths = Number.parseInt(args2[++i], 10);
470
+ } else if (arg === "--with-flow" || arg === "--flow") {
471
+ withFlow = "on";
472
+ } else if (arg === "--no-flow") {
473
+ withFlow = "off";
311
474
  } else if (arg !== "--no-color" && !arg.startsWith("-")) {
312
475
  binary = arg;
313
476
  }
@@ -360,11 +523,30 @@ ${C.bold}${C.magenta}${binary}${C.reset} ${C.gray}— shell history analysis${C.
360
523
  }
361
524
  console.log();
362
525
  }
526
+ if (withFlow !== "off") {
527
+ const minSteps = withFlow === "on" ? 2 : 3;
528
+ const topForFlow = pickWorkflowForFlow(result.workflows, minSteps);
529
+ if (topForFlow) {
530
+ const flowWorkflow = minedToFlowWorkflow(topForFlow);
531
+ const rendered = shouldUseColor(args2) ? flowToAnsi(flowWorkflow) : flowToString(flowWorkflow);
532
+ console.log(`${C.bold}Top workflow (visualized):${C.reset}`);
533
+ console.log(rendered);
534
+ console.log();
535
+ }
536
+ }
363
537
  } catch (err) {
364
538
  console.error(`Error: ${err.message}`);
365
539
  process.exit(1);
366
540
  }
367
541
  }
542
+ function pickWorkflowForFlow(workflows, minSteps = 3) {
543
+ for (const wf of workflows) {
544
+ const len = wf.path[0]?.length ?? 0;
545
+ if (len >= minSteps)
546
+ return wf;
547
+ }
548
+ return null;
549
+ }
368
550
  async function runArchaeologyCmd(args2) {
369
551
  let binary = null;
370
552
  let skipCache = false;
@@ -440,4 +622,4 @@ ${C.bold}${C.yellow}\uD83D\uDCA1 Skill suggestions:${C.reset}`);
440
622
  }
441
623
  }
442
624
 
443
- //# debugId=F977FC1E65697C7D64756E2164756E21
625
+ //# debugId=6575AA9BC14C249964756E2164756E21
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 } 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\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 --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)\n -h, --help Show this help\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\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 !== \"--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\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"
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\", \"safe-help\"]);\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 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 {\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 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 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\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 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 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 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\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"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,aAAa,KAAK;AAExB,IAAM,mBAAmB,IAAI,IAAI,CAAC,QAAQ,QAAQ,aAAa,CAAC;AAChE,IAAM,aAAa,KAAK,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI;AAEhE,IAAI,CAAC,cAAe,cAAc,CAAC,iBAAiB,IAAI,cAAc,EAAE,GAAI;AAAA,EAC3E,cAAc;AAAA,EACd,QAAQ,KAAK,CAAC;AACf;AAEA,IAAI,YAAY;AAAA,EACf,IAAI,eAAe;AAAA,IAAQ,cAAc;AAAA,EACpC,SAAI,eAAe;AAAA,IAAQ,cAAc;AAAA,EACzC,SAAI,eAAe;AAAA,IAAe,qBAAqB;AAAA,EACvD;AAAA,kBAAc;AAAA,EACnB,QAAQ,KAAK,CAAC;AACf;AAEA,IAAI,eAAe,QAAQ;AAAA,EAC1B,MAAM,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5B,EAAO,SAAI,eAAe,QAAQ;AAAA,EACjC,MAAM,QAAQ,KAAK,MAAM,CAAC,CAAC;AAC5B,EAAO,SAAI,eAAe,eAAe;AAAA,EACxC,MAAM,kBAAkB,KAAK,MAAM,CAAC,CAAC;AACtC,EAAO;AAAA,EACN,MAAM,QAAQ,IAAI;AAAA;AAGnB,SAAS,aAAa,GAAG;AAAA,EACxB,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAqBZ;AAAA;AAGD,SAAS,aAAa,GAAG;AAAA,EACxB,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAmBZ;AAAA;AAGD,SAAS,oBAAoB,GAAG;AAAA,EAC/B,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAqBZ;AAAA;AAGD,SAAS,aAAa,GAAG;AAAA,EACxB,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAiBZ;AAAA;AAGD,eAAe,OAAO,CAAC,OAAgB;AAAA,EACtC,MAAM,OAAoB;AAAA,IACzB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,WAAW;AAAA,IACX,cAAc;AAAA,IACd,SAAS;AAAA,EACV;AAAA,EAEA,IAAI,QAAQ;AAAA,EACZ,IAAI,SAA8C;AAAA,EAClD,IAAI,YAA2B;AAAA,EAC/B,IAAI,SAAwB;AAAA,EAE5B,KAAK,QAAQ,eAAe,KAAI;AAAA,EAEhC,SAAS,IAAI,EAAG,IAAI,MAAK,QAAQ,KAAK;AAAA,IACrC,MAAM,MAAM,MAAK;AAAA,IACjB,IAAI,QAAQ,aAAa,MAAK,IAAI,IAAI;AAAA,MACrC,QAAQ,OAAO,SAAS,MAAK,EAAE,IAAK,EAAE;AAAA,IACvC,EAAO,SAAI,QAAQ,aAAa;AAAA,MAC/B,KAAK,UAAU;AAAA,MACf,KAAK,mBAAmB;AAAA,IACzB,EAAO,SAAI,QAAQ,cAAc;AAAA,MAChC,KAAK,YAAY;AAAA,IAClB,EAAO,SAAI,QAAQ,aAAa;AAAA,MAC/B,KAAK,WAAW;AAAA,IACjB,EAAO,SAAI,QAAQ,cAAc;AAAA,MAChC,KAAK,QAAQ;AAAA,IACd,EAAO,SAAI,QAAQ,cAAc,MAAK,IAAI,IAAI;AAAA,MAC7C,SAAS,MAAK,EAAE;AAAA,IACjB,EAAO,SAAI,QAAQ,aAAa,MAAK,IAAI,IAAI;AAAA,MAC5C,YAAY,MAAK,EAAE;AAAA,IACpB,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAChC,SAAS;AAAA,IACV;AAAA,EACD;AAAA,EAEA,IAAI;AAAA,IACH,IAAI;AAAA,IACJ,IAAI,WAAW;AAAA,MACd,MAAM,QAAQ,MAAM,UAAU;AAAA,MAC9B,OAAO,UAAU,WAAW,KAAK;AAAA,IAClC,EAAO,SAAI,QAAQ;AAAA,MAClB,OAAO,MAAM,mBAAmB,QAAQ,CAAC,GAAG,KAAK;AAAA,IAClD,EAAO;AAAA,MACN,QAAQ,MAAM,oDAAoD;AAAA,MAClE,QAAQ,KAAK,CAAC;AAAA;AAAA,IAGf,IAAI,WAAW,QAAQ;AAAA,MACtB,QAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,IAC1C,EAAO,SAAI,WAAW,QAAQ;AAAA,MAC7B,QAAQ,IAAI,WAAW,MAAM,IAAI,CAAC;AAAA,IACnC,EAAO,SAAI,WAAW,UAAU;AAAA,MAC/B,QAAQ,IAAI,aAAa,MAAM,IAAI,CAAC;AAAA,IACrC,EAAO;AAAA,MACN,UAAU,MAAM,IAAI;AAAA;AAAA,IAEpB,OAAO,KAAU;AAAA,IAClB,QAAQ,MAAM,UAAU,IAAI,SAAS;AAAA,IACrC,QAAQ,KAAK,CAAC;AAAA;AAAA;AAIhB,eAAe,OAAO,CAAC,OAAgB;AAAA,EACtC,MAAM,OAA0B;AAAA,IAC/B,OAAO;AAAA,IACP,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,SAAS;AAAA,EACV;AAAA,EAEA,IAAI,SAAqC;AAAA,EACzC,IAAI,OAAsB;AAAA,EAC1B,IAAI,eAAe;AAAA,EAEnB,SAAS,IAAI,EAAG,IAAI,MAAK,QAAQ,KAAK;AAAA,IACrC,MAAM,MAAM,MAAK;AAAA,IACjB,IAAI,QAAQ,aAAa;AAAA,MACxB,KAAK,UAAU;AAAA,MACf,KAAK,mBAAmB;AAAA,IACzB,EAAO,SAAI,QAAQ,cAAc;AAAA,MAChC,KAAK,QAAQ;AAAA,IACd,EAAO,SAAI,QAAQ,iBAAiB;AAAA,MACnC,eAAe;AAAA,IAChB,EAAO,SAAI,QAAQ,cAAc,MAAK,IAAI,IAAI;AAAA,MAC7C,SAAS,MAAK,EAAE;AAAA,IACjB,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAChC,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,IAAI,CAAC,MAAM;AAAA,IACV,QAAQ,MAAM,qCAAqC;AAAA,IACnD,QAAQ,MAAM,sCAAsC;AAAA,IACpD,QAAQ,KAAK,CAAC;AAAA,EACf;AAAA,EAEA,IAAI;AAAA,IACH,MAAM,OAAO,MAAM,IAAI,KAAK,IAAI,EAAE,KAAK;AAAA,IACvC,MAAM,WAAW,cAAc,IAAI;AAAA,IAEnC,IAAI,CAAC,cAAc;AAAA,MAClB,MAAM,SAAS,iBAAiB,QAAQ;AAAA,MACxC,WAAW,OAAO,OAAO,QAAQ;AAAA,QAChC,MAAM,SAAS,IAAI,aAAa,UAAU,cAAa;AAAA,QACvD,MAAM,QAAQ;AAAA,QACd,MAAM,WAAW,IAAI,OAAO,KAAK,IAAI,UAAU,IAAI,OAAO,KAAK,IAAI,KAAK,QAAO,IAAI,KAAK,QAAQ;AAAA,QAChG,QAAQ,MAAM,GAAG,SAAS,YAAY,IAAI,UAAU,OAAO;AAAA,MAC5D;AAAA,MACA,IAAI,CAAC,OAAO;AAAA,QAAO,QAAQ,KAAK,CAAC;AAAA,IAClC;AAAA,IAEA,IAAI,WAAW,QAAQ;AAAA,MACtB,QAAQ,IAAI,WAAW,UAAU,IAAI,CAAC;AAAA,IACvC,EAAO,SAAI,WAAW,UAAU;AAAA,MAC/B,QAAQ,IAAI,aAAa,UAAU,IAAI,CAAC;AAAA,IACzC,EAAO;AAAA,MACN,QAAQ,IAAI,WAAW,UAAU,IAAI,CAAC;AAAA;AAAA,IAEtC,OAAO,KAAU;AAAA,IAClB,QAAQ,MAAM,UAAU,IAAI,SAAS;AAAA,IACrC,QAAQ,KAAK,CAAC;AAAA;AAAA;AAIhB,eAAe,SAAS,GAAoB;AAAA,EAC3C,MAAM,SAAmB,CAAC;AAAA,EAC1B,iBAAiB,SAAS,QAAQ,OAAO;AAAA,IACxC,OAAO,KAAK,KAAe;AAAA,EAC5B;AAAA,EACA,OAAO,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO;AAAA;AAG9C,SAAS,cAAc,CAAC,OAAyB;AAAA,EAChD,IAAI,MAAK,SAAS,YAAY;AAAA,IAAG,OAAO;AAAA,EACxC,IAAI,QAAQ,IAAI;AAAA,IAAU,OAAO;AAAA,EACjC,IAAI,QAAQ,IAAI;AAAA,IAAa,OAAO;AAAA,EACpC,OAAO,CAAC,CAAC,QAAQ,OAAO;AAAA;AAGzB,SAAS,UAAU,CAAC,SAAkB;AAAA,EACrC,IAAI,CAAC,SAAS;AAAA,IACb,OAAO,EAAE,OAAO,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,OAAO,IAAI,QAAQ,IAAI,KAAK,IAAI,SAAS,IAAI,MAAM,GAAG;AAAA,EACxG;AAAA,EACA,OAAO;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,EACP;AAAA;AAGD,eAAe,OAAO,CAAC,OAAgB;AAAA,EACtC,IAAI,SAAwB;AAAA,EAC5B,IAAI,aAAa;AAAA,EACjB,IAAI;AAAA,EACJ,IAAI,SAA0B;AAAA,EAC9B,IAAI,WAAW;AAAA,EAEf,SAAS,IAAI,EAAG,IAAI,MAAK,QAAQ,KAAK;AAAA,IACrC,MAAM,MAAM,MAAK;AAAA,IACjB,IAAI,QAAQ,mBAAmB,MAAK,IAAI,IAAI;AAAA,MAC3C,aAAa,OAAO,SAAS,MAAK,EAAE,IAAK,EAAE;AAAA,IAC5C,EAAO,SAAI,QAAQ,oBAAoB,MAAK,IAAI,IAAI;AAAA,MACnD,cAAc,MAAK,EAAE;AAAA,IACtB,EAAO,SAAI,QAAQ,cAAc,MAAK,IAAI,IAAI;AAAA,MAC7C,SAAS,MAAK,EAAE;AAAA,IACjB,EAAO,SAAI,QAAQ,iBAAiB,MAAK,IAAI,IAAI;AAAA,MAChD,WAAW,OAAO,SAAS,MAAK,EAAE,IAAK,EAAE;AAAA,IAC1C,EAAO,SAAI,QAAQ,gBAAgB,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MACxD,SAAS;AAAA,IACV;AAAA,EACD;AAAA,EAEA,IAAI,CAAC,QAAQ;AAAA,IACZ,QAAQ,MAAM,8BAA8B;AAAA,IAC5C,QAAQ,MAAM,qCAAqC;AAAA,IACnD,QAAQ,KAAK,CAAC;AAAA,EACf;AAAA,EAEA,IAAI;AAAA,IACH,MAAM,SAAS,MAAM,QAAQ,QAAQ,EAAE,YAAY,YAAY,CAAC;AAAA,IAEhE,IAAI,WAAW,QAAQ;AAAA,MACtB,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,MAC3C;AAAA,IACD;AAAA,IAEA,MAAM,IAAI,WAAW,eAAe,KAAI,CAAC;AAAA,IAEzC,QAAQ,IAAI;AAAA,EAAK,EAAE,OAAO,EAAE,UAAU,SAAS,EAAE,SAAS,EAAE,+BAA8B,EAAE;AAAA,CAAS;AAAA,IACrG,QAAQ,IAAI,GAAG,EAAE,aAAa,EAAE,OAAO;AAAA,IACvC,QAAQ,IAAI,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,OAAO,MAAM,mBAAmB,EAAE,OAAO;AAAA,IACnG,QAAQ,IAAI,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,OAAO,MAAM,oBAAoB,EAAE,OAAO;AAAA,IACpG,QAAQ,IAAI,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,OAAO,mBAAmB,EAAE;AAAA,CAAS;AAAA,IAE/F,IAAI,OAAO,MAAM,eAAe,SAAS,GAAG;AAAA,MAC3C,QAAQ,IAAI,GAAG,EAAE,uBAAuB,EAAE,OAAO;AAAA,MACjD,MAAM,MAAM,OAAO,MAAM,eAAe,GAAI;AAAA,MAC5C,aAAa,yBAAY,WAAW,OAAO,MAAM,eAAe,MAAM,GAAG,CAAC,GAAG;AAAA,QAC5E,MAAM,MAAM,IAAG,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,QAAQ,MAAO,EAAE,CAAC,CAAC;AAAA,QACjE,QAAQ,IAAI,KAAK,EAAE,QAAQ,YAAW,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,EAAE,OAAO;AAAA,MAClH;AAAA,MACA,QAAQ,IAAI;AAAA,IACb;AAAA,IAEA,IAAI,OAAO,UAAU,SAAS,GAAG;AAAA,MAChC,QAAQ,IAAI,GAAG,EAAE,4BAA4B,EAAE,OAAO;AAAA,MACtD,WAAW,MAAM,OAAO,UAAU,MAAM,GAAG,QAAQ,GAAG;AAAA,QACrD,MAAM,QAAQ,GAAG,KAAK,GAAI,IAAI,OAAK,GAAG,EAAE,QAAQ,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,QAAO,EAAE,QAAQ;AAAA,QAC3F,QAAQ,IAAI,KAAK,SAAS,EAAE,OAAO,GAAG,YAAW,EAAE,OAAO;AAAA,MAC3D;AAAA,MACA,QAAQ,IAAI;AAAA,IACb;AAAA,IAEA,IAAI,OAAO,YAAY,SAAS,GAAG;AAAA,MAClC,QAAQ,IAAI,GAAG,EAAE,OAAO,EAAE,wCAA6B,EAAE,OAAO;AAAA,MAChE,WAAW,KAAK,OAAO,YAAY,MAAM,GAAG,CAAC,GAAG;AAAA,QAC/C,MAAM,QACL,EAAE,aAAa,SACZ,GAAG,EAAE,cAAc,EAAE,UACrB,EAAE,aAAa,WACd,GAAG,EAAE,cAAc,EAAE,UACrB,GAAG,EAAE,WAAW,EAAE;AAAA,QACvB,QAAQ,IAAI;AAAA,IAAO,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAU,EAAE,aAAa;AAAA,QAC1E,QAAQ,IAAI,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO;AAAA,QAC/C,QAAQ,IAAI,OAAO,EAAE,MAAM,EAAE,SAAS,KAAK,MAAM,IAAI,EAAE,OAAO;AAAA,MAC/D;AAAA,MACA,QAAQ,IAAI;AAAA,IACb;AAAA,IACC,OAAO,KAAU;AAAA,IAClB,QAAQ,MAAM,UAAU,IAAI,SAAS;AAAA,IACrC,QAAQ,KAAK,CAAC;AAAA;AAAA;AAIhB,eAAe,iBAAiB,CAAC,OAAgB;AAAA,EAChD,IAAI,SAAwB;AAAA,EAC5B,IAAI,YAAY;AAAA,EAChB,IAAI,WAAW;AAAA,EACf,IAAI,SAA0B;AAAA,EAE9B,SAAS,IAAI,EAAG,IAAI,MAAK,QAAQ,KAAK;AAAA,IACrC,MAAM,MAAM,MAAK;AAAA,IACjB,IAAI,QAAQ,cAAc;AAAA,MACzB,YAAY;AAAA,IACb,EAAO,SAAI,QAAQ,iBAAiB,MAAK,IAAI,IAAI;AAAA,MAChD,WAAW,OAAO,SAAS,MAAK,EAAE,IAAK,EAAE;AAAA,IAC1C,EAAO,SAAI,QAAQ,cAAc,MAAK,IAAI,IAAI;AAAA,MAC7C,SAAS,MAAK,EAAE;AAAA,IACjB,EAAO,SAAI,QAAQ,gBAAgB,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MACxD,SAAS;AAAA,IACV;AAAA,EACD;AAAA,EAEA,IAAI,CAAC,QAAQ;AAAA,IACZ,QAAQ,MAAM,8BAA8B;AAAA,IAC5C,QAAQ,MAAM,4CAA4C;AAAA,IAC1D,QAAQ,KAAK,CAAC;AAAA,EACf;AAAA,EAEA,MAAM,IAAI,WAAW,eAAe,KAAI,CAAC;AAAA,EAEzC,IAAI;AAAA,IACH,QAAQ,MAAM,GAAG,EAAE,mEAAkE,EAAE,OAAO;AAAA,IAC9F,QAAQ,MAAM,GAAG,EAAE,mEAAmE,EAAE,OAAO;AAAA,IAC/F,QAAQ,MAAM,EAAE;AAAA,IAEhB,OAAO,MAAM,QAAQ,MAAM,QAAQ,IAAI;AAAA,MACtC,eAAe,QAAQ,IAAI,cAAgB,EAAE,WAAW,cAAc,SAAS,CAAC;AAAA,MAChF,QAAQ,QAAQ,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,MAAM,IAAI;AAAA,IACpD,CAAC;AAAA,IAED,IAAI,WAAW,QAAQ;AAAA,MACtB,QAAQ,IAAI,KAAK,UAAU,EAAE,aAAa,MAAM,QAAQ,KAAK,GAAG,MAAM,CAAC,CAAC;AAAA,MACxE;AAAA,IACD;AAAA,IAEA,QAAQ,IAAI,GAAG,EAAE,OAAO,EAAE,UAAU,SAAS,EAAE,OAAO;AAAA,IACtD,IAAI,KAAK,KAAK,aAAa;AAAA,MAC1B,QAAQ,IAAI,GAAG,EAAE,OAAO,KAAK,KAAK,cAAc,EAAE,OAAO;AAAA,IAC1D;AAAA,IACA,QAAQ,IAAI;AAAA,IAEZ,QAAQ,IAAI,GAAG,EAAE,YAAY,EAAE,OAAO;AAAA,IACtC,QAAQ,IAAI,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,KAAK,MAAM,eAAe,EAAE,OAAO;AAAA,IAC1F,QAAQ,IAAI,KAAK,EAAE,aAAa,EAAE,YAAY,KAAK,YAAY,GAAG,EAAE,WAAW,EAAE,UAAU,GAAG,EAAE,QAAQ,EAAE,SAAS;AAAA,IACnH,QAAQ,IAAI;AAAA,IAEZ,IAAI,MAAM;AAAA,MACT,QAAQ,IAAI,GAAG,EAAE,gCAAgC,EAAE,OAAO;AAAA,MAC1D,QAAQ,IAAI,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,KAAK,MAAM,mBAAmB,EAAE,OAAO;AAAA,MACjG,QAAQ,IAAI,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,OAAO,KAAK,MAAM,oBAAoB,EAAE,OAAO;AAAA,MAElG,IAAI,KAAK,UAAU,SAAS,GAAG;AAAA,QAC9B,QAAQ,IAAI;AAAA,EAAK,EAAE,4BAA4B,EAAE,OAAO;AAAA,QACxD,WAAW,MAAM,KAAK,UAAU,MAAM,GAAG,CAAC,GAAG;AAAA,UAC5C,MAAM,QAAQ,GAAG,KAAK,GAAI,IAAI,OAAK,GAAG,EAAE,QAAQ,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,QAAO,EAAE,QAAQ;AAAA,UAC3F,QAAQ,IAAI,KAAK,SAAS,EAAE,OAAO,GAAG,YAAW,EAAE,OAAO;AAAA,QAC3D;AAAA,MACD;AAAA,MAEA,IAAI,KAAK,YAAY,SAAS,GAAG;AAAA,QAChC,QAAQ,IAAI;AAAA,EAAK,EAAE,OAAO,EAAE,wCAA6B,EAAE,OAAO;AAAA,QAClE,WAAW,KAAK,KAAK,YAAY,MAAM,GAAG,CAAC,GAAG;AAAA,UAC7C,QAAQ,IAAI,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAU,EAAE,aAAa;AAAA,UAC/D,QAAQ,IAAI,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO;AAAA,QAChD;AAAA,MACD;AAAA,IACD;AAAA,IAEA,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI,GAAG,EAAE,yDAAyD,EAAE,OAAO;AAAA,IACnF,QAAQ,IAAI,GAAG,EAAE,+BAA+B,EAAE,OAAO;AAAA,IACzD,QAAQ,IAAI;AAAA,IACX,OAAO,KAAU;AAAA,IAClB,QAAQ,MAAM,GAAG,EAAE,aAAa,IAAI,UAAU,EAAE,OAAO;AAAA,IACvD,QAAQ,KAAK,CAAC;AAAA;AAAA;",
8
- "debugId": "F977FC1E65697C7D64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "6575AA9BC14C249964756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -4,9 +4,10 @@ import { buildTransitions, normalizeTransitions, extractSubcommand, extractSubco
4
4
  import { extractPaths, clusterIntoWorkflows } from "./workflows";
5
5
  import { computeStats } from "./stats";
6
6
  import { suggestSkills, type SkillSuggestion } from "./suggest";
7
+ import { minedToFlowWorkflow } from "./to-flow";
7
8
  import type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions } from "./types";
8
9
  export type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion };
9
- export { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat, segmentSessions, filterByCli, buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, };
10
+ export { parseHistory, readHistoryFile, defaultHistoryPath, tokenize, detectHistoryFormat, segmentSessions, filterByCli, buildTransitions, normalizeTransitions, extractSubcommand, extractSubcommandPath, extractPaths, clusterIntoWorkflows, computeStats, suggestSkills, minedToFlowWorkflow, };
10
11
  export interface MineResult {
11
12
  cli: string;
12
13
  stats: CliUsageStats;
@@ -9,13 +9,14 @@ import {
9
9
  extractSubcommandPath,
10
10
  filterByCli,
11
11
  mineCli,
12
+ minedToFlowWorkflow,
12
13
  normalizeTransitions,
13
14
  parseHistory,
14
15
  readHistoryFile,
15
16
  segmentSessions,
16
17
  suggestSkills,
17
18
  tokenize
18
- } from "../chunk-57gtsvhb.js";
19
+ } from "../chunk-dnq2rnr7.js";
19
20
  export {
20
21
  tokenize,
21
22
  suggestSkills,
@@ -23,6 +24,7 @@ export {
23
24
  readHistoryFile,
24
25
  parseHistory,
25
26
  normalizeTransitions,
27
+ minedToFlowWorkflow,
26
28
  mineCli,
27
29
  filterByCli,
28
30
  extractSubcommandPath,
@@ -35,4 +37,4 @@ export {
35
37
  buildTransitions
36
38
  };
37
39
 
38
- //# debugId=79FF1A9AE05DD20F64756E2164756E21
40
+ //# debugId=34A9477E11B0A64764756E2164756E21
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "79FF1A9AE05DD20F64756E2164756E21",
7
+ "debugId": "34A9477E11B0A64764756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -0,0 +1,12 @@
1
+ import type { Workflow } from "../flow/types";
2
+ import type { MinedWorkflow } from "./types";
3
+ /**
4
+ * Convert a MinedWorkflow (discovered from shell history) into a Workflow
5
+ * that the flow renderer can visualize as an ASCII DAG.
6
+ *
7
+ * The mined workflow is a linear path like ["add", "commit", "push"] with
8
+ * a frequency count. We turn it into a linear Workflow with one node per
9
+ * step and edges in order — matching the shape of the handcrafted YAML
10
+ * workflows in workflows/.
11
+ */
12
+ export declare function minedToFlowWorkflow(mined: MinedWorkflow, occurrences?: number): Workflow;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crafter/cli-tree",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
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
@@ -49,7 +49,7 @@ The helper alias used throughout this skill:
49
49
 
50
50
  ```bash
51
51
  # Short hand. The first invocation downloads the package; subsequent runs are cached.
52
- CLITREE="bunx @crafter/cli-tree"
52
+ CLITREE="bunx @crafter/cli-tree@latest"
53
53
  ```
54
54
 
55
55
  ## Phase 1 — Parse the --help tree
@@ -67,16 +67,36 @@ If the parse fails completely (empty output, error), try:
67
67
 
68
68
  ## Phase 2 — Mine shell history
69
69
 
70
+ Run the miner **twice** — once for structured data you can reason over, and once for the pretty ANSI output you'll paste directly into the report.
71
+
72
+ **2a. Structured data (for your reasoning):**
73
+
70
74
  ```bash
71
75
  $CLITREE mine "$TARGET_BINARY" --format json
72
76
  ```
73
77
 
74
78
  Read the result. You get:
75
79
  - `stats.totalInvocations` — how much the user uses this CLI
76
- - `stats.topSubcommands` — their most-used commands
80
+ - `stats.topSubcommands` — their most-used commands with counts
77
81
  - `workflows` — sequences that repeat (≥3 times)
78
82
  - `suggestions` — candidate skills to create
79
83
 
84
+ **2b. Pretty output (for the visual report):**
85
+
86
+ ```bash
87
+ $CLITREE mine "$TARGET_BINARY"
88
+ ```
89
+
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.
99
+
80
100
  Three scenarios from the invocation count:
81
101
 
82
102
  | Invocations | What it means | What to do |
@@ -104,24 +124,77 @@ For detailed prompt templates that help you think through each category systemat
104
124
 
105
125
  ## Phase 4 — Validate every proposal
106
126
 
107
- 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:
108
145
 
109
146
  ```bash
110
- # Primary check: is it in --help?
111
- "$TARGET_BINARY" "$SUBCOMMAND" --help 2>&1 | grep -E "(--<flag>|-<short>\\b)"
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
+ ```
112
152
 
113
- # Fallback: man page
114
- man "$TARGET_BINARY" 2>/dev/null | grep -E "(--<flag>|-<short>\\b)" | head -5
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"
164
+
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"
115
170
  ```
116
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
+
117
180
  Mark each finding:
118
- - **`verified`** — appears in `--help`
119
- - **`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`
120
183
  - **`unconfirmed`** — neither confirms; keep only if you're highly confident AND can explain the evidence (e.g. "shown in docker/docker#12345")
121
184
  - **`rejected`** — fail to validate → drop it silently, never include in final output
122
185
 
123
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.
124
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
+
125
198
  ## Phase 5 — Render the report
126
199
 
127
200
  Produce this exact structure. Consistency matters — the user learns the shape and scans it quickly on future runs.
@@ -133,12 +206,11 @@ Produce this exact structure. Consistency matters — the user learns the shape
133
206
  <one-line summary: N commands, M flags>
134
207
 
135
208
  ## Your usage
136
- <from history: invocations, top subcommands, sessions>
137
- <or: "No usage detected — showing canonical patterns from my knowledge">
209
+ <Paste the full ANSI block from `$CLITREE mine <binary>` (phase 2b) inside a triple-backtick fenced code block. This gives the user ASCII bar charts + workflow list + skill suggestions visually, instead of re-typing them as prose.>
210
+ <If history is empty, write: "No usage detected — showing canonical patterns from my knowledge">
138
211
 
139
212
  ## Workflows you repeat
140
- <from mining — top 5, with frequency>
141
- <or omit section entirely if no history>
213
+ <If you pasted the full mine block above, this section can be omitted the mine output already includes it. Otherwise, list the top 5 workflows with frequency.>
142
214
 
143
215
  ## Hidden / undocumented findings
144
216
  ✓ --flag-a (verified) — what it does
package/src/cli.ts CHANGED
@@ -4,13 +4,13 @@ import { printTree, treeToString, treeToHtml } from "./index";
4
4
  import type { TreeOptions } from "./types";
5
5
  import { parseWorkflow, validateWorkflow, flowToAnsi, flowToString, flowToHtml } from "./flow";
6
6
  import type { FlowRenderOptions } from "./flow/types";
7
- import { mineCli } from "./miner";
7
+ import { mineCli, minedToFlowWorkflow } from "./miner";
8
8
  import { runArchaeology, NullDelegate } from "./archaeology";
9
9
 
10
10
  const args = process.argv.slice(2);
11
11
  const subcommand = args[0];
12
12
 
13
- const HELP_SUBCOMMANDS = new Set(["flow", "mine", "archaeology"]);
13
+ const HELP_SUBCOMMANDS = new Set(["flow", "mine", "archaeology", "safe-help"]);
14
14
  const isHelpFlag = args.includes("--help") || args.includes("-h");
15
15
 
16
16
  if (!subcommand || (isHelpFlag && !HELP_SUBCOMMANDS.has(subcommand ?? ""))) {
@@ -22,6 +22,7 @@ if (isHelpFlag) {
22
22
  if (subcommand === "flow") printFlowHelp();
23
23
  else if (subcommand === "mine") printMineHelp();
24
24
  else if (subcommand === "archaeology") printArchaeologyHelp();
25
+ else if (subcommand === "safe-help") printSafeHelpHelp();
25
26
  else printMainHelp();
26
27
  process.exit(0);
27
28
  }
@@ -32,6 +33,8 @@ if (subcommand === "flow") {
32
33
  await runMine(args.slice(1));
33
34
  } else if (subcommand === "archaeology") {
34
35
  await runArchaeologyCmd(args.slice(1));
36
+ } else if (subcommand === "safe-help") {
37
+ await runSafeHelp(args.slice(1));
35
38
  } else {
36
39
  await runTree(args);
37
40
  }
@@ -45,22 +48,60 @@ function printMainHelp() {
45
48
  clitree flow <file> [options] Render a workflow YAML as a DAG
46
49
  clitree mine <binary> [options] Mine shell history for workflows
47
50
  clitree archaeology <binary> [options] Full analysis: tree + mining + (LLM)
51
+ clitree safe-help <binary> [sub...] Fetch clean help for any CLI (no pager, no overstriking)
48
52
 
49
53
  Examples:
50
54
  clitree docker # basic tree
51
55
  clitree mine git # "what workflows do I repeat with git?"
52
56
  clitree archaeology bun # tree + mining + LLM archaeology
57
+ clitree safe-help git commit # avoid the git man-page pager trap
53
58
 
54
59
  Subcommands:
55
60
  tree Parse --help output (default; passing a binary name invokes this)
56
61
  flow Render a workflow YAML file as an ASCII DAG
57
62
  mine Discover workflows from your shell history
58
63
  archaeology Run full analysis (tree + mine + LLM proposals when available)
64
+ safe-help Return inline help for any CLI, handling pager/overstrike edge cases
59
65
 
60
66
  Help for a subcommand: clitree <subcommand> --help
61
67
  `);
62
68
  }
63
69
 
70
+ function printSafeHelpHelp() {
71
+ console.log(`
72
+ clitree safe-help — Fetch clean help output for any CLI
73
+
74
+ Usage:
75
+ clitree safe-help <binary> [subcommand...] [options]
76
+
77
+ Why this exists:
78
+ Running '<cli> --help' directly is a minefield on agents and scripts:
79
+ - 'git commit --help' opens a pager in a TTY and hangs
80
+ - Piping 'git <sub> --help' returns nroff with overstrike (ffiixxuupp)
81
+ - Some CLIs use 'help <sub>' instead of '<sub> --help'
82
+ - macOS man pages emit \\b sequences that need col -bx
83
+
84
+ safe-help tries the right variants in order, cleans overstrikes, and
85
+ returns plain text every time.
86
+
87
+ Strategy (in order):
88
+ 1. <cli> <sub> -h — short inline help
89
+ 2. <cli> <sub> --help — long help (captured, overstrike-stripped)
90
+ 3. <cli> help <sub> — alternate syntax
91
+ 4. MANPAGER=cat man <cli>-<sub> | col -bx — final man fallback
92
+
93
+ Examples:
94
+ clitree safe-help git commit
95
+ clitree safe-help docker run
96
+ clitree safe-help kubectl get pods
97
+ clitree safe-help bun install
98
+
99
+ Options:
100
+ --no-color Disable ANSI codes (auto-detects non-TTY)
101
+ -h, --help Show this help
102
+ `);
103
+ }
104
+
64
105
  function printMineHelp() {
65
106
  console.log(`
66
107
  clitree mine — Mine your shell history for CLI workflows
@@ -70,7 +111,7 @@ function printMineHelp() {
70
111
 
71
112
  Examples:
72
113
  clitree mine git
73
- clitree mine docker --min-support 5
114
+ clitree mine docker --min-support 5 --with-flow
74
115
  clitree mine bun --format json > bun-flows.json
75
116
  clitree mine git --no-color | tee report.txt
76
117
 
@@ -79,8 +120,13 @@ function printMineHelp() {
79
120
  --history-path <p> Custom shell history path (default: ~/.zsh_history)
80
121
  --format <fmt> Output format: ansi (default), json
81
122
  --max-paths <n> Max workflows to show (default: 10)
123
+ --with-flow Always render the top workflow as an ASCII DAG
124
+ --no-flow Never render the DAG (overrides auto-detect)
82
125
  --no-color Disable ANSI colors (also auto-disabled when stdout is not a TTY)
83
126
  -h, --help Show this help
127
+
128
+ By default, the top workflow is rendered as a DAG only when it has 3+ steps.
129
+ Use --with-flow to force it on even for 2-step chains, or --no-flow to skip.
84
130
  `);
85
131
  }
86
132
 
@@ -267,6 +313,138 @@ async function readStdin(): Promise<string> {
267
313
  return Buffer.concat(chunks).toString("utf-8");
268
314
  }
269
315
 
316
+ function stripOverstrike(text: string): string {
317
+ // Strip nroff bold via char\bchar, underline via _\bchar, and stray control chars.
318
+ // This is what `col -bx` does.
319
+ return text
320
+ .replace(/(.)\b\1/g, "$1")
321
+ .replace(/_\b(.)/g, "$1")
322
+ .replace(/\b/g, "")
323
+ .replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
324
+ }
325
+
326
+ function looksLikeHelp(text: string): boolean {
327
+ if (!text.trim()) return false;
328
+ if (text.length < 40) return false;
329
+ const firstChunk = text.slice(0, 200).toLowerCase();
330
+ // Error messages from unknown subcommands or unsupported flags
331
+ if (/(unknown|invalid|no such|not a \w+ command|flag needs an argument|unrecognized)/.test(firstChunk)) {
332
+ return false;
333
+ }
334
+ // "Run '... --help' for more information" is a hint, not the help itself
335
+ if (/run '.+' for more information/.test(firstChunk)) return false;
336
+ return true;
337
+ }
338
+
339
+ async function tryHelpVariant(binary: string, argv: string[], timeoutMs = 5000): Promise<string | null> {
340
+ try {
341
+ const proc = Bun.spawn([binary, ...argv], {
342
+ stdout: "pipe",
343
+ stderr: "pipe",
344
+ env: { ...process.env, PAGER: "cat", MANPAGER: "cat", GIT_PAGER: "cat" },
345
+ });
346
+
347
+ const timer = setTimeout(() => proc.kill(), timeoutMs);
348
+
349
+ const [stdout, stderr] = await Promise.all([
350
+ new Response(proc.stdout).text(),
351
+ new Response(proc.stderr).text(),
352
+ ]);
353
+ clearTimeout(timer);
354
+ await proc.exited;
355
+
356
+ const combined = stdout || stderr;
357
+ if (!looksLikeHelp(combined)) return null;
358
+ return stripOverstrike(combined);
359
+ } catch {
360
+ return null;
361
+ }
362
+ }
363
+
364
+ async function tryManPage(binary: string, subPath: string[], timeoutMs = 5000): Promise<string | null> {
365
+ // Try 'man binary-sub' (git-commit), then 'man binary sub' as a fallback.
366
+ const candidates = [
367
+ subPath.length > 0 ? [`${binary}-${subPath.join("-")}`] : [binary],
368
+ [binary, ...subPath],
369
+ ];
370
+
371
+ for (const args of candidates) {
372
+ try {
373
+ const proc = Bun.spawn(["man", ...args], {
374
+ stdout: "pipe",
375
+ stderr: "pipe",
376
+ env: { ...process.env, MANPAGER: "cat", PAGER: "cat" },
377
+ });
378
+
379
+ const timer = setTimeout(() => proc.kill(), timeoutMs);
380
+ const [stdout] = await Promise.all([
381
+ new Response(proc.stdout).text(),
382
+ new Response(proc.stderr).text(),
383
+ ]);
384
+ clearTimeout(timer);
385
+ await proc.exited;
386
+
387
+ if (looksLikeHelp(stdout)) return stripOverstrike(stdout);
388
+ } catch {}
389
+ }
390
+ return null;
391
+ }
392
+
393
+ async function runSafeHelp(args: string[]) {
394
+ let binary: string | null = null;
395
+ const subPath: string[] = [];
396
+
397
+ for (const arg of args) {
398
+ if (arg === "--no-color" || arg === "--help" || arg === "-h") continue;
399
+ if (!binary) {
400
+ binary = arg;
401
+ } else {
402
+ subPath.push(arg);
403
+ }
404
+ }
405
+
406
+ if (!binary) {
407
+ console.error("Error: provide a binary name");
408
+ console.error("Run 'clitree safe-help --help' for usage");
409
+ process.exit(1);
410
+ }
411
+
412
+ // Strategy in order of preference:
413
+ // 1. `<cli> <sub> -h` — short inline help, no pager
414
+ // 2. `<cli> <sub> --help` — long form, overstrike-stripped
415
+ // 3. `<cli> help <sub>` — alternate syntax (git, go, bun)
416
+ // 4. `man <cli>-<sub>` or `man <cli> <sub>` — final fallback
417
+ const variants: Array<{ label: string; args: string[] }> = [
418
+ { label: "short help (-h)", args: [...subPath, "-h"] },
419
+ { label: "long help (--help)", args: [...subPath, "--help"] },
420
+ ];
421
+
422
+ if (subPath.length > 0) {
423
+ variants.push({ label: "help subcommand", args: ["help", ...subPath] });
424
+ }
425
+
426
+ for (const variant of variants) {
427
+ const output = await tryHelpVariant(binary, variant.args);
428
+ if (output) {
429
+ process.stdout.write(output);
430
+ if (!output.endsWith("\n")) process.stdout.write("\n");
431
+ return;
432
+ }
433
+ }
434
+
435
+ // Last resort: man page
436
+ const manOutput = await tryManPage(binary, subPath);
437
+ if (manOutput) {
438
+ process.stdout.write(manOutput);
439
+ if (!manOutput.endsWith("\n")) process.stdout.write("\n");
440
+ return;
441
+ }
442
+
443
+ console.error(`Error: could not fetch help for ${binary} ${subPath.join(" ")}`);
444
+ console.error("Tried: -h, --help, help subcommand, and man page.");
445
+ process.exit(1);
446
+ }
447
+
270
448
  function shouldUseColor(args: string[]): boolean {
271
449
  if (args.includes("--no-color")) return false;
272
450
  if (process.env.NO_COLOR) return false;
@@ -297,6 +475,7 @@ async function runMine(args: string[]) {
297
475
  let historyPath: string | undefined;
298
476
  let format: "ansi" | "json" = "ansi";
299
477
  let maxPaths = 10;
478
+ let withFlow: "auto" | "on" | "off" = "auto";
300
479
 
301
480
  for (let i = 0; i < args.length; i++) {
302
481
  const arg = args[i]!;
@@ -308,6 +487,10 @@ async function runMine(args: string[]) {
308
487
  format = args[++i] as "ansi" | "json";
309
488
  } else if (arg === "--max-paths" && args[i + 1]) {
310
489
  maxPaths = Number.parseInt(args[++i]!, 10);
490
+ } else if (arg === "--with-flow" || arg === "--flow") {
491
+ withFlow = "on";
492
+ } else if (arg === "--no-flow") {
493
+ withFlow = "off";
311
494
  } else if (arg !== "--no-color" && !arg.startsWith("-")) {
312
495
  binary = arg;
313
496
  }
@@ -369,12 +552,40 @@ async function runMine(args: string[]) {
369
552
  }
370
553
  console.log();
371
554
  }
555
+
556
+ // Pick the top workflow worth visualizing as a DAG.
557
+ // In "auto" mode, prefer the highest-support workflow with 3+ steps —
558
+ // 2-step chains are more readable as text than as boxed diagrams.
559
+ // In "on" mode, render whatever is the top regardless of length.
560
+ // In "off" mode, skip.
561
+ if (withFlow !== "off") {
562
+ const minSteps = withFlow === "on" ? 2 : 3;
563
+ const topForFlow = pickWorkflowForFlow(result.workflows, minSteps);
564
+ if (topForFlow) {
565
+ const flowWorkflow = minedToFlowWorkflow(topForFlow);
566
+ const rendered = shouldUseColor(args) ? flowToAnsi(flowWorkflow) : flowToString(flowWorkflow);
567
+ console.log(`${C.bold}Top workflow (visualized):${C.reset}`);
568
+ console.log(rendered);
569
+ console.log();
570
+ }
571
+ }
372
572
  } catch (err: any) {
373
573
  console.error(`Error: ${err.message}`);
374
574
  process.exit(1);
375
575
  }
376
576
  }
377
577
 
578
+ function pickWorkflowForFlow<T extends { path: string[][]; support: number }>(
579
+ workflows: T[],
580
+ minSteps = 3,
581
+ ): T | null {
582
+ for (const wf of workflows) {
583
+ const len = wf.path[0]?.length ?? 0;
584
+ if (len >= minSteps) return wf;
585
+ }
586
+ return null;
587
+ }
588
+
378
589
  async function runArchaeologyCmd(args: string[]) {
379
590
  let binary: string | null = null;
380
591
  let skipCache = false;
@@ -4,6 +4,7 @@ import { buildTransitions, normalizeTransitions, extractSubcommand, extractSubco
4
4
  import { extractPaths, clusterIntoWorkflows } from "./workflows";
5
5
  import { computeStats } from "./stats";
6
6
  import { suggestSkills, type SkillSuggestion } from "./suggest";
7
+ import { minedToFlowWorkflow } from "./to-flow";
7
8
  import type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions } from "./types";
8
9
 
9
10
  export type { HistoryEntry, Session, Transition, MinedWorkflow, CliUsageStats, MineOptions, SkillSuggestion };
@@ -23,6 +24,7 @@ export {
23
24
  clusterIntoWorkflows,
24
25
  computeStats,
25
26
  suggestSkills,
27
+ minedToFlowWorkflow,
26
28
  };
27
29
 
28
30
  export interface MineResult {
@@ -0,0 +1,36 @@
1
+ import type { Workflow } from "../flow/types";
2
+ import type { MinedWorkflow } from "./types";
3
+
4
+ /**
5
+ * Convert a MinedWorkflow (discovered from shell history) into a Workflow
6
+ * that the flow renderer can visualize as an ASCII DAG.
7
+ *
8
+ * The mined workflow is a linear path like ["add", "commit", "push"] with
9
+ * a frequency count. We turn it into a linear Workflow with one node per
10
+ * step and edges in order — matching the shape of the handcrafted YAML
11
+ * workflows in workflows/.
12
+ */
13
+ export function minedToFlowWorkflow(mined: MinedWorkflow, occurrences?: number): Workflow {
14
+ const path = mined.path[0] ?? [];
15
+ const label = path.join(" → ");
16
+ const freq = occurrences ?? mined.support;
17
+
18
+ const nodes = path.map((sub, idx) => ({
19
+ id: `n${idx}`,
20
+ command: [mined.cli, sub],
21
+ label: sub,
22
+ }));
23
+
24
+ const edges = [];
25
+ for (let i = 0; i < nodes.length - 1; i++) {
26
+ edges.push({ from: nodes[i]!.id, to: nodes[i + 1]!.id });
27
+ }
28
+
29
+ return {
30
+ name: label,
31
+ description: `Seen ${freq}× in your shell history`,
32
+ cli: mined.cli,
33
+ nodes,
34
+ edges,
35
+ };
36
+ }