@stupidloud/codegraph 0.7.14 → 0.7.20

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 (136) hide show
  1. package/README.md +44 -10
  2. package/README.zh-CN.md +3 -8
  3. package/dist/bin/codegraph.js +102 -24
  4. package/dist/bin/codegraph.js.map +1 -1
  5. package/dist/bin/node-version-check.d.ts +3 -0
  6. package/dist/bin/node-version-check.d.ts.map +1 -1
  7. package/dist/bin/node-version-check.js +5 -2
  8. package/dist/bin/node-version-check.js.map +1 -1
  9. package/dist/bin/uninstall.d.ts +7 -7
  10. package/dist/bin/uninstall.d.ts.map +1 -1
  11. package/dist/bin/uninstall.js +23 -135
  12. package/dist/bin/uninstall.js.map +1 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +0 -2
  15. package/dist/config.js.map +1 -1
  16. package/dist/context/index.d.ts.map +1 -1
  17. package/dist/context/index.js +4 -2
  18. package/dist/context/index.js.map +1 -1
  19. package/dist/db/migrations.d.ts +1 -1
  20. package/dist/db/migrations.d.ts.map +1 -1
  21. package/dist/db/migrations.js +22 -8
  22. package/dist/db/migrations.js.map +1 -1
  23. package/dist/db/queries.d.ts.map +1 -1
  24. package/dist/db/queries.js +7 -1
  25. package/dist/db/queries.js.map +1 -1
  26. package/dist/db/schema.sql +0 -1
  27. package/dist/extraction/index.d.ts +1 -1
  28. package/dist/extraction/index.d.ts.map +1 -1
  29. package/dist/index.d.ts +0 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -3
  32. package/dist/index.js.map +1 -1
  33. package/dist/installer/claude-md-template.d.ts +10 -6
  34. package/dist/installer/claude-md-template.d.ts.map +1 -1
  35. package/dist/installer/claude-md-template.js +15 -40
  36. package/dist/installer/claude-md-template.js.map +1 -1
  37. package/dist/installer/config-writer.d.ts +17 -24
  38. package/dist/installer/config-writer.d.ts.map +1 -1
  39. package/dist/installer/config-writer.js +44 -239
  40. package/dist/installer/config-writer.js.map +1 -1
  41. package/dist/installer/index.d.ts +45 -4
  42. package/dist/installer/index.d.ts.map +1 -1
  43. package/dist/installer/index.js +216 -79
  44. package/dist/installer/index.js.map +1 -1
  45. package/dist/installer/instructions-template.d.ts +28 -0
  46. package/dist/installer/instructions-template.d.ts.map +1 -0
  47. package/dist/installer/instructions-template.js +63 -0
  48. package/dist/installer/instructions-template.js.map +1 -0
  49. package/dist/installer/targets/claude.d.ts +27 -0
  50. package/dist/installer/targets/claude.d.ts.map +1 -0
  51. package/dist/installer/targets/claude.js +246 -0
  52. package/dist/installer/targets/claude.js.map +1 -0
  53. package/dist/installer/targets/codex.d.ts +18 -0
  54. package/dist/installer/targets/codex.d.ts.map +1 -0
  55. package/dist/installer/targets/codex.js +185 -0
  56. package/dist/installer/targets/codex.js.map +1 -0
  57. package/dist/installer/targets/cursor.d.ts +35 -0
  58. package/dist/installer/targets/cursor.d.ts.map +1 -0
  59. package/dist/installer/targets/cursor.js +229 -0
  60. package/dist/installer/targets/cursor.js.map +1 -0
  61. package/dist/installer/targets/opencode.d.ts +30 -0
  62. package/dist/installer/targets/opencode.d.ts.map +1 -0
  63. package/dist/installer/targets/opencode.js +235 -0
  64. package/dist/installer/targets/opencode.js.map +1 -0
  65. package/dist/installer/targets/registry.d.ts +35 -0
  66. package/dist/installer/targets/registry.d.ts.map +1 -0
  67. package/dist/installer/targets/registry.js +83 -0
  68. package/dist/installer/targets/registry.js.map +1 -0
  69. package/dist/installer/targets/shared.d.ts +77 -0
  70. package/dist/installer/targets/shared.d.ts.map +1 -0
  71. package/dist/installer/targets/shared.js +246 -0
  72. package/dist/installer/targets/shared.js.map +1 -0
  73. package/dist/installer/targets/toml.d.ts +52 -0
  74. package/dist/installer/targets/toml.d.ts.map +1 -0
  75. package/dist/installer/targets/toml.js +147 -0
  76. package/dist/installer/targets/toml.js.map +1 -0
  77. package/dist/installer/targets/types.d.ts +116 -0
  78. package/dist/installer/targets/types.d.ts.map +1 -0
  79. package/dist/installer/targets/types.js +16 -0
  80. package/dist/installer/targets/types.js.map +1 -0
  81. package/dist/mcp/index.d.ts +4 -0
  82. package/dist/mcp/index.d.ts.map +1 -1
  83. package/dist/mcp/index.js +34 -9
  84. package/dist/mcp/index.js.map +1 -1
  85. package/dist/mcp/server-instructions.d.ts +1 -1
  86. package/dist/mcp/server-instructions.d.ts.map +1 -1
  87. package/dist/mcp/server-instructions.js +6 -6
  88. package/dist/mcp/tools.d.ts +61 -5
  89. package/dist/mcp/tools.d.ts.map +1 -1
  90. package/dist/mcp/tools.js +389 -81
  91. package/dist/mcp/tools.js.map +1 -1
  92. package/dist/search/query-utils.d.ts.map +1 -1
  93. package/dist/search/query-utils.js +29 -26
  94. package/dist/search/query-utils.js.map +1 -1
  95. package/dist/semantic-config-prompt.d.ts.map +1 -1
  96. package/dist/semantic-config-prompt.js +2 -3
  97. package/dist/semantic-config-prompt.js.map +1 -1
  98. package/dist/types.d.ts +0 -2
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +1 -2
  101. package/dist/types.js.map +1 -1
  102. package/dist/ui/glyphs.d.ts +42 -0
  103. package/dist/ui/glyphs.d.ts.map +1 -0
  104. package/dist/ui/glyphs.js +78 -0
  105. package/dist/ui/glyphs.js.map +1 -0
  106. package/dist/ui/shimmer-progress.d.ts +1 -0
  107. package/dist/ui/shimmer-progress.d.ts.map +1 -1
  108. package/dist/ui/shimmer-progress.js +7 -0
  109. package/dist/ui/shimmer-progress.js.map +1 -1
  110. package/dist/ui/shimmer-worker.js +20 -11
  111. package/dist/ui/shimmer-worker.js.map +1 -1
  112. package/dist/ui/types.d.ts +1 -0
  113. package/dist/ui/types.d.ts.map +1 -1
  114. package/dist/vectors/embedder.d.ts +15 -8
  115. package/dist/vectors/embedder.d.ts.map +1 -1
  116. package/dist/vectors/embedder.js +81 -53
  117. package/dist/vectors/embedder.js.map +1 -1
  118. package/dist/vectors/index.d.ts +1 -1
  119. package/dist/vectors/index.d.ts.map +1 -1
  120. package/dist/vectors/index.js.map +1 -1
  121. package/dist/vectors/manager.d.ts +5 -1
  122. package/dist/vectors/manager.d.ts.map +1 -1
  123. package/dist/vectors/manager.js +47 -28
  124. package/dist/vectors/manager.js.map +1 -1
  125. package/dist/vectors/search.d.ts +1 -1
  126. package/dist/vectors/search.d.ts.map +1 -1
  127. package/dist/vectors/search.js +9 -16
  128. package/dist/vectors/search.js.map +1 -1
  129. package/package.json +3 -2
  130. package/scripts/agent-eval/itrun.sh +107 -0
  131. package/scripts/agent-eval/parse-run.mjs +45 -0
  132. package/scripts/agent-eval/parse-session.mjs +93 -0
  133. package/scripts/agent-eval/run-agent.sh +34 -0
  134. package/scripts/extract-release-notes.mjs +130 -0
  135. package/scripts/local-install.sh +41 -0
  136. package/scripts/release.sh +68 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # CodeGraph
4
4
 
5
- ### Supercharge Claude Code with Semantic Code Intelligence
5
+ ### Supercharge Claude Code, Cursor, Codex, and OpenCode with Semantic Code Intelligence
6
6
 
7
7
  **94% fewer tool calls · 77% faster exploration · 100% local**
8
8
 
@@ -13,6 +13,10 @@
13
13
  [![Windows](https://img.shields.io/badge/Windows-supported-blue.svg)](#)
14
14
  [![macOS](https://img.shields.io/badge/macOS-supported-blue.svg)](#)
15
15
  [![Linux](https://img.shields.io/badge/Linux-supported-blue.svg)](#)
16
+ [![Claude Code](https://img.shields.io/badge/Claude_Code-supported-blueviolet.svg)](#)
17
+ [![Cursor](https://img.shields.io/badge/Cursor-supported-blueviolet.svg)](#)
18
+ [![Codex CLI](https://img.shields.io/badge/Codex_CLI-supported-blueviolet.svg)](#)
19
+ [![opencode](https://img.shields.io/badge/opencode-supported-blueviolet.svg)](#)
16
20
 
17
21
  [English](./README.md) · [简体中文](./README.zh-CN.md)
18
22
 
@@ -24,7 +28,7 @@
24
28
  npx @stupidloud/codegraph
25
29
  ```
26
30
 
27
- <sub>Interactive installer configures Claude Code automatically</sub>
31
+ <sub>Interactive installer auto-configures your agent(s) — Claude Code, Cursor, Codex CLI, opencode</sub>
28
32
 
29
33
  #### Initialize Projects
30
34
 
@@ -151,15 +155,33 @@ npx @stupidloud/codegraph
151
155
  ```
152
156
 
153
157
  The installer will:
154
- - Prompt to install `codegraph` globally (needed for the MCP server)
155
- - Configure the MCP server in `~/.claude.json`
156
- - Set up auto-allow permissions for CodeGraph tools
157
- - Add global instructions to `~/.claude/CLAUDE.md`
158
- - Optionally initialize your current project
158
+ - Ask which agent(s) to configure auto-detects installed ones from: **Claude Code**, **Cursor**, **Codex CLI**, **opencode**
159
+ - Prompt to install `codegraph` on your PATH (so agents can launch the MCP server)
160
+ - Ask whether configs apply to all your projects or just this one
161
+ - Write each chosen agent's MCP server config + an instructions file (e.g. `CLAUDE.md`, `.cursor/rules/codegraph.mdc`, `~/.codex/AGENTS.md`)
162
+ - Set up auto-allow permissions when Claude Code is one of the targets
163
+ - Initialize your current project (local installs only)
159
164
 
160
- ### 2. Restart Claude Code
165
+ **Non-interactive (scripting / CI):**
161
166
 
162
- Restart Claude Code for the MCP server to load.
167
+ ```bash
168
+ codegraph install --yes # auto-detect agents, install global
169
+ codegraph install --target=cursor,claude --yes # explicit target list
170
+ codegraph install --target=auto --location=local # detected agents, project-local
171
+ codegraph install --print-config codex # print snippet, no file writes
172
+ ```
173
+
174
+ | Flag | Values | Default |
175
+ |---|---|---|
176
+ | `--target` | `auto`, `all`, `none`, or csv (`claude,cursor,...`) | prompt |
177
+ | `--location` | `global`, `local` | prompt |
178
+ | `--yes` | (boolean) | prompt every step |
179
+ | `--no-permissions` | (boolean) skip Claude auto-allow list | permissions on |
180
+ | `--print-config <id>` | dump snippet for one agent and exit | — |
181
+
182
+ ### 2. Restart Your Agent
183
+
184
+ Restart your agent (Claude Code / Cursor / Codex CLI / opencode) for the MCP server to load.
163
185
 
164
186
  ### 3. Initialize Projects
165
187
 
@@ -168,7 +190,9 @@ cd your-project
168
190
  codegraph init -i
169
191
  ```
170
192
 
171
- That's it! Claude Code will use CodeGraph tools automatically when a `.codegraph/` directory exists.
193
+ Builds the per-project knowledge graph index. Also wires up any project-local agent surfaces (e.g. Cursor's `.cursor/rules/codegraph.mdc`) so a single global `codegraph install` works in every project you open — no need to re-run the installer per project.
194
+
195
+ That's it — your agent will use CodeGraph tools automatically when a `.codegraph/` directory exists.
172
196
 
173
197
  <details>
174
198
  <summary><strong>Manual Setup (Alternative)</strong></summary>
@@ -469,6 +493,16 @@ The `.codegraph/config.json` file controls indexing:
469
493
 
470
494
  **Missing symbols** — The MCP server auto-syncs on save (wait a couple seconds). Run `codegraph sync` manually if needed. Check that the file's language is supported and isn't excluded by config patterns.
471
495
 
496
+ ## Star History
497
+
498
+ <a href="https://www.star-history.com/?repos=colbymchenry%2Fcodegraph&type=date&legend=top-left">
499
+ <picture>
500
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=colbymchenry/codegraph&type=date&theme=dark&legend=top-left" />
501
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=colbymchenry/codegraph&type=date&legend=top-left" />
502
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=colbymchenry/codegraph&type=date&legend=top-left" />
503
+ </picture>
504
+ </a>
505
+
472
506
  ## License
473
507
 
474
508
  MIT
package/README.zh-CN.md CHANGED
@@ -53,8 +53,7 @@ Gemini API key / Jina API key
53
53
  "enabled": true,
54
54
  "provider": "gemini",
55
55
  "apiKey": "YOUR_GEMINI_API_KEY",
56
- "model": "gemini-embedding-001",
57
- "outputDimensionality": 768,
56
+ "model": "gemini-embedding-2",
58
57
  "batchSize": 32
59
58
  }
60
59
  }
@@ -69,7 +68,6 @@ Jina 示例:
69
68
  "provider": "jina",
70
69
  "apiKey": "YOUR_JINA_API_KEY",
71
70
  "model": "jina-embeddings-v5-text-nano",
72
- "outputDimensionality": 768,
73
71
  "batchSize": 32
74
72
  }
75
73
  }
@@ -150,7 +148,6 @@ const cg = await CodeGraph.init('/path/to/project', {
150
148
  provider: 'jina',
151
149
  apiKey: process.env.JINA_API_KEY,
152
150
  model: 'jina-embeddings-v5-text-nano',
153
- outputDimensionality: 768,
154
151
  batchSize: 32,
155
152
  },
156
153
  },
@@ -184,8 +181,7 @@ cg.close();
184
181
  "semanticSearch": {
185
182
  "enabled": false,
186
183
  "provider": "gemini",
187
- "model": "gemini-embedding-001",
188
- "outputDimensionality": 768,
184
+ "model": "gemini-embedding-2",
189
185
  "batchSize": 32
190
186
  }
191
187
  }
@@ -202,8 +198,7 @@ cg.close();
202
198
  | `semanticSearch.enabled` | 是否启用远程 embedding 语义搜索 |
203
199
  | `semanticSearch.provider` | `gemini` 或 `jina` |
204
200
  | `semanticSearch.apiKey` | Provider API key |
205
- | `semanticSearch.model` | Gemini 默认 `gemini-embedding-001`;Jina 默认 `jina-embeddings-v5-text-nano` |
206
- | `semanticSearch.outputDimensionality` | 默认 `768` |
201
+ | `semanticSearch.model` | Gemini 默认 `gemini-embedding-2`;Jina 默认 `jina-embeddings-v5-text-nano` |
207
202
  | `semanticSearch.batchSize` | 每批生成多少个节点 embedding |
208
203
 
209
204
  ## 支持语言
@@ -58,6 +58,7 @@ const fs = __importStar(require("fs"));
58
58
  const child_process_1 = require("child_process");
59
59
  const directory_1 = require("../directory");
60
60
  const shimmer_progress_1 = require("../ui/shimmer-progress");
61
+ const glyphs_1 = require("../ui/glyphs");
61
62
  const node_version_check_1 = require("./node-version-check");
62
63
  // Lazy-load heavy modules (CodeGraph, runInstaller) to keep CLI startup fast.
63
64
  async function loadCodeGraph() {
@@ -66,7 +67,7 @@ async function loadCodeGraph() {
66
67
  }
67
68
  catch (err) {
68
69
  const msg = err instanceof Error ? err.message : String(err);
69
- console.error('\x1b[31m✗\x1b[0m Failed to load CodeGraph modules.');
70
+ console.error(`\x1b[31m${(0, glyphs_1.getGlyphs)().err}\x1b[0m Failed to load CodeGraph modules.`);
70
71
  console.error(`\n Node: ${process.version} Platform: ${process.platform} ${process.arch}`);
71
72
  console.error(`\n Error: ${msg}`);
72
73
  console.error('\n Try reinstalling with: npm install -g @stupidloud/codegraph\n');
@@ -204,12 +205,14 @@ function main() {
204
205
  function createVerboseProgress() {
205
206
  let lastPhase = '';
206
207
  let lastPct = -1;
208
+ let lastDetail = '';
207
209
  const startTime = Date.now();
208
210
  return (progress) => {
209
211
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
210
212
  if (progress.phase !== lastPhase) {
211
213
  lastPhase = progress.phase;
212
214
  lastPct = -1;
215
+ lastDetail = '';
213
216
  console.log(`[${elapsed}s] Phase: ${progress.phase}`);
214
217
  }
215
218
  if (progress.total > 0) {
@@ -217,7 +220,13 @@ function main() {
217
220
  // Log every 5% to keep output manageable
218
221
  if (pct >= lastPct + 5 || progress.current === progress.total) {
219
222
  lastPct = pct;
220
- console.log(`[${elapsed}s] ${progress.current}/${progress.total} (${pct}%)${progress.currentFile ? ` ${progress.currentFile}` : ''}`);
223
+ console.log(`[${elapsed}s] ${progress.current}/${progress.total} (${pct}%)${progress.currentFile ? ` ${(0, glyphs_1.getGlyphs)().dash} ${progress.currentFile}` : ''}`);
224
+ }
225
+ }
226
+ else if (progress.currentFile) {
227
+ if (progress.currentFile !== lastDetail) {
228
+ lastDetail = progress.currentFile;
229
+ console.log(`[${elapsed}s] ${progress.currentFile}`);
221
230
  }
222
231
  }
223
232
  else if (progress.current > 0) {
@@ -232,25 +241,25 @@ function main() {
232
241
  * Print success message
233
242
  */
234
243
  function success(message) {
235
- console.log(chalk.green('✓') + ' ' + message);
244
+ console.log(chalk.green((0, glyphs_1.getGlyphs)().ok) + ' ' + message);
236
245
  }
237
246
  /**
238
247
  * Print error message
239
248
  */
240
249
  function error(message) {
241
- console.error(chalk.red('✗') + ' ' + message);
250
+ console.error(chalk.red((0, glyphs_1.getGlyphs)().err) + ' ' + message);
242
251
  }
243
252
  /**
244
253
  * Print info message
245
254
  */
246
255
  function info(message) {
247
- console.log(chalk.blue('ℹ') + ' ' + message);
256
+ console.log(chalk.blue((0, glyphs_1.getGlyphs)().info) + ' ' + message);
248
257
  }
249
258
  /**
250
259
  * Print warning message
251
260
  */
252
261
  function warn(message) {
253
- console.log(chalk.yellow('⚠') + ' ' + message);
262
+ console.log(chalk.yellow((0, glyphs_1.getGlyphs)().warn) + ' ' + message);
254
263
  }
255
264
  /**
256
265
  * Print indexing results using clack log methods
@@ -270,7 +279,7 @@ function main() {
270
279
  // continuing to the misleading "No files found" branch or throwing.
271
280
  if (!result.success && !hasErrors && result.filesIndexed === 0) {
272
281
  const generic = result.errors.find((e) => e.severity === 'error');
273
- clack.log.error(generic?.message ?? 'Indexing failed no further details available');
282
+ clack.log.error(generic?.message ?? `Indexing failed ${(0, glyphs_1.getGlyphs)().dash} no further details available`);
274
283
  return;
275
284
  }
276
285
  if (result.filesIndexed > 0) {
@@ -283,7 +292,7 @@ function main() {
283
292
  clack.log.info(`${formatNumber(result.nodesCreated)} nodes, ${formatNumber(result.edgesCreated)} edges in ${formatDuration(result.durationMs)}`);
284
293
  }
285
294
  else if (hasErrors) {
286
- clack.log.error(`Indexing failed all ${formatNumber(result.filesErrored)} files had errors`);
295
+ clack.log.error(`Indexing failed ${(0, glyphs_1.getGlyphs)().dash} all ${formatNumber(result.filesErrored)} files had errors`);
287
296
  }
288
297
  else {
289
298
  clack.log.warn('No files found to index');
@@ -313,7 +322,7 @@ function main() {
313
322
  clack.log.info('See .codegraph/errors.log for details');
314
323
  }
315
324
  if (result.filesIndexed > 0) {
316
- clack.log.info('The index is fully usable only the failed files are missing.');
325
+ clack.log.info(`The index is fully usable ${(0, glyphs_1.getGlyphs)().dash} only the failed files are missing.`);
317
326
  }
318
327
  }
319
328
  else if (projectPath) {
@@ -350,7 +359,7 @@ function main() {
350
359
  }
351
360
  }
352
361
  const lines = [
353
- `CodeGraph Error Log ${new Date().toISOString()}`,
362
+ `CodeGraph Error Log - ${new Date().toISOString()}`,
354
363
  `${errorsByFile.size} files with errors`,
355
364
  '',
356
365
  ];
@@ -383,6 +392,16 @@ function main() {
383
392
  if ((0, directory_1.isInitialized)(projectPath)) {
384
393
  clack.log.warn(`Already initialized in ${projectPath}`);
385
394
  clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update');
395
+ // Re-run agent surface wiring so re-running `init` is the
396
+ // documented way to recover a project that's missing its
397
+ // Cursor rules file (or future per-agent project surfaces).
398
+ try {
399
+ const { wireProjectSurfacesForGlobalAgents } = await Promise.resolve().then(() => __importStar(require('../installer')));
400
+ for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
401
+ clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
402
+ }
403
+ }
404
+ catch { /* non-fatal */ }
386
405
  clack.outro('');
387
406
  return;
388
407
  }
@@ -394,6 +413,20 @@ function main() {
394
413
  config: semanticConfig,
395
414
  });
396
415
  clack.log.success(`Initialized in ${projectPath}`);
416
+ // Bootstrap project-local surfaces for any agent that's
417
+ // configured globally (Cursor needs ./.cursor/rules/codegraph.mdc
418
+ // to actually prefer codegraph over native grep). Silent when
419
+ // there's nothing to write.
420
+ try {
421
+ const { wireProjectSurfacesForGlobalAgents } = await Promise.resolve().then(() => __importStar(require('../installer')));
422
+ for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
423
+ clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
424
+ }
425
+ }
426
+ catch (err) {
427
+ const msg = err instanceof Error ? err.message : String(err);
428
+ clack.log.warn(`Skipped wiring project-local agent surfaces: ${msg}`);
429
+ }
397
430
  if (options.index) {
398
431
  let result;
399
432
  if (options.verbose) {
@@ -403,7 +436,7 @@ function main() {
403
436
  });
404
437
  }
405
438
  else {
406
- process.stdout.write(`${colors.dim}│${colors.reset}\n`);
439
+ process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
407
440
  const progress = (0, shimmer_progress_1.createShimmerProgress)();
408
441
  result = await cg.indexAll({
409
442
  onProgress: progress.onProgress,
@@ -442,7 +475,7 @@ function main() {
442
475
  const readline = await Promise.resolve().then(() => __importStar(require('readline')));
443
476
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
444
477
  const answer = await new Promise((resolve) => {
445
- rl.question(chalk.yellow('⚠ This will permanently delete all CodeGraph data. Continue? (y/N) '), resolve);
478
+ rl.question(chalk.yellow(`${(0, glyphs_1.getGlyphs)().warn} This will permanently delete all CodeGraph data. Continue? (y/N) `), resolve);
446
479
  });
447
480
  rl.close();
448
481
  if (answer.toLowerCase() !== 'y') {
@@ -503,7 +536,7 @@ function main() {
503
536
  });
504
537
  }
505
538
  else {
506
- process.stdout.write(`${colors.dim}│${colors.reset}\n`);
539
+ process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
507
540
  const progress = (0, shimmer_progress_1.createShimmerProgress)();
508
541
  result = await cg.indexAll({
509
542
  onProgress: progress.onProgress,
@@ -547,7 +580,7 @@ function main() {
547
580
  }
548
581
  const clack = await importESM('@clack/prompts');
549
582
  clack.intro('Syncing CodeGraph');
550
- process.stdout.write(`${colors.dim}│${colors.reset}\n`);
583
+ process.stdout.write(`${colors.dim}${(0, glyphs_1.getGlyphs)().rail}${colors.reset}\n`);
551
584
  const progress = (0, shimmer_progress_1.createShimmerProgress)();
552
585
  const result = await cg.sync({
553
586
  onProgress: progress.onProgress,
@@ -566,7 +599,7 @@ function main() {
566
599
  details.push(`Modified: ${result.filesModified}`);
567
600
  if (result.filesRemoved > 0)
568
601
  details.push(`Removed: ${result.filesRemoved}`);
569
- clack.log.info(`${details.join(', ')} ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
602
+ clack.log.info(`${details.join(', ')} ${(0, glyphs_1.getGlyphs)().dash} ${formatNumber(result.nodesUpdated)} nodes in ${formatDuration(result.durationMs)}`);
570
603
  }
571
604
  clack.outro('Done');
572
605
  cg.destroy();
@@ -641,7 +674,7 @@ function main() {
641
674
  // when the native build fails.
642
675
  const backendLabel = backend === 'native'
643
676
  ? chalk.green('native')
644
- : chalk.yellow('wasm slower fallback; run `npm rebuild better-sqlite3`');
677
+ : chalk.yellow(`wasm ${(0, glyphs_1.getGlyphs)().dash} slower fallback; run \`npm rebuild better-sqlite3\``);
645
678
  console.log(` Backend: ${backendLabel}`);
646
679
  console.log();
647
680
  // Node breakdown
@@ -886,8 +919,9 @@ function main() {
886
919
  const renderNode = (node, prefix, isLast, depth) => {
887
920
  if (maxDepth !== undefined && depth > maxDepth)
888
921
  return;
889
- const connector = isLast ? '└── ' : '├── ';
890
- const childPrefix = isLast ? ' ' : '│ ';
922
+ const glyphs = (0, glyphs_1.getGlyphs)();
923
+ const connector = isLast ? glyphs.treeLast : glyphs.treeBranch;
924
+ const childPrefix = isLast ? ' ' : glyphs.treePipe;
891
925
  if (node.name) {
892
926
  let line = prefix + connector + node.name;
893
927
  if (node.file && includeMetadata) {
@@ -968,7 +1002,7 @@ function main() {
968
1002
  // Default: show info about MCP mode.
969
1003
  // Use stderr so stdout stays clean for any piped/stdio usage.
970
1004
  console.error(chalk.bold('\nCodeGraph MCP Server\n'));
971
- console.error(chalk.blue('ℹ') + ' Use --mcp flag to start the MCP server');
1005
+ console.error(chalk.blue((0, glyphs_1.getGlyphs)().info) + ' Use --mcp flag to start the MCP server');
972
1006
  console.error('\nTo use with Claude Code, add to your MCP configuration:');
973
1007
  console.error(chalk.dim(`
974
1008
  {
@@ -1144,7 +1178,7 @@ function main() {
1144
1178
  }
1145
1179
  const lockPath = path.join((0, directory_1.getCodeGraphDir)(projectPath), 'codegraph.lock');
1146
1180
  if (!fs.existsSync(lockPath)) {
1147
- info('No lock file found nothing to do');
1181
+ info(`No lock file found ${(0, glyphs_1.getGlyphs)().dash} nothing to do`);
1148
1182
  return;
1149
1183
  }
1150
1184
  fs.unlinkSync(lockPath);
@@ -1290,10 +1324,54 @@ function main() {
1290
1324
  */
1291
1325
  program
1292
1326
  .command('install')
1293
- .description('Run interactive installer for Claude Code integration')
1294
- .action(async () => {
1295
- const { runInstaller } = await Promise.resolve().then(() => __importStar(require('../installer')));
1296
- await runInstaller();
1327
+ .description('Install codegraph MCP server into one or more agents (Claude Code, Cursor, Codex CLI, opencode)')
1328
+ .option('-t, --target <ids>', 'Target agent(s): comma-separated ids, or "auto"|"all"|"none". Default: prompt')
1329
+ .option('-l, --location <where>', 'Install location: "global" or "local". Default: prompt')
1330
+ .option('-y, --yes', 'Non-interactive: defaults to --location=global --target=auto, auto-allow on')
1331
+ .option('--no-permissions', 'Skip writing the auto-allow permissions list (Claude Code only)')
1332
+ .option('--print-config <id>', 'Print MCP config snippet for the named agent and exit (no file writes)')
1333
+ .action(async (opts) => {
1334
+ if (opts.printConfig) {
1335
+ const { getTarget, listTargetIds } = await Promise.resolve().then(() => __importStar(require('../installer/targets/registry')));
1336
+ const target = getTarget(opts.printConfig);
1337
+ if (!target) {
1338
+ const known = listTargetIds().join(', ');
1339
+ error(`Unknown target "${opts.printConfig}". Known: ${known}.`);
1340
+ process.exit(1);
1341
+ }
1342
+ const loc = (opts.location === 'local' ? 'local' : 'global');
1343
+ process.stdout.write(target.printConfig(loc));
1344
+ return;
1345
+ }
1346
+ const { runInstallerWithOptions } = await Promise.resolve().then(() => __importStar(require('../installer')));
1347
+ if (opts.location && opts.location !== 'global' && opts.location !== 'local') {
1348
+ error(`--location must be "global" or "local" (got "${opts.location}").`);
1349
+ process.exit(1);
1350
+ }
1351
+ try {
1352
+ // Commander's `--no-permissions` makes `opts.permissions === false`;
1353
+ // omitting the flag leaves it `true` (the positive-form default).
1354
+ // We MUST treat the default-true as "user did not override — let
1355
+ // the orchestrator prompt" and only forward an explicit `false`
1356
+ // (or `true` when --yes implies it). Otherwise the auto-allow
1357
+ // prompt is silently skipped on every interactive run.
1358
+ const explicitNoPermissions = opts.permissions === false;
1359
+ const autoAllow = explicitNoPermissions
1360
+ ? false
1361
+ : opts.yes
1362
+ ? true
1363
+ : undefined;
1364
+ await runInstallerWithOptions({
1365
+ target: opts.target,
1366
+ location: opts.location,
1367
+ autoAllow,
1368
+ yes: opts.yes,
1369
+ });
1370
+ }
1371
+ catch (err) {
1372
+ error(err instanceof Error ? err.message : String(err));
1373
+ process.exit(1);
1374
+ }
1297
1375
  });
1298
1376
  // Parse and run
1299
1377
  program.parse();