@boshu2/vibe-check 1.5.0 → 1.6.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.
Files changed (148) hide show
  1. package/.agents/bundles/insight-mining-dashboard-research-2025-11-30.md +400 -0
  2. package/.agents/bundles/storage-enhancement-research-2025-11-30.md +292 -0
  3. package/.agents/bundles/timeline-feature-research-complete-2025-11-30.md +301 -0
  4. package/.agents/plans/insight-dashboard-plan-2025-11-30.md +1130 -0
  5. package/.agents/plans/json-storage-enhancement-plan.md +717 -0
  6. package/.agents/plans/storage-hardening-and-cache-plan.md +592 -0
  7. package/.agents/plans/test-coverage-gaps-plan.md +1117 -0
  8. package/.agents/plans/timeline-feature-plan.md +193 -0
  9. package/.agents/plans/vibe_timeline_research_findings.md +553 -0
  10. package/.claude/settings.local.json +1 -0
  11. package/.vibe-check/.gitignore +6 -0
  12. package/CHANGELOG.md +46 -0
  13. package/CLAUDE.md +24 -0
  14. package/CONTRIBUTING.md +227 -0
  15. package/README.md +165 -144
  16. package/claude-progress.json +191 -9
  17. package/claude-progress.txt +257 -0
  18. package/dashboard/app.js +75 -2
  19. package/dashboard/dashboard-data.json +653 -0
  20. package/dashboard/index.html +13 -0
  21. package/dashboard/styles.css +61 -0
  22. package/dist/analysis/cross-session-analysis.d.ts +68 -0
  23. package/dist/analysis/cross-session-analysis.d.ts.map +1 -0
  24. package/dist/analysis/cross-session-analysis.js +174 -0
  25. package/dist/analysis/cross-session-analysis.js.map +1 -0
  26. package/dist/analysis/index.d.ts +2 -0
  27. package/dist/analysis/index.d.ts.map +1 -0
  28. package/dist/analysis/index.js +12 -0
  29. package/dist/analysis/index.js.map +1 -0
  30. package/dist/cli.js +10 -1
  31. package/dist/cli.js.map +1 -1
  32. package/dist/commands/analyze.d.ts +2 -0
  33. package/dist/commands/analyze.d.ts.map +1 -1
  34. package/dist/commands/analyze.js +105 -2
  35. package/dist/commands/analyze.js.map +1 -1
  36. package/dist/commands/cache.d.ts +6 -0
  37. package/dist/commands/cache.d.ts.map +1 -0
  38. package/dist/commands/cache.js +168 -0
  39. package/dist/commands/cache.js.map +1 -0
  40. package/dist/commands/dashboard.d.ts +8 -0
  41. package/dist/commands/dashboard.d.ts.map +1 -0
  42. package/dist/commands/dashboard.js +109 -0
  43. package/dist/commands/dashboard.js.map +1 -0
  44. package/dist/commands/index.d.ts +3 -0
  45. package/dist/commands/index.d.ts.map +1 -1
  46. package/dist/commands/index.js +8 -1
  47. package/dist/commands/index.js.map +1 -1
  48. package/dist/commands/timeline.d.ts +14 -0
  49. package/dist/commands/timeline.d.ts.map +1 -0
  50. package/dist/commands/timeline.js +462 -0
  51. package/dist/commands/timeline.js.map +1 -0
  52. package/dist/git.d.ts +24 -0
  53. package/dist/git.d.ts.map +1 -1
  54. package/dist/git.js +94 -0
  55. package/dist/git.js.map +1 -1
  56. package/dist/insights/generators.d.ts +44 -0
  57. package/dist/insights/generators.d.ts.map +1 -0
  58. package/dist/insights/generators.js +289 -0
  59. package/dist/insights/generators.js.map +1 -0
  60. package/dist/insights/index.d.ts +16 -0
  61. package/dist/insights/index.d.ts.map +1 -0
  62. package/dist/insights/index.js +171 -0
  63. package/dist/insights/index.js.map +1 -0
  64. package/dist/insights/types.d.ts +93 -0
  65. package/dist/insights/types.d.ts.map +1 -0
  66. package/dist/insights/types.js +6 -0
  67. package/dist/insights/types.js.map +1 -0
  68. package/dist/output/timeline-html.d.ts +6 -0
  69. package/dist/output/timeline-html.d.ts.map +1 -0
  70. package/dist/output/timeline-html.js +389 -0
  71. package/dist/output/timeline-html.js.map +1 -0
  72. package/dist/output/timeline-markdown.d.ts +6 -0
  73. package/dist/output/timeline-markdown.d.ts.map +1 -0
  74. package/dist/output/timeline-markdown.js +167 -0
  75. package/dist/output/timeline-markdown.js.map +1 -0
  76. package/dist/output/timeline.d.ts +9 -0
  77. package/dist/output/timeline.d.ts.map +1 -0
  78. package/dist/output/timeline.js +318 -0
  79. package/dist/output/timeline.js.map +1 -0
  80. package/dist/patterns/detour.d.ts +32 -0
  81. package/dist/patterns/detour.d.ts.map +1 -0
  82. package/dist/patterns/detour.js +137 -0
  83. package/dist/patterns/detour.js.map +1 -0
  84. package/dist/patterns/flow-state.d.ts +16 -0
  85. package/dist/patterns/flow-state.d.ts.map +1 -0
  86. package/dist/patterns/flow-state.js +40 -0
  87. package/dist/patterns/flow-state.js.map +1 -0
  88. package/dist/patterns/index.d.ts +8 -0
  89. package/dist/patterns/index.d.ts.map +1 -0
  90. package/dist/patterns/index.js +22 -0
  91. package/dist/patterns/index.js.map +1 -0
  92. package/dist/patterns/intervention-effectiveness.d.ts +42 -0
  93. package/dist/patterns/intervention-effectiveness.d.ts.map +1 -0
  94. package/dist/patterns/intervention-effectiveness.js +196 -0
  95. package/dist/patterns/intervention-effectiveness.js.map +1 -0
  96. package/dist/patterns/late-night.d.ts +30 -0
  97. package/dist/patterns/late-night.d.ts.map +1 -0
  98. package/dist/patterns/late-night.js +141 -0
  99. package/dist/patterns/late-night.js.map +1 -0
  100. package/dist/patterns/post-delete-sprint.d.ts +28 -0
  101. package/dist/patterns/post-delete-sprint.d.ts.map +1 -0
  102. package/dist/patterns/post-delete-sprint.js +85 -0
  103. package/dist/patterns/post-delete-sprint.js.map +1 -0
  104. package/dist/patterns/spiral-regression.d.ts +49 -0
  105. package/dist/patterns/spiral-regression.d.ts.map +1 -0
  106. package/dist/patterns/spiral-regression.js +219 -0
  107. package/dist/patterns/spiral-regression.js.map +1 -0
  108. package/dist/patterns/thrashing.d.ts +25 -0
  109. package/dist/patterns/thrashing.d.ts.map +1 -0
  110. package/dist/patterns/thrashing.js +111 -0
  111. package/dist/patterns/thrashing.js.map +1 -0
  112. package/dist/storage/atomic.d.ts +40 -0
  113. package/dist/storage/atomic.d.ts.map +1 -0
  114. package/dist/storage/atomic.js +155 -0
  115. package/dist/storage/atomic.js.map +1 -0
  116. package/dist/storage/commit-log.d.ts +35 -0
  117. package/dist/storage/commit-log.d.ts.map +1 -0
  118. package/dist/storage/commit-log.js +128 -0
  119. package/dist/storage/commit-log.js.map +1 -0
  120. package/dist/storage/index.d.ts +5 -0
  121. package/dist/storage/index.d.ts.map +1 -0
  122. package/dist/storage/index.js +33 -0
  123. package/dist/storage/index.js.map +1 -0
  124. package/dist/storage/schema.d.ts +32 -0
  125. package/dist/storage/schema.d.ts.map +1 -0
  126. package/dist/storage/schema.js +37 -0
  127. package/dist/storage/schema.js.map +1 -0
  128. package/dist/storage/timeline-store.d.ts +117 -0
  129. package/dist/storage/timeline-store.d.ts.map +1 -0
  130. package/dist/storage/timeline-store.js +438 -0
  131. package/dist/storage/timeline-store.js.map +1 -0
  132. package/dist/types.d.ts +96 -0
  133. package/dist/types.d.ts.map +1 -1
  134. package/docs/ARCHITECTURE.md +458 -0
  135. package/docs/DATA-ARCHITECTURE.md +565 -0
  136. package/docs/GAMIFICATION.md +564 -0
  137. package/docs/JSON-STORAGE-PATTERNS.md +512 -0
  138. package/docs/METRICS-EXPLAINED.md +394 -0
  139. package/docs/UNIFIED-ECOSYSTEM.md +560 -0
  140. package/docs/VIBE-ECOSYSTEM.md +406 -0
  141. package/docs/images/dashboard.png +0 -0
  142. package/feature-list.json +48 -0
  143. package/package.json +2 -1
  144. package/vitest.config.ts +1 -5
  145. package/.vibe-check/calibration.json +0 -38
  146. package/.vibe-check/latest.json +0 -114
  147. package/.vibe-check/sessions.json +0 -44
  148. package/PLAN-ultimate-game.md +0 -1362
