@codragraph/cli 1.6.4 → 2.1.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 (105) hide show
  1. package/README.md +34 -0
  2. package/dist/_shared/cgdb/schema-constants.d.ts +16 -0
  3. package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -0
  4. package/dist/_shared/cgdb/schema-constants.js +67 -0
  5. package/dist/_shared/cgdb/schema-constants.js.map +1 -0
  6. package/dist/_shared/index.d.ts +2 -2
  7. package/dist/_shared/index.js +1 -1
  8. package/dist/cli/analyze.d.ts +22 -0
  9. package/dist/cli/analyze.js +109 -6
  10. package/dist/cli/compress-stats.d.ts +29 -0
  11. package/dist/cli/compress-stats.js +97 -0
  12. package/dist/cli/graphstore.d.ts +6 -2
  13. package/dist/cli/graphstore.js +45 -23
  14. package/dist/cli/index-repo.js +3 -3
  15. package/dist/cli/index.js +16 -2
  16. package/dist/cli/profile-heap.d.ts +35 -0
  17. package/dist/cli/profile-heap.js +126 -0
  18. package/dist/cli/setup.d.ts +13 -0
  19. package/dist/cli/setup.js +22 -11
  20. package/dist/cli/skill-gen.d.ts +14 -2
  21. package/dist/cli/skill-gen.js +52 -19
  22. package/dist/cli/tool.js +4 -0
  23. package/dist/cli/wiki.js +3 -3
  24. package/dist/core/augmentation/engine.js +7 -7
  25. package/dist/core/cgdb/cgdb-adapter.d.ts +176 -0
  26. package/dist/core/cgdb/cgdb-adapter.js +1320 -0
  27. package/dist/core/cgdb/content-read.d.ts +46 -0
  28. package/dist/core/cgdb/content-read.js +64 -0
  29. package/dist/core/cgdb/csv-generator.d.ts +29 -0
  30. package/dist/core/cgdb/csv-generator.js +492 -0
  31. package/dist/core/cgdb/pool-adapter.d.ts +93 -0
  32. package/dist/core/cgdb/pool-adapter.js +550 -0
  33. package/dist/core/cgdb/schema.d.ts +62 -0
  34. package/dist/core/cgdb/schema.js +502 -0
  35. package/dist/core/embeddings/embedding-pipeline.js +27 -10
  36. package/dist/core/graphstore/cgdb-row-source.d.ts +19 -0
  37. package/dist/core/graphstore/cgdb-row-source.js +141 -0
  38. package/dist/core/graphstore/index.d.ts +1 -1
  39. package/dist/core/graphstore/index.js +3 -3
  40. package/dist/core/group/bridge-db.d.ts +2 -2
  41. package/dist/core/group/bridge-db.js +123 -36
  42. package/dist/core/group/bridge-schema.d.ts +4 -4
  43. package/dist/core/group/bridge-schema.js +4 -4
  44. package/dist/core/group/cross-impact.js +3 -3
  45. package/dist/core/group/sync.js +4 -4
  46. package/dist/core/lbug/content-read.d.ts +46 -0
  47. package/dist/core/lbug/content-read.js +64 -0
  48. package/dist/core/lbug/csv-generator.d.ts +2 -6
  49. package/dist/core/lbug/csv-generator.js +45 -12
  50. package/dist/core/lbug/lbug-adapter.d.ts +4 -1
  51. package/dist/core/lbug/lbug-adapter.js +153 -21
  52. package/dist/core/lbug/schema.d.ts +7 -7
  53. package/dist/core/lbug/schema.js +18 -0
  54. package/dist/core/run-analyze.d.ts +13 -0
  55. package/dist/core/run-analyze.js +114 -27
  56. package/dist/core/search/bm25-index.d.ts +3 -3
  57. package/dist/core/search/bm25-index.js +75 -23
  58. package/dist/core/search/hybrid-search.js +2 -2
  59. package/dist/core/wiki/generator.d.ts +2 -2
  60. package/dist/core/wiki/generator.js +4 -4
  61. package/dist/core/wiki/graph-queries.d.ts +2 -2
  62. package/dist/core/wiki/graph-queries.js +5 -5
  63. package/dist/mcp/core/cgdb-adapter.d.ts +5 -0
  64. package/dist/mcp/core/cgdb-adapter.js +5 -0
  65. package/dist/mcp/core/embedder.js +1 -1
  66. package/dist/mcp/local/local-backend.d.ts +2 -2
  67. package/dist/mcp/local/local-backend.js +36 -19
  68. package/dist/mcp/server.js +3 -3
  69. package/dist/mcp/tools.js +1 -1
  70. package/dist/server/analyze-worker.js +2 -2
  71. package/dist/server/api.js +34 -33
  72. package/dist/storage/repo-manager.d.ts +42 -3
  73. package/dist/storage/repo-manager.js +23 -4
  74. package/hooks/claude/codragraph-hook.cjs +98 -5
  75. package/package.json +4 -4
  76. package/scripts/build-tree-sitter-proto.cjs +15 -3
  77. package/scripts/build.js +8 -9
  78. package/scripts/patch-tree-sitter-swift.cjs +17 -4
  79. package/skills/codragraph-api-surface.md +110 -0
  80. package/skills/codragraph-config-audit.md +146 -0
  81. package/skills/codragraph-cross-repo-impact.md +135 -0
  82. package/skills/codragraph-data-lineage.md +137 -0
  83. package/skills/codragraph-dead-code.md +119 -0
  84. package/skills/codragraph-gh-actions-debug.md +162 -0
  85. package/skills/codragraph-gh-issue-workflow.md +178 -0
  86. package/skills/codragraph-gh-pr-workflow.md +176 -0
  87. package/skills/codragraph-gh-release-workflow.md +187 -0
  88. package/skills/codragraph-git-bisect.md +176 -0
  89. package/skills/codragraph-git-force-push.md +147 -0
  90. package/skills/codragraph-git-history-rewrite.md +174 -0
  91. package/skills/codragraph-git-rebase-vs-merge.md +138 -0
  92. package/skills/codragraph-git-recovery.md +181 -0
  93. package/skills/codragraph-git-worktree.md +145 -0
  94. package/skills/codragraph-migration-tracking.md +130 -0
  95. package/skills/codragraph-notebook-context.md +136 -0
  96. package/skills/codragraph-observability-coverage.md +125 -0
  97. package/skills/codragraph-onboarding.md +129 -0
  98. package/skills/codragraph-perf-hotspots.md +132 -0
  99. package/skills/codragraph-project-switcher.md +116 -0
  100. package/skills/codragraph-security-audit.md +144 -0
  101. package/skills/codragraph-sql-tracing.md +122 -0
  102. package/skills/codragraph-supply-chain-audit.md +153 -0
  103. package/skills/codragraph-test-coverage.md +97 -0
  104. package/vendor/tree-sitter-proto/bindings/node/index.js +3 -3
  105. package/vendor/tree-sitter-proto/src/node-types.json +1 -1
