@boshu2/vibe-check 1.4.0 → 1.6.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 (188) 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 +200 -143
  16. package/claude-progress.json +200 -12
  17. package/claude-progress.txt +310 -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/profile.d.ts.map +1 -1
  49. package/dist/commands/profile.js +140 -31
  50. package/dist/commands/profile.js.map +1 -1
  51. package/dist/commands/timeline.d.ts +14 -0
  52. package/dist/commands/timeline.d.ts.map +1 -0
  53. package/dist/commands/timeline.js +462 -0
  54. package/dist/commands/timeline.js.map +1 -0
  55. package/dist/gamification/badges.d.ts +29 -0
  56. package/dist/gamification/badges.d.ts.map +1 -0
  57. package/dist/gamification/badges.js +114 -0
  58. package/dist/gamification/badges.js.map +1 -0
  59. package/dist/gamification/challenges.d.ts +42 -0
  60. package/dist/gamification/challenges.d.ts.map +1 -0
  61. package/dist/gamification/challenges.js +184 -0
  62. package/dist/gamification/challenges.js.map +1 -0
  63. package/dist/gamification/hall-of-fame.d.ts +17 -0
  64. package/dist/gamification/hall-of-fame.d.ts.map +1 -0
  65. package/dist/gamification/hall-of-fame.js +64 -0
  66. package/dist/gamification/hall-of-fame.js.map +1 -0
  67. package/dist/gamification/leaderboards.d.ts +49 -0
  68. package/dist/gamification/leaderboards.d.ts.map +1 -0
  69. package/dist/gamification/leaderboards.js +179 -0
  70. package/dist/gamification/leaderboards.js.map +1 -0
  71. package/dist/gamification/share.d.ts +29 -0
  72. package/dist/gamification/share.d.ts.map +1 -0
  73. package/dist/gamification/share.js +57 -0
  74. package/dist/gamification/share.js.map +1 -0
  75. package/dist/gamification/stats.d.ts +34 -0
  76. package/dist/gamification/stats.d.ts.map +1 -0
  77. package/dist/gamification/stats.js +91 -0
  78. package/dist/gamification/stats.js.map +1 -0
  79. package/dist/gamification/streaks.d.ts +9 -1
  80. package/dist/gamification/streaks.d.ts.map +1 -1
  81. package/dist/gamification/streaks.js +37 -4
  82. package/dist/gamification/streaks.js.map +1 -1
  83. package/dist/gamification/types.d.ts +35 -0
  84. package/dist/gamification/types.d.ts.map +1 -1
  85. package/dist/gamification/types.js +11 -3
  86. package/dist/gamification/types.js.map +1 -1
  87. package/dist/gamification/xp.d.ts +6 -2
  88. package/dist/gamification/xp.d.ts.map +1 -1
  89. package/dist/gamification/xp.js +27 -5
  90. package/dist/gamification/xp.js.map +1 -1
  91. package/dist/git.d.ts +24 -0
  92. package/dist/git.d.ts.map +1 -1
  93. package/dist/git.js +94 -0
  94. package/dist/git.js.map +1 -1
  95. package/dist/insights/generators.d.ts +44 -0
  96. package/dist/insights/generators.d.ts.map +1 -0
  97. package/dist/insights/generators.js +289 -0
  98. package/dist/insights/generators.js.map +1 -0
  99. package/dist/insights/index.d.ts +16 -0
  100. package/dist/insights/index.d.ts.map +1 -0
  101. package/dist/insights/index.js +171 -0
  102. package/dist/insights/index.js.map +1 -0
  103. package/dist/insights/types.d.ts +93 -0
  104. package/dist/insights/types.d.ts.map +1 -0
  105. package/dist/insights/types.js +6 -0
  106. package/dist/insights/types.js.map +1 -0
  107. package/dist/output/terminal.d.ts.map +1 -1
  108. package/dist/output/terminal.js +39 -0
  109. package/dist/output/terminal.js.map +1 -1
  110. package/dist/output/timeline-html.d.ts +6 -0
  111. package/dist/output/timeline-html.d.ts.map +1 -0
  112. package/dist/output/timeline-html.js +389 -0
  113. package/dist/output/timeline-html.js.map +1 -0
  114. package/dist/output/timeline-markdown.d.ts +6 -0
  115. package/dist/output/timeline-markdown.d.ts.map +1 -0
  116. package/dist/output/timeline-markdown.js +167 -0
  117. package/dist/output/timeline-markdown.js.map +1 -0
  118. package/dist/output/timeline.d.ts +9 -0
  119. package/dist/output/timeline.d.ts.map +1 -0
  120. package/dist/output/timeline.js +318 -0
  121. package/dist/output/timeline.js.map +1 -0
  122. package/dist/patterns/detour.d.ts +32 -0
  123. package/dist/patterns/detour.d.ts.map +1 -0
  124. package/dist/patterns/detour.js +137 -0
  125. package/dist/patterns/detour.js.map +1 -0
  126. package/dist/patterns/flow-state.d.ts +16 -0
  127. package/dist/patterns/flow-state.d.ts.map +1 -0
  128. package/dist/patterns/flow-state.js +40 -0
  129. package/dist/patterns/flow-state.js.map +1 -0
  130. package/dist/patterns/index.d.ts +8 -0
  131. package/dist/patterns/index.d.ts.map +1 -0
  132. package/dist/patterns/index.js +22 -0
  133. package/dist/patterns/index.js.map +1 -0
  134. package/dist/patterns/intervention-effectiveness.d.ts +42 -0
  135. package/dist/patterns/intervention-effectiveness.d.ts.map +1 -0
  136. package/dist/patterns/intervention-effectiveness.js +196 -0
  137. package/dist/patterns/intervention-effectiveness.js.map +1 -0
  138. package/dist/patterns/late-night.d.ts +30 -0
  139. package/dist/patterns/late-night.d.ts.map +1 -0
  140. package/dist/patterns/late-night.js +141 -0
  141. package/dist/patterns/late-night.js.map +1 -0
  142. package/dist/patterns/post-delete-sprint.d.ts +28 -0
  143. package/dist/patterns/post-delete-sprint.d.ts.map +1 -0
  144. package/dist/patterns/post-delete-sprint.js +85 -0
  145. package/dist/patterns/post-delete-sprint.js.map +1 -0
  146. package/dist/patterns/spiral-regression.d.ts +49 -0
  147. package/dist/patterns/spiral-regression.d.ts.map +1 -0
  148. package/dist/patterns/spiral-regression.js +219 -0
  149. package/dist/patterns/spiral-regression.js.map +1 -0
  150. package/dist/patterns/thrashing.d.ts +25 -0
  151. package/dist/patterns/thrashing.d.ts.map +1 -0
  152. package/dist/patterns/thrashing.js +111 -0
  153. package/dist/patterns/thrashing.js.map +1 -0
  154. package/dist/storage/atomic.d.ts +40 -0
  155. package/dist/storage/atomic.d.ts.map +1 -0
  156. package/dist/storage/atomic.js +155 -0
  157. package/dist/storage/atomic.js.map +1 -0
  158. package/dist/storage/commit-log.d.ts +35 -0
  159. package/dist/storage/commit-log.d.ts.map +1 -0
  160. package/dist/storage/commit-log.js +128 -0
  161. package/dist/storage/commit-log.js.map +1 -0
  162. package/dist/storage/index.d.ts +5 -0
  163. package/dist/storage/index.d.ts.map +1 -0
  164. package/dist/storage/index.js +33 -0
  165. package/dist/storage/index.js.map +1 -0
  166. package/dist/storage/schema.d.ts +32 -0
  167. package/dist/storage/schema.d.ts.map +1 -0
  168. package/dist/storage/schema.js +37 -0
  169. package/dist/storage/schema.js.map +1 -0
  170. package/dist/storage/timeline-store.d.ts +117 -0
  171. package/dist/storage/timeline-store.d.ts.map +1 -0
  172. package/dist/storage/timeline-store.js +438 -0
  173. package/dist/storage/timeline-store.js.map +1 -0
  174. package/dist/types.d.ts +96 -0
  175. package/dist/types.d.ts.map +1 -1
  176. package/docs/ARCHITECTURE.md +458 -0
  177. package/docs/DATA-ARCHITECTURE.md +565 -0
  178. package/docs/GAMIFICATION.md +564 -0
  179. package/docs/JSON-STORAGE-PATTERNS.md +512 -0
  180. package/docs/METRICS-EXPLAINED.md +394 -0
  181. package/docs/UNIFIED-ECOSYSTEM.md +560 -0
  182. package/docs/VIBE-ECOSYSTEM.md +406 -0
  183. package/feature-list.json +103 -1
  184. package/package.json +2 -1
  185. package/vitest.config.ts +1 -5
  186. package/.vibe-check/calibration.json +0 -38
  187. package/.vibe-check/latest.json +0 -114
  188. package/.vibe-check/sessions.json +0 -34
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Intervention Effectiveness Scoring
3
+ *
4
+ * Analyzes how well different interventions break spirals
5
+ * and provides data-driven recommendations.
6
+ */
7
+ import { InterventionMemory, InterventionType } from '../gamification/types';
8
+ export interface InterventionScore {
9
+ type: InterventionType;
10
+ name: string;
11
+ icon: string;
12
+ effectiveness: number;
13
+ avgResolutionTime: number;
14
+ totalUses: number;
15
+ successRate: number;
16
+ bestForPatterns: string[];
17
+ }
18
+ export interface EffectivenessAnalysis {
19
+ scores: InterventionScore[];
20
+ topRecommendation: InterventionType | null;
21
+ insights: string[];
22
+ }
23
+ /**
24
+ * Calculate effectiveness scores for all interventions
25
+ */
26
+ export declare function calculateEffectiveness(memory: InterventionMemory | undefined): EffectivenessAnalysis;
27
+ /**
28
+ * Get recommended intervention for a specific situation
29
+ */
30
+ export declare function getRecommendation(memory: InterventionMemory | undefined, pattern?: string, currentDuration?: number): {
31
+ intervention: InterventionType;
32
+ reason: string;
33
+ urgency: 'low' | 'medium' | 'high';
34
+ };
35
+ /**
36
+ * Compare two interventions
37
+ */
38
+ export declare function compareInterventions(memory: InterventionMemory | undefined, type1: InterventionType, type2: InterventionType): {
39
+ winner: InterventionType | null;
40
+ comparison: string;
41
+ };
42
+ //# sourceMappingURL=intervention-effectiveness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intervention-effectiveness.d.ts","sourceRoot":"","sources":["../../src/patterns/intervention-effectiveness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAsB,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEjG,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,iBAAiB,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC3C,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAaD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,qBAAqB,CAyEpG;AAmDD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB;IACD,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACpC,CAkCA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,gBAAgB,GACtB;IACD,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB,CAyCA"}
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ /**
3
+ * Intervention Effectiveness Scoring
4
+ *
5
+ * Analyzes how well different interventions break spirals
6
+ * and provides data-driven recommendations.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.calculateEffectiveness = calculateEffectiveness;
10
+ exports.getRecommendation = getRecommendation;
11
+ exports.compareInterventions = compareInterventions;
12
+ // Intervention metadata
13
+ const INTERVENTION_META = {
14
+ TRACER_TEST: { name: 'Tracer Test', icon: '🧪' },
15
+ BREAK: { name: 'Take a Break', icon: '☕' },
16
+ DOCS: { name: 'Read Docs', icon: '📚' },
17
+ REFACTOR: { name: 'Refactor', icon: '🔄' },
18
+ HELP: { name: 'Ask for Help', icon: '🤝' },
19
+ ROLLBACK: { name: 'Rollback', icon: '⏪' },
20
+ OTHER: { name: 'Other', icon: '💡' },
21
+ };
22
+ /**
23
+ * Calculate effectiveness scores for all interventions
24
+ */
25
+ function calculateEffectiveness(memory) {
26
+ if (!memory || memory.records.length === 0) {
27
+ return {
28
+ scores: [],
29
+ topRecommendation: null,
30
+ insights: ['No intervention data yet. Use `vibe-check intervene` to record your techniques.'],
31
+ };
32
+ }
33
+ // Group records by intervention type
34
+ const byType = new Map();
35
+ for (const record of memory.records) {
36
+ if (!byType.has(record.type)) {
37
+ byType.set(record.type, []);
38
+ }
39
+ byType.get(record.type).push(record);
40
+ }
41
+ // Calculate scores for each type
42
+ const scores = [];
43
+ for (const [type, records] of byType.entries()) {
44
+ const meta = INTERVENTION_META[type] || { name: type, icon: '💡' };
45
+ // Average resolution time
46
+ const totalDuration = records.reduce((sum, r) => sum + r.spiralDuration, 0);
47
+ const avgResolutionTime = Math.round(totalDuration / records.length);
48
+ // Find patterns this intervention is used for
49
+ const patternCounts = new Map();
50
+ for (const record of records) {
51
+ if (record.spiralPattern) {
52
+ patternCounts.set(record.spiralPattern, (patternCounts.get(record.spiralPattern) || 0) + 1);
53
+ }
54
+ }
55
+ const bestForPatterns = Array.from(patternCounts.entries())
56
+ .sort((a, b) => b[1] - a[1])
57
+ .slice(0, 2)
58
+ .map(([pattern]) => pattern);
59
+ // Calculate effectiveness score
60
+ // Lower resolution time = higher effectiveness
61
+ // More uses = more reliable data
62
+ const baseScore = Math.max(0, 100 - avgResolutionTime); // Penalize long resolutions
63
+ const usageBonus = Math.min(20, records.length * 2); // Up to 20 bonus for usage
64
+ const effectiveness = Math.min(100, Math.round(baseScore + usageBonus));
65
+ scores.push({
66
+ type,
67
+ name: meta.name,
68
+ icon: meta.icon,
69
+ effectiveness,
70
+ avgResolutionTime,
71
+ totalUses: records.length,
72
+ successRate: 100, // All recorded interventions are "successful" by definition
73
+ bestForPatterns,
74
+ });
75
+ }
76
+ // Sort by effectiveness
77
+ scores.sort((a, b) => b.effectiveness - a.effectiveness);
78
+ // Generate insights
79
+ const insights = generateInsights(scores, memory);
80
+ return {
81
+ scores,
82
+ topRecommendation: scores.length > 0 ? scores[0].type : null,
83
+ insights,
84
+ };
85
+ }
86
+ /**
87
+ * Generate actionable insights from effectiveness data
88
+ */
89
+ function generateInsights(scores, memory) {
90
+ const insights = [];
91
+ if (scores.length === 0)
92
+ return insights;
93
+ // Top performer insight
94
+ const top = scores[0];
95
+ if (top.totalUses >= 3) {
96
+ insights.push(`${top.icon} ${top.name} is your most effective technique (${top.avgResolutionTime}m avg resolution)`);
97
+ }
98
+ // Underused effective techniques
99
+ const underused = scores.filter(s => s.effectiveness > 70 && s.totalUses < 3);
100
+ if (underused.length > 0) {
101
+ const technique = underused[0];
102
+ insights.push(`Try ${technique.icon} ${technique.name} more often - it resolves issues in ${technique.avgResolutionTime}m`);
103
+ }
104
+ // Pattern-specific recommendations
105
+ const patternInterventions = memory.effectiveByPattern;
106
+ for (const [pattern, types] of Object.entries(patternInterventions)) {
107
+ if (types.length > 0) {
108
+ const bestType = types[0];
109
+ const meta = INTERVENTION_META[bestType];
110
+ if (meta) {
111
+ insights.push(`For ${pattern} issues, ${meta.icon} ${meta.name} works best for you`);
112
+ }
113
+ }
114
+ }
115
+ // Time-based insight
116
+ if (memory.avgTimeToIntervene > 30) {
117
+ insights.push(`You wait ${memory.avgTimeToIntervene}m on average before intervening. Try the 15-minute rule.`);
118
+ }
119
+ return insights.slice(0, 4); // Max 4 insights
120
+ }
121
+ /**
122
+ * Get recommended intervention for a specific situation
123
+ */
124
+ function getRecommendation(memory, pattern, currentDuration) {
125
+ const defaultRec = {
126
+ intervention: 'TRACER_TEST',
127
+ reason: 'Write a test to validate your assumptions',
128
+ urgency: 'medium',
129
+ };
130
+ if (!memory || memory.records.length === 0) {
131
+ return defaultRec;
132
+ }
133
+ // Check for pattern-specific recommendation
134
+ if (pattern && memory.effectiveByPattern[pattern]?.length > 0) {
135
+ const type = memory.effectiveByPattern[pattern][0];
136
+ const meta = INTERVENTION_META[type];
137
+ return {
138
+ intervention: type,
139
+ reason: `${meta.icon} ${meta.name} has worked for ${pattern} before`,
140
+ urgency: currentDuration && currentDuration > 30 ? 'high' : 'medium',
141
+ };
142
+ }
143
+ // Fall back to most used effective intervention
144
+ if (memory.topInterventions.length > 0) {
145
+ const type = memory.topInterventions[0];
146
+ const meta = INTERVENTION_META[type];
147
+ return {
148
+ intervention: type,
149
+ reason: `${meta.icon} ${meta.name} is your most reliable technique`,
150
+ urgency: currentDuration && currentDuration > 45 ? 'high' : 'medium',
151
+ };
152
+ }
153
+ return defaultRec;
154
+ }
155
+ /**
156
+ * Compare two interventions
157
+ */
158
+ function compareInterventions(memory, type1, type2) {
159
+ if (!memory || memory.records.length === 0) {
160
+ return { winner: null, comparison: 'Not enough data to compare' };
161
+ }
162
+ const records1 = memory.records.filter(r => r.type === type1);
163
+ const records2 = memory.records.filter(r => r.type === type2);
164
+ if (records1.length === 0 && records2.length === 0) {
165
+ return { winner: null, comparison: 'Neither intervention has been used' };
166
+ }
167
+ const avg1 = records1.length > 0
168
+ ? records1.reduce((sum, r) => sum + r.spiralDuration, 0) / records1.length
169
+ : Infinity;
170
+ const avg2 = records2.length > 0
171
+ ? records2.reduce((sum, r) => sum + r.spiralDuration, 0) / records2.length
172
+ : Infinity;
173
+ const meta1 = INTERVENTION_META[type1];
174
+ const meta2 = INTERVENTION_META[type2];
175
+ if (avg1 < avg2) {
176
+ const diff = Math.round(avg2 - avg1);
177
+ return {
178
+ winner: type1,
179
+ comparison: `${meta1.icon} ${meta1.name} resolves ${diff}m faster than ${meta2.icon} ${meta2.name}`,
180
+ };
181
+ }
182
+ else if (avg2 < avg1) {
183
+ const diff = Math.round(avg1 - avg2);
184
+ return {
185
+ winner: type2,
186
+ comparison: `${meta2.icon} ${meta2.name} resolves ${diff}m faster than ${meta1.icon} ${meta1.name}`,
187
+ };
188
+ }
189
+ else {
190
+ return {
191
+ winner: null,
192
+ comparison: `${meta1.icon} ${meta1.name} and ${meta2.icon} ${meta2.name} are equally effective`,
193
+ };
194
+ }
195
+ }
196
+ //# sourceMappingURL=intervention-effectiveness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intervention-effectiveness.js","sourceRoot":"","sources":["../../src/patterns/intervention-effectiveness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { TimelineSession } from '../types';
2
+ export interface LateNightSpiralResult {
3
+ detected: boolean;
4
+ spirals: LateNightSpiral[];
5
+ totalDuration: number;
6
+ message: string;
7
+ }
8
+ export interface LateNightSpiral {
9
+ sessionId: string;
10
+ startTime: Date;
11
+ endTime: Date;
12
+ duration: number;
13
+ fixCount: number;
14
+ component: string;
15
+ resolved: boolean;
16
+ nextDayResolution?: {
17
+ duration: number;
18
+ improvement: number;
19
+ };
20
+ }
21
+ /**
22
+ * Detect late-night spirals: debug sessions after 22:00 with 3+ fix commits.
23
+ *
24
+ * Definition: Debug session after 22:00 with 3+ fix commits
25
+ * Value: Show that tired debugging is inefficient
26
+ *
27
+ * Enhanced: Also compare with "fresh eyes" resolution time if available
28
+ */
29
+ export declare function detectLateNightSpiral(sessions: TimelineSession[]): LateNightSpiralResult;
30
+ //# sourceMappingURL=late-night.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"late-night.d.ts","sourceRoot":"","sources":["../../src/patterns/late-night.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,eAAe,EAAY,MAAM,UAAU,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAOD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,EAAE,GAC1B,qBAAqB,CAwFvB"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectLateNightSpiral = detectLateNightSpiral;
4
+ // Late night threshold: 22:00 (10 PM)
5
+ const LATE_NIGHT_HOUR = 22;
6
+ // Early morning threshold: 06:00 (6 AM)
7
+ const EARLY_MORNING_HOUR = 6;
8
+ /**
9
+ * Detect late-night spirals: debug sessions after 22:00 with 3+ fix commits.
10
+ *
11
+ * Definition: Debug session after 22:00 with 3+ fix commits
12
+ * Value: Show that tired debugging is inefficient
13
+ *
14
+ * Enhanced: Also compare with "fresh eyes" resolution time if available
15
+ */
16
+ function detectLateNightSpiral(sessions) {
17
+ const lateNightSpirals = [];
18
+ for (const session of sessions) {
19
+ // Check if session is during late night hours
20
+ const sessionHour = session.start.getHours();
21
+ const isLateNight = sessionHour >= LATE_NIGHT_HOUR || sessionHour < EARLY_MORNING_HOUR;
22
+ if (!isLateNight)
23
+ continue;
24
+ // Check for spirals in this session
25
+ for (const spiral of session.spirals) {
26
+ // A spiral is 3+ fix commits for same component
27
+ if (spiral.commits < 3)
28
+ continue;
29
+ // Find if this component was fixed the next day
30
+ const nextDayFix = findNextDayResolution(spiral.component, session, sessions);
31
+ lateNightSpirals.push({
32
+ sessionId: session.id,
33
+ startTime: spiral.firstCommit,
34
+ endTime: spiral.lastCommit,
35
+ duration: spiral.duration,
36
+ fixCount: spiral.commits,
37
+ component: spiral.component,
38
+ resolved: !nextDayFix, // If no next-day fix, they solved it at night
39
+ nextDayResolution: nextDayFix,
40
+ });
41
+ }
42
+ // Also check for high fix density even without formal spirals
43
+ const fixCommits = session.commits.filter(c => c.type === 'fix');
44
+ if (fixCommits.length >= 3 && session.spirals.length === 0) {
45
+ // Late night session with lots of fixes but no detected spiral
46
+ // Could be a diffuse debugging session
47
+ const components = new Set(fixCommits.map(c => c.scope || 'unknown'));
48
+ for (const component of components) {
49
+ const componentFixes = fixCommits.filter(c => (c.scope || 'unknown') === component);
50
+ if (componentFixes.length >= 3) {
51
+ const duration = componentFixes.length > 1
52
+ ? Math.round((componentFixes[componentFixes.length - 1].timestamp.getTime() -
53
+ componentFixes[0].timestamp.getTime()) / (1000 * 60))
54
+ : session.duration;
55
+ lateNightSpirals.push({
56
+ sessionId: session.id,
57
+ startTime: componentFixes[0].timestamp,
58
+ endTime: componentFixes[componentFixes.length - 1].timestamp,
59
+ duration,
60
+ fixCount: componentFixes.length,
61
+ component,
62
+ resolved: true, // Assume resolved if no next-day data
63
+ });
64
+ }
65
+ }
66
+ }
67
+ }
68
+ // Calculate total duration
69
+ const totalDuration = lateNightSpirals.reduce((sum, s) => sum + s.duration, 0);
70
+ // Generate message
71
+ let message = '';
72
+ if (lateNightSpirals.length > 0) {
73
+ const withFreshEyes = lateNightSpirals.filter(s => s.nextDayResolution);
74
+ if (withFreshEyes.length > 0) {
75
+ const avgImprovement = withFreshEyes.reduce((sum, s) => sum + (s.nextDayResolution?.improvement || 0), 0) / withFreshEyes.length;
76
+ message = `🌙 ${lateNightSpirals.length} late-night spiral${lateNightSpirals.length > 1 ? 's' : ''}: ` +
77
+ `${formatDuration(totalDuration)} debugging after 10pm. ` +
78
+ `Fresh eyes solve ${Math.round(avgImprovement * 100)}% faster.`;
79
+ }
80
+ else {
81
+ message = `🌙 ${lateNightSpirals.length} late-night spiral${lateNightSpirals.length > 1 ? 's' : ''}: ` +
82
+ `${formatDuration(totalDuration)} debugging after 10pm. Consider sleeping on it!`;
83
+ }
84
+ }
85
+ return {
86
+ detected: lateNightSpirals.length > 0,
87
+ spirals: lateNightSpirals,
88
+ totalDuration,
89
+ message,
90
+ };
91
+ }
92
+ /**
93
+ * Check if the same component was fixed more quickly the next day
94
+ */
95
+ function findNextDayResolution(component, lateNightSession, allSessions) {
96
+ // Look for sessions the next day
97
+ const lateNightDate = lateNightSession.start.toDateString();
98
+ for (const session of allSessions) {
99
+ // Skip the late night session itself
100
+ if (session.id === lateNightSession.id)
101
+ continue;
102
+ // Check if this session is the next day (or later morning)
103
+ const sessionDate = session.start.toDateString();
104
+ const sessionHour = session.start.getHours();
105
+ // Must be after the late night session
106
+ if (session.start <= lateNightSession.end)
107
+ continue;
108
+ // Look for fixes to the same component
109
+ const componentFixes = session.commits.filter(c => c.type === 'fix' && (c.scope || 'unknown') === component);
110
+ if (componentFixes.length > 0) {
111
+ // Found a next-day resolution
112
+ // Calculate how long it took with fresh eyes
113
+ const freshDuration = componentFixes.length > 1
114
+ ? Math.round((componentFixes[componentFixes.length - 1].timestamp.getTime() -
115
+ componentFixes[0].timestamp.getTime()) / (1000 * 60))
116
+ : 15; // Assume 15 minutes for single-commit fixes
117
+ // Compare with late night duration
118
+ const lateNightDuration = lateNightSession.spirals.find(s => s.component === component)?.duration || 30;
119
+ const improvement = lateNightDuration > 0
120
+ ? (lateNightDuration - freshDuration) / lateNightDuration
121
+ : 0;
122
+ return {
123
+ duration: freshDuration,
124
+ improvement: Math.max(0, improvement), // Only positive improvements
125
+ };
126
+ }
127
+ }
128
+ return undefined;
129
+ }
130
+ /**
131
+ * Format duration for display
132
+ */
133
+ function formatDuration(minutes) {
134
+ if (minutes < 60) {
135
+ return `${minutes}m`;
136
+ }
137
+ const hours = Math.floor(minutes / 60);
138
+ const mins = minutes % 60;
139
+ return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
140
+ }
141
+ //# sourceMappingURL=late-night.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"late-night.js","sourceRoot":"","sources":["../../src/patterns/late-night.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { TimelineSession } from '../types';
2
+ export interface PostDeleteSprintResult {
3
+ detected: boolean;
4
+ deleteSession: {
5
+ id: string;
6
+ linesDeleted: number;
7
+ timestamp: Date;
8
+ } | null;
9
+ sprintSession: {
10
+ id: string;
11
+ features: number;
12
+ duration: number;
13
+ velocity: number;
14
+ } | null;
15
+ velocityIncrease: number;
16
+ message: string;
17
+ }
18
+ /**
19
+ * Detect post-delete sprints across sessions.
20
+ *
21
+ * Definition: Deletions > 2× additions in one session, then velocity >50% above baseline
22
+ * Value: Shows ROI of simplification
23
+ */
24
+ export declare function detectPostDeleteSprint(sessions: TimelineSession[], commitStats: Map<string, {
25
+ additions: number;
26
+ deletions: number;
27
+ }>): PostDeleteSprintResult;
28
+ //# sourceMappingURL=post-delete-sprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-delete-sprint.d.ts","sourceRoot":"","sources":["../../src/patterns/post-delete-sprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,IAAI,CAAC;KACjB,GAAG,IAAI,CAAC;IACT,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EAAE,EAC3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACjE,sBAAsB,CAmFxB"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectPostDeleteSprint = detectPostDeleteSprint;
4
+ /**
5
+ * Detect post-delete sprints across sessions.
6
+ *
7
+ * Definition: Deletions > 2× additions in one session, then velocity >50% above baseline
8
+ * Value: Shows ROI of simplification
9
+ */
10
+ function detectPostDeleteSprint(sessions, commitStats) {
11
+ if (sessions.length < 2) {
12
+ return {
13
+ detected: false,
14
+ deleteSession: null,
15
+ sprintSession: null,
16
+ velocityIncrease: 0,
17
+ message: 'Not enough sessions to detect pattern',
18
+ };
19
+ }
20
+ // Calculate baseline velocity (features per hour across all sessions)
21
+ let totalFeatures = 0;
22
+ let totalMinutes = 0;
23
+ for (const session of sessions) {
24
+ const featCount = session.commits.filter(c => c.type === 'feat').length;
25
+ totalFeatures += featCount;
26
+ totalMinutes += session.duration;
27
+ }
28
+ const baselineVelocity = totalMinutes > 0 ? (totalFeatures / totalMinutes) * 60 : 0;
29
+ // Find sessions with heavy deletions (deletions > 2× additions)
30
+ for (let i = 0; i < sessions.length - 1; i++) {
31
+ const session = sessions[i];
32
+ // Calculate total additions/deletions for this session
33
+ let sessionAdditions = 0;
34
+ let sessionDeletions = 0;
35
+ for (const commit of session.commits) {
36
+ const stats = commitStats.get(commit.hash);
37
+ if (stats) {
38
+ sessionAdditions += stats.additions;
39
+ sessionDeletions += stats.deletions;
40
+ }
41
+ }
42
+ // Check if this is a "delete session" (deletions > 2× additions)
43
+ const isDeleteSession = sessionDeletions > sessionAdditions * 2 && sessionDeletions > 100;
44
+ if (isDeleteSession) {
45
+ // Check subsequent sessions for sprint behavior
46
+ for (let j = i + 1; j < sessions.length; j++) {
47
+ const sprintCandidate = sessions[j];
48
+ const sprintFeatures = sprintCandidate.commits.filter(c => c.type === 'feat').length;
49
+ const sprintDuration = sprintCandidate.duration;
50
+ // Calculate sprint velocity
51
+ const sprintVelocity = sprintDuration > 0 ? (sprintFeatures / sprintDuration) * 60 : 0;
52
+ // Check if sprint velocity is >50% above baseline
53
+ const velocityIncrease = baselineVelocity > 0
54
+ ? ((sprintVelocity - baselineVelocity) / baselineVelocity) * 100
55
+ : 0;
56
+ if (velocityIncrease > 50 && sprintFeatures >= 3) {
57
+ return {
58
+ detected: true,
59
+ deleteSession: {
60
+ id: session.id,
61
+ linesDeleted: sessionDeletions,
62
+ timestamp: session.start,
63
+ },
64
+ sprintSession: {
65
+ id: sprintCandidate.id,
66
+ features: sprintFeatures,
67
+ duration: sprintDuration,
68
+ velocity: Math.round(sprintVelocity * 10) / 10,
69
+ },
70
+ velocityIncrease: Math.round(velocityIncrease),
71
+ message: `${Math.round(velocityIncrease)}% faster after removing ${sessionDeletions} lines`,
72
+ };
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return {
78
+ detected: false,
79
+ deleteSession: null,
80
+ sprintSession: null,
81
+ velocityIncrease: 0,
82
+ message: 'No post-delete sprint detected',
83
+ };
84
+ }
85
+ //# sourceMappingURL=post-delete-sprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-delete-sprint.js","sourceRoot":"","sources":["../../src/patterns/post-delete-sprint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Spiral Regression Detection
3
+ *
4
+ * Detects when spiral patterns re-emerge after a period of improvement.
5
+ * Uses weekly trend analysis to identify regressions.
6
+ */
7
+ import { StoredSession, TrendData } from '../storage/timeline-store';
8
+ export interface RegressionAlert {
9
+ type: 'spiral_regression' | 'recovery_time_regression';
10
+ severity: 'warning' | 'critical';
11
+ message: string;
12
+ metric: string;
13
+ currentValue: number;
14
+ baselineValue: number;
15
+ changePercent: number;
16
+ period: string;
17
+ recommendation: string;
18
+ }
19
+ export interface RegressionAnalysis {
20
+ hasRegression: boolean;
21
+ alerts: RegressionAlert[];
22
+ summary: string;
23
+ improvementStreak: number;
24
+ }
25
+ /**
26
+ * Detect spiral regressions from trend data
27
+ */
28
+ export declare function detectRegressions(trends: TrendData): RegressionAnalysis;
29
+ /**
30
+ * Analyze recovery time trends for a specific pattern
31
+ */
32
+ export declare function analyzeRecoveryTimeTrend(sessions: StoredSession[], component: string): {
33
+ improving: boolean;
34
+ trend: 'improving' | 'stable' | 'worsening';
35
+ avgRecoveryTime: number;
36
+ recentRecoveryTime: number;
37
+ samples: number;
38
+ };
39
+ /**
40
+ * Get all component recovery trends
41
+ */
42
+ export declare function getAllRecoveryTrends(sessions: StoredSession[]): Array<{
43
+ component: string;
44
+ trend: 'improving' | 'stable' | 'worsening';
45
+ avgTime: number;
46
+ recentTime: number;
47
+ samples: number;
48
+ }>;
49
+ //# sourceMappingURL=spiral-regression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spiral-regression.d.ts","sourceRoot":"","sources":["../../src/patterns/spiral-regression.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAa,MAAM,2BAA2B,CAAC;AAEhF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,GAAG,0BAA0B,CAAC;IACvD,QAAQ,EAAE,SAAS,GAAG,UAAU,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,kBAAkB,CAkDvE;AAwGD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,EAAE,EACzB,SAAS,EAAE,MAAM,GAChB;IACD,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC5C,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAgDA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAyBD"}