@@ -0,0 +1,462 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createTimelineCommand = createTimelineCommand;
7
+ exports.runTimeline = runTimeline;
8
+ const commander_1 = require("commander");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const git_1 = require("../git");
11
+ const metrics_1 = require("../metrics");
12
+ const timeline_1 = require("../output/timeline");
13
+ const timeline_markdown_1 = require("../output/timeline-markdown");
14
+ const timeline_html_1 = require("../output/timeline-html");
15
+ const storage_1 = require("../storage");
16
+ const date_fns_1 = require("date-fns");
17
+ const flow_state_1 = require("../patterns/flow-state");
18
+ const post_delete_sprint_1 = require("../patterns/post-delete-sprint");
19
+ const thrashing_1 = require("../patterns/thrashing");
20
+ const detour_1 = require("../patterns/detour");
21
+ const late_night_1 = require("../patterns/late-night");
22
+ const spiral_regression_1 = require("../patterns/spiral-regression");
23
+ // Session gap threshold: 60 minutes
24
+ const SESSION_GAP_MINUTES = 60;
25
+ function createTimelineCommand() {
26
+ const cmd = new commander_1.Command('timeline')
27
+ .description('View your coding journey as a timeline with sessions and patterns')
28
+ .option('--since <date>', 'Start date for analysis (default: "1 week ago")', '1 week ago')
29
+ .option('--until <date>', 'End date for analysis (default: now)')
30
+ .option('-f, --format <type>', 'Output format: terminal, json, markdown, html', 'terminal')
31
+ .option('-r, --repo <path>', 'Repository path', process.cwd())
32
+ .option('-v, --verbose', 'Show verbose output', false)
33
+ .option('--expand [date]', 'Expand day details (all or specific date like "Nov-29")')
34
+ .option('--no-cache', 'Skip cache and fetch fresh data from git')
35
+ .option('--insights', 'Show compounding insights from historical data')
36
+ .action(async (options) => {
37
+ await runTimeline(options);
38
+ });
39
+ return cmd;
40
+ }
41
+ async function runTimeline(options) {
42
+ try {
43
+ const { since, until, format: outputFormat, repo, verbose, expand, noCache, insights } = options;
44
+ // Check if repo is valid
45
+ if (!(await (0, git_1.isGitRepo)(repo))) {
46
+ console.error(chalk_1.default.red(`Not a git repository: ${repo}`));
47
+ process.exit(1);
48
+ }
49
+ // Load existing store for caching
50
+ const store = (0, storage_1.loadStore)(repo);
51
+ const latestCommitHash = await (0, git_1.getLatestCommitHash)(repo);
52
+ if (verbose) {
53
+ console.error(chalk_1.default.gray(`Analyzing repository: ${repo}`));
54
+ console.error(chalk_1.default.gray(`Since: ${since}`));
55
+ if (until)
56
+ console.error(chalk_1.default.gray(`Until: ${until}`));
57
+ console.error(chalk_1.default.gray(`Cache: ${(0, storage_1.getStorePath)(repo)}`));
58
+ console.error(chalk_1.default.gray(`Last cached commit: ${store.lastCommitHash || 'none'}`));
59
+ console.error(chalk_1.default.gray(`Latest commit: ${latestCommitHash}`));
60
+ }
61
+ // Get commits
62
+ const commits = await (0, git_1.getCommits)(repo, since, until);
63
+ if (commits.length === 0) {
64
+ console.log(chalk_1.default.yellow('\nNo commits found in the specified range.\n'));
65
+ console.log(chalk_1.default.gray('Try specifying a different date range:'));
66
+ console.log(chalk_1.default.gray(' vibe-check timeline --since "1 month ago"'));
67
+ process.exit(0);
68
+ }
69
+ if (verbose) {
70
+ console.error(chalk_1.default.gray(`Found ${commits.length} commits`));
71
+ }
72
+ // Get commit stats for pattern detection
73
+ if (verbose) {
74
+ console.error(chalk_1.default.gray('Gathering file stats for pattern detection...'));
75
+ }
76
+ const commitStats = await (0, git_1.getCommitStats)(repo, since, until);
77
+ // Build timeline with pattern detection
78
+ const timeline = buildTimeline(commits, commitStats.filesPerCommit, commitStats.lineStatsPerCommit);
79
+ // Update and save store (unless --no-cache)
80
+ if (!noCache) {
81
+ // Append commits to NDJSON log (source of truth)
82
+ const appendedCount = (0, storage_1.appendCommits)(commits, repo);
83
+ if (verbose && appendedCount > 0) {
84
+ console.error(chalk_1.default.gray(`Appended ${appendedCount} new commits to log`));
85
+ }
86
+ const updatedStore = (0, storage_1.updateStore)(store, timeline, latestCommitHash);
87
+ (0, storage_1.saveStore)(updatedStore, repo);
88
+ if (verbose) {
89
+ console.error(chalk_1.default.gray(`Cache updated: ${updatedStore.sessions.length} sessions, ${updatedStore.insights.length} insights`));
90
+ }
91
+ }
92
+ // Show insights if requested
93
+ if (insights) {
94
+ console.log('');
95
+ console.log(chalk_1.default.bold.magenta('═'.repeat(64)));
96
+ console.log(chalk_1.default.bold.magenta(' COMPOUNDING INSIGHTS'));
97
+ console.log(chalk_1.default.bold.magenta('═'.repeat(64)));
98
+ console.log('');
99
+ // Check for regressions
100
+ const regressionAnalysis = (0, spiral_regression_1.detectRegressions)(store.trends);
101
+ if (regressionAnalysis.hasRegression) {
102
+ console.log(chalk_1.default.bold.red(' ⚠ REGRESSION ALERTS'));
103
+ for (const alert of regressionAnalysis.alerts) {
104
+ const icon = alert.severity === 'critical' ? chalk_1.default.red('🚨') : chalk_1.default.yellow('⚠');
105
+ console.log(` ${icon} ${alert.message}`);
106
+ console.log(chalk_1.default.gray(` ${alert.recommendation}`));
107
+ }
108
+ console.log('');
109
+ }
110
+ else if (regressionAnalysis.improvementStreak > 0) {
111
+ console.log(chalk_1.default.green(` 🎯 ${regressionAnalysis.improvementStreak}-week improvement streak!`));
112
+ console.log('');
113
+ }
114
+ // Show stored insights
115
+ if (store.insights.length > 0) {
116
+ for (const insight of store.insights.slice(0, 5)) {
117
+ const icon = insight.type === 'pattern' ? '🔄' : insight.type === 'recommendation' ? '💡' : '📈';
118
+ console.log(` ${icon} ${insight.message}`);
119
+ console.log(chalk_1.default.gray(` (${insight.occurrences} occurrences)`));
120
+ }
121
+ console.log('');
122
+ }
123
+ // Show recovery time trends
124
+ const recoveryTrends = (0, spiral_regression_1.getAllRecoveryTrends)(store.sessions);
125
+ const improvingComponents = recoveryTrends.filter(t => t.trend === 'improving');
126
+ const worseningComponents = recoveryTrends.filter(t => t.trend === 'worsening');
127
+ if (improvingComponents.length > 0) {
128
+ console.log(chalk_1.default.bold.green(' 📉 Improving Recovery Times:'));
129
+ for (const comp of improvingComponents.slice(0, 3)) {
130
+ console.log(chalk_1.default.green(` ${comp.component}: ${comp.avgTime}m → ${comp.recentTime}m`));
131
+ }
132
+ console.log('');
133
+ }
134
+ if (worseningComponents.length > 0) {
135
+ console.log(chalk_1.default.bold.yellow(' 📈 Slower Recovery Times:'));
136
+ for (const comp of worseningComponents.slice(0, 3)) {
137
+ console.log(chalk_1.default.yellow(` ${comp.component}: ${comp.avgTime}m → ${comp.recentTime}m`));
138
+ }
139
+ console.log('');
140
+ }
141
+ // Show week-over-week trends
142
+ if (store.trends.improvements.length > 0) {
143
+ console.log(chalk_1.default.bold.white(' Week-over-Week:'));
144
+ for (const imp of store.trends.improvements) {
145
+ const arrow = imp.direction === 'up' ? chalk_1.default.green('↑') : imp.direction === 'down' ? chalk_1.default.red('↓') : chalk_1.default.gray('→');
146
+ console.log(` ${arrow} ${imp.metric}: ${imp.change > 0 ? '+' : ''}${imp.change}%`);
147
+ }
148
+ console.log('');
149
+ }
150
+ }
151
+ // Output based on format
152
+ if (outputFormat === 'json') {
153
+ // Include store insights in JSON output
154
+ const output = {
155
+ ...timeline,
156
+ storedInsights: store.insights,
157
+ trends: store.trends,
158
+ patternStats: store.patterns,
159
+ };
160
+ console.log(JSON.stringify(output, null, 2));
161
+ }
162
+ else if (outputFormat === 'markdown') {
163
+ const output = (0, timeline_markdown_1.formatTimelineMarkdown)(timeline);
164
+ console.log(output);
165
+ }
166
+ else if (outputFormat === 'html') {
167
+ const output = (0, timeline_html_1.formatTimelineHtml)(timeline);
168
+ console.log(output);
169
+ }
170
+ else {
171
+ // Terminal output
172
+ const output = (0, timeline_1.formatTimelineTerminal)(timeline, { expand });
173
+ console.log(output);
174
+ }
175
+ }
176
+ catch (error) {
177
+ if (error instanceof Error) {
178
+ console.error(chalk_1.default.red(`Error: ${error.message}`));
179
+ if (options.verbose) {
180
+ console.error(chalk_1.default.gray(error.stack));
181
+ }
182
+ }
183
+ else {
184
+ console.error(chalk_1.default.red('An unexpected error occurred'));
185
+ }
186
+ process.exit(1);
187
+ }
188
+ }
189
+ /**
190
+ * Build a complete timeline from commits
191
+ */
192
+ function buildTimeline(commits, filesPerCommit, lineStatsPerCommit) {
193
+ // Sort commits chronologically (oldest first)
194
+ const sortedCommits = [...commits].sort((a, b) => a.date.getTime() - b.date.getTime());
195
+ // Detect sessions
196
+ const sessions = detectSessions(sortedCommits);
197
+ // Group sessions into days
198
+ const days = groupByDay(sessions);
199
+ // Calculate aggregates
200
+ const totalCommits = sortedCommits.length;
201
+ const totalActiveMinutes = sessions.reduce((sum, s) => sum + s.duration, 0);
202
+ const totalFeatures = sortedCommits.filter(c => c.type === 'feat').length;
203
+ const totalFixes = sortedCommits.filter(c => c.type === 'fix').length;
204
+ const totalSpirals = sessions.reduce((sum, s) => sum + s.spirals.length, 0);
205
+ const flowStates = sessions.filter(s => s.flowState).length;
206
+ const totalXp = sessions.reduce((sum, s) => sum + s.xpEarned, 0);
207
+ // Build trend sparkline
208
+ const trend = days.map(d => d.dayScore);
209
+ // Calculate date range
210
+ const from = sortedCommits[0].date;
211
+ const to = sortedCommits[sortedCommits.length - 1].date;
212
+ const totalDays = (0, date_fns_1.differenceInDays)(to, from) + 1;
213
+ // Phase 2: Detect post-delete sprint
214
+ const postDeleteResult = (0, post_delete_sprint_1.detectPostDeleteSprint)(sessions, lineStatsPerCommit);
215
+ const postDeleteSprint = postDeleteResult.detected
216
+ ? {
217
+ detected: true,
218
+ linesDeleted: postDeleteResult.deleteSession?.linesDeleted || 0,
219
+ velocityIncrease: postDeleteResult.velocityIncrease,
220
+ message: postDeleteResult.message,
221
+ }
222
+ : null;
223
+ // Phase 2: Detect thrashing across all events
224
+ const allEvents = sessions.flatMap(s => s.commits);
225
+ const thrashingResult = (0, thrashing_1.detectThrashing)(allEvents, filesPerCommit, lineStatsPerCommit);
226
+ const thrashing = thrashingResult.detected
227
+ ? {
228
+ detected: true,
229
+ files: thrashingResult.files.map(f => ({
230
+ path: f.path,
231
+ touchCount: f.touchCount,
232
+ efficiency: f.efficiency,
233
+ })),
234
+ message: thrashingResult.message,
235
+ }
236
+ : null;
237
+ // Phase 3: Detect detours (code added then deleted)
238
+ const detourResult = (0, detour_1.detectDetour)(allEvents, filesPerCommit, lineStatsPerCommit);
239
+ const detours = detourResult.detected
240
+ ? {
241
+ detected: true,
242
+ detours: detourResult.detours.map(d => ({
243
+ scope: d.scope,
244
+ filesAffected: d.filesAffected,
245
+ linesAdded: d.linesAdded,
246
+ linesDeleted: d.linesDeleted,
247
+ duration: d.duration,
248
+ })),
249
+ totalTimeLost: detourResult.totalTimeLost,
250
+ message: detourResult.message,
251
+ }
252
+ : null;
253
+ // Phase 3: Detect late-night spirals
254
+ const lateNightResult = (0, late_night_1.detectLateNightSpiral)(sessions);
255
+ const lateNightSpirals = lateNightResult.detected
256
+ ? {
257
+ detected: true,
258
+ spirals: lateNightResult.spirals.map(s => ({
259
+ component: s.component,
260
+ duration: s.duration,
261
+ fixCount: s.fixCount,
262
+ resolved: s.resolved,
263
+ })),
264
+ totalDuration: lateNightResult.totalDuration,
265
+ message: lateNightResult.message,
266
+ }
267
+ : null;
268
+ return {
269
+ from,
270
+ to,
271
+ activeDays: days.length,
272
+ totalDays,
273
+ days,
274
+ sessions,
275
+ totalCommits,
276
+ totalActiveMinutes,
277
+ totalFeatures,
278
+ totalFixes,
279
+ totalSpirals,
280
+ flowStates,
281
+ postDeleteSprint,
282
+ thrashing,
283
+ detours,
284
+ lateNightSpirals,
285
+ totalXp,
286
+ trend,
287
+ };
288
+ }
289
+ /**
290
+ * Detect sessions from commits using 1-hour gap threshold
291
+ */
292
+ function detectSessions(commits) {
293
+ if (commits.length === 0)
294
+ return [];
295
+ const sessions = [];
296
+ let currentSession = [];
297
+ let sessionCounter = 0;
298
+ for (let i = 0; i < commits.length; i++) {
299
+ const commit = commits[i];
300
+ const prevCommit = i > 0 ? commits[i - 1] : null;
301
+ // Calculate gap from previous commit
302
+ const gapMinutes = prevCommit
303
+ ? (0, date_fns_1.differenceInMinutes)(commit.date, prevCommit.date)
304
+ : 0;
305
+ // Start new session if gap exceeds threshold
306
+ if (gapMinutes > SESSION_GAP_MINUTES && currentSession.length > 0) {
307
+ sessions.push(buildSession(currentSession, sessionCounter));
308
+ sessionCounter++;
309
+ currentSession = [];
310
+ }
311
+ // Add event to current session
312
+ const event = {
313
+ hash: commit.hash,
314
+ timestamp: commit.date,
315
+ author: commit.author,
316
+ subject: commit.message,
317
+ type: commit.type,
318
+ scope: commit.scope,
319
+ sessionId: `session-${sessionCounter}`,
320
+ sessionPosition: currentSession.length,
321
+ gapMinutes,
322
+ isRefactor: commit.type === 'refactor',
323
+ spiralDepth: 0, // Will be calculated in buildSession
324
+ };
325
+ currentSession.push(event);
326
+ }
327
+ // Don't forget the last session
328
+ if (currentSession.length > 0) {
329
+ sessions.push(buildSession(currentSession, sessionCounter));
330
+ }
331
+ return sessions;
332
+ }
333
+ /**
334
+ * Build a session from events
335
+ */
336
+ function buildSession(events, sessionNum) {
337
+ const start = events[0].timestamp;
338
+ const end = events[events.length - 1].timestamp;
339
+ const duration = (0, date_fns_1.differenceInMinutes)(end, start) || 1; // At least 1 minute
340
+ // Convert events back to Commit format for metrics analysis
341
+ const commits = events.map(e => ({
342
+ hash: e.hash,
343
+ date: e.timestamp,
344
+ message: e.subject,
345
+ type: e.type,
346
+ scope: e.scope,
347
+ author: e.author,
348
+ }));
349
+ // Analyze metrics for this session
350
+ const analysis = (0, metrics_1.analyzeCommits)(commits);
351
+ // Detect fix chains (spirals)
352
+ const spirals = analysis.fixChains.filter(fc => fc.isSpiral);
353
+ // Mark spiral depth on events
354
+ for (const spiral of spirals) {
355
+ let depth = 1;
356
+ for (const event of events) {
357
+ if (event.type === 'fix' && event.scope === spiral.component) {
358
+ event.spiralDepth = depth++;
359
+ }
360
+ }
361
+ }
362
+ // Detect flow state using enhanced pattern detection
363
+ const flowStateResult = (0, flow_state_1.detectFlowState)(events, duration);
364
+ const flowState = flowStateResult.detected;
365
+ // Calculate XP (simplified - base XP on session quality)
366
+ const xpEarned = calculateSessionXp(analysis.overall, commits.length, spirals.length);
367
+ return {
368
+ id: `session-${sessionNum}`,
369
+ start,
370
+ end,
371
+ duration,
372
+ commits: events,
373
+ vibeScore: null, // Would need semantic-free metrics for full score
374
+ overall: analysis.overall,
375
+ trustPassRate: analysis.metrics.trustPassRate.value,
376
+ reworkRatio: analysis.metrics.reworkRatio.value,
377
+ flowState,
378
+ spirals,
379
+ xpEarned,
380
+ };
381
+ }
382
+ /**
383
+ * Calculate XP for a session
384
+ */
385
+ function calculateSessionXp(overall, commits, spirals) {
386
+ const baseXp = {
387
+ 'ELITE': 50,
388
+ 'HIGH': 30,
389
+ 'MEDIUM': 20,
390
+ 'LOW': 10,
391
+ };
392
+ let xp = baseXp[overall];
393
+ xp += commits * 2; // 2 XP per commit
394
+ xp -= spirals * 10; // -10 XP per spiral
395
+ return Math.max(0, xp);
396
+ }
397
+ /**
398
+ * Group sessions into days
399
+ */
400
+ function groupByDay(sessions) {
401
+ const dayMap = new Map();
402
+ for (const session of sessions) {
403
+ const dateKey = (0, date_fns_1.format)(session.start, 'yyyy-MM-dd');
404
+ if (!dayMap.has(dateKey)) {
405
+ dayMap.set(dateKey, []);
406
+ }
407
+ dayMap.get(dateKey).push(session);
408
+ }
409
+ // Convert map to array of TimelineDay
410
+ const days = [];
411
+ for (const [dateKey, daySessions] of dayMap.entries()) {
412
+ const date = (0, date_fns_1.parseISO)(dateKey);
413
+ const totalCommits = daySessions.reduce((sum, s) => sum + s.commits.length, 0);
414
+ const totalDuration = daySessions.reduce((sum, s) => sum + s.duration, 0);
415
+ const totalXp = daySessions.reduce((sum, s) => sum + s.xpEarned, 0);
416
+ const spiralCount = daySessions.reduce((sum, s) => sum + s.spirals.length, 0);
417
+ // Calculate day score (average of session trust pass rates)
418
+ const scores = daySessions.map(s => s.trustPassRate);
419
+ const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;
420
+ // Calculate day rating
421
+ const dayRating = calculateDayRating(daySessions);
422
+ days.push({
423
+ date: dateKey,
424
+ displayDate: (0, date_fns_1.format)(date, 'EEE MMM d'),
425
+ sessions: daySessions,
426
+ dayScore: Math.round(avgScore),
427
+ dayRating,
428
+ totalCommits,
429
+ totalDuration,
430
+ totalXp,
431
+ spiralCount,
432
+ });
433
+ }
434
+ // Sort by date
435
+ days.sort((a, b) => a.date.localeCompare(b.date));
436
+ return days;
437
+ }
438
+ /**
439
+ * Calculate overall rating for a day
440
+ */
441
+ function calculateDayRating(sessions) {
442
+ const ratings = sessions.map(s => s.overall);
443
+ // Count each rating type
444
+ const counts = {
445
+ 'ELITE': ratings.filter(r => r === 'ELITE').length,
446
+ 'HIGH': ratings.filter(r => r === 'HIGH').length,
447
+ 'MEDIUM': ratings.filter(r => r === 'MEDIUM').length,
448
+ 'LOW': ratings.filter(r => r === 'LOW').length,
449
+ };
450
+ // Majority wins, with tie-breakers favoring higher ratings
451
+ if (counts.ELITE >= counts.HIGH && counts.ELITE >= counts.MEDIUM && counts.ELITE >= counts.LOW) {
452
+ return 'ELITE';
453
+ }
454
+ if (counts.HIGH >= counts.MEDIUM && counts.HIGH >= counts.LOW) {
455
+ return 'HIGH';
456
+ }
457
+ if (counts.MEDIUM >= counts.LOW) {
458
+ return 'MEDIUM';
459
+ }
460
+ return 'LOW';
461
+ }
462
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/commands/timeline.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  import { Commit } from './types';
2
2
  export declare function getCommits(repoPath: string, since?: string, until?: string): Promise<Commit[]>;