@@ -12,8 +12,27 @@
12
12
  */
13
13
 
14
14
  const fs = require('fs');
15
+ const os = require('os');
15
16
  const path = require('path');
16
- const { spawnSync } = require('child_process');
17
+ const { spawnSync, spawn } = require('child_process');
18
+
19
+ /**
20
+ * Decide whether background auto-reindex is opted in. Two equivalent signals:
21
+ * 1. CODRAGRAPH_AUTO_REINDEX=1 in env (good for shells, CI)
22
+ * 2. `{ "autoReindex": true }` in ~/.codragraph/config.json (good for GUI
23
+ * editor launches on Windows, where shell env doesn't propagate to
24
+ * hook child processes reliably)
25
+ */
26
+ function isAutoReindexEnabled() {
27
+ if (process.env.CODRAGRAPH_AUTO_REINDEX === '1') return true;
28
+ try {
29
+ const configPath = path.join(os.homedir(), '.codragraph', 'config.json');
30
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
31
+ return config && config.autoReindex === true;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
17
36
 
18
37
  /**
19
38
  * Read JSON input from stdin synchronously.
@@ -217,8 +236,8 @@ function handlePostToolUse(input) {
217
236
 
218
237
  const cwd = input.cwd || process.cwd();
219
238
  if (!path.isAbsolute(cwd)) return;
220
- const gitNexusDir = findCodraGraphDir(cwd);
221
- if (!gitNexusDir) return;
239
+ const codragraphDir = findCodraGraphDir(cwd);
240
+ if (!codragraphDir) return;
222
241
 
223
242
  // Compare HEAD against last indexed commit — skip if unchanged
224
243
  let currentHead = '';
@@ -239,7 +258,7 @@ function handlePostToolUse(input) {
239
258
  let lastCommit = '';
240
259
  let hadEmbeddings = false;
241
260
  try {
242
- const meta = JSON.parse(fs.readFileSync(path.join(gitNexusDir, 'meta.json'), 'utf-8'));
261
+ const meta = JSON.parse(fs.readFileSync(path.join(codragraphDir, 'meta.json'), 'utf-8'));
243
262
  lastCommit = meta.lastCommit || '';
244
263
  hadEmbeddings = meta.stats && meta.stats.embeddings > 0;
245
264
  } catch {
@@ -250,10 +269,84 @@ function handlePostToolUse(input) {
250
269
  if (currentHead && currentHead === lastCommit) return;
251
270
 
252
271
  const analyzeCmd = `npx @codragraph/cli analyze${hadEmbeddings ? ' --embeddings' : ''}`;
272
+
273
+ // Opt-in background auto-reindex.
274
+ // Default stays as notification-only because spawning analyze while an MCP
275
+ // server holds LadybugDB will fail with a database-busy error — the
276
+ // notification path lets the agent reindex at a quiet moment instead.
277
+ // Power users who run MCP outside Claude Code's lifecycle can opt in via
278
+ // CODRAGRAPH_AUTO_REINDEX=1 or `{ "autoReindex": true }` in
279
+ // ~/.codragraph/config.json.
280
+ if (isAutoReindexEnabled()) {
281
+ // The "coalesce" file is a single-process gate: it exists only while a
282
+ // reindex is in flight. The spawned analyze removes it on exit (success or
283
+ // failure) via CODRAGRAPH_REINDEX_LOCK_PATH; the 10-min mtime fallback
284
+ // catches the rare crash that bypasses analyze's exit handler.
285
+ const coalescePath = path.join(codragraphDir, '.reindex.coalesce');
286
+ const crashSafetyTtlMs = 10 * 60 * 1000;
287
+ let inFlight = false;
288
+ try {
289
+ const stat = fs.statSync(coalescePath);
290
+ if (Date.now() - stat.mtimeMs < crashSafetyTtlMs) inFlight = true;
291
+ } catch {
292
+ /* no coalesce file — no reindex in flight */
293
+ }
294
+
295
+ if (!inFlight) {
296
+ try {
297
+ fs.writeFileSync(coalescePath, String(process.pid));
298
+ } catch {
299
+ /* best-effort — gate is for coalescing, not correctness */
300
+ }
301
+
302
+ const cliPath = resolveCliPath();
303
+ const reindexArgs = hadEmbeddings
304
+ ? ['analyze', '--embeddings', '--no-setup']
305
+ : ['analyze', '--no-setup'];
306
+ const spawnEnv = { ...process.env, CODRAGRAPH_REINDEX_LOCK_PATH: coalescePath };
307
+ const spawnOpts = {
308
+ cwd,
309
+ detached: true,
310
+ stdio: 'ignore',
311
+ windowsHide: true,
312
+ env: spawnEnv,
313
+ };
314
+ try {
315
+ let child;
316
+ if (cliPath) {
317
+ child = spawn(process.execPath, [cliPath, ...reindexArgs], spawnOpts);
318
+ } else if (process.platform === 'win32') {
319
+ child = spawn('cmd', ['/c', 'npx', '-y', '@codragraph/cli', ...reindexArgs], spawnOpts);
320
+ } else {
321
+ child = spawn('npx', ['-y', '@codragraph/cli', ...reindexArgs], spawnOpts);
322
+ }
323
+ child.unref();
324
+ } catch {
325
+ /* spawn failed — fall through to notification */
326
+ }
327
+
328
+ sendHookResponse(
329
+ 'PostToolUse',
330
+ `CodraGraph: auto-reindex started in background ` +
331
+ `(HEAD ${lastCommit ? lastCommit.slice(0, 7) : 'never'} → ${currentHead.slice(0, 7)}). ` +
332
+ `If an MCP server is currently holding the database, the reindex will fail silently — ` +
333
+ `run \`${analyzeCmd}\` manually after closing the agent session.`,
334
+ );
335
+ return;
336
+ }
337
+
338
+ sendHookResponse(
339
+ 'PostToolUse',
340
+ `CodraGraph: auto-reindex coalesced — another reindex is in flight (will pick up your latest commit when it finishes).`,
341
+ );
342
+ return;
343
+ }
344
+
253
345
  sendHookResponse(
254
346
  'PostToolUse',
255
347
  `CodraGraph index is stale (last indexed: ${lastCommit ? lastCommit.slice(0, 7) : 'never'}). ` +
256
- `Run \`${analyzeCmd}\` to update the knowledge graph.`,
348
+ `Run \`${analyzeCmd}\` to update the knowledge graph. ` +
349
+ `Set CODRAGRAPH_AUTO_REINDEX=1 (or autoReindex: true in ~/.codragraph/config.json) for background auto-reindex.`,
257
350
  );
258
351
  }
259
352
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codragraph/cli",
3
- "version": "1.6.4",
3
+ "version": "2.1.0",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": {
6
6
  "name": "Anit Chaudhary",
@@ -56,10 +56,10 @@
56
56
  "prepack": "node scripts/build.js"
57
57
  },
58
58
  "dependencies": {
59
+ "@codragraph/graphstore": "^2.1.0",
59
60
  "@huggingface/transformers": "^4.1.0",
60
- "@ladybugdb/core": "^0.15.2",
61
+ "@ladybugdb/core": "^0.16.0",
61
62
  "@modelcontextprotocol/sdk": "^1.0.0",
62
- "@codragraph/graphstore": "^0.1.1",
63
63
  "@scarf/scarf": "^1.4.0",
64
64
  "cli-progress": "^3.12.0",
65
65
  "commander": "^14.0.3",
@@ -99,6 +99,7 @@
99
99
  "tree-sitter-swift": "^0.6.0"
100
100
  },
101
101
  "devDependencies": {
102
+ "@codragraph/shared": "file:../shared",
102
103
  "@types/cli-progress": "^3.11.6",
103
104
  "@types/cors": "^2.8.17",
104
105
  "@types/express": "^4.17.21",
@@ -106,7 +107,6 @@
106
107
  "@types/node": "^25.6.0",
107
108
  "@types/uuid": "^11.0.0",
108
109
  "@vitest/coverage-v8": "^4.0.18",
109
- "@codragraph/shared": "file:../codragraph-shared",
110
110
  "tsx": "^4.0.0",
111
111
  "typescript": "^5.4.5",
112
112
  "vitest": "^4.0.18"
@@ -34,14 +34,26 @@ const fs = require('fs');
34
34
  const path = require('path');
35
35
  const { execSync } = require('child_process');
36
36
 
37
- const protoDir = path.join(__dirname, '..', 'node_modules', 'tree-sitter-proto');
37
+ // Resolve tree-sitter-proto from BOTH the codragraph package itself AND any
38
+ // monorepo root that hoisted the dep. npm workspaces hoist optional deps to
39
+ // the workspace root, so the package-local path doesn't exist on a workspace
40
+ // install. Same trap as patch-tree-sitter-swift.cjs — see that file for the
41
+ // full failure mode.
42
+ const protoCandidates = [
43
+ path.join(__dirname, '..', 'node_modules', 'tree-sitter-proto'),
44
+ path.join(__dirname, '..', '..', 'node_modules', 'tree-sitter-proto'),
45
+ ];
46
+ const protoDir = protoCandidates.find((d) => fs.existsSync(path.join(d, 'binding.gyp')));
47
+ if (!protoDir) {
48
+ // tree-sitter-proto is an optionalDependency; absent when install
49
+ // skipped optional deps or the file: dep was not resolved.
50
+ process.exit(0);
51
+ }
38
52
  const bindingGyp = path.join(protoDir, 'binding.gyp');
39
53
  const bindingNode = path.join(protoDir, 'build', 'Release', 'tree_sitter_proto_binding.node');
40
54
 
41
55
  try {
42
56
  if (!fs.existsSync(bindingGyp)) {
43
- // tree-sitter-proto is an optionalDependency; absent when install
44
- // skipped optional deps or the file: dep was not resolved.
45
57
  process.exit(0);
46
58
  }
47
59
 
package/scripts/build.js CHANGED
@@ -17,20 +17,19 @@ import { fileURLToPath } from 'node:url';
17
17
 
18
18
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
19
  const ROOT = path.resolve(__dirname, '..');
20
- // Workspace directory names (NOT package names package names are
21
- // `@codragraph/shared` / `@codragraph/graphstore`, but the on-disk
22
- // dirs stay as `codragraph-shared` / `codragraph-graphstore`).
23
- const SHARED_ROOT = path.resolve(ROOT, '..', 'codragraph-shared');
24
- const GRAPHSTORE_ROOT = path.resolve(ROOT, '..', 'codragraph-graphstore');
20
+ // Workspace directory names packages live under `packages/<short>` on disk
21
+ // and publish as `@codragraph/<short>` on npm.
22
+ const SHARED_ROOT = path.resolve(ROOT, '..', 'shared');
23
+ const GRAPHSTORE_ROOT = path.resolve(ROOT, '..', 'graphstore');
25
24
  const DIST = path.join(ROOT, 'dist');
26
25
  const SHARED_DEST = path.join(DIST, '_shared');
27
26
 
28
- // ── 1. Build codragraph-shared ───────────────────────────────────────
29
- console.log('[build] compiling codragraph-shared…');
27
+ // ── 1. Build @codragraph/shared ──────────────────────────────────────
28
+ console.log('[build] compiling @codragraph/shared…');
30
29
  execSync('npx tsc', { cwd: SHARED_ROOT, stdio: 'inherit' });
31
30
 
32
- // ── 2. Build codragraph-graphstore ───────────────────────────────────
33
- // codragraph depends on this for snapshot/branch/diff types. On a
31
+ // ── 2. Build @codragraph/graphstore ──────────────────────────────────
32
+ // core depends on this for snapshot/branch/diff types. On a
34
33
  // fresh checkout (CI, npm ci) the graphstore dist is empty until we
35
34
  // build it here, so step 3 would otherwise fail to resolve
36
35
  // `@codragraph/graphstore` imports. Skip gracefully if the workspace
@@ -29,13 +29,26 @@ const fs = require('fs');
29
29
  const path = require('path');
30
30
  const { execSync } = require('child_process');
31
31
 
32
- const swiftDir = path.join(__dirname, '..', 'node_modules', 'tree-sitter-swift');
32
+ // Resolve tree-sitter-swift from BOTH the codragraph package itself AND any
33
+ // monorepo root that hoisted the dep. npm workspaces hoist optional deps to
34
+ // the workspace root, so `codragraph/node_modules/tree-sitter-swift` doesn't
35
+ // exist when this script runs as the codragraph postinstall — checking only
36
+ // that path silently no-ops, which is exactly the failure that left
37
+ // Windows Node 22.14 users without a Swift parser.
38
+ //
39
+ // Order matters: the package-local dir takes precedence (standalone install),
40
+ // then the parent monorepo root (workspace install).
41
+ const candidateDirs = [
42
+ path.join(__dirname, '..', 'node_modules', 'tree-sitter-swift'),
43
+ path.join(__dirname, '..', '..', 'node_modules', 'tree-sitter-swift'),
44
+ ];
45
+ const swiftDir = candidateDirs.find((d) => fs.existsSync(path.join(d, 'binding.gyp')));
46
+ if (!swiftDir) {
47
+ process.exit(0);
48
+ }
33
49
  const bindingPath = path.join(swiftDir, 'binding.gyp');
34
50
 
35
51
  try {
36
- if (!fs.existsSync(bindingPath)) {
37
- process.exit(0);
38
- }
39
52
 
40
53
  const content = fs.readFileSync(bindingPath, 'utf8');
41
54
  let needsRebuild = false;
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: codragraph-api-surface
3
+ description: "Use when the user wants to enumerate the public API of a package or codebase, understand what's exported, audit breaking change risk, or compare API shapes across versions. Examples: \"what's our public API\", \"list exports\", \"API surface\", \"what would break if I remove X\", \"document the public interface\""
4
+ ---
5
+
6
+ # API Surface Audit with CodraGraph
7
+
8
+ ## When to Use
9
+
10
+ - "What's the public API of this package?"
11
+ - "List every exported function / class / type"
12
+ - "What would break if I remove or rename `<symbol>`?"
13
+ - Pre-release API freeze audit
14
+ - Generating API documentation from the graph
15
+ - Comparing API surface across versions (with `codragraph diff --semantic`)
16
+
17
+ ## Why CodraGraph helps here
18
+
19
+ Reading every `index.ts` / `__init__.py` / `mod.rs` by hand misses re-exports
20
+ and framework-magic exports (Next.js page routes, decorators, registered
21
+ plugins). CodraGraph's `isExported` property is computed by language-aware
22
+ export detection — covers default exports, named re-exports, `__all__`,
23
+ `pub use`, etc., consistently across all 16 supported languages.
24
+
25
+ ## Workflow
26
+
27
+ ```
28
+ 1. codragraph_cypher({query: `
29
+ MATCH (n) WHERE n.isExported = true
30
+ RETURN labels(n)[0] AS table, n.name, n.filePath, n.id
31
+ ORDER BY table, n.filePath, n.name
32
+ `})
33
+ → every exported symbol, grouped by table
34
+
35
+ 2. For each high-traffic export:
36
+ codragraph_impact({target: "<name>", direction: "upstream"})
37
+ → who depends on it (within this repo)
38
+
39
+ 3. For cross-repo audits (multi-repo group):
40
+ codragraph_impact({repo: "@<group>", target: "<name>", direction: "upstream"})
41
+ → blast radius across every group member
42
+
43
+ 4. Compare across versions:
44
+ codragraph diff <baseline> <head> --semantic --json
45
+ → addedAPIs / removedAPIs / classifiedModifications
46
+ → produces a versioned changelog of what your public surface gained / lost
47
+ ```
48
+
49
+ > Pair with `codragraph-pr-review` skill when reviewing a PR that touches
50
+ > exported symbols — the impact-across-group check is the difference between
51
+ > "breaks our consumers" and "internal refactor."
52
+
53
+ ## Checklist
54
+
55
+ ```
56
+ - [ ] Cypher query for n.isExported = true
57
+ - [ ] Group by file or by community (Leiden cluster)
58
+ - [ ] For each non-trivial export, run impact upstream
59
+ - [ ] If the package is in a group, run impact with repo: "@group" too
60
+ - [ ] Compare with previous release: codragraph diff <prev-tag> HEAD --semantic
61
+ - [ ] Flag exports with no documented consumers — candidates for visibility
62
+ reduction (export → internal)
63
+ ```
64
+
65
+ ## Example: "What's our public API?"
66
+
67
+ ```
68
+ 1. codragraph_cypher({
69
+ query: `MATCH (n) WHERE n.isExported = true
70
+ RETURN labels(n)[0] AS table, n.name, n.filePath`
71
+ })
72
+ → 47 exports: 22 Function, 12 Class, 8 Interface, 5 Constant
73
+
74
+ 2. Top-level functions:
75
+ - createClient (src/index.ts) ← 14 callers
76
+ - fetchUser (src/api.ts) ← 6 callers
77
+ - validate (src/utils.ts) ← 1 internal caller only ⚠ over-exported
78
+
79
+ 3. codragraph_impact({target: "validate", direction: "upstream"})
80
+ → d=1: only formatPayload (same package). No external consumers.
81
+ → Recommend: drop the `export` keyword. Internal-only.
82
+
83
+ 4. Compare with v1.5.3 release:
84
+ codragraph diff v1.5.3 HEAD --semantic
85
+ → +3 added APIs, -1 removed API (mappings.toCamelCase), ~2 modified
86
+ → Removed API is a SemVer major bump.
87
+ ```
88
+
89
+ ## Output Format
90
+
91
+ ```markdown
92
+ ## API Surface: <package>
93
+
94
+ ### Exports (47 total)
95
+ | Symbol | Table | File | Callers (internal) | Notes |
96
+ |--------|-------|------|-------------------:|-------|
97
+ | createClient | Function | src/index.ts | 14 | core entry |
98
+ | validate | Function | src/utils.ts | 1 | over-exported, suggest internal |
99
+ | ...
100
+
101
+ ### Diff vs <previous-tag>
102
+ - **Added (3):** `subscribe`, `unsubscribe`, `EventBus`
103
+ - **Removed (1):** `toCamelCase` ⚠ SemVer major
104
+ - **Modified (2):** `createClient` (param 3→4), `fetchUser` (return type)
105
+
106
+ ### Recommendations
107
+ - Reduce visibility on 4 over-exported internals
108
+ - Document the 3 new APIs in the release notes
109
+ - The removed `toCamelCase` requires a major version bump
110
+ ```
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: codragraph-config-audit
3
+ description: "Use to audit how environment variables, config files, and feature flags are read and used across the codebase — find unused config, missing defaults, undocumented env vars, secrets read into logs. Examples: \"audit env vars\", \"unused config\", \"who reads FOO_BAR env\", \"feature flag usage\", \"config sprawl\""
4
+ ---
5
+
6
+ # Configuration Audit with CodraGraph
7
+
8
+ ## When to Use
9
+
10
+ - "Which env vars do we actually read?"
11
+ - "Which env vars are read but never set in deploy configs?"
12
+ - "Find the unused feature flags I can delete."
13
+ - "Who reads `STRIPE_SECRET_KEY`?"
14
+ - "Is `<config>` ever logged or sent to telemetry?"
15
+ - "Audit config sprawl before consolidating."
16
+
17
+ ## Why CodraGraph helps here
18
+
19
+ Configuration enters your code through a small set of helpers:
20
+ `process.env.X`, `os.getenv("X")`, `config.get("foo.bar")`,
21
+ `featureFlags.isEnabled("flag")`. CodraGraph indexes the calls to those
22
+ helpers and the literal arguments — so a `query` for the helper plus a
23
+ `context` of each call site produces a complete picture of which keys
24
+ are read where.
25
+
26
+ ## Workflow
27
+
28
+ ```
29
+ 1. Identify the config helpers (per-language patterns):
30
+ codragraph_query({query: "process.env getenv ConfigService featureFlags"})
31
+ → list of config-read helpers
32
+
33
+ 2. For each helper, find every call site and its key argument:
34
+ codragraph_cypher({query: `
35
+ MATCH (caller)-[:CALLS]->(helper {name: 'getenv'})
36
+ RETURN caller.name, caller.filePath
37
+ `})
38
+ → For richer key-extraction, read the bodies via context:
39
+ codragraph_context({name: "<caller>", content: true})
40
+ → look for the literal string passed to getenv()
41
+
42
+ 3. Cross-check with deploy configs:
43
+ - Read .env / .env.example / docker-compose.yml / k8s ConfigMaps
44
+ - Build the SET of keys actually defined
45
+ - For each key your code reads but isn't defined: undocumented env var
46
+ - For each key defined but no code reads: dead config — delete
47
+
48
+ 4. Feature-flag specific audit:
49
+ codragraph_query({query: "featureFlags.isEnabled flag.evaluate"})
50
+ → For each flag-read site: codragraph_impact upstream
51
+ → Flags with no callers can be removed
52
+ → Flags with one branch always returning true / false are stale
53
+
54
+ 5. Secret-leakage check:
55
+ codragraph_query({query: "STRIPE_SECRET DATABASE_URL API_KEY"})
56
+ → For each match: codragraph_context to confirm the value is not
57
+ piped to logger / tracer / metrics
58
+ ```
59
+
60
+ ## Audit dimensions
61
+
62
+ | Dimension | Question | CodraGraph approach |
63
+ |---|---|---|
64
+ | **Used** | Is this env var read anywhere? | `query` for the literal key |
65
+ | **Documented** | Is the key in `.env.example` / docs? | grep deploy files; subtract from used set |
66
+ | **Defaulted** | Does the read have a default? | `context` shows the surrounding code |
67
+ | **Validated** | Is the value parsed / type-checked? | `context` for `parseInt` / `URL` / Zod schema in the caller |
68
+ | **Logged** | Does the value flow to telemetry? | `impact` downstream from the read site → check telemetry helpers |
69
+ | **Stale flag** | Is the flag still toggled in production? | combine with deploy-config check |
70
+
71
+ ## Feature flag lifecycle audit
72
+
73
+ ```
74
+ codragraph_cypher({query: `
75
+ MATCH (caller)-[:CALLS]->(ff {name: 'isEnabled'})
76
+ RETURN caller.name, caller.filePath, count(*) AS uses
77
+ ORDER BY uses DESC
78
+ `})
79
+ → for each call site, codragraph_context to extract the flag NAME literal
80
+
81
+ # Then:
82
+ - Flag name read by 0 callers → remove
83
+ - Flag name with both branches identical → stale (always-true or always-false)
84
+ - Flag still wired in code, but config has it pinned `true` for >90 days → graduate
85
+ ```
86
+
87
+ ## Checklist
88
+
89
+ ```
90
+ - [ ] Listed config helpers (env / config / featureFlag readers)
91
+ - [ ] Built the read-set: { key: [ call sites ] }
92
+ - [ ] Built the defined-set from deploy configs
93
+ - [ ] Diff: undocumented (in code, not in config) + dead (in config, not in code)
94
+ - [ ] Spot-check defaults / validation / secret leakage on critical keys
95
+ - [ ] Feature-flag staleness check
96
+ - [ ] Output: read map + recommended deletions / required deploy changes
97
+ ```
98
+
99
+ ## Example: "Audit our feature flags"
100
+
101
+ ```
102
+ 1. codragraph_query({query: "featureFlags.isEnabled"})
103
+ → 47 call sites in 23 files
104
+
105
+ 2. For each call site, extract the flag string (codragraph_context):
106
+ - 'new_checkout' (12 sites)
107
+ - 'experimental_search' (4 sites)
108
+ - 'use_new_pricing' (8 sites)
109
+ - 'kill_legacy_admin' (1 site)
110
+ - 'canary_v3' (0 sites — defined in code dead)
111
+
112
+ 3. Cross-check deploys:
113
+ - 'new_checkout' set to TRUE for 100%% prod since 2026-01 (graduate it)
114
+ - 'experimental_search' set to TRUE for 5%% prod (active experiment, keep)
115
+ - 'use_new_pricing' set to TRUE for 100%% prod since 2026-03 (graduate)
116
+ - 'kill_legacy_admin' set to TRUE for 100%% prod since 2026-02 (graduate)
117
+ - 'canary_v3' not configured anywhere (truly dead)
118
+
119
+ 4. Findings:
120
+ - DELETE: 'canary_v3' (dead code, no callers, no config)
121
+ - GRADUATE: 'new_checkout', 'use_new_pricing', 'kill_legacy_admin' →
122
+ remove the flag check; keep the new behavior unconditionally
123
+ - KEEP: 'experimental_search'
124
+ - Codebase loses: 21 call sites, 1 unused flag definition
125
+ ```
126
+
127
+ ## Output Format
128
+
129
+ ```markdown
130
+ ## Config Audit: <scope>
131
+
132
+ ### Env vars / config keys
133
+ | Key | Read sites | Defined? | Default? | Validated? | Notes |
134
+ |---|--:|---|---|---|---|
135
+ | DATABASE_URL | 4 | ✓ | ✗ | ✗ | add Zod parse |
136
+ | EXPERIMENTAL_FOO | 1 | ✗ | ✓ ('false') | ✓ | undocumented; either document or delete |
137
+ | ... | ... | ... | ... | ... | ... |
138
+
139
+ ### Feature flags
140
+ - DELETE (no callers): canary_v3, legacy_dashboard_b
141
+ - GRADUATE (100%% production for >90 days): new_checkout, kill_legacy_admin
142
+ - KEEP (active experiment): experimental_search, ai_summarize_v2
143
+
144
+ ### Secret-leak check
145
+ - 0 paths from secret reads to logger/metrics/tracer found ✓
146
+ ```
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: codragraph-cross-repo-impact
3
+ description: "Use when assessing the blast radius of a change that crosses repository boundaries — a shared library used by multiple services, a contract / protobuf / OpenAPI schema consumed by N consumers, a microservices change. Examples: \"what services consume X\", \"cross-repo blast radius\", \"will this break the consumers\", \"who depends on this contract\""
4
+ ---
5
+
6
+ # Cross-Repo Impact Analysis with CodraGraph
7
+
8
+ ## When to Use
9
+
10
+ - "What other repos consume `<symbol>` from this one?"
11
+ - "If I change this gRPC method / OpenAPI route / protobuf message, what breaks?"
12
+ - "Cross-repo blast radius for `<change>`"
13
+ - Microservices architecture: assessing a contract change
14
+ - Shared-library author: deciding if a function is safe to remove
15
+
16
+ ## Why CodraGraph helps here
17
+
18
+ CodraGraph's **groups** (sets of related repos sharing a `group.yaml`)
19
+ maintain a Contract Registry — provider/consumer rows for every cross-repo
20
+ reference (gRPC service / method, OpenAPI route, protobuf message). The
21
+ group-mode `impact` walks both the local call graph AND the contract
22
+ bridges, so a single call returns the blast radius across every member
23
+ repo. You don't need to re-run impact in each consumer separately.
24
+
25
+ ## Workflow
26
+
27
+ ```
28
+ 1. Identify the group:
29
+ codragraph_group_list({})
30
+ → list of groups + their member repos
31
+
32
+ 2. Confirm the symbol exists in the producer repo:
33
+ codragraph_context({repo: "<producerRepo>", name: "<symbol>"})
34
+
35
+ 3. Run group-mode impact:
36
+ codragraph_impact({repo: "@<group>", target: "<symbol>", direction: "upstream"})
37
+ → d=1 callers spanning every group member
38
+ (in-repo callers + contract-bridge consumers)
39
+
40
+ 4. Inspect the Contract Registry to see provider/consumer rows directly:
41
+ READ codragraph://group/<groupName>/contracts
42
+ → list of contracts touching the symbol or its API
43
+
44
+ 5. Check group-status / staleness:
45
+ READ codragraph://group/<groupName>/status
46
+ → which member repos haven't been re-indexed recently
47
+ (stale members produce stale impact results)
48
+
49
+ 6. Surface the worst-case consumer:
50
+ any consumer not updated since the schema change = potential breakage
51
+ ```
52
+
53
+ > If any member repo's index is stale, group-mode impact may underreport.
54
+ > Re-analyze stale members before relying on the results.
55
+
56
+ ## Checklist
57
+
58
+ ```
59
+ - [ ] group_list to confirm the group exists and the producer is a member
60
+ - [ ] context on the symbol in the producer repo
61
+ - [ ] Group-mode impact upstream
62
+ - [ ] Inspect Contract Registry for provider/consumer rows
63
+ - [ ] Check group/status for stale members; re-analyze if needed
64
+ - [ ] List affected consumer repos by impact depth
65
+ - [ ] Recommend coordinated PRs across consumers (if breaking)
66
+ ```
67
+
68
+ ## When to Use Which Tool
69
+
70
+ | Question | Tool |
71
+ | --- | --- |
72
+ | "Which repos are in my group?" | `group_list` |
73
+ | "What contracts cross between member A and member B?" | Contract Registry resource |
74
+ | "If I change this provider method, what breaks?" | Group-mode `impact` |
75
+ | "Are all consumers up to date with the latest provider commit?" | `group/<name>/status` resource |
76
+ | "What's the structural diff between last release and now in repo X?" | Per-repo `diff --semantic` |
77
+
78
+ ## Example: "Will renaming `getUserProfile` break my microservices?"
79
+
80
+ ```
81
+ 1. codragraph_group_list({})
82
+ → group "platform": [user-service, web-app, mobile-bff, admin-portal]
83
+
84
+ 2. codragraph_context({repo: "user-service", name: "getUserProfile"})
85
+ → exported gRPC method in user.proto, defined in user-service
86
+
87
+ 3. codragraph_impact({repo: "@platform", target: "getUserProfile", direction: "upstream"})
88
+ → d=1 callers (across the group):
89
+ - web-app/src/api/userClient.ts (CALLS via grpc-web)
90
+ - mobile-bff/internal/user.go (CALLS via grpc.NewClient)
91
+ - admin-portal/src/services/users.tsx (CALLS via grpc-web)
92
+ → 3 consumer repos depend on this method by exact name.
93
+
94
+ 4. READ codragraph://group/platform/contracts
95
+ → user.UserService.getUserProfile: provider=user-service,
96
+ consumers=[web-app, mobile-bff, admin-portal]
97
+
98
+ 5. READ codragraph://group/platform/status
99
+ → web-app last indexed 2 hours ago ✓
100
+ → mobile-bff last indexed 3 days ago ⚠ (might miss recent callers)
101
+ → admin-portal last indexed 1 month ago ⚠⚠ (re-analyze first!)
102
+
103
+ 6. Recommendation:
104
+ - HIGH-RISK rename. 3 consumer repos must change in lockstep.
105
+ - Re-index admin-portal before trusting the d=1 list.
106
+ - Coordinated PR sequence:
107
+ 1. Add new method (getUserProfileV2) in user-service
108
+ 2. Migrate web-app, mobile-bff, admin-portal to V2
109
+ 3. Remove getUserProfile in user-service after all consumers ship
110
+ - Alternative: keep both, deprecate old, drop in next major.
111
+ ```
112
+
113
+ ## Output Format
114
+
115
+ ```markdown
116
+ ## Cross-Repo Impact: `<symbol>` in `<producer-repo>` (group `@<group>`)
117
+
118
+ ### Consumers (d=1)
119
+ | Repo | Caller | Path | Notes |
120
+ | --- | --- | --- | --- |
121
+ | web-app | userClient.ts | grpc-web | active |
122
+ | mobile-bff | internal/user.go | grpc native | active |
123
+ | admin-portal | services/users.tsx | grpc-web | last indexed 1mo ago ⚠ |
124
+
125
+ ### Contracts touching this symbol
126
+ - `user.UserService.getUserProfile` (provider: user-service)
127
+
128
+ ### Staleness
129
+ Re-analyze `admin-portal` before trusting these results.
130
+
131
+ ### Recommended migration sequence
132
+ 1. Add `getUserProfileV2` alongside the old method
133
+ 2. Migrate consumers to V2 (separate PRs per repo)
134
+ 3. Remove old method after all consumers ship
135
+ ```