@mesadev/agentblame 0.2.2 → 0.2.3

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/dist/lib/db.js DELETED
@@ -1,291 +0,0 @@
1
- "use strict";
2
- /**
3
- * Pending Edits Store
4
- *
5
- * Reads AI edit logs from ~/.agentblame/logs/ (JSON lines format)
6
- * Supports line-level matching for precise attribution.
7
- */
8
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
- if (k2 === undefined) k2 = k;
10
- var desc = Object.getOwnPropertyDescriptor(m, k);
11
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
- desc = { enumerable: true, get: function() { return m[k]; } };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- }) : (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- }));
19
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
- Object.defineProperty(o, "default", { enumerable: true, value: v });
21
- }) : function(o, v) {
22
- o["default"] = v;
23
- });
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.computeNormalizedHash = exports.computeContentHash = void 0;
43
- exports.readPendingEdits = readPendingEdits;
44
- exports.buildLineHashIndex = buildLineHashIndex;
45
- exports.findLineMatch = findLineMatch;
46
- exports.markEditsAsMatched = markEditsAsMatched;
47
- exports.cleanupOldEntries = cleanupOldEntries;
48
- const fs = __importStar(require("node:fs"));
49
- const path = __importStar(require("node:path"));
50
- const util_1 = require("./util");
51
- Object.defineProperty(exports, "computeContentHash", { enumerable: true, get: function () { return util_1.computeContentHash; } });
52
- Object.defineProperty(exports, "computeNormalizedHash", { enumerable: true, get: function () { return util_1.computeNormalizedHash; } });
53
- // =============================================================================
54
- // Reading Pending Edits
55
- // =============================================================================
56
- /**
57
- * Read all pending edits from log files
58
- * @param includeMatched - If true, also include already-matched edits (for re-matching across branches)
59
- */
60
- function readPendingEdits(includeMatched = false) {
61
- const logsDir = (0, util_1.getLogsDir)();
62
- const edits = [];
63
- if (!fs.existsSync(logsDir)) {
64
- return edits;
65
- }
66
- const logFiles = ["cursor-generated.log", "claude-generated.log"];
67
- for (const file of logFiles) {
68
- const logPath = path.join(logsDir, file);
69
- if (!fs.existsSync(logPath)) {
70
- continue;
71
- }
72
- const content = fs.readFileSync(logPath, "utf-8");
73
- const lines = content.split("\n").filter((line) => line.trim());
74
- for (let i = 0; i < lines.length; i++) {
75
- try {
76
- const entry = JSON.parse(lines[i]);
77
- // Skip already matched entries unless includeMatched is true
78
- if (entry.status === "matched" && !includeMatched) {
79
- continue;
80
- }
81
- // Validate required fields
82
- if (!entry.content || !entry.file_path || !entry.content_hash) {
83
- continue;
84
- }
85
- edits.push({
86
- ...entry,
87
- source_log: file,
88
- line_number: i,
89
- });
90
- }
91
- catch {
92
- // Skip malformed lines
93
- }
94
- }
95
- }
96
- return edits;
97
- }
98
- // =============================================================================
99
- // Line-Level Matching
100
- // =============================================================================
101
- /**
102
- * Build a hash index from pending edits for fast line lookup
103
- */
104
- function buildLineHashIndex(edits) {
105
- const exactHash = new Map();
106
- const normalizedHash = new Map();
107
- for (const edit of edits) {
108
- if (!edit.lines)
109
- continue;
110
- for (const line of edit.lines) {
111
- // Exact hash index
112
- if (!exactHash.has(line.hash)) {
113
- exactHash.set(line.hash, []);
114
- }
115
- exactHash.get(line.hash).push({ edit, line });
116
- // Normalized hash index
117
- if (!normalizedHash.has(line.hash_normalized)) {
118
- normalizedHash.set(line.hash_normalized, []);
119
- }
120
- normalizedHash.get(line.hash_normalized).push({ edit, line });
121
- }
122
- }
123
- return { exactHash, normalizedHash };
124
- }
125
- /**
126
- * Find a line match using the priority strategy:
127
- * 1. Exact hash match (1.0)
128
- * 2. Normalized hash match (0.95)
129
- * 3. Line contained in AI content (0.9)
130
- * 4. AI content contained in line (0.85)
131
- */
132
- function findLineMatch(lineContent, lineHash, lineHashNormalized, filePath, hashIndex, edits) {
133
- // Strategy 1: Exact hash match
134
- const exactMatches = hashIndex.exactHash.get(lineHash);
135
- if (exactMatches && exactMatches.length > 0) {
136
- // Prefer matches from same file
137
- const sameFileMatch = exactMatches.find((m) => pathsMatch(m.edit.file_path, filePath));
138
- const match = sameFileMatch || exactMatches[exactMatches.length - 1];
139
- return {
140
- edit: match.edit,
141
- line: match.line,
142
- matchType: "exact_hash",
143
- confidence: 1.0,
144
- };
145
- }
146
- // Strategy 2: Normalized hash match
147
- const normalizedMatches = hashIndex.normalizedHash.get(lineHashNormalized);
148
- if (normalizedMatches && normalizedMatches.length > 0) {
149
- const sameFileMatch = normalizedMatches.find((m) => pathsMatch(m.edit.file_path, filePath));
150
- const match = sameFileMatch || normalizedMatches[normalizedMatches.length - 1];
151
- return {
152
- edit: match.edit,
153
- line: match.line,
154
- matchType: "normalized_hash",
155
- confidence: 0.95,
156
- };
157
- }
158
- // Strategy 3: Line contained in AI edit content
159
- const normalizedLine = lineContent.trim();
160
- if (normalizedLine.length > 10) {
161
- // Only check for non-trivial lines
162
- for (const edit of edits) {
163
- if (!pathsMatch(edit.file_path, filePath))
164
- continue;
165
- if (edit.content.includes(normalizedLine)) {
166
- return {
167
- edit,
168
- line: { content: normalizedLine, hash: lineHash, hash_normalized: lineHashNormalized },
169
- matchType: "line_in_ai_content",
170
- confidence: 0.9,
171
- };
172
- }
173
- }
174
- }
175
- // Strategy 4: AI content contained in line (AI wrote part of line)
176
- for (const edit of edits) {
177
- if (!pathsMatch(edit.file_path, filePath))
178
- continue;
179
- for (const aiLine of edit.lines || []) {
180
- const trimmedAiLine = aiLine.content.trim();
181
- if (trimmedAiLine.length > 10 && normalizedLine.includes(trimmedAiLine)) {
182
- // Check if AI content is >50% of line
183
- const ratio = trimmedAiLine.length / normalizedLine.length;
184
- if (ratio > 0.5) {
185
- return {
186
- edit,
187
- line: aiLine,
188
- matchType: "ai_content_in_line",
189
- confidence: 0.85,
190
- };
191
- }
192
- }
193
- }
194
- }
195
- return null;
196
- }
197
- /**
198
- * Check if two file paths refer to the same file
199
- */
200
- function pathsMatch(path1, path2) {
201
- const name1 = path1.split("/").pop();
202
- const name2 = path2.split("/").pop();
203
- return (name1 === name2 || path1.endsWith(path2) || path2.endsWith(name1 || ""));
204
- }
205
- // =============================================================================
206
- // Marking Edits as Matched
207
- // =============================================================================
208
- /**
209
- * Mark entries as matched in the log file
210
- */
211
- function markEditsAsMatched(sourceLog, lineNumbers, commitSha) {
212
- const logsDir = (0, util_1.getLogsDir)();
213
- const logPath = path.join(logsDir, sourceLog);
214
- if (!fs.existsSync(logPath)) {
215
- return;
216
- }
217
- const content = fs.readFileSync(logPath, "utf-8");
218
- const lines = content.split("\n");
219
- const lineSet = new Set(lineNumbers);
220
- const timestamp = new Date().toISOString();
221
- const updatedLines = lines.map((line, i) => {
222
- if (!line.trim() || !lineSet.has(i)) {
223
- return line;
224
- }
225
- try {
226
- const entry = JSON.parse(line);
227
- entry.status = "matched";
228
- entry.matched_commit = commitSha;
229
- entry.matched_at = timestamp;
230
- return JSON.stringify(entry);
231
- }
232
- catch {
233
- return line;
234
- }
235
- });
236
- fs.writeFileSync(logPath, updatedLines.join("\n"));
237
- }
238
- // =============================================================================
239
- // Cleanup
240
- // =============================================================================
241
- /**
242
- * Clean up old log entries
243
- * - Removes matched entries older than maxAgeDays
244
- * - Removes unmatched entries older than expireDays
245
- */
246
- function cleanupOldEntries(maxAgeDays = 7, expireDays = 30) {
247
- const logsDir = (0, util_1.getLogsDir)();
248
- if (!fs.existsSync(logsDir)) {
249
- return { removed: 0, kept: 0 };
250
- }
251
- const logFiles = ["cursor-generated.log", "claude-generated.log"];
252
- const now = Date.now();
253
- const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
254
- const expireMs = expireDays * 24 * 60 * 60 * 1000;
255
- let removed = 0;
256
- let kept = 0;
257
- for (const file of logFiles) {
258
- const logPath = path.join(logsDir, file);
259
- if (!fs.existsSync(logPath))
260
- continue;
261
- const content = fs.readFileSync(logPath, "utf-8");
262
- const lines = content.split("\n");
263
- const keptLines = [];
264
- for (const line of lines) {
265
- if (!line.trim())
266
- continue;
267
- try {
268
- const entry = JSON.parse(line);
269
- const timestamp = new Date(entry.timestamp).getTime();
270
- const age = now - timestamp;
271
- if (entry.status === "matched" && age > maxAgeMs) {
272
- removed++;
273
- }
274
- else if (!entry.status && age > expireMs) {
275
- removed++;
276
- }
277
- else {
278
- keptLines.push(line);
279
- kept++;
280
- }
281
- }
282
- catch {
283
- keptLines.push(line);
284
- kept++;
285
- }
286
- }
287
- fs.writeFileSync(logPath, keptLines.join("\n") + (keptLines.length ? "\n" : ""));
288
- }
289
- return { removed, kept };
290
- }
291
- //# sourceMappingURL=db.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}