@mesadev/agentblame 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/dist/blame.d.ts +14 -0
- package/dist/blame.js +252 -0
- package/dist/blame.js.map +1 -0
- package/dist/capture.d.ts +16 -0
- package/dist/capture.js +284 -0
- package/dist/capture.js.map +1 -0
- package/dist/cleanup.d.ts +10 -0
- package/dist/cleanup.js +136 -0
- package/dist/cleanup.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +240 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/db.d.ts +53 -0
- package/dist/lib/db.js +290 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/diff.d.ts +13 -0
- package/dist/lib/diff.js +32 -0
- package/dist/lib/diff.js.map +1 -0
- package/dist/lib/git/gitBlame.d.ts +25 -0
- package/dist/lib/git/gitBlame.js +87 -0
- package/dist/lib/git/gitBlame.js.map +1 -0
- package/dist/lib/git/gitCli.d.ts +17 -0
- package/dist/lib/git/gitCli.js +57 -0
- package/dist/lib/git/gitCli.js.map +1 -0
- package/dist/lib/git/gitConfig.d.ts +20 -0
- package/dist/lib/git/gitConfig.js +91 -0
- package/dist/lib/git/gitConfig.js.map +1 -0
- package/dist/lib/git/gitDiff.d.ts +42 -0
- package/dist/lib/git/gitDiff.js +346 -0
- package/dist/lib/git/gitDiff.js.map +1 -0
- package/dist/lib/git/gitNotes.d.ts +31 -0
- package/dist/lib/git/gitNotes.js +93 -0
- package/dist/lib/git/gitNotes.js.map +1 -0
- package/dist/lib/git/index.d.ts +5 -0
- package/dist/lib/git/index.js +22 -0
- package/dist/lib/git/index.js.map +1 -0
- package/dist/lib/hooks.d.ts +65 -0
- package/dist/lib/hooks.js +423 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/index.d.ts +10 -0
- package/dist/lib/index.js +33 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/types.d.ts +190 -0
- package/dist/lib/types.js +8 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/util.d.ts +24 -0
- package/dist/lib/util.js +82 -0
- package/dist/lib/util.js.map +1 -0
- package/dist/process.d.ts +14 -0
- package/dist/process.js +224 -0
- package/dist/process.js.map +1 -0
- package/dist/sync.d.ts +15 -0
- package/dist/sync.js +413 -0
- package/dist/sync.js.map +1 -0
- package/dist/transfer-notes.d.ts +16 -0
- package/dist/transfer-notes.js +426 -0
- package/dist/transfer-notes.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hook Installation
|
|
4
|
+
*
|
|
5
|
+
* Install and manage hooks for Cursor and Claude Code.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.CLAUDE_SETTINGS_FILE = exports.CLAUDE_SETTINGS_DIR = exports.CURSOR_HOOKS_CONFIG = exports.CLAUDE_GENERATED_LOG = exports.CURSOR_GENERATED_LOG = exports.AGENTBLAME_LOGS_DIR = exports.AGENTBLAME_HOOKS_DIR = exports.AGENTBLAME_ROOT = void 0;
|
|
42
|
+
exports.ensureAgentBlameDirectories = ensureAgentBlameDirectories;
|
|
43
|
+
exports.installCursorHooks = installCursorHooks;
|
|
44
|
+
exports.installClaudeHooks = installClaudeHooks;
|
|
45
|
+
exports.areCursorHooksInstalled = areCursorHooksInstalled;
|
|
46
|
+
exports.areClaudeHooksInstalled = areClaudeHooksInstalled;
|
|
47
|
+
exports.installAllHooks = installAllHooks;
|
|
48
|
+
exports.installGlobalGitHook = installGlobalGitHook;
|
|
49
|
+
exports.uninstallGlobalGitHook = uninstallGlobalGitHook;
|
|
50
|
+
exports.installGitHook = installGitHook;
|
|
51
|
+
exports.uninstallGitHook = uninstallGitHook;
|
|
52
|
+
exports.uninstallCursorHooks = uninstallCursorHooks;
|
|
53
|
+
exports.uninstallClaudeHooks = uninstallClaudeHooks;
|
|
54
|
+
const fs = __importStar(require("node:fs"));
|
|
55
|
+
const path = __importStar(require("node:path"));
|
|
56
|
+
const os = __importStar(require("node:os"));
|
|
57
|
+
exports.AGENTBLAME_ROOT = path.join(os.homedir(), ".agentblame");
|
|
58
|
+
exports.AGENTBLAME_HOOKS_DIR = path.join(exports.AGENTBLAME_ROOT, "hooks");
|
|
59
|
+
exports.AGENTBLAME_LOGS_DIR = path.join(exports.AGENTBLAME_ROOT, "logs");
|
|
60
|
+
// Log files
|
|
61
|
+
exports.CURSOR_GENERATED_LOG = path.join(exports.AGENTBLAME_LOGS_DIR, "cursor-generated.log");
|
|
62
|
+
exports.CLAUDE_GENERATED_LOG = path.join(exports.AGENTBLAME_LOGS_DIR, "claude-generated.log");
|
|
63
|
+
// Cursor hooks.json location
|
|
64
|
+
exports.CURSOR_HOOKS_CONFIG = path.join(os.homedir(), ".cursor", "hooks.json");
|
|
65
|
+
// Claude Code settings.json location
|
|
66
|
+
exports.CLAUDE_SETTINGS_DIR = path.join(os.homedir(), ".claude");
|
|
67
|
+
exports.CLAUDE_SETTINGS_FILE = path.join(exports.CLAUDE_SETTINGS_DIR, "settings.json");
|
|
68
|
+
/**
|
|
69
|
+
* Ensure the ~/.agentblame/ directory structure exists.
|
|
70
|
+
*/
|
|
71
|
+
async function ensureAgentBlameDirectories() {
|
|
72
|
+
await fs.promises.mkdir(exports.AGENTBLAME_HOOKS_DIR, { recursive: true });
|
|
73
|
+
await fs.promises.mkdir(exports.AGENTBLAME_LOGS_DIR, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create an empty file if it doesn't exist.
|
|
77
|
+
*/
|
|
78
|
+
async function touchFile(filePath) {
|
|
79
|
+
try {
|
|
80
|
+
const handle = await fs.promises.open(filePath, "a");
|
|
81
|
+
await handle.close();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Ignore errors
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Find the capture script path.
|
|
89
|
+
* Looks in common locations for the agentblame hooks package.
|
|
90
|
+
*/
|
|
91
|
+
function findCaptureScript() {
|
|
92
|
+
const possiblePaths = [
|
|
93
|
+
// npm global install
|
|
94
|
+
path.join(os.homedir(), ".npm-global", "lib", "node_modules", "agentblame", "packages", "hooks", "src", "capture.ts"),
|
|
95
|
+
// Local development (monorepo)
|
|
96
|
+
path.join(__dirname, "..", "..", "hooks", "src", "capture.ts"),
|
|
97
|
+
// Installed as dependency
|
|
98
|
+
path.join(__dirname, "..", "node_modules", "@mesadev", "agentblame-hooks", "src", "capture.ts"),
|
|
99
|
+
];
|
|
100
|
+
for (const p of possiblePaths) {
|
|
101
|
+
if (fs.existsSync(p)) {
|
|
102
|
+
return p;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Generate the hook command for a given provider.
|
|
109
|
+
*/
|
|
110
|
+
function getHookCommand(provider, captureScript, event) {
|
|
111
|
+
const eventArg = event ? ` --event ${event}` : "";
|
|
112
|
+
return `bun run "${captureScript}" --provider ${provider}${eventArg}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Install the Cursor hooks and configure ~/.cursor/hooks.json
|
|
116
|
+
*/
|
|
117
|
+
async function installCursorHooks(captureScript) {
|
|
118
|
+
if (process.platform === "win32") {
|
|
119
|
+
console.error("Windows is not supported yet");
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const script = captureScript || findCaptureScript();
|
|
123
|
+
if (!script) {
|
|
124
|
+
console.error("Could not find capture script. Make sure agentblame is installed correctly.");
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
await ensureAgentBlameDirectories();
|
|
129
|
+
await touchFile(exports.CURSOR_GENERATED_LOG);
|
|
130
|
+
// Update ~/.cursor/hooks.json
|
|
131
|
+
await fs.promises.mkdir(path.dirname(exports.CURSOR_HOOKS_CONFIG), {
|
|
132
|
+
recursive: true,
|
|
133
|
+
});
|
|
134
|
+
let config = {};
|
|
135
|
+
try {
|
|
136
|
+
const existing = await fs.promises.readFile(exports.CURSOR_HOOKS_CONFIG, "utf8");
|
|
137
|
+
config = JSON.parse(existing || "{}");
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// File doesn't exist or invalid JSON
|
|
141
|
+
}
|
|
142
|
+
config.version = config.version ?? 1;
|
|
143
|
+
config.hooks = config.hooks ?? {};
|
|
144
|
+
const fileEditCommand = getHookCommand("cursor", script, "afterFileEdit");
|
|
145
|
+
// Configure afterFileEdit
|
|
146
|
+
config.hooks.afterFileEdit = config.hooks.afterFileEdit ?? [];
|
|
147
|
+
if (!Array.isArray(config.hooks.afterFileEdit)) {
|
|
148
|
+
config.hooks.afterFileEdit = [];
|
|
149
|
+
}
|
|
150
|
+
// Remove any existing agentblame hooks first
|
|
151
|
+
config.hooks.afterFileEdit = config.hooks.afterFileEdit.filter((h) => !h?.command?.includes("agentblame") && !h?.command?.includes("capture.ts"));
|
|
152
|
+
config.hooks.afterFileEdit.push({ command: fileEditCommand });
|
|
153
|
+
// Clean up old afterTabFileEdit hooks
|
|
154
|
+
if (config.hooks.afterTabFileEdit) {
|
|
155
|
+
config.hooks.afterTabFileEdit = config.hooks.afterTabFileEdit.filter((h) => !h?.command?.includes("agentblame") && !h?.command?.includes("capture.ts"));
|
|
156
|
+
if (config.hooks.afterTabFileEdit.length === 0) {
|
|
157
|
+
delete config.hooks.afterTabFileEdit;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
await fs.promises.writeFile(exports.CURSOR_HOOKS_CONFIG, JSON.stringify(config, null, 2), "utf8");
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
console.error("Failed to install Cursor hooks:", err);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Install the Claude Code hooks and configure ~/.claude/settings.json
|
|
170
|
+
*/
|
|
171
|
+
async function installClaudeHooks(captureScript) {
|
|
172
|
+
if (process.platform === "win32") {
|
|
173
|
+
console.error("Windows is not supported yet");
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
const script = captureScript || findCaptureScript();
|
|
177
|
+
if (!script) {
|
|
178
|
+
console.error("Could not find capture script. Make sure agentblame is installed correctly.");
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
await ensureAgentBlameDirectories();
|
|
183
|
+
await touchFile(exports.CLAUDE_GENERATED_LOG);
|
|
184
|
+
// Update ~/.claude/settings.json
|
|
185
|
+
await fs.promises.mkdir(exports.CLAUDE_SETTINGS_DIR, { recursive: true });
|
|
186
|
+
let config = {};
|
|
187
|
+
try {
|
|
188
|
+
const existing = await fs.promises.readFile(exports.CLAUDE_SETTINGS_FILE, "utf8");
|
|
189
|
+
config = JSON.parse(existing || "{}");
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// File doesn't exist or invalid JSON
|
|
193
|
+
}
|
|
194
|
+
config.hooks = config.hooks ?? {};
|
|
195
|
+
const hookCommand = getHookCommand("claude", script);
|
|
196
|
+
// Configure PostToolUse hook for Edit/Write/MultiEdit
|
|
197
|
+
config.hooks.PostToolUse = config.hooks.PostToolUse ?? [];
|
|
198
|
+
if (!Array.isArray(config.hooks.PostToolUse)) {
|
|
199
|
+
config.hooks.PostToolUse = [];
|
|
200
|
+
}
|
|
201
|
+
// Remove any existing agentblame hooks first
|
|
202
|
+
config.hooks.PostToolUse = config.hooks.PostToolUse.filter((h) => !h?.hooks?.some((hh) => hh?.command?.includes("agentblame") ||
|
|
203
|
+
hh?.command?.includes("capture.ts")));
|
|
204
|
+
// Add the new hook
|
|
205
|
+
config.hooks.PostToolUse.push({
|
|
206
|
+
matcher: "Edit|Write|MultiEdit",
|
|
207
|
+
hooks: [{ type: "command", command: hookCommand }],
|
|
208
|
+
});
|
|
209
|
+
await fs.promises.writeFile(exports.CLAUDE_SETTINGS_FILE, JSON.stringify(config, null, 2), "utf8");
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
catch (err) {
|
|
213
|
+
console.error("Failed to install Claude hooks:", err);
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Check if Cursor hooks are installed.
|
|
219
|
+
*/
|
|
220
|
+
async function areCursorHooksInstalled() {
|
|
221
|
+
try {
|
|
222
|
+
const config = JSON.parse(await fs.promises.readFile(exports.CURSOR_HOOKS_CONFIG, "utf8"));
|
|
223
|
+
const hasFileEdit = config.hooks?.afterFileEdit?.some((h) => h?.command?.includes("agentblame") || h?.command?.includes("capture.ts"));
|
|
224
|
+
return hasFileEdit === true;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Check if Claude Code hooks are installed.
|
|
232
|
+
*/
|
|
233
|
+
async function areClaudeHooksInstalled() {
|
|
234
|
+
try {
|
|
235
|
+
const config = JSON.parse(await fs.promises.readFile(exports.CLAUDE_SETTINGS_FILE, "utf8"));
|
|
236
|
+
const hasHook = config.hooks?.PostToolUse?.some((h) => h?.hooks?.some((hh) => hh?.command?.includes("agentblame") ||
|
|
237
|
+
hh?.command?.includes("capture.ts")));
|
|
238
|
+
return hasHook === true;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Install all hooks (Cursor and Claude Code)
|
|
246
|
+
*/
|
|
247
|
+
async function installAllHooks(captureScript) {
|
|
248
|
+
const cursor = await installCursorHooks(captureScript);
|
|
249
|
+
const claude = await installClaudeHooks(captureScript);
|
|
250
|
+
return { cursor, claude };
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Install global git hook via core.hooksPath
|
|
254
|
+
* This makes agentblame work for ALL repos without per-repo setup
|
|
255
|
+
*/
|
|
256
|
+
async function installGlobalGitHook() {
|
|
257
|
+
const globalHooksDir = path.join(exports.AGENTBLAME_ROOT, "git-hooks");
|
|
258
|
+
const hookPath = path.join(globalHooksDir, "post-commit");
|
|
259
|
+
// Find the CLI script
|
|
260
|
+
const cliScript = path.resolve(__dirname, "..", "..", "cli", "src", "index.ts");
|
|
261
|
+
// The hook auto-configures push refspec on first run in each repo
|
|
262
|
+
const hookContent = `#!/bin/sh
|
|
263
|
+
# Agent Blame - Auto-process commits for AI attribution
|
|
264
|
+
# Auto-configure notes push if not already set up
|
|
265
|
+
if ! git config --get-all remote.origin.push 2>/dev/null | grep -q "refs/notes/agentblame"; then
|
|
266
|
+
# Add default branch push first if no push refspec exists
|
|
267
|
+
if [ -z "$(git config --get-all remote.origin.push 2>/dev/null)" ]; then
|
|
268
|
+
git config --local --add remote.origin.push "refs/heads/*" 2>/dev/null || true
|
|
269
|
+
fi
|
|
270
|
+
git config --local --add remote.origin.push "refs/notes/agentblame" 2>/dev/null || true
|
|
271
|
+
fi
|
|
272
|
+
bun run "${cliScript}" process HEAD 2>/dev/null || true
|
|
273
|
+
`;
|
|
274
|
+
try {
|
|
275
|
+
await fs.promises.mkdir(globalHooksDir, { recursive: true });
|
|
276
|
+
await fs.promises.writeFile(hookPath, hookContent, { mode: 0o755 });
|
|
277
|
+
// Set global core.hooksPath
|
|
278
|
+
const { execSync } = await Promise.resolve().then(() => __importStar(require("node:child_process")));
|
|
279
|
+
execSync(`git config --global core.hooksPath "${globalHooksDir}"`, {
|
|
280
|
+
stdio: "pipe",
|
|
281
|
+
});
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
console.error("Failed to install global git hook:", err);
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Uninstall global git hook
|
|
291
|
+
*/
|
|
292
|
+
async function uninstallGlobalGitHook() {
|
|
293
|
+
try {
|
|
294
|
+
const { execSync } = await Promise.resolve().then(() => __importStar(require("node:child_process")));
|
|
295
|
+
// Remove core.hooksPath config
|
|
296
|
+
execSync("git config --global --unset core.hooksPath", {
|
|
297
|
+
stdio: "pipe",
|
|
298
|
+
});
|
|
299
|
+
// Remove hooks directory
|
|
300
|
+
const globalHooksDir = path.join(exports.AGENTBLAME_ROOT, "git-hooks");
|
|
301
|
+
if (fs.existsSync(globalHooksDir)) {
|
|
302
|
+
await fs.promises.rm(globalHooksDir, { recursive: true });
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return true; // Ignore errors (config might not exist)
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Install git post-commit hook to auto-process commits (per-repo)
|
|
312
|
+
*/
|
|
313
|
+
async function installGitHook(repoRoot) {
|
|
314
|
+
const hooksDir = path.join(repoRoot, ".git", "hooks");
|
|
315
|
+
const hookPath = path.join(hooksDir, "post-commit");
|
|
316
|
+
// Find the CLI script
|
|
317
|
+
const cliScript = path.resolve(__dirname, "..", "..", "cli", "src", "index.ts");
|
|
318
|
+
const hookContent = `#!/bin/sh
|
|
319
|
+
# Agent Blame - Auto-process commits for AI attribution
|
|
320
|
+
bun run "${cliScript}" process HEAD 2>/dev/null || true
|
|
321
|
+
`;
|
|
322
|
+
try {
|
|
323
|
+
await fs.promises.mkdir(hooksDir, { recursive: true });
|
|
324
|
+
// Check if hook already exists
|
|
325
|
+
let existingContent = "";
|
|
326
|
+
try {
|
|
327
|
+
existingContent = await fs.promises.readFile(hookPath, "utf8");
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// File doesn't exist
|
|
331
|
+
}
|
|
332
|
+
// Don't overwrite if already has agentblame
|
|
333
|
+
if (existingContent.includes("agentblame")) {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
// Append to existing hook or create new
|
|
337
|
+
if (existingContent && !existingContent.includes("agentblame")) {
|
|
338
|
+
// Append to existing hook
|
|
339
|
+
const newContent = existingContent.trimEnd() + "\n\n" + hookContent.split("\n").slice(1).join("\n");
|
|
340
|
+
await fs.promises.writeFile(hookPath, newContent, { mode: 0o755 });
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
// Create new hook
|
|
344
|
+
await fs.promises.writeFile(hookPath, hookContent, { mode: 0o755 });
|
|
345
|
+
}
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
catch (err) {
|
|
349
|
+
console.error("Failed to install git hook:", err);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Uninstall git post-commit hook
|
|
355
|
+
*/
|
|
356
|
+
async function uninstallGitHook(repoRoot) {
|
|
357
|
+
const hookPath = path.join(repoRoot, ".git", "hooks", "post-commit");
|
|
358
|
+
try {
|
|
359
|
+
if (!fs.existsSync(hookPath)) {
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
const content = await fs.promises.readFile(hookPath, "utf8");
|
|
363
|
+
if (!content.includes("agentblame")) {
|
|
364
|
+
return true; // Not our hook
|
|
365
|
+
}
|
|
366
|
+
// Remove agentblame lines
|
|
367
|
+
const lines = content.split("\n");
|
|
368
|
+
const newLines = lines.filter((line) => !line.includes("agentblame") && !line.includes("Agent Blame"));
|
|
369
|
+
if (newLines.filter((l) => l.trim() && !l.startsWith("#!")).length === 0) {
|
|
370
|
+
// Only shebang left, delete the file
|
|
371
|
+
await fs.promises.unlink(hookPath);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
await fs.promises.writeFile(hookPath, newLines.join("\n"), { mode: 0o755 });
|
|
375
|
+
}
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
console.error("Failed to uninstall git hook:", err);
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Uninstall Cursor hooks
|
|
385
|
+
*/
|
|
386
|
+
async function uninstallCursorHooks() {
|
|
387
|
+
try {
|
|
388
|
+
if (fs.existsSync(exports.CURSOR_HOOKS_CONFIG)) {
|
|
389
|
+
const config = JSON.parse(await fs.promises.readFile(exports.CURSOR_HOOKS_CONFIG, "utf8"));
|
|
390
|
+
if (config.hooks?.afterFileEdit) {
|
|
391
|
+
config.hooks.afterFileEdit = config.hooks.afterFileEdit.filter((h) => !h?.command?.includes("agentblame") &&
|
|
392
|
+
!h?.command?.includes("capture.ts"));
|
|
393
|
+
}
|
|
394
|
+
await fs.promises.writeFile(exports.CURSOR_HOOKS_CONFIG, JSON.stringify(config, null, 2), "utf8");
|
|
395
|
+
}
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
console.error("Failed to uninstall Cursor hooks:", err);
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Uninstall Claude Code hooks
|
|
405
|
+
*/
|
|
406
|
+
async function uninstallClaudeHooks() {
|
|
407
|
+
try {
|
|
408
|
+
if (fs.existsSync(exports.CLAUDE_SETTINGS_FILE)) {
|
|
409
|
+
const config = JSON.parse(await fs.promises.readFile(exports.CLAUDE_SETTINGS_FILE, "utf8"));
|
|
410
|
+
if (config.hooks?.PostToolUse) {
|
|
411
|
+
config.hooks.PostToolUse = config.hooks.PostToolUse.filter((h) => !h?.hooks?.some((hh) => hh?.command?.includes("agentblame") ||
|
|
412
|
+
hh?.command?.includes("capture.ts")));
|
|
413
|
+
}
|
|
414
|
+
await fs.promises.writeFile(exports.CLAUDE_SETTINGS_FILE, JSON.stringify(config, null, 2), "utf8");
|
|
415
|
+
}
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
catch (err) {
|
|
419
|
+
console.error("Failed to uninstall Claude hooks:", err);
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCH,kEAGC;AAoDD,gDAqEC;AAKD,gDAkEC;AAKD,0DAcC;AAKD,0DAiBC;AAKD,0CAMC;AAMD,oDAoCC;AAKD,wDAmBC;AAKD,wCA2CC;AAKD,4CAgCC;AAKD,oDA0BC;AAKD,oDA6BC;AAlfD,4CAA8B;AAC9B,gDAAkC;AAClC,4CAA8B;AAEjB,QAAA,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AACzD,QAAA,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,EAAE,OAAO,CAAC,CAAC;AAC3D,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,EAAE,MAAM,CAAC,CAAC;AAEtE,YAAY;AACC,QAAA,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAC3C,2BAAmB,EACnB,sBAAsB,CACvB,CAAC;AACW,QAAA,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAC3C,2BAAmB,EACnB,sBAAsB,CACvB,CAAC;AAEF,6BAA6B;AAChB,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAC1C,EAAE,CAAC,OAAO,EAAE,EACZ,SAAS,EACT,YAAY,CACb,CAAC;AAEF,qCAAqC;AACxB,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACzD,QAAA,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAC3C,2BAAmB,EACnB,eAAe,CAChB,CAAC;AAEF;;GAEG;AACI,KAAK,UAAU,2BAA2B;IAC/C,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,4BAAoB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,2BAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,SAAS,CAAC,QAAgB;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACrD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB;IACxB,MAAM,aAAa,GAAG;QACpB,qBAAqB;QACrB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC;QACrH,+BAA+B;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC;QAC9D,0BAA0B;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,CAAC;KAChG,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,QAA6B,EAC7B,aAAqB,EACrB,KAAc;IAEd,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,OAAO,YAAY,aAAa,gBAAgB,QAAQ,GAAG,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,aAAsB;IAEtB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,IAAI,iBAAiB,EAAE,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;QAC7F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,2BAA2B,EAAE,CAAC;QACpC,MAAM,SAAS,CAAC,4BAAoB,CAAC,CAAC;QAEtC,8BAA8B;QAC9B,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,2BAAmB,CAAC,EAAE;YACzD,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,IAAI,MAAM,GAAQ,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,2BAAmB,EAAE,MAAM,CAAC,CAAC;YACzE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;QAED,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QAElC,MAAM,eAAe,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;QAE1E,0BAA0B;QAC1B,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC;QAClC,CAAC;QAED,6CAA6C;QAC7C,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAC5D,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACvF,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;QAE9D,sCAAsC;QACtC,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAClE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACvF,CAAC;YACF,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/C,OAAO,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC;YACvC,CAAC;QACH,CAAC;QAED,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CACzB,2BAAmB,EACnB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,aAAsB;IAEtB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,IAAI,iBAAiB,EAAE,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;QAC7F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,2BAA2B,EAAE,CAAC;QACpC,MAAM,SAAS,CAAC,4BAAoB,CAAC,CAAC;QAEtC,iCAAiC;QACjC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,2BAAmB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAElE,IAAI,MAAM,GAAQ,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAAoB,EAAE,MAAM,CAAC,CAAC;YAC1E,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;QAED,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QAElC,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAErD,sDAAsD;QACtD,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;QAChC,CAAC;QAED,6CAA6C;QAC7C,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CACxD,CAAC,CAAM,EAAE,EAAE,CACT,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CACb,CAAC,EAAO,EAAE,EAAE,CACV,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC;YACnC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACtC,CACJ,CAAC;QAEF,mBAAmB;QACnB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC;YAC5B,OAAO,EAAE,sBAAsB;YAC/B,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SACnD,CAAC,CAAC;QAEH,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CACzB,4BAAoB,EACpB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,uBAAuB;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,2BAAmB,EAAE,MAAM,CAAC,CACxD,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,CACnD,CAAC,CAAM,EAAE,EAAE,CACT,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAC3E,CAAC;QACF,OAAO,WAAW,KAAK,IAAI,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,uBAAuB;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAAoB,EAAE,MAAM,CAAC,CACzD,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CACzD,CAAC,EAAE,KAAK,EAAE,IAAI,CACZ,CAAC,EAAO,EAAE,EAAE,CACV,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC;YACnC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACtC,CACF,CAAC;QACF,OAAO,OAAO,KAAK,IAAI,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,eAAe,CACnC,aAAsB;IAEtB,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,aAAa,CAAC,CAAC;IACvD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,oBAAoB;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,EAAE,WAAW,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAE1D,sBAAsB;IACtB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAEhF,kEAAkE;IAClE,MAAM,WAAW,GAAG;;;;;;;;;;WAUX,SAAS;CACnB,CAAC;IAEA,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEpE,4BAA4B;QAC5B,MAAM,EAAE,QAAQ,EAAE,GAAG,wDAAa,oBAAoB,GAAC,CAAC;QACxD,QAAQ,CAAC,uCAAuC,cAAc,GAAG,EAAE;YACjE,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,sBAAsB;IAC1C,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,wDAAa,oBAAoB,GAAC,CAAC;QAExD,+BAA+B;QAC/B,QAAQ,CAAC,4CAA4C,EAAE;YACrD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,yBAAyB;QACzB,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAe,EAAE,WAAW,CAAC,CAAC;QAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAClC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,yCAAyC;IACxD,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAEpD,sBAAsB;IACtB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAEhF,MAAM,WAAW,GAAG;;WAEX,SAAS;CACnB,CAAC;IAEA,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvD,+BAA+B;QAC/B,IAAI,eAAe,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,eAAe,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;QAED,4CAA4C;QAC5C,IAAI,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wCAAwC;QACxC,IAAI,eAAe,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/D,0BAA0B;YAC1B,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,kBAAkB;YAClB,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAErE,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7D,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,CAAC,eAAe;QAC9B,CAAC;QAED,0BAA0B;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAC3B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CACxE,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzE,qCAAqC;YACrC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,2BAAmB,CAAC,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,2BAAmB,EAAE,MAAM,CAAC,CACxD,CAAC;YAEF,IAAI,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC;gBAChC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAC5D,CAAC,CAAM,EAAE,EAAE,CACT,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC;oBACnC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACtC,CAAC;YACJ,CAAC;YAED,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CACzB,2BAAmB,EACnB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,4BAAoB,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CACvB,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,4BAAoB,EAAE,MAAM,CAAC,CACzD,CAAC;YAEF,IAAI,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CACxD,CAAC,CAAM,EAAE,EAAE,CACT,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CACb,CAAC,EAAO,EAAE,EAAE,CACV,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC;oBACnC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CACtC,CACJ,CAAC;YACJ,CAAC;YAED,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CACzB,4BAAoB,EACpB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,MAAM,CACP,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./util";
|
|
3
|
+
export * from "./db";
|
|
4
|
+
export * from "./diff";
|
|
5
|
+
export * from "./hooks";
|
|
6
|
+
export * from "./git/gitCli";
|
|
7
|
+
export * from "./git/gitDiff";
|
|
8
|
+
export * from "./git/gitBlame";
|
|
9
|
+
export * from "./git/gitNotes";
|
|
10
|
+
export * from "./git/gitConfig";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// Types
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
// Utilities
|
|
20
|
+
__exportStar(require("./util"), exports);
|
|
21
|
+
// Database/logs
|
|
22
|
+
__exportStar(require("./db"), exports);
|
|
23
|
+
// Diff utilities
|
|
24
|
+
__exportStar(require("./diff"), exports);
|
|
25
|
+
// Hook installation
|
|
26
|
+
__exportStar(require("./hooks"), exports);
|
|
27
|
+
// Git operations
|
|
28
|
+
__exportStar(require("./git/gitCli"), exports);
|
|
29
|
+
__exportStar(require("./git/gitDiff"), exports);
|
|
30
|
+
__exportStar(require("./git/gitBlame"), exports);
|
|
31
|
+
__exportStar(require("./git/gitNotes"), exports);
|
|
32
|
+
__exportStar(require("./git/gitConfig"), exports);
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,QAAQ;AACR,0CAAwB;AAExB,YAAY;AACZ,yCAAuB;AAEvB,gBAAgB;AAChB,uCAAqB;AAErB,iBAAiB;AACjB,yCAAuB;AAEvB,oBAAoB;AACpB,0CAAwB;AAExB,iBAAiB;AACjB,+CAA6B;AAC7B,gDAA8B;AAC9B,iDAA+B;AAC/B,iDAA+B;AAC/B,kDAAgC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Types for Agent Blame
|
|
3
|
+
*
|
|
4
|
+
* Line-level attribution tracking for AI-generated code.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* AI provider that generated the code
|
|
8
|
+
*/
|
|
9
|
+
export type AiProvider = "cursor" | "claude_code";
|
|
10
|
+
/**
|
|
11
|
+
* Source of the AI edit (how it was triggered)
|
|
12
|
+
*/
|
|
13
|
+
export type AiSource = "composer" | "agent" | "inline" | "unknown";
|
|
14
|
+
/**
|
|
15
|
+
* Attribution category - we only track AI-generated code
|
|
16
|
+
* Human is the default for unattributed code
|
|
17
|
+
*/
|
|
18
|
+
export type AttributionCategory = "ai_generated";
|
|
19
|
+
/**
|
|
20
|
+
* How the match was determined
|
|
21
|
+
*/
|
|
22
|
+
export type MatchType = "exact_hash" | "normalized_hash" | "line_in_ai_content" | "ai_content_in_line" | "move_detected";
|
|
23
|
+
/**
|
|
24
|
+
* A single edit from Cursor
|
|
25
|
+
*/
|
|
26
|
+
export interface CursorEdit {
|
|
27
|
+
old_string: string;
|
|
28
|
+
new_string: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Raw payload from Cursor hooks (afterFileEdit)
|
|
32
|
+
*/
|
|
33
|
+
export interface CursorHookPayload {
|
|
34
|
+
file_path: string;
|
|
35
|
+
edits: CursorEdit[];
|
|
36
|
+
model?: string;
|
|
37
|
+
conversation_id?: string;
|
|
38
|
+
generation_id?: string;
|
|
39
|
+
cursor_version?: string;
|
|
40
|
+
workspace_roots?: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Raw payload from Claude Code hooks (PostToolUse)
|
|
44
|
+
*/
|
|
45
|
+
export interface ClaudeHookPayload {
|
|
46
|
+
tool_name?: string;
|
|
47
|
+
tool_input?: {
|
|
48
|
+
file_path?: string;
|
|
49
|
+
old_string?: string;
|
|
50
|
+
new_string?: string;
|
|
51
|
+
content?: string;
|
|
52
|
+
};
|
|
53
|
+
file_path?: string;
|
|
54
|
+
old_string?: string;
|
|
55
|
+
new_string?: string;
|
|
56
|
+
content?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A single line captured from an AI edit
|
|
60
|
+
*/
|
|
61
|
+
export interface CapturedLine {
|
|
62
|
+
content: string;
|
|
63
|
+
hash: string;
|
|
64
|
+
hash_normalized: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A captured AI edit entry - stored in log files
|
|
68
|
+
*/
|
|
69
|
+
export interface CapturedEdit {
|
|
70
|
+
timestamp: string;
|
|
71
|
+
provider: AiProvider;
|
|
72
|
+
file_path: string;
|
|
73
|
+
model: string | null;
|
|
74
|
+
lines: CapturedLine[];
|
|
75
|
+
content: string;
|
|
76
|
+
content_hash: string;
|
|
77
|
+
content_hash_normalized: string;
|
|
78
|
+
edit_type: "addition" | "modification" | "replacement";
|
|
79
|
+
old_content?: string;
|
|
80
|
+
status?: "pending" | "matched";
|
|
81
|
+
matched_commit?: string;
|
|
82
|
+
matched_at?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Pending edit with source tracking for marking as matched
|
|
86
|
+
*/
|
|
87
|
+
export interface PendingEdit extends CapturedEdit {
|
|
88
|
+
source_log: string;
|
|
89
|
+
line_number: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A hunk of code from a git diff
|
|
93
|
+
*/
|
|
94
|
+
export interface DiffHunk {
|
|
95
|
+
path: string;
|
|
96
|
+
start_line: number;
|
|
97
|
+
end_line: number;
|
|
98
|
+
content: string;
|
|
99
|
+
content_hash: string;
|
|
100
|
+
content_hash_normalized: string;
|
|
101
|
+
lines: Array<{
|
|
102
|
+
line_number: number;
|
|
103
|
+
content: string;
|
|
104
|
+
hash: string;
|
|
105
|
+
hash_normalized: string;
|
|
106
|
+
}>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Deleted lines from a commit (for move detection)
|
|
110
|
+
*/
|
|
111
|
+
export interface DeletedBlock {
|
|
112
|
+
path: string;
|
|
113
|
+
start_line: number;
|
|
114
|
+
lines: string[];
|
|
115
|
+
normalized_content: string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A detected move operation
|
|
119
|
+
*/
|
|
120
|
+
export interface MoveMapping {
|
|
121
|
+
from_path: string;
|
|
122
|
+
from_start_line: number;
|
|
123
|
+
to_path: string;
|
|
124
|
+
to_start_line: number;
|
|
125
|
+
line_count: number;
|
|
126
|
+
normalized_content: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Attribution for a single line
|
|
130
|
+
*/
|
|
131
|
+
export interface LineAttribution {
|
|
132
|
+
path: string;
|
|
133
|
+
line: number;
|
|
134
|
+
provider: AiProvider;
|
|
135
|
+
model: string | null;
|
|
136
|
+
confidence: number;
|
|
137
|
+
match_type: MatchType;
|
|
138
|
+
content_hash: string;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Attribution for a range of lines (merged consecutive lines)
|
|
142
|
+
*/
|
|
143
|
+
export interface RangeAttribution {
|
|
144
|
+
path: string;
|
|
145
|
+
start_line: number;
|
|
146
|
+
end_line: number;
|
|
147
|
+
provider: AiProvider;
|
|
148
|
+
model: string | null;
|
|
149
|
+
confidence: number;
|
|
150
|
+
match_type: MatchType;
|
|
151
|
+
content_hash: string;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Result of matching a commit
|
|
155
|
+
*/
|
|
156
|
+
export interface MatchResult {
|
|
157
|
+
sha: string;
|
|
158
|
+
attributions: RangeAttribution[];
|
|
159
|
+
unmatched_lines: number;
|
|
160
|
+
total_lines: number;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Git notes format for storing attribution
|
|
164
|
+
*/
|
|
165
|
+
export interface GitNotesAttribution {
|
|
166
|
+
version: 1;
|
|
167
|
+
timestamp: string;
|
|
168
|
+
attributions: Array<{
|
|
169
|
+
path: string;
|
|
170
|
+
start_line: number;
|
|
171
|
+
end_line: number;
|
|
172
|
+
category: AttributionCategory;
|
|
173
|
+
provider: AiProvider;
|
|
174
|
+
model: string | null;
|
|
175
|
+
confidence: number;
|
|
176
|
+
match_type: MatchType;
|
|
177
|
+
content_hash: string;
|
|
178
|
+
}>;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Git repository state
|
|
182
|
+
*/
|
|
183
|
+
export interface GitState {
|
|
184
|
+
branch: string | null;
|
|
185
|
+
head: string | null;
|
|
186
|
+
mergeHead: string | null;
|
|
187
|
+
rebaseHead: string | null;
|
|
188
|
+
cherryPickHead: string | null;
|
|
189
|
+
bisectLog: boolean;
|
|
190
|
+
}
|