kirograph 0.27.2 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +14 -7
  2. package/dist/bin/commands/annotations.js +56 -0
  3. package/dist/bin/commands/annotations.js.map +7 -0
  4. package/dist/bin/commands/ast-rewrite.js +55 -0
  5. package/dist/bin/commands/ast-rewrite.js.map +7 -0
  6. package/dist/bin/commands/bench.js +103 -0
  7. package/dist/bin/commands/bench.js.map +7 -0
  8. package/dist/bin/commands/branch.js +133 -0
  9. package/dist/bin/commands/branch.js.map +7 -0
  10. package/dist/bin/commands/changelog.js +55 -0
  11. package/dist/bin/commands/changelog.js.map +7 -0
  12. package/dist/bin/commands/commit-context.js +55 -0
  13. package/dist/bin/commands/commit-context.js.map +7 -0
  14. package/dist/bin/commands/complexity.js +60 -0
  15. package/dist/bin/commands/complexity.js.map +7 -0
  16. package/dist/bin/commands/cost.js +146 -0
  17. package/dist/bin/commands/cost.js.map +7 -0
  18. package/dist/bin/commands/dependency-depth.js +55 -0
  19. package/dist/bin/commands/dependency-depth.js.map +7 -0
  20. package/dist/bin/commands/diff-context.js +55 -0
  21. package/dist/bin/commands/diff-context.js.map +7 -0
  22. package/dist/bin/commands/distribution.js +56 -0
  23. package/dist/bin/commands/distribution.js.map +7 -0
  24. package/dist/bin/commands/doc-coverage.js +56 -0
  25. package/dist/bin/commands/doc-coverage.js.map +7 -0
  26. package/dist/bin/commands/doctor.js +202 -0
  27. package/dist/bin/commands/doctor.js.map +7 -0
  28. package/dist/bin/commands/dsm.js +56 -0
  29. package/dist/bin/commands/dsm.js.map +7 -0
  30. package/dist/bin/commands/gini.js +55 -0
  31. package/dist/bin/commands/gini.js.map +7 -0
  32. package/dist/bin/commands/god-class.js +56 -0
  33. package/dist/bin/commands/god-class.js.map +7 -0
  34. package/dist/bin/commands/health.js +55 -0
  35. package/dist/bin/commands/health.js.map +7 -0
  36. package/dist/bin/commands/help.js +224 -45
  37. package/dist/bin/commands/help.js.map +2 -2
  38. package/dist/bin/commands/inheritance-depth.js +56 -0
  39. package/dist/bin/commands/inheritance-depth.js.map +7 -0
  40. package/dist/bin/commands/insert-at.js +55 -0
  41. package/dist/bin/commands/insert-at.js.map +7 -0
  42. package/dist/bin/commands/largest.js +56 -0
  43. package/dist/bin/commands/largest.js.map +7 -0
  44. package/dist/bin/commands/manifest.js +158 -0
  45. package/dist/bin/commands/manifest.js.map +7 -0
  46. package/dist/bin/commands/module-api.js +57 -0
  47. package/dist/bin/commands/module-api.js.map +7 -0
  48. package/dist/bin/commands/monitor.js +91 -0
  49. package/dist/bin/commands/monitor.js.map +7 -0
  50. package/dist/bin/commands/multi-replace.js +66 -0
  51. package/dist/bin/commands/multi-replace.js.map +7 -0
  52. package/dist/bin/commands/pr-context.js +55 -0
  53. package/dist/bin/commands/pr-context.js.map +7 -0
  54. package/dist/bin/commands/query.js +19 -1
  55. package/dist/bin/commands/query.js.map +3 -3
  56. package/dist/bin/commands/rank.js +56 -0
  57. package/dist/bin/commands/rank.js.map +7 -0
  58. package/dist/bin/commands/read.js +1 -1
  59. package/dist/bin/commands/read.js.map +2 -2
  60. package/dist/bin/commands/recursion.js +56 -0
  61. package/dist/bin/commands/recursion.js.map +7 -0
  62. package/dist/bin/commands/rename-preview.js +56 -0
  63. package/dist/bin/commands/rename-preview.js.map +7 -0
  64. package/dist/bin/commands/session.js +60 -0
  65. package/dist/bin/commands/session.js.map +7 -0
  66. package/dist/bin/commands/simplify-scan.js +56 -0
  67. package/dist/bin/commands/simplify-scan.js.map +7 -0
  68. package/dist/bin/commands/str-replace.js +55 -0
  69. package/dist/bin/commands/str-replace.js.map +7 -0
  70. package/dist/bin/commands/test-coverage.js +59 -0
  71. package/dist/bin/commands/test-coverage.js.map +7 -0
  72. package/dist/bin/commands/test-map.js +56 -0
  73. package/dist/bin/commands/test-map.js.map +7 -0
  74. package/dist/bin/commands/test-risk.js +59 -0
  75. package/dist/bin/commands/test-risk.js.map +7 -0
  76. package/dist/bin/commands/unused-imports.js +55 -0
  77. package/dist/bin/commands/unused-imports.js.map +7 -0
  78. package/dist/bin/commands/upgrade.js +78 -0
  79. package/dist/bin/commands/upgrade.js.map +7 -0
  80. package/dist/bin/installer/common.js +5 -1
  81. package/dist/bin/installer/common.js.map +2 -2
  82. package/dist/bin/installer/config-prompt.js +140 -11
  83. package/dist/bin/installer/config-prompt.js.map +3 -3
  84. package/dist/bin/installer/index.js +38 -6
  85. package/dist/bin/installer/index.js.map +2 -2
  86. package/dist/bin/installer/instructions.js +7 -11
  87. package/dist/bin/installer/instructions.js.map +2 -2
  88. package/dist/bin/installer/mcp.js.map +2 -2
  89. package/dist/bin/installer/steering.js +531 -100
  90. package/dist/bin/installer/steering.js.map +2 -2
  91. package/dist/bin/installer/targets/kiro.js +7 -3
  92. package/dist/bin/installer/targets/kiro.js.map +2 -2
  93. package/dist/bin/kirograph.js +73 -1
  94. package/dist/bin/kirograph.js.map +3 -3
  95. package/dist/config.js +26 -8
  96. package/dist/config.js.map +2 -2
  97. package/dist/core/branch-manager.js +111 -0
  98. package/dist/core/branch-manager.js.map +7 -0
  99. package/dist/core/pipeline.js +3 -3
  100. package/dist/core/pipeline.js.map +2 -2
  101. package/dist/data/pixelrag-bridge.js +93 -0
  102. package/dist/data/pixelrag-bridge.js.map +7 -0
  103. package/dist/data/pixelrag-manager.js +416 -0
  104. package/dist/data/pixelrag-manager.js.map +7 -0
  105. package/dist/db/database.js +34 -7
  106. package/dist/db/database.js.map +2 -2
  107. package/dist/db/schema.sql +7 -1
  108. package/dist/extraction/complexity.js +116 -0
  109. package/dist/extraction/complexity.js.map +7 -0
  110. package/dist/extraction/extractor.js +52 -1
  111. package/dist/extraction/extractor.js.map +2 -2
  112. package/dist/graph/git-context.js +229 -0
  113. package/dist/graph/git-context.js.map +7 -0
  114. package/dist/index.js +4 -2
  115. package/dist/index.js.map +2 -2
  116. package/dist/mcp/handler.js +446 -0
  117. package/dist/mcp/handler.js.map +7 -0
  118. package/dist/mcp/handlers/architecture.js +297 -0
  119. package/dist/mcp/handlers/architecture.js.map +7 -0
  120. package/dist/mcp/handlers/branch.js +175 -0
  121. package/dist/mcp/handlers/branch.js.map +7 -0
  122. package/dist/mcp/handlers/code-health.js +563 -0
  123. package/dist/mcp/handlers/code-health.js.map +7 -0
  124. package/dist/mcp/handlers/complexity.js +267 -0
  125. package/dist/mcp/handlers/complexity.js.map +7 -0
  126. package/dist/mcp/handlers/core.js +611 -0
  127. package/dist/mcp/handlers/core.js.map +7 -0
  128. package/dist/mcp/handlers/data.js +337 -0
  129. package/dist/mcp/handlers/data.js.map +7 -0
  130. package/dist/mcp/handlers/docs.js +159 -0
  131. package/dist/mcp/handlers/docs.js.map +7 -0
  132. package/dist/mcp/handlers/edit-primitives.js +200 -0
  133. package/dist/mcp/handlers/edit-primitives.js.map +7 -0
  134. package/dist/mcp/handlers/git-context.js +286 -0
  135. package/dist/mcp/handlers/git-context.js.map +7 -0
  136. package/dist/mcp/handlers/memory.js +363 -0
  137. package/dist/mcp/handlers/memory.js.map +7 -0
  138. package/dist/mcp/handlers/patterns.js +310 -0
  139. package/dist/mcp/handlers/patterns.js.map +7 -0
  140. package/dist/mcp/handlers/security.js +699 -0
  141. package/dist/mcp/handlers/security.js.map +7 -0
  142. package/dist/mcp/handlers/utils.js +97 -0
  143. package/dist/mcp/handlers/utils.js.map +7 -0
  144. package/dist/mcp/handlers/watchmen.js +104 -0
  145. package/dist/mcp/handlers/watchmen.js.map +7 -0
  146. package/dist/mcp/handlers/wiki.js +242 -0
  147. package/dist/mcp/handlers/wiki.js.map +7 -0
  148. package/dist/mcp/server.js +72 -3
  149. package/dist/mcp/server.js.map +2 -2
  150. package/dist/mcp/tool-names.js +94 -7
  151. package/dist/mcp/tool-names.js.map +2 -2
  152. package/dist/mcp/tools.js +445 -3210
  153. package/dist/mcp/tools.js.map +3 -3
  154. package/dist/types.js.map +2 -2
  155. package/package.json +36 -10
