@boshu2/vibe-check 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.agents/bundles/actionable-coaching-plan-2025-12-02.md +209 -0
  2. package/.agents/plans/git-forensics-enhancement-2025-12-05.md +493 -0
  3. package/.claude/skills/typescript-review.md +152 -0
  4. package/CHANGELOG.md +41 -5
  5. package/CLAUDE.md +85 -23
  6. package/Makefile +43 -19
  7. package/README.md +178 -172
  8. package/SECURITY.md +5 -1
  9. package/assets/logo-dark.svg +47 -0
  10. package/assets/logo.svg +47 -0
  11. package/claude-progress.json +28 -7
  12. package/claude-progress.txt +48 -0
  13. package/dist/analyzers/patterns.d.ts +62 -0
  14. package/dist/analyzers/patterns.d.ts.map +1 -0
  15. package/dist/analyzers/patterns.js +103 -0
  16. package/dist/analyzers/patterns.js.map +1 -0
  17. package/dist/analyzers/quality.d.ts +58 -0
  18. package/dist/analyzers/quality.d.ts.map +1 -0
  19. package/dist/analyzers/quality.js +114 -0
  20. package/dist/analyzers/quality.js.map +1 -0
  21. package/dist/analyzers/sessions.d.ts +45 -0
  22. package/dist/analyzers/sessions.d.ts.map +1 -0
  23. package/dist/analyzers/sessions.js +123 -0
  24. package/dist/analyzers/sessions.js.map +1 -0
  25. package/dist/cli.js +4 -0
  26. package/dist/cli.js.map +1 -1
  27. package/dist/commands/analyze.d.ts.map +1 -1
  28. package/dist/commands/analyze.js +5 -0
  29. package/dist/commands/analyze.js.map +1 -1
  30. package/dist/commands/forensics.d.ts +29 -0
  31. package/dist/commands/forensics.d.ts.map +1 -0
  32. package/dist/commands/forensics.js +213 -0
  33. package/dist/commands/forensics.js.map +1 -0
  34. package/dist/commands/index.d.ts +4 -0
  35. package/dist/commands/index.d.ts.map +1 -1
  36. package/dist/commands/index.js +11 -1
  37. package/dist/commands/index.js.map +1 -1
  38. package/dist/commands/insights.d.ts +3 -0
  39. package/dist/commands/insights.d.ts.map +1 -0
  40. package/dist/commands/insights.js +120 -0
  41. package/dist/commands/insights.js.map +1 -0
  42. package/dist/commands/pipeline.d.ts +3 -0
  43. package/dist/commands/pipeline.d.ts.map +1 -0
  44. package/dist/commands/pipeline.js +485 -0
  45. package/dist/commands/pipeline.js.map +1 -0
  46. package/dist/commands/profile.d.ts +0 -1
  47. package/dist/commands/profile.d.ts.map +1 -1
  48. package/dist/commands/profile.js +0 -4
  49. package/dist/commands/profile.js.map +1 -1
  50. package/dist/commands/session.d.ts +9 -0
  51. package/dist/commands/session.d.ts.map +1 -1
  52. package/dist/commands/session.js +95 -0
  53. package/dist/commands/session.js.map +1 -1
  54. package/dist/commands/sessions.d.ts +20 -0
  55. package/dist/commands/sessions.d.ts.map +1 -0
  56. package/dist/commands/sessions.js +201 -0
  57. package/dist/commands/sessions.js.map +1 -0
  58. package/dist/commands/watch.d.ts.map +1 -1
  59. package/dist/commands/watch.js +124 -7
  60. package/dist/commands/watch.js.map +1 -1
  61. package/dist/inner-loop/context-amnesia.d.ts +20 -0
  62. package/dist/inner-loop/context-amnesia.d.ts.map +1 -0
  63. package/dist/inner-loop/context-amnesia.js +249 -0
  64. package/dist/inner-loop/context-amnesia.js.map +1 -0
  65. package/dist/inner-loop/index.d.ts +39 -0
  66. package/dist/inner-loop/index.d.ts.map +1 -0
  67. package/dist/inner-loop/index.js +208 -0
  68. package/dist/inner-loop/index.js.map +1 -0
  69. package/dist/inner-loop/instruction-drift.d.ts +28 -0
  70. package/dist/inner-loop/instruction-drift.d.ts.map +1 -0
  71. package/dist/inner-loop/instruction-drift.js +260 -0
  72. package/dist/inner-loop/instruction-drift.js.map +1 -0
  73. package/dist/inner-loop/logging-only.d.ts +30 -0
  74. package/dist/inner-loop/logging-only.d.ts.map +1 -0
  75. package/dist/inner-loop/logging-only.js +264 -0
  76. package/dist/inner-loop/logging-only.js.map +1 -0
  77. package/dist/inner-loop/tests-passing-lie.d.ts +34 -0
  78. package/dist/inner-loop/tests-passing-lie.d.ts.map +1 -0
  79. package/dist/inner-loop/tests-passing-lie.js +213 -0
  80. package/dist/inner-loop/tests-passing-lie.js.map +1 -0
  81. package/dist/inner-loop/types.d.ts +111 -0
  82. package/dist/inner-loop/types.d.ts.map +1 -0
  83. package/dist/inner-loop/types.js +29 -0
  84. package/dist/inner-loop/types.js.map +1 -0
  85. package/dist/storage/index.d.ts +1 -0
  86. package/dist/storage/index.d.ts.map +1 -1
  87. package/dist/storage/index.js +11 -1
  88. package/dist/storage/index.js.map +1 -1
  89. package/dist/storage/spiral-history.d.ts +62 -0
  90. package/dist/storage/spiral-history.d.ts.map +1 -0
  91. package/dist/storage/spiral-history.js +265 -0
  92. package/dist/storage/spiral-history.js.map +1 -0
  93. package/docs/ARCHITECTURE.md +2 -10
  94. package/docs/FEATURES.md +340 -0
  95. package/docs/GAMIFICATION.md +19 -266
  96. package/docs/VIBE-ECOSYSTEM.md +12 -78
  97. package/feature-list.json +140 -88
  98. package/package.json +1 -1
