@mesadev/agentblame 0.2.11 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/agentblame.js +3500 -0
  2. package/dist/blame.d.ts +4 -1
  3. package/dist/blame.js +293 -78
  4. package/dist/blame.js.map +1 -1
  5. package/dist/capture.d.ts +4 -7
  6. package/dist/capture.js +464 -486
  7. package/dist/capture.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +248 -85
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/analytics.d.ts +179 -0
  12. package/dist/lib/analytics.js +833 -0
  13. package/dist/lib/analytics.js.map +1 -0
  14. package/dist/lib/attribution.d.ts +54 -0
  15. package/dist/lib/attribution.js +266 -0
  16. package/dist/lib/attribution.js.map +1 -0
  17. package/dist/lib/checkpoint.d.ts +97 -0
  18. package/dist/lib/checkpoint.js +441 -0
  19. package/dist/lib/checkpoint.js.map +1 -0
  20. package/dist/lib/config.d.ts +46 -0
  21. package/dist/lib/config.js +123 -0
  22. package/dist/lib/config.js.map +1 -0
  23. package/dist/lib/database.d.ts +115 -85
  24. package/dist/lib/database.js +305 -325
  25. package/dist/lib/database.js.map +1 -1
  26. package/dist/lib/delta.d.ts +78 -0
  27. package/dist/lib/delta.js +309 -0
  28. package/dist/lib/delta.js.map +1 -0
  29. package/dist/lib/git/gitBlame.js +9 -4
  30. package/dist/lib/git/gitBlame.js.map +1 -1
  31. package/dist/lib/git/gitConfig.d.ts +5 -3
  32. package/dist/lib/git/gitConfig.js +41 -6
  33. package/dist/lib/git/gitConfig.js.map +1 -1
  34. package/dist/lib/git/gitDiff.d.ts +13 -1
  35. package/dist/lib/git/gitDiff.js +39 -7
  36. package/dist/lib/git/gitDiff.js.map +1 -1
  37. package/dist/lib/git/gitNotes.d.ts +30 -4
  38. package/dist/lib/git/gitNotes.js +140 -24
  39. package/dist/lib/git/gitNotes.js.map +1 -1
  40. package/dist/lib/hooks.d.ts +1 -0
  41. package/dist/lib/hooks.js +148 -27
  42. package/dist/lib/hooks.js.map +1 -1
  43. package/dist/lib/index.d.ts +7 -0
  44. package/dist/lib/index.js +13 -0
  45. package/dist/lib/index.js.map +1 -1
  46. package/dist/lib/storage.d.ts +163 -0
  47. package/dist/lib/storage.js +823 -0
  48. package/dist/lib/storage.js.map +1 -0
  49. package/dist/lib/trace.d.ts +118 -0
  50. package/dist/lib/trace.js +499 -0
  51. package/dist/lib/trace.js.map +1 -0
  52. package/dist/lib/types.d.ts +322 -114
  53. package/dist/lib/types.js +2 -1
  54. package/dist/lib/types.js.map +1 -1
  55. package/dist/lib/util.d.ts +8 -8
  56. package/dist/lib/util.js +18 -22
  57. package/dist/lib/util.js.map +1 -1
  58. package/dist/lib/watcher.d.ts +104 -0
  59. package/dist/lib/watcher.js +398 -0
  60. package/dist/lib/watcher.js.map +1 -0
  61. package/dist/post-merge.js +460 -421
  62. package/dist/post-merge.js.map +1 -1
  63. package/dist/process.d.ts +6 -5
  64. package/dist/process.js +233 -152
  65. package/dist/process.js.map +1 -1
  66. package/dist/sync.js +172 -131
  67. package/dist/sync.js.map +1 -1
  68. package/package.json +3 -2