3
3
  export declare function isGitRepo(repoPath: string): Promise<boolean>;
4
+ /**
5
+ * Get the latest commit hash in the repo
6
+ */
7
+ export declare function getLatestCommitHash(repoPath: string): Promise<string>;
8
+ /**
9
+ * Get commits since a specific commit hash (for incremental sync)
10
+ */
11
+ export declare function getCommitsSince(repoPath: string, sinceHash: string): Promise<Commit[]>;
12
+ /**
13
+ * Check if a commit hash exists in the repo
14
+ */
15
+ export declare function commitExists(repoPath: string, hash: string): Promise<boolean>;
4
16
  export interface FileStats {
5
17
  filesPerCommit: Map<string, string[]>;
6
18
  lineStats: {
@@ -8,8 +20,20 @@ export interface FileStats {
8
20
  deletions: number;
9
21
  }[];
10
22
  }
23
+ export interface CommitStats {
24
+ filesPerCommit: Map<string, string[]>;
25
+ lineStatsPerCommit: Map<string, {
26
+ additions: number;
27
+ deletions: number;
28
+ }>;
29
+ }
11
30
  /**
12
31
  * Get file-level statistics for semantic-free metrics.
13
32
  */
14
33
  export declare function getFileStats(repoPath: string, since?: string, until?: string): Promise<FileStats>;
34
+ /**
35
+ * Get per-commit statistics for pattern detection.
36
+ * Returns a map of commit hash -> stats
37
+ */
38
+ export declare function getCommitStats(repoPath: string, since?: string, until?: string): Promise<CommitStats>;
15
39
  //# sourceMappingURL=git.d.ts.map
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AA+BD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAmDpB"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AA+BD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnF;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAmDpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,CAgDtB"}
package/dist/git.js CHANGED
@@ -5,7 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getCommits = getCommits;
7
7
  exports.isGitRepo = isGitRepo;
