kirograph 0.14.1 → 0.15.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 (85) hide show
  1. package/README.md +128 -20
  2. package/dist/assets/logo.png +0 -0
  3. package/dist/bin/commands/help.js +3 -0
  4. package/dist/bin/commands/help.js.map +2 -2
  5. package/dist/bin/commands/uninit.js +10 -13
  6. package/dist/bin/commands/uninit.js.map +2 -2
  7. package/dist/bin/installer/config-prompt.js +37 -23
  8. package/dist/bin/installer/config-prompt.js.map +2 -2
  9. package/dist/bin/installer/hooks.js +20 -1
  10. package/dist/bin/installer/hooks.js.map +2 -2
  11. package/dist/bin/installer/index.js +9 -4
  12. package/dist/bin/installer/index.js.map +2 -2
  13. package/dist/bin/installer/prompts.js +37 -6
  14. package/dist/bin/installer/prompts.js.map +2 -2
  15. package/dist/bin/installer/steering.js +19 -0
  16. package/dist/bin/installer/steering.js.map +2 -2
  17. package/dist/bin/installer/targets/aider.js +72 -0
  18. package/dist/bin/installer/targets/aider.js.map +7 -0
  19. package/dist/bin/installer/targets/amp.js +91 -0
  20. package/dist/bin/installer/targets/amp.js.map +7 -0
  21. package/dist/bin/installer/targets/antigravity.js +109 -0
  22. package/dist/bin/installer/targets/antigravity.js.map +7 -0
  23. package/dist/bin/installer/targets/augment.js +81 -0
  24. package/dist/bin/installer/targets/augment.js.map +7 -0
  25. package/dist/bin/installer/targets/claude.js +1 -1
  26. package/dist/bin/installer/targets/claude.js.map +2 -2
  27. package/dist/bin/installer/targets/cline.js +91 -0
  28. package/dist/bin/installer/targets/cline.js.map +7 -0
  29. package/dist/bin/installer/targets/codex.js +1 -1
  30. package/dist/bin/installer/targets/codex.js.map +2 -2
  31. package/dist/bin/installer/targets/continue.js +107 -0
  32. package/dist/bin/installer/targets/continue.js.map +7 -0
  33. package/dist/bin/installer/targets/copilot.js +123 -0
  34. package/dist/bin/installer/targets/copilot.js.map +7 -0
  35. package/dist/bin/installer/targets/cursor.js +143 -0
  36. package/dist/bin/installer/targets/cursor.js.map +7 -0
  37. package/dist/bin/installer/targets/devin.js +148 -0
  38. package/dist/bin/installer/targets/devin.js.map +7 -0
  39. package/dist/bin/installer/targets/gemini-cli.js +126 -0
  40. package/dist/bin/installer/targets/gemini-cli.js.map +7 -0
  41. package/dist/bin/installer/targets/generic.js +120 -0
  42. package/dist/bin/installer/targets/generic.js.map +7 -0
  43. package/dist/bin/installer/targets/goose.js +72 -0
  44. package/dist/bin/installer/targets/goose.js.map +7 -0
  45. package/dist/bin/installer/targets/index.js.map +1 -1
  46. package/dist/bin/installer/targets/junie.js +105 -0
  47. package/dist/bin/installer/targets/junie.js.map +7 -0
  48. package/dist/bin/installer/targets/kilo.js +122 -0
  49. package/dist/bin/installer/targets/kilo.js.map +7 -0
  50. package/dist/bin/installer/targets/kiro.js +3 -3
  51. package/dist/bin/installer/targets/kiro.js.map +2 -2
  52. package/dist/bin/installer/targets/opencode.js +135 -0
  53. package/dist/bin/installer/targets/opencode.js.map +7 -0
  54. package/dist/bin/installer/targets/openhands.js +90 -0
  55. package/dist/bin/installer/targets/openhands.js.map +7 -0
  56. package/dist/bin/installer/targets/replit.js +72 -0
  57. package/dist/bin/installer/targets/replit.js.map +7 -0
  58. package/dist/bin/installer/targets/roo.js +96 -0
  59. package/dist/bin/installer/targets/roo.js.map +7 -0
  60. package/dist/bin/installer/targets/tabnine.js +82 -0
  61. package/dist/bin/installer/targets/tabnine.js.map +7 -0
  62. package/dist/bin/installer/targets/trae.js +84 -0
  63. package/dist/bin/installer/targets/trae.js.map +7 -0
  64. package/dist/bin/installer/targets/warp.js +97 -0
  65. package/dist/bin/installer/targets/warp.js.map +7 -0
  66. package/dist/bin/installer/targets/windsurf.js +141 -0
  67. package/dist/bin/installer/targets/windsurf.js.map +7 -0
  68. package/dist/bin/kirograph.js +3 -1
  69. package/dist/bin/kirograph.js.map +3 -3
  70. package/dist/compression/naive-cost.js +14 -0
  71. package/dist/compression/naive-cost.js.map +2 -2
  72. package/dist/compression/tracker.js +18 -4
  73. package/dist/compression/tracker.js.map +2 -2
  74. package/dist/compression/types.js.map +1 -1
  75. package/dist/config.js +33 -1
  76. package/dist/config.js.map +2 -2
  77. package/dist/db/database.js +17 -0
  78. package/dist/db/database.js.map +2 -2
  79. package/dist/index.js +3 -0
  80. package/dist/index.js.map +2 -2
  81. package/dist/mcp/tool-names.js +5 -1
  82. package/dist/mcp/tool-names.js.map +2 -2
  83. package/dist/mcp/tools.js +232 -3
  84. package/dist/mcp/tools.js.map +2 -2
  85. package/package.json +1 -1
package/README.md CHANGED
@@ -80,6 +80,29 @@ Enable via `kirograph install` or directly in `.kirograph/config.json`:
80
80
 
