crg-dev-kit 2.0.5 → 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 (2) hide show
  1. package/package.json +1 -1
  2. package/server.js +141 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crg-dev-kit",
3
- "version": "2.0.5",
3
+ "version": "2.1.0",
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
@@ -1,7 +1,7 @@
1
1
  const http = require('http');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
- const { execFile } = require('child_process');
4
+ const { execFile, exec } = require('child_process');
5
5
  const analytics = require('./lib/analytics');
6
6
  const roi = require('./lib/roi');
7
7
  const actions = require('./lib/actions');
@@ -124,9 +124,9 @@ function buildPage() {
124
124
  <meta name="description" content="One-click setup for AI-powered code review with knowledge graph">
125
125
  <script src="https://unpkg.com/htmx.org@2.0.4"></script>
126
126
  <style>
127
- @import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&family=JetBrains+Mono:wght@400;500;600&display=swap');
127
+ @import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');
128
128
  *{margin:0;padding:0;box-sizing:border-box}
129
- :root{--bg:#fafaf9;--s:#fff;--b:#e7e5e4;--t:#1c1917;--t2:#57534e;--t3:#78716c;--t4:#a8a29e;--a:#ea580c;--al:#fff7ed;--ab:#fed7aa;--m:'JetBrains Mono',monospace;--f:'DM Sans',sans-serif}
129
+ :root{--bg:#fafaf9;--s:#fff;--b:#e7e5e4;--t:#1c1917;--t2:#57534e;--t3:#78716c;--t4:#a8a29e;--a:#ea580c;--al:#fff7ed;--ab:#fed7aa;--m:'JetBrains Mono',monospace;--f:'DM Sans',system-ui,-apple-system,sans-serif}
130
130
  body{font-family:var(--f);background:var(--bg);color:var(--t);line-height:1.5;-webkit-font-smoothing:antialiased}
131
131
  .skip-link{position:absolute;left:-9999px;top:0;background:var(--a);color:#fff;padding:8px 16px;z-index:999}
132
132
  .skip-link:focus{left:0}
@@ -171,6 +171,13 @@ section{max-width:clamp(320px,90vw,780px);margin:0 auto;padding:0 clamp(16px,4vw
171
171
  .dl-size{font-family:var(--m);font-size:11px;color:var(--t4);flex-shrink:0}
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
+ .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}
176
+ .install-card:hover{border-color:var(--a)}
177
+ .install-header{display:flex;gap:12px;align-items:flex-start}
178
+ .install-icon{font-size:24px;line-height:1}
179
+ .install-title{font-weight:700;font-size:15px}
180
+ .install-desc{font-size:12px;color:var(--t3);margin-top:2px}
174
181
  .rc{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:clamp(16px,3vw,32px)}
175
182
  .rc h1{font-size:22px;font-weight:700;margin-bottom:16px;letter-spacing:-0.02em}
176
183
  .rc h2{font-size:17px;font-weight:700;margin:24px 0 8px}
@@ -245,7 +252,7 @@ footer a{color:var(--a);text-decoration:none;font-weight:600}
245
252
  .btn-secondary{background:var(--bg);color:var(--t2);border:1px solid var(--b)}
246
253
  .check-pass{color:#16a34a}
247
254
  .check-fail{color:#dc2626}
248
- .check-item{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid var(--b)}
255
+ .check-item{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid var(--b);color:var(--t)}
249
256
  .check-item:last-child{border-bottom:none}
250
257
  .result-box{background:var(--s);border:1px solid var(--b);border-radius:8px;padding:20px;margin-top:16px}
251
258
  .result-success{border-color:#16a34a;background:#f0fdf4}
@@ -261,6 +268,18 @@ footer a{color:var(--a);text-decoration:none;font-weight:600}
261
268
  @media(prefers-color-scheme:dark){
262
269
  :root{--bg:#1c1917;--s:#292524;--b:#44403c;--t:#fafaf9;--t2:#d6d3d1;--t3:#a8a29e;--t4:#78716c;--al:#292524;--ab:#44403c}
263
270
  .dl-card:hover,.roi-card,.stat-card,.tool-card,.project-table table,.roi-compare{background:var(--s)}
271
+ .result-box{background:var(--s)}
272
+ .result-success{background:#16653420;border-color:#22c55e}
273
+ .result-error{background:#991b1b20;border-color:#ef4444}
274
+ .check-pass{color:#22c55e}
275
+ .check-fail{color:#ef4444}
276
+ }
277
+ @media(prefers-color-scheme:light){
278
+ :root{--bg:#fafaf9;--s:#fff;--b:#e7e5e4;--t:#1c1917;--t2:#57534e;--t3:#78716c;--t4:#a8a29e;--al:#fff7ed;--ab:#fed7aa}
279
+ .result-success{background:#f0fdf4;border-color:#16a34a}
280
+ .result-error{background:#fef2f2;border-color:#dc2626}
281
+ .check-pass{color:#16a34a}
282
+ .check-fail{color:#dc2626}
264
283
  }
265
284
  @media(max-width:768px){
266
285
  .analytics-grid,.roi-grid{grid-template-columns:repeat(2,1fr)}
@@ -345,31 +364,82 @@ function tabDashboard(cwd) {
345
364
  function tabInstall(cwd) {
346
365
  return `
347
366
  <section>
348
- <div class="st">Install CRG Dev Kit</div>
349
- <p style="color:var(--t2);font-size:14px;margin-bottom:16px">Copy setup scripts, CLAUDE.md, and health check to your project directory.</p>
350
- <div style="margin-bottom:16px">
351
- <label for="install-dir" style="font-size:12px;font-weight:600;color:var(--t3);display:block;margin-bottom:6px">Target Directory</label>
352
- <input class="input" id="install-dir" name="targetDir" value="${esc(cwd)}" />
367
+ <div class="st">Quick Install Maximum Token Savings</div>
368
+ <p style="color:var(--t2);font-size:14px;margin-bottom:20px">Install both CRG + token-optimizer-mcp for 95%+ token reduction.</p>
369
+
370
+ <div class="install-options">
371
+ <div class="install-card">
372
+ <div class="install-header">
373
+ <span class="install-icon">⚡</span>
374
+ <div>
375
+ <div class="install-title">Full Stack (Recommended)</div>
376
+ <div class="install-desc">CRG + token-optimizer — maximum savings</div>
377
+ </div>
378
+ </div>
379
+ <button class="btn" style="width:100%;margin-top:12px"
380
+ hx-post="/api/install-fullstack"
381
+ hx-target="#install-result"
382
+ hx-swap="innerHTML">
383
+ Install Full Stack
384
+ </button>
385
+ </div>
386
+
387
+ <div class="install-card">
388
+ <div class="install-header">
389
+ <span class="install-icon">📊</span>
390
+ <div>
391
+ <div class="install-title">CRG Only</div>
392
+ <div class="install-desc">Knowledge graph — reads less, understands more</div>
393
+ </div>
394
+ </div>
395
+ <button class="btn btn-secondary" style="width:100%;margin-top:12px"
396
+ hx-post="/api/install"
397
+ hx-target="#install-result"
398
+ hx-swap="innerHTML"
399
+ hx-include="#install-dir">
400
+ Install CRG Only
401
+ </button>
402
+ </div>
403
+
404
+ <div class="install-card">
405
+ <div class="install-header">
406
+ <span class="install-icon">🎯</span>
407
+ <div>
408
+ <div class="install-title">token-optimizer Only</div>
409
+ <div class="install-desc">Smart caching + compression</div>
410
+ </div>
411
+ </div>
412
+ <button class="btn btn-secondary" style="width:100%;margin-top:12px"
413
+ hx-post="/api/install-optimizer"
414
+ hx-target="#install-result"
415
+ hx-swap="innerHTML">
416
+ Install token-optimizer
417
+ </button>
418
+ </div>
353
419
  </div>
354
- <div style="display:flex;gap:12px;flex-wrap:wrap">
355
- <button class="btn"
356
- hx-post="/api/install"
357
- hx-target="#install-result"
358
- hx-swap="innerHTML"
359
- hx-include="#install-dir"
360
- hx-indicator="#install-spinner">
361
- Install Files <span id="install-spinner" class="htmx-indicator"><span class="spinner"></span></span>
362
- </button>
363
- <button class="btn btn-danger"
364
- hx-post="/api/uninstall"
365
- hx-target="#install-result"
366
- hx-swap="innerHTML"
367
- hx-include="#install-dir"
368
- hx-indicator="#uninstall-spinner">
369
- Uninstall <span id="uninstall-spinner" class="htmx-indicator"><span class="spinner"></span></span>
370
- </button>
420
+
421
+ <div style="margin-top:24px">
422
+ <label for="install-dir" style="font-size:12px;font-weight:600;color:var(--t3);display:block;margin-bottom:6px">Target Directory (for CRG files)</label>
423
+ <input class="input" id="install-dir" name="targetDir" value="${esc(cwd)}" />
371
424
  </div>
425
+
372
426
  <div id="install-result"></div>
427
+
428
+ <div class="st" style="margin-top:32px">Why Full Stack?</div>
429
+ <div class="roi-grid" style="grid-template-columns:repeat(3,1fr)">
430
+ <div class="roi-card">
431
+ <div class="roi-value" style="color:#16a34a">6.8x</div>
432
+ <div class="roi-label">CRG Reduction</div>
433
+ </div>
434
+ <div class="roi-card">
435
+ <div class="roi-value" style="color:#16a34a">95%</div>
436
+ <div class="roi-label">token-optimizer</div>
437
+ </div>
438
+ <div class="roi-card">
439
+ <div class="roi-value" style="color:#ea580c">49x</div>
440
+ <div class="roi-label">Combined</div>
441
+ </div>
442
+ </div>
373
443
  </section>`;
374
444
  }
375
445
 
@@ -706,6 +776,41 @@ function start(port, noOpen) {
706
776
  }
707
777
  });
708
778
 
779
+ } else if (url.pathname === '/api/install-optimizer' && req.method === 'POST') {
780
+ exec('npm install -g token-optimizer-mcp', (err, stdout, stderr) => {
781
+ if (err) {
782
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
783
+ res.end(`<div class="result-box result-error"><p>Failed to install: ${esc(stderr || err.message)}</p></div>`);
784
+ return;
785
+ }
786
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
787
+ 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
+ });
789
+
790
+ } else if (url.pathname === '/api/install-fullstack' && req.method === 'POST') {
791
+ readBody(req, res, (data) => {
792
+ const targetDir = data.targetDir || cwd;
793
+ let output = '';
794
+
795
+ try {
796
+ const crgResult = actions.install(targetDir);
797
+ output += `<div class="check-item"><span class="check-pass">✓</span> CRG installed (${crgResult.copied} files)</div>`;
798
+ } catch (err) {
799
+ output += `<div class="check-item"><span class="check-fail">✗</span> CRG: ${esc(err.message)}</div>`;
800
+ }
801
+
802
+ exec('npm install -g token-optimizer-mcp', (err, stdout, stderr) => {
803
+ if (err) {
804
+ output += `<div class="check-item"><span class="check-fail">✗</span> token-optimizer: ${esc(stderr || err.message)}</div>`;
805
+ } else {
806
+ output += `<div class="check-item"><span class="check-pass">✓</span> token-optimizer-mcp installed</div>`;
807
+ }
808
+
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>`);
811
+ });
812
+ });
813
+
709
814
  } else if (url.pathname === '/api/uninstall' && req.method === 'POST') {
710
815
  readBody(req, res, (data) => {
711
816
  const targetDir = data.targetDir || cwd;
@@ -741,18 +846,21 @@ function start(port, noOpen) {
741
846
 
742
847
  } else if (url.pathname === '/api/report') {
743
848
  const report = analytics.generateReport();
744
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
745
- res.end(report);
849
+ const html = mdToHtml(report);
850
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
851
+ res.end(`<div class="rc">${html}</div>`);
746
852
 
747
853
  } else if (url.pathname === '/api/roi-report') {
748
854
  const report = roi.generateROIReport(cwd);
749
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
750
- res.end(report);
855
+ const html = mdToHtml(report);
856
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
857
+ res.end(`<div class="rc">${html}</div>`);
751
858
 
752
859
  } else if (url.pathname === '/api/daily-breakdown') {
753
- const breakdown = analytics.generateDailyBreakdown(cwd);
754
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
755
- res.end(breakdown);
860
+ const breakdown = roi.generateDailyBreakdown();
861
+ const html = mdToHtml(breakdown);
862
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
863
+ res.end(`<div class="rc">${html}</div>`);
756
864
 
757
865
  } else if (url.pathname === '/api/session' && req.method === 'POST') {
758
866
  readBody(req, res, (data) => {