crg-dev-kit 2.1.0 → 2.2.1

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.
package/assets/CLAUDE.md CHANGED
@@ -1,48 +1,78 @@
1
- ## MCP Tools: code-review-graph
2
-
3
- **Graph first, grep second.** Use CRG tools before Grep/Glob/Read — fewer tokens, structural context.
4
-
5
- ### Tools that work (no extras)
6
-
7
- | Tool | When |
8
- |------|------|
9
- | `detect_changes` | Review changes risk-scored, prioritized |
10
- | `get_review_context` | Token-efficient source snippets for review |
11
- | `get_impact_radius` | Blast radius of changed files (2-hop BFS) |
12
- | `query_graph` | 8 patterns: callers_of, callees_of, imports_of, importers_of, children_of, tests_for, inheritors_of, file_summary |
13
- | `semantic_search_nodes` | Find functions/classes by keyword |
14
- | `refactor_tool` | mode=rename (preview+apply), mode=dead_code, mode=suggest |
15
- | `apply_refactor` | Execute previewed rename (10min expiry) |
16
- | `find_large_functions` | Functions/classes over N lines |
17
- | `build_or_update_graph` | Build or refresh the graph |
18
- | `list_graph_stats` | Node/edge counts, health |
19
- | `cross_repo_search` | Search across registered repos |
20
-
21
- ### Tools that need [communities] extra
22
-
23
- | Tool | Note |
24
- |------|------|
25
- | `get_architecture_overview` | **Returns empty without communities — no error** |
26
- | `list_communities` | Use min_size=20 to avoid token overflow |
27
- | `get_community` | include_members=true for deep dive |
28
- | `generate_wiki` | Also needs Ollama running |
29
-
30
- ### Broken in v2.1.0 skip these
31
-
32
- - `get_affected_flows` depends on flows (broken)
33
- - `list_flows` / `get_flow` — trace_flows TypeError bug
34
-
35
- ### Workflow
36
-
37
- 1. Graph auto-updates via hooks on file save.
38
- 2. `detect_changes` for code review.
39
- 3. `query_graph pattern="tests_for"` for coverage check.
40
- 4. `get_impact_radius` before merging.
41
- 5. Fall back to Grep/Glob/Read only when graph doesn't cover it.
42
-
43
- ### Gotchas
44
-
45
- - Communities return 0? Restart AI tool (MCP server caches old env).
46
- - Over-clustered? `list_communities(min_size=20)`.
47
- - Package name is `code-review-graph` NOT `crg`.
48
- - Linux: use pipx, not pip. Extras via `pipx inject`.
1
+ # ${PROJECT_NAME}
2
+
3
+ ## MANDATORY: Use CRG Tools First
4
+
5
+ **CRITICAL: You MUST use code-review-graph (CRG) tools for ALL code exploration. Never use Read/Glob/Grep directly.**
6
+
7
+ ### Required Workflow
8
+
9
+ 1. **Every file read** Use `get_review_context` or `query_graph` first
10
+ 2. **Code review** Use `detect_changes`
11
+ 3. **Finding tests** Use `query_graph pattern="tests_for"`
12
+ 4. **Understanding code** Use `query_graph pattern="callees_of"` or `callers_of"`
13
+ 5. **Impact analysis** Use `get_impact_radius`
14
+
15
+ ### Why This Matters
16
+
17
+ - **CRG**: 6.8x fewer tokens on file reads
18
+ - **token-optimizer**: 95% compression on tool outputs
19
+ - **mem0**: Persistent memory across sessions
20
+ - **Combined**: Up to 49x token reduction + memory that persists
21
+
22
+ ### When You MUST Use CRG
23
+
24
+ | Task | CRG Tool |
25
+ |------|----------|
26
+ | Read any file | `get_review_context` |
27
+ | Find function usages | `query_graph` with callers_of |
28
+ | Find tests for code | `query_graph pattern="tests_for"` |
29
+ | Understand imports | `query_graph pattern="imports_of"` |
30
+ | Review changes | `detect_changes` |
31
+ | See impact radius | `get_impact_radius` |
32
+ | Search code | `semantic_search_nodes` |
33
+
34
+ ### Memory: Log Your Decisions
35
+
36
+ After completing a significant task, log the decision:
37
+ ```
38
+ mem0.add("Added auth middleware. Why: Need rate limiting. Files: auth.js, rate.js. Context: 3 endpoints.")
39
+ ```
40
+
41
+ This builds persistent memory for future sessions.
42
+
43
+ ### Fallback Only If
44
+
45
+ - CRG returns insufficient info
46
+ - File not in graph yet
47
+ - Need very recent changes not yet in graph
48
+
49
+ ### Available Tools
50
+
51
+ ```
52
+ CRG (code-review-graph):
53
+ detect_changes - Risk-scored change review
54
+ get_review_context - Token-efficient snippets
55
+ get_impact_radius - Blast radius analysis
56
+ query_graph - Callers, callees, tests, imports
57
+ semantic_search - Find by meaning
58
+ build_or_update_graph - Refresh graph
59
+ list_graph_stats - Check graph health
60
+
61
+ Memory (mem0):
62
+ mem0.add - Store decision/context
63
+ mem0.search - Retrieve past context
64
+ ```
65
+
66
+ ### Quick Commands
67
+
68
+ ```bash
69
+ # Build graph when new code is added
70
+ code-review-graph build
71
+
72
+ # Check graph stats
73
+ code-review-graph list_graph_stats
74
+ ```
75
+
76
+ ---
77
+
78
+ *This file auto-generated by crg-dev-kit.*
package/lib/actions.js CHANGED
@@ -53,6 +53,9 @@ function install(targetDir, trackROI = true) {
53
53
  }
