@boshu2/vibe-check 1.6.2 → 1.8.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.
- package/.agents/bundles/actionable-coaching-plan-2025-12-02.md +209 -0
- package/.agents/bundles/automatic-learning-cadence-plan-2025-12-02.md +1297 -0
- package/.agents/bundles/automatic-learning-cadence-research-2025-12-02.md +481 -0
- package/.agents/bundles/dashboard-data-quality-plan.md +458 -0
- package/.agents/bundles/rating-scoring-alignment-plan.md +427 -0
- package/.agents/bundles/rpi-session-capture-plan-2025-12-02.md +693 -0
- package/.agents/bundles/rpi-session-capture-research-2025-12-02.md +433 -0
- package/.agents/bundles/session-integration-plan-2025-12-02.md +144 -0
- package/.agents/plans/git-forensics-enhancement-2025-12-05.md +493 -0
- package/.claude/skills/typescript-review.md +152 -0
- package/CHANGELOG.md +53 -0
- package/CLAUDE.md +79 -3
- package/Makefile +160 -0
- package/README.md +141 -155
- package/SECURITY.md +5 -1
- package/assets/logo-dark.svg +47 -0
- package/assets/logo.svg +47 -0
- package/claude-progress.json +54 -4
- package/claude-progress.txt +114 -0
- package/dashboard/app.js +699 -66
- package/dashboard/chart.min.js +20 -0
- package/dashboard/dashboard-data.js +764 -0
- package/dashboard/dashboard-data.json +182 -71
- package/dashboard/index.html +139 -14
- package/dashboard/styles.css +579 -4
- package/dist/analyzers/patterns.d.ts +62 -0
- package/dist/analyzers/patterns.d.ts.map +1 -0
- package/dist/analyzers/patterns.js +103 -0
- package/dist/analyzers/patterns.js.map +1 -0
- package/dist/analyzers/quality.d.ts +58 -0
- package/dist/analyzers/quality.d.ts.map +1 -0
- package/dist/analyzers/quality.js +114 -0
- package/dist/analyzers/quality.js.map +1 -0
- package/dist/analyzers/sessions.d.ts +45 -0
- package/dist/analyzers/sessions.d.ts.map +1 -0
- package/dist/analyzers/sessions.js +123 -0
- package/dist/analyzers/sessions.js.map +1 -0
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +43 -2
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/dashboard.js +4 -1
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/forensics.d.ts +29 -0
- package/dist/commands/forensics.d.ts.map +1 -0
- package/dist/commands/forensics.js +213 -0
- package/dist/commands/forensics.js.map +1 -0
- package/dist/commands/index.d.ts +5 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +13 -3
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/insights.d.ts +3 -0
- package/dist/commands/insights.d.ts.map +1 -0
- package/dist/commands/insights.js +120 -0
- package/dist/commands/insights.js.map +1 -0
- package/dist/commands/learn.d.ts +3 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +161 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/lesson.d.ts +8 -0
- package/dist/commands/lesson.d.ts.map +1 -0
- package/dist/commands/lesson.js +206 -0
- package/dist/commands/lesson.js.map +1 -0
- package/dist/commands/pipeline.d.ts +3 -0
- package/dist/commands/pipeline.d.ts.map +1 -0
- package/dist/commands/pipeline.js +485 -0
- package/dist/commands/pipeline.js.map +1 -0
- package/dist/commands/profile.d.ts +0 -1
- package/dist/commands/profile.d.ts.map +1 -1
- package/dist/commands/profile.js +3 -206
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/session.d.ts +51 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +599 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/sessions.d.ts +20 -0
- package/dist/commands/sessions.d.ts.map +1 -0
- package/dist/commands/sessions.js +201 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +48 -7
- package/dist/commands/watch.js.map +1 -1
- package/dist/gamification/index.d.ts +1 -3
- package/dist/gamification/index.d.ts.map +1 -1
- package/dist/gamification/index.js +2 -5
- package/dist/gamification/index.js.map +1 -1
- package/dist/gamification/pattern-memory.d.ts +1 -1
- package/dist/gamification/pattern-memory.d.ts.map +1 -1
- package/dist/gamification/pattern-memory.js.map +1 -1
- package/dist/gamification/profile.d.ts +2 -2
- package/dist/gamification/profile.d.ts.map +1 -1
- package/dist/gamification/profile.js +2 -15
- package/dist/gamification/profile.js.map +1 -1
- package/dist/gamification/types.d.ts +8 -2
- package/dist/gamification/types.d.ts.map +1 -1
- package/dist/gamification/types.js.map +1 -1
- package/dist/insights/index.d.ts.map +1 -1
- package/dist/insights/index.js +16 -4
- package/dist/insights/index.js.map +1 -1
- package/dist/insights/types.d.ts +14 -0
- package/dist/insights/types.d.ts.map +1 -1
- package/dist/learning/cadence.d.ts +15 -0
- package/dist/learning/cadence.d.ts.map +1 -0
- package/dist/learning/cadence.js +130 -0
- package/dist/learning/cadence.js.map +1 -0
- package/dist/learning/index.d.ts +19 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +35 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/lessons-storage.d.ts +48 -0
- package/dist/learning/lessons-storage.d.ts.map +1 -0
- package/dist/learning/lessons-storage.js +266 -0
- package/dist/learning/lessons-storage.js.map +1 -0
- package/dist/learning/lessons-types.d.ts +83 -0
- package/dist/learning/lessons-types.d.ts.map +1 -0
- package/dist/learning/lessons-types.js +15 -0
- package/dist/learning/lessons-types.js.map +1 -0
- package/dist/learning/nudges.d.ts +20 -0
- package/dist/learning/nudges.d.ts.map +1 -0
- package/dist/learning/nudges.js +68 -0
- package/dist/learning/nudges.js.map +1 -0
- package/dist/learning/retrospective.d.ts +27 -0
- package/dist/learning/retrospective.d.ts.map +1 -0
- package/dist/learning/retrospective.js +184 -0
- package/dist/learning/retrospective.js.map +1 -0
- package/dist/learning/storage.d.ts +44 -0
- package/dist/learning/storage.d.ts.map +1 -0
- package/dist/learning/storage.js +194 -0
- package/dist/learning/storage.js.map +1 -0
- package/dist/learning/surfacing.d.ts +36 -0
- package/dist/learning/surfacing.d.ts.map +1 -0
- package/dist/learning/surfacing.js +255 -0
- package/dist/learning/surfacing.js.map +1 -0
- package/dist/learning/synthesis.d.ts +17 -0
- package/dist/learning/synthesis.d.ts.map +1 -0
- package/dist/learning/synthesis.js +293 -0
- package/dist/learning/synthesis.js.map +1 -0
- package/dist/learning/types.d.ts +60 -0
- package/dist/learning/types.d.ts.map +1 -0
- package/dist/learning/types.js +17 -0
- package/dist/learning/types.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +11 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/spiral-history.d.ts +62 -0
- package/dist/storage/spiral-history.d.ts.map +1 -0
- package/dist/storage/spiral-history.js +265 -0
- package/dist/storage/spiral-history.js.map +1 -0
- package/docs/ARCHITECTURE.md +2 -10
- package/docs/GAMIFICATION.md +19 -266
- package/docs/METRICS.md +528 -0
- package/docs/VIBE-ECOSYSTEM.md +12 -78
- package/feature-list.json +141 -68
- package/package.json +1 -1
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
# Dashboard Data Quality Fixes - Implementation Plan
|
|
2
|
+
|
|
3
|
+
**Type:** Plan
|
|
4
|
+
**Created:** 2025-11-30
|
|
5
|
+
**Loop:** Middle (bridges analysis to implementation)
|
|
6
|
+
**Tags:** dashboard, data-quality, metrics, rating
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Fix data quality issues in vibe-check dashboard:
|
|
13
|
+
1. **Rating system mismatch** - ELITE rating shows for low scores (63%)
|
|
14
|
+
2. **Mock data in visualizations** - Radar chart uses hardcoded values
|
|
15
|
+
3. **Missing metric context** - Session records don't store actual metrics
|
|
16
|
+
|
|
17
|
+
## Root Cause Analysis
|
|
18
|
+
|
|
19
|
+
### Issue 1: Rating vs Score Disconnect
|
|
20
|
+
|
|
21
|
+
**Finding:** The `overall` rating (ELITE/HIGH/MEDIUM/LOW) is calculated from **metric ratings**, not the vibeScore percentage.
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// src/metrics/index.ts:96-111
|
|
25
|
+
function calculateOverallRating(ratings: Rating[]): OverallRating {
|
|
26
|
+
const scores = { elite: 4, high: 3, medium: 2, low: 1 };
|
|
27
|
+
const avgScore = ratings.reduce((sum, r) => sum + scores[r], 0) / ratings.length;
|
|
28
|
+
|
|
29
|
+
if (avgScore >= 3.5) return 'ELITE'; // 5 metrics averaging 3.5+
|
|
30
|
+
// ...
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Meanwhile, `vibeScore` is calculated separately from semantic-free metrics (fileChurn, timeSpiral, etc.).
|
|
35
|
+
|
|
36
|
+
**Result:** A session can have vibeScore=63% but rating=ELITE if the individual metric ratings (velocity, rework, trust, spirals, flow) all score well.
|
|
37
|
+
|
|
38
|
+
**Decision:** This is actually **correct by design**. The vibeScore is a different measure than the overall rating. The issue is **display confusion** - we should clarify this in the UI.
|
|
39
|
+
|
|
40
|
+
### Issue 2: Mock Data in Radar Chart
|
|
41
|
+
|
|
42
|
+
**Finding:** The main radar chart in `app.js:380-391` uses hardcoded mock data:
|
|
43
|
+
```javascript
|
|
44
|
+
data: [92, 78, 85, 88, 95], // NOT REAL DATA
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
And the session detail modal calculates fake metrics:
|
|
48
|
+
```javascript
|
|
49
|
+
const velocity = Math.round(session.commits / 2); // fake
|
|
50
|
+
const trustRate = Math.max(0, 100 - (session.spirals * 10)); // fake
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Solution:** We need to either:
|
|
54
|
+
1. Store real metrics in SessionRecord (schema change)
|
|
55
|
+
2. Re-calculate metrics from commits when building dashboard data
|
|
56
|
+
|
|
57
|
+
Option 2 is simpler and maintains backward compatibility.
|
|
58
|
+
|
|
59
|
+
### Issue 3: Session Record Missing Metrics
|
|
60
|
+
|
|
61
|
+
**Finding:** `SessionRecord` in types stores minimal data:
|
|
62
|
+
```typescript
|
|
63
|
+
interface SessionRecord {
|
|
64
|
+
vibeScore: number;
|
|
65
|
+
overall: string;
|
|
66
|
+
commits: number;
|
|
67
|
+
spirals: number;
|
|
68
|
+
xpEarned: number;
|
|
69
|
+
// NO: iterationVelocity, reworkRatio, trustPassRate, flowEfficiency
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Solution:** Enhance SessionRecord to include metrics, and update dashboard to use them.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Implementation Plan
|
|
78
|
+
|
|
79
|
+
### Phase 1: Enhance SessionRecord (Store Real Metrics)
|
|
80
|
+
|
|
81
|
+
#### File: `src/gamification/types.ts:38-49`
|
|
82
|
+
|
|
83
|
+
**Before:**
|
|
84
|
+
```typescript
|
|
85
|
+
export interface SessionRecord {
|
|
86
|
+
date: string;
|
|
87
|
+
timestamp: string;
|
|
88
|
+
vibeScore: number;
|
|
89
|
+
overall: 'ELITE' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
90
|
+
commits: number;
|
|
91
|
+
spirals: number;
|
|
92
|
+
xpEarned: number;
|
|
93
|
+
achievementsUnlocked: string[];
|
|
94
|
+
periodFrom?: string;
|
|
95
|
+
periodTo?: string;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**After:**
|
|
100
|
+
```typescript
|
|
101
|
+
export interface SessionRecord {
|
|
102
|
+
date: string;
|
|
103
|
+
timestamp: string;
|
|
104
|
+
vibeScore: number;
|
|
105
|
+
overall: 'ELITE' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
106
|
+
commits: number;
|
|
107
|
+
spirals: number;
|
|
108
|
+
xpEarned: number;
|
|
109
|
+
achievementsUnlocked: string[];
|
|
110
|
+
periodFrom?: string;
|
|
111
|
+
periodTo?: string;
|
|
112
|
+
// NEW: Store actual metric values for dashboard
|
|
113
|
+
metrics?: {
|
|
114
|
+
iterationVelocity: number; // commits/hour
|
|
115
|
+
reworkRatio: number; // % fix commits
|
|
116
|
+
trustPassRate: number; // % commits without immediate fix
|
|
117
|
+
flowEfficiency: number; // % time building vs debugging
|
|
118
|
+
debugSpiralDuration: number; // avg minutes in spirals
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Validation:** TypeScript compile, existing sessions still load (metrics optional)
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Phase 2: Record Metrics During Analysis
|
|
128
|
+
|
|
129
|
+
#### File: `src/gamification/profile.ts` - `recordSession` function
|
|
130
|
+
|
|
131
|
+
**Find the recordSession function and add metrics parameter.**
|
|
132
|
+
|
|
133
|
+
**Before (around line 130):**
|
|
134
|
+
```typescript
|
|
135
|
+
export function recordSession(
|
|
136
|
+
vibeScore: number,
|
|
137
|
+
overall: OverallRating,
|
|
138
|
+
commits: number,
|
|
139
|
+
spirals: number
|
|
140
|
+
): { profile: UserProfile; achievements: Achievement[] } {
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**After:**
|
|
144
|
+
```typescript
|
|
145
|
+
export interface RecordSessionOptions {
|
|
146
|
+
vibeScore: number;
|
|
147
|
+
overall: OverallRating;
|
|
148
|
+
commits: number;
|
|
149
|
+
spirals: number;
|
|
150
|
+
metrics?: {
|
|
151
|
+
iterationVelocity: number;
|
|
152
|
+
reworkRatio: number;
|
|
153
|
+
trustPassRate: number;
|
|
154
|
+
flowEfficiency: number;
|
|
155
|
+
debugSpiralDuration: number;
|
|
156
|
+
};
|
|
157
|
+
periodFrom?: string;
|
|
158
|
+
periodTo?: string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function recordSession(
|
|
162
|
+
options: RecordSessionOptions
|
|
163
|
+
): { profile: UserProfile; achievements: Achievement[] } {
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Then update the session creation to include metrics.**
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### Phase 3: Pass Metrics from Analyze Command
|
|
171
|
+
|
|
172
|
+
#### File: `src/commands/analyze.ts` - around line 240
|
|
173
|
+
|
|
174
|
+
**Find where recordGamificationSession is called and pass metrics.**
|
|
175
|
+
|
|
176
|
+
**Before:**
|
|
177
|
+
```typescript
|
|
178
|
+
recordGamificationSession(
|
|
179
|
+
Math.round(vibeScoreValue * 100),
|
|
180
|
+
result.overall,
|
|
181
|
+
commits.length,
|
|
182
|
+
spiralCount
|
|
183
|
+
);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**After:**
|
|
187
|
+
```typescript
|
|
188
|
+
recordGamificationSession({
|
|
189
|
+
vibeScore: Math.round(vibeScoreValue * 100),
|
|
190
|
+
overall: result.overall,
|
|
191
|
+
commits: commits.length,
|
|
192
|
+
spirals: spiralCount,
|
|
193
|
+
metrics: {
|
|
194
|
+
iterationVelocity: result.metrics.iterationVelocity.value,
|
|
195
|
+
reworkRatio: result.metrics.reworkRatio.value,
|
|
196
|
+
trustPassRate: result.metrics.trustPassRate.value,
|
|
197
|
+
flowEfficiency: result.metrics.flowEfficiency.value,
|
|
198
|
+
debugSpiralDuration: result.metrics.debugSpiralDuration.value,
|
|
199
|
+
},
|
|
200
|
+
periodFrom: result.period.from.toISOString(),
|
|
201
|
+
periodTo: result.period.to.toISOString(),
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
### Phase 4: Update Dashboard Data Builder
|
|
208
|
+
|
|
209
|
+
#### File: `src/insights/index.ts` - `buildDashboardData` function
|
|
210
|
+
|
|
211
|
+
**Update sessions mapping to include metrics (around line 192):**
|
|
212
|
+
|
|
213
|
+
**Before:**
|
|
214
|
+
```typescript
|
|
215
|
+
sessions: sessions.slice(-50).reverse().map(s => ({
|
|
216
|
+
date: s.date,
|
|
217
|
+
vibeScore: s.vibeScore,
|
|
218
|
+
rating: s.overall,
|
|
219
|
+
commits: s.commits,
|
|
220
|
+
spirals: s.spirals,
|
|
221
|
+
xpEarned: s.xpEarned,
|
|
222
|
+
})),
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**After:**
|
|
226
|
+
```typescript
|
|
227
|
+
sessions: sessions.slice(-50).reverse().map(s => ({
|
|
228
|
+
date: s.date,
|
|
229
|
+
vibeScore: s.vibeScore,
|
|
230
|
+
rating: s.overall,
|
|
231
|
+
commits: s.commits,
|
|
232
|
+
spirals: s.spirals,
|
|
233
|
+
xpEarned: s.xpEarned,
|
|
234
|
+
metrics: s.metrics || null,
|
|
235
|
+
})),
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Also add aggregate metrics for the main radar chart:**
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
// Calculate average metrics from recent sessions
|
|
242
|
+
const recentWithMetrics = sessions.filter(s => s.metrics).slice(-10);
|
|
243
|
+
const avgMetrics = recentWithMetrics.length > 0 ? {
|
|
244
|
+
iterationVelocity: avg(recentWithMetrics.map(s => s.metrics!.iterationVelocity)),
|
|
245
|
+
reworkRatio: avg(recentWithMetrics.map(s => s.metrics!.reworkRatio)),
|
|
246
|
+
trustPassRate: avg(recentWithMetrics.map(s => s.metrics!.trustPassRate)),
|
|
247
|
+
flowEfficiency: avg(recentWithMetrics.map(s => s.metrics!.flowEfficiency)),
|
|
248
|
+
debugSpiralDuration: avg(recentWithMetrics.map(s => s.metrics!.debugSpiralDuration)),
|
|
249
|
+
} : null;
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Add to charts section:
|
|
253
|
+
```typescript
|
|
254
|
+
charts: {
|
|
255
|
+
scoreTrend,
|
|
256
|
+
ratingDistribution,
|
|
257
|
+
hourlyActivity,
|
|
258
|
+
scopeHealth,
|
|
259
|
+
avgMetrics, // NEW
|
|
260
|
+
},
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Phase 5: Update Dashboard UI to Use Real Metrics
|
|
266
|
+
|
|
267
|
+
#### File: `dashboard/app.js` - `initRadarChart` function (line 374)
|
|
268
|
+
|
|
269
|
+
**Before:**
|
|
270
|
+
```javascript
|
|
271
|
+
// Mock metrics data
|
|
272
|
+
this.charts.radar = new Chart(ctx, {
|
|
273
|
+
type: 'radar',
|
|
274
|
+
data: {
|
|
275
|
+
labels: ['Trust Pass', 'Velocity', 'Flow', 'Stability', 'No Spirals'],
|
|
276
|
+
datasets: [{
|
|
277
|
+
label: 'Current',
|
|
278
|
+
data: [92, 78, 85, 88, 95], // HARDCODED
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**After:**
|
|
282
|
+
```javascript
|
|
283
|
+
initRadarChart() {
|
|
284
|
+
const canvas = document.getElementById('radarCanvas');
|
|
285
|
+
if (!canvas) return;
|
|
286
|
+
const ctx = canvas.getContext('2d');
|
|
287
|
+
if (!ctx) return;
|
|
288
|
+
|
|
289
|
+
// Use real metrics from dashboard data, or defaults
|
|
290
|
+
const metrics = this.dashboardData?.charts?.avgMetrics;
|
|
291
|
+
const data = metrics ? [
|
|
292
|
+
Math.min(100, metrics.trustPassRate),
|
|
293
|
+
Math.min(100, metrics.iterationVelocity * 10), // scale velocity to 0-100
|
|
294
|
+
Math.min(100, metrics.flowEfficiency),
|
|
295
|
+
Math.max(0, 100 - metrics.reworkRatio), // invert: lower rework = higher score
|
|
296
|
+
Math.max(0, 100 - metrics.debugSpiralDuration * 2), // scale spirals
|
|
297
|
+
] : [80, 80, 80, 80, 80]; // default if no data
|
|
298
|
+
|
|
299
|
+
this.charts.radar = new Chart(ctx, {
|
|
300
|
+
// ...
|
|
301
|
+
datasets: [{
|
|
302
|
+
label: 'Average',
|
|
303
|
+
data: data,
|
|
304
|
+
// ...
|
|
305
|
+
}]
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### Phase 6: Update Session Detail Modal
|
|
313
|
+
|
|
314
|
+
#### File: `dashboard/app.js` - `showSessionDetail` function (line 843)
|
|
315
|
+
|
|
316
|
+
**Before:**
|
|
317
|
+
```javascript
|
|
318
|
+
// Calculate derived metrics (mock values based on score)
|
|
319
|
+
const velocity = Math.round(session.commits / 2);
|
|
320
|
+
const trustRate = Math.max(0, 100 - (session.spirals * 10));
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**After:**
|
|
324
|
+
```javascript
|
|
325
|
+
// Use real metrics if available, otherwise estimate
|
|
326
|
+
const metrics = session.metrics;
|
|
327
|
+
const velocity = metrics?.iterationVelocity?.toFixed(1) || `~${Math.round(session.commits / 2)}`;
|
|
328
|
+
const trustRate = metrics?.trustPassRate?.toFixed(0) || Math.max(0, 100 - (session.spirals * 10));
|
|
329
|
+
const reworkRatio = metrics?.reworkRatio?.toFixed(0) || '--';
|
|
330
|
+
const flowEff = metrics?.flowEfficiency?.toFixed(0) || '--';
|
|
331
|
+
|
|
332
|
+
document.getElementById('detailVelocity').textContent = `${velocity}/hr`;
|
|
333
|
+
document.getElementById('detailTrust').textContent = `${trustRate}%`;
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
### Phase 7: Add Clarification to UI
|
|
339
|
+
|
|
340
|
+
#### File: `dashboard/index.html` - Stats card section
|
|
341
|
+
|
|
342
|
+
Add tooltip or subtitle explaining the difference:
|
|
343
|
+
|
|
344
|
+
**Before:**
|
|
345
|
+
```html
|
|
346
|
+
<span class="stat-label">Current Vibe Score</span>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**After:**
|
|
350
|
+
```html
|
|
351
|
+
<span class="stat-label">Current Vibe Score</span>
|
|
352
|
+
<span class="stat-hint" title="Code pattern health (0-100%)">Pattern Score</span>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Add CSS for hint:
|
|
356
|
+
```css
|
|
357
|
+
.stat-hint {
|
|
358
|
+
font-size: 0.625rem;
|
|
359
|
+
color: var(--text-muted);
|
|
360
|
+
display: block;
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Implementation Order
|
|
367
|
+
|
|
368
|
+
| Step | Action | Files | Validation |
|
|
369
|
+
|------|--------|-------|------------|
|
|
370
|
+
| 1 | Add metrics to SessionRecord type | `types.ts` | `npm run build` |
|
|
371
|
+
| 2 | Update recordSession signature | `profile.ts` | `npm run build` |
|
|
372
|
+
| 3 | Pass metrics from analyze | `analyze.ts` | `npm run build` |
|
|
373
|
+
| 4 | Update dashboard data builder | `insights/index.ts` | `npm run build` |
|
|
374
|
+
| 5 | Use real data in radar chart | `app.js` | Visual check |
|
|
375
|
+
| 6 | Use real data in session modal | `app.js` | Visual check |
|
|
376
|
+
| 7 | Add UI clarification | `index.html`, `styles.css` | Visual check |
|
|
377
|
+
| 8 | Full test | All | `vibe-check dashboard` |
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Rollback Procedure
|
|
382
|
+
|
|
383
|
+
All changes are additive (new optional fields). To rollback:
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
git checkout HEAD~1 -- src/gamification/types.ts
|
|
387
|
+
git checkout HEAD~1 -- src/gamification/profile.ts
|
|
388
|
+
git checkout HEAD~1 -- src/commands/analyze.ts
|
|
389
|
+
git checkout HEAD~1 -- src/insights/index.ts
|
|
390
|
+
git checkout HEAD~1 -- dashboard/app.js
|
|
391
|
+
npm run build
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Validation Strategy
|
|
397
|
+
|
|
398
|
+
### After Each Step
|
|
399
|
+
```bash
|
|
400
|
+
npm run build # No TypeScript errors
|
|
401
|
+
npm test # Tests still pass
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### After All Steps
|
|
405
|
+
```bash
|
|
406
|
+
# Generate fresh dashboard data
|
|
407
|
+
node dist/cli.js dashboard --no-open
|
|
408
|
+
|
|
409
|
+
# Verify metrics are in output
|
|
410
|
+
cat dashboard/dashboard-data.json | grep -A5 '"metrics"'
|
|
411
|
+
|
|
412
|
+
# Open dashboard and verify:
|
|
413
|
+
# 1. Radar chart shows real values (not 92, 78, 85, 88, 95)
|
|
414
|
+
# 2. Session detail shows real metrics
|
|
415
|
+
# 3. UI clarifies score vs rating
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Risk Assessment
|
|
421
|
+
|
|
422
|
+
| Risk | Level | Mitigation |
|
|
423
|
+
|------|-------|------------|
|
|
424
|
+
| Breaking existing profiles | Low | metrics field is optional |
|
|
425
|
+
| TypeScript errors | Low | Incremental compilation |
|
|
426
|
+
| Dashboard not loading | Medium | Keep old data format compatible |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Files Changed Summary
|
|
431
|
+
|
|
432
|
+
| File | Change Type | Lines Changed |
|
|
433
|
+
|------|-------------|---------------|
|
|
434
|
+
| `src/gamification/types.ts` | Modify | +10 |
|
|
435
|
+
| `src/gamification/profile.ts` | Modify | +25 |
|
|
436
|
+
| `src/commands/analyze.ts` | Modify | +15 |
|
|
437
|
+
| `src/insights/index.ts` | Modify | +20 |
|
|
438
|
+
| `dashboard/app.js` | Modify | +30 |
|
|
439
|
+
| `dashboard/index.html` | Modify | +5 |
|
|
440
|
+
| `dashboard/styles.css` | Modify | +5 |
|
|
441
|
+
|
|
442
|
+
**Total:** ~110 lines changed across 7 files
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Approval Checklist
|
|
447
|
+
|
|
448
|
+
- [ ] Schema change is backward compatible (optional field)
|
|
449
|
+
- [ ] All TypeScript files will compile
|
|
450
|
+
- [ ] Dashboard handles missing metrics gracefully
|
|
451
|
+
- [ ] Real metrics flow from analyze → profile → dashboard
|
|
452
|
+
- [ ] UI clearly distinguishes vibeScore from rating
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
## Next Step
|
|
457
|
+
|
|
458
|
+
Once approved: Implement changes in order listed above.
|