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 +78 -48
- package/lib/actions.js +3 -5
- package/package.json +1 -1
- package/server.js +89 -15
package/assets/CLAUDE.md
CHANGED
|
@@ -1,48 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
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
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 —
|
|
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:#
|
|
440
|
-
<div class="roi-label">
|
|
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"
|
|
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">
|
|
628
|
-
<p style="font-size:14px;color:var(--t3);margin-bottom:16px">
|
|
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
|
|
850
|
+
output += `<div class="check-item"><span class="check-pass">✓</span> token-optimizer installed</div>`;
|
|
807
851
|
}
|
|
808
852
|
|
|
809
|
-
|
|
810
|
-
|
|
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);
|