@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
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ /**
3
+ * Logging-Only Commit Detector
4
+ *
5
+ * Detects "Debug Loop Spiral" pattern where AI adds logging/print statements
6
+ * instead of actually fixing the root cause. Signs of this:
7
+ *
8
+ * - Commits that only add console.log/print statements
9
+ * - Multiple consecutive debugging commits without substantive changes
10
+ * - Increasing logging density without resolution
11
+ *
12
+ * This is a key "Inner Loop Disaster" in vibe coding.
13
+ */
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.detectLoggingOnlyCommits = detectLoggingOnlyCommits;
19
+ exports.analyzeCommitForLogging = analyzeCommitForLogging;
20
+ exports.analyzeCommitsForLogging = analyzeCommitsForLogging;
21
+ const simple_git_1 = __importDefault(require("simple-git"));
22
+ const types_1 = require("./types");
23
+ // Patterns that indicate logging statements by language
24
+ const LOGGING_PATTERNS = {
25
+ javascript: [
26
+ /console\.(log|error|warn|debug|info|trace|dir|table)\s*\(/,
27
+ /console\.(time|timeEnd|timeLog|group|groupEnd)\s*\(/,
28
+ /debugger;/,
29
+ ],
30
+ typescript: [
31
+ /console\.(log|error|warn|debug|info|trace|dir|table)\s*\(/,
32
+ /console\.(time|timeEnd|timeLog|group|groupEnd)\s*\(/,
33
+ /debugger;/,
34
+ ],
35
+ python: [
36
+ /print\s*\(/,
37
+ /logging\.(debug|info|warning|error|critical)\s*\(/,
38
+ /logger\.(debug|info|warning|error|critical)\s*\(/,
39
+ /pprint\s*\(/,
40
+ /breakpoint\s*\(/,
41
+ /import\s+pdb/,
42
+ /pdb\.set_trace\s*\(/,
43
+ ],
44
+ java: [
45
+ /System\.out\.print(ln)?\s*\(/,
46
+ /System\.err\.print(ln)?\s*\(/,
47
+ /logger\.(debug|info|warn|error|trace)\s*\(/,
48
+ /log\.(debug|info|warn|error|trace)\s*\(/,
49
+ /LOG\.(debug|info|warn|error|trace)\s*\(/,
50
+ ],
51
+ go: [
52
+ /fmt\.Print(ln|f)?\s*\(/,
53
+ /log\.Print(ln|f)?\s*\(/,
54
+ /log\.(Debug|Info|Warn|Error|Fatal)(f|ln)?\s*\(/,
55
+ ],
56
+ rust: [
57
+ /println!\s*\(/,
58
+ /eprintln!\s*\(/,
59
+ /dbg!\s*\(/,
60
+ /debug!\s*\(/,
61
+ /info!\s*\(/,
62
+ /warn!\s*\(/,
63
+ /error!\s*\(/,
64
+ /trace!\s*\(/,
65
+ ],
66
+ ruby: [
67
+ /puts\s+/,
68
+ /p\s+/,
69
+ /pp\s+/,
70
+ /Rails\.logger\.(debug|info|warn|error)\s*\(/,
71
+ /logger\.(debug|info|warn|error)\s*\(/,
72
+ /binding\.pry/,
73
+ /byebug/,
74
+ ],
75
+ php: [
76
+ /var_dump\s*\(/,
77
+ /print_r\s*\(/,
78
+ /echo\s+/,
79
+ /error_log\s*\(/,
80
+ /dd\s*\(/,
81
+ /dump\s*\(/,
82
+ ],
83
+ };
84
+ // Aggregate all patterns for quick detection
85
+ const ALL_LOGGING_PATTERNS = Object.values(LOGGING_PATTERNS).flat();
86
+ /**
87
+ * Detect logging-only commits from timeline events.
88
+ * This is a lightweight version that infers from commit messages.
89
+ */
90
+ function detectLoggingOnlyCommits(events, config = {}) {
91
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
92
+ const loggingCommits = [];
93
+ if (events.length === 0) {
94
+ return {
95
+ detected: false,
96
+ loggingCommits: [],
97
+ consecutiveLoggingCount: 0,
98
+ totalLoggingCommits: 0,
99
+ message: 'No commits to analyze',
100
+ };
101
+ }
102
+ // Sort by timestamp
103
+ const sorted = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
104
+ // Patterns that suggest logging/debugging activity
105
+ const debuggingPatterns = [
106
+ /\badd(ed|ing)?\s+(log|debug|print)/i,
107
+ /\blog(ging)?\b/i,
108
+ /\bdebug(ging)?\b/i,
109
+ /\bprint\s+statement/i,
110
+ /\btrace\b/i,
111
+ /\bconsole\b/i,
112
+ /\btemporary\b/i,
113
+ /\btemp\b/i,
114
+ /\bwip\b/i,
115
+ /\binvestigat/i,
116
+ /\bdiagnos/i,
117
+ ];
118
+ for (const event of sorted) {
119
+ const message = event.subject.toLowerCase();
120
+ const isDebugging = debuggingPatterns.some((p) => p.test(message));
121
+ // Infer if this is a logging-only commit
122
+ // True if message suggests debugging AND it's a small change
123
+ if (isDebugging) {
124
+ loggingCommits.push({
125
+ hash: event.hash,
126
+ message: event.subject,
127
+ timestamp: event.timestamp,
128
+ loggingStatements: 0, // Will be updated if we analyze diff
129
+ actualFixes: 0,
130
+ isLoggingOnly: true, // Inferred
131
+ loggingPatterns: [],
132
+ });
133
+ }
134
+ }
135
+ // Find longest consecutive run
136
+ let maxConsecutive = 0;
137
+ let currentConsecutive = 0;
138
+ for (const event of sorted) {
139
+ const isLogging = loggingCommits.some((lc) => lc.hash === event.hash);
140
+ if (isLogging) {
141
+ currentConsecutive++;
142
+ maxConsecutive = Math.max(maxConsecutive, currentConsecutive);
143
+ }
144
+ else {
145
+ currentConsecutive = 0;
146
+ }
147
+ }
148
+ const detected = maxConsecutive >= cfg.maxConsecutiveLoggingCommits;
149
+ let message = '';
150
+ if (detected) {
151
+ message = `🔍 Debug loop detected: ${maxConsecutive} consecutive logging/debug commits. Consider stepping back to understand the root cause.`;
152
+ }
153
+ else if (loggingCommits.length > 0) {
154
+ message = `${loggingCommits.length} debug/logging commit${loggingCommits.length > 1 ? 's' : ''} found`;
155
+ }
156
+ return {
157
+ detected,
158
+ loggingCommits: loggingCommits.slice(0, 10),
159
+ consecutiveLoggingCount: maxConsecutive,
160
+ totalLoggingCommits: loggingCommits.length,
161
+ message,
162
+ };
163
+ }
164
+ /**
165
+ * Analyze a commit diff to count logging statements.
166
+ * This is the more accurate version that actually looks at the diff.
167
+ */
168
+ async function analyzeCommitForLogging(repoPath, commitHash, config = {}) {
169
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
170
+ const git = (0, simple_git_1.default)(repoPath);
171
+ try {
172
+ // Get the commit diff
173
+ const diff = await git.show([commitHash, '--format=', '--unified=0']);
174
+ const commitLog = await git.log(['-1', '--format=%s', commitHash]);
175
+ const message = commitLog.latest?.message || '';
176
+ // Count logging statements added (lines starting with +)
177
+ const addedLines = diff
178
+ .split('\n')
179
+ .filter((line) => line.startsWith('+') && !line.startsWith('+++'));
180
+ let loggingStatements = 0;
181
+ const foundPatterns = [];
182
+ for (const line of addedLines) {
183
+ for (const pattern of ALL_LOGGING_PATTERNS) {
184
+ if (pattern.test(line)) {
185
+ loggingStatements++;
186
+ // Extract pattern name for reporting
187
+ const patternStr = pattern.toString();
188
+ if (!foundPatterns.includes(patternStr)) {
189
+ foundPatterns.push(patternStr);
190
+ }
191
+ break;
192
+ }
193
+ }
194
+ }
195
+ // Count non-logging changes
196
+ const actualFixes = addedLines.length - loggingStatements;
197
+ // Determine if this is logging-only
198
+ const isLoggingOnly = loggingStatements > 0 && (actualFixes === 0 || loggingStatements / addedLines.length > 0.8);
199
+ return {
200
+ hash: commitHash,
201
+ message,
202
+ timestamp: new Date(), // Would need to get from git log
203
+ loggingStatements,
204
+ actualFixes,
205
+ isLoggingOnly,
206
+ loggingPatterns: foundPatterns,
207
+ };
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ }
213
+ /**
214
+ * Analyze multiple commits for logging patterns.
215
+ * Returns detailed analysis with diff inspection.
216
+ */
217
+ async function analyzeCommitsForLogging(repoPath, events, config = {}) {
218
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
219
+ const loggingCommits = [];
220
+ // Analyze each commit
221
+ for (const event of events) {
222
+ const result = await analyzeCommitForLogging(repoPath, event.hash, config);
223
+ if (result) {
224
+ result.timestamp = event.timestamp;
225
+ if (result.loggingStatements > 0) {
226
+ loggingCommits.push(result);
227
+ }
228
+ }
229
+ }
230
+ // Sort by timestamp
231
+ loggingCommits.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
232
+ // Find consecutive logging-only commits
233
+ let maxConsecutive = 0;
234
+ let currentConsecutive = 0;
235
+ const sorted = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
236
+ for (const event of sorted) {
237
+ const loggingCommit = loggingCommits.find((lc) => lc.hash === event.hash);
238
+ if (loggingCommit?.isLoggingOnly) {
239
+ currentConsecutive++;
240
+ maxConsecutive = Math.max(maxConsecutive, currentConsecutive);
241
+ }
242
+ else {
243
+ currentConsecutive = 0;
244
+ }
245
+ }
246
+ const detected = maxConsecutive >= cfg.maxConsecutiveLoggingCommits;
247
+ // Generate message
248
+ let message = '';
249
+ if (detected) {
250
+ const totalLogging = loggingCommits.reduce((sum, c) => sum + c.loggingStatements, 0);
251
+ message = `🔍 Debug loop spiral: ${maxConsecutive} consecutive logging commits (${totalLogging} log statements added). Stop and think about the root cause.`;
252
+ }
253
+ else if (loggingCommits.length > 0) {
254
+ message = `${loggingCommits.filter((c) => c.isLoggingOnly).length} logging-only commit${loggingCommits.length > 1 ? 's' : ''} detected`;
255
+ }
256
+ return {
257
+ detected,
258
+ loggingCommits,
259
+ consecutiveLoggingCount: maxConsecutive,
260
+ totalLoggingCommits: loggingCommits.length,
261
+ message,
262
+ };
263
+ }
264
+ //# sourceMappingURL=logging-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-only.js","sourceRoot":"","sources":["../../src/inner-loop/logging-only.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
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 { TimelineEvent } from '../types';
13
+ import { TestsPassingLieResult, InnerLoopConfig } from './types';
14
+ /**
15
+ * Detect "tests passing" lies through pattern analysis.
16
+ * This is the inferred method that works without running actual tests.
17
+ */
18
+ export declare function detectTestsPassingLie(events: TimelineEvent[], filesPerCommit: Map<string, string[]>, config?: Partial<InnerLoopConfig>): TestsPassingLieResult;
19
+ /**
20
+ * Verify a specific commit by actually running tests.
21
+ * This requires the repo to be at that commit state.
22
+ */
23
+ export declare function verifyCommit(repoPath: string, commitHash: string, config?: Partial<InnerLoopConfig>): Promise<{
24
+ passed: boolean;
25
+ output: string;
26
+ }>;
27
+ /**
28
+ * Verify build passes for a commit.
29
+ */
30
+ export declare function verifyBuild(repoPath: string, config?: Partial<InnerLoopConfig>): Promise<{
31
+ passed: boolean;
32
+ output: string;
33
+ }>;
34
+ //# sourceMappingURL=tests-passing-lie.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tests-passing-lie.d.ts","sourceRoot":"","sources":["../../src/inner-loop/tests-passing-lie.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,qBAAqB,EAErB,eAAe,EAEhB,MAAM,SAAS,CAAC;AAiCjB;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EAAE,EACvB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACrC,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,qBAAqB,CAqEvB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB9C;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAqB9C"}
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * "Tests Passing" Lie Detector
4
+ *
5
+ * Detects when AI claims "all tests passing" or "working" but the code
6
+ * actually doesn't work. This is detected through:
7
+ *
8
+ * 1. Inferred: Commit claims success but is immediately followed by fixes
9
+ * 2. Verified: Actually run tests/build and compare to commit claims
10
+ *
11
+ * This is a key "Inner Loop Disaster" in vibe coding.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.detectTestsPassingLie = detectTestsPassingLie;
15
+ exports.verifyCommit = verifyCommit;
16
+ exports.verifyBuild = verifyBuild;
17
+ const date_fns_1 = require("date-fns");
18
+ const child_process_1 = require("child_process");
19
+ const util_1 = require("util");
20
+ const types_1 = require("./types");
21
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
22
+ // Patterns that indicate a claim of success
23
+ const SUCCESS_CLAIM_PATTERNS = [
24
+ /\bfix(ed|es)?\b/i,
25
+ /\bworking\b/i,
26
+ /\bdone\b/i,
27
+ /\bcomplete[ds]?\b/i,
28
+ /\bresolve[ds]?\b/i,
29
+ /\bpass(es|ing)?\b/i,
30
+ /\bgreen\b/i,
31
+ /\bsuccessful(ly)?\b/i,
32
+ /\ball\s+tests?\b/i,
33
+ /\bready\b/i,
34
+ /\bshould\s+work/i,
35
+ /\bnow\s+works?\b/i,
36
+ ];
37
+ // Patterns that indicate the commit is tentative (not a lie if it fails)
38
+ const TENTATIVE_PATTERNS = [
39
+ /\btry\b/i,
40
+ /\battempt/i,
41
+ /\bmaybe\b/i,
42
+ /\bwip\b/i,
43
+ /\bwork\s*in\s*progress/i,
44
+ /\bexperiment/i,
45
+ /\btest(ing)?\b/i, // Just "testing" something
46
+ /\bdebug/i,
47
+ /\binvestigat/i,
48
+ ];
49
+ /**
50
+ * Detect "tests passing" lies through pattern analysis.
51
+ * This is the inferred method that works without running actual tests.
52
+ */
53
+ function detectTestsPassingLie(events, filesPerCommit, config = {}) {
54
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
55
+ const lies = [];
56
+ if (events.length < 2) {
57
+ return {
58
+ detected: false,
59
+ lies: [],
60
+ totalLies: 0,
61
+ message: 'Not enough commits to detect lies',
62
+ };
63
+ }
64
+ // Sort by timestamp ascending
65
+ const sorted = [...events].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
66
+ for (let i = 0; i < sorted.length - 1; i++) {
67
+ const commit = sorted[i];
68
+ const claimsSuccess = claimsToBeSuccessful(commit.subject);
69
+ const isTentative = isTentativeCommit(commit.subject);
70
+ // Skip if tentative or doesn't claim success
71
+ if (!claimsSuccess || isTentative)
72
+ continue;
73
+ // Look at following commits within 30 minutes
74
+ const followingCommits = getFollowingCommitsInWindow(sorted, i, 30);
75
+ // Check if followed by fix commits on same files
76
+ const commitFiles = filesPerCommit.get(commit.hash) || [];
77
+ const quickFixes = followingCommits.filter((fc) => {
78
+ if (fc.type !== 'fix')
79
+ return false;
80
+ // Check file overlap
81
+ const fcFiles = filesPerCommit.get(fc.hash) || [];
82
+ const hasOverlap = commitFiles.some((f) => fcFiles.includes(f));
83
+ // Or same scope
84
+ const sameScope = commit.scope && fc.scope === commit.scope;
85
+ return hasOverlap || sameScope;
86
+ });
87
+ if (quickFixes.length > 0) {
88
+ const gap = (0, date_fns_1.differenceInMinutes)(quickFixes[0].timestamp, commit.timestamp);
89
+ lies.push({
90
+ commitHash: commit.hash,
91
+ commitMessage: commit.subject,
92
+ timestamp: commit.timestamp,
93
+ claimedSuccess: true,
94
+ actualResult: 'inferred',
95
+ verificationMethod: 'inferred',
96
+ });
97
+ }
98
+ }
99
+ const detected = lies.length > 0;
100
+ let message = '';
101
+ if (detected) {
102
+ const lieRate = Math.round((lies.length / events.length) * 100);
103
+ message = `🤥 ${lies.length} "tests passing" lie${lies.length > 1 ? 's' : ''} detected: commits claimed success but required immediate fixes (${lieRate}% lie rate)`;
104
+ }
105
+ return {
106
+ detected,
107
+ lies: lies.slice(0, 10),
108
+ totalLies: lies.length,
109
+ message,
110
+ };
111
+ }
112
+ /**
113
+ * Verify a specific commit by actually running tests.
114
+ * This requires the repo to be at that commit state.
115
+ */
116
+ async function verifyCommit(repoPath, commitHash, config = {}) {
117
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
118
+ // Determine test command
119
+ const testCommand = cfg.testCommand || detectTestCommand(repoPath);
120
+ if (!testCommand) {
121
+ return { passed: true, output: 'No test command configured or detected' };
122
+ }
123
+ try {
124
+ const { stdout, stderr } = await execAsync(testCommand, {
125
+ cwd: repoPath,
126
+ timeout: 120000, // 2 minute timeout
127
+ });
128
+ return { passed: true, output: stdout + stderr };
129
+ }
130
+ catch (error) {
131
+ const execError = error;
132
+ return {
133
+ passed: false,
134
+ output: (execError.stdout || '') + (execError.stderr || '') + (execError.message || ''),
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Verify build passes for a commit.
140
+ */
141
+ async function verifyBuild(repoPath, config = {}) {
142
+ const cfg = { ...types_1.DEFAULT_INNER_LOOP_CONFIG, ...config };
143
+ const buildCommand = cfg.buildCommand || detectBuildCommand(repoPath);
144
+ if (!buildCommand) {
145
+ return { passed: true, output: 'No build command configured or detected' };
146
+ }
147
+ try {
148
+ const { stdout, stderr } = await execAsync(buildCommand, {
149
+ cwd: repoPath,
150
+ timeout: 300000, // 5 minute timeout
151
+ });
152
+ return { passed: true, output: stdout + stderr };
153
+ }
154
+ catch (error) {
155
+ const execError = error;
156
+ return {
157
+ passed: false,
158
+ output: (execError.stdout || '') + (execError.stderr || '') + (execError.message || ''),
159
+ };
160
+ }
161
+ }
162
+ /**
163
+ * Check if a commit message claims success.
164
+ */
165
+ function claimsToBeSuccessful(message) {
166
+ return SUCCESS_CLAIM_PATTERNS.some((p) => p.test(message));
167
+ }
168
+ /**
169
+ * Check if a commit is tentative (WIP, try, experiment, etc.)
170
+ */
171
+ function isTentativeCommit(message) {
172
+ return TENTATIVE_PATTERNS.some((p) => p.test(message));
173
+ }
174
+ /**
175
+ * Get commits following a given index within a time window.
176
+ */
177
+ function getFollowingCommitsInWindow(events, index, windowMinutes) {
178
+ const result = [];
179
+ const baseTime = events[index].timestamp;
180
+ const windowEnd = new Date(baseTime.getTime() + windowMinutes * 60 * 1000);
181
+ for (let i = index + 1; i < events.length; i++) {
182
+ if (events[i].timestamp > windowEnd)
183
+ break;
184
+ result.push(events[i]);
185
+ }
186
+ return result;
187
+ }
188
+ /**
189
+ * Detect test command from project configuration.
190
+ */
191
+ function detectTestCommand(repoPath) {
192
+ // Common test commands by project type
193
+ // In real implementation, we'd check package.json, Makefile, etc.
194
+ const commands = [
195
+ 'npm test',
196
+ 'yarn test',
197
+ 'pnpm test',
198
+ 'make test',
199
+ 'cargo test',
200
+ 'go test ./...',
201
+ 'pytest',
202
+ 'python -m pytest',
203
+ ];
204
+ // For now, return npm test as default for Node projects
205
+ return 'npm test';
206
+ }
207
+ /**
208
+ * Detect build command from project configuration.
209
+ */
210
+ function detectBuildCommand(repoPath) {
211
+ return 'npm run build';
212
+ }
213
+ //# 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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"}