@@ -3,6 +3,54 @@ Created: 2025-11-29
3
3
 
4
4
  ## Session Log
5
5
 
6
+ --- 2025-12-02 21:00 - Major Cleanup & Actionable Coaching Plan ---
7
+
8
+ VIBE LEVEL: 3 (Balanced, verify key outputs)
9
+
10
+ COMPLETED:
11
+ - Major codebase cleanup:
12
+ - Cut learning system (10 files, 1755 lines)
13
+ - Cut advanced gamification (7 files, 1215 lines)
14
+ - Removed learn, lesson, intervene commands
15
+ - 78 → 58 source files, -3900 lines total
16
+ - Published v1.7.0 to npm
17
+ - Fixed all documentation:
18
+ - Makefile, CLAUDE.md, README.md
19
+ - docs/GAMIFICATION.md (full rewrite)
20
+ - docs/ARCHITECTURE.md, docs/VIBE-ECOSYSTEM.md
21
+ - Created actionable coaching plan:
22
+ - 5 new features (VIBE-040 to VIBE-044)
23
+ - Spiral history storage, personalized alerts
24
+ - ~300-400 lines, lean implementation
25
+
26
+ COMMITS:
27
+ - 6c28204 refactor: remove learning system and advanced gamification
28
+ - 1526f6d chore: bump version to 1.7.0
29
+ - fbe6a89 docs: remove references to deleted commands
30
+ - e77a6c9 docs: update GAMIFICATION.md and ARCHITECTURE.md
31
+ - 8f77bda docs: update VIBE-ECOSYSTEM.md and ARCHITECTURE.md
32
+ - e4515e8 feat(dashboard): enhanced visual dashboard
33
+ - 5ec7758 chore: add session bundles
34
+ - 871a0c4 plan: actionable coaching enhancement
35
+
36
+ ARTIFACTS:
37
+ - .agents/bundles/actionable-coaching-plan-2025-12-02.md
38
+ - feature-list.json updated with VIBE-040 to VIBE-044
39
+
40
+ REMAINING:
41
+ - VIBE-040: Spiral history storage (NDJSON)
42
+ - VIBE-041: Auto-record spirals during analyze/session
43
+ - VIBE-042: Personalized watch alerts
44
+ - VIBE-043: Session end coaching
45
+ - VIBE-044: Insights command
46
+
47
+ NEXT SESSION SHOULD:
48
+ - Start with VIBE-040: Create src/storage/spiral-history.ts
49
+ - Implement NDJSON append/query functions
50
+ - Then VIBE-041: Wire into analyze.ts and session.ts
51
+
52
+ ================================================================================
53
+
6
54
  --- 2025-12-02 - Automatic Learning Cadence Research & Planning ---
7
55
 