@@ -46,14 +46,16 @@ const GROUPS = [
46
46
  { name: "install", desc: "Wire up MCP/instructions for an agent workspace", opts: ["--target <t> kiro | cursor | claude | windsurf | ...", "Kiro install: prompts to import global hooks"] },
47
47
  { name: "init", args: "[path]", desc: "Initialize KiroGraph in a project", opts: ["-i, --index Index immediately after init"] },
48
48
  { name: "uninit", args: "[path]", desc: "Remove KiroGraph from a project", opts: ["--force Skip confirmation", '--target <t> Target to clean up (or "all")'] },
49
- { name: "hook", desc: "Manage global Kiro hooks in ~/.kirograph/hooks/", opts: ["save [path] Save workspace hooks to global store", "import [path] Import global hooks into workspace", "list List saved global hooks", "--all Save or import all without prompting (save/import)"] }
49
+ { name: "hook", desc: "Manage global Kiro hooks in ~/.kirograph/hooks/", opts: ["save [path] Save workspace hooks to global store", "import [path] Import global hooks into workspace", "list List saved global hooks", "--all Save or import all without prompting (save/import)"] },
50
+ { name: "doctor", args: "[path]", desc: "Health check: index, config, hooks, and permissions", opts: ["--fix Auto-repair fixable issues"] }
50
51
  ],
