@boshu2/vibe-check 1.5.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.
- package/.agents/bundles/insight-mining-dashboard-research-2025-11-30.md +400 -0
- package/.agents/bundles/storage-enhancement-research-2025-11-30.md +292 -0
- package/.agents/bundles/timeline-feature-research-complete-2025-11-30.md +301 -0
- package/.agents/plans/insight-dashboard-plan-2025-11-30.md +1130 -0
- package/.agents/plans/json-storage-enhancement-plan.md +717 -0
- package/.agents/plans/storage-hardening-and-cache-plan.md +592 -0
- package/.agents/plans/test-coverage-gaps-plan.md +1117 -0
- package/.agents/plans/timeline-feature-plan.md +193 -0
- package/.agents/plans/vibe_timeline_research_findings.md +553 -0
- package/.claude/settings.local.json +1 -0
- package/.vibe-check/.gitignore +6 -0
- package/CHANGELOG.md +46 -0
- package/CLAUDE.md +24 -0
- package/CONTRIBUTING.md +227 -0
- package/README.md +200 -143
- package/claude-progress.json +191 -9
- package/claude-progress.txt +257 -0
- package/dashboard/app.js +75 -2
- package/dashboard/dashboard-data.json +653 -0
- package/dashboard/index.html +13 -0
- package/dashboard/styles.css +61 -0
- package/dist/analysis/cross-session-analysis.d.ts +68 -0
- package/dist/analysis/cross-session-analysis.d.ts.map +1 -0
- package/dist/analysis/cross-session-analysis.js +174 -0
- package/dist/analysis/cross-session-analysis.js.map +1 -0
- package/dist/analysis/index.d.ts +2 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +12 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts +2 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +105 -2
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +168 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/dashboard.d.ts +8 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +109 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/index.d.ts +3 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +8 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/timeline.d.ts +14 -0
- package/dist/commands/timeline.d.ts.map +1 -0
- package/dist/commands/timeline.js +462 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/git.d.ts +24 -0
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +94 -0
- package/dist/git.js.map +1 -1
- package/dist/insights/generators.d.ts +44 -0
- package/dist/insights/generators.d.ts.map +1 -0
- package/dist/insights/generators.js +289 -0
- package/dist/insights/generators.js.map +1 -0
- package/dist/insights/index.d.ts +16 -0
- package/dist/insights/index.d.ts.map +1 -0
- package/dist/insights/index.js +171 -0
- package/dist/insights/index.js.map +1 -0
- package/dist/insights/types.d.ts +93 -0
- package/dist/insights/types.d.ts.map +1 -0
- package/dist/insights/types.js +6 -0
- package/dist/insights/types.js.map +1 -0
- package/dist/output/timeline-html.d.ts +6 -0
- package/dist/output/timeline-html.d.ts.map +1 -0
- package/dist/output/timeline-html.js +389 -0
- package/dist/output/timeline-html.js.map +1 -0
- package/dist/output/timeline-markdown.d.ts +6 -0
- package/dist/output/timeline-markdown.d.ts.map +1 -0
- package/dist/output/timeline-markdown.js +167 -0
- package/dist/output/timeline-markdown.js.map +1 -0
- package/dist/output/timeline.d.ts +9 -0
- package/dist/output/timeline.d.ts.map +1 -0
- package/dist/output/timeline.js +318 -0
- package/dist/output/timeline.js.map +1 -0
- package/dist/patterns/detour.d.ts +32 -0
- package/dist/patterns/detour.d.ts.map +1 -0
- package/dist/patterns/detour.js +137 -0
- package/dist/patterns/detour.js.map +1 -0
- package/dist/patterns/flow-state.d.ts +16 -0
- package/dist/patterns/flow-state.d.ts.map +1 -0
- package/dist/patterns/flow-state.js +40 -0
- package/dist/patterns/flow-state.js.map +1 -0
- package/dist/patterns/index.d.ts +8 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +22 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/intervention-effectiveness.d.ts +42 -0
- package/dist/patterns/intervention-effectiveness.d.ts.map +1 -0
- package/dist/patterns/intervention-effectiveness.js +196 -0
- package/dist/patterns/intervention-effectiveness.js.map +1 -0
- package/dist/patterns/late-night.d.ts +30 -0
- package/dist/patterns/late-night.d.ts.map +1 -0
- package/dist/patterns/late-night.js +141 -0
- package/dist/patterns/late-night.js.map +1 -0
- package/dist/patterns/post-delete-sprint.d.ts +28 -0
- package/dist/patterns/post-delete-sprint.d.ts.map +1 -0
- package/dist/patterns/post-delete-sprint.js +85 -0
- package/dist/patterns/post-delete-sprint.js.map +1 -0
- package/dist/patterns/spiral-regression.d.ts +49 -0
- package/dist/patterns/spiral-regression.d.ts.map +1 -0
- package/dist/patterns/spiral-regression.js +219 -0
- package/dist/patterns/spiral-regression.js.map +1 -0
- package/dist/patterns/thrashing.d.ts +25 -0
- package/dist/patterns/thrashing.d.ts.map +1 -0
- package/dist/patterns/thrashing.js +111 -0
- package/dist/patterns/thrashing.js.map +1 -0
- package/dist/storage/atomic.d.ts +40 -0
- package/dist/storage/atomic.d.ts.map +1 -0
- package/dist/storage/atomic.js +155 -0
- package/dist/storage/atomic.js.map +1 -0
- package/dist/storage/commit-log.d.ts +35 -0
- package/dist/storage/commit-log.d.ts.map +1 -0
- package/dist/storage/commit-log.js +128 -0
- package/dist/storage/commit-log.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +33 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/schema.d.ts +32 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +37 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/timeline-store.d.ts +117 -0
- package/dist/storage/timeline-store.d.ts.map +1 -0
- package/dist/storage/timeline-store.js +438 -0
- package/dist/storage/timeline-store.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +458 -0
- package/docs/DATA-ARCHITECTURE.md +565 -0
- package/docs/GAMIFICATION.md +564 -0
- package/docs/JSON-STORAGE-PATTERNS.md +512 -0
- package/docs/METRICS-EXPLAINED.md +394 -0
- package/docs/UNIFIED-ECOSYSTEM.md +560 -0
- package/docs/VIBE-ECOSYSTEM.md +406 -0
- package/feature-list.json +48 -0
- package/package.json +2 -1
- package/vitest.config.ts +1 -5
- package/.vibe-check/calibration.json +0 -38
- package/.vibe-check/latest.json +0 -114
- package/.vibe-check/sessions.json +0 -44
- package/PLAN-ultimate-game.md +0 -1362
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectDetour = detectDetour;
|
|
4
|
+
/**
|
|
5
|
+
* Detect detours: code added then deleted within the analysis window.
|
|
6
|
+
*
|
|
7
|
+
* Definition: Code added then deleted in same analysis window
|
|
8
|
+
* Value: Track wasted time, learn from experiments
|
|
9
|
+
*
|
|
10
|
+
* How it works:
|
|
11
|
+
* 1. Track files/scopes with significant additions
|
|
12
|
+
* 2. Look for later commits that delete from same files/scopes
|
|
13
|
+
* 3. If deletions exceed 50% of additions, it's a detour
|
|
14
|
+
*/
|
|
15
|
+
function detectDetour(events, filesPerCommit, lineStatsPerCommit) {
|
|
16
|
+
const detours = [];
|
|
17
|
+
// Group commits by scope (use scope or infer from files)
|
|
18
|
+
const scopeHistory = new Map();
|
|
19
|
+
// Build history per scope
|
|
20
|
+
for (const event of events) {
|
|
21
|
+
const scope = event.scope || inferScope(event, filesPerCommit);
|
|
22
|
+
if (!scope)
|
|
23
|
+
continue;
|
|
24
|
+
const stats = lineStatsPerCommit.get(event.hash);
|
|
25
|
+
if (!stats)
|
|
26
|
+
continue;
|
|
27
|
+
if (!scopeHistory.has(scope)) {
|
|
28
|
+
scopeHistory.set(scope, {
|
|
29
|
+
additions: 0,
|
|
30
|
+
deletions: 0,
|
|
31
|
+
files: new Set(),
|
|
32
|
+
firstAddTime: event.timestamp,
|
|
33
|
+
lastDeleteTime: event.timestamp,
|
|
34
|
+
addCommits: [],
|
|
35
|
+
deleteCommits: [],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const history = scopeHistory.get(scope);
|
|
39
|
+
history.additions += stats.additions;
|
|
40
|
+
history.deletions += stats.deletions;
|
|
41
|
+
// Track files touched
|
|
42
|
+
const files = filesPerCommit.get(event.hash) || [];
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
history.files.add(file);
|
|
45
|
+
}
|
|
46
|
+
// Track commit types
|
|
47
|
+
if (stats.additions > stats.deletions) {
|
|
48
|
+
if (history.addCommits.length === 0) {
|
|
49
|
+
history.firstAddTime = event.timestamp;
|
|
50
|
+
}
|
|
51
|
+
history.addCommits.push(event);
|
|
52
|
+
}
|
|
53
|
+
else if (stats.deletions > stats.additions * 2) {
|
|
54
|
+
// Significant deletion
|
|
55
|
+
history.lastDeleteTime = event.timestamp;
|
|
56
|
+
history.deleteCommits.push(event);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Identify detours: scopes where we added then deleted significantly
|
|
60
|
+
for (const [scope, history] of scopeHistory.entries()) {
|
|
61
|
+
// Skip if no significant additions followed by deletions
|
|
62
|
+
if (history.addCommits.length === 0 || history.deleteCommits.length === 0) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Check if deletions happened AFTER additions
|
|
66
|
+
const lastAdd = history.addCommits[history.addCommits.length - 1];
|
|
67
|
+
const hasDeleteAfterAdd = history.deleteCommits.some(d => d.timestamp > lastAdd.timestamp);
|
|
68
|
+
if (!hasDeleteAfterAdd)
|
|
69
|
+
continue;
|
|
70
|
+
// Detour threshold: deleted >50% of what was added
|
|
71
|
+
const netDeletionRatio = history.deletions / Math.max(history.additions, 1);
|
|
72
|
+
if (netDeletionRatio < 0.5)
|
|
73
|
+
continue;
|
|
74
|
+
// This is a detour
|
|
75
|
+
const duration = Math.round((history.lastDeleteTime.getTime() - history.firstAddTime.getTime()) / (1000 * 60));
|
|
76
|
+
detours.push({
|
|
77
|
+
scope,
|
|
78
|
+
filesAffected: Array.from(history.files),
|
|
79
|
+
linesAdded: history.additions,
|
|
80
|
+
linesDeleted: history.deletions,
|
|
81
|
+
startTime: history.firstAddTime,
|
|
82
|
+
endTime: history.lastDeleteTime,
|
|
83
|
+
duration,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Calculate total time lost
|
|
87
|
+
const totalTimeLost = detours.reduce((sum, d) => sum + d.duration, 0);
|
|
88
|
+
// Generate message
|
|
89
|
+
let message = '';
|
|
90
|
+
if (detours.length > 0) {
|
|
91
|
+
const topDetour = detours.sort((a, b) => b.duration - a.duration)[0];
|
|
92
|
+
message = `🚧 ${detours.length} detour${detours.length > 1 ? 's' : ''} detected: ` +
|
|
93
|
+
`${topDetour.scope} took ${formatDuration(topDetour.duration)} ` +
|
|
94
|
+
`(${topDetour.linesAdded} lines added, then ${topDetour.linesDeleted} deleted)`;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
detected: detours.length > 0,
|
|
98
|
+
detours,
|
|
99
|
+
totalTimeLost,
|
|
100
|
+
message,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Infer scope from files touched by a commit
|
|
105
|
+
*/
|
|
106
|
+
function inferScope(event, filesPerCommit) {
|
|
107
|
+
const files = filesPerCommit.get(event.hash) || [];
|
|
108
|
+
if (files.length === 0)
|
|
109
|
+
return null;
|
|
110
|
+
// Find common directory or file pattern
|
|
111
|
+
const commonParts = files[0].split('/');
|
|
112
|
+
for (let i = 1; i < files.length; i++) {
|
|
113
|
+
const parts = files[i].split('/');
|
|
114
|
+
let j = 0;
|
|
115
|
+
while (j < commonParts.length && j < parts.length && commonParts[j] === parts[j]) {
|
|
116
|
+
j++;
|
|
117
|
+
}
|
|
118
|
+
commonParts.length = j;
|
|
119
|
+
}
|
|
120
|
+
// Return the deepest meaningful directory
|
|
121
|
+
if (commonParts.length >= 2) {
|
|
122
|
+
return commonParts.slice(0, 2).join('/');
|
|
123
|
+
}
|
|
124
|
+
return commonParts[0] || null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Format duration for display
|
|
128
|
+
*/
|
|
129
|
+
function formatDuration(minutes) {
|
|
130
|
+
if (minutes < 60) {
|
|
131
|
+
return `${minutes}m`;
|
|
132
|
+
}
|
|
133
|
+
const hours = Math.floor(minutes / 60);
|
|
134
|
+
const mins = minutes % 60;
|
|
135
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=detour.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detour.js","sourceRoot":"","sources":["../../src/patterns/detour.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TimelineEvent } from '../types';
|
|
2
|
+
export interface FlowStateResult {
|
|
3
|
+
detected: boolean;
|
|
4
|
+
duration: number;
|
|
5
|
+
commits: number;
|
|
6
|
+
velocity: number;
|
|
7
|
+
peakType: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detect flow state in a session.
|
|
11
|
+
*
|
|
12
|
+
* Definition: 5+ non-fix commits, no gap >30m, duration >45m
|
|
13
|
+
* Value: Shows when you're in the zone
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectFlowState(events: TimelineEvent[], sessionDuration: number): FlowStateResult;
|
|
16
|
+
//# sourceMappingURL=flow-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-state.d.ts","sourceRoot":"","sources":["../../src/patterns/flow-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EAAE,EACvB,eAAe,EAAE,MAAM,GACtB,eAAe,CAkCjB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.detectFlowState = detectFlowState;
|
|
4
|
+
/**
|
|
5
|
+
* Detect flow state in a session.
|
|
6
|
+
*
|
|
7
|
+
* Definition: 5+ non-fix commits, no gap >30m, duration >45m
|
|
8
|
+
* Value: Shows when you're in the zone
|
|
9
|
+
*/
|
|
10
|
+
function detectFlowState(events, sessionDuration) {
|
|
11
|
+
// Count non-fix commits
|
|
12
|
+
const nonFixCommits = events.filter(e => e.type !== 'fix');
|
|
13
|
+
const nonFixCount = nonFixCommits.length;
|
|
14
|
+
// Find max gap between consecutive commits
|
|
15
|
+
let maxGap = 0;
|
|
16
|
+
for (let i = 1; i < events.length; i++) {
|
|
17
|
+
maxGap = Math.max(maxGap, events[i].gapMinutes);
|
|
18
|
+
}
|
|
19
|
+
// Check flow state conditions
|
|
20
|
+
const detected = nonFixCount >= 5 && maxGap <= 30 && sessionDuration >= 45;
|
|
21
|
+
// Calculate velocity (commits per hour)
|
|
22
|
+
const velocity = sessionDuration > 0
|
|
23
|
+
? (events.length / sessionDuration) * 60
|
|
24
|
+
: 0;
|
|
25
|
+
// Find peak commit type during flow
|
|
26
|
+
const typeCounts = {};
|
|
27
|
+
for (const event of nonFixCommits) {
|
|
28
|
+
typeCounts[event.type] = (typeCounts[event.type] || 0) + 1;
|
|
29
|
+
}
|
|
30
|
+
const peakType = Object.entries(typeCounts)
|
|
31
|
+
.sort((a, b) => b[1] - a[1])[0]?.[0] || 'other';
|
|
32
|
+
return {
|
|
33
|
+
detected,
|
|
34
|
+
duration: sessionDuration,
|
|
35
|
+
commits: events.length,
|
|
36
|
+
velocity: Math.round(velocity * 10) / 10,
|
|
37
|
+
peakType,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=flow-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-state.js","sourceRoot":"","sources":["../../src/patterns/flow-state.ts"],"names":[],"mappings":";;AAgBA,0CAqCC;AA3CD;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,MAAuB,EACvB,eAAuB;IAEvB,wBAAwB;IACxB,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC;IAEzC,2CAA2C;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,WAAW,IAAI,CAAC,IAAI,MAAM,IAAI,EAAE,IAAI,eAAe,IAAI,EAAE,CAAC;IAE3E,wCAAwC;IACxC,MAAM,QAAQ,GAAG,eAAe,GAAG,CAAC;QAClC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE;QACxC,CAAC,CAAC,CAAC,CAAC;IAEN,oCAAoC;IACpC,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;SACxC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IAElD,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,eAAe;QACzB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE;QACxC,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { detectFlowState, FlowStateResult } from './flow-state';
|
|
2
|
+
export { detectPostDeleteSprint, PostDeleteSprintResult } from './post-delete-sprint';
|
|
3
|
+
export { detectThrashing, ThrashingResult, ThrashingFile } from './thrashing';
|
|
4
|
+
export { detectDetour, DetourResult, Detour } from './detour';
|
|
5
|
+
export { detectLateNightSpiral, LateNightSpiralResult, LateNightSpiral } from './late-night';
|
|
6
|
+
export { detectRegressions, analyzeRecoveryTimeTrend, getAllRecoveryTrends, RegressionAlert, RegressionAnalysis, } from './spiral-regression';
|
|
7
|
+
export { calculateEffectiveness, getRecommendation, compareInterventions, InterventionScore, EffectivenessAnalysis, } from './intervention-effectiveness';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compareInterventions = exports.getRecommendation = exports.calculateEffectiveness = exports.getAllRecoveryTrends = exports.analyzeRecoveryTimeTrend = exports.detectRegressions = exports.detectLateNightSpiral = exports.detectDetour = exports.detectThrashing = exports.detectPostDeleteSprint = exports.detectFlowState = void 0;
|
|
4
|
+
var flow_state_1 = require("./flow-state");
|
|
5
|
+
Object.defineProperty(exports, "detectFlowState", { enumerable: true, get: function () { return flow_state_1.detectFlowState; } });
|
|
6
|
+
var post_delete_sprint_1 = require("./post-delete-sprint");
|
|
7
|
+
Object.defineProperty(exports, "detectPostDeleteSprint", { enumerable: true, get: function () { return post_delete_sprint_1.detectPostDeleteSprint; } });
|
|
8
|
+
var thrashing_1 = require("./thrashing");
|
|
9
|
+
Object.defineProperty(exports, "detectThrashing", { enumerable: true, get: function () { return thrashing_1.detectThrashing; } });
|
|
10
|
+
var detour_1 = require("./detour");
|
|
11
|
+
Object.defineProperty(exports, "detectDetour", { enumerable: true, get: function () { return detour_1.detectDetour; } });
|
|
12
|
+
var late_night_1 = require("./late-night");
|
|
13
|
+
Object.defineProperty(exports, "detectLateNightSpiral", { enumerable: true, get: function () { return late_night_1.detectLateNightSpiral; } });
|
|
14
|
+
var spiral_regression_1 = require("./spiral-regression");
|
|
15
|
+
Object.defineProperty(exports, "detectRegressions", { enumerable: true, get: function () { return spiral_regression_1.detectRegressions; } });
|
|
16
|
+
Object.defineProperty(exports, "analyzeRecoveryTimeTrend", { enumerable: true, get: function () { return spiral_regression_1.analyzeRecoveryTimeTrend; } });
|
|
17
|
+
Object.defineProperty(exports, "getAllRecoveryTrends", { enumerable: true, get: function () { return spiral_regression_1.getAllRecoveryTrends; } });
|
|
18
|
+
var intervention_effectiveness_1 = require("./intervention-effectiveness");
|
|
19
|
+
Object.defineProperty(exports, "calculateEffectiveness", { enumerable: true, get: function () { return intervention_effectiveness_1.calculateEffectiveness; } });
|
|
20
|
+
Object.defineProperty(exports, "getRecommendation", { enumerable: true, get: function () { return intervention_effectiveness_1.getRecommendation; } });
|
|
21
|
+
Object.defineProperty(exports, "compareInterventions", { enumerable: true, get: function () { return intervention_effectiveness_1.compareInterventions; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAAvD,6GAAA,eAAe,OAAA;AACxB,2DAAsF;AAA7E,4HAAA,sBAAsB,OAAA;AAC/B,yCAA8E;AAArE,4GAAA,eAAe,OAAA;AACxB,mCAA8D;AAArD,sGAAA,YAAY,OAAA;AACrB,2CAA6F;AAApF,mHAAA,qBAAqB,OAAA;AAC9B,yDAM6B;AAL3B,sHAAA,iBAAiB,OAAA;AACjB,6HAAA,wBAAwB,OAAA;AACxB,yHAAA,oBAAoB,OAAA;AAItB,2EAMsC;AALpC,oIAAA,sBAAsB,OAAA;AACtB,+HAAA,iBAAiB,OAAA;AACjB,kIAAA,oBAAoB,OAAA"}
|
|
@@ -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"}
|