crg-dev-kit 2.0.7 → 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 +135 -30
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crg-dev-kit",
3
- "version": "2.0.7",
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');
@@ -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,9 +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}
264
276
  }
265
277
  @media(prefers-color-scheme:light){
266
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}
267
283
  }
268
284
  @media(max-width:768px){
269
285
  .analytics-grid,.roi-grid{grid-template-columns:repeat(2,1fr)}
@@ -348,31 +364,82 @@ function tabDashboard(cwd) {
348
364
  function tabInstall(cwd) {
349
365
  return `
350
366
  <section>
351
- <div class="st">Install CRG Dev Kit</div>
352
- <p style="color:var(--t2);font-size:14px;margin-bottom:16px">Copy setup scripts, CLAUDE.md, and health check to your project directory.</p>
353
- <div style="margin-bottom:16px">
354
- <label for="install-dir" style="font-size:12px;font-weight:600;color:var(--t3);display:block;margin-bottom:6px">Target Directory</label>
355
- <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>
356
419
  </div>
357
- <div style="display:flex;gap:12px;flex-wrap:wrap">
358
- <button class="btn"
359
- hx-post="/api/install"
360
- hx-target="#install-result"
361
- hx-swap="innerHTML"
362
- hx-include="#install-dir"
363
- hx-indicator="#install-spinner">
364
- Install Files <span id="install-spinner" class="htmx-indicator"><span class="spinner"></span></span>
365
- </button>
366
- <button class="btn btn-danger"
367
- hx-post="/api/uninstall"
368
- hx-target="#install-result"
369
- hx-swap="innerHTML"
370
- hx-include="#install-dir"
371
- hx-indicator="#uninstall-spinner">
372
- Uninstall <span id="uninstall-spinner" class="htmx-indicator"><span class="spinner"></span></span>
373
- </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)}" />
374
424
  </div>
425
+
375
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>
376
443
  </section>`;
377
444
  }
378
445
 
@@ -709,6 +776,41 @@ function start(port, noOpen) {
709
776
  }
710
777
  });
711
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
+
712
814
  } else if (url.pathname === '/api/uninstall' && req.method === 'POST') {
713
815
  readBody(req, res, (data) => {
714
816
  const targetDir = data.targetDir || cwd;
@@ -744,18 +846,21 @@ function start(port, noOpen) {
744
846
 
745
847
  } else if (url.pathname === '/api/report') {
746
848
  const report = analytics.generateReport();
747
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
748
- 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>`);
749
852
 
750
853
  } else if (url.pathname === '/api/roi-report') {
751
854
  const report = roi.generateROIReport(cwd);
752
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
753
- 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>`);
754
858
 
755
859
  } else if (url.pathname === '/api/daily-breakdown') {
756
860
  const breakdown = roi.generateDailyBreakdown();
757
- res.writeHead(200, { 'Content-Type': 'text/markdown' });
758
- res.end(breakdown);
861
+ const html = mdToHtml(breakdown);
862
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
863
+ res.end(`<div class="rc">${html}</div>`);
759
864
 
760
865
  } else if (url.pathname === '/api/session' && req.method === 'POST') {
761
866
  readBody(req, res, (data) => {