81
81
  See the [Architecture Analysis](#architecture-analysis-opt-in-1) section below for full details.
82
82
 
83
+ ### Memory (opt-in)
84
+
85
+ When `enableMemory: true` is set, KiroGraph stores persistent observations across sessions — decisions, errors, patterns, and architecture notes. Observations are:
86
+
87
+ - **Compressed** with the caveman grammar (if caveman mode is enabled) — deterministic, no LLM tokens spent
88
+ - **Linked to code symbols** — identifiers in observation text are matched against the graph and stored as stable `qualified_name` references
89
+ - **Embedded** with the configured semantic engine — enabling natural-language search over past observations
90
+ - **Deduplicated** — SHA-256 content hash prevents storing the same observation twice
91
+
92
+ Memory surfaces automatically in `kirograph_context` and `kirograph_impact` results when relevant observations are linked to the symbols being queried. The agent can also search memory directly via `kirograph_mem_search` or store new observations via `kirograph_mem_store`.
93
+
94
+ Zero LLM tokens on write. ~150-350 tokens per search (vs ~2000-5000 tokens to re-discover context by reading files).
95
+
96
+ Enable via `kirograph install` or directly in `.kirograph/config.json`:
97
+
98
+ ```json
99
+ {
100
+ "enableMemory": true
101
+ }
102
+ ```
103
+
104
+ See the [Memory](#memory-requires-enablememory-true) section below for full details.
105
+
83
106
  ## Installation
84
107
 
85
108
  ### From npm (not yet available on npm registry)
@@ -179,7 +202,7 @@ kg install
179
202
  └───────────────────────────────────────────┘
180
203
  ```
181
204
 
182
- Kiro hooks mark the index dirty on every file save or create, then flush on agent idle, batching changes efficiently with no overhead during active editing.
205
+ A single Kiro hook triggers on `agentStop` and asks the agent to sync the index if any source files were changed during the session. No per-file hooks, no background watcher — zero overhead during active editing.
183
206
 
184
207
  ## Using with Kiro
185
208
 
@@ -201,37 +224,36 @@ Registers the KiroGraph MCP server. Used by both the IDE and the CLI agent:
201
224
  "kirograph_status", "kirograph_files", "kirograph_dead_code",
202
225
  "kirograph_circular_deps", "kirograph_path", "kirograph_type_hierarchy",
203
226
  "kirograph_architecture", "kirograph_coupling", "kirograph_package",
204
- "kirograph_hotspots", "kirograph_surprising", "kirograph_diff"
227
+ "kirograph_hotspots", "kirograph_surprising", "kirograph_diff",
228
+ "kirograph_exec", "kirograph_gain"
229
+ "kirograph_mem_search", "kirograph_mem_store",
230
+ "kirograph_mem_timeline", "kirograph_mem_status"
205
231
  ]
206
232
  }
207
233
  }
208
234
  }
209
235
  ```
210
236
 
211
- ### IDE Auto-Sync Hooks (`.kiro/hooks/`)
212
-
213
- Four hooks keep the index fresh automatically in the Kiro IDE:
237
+ ### IDE Hooks (`.kiro/hooks/`)
214
238
 
215
- | Hook | Event | Action |
216
- |------|-------|--------|
217
- | `kirograph-mark-dirty-on-save.json` | `fileEdited` | `kirograph mark-dirty` |
218
- | `kirograph-mark-dirty-on-create.json` | `fileCreated` | `kirograph mark-dirty` |
219
- | `kirograph-sync-on-delete.json` | `fileDeleted` | `kirograph sync-if-dirty` |
220
- | `kirograph-sync-if-dirty.json` | `agentStop` | `kirograph sync-if-dirty --quiet` |
239
+ Up to two hooks are installed (`.kiro.hook` extension):
221
240
 
222
- File changes are batched: saves and creates write a dirty marker; the actual sync runs when the agent stops. Deletes sync immediately. This means no overhead during active editing.
241
+ | Hook file | Event | Type | Behavior |
242
+ |-----------|-------|------|----------|
243
+ | `kirograph-sync-if-dirty.kiro.hook` | `agentStop` | `runCommand` | Runs `kirograph sync --quiet` when the agent stops, syncing any file changes from the session. The sync command skips unchanged files via content hashing, so it's fast even when nothing changed. |
244
+ | `kirograph-compress-hint.kiro.hook` | `preToolUse` (shell) | `askAgent` | Reminds the agent to use `kirograph_exec` for commands that benefit from token compression (git, gh, test, lint, build, docker, aws, grep). Only installed when shell compression is enabled. |
223
245
 
224
- Hooks fire for: `.ts`, `.tsx`, `.js`, `.jsx`, `.py`, `.go`, `.rs`, `.java`, `.cs`, `.rb`, `.php`, `.swift`, `.kt`, `.dart`, `.ex`, `.exs`
246
+ The sync hook replaces the previous per-file approach (mark-dirty-on-save, mark-dirty-on-create, sync-on-delete). A single `agentStop` hook handles all file changes in one pass with zero overhead during active editing.
225
247
 
226
248
  ### CLI Agent Config (`.kiro/agents/kirograph.json`)
227
249
 
228
- A custom agent for Kiro CLI that wires up the MCP server, inlines the steering instructions as a prompt, and handles sync in the CLI's own hook format. The CLI has no file-watch events, so syncing is handled at session boundaries instead:
250
+ A custom agent for Kiro CLI that wires up the MCP server, references the steering file as a resource, and handles sync in the CLI's own hook format. The CLI has no file-watch events, so syncing is handled at session boundaries:
229
251
 
230
- | Hook | Event | Action |
231
- |------|-------|--------|
232
- | `agentSpawn` | Agent starts | `kirograph sync-if-dirty --quiet` (catches edits made between sessions) |
233
- | `userPromptSubmit` | Each prompt | `kirograph sync-if-dirty --quiet` (keeps graph fresh within a session) |
234
- | `stop` | End of each turn | `kirograph sync-if-dirty --quiet` (deferred flush, mirrors IDE `agentStop`) |
252
+ | Event | Action |
253
+ |-------|--------|
254
+ | `agentSpawn` | `kirograph sync-if-dirty --quiet` (catches edits made between sessions) |
255
+ | `userPromptSubmit` | `kirograph sync-if-dirty --quiet` (keeps graph fresh within a session) |
256
+ | `stop` | `kirograph sync-if-dirty --quiet` (deferred flush, mirrors IDE `agentStop`) |
235
257
 
236
258
  Use it with:
237
259
 
@@ -531,6 +553,50 @@ Show token savings statistics from compressed command outputs.
531
553
 
532
554
  Returns total commands, original/compressed token counts, savings percentage, breakdown by command family, and recent command history.
533
555
 
556
+ ### `kirograph_mem_search` *(requires `enableMemory: true`)*
557
+
558
+ Search project memory for past decisions, errors, patterns, and context.
559
+
560
+ | Parameter | Type | Default | Description |
561
+ |-----------|------|---------|-------------|
562
+ | `query` | string | required | Natural language search query |
563
+ | `kind` | string | - | Filter: `decision`, `error`, `pattern`, `architecture`, `summary`, `note` |
564
+ | `limit` | number | 10 | Max results |
565
+ | `sessionId` | string | - | Filter to specific session |
566
+ | `projectPath` | string | cwd | Project root path |
567
+
568
+ **How it works:** Hybrid search combining FTS5 keyword matching and vector cosine similarity (using the configured semantic engine). Results are ranked by a blended score (configurable via `memorySearchAlpha`). Falls back to FTS-only if embeddings are disabled or model mismatch is detected.
569
+
570
+ ### `kirograph_mem_store` *(requires `enableMemory: true`)*
571
+
572
+ Store an observation in project memory. Content is automatically compressed (if caveman mode is on) and linked to relevant code symbols.
573
+
574
+ | Parameter | Type | Default | Description |
575
+ |-----------|------|---------|-------------|
576
+ | `content` | string | required | Observation text |
577
+ | `kind` | string | `note` | `decision`, `error`, `pattern`, `architecture`, `summary`, `note` |
578
+ | `projectPath` | string | cwd | Project root path |
579
+
580
+ **How it works:** Strips `<private>` blocks → applies caveman compression (if enabled) → computes SHA-256 hash for deduplication → stores in `mem_observations` → detects symbol identifiers and creates `mem_links` → embeds with the configured model. Zero LLM tokens consumed.
581
+
582
+ ### `kirograph_mem_timeline` *(requires `enableMemory: true`)*
583
+
584
+ List recent sessions and their observations chronologically.
585
+
586
+ | Parameter | Type | Default | Description |
587
+ |-----------|------|---------|-------------|
588
+ | `limit` | number | 5 | Number of sessions to show |
589
+ | `sessionId` | string | - | Show observations for a specific session |
590
+ | `projectPath` | string | cwd | Project root path |
591
+
592
+ ### `kirograph_mem_status` *(requires `enableMemory: true`)*
593
+
594
+ Memory subsystem health: session count, observations, embedding coverage, model mismatch detection.
595
+
596
+ | Parameter | Type | Default | Description |
597
+ |-----------|------|---------|-------------|
598
+ | `projectPath` | string | cwd | Project root path |
599
+
534
600
  ## CLI Reference
535
601
 
536
602
  ### Setup
@@ -809,6 +875,8 @@ The `kirograph_gain` MCP tool exposes the same stats to the agent.
809
875
  | `kirograph_dead_code` | Not feasible manually (read every file) | 5× output, min 15,000 |
810
876
  | `kirograph_hotspots` | Not feasible manually (count edges for every symbol) | 5× output, min 15,000 |
811
877
  | `kirograph_architecture` | Not feasible manually | 4× output, min 7,500 |
878
+ | `kirograph_mem_search` | Re-read 3-5 files to recall past decisions + grep | ~5,800 tokens |
879
+ | `kirograph_mem_timeline` | Ask user or re-read session history | ~2,300 tokens |
812
880
 
813
881
  Constants used: 1,500 tokens per average source file (~200 lines), 800 tokens per grep result set, 2,000 tokens per directory listing. These are conservative estimates; in practice agents often read more files, retry failed searches, and explore dead ends.
814
882
 
@@ -930,6 +998,46 @@ kirograph path --format json # JSON output
930
998
 
931
999
  The command resolves symbol names using the same fuzzy search as `kirograph query`, preferring real symbol kinds (class, function, method…) over import/file nodes. The result shows each hop with file and line.
932
1000
 
1001
+ ### Memory *(requires `enableMemory: true`)*
1002
+
1003
+ Persistent cross-session observations — search, store, and manage project memory from the CLI.
1004
+
1005
+ ```bash
1006
+ # Search (mirrors kirograph_mem_search)
1007
+ kirograph mem search "payment retry" # hybrid FTS + vector search
1008
+ kirograph mem search "auth bug" --kind error # filter by kind
1009
+ kirograph mem search "refactor" --limit 5 # limit results
1010
+ kirograph mem search "token" --format json # JSON output
1011
+
1012
+ # Store (mirrors kirograph_mem_store)
1013
+ kirograph mem store "decided to use idempotency keys for payments"
1014
+ kirograph mem store "auth bug: token refresh missing" --kind error
1015
+ kirograph mem store --kind decision < decision.txt # pipe from stdin
1016
+
1017
+ # Timeline (mirrors kirograph_mem_timeline)
1018
+ kirograph mem timeline # last 5 sessions
1019
+ kirograph mem timeline --limit 10 # more sessions
1020
+ kirograph mem timeline --session <id> # specific session
1021
+ kirograph mem timeline --format json
1022
+
1023
+ # Status (mirrors kirograph_mem_status)
1024
+ kirograph mem status # health dashboard
1025
+
1026
+ # Maintenance
1027
+ kirograph mem prune --older-than 90d # cleanup old observations
1028
+ kirograph mem export --format jsonl # machine-readable export (importable)
1029
+ kirograph mem export --format md # human-readable export
1030
+ kirograph mem import backup.jsonl # restore from backup (deduplicates)
1031
+ kirograph mem reembed # re-embed after model change
1032
+ kirograph mem reembed --batch 50 # control batch size
1033
+ kirograph mem lint # find stale links, model mismatch
1034
+ kirograph mem lint --fix # auto-repair issues
1035
+ ```
1036
+
1037
+ **How observations are stored:** Text → strip `<private>` blocks → caveman compress (if enabled) → SHA-256 dedup check → store → detect symbol identifiers → link to graph → embed. Zero LLM tokens.
1038
+
1039
+ **How observations surface:** `kirograph_context` and `kirograph_impact` automatically include relevant memory observations (max 3, above relevance threshold 0.3) when memory is enabled. No extra tool call needed.
1040
+
933
1041
  ### Graph Export
934
1042
 
935
1043
  Export the full graph as an interactive dashboard. three files served from a local directory, no server required, works offline.
@@ -1062,7 +1170,7 @@ By default, KiroGraph uses exact name lookup and full-text search. Enable semant
1062
1170
  }
1063
1171
  ```
1064
1172
 
1065
- This generates vector embeddings for all functions, methods, classes, interfaces, type aliases, components, and modules using a local embedding model (downloaded automatically to `~/.kirograph/models/` on first use). Embeddings are kept in sync automatically via Kiro hooks. on every file save, create, or delete.
1173
+ This generates vector embeddings for all functions, methods, classes, interfaces, type aliases, components, and modules using a local embedding model (downloaded automatically to `~/.kirograph/models/` on first use). Embeddings are kept in sync automatically via the Kiro `agentStop` hook, which syncs the index (including embeddings) whenever files change during a session.
1066
1174
 
1067
1175
  Run `kirograph install` to be guided through model and engine selection interactively with arrow-key menus, or set the fields manually in `.kirograph/config.json`.
1068
1176
 
Binary file
@@ -92,6 +92,7 @@ function printColoredHelp() {
92
92
  { name: "compression", args: "[level]", desc: "Set shell compression level (off | normal | aggressive | ultra)" },
93
93
  { name: "exec", args: "<command...>", desc: "Run a shell command with token-optimized output", opts: ["-l, --level <l> normal | aggressive | ultra", "-t, --timeout <s> Timeout in seconds (default 60)", "--raw Show raw + compressed for comparison", "--json Output as JSON"] },
94
94
  { name: "gain", desc: "Show token savings from compressed command outputs", opts: ["--graph ASCII graph (last 30 days)", "--history Recent command history", "--daily Day-by-day breakdown", "--period <p> session | today | week | all"] },
95
+ { name: "mem", args: "<command>", desc: "Persistent memory (search, store, timeline, status, prune, lint, reembed)" },
95
96
  { name: "serve", desc: "Start the MCP server", opts: ["--mcp Run as MCP stdio server", "--path <p> Project path"] },
96
97
  { name: "dashboard", desc: "Manage the Qdrant or Typesense dashboard server", opts: ["start [path] Start server and open dashboard", "stop [path] Stop the running server"] }
97
98
  ]
@@ -193,6 +194,8 @@ ${c.bold}${c.paleLavender}USAGE${c.reset}`);
193
194
  ["kirograph exec --level ultra npm test", "Run tests with ultra compression"],