51
52
  examples: [
52
53
  ["kirograph install", "Wire up Kiro MCP + hooks + steering"],
53
- ["kirograph install --target cursor", "Wire up Cursor MCP + rules + hooks"],
54
+ ["kirograph install --target claude", "Wire up Claude Code MCP + project memory"],
54
55
  ["kirograph init --index", "Init and immediately index"],
55
56
  ["kirograph hook save", "Save workspace hooks to your global library"],
56
- ["kirograph hook import", "Import global hooks into this project"]
57
+ ["kirograph hook import", "Import global hooks into this project"],
58
+ ["kirograph doctor --fix", "Check and auto-repair installation issues"]
57
59
  ]
58
60
  },
59
61
  {
@@ -79,13 +81,18 @@ const GROUPS = [
79
81
  { name: "query", args: "<search>", desc: "Search for symbols by name", opts: ["--kind <k> Filter by kind", "--limit <n> Max results"] },
80
82
  { name: "context", args: "<task>", desc: "Build relevant code context for a task", opts: ["--max-nodes <n> Max symbols", "--no-code Exclude code", "--format <f> markdown | json"] },
81
83
  { name: "files", args: "[path]", desc: "Show project file structure", opts: ["--format <f> tree | flat | grouped | compact", "--filter <p> Directory prefix", "--pattern <g> Glob"] },
82
- { name: "path", args: "<from> <to>", desc: "Shortest path between two symbols" },
83
- { name: "affected", args: "[files...]", desc: "Find test files affected by changes", opts: ["--stdin Read from stdin", "-d <n> Depth", "-q Quiet"] }
84
+ { name: "path", args: "<from> <to>", desc: "Shortest dependency path between two symbols" },
85
+ { name: "affected", args: "[files...]", desc: "Find test files affected by changed source files", opts: ["--stdin Read from stdin", "-d <n> Depth", "-q Quiet"] },
86
+ { name: "callers", args: "<symbol>", desc: "List symbols that call a given function or method", opts: ["--limit <n> Max results"] },
87
+ { name: "callees", args: "<symbol>", desc: "List symbols called by a given function or method", opts: ["--limit <n> Max results"] },
88
+ { name: "impact", args: "<symbol>", desc: "Show symbols affected by changing a given symbol", opts: ["-d, --depth <n> Max traversal depth"] }
84
89
  ],
85
90
  examples: [
86
91
  ["kirograph query useState", "Find symbols named useState"],
87
92
  ['kirograph context "add dark mode"', "Get context for a task"],
88
- ["kirograph path LoginController Pool", "How are these connected?"],
93
+ ["kirograph callers parseToken", "Who calls parseToken?"],
94
+ ["kirograph callees handleRequest", "What does handleRequest call?"],
95
+ ["kirograph impact UserService", "What breaks if UserService changes?"],
89
96
  ["git diff --name-only | kirograph affected --stdin", "Affected tests from git diff"]
90
97
  ]
91
98
  },
@@ -96,13 +103,21 @@ const GROUPS = [
96
103
  { name: "hotspots", args: "[path]", desc: "Most-connected symbols by edge degree", opts: ["--limit <n> Max results", "--format <f> table | json"] },
97
104
  { name: "surprising", args: "[path]", desc: "Non-obvious cross-file connections", opts: ["--limit <n> Max results"] },
98
105
  { name: "dead-code", args: "[path]", desc: "Unreferenced unexported symbols", opts: ["--limit <n> Max results"] },
106
+ { name: "circular-deps", args: "[path]", desc: "Find circular dependency cycles", opts: ["-j, --json JSON output"] },
107
+ { name: "largest", args: "[path]", desc: "Symbols ranked by lines of code", opts: ["--limit <n> Max results"] },
108
+ { name: "rank", args: "[path]", desc: "Symbols ranked by fan-in or fan-out edge count", opts: ["--by <by> fan-in | fan-out"] },
109
+ { name: "distribution", args: "[dir]", desc: "Symbol-kind breakdown per file or directory", opts: ["--limit <n> Max results"] },
110
+ { name: "god-class", args: "[path]", desc: "Classes ranked by member count (god-class risk)", opts: ["--limit <n> Max results"] },
111
+ { name: "gini", args: "[path]", desc: "Gini inequality coefficient of a metric", opts: ["--metric <m> loc | fan-in | fan-out"] },
99
112
  { name: "snapshot", desc: "Save/list/diff graph snapshots", opts: ["save [label]", "list", "diff [label] --format summary|full|json"] },
100
113
  { name: "export", desc: "Interactive graph dashboard", opts: ["build [path] Generate HTML", "start [path] Generate and open"] }
101
114
  ],
102
115
  examples: [
103
116
  ["kirograph hotspots --limit 10", "Top 10 most-connected symbols"],
117
+ ["kirograph circular-deps", "Find all circular dependency cycles"],
118
+ ["kirograph largest --limit 20", "Biggest functions by LOC"],
119
+ ["kirograph god-class", "Find potential god classes"],
104
120
  ["kirograph snapshot save pre-refactor", "Save before a refactor"],
105
- ["kirograph snapshot diff pre-refactor", "See what changed"],
106
121
  ["kirograph export start", "Open the graph dashboard"]
107
122
  ]
108
123
  },
@@ -112,12 +127,176 @@ const GROUPS = [
112
127
  commands: [
113
128
  { name: "architecture", args: "[path]", desc: "Package graph and layer map", opts: ["--packages Packages only", "--layers Layers only"] },
114
129
  { name: "coupling", args: "[path]", desc: "Coupling metrics per package", opts: ["--sort <s> instability | ca | ce | name", "--package <n> Detail view"] },
115
- { name: "package", args: "<name>", desc: "Inspect a package", opts: ["--no-files Omit file list"] }
130
+ { name: "package", args: "<name>", desc: "Inspect a package", opts: ["--no-files Omit file list"] },
131
+ { name: "type-hierarchy", args: "<symbol>", desc: "Traverse base/derived types of a class or interface", opts: ["--direction <dir> up | down | both"] },
132
+ { name: "communities", args: "[path]", desc: "Detect code communities (clusters of related symbols)" },
133
+ { name: "manifest", args: "[path]", desc: "Workspace manifest: packages, versions, licenses, version drift" }
116
134
  ],
117
135
  examples: [
118
136
  ["kirograph architecture --packages", "List all detected packages"],
119
137
  ["kirograph coupling --sort instability", "Packages ranked by instability"],
120
- ["kirograph package src/auth", "Inspect the auth package"]
138
+ ["kirograph type-hierarchy UserRepository --direction up", "What interfaces does this implement?"],
139
+ ["kirograph communities", "Find tightly coupled clusters"],
140
+ ["kirograph manifest", "Show all dependency versions and drift"]
141
+ ]
142
+ },
143
+ {
144
+ icon: "\u{1F3E5}",
145
+ title: "Code Health",
146
+ commands: [
147
+ { name: "module-api", args: "[path]", desc: "List all exported symbols in a file or directory", opts: ["--limit <n> Max results"] },
148
+ { name: "rename-preview", args: "<symbol>", desc: "Show all reference sites for a symbol before renaming", opts: ["--limit <n> Max results"] },
149
+ { name: "doc-coverage", args: "[path]", desc: "Find exported symbols missing docstrings", opts: ["--limit <n> Max results"] },
150
+ { name: "inheritance-depth", args: "[path]", desc: "Find deepest inheritance chains", opts: ["--limit <n> Max results"] },
151
+ { name: "recursion", args: "[path]", desc: "Find recursive and mutually-recursive functions", opts: ["--limit <n> Max results"] },
152
+ { name: "annotations", args: "[path]", desc: "Decorator/attribute histogram across the codebase", opts: ["--decorator <name> Filter by name"] },
153
+ { name: "unused-imports", args: "[path]", desc: "Find import nodes with zero resolved downstream edges", opts: ["--limit <n> Max results"] },
154
+ { name: "dependency-depth", args: "[path]", desc: "Topological depth of each file in the import graph", opts: ["--limit <n> Max files"] },
155
+ { name: "session", desc: "Save or compare session baselines for tracking changes", opts: ["start Start a session baseline", "end Compare current state to baseline"] },
156
+ { name: "refactor", desc: "Refactoring tools: rename preview and community-driven suggestions", opts: ["rename <symbol> Preview rename locations", "suggest Get refactoring suggestions"] }
157
+ ],
158
+ examples: [
159
+ ["kirograph module-api src/auth", "List public API of the auth module"],
160
+ ["kirograph rename-preview handleLogin", "Find all sites before renaming"],
161
+ ["kirograph doc-coverage", "Find undocumented exports"],
162
+ ["kirograph unused-imports", "Find dead import statements"],
163
+ ["kirograph session start && <edit> && kirograph session end", "Diff graph before and after a change"]
164
+ ]
165
+ },
166
+ {
167
+ icon: "\u{1F52C}",
168
+ title: "Analysis",
169
+ commands: [
170
+ { name: "complexity", args: "[path]", desc: "Rank functions by cyclomatic, cognitive, and maintainability score", opts: ["--limit <n> Max results"] },
171
+ { name: "simplify-scan", args: "[path]", desc: "Find candidates for simplification by complexity and dead code", opts: ["--limit <n> Max results"] },
172
+ { name: "health", args: "[path]", desc: "Composite codebase health score (0-10000) with grade" },
173
+ { name: "dsm", args: "[path]", desc: "Design Structure Matrix \u2014 detect strongly coupled module groups", opts: ["--limit <n> Max groups"] },
174
+ { name: "test-risk", args: "[path]", desc: "Rank untested code by risk score (complexity \xD7 fan-in)", opts: ["--limit <n> Max results"] },
175
+ { name: "test-coverage", args: "[path]", desc: "Show test coverage gaps from lcov/Istanbul reports", opts: ["--sort <order> asc (worst first) | desc"] }
176
+ ],
177
+ examples: [
178
+ ["kirograph health", "Get overall health score and grade"],
179
+ ["kirograph complexity --limit 10", "Top 10 most complex functions"],
180
+ ["kirograph test-risk", "Which untested code is highest risk?"],
181
+ ["kirograph test-coverage", "Show worst-covered files first"],
182
+ ["kirograph dsm", "Find tightly coupled module groups"]
183
+ ]
184
+ },
185
+ {
186
+ icon: "\u{1F33F}",
187
+ title: "Git",
188
+ commands: [
189
+ { name: "diff-context", args: "[path]", desc: "Changed symbols, their callers/callees, and affected tests", opts: ["--staged Use staged changes only"] },
190
+ { name: "commit-context", args: "[path]", desc: "Structured summary of staged changes for a commit message" },
191
+ { name: "pr-context", args: "<base> [head]", desc: "Semantic diff between two git refs for PR descriptions", opts: ["--format <fmt> text | json"] },
192
+ { name: "changelog", args: "<ref1> <ref2>", desc: "Human-readable semantic diff between two git refs" },
193
+ { name: "test-map", args: "[symbol]", desc: "Map symbols to test files; show uncovered symbols", opts: ["--limit <n> Max results"] }
194
+ ],
195
+ examples: [
196
+ ["kirograph diff-context --staged", "What does my staged diff actually change?"],
197
+ ["kirograph commit-context", "Generate a structured commit message draft"],
198
+ ["kirograph pr-context main", "Semantic PR description vs main"],
199
+ ["kirograph changelog v1.0 v1.1", "What changed between two tags?"],
200
+ ["kirograph test-map", "Which symbols have no test coverage?"]
201
+ ]
202
+ },
203
+ {
204
+ icon: "\u270F\uFE0F",
205
+ title: "Edit",
206
+ commands: [
207
+ { name: "str-replace", args: "<file> <old> <new>", desc: "Replace unique string anchor in a file; fails on 0 or >1 matches" },
208
+ { name: "multi-replace", args: "<file> <pairs-json>", desc: "Multiple string replacements as an all-or-nothing transaction" },
209
+ { name: "insert-at", args: "<file> <anchor> <content>", desc: "Insert content before or after an anchor or line number", opts: ["--after Insert after anchor", "--line Treat anchor as line number"] },
210
+ { name: "ast-rewrite", args: "<file> <pattern> <rewrite>", desc: "Structural rewrite via ast-grep (requires ast-grep on PATH)" }
211
+ ],
212
+ examples: [
213
+ ['kirograph str-replace auth.ts "return null" "return undefined"', "Safe replace a unique string"],
214
+ ['kirograph insert-at server.ts "app.listen" "app.use(logger());" --before', "Insert before a line"],
215
+ ['kirograph ast-rewrite src/api.ts "console.log($MSG)" "logger.debug($MSG)"', "Structural rewrite"]
216
+ ]
217
+ },
218
+ {
219
+ icon: "\u{1F332}",
220
+ title: "Branch",
221
+ commands: [
222
+ { name: "branch list", desc: "List tracked branches with size and last-sync time" },
223
+ { name: "branch add", args: "[name]", desc: "Start tracking a branch (copies current index)" },
224
+ { name: "branch remove", args: "<name>", desc: "Stop tracking a branch and delete its DB" },
225
+ { name: "branch gc", desc: "Remove DBs for branches that no longer exist in git" },
226
+ { name: "branch diff", args: "<a> <b>", desc: "Symbol diff between two tracked branch DBs" },
227
+ { name: "branch search", args: "<name> <query>", desc: "Search symbols in a branch DB without switching" }
228
+ ],
229
+ examples: [
230
+ ["kirograph branch list", "See all tracked branches"],
231
+ ["kirograph branch add feature/auth", "Track the auth branch"],
232
+ ["kirograph branch diff main feature/auth", "What symbols changed?"],
233
+ ['kirograph branch search feature/auth "handleLogin"', "Search in branch without switching"],
234
+ ["kirograph branch gc", "Clean up deleted branches"]
235
+ ]
236
+ },
237
+ {
238
+ icon: "\u{1F4DA}",
239
+ title: "Docs",
240
+ commands: [
241
+ { name: "docs toc", args: "[file]", desc: "Table of contents for a file or the whole project" },
242
+ { name: "docs search", args: "<query>", desc: "Full-text search over documentation sections", opts: ["--limit <n> Max results", "--section <id> Restrict to section"] },
243
+ { name: "docs section", args: "<id>", desc: "Print the full content of a section by ID" },
244
+ { name: "docs outline", args: "<file>", desc: "Print heading hierarchy for a document" },
245
+ { name: "docs refs", args: "<id>", desc: "Show code-to-doc and doc-to-code cross-references" },
246
+ { name: "docs reindex", desc: "Force re-index all documentation files" },
247
+ { name: "docs lint", desc: "Find broken refs, stale sections, FTS desync" }
248
+ ],
249
+ examples: [
250
+ ["kirograph docs toc", "Table of contents for the project"],
251
+ ['kirograph docs search "authentication"', "Find docs about auth"],
252
+ ["kirograph docs section api.auth.login", "Read a specific section"],
253
+ ["kirograph docs refs api.auth.login", "Which code references this doc section?"]
254
+ ]
255
+ },
256
+ {
257
+ icon: "\u{1F5C4}\uFE0F",
258
+ title: "Data",
259
+ commands: [
260
+ { name: "data list", desc: "List all indexed datasets" },
261
+ { name: "data describe", args: "<dataset>", desc: "Show schema and column profiles", opts: ["--format <f> table | json"] },
262
+ { name: "data query", args: "<dataset>", desc: "Query rows with filters", opts: ["--filter <f> col:op:val", "--limit <n> Max rows", "--format <f> table | json | csv"] },
263
+ { name: "data aggregate", args: "<dataset>", desc: "Server-side GROUP BY aggregation", opts: ["--group-by <col>", "--metric <agg:col> sum|avg|count|min|max"] },
264
+ { name: "data search", args: "<dataset> <q>", desc: "Search column names and sample values" },
265
+ { name: "data join", args: "<left> <right>", desc: "SQL JOIN across two indexed datasets", opts: ["--left-col <c> Join key", "--right-col <c> Join key", "--type inner|left|right"] },
266
+ { name: "data correlations", args: "<dataset>", desc: "Pairwise Pearson correlations between numeric columns" },
267
+ { name: "data quality", args: "<dataset>", desc: "Data quality triage: rank columns by risk" },
268
+ { name: "data drift", args: "<dataset>", desc: "Show schema drift between last two indexes" },
269
+ { name: "data history", args: "<dataset>", desc: "Show history of schema changes for a dataset" }
270
+ ],
271
+ examples: [
272
+ ["kirograph data list", "List all indexed datasets"],
273
+ ["kirograph data describe orders", "Schema and column profiles for orders"],
274
+ ["kirograph data query orders --filter status:eq:shipped", "Filter rows"],
275
+ ["kirograph data aggregate orders --group-by region --metric sum:amount", "Aggregate by region"],
276
+ ["kirograph data join users orders --left-col id --right-col user_id", "Join datasets"]
277
+ ]
278
+ },
279
+ {
280
+ icon: "\u{1F4D6}",
281
+ title: "Wiki",
282
+ commands: [
283
+ { name: "wiki init", desc: "Initialize wiki: create SCHEMA.md and MANIFEST.md" },
284
+ { name: "wiki ingest", args: "[source]", desc: "Print the ingest prompt for the LLM (reads file or stdin)" },
285
+ { name: "wiki search", args: "<query>", desc: "Full-text search over wiki pages", opts: ["--limit <n> Max results"] },
286
+ { name: "wiki page", args: "<slug>", desc: "Print the full content of a wiki page" },
287
+ { name: "wiki list", desc: "List all wiki pages" },
288
+ { name: "wiki lint", desc: "Health check the wiki for broken links, orphans, contradictions" },
289
+ { name: "wiki reindex", desc: "Rebuild SQLite index from .kirograph/wiki/*.md files" },
290
+ { name: "wiki status", desc: "Wiki subsystem stats: page count, source count, oldest/newest page" },
291
+ { name: "wiki synthesize", desc: "Run local-model wiki synthesis over the pending source queue" },
292
+ { name: "wiki apply-diff", args: "[diff]", desc: "Apply a WIKI_DIFF string to the wiki" }
293
+ ],
294
+ examples: [
295
+ ["kirograph wiki init", "Initialize the wiki in this project"],
296
+ ['kirograph wiki search "authentication flow"', "Find wiki pages about auth"],
297
+ ["kirograph wiki page arch-overview", "Read a specific wiki page"],
298
+ ["kirograph wiki lint", "Check wiki health"],
299
+ ["kirograph wiki status", "How many pages and sources?"]
121
300
  ]
122
301
  },
123
302
  {
@@ -126,17 +305,26 @@ const GROUPS = [
126
305
  commands: [
127
306
  { name: "mem search", args: "<query>", desc: "Search past observations", opts: ["--kind <k> Filter by kind", "--limit <n> Max results"] },
128
307
  { name: "mem store", args: "<text>", desc: "Store an observation", opts: ["--kind <k> decision | error | pattern | architecture | note"] },
308
+ { name: "mem capture", args: "<text>", desc: "Passively extract multiple observations from free-form text" },
129
309
  { name: "mem timeline", desc: "List recent sessions and observations" },
130
310
  { name: "mem status", desc: "Memory health dashboard" },
131
311
  { name: "mem prune", desc: "Remove old observations", opts: ["--older-than <d> Duration (e.g. 90d)"] },
132
312
  { name: "mem export", desc: "Export observations", opts: ["--format <f> jsonl | md"] },
133
- { name: "mem reembed", desc: "Re-embed after model change" },
134
- { name: "mem lint", desc: "Health check and auto-repair", opts: ["--fix Auto-fix issues"] }
313
+ { name: "mem lint", desc: "Health check and auto-repair", opts: ["--fix Auto-fix issues"] },
314
+ { name: "mem reembed", desc: "Re-embed all observations after model change" },
315
+ { name: "mem conflicts list", desc: "List pending conflict relations" },
316
+ { name: "mem conflicts ignore", args: "<id>", desc: "Dismiss a pending conflict relation" },
317
+ { name: "mem watchmen status", desc: "Show watchmen observation counter and last synthesis time" },
318
+ { name: "mem watchmen synthesize", desc: "Run watchmen synthesis: produce brief and/or skill files" },
319
+ { name: "mem watchmen reset", desc: "Reset the watchmen observation counter to zero" }
135
320
  ],
136
321
  examples: [
137
322
  ['kirograph mem search "auth decision"', "Search for past decisions"],
138
323
  ['kirograph mem store "use idempotency keys" --kind decision', "Store a decision"],
139
- ["kirograph mem timeline", "See recent sessions"]
324
+ ["kirograph mem prune --older-than 90d", "Remove observations older than 90 days"],
325
+ ["kirograph mem conflicts list", "See pending conflict relations"],
326
+ ["kirograph mem watchmen status", "Check watchmen counter and last synthesis"],
327
+ ["kirograph mem watchmen synthesize", "Trigger watchmen synthesis manually"]
140
328
  ]
141
329
  },
142
330
  {
@@ -251,16 +439,24 @@ const GROUPS = [
251
439
  { name: "compression", args: "[level]", desc: "Shell compression level (off | normal | aggressive | ultra)" },
252
440
  { name: "exec", args: "<cmd>", desc: "Run command with token-optimized output", opts: ["-l <level> Compression level", "-t <sec> Timeout"] },
253
441
  { name: "gain", desc: "Token savings statistics", opts: ["--graph ASCII chart", "--history Recent commands", "--daily Day breakdown"] },
442
+ { name: "bench", desc: "Run local token-efficiency benchmark across KiroGraph tools", opts: ["--quiet Suppress per-tool output"] },
443
+ { name: "monitor", desc: "Live tail of mcp-calls.jsonl \u2014 watch MCP tool usage in real time", opts: ["--lines <n> Initial lines to show"] },
444
+ { name: "upgrade", desc: "Update KiroGraph to the latest version", opts: ["--dry-run Show what would change without installing"] },
445
+ { name: "cost", args: "[sessionDir]", desc: "Analyze MCP tool usage and token cost from Claude session transcripts", opts: ["--last <n> Last N sessions", "--category Group by tool category"] },
254
446
  { name: "serve", desc: "Start the MCP server", opts: ["--mcp Run as stdio MCP", "--path <p> Project path"] }
255
447
  ],
256
448
  examples: [
257
449
  ["kirograph caveman lite", "Enable lite caveman mode"],
258
450
  ["kirograph exec git status", "Run git status with compression"],
259
- ["kirograph gain --graph", "Show token savings graph"]
451
+ ["kirograph gain --graph", "Show token savings graph"],
452
+ ["kirograph bench", "Run token-efficiency benchmark"],
453
+ ["kirograph monitor", "Watch MCP tool calls live"],
454
+ ["kirograph cost --last 5", "Cost breakdown for the last 5 sessions"],
455
+ ["kirograph upgrade --dry-run", "Preview available KiroGraph update"]
260
456
  ]
261
457
  }
262
458
  ];
263
- function renderGroup(group, highlightIdx) {
459
+ function renderGroup(group, highlightIdx, interactive = false) {
264
460
  const lines = [];
265
461
  const nameWidth = Math.max(...group.commands.map((cmd) => (cmd.name + (cmd.args ? " " + cmd.args : "")).length)) + 2;
266
462
  lines.push("");
@@ -274,14 +470,14 @@ function renderGroup(group, highlightIdx) {
274
470
  const namePart = isHighlighted ? `${c.bold}${c.lavender}${cmd.name}${c.reset}${cmd.args ? " " + c.bold + cmd.args + c.reset : ""}` : `${c.lavender}${cmd.name}${c.reset}${cmd.args ? " " + c.dim + cmd.args + c.reset : ""}`;
275
471
  const pad = " ".repeat(Math.max(0, nameWidth - signature.length));
276
472
  lines.push(`${prefix}${namePart}${pad}${c.gray}${cmd.desc}${c.reset}`);
277
- if (cmd.opts) {
473
+ if (cmd.opts && (!interactive || isHighlighted)) {
278
474
  for (const opt of cmd.opts) {
279
475
  const [flag, ...rest] = opt.split(/ +/);
280
476
  lines.push(` ${c.purple}${flag}${c.reset}${rest.length ? " " + c.dim + rest.join(" ") + c.reset : ""}`);
281
477
  }
282
478
  }
283
479
  }
284
- if (group.examples.length > 0) {
480
+ if (!interactive && group.examples.length > 0) {
285
481
  lines.push("");
286
482
  lines.push(` ${c.bold}${c.paleLavender}EXAMPLES${c.reset}`);
287
483
  lines.push("");
@@ -301,37 +497,25 @@ function renderTabs(selectedIdx) {
301
497
  }).join(" ");
302
498
  }
303
499
  function printInteractiveHelp() {
304
- const CLEAR_LINE = "\x1B[2K\x1B[G";
305
500
  let selectedTab = 0;
306
501
  let selectedCmd = 0;
307
- let prevLineCount = 0;
308
- function render(first) {
309
- if (!first && prevLineCount > 0) {
310
- process.stdout.write(`\x1B[${prevLineCount}A`);
311
- for (let i = 0; i < prevLineCount; i++) {
312
- process.stdout.write(`${CLEAR_LINE}
313
- `);
314
- }
315
- process.stdout.write(`\x1B[${prevLineCount}A`);
316
- }
502
+ function render() {
503
+ process.stdout.write("\x1B[H\x1B[J");
317
504
  const lines = [];
318
505
  lines.push("");
319
506
  lines.push(` ${renderTabs(selectedTab)}`);
320
507
  lines.push(` ${c.dim}\u2190 \u2192 tabs \xB7 \u2191 \u2193 commands \xB7 enter to use \xB7 q quit${c.reset}`);
321
- lines.push(...renderGroup(GROUPS[selectedTab], selectedCmd));
322
- lines.push("");
323
- for (const line of lines) {
324
- process.stdout.write(`${CLEAR_LINE}${line}
325
- `);
326
- }
327
- prevLineCount = lines.length;
508
+ lines.push(...renderGroup(GROUPS[selectedTab], selectedCmd, true));
509
+ process.stdout.write(lines.join("\n") + "\n");
328
510
  }
511
+ process.stdout.write("\x1B[?1049h\x1B[?25l");
329
512
  (0, import_banner.printBanner)();
330
513
  console.log(`
331
514
  ${c.bold}${c.paleLavender}USAGE${c.reset} ${c.lavender}kirograph${c.reset} ${c.gray}<command>${c.reset} ${c.dim}[options]${c.reset}`);
332
- render(true);
515
+ render();
333
516
  const stdin = process.stdin;
334
517
  if (!stdin.isTTY) {
518
+ process.stdout.write("\x1B[?25h\x1B[?1049l");
335
519
  for (let i = 1; i < GROUPS.length; i++) {
336
520
  const lines = renderGroup(GROUPS[i], -1);
337
521
  for (const line of lines) console.log(line);
@@ -345,24 +529,25 @@ ${c.bold}${c.paleLavender}USAGE${c.reset} ${c.lavender}kirograph${c.reset} ${c.
345
529
  stdin.removeListener("data", onData);
346
530
  stdin.setRawMode(false);
347
531
  stdin.pause();
532
+ process.stdout.write("\x1B[?25h\x1B[?1049l");
348
533
  }
349
534
  function onData(key) {
350
535
  if (key.startsWith("\x1B[")) {
351
536
  if (key === "\x1B[C") {
352
537
  selectedTab = (selectedTab + 1) % GROUPS.length;
353
538
  selectedCmd = 0;
354
- render(false);
539
+ render();
355
540
  } else if (key === "\x1B[D") {
356
541
  selectedTab = (selectedTab - 1 + GROUPS.length) % GROUPS.length;
357
542
  selectedCmd = 0;
358
- render(false);
543
+ render();
359
544
  } else if (key === "\x1B[B") {
360
545
  const maxCmd = GROUPS[selectedTab].commands.length - 1;
361
546
  selectedCmd = Math.min(selectedCmd + 1, maxCmd);
362
- render(false);
547
+ render();
363
548
  } else if (key === "\x1B[A") {
364
549
  selectedCmd = Math.max(selectedCmd - 1, 0);
365
- render(false);
550
+ render();
366
551
  }
367
552
  return;
368
553
  }
@@ -370,12 +555,6 @@ ${c.bold}${c.paleLavender}USAGE${c.reset} ${c.lavender}kirograph${c.reset} ${c.
370
555
  cleanup();
371
556
  const cmd = GROUPS[selectedTab].commands[selectedCmd];
372
557
  const fullCmd = `kirograph ${cmd.name}${cmd.args ? " " + cmd.args : ""}`;
373
- process.stdout.write(`\x1B[${prevLineCount}A`);
374
- for (let i = 0; i < prevLineCount; i++) {
375
- process.stdout.write(`${CLEAR_LINE}
376
- `);
377
- }
378
- process.stdout.write(`\x1B[${prevLineCount}A`);
379
558
  console.log(`
380
559
  ${c.green}${c.bold}$${c.reset} ${fullCmd}
381
560
  `);