@mesadev/agentblame 0.2.10 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentblame.js +3500 -0
- package/dist/blame.d.ts +4 -1
- package/dist/blame.js +280 -78
- package/dist/blame.js.map +1 -1
- package/dist/capture.d.ts +4 -7
- package/dist/capture.js +465 -467
- package/dist/capture.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +334 -72
- package/dist/index.js.map +1 -1
- package/dist/lib/analytics.d.ts +179 -0
- package/dist/lib/analytics.js +833 -0
- package/dist/lib/analytics.js.map +1 -0
- package/dist/lib/attribution.d.ts +54 -0
- package/dist/lib/attribution.js +266 -0
- package/dist/lib/attribution.js.map +1 -0
- package/dist/lib/checkpoint.d.ts +97 -0
- package/dist/lib/checkpoint.js +441 -0
- package/dist/lib/checkpoint.js.map +1 -0
- package/dist/lib/config.d.ts +46 -0
- package/dist/lib/config.js +123 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/database.d.ts +115 -85
- package/dist/lib/database.js +306 -323
- package/dist/lib/database.js.map +1 -1
- package/dist/lib/delta.d.ts +78 -0
- package/dist/lib/delta.js +309 -0
- package/dist/lib/delta.js.map +1 -0
- package/dist/lib/git/gitBlame.js +9 -4
- package/dist/lib/git/gitBlame.js.map +1 -1
- package/dist/lib/git/gitConfig.d.ts +5 -3
- package/dist/lib/git/gitConfig.js +41 -6
- package/dist/lib/git/gitConfig.js.map +1 -1
- package/dist/lib/git/gitDiff.d.ts +13 -1
- package/dist/lib/git/gitDiff.js +39 -7
- package/dist/lib/git/gitDiff.js.map +1 -1
- package/dist/lib/git/gitNotes.d.ts +30 -4
- package/dist/lib/git/gitNotes.js +140 -24
- package/dist/lib/git/gitNotes.js.map +1 -1
- package/dist/lib/hooks.d.ts +1 -0
- package/dist/lib/hooks.js +148 -27
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/index.d.ts +7 -0
- package/dist/lib/index.js +13 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/storage.d.ts +163 -0
- package/dist/lib/storage.js +823 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/trace.d.ts +118 -0
- package/dist/lib/trace.js +499 -0
- package/dist/lib/trace.js.map +1 -0
- package/dist/lib/types.d.ts +322 -114
- package/dist/lib/types.js +2 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/util.d.ts +8 -8
- package/dist/lib/util.js +18 -22
- package/dist/lib/util.js.map +1 -1
- package/dist/lib/watcher.d.ts +104 -0
- package/dist/lib/watcher.js +398 -0
- package/dist/lib/watcher.js.map +1 -0
- package/dist/post-merge.js +460 -421
- package/dist/post-merge.js.map +1 -1
- package/dist/process.d.ts +6 -5
- package/dist/process.js +182 -158
- package/dist/process.js.map +1 -1
- package/dist/sync.js +172 -131
- package/dist/sync.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Watcher Module v3
|
|
3
|
+
*
|
|
4
|
+
* @deprecated This module is deprecated. Use checkpoint.ts instead.
|
|
5
|
+
*
|
|
6
|
+
* The file watcher approach is not bulletproof because:
|
|
7
|
+
* 1. File watchers can miss rapid changes
|
|
8
|
+
* 2. Race conditions between AI edits and human edits
|
|
9
|
+
* 3. Platform-specific behavior differences
|
|
10
|
+
*
|
|
11
|
+
* The checkpoint-based approach (checkpoint.ts) is bulletproof because:
|
|
12
|
+
* 1. beforeSubmitPrompt/PreToolUse captures state BEFORE AI acts
|
|
13
|
+
* 2. afterFileEdit/PostToolUse captures state AFTER AI acts
|
|
14
|
+
* 3. No race conditions - deterministic capture at hook boundaries
|
|
15
|
+
*
|
|
16
|
+
* This module is kept for backward compatibility but should not be used.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FileWatcher {
|
|
19
|
+
private watcher;
|
|
20
|
+
private repoRoot;
|
|
21
|
+
private aiEditInProgress;
|
|
22
|
+
private debounceTimers;
|
|
23
|
+
private debounceMs;
|
|
24
|
+
private lastCapturedBlobs;
|
|
25
|
+
constructor(repoRoot: string, options?: {
|
|
26
|
+
debounceMs?: number;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Start watching the repository for file changes
|
|
30
|
+
*/
|
|
31
|
+
start(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Stop watching
|
|
34
|
+
*/
|
|
35
|
+
stop(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Mark a file as being edited by AI (called by capture hook)
|
|
38
|
+
*/
|
|
39
|
+
markAIEditStart(filePath: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Mark AI edit as complete
|
|
42
|
+
*/
|
|
43
|
+
markAIEditEnd(filePath: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Check if an AI edit is in progress for a file
|
|
46
|
+
*/
|
|
47
|
+
isAIEditInProgress(filePath: string): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Handle a file change event
|
|
50
|
+
*/
|
|
51
|
+
private handleFileChange;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a path should be ignored
|
|
54
|
+
*/
|
|
55
|
+
private shouldIgnore;
|
|
56
|
+
/**
|
|
57
|
+
* Debounce a function call for a specific key
|
|
58
|
+
*/
|
|
59
|
+
private debounce;
|
|
60
|
+
/**
|
|
61
|
+
* Normalize path for comparison
|
|
62
|
+
*/
|
|
63
|
+
private normalizePath;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start the global file watcher for a repository
|
|
67
|
+
*/
|
|
68
|
+
export declare function startWatcher(repoRoot: string): FileWatcher;
|
|
69
|
+
/**
|
|
70
|
+
* Stop the global file watcher
|
|
71
|
+
*/
|
|
72
|
+
export declare function stopWatcher(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get the global file watcher
|
|
75
|
+
*/
|
|
76
|
+
export declare function getWatcher(): FileWatcher | null;
|
|
77
|
+
/**
|
|
78
|
+
* Mark AI edit start (for coordination with capture hook)
|
|
79
|
+
*/
|
|
80
|
+
export declare function markAIEditStart(filePath: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Mark AI edit end
|
|
83
|
+
*/
|
|
84
|
+
export declare function markAIEditEnd(filePath: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* Save watcher state to disk (for daemon mode)
|
|
87
|
+
*/
|
|
88
|
+
export declare function saveWatcherState(repoRoot: string): void;
|
|
89
|
+
/**
|
|
90
|
+
* Load watcher state from disk
|
|
91
|
+
*/
|
|
92
|
+
export declare function loadWatcherState(repoRoot: string): {
|
|
93
|
+
running: boolean;
|
|
94
|
+
pid: number;
|
|
95
|
+
startedAt: string;
|
|
96
|
+
} | null;
|
|
97
|
+
/**
|
|
98
|
+
* Clear watcher state
|
|
99
|
+
*/
|
|
100
|
+
export declare function clearWatcherState(repoRoot: string): void;
|
|
101
|
+
/**
|
|
102
|
+
* Check if another watcher process is running
|
|
103
|
+
*/
|
|
104
|
+
export declare function isWatcherRunning(repoRoot: string): boolean;
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* File Watcher Module v3
|
|
4
|
+
*
|
|
5
|
+
* @deprecated This module is deprecated. Use checkpoint.ts instead.
|
|
6
|
+
*
|
|
7
|
+
* The file watcher approach is not bulletproof because:
|
|
8
|
+
* 1. File watchers can miss rapid changes
|
|
9
|
+
* 2. Race conditions between AI edits and human edits
|
|
10
|
+
* 3. Platform-specific behavior differences
|
|
11
|
+
*
|
|
12
|
+
* The checkpoint-based approach (checkpoint.ts) is bulletproof because:
|
|
13
|
+
* 1. beforeSubmitPrompt/PreToolUse captures state BEFORE AI acts
|
|
14
|
+
* 2. afterFileEdit/PostToolUse captures state AFTER AI acts
|
|
15
|
+
* 3. No race conditions - deterministic capture at hook boundaries
|
|
16
|
+
*
|
|
17
|
+
* This module is kept for backward compatibility but should not be used.
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
36
|
+
var ownKeys = function(o) {
|
|
37
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
48
|
+
__setModuleDefault(result, mod);
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.FileWatcher = void 0;
|
|
54
|
+
exports.startWatcher = startWatcher;
|
|
55
|
+
exports.stopWatcher = stopWatcher;
|
|
56
|
+
exports.getWatcher = getWatcher;
|
|
57
|
+
exports.markAIEditStart = markAIEditStart;
|
|
58
|
+
exports.markAIEditEnd = markAIEditEnd;
|
|
59
|
+
exports.saveWatcherState = saveWatcherState;
|
|
60
|
+
exports.loadWatcherState = loadWatcherState;
|
|
61
|
+
exports.clearWatcherState = clearWatcherState;
|
|
62
|
+
exports.isWatcherRunning = isWatcherRunning;
|
|
63
|
+
const node_fs_1 = require("node:fs");
|
|
64
|
+
const fs = __importStar(require("node:fs"));
|
|
65
|
+
const path = __importStar(require("node:path"));
|
|
66
|
+
const storage_1 = require("./storage");
|
|
67
|
+
// =============================================================================
|
|
68
|
+
// File Watcher Class
|
|
69
|
+
// =============================================================================
|
|
70
|
+
class FileWatcher {
|
|
71
|
+
watcher = null;
|
|
72
|
+
repoRoot;
|
|
73
|
+
aiEditInProgress = new Set();
|
|
74
|
+
debounceTimers = new Map();
|
|
75
|
+
debounceMs;
|
|
76
|
+
lastCapturedBlobs = new Map(); // Avoid duplicate captures
|
|
77
|
+
constructor(repoRoot, options) {
|
|
78
|
+
this.repoRoot = repoRoot;
|
|
79
|
+
this.debounceMs = options?.debounceMs ?? 500;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Start watching the repository for file changes
|
|
83
|
+
*/
|
|
84
|
+
start() {
|
|
85
|
+
if (this.watcher) {
|
|
86
|
+
return; // Already watching
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
this.watcher = (0, node_fs_1.watch)(this.repoRoot, { recursive: true }, (event, filename) => {
|
|
90
|
+
if (!filename)
|
|
91
|
+
return;
|
|
92
|
+
if (this.shouldIgnore(filename))
|
|
93
|
+
return;
|
|
94
|
+
// Debounce rapid changes
|
|
95
|
+
this.debounce(filename, async () => {
|
|
96
|
+
await this.handleFileChange(filename);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
this.watcher.on("error", (err) => {
|
|
100
|
+
console.error("[agentblame] Watcher error:", err.message);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error("[agentblame] Failed to start watcher:", err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Stop watching
|
|
109
|
+
*/
|
|
110
|
+
stop() {
|
|
111
|
+
if (this.watcher) {
|
|
112
|
+
this.watcher.close();
|
|
113
|
+
this.watcher = null;
|
|
114
|
+
}
|
|
115
|
+
// Clear all pending debounce timers
|
|
116
|
+
for (const timer of this.debounceTimers.values()) {
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
}
|
|
119
|
+
this.debounceTimers.clear();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Mark a file as being edited by AI (called by capture hook)
|
|
123
|
+
*/
|
|
124
|
+
markAIEditStart(filePath) {
|
|
125
|
+
const normalized = this.normalizePath(filePath);
|
|
126
|
+
this.aiEditInProgress.add(normalized);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Mark AI edit as complete
|
|
130
|
+
*/
|
|
131
|
+
markAIEditEnd(filePath) {
|
|
132
|
+
const normalized = this.normalizePath(filePath);
|
|
133
|
+
this.aiEditInProgress.delete(normalized);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Check if an AI edit is in progress for a file
|
|
137
|
+
*/
|
|
138
|
+
isAIEditInProgress(filePath) {
|
|
139
|
+
const normalized = this.normalizePath(filePath);
|
|
140
|
+
return this.aiEditInProgress.has(normalized);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Handle a file change event
|
|
144
|
+
*/
|
|
145
|
+
async handleFileChange(relativePath) {
|
|
146
|
+
const absolutePath = path.join(this.repoRoot, relativePath);
|
|
147
|
+
const normalized = this.normalizePath(relativePath);
|
|
148
|
+
// Skip if AI edit in progress (already captured by hook)
|
|
149
|
+
if (this.aiEditInProgress.has(normalized)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Skip if file doesn't exist (was deleted)
|
|
153
|
+
if (!fs.existsSync(absolutePath)) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Skip directories
|
|
157
|
+
try {
|
|
158
|
+
const stat = fs.statSync(absolutePath);
|
|
159
|
+
if (stat.isDirectory())
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Read file content
|
|
166
|
+
const content = (0, storage_1.readFileContent)(absolutePath);
|
|
167
|
+
if (content === null)
|
|
168
|
+
return;
|
|
169
|
+
// Get current HEAD
|
|
170
|
+
const baseSha = await (0, storage_1.getGitHead)(this.repoRoot);
|
|
171
|
+
if (!baseSha)
|
|
172
|
+
return;
|
|
173
|
+
// Capture as human edit
|
|
174
|
+
try {
|
|
175
|
+
const blobSha = await (0, storage_1.captureFileSnapshot)(this.repoRoot, baseSha, relativePath, content, null, // No session (human edit)
|
|
176
|
+
"human_edit");
|
|
177
|
+
// Track to avoid duplicate captures
|
|
178
|
+
this.lastCapturedBlobs.set(normalized, blobSha);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
// Silent failure - don't interrupt user workflow
|
|
182
|
+
if (process.env.AGENTBLAME_DEBUG) {
|
|
183
|
+
console.error("[agentblame] Failed to capture human edit:", err);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if a path should be ignored
|
|
189
|
+
*/
|
|
190
|
+
shouldIgnore(relativePath) {
|
|
191
|
+
// Ignore git directory
|
|
192
|
+
if (relativePath.startsWith(".git"))
|
|
193
|
+
return true;
|
|
194
|
+
if (relativePath.includes("/.git/"))
|
|
195
|
+
return true;
|
|
196
|
+
// Ignore node_modules
|
|
197
|
+
if (relativePath.includes("node_modules"))
|
|
198
|
+
return true;
|
|
199
|
+
// Ignore common build outputs
|
|
200
|
+
if (relativePath.includes("/dist/"))
|
|
201
|
+
return true;
|
|
202
|
+
if (relativePath.includes("/build/"))
|
|
203
|
+
return true;
|
|
204
|
+
if (relativePath.includes("/.next/"))
|
|
205
|
+
return true;
|
|
206
|
+
// Ignore agentblame's own files
|
|
207
|
+
if (relativePath.includes(".agentblame"))
|
|
208
|
+
return true;
|
|
209
|
+
// Ignore common generated files
|
|
210
|
+
if (relativePath.endsWith(".lock"))
|
|
211
|
+
return true;
|
|
212
|
+
if (relativePath.endsWith("-lock.json"))
|
|
213
|
+
return true;
|
|
214
|
+
if (relativePath.endsWith(".log"))
|
|
215
|
+
return true;
|
|
216
|
+
// Ignore binary files by extension
|
|
217
|
+
const binaryExtensions = [
|
|
218
|
+
".png",
|
|
219
|
+
".jpg",
|
|
220
|
+
".jpeg",
|
|
221
|
+
".gif",
|
|
222
|
+
".ico",
|
|
223
|
+
".webp",
|
|
224
|
+
".mp3",
|
|
225
|
+
".mp4",
|
|
226
|
+
".wav",
|
|
227
|
+
".avi",
|
|
228
|
+
".mov",
|
|
229
|
+
".pdf",
|
|
230
|
+
".zip",
|
|
231
|
+
".tar",
|
|
232
|
+
".gz",
|
|
233
|
+
".rar",
|
|
234
|
+
".7z",
|
|
235
|
+
".exe",
|
|
236
|
+
".dll",
|
|
237
|
+
".so",
|
|
238
|
+
".dylib",
|
|
239
|
+
".wasm",
|
|
240
|
+
".ttf",
|
|
241
|
+
".woff",
|
|
242
|
+
".woff2",
|
|
243
|
+
".eot",
|
|
244
|
+
];
|
|
245
|
+
const ext = path.extname(relativePath).toLowerCase();
|
|
246
|
+
if (binaryExtensions.includes(ext))
|
|
247
|
+
return true;
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Debounce a function call for a specific key
|
|
252
|
+
*/
|
|
253
|
+
debounce(key, fn) {
|
|
254
|
+
const existing = this.debounceTimers.get(key);
|
|
255
|
+
if (existing) {
|
|
256
|
+
clearTimeout(existing);
|
|
257
|
+
}
|
|
258
|
+
const timer = setTimeout(async () => {
|
|
259
|
+
this.debounceTimers.delete(key);
|
|
260
|
+
try {
|
|
261
|
+
await fn();
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
if (process.env.AGENTBLAME_DEBUG) {
|
|
265
|
+
console.error("[agentblame] Debounced function error:", err);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}, this.debounceMs);
|
|
269
|
+
this.debounceTimers.set(key, timer);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Normalize path for comparison
|
|
273
|
+
*/
|
|
274
|
+
normalizePath(filePath) {
|
|
275
|
+
// Remove leading ./ or /
|
|
276
|
+
return filePath.replace(/^\.?\//, "").replace(/\\/g, "/");
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
exports.FileWatcher = FileWatcher;
|
|
280
|
+
// =============================================================================
|
|
281
|
+
// Global Watcher Instance
|
|
282
|
+
// =============================================================================
|
|
283
|
+
let globalWatcher = null;
|
|
284
|
+
/**
|
|
285
|
+
* Start the global file watcher for a repository
|
|
286
|
+
*/
|
|
287
|
+
function startWatcher(repoRoot) {
|
|
288
|
+
if (globalWatcher) {
|
|
289
|
+
globalWatcher.stop();
|
|
290
|
+
}
|
|
291
|
+
globalWatcher = new FileWatcher(repoRoot);
|
|
292
|
+
globalWatcher.start();
|
|
293
|
+
return globalWatcher;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Stop the global file watcher
|
|
297
|
+
*/
|
|
298
|
+
function stopWatcher() {
|
|
299
|
+
if (globalWatcher) {
|
|
300
|
+
globalWatcher.stop();
|
|
301
|
+
globalWatcher = null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Get the global file watcher
|
|
306
|
+
*/
|
|
307
|
+
function getWatcher() {
|
|
308
|
+
return globalWatcher;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Mark AI edit start (for coordination with capture hook)
|
|
312
|
+
*/
|
|
313
|
+
function markAIEditStart(filePath) {
|
|
314
|
+
if (globalWatcher) {
|
|
315
|
+
globalWatcher.markAIEditStart(filePath);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Mark AI edit end
|
|
320
|
+
*/
|
|
321
|
+
function markAIEditEnd(filePath) {
|
|
322
|
+
if (globalWatcher) {
|
|
323
|
+
globalWatcher.markAIEditEnd(filePath);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// =============================================================================
|
|
327
|
+
// Watcher State Persistence
|
|
328
|
+
// =============================================================================
|
|
329
|
+
/**
|
|
330
|
+
* Save watcher state to disk (for daemon mode)
|
|
331
|
+
*/
|
|
332
|
+
function saveWatcherState(repoRoot) {
|
|
333
|
+
const stateFile = path.join((0, storage_1.getAgentBlameGitDir)(repoRoot), "watcher.json");
|
|
334
|
+
const state = {
|
|
335
|
+
running: globalWatcher !== null,
|
|
336
|
+
pid: process.pid,
|
|
337
|
+
startedAt: new Date().toISOString(),
|
|
338
|
+
};
|
|
339
|
+
try {
|
|
340
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), "utf8");
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
// Silent failure
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Load watcher state from disk
|
|
348
|
+
*/
|
|
349
|
+
function loadWatcherState(repoRoot) {
|
|
350
|
+
const stateFile = path.join((0, storage_1.getAgentBlameGitDir)(repoRoot), "watcher.json");
|
|
351
|
+
try {
|
|
352
|
+
if (fs.existsSync(stateFile)) {
|
|
353
|
+
const content = fs.readFileSync(stateFile, "utf8");
|
|
354
|
+
return JSON.parse(content);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// Silent failure
|
|
359
|
+
}
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Clear watcher state
|
|
364
|
+
*/
|
|
365
|
+
function clearWatcherState(repoRoot) {
|
|
366
|
+
const stateFile = path.join((0, storage_1.getAgentBlameGitDir)(repoRoot), "watcher.json");
|
|
367
|
+
try {
|
|
368
|
+
if (fs.existsSync(stateFile)) {
|
|
369
|
+
fs.unlinkSync(stateFile);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// Silent failure
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// =============================================================================
|
|
377
|
+
// Check if watcher should be running
|
|
378
|
+
// =============================================================================
|
|
379
|
+
/**
|
|
380
|
+
* Check if another watcher process is running
|
|
381
|
+
*/
|
|
382
|
+
function isWatcherRunning(repoRoot) {
|
|
383
|
+
const state = loadWatcherState(repoRoot);
|
|
384
|
+
if (!state || !state.running) {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
// Check if the process is still alive
|
|
388
|
+
try {
|
|
389
|
+
process.kill(state.pid, 0); // Signal 0 checks if process exists
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Process doesn't exist
|
|
394
|
+
clearWatcherState(repoRoot);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/lib/watcher.ts"],"names":[],"mappings":"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"}
|