@boshu2/vibe-check 1.8.0 → 2.0.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/.claude/settings.local.json +1 -1
- package/CHANGELOG.md +10 -0
- package/CLAUDE.md +58 -0
- package/Makefile +43 -6
- package/README.md +80 -27
- package/bin/vibe-check.js +1 -1
- package/claude-progress.json +18 -0
- package/dist/analysis/cross-session-analysis.d.ts +1 -1
- package/dist/analysis/cross-session-analysis.d.ts.map +1 -1
- package/dist/analysis/cross-session-analysis.js +9 -18
- package/dist/analysis/cross-session-analysis.js.map +1 -1
- package/dist/analysis/index.d.ts +1 -1
- package/dist/analysis/index.d.ts.map +1 -1
- package/dist/analysis/index.js +1 -11
- package/dist/analysis/index.js.map +1 -1
- package/dist/analyzers/audit.d.ts +28 -0
- package/dist/analyzers/audit.d.ts.map +1 -0
- package/dist/analyzers/audit.js +86 -0
- package/dist/analyzers/audit.js.map +1 -0
- package/dist/analyzers/patterns.d.ts +1 -1
- package/dist/analyzers/patterns.d.ts.map +1 -1
- package/dist/analyzers/patterns.js +4 -10
- package/dist/analyzers/patterns.js.map +1 -1
- package/dist/analyzers/quality.d.ts +1 -1
- package/dist/analyzers/quality.d.ts.map +1 -1
- package/dist/analyzers/quality.js +5 -12
- package/dist/analyzers/quality.js.map +1 -1
- package/dist/analyzers/sessions.d.ts +1 -1
- package/dist/analyzers/sessions.d.ts.map +1 -1
- package/dist/analyzers/sessions.js +1 -4
- package/dist/analyzers/sessions.js.map +1 -1
- package/dist/cli.js +20 -20
- package/dist/cli.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +114 -149
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +77 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/cache.js +31 -70
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +22 -58
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/forensics.d.ts +2 -2
- package/dist/commands/forensics.d.ts.map +1 -1
- package/dist/commands/forensics.js +41 -48
- package/dist/commands/forensics.js.map +1 -1
- package/dist/commands/index.d.ts +14 -13
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +14 -33
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init-hook.js +26 -32
- package/dist/commands/init-hook.js.map +1 -1
- package/dist/commands/insights.js +39 -45
- package/dist/commands/insights.js.map +1 -1
- package/dist/commands/pipeline.js +39 -78
- package/dist/commands/pipeline.js.map +1 -1
- package/dist/commands/profile.js +68 -74
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/session.d.ts +9 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +134 -118
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/sessions.d.ts +1 -1
- package/dist/commands/sessions.d.ts.map +1 -1
- package/dist/commands/sessions.js +42 -49
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/start.js +22 -67
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/timeline.js +74 -81
- package/dist/commands/timeline.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +117 -47
- package/dist/commands/watch.js.map +1 -1
- package/dist/gamification/achievements.d.ts +1 -1
- package/dist/gamification/achievements.d.ts.map +1 -1
- package/dist/gamification/achievements.js +7 -13
- package/dist/gamification/achievements.js.map +1 -1
- package/dist/gamification/index.d.ts +8 -8
- package/dist/gamification/index.d.ts.map +1 -1
- package/dist/gamification/index.js +8 -28
- package/dist/gamification/index.js.map +1 -1
- package/dist/gamification/profile.d.ts +2 -2
- package/dist/gamification/profile.d.ts.map +1 -1
- package/dist/gamification/profile.js +21 -64
- package/dist/gamification/profile.js.map +1 -1
- package/dist/gamification/stats.d.ts +1 -1
- package/dist/gamification/stats.d.ts.map +1 -1
- package/dist/gamification/stats.js +4 -10
- package/dist/gamification/stats.js.map +1 -1
- package/dist/gamification/streaks.d.ts +1 -1
- package/dist/gamification/streaks.d.ts.map +1 -1
- package/dist/gamification/streaks.js +8 -18
- package/dist/gamification/streaks.js.map +1 -1
- package/dist/gamification/types.js +3 -6
- package/dist/gamification/types.js.map +1 -1
- package/dist/gamification/xp.d.ts +1 -1
- package/dist/gamification/xp.d.ts.map +1 -1
- package/dist/gamification/xp.js +29 -38
- package/dist/gamification/xp.js.map +1 -1
- package/dist/git.d.ts +1 -1
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +15 -27
- package/dist/git.js.map +1 -1
- package/dist/inner-loop/context-amnesia.d.ts +20 -0
- package/dist/inner-loop/context-amnesia.d.ts.map +1 -0
- package/dist/inner-loop/context-amnesia.js +246 -0
- package/dist/inner-loop/context-amnesia.js.map +1 -0
- package/dist/inner-loop/index.d.ts +39 -0
- package/dist/inner-loop/index.d.ts.map +1 -0
- package/dist/inner-loop/index.js +181 -0
- package/dist/inner-loop/index.js.map +1 -0
- package/dist/inner-loop/instruction-drift.d.ts +28 -0
- package/dist/inner-loop/instruction-drift.d.ts.map +1 -0
- package/dist/inner-loop/instruction-drift.js +255 -0
- package/dist/inner-loop/instruction-drift.js.map +1 -0
- package/dist/inner-loop/logging-only.d.ts +30 -0
- package/dist/inner-loop/logging-only.d.ts.map +1 -0
- package/dist/inner-loop/logging-only.js +256 -0
- package/dist/inner-loop/logging-only.js.map +1 -0
- package/dist/inner-loop/tests-passing-lie.d.ts +34 -0
- package/dist/inner-loop/tests-passing-lie.d.ts.map +1 -0
- package/dist/inner-loop/tests-passing-lie.js +208 -0
- package/dist/inner-loop/tests-passing-lie.js.map +1 -0
- package/dist/inner-loop/types.d.ts +111 -0
- package/dist/inner-loop/types.d.ts.map +1 -0
- package/dist/inner-loop/types.js +26 -0
- package/dist/inner-loop/types.js.map +1 -0
- package/dist/insights/generators.d.ts +4 -4
- package/dist/insights/generators.d.ts.map +1 -1
- package/dist/insights/generators.js +9 -20
- package/dist/insights/generators.js.map +1 -1
- package/dist/insights/index.d.ts +4 -4
- package/dist/insights/index.d.ts.map +1 -1
- package/dist/insights/index.js +23 -27
- package/dist/insights/index.js.map +1 -1
- package/dist/insights/types.js +1 -2
- package/dist/insights/types.js.map +1 -1
- package/dist/metrics/code-stability.d.ts +1 -1
- package/dist/metrics/code-stability.d.ts.map +1 -1
- package/dist/metrics/code-stability.js +1 -4
- package/dist/metrics/code-stability.js.map +1 -1
- package/dist/metrics/file-churn.d.ts +1 -1
- package/dist/metrics/file-churn.d.ts.map +1 -1
- package/dist/metrics/file-churn.js +1 -4
- package/dist/metrics/file-churn.js.map +1 -1
- package/dist/metrics/flow.d.ts +1 -1
- package/dist/metrics/flow.d.ts.map +1 -1
- package/dist/metrics/flow.js +1 -4
- package/dist/metrics/flow.js.map +1 -1
- package/dist/metrics/index.d.ts +2 -2
- package/dist/metrics/index.d.ts.map +1 -1
- package/dist/metrics/index.js +15 -20
- package/dist/metrics/index.js.map +1 -1
- package/dist/metrics/rework.d.ts +1 -1
- package/dist/metrics/rework.d.ts.map +1 -1
- package/dist/metrics/rework.js +1 -4
- package/dist/metrics/rework.js.map +1 -1
- package/dist/metrics/spirals.d.ts +1 -1
- package/dist/metrics/spirals.d.ts.map +1 -1
- package/dist/metrics/spirals.js +5 -10
- package/dist/metrics/spirals.js.map +1 -1
- package/dist/metrics/time-spiral.d.ts +1 -1
- package/dist/metrics/time-spiral.d.ts.map +1 -1
- package/dist/metrics/time-spiral.js +1 -4
- package/dist/metrics/time-spiral.js.map +1 -1
- package/dist/metrics/trust.d.ts +1 -1
- package/dist/metrics/trust.d.ts.map +1 -1
- package/dist/metrics/trust.js +3 -6
- package/dist/metrics/trust.js.map +1 -1
- package/dist/metrics/velocity-anomaly.d.ts +1 -1
- package/dist/metrics/velocity-anomaly.d.ts.map +1 -1
- package/dist/metrics/velocity-anomaly.js +3 -6
- package/dist/metrics/velocity-anomaly.js.map +1 -1
- package/dist/metrics/velocity.d.ts +1 -1
- package/dist/metrics/velocity.d.ts.map +1 -1
- package/dist/metrics/velocity.js +6 -10
- package/dist/metrics/velocity.js.map +1 -1
- package/dist/output/index.d.ts +4 -4
- package/dist/output/index.d.ts.map +1 -1
- package/dist/output/index.js +10 -18
- package/dist/output/index.js.map +1 -1
- package/dist/output/json.d.ts +1 -1
- package/dist/output/json.d.ts.map +1 -1
- package/dist/output/json.js +1 -4
- package/dist/output/json.js.map +1 -1
- package/dist/output/markdown.d.ts +1 -1
- package/dist/output/markdown.d.ts.map +1 -1
- package/dist/output/markdown.js +5 -8
- package/dist/output/markdown.js.map +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/output/terminal.d.ts.map +1 -1
- package/dist/output/terminal.js +55 -62
- package/dist/output/terminal.js.map +1 -1
- package/dist/output/timeline-html.d.ts +1 -1
- package/dist/output/timeline-html.d.ts.map +1 -1
- package/dist/output/timeline-html.js +5 -8
- package/dist/output/timeline-html.js.map +1 -1
- package/dist/output/timeline-markdown.d.ts +1 -1
- package/dist/output/timeline-markdown.d.ts.map +1 -1
- package/dist/output/timeline-markdown.js +5 -8
- package/dist/output/timeline-markdown.js.map +1 -1
- package/dist/output/timeline.d.ts +1 -1
- package/dist/output/timeline.d.ts.map +1 -1
- package/dist/output/timeline.js +46 -52
- package/dist/output/timeline.js.map +1 -1
- package/dist/patterns/detour.d.ts +1 -1
- package/dist/patterns/detour.d.ts.map +1 -1
- package/dist/patterns/detour.js +1 -4
- package/dist/patterns/detour.js.map +1 -1
- package/dist/patterns/flow-state.d.ts +1 -1
- package/dist/patterns/flow-state.d.ts.map +1 -1
- package/dist/patterns/flow-state.js +1 -4
- package/dist/patterns/flow-state.js.map +1 -1
- package/dist/patterns/index.d.ts +7 -7
- package/dist/patterns/index.d.ts.map +1 -1
- package/dist/patterns/index.js +7 -21
- package/dist/patterns/index.js.map +1 -1
- package/dist/patterns/intervention-effectiveness.d.ts +1 -1
- package/dist/patterns/intervention-effectiveness.d.ts.map +1 -1
- package/dist/patterns/intervention-effectiveness.js +3 -8
- package/dist/patterns/intervention-effectiveness.js.map +1 -1
- package/dist/patterns/late-night.d.ts +1 -1
- package/dist/patterns/late-night.d.ts.map +1 -1
- package/dist/patterns/late-night.js +1 -4
- package/dist/patterns/late-night.js.map +1 -1
- package/dist/patterns/post-delete-sprint.d.ts +1 -1
- package/dist/patterns/post-delete-sprint.d.ts.map +1 -1
- package/dist/patterns/post-delete-sprint.js +1 -4
- package/dist/patterns/post-delete-sprint.js.map +1 -1
- package/dist/patterns/spiral-regression.d.ts +1 -1
- package/dist/patterns/spiral-regression.d.ts.map +1 -1
- package/dist/patterns/spiral-regression.js +3 -8
- package/dist/patterns/spiral-regression.js.map +1 -1
- package/dist/patterns/thrashing.d.ts +1 -1
- package/dist/patterns/thrashing.d.ts.map +1 -1
- package/dist/patterns/thrashing.js +3 -6
- package/dist/patterns/thrashing.js.map +1 -1
- package/dist/score/index.d.ts +3 -3
- package/dist/score/index.d.ts.map +1 -1
- package/dist/score/index.js +4 -10
- package/dist/score/index.js.map +1 -1
- package/dist/score/weights.js +2 -6
- package/dist/score/weights.js.map +1 -1
- package/dist/sessions/index.js +9 -51
- package/dist/sessions/index.js.map +1 -1
- package/dist/storage/atomic.js +10 -51
- package/dist/storage/atomic.js.map +1 -1
- package/dist/storage/commit-log.d.ts +1 -1
- package/dist/storage/commit-log.d.ts.map +1 -1
- package/dist/storage/commit-log.js +11 -51
- package/dist/storage/commit-log.js.map +1 -1
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +5 -37
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/schema.js +4 -9
- package/dist/storage/schema.js.map +1 -1
- package/dist/storage/spiral-history.js +14 -57
- package/dist/storage/spiral-history.js.map +1 -1
- package/dist/storage/timeline-store.d.ts +2 -2
- package/dist/storage/timeline-store.d.ts.map +1 -1
- package/dist/storage/timeline-store.js +17 -61
- package/dist/storage/timeline-store.js.map +1 -1
- package/dist/types.js +1 -2
- package/docs/ENHANCEMENT-PLAN.md +361 -0
- package/docs/FEATURES.md +340 -0
- package/feature-list.json +6 -0
- package/package.json +8 -7
- package/dist/calibration/ece.d.ts +0 -26
- package/dist/calibration/ece.d.ts.map +0 -1
- package/dist/calibration/ece.js +0 -93
- package/dist/calibration/ece.js.map +0 -1
- package/dist/calibration/index.d.ts +0 -3
- package/dist/calibration/index.d.ts.map +0 -1
- package/dist/calibration/index.js +0 -15
- package/dist/calibration/index.js.map +0 -1
- package/dist/calibration/storage.d.ts +0 -34
- package/dist/calibration/storage.d.ts.map +0 -1
- package/dist/calibration/storage.js +0 -188
- package/dist/calibration/storage.js.map +0 -1
- package/dist/commands/intervene.d.ts +0 -15
- package/dist/commands/intervene.d.ts.map +0 -1
- package/dist/commands/intervene.js +0 -183
- package/dist/commands/intervene.js.map +0 -1
- package/dist/commands/learn.d.ts +0 -3
- package/dist/commands/learn.d.ts.map +0 -1
- package/dist/commands/learn.js +0 -161
- package/dist/commands/learn.js.map +0 -1
- package/dist/commands/lesson.d.ts +0 -8
- package/dist/commands/lesson.d.ts.map +0 -1
- package/dist/commands/lesson.js +0 -206
- package/dist/commands/lesson.js.map +0 -1
- package/dist/commands/level.d.ts +0 -3
- package/dist/commands/level.d.ts.map +0 -1
- package/dist/commands/level.js +0 -277
- package/dist/commands/level.js.map +0 -1
- package/dist/gamification/badges.d.ts +0 -29
- package/dist/gamification/badges.d.ts.map +0 -1
- package/dist/gamification/badges.js +0 -114
- package/dist/gamification/badges.js.map +0 -1
- package/dist/gamification/challenges.d.ts +0 -42
- package/dist/gamification/challenges.d.ts.map +0 -1
- package/dist/gamification/challenges.js +0 -184
- package/dist/gamification/challenges.js.map +0 -1
- package/dist/gamification/hall-of-fame.d.ts +0 -17
- package/dist/gamification/hall-of-fame.d.ts.map +0 -1
- package/dist/gamification/hall-of-fame.js +0 -64
- package/dist/gamification/hall-of-fame.js.map +0 -1
- package/dist/gamification/intervention-memory.d.ts +0 -61
- package/dist/gamification/intervention-memory.d.ts.map +0 -1
- package/dist/gamification/intervention-memory.js +0 -229
- package/dist/gamification/intervention-memory.js.map +0 -1
- package/dist/gamification/leaderboards.d.ts +0 -49
- package/dist/gamification/leaderboards.d.ts.map +0 -1
- package/dist/gamification/leaderboards.js +0 -179
- package/dist/gamification/leaderboards.js.map +0 -1
- package/dist/gamification/pattern-memory.d.ts +0 -45
- package/dist/gamification/pattern-memory.d.ts.map +0 -1
- package/dist/gamification/pattern-memory.js +0 -188
- package/dist/gamification/pattern-memory.js.map +0 -1
- package/dist/gamification/share.d.ts +0 -29
- package/dist/gamification/share.d.ts.map +0 -1
- package/dist/gamification/share.js +0 -57
- package/dist/gamification/share.js.map +0 -1
- package/dist/learning/cadence.d.ts +0 -15
- package/dist/learning/cadence.d.ts.map +0 -1
- package/dist/learning/cadence.js +0 -130
- package/dist/learning/cadence.js.map +0 -1
- package/dist/learning/index.d.ts +0 -19
- package/dist/learning/index.d.ts.map +0 -1
- package/dist/learning/index.js +0 -35
- package/dist/learning/index.js.map +0 -1
- package/dist/learning/lessons-storage.d.ts +0 -48
- package/dist/learning/lessons-storage.d.ts.map +0 -1
- package/dist/learning/lessons-storage.js +0 -266
- package/dist/learning/lessons-storage.js.map +0 -1
- package/dist/learning/lessons-types.d.ts +0 -83
- package/dist/learning/lessons-types.d.ts.map +0 -1
- package/dist/learning/lessons-types.js +0 -15
- package/dist/learning/lessons-types.js.map +0 -1
- package/dist/learning/nudges.d.ts +0 -20
- package/dist/learning/nudges.d.ts.map +0 -1
- package/dist/learning/nudges.js +0 -68
- package/dist/learning/nudges.js.map +0 -1
- package/dist/learning/retrospective.d.ts +0 -27
- package/dist/learning/retrospective.d.ts.map +0 -1
- package/dist/learning/retrospective.js +0 -184
- package/dist/learning/retrospective.js.map +0 -1
- package/dist/learning/storage.d.ts +0 -44
- package/dist/learning/storage.d.ts.map +0 -1
- package/dist/learning/storage.js +0 -194
- package/dist/learning/storage.js.map +0 -1
- package/dist/learning/surfacing.d.ts +0 -36
- package/dist/learning/surfacing.d.ts.map +0 -1
- package/dist/learning/surfacing.js +0 -255
- package/dist/learning/surfacing.js.map +0 -1
- package/dist/learning/synthesis.d.ts +0 -17
- package/dist/learning/synthesis.d.ts.map +0 -1
- package/dist/learning/synthesis.js +0 -293
- package/dist/learning/synthesis.js.map +0 -1
- package/dist/learning/types.d.ts +0 -60
- package/dist/learning/types.d.ts.map +0 -1
- package/dist/learning/types.js +0 -17
- package/dist/learning/types.js.map +0 -1
- package/dist/recommend/index.d.ts +0 -3
- package/dist/recommend/index.d.ts.map +0 -1
- package/dist/recommend/index.js +0 -14
- package/dist/recommend/index.js.map +0 -1
- package/dist/recommend/ordered-logistic.d.ts +0 -49
- package/dist/recommend/ordered-logistic.d.ts.map +0 -1
- package/dist/recommend/ordered-logistic.js +0 -153
- package/dist/recommend/ordered-logistic.js.map +0 -1
- package/dist/recommend/questions.d.ts +0 -19
- package/dist/recommend/questions.d.ts.map +0 -1
- package/dist/recommend/questions.js +0 -73
- package/dist/recommend/questions.js.map +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Tests Passing" Lie Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects when AI claims "all tests passing" or "working" but the code
|
|
5
|
+
* actually doesn't work. This is detected through:
|
|
6
|
+
*
|
|
7
|
+
* 1. Inferred: Commit claims success but is immediately followed by fixes
|
|
8
|
+
* 2. Verified: Actually run tests/build and compare to commit claims
|
|
9
|
+
*
|
|
10
|
+
* This is a key "Inner Loop Disaster" in vibe coding.
|
|
11
|
+
*/
|
|
12
|
+
import { differenceInMinutes } from 'date-fns';
|
|
13
|
+
import { exec } from 'child_process';
|
|
14
|
+
import { promisify } from 'util';
|
|
15
|
+
import { DEFAULT_INNER_LOOP_CONFIG, } from './types.js';
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
// Patterns that indicate a claim of success
|
|
18
|
+
const SUCCESS_CLAIM_PATTERNS = [
|
|
19
|
+
/\bfix(ed|es)?\b/i,
|
|
20
|
+
/\bworking\b/i,
|
|
21
|
+
/\bdone\b/i,
|
|
22
|
+
/\bcomplete[ds]?\b/i,
|
|
23
|
+
/\bresolve[ds]?\b/i,
|
|
24
|
+
/\bpass(es|ing)?\b/i,
|
|
25
|
+
/\bgreen\b/i,
|
|
26
|
+
/\bsuccessful(ly)?\b/i,
|
|
27
|
+
/\ball\s+tests?\b/i,
|
|
28
|
+
/\bready\b/i,
|
|
29
|
+
/\bshould\s+work/i,
|
|
30
|
+
/\bnow\s+works?\b/i,
|
|
31
|
+
];
|
|
32
|
+
// Patterns that indicate the commit is tentative (not a lie if it fails)
|
|
33
|
+
const TENTATIVE_PATTERNS = [
|
|
34
|
+
/\btry\b/i,
|
|
35
|
+
/\battempt/i,
|
|
36
|
+
/\bmaybe\b/i,
|
|
37
|
+
/\bwip\b/i,
|
|
38
|
+
/\bwork\s*in\s*progress/i,
|
|
39
|
+
/\bexperiment/i,
|
|
40
|
+
/\btest(ing)?\b/i, // Just "testing" something
|
|
41
|
+
/\bdebug/i,
|
|
42
|
+
/\binvestigat/i,
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Detect "tests passing" lies through pattern analysis.
|
|
46
|
+
* This is the inferred method that works without running actual tests.
|
|
47
|
+
*/
|
|
48
|
+
export function detectTestsPassingLie(events, filesPerCommit, config = {}) {
|
|
49
|
+
const cfg = { ...DEFAULT_INNER_LOOP_CONFIG, ...config };
|
|
50
|
+
const lies = [];
|
|
51
|
+
if (events.length < 2) {
|
|
52
|
+
return {
|
|
53
|
+
detected: false,
|
|
54
|
+
lies: [],
|
|
55
|
+
totalLies: 0,
|
|
56
|
+
message: 'Not enough commits to detect lies',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Sort by timestamp ascending
|
|
60
|
+
const sorted = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
61
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
62
|
+
const commit = sorted[i];
|
|
63
|
+
const claimsSuccess = claimsToBeSuccessful(commit.subject);
|
|
64
|
+
const isTentative = isTentativeCommit(commit.subject);
|
|
65
|
+
// Skip if tentative or doesn't claim success
|
|
66
|
+
if (!claimsSuccess || isTentative)
|
|
67
|
+
continue;
|
|
68
|
+
// Look at following commits within 30 minutes
|
|
69
|
+
const followingCommits = getFollowingCommitsInWindow(sorted, i, 30);
|
|
70
|
+
// Check if followed by fix commits on same files
|
|
71
|
+
const commitFiles = filesPerCommit.get(commit.hash) || [];
|
|
72
|
+
const quickFixes = followingCommits.filter((fc) => {
|
|
73
|
+
if (fc.type !== 'fix')
|
|
74
|
+
return false;
|
|
75
|
+
// Check file overlap
|
|
76
|
+
const fcFiles = filesPerCommit.get(fc.hash) || [];
|
|
77
|
+
const hasOverlap = commitFiles.some((f) => fcFiles.includes(f));
|
|
78
|
+
// Or same scope
|
|
79
|
+
const sameScope = commit.scope && fc.scope === commit.scope;
|
|
80
|
+
return hasOverlap || sameScope;
|
|
81
|
+
});
|
|
82
|
+
if (quickFixes.length > 0) {
|
|
83
|
+
const gap = differenceInMinutes(quickFixes[0].timestamp, commit.timestamp);
|
|
84
|
+
lies.push({
|
|
85
|
+
commitHash: commit.hash,
|
|
86
|
+
commitMessage: commit.subject,
|
|
87
|
+
timestamp: commit.timestamp,
|
|
88
|
+
claimedSuccess: true,
|
|
89
|
+
actualResult: 'inferred',
|
|
90
|
+
verificationMethod: 'inferred',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const detected = lies.length > 0;
|
|
95
|
+
let message = '';
|
|
96
|
+
if (detected) {
|
|
97
|
+
const lieRate = Math.round((lies.length / events.length) * 100);
|
|
98
|
+
message = `🤥 ${lies.length} "tests passing" lie${lies.length > 1 ? 's' : ''} detected: commits claimed success but required immediate fixes (${lieRate}% lie rate)`;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
detected,
|
|
102
|
+
lies: lies.slice(0, 10),
|
|
103
|
+
totalLies: lies.length,
|
|
104
|
+
message,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Verify a specific commit by actually running tests.
|
|
109
|
+
* This requires the repo to be at that commit state.
|
|
110
|
+
*/
|
|
111
|
+
export async function verifyCommit(repoPath, commitHash, config = {}) {
|
|
112
|
+
const cfg = { ...DEFAULT_INNER_LOOP_CONFIG, ...config };
|
|
113
|
+
// Determine test command
|
|
114
|
+
const testCommand = cfg.testCommand || detectTestCommand(repoPath);
|
|
115
|
+
if (!testCommand) {
|
|
116
|
+
return { passed: true, output: 'No test command configured or detected' };
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const { stdout, stderr } = await execAsync(testCommand, {
|
|
120
|
+
cwd: repoPath,
|
|
121
|
+
timeout: 120000, // 2 minute timeout
|
|
122
|
+
});
|
|
123
|
+
return { passed: true, output: stdout + stderr };
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const execError = error;
|
|
127
|
+
return {
|
|
128
|
+
passed: false,
|
|
129
|
+
output: (execError.stdout || '') + (execError.stderr || '') + (execError.message || ''),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Verify build passes for a commit.
|
|
135
|
+
*/
|
|
136
|
+
export async function verifyBuild(repoPath, config = {}) {
|
|
137
|
+
const cfg = { ...DEFAULT_INNER_LOOP_CONFIG, ...config };
|
|
138
|
+
const buildCommand = cfg.buildCommand || detectBuildCommand(repoPath);
|
|
139
|
+
if (!buildCommand) {
|
|
140
|
+
return { passed: true, output: 'No build command configured or detected' };
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const { stdout, stderr } = await execAsync(buildCommand, {
|
|
144
|
+
cwd: repoPath,
|
|
145
|
+
timeout: 300000, // 5 minute timeout
|
|
146
|
+
});
|
|
147
|
+
return { passed: true, output: stdout + stderr };
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
const execError = error;
|
|
151
|
+
return {
|
|
152
|
+
passed: false,
|
|
153
|
+
output: (execError.stdout || '') + (execError.stderr || '') + (execError.message || ''),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if a commit message claims success.
|
|
159
|
+
*/
|
|
160
|
+
function claimsToBeSuccessful(message) {
|
|
161
|
+
return SUCCESS_CLAIM_PATTERNS.some((p) => p.test(message));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Check if a commit is tentative (WIP, try, experiment, etc.)
|
|
165
|
+
*/
|
|
166
|
+
function isTentativeCommit(message) {
|
|
167
|
+
return TENTATIVE_PATTERNS.some((p) => p.test(message));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get commits following a given index within a time window.
|
|
171
|
+
*/
|
|
172
|
+
function getFollowingCommitsInWindow(events, index, windowMinutes) {
|
|
173
|
+
const result = [];
|
|
174
|
+
const baseTime = events[index].timestamp;
|
|
175
|
+
const windowEnd = new Date(baseTime.getTime() + windowMinutes * 60 * 1000);
|
|
176
|
+
for (let i = index + 1; i < events.length; i++) {
|
|
177
|
+
if (events[i].timestamp > windowEnd)
|
|
178
|
+
break;
|
|
179
|
+
result.push(events[i]);
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Detect test command from project configuration.
|
|
185
|
+
*/
|
|
186
|
+
function detectTestCommand(repoPath) {
|
|
187
|
+
// Common test commands by project type
|
|
188
|
+
// In real implementation, we'd check package.json, Makefile, etc.
|
|
189
|
+
const commands = [
|
|
190
|
+
'npm test',
|
|
191
|
+
'yarn test',
|
|
192
|
+
'pnpm test',
|
|
193
|
+
'make test',
|
|
194
|
+
'cargo test',
|
|
195
|
+
'go test ./...',
|
|
196
|
+
'pytest',
|
|
197
|
+
'python -m pytest',
|
|
198
|
+
];
|
|
199
|
+
// For now, return npm test as default for Node projects
|
|
200
|
+
return 'npm test';
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Detect build command from project configuration.
|
|
204
|
+
*/
|
|
205
|
+
function detectBuildCommand(repoPath) {
|
|
206
|
+
return 'npm run build';
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=tests-passing-lie.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tests-passing-lie.js","sourceRoot":"","sources":["../../src/inner-loop/tests-passing-lie.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inner Loop Failure Pattern Types
|
|
3
|
+
*
|
|
4
|
+
* These detect the 4 "Inner Loop Disasters" from vibe coding:
|
|
5
|
+
* 1. "Tests Passing" Lie - AI claims success but code doesn't work
|
|
6
|
+
* 2. Context Amnesia - Forgets instructions, re-does work
|
|
7
|
+
* 3. Instruction Drift - "Improves" things not asked for
|
|
8
|
+
* 4. Debug Loop Spiral - Adds logging instead of fixing
|
|
9
|
+
*/
|
|
10
|
+
export interface TestsPassingLieResult {
|
|
11
|
+
detected: boolean;
|
|
12
|
+
lies: TestsPassingLie[];
|
|
13
|
+
totalLies: number;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export interface TestsPassingLie {
|
|
17
|
+
commitHash: string;
|
|
18
|
+
commitMessage: string;
|
|
19
|
+
timestamp: Date;
|
|
20
|
+
claimedSuccess: boolean;
|
|
21
|
+
actualResult: 'build_failed' | 'tests_failed' | 'unknown';
|
|
22
|
+
verificationMethod: 'npm_test' | 'npm_build' | 'make_test' | 'inferred';
|
|
23
|
+
}
|
|
24
|
+
export interface ContextAmnesiaResult {
|
|
25
|
+
detected: boolean;
|
|
26
|
+
incidents: ContextAmnesiaIncident[];
|
|
27
|
+
totalIncidents: number;
|
|
28
|
+
totalTimeWasted: number;
|
|
29
|
+
message: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ContextAmnesiaIncident {
|
|
32
|
+
type: 'revert' | 'reimplementation' | 'forgotten_change';
|
|
33
|
+
originalCommit: {
|
|
34
|
+
hash: string;
|
|
35
|
+
message: string;
|
|
36
|
+
timestamp: Date;
|
|
37
|
+
};
|
|
38
|
+
repeatCommit: {
|
|
39
|
+
hash: string;
|
|
40
|
+
message: string;
|
|
41
|
+
timestamp: Date;
|
|
42
|
+
};
|
|
43
|
+
scope: string | null;
|
|
44
|
+
filesAffected: string[];
|
|
45
|
+
gapMinutes: number;
|
|
46
|
+
description: string;
|
|
47
|
+
}
|
|
48
|
+
export interface InstructionDriftResult {
|
|
49
|
+
detected: boolean;
|
|
50
|
+
drifts: InstructionDrift[];
|
|
51
|
+
totalDriftCommits: number;
|
|
52
|
+
totalUnauthorizedFiles: number;
|
|
53
|
+
message: string;
|
|
54
|
+
}
|
|
55
|
+
export interface InstructionDrift {
|
|
56
|
+
commitHash: string;
|
|
57
|
+
commitMessage: string;
|
|
58
|
+
timestamp: Date;
|
|
59
|
+
driftType: 'scope_creep' | 'unrequested_refactor' | 'unrequested_improvement' | 'style_change';
|
|
60
|
+
unauthorizedFiles: string[];
|
|
61
|
+
authorizedScope: string[];
|
|
62
|
+
description: string;
|
|
63
|
+
}
|
|
64
|
+
export interface SessionScope {
|
|
65
|
+
intendedFiles: string[];
|
|
66
|
+
intendedDirs: string[];
|
|
67
|
+
taskDescription?: string;
|
|
68
|
+
startTime: Date;
|
|
69
|
+
}
|
|
70
|
+
export interface LoggingOnlyResult {
|
|
71
|
+
detected: boolean;
|
|
72
|
+
loggingCommits: LoggingOnlyCommit[];
|
|
73
|
+
consecutiveLoggingCount: number;
|
|
74
|
+
totalLoggingCommits: number;
|
|
75
|
+
message: string;
|
|
76
|
+
}
|
|
77
|
+
export interface LoggingOnlyCommit {
|
|
78
|
+
hash: string;
|
|
79
|
+
message: string;
|
|
80
|
+
timestamp: Date;
|
|
81
|
+
loggingStatements: number;
|
|
82
|
+
actualFixes: number;
|
|
83
|
+
isLoggingOnly: boolean;
|
|
84
|
+
loggingPatterns: string[];
|
|
85
|
+
}
|
|
86
|
+
export interface InnerLoopAnalysis {
|
|
87
|
+
testsPassingLie: TestsPassingLieResult;
|
|
88
|
+
contextAmnesia: ContextAmnesiaResult;
|
|
89
|
+
instructionDrift: InstructionDriftResult;
|
|
90
|
+
loggingOnly: LoggingOnlyResult;
|
|
91
|
+
summary: {
|
|
92
|
+
totalIssuesDetected: number;
|
|
93
|
+
criticalIssues: number;
|
|
94
|
+
warningIssues: number;
|
|
95
|
+
overallHealth: 'healthy' | 'warning' | 'critical';
|
|
96
|
+
};
|
|
97
|
+
recommendations: string[];
|
|
98
|
+
}
|
|
99
|
+
export interface InnerLoopConfig {
|
|
100
|
+
runTestsAfterCommit: boolean;
|
|
101
|
+
testCommand?: string;
|
|
102
|
+
buildCommand?: string;
|
|
103
|
+
amnesiaWindowMinutes: number;
|
|
104
|
+
similarityThreshold: number;
|
|
105
|
+
sessionScope?: SessionScope;
|
|
106
|
+
allowedDriftFiles: string[];
|
|
107
|
+
maxConsecutiveLoggingCommits: number;
|
|
108
|
+
loggingPatterns: RegExp[];
|
|
109
|
+
}
|
|
110
|
+
export declare const DEFAULT_INNER_LOOP_CONFIG: InnerLoopConfig;
|
|
111
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/inner-loop/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inner Loop Failure Pattern Types
|
|
3
|
+
*
|
|
4
|
+
* These detect the 4 "Inner Loop Disasters" from vibe coding:
|
|
5
|
+
* 1. "Tests Passing" Lie - AI claims success but code doesn't work
|
|
6
|
+
* 2. Context Amnesia - Forgets instructions, re-does work
|
|
7
|
+
* 3. Instruction Drift - "Improves" things not asked for
|
|
8
|
+
* 4. Debug Loop Spiral - Adds logging instead of fixing
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_INNER_LOOP_CONFIG = {
|
|
11
|
+
runTestsAfterCommit: false,
|
|
12
|
+
amnesiaWindowMinutes: 60,
|
|
13
|
+
similarityThreshold: 0.7,
|
|
14
|
+
allowedDriftFiles: ['package.json', 'package-lock.json', 'tsconfig.json', '.gitignore'],
|
|
15
|
+
maxConsecutiveLoggingCommits: 3,
|
|
16
|
+
loggingPatterns: [
|
|
17
|
+
/console\.(log|error|warn|debug|info)\(/,
|
|
18
|
+
/print\s*\(/,
|
|
19
|
+
/logger\.(log|error|warn|debug|info)\(/,
|
|
20
|
+
/System\.out\.print/,
|
|
21
|
+
/fmt\.Print/,
|
|
22
|
+
/debug!\(/,
|
|
23
|
+
/println!\(/,
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/inner-loop/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuJH,MAAM,CAAC,MAAM,yBAAyB,GAAoB;IACxD,mBAAmB,EAAE,KAAK;IAC1B,oBAAoB,EAAE,EAAE;IACxB,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,CAAC,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,CAAC;IACvF,4BAA4B,EAAE,CAAC;IAC/B,eAAe,EAAE;QACf,wCAAwC;QACxC,YAAY;QACZ,uCAAuC;QACvC,oBAAoB;QACpB,YAAY;QACZ,UAAU;QACV,YAAY;KACb;CACF,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Insight generators - each produces insights from specific data sources
|
|
3
3
|
*/
|
|
4
|
-
import { Insight } from './types';
|
|
5
|
-
import { UserProfile } from '../gamification/types';
|
|
6
|
-
import { TimelineStore } from '../storage/timeline-store';
|
|
7
|
-
import { Commit } from '../types';
|
|
4
|
+
import { Insight } from './types.js';
|
|
5
|
+
import { UserProfile } from '../gamification/types.js';
|
|
6
|
+
import { TimelineStore } from '../storage/timeline-store.js';
|
|
7
|
+
import { Commit } from '../types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Find peak productivity hours from commits
|
|
10
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/insights/generators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/insights/generators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAgC1E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,IAAI,CA+BrF;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAwClF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAwB9E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CA8BhF;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAoBjF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAwB1E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAwBrF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,IAAI,CAgCxE"}
|
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Insight generators - each produces insights from specific data sources
|
|
4
3
|
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.generatePeakHoursInsight = generatePeakHoursInsight;
|
|
7
|
-
exports.generateImprovementStreakInsight = generateImprovementStreakInsight;
|
|
8
|
-
exports.generateProblematicScopesInsight = generateProblematicScopesInsight;
|
|
9
|
-
exports.generateStreakRiskInsight = generateStreakRiskInsight;
|
|
10
|
-
exports.generatePersonalBestInsight = generatePersonalBestInsight;
|
|
11
|
-
exports.generateLevelProgressInsight = generateLevelProgressInsight;
|
|
12
|
-
exports.generateLateNightInsight = generateLateNightInsight;
|
|
13
|
-
exports.generateRecentAchievementInsight = generateRecentAchievementInsight;
|
|
14
|
-
exports.generateBestDayInsight = generateBestDayInsight;
|
|
15
4
|
/**
|
|
16
5
|
* Find peak productivity hours from commits
|
|
17
6
|
*/
|
|
18
|
-
function generatePeakHoursInsight(commits) {
|
|
7
|
+
export function generatePeakHoursInsight(commits) {
|
|
19
8
|
if (commits.length < 10)
|
|
20
9
|
return null;
|
|
21
10
|
const hourCounts = {};
|
|
@@ -48,7 +37,7 @@ function generatePeakHoursInsight(commits) {
|
|
|
48
37
|
/**
|
|
49
38
|
* Detect improvement streak from trends
|
|
50
39
|
*/
|
|
51
|
-
function generateImprovementStreakInsight(store) {
|
|
40
|
+
export function generateImprovementStreakInsight(store) {
|
|
52
41
|
const weeks = store.trends.weekly;
|
|
53
42
|
if (weeks.length < 2)
|
|
54
43
|
return null;
|
|
@@ -83,7 +72,7 @@ function generateImprovementStreakInsight(store) {
|
|
|
83
72
|
/**
|
|
84
73
|
* Find problematic scopes with high fix ratios
|
|
85
74
|
*/
|
|
86
|
-
function generateProblematicScopesInsight(commits) {
|
|
75
|
+
export function generateProblematicScopesInsight(commits) {
|
|
87
76
|
const scopeStats = new Map();
|
|
88
77
|
for (const commit of commits) {
|
|
89
78
|
const scope = commit.scope || '(no scope)';
|
|
@@ -124,7 +113,7 @@ function generateProblematicScopesInsight(commits) {
|
|
|
124
113
|
/**
|
|
125
114
|
* Check for streak at risk
|
|
126
115
|
*/
|
|
127
|
-
function generateStreakRiskInsight(profile) {
|
|
116
|
+
export function generateStreakRiskInsight(profile) {
|
|
128
117
|
const { streak } = profile;
|
|
129
118
|
if (streak.current < 3)
|
|
130
119
|
return null;
|
|
@@ -151,7 +140,7 @@ function generateStreakRiskInsight(profile) {
|
|
|
151
140
|
/**
|
|
152
141
|
* Celebrate personal best
|
|
153
142
|
*/
|
|
154
|
-
function generatePersonalBestInsight(profile) {
|
|
143
|
+
export function generatePersonalBestInsight(profile) {
|
|
155
144
|
const sessions = profile.sessions;
|
|
156
145
|
if (sessions.length < 2)
|
|
157
146
|
return null;
|
|
@@ -183,7 +172,7 @@ function generatePersonalBestInsight(profile) {
|
|
|
183
172
|
/**
|
|
184
173
|
* Show level progress
|
|
185
174
|
*/
|
|
186
|
-
function generateLevelProgressInsight(profile) {
|
|
175
|
+
export function generateLevelProgressInsight(profile) {
|
|
187
176
|
const { xp } = profile;
|
|
188
177
|
const progress = Math.round((xp.currentLevelXP / xp.nextLevelXP) * 100);
|
|
189
178
|
if (progress >= 80) {
|
|
@@ -205,7 +194,7 @@ function generateLevelProgressInsight(profile) {
|
|
|
205
194
|
/**
|
|
206
195
|
* Late night warning
|
|
207
196
|
*/
|
|
208
|
-
function generateLateNightInsight(commits) {
|
|
197
|
+
export function generateLateNightInsight(commits) {
|
|
209
198
|
const recentCommits = commits.slice(-20);
|
|
210
199
|
if (recentCommits.length < 5)
|
|
211
200
|
return null;
|
|
@@ -231,7 +220,7 @@ function generateLateNightInsight(commits) {
|
|
|
231
220
|
/**
|
|
232
221
|
* Recent achievement
|
|
233
222
|
*/
|
|
234
|
-
function generateRecentAchievementInsight(profile) {
|
|
223
|
+
export function generateRecentAchievementInsight(profile) {
|
|
235
224
|
const recent = profile.achievements
|
|
236
225
|
.filter(a => a.unlockedAt)
|
|
237
226
|
.sort((a, b) => new Date(b.unlockedAt).getTime() - new Date(a.unlockedAt).getTime())
|
|
@@ -257,7 +246,7 @@ function generateRecentAchievementInsight(profile) {
|
|
|
257
246
|
/**
|
|
258
247
|
* Best day of week insight
|
|
259
248
|
*/
|
|
260
|
-
function generateBestDayInsight(commits) {
|
|
249
|
+
export function generateBestDayInsight(commits) {
|
|
261
250
|
if (commits.length < 20)
|
|
262
251
|
return null;
|
|
263
252
|
const dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generators.js","sourceRoot":"","sources":["../../src/insights/generators.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generators.js","sourceRoot":"","sources":["../../src/insights/generators.ts"],"names":[],"mappings":"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"}
|
package/dist/insights/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Insight Engine - generates prioritized insights from all data sources
|
|
3
3
|
*/
|
|
4
|
-
import { Insight, DashboardData } from './types';
|
|
5
|
-
import { UserProfile } from '../gamification/types';
|
|
6
|
-
import { Commit } from '../types';
|
|
7
|
-
export { Insight, DashboardData } from './types';
|
|
4
|
+
import { Insight, DashboardData } from './types.js';
|
|
5
|
+
import { UserProfile } from '../gamification/types.js';
|
|
6
|
+
import { Commit } from '../types.js';
|
|
7
|
+
export { Insight, DashboardData } from './types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Generate all insights from available data
|
|
10
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/insights/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/insights/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAYpD,OAAO,EAAE,WAAW,EAAU,MAAM,0BAA0B,CAAC;AAI/D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,EAAE,CA4BX;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,GAAE,MAAsB,GAAG,aAAa,CAuJlF"}
|
package/dist/insights/index.js
CHANGED
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Insight Engine - generates prioritized insights from all data sources
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const storage_1 = require("../storage");
|
|
11
|
-
const profile_1 = require("../gamification/profile");
|
|
12
|
-
const achievements_1 = require("../gamification/achievements");
|
|
4
|
+
import { generatePeakHoursInsight, generateImprovementStreakInsight, generateProblematicScopesInsight, generateStreakRiskInsight, generatePersonalBestInsight, generateLevelProgressInsight, generateLateNightInsight, generateRecentAchievementInsight, generateBestDayInsight, } from './generators.js';
|
|
5
|
+
import { LEVELS } from '../gamification/types.js';
|
|
6
|
+
import { loadStore, readCommitLog } from '../storage/index.js';
|
|
7
|
+
import { loadProfile } from '../gamification/profile.js';
|
|
8
|
+
import { ACHIEVEMENTS } from '../gamification/achievements.js';
|
|
13
9
|
/**
|
|
14
10
|
* Generate all insights from available data
|
|
15
11
|
*/
|
|
16
|
-
function generateInsights(profile, commits, repoPath) {
|
|
17
|
-
const store =
|
|
12
|
+
export function generateInsights(profile, commits, repoPath) {
|
|
13
|
+
const store = loadStore(repoPath);
|
|
18
14
|
const insights = [];
|
|
19
15
|
// Run all generators
|
|
20
16
|
const generators = [
|
|
21
|
-
() =>
|
|
22
|
-
() =>
|
|
23
|
-
() =>
|
|
24
|
-
() =>
|
|
25
|
-
() =>
|
|
26
|
-
() =>
|
|
27
|
-
() =>
|
|
28
|
-
() =>
|
|
29
|
-
() =>
|
|
17
|
+
() => generatePeakHoursInsight(commits),
|
|
18
|
+
() => generateBestDayInsight(commits),
|
|
19
|
+
() => generateImprovementStreakInsight(store),
|
|
20
|
+
() => generateProblematicScopesInsight(commits),
|
|
21
|
+
() => generateStreakRiskInsight(profile),
|
|
22
|
+
() => generatePersonalBestInsight(profile),
|
|
23
|
+
() => generateLevelProgressInsight(profile),
|
|
24
|
+
() => generateLateNightInsight(commits),
|
|
25
|
+
() => generateRecentAchievementInsight(profile),
|
|
30
26
|
];
|
|
31
27
|
for (const gen of generators) {
|
|
32
28
|
try {
|
|
@@ -44,12 +40,12 @@ function generateInsights(profile, commits, repoPath) {
|
|
|
44
40
|
/**
|
|
45
41
|
* Build complete dashboard data export
|
|
46
42
|
*/
|
|
47
|
-
function buildDashboardData(repoPath = process.cwd()) {
|
|
48
|
-
const profile =
|
|
49
|
-
const commits =
|
|
50
|
-
const store =
|
|
43
|
+
export function buildDashboardData(repoPath = process.cwd()) {
|
|
44
|
+
const profile = loadProfile();
|
|
45
|
+
const commits = readCommitLog(repoPath);
|
|
46
|
+
const store = loadStore(repoPath);
|
|
51
47
|
// Level info
|
|
52
|
-
const levelInfo =
|
|
48
|
+
const levelInfo = LEVELS.find(l => l.level === profile.xp.level) || LEVELS[0];
|
|
53
49
|
// Calculate averages
|
|
54
50
|
const sessions = profile.sessions;
|
|
55
51
|
const now = Date.now();
|
|
@@ -111,7 +107,7 @@ function buildDashboardData(repoPath = process.cwd()) {
|
|
|
111
107
|
// Generate insights
|
|
112
108
|
const insights = generateInsights(profile, commits, repoPath);
|
|
113
109
|
// Map achievements
|
|
114
|
-
const allAchievements =
|
|
110
|
+
const allAchievements = ACHIEVEMENTS.map(a => {
|
|
115
111
|
const unlocked = profile.achievements.find(ua => ua.id === a.id);
|
|
116
112
|
return {
|
|
117
113
|
id: a.id,
|
|
@@ -141,7 +137,7 @@ function buildDashboardData(repoPath = process.cwd()) {
|
|
|
141
137
|
longest: profile.streak.longest,
|
|
142
138
|
},
|
|
143
139
|
achievementCount: profile.achievements.length,
|
|
144
|
-
totalAchievements:
|
|
140
|
+
totalAchievements: ACHIEVEMENTS.length,
|
|
145
141
|
},
|
|
146
142
|
stats: {
|
|
147
143
|
current: {
|