@@ -0,0 +1,441 @@
1
+ "use strict";
2
+ /**
3
+ * Checkpoint Module v3
4
+ *
5
+ * Bulletproof capture of file states before AI edits.
6
+ * This replaces the file watcher approach with a deterministic checkpoint system.
7
+ *
8
+ * Strategy:
9
+ * - Cursor: beforeSubmitPrompt captures modified files, afterFileEdit uses checkpoint
10
+ * - Claude: PreToolUse captures target file, PostToolUse uses checkpoint
11
+ * - OpenCode: tool.execute.before captures target file, tool.execute.after uses checkpoint
12
+ *
13
+ * Storage: .git/agentblame/checkpoints/{conversation_id}.json
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.hashContent = hashContent;
50
+ exports.hasFileChanged = hasFileChanged;
51
+ exports.getCheckpointContent = getCheckpointContent;
52
+ exports.getCheckpointsDir = getCheckpointsDir;
53
+ exports.getCheckpointPath = getCheckpointPath;
54
+ exports.ensureCheckpointsDir = ensureCheckpointsDir;
55
+ exports.saveCheckpoint = saveCheckpoint;
56
+ exports.loadCheckpoint = loadCheckpoint;
57
+ exports.updateCheckpointFile = updateCheckpointFile;
58
+ exports.updateCheckpointWithContent = updateCheckpointWithContent;
59
+ exports.getCheckpointBlob = getCheckpointBlob;
60
+ exports.deleteCheckpoint = deleteCheckpoint;
61
+ exports.cleanupOldCheckpoints = cleanupOldCheckpoints;
62
+ exports.getGitModifiedFiles = getGitModifiedFiles;
63
+ exports.captureBeforePromptCheckpoint = captureBeforePromptCheckpoint;
64
+ exports.captureFileCheckpoint = captureFileCheckpoint;
65
+ exports.getBeforeBlob = getBeforeBlob;
66
+ const fs = __importStar(require("node:fs"));
67
+ const path = __importStar(require("node:path"));
68
+ const node_child_process_1 = require("node:child_process");
69
+ const node_crypto_1 = require("node:crypto");
70
+ const storage_1 = require("./storage");
71
+ // =============================================================================
72
+ // Hash Helpers
73
+ // =============================================================================
74
+ /**
75
+ * Compute a fast content hash for comparison
76
+ * Uses SHA256 truncated to 16 chars for efficiency
77
+ */
78
+ function hashContent(content) {
79
+ return (0, node_crypto_1.createHash)("sha256").update(content).digest("hex").slice(0, 16);
80
+ }
81
+ /**
82
+ * Check if a file has changed since the checkpoint
83
+ * Returns true if the file content differs from the checkpoint
84
+ */
85
+ async function hasFileChanged(repoRoot, conversationId, filePath) {
86
+ const checkpoint = loadCheckpoint(repoRoot, conversationId);
87
+ if (!checkpoint) {
88
+ return false; // No checkpoint, can't detect change
89
+ }
90
+ const fileCheckpoint = checkpoint.files[filePath];
91
+ if (!fileCheckpoint) {
92
+ return false; // File not in checkpoint
93
+ }
94
+ // Read current file content
95
+ const absolutePath = filePath.startsWith("/")
96
+ ? filePath
97
+ : path.join(repoRoot, filePath);
98
+ try {
99
+ const currentContent = fs.readFileSync(absolutePath, "utf8");
100
+ const currentHash = hashContent(currentContent);
101
+ return currentHash !== fileCheckpoint.contentHash;
102
+ }
103
+ catch {
104
+ return false; // Can't read file
105
+ }
106
+ }
107
+ /**
108
+ * Get checkpoint content for a file (loads from git blob)
109
+ */
110
+ async function getCheckpointContent(repoRoot, conversationId, filePath) {
111
+ const checkpoint = loadCheckpoint(repoRoot, conversationId);
112
+ if (!checkpoint) {
113
+ return null;
114
+ }
115
+ const fileCheckpoint = checkpoint.files[filePath];
116
+ if (!fileCheckpoint) {
117
+ return null;
118
+ }
119
+ try {
120
+ return await (0, storage_1.loadSnapshot)(repoRoot, fileCheckpoint.blobSha);
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ // =============================================================================
127
+ // Path Helpers
128
+ // =============================================================================
129
+ /**
130
+ * Get the checkpoints directory path
131
+ */
132
+ function getCheckpointsDir(repoRoot) {
133
+ return path.join((0, storage_1.getAgentBlameGitDir)(repoRoot), "checkpoints");
134
+ }
135
+ /**
136
+ * Get the checkpoint file path for a conversation
137
+ */
138
+ function getCheckpointPath(repoRoot, conversationId) {
139
+ // Sanitize conversation ID for filesystem
140
+ const safeId = conversationId.replace(/[^a-zA-Z0-9-_]/g, "_");
141
+ return path.join(getCheckpointsDir(repoRoot), `${safeId}.json`);
142
+ }
143
+ /**
144
+ * Ensure checkpoints directory exists
145
+ */
146
+ function ensureCheckpointsDir(repoRoot) {
147
+ const dir = getCheckpointsDir(repoRoot);
148
+ if (!fs.existsSync(dir)) {
149
+ fs.mkdirSync(dir, { recursive: true });
150
+ }
151
+ }
152
+ // =============================================================================
153
+ // Checkpoint CRUD
154
+ // =============================================================================
155
+ /**
156
+ * Save a checkpoint for a conversation
157
+ */
158
+ function saveCheckpoint(repoRoot, checkpoint) {
159
+ ensureCheckpointsDir(repoRoot);
160
+ const checkpointPath = getCheckpointPath(repoRoot, checkpoint.conversationId);
161
+ fs.writeFileSync(checkpointPath, JSON.stringify(checkpoint, null, 2), "utf8");
162
+ if (process.env.AGENTBLAME_DEBUG) {
163
+ console.error(`[agentblame] Saved checkpoint: ${checkpoint.conversationId} with ${Object.keys(checkpoint.files).length} files`);
164
+ }
165
+ }
166
+ /**
167
+ * Load a checkpoint for a conversation
168
+ */
169
+ function loadCheckpoint(repoRoot, conversationId) {
170
+ const checkpointPath = getCheckpointPath(repoRoot, conversationId);
171
+ if (!fs.existsSync(checkpointPath)) {
172
+ return null;
173
+ }
174
+ try {
175
+ const content = fs.readFileSync(checkpointPath, "utf8");
176
+ return JSON.parse(content);
177
+ }
178
+ catch {
179
+ return null;
180
+ }
181
+ }
182
+ /**
183
+ * Update a checkpoint with a new file state
184
+ */
185
+ function updateCheckpointFile(repoRoot, conversationId, filePath, blobSha, contentHash) {
186
+ let checkpoint = loadCheckpoint(repoRoot, conversationId);
187
+ if (!checkpoint) {
188
+ checkpoint = {
189
+ conversationId,
190
+ timestamp: new Date().toISOString(),
191
+ files: {},
192
+ };
193
+ }
194
+ checkpoint.files[filePath] = {
195
+ blobSha,
196
+ contentHash,
197
+ timestamp: new Date().toISOString(),
198
+ };
199
+ saveCheckpoint(repoRoot, checkpoint);
200
+ }
201
+ /**
202
+ * Update checkpoint with content (computes hash and stores blob)
203
+ */
204
+ async function updateCheckpointWithContent(repoRoot, conversationId, filePath, content) {
205
+ const blobSha = await (0, storage_1.storeSnapshot)(repoRoot, content);
206
+ const contentHash = hashContent(content);
207
+ updateCheckpointFile(repoRoot, conversationId, filePath, blobSha, contentHash);
208
+ }
209
+ /**
210
+ * Get the "before" blob for a file from checkpoint
211
+ * Returns null if no checkpoint exists for this file
212
+ */
213
+ function getCheckpointBlob(repoRoot, conversationId, filePath) {
214
+ const checkpoint = loadCheckpoint(repoRoot, conversationId);
215
+ if (!checkpoint) {
216
+ return null;
217
+ }
218
+ return checkpoint.files[filePath]?.blobSha || null;
219
+ }
220
+ /**
221
+ * Delete a checkpoint (cleanup after commit or session end)
222
+ */
223
+ function deleteCheckpoint(repoRoot, conversationId) {
224
+ const checkpointPath = getCheckpointPath(repoRoot, conversationId);
225
+ if (fs.existsSync(checkpointPath)) {
226
+ fs.unlinkSync(checkpointPath);
227
+ }
228
+ }
229
+ /**
230
+ * Clean up old checkpoints (older than specified hours)
231
+ */
232
+ function cleanupOldCheckpoints(repoRoot, maxAgeHours = 24) {
233
+ const dir = getCheckpointsDir(repoRoot);
234
+ if (!fs.existsSync(dir)) {
235
+ return 0;
236
+ }
237
+ const now = Date.now();
238
+ const maxAgeMs = maxAgeHours * 60 * 60 * 1000;
239
+ let cleaned = 0;
240
+ try {
241
+ const files = fs.readdirSync(dir);
242
+ for (const file of files) {
243
+ if (!file.endsWith(".json"))
244
+ continue;
245
+ const filePath = path.join(dir, file);
246
+ const stat = fs.statSync(filePath);
247
+ if (now - stat.mtimeMs > maxAgeMs) {
248
+ fs.unlinkSync(filePath);
249
+ cleaned++;
250
+ }
251
+ }
252
+ }
253
+ catch {
254
+ // Silent failure
255
+ }
256
+ return cleaned;
257
+ }
258
+ // =============================================================================
259
+ // Git Status Helpers
260
+ // =============================================================================
261
+ /**
262
+ * Get list of modified files from git status (staged + unstaged)
263
+ * These are files that may have human edits since last commit
264
+ */
265
+ async function getGitModifiedFiles(repoRoot) {
266
+ return new Promise((resolve) => {
267
+ const proc = (0, node_child_process_1.spawn)("git", ["status", "--porcelain", "-z"], {
268
+ cwd: repoRoot,
269
+ stdio: ["ignore", "pipe", "pipe"],
270
+ });
271
+ let stdout = "";
272
+ proc.stdout.on("data", (data) => {
273
+ stdout += data.toString();
274
+ });
275
+ proc.on("close", (code) => {
276
+ if (code !== 0) {
277
+ resolve([]);
278
+ return;
279
+ }
280
+ // Parse git status output (NUL-separated)
281
+ const files = [];
282
+ const entries = stdout.split("\0").filter(Boolean);
283
+ for (const entry of entries) {
284
+ // Format: XY filename (where XY is status codes)
285
+ if (entry.length < 4)
286
+ continue;
287
+ const status = entry.substring(0, 2);
288
+ const filePath = entry.substring(3);
289
+ // Include modified, added, and renamed files (not deleted)
290
+ if (status.includes("M") || status.includes("A") || status.includes("R") || status === "??") {
291
+ // For renamed files, use the new name (after ->)
292
+ const actualPath = filePath.includes(" -> ")
293
+ ? filePath.split(" -> ")[1]
294
+ : filePath;
295
+ files.push(actualPath);
296
+ }
297
+ }
298
+ resolve(files);
299
+ });
300
+ proc.on("error", () => {
301
+ resolve([]);
302
+ });
303
+ });
304
+ }
305
+ /**
306
+ * Read file content from disk
307
+ */
308
+ function readFileContent(filePath) {
309
+ try {
310
+ return fs.readFileSync(filePath, "utf8");
311
+ }
312
+ catch {
313
+ return null;
314
+ }
315
+ }
316
+ // =============================================================================
317
+ // Checkpoint Capture Functions
318
+ // =============================================================================
319
+ /**
320
+ * Capture checkpoint for Cursor's beforeSubmitPrompt
321
+ * Captures all modified files (from git status) since they may have human edits
322
+ */
323
+ async function captureBeforePromptCheckpoint(repoRoot, conversationId) {
324
+ const checkpoint = {
325
+ conversationId,
326
+ timestamp: new Date().toISOString(),
327
+ files: {},
328
+ };
329
+ // Get all modified files from git status
330
+ const modifiedFiles = await getGitModifiedFiles(repoRoot);
331
+ if (process.env.AGENTBLAME_DEBUG) {
332
+ console.error(`[agentblame] beforeSubmitPrompt: ${modifiedFiles.length} modified files`);
333
+ }
334
+ // Capture each modified file's current state
335
+ for (const relativePath of modifiedFiles) {
336
+ const absolutePath = path.join(repoRoot, relativePath);
337
+ const content = readFileContent(absolutePath);
338
+ if (content === null)
339
+ continue;
340
+ try {
341
+ const blobSha = await (0, storage_1.storeSnapshot)(repoRoot, content);
342
+ const contentHash = hashContent(content);
343
+ checkpoint.files[relativePath] = {
344
+ blobSha,
345
+ contentHash,
346
+ timestamp: new Date().toISOString(),
347
+ };
348
+ }
349
+ catch {
350
+ // Skip files that fail to store
351
+ }
352
+ }
353
+ saveCheckpoint(repoRoot, checkpoint);
354
+ return checkpoint;
355
+ }
356
+ /**
357
+ * Capture checkpoint for a single file (Claude PreToolUse / OpenCode tool.execute.before)
358
+ * More efficient than capturing all modified files since we know the target
359
+ */
360
+ async function captureFileCheckpoint(repoRoot, conversationId, filePath) {
361
+ // Make path relative if absolute
362
+ const relativePath = filePath.startsWith(repoRoot)
363
+ ? filePath.slice(repoRoot.length + 1)
364
+ : filePath;
365
+ const absolutePath = filePath.startsWith("/")
366
+ ? filePath
367
+ : path.join(repoRoot, filePath);
368
+ const content = readFileContent(absolutePath);
369
+ if (content === null) {
370
+ // File doesn't exist yet (new file)
371
+ return null;
372
+ }
373
+ try {
374
+ const blobSha = await (0, storage_1.storeSnapshot)(repoRoot, content);
375
+ const contentHash = hashContent(content);
376
+ updateCheckpointFile(repoRoot, conversationId, relativePath, blobSha, contentHash);
377
+ if (process.env.AGENTBLAME_DEBUG) {
378
+ console.error(`[agentblame] PreToolUse checkpoint: ${relativePath} -> ${blobSha.slice(0, 8)}`);
379
+ }
380
+ return blobSha;
381
+ }
382
+ catch (err) {
383
+ if (process.env.AGENTBLAME_DEBUG) {
384
+ console.error(`[agentblame] Failed to capture file checkpoint:`, err);
385
+ }
386
+ return null;
387
+ }
388
+ }
389
+ /**
390
+ * Get the "before" blob for a file, using checkpoint if available, else git HEAD
391
+ */
392
+ async function getBeforeBlob(repoRoot, conversationId, filePath) {
393
+ // Make path relative
394
+ const relativePath = filePath.startsWith(repoRoot)
395
+ ? filePath.slice(repoRoot.length + 1)
396
+ : filePath;
397
+ // First, check checkpoint
398
+ const checkpointBlob = getCheckpointBlob(repoRoot, conversationId, relativePath);
399
+ if (checkpointBlob) {
400
+ if (process.env.AGENTBLAME_DEBUG) {
401
+ console.error(`[agentblame] Using checkpoint blob for ${relativePath}: ${checkpointBlob.slice(0, 8)}`);
402
+ }
403
+ return checkpointBlob;
404
+ }
405
+ // Fall back to git HEAD
406
+ return getFileBlobAtHead(repoRoot, relativePath);
407
+ }
408
+ /**
409
+ * Get the blob SHA for a file at HEAD
410
+ */
411
+ async function getFileBlobAtHead(repoRoot, filePath) {
412
+ return new Promise((resolve) => {
413
+ const proc = (0, node_child_process_1.spawn)("git", ["ls-tree", "HEAD", filePath], {
414
+ cwd: repoRoot,
415
+ stdio: ["ignore", "pipe", "pipe"],
416
+ });
417
+ let stdout = "";
418
+ proc.stdout.on("data", (data) => {
419
+ stdout += data.toString();
420
+ });
421
+ proc.on("close", (code) => {
422
+ if (code === 0 && stdout.trim()) {
423
+ // Output format: mode type blob\tpath
424
+ const parts = stdout.trim().split(/\s+/);
425
+ if (parts.length >= 3) {
426
+ resolve(parts[2]); // The blob SHA
427
+ }
428
+ else {
429
+ resolve(null);
430
+ }
431
+ }
432
+ else {
433
+ resolve(null);
434
+ }
435
+ });
436
+ proc.on("error", () => {
437
+ resolve(null);
438
+ });
439
+ });
440
+ }
441
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/lib/checkpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Agent Blame Configuration
3
+ *
4
+ * Manages user preferences stored in git config.
5
+ * Settings are stored per-repo in .git/config under [agentblame] section.
6
+ */
7
+ /**
8
+ * Configuration keys and their defaults
9
+ */
10
+ export interface AgentBlameConfig {
11
+ /** Whether to store actual prompt content (default: true) */
12
+ storePromptContent: boolean;
13
+ }
14
+ /**
15
+ * Get a configuration value
16
+ */
17
+ export declare function getConfig<K extends keyof AgentBlameConfig>(repoRoot: string, key: K): Promise<AgentBlameConfig[K]>;
18
+ /**
19
+ * Set a configuration value
20
+ */
21
+ export declare function setConfig<K extends keyof AgentBlameConfig>(repoRoot: string, key: K, value: AgentBlameConfig[K]): Promise<void>;
22
+ /**
23
+ * Unset a configuration value (revert to default)
24
+ */
25
+ export declare function unsetConfig<K extends keyof AgentBlameConfig>(repoRoot: string, key: K): Promise<void>;
26
+ /**
27
+ * Get all configuration values
28
+ */
29
+ export declare function getAllConfig(repoRoot: string): Promise<AgentBlameConfig>;
30
+ /**
31
+ * List all configuration with their current values and defaults
32
+ */
33
+ export declare function listConfig(repoRoot: string): Promise<Array<{
34
+ key: string;
35
+ value: string;
36
+ default: string;
37
+ isDefault: boolean;
38
+ }>>;
39
+ /**
40
+ * Valid config keys for user input validation
41
+ */
42
+ export declare const VALID_CONFIG_KEYS: (keyof AgentBlameConfig)[];
43
+ /**
44
+ * Parse a string value to the appropriate type for a config key
45
+ */
46
+ export declare function parseConfigValue<K extends keyof AgentBlameConfig>(key: K, value: string): AgentBlameConfig[K] | null;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ /**
3
+ * Agent Blame Configuration
4
+ *
5
+ * Manages user preferences stored in git config.
6
+ * Settings are stored per-repo in .git/config under [agentblame] section.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.VALID_CONFIG_KEYS = void 0;
10
+ exports.getConfig = getConfig;
11
+ exports.setConfig = setConfig;
12
+ exports.unsetConfig = unsetConfig;
13
+ exports.getAllConfig = getAllConfig;
14
+ exports.listConfig = listConfig;
15
+ exports.parseConfigValue = parseConfigValue;
16
+ const gitCli_1 = require("./git/gitCli");
17
+ const CONFIG_DEFAULTS = {
18
+ storePromptContent: false, // Default: don't store prompt text (privacy-first)
19
+ };
20
+ const CONFIG_PREFIX = "agentblame";
21
+ /**
22
+ * Get a configuration value
23
+ */
24
+ async function getConfig(repoRoot, key) {
25
+ try {
26
+ const result = await (0, gitCli_1.runGit)(repoRoot, [
27
+ "config",
28
+ "--local",
29
+ "--get",
30
+ `${CONFIG_PREFIX}.${key}`,
31
+ ]);
32
+ // git config --get returns exit code 1 if key not found
33
+ if (result.exitCode !== 0) {
34
+ return CONFIG_DEFAULTS[key];
35
+ }
36
+ const value = result.stdout.trim();
37
+ // Parse based on type
38
+ if (typeof CONFIG_DEFAULTS[key] === "boolean") {
39
+ return (value === "true");
40
+ }
41
+ return value;
42
+ }
43
+ catch {
44
+ // Return default if not set
45
+ return CONFIG_DEFAULTS[key];
46
+ }
47
+ }
48
+ /**
49
+ * Set a configuration value
50
+ */
51
+ async function setConfig(repoRoot, key, value) {
52
+ await (0, gitCli_1.runGit)(repoRoot, [
53
+ "config",
54
+ "--local",
55
+ `${CONFIG_PREFIX}.${key}`,
56
+ String(value),
57
+ ]);
58
+ }
59
+ /**
60
+ * Unset a configuration value (revert to default)
61
+ */
62
+ async function unsetConfig(repoRoot, key) {
63
+ try {
64
+ await (0, gitCli_1.runGit)(repoRoot, [
65
+ "config",
66
+ "--local",
67
+ "--unset",
68
+ `${CONFIG_PREFIX}.${key}`,
69
+ ]);
70
+ }
71
+ catch {
72
+ // Ignore if not set
73
+ }
74
+ }
75
+ /**
76
+ * Get all configuration values
77
+ */
78
+ async function getAllConfig(repoRoot) {
79
+ const config = { ...CONFIG_DEFAULTS };
80
+ for (const key of Object.keys(CONFIG_DEFAULTS)) {
81
+ config[key] = await getConfig(repoRoot, key);
82
+ }
83
+ return config;
84
+ }
85
+ /**
86
+ * List all configuration with their current values and defaults
87
+ */
88
+ async function listConfig(repoRoot) {
89
+ const result = [];
90
+ for (const key of Object.keys(CONFIG_DEFAULTS)) {
91
+ const currentValue = await getConfig(repoRoot, key);
92
+ const defaultValue = CONFIG_DEFAULTS[key];
93
+ const isDefault = currentValue === defaultValue;
94
+ result.push({
95
+ key,
96
+ value: String(currentValue),
97
+ default: String(defaultValue),
98
+ isDefault,
99
+ });
100
+ }
101
+ return result;
102
+ }
103
+ /**
104
+ * Valid config keys for user input validation
105
+ */
106
+ exports.VALID_CONFIG_KEYS = Object.keys(CONFIG_DEFAULTS);
107
+ /**
108
+ * Parse a string value to the appropriate type for a config key
109
+ */
110
+ function parseConfigValue(key, value) {
111
+ const defaultValue = CONFIG_DEFAULTS[key];
112
+ if (typeof defaultValue === "boolean") {
113
+ if (value === "true" || value === "1" || value === "yes") {
114
+ return true;
115
+ }
116
+ if (value === "false" || value === "0" || value === "no") {
117
+ return false;
118
+ }
119
+ return null; // Invalid boolean value
120
+ }
121
+ return value;
122
+ }
123
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}