8
+ exports.getLatestCommitHash = getLatestCommitHash;
9
+ exports.getCommitsSince = getCommitsSince;
10
+ exports.commitExists = commitExists;
8
11
  exports.getFileStats = getFileStats;
12
+ exports.getCommitStats = getCommitStats;
9
13
  const simple_git_1 = __importDefault(require("simple-git"));
10
14
  const COMMIT_TYPES = ['feat', 'fix', 'docs', 'chore', 'refactor', 'test', 'style'];
11
15
  async function getCommits(repoPath, since, until) {
@@ -62,6 +66,47 @@ async function isGitRepo(repoPath) {
62
66
  return false;
63
67
  }
64
68
  }
69
+ /**
70
+ * Get the latest commit hash in the repo
71
+ */
72
+ async function getLatestCommitHash(repoPath) {
73
+ const git = (0, simple_git_1.default)(repoPath);
74
+ try {
75
+ const log = await git.log({ n: 1 });
76
+ return log.latest?.hash.substring(0, 7) || '';
77
+ }
78
+ catch {
79
+ return '';
80
+ }
81
+ }
82
+ /**
83
+ * Get commits since a specific commit hash (for incremental sync)
84
+ */
85
+ async function getCommitsSince(repoPath, sinceHash) {
86
+ const git = (0, simple_git_1.default)(repoPath);
87
+ try {
88
+ // Get commits after the given hash
89
+ const log = await git.log({ from: sinceHash, to: 'HEAD' });
90
+ return log.all.map((entry) => parseCommit(entry));
91
+ }
92
+ catch {
93
+ // If hash doesn't exist or error, return empty
94
+ return [];
95
+ }
96
+ }
97
+ /**
98
+ * Check if a commit hash exists in the repo
99
+ */
100
+ async function commitExists(repoPath, hash) {
101
+ const git = (0, simple_git_1.default)(repoPath);
102
+ try {
103
+ await git.raw(['cat-file', '-t', hash]);
104
+ return true;
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
65
110
  /**
66
111
  * Get file-level statistics for semantic-free metrics.
67
112
  */
@@ -113,4 +158,53 @@ async function getFileStats(repoPath, since, until) {
113
158
  }
114
159
  return { filesPerCommit, lineStats };
115
160
  }
161
+ /**
162
+ * Get per-commit statistics for pattern detection.
163
+ * Returns a map of commit hash -> stats
164
+ */
165
+ async function getCommitStats(repoPath, since, until) {
166
+ const git = (0, simple_git_1.default)(repoPath);
167
+ const filesPerCommit = new Map();
168
+ const lineStatsPerCommit = new Map();
169
+ // Build options for git log
170
+ const logOptions = {};
171
+ if (since)
172
+ logOptions['--since'] = since;
173
+ if (until)
174
+ logOptions['--until'] = until;
175
+ try {
176
+ const log = await git.log(logOptions);
177
+ for (const commit of log.all) {
178
+ const hash = commit.hash.substring(0, 7);
179
+ try {
180
+ const diffStat = await git.raw(['diff-tree', '--numstat', '--root', '-r', commit.hash]);
181
+ const lines = diffStat.trim().split('\n').filter(l => l.length > 0);
182
+ const files = [];
183
+ let additions = 0;
184
+ let deletions = 0;
185
+ for (const line of lines) {
186
+ const parts = line.split('\t');
187
+ if (parts.length >= 3) {
188
+ const add = parseInt(parts[0], 10) || 0;
189
+ const del = parseInt(parts[1], 10) || 0;
190
+ const file = parts[2];
191
+ additions += add;
192
+ deletions += del;
193
+ files.push(file);
194
+ }
195
+ }
196
+ filesPerCommit.set(hash, files);
197
+ lineStatsPerCommit.set(hash, { additions, deletions });
198
+ }
199
+ catch {
200
+ filesPerCommit.set(hash, []);
201
+ lineStatsPerCommit.set(hash, { additions: 0, deletions: 0 });
202
+ }
203
+ }
204
+ }
205
+ catch {
206
+ // Return empty stats on error
207
+ }
208
+ return { filesPerCommit, lineStatsPerCommit };
209
+ }
116
210
  //# sourceMappingURL=git.js.map