194
195
  ["kirograph exec --raw cargo build", "Show raw vs compressed comparison"],
195
196
  ["kirograph gain --graph", "Show token savings graph"],
197
+ ['kirograph mem search "auth decision"', "Search memory for past decisions"],
198
+ ['kirograph mem store "use idempotency keys" --kind decision', "Store a decision"],
196
199
  ["kirograph serve --mcp", "Start the MCP server"]
197
200
  ]
198
201
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/bin/commands/help.ts"],
4
- "sourcesContent": ["import { Command } from 'commander';\nimport { printBanner } from '../banner';\n\ntype CommandEntry = { name: string; args?: string; desc: string; opts?: string[] };\ntype Group = { title: string; commands: CommandEntry[] };\n\nexport function printColoredHelp(): void {\n const c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n violet: '\\x1b[38;5;99m',\n purple: '\\x1b[38;5;135m',\n lavender: '\\x1b[38;5;141m',\n paleLavender: '\\x1b[38;5;183m',\n gray: '\\x1b[90m',\n brown: '\\x1b[38;5;130m',\n };\n\n const groups: Group[] = [\n {\n title: '\uD83D\uDD27 Workspace Setup',\n commands: [\n { name: 'install', desc: 'Wire up MCP/instructions for an agent workspace', opts: ['--target <t> kiro | claude | codex'] },\n { name: 'init', args: '[path]', desc: 'Initialize KiroGraph in a project', opts: ['-i, --index Index immediately after init'] },\n { name: 'uninit', args: '[path]', desc: 'Remove KiroGraph from a project', opts: ['--force Skip confirmation', '--target <t> kiro | claude | codex | all'] },\n { name: 'uninstall', args: '[path]', desc: 'Alias for uninit', opts: ['--force Skip confirmation', '--target <t> kiro | claude | codex | all'] },\n ],\n },\n {\n title: '\uD83D\uDCE6 Indexing',\n commands: [\n { name: 'index', args: '[path]', desc: 'Full re-index of a project', opts: ['--force Force re-index all files'] },\n { name: 'sync', args: '[path]', desc: 'Incremental sync of changed files', opts: ['--files <f> Specific files to sync'] },\n { name: 'sync-if-dirty', args: '[path]', desc: 'Sync only if a dirty marker is present', opts: ['-q, --quiet Suppress output'] },\n { name: 'mark-dirty', args: '[path]', desc: 'Write a dirty marker for deferred sync' },\n { name: 'unlock', args: '[path]', desc: 'Force-release a stale lock file' },\n ],\n },\n {\n title: '\uD83D\uDD0D Search & Exploration',\n commands: [\n { name: 'status', args: '[path]', desc: 'Show index statistics and health' },\n { name: 'query', args: '<search>', desc: 'Search for symbols by name', opts: ['--kind <k> Filter by kind', '--limit <n> Max results (default 10)'] },\n { name: 'context', args: '<task>', desc: 'Build relevant code context for a task', opts: ['--max-nodes <n> Max symbols (default 20)', '--no-code Exclude code snippets', '--format <fmt> markdown | json'] },\n { name: 'files', args: '[path]', desc: 'Show project file structure from the index', opts: ['--format <fmt> tree | flat | grouped', '--filter <path> Filter by directory prefix', '--pattern <glob> Filter by glob', '--max-depth <n> Limit tree depth', '--json Output as JSON'] },\n { name: 'path', args: '<from> <to>', desc: 'Find the shortest path between two symbols', opts: ['--format <fmt> table | json'] },\n { name: 'export build', args: '[path]', desc: 'Generate the interactive graph dashboard (.kirograph/export/)', opts: ['-o, --output <dir> Custom output directory', '--include-contains Include structural contains edges'] },\n { name: 'export start', args: '[path]', desc: 'Generate and open the dashboard in the browser', opts: ['-o, --output <dir> Custom output directory', '--include-contains Include structural contains edges'] },\n { name: 'affected', args: '[files...]', desc: 'Find test files affected by changed source files', opts: ['--stdin Read file list from stdin', '-d, --depth <n> Max traversal depth (default 5)', '-f, --filter <g> Custom test file glob', '-j, --json Output as JSON', '-q, --quiet File paths only'] },\n ],\n },\n {\n title: '\uD83D\uDCCA Graph Insights',\n commands: [\n { name: 'hotspots', args: '[path]', desc: 'Find most-connected symbols by edge degree', opts: ['--limit <n> Max results (default 20)', '--format <f> table | json'] },\n { name: 'surprising', args: '[path]', desc: 'Find non-obvious cross-file connections', opts: ['--limit <n> Max results (default 20)', '--format <f> table | json'] },\n { name: 'dead-code', args: '[path]', desc: 'Find unexported symbols with no incoming references', opts: ['--limit <n> Max results (default 50)', '--format <f> table | json'] },\n { name: 'snapshot', desc: 'Save or list graph snapshots for structural diffing', opts: ['save [label] Save current graph state', 'list List saved snapshots', 'diff [label] Diff current graph vs a snapshot --format summary|full|json'] },\n ],\n },\n {\n title: '\uD83C\uDFDB\uFE0F Architecture Analysis',\n commands: [\n { name: 'architecture', args: '[path]', desc: 'Show package graph and layer map', opts: ['--packages Show packages only', '--layers Show layers only', '--format <f> json'] },\n { name: 'coupling', args: '[path]', desc: 'Show coupling metrics per package', opts: ['--sort <s> instability | ca | ce | name', '--package <n> Detail view for one package', '--format <f> json'] },\n { name: 'package', args: '<name>', desc: 'Inspect a package: deps, files, metrics', opts: ['--no-files Omit file list', '--format <f> json'] },\n ],\n },\n {\n title: '\u2699\uFE0F Agent & Configuration',\n commands: [\n { name: 'caveman', args: '[mode]', desc: 'Set agent communication style (off | lite | full | ultra)' },\n { name: 'compression', args: '[level]', desc: 'Set shell compression level (off | normal | aggressive | ultra)' },\n { name: 'exec', args: '<command...>', desc: 'Run a shell command with token-optimized output', opts: ['-l, --level <l> normal | aggressive | ultra', '-t, --timeout <s> Timeout in seconds (default 60)', '--raw Show raw + compressed for comparison', '--json Output as JSON'] },\n { name: 'gain', desc: 'Show token savings from compressed command outputs', opts: ['--graph ASCII graph (last 30 days)', '--history Recent command history', '--daily Day-by-day breakdown', '--period <p> session | today | week | all'] },\n { name: 'serve', desc: 'Start the MCP server', opts: ['--mcp Run as MCP stdio server', '--path <p> Project path'] },\n { name: 'dashboard', desc: 'Manage the Qdrant or Typesense dashboard server', opts: ['start [path] Start server and open dashboard', 'stop [path] Stop the running server'] },\n ],\n },\n ];\n\n console.log(`\\n${c.bold}${c.paleLavender}USAGE${c.reset}`);\n console.log(` ${c.lavender}kirograph${c.reset} ${c.gray}<command>${c.reset} ${c.dim}[options]${c.reset}\\n`);\n\n // Compute max name+args width across ALL groups for alignment\n const allCmds = groups.flatMap(g => g.commands);\n const nameWidth = Math.max(...allCmds.map(cmd => (cmd.name + (cmd.args ? ' ' + cmd.args : '')).length)) + 2;\n\n for (const group of groups) {\n console.log(`${c.bold}${c.paleLavender}${group.title.toUpperCase()}${c.reset}\\n`);\n for (const cmd of group.commands) {\n const signature = cmd.name + (cmd.args ? ' ' + cmd.args : '');\n const isCaveman = cmd.name === 'caveman';\n const nameColor = isCaveman ? c.brown : c.lavender;\n const prefix = isCaveman ? '\uD83E\uDEA8 ' : ' ';\n const namePart = `${nameColor}${cmd.name}${c.reset}${cmd.args ? ' ' + c.dim + cmd.args + c.reset : ''}`;\n const pad = ' '.repeat(Math.max(0, nameWidth - signature.length));\n console.log(`${prefix}${namePart}${pad}${c.gray}${cmd.desc}${c.reset}`);\n if (isCaveman) {\n // desc starts at: emoji prefix (3 display cols: \uD83E\uDEA8 + space) + nameWidth\n const inspiredPad = ' '.repeat(3 + nameWidth);\n console.log(`${inspiredPad}${c.dim}Inspired by Caveman , original idea by github.com/JuliusBrussee/caveman${c.reset}`);\n console.log();\n }\n if (cmd.opts) {\n for (const opt of cmd.opts) {\n const [flag, ...rest] = opt.split(/ +/);\n const optPad = ' '.repeat(nameWidth + 2);\n console.log(` ${optPad}${c.purple}${flag}${c.reset}${rest.length ? ' ' + c.dim + rest.join(' ') + c.reset : ''}`);\n }\n console.log();\n }\n }\n if (!groups[groups.length - 1].commands.includes(group.commands[group.commands.length - 1])) {\n // extra spacing between groups handled by opts blank line; add one if no opts\n const lastHasOpts = group.commands[group.commands.length - 1].opts;\n if (!lastHasOpts) console.log();\n }\n }\n\n console.log(`${c.bold}${c.paleLavender}GLOBAL FLAGS${c.reset}\\n`);\n console.log(` ${c.purple}-h, --help${c.reset} ${c.gray}Show this help${c.reset}`);\n console.log(` ${c.purple}-V, --version${c.reset} ${c.gray}Show version number${c.reset}\\n`);\n\n console.log(`${c.bold}${c.paleLavender}EXAMPLES${c.reset}\\n`);\n\n const exampleGroups: Array<{ title: string; examples: [string, string][] }> = [\n {\n title: '\uD83D\uDD27 Setup & indexing',\n examples: [\n ['kirograph install', 'Wire up Kiro MCP + hooks + steering for the current workspace'],\n ['kirograph install --target claude', 'Wire up Claude Code MCP + project memory'],\n ['kirograph install --target codex', 'Install Codex project instructions and print MCP config'],\n ['kirograph init --index', 'Init and immediately index the project'],\n ['kirograph sync', 'Incremental sync of changed files'],\n ],\n },\n {\n title: '\uD83D\uDD0D Search & exploration',\n examples: [\n ['kirograph query useState', 'Find all symbols named useState'],\n ['kirograph context \"add dark mode\"', 'Get relevant code context for a task'],\n ['kirograph files --format grouped', 'Show files grouped by directory'],\n ['kirograph path LoginController DatabasePool', 'Find how two symbols are connected'],\n ['kirograph affected src/auth.ts', 'Find tests affected by a change'],\n ['git diff --name-only | kirograph affected --stdin', 'Affected tests from a git diff'],\n ['kirograph export start', 'Open the interactive graph dashboard in the browser'],\n ['kirograph export build -o /tmp/graph', 'Export the dashboard to a custom directory'],\n ],\n },\n {\n title: '\uD83D\uDCCA Graph insights',\n examples: [\n ['kirograph hotspots --limit 10', 'Top 10 most-connected symbols'],\n ['kirograph surprising', 'Find unexpected cross-module connections'],\n ['kirograph dead-code', 'Find unreferenced unexported symbols'],\n ['kirograph snapshot save pre-refactor', 'Save a named snapshot before a refactor'],\n ['kirograph snapshot diff pre-refactor', 'Diff current graph vs the named snapshot'],\n ],\n },\n {\n title: '\uD83C\uDFDB\uFE0F Architecture',\n examples: [\n ['kirograph architecture --packages', 'List all detected packages'],\n ['kirograph coupling --sort instability', 'Show packages ranked by instability'],\n ['kirograph package src/auth', 'Inspect the auth package'],\n ],\n },\n {\n title: '\u2699\uFE0F Agent',\n examples: [\n ['kirograph caveman full', 'Enable full caveman mode for the agent'],\n ['kirograph caveman off', 'Disable caveman mode'],\n ['kirograph compression aggressive', 'Set compression to aggressive level'],\n ['kirograph compression off', 'Disable compression hook (tool still available)'],\n ['kirograph exec git status', 'Run git status with compression'],\n ['kirograph exec --level ultra npm test', 'Run tests with ultra compression'],\n ['kirograph exec --raw cargo build', 'Show raw vs compressed comparison'],\n ['kirograph gain --graph', 'Show token savings graph'],\n ['kirograph serve --mcp', 'Start the MCP server'],\n ],\n },\n ];\n\n for (const eg of exampleGroups) {\n console.log(` ${c.dim}${eg.title}${c.reset}`);\n for (const [ex, desc] of eg.examples) {\n console.log(` ${c.violet}$${c.reset} ${c.lavender}${ex}${c.reset}`);\n console.log(` ${c.dim}${desc}${c.reset}`);\n }\n console.log();\n }\n}\n\nexport function register(program: Command): void {\n program.configureHelp({ formatHelp: () => '' });\n program.addHelpText('afterAll', '');\n program.helpInformation = () => {\n printBanner();\n printColoredHelp();\n return '';\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Command } from 'commander';\nimport { printBanner } from '../banner';\n\ntype CommandEntry = { name: string; args?: string; desc: string; opts?: string[] };\ntype Group = { title: string; commands: CommandEntry[] };\n\nexport function printColoredHelp(): void {\n const c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n violet: '\\x1b[38;5;99m',\n purple: '\\x1b[38;5;135m',\n lavender: '\\x1b[38;5;141m',\n paleLavender: '\\x1b[38;5;183m',\n gray: '\\x1b[90m',\n brown: '\\x1b[38;5;130m',\n };\n\n const groups: Group[] = [\n {\n title: '\uD83D\uDD27 Workspace Setup',\n commands: [\n { name: 'install', desc: 'Wire up MCP/instructions for an agent workspace', opts: ['--target <t> kiro | claude | codex'] },\n { name: 'init', args: '[path]', desc: 'Initialize KiroGraph in a project', opts: ['-i, --index Index immediately after init'] },\n { name: 'uninit', args: '[path]', desc: 'Remove KiroGraph from a project', opts: ['--force Skip confirmation', '--target <t> kiro | claude | codex | all'] },\n { name: 'uninstall', args: '[path]', desc: 'Alias for uninit', opts: ['--force Skip confirmation', '--target <t> kiro | claude | codex | all'] },\n ],\n },\n {\n title: '\uD83D\uDCE6 Indexing',\n commands: [\n { name: 'index', args: '[path]', desc: 'Full re-index of a project', opts: ['--force Force re-index all files'] },\n { name: 'sync', args: '[path]', desc: 'Incremental sync of changed files', opts: ['--files <f> Specific files to sync'] },\n { name: 'sync-if-dirty', args: '[path]', desc: 'Sync only if a dirty marker is present', opts: ['-q, --quiet Suppress output'] },\n { name: 'mark-dirty', args: '[path]', desc: 'Write a dirty marker for deferred sync' },\n { name: 'unlock', args: '[path]', desc: 'Force-release a stale lock file' },\n ],\n },\n {\n title: '\uD83D\uDD0D Search & Exploration',\n commands: [\n { name: 'status', args: '[path]', desc: 'Show index statistics and health' },\n { name: 'query', args: '<search>', desc: 'Search for symbols by name', opts: ['--kind <k> Filter by kind', '--limit <n> Max results (default 10)'] },\n { name: 'context', args: '<task>', desc: 'Build relevant code context for a task', opts: ['--max-nodes <n> Max symbols (default 20)', '--no-code Exclude code snippets', '--format <fmt> markdown | json'] },\n { name: 'files', args: '[path]', desc: 'Show project file structure from the index', opts: ['--format <fmt> tree | flat | grouped', '--filter <path> Filter by directory prefix', '--pattern <glob> Filter by glob', '--max-depth <n> Limit tree depth', '--json Output as JSON'] },\n { name: 'path', args: '<from> <to>', desc: 'Find the shortest path between two symbols', opts: ['--format <fmt> table | json'] },\n { name: 'export build', args: '[path]', desc: 'Generate the interactive graph dashboard (.kirograph/export/)', opts: ['-o, --output <dir> Custom output directory', '--include-contains Include structural contains edges'] },\n { name: 'export start', args: '[path]', desc: 'Generate and open the dashboard in the browser', opts: ['-o, --output <dir> Custom output directory', '--include-contains Include structural contains edges'] },\n { name: 'affected', args: '[files...]', desc: 'Find test files affected by changed source files', opts: ['--stdin Read file list from stdin', '-d, --depth <n> Max traversal depth (default 5)', '-f, --filter <g> Custom test file glob', '-j, --json Output as JSON', '-q, --quiet File paths only'] },\n ],\n },\n {\n title: '\uD83D\uDCCA Graph Insights',\n commands: [\n { name: 'hotspots', args: '[path]', desc: 'Find most-connected symbols by edge degree', opts: ['--limit <n> Max results (default 20)', '--format <f> table | json'] },\n { name: 'surprising', args: '[path]', desc: 'Find non-obvious cross-file connections', opts: ['--limit <n> Max results (default 20)', '--format <f> table | json'] },\n { name: 'dead-code', args: '[path]', desc: 'Find unexported symbols with no incoming references', opts: ['--limit <n> Max results (default 50)', '--format <f> table | json'] },\n { name: 'snapshot', desc: 'Save or list graph snapshots for structural diffing', opts: ['save [label] Save current graph state', 'list List saved snapshots', 'diff [label] Diff current graph vs a snapshot --format summary|full|json'] },\n ],\n },\n {\n title: '\uD83C\uDFDB\uFE0F Architecture Analysis',\n commands: [\n { name: 'architecture', args: '[path]', desc: 'Show package graph and layer map', opts: ['--packages Show packages only', '--layers Show layers only', '--format <f> json'] },\n { name: 'coupling', args: '[path]', desc: 'Show coupling metrics per package', opts: ['--sort <s> instability | ca | ce | name', '--package <n> Detail view for one package', '--format <f> json'] },\n { name: 'package', args: '<name>', desc: 'Inspect a package: deps, files, metrics', opts: ['--no-files Omit file list', '--format <f> json'] },\n ],\n },\n {\n title: '\u2699\uFE0F Agent & Configuration',\n commands: [\n { name: 'caveman', args: '[mode]', desc: 'Set agent communication style (off | lite | full | ultra)' },\n { name: 'compression', args: '[level]', desc: 'Set shell compression level (off | normal | aggressive | ultra)' },\n { name: 'exec', args: '<command...>', desc: 'Run a shell command with token-optimized output', opts: ['-l, --level <l> normal | aggressive | ultra', '-t, --timeout <s> Timeout in seconds (default 60)', '--raw Show raw + compressed for comparison', '--json Output as JSON'] },\n { name: 'gain', desc: 'Show token savings from compressed command outputs', opts: ['--graph ASCII graph (last 30 days)', '--history Recent command history', '--daily Day-by-day breakdown', '--period <p> session | today | week | all'] },\n { name: 'mem', args: '<command>', desc: 'Persistent memory (search, store, timeline, status, prune, lint, reembed)' },\n { name: 'serve', desc: 'Start the MCP server', opts: ['--mcp Run as MCP stdio server', '--path <p> Project path'] },\n { name: 'dashboard', desc: 'Manage the Qdrant or Typesense dashboard server', opts: ['start [path] Start server and open dashboard', 'stop [path] Stop the running server'] },\n ],\n },\n ];\n\n console.log(`\\n${c.bold}${c.paleLavender}USAGE${c.reset}`);\n console.log(` ${c.lavender}kirograph${c.reset} ${c.gray}<command>${c.reset} ${c.dim}[options]${c.reset}\\n`);\n\n // Compute max name+args width across ALL groups for alignment\n const allCmds = groups.flatMap(g => g.commands);\n const nameWidth = Math.max(...allCmds.map(cmd => (cmd.name + (cmd.args ? ' ' + cmd.args : '')).length)) + 2;\n\n for (const group of groups) {\n console.log(`${c.bold}${c.paleLavender}${group.title.toUpperCase()}${c.reset}\\n`);\n for (const cmd of group.commands) {\n const signature = cmd.name + (cmd.args ? ' ' + cmd.args : '');\n const isCaveman = cmd.name === 'caveman';\n const nameColor = isCaveman ? c.brown : c.lavender;\n const prefix = isCaveman ? '\uD83E\uDEA8 ' : ' ';\n const namePart = `${nameColor}${cmd.name}${c.reset}${cmd.args ? ' ' + c.dim + cmd.args + c.reset : ''}`;\n const pad = ' '.repeat(Math.max(0, nameWidth - signature.length));\n console.log(`${prefix}${namePart}${pad}${c.gray}${cmd.desc}${c.reset}`);\n if (isCaveman) {\n // desc starts at: emoji prefix (3 display cols: \uD83E\uDEA8 + space) + nameWidth\n const inspiredPad = ' '.repeat(3 + nameWidth);\n console.log(`${inspiredPad}${c.dim}Inspired by Caveman , original idea by github.com/JuliusBrussee/caveman${c.reset}`);\n console.log();\n }\n if (cmd.opts) {\n for (const opt of cmd.opts) {\n const [flag, ...rest] = opt.split(/ +/);\n const optPad = ' '.repeat(nameWidth + 2);\n console.log(` ${optPad}${c.purple}${flag}${c.reset}${rest.length ? ' ' + c.dim + rest.join(' ') + c.reset : ''}`);\n }\n console.log();\n }\n }\n if (!groups[groups.length - 1].commands.includes(group.commands[group.commands.length - 1])) {\n // extra spacing between groups handled by opts blank line; add one if no opts\n const lastHasOpts = group.commands[group.commands.length - 1].opts;\n if (!lastHasOpts) console.log();\n }\n }\n\n console.log(`${c.bold}${c.paleLavender}GLOBAL FLAGS${c.reset}\\n`);\n console.log(` ${c.purple}-h, --help${c.reset} ${c.gray}Show this help${c.reset}`);\n console.log(` ${c.purple}-V, --version${c.reset} ${c.gray}Show version number${c.reset}\\n`);\n\n console.log(`${c.bold}${c.paleLavender}EXAMPLES${c.reset}\\n`);\n\n const exampleGroups: Array<{ title: string; examples: [string, string][] }> = [\n {\n title: '\uD83D\uDD27 Setup & indexing',\n examples: [\n ['kirograph install', 'Wire up Kiro MCP + hooks + steering for the current workspace'],\n ['kirograph install --target claude', 'Wire up Claude Code MCP + project memory'],\n ['kirograph install --target codex', 'Install Codex project instructions and print MCP config'],\n ['kirograph init --index', 'Init and immediately index the project'],\n ['kirograph sync', 'Incremental sync of changed files'],\n ],\n },\n {\n title: '\uD83D\uDD0D Search & exploration',\n examples: [\n ['kirograph query useState', 'Find all symbols named useState'],\n ['kirograph context \"add dark mode\"', 'Get relevant code context for a task'],\n ['kirograph files --format grouped', 'Show files grouped by directory'],\n ['kirograph path LoginController DatabasePool', 'Find how two symbols are connected'],\n ['kirograph affected src/auth.ts', 'Find tests affected by a change'],\n ['git diff --name-only | kirograph affected --stdin', 'Affected tests from a git diff'],\n ['kirograph export start', 'Open the interactive graph dashboard in the browser'],\n ['kirograph export build -o /tmp/graph', 'Export the dashboard to a custom directory'],\n ],\n },\n {\n title: '\uD83D\uDCCA Graph insights',\n examples: [\n ['kirograph hotspots --limit 10', 'Top 10 most-connected symbols'],\n ['kirograph surprising', 'Find unexpected cross-module connections'],\n ['kirograph dead-code', 'Find unreferenced unexported symbols'],\n ['kirograph snapshot save pre-refactor', 'Save a named snapshot before a refactor'],\n ['kirograph snapshot diff pre-refactor', 'Diff current graph vs the named snapshot'],\n ],\n },\n {\n title: '\uD83C\uDFDB\uFE0F Architecture',\n examples: [\n ['kirograph architecture --packages', 'List all detected packages'],\n ['kirograph coupling --sort instability', 'Show packages ranked by instability'],\n ['kirograph package src/auth', 'Inspect the auth package'],\n ],\n },\n {\n title: '\u2699\uFE0F Agent',\n examples: [\n ['kirograph caveman full', 'Enable full caveman mode for the agent'],\n ['kirograph caveman off', 'Disable caveman mode'],\n ['kirograph compression aggressive', 'Set compression to aggressive level'],\n ['kirograph compression off', 'Disable compression hook (tool still available)'],\n ['kirograph exec git status', 'Run git status with compression'],\n ['kirograph exec --level ultra npm test', 'Run tests with ultra compression'],\n ['kirograph exec --raw cargo build', 'Show raw vs compressed comparison'],\n ['kirograph gain --graph', 'Show token savings graph'],\n ['kirograph mem search \"auth decision\"', 'Search memory for past decisions'],\n ['kirograph mem store \"use idempotency keys\" --kind decision', 'Store a decision'],\n ['kirograph serve --mcp', 'Start the MCP server'],\n ],\n },\n ];\n\n for (const eg of exampleGroups) {\n console.log(` ${c.dim}${eg.title}${c.reset}`);\n for (const [ex, desc] of eg.examples) {\n console.log(` ${c.violet}$${c.reset} ${c.lavender}${ex}${c.reset}`);\n console.log(` ${c.dim}${desc}${c.reset}`);\n }\n console.log();\n }\n}\n\nexport function register(program: Command): void {\n program.configureHelp({ formatHelp: () => '' });\n program.addHelpText('afterAll', '');\n program.helpInformation = () => {\n printBanner();\n printColoredHelp();\n return '';\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -34,8 +34,10 @@ __export(uninit_exports, {
34
34
  module.exports = __toCommonJS(uninit_exports);
35
35
  var path = __toESM(require("path"));
36
36
  var fs = __toESM(require("fs"));
37
+ var readline = __toESM(require("readline"));
37
38
  var import_banner = require("../banner");
38
39
  var import_ui = require("../ui");
40
+ var import_prompts = require("../installer/prompts");
39
41
  const UNINIT_FAREWELLS = [
40
42
  "Oh. So it's come to this.",
41
43
  "We're sorry to see you go. (Are we? Yes. We are.)",
@@ -49,14 +51,6 @@ const UNINIT_FAREWELLS = [
49
51
  "See you on the other side of `kirograph install`."
50
52
  ];
51
53
  const UNINIT_TARGETS = ["kiro", "claude", "codex", "all"];
52
- async function confirm(question) {
53
- const readline = await import("readline");
54
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
55
- return new Promise((resolve) => rl.question(question, (ans) => {
56
- rl.close();
57
- resolve(ans.toLowerCase() === "y");
58
- }));
59
- }
60
54
  async function runUninit(projectPath, opts) {
61
55
  const target = path.resolve(projectPath ?? process.cwd());
62
56
  const integration = (opts.target ?? "kiro").toLowerCase();
@@ -77,10 +71,11 @@ async function runUninit(projectPath, opts) {
77
71
  console.log(` ${import_ui.violet}${import_ui.bold}${farewell}${import_ui.reset}`);
78
72
  console.log(`
79
73
  ${import_ui.dim}This can remove ${integration} integration files and, separately, the shared .kirograph/ data.${import_ui.reset}`);
80
- console.log(` ${import_ui.dim}Your source code is untouched.${import_ui.reset}
81
- `);
82
- removeIntegration = await confirm(` ${import_ui.violet}Remove ${integration} integration files?${import_ui.reset} ${import_ui.dim}(y/N)${import_ui.reset} `);
83
- removeGraph = await confirm(` ${import_ui.violet}Remove shared .kirograph/ data too?${import_ui.reset} ${import_ui.dim}(y/N)${import_ui.reset} `);
74
+ console.log(` ${import_ui.dim}Your source code is untouched.${import_ui.reset}`);
75
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
76
+ removeIntegration = await (0, import_prompts.askToggle)(rl, `Remove ${integration} integration files?`, "Removes hooks, steering, MCP config, and agent instructions for this target.", false);
77
+ removeGraph = await (0, import_prompts.askToggle)(rl, "Remove shared .kirograph/ data too?", "Deletes the graph database, snapshots, and all indexed data. Cannot be undone.", false);
78
+ rl.close();
84
79
  if (!removeIntegration && !removeGraph) {
85
80
  console.log(`
86
81
  ${import_ui.dim}Cancelled. Nothing removed.${import_ui.reset}
@@ -100,6 +95,7 @@ async function runUninit(projectPath, opts) {
100
95
  "kirograph-sync-on-delete.kiro.hook",
101
96
  "kirograph-sync-if-dirty.kiro.hook",
102
97
  "kirograph-compress-hint.kiro.hook",
98
+ "kirograph-mem-capture.kiro.hook",
103
99
  // Legacy .json filenames
104
100
  "kirograph-mark-dirty-on-save.json",
105
101
  "kirograph-mark-dirty-on-create.json",
@@ -107,7 +103,8 @@ async function runUninit(projectPath, opts) {
107
103
  "kirograph-sync-if-dirty.json",
108
104
  "kirograph-sync-on-save.json",
109
105
  "kirograph-sync-on-create.json",
110
- "kirograph-compress-hint.json"
106
+ "kirograph-compress-hint.json",
107
+ "kirograph-mem-capture.json"
111
108
  ];
112
109
  const hooksDir = path.join(target, ".kiro", "hooks");
113
110
  let removedHooks = 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/bin/commands/uninit.ts"],
4
- "sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\ntype UninitTarget = 'kiro' | 'claude' | 'codex' | 'all';\n\nconst UNINIT_TARGETS: UninitTarget[] = ['kiro', 'claude', 'codex', 'all'];\n\nasync function confirm(question: string): Promise<boolean> {\n const readline = await import('readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n return new Promise<boolean>(resolve => rl.question(question, ans => {\n rl.close();\n resolve(ans.toLowerCase() === 'y');\n }));\n}\n\nasync function runUninit(projectPath: string | undefined, opts: { force?: boolean; target?: string }): Promise<void> {\n const target = path.resolve(projectPath ?? process.cwd());\n const integration = (opts.target ?? 'kiro').toLowerCase() as UninitTarget;\n if (!UNINIT_TARGETS.includes(integration)) {\n console.error(`Unknown uninit target: ${opts.target}. Choose from: kiro, claude, codex, all`);\n process.exit(1);\n }\n const dir = path.join(target, '.kirograph');\n if (!fs.existsSync(dir)) { console.log('Not initialized.'); return; }\n\n let removeIntegration = true;\n let removeGraph = opts.force === true;\n\n if (!opts.force) {\n printBanner();\n const farewell = UNINIT_FAREWELLS[Math.floor(Math.random() * UNINIT_FAREWELLS.length)]!;\n console.log(` ${violet}${bold}${farewell}${reset}`);\n console.log(`\\n ${dim}This can remove ${integration} integration files and, separately, the shared .kirograph/ data.${reset}`);\n console.log(` ${dim}Your source code is untouched.${reset}\\n`);\n\n removeIntegration = await confirm(` ${violet}Remove ${integration} integration files?${reset} ${dim}(y/N)${reset} `);\n removeGraph = await confirm(` ${violet}Remove shared .kirograph/ data too?${reset} ${dim}(y/N)${reset} `);\n\n if (!removeIntegration && !removeGraph) {\n console.log(`\\n ${dim}Cancelled. Nothing removed.${reset}\\n`);\n return;\n }\n console.log();\n }\n\n if (removeGraph) {\n fs.rmSync(dir, { recursive: true, force: true });\n console.log(` ${green}\u2713${reset} Removed .kirograph/`);\n }\n\n if (removeIntegration && (integration === 'kiro' || integration === 'all')) {\n // Remove .kiro hooks created by kirograph\n const kiroHooks = [\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n 'kirograph-sync-if-dirty.kiro.hook',\n 'kirograph-compress-hint.kiro.hook',\n // Legacy .json filenames\n 'kirograph-mark-dirty-on-save.json',\n 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-sync-if-dirty.json',\n 'kirograph-sync-on-save.json',\n 'kirograph-sync-on-create.json',\n 'kirograph-compress-hint.json',\n ];\n const hooksDir = path.join(target, '.kiro', 'hooks');\n let removedHooks = 0;\n for (const hook of kiroHooks) {\n const p = path.join(hooksDir, hook);\n if (fs.existsSync(p)) { fs.unlinkSync(p); removedHooks++; }\n }\n if (removedHooks > 0) console.log(` ${green}\u2713${reset} Removed ${removedHooks} hook(s) from .kiro/hooks/`);\n\n // Remove .kiro/steering/kirograph.md\n const steeringPath = path.join(target, '.kiro', 'steering', 'kirograph.md');\n if (fs.existsSync(steeringPath)) {\n fs.unlinkSync(steeringPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/steering/kirograph.md`);\n }\n\n // Remove .kiro/agents/kirograph.json\n const agentPath = path.join(target, '.kiro', 'agents', 'kirograph.json');\n if (fs.existsSync(agentPath)) {\n fs.unlinkSync(agentPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/agents/kirograph.json`);\n }\n\n // Remove kirograph server from .kiro/settings/mcp.json\n const { removeMcpServersConfig } = await Promise.resolve().then(() => require('../installer/common.js'));\n const mcpPath = path.join(target, '.kiro', 'settings', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` ${green}\u2713${reset} Removed kirograph from .kiro/settings/mcp.json`);\n }\n }\n\n if (removeIntegration && (integration === 'claude' || integration === 'all')) {\n const { uninitClaude } = await Promise.resolve().then(() => require('../installer/targets/claude.js'));\n uninitClaude(target);\n }\n\n if (removeIntegration && (integration === 'codex' || integration === 'all')) {\n const { uninitCodex } = await Promise.resolve().then(() => require('../installer/targets/codex.js'));\n uninitCodex(target);\n }\n\n console.log(`\\n ${dim}Done. Run ${violet}kirograph install --target ${integration === 'all' ? 'kiro' : integration}${reset}${dim} to come back anytime.${reset}\\n`);\n}\n\nexport function register(program: Command): void {\n program\n .command('uninit [projectPath]')\n .description('Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n\n program\n .command('uninstall [projectPath]')\n .description('Alias for uninit. Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\nimport { askToggle } from '../installer/prompts';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\ntype UninitTarget = 'kiro' | 'claude' | 'codex' | 'all';\n\nconst UNINIT_TARGETS: UninitTarget[] = ['kiro', 'claude', 'codex', 'all'];\n\nasync function runUninit(projectPath: string | undefined, opts: { force?: boolean; target?: string }): Promise<void> {\n const target = path.resolve(projectPath ?? process.cwd());\n const integration = (opts.target ?? 'kiro').toLowerCase() as UninitTarget;\n if (!UNINIT_TARGETS.includes(integration)) {\n console.error(`Unknown uninit target: ${opts.target}. Choose from: kiro, claude, codex, all`);\n process.exit(1);\n }\n const dir = path.join(target, '.kirograph');\n if (!fs.existsSync(dir)) { console.log('Not initialized.'); return; }\n\n let removeIntegration = true;\n let removeGraph = opts.force === true;\n\n if (!opts.force) {\n printBanner();\n const farewell = UNINIT_FAREWELLS[Math.floor(Math.random() * UNINIT_FAREWELLS.length)]!;\n console.log(` ${violet}${bold}${farewell}${reset}`);\n console.log(`\\n ${dim}This can remove ${integration} integration files and, separately, the shared .kirograph/ data.${reset}`);\n console.log(` ${dim}Your source code is untouched.${reset}`);\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n removeIntegration = await askToggle(rl, `Remove ${integration} integration files?`, 'Removes hooks, steering, MCP config, and agent instructions for this target.', false);\n removeGraph = await askToggle(rl, 'Remove shared .kirograph/ data too?', 'Deletes the graph database, snapshots, and all indexed data. Cannot be undone.', false);\n\n rl.close();\n\n if (!removeIntegration && !removeGraph) {\n console.log(`\\n ${dim}Cancelled. Nothing removed.${reset}\\n`);\n return;\n }\n console.log();\n }\n\n if (removeGraph) {\n fs.rmSync(dir, { recursive: true, force: true });\n console.log(` ${green}\u2713${reset} Removed .kirograph/`);\n }\n\n if (removeIntegration && (integration === 'kiro' || integration === 'all')) {\n // Remove .kiro hooks created by kirograph\n const kiroHooks = [\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n 'kirograph-sync-if-dirty.kiro.hook',\n 'kirograph-compress-hint.kiro.hook',\n 'kirograph-mem-capture.kiro.hook',\n // Legacy .json filenames\n 'kirograph-mark-dirty-on-save.json',\n 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-sync-if-dirty.json',\n 'kirograph-sync-on-save.json',\n 'kirograph-sync-on-create.json',\n 'kirograph-compress-hint.json',\n 'kirograph-mem-capture.json',\n ];\n const hooksDir = path.join(target, '.kiro', 'hooks');\n let removedHooks = 0;\n for (const hook of kiroHooks) {\n const p = path.join(hooksDir, hook);\n if (fs.existsSync(p)) { fs.unlinkSync(p); removedHooks++; }\n }\n if (removedHooks > 0) console.log(` ${green}\u2713${reset} Removed ${removedHooks} hook(s) from .kiro/hooks/`);\n\n // Remove .kiro/steering/kirograph.md\n const steeringPath = path.join(target, '.kiro', 'steering', 'kirograph.md');\n if (fs.existsSync(steeringPath)) {\n fs.unlinkSync(steeringPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/steering/kirograph.md`);\n }\n\n // Remove .kiro/agents/kirograph.json\n const agentPath = path.join(target, '.kiro', 'agents', 'kirograph.json');\n if (fs.existsSync(agentPath)) {\n fs.unlinkSync(agentPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/agents/kirograph.json`);\n }\n\n // Remove kirograph server from .kiro/settings/mcp.json\n const { removeMcpServersConfig } = await Promise.resolve().then(() => require('../installer/common.js'));\n const mcpPath = path.join(target, '.kiro', 'settings', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` ${green}\u2713${reset} Removed kirograph from .kiro/settings/mcp.json`);\n }\n }\n\n if (removeIntegration && (integration === 'claude' || integration === 'all')) {\n const { uninitClaude } = await Promise.resolve().then(() => require('../installer/targets/claude.js'));\n uninitClaude(target);\n }\n\n if (removeIntegration && (integration === 'codex' || integration === 'all')) {\n const { uninitCodex } = await Promise.resolve().then(() => require('../installer/targets/codex.js'));\n uninitCodex(target);\n }\n\n console.log(`\\n ${dim}Done. Run ${violet}kirograph install --target ${integration === 'all' ? 'kiro' : integration}${reset}${dim} to come back anytime.${reset}\\n`);\n}\n\nexport function register(program: Command): void {\n program\n .command('uninit [projectPath]')\n .description('Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n\n program\n .command('uninstall [projectPath]')\n .description('Alias for uninit. Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', 'Integration target to clean up: kiro, claude, codex, or all', 'kiro')\n .action(runUninit);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -57,16 +57,17 @@ const PRESET_MODELS = [
57
57
  }
58
58
  ];
59
59
  async function promptConfigOptions(rl) {
60
- const enableEmbeddings = await (0, import_prompts.askBool)(
60
+ (0, import_prompts.printSection)("\u{1F50D}", "Semantic Search");
61
+ const enableEmbeddings = await (0, import_prompts.askToggle)(
61
62
  rl,
62
- "Enable semantic embeddings for similarity search? (requires a local embedding model)",
63
- "Enables semantic/similarity-based code search. Increases indexing time; the chosen embedding model is downloaded automatically on first use."
63
+ "Semantic embeddings (similarity search):",
64
+ "Enables natural-language code search via vector embeddings. A local model (~130MB) is downloaded on first use."
64
65
  );
65
- const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal" };
66
+ const patch = { enableEmbeddings, useVecIndex: false, semanticEngine: "cosine", typesenseDashboard: false, qdrantDashboard: false, extractDocstrings: true, trackCallSites: true, enableArchitecture: false, cavemanMode: "off", shellCompressionLevel: "normal", enableMemory: false };
66
67
  if (enableEmbeddings) {
67
68
  const modelChoice = await (0, import_prompts.arrowSelect)(
68
69
  rl,
69
- "Choose an embedding model:",
70
+ "Embedding model:",
70
71
  PRESET_MODELS.map((m) => ({ value: m.value, label: m.label, description: m.description }))
71
72
  );
72
73
  let embeddingModel;
@@ -100,7 +101,7 @@ async function promptConfigOptions(rl) {
100
101
  }
101
102
  patch.embeddingModel = embeddingModel;
102
103
  patch.embeddingDim = embeddingDim;
103
- const semanticEngine = await (0, import_prompts.arrowSelect)(rl, "Choose the semantic search engine:", [
104
+ const semanticEngine = await (0, import_prompts.arrowSelect)(rl, "Vector search engine:", [
104
105
  { value: "cosine", label: "cosine", description: "In-process cosine similarity. No extra deps. Best for small/medium projects." },
105
106
  { value: "sqlite-vec", label: "sqlite-vec", description: "ANN index. Sub-linear search. Best for large codebases. Needs: better-sqlite3, sqlite-vec (native)." },
106
107
  { value: "orama", label: "orama", description: "Hybrid search (full-text + vector). Pure JS. Needs: @orama/orama, @orama/plugin-data-persistence." },
@@ -112,49 +113,62 @@ async function promptConfigOptions(rl) {
112
113
  patch.semanticEngine = semanticEngine;
113
114
  patch.useVecIndex = semanticEngine === "sqlite-vec";
114
115
  if (semanticEngine === "typesense") {
115
- patch.typesenseDashboard = await (0, import_prompts.askBool)(
116
+ patch.typesenseDashboard = await (0, import_prompts.askToggle)(
116
117
  rl,
117
- "Open Typesense dashboard after indexing?",
118
- "Serves the Typesense Dashboard locally and opens it in your browser after indexing completes."
118
+ "Typesense dashboard:",
119
+ "Serves the Typesense Dashboard locally and opens it in your browser after indexing completes.",
120
+ false
119
121
  );
120
122
  }
121
123
  if (semanticEngine === "qdrant") {
122
- patch.qdrantDashboard = await (0, import_prompts.askBool)(
124
+ patch.qdrantDashboard = await (0, import_prompts.askToggle)(
123
125
  rl,
124
- "Open Qdrant dashboard after indexing?",
125
- "Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes."
126
+ "Qdrant dashboard:",
127
+ "Downloads the Qdrant Web UI (first time only) and opens it in your browser after indexing completes.",
128
+ false
126
129
  );
127
130
  }
128
131
  }
129
- patch.extractDocstrings = await (0, import_prompts.askBool)(
132
+ (0, import_prompts.printSection)("\u{1F4CA}", "Graph Features");
133
+ patch.extractDocstrings = await (0, import_prompts.askToggle)(
130
134
  rl,
131
- "Extract docstrings from source files?",
135
+ "Docstring extraction:",
132
136
  "Enriches symbol metadata and improves context quality. Slightly increases indexing time."
133
137
  );
134
- patch.trackCallSites = await (0, import_prompts.askBool)(
138
+ patch.trackCallSites = await (0, import_prompts.askToggle)(
135
139
  rl,
136
- "Track call sites to enable caller/callee graph traversal?",
137
- "Enables the kirograph_callers and kirograph_callees MCP tools for graph traversal. Increases index size."
140
+ "Call site tracking (caller/callee graph):",
141
+ "Enables kirograph_callers and kirograph_callees MCP tools. Increases index size."
138
142
  );
139
- patch.enableArchitecture = await (0, import_prompts.askBool)(
143
+ patch.enableArchitecture = await (0, import_prompts.askToggle)(
140
144
  rl,
141
- "Enable architecture analysis (package graph + layer detection)?",
142
- "Detects packages from manifests (package.json, go.mod, Cargo.toml, etc.) and architectural layers (api, service, data, ui, shared) from file structure. Enables kirograph_architecture, kirograph_coupling, and kirograph_package MCP tools."
145
+ "Architecture analysis (packages + layers):",
146
+ "Detects packages from manifests and architectural layers. Enables kirograph_architecture, kirograph_coupling, kirograph_package.",
147
+ false
143
148
  );
144
- const cavemanChoice = await (0, import_prompts.arrowSelect)(rl, "Caveman mode: agent communication style:", [
145
- { value: "off", label: "off", description: "Normal responses" },
149
+ (0, import_prompts.printSection)("\u{1F916}", "Agent Behavior");
150
+ const cavemanChoice = await (0, import_prompts.arrowSelect)(rl, "Communication style (caveman mode):", [
151
+ { value: "off", label: "off", description: "Normal responses \u2014 no compression" },
146
152
  { value: "lite", label: "lite", description: "Compact, no filler, full sentences" },
147
153
  { value: "full", label: "full", description: "Fragments, no articles, short synonyms" },
148
154
  { value: "ultra", label: "ultra", description: "Max compression, abbreviations, \u2192 for causality" }
149
155
  ]);
150
156
  patch.cavemanMode = cavemanChoice;
151
- const compressionChoice = await (0, import_prompts.arrowSelect)(rl, "Shell compression: default level for kirograph_exec:", [
157
+ const compressionChoice = await (0, import_prompts.arrowSelect)(rl, "Shell compression (kirograph_exec default level):", [
152
158
  { value: "off", label: "off", description: "No compression hook or steering (tool still available)" },
153
159
  { value: "normal", label: "normal", description: "Balanced: removes noise, keeps structure (recommended)" },
154
160
  { value: "aggressive", label: "aggressive", description: "More compact: groups by category, limits output" },
155
161
  { value: "ultra", label: "ultra", description: "Maximum compression: counts and summaries only" }
156
162
  ]);
157
163
  patch.shellCompressionLevel = compressionChoice;
164
+ (0, import_prompts.printSection)("\u{1F9E0}", "Memory");
165
+ patch.enableMemory = await (0, import_prompts.askToggle)(
166
+ rl,
167
+ "Persistent memory (cross-session observations):",
168
+ "Stores decisions, errors, and patterns across sessions. Compressed (if caveman is on), linked to code symbols, searchable via kirograph_mem_* tools. Zero LLM tokens on write.",
169
+ false
170
+ // Requires explicit enable
171
+ );
158
172
  return patch;
159
173
  }
160
174
  // Annotate the CommonJS export names for ESM import in node: