@boshu2/vibe-check 0.1.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/.dockerignore +46 -0
- package/.gitattributes +3 -0
- package/.pre-commit-hooks.yaml +11 -0
- package/AGENTS.md +40 -0
- package/CHANGELOG.md +322 -0
- package/CLAUDE.md +342 -0
- package/CONTRIBUTING.md +227 -0
- package/Dockerfile +26 -0
- package/LICENSE +201 -0
- package/Makefile +213 -0
- package/README.md +165 -0
- package/SECURITY.md +182 -0
- package/action.yml +270 -0
- package/assets/logo-dark.svg +47 -0
- package/assets/logo.svg +47 -0
- package/bin/vc.js +2 -0
- package/bin/vibe-check.js +2 -0
- package/claude-progress.json +312 -0
- package/claude-progress.txt +572 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/analyze-helpers.d.ts +43 -0
- package/dist/commands/analyze-helpers.d.ts.map +1 -0
- package/dist/commands/analyze-helpers.js +124 -0
- package/dist/commands/analyze-helpers.js.map +1 -0
- package/dist/commands/analyze.d.ts +21 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +114 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/errors.d.ts +100 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +208 -0
- package/dist/errors.js.map +1 -0
- package/dist/git.d.ts +39 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +206 -0
- package/dist/git.js.map +1 -0
- 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 +36 -0
- package/dist/inner-loop/instruction-drift.d.ts.map +1 -0
- package/dist/inner-loop/instruction-drift.js +270 -0
- package/dist/inner-loop/instruction-drift.js.map +1 -0
- package/dist/inner-loop/logging-only.d.ts +64 -0
- package/dist/inner-loop/logging-only.d.ts.map +1 -0
- package/dist/inner-loop/logging-only.js +292 -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 +213 -0
- package/dist/inner-loop/tests-passing-lie.js.map +1 -0
- package/dist/inner-loop/types.d.ts +125 -0
- package/dist/inner-loop/types.d.ts.map +1 -0
- package/dist/inner-loop/types.js +27 -0
- package/dist/inner-loop/types.js.map +1 -0
- package/dist/internal/context/index.d.ts +74 -0
- package/dist/internal/context/index.d.ts.map +1 -0
- package/dist/internal/context/index.js +151 -0
- package/dist/internal/context/index.js.map +1 -0
- package/dist/internal/context/types.d.ts +75 -0
- package/dist/internal/context/types.d.ts.map +1 -0
- package/dist/internal/context/types.js +8 -0
- package/dist/internal/context/types.js.map +1 -0
- package/dist/internal/output/contract.d.ts +81 -0
- package/dist/internal/output/contract.d.ts.map +1 -0
- package/dist/internal/output/contract.js +112 -0
- package/dist/internal/output/contract.js.map +1 -0
- package/dist/internal/output/index.d.ts +7 -0
- package/dist/internal/output/index.d.ts.map +1 -0
- package/dist/internal/output/index.js +7 -0
- package/dist/internal/output/index.js.map +1 -0
- package/dist/metrics/flow.d.ts +20 -0
- package/dist/metrics/flow.d.ts.map +1 -0
- package/dist/metrics/flow.js +85 -0
- package/dist/metrics/flow.js.map +1 -0
- package/dist/metrics/index.d.ts +4 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +161 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/rework.d.ts +12 -0
- package/dist/metrics/rework.d.ts.map +1 -0
- package/dist/metrics/rework.js +51 -0
- package/dist/metrics/rework.js.map +1 -0
- package/dist/metrics/spirals.d.ts +17 -0
- package/dist/metrics/spirals.d.ts.map +1 -0
- package/dist/metrics/spirals.js +157 -0
- package/dist/metrics/spirals.js.map +1 -0
- package/dist/metrics/trust.d.ts +12 -0
- package/dist/metrics/trust.d.ts.map +1 -0
- package/dist/metrics/trust.js +175 -0
- package/dist/metrics/trust.js.map +1 -0
- package/dist/metrics/velocity.d.ts +25 -0
- package/dist/metrics/velocity.d.ts.map +1 -0
- package/dist/metrics/velocity.js +120 -0
- package/dist/metrics/velocity.js.map +1 -0
- package/dist/output/index.d.ts +10 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +20 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/json.d.ts +3 -0
- package/dist/output/json.d.ts.map +1 -0
- package/dist/output/json.js +48 -0
- package/dist/output/json.js.map +1 -0
- package/dist/output/markdown.d.ts +3 -0
- package/dist/output/markdown.d.ts.map +1 -0
- package/dist/output/markdown.js +84 -0
- package/dist/output/markdown.js.map +1 -0
- package/dist/output/terminal.d.ts +10 -0
- package/dist/output/terminal.d.ts.map +1 -0
- package/dist/output/terminal.js +153 -0
- package/dist/output/terminal.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/docs/ARCHITECTURE.md +450 -0
- package/docs/DEPLOYMENT.md +394 -0
- package/docs/METRICS-EXPLAINED.md +394 -0
- package/docs/REFERENCE.md +230 -0
- package/docs/images/dashboard.png +0 -0
- package/drivers/README.md +327 -0
- package/drivers/go.sh +131 -0
- package/drivers/java.sh +137 -0
- package/drivers/javascript.sh +134 -0
- package/drivers/php.sh +132 -0
- package/drivers/python.sh +90 -0
- package/drivers/rust.sh +132 -0
- package/feature-list.json +273 -0
- package/hooks/pre-push +107 -0
- package/package.json +47 -0
- package/vitest.config.ts +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Commit } from './types.js';
|
|
2
|
+
export declare function getCommits(repoPath: string, since?: string, until?: string, timeoutSeconds?: number, maxCommits?: number): Promise<Commit[]>;
|
|
3
|
+
export declare function isGitRepo(repoPath: string): Promise<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* Get the latest commit hash in the repo
|
|
6
|
+
*/
|
|
7
|
+
export declare function getLatestCommitHash(repoPath: string): Promise<string>;
|
|
8
|
+
/**
|
|
9
|
+
* Get commits since a specific commit hash (for incremental sync)
|
|
10
|
+
*/
|
|
11
|
+
export declare function getCommitsSince(repoPath: string, sinceHash: string): Promise<Commit[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Check if a commit hash exists in the repo
|
|
14
|
+
*/
|
|
15
|
+
export declare function commitExists(repoPath: string, hash: string): Promise<boolean>;
|
|
16
|
+
export interface FileStats {
|
|
17
|
+
filesPerCommit: Map<string, string[]>;
|
|
18
|
+
lineStats: {
|
|
19
|
+
additions: number;
|
|
20
|
+
deletions: number;
|
|
21
|
+
}[];
|
|
22
|
+
}
|
|
23
|
+
export interface CommitStats {
|
|
24
|
+
filesPerCommit: Map<string, string[]>;
|
|
25
|
+
lineStatsPerCommit: Map<string, {
|
|
26
|
+
additions: number;
|
|
27
|
+
deletions: number;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get file-level statistics for semantic-free metrics.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getFileStats(repoPath: string, since?: string, until?: string): Promise<FileStats>;
|
|
34
|
+
/**
|
|
35
|
+
* Get per-commit statistics for pattern detection.
|
|
36
|
+
* Returns a map of commit hash -> stats
|
|
37
|
+
*/
|
|
38
|
+
export declare function getCommitStats(repoPath: string, since?: string, until?: string): Promise<CommitStats>;
|
|
39
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAOpC,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgDnB;AAkCD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnF;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3E;AAwFD;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAGpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC,CAGtB"}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { simpleGit } from 'simple-git';
|
|
2
|
+
const COMMIT_TYPES = ['feat', 'fix', 'docs', 'chore', 'refactor', 'test', 'style', 'tracer'];
|
|
3
|
+
// Tracer bullet commit patterns (tb: is shorthand for tracer:)
|
|
4
|
+
const TRACER_ALIASES = ['tb'];
|
|
5
|
+
export async function getCommits(repoPath, since, until, timeoutSeconds, maxCommits) {
|
|
6
|
+
// Configure git with timeout if provided
|
|
7
|
+
const git = simpleGit(repoPath, {
|
|
8
|
+
timeout: {
|
|
9
|
+
block: timeoutSeconds ? timeoutSeconds * 1000 : 120000, // Default 120s
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
// Build options for git log
|
|
13
|
+
const options = {};
|
|
14
|
+
if (since) {
|
|
15
|
+
options['--since'] = since;
|
|
16
|
+
}
|
|
17
|
+
if (until) {
|
|
18
|
+
options['--until'] = until;
|
|
19
|
+
}
|
|
20
|
+
// Add max-count if limit specified
|
|
21
|
+
if (maxCommits) {
|
|
22
|
+
options['--max-count'] = maxCommits;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const log = await git.log(options);
|
|
26
|
+
const commitCount = log.all.length;
|
|
27
|
+
// Warn if we hit the max commits limit
|
|
28
|
+
if (maxCommits && commitCount >= maxCommits) {
|
|
29
|
+
console.warn(`\nWarning: Analyzed first ${commitCount} commits (limit: ${maxCommits})`);
|
|
30
|
+
console.warn(`Use --max-commits to adjust the limit.\n`);
|
|
31
|
+
}
|
|
32
|
+
return log.all.map((entry) => parseCommit(entry));
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
36
|
+
// Check if this is a timeout error
|
|
37
|
+
if (errorMsg.includes('timeout') || errorMsg.includes('ETIMEDOUT')) {
|
|
38
|
+
console.error(`\nError: Git operation timed out after ${timeoutSeconds || 'default'}s`);
|
|
39
|
+
console.error('Try increasing the timeout with --timeout <seconds>\n');
|
|
40
|
+
process.exit(2); // ExitCode.GIT_ERROR
|
|
41
|
+
}
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
throw new Error(`Failed to read git log: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function parseCommit(entry) {
|
|
49
|
+
const { hash, date, message, author_name } = entry;
|
|
50
|
+
// Parse conventional commit format: type(scope): description
|
|
51
|
+
const conventionalMatch = message.match(/^(\w+)(?:\(([^)]+)\))?:\s*(.+)/);
|
|
52
|
+
let type = 'other';
|
|
53
|
+
let scope = null;
|
|
54
|
+
if (conventionalMatch) {
|
|
55
|
+
const [, rawType, rawScope] = conventionalMatch;
|
|
56
|
+
const normalizedType = rawType.toLowerCase();
|
|
57
|
+
// Check for tracer aliases (tb: -> tracer)
|
|
58
|
+
if (TRACER_ALIASES.includes(normalizedType)) {
|
|
59
|
+
type = 'tracer';
|
|
60
|
+
}
|
|
61
|
+
else if (COMMIT_TYPES.includes(normalizedType)) {
|
|
62
|
+
type = normalizedType;
|
|
63
|
+
}
|
|
64
|
+
scope = rawScope || null;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
hash: hash.substring(0, 7),
|
|
68
|
+
date: new Date(date),
|
|
69
|
+
message: message.split('\n')[0], // First line only
|
|
70
|
+
type,
|
|
71
|
+
scope,
|
|
72
|
+
author: author_name,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function isGitRepo(repoPath) {
|
|
76
|
+
const git = simpleGit(repoPath);
|
|
77
|
+
try {
|
|
78
|
+
await git.status();
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the latest commit hash in the repo
|
|
87
|
+
*/
|
|
88
|
+
export async function getLatestCommitHash(repoPath) {
|
|
89
|
+
const git = simpleGit(repoPath);
|
|
90
|
+
try {
|
|
91
|
+
const log = await git.log({ n: 1 });
|
|
92
|
+
return log.latest?.hash.substring(0, 7) || '';
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return '';
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get commits since a specific commit hash (for incremental sync)
|
|
100
|
+
*/
|
|
101
|
+
export async function getCommitsSince(repoPath, sinceHash) {
|
|
102
|
+
const git = simpleGit(repoPath);
|
|
103
|
+
try {
|
|
104
|
+
// Get commits after the given hash
|
|
105
|
+
const log = await git.log({ from: sinceHash, to: 'HEAD' });
|
|
106
|
+
return log.all.map((entry) => parseCommit(entry));
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// If hash doesn't exist or error, return empty
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if a commit hash exists in the repo
|
|
115
|
+
*/
|
|
116
|
+
export async function commitExists(repoPath, hash) {
|
|
117
|
+
const git = simpleGit(repoPath);
|
|
118
|
+
try {
|
|
119
|
+
await git.raw(['cat-file', '-t', hash]);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Internal: Parse diff stats from git diff-tree output.
|
|
128
|
+
* Extracted to avoid duplication between getFileStats and getCommitStats.
|
|
129
|
+
*/
|
|
130
|
+
function parseDiffStats(diffStat) {
|
|
131
|
+
const lines = diffStat.trim().split('\n').filter(l => l.length > 0);
|
|
132
|
+
const files = [];
|
|
133
|
+
let additions = 0;
|
|
134
|
+
let deletions = 0;
|
|
135
|
+
for (const line of lines) {
|
|
136
|
+
const parts = line.split('\t');
|
|
137
|
+
if (parts.length >= 3) {
|
|
138
|
+
const add = parseInt(parts[0], 10) || 0;
|
|
139
|
+
const del = parseInt(parts[1], 10) || 0;
|
|
140
|
+
const file = parts[2];
|
|
141
|
+
additions += add;
|
|
142
|
+
deletions += del;
|
|
143
|
+
files.push(file);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { files, additions, deletions };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Internal: Get diff stats for a single commit.
|
|
150
|
+
* Returns files changed and line stats.
|
|
151
|
+
*/
|
|
152
|
+
async function getCommitDiffStats(git, commitHash) {
|
|
153
|
+
try {
|
|
154
|
+
const diffStat = await git.raw(['diff-tree', '--numstat', '--root', '-r', commitHash]);
|
|
155
|
+
return parseDiffStats(diffStat);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return { files: [], additions: 0, deletions: 0 };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Internal: Core implementation for fetching git statistics.
|
|
163
|
+
* Used by both getFileStats and getCommitStats to avoid code duplication.
|
|
164
|
+
*/
|
|
165
|
+
async function fetchGitStats(repoPath, since, until) {
|
|
166
|
+
const git = simpleGit(repoPath);
|
|
167
|
+
const filesPerCommit = new Map();
|
|
168
|
+
const lineStatsArray = [];
|
|
169
|
+
const lineStatsMap = new Map();
|
|
170
|
+
// Build options for git log
|
|
171
|
+
const logOptions = {};
|
|
172
|
+
if (since)
|
|
173
|
+
logOptions['--since'] = since;
|
|
174
|
+
if (until)
|
|
175
|
+
logOptions['--until'] = until;
|
|
176
|
+
try {
|
|
177
|
+
const log = await git.log(logOptions);
|
|
178
|
+
for (const commit of log.all) {
|
|
179
|
+
const hash = commit.hash.substring(0, 7);
|
|
180
|
+
const stats = await getCommitDiffStats(git, commit.hash);
|
|
181
|
+
filesPerCommit.set(hash, stats.files);
|
|
182
|
+
lineStatsArray.push({ additions: stats.additions, deletions: stats.deletions });
|
|
183
|
+
lineStatsMap.set(hash, { additions: stats.additions, deletions: stats.deletions });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// Return empty stats on error - silent fail
|
|
188
|
+
}
|
|
189
|
+
return { filesPerCommit, lineStatsArray, lineStatsMap };
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get file-level statistics for semantic-free metrics.
|
|
193
|
+
*/
|
|
194
|
+
export async function getFileStats(repoPath, since, until) {
|
|
195
|
+
const { filesPerCommit, lineStatsArray } = await fetchGitStats(repoPath, since, until);
|
|
196
|
+
return { filesPerCommit, lineStats: lineStatsArray };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get per-commit statistics for pattern detection.
|
|
200
|
+
* Returns a map of commit hash -> stats
|
|
201
|
+
*/
|
|
202
|
+
export async function getCommitStats(repoPath, since, until) {
|
|
203
|
+
const { filesPerCommit, lineStatsMap } = await fetchGitStats(repoPath, since, until);
|
|
204
|
+
return { filesPerCommit, lineStatsPerCommit: lineStatsMap };
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Amnesia Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects when AI forgets previous instructions and:
|
|
5
|
+
* - Reverts intentional changes
|
|
6
|
+
* - Re-implements code that was just deleted
|
|
7
|
+
* - Repeats the same fix multiple times
|
|
8
|
+
*
|
|
9
|
+
* This is a key "Inner Loop Disaster" in vibe coding.
|
|
10
|
+
*/
|
|
11
|
+
import { TimelineEvent } from '../types.js';
|
|
12
|
+
import { ContextAmnesiaResult, InnerLoopConfig } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Detect context amnesia patterns in commit history.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectContextAmnesia(events: TimelineEvent[], filesPerCommit: Map<string, string[]>, lineStatsPerCommit: Map<string, {
|
|
17
|
+
additions: number;
|
|
18
|
+
deletions: number;
|
|
19
|
+
}>, config?: Partial<InnerLoopConfig>): ContextAmnesiaResult;
|
|
20
|
+
//# sourceMappingURL=context-amnesia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-amnesia.d.ts","sourceRoot":"","sources":["../../src/inner-loop/context-amnesia.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,oBAAoB,EAEpB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAapB;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EAAE,EACvB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACrC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EACzE,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,oBAAoB,CAuDtB"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Amnesia Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects when AI forgets previous instructions and:
|
|
5
|
+
* - Reverts intentional changes
|
|
6
|
+
* - Re-implements code that was just deleted
|
|
7
|
+
* - Repeats the same fix multiple times
|
|
8
|
+
*
|
|
9
|
+
* This is a key "Inner Loop Disaster" in vibe coding.
|
|
10
|
+
*/
|
|
11
|
+
import { differenceInMinutes } from 'date-fns';
|
|
12
|
+
import { DEFAULT_INNER_LOOP_CONFIG, } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Detect context amnesia patterns in commit history.
|
|
15
|
+
*/
|
|
16
|
+
export function detectContextAmnesia(events, filesPerCommit, lineStatsPerCommit, config = {}) {
|
|
17
|
+
const cfg = { ...DEFAULT_INNER_LOOP_CONFIG, ...config };
|
|
18
|
+
const incidents = [];
|
|
19
|
+
if (events.length < 2) {
|
|
20
|
+
return {
|
|
21
|
+
detected: false,
|
|
22
|
+
incidents: [],
|
|
23
|
+
totalIncidents: 0,
|
|
24
|
+
totalTimeWasted: 0,
|
|
25
|
+
message: 'Not enough commits to detect context amnesia',
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// Build enriched commit data
|
|
29
|
+
const commits = events.map((e) => ({
|
|
30
|
+
hash: e.hash,
|
|
31
|
+
message: e.subject,
|
|
32
|
+
timestamp: e.timestamp,
|
|
33
|
+
scope: e.scope,
|
|
34
|
+
files: filesPerCommit.get(e.hash) || [],
|
|
35
|
+
additions: lineStatsPerCommit.get(e.hash)?.additions || 0,
|
|
36
|
+
deletions: lineStatsPerCommit.get(e.hash)?.deletions || 0,
|
|
37
|
+
type: e.type,
|
|
38
|
+
}));
|
|
39
|
+
// Sort by timestamp ascending
|
|
40
|
+
commits.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
41
|
+
// Detection strategies
|
|
42
|
+
const revertIncidents = detectReverts(commits, cfg);
|
|
43
|
+
const reimplementIncidents = detectReimplementation(commits, cfg);
|
|
44
|
+
const repeatedFixIncidents = detectRepeatedFixes(commits, cfg);
|
|
45
|
+
incidents.push(...revertIncidents, ...reimplementIncidents, ...repeatedFixIncidents);
|
|
46
|
+
// Calculate total time wasted
|
|
47
|
+
const totalTimeWasted = incidents.reduce((sum, i) => sum + i.gapMinutes, 0);
|
|
48
|
+
// Generate message
|
|
49
|
+
const detected = incidents.length > 0;
|
|
50
|
+
let message = '';
|
|
51
|
+
if (detected) {
|
|
52
|
+
const types = new Set(incidents.map((i) => i.type));
|
|
53
|
+
const typeStr = Array.from(types).join(', ');
|
|
54
|
+
message = `🧠 Context amnesia detected: ${incidents.length} incident${incidents.length > 1 ? 's' : ''} (${typeStr}). ~${totalTimeWasted}m potentially wasted.`;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
detected,
|
|
58
|
+
incidents: incidents.slice(0, 10), // Top 10
|
|
59
|
+
totalIncidents: incidents.length,
|
|
60
|
+
totalTimeWasted,
|
|
61
|
+
message,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Detect explicit reverts or undo patterns.
|
|
66
|
+
*/
|
|
67
|
+
function detectReverts(commits, config) {
|
|
68
|
+
const incidents = [];
|
|
69
|
+
// Patterns that indicate a revert
|
|
70
|
+
const revertPatterns = [
|
|
71
|
+
/revert/i,
|
|
72
|
+
/undo/i,
|
|
73
|
+
/rollback/i,
|
|
74
|
+
/back\s*out/i,
|
|
75
|
+
/restore\s+previous/i,
|
|
76
|
+
];
|
|
77
|
+
for (let i = 1; i < commits.length; i++) {
|
|
78
|
+
const commit = commits[i];
|
|
79
|
+
const isRevert = revertPatterns.some((p) => p.test(commit.message));
|
|
80
|
+
if (isRevert) {
|
|
81
|
+
// Find what was reverted (look back within window)
|
|
82
|
+
const windowStart = new Date(commit.timestamp.getTime() - config.amnesiaWindowMinutes * 60 * 1000);
|
|
83
|
+
// Find commits in window that touch same files
|
|
84
|
+
for (let j = i - 1; j >= 0; j--) {
|
|
85
|
+
const original = commits[j];
|
|
86
|
+
if (original.timestamp < windowStart)
|
|
87
|
+
break;
|
|
88
|
+
const sharedFiles = commit.files.filter((f) => original.files.includes(f));
|
|
89
|
+
if (sharedFiles.length > 0) {
|
|
90
|
+
const gap = differenceInMinutes(commit.timestamp, original.timestamp);
|
|
91
|
+
incidents.push({
|
|
92
|
+
type: 'revert',
|
|
93
|
+
originalCommit: {
|
|
94
|
+
hash: original.hash,
|
|
95
|
+
message: original.message,
|
|
96
|
+
timestamp: original.timestamp,
|
|
97
|
+
},
|
|
98
|
+
repeatCommit: {
|
|
99
|
+
hash: commit.hash,
|
|
100
|
+
message: commit.message,
|
|
101
|
+
timestamp: commit.timestamp,
|
|
102
|
+
},
|
|
103
|
+
scope: commit.scope || original.scope,
|
|
104
|
+
filesAffected: sharedFiles,
|
|
105
|
+
gapMinutes: gap,
|
|
106
|
+
description: `Reverted changes from ${gap}m ago`,
|
|
107
|
+
});
|
|
108
|
+
break; // Only count once per revert
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return incidents;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Detect reimplementation: code deleted then similar code re-added.
|
|
117
|
+
*/
|
|
118
|
+
function detectReimplementation(commits, config) {
|
|
119
|
+
const incidents = [];
|
|
120
|
+
// Track significant deletions
|
|
121
|
+
const deletions = [];
|
|
122
|
+
for (const commit of commits) {
|
|
123
|
+
// Significant deletion: more deletions than additions
|
|
124
|
+
if (commit.deletions > commit.additions && commit.deletions > 10) {
|
|
125
|
+
deletions.push({
|
|
126
|
+
commit,
|
|
127
|
+
files: commit.files,
|
|
128
|
+
linesDeleted: commit.deletions,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Look for later commits that re-add similar content to same files
|
|
133
|
+
for (const deletion of deletions) {
|
|
134
|
+
const windowEnd = new Date(deletion.commit.timestamp.getTime() + config.amnesiaWindowMinutes * 60 * 1000);
|
|
135
|
+
for (const commit of commits) {
|
|
136
|
+
// Must be after the deletion
|
|
137
|
+
if (commit.timestamp <= deletion.commit.timestamp)
|
|
138
|
+
continue;
|
|
139
|
+
if (commit.timestamp > windowEnd)
|
|
140
|
+
continue;
|
|
141
|
+
// Must touch same files with additions
|
|
142
|
+
const sharedFiles = commit.files.filter((f) => deletion.files.includes(f));
|
|
143
|
+
if (sharedFiles.length === 0)
|
|
144
|
+
continue;
|
|
145
|
+
// Must have significant additions (reimplementing)
|
|
146
|
+
if (commit.additions < deletion.linesDeleted * 0.5)
|
|
147
|
+
continue;
|
|
148
|
+
const gap = differenceInMinutes(commit.timestamp, deletion.commit.timestamp);
|
|
149
|
+
// Check if this looks like reimplementation vs intentional refactor
|
|
150
|
+
// Refactors usually have "refactor" in message
|
|
151
|
+
if (/refactor/i.test(commit.message))
|
|
152
|
+
continue;
|
|
153
|
+
incidents.push({
|
|
154
|
+
type: 'reimplementation',
|
|
155
|
+
originalCommit: {
|
|
156
|
+
hash: deletion.commit.hash,
|
|
157
|
+
message: deletion.commit.message,
|
|
158
|
+
timestamp: deletion.commit.timestamp,
|
|
159
|
+
},
|
|
160
|
+
repeatCommit: {
|
|
161
|
+
hash: commit.hash,
|
|
162
|
+
message: commit.message,
|
|
163
|
+
timestamp: commit.timestamp,
|
|
164
|
+
},
|
|
165
|
+
scope: commit.scope || deletion.commit.scope,
|
|
166
|
+
filesAffected: sharedFiles,
|
|
167
|
+
gapMinutes: gap,
|
|
168
|
+
description: `Deleted ${deletion.linesDeleted} lines, then re-added ${commit.additions} lines ${gap}m later`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return incidents;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Detect repeated fixes: same area fixed multiple times in short window.
|
|
176
|
+
*/
|
|
177
|
+
function detectRepeatedFixes(commits, config) {
|
|
178
|
+
const incidents = [];
|
|
179
|
+
// Group fix commits by scope/files
|
|
180
|
+
const fixCommits = commits.filter((c) => c.type === 'fix');
|
|
181
|
+
// Track fixes per scope within time window
|
|
182
|
+
const scopeFixes = new Map();
|
|
183
|
+
for (const fix of fixCommits) {
|
|
184
|
+
const scope = fix.scope || fix.files[0] || 'unknown';
|
|
185
|
+
if (!scopeFixes.has(scope)) {
|
|
186
|
+
scopeFixes.set(scope, []);
|
|
187
|
+
}
|
|
188
|
+
scopeFixes.get(scope).push(fix);
|
|
189
|
+
}
|
|
190
|
+
// Find scopes with 3+ fixes in window (beyond normal spiral detection)
|
|
191
|
+
for (const [scope, fixes] of scopeFixes) {
|
|
192
|
+
if (fixes.length < 3)
|
|
193
|
+
continue;
|
|
194
|
+
// Check if messages are similar (forgot what was tried)
|
|
195
|
+
for (let i = 0; i < fixes.length - 1; i++) {
|
|
196
|
+
const current = fixes[i];
|
|
197
|
+
const next = fixes[i + 1];
|
|
198
|
+
const gap = differenceInMinutes(next.timestamp, current.timestamp);
|
|
199
|
+
if (gap > config.amnesiaWindowMinutes)
|
|
200
|
+
continue;
|
|
201
|
+
// Check message similarity
|
|
202
|
+
const similarity = calculateSimilarity(current.message, next.message);
|
|
203
|
+
if (similarity > config.similarityThreshold) {
|
|
204
|
+
incidents.push({
|
|
205
|
+
type: 'forgotten_change',
|
|
206
|
+
originalCommit: {
|
|
207
|
+
hash: current.hash,
|
|
208
|
+
message: current.message,
|
|
209
|
+
timestamp: current.timestamp,
|
|
210
|
+
},
|
|
211
|
+
repeatCommit: {
|
|
212
|
+
hash: next.hash,
|
|
213
|
+
message: next.message,
|
|
214
|
+
timestamp: next.timestamp,
|
|
215
|
+
},
|
|
216
|
+
scope,
|
|
217
|
+
filesAffected: [...new Set([...current.files, ...next.files])],
|
|
218
|
+
gapMinutes: gap,
|
|
219
|
+
description: `Similar fix attempted ${gap}m later (${Math.round(similarity * 100)}% similar)`,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return incidents;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Calculate similarity between two commit messages (Jaccard index).
|
|
228
|
+
*/
|
|
229
|
+
function calculateSimilarity(msg1, msg2) {
|
|
230
|
+
const words1 = new Set(msg1
|
|
231
|
+
.toLowerCase()
|
|
232
|
+
.replace(/[^a-z0-9\s]/g, '')
|
|
233
|
+
.split(/\s+/)
|
|
234
|
+
.filter((w) => w.length > 2));
|
|
235
|
+
const words2 = new Set(msg2
|
|
236
|
+
.toLowerCase()
|
|
237
|
+
.replace(/[^a-z0-9\s]/g, '')
|
|
238
|
+
.split(/\s+/)
|
|
239
|
+
.filter((w) => w.length > 2));
|
|
240
|
+
if (words1.size === 0 || words2.size === 0)
|
|
241
|
+
return 0;
|
|
242
|
+
const intersection = new Set([...words1].filter((w) => words2.has(w)));
|
|
243
|
+
const union = new Set([...words1, ...words2]);
|
|
244
|
+
return intersection.size / union.size;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=context-amnesia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-amnesia.js","sourceRoot":"","sources":["../../src/inner-loop/context-amnesia.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inner Loop Failure Pattern Detection
|
|
3
|
+
*
|
|
4
|
+
* This module detects 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
|
+
import { TimelineEvent } from '../types.js';
|
|
11
|
+
import { InnerLoopAnalysis, InnerLoopConfig } from './types.js';
|
|
12
|
+
export * from './types.js';
|
|
13
|
+
export { detectTestsPassingLie } from './tests-passing-lie.js';
|
|
14
|
+
export { detectContextAmnesia } from './context-amnesia.js';
|
|
15
|
+
export { detectInstructionDrift, createSessionScope, inferSessionScope } from './instruction-drift.js';
|
|
16
|
+
export { detectLoggingOnlyCommits, analyzeCommitsForLogging } from './logging-only.js';
|
|
17
|
+
/**
|
|
18
|
+
* Run all inner loop failure pattern detectors.
|
|
19
|
+
*/
|
|
20
|
+
export declare function analyzeInnerLoop(events: TimelineEvent[], filesPerCommit: Map<string, string[]>, lineStatsPerCommit: Map<string, {
|
|
21
|
+
additions: number;
|
|
22
|
+
deletions: number;
|
|
23
|
+
}>, config?: Partial<InnerLoopConfig>): InnerLoopAnalysis;
|
|
24
|
+
/**
|
|
25
|
+
* Quick check for inner loop issues (fast, no diff analysis).
|
|
26
|
+
*/
|
|
27
|
+
export declare function quickInnerLoopCheck(events: TimelineEvent[], filesPerCommit: Map<string, string[]>, lineStatsPerCommit: Map<string, {
|
|
28
|
+
additions: number;
|
|
29
|
+
deletions: number;
|
|
30
|
+
}>): {
|
|
31
|
+
hasIssues: boolean;
|
|
32
|
+
issueCount: number;
|
|
33
|
+
topIssue: string | null;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Format inner loop analysis for terminal output.
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatInnerLoopAnalysis(analysis: InnerLoopAnalysis): string;
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inner-loop/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,iBAAiB,EACjB,eAAe,EAOhB,MAAM,YAAY,CAAC;AAOpB,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEvF;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EAAE,EACvB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACrC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,EACzE,MAAM,GAAE,OAAO,CAAC,eAAe,CAAM,GACpC,iBAAiB,CAqDnB;AA2FD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,aAAa,EAAE,EACvB,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACrC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACxE;IACD,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAcA;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAgD3E"}
|