8
56
  VIBE LEVEL: 4 (Research/Planning, exploratory)
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Pattern Detection Analyzer (VIBE-045)
3
+ *
4
+ * Analyzes git history to detect failure patterns:
5
+ * - Debug spirals ("take N" pattern)
6
+ * - Vague commits (<20 chars)
7
+ * - Context amnesia (repeated scope visits)
8
+ *
9
+ * Proven algorithm from release-engineering retrospective (475 commits analyzed).
10
+ */
11
+ import { Commit } from '../types';
12
+ export interface DebugSpiral {
13
+ count: number;
14
+ durationMinutes: number;
15
+ commits: string[];
16
+ dates: string[];
17
+ }
18
+ export interface VagueCommitInfo {
19
+ count: number;
20
+ percentage: number;
21
+ threshold: number;
22
+ examples: string[];
23
+ }
24
+ export interface ContextAmnesiaInfo {
25
+ scopes: {
26
+ name: string;
27
+ visits: number;
28
+ }[];
29
+ }
30
+ export interface PatternDetectionResult {
31
+ debugSpirals: DebugSpiral | null;
32
+ vagueCommits: VagueCommitInfo;
33
+ contextAmnesia: ContextAmnesiaInfo;
34
+ }
35
+ /**
36
+ * Detect "take N" pattern indicating debug spirals.
37
+ *
38
+ * A debug spiral is detected when 3+ commits match the pattern "take N" or similar
39
+ * retry patterns, indicating the developer is stuck in a fix-retry loop.
40
+ */
41
+ export declare function detectDebugSpirals(commits: Commit[]): DebugSpiral | null;
42
+ /**
43
+ * Detect vague commits - messages that are too short to be meaningful.
44
+ *
45
+ * Threshold: < 20 characters is considered vague.
46
+ * Examples: "ci", "v3", "blah", "take 2", "fix"
47
+ */
48
+ export declare function detectVagueCommits(commits: Commit[], threshold?: number): VagueCommitInfo;
49
+ /**
50
+ * Detect context amnesia - repeatedly returning to the same scope/component.
51
+ *
52
+ * This indicates the developer keeps revisiting the same area, possibly
53
+ * due to incomplete understanding or forgotten context.
54
+ *
55
+ * Reports scopes that appear in 5+ commits.
56
+ */
57
+ export declare function detectContextAmnesia(commits: Commit[], minVisits?: number): ContextAmnesiaInfo;
58
+ /**
59
+ * Run all pattern detection on a set of commits.
60
+ */
61
+ export declare function detectPatterns(commits: Commit[]): PatternDetectionResult;
62
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/analyzers/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,YAAY,EAAE,eAAe,CAAC;IAC9B,cAAc,EAAE,kBAAkB,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,GAAG,IAAI,CAoCxE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,GAAE,MAAW,GACrB,eAAe,CAmBjB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,GAAE,MAAU,GACpB,kBAAkB,CAiBpB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAMxE"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * Pattern Detection Analyzer (VIBE-045)
4
+ *
5
+ * Analyzes git history to detect failure patterns:
6
+ * - Debug spirals ("take N" pattern)
7
+ * - Vague commits (<20 chars)
8
+ * - Context amnesia (repeated scope visits)
9
+ *
10
+ * Proven algorithm from release-engineering retrospective (475 commits analyzed).
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.detectDebugSpirals = detectDebugSpirals;
14
+ exports.detectVagueCommits = detectVagueCommits;
15
+ exports.detectContextAmnesia = detectContextAmnesia;
16
+ exports.detectPatterns = detectPatterns;
17
+ /**
18
+ * Detect "take N" pattern indicating debug spirals.
19
+ *
20
+ * A debug spiral is detected when 3+ commits match the pattern "take N" or similar
21
+ * retry patterns, indicating the developer is stuck in a fix-retry loop.
22
+ */
23
+ function detectDebugSpirals(commits) {
24
+ const takePattern = /^take\s*[0-9]+$/i;
25
+ const retryPatterns = [
26
+ /^(fix|try|attempt)\s*#?\d+$/i, // "fix 2", "try #3"
27
+ /^(wip|temp|test)\s*\d*$/i, // "wip", "wip2"
28
+ /^v\d+$/i, // "v2", "v3"
29
+ takePattern,
30
+ ];
31
+ const spiralCommits = commits.filter((c) => retryPatterns.some((pattern) => pattern.test(c.message.trim())));
32
+ if (spiralCommits.length < 3) {
33
+ return null;
34
+ }
35
+ // Sort by date to calculate duration
36
+ const sorted = [...spiralCommits].sort((a, b) => a.date.getTime() - b.date.getTime());
37
+ const first = sorted[0];
38
+ const last = sorted[sorted.length - 1];
39
+ const durationMinutes = (last.date.getTime() - first.date.getTime()) / (60 * 1000);
40
+ // Get unique dates
41
+ const dates = [...new Set(sorted.map((c) => c.date.toISOString().split('T')[0]))];
42
+ return {
43
+ count: spiralCommits.length,
44
+ durationMinutes: Math.round(durationMinutes * 10) / 10,
45
+ commits: spiralCommits.map((c) => c.hash),
46
+ dates,
47
+ };
48
+ }
49
+ /**
50
+ * Detect vague commits - messages that are too short to be meaningful.
51
+ *
52
+ * Threshold: < 20 characters is considered vague.
53
+ * Examples: "ci", "v3", "blah", "take 2", "fix"
54
+ */
55
+ function detectVagueCommits(commits, threshold = 20) {
56
+ const vagueCommits = commits.filter((c) => c.message.trim().length < threshold);
57
+ // Get example vague messages (deduplicated, max 10)
58
+ const examples = [
59
+ ...new Set(vagueCommits.map((c) => c.message.trim())),
60
+ ].slice(0, 10);
61
+ return {
62
+ count: vagueCommits.length,
63
+ percentage: commits.length > 0
64
+ ? Math.round((vagueCommits.length / commits.length) * 1000) / 10
65
+ : 0,
66
+ threshold,
67
+ examples,
68
+ };
69
+ }
70
+ /**
71
+ * Detect context amnesia - repeatedly returning to the same scope/component.
72
+ *
73
+ * This indicates the developer keeps revisiting the same area, possibly
74
+ * due to incomplete understanding or forgotten context.
75
+ *
76
+ * Reports scopes that appear in 5+ commits.
77
+ */
78
+ function detectContextAmnesia(commits, minVisits = 5) {
79
+ const scopeCounts = new Map();
80
+ for (const commit of commits) {
81
+ if (commit.scope) {
82
+ const current = scopeCounts.get(commit.scope) || 0;
83
+ scopeCounts.set(commit.scope, current + 1);
84
+ }
85
+ }
86
+ // Filter to scopes with high visit counts, sorted descending
87
+ const scopes = Array.from(scopeCounts.entries())
88
+ .filter(([, count]) => count >= minVisits)
89
+ .sort((a, b) => b[1] - a[1])
90
+ .map(([name, visits]) => ({ name, visits }));
91
+ return { scopes };
92
+ }
93
+ /**
94
+ * Run all pattern detection on a set of commits.
95
+ */
96
+ function detectPatterns(commits) {
97
+ return {
98
+ debugSpirals: detectDebugSpirals(commits),
99
+ vagueCommits: detectVagueCommits(commits),
100
+ contextAmnesia: detectContextAmnesia(commits),
101
+ };
102
+ }
103
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/analyzers/patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Quality Metrics Analyzer (VIBE-045)
3
+ *
4
+ * Calculates commit message quality metrics:
5
+ * - Conventional commits percentage
6
+ * - Descriptive commits percentage
7
+ * - Vague commits percentage
8
+ *
9
+ * Proven algorithm from release-engineering retrospective.
10
+ */
11
+ import { Commit } from '../types';
12
+ export interface QualityMetrics {
13
+ totalCommits: number;
14
+ conventionalCommits: {
15
+ count: number;
16
+ percentage: number;
17
+ };
18
+ descriptiveCommits: {
19
+ count: number;
20
+ percentage: number;
21
+ minLength: number;
22
+ };
23
+ vagueCommits: {
24
+ count: number;
25
+ percentage: number;
26
+ threshold: number;
27
+ };
28
+ }
29
+ /**
30
+ * Check if a commit message follows conventional commit format.
31
+ *
32
+ * Format: type(scope?): description
33
+ * Examples: "feat: add login", "fix(auth): handle token expiry"
34
+ */
35
+ export declare function isConventionalCommit(message: string): boolean;
36
+ /**
37
+ * Check if a commit message is descriptive (meaningful length).
38
+ *
39
+ * A descriptive commit has at least 20 characters in the first line.
40
+ */
41
+ export declare function isDescriptiveCommit(message: string, minLength?: number): boolean;
42
+ /**
43
+ * Check if a commit message is vague (too short to be meaningful).
44
+ *
45
+ * Threshold: < 20 characters
46
+ */
47
+ export declare function isVagueCommit(message: string, threshold?: number): boolean;
48
+ /**
49
+ * Calculate quality metrics for a set of commits.
50
+ */
51
+ export declare function calculateQualityMetrics(commits: Commit[], vagueThreshold?: number, descriptiveMinLength?: number): QualityMetrics;
52
+ /**
53
+ * Generate a recommendation based on quality metrics.
54
+ *
55
+ * Returns 'sweep' if cleanup is recommended, 'maintain' if quality is acceptable.
56
+ */
57
+ export declare function getRecommendation(metrics: QualityMetrics, hasSpirals: boolean): 'sweep' | 'maintain' | 'celebrate';
58
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/analyzers/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,kBAAkB,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAmBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAM7D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAW,GACrB,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAW,GACrB,OAAO,CAGT;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,GAAE,MAAW,EAC3B,oBAAoB,GAAE,MAAW,GAChC,cAAc,CAyChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,OAAO,GAClB,OAAO,GAAG,UAAU,GAAG,WAAW,CAgBpC"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * Quality Metrics Analyzer (VIBE-045)
4
+ *
5
+ * Calculates commit message quality metrics:
6
+ * - Conventional commits percentage
7
+ * - Descriptive commits percentage
8
+ * - Vague commits percentage
9
+ *
10
+ * Proven algorithm from release-engineering retrospective.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.isConventionalCommit = isConventionalCommit;
14
+ exports.isDescriptiveCommit = isDescriptiveCommit;
15
+ exports.isVagueCommit = isVagueCommit;
16
+ exports.calculateQualityMetrics = calculateQualityMetrics;
17
+ exports.getRecommendation = getRecommendation;
18
+ /**
19
+ * Conventional commit types as per spec.
20
+ */
21
+ const CONVENTIONAL_TYPES = [
22
+ 'feat',
23
+ 'fix',
24
+ 'docs',
25
+ 'style',
26
+ 'refactor',
27
+ 'perf',
28
+ 'test',
29
+ 'build',
30
+ 'ci',
31
+ 'chore',
32
+ 'revert',
33
+ ];
34
+ /**
35
+ * Check if a commit message follows conventional commit format.
36
+ *
37
+ * Format: type(scope?): description
38
+ * Examples: "feat: add login", "fix(auth): handle token expiry"
39
+ */
40
+ function isConventionalCommit(message) {
41
+ const conventionalPattern = new RegExp(`^(${CONVENTIONAL_TYPES.join('|')})(\\([^)]+\\))?:\\s*.+`, 'i');
42
+ return conventionalPattern.test(message.trim());
43
+ }
44
+ /**
45
+ * Check if a commit message is descriptive (meaningful length).
46
+ *
47
+ * A descriptive commit has at least 20 characters in the first line.
48
+ */
49
+ function isDescriptiveCommit(message, minLength = 20) {
50
+ const firstLine = message.trim().split('\n')[0];
51
+ return firstLine.length >= minLength;
52
+ }
53
+ /**
54
+ * Check if a commit message is vague (too short to be meaningful).
55
+ *
56
+ * Threshold: < 20 characters
57
+ */
58
+ function isVagueCommit(message, threshold = 20) {
59
+ const firstLine = message.trim().split('\n')[0];
60
+ return firstLine.length < threshold;
61
+ }
62
+ /**
63
+ * Calculate quality metrics for a set of commits.
64
+ */
65
+ function calculateQualityMetrics(commits, vagueThreshold = 20, descriptiveMinLength = 20) {
66
+ const total = commits.length;
67
+ if (total === 0) {
68
+ return {
69
+ totalCommits: 0,
70
+ conventionalCommits: { count: 0, percentage: 0 },
71
+ descriptiveCommits: { count: 0, percentage: 0, minLength: descriptiveMinLength },
72
+ vagueCommits: { count: 0, percentage: 0, threshold: vagueThreshold },
73
+ };
74
+ }
75
+ const conventionalCount = commits.filter((c) => isConventionalCommit(c.message)).length;
76
+ const descriptiveCount = commits.filter((c) => isDescriptiveCommit(c.message, descriptiveMinLength)).length;
77
+ const vagueCount = commits.filter((c) => isVagueCommit(c.message, vagueThreshold)).length;
78
+ return {
79
+ totalCommits: total,
80
+ conventionalCommits: {
81
+ count: conventionalCount,
82
+ percentage: Math.round((conventionalCount / total) * 1000) / 10,
83
+ },
84
+ descriptiveCommits: {
85
+ count: descriptiveCount,
86
+ percentage: Math.round((descriptiveCount / total) * 1000) / 10,
87
+ minLength: descriptiveMinLength,
88
+ },
89
+ vagueCommits: {
90
+ count: vagueCount,
91
+ percentage: Math.round((vagueCount / total) * 1000) / 10,
92
+ threshold: vagueThreshold,
93
+ },
94
+ };
95
+ }
96
+ /**
97
+ * Generate a recommendation based on quality metrics.
98
+ *
99
+ * Returns 'sweep' if cleanup is recommended, 'maintain' if quality is acceptable.
100
+ */
101
+ function getRecommendation(metrics, hasSpirals) {
102
+ // Sweep if: >50% vague commits OR any debug spirals
103
+ if (metrics.vagueCommits.percentage > 50 || hasSpirals) {
104
+ return 'sweep';
105
+ }
106
+ // Celebrate if: >80% conventional AND <10% vague
107
+ if (metrics.conventionalCommits.percentage > 80 &&
108
+ metrics.vagueCommits.percentage < 10) {
109
+ return 'celebrate';
110
+ }
111
+ // Otherwise maintain current practices
112
+ return 'maintain';
113
+ }
114
+ //# sourceMappingURL=quality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.js","sourceRoot":"","sources":["../../src/analyzers/quality.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Session Detection Algorithm (VIBE-046)
3
+ *
4
+ * Identifies work sessions from git history using configurable time gap threshold.
5
+ * Proven algorithm from release-engineering retrospective (46 sessions detected from 475 commits).
6
+ *
7
+ * Default threshold: 90 minutes between commits starts a new session.
8
+ */
9
+ import { Commit } from '../types';
10
+ export interface DetectedSession {
11
+ sessionId: number;
12
+ startDate: Date;
13
+ endDate: Date;
14
+ durationMinutes: number;
15
+ commits: Commit[];
16
+ commitCount: number;
17
+ }
18
+ export interface SessionStats {
19
+ totalSessions: number;
20
+ totalCommits: number;
21
+ avgCommitsPerSession: number;
22
+ avgDurationMinutes: number;
23
+ medianDurationMinutes: number;
24
+ longestSessionMinutes: number;
25
+ shortestSessionMinutes: number;
26
+ }
27
+ export interface SessionDetectionResult {
28
+ sessions: DetectedSession[];
29
+ stats: SessionStats;
30
+ analysisRange: {
31
+ from: Date;
32
+ to: Date;
33
+ };
34
+ }
35
+ /**
36
+ * Detect work sessions from a list of commits.
37
+ *
38
+ * A new session starts when the gap between consecutive commits exceeds the threshold.
39
+ *
40
+ * @param commits List of commits (will be sorted by date)
41
+ * @param gapThresholdMinutes Minutes between commits to start new session (default: 90)
42
+ * @returns Session detection result with sessions and statistics
43
+ */
44
+ export declare function detectSessions(commits: Commit[], gapThresholdMinutes?: number): SessionDetectionResult;
45
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/analyzers/sessions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE;QACb,IAAI,EAAE,IAAI,CAAC;QACX,EAAE,EAAE,IAAI,CAAC;KACV,CAAC;CACH;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EAAE,EACjB,mBAAmB,GAAE,MAAW,GAC/B,sBAAsB,CAkExB"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ /**
3
+ * Session Detection Algorithm (VIBE-046)
4
+ *
5
+ * Identifies work sessions from git history using configurable time gap threshold.
6
+ * Proven algorithm from release-engineering retrospective (46 sessions detected from 475 commits).
7
+ *
8
+ * Default threshold: 90 minutes between commits starts a new session.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.detectSessions = detectSessions;
12
+ /**
13
+ * Detect work sessions from a list of commits.
14
+ *
15
+ * A new session starts when the gap between consecutive commits exceeds the threshold.
16
+ *
17
+ * @param commits List of commits (will be sorted by date)
18
+ * @param gapThresholdMinutes Minutes between commits to start new session (default: 90)
19
+ * @returns Session detection result with sessions and statistics
20
+ */
21
+ function detectSessions(commits, gapThresholdMinutes = 90) {
22
+ if (commits.length === 0) {
23
+ return {
24
+ sessions: [],
25
+ stats: {
26
+ totalSessions: 0,
27
+ totalCommits: 0,
28
+ avgCommitsPerSession: 0,
29
+ avgDurationMinutes: 0,
30
+ medianDurationMinutes: 0,
31
+ longestSessionMinutes: 0,
32
+ shortestSessionMinutes: 0,
33
+ },
34
+ analysisRange: {
35
+ from: new Date(),
36
+ to: new Date(),
37
+ },
38
+ };
39
+ }
40
+ // Sort commits by date (oldest first)
41
+ const sortedCommits = [...commits].sort((a, b) => a.date.getTime() - b.date.getTime());
42
+ const gapThresholdMs = gapThresholdMinutes * 60 * 1000;
43
+ const sessions = [];
44
+ let currentSessionCommits = [];
45
+ let sessionId = 1;
46
+ for (const commit of sortedCommits) {
47
+ if (currentSessionCommits.length === 0) {
48
+ // Start first session
49
+ currentSessionCommits = [commit];
50
+ }
51
+ else {
52
+ const lastCommit = currentSessionCommits[currentSessionCommits.length - 1];
53
+ const gap = commit.date.getTime() - lastCommit.date.getTime();
54
+ if (gap > gapThresholdMs) {
55
+ // Gap exceeded - save current session and start new one
56
+ sessions.push(createSession(sessionId, currentSessionCommits));
57
+ sessionId++;
58
+ currentSessionCommits = [commit];
59
+ }
60
+ else {
61
+ // Continue current session
62
+ currentSessionCommits.push(commit);
63
+ }
64
+ }
65
+ }
66
+ // Don't forget the last session
67
+ if (currentSessionCommits.length > 0) {
68
+ sessions.push(createSession(sessionId, currentSessionCommits));
69
+ }
70
+ // Calculate statistics
71
+ const stats = calculateStats(sessions);
72
+ return {
73
+ sessions,
74
+ stats,
75
+ analysisRange: {
76
+ from: sortedCommits[0].date,
77
+ to: sortedCommits[sortedCommits.length - 1].date,
78
+ },
79
+ };
80
+ }
81
+ function createSession(sessionId, commits) {
82
+ const startDate = commits[0].date;
83
+ const endDate = commits[commits.length - 1].date;
84
+ const durationMinutes = (endDate.getTime() - startDate.getTime()) / (60 * 1000);
85
+ return {
86
+ sessionId,
87
+ startDate,
88
+ endDate,
89
+ durationMinutes: Math.round(durationMinutes * 10) / 10, // Round to 1 decimal
90
+ commits,
91
+ commitCount: commits.length,
92
+ };
93
+ }
94
+ function calculateStats(sessions) {
95
+ if (sessions.length === 0) {
96
+ return {
97
+ totalSessions: 0,
98
+ totalCommits: 0,
99
+ avgCommitsPerSession: 0,
100
+ avgDurationMinutes: 0,
101
+ medianDurationMinutes: 0,
102
+ longestSessionMinutes: 0,
103
+ shortestSessionMinutes: 0,
104
+ };
105
+ }
106
+ const totalCommits = sessions.reduce((sum, s) => sum + s.commitCount, 0);
107
+ const durations = sessions.map((s) => s.durationMinutes).sort((a, b) => a - b);
108
+ // Calculate median
109
+ const mid = Math.floor(durations.length / 2);
110
+ const medianDuration = durations.length % 2 === 0
111
+ ? (durations[mid - 1] + durations[mid]) / 2
112
+ : durations[mid];
113
+ return {
114
+ totalSessions: sessions.length,
115
+ totalCommits,
116
+ avgCommitsPerSession: Math.round((totalCommits / sessions.length) * 10) / 10,
117
+ avgDurationMinutes: Math.round((durations.reduce((sum, d) => sum + d, 0) / durations.length) * 10) / 10,
118
+ medianDurationMinutes: Math.round(medianDuration * 10) / 10,
119
+ longestSessionMinutes: durations[durations.length - 1],
120
+ shortestSessionMinutes: durations[0],
121
+ };
122
+ }
123
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/analyzers/sessions.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -22,6 +22,10 @@ program.addCommand((0, commands_1.createTimelineCommand)());
22
22
  program.addCommand((0, commands_1.createCacheCommand)());