54
54
  }
55
55
 
56
+ // Don't update global CLAUDE.md - preserve user's custom rules
57
+ // The project CLAUDE.md already has all CRG instructions
58
+
56
59
  if (trackROI) {
57
60
  roi.setInstallDate(targetDir);
58
61
  }
@@ -99,11 +102,9 @@ function uninstall(targetDir) {
99
102
  function healthCheck(targetDir) {
100
103
  const results = [];
101
104
 
102
- // Check graph DB
103
105
  const dbPath = path.join(targetDir, '.code-review-graph', 'graph.db');
104
106
  results.push({ check: 'Graph DB exists', pass: fs.existsSync(dbPath) });
105
107
 
106
- // Check setup files
107
108
  results.push({ check: 'setup-crg.sh present', pass: fs.existsSync(path.join(targetDir, 'setup-crg.sh')) });
108
109
  results.push({ check: 'CLAUDE.md present', pass: fs.existsSync(path.join(targetDir, 'CLAUDE.md')) });
109
110
 
@@ -111,11 +112,8 @@ function healthCheck(targetDir) {
111
112
  execFile('code-review-graph', ['--version'], (err, stdout) => {
112
113
  results.push({ check: 'code-review-graph CLI', pass: !err, version: err ? null : (stdout || '').trim() });
113
114
 
114
- // Try getting graph stats
115
115
  if (fs.existsSync(dbPath)) {
116
116
  try {
117
- const sqlite3 = require('child_process');
118
- // Use python to read SQLite since we can't require sqlite3
119
117
  const cmd = `python3 -c "import sqlite3,json;db=sqlite3.connect('${dbPath}');r=dict(nodes=db.execute('SELECT COUNT(*) FROM nodes').fetchone()[0],edges=db.execute('SELECT COUNT(*) FROM edges').fetchone()[0]);print(json.dumps(r))"`;
120
118
  execFile('bash', ['-c', cmd], (err2, stdout2) => {
121
119
  if (!err2 && stdout2) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crg-dev-kit",
3
- "version": "2.1.0",
3
+ "version": "2.2.1",
4
4
  "description": "One-click setup for code-review-graph — AI-powered codebase knowledge graph with token analytics",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -172,12 +172,13 @@ section{max-width:clamp(320px,90vw,780px);margin:0 auto;padding:0 clamp(16px,4vw
172
172
  .dl-btn{background:var(--a);color:#fff;padding:6px 14px;border-radius:5px;font-size:12px;font-weight:700;flex-shrink:0;transition:background .15s}
173
173
  .dl-card:hover .dl-btn{background:#c2410c}
174
174
  .install-options{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px;margin-bottom:24px}
175
- .install-card{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:20px}
175
+ .install-card{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:20px;display:flex;flex-direction:column}
176
176
  .install-card:hover{border-color:var(--a)}
177
- .install-header{display:flex;gap:12px;align-items:flex-start}
177
+ .install-header{display:flex;gap:12px;align-items:flex-start;margin-bottom:12px}
178
178
  .install-icon{font-size:24px;line-height:1}
179
179
  .install-title{font-weight:700;font-size:15px}
180
180
  .install-desc{font-size:12px;color:var(--t3);margin-top:2px}
181
+ .install-card .btn{margin-top:auto}
181
182
  .rc{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:clamp(16px,3vw,32px)}
182
183
  .rc h1{font-size:22px;font-weight:700;margin-bottom:16px;letter-spacing:-0.02em}
183
184
  .rc h2{font-size:17px;font-weight:700;margin:24px 0 8px}
@@ -243,6 +244,9 @@ footer a{color:var(--a);text-decoration:none;font-weight:600}
243
244
  .tool-name{font-family:var(--m);font-size:11px;color:var(--a);font-weight:600}
244
245
  .tool-label{font-size:14px;font-weight:600;color:var(--t)}
245
246
  .tool-desc{font-size:12px;color:var(--t3);line-height:1.4}
247
+ .btn-tool{background:var(--a);color:#fff;border:none;border-radius:4px;padding:4px 12px;font-size:11px;font-weight:600;cursor:pointer;margin-top:8px;width:100%}
248
+ .btn-tool:hover{background:#c2410c}
249
+ .btn-tool:disabled{opacity:.5;cursor:not-allowed}
246
250
  .btn{background:var(--a);color:#fff;padding:10px 20px;border:none;border-radius:6px;font-weight:700;font-size:13px;cursor:pointer;font-family:inherit;transition:background .15s}
247
251
  .btn:hover{background:#c2410c}
248
252
  .btn:focus-visible{outline:2px solid var(--a);outline-offset:2px}
@@ -366,14 +370,13 @@ function tabInstall(cwd) {
366
370
  <section>
367
371
  <div class="st">Quick Install — Maximum Token Savings</div>
368
372
  <p style="color:var(--t2);font-size:14px;margin-bottom:20px">Install both CRG + token-optimizer-mcp for 95%+ token reduction.</p>
369
-
370
373
  <div class="install-options">
371
374
  <div class="install-card">
372
375
  <div class="install-header">
373
376
  <span class="install-icon">⚡</span>
374
377
  <div>
375
378
  <div class="install-title">Full Stack (Recommended)</div>
376
- <div class="install-desc">CRG + token-optimizer — maximum savings</div>
379
+ <div class="install-desc">CRG + token-optimizer + mem0 95%+ token savings + persistent memory</div>
377
380
  </div>
378
381
  </div>
379
382
  <button class="btn" style="width:100%;margin-top:12px"
@@ -406,7 +409,7 @@ function tabInstall(cwd) {
406
409
  <span class="install-icon">🎯</span>
407
410
  <div>
408
411
  <div class="install-title">token-optimizer Only</div>
409
- <div class="install-desc">Smart caching + compression</div>
412
+ <div class="install-desc">Smart caching + compression for tool outputs</div>
410
413
  </div>
411
414
  </div>
412
415
  <button class="btn btn-secondary" style="width:100%;margin-top:12px"
@@ -416,6 +419,22 @@ function tabInstall(cwd) {
416
419
  Install token-optimizer
417
420
  </button>
418
421
  </div>
422
+
423
+ <div class="install-card">
424
+ <div class="install-header">
425
+ <span class="install-icon">🧠</span>
426
+ <div>
427
+ <div class="install-title">mem0 Only</div>
428
+ <div class="install-desc">Persistent memory layer for sessions</div>
429
+ </div>
430
+ </div>
431
+ <button class="btn btn-secondary" style="width:100%;margin-top:12px"
432
+ hx-post="/api/install-mem0"
433
+ hx-target="#install-result"
434
+ hx-swap="innerHTML">
435
+ Install mem0
436
+ </button>
437
+ </div>
419
438
  </div>
420
439
 
421
440
  <div style="margin-top:24px">
@@ -436,8 +455,8 @@ function tabInstall(cwd) {
436
455
  <div class="roi-label">token-optimizer</div>
437
456
  </div>
438
457
  <div class="roi-card">
439
- <div class="roi-value" style="color:#ea580c">49x</div>
440
- <div class="roi-label">Combined</div>
458
+ <div class="roi-value" style="color:#16a34a">🧠</div>
459
+ <div class="roi-label">mem0 Memory</div>
441
460
  </div>
442
461
  </div>
443
462
  </section>`;
@@ -616,17 +635,31 @@ function tabAnalytics(cwd) {
616
635
  return `<section>${roiHtml}${tokenHtml}</section>`;
617
636
  }
618
637
 
619
- function tabTools() {
638
+ function tabTools(cwd) {
620
639
  const toolCards = CRG_TOOLS.map(t => `
621
- <div class="tool-card" tabindex="0">
640
+ <div class="tool-card">
622
641
  <span class="tool-name">${t.name}</span>
623
642
  <span class="tool-label">${t.label}</span>
624
643
  <span class="tool-desc">${t.desc}</span>
644
+ <button class="btn-tool" onclick="runTool('${t.name}')">Run</button>
625
645
  </div>`).join('');
626
646
  return `<section>
627
- <div class="st">Available Tools</div>
628
- <p style="font-size:14px;color:var(--t3);margin-bottom:16px">These MCP tools are available in your projects after setup. They provide token-efficient code review and analysis.</p>
647
+ <div class="st">CRG Tools</div>
648
+ <p style="font-size:14px;color:var(--t3);margin-bottom:16px">Run tools directly from here. Click Run to execute.</p>
629
649
  <div class="tools-grid">${toolCards}</div>
650
+ <div id="tool-result" style="margin-top:16px"></div>
651
+
652
+ <div class="st" style="margin-top:32px">Graph Actions</div>
653
+ <div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:16px">
654
+ <button class="btn" hx-post="/api/graph/update" hx-target="#graph-result" hx-swap="innerHTML">
655
+ ↻ Rebuild Graph
656
+ </button>
657
+ <button class="btn btn-secondary" hx-get="/api/graph/stats" hx-target="#graph-stats" hx-swap="innerHTML">
658
+ View Stats
659
+ </button>
660
+ </div>
661
+ <div id="graph-result"></div>
662
+ <div id="graph-stats" class="result-box" style="display:none"></div>
630
663
  </section>`;
631
664
  }
632
665
 
@@ -752,7 +785,7 @@ function start(port, noOpen) {
752
785
 
753
786
  } else if (url.pathname === '/tab/tools') {
754
787
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
755
- res.end(tabTools());
788
+ res.end(tabTools(cwd));
756
789
 
757
790
  } else if (url.pathname === '/tab/downloads') {
758
791
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
@@ -787,6 +820,17 @@ function start(port, noOpen) {
787
820
  res.end(`<div class="result-box result-success"><p>✓ token-optimizer-mcp installed globally</p><p style="font-size:13px;color:var(--t3);margin-top:8px">Add to your Claude Code config to activate.</p></div>`);
788
821
  });
789
822
 
823
+ } else if (url.pathname === '/api/install-mem0' && req.method === 'POST') {
824
+ exec('pip install mem0ai 2>&1', (err, stdout, stderr) => {
825
+ if (err) {
826
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
827
+ res.end(`<div class="result-box result-error"><p>Failed to install mem0: ${esc(stderr || err.message)}</p></div>`);
828
+ return;
829
+ }
830
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
831
+ res.end(`<div class="result-box result-success"><p>✓ mem0 installed</p><p style="font-size:13px;color:var(--t3);margin-top:8px">Persistent memory layer ready.</p></div>`);
832
+ });
833
+
790
834
  } else if (url.pathname === '/api/install-fullstack' && req.method === 'POST') {
791
835
  readBody(req, res, (data) => {
792
836
  const targetDir = data.targetDir || cwd;
@@ -803,11 +847,19 @@ function start(port, noOpen) {
803
847
  if (err) {
804
848
  output += `<div class="check-item"><span class="check-fail">✗</span> token-optimizer: ${esc(stderr || err.message)}</div>`;
805
849
  } else {
806
- output += `<div class="check-item"><span class="check-pass">✓</span> token-optimizer-mcp installed</div>`;
850
+ output += `<div class="check-item"><span class="check-pass">✓</span> token-optimizer installed</div>`;
807
851
  }
808
852
 
809
- res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
810
- res.end(`<div class="result-box result-success">${output}<p style="margin-top:16px;font-size:13px;color:var(--t3)">⚡ Both tools installed! Update your .mcp.json to activate token-optimizer.</p></div>`);
853
+ exec('pip install mem0ai 2>&1', (err2, stdout2, stderr2) => {
854
+ if (err2) {
855
+ output += `<div class="check-item"><span class="check-fail">✗</span> mem0: ${esc(stderr2 || err2.message)}</div>`;
856
+ } else {
857
+ output += `<div class="check-item"><span class="check-pass">✓</span> mem0 (memory layer) installed</div>`;
858
+ }
859
+
860
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
861
+ res.end(`<div class="result-box result-success">${output}<p style="margin-top:16px;font-size:13px;color:var(--t3)">⚡ All 3 tools installed! See docs for configuration.</p></div>`);
862
+ });
811
863
  });
812
864
  });
813
865
 
@@ -856,6 +908,28 @@ function start(port, noOpen) {
856
908
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
857
909
  res.end(`<div class="rc">${html}</div>`);
858
910
 
911
+ } else if (url.pathname === '/api/graph/update' && req.method === 'POST') {
912
+ exec('code-review-graph build', { cwd: cwd }, (err, stdout, stderr) => {
913
+ if (err) {
914
+ res.writeHead(200, { 'Content-Type': 'text/html' });
915
+ res.end(`<div class="result-box result-error"><p>Build failed: ${esc(stderr || err.message)}</p></div>`);
916
+ return;
917
+ }
918
+ res.writeHead(200, { 'Content-Type': 'text/html' });
919
+ res.end(`<div class="result-box result-success"><p>✓ Graph updated successfully</p><p style="font-size:12px;color:var(--t3)">${esc(stdout)}</p></div>`);
920
+ });
921
+
922
+ } else if (url.pathname === '/api/graph/stats') {
923
+ exec('code-review-graph list_graph_stats', { cwd: cwd }, (err, stdout, stderr) => {
924
+ if (err) {
925
+ res.writeHead(200, { 'Content-Type': 'text/html' });
926
+ res.end(`<p style="color:var(--t3)">Graph stats unavailable</p>`);
927
+ return;
928
+ }
929
+ res.writeHead(200, { 'Content-Type': 'text/html' });
930
+ res.end(`<pre style="font-family:var(--m);font-size:12px;background:var(--bg);padding:12px;border-radius:6px">${esc(stdout)}</pre>`);
931
+ });
932
+
859
933
  } else if (url.pathname === '/api/daily-breakdown') {
860
934
  const breakdown = roi.generateDailyBreakdown();
861
935
  const html = mdToHtml(breakdown);