crg-dev-kit 2.0.1 → 2.0.2

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/lib/analytics.js CHANGED
@@ -156,9 +156,14 @@ function getProjectStats(projectPath) {
156
156
  };
157
157
  }
158
158
 
159
- function getAllStats() {
159
+ function getAllStats(scopeProject) {
160
160
  const sessions = readJSON(SESSIONS_FILE, []);
161
- const completedSessions = sessions.filter(s => s.status === 'completed');
161
+ let completedSessions = sessions.filter(s => s.status === 'completed');
162
+
163
+ if (scopeProject) {
164
+ const resolved = path.resolve(scopeProject);
165
+ completedSessions = completedSessions.filter(s => s.project === resolved);
166
+ }
162
167
 
163
168
  if (completedSessions.length === 0) return null;
164
169
 
package/lib/roi.js CHANGED
@@ -6,10 +6,20 @@ function getInstallDate(projectPath) {
6
6
  const installFile = path.join(ANALYTICS_DIR, 'install.json');
7
7
  try {
8
8
  const data = JSON.parse(fs.readFileSync(installFile, 'utf8'));
9
+ // Support both old format (single object) and new format (keyed by path)
10
+ if (data.projectPath) {
11
+ // Old format: { projectPath, installedAt }
12
+ if (projectPath) return data.projectPath === projectPath ? data.installedAt : null;
13
+ return data.installedAt;
14
+ }
15
+ // New format: { "/path": { installedAt } }
9
16
  if (projectPath) {
10
- return data.projectPath === projectPath ? data.installedAt : null;
17
+ const resolved = path.resolve(projectPath);
18
+ return data[resolved] ? data[resolved].installedAt : null;
11
19
  }
12
- return data.installedAt;
20
+ // Return first entry
21
+ const first = Object.values(data)[0];
22
+ return first ? first.installedAt : null;
13
23
  } catch {
14
24
  return null;
15
25
  }
@@ -18,12 +28,16 @@ function getInstallDate(projectPath) {
18
28
  function setInstallDate(projectPath) {
19
29
  ensureDir();
20
30
  const installFile = path.join(ANALYTICS_DIR, 'install.json');
21
- const record = {
22
- projectPath: projectPath,
23
- installedAt: new Date().toISOString()
24
- };
25
- fs.writeFileSync(installFile, JSON.stringify(record, null, 2));
26
- return record;
31
+ const resolved = path.resolve(projectPath);
32
+ let data = {};
33
+ try { data = JSON.parse(fs.readFileSync(installFile, 'utf8')); } catch {}
34
+ // Migrate old format
35
+ if (data.projectPath) {
36
+ data = { [data.projectPath]: { installedAt: data.installedAt } };
37
+ }
38
+ data[resolved] = { installedAt: new Date().toISOString() };
39
+ fs.writeFileSync(installFile, JSON.stringify(data, null, 2));
40
+ return data[resolved];
27
41
  }
28
42
 
29
43
  function parseHistory(fromDate, toDate) {
@@ -161,11 +175,18 @@ function calculateROI(projectPath) {
161
175
  };
162
176
  }
163
177
 
164
- function getAllProjectsROI() {
178
+ function getAllProjectsROI(scopeProject) {
179
+ if (scopeProject) {
180
+ return calculateROI(scopeProject);
181
+ }
165
182
  const installFile = path.join(ANALYTICS_DIR, 'install.json');
166
183
  try {
167
184
  const installData = JSON.parse(fs.readFileSync(installFile, 'utf8'));
168
- return calculateROI(installData.projectPath);
185
+ // Old format
186
+ if (installData.projectPath) return calculateROI(installData.projectPath);
187
+ // New format — return first
188
+ const first = Object.keys(installData)[0];
189
+ return first ? calculateROI(first) : { error: 'No installation found', installed: false };
169
190
  } catch {
170
191
  return { error: 'No installation found', installed: false };
171
192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crg-dev-kit",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
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
@@ -359,10 +359,10 @@ function tabStatusFragment(statusData) {
359
359
  </section>`;
360
360
  }
361
361
 
362
- function tabAnalytics() {
362
+ function tabAnalytics(cwd) {
363
363
  let roiHtml = '';
364
364
  try {
365
- const roiData = roi.getAllProjectsROI();
365
+ const roiData = roi.getAllProjectsROI(cwd);
366
366
  if (roiData.installed) {
367
367
  const verdictColor = roiData.roi.verdict === 'positive' ? '#16a34a' : roiData.roi.verdict === 'neutral' ? '#ea580c' : '#dc2626';
368
368
  const verdictIcon = roiData.roi.verdict === 'positive' ? '&#10003;' : roiData.roi.verdict === 'neutral' ? '&#8722;' : '&#9888;';
@@ -428,7 +428,7 @@ function tabAnalytics() {
428
428
  }
429
429
 
430
430
  let tokenHtml = '';
431
- const analyticsData = analytics.getAllStats();
431
+ const analyticsData = analytics.getAllStats(cwd);
432
432
  if (analyticsData) {
433
433
  const savingsColor = analyticsData.avgSavingsPercent >= 70 ? '#16a34a' : analyticsData.avgSavingsPercent >= 50 ? '#ea580c' : '#dc2626';
434
434
  tokenHtml = `
@@ -615,7 +615,7 @@ function start(port, noOpen) {
615
615
 
616
616
  } else if (url.pathname === '/tab/analytics') {
617
617
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
618
- res.end(tabAnalytics());
618
+ res.end(tabAnalytics(cwd));
619
619
 
620
620
  } else if (url.pathname === '/tab/tools') {
621
621
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
@@ -667,12 +667,12 @@ function start(port, noOpen) {
667
667
 
668
668
  /* ── Existing JSON API endpoints ────────────────────────────── */
669
669
  } else if (url.pathname === '/api/analytics') {
670
- const data = analytics.getAllStats();
670
+ const data = analytics.getAllStats(cwd);
671
671
  res.writeHead(200, { 'Content-Type': 'application/json' });
672
672
  res.end(JSON.stringify(data || { message: 'No analytics data yet' }));
673
673
 
674
674
  } else if (url.pathname === '/api/roi') {
675
- const data = roi.getAllProjectsROI();
675
+ const data = roi.getAllProjectsROI(cwd);
676
676
  res.writeHead(200, { 'Content-Type': 'application/json' });
677
677
  res.end(JSON.stringify(data));
678
678
 
@@ -776,7 +776,7 @@ function start(port, noOpen) {
776
776
  const url = `http://localhost:${availablePort}`;
777
777
  const portMsg = availablePort !== port ? ` (port ${port} was busy, using ${availablePort})` : '';
778
778
  console.log(`\n \x1b[36mCRG Dev Kit\x1b[0m running at \x1b[1m${url}\x1b[0m${portMsg}\n`);
779
- const analyticsData = analytics.getAllStats();
779
+ const analyticsData = analytics.getAllStats(cwd);
780
780
  if (analyticsData) {
781
781
  console.log(` \x1b[32m${analyticsData.avgSavingsPercent}% avg token savings\x1b[0m across \x1b[1m${analyticsData.totalSessions}\x1b[0m sessions\n`);
782
782
  }