23
23
  program.addCommand((0, commands_1.createDashboardCommand)());
24
24
  program.addCommand((0, commands_1.createSessionCommand)());
25
+ program.addCommand((0, commands_1.createInsightsCommand)());
26
+ program.addCommand((0, commands_1.createPipelineCommand)());
27
+ program.addCommand((0, commands_1.createSessionsCommand)());
28
+ program.addCommand((0, commands_1.createForensicsCommand)());
25
29
  // Default behavior: if no subcommand, run analyze with passed options
26
30
  // This maintains backwards compatibility with v1.x usage
27
31
  program
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,yCAA4O;AAE5O,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,CAAC;KAChB,uBAAuB,EAAE;KACzB,kBAAkB,EAAE,CAAC;AAExB,kBAAkB;AAClB,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,iCAAsB,GAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAE3C,sEAAsE;AACtE,yDAAyD;AACzD,OAAO;KACJ,MAAM,CAAC,gBAAgB,EAAE,8CAA8C,CAAC;KACxE,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,CAAC;KAChE,MAAM,CAAC,qBAAqB,EAAE,yCAAyC,EAAE,UAAU,CAAC;KACpF,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC7D,MAAM,CAAC,eAAe,EAAE,qBAAqB,EAAE,KAAK,CAAC;KACrD,MAAM,CAAC,SAAS,EAAE,4CAA4C,EAAE,KAAK,CAAC;KACtE,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,cAAc,EAAE,mCAAmC,EAAE,KAAK,CAAC;KAClE,MAAM,CAAC,YAAY,EAAE,0DAA0D,CAAC;KAChF,MAAM,CAAC,iBAAiB,EAAE,yDAAyD,CAAC;KACpF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,wDAAwD;IACxD,MAAM,IAAA,qBAAU,EAAC;QACf,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,yCAAyU;AAEzU,8DAA8D;AAC9D,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,CAAC;KAChB,uBAAuB,EAAE;KACzB,kBAAkB,EAAE,CAAC;AAExB,kBAAkB;AAClB,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,6BAAkB,GAAE,CAAC,CAAC;AACzC,OAAO,CAAC,UAAU,CAAC,IAAA,iCAAsB,GAAE,CAAC,CAAC;AAC7C,OAAO,CAAC,UAAU,CAAC,IAAA,+BAAoB,GAAE,CAAC,CAAC;AAC3C,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,gCAAqB,GAAE,CAAC,CAAC;AAC5C,OAAO,CAAC,UAAU,CAAC,IAAA,iCAAsB,GAAE,CAAC,CAAC;AAE7C,sEAAsE;AACtE,yDAAyD;AACzD,OAAO;KACJ,MAAM,CAAC,gBAAgB,EAAE,8CAA8C,CAAC;KACxE,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,CAAC;KAChE,MAAM,CAAC,qBAAqB,EAAE,yCAAyC,EAAE,UAAU,CAAC;KACpF,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC7D,MAAM,CAAC,eAAe,EAAE,qBAAqB,EAAE,KAAK,CAAC;KACrD,MAAM,CAAC,SAAS,EAAE,4CAA4C,EAAE,KAAK,CAAC;KACtE,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,cAAc,EAAE,mCAAmC,EAAE,KAAK,CAAC;KAClE,MAAM,CAAC,YAAY,EAAE,0DAA0D,CAAC;KAChF,MAAM,CAAC,iBAAiB,EAAE,yDAAyD,CAAC;KACpF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,wDAAwD;IACxD,MAAM,IAAA,qBAAU,EAAC;QACf,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgCpC,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAkB9C;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsXvE"}
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiCpC,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAkB9C;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgYvE"}
@@ -22,6 +22,7 @@ const types_1 = require("../gamification/types");
22
22
  const start_1 = require("./start");
23
23
  const sessions_1 = require("../sessions");
24
24
  const analysis_1 = require("../analysis");
25
+ const spiral_history_1 = require("../storage/spiral-history");
25
26
  function createAnalyzeCommand() {
26
27
  const cmd = new commander_1.Command('analyze')
27
28
  .description('Analyze git history for vibe coding metrics')
@@ -150,6 +151,10 @@ async function runAnalyze(options) {
150
151
  const trustPassRate = result.metrics.trustPassRate.value;
151
152
  const reworkRatio = result.metrics.reworkRatio.value;
152
153
  const spiralCount = result.fixChains.filter(fc => fc.isSpiral).length;
154
+ // Record detected spirals to history for personalized coaching
155
+ for (const chain of result.fixChains.filter(fc => fc.isSpiral)) {
156
+ (0, spiral_history_1.appendSpiral)(chain.pattern || 'OTHER', chain.component, chain.duration, chain.commits);
157
+ }
153
158
  // Session comparison (if manual session was active via `start`)
154
159
  if (session && format === 'terminal') {
155
160
  const levelInfo = start_1.LEVEL_INFO[session.level];