@memnexus-ai/cli 1.7.61 → 1.7.63

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 (60) hide show
  1. package/dist/commands/commit-context.d.ts +10 -0
  2. package/dist/commands/commit-context.d.ts.map +1 -0
  3. package/dist/commands/commit-context.js +356 -0
  4. package/dist/commands/commit-context.js.map +1 -0
  5. package/dist/commands/hook.d.ts +15 -0
  6. package/dist/commands/hook.d.ts.map +1 -0
  7. package/dist/commands/hook.js +201 -0
  8. package/dist/commands/hook.js.map +1 -0
  9. package/dist/commands/setup.d.ts.map +1 -1
  10. package/dist/commands/setup.js +42 -0
  11. package/dist/commands/setup.js.map +1 -1
  12. package/dist/index.js +4 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/agent-help.d.ts.map +1 -1
  15. package/dist/lib/agent-help.js +37 -0
  16. package/dist/lib/agent-help.js.map +1 -1
  17. package/dist/lib/commit-context/fact-enricher.d.ts +40 -0
  18. package/dist/lib/commit-context/fact-enricher.d.ts.map +1 -0
  19. package/dist/lib/commit-context/fact-enricher.js +46 -0
  20. package/dist/lib/commit-context/fact-enricher.js.map +1 -0
  21. package/dist/lib/commit-context/git-reader.d.ts +23 -0
  22. package/dist/lib/commit-context/git-reader.d.ts.map +1 -0
  23. package/dist/lib/commit-context/git-reader.js +108 -0
  24. package/dist/lib/commit-context/git-reader.js.map +1 -0
  25. package/dist/lib/commit-context/heuristic-summarizer.d.ts +18 -0
  26. package/dist/lib/commit-context/heuristic-summarizer.d.ts.map +1 -0
  27. package/dist/lib/commit-context/heuristic-summarizer.js +124 -0
  28. package/dist/lib/commit-context/heuristic-summarizer.js.map +1 -0
  29. package/dist/lib/commit-context/hook-installer.d.ts +18 -0
  30. package/dist/lib/commit-context/hook-installer.d.ts.map +1 -0
  31. package/dist/lib/commit-context/hook-installer.js +140 -0
  32. package/dist/lib/commit-context/hook-installer.js.map +1 -0
  33. package/dist/lib/commit-context/index.d.ts +15 -0
  34. package/dist/lib/commit-context/index.d.ts.map +1 -0
  35. package/dist/lib/commit-context/index.js +55 -0
  36. package/dist/lib/commit-context/index.js.map +1 -0
  37. package/dist/lib/commit-context/llm-summarizer.d.ts +9 -0
  38. package/dist/lib/commit-context/llm-summarizer.d.ts.map +1 -0
  39. package/dist/lib/commit-context/llm-summarizer.js +145 -0
  40. package/dist/lib/commit-context/llm-summarizer.js.map +1 -0
  41. package/dist/lib/commit-context/local-cache.d.ts +35 -0
  42. package/dist/lib/commit-context/local-cache.d.ts.map +1 -0
  43. package/dist/lib/commit-context/local-cache.js +161 -0
  44. package/dist/lib/commit-context/local-cache.js.map +1 -0
  45. package/dist/lib/commit-context/privacy-filter.d.ts +13 -0
  46. package/dist/lib/commit-context/privacy-filter.d.ts.map +1 -0
  47. package/dist/lib/commit-context/privacy-filter.js +46 -0
  48. package/dist/lib/commit-context/privacy-filter.js.map +1 -0
  49. package/dist/lib/commit-context/session-reader.d.ts +36 -0
  50. package/dist/lib/commit-context/session-reader.d.ts.map +1 -0
  51. package/dist/lib/commit-context/session-reader.js +277 -0
  52. package/dist/lib/commit-context/session-reader.js.map +1 -0
  53. package/dist/lib/commit-context/types.d.ts +62 -0
  54. package/dist/lib/commit-context/types.d.ts.map +1 -0
  55. package/dist/lib/commit-context/types.js +6 -0
  56. package/dist/lib/commit-context/types.js.map +1 -0
  57. package/dist/lib/setup/rules-templates.d.ts.map +1 -1
  58. package/dist/lib/setup/rules-templates.js +2 -0
  59. package/dist/lib/setup/rules-templates.js.map +1 -1
  60. package/package.json +2 -1
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTrivialCommit = isTrivialCommit;
4
+ exports.summarizeCommit = summarizeCommit;
5
+ /** Patterns for trivial commits that should be skipped */
6
+ const TRIVIAL_PATTERNS = [
7
+ /^Merge\s+(branch|pull\s+request|remote)/i,
8
+ /^v?\d+\.\d+\.\d+/, // Version bumps like v1.2.3
9
+ /^\[skip ci\]/i,
10
+ /^wip$/i,
11
+ ];
12
+ /**
13
+ * Check if a commit is trivial and should be skipped.
14
+ */
15
+ function isTrivialCommit(git) {
16
+ // Merge commits
17
+ if (git.isMergeCommit) {
18
+ return { trivial: true, reason: 'merge commit' };
19
+ }
20
+ // Pattern-based detection
21
+ for (const pattern of TRIVIAL_PATTERNS) {
22
+ if (pattern.test(git.message)) {
23
+ // [skip ci] with <=1 file is trivial; with more files, it's worth capturing
24
+ if (/^\[skip ci\]/i.test(git.message) && git.filesChanged.length > 1) {
25
+ continue;
26
+ }
27
+ return { trivial: true, reason: `matches pattern: ${pattern.source}` };
28
+ }
29
+ }
30
+ // Bare "wip" with <=1 file
31
+ if (/^wip$/i.test(git.message) && git.filesChanged.length <= 1) {
32
+ return { trivial: true, reason: 'bare wip commit' };
33
+ }
34
+ return { trivial: false };
35
+ }
36
+ /**
37
+ * Build the structured markdown content for a commit context memory.
38
+ */
39
+ function buildContent(git, session) {
40
+ const lines = [];
41
+ // Header
42
+ lines.push(`## CommitContext: ${git.message} (${git.shortSha})`);
43
+ lines.push('');
44
+ // Metadata
45
+ lines.push(`**Commit:** ${git.sha}`);
46
+ lines.push(`**Branch:** ${git.branch}`);
47
+ if (session) {
48
+ const modelPart = session.model ? ` | **Model:** ${session.model}` : '';
49
+ lines.push(`**Agent:** ${session.agent}${modelPart}`);
50
+ }
51
+ // Files changed
52
+ const changeStats = `+${git.insertions} -${git.deletions}`;
53
+ lines.push(`**Files changed** (${git.filesChanged.length}): ${changeStats}`);
54
+ for (const file of git.filesChanged.slice(0, 20)) {
55
+ lines.push(`- ${file}`);
56
+ }
57
+ if (git.filesChanged.length > 20) {
58
+ lines.push(`- ... and ${git.filesChanged.length - 20} more`);
59
+ }
60
+ // Session info
61
+ if (session && session.totalToolCalls > 0) {
62
+ lines.push('');
63
+ lines.push(`### Tool calls (${session.totalToolCalls})`);
64
+ const toolSummary = session.toolCalls
65
+ .slice(0, 8)
66
+ .map((tc) => `${tc.name}: ${tc.count}`)
67
+ .join(', ');
68
+ lines.push(toolSummary);
69
+ }
70
+ if (session && session.recentPrompts.length > 0) {
71
+ lines.push('');
72
+ lines.push('### Recent prompts');
73
+ for (const prompt of session.recentPrompts) {
74
+ const truncated = prompt.length > 150 ? prompt.slice(0, 150) + '...' : prompt;
75
+ lines.push(`> ${truncated}`);
76
+ }
77
+ }
78
+ if (session && session.errors.length > 0) {
79
+ lines.push('');
80
+ lines.push('### Errors encountered');
81
+ for (const err of session.errors) {
82
+ lines.push(`- ${err}`);
83
+ }
84
+ }
85
+ return lines.join('\n');
86
+ }
87
+ /**
88
+ * Build the context field (max 200 chars).
89
+ * Format: "commit:<sha> branch:<branch> agent:<agent>"
90
+ */
91
+ function buildContextField(git, session) {
92
+ const agent = session?.agent || 'unknown';
93
+ const field = `commit:${git.shortSha} branch:${git.branch} agent:${agent}`;
94
+ return field.slice(0, 200);
95
+ }
96
+ /**
97
+ * Summarize a commit into a CommitContextData structure.
98
+ */
99
+ function summarizeCommit(git, session) {
100
+ const { trivial, reason } = isTrivialCommit(git);
101
+ if (trivial) {
102
+ return {
103
+ git,
104
+ session,
105
+ content: '',
106
+ contextField: '',
107
+ topics: ['commit-context'],
108
+ skipped: true,
109
+ skipReason: reason,
110
+ };
111
+ }
112
+ const content = buildContent(git, session);
113
+ const contextField = buildContextField(git, session);
114
+ const topics = ['commit-context'];
115
+ return {
116
+ git,
117
+ session,
118
+ content,
119
+ contextField,
120
+ topics,
121
+ skipped: false,
122
+ };
123
+ }
124
+ //# sourceMappingURL=heuristic-summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heuristic-summarizer.js","sourceRoot":"","sources":["../../../src/lib/commit-context/heuristic-summarizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface HookInstallResult {
2
+ hookPath: string;
3
+ action: 'created' | 'appended' | 'already-installed';
4
+ gitignoreUpdated: boolean;
5
+ }
6
+ /**
7
+ * Install the post-commit hook for CommitContext.
8
+ *
9
+ * @param projectRoot - Root of the git project
10
+ * @param dryRun - If true, don't write files
11
+ * @returns Install result
12
+ */
13
+ export declare function installHook(projectRoot: string, dryRun?: boolean): HookInstallResult;
14
+ /**
15
+ * Check if the post-commit hook is already installed.
16
+ */
17
+ export declare function isHookInstalled(projectRoot: string): boolean;
18
+ //# sourceMappingURL=hook-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-installer.d.ts","sourceRoot":"","sources":["../../../src/lib/commit-context/hook-installer.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,mBAAmB,CAAC;IACrD,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,iBAAiB,CA0B3F;AA+CD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ5D"}
@@ -0,0 +1,140 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.installHook = installHook;
37
+ exports.isHookInstalled = isHookInstalled;
38
+ /**
39
+ * Hook Installer — installs post-commit git hook for CommitContext capture.
40
+ *
41
+ * Detection order:
42
+ * 1. .husky/ directory → create/append .husky/post-commit
43
+ * 2. .git/hooks/ fallback → create/append .git/hooks/post-commit
44
+ *
45
+ * Always idempotent — checks for existing `mx hook post-commit` line.
46
+ * Also adds .mx/ to .gitignore.
47
+ */
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const HOOK_MARKER = 'mx hook post-commit';
51
+ const HOOK_SCRIPT = `#!/bin/sh
52
+ # MemNexus CommitContext — capture commit reasoning automatically
53
+ mx hook post-commit &
54
+ `;
55
+ /**
56
+ * Install the post-commit hook for CommitContext.
57
+ *
58
+ * @param projectRoot - Root of the git project
59
+ * @param dryRun - If true, don't write files
60
+ * @returns Install result
61
+ */
62
+ function installHook(projectRoot, dryRun = false) {
63
+ const hookPath = resolveHookPath(projectRoot);
64
+ const gitignoreUpdated = ensureGitignore(projectRoot, dryRun);
65
+ // Check if already installed
66
+ if (fs.existsSync(hookPath)) {
67
+ const existing = fs.readFileSync(hookPath, 'utf8');
68
+ if (existing.includes(HOOK_MARKER)) {
69
+ return { hookPath, action: 'already-installed', gitignoreUpdated };
70
+ }
71
+ // Append to existing hook
72
+ if (!dryRun) {
73
+ const appendContent = `\n# MemNexus CommitContext — capture commit reasoning automatically\nmx hook post-commit &\n`;
74
+ fs.appendFileSync(hookPath, appendContent, 'utf8');
75
+ }
76
+ return { hookPath, action: 'appended', gitignoreUpdated };
77
+ }
78
+ // Create new hook file
79
+ if (!dryRun) {
80
+ const dir = path.dirname(hookPath);
81
+ fs.mkdirSync(dir, { recursive: true });
82
+ fs.writeFileSync(hookPath, HOOK_SCRIPT, { mode: 0o755, encoding: 'utf8' });
83
+ }
84
+ return { hookPath, action: 'created', gitignoreUpdated };
85
+ }
86
+ /**
87
+ * Resolve the hook file path (husky or .git/hooks).
88
+ */
89
+ function resolveHookPath(projectRoot) {
90
+ // Check for husky directory
91
+ const huskyDir = path.join(projectRoot, '.husky');
92
+ if (fs.existsSync(huskyDir) && fs.statSync(huskyDir).isDirectory()) {
93
+ return path.join(huskyDir, 'post-commit');
94
+ }
95
+ // Fall back to .git/hooks
96
+ return path.join(projectRoot, '.git', 'hooks', 'post-commit');
97
+ }
98
+ /**
99
+ * Ensure .mx/ is in .gitignore.
100
+ * Returns true if .gitignore was updated.
101
+ */
102
+ function ensureGitignore(projectRoot, dryRun) {
103
+ const gitignorePath = path.join(projectRoot, '.gitignore');
104
+ const entry = '.mx/';
105
+ try {
106
+ if (fs.existsSync(gitignorePath)) {
107
+ const content = fs.readFileSync(gitignorePath, 'utf8');
108
+ if (content.includes(entry)) {
109
+ return false; // Already present
110
+ }
111
+ if (!dryRun) {
112
+ const separator = content.endsWith('\n') ? '' : '\n';
113
+ fs.appendFileSync(gitignorePath, `${separator}${entry}\n`, 'utf8');
114
+ }
115
+ return true;
116
+ }
117
+ // No .gitignore — create one
118
+ if (!dryRun) {
119
+ fs.writeFileSync(gitignorePath, `${entry}\n`, 'utf8');
120
+ }
121
+ return true;
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ }
127
+ /**
128
+ * Check if the post-commit hook is already installed.
129
+ */
130
+ function isHookInstalled(projectRoot) {
131
+ const hookPath = resolveHookPath(projectRoot);
132
+ try {
133
+ const content = fs.readFileSync(hookPath, 'utf8');
134
+ return content.includes(HOOK_MARKER);
135
+ }
136
+ catch {
137
+ return false;
138
+ }
139
+ }
140
+ //# sourceMappingURL=hook-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-installer.js","sourceRoot":"","sources":["../../../src/lib/commit-context/hook-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * CommitContext — automatic commit context capture.
3
+ *
4
+ * Barrel exports for all commit-context modules.
5
+ */
6
+ export * from './types';
7
+ export { readGitContext, parseShortStat, readDiffContent } from './git-reader';
8
+ export { readSessionContext, findClaudeProjectDir, findLatestSession, parseSessionTail, deriveProjectDirName, getTranscriptExcerpt, } from './session-reader';
9
+ export { summarizeCommit, isTrivialCommit } from './heuristic-summarizer';
10
+ export { summarizeWithLLM } from './llm-summarizer';
11
+ export { sanitize } from './privacy-filter';
12
+ export { enrichCommitFacts } from './fact-enricher';
13
+ export { writeCache, readCache, listCache, markSynced, markSyncError, getCacheDir, findProjectRoot, } from './local-cache';
14
+ export { installHook, isHookInstalled } from './hook-installer';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/commit-context/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,55 @@
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
+ exports.isHookInstalled = exports.installHook = exports.findProjectRoot = exports.getCacheDir = exports.markSyncError = exports.markSynced = exports.listCache = exports.readCache = exports.writeCache = exports.enrichCommitFacts = exports.sanitize = exports.summarizeWithLLM = exports.isTrivialCommit = exports.summarizeCommit = exports.getTranscriptExcerpt = exports.deriveProjectDirName = exports.parseSessionTail = exports.findLatestSession = exports.findClaudeProjectDir = exports.readSessionContext = exports.readDiffContent = exports.parseShortStat = exports.readGitContext = void 0;
18
+ /**
19
+ * CommitContext — automatic commit context capture.
20
+ *
21
+ * Barrel exports for all commit-context modules.
22
+ */
23
+ __exportStar(require("./types"), exports);
24
+ var git_reader_1 = require("./git-reader");
25
+ Object.defineProperty(exports, "readGitContext", { enumerable: true, get: function () { return git_reader_1.readGitContext; } });
26
+ Object.defineProperty(exports, "parseShortStat", { enumerable: true, get: function () { return git_reader_1.parseShortStat; } });
27
+ Object.defineProperty(exports, "readDiffContent", { enumerable: true, get: function () { return git_reader_1.readDiffContent; } });
28
+ var session_reader_1 = require("./session-reader");
29
+ Object.defineProperty(exports, "readSessionContext", { enumerable: true, get: function () { return session_reader_1.readSessionContext; } });
30
+ Object.defineProperty(exports, "findClaudeProjectDir", { enumerable: true, get: function () { return session_reader_1.findClaudeProjectDir; } });
31
+ Object.defineProperty(exports, "findLatestSession", { enumerable: true, get: function () { return session_reader_1.findLatestSession; } });
32
+ Object.defineProperty(exports, "parseSessionTail", { enumerable: true, get: function () { return session_reader_1.parseSessionTail; } });
33
+ Object.defineProperty(exports, "deriveProjectDirName", { enumerable: true, get: function () { return session_reader_1.deriveProjectDirName; } });
34
+ Object.defineProperty(exports, "getTranscriptExcerpt", { enumerable: true, get: function () { return session_reader_1.getTranscriptExcerpt; } });
35
+ var heuristic_summarizer_1 = require("./heuristic-summarizer");
36
+ Object.defineProperty(exports, "summarizeCommit", { enumerable: true, get: function () { return heuristic_summarizer_1.summarizeCommit; } });
37
+ Object.defineProperty(exports, "isTrivialCommit", { enumerable: true, get: function () { return heuristic_summarizer_1.isTrivialCommit; } });
38
+ var llm_summarizer_1 = require("./llm-summarizer");
39
+ Object.defineProperty(exports, "summarizeWithLLM", { enumerable: true, get: function () { return llm_summarizer_1.summarizeWithLLM; } });
40
+ var privacy_filter_1 = require("./privacy-filter");
41
+ Object.defineProperty(exports, "sanitize", { enumerable: true, get: function () { return privacy_filter_1.sanitize; } });
42
+ var fact_enricher_1 = require("./fact-enricher");
43
+ Object.defineProperty(exports, "enrichCommitFacts", { enumerable: true, get: function () { return fact_enricher_1.enrichCommitFacts; } });
44
+ var local_cache_1 = require("./local-cache");
45
+ Object.defineProperty(exports, "writeCache", { enumerable: true, get: function () { return local_cache_1.writeCache; } });
46
+ Object.defineProperty(exports, "readCache", { enumerable: true, get: function () { return local_cache_1.readCache; } });
47
+ Object.defineProperty(exports, "listCache", { enumerable: true, get: function () { return local_cache_1.listCache; } });
48
+ Object.defineProperty(exports, "markSynced", { enumerable: true, get: function () { return local_cache_1.markSynced; } });
49
+ Object.defineProperty(exports, "markSyncError", { enumerable: true, get: function () { return local_cache_1.markSyncError; } });
50
+ Object.defineProperty(exports, "getCacheDir", { enumerable: true, get: function () { return local_cache_1.getCacheDir; } });
51
+ Object.defineProperty(exports, "findProjectRoot", { enumerable: true, get: function () { return local_cache_1.findProjectRoot; } });
52
+ var hook_installer_1 = require("./hook-installer");
53
+ Object.defineProperty(exports, "installHook", { enumerable: true, get: function () { return hook_installer_1.installHook; } });
54
+ Object.defineProperty(exports, "isHookInstalled", { enumerable: true, get: function () { return hook_installer_1.isHookInstalled; } });
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/commit-context/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA;;;;GAIG;AACH,0CAAwB;AACxB,2CAA+E;AAAtE,4GAAA,cAAc,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,6GAAA,eAAe,OAAA;AACxD,mDAO0B;AANxB,oHAAA,kBAAkB,OAAA;AAClB,sHAAA,oBAAoB,OAAA;AACpB,mHAAA,iBAAiB,OAAA;AACjB,kHAAA,gBAAgB,OAAA;AAChB,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AAEtB,+DAA0E;AAAjE,uHAAA,eAAe,OAAA;AAAE,uHAAA,eAAe,OAAA;AACzC,mDAAoD;AAA3C,kHAAA,gBAAgB,OAAA;AACzB,mDAA4C;AAAnC,0GAAA,QAAQ,OAAA;AACjB,iDAAoD;AAA3C,kHAAA,iBAAiB,OAAA;AAC1B,6CAQuB;AAPrB,yGAAA,UAAU,OAAA;AACV,wGAAA,SAAS,OAAA;AACT,wGAAA,SAAS,OAAA;AACT,yGAAA,UAAU,OAAA;AACV,4GAAA,aAAa,OAAA;AACb,0GAAA,WAAW,OAAA;AACX,8GAAA,eAAe,OAAA;AAEjB,mDAAgE;AAAvD,6GAAA,WAAW,OAAA;AAAE,iHAAA,eAAe,OAAA"}
@@ -0,0 +1,9 @@
1
+ import type { GitContext, SessionContext, CommitContextData } from './types';
2
+ /**
3
+ * Summarize a commit using the Anthropic LLM API.
4
+ *
5
+ * @throws Error if ANTHROPIC_API_KEY is not set
6
+ * @throws Error if the API call fails
7
+ */
8
+ export declare function summarizeWithLLM(git: GitContext, session: SessionContext | undefined, diffContent: string, transcriptExcerpt: string, sessionMemories?: string): Promise<CommitContextData>;
9
+ //# sourceMappingURL=llm-summarizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-summarizer.d.ts","sourceRoot":"","sources":["../../../src/lib/commit-context/llm-summarizer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAuD7E;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,MAAM,EACzB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,iBAAiB,CAAC,CAwF5B"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.summarizeWithLLM = summarizeWithLLM;
7
+ /**
8
+ * LLM Summarizer — calls Anthropic Haiku to produce rich distilled commit context.
9
+ *
10
+ * Requires ANTHROPIC_API_KEY. Fails with clear error if not set.
11
+ * Use --summarizer heuristic to opt into heuristic-only mode (no key required).
12
+ */
13
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
14
+ const privacy_filter_1 = require("./privacy-filter");
15
+ const MODEL = 'claude-haiku-4-5-20251001';
16
+ const MAX_OUTPUT_TOKENS = 1024;
17
+ const DISTILLATION_PROMPT = `You are a commit context analyzer. Given git metadata, a diff, and optionally an AI agent transcript, produce a structured markdown summary of what was done and why.
18
+
19
+ Output format (use only sections that have content):
20
+
21
+ ## CommitContext: <commit message> (<short sha>)
22
+
23
+ <!-- commit-metadata
24
+ sha: <full sha>
25
+ short_sha: <short sha>
26
+ branch: <branch>
27
+ author: <author>
28
+ timestamp: <timestamp>
29
+ message: <commit message>
30
+ files:
31
+ <file list, one per line with " - " prefix>
32
+ insertions: <number>
33
+ deletions: <number>
34
+ parent_sha: <if available>
35
+ agent: <agent or "none">
36
+ model: <model or "none">
37
+ -->
38
+
39
+ **Branch:** <branch>
40
+ **Files changed** (<count>): +<insertions> -<deletions>
41
+ <file list as bullet points>
42
+
43
+ ### What changed
44
+ <1-3 sentence summary of the actual code changes>
45
+
46
+ ### Key decisions
47
+ <Bullet points of important technical decisions made, if evident from the diff or transcript>
48
+
49
+ ### Debugging path
50
+ <If there was debugging involved, summarize the path from problem to solution>
51
+
52
+ ### Patterns used
53
+ <Notable design patterns, conventions, or approaches used>
54
+
55
+ ### Gotchas
56
+ <Any pitfalls, edge cases, or non-obvious things to watch out for>
57
+
58
+ Rules:
59
+ - Be concise — this is a reference document, not a narrative
60
+ - Only include sections that have actual content
61
+ - Focus on the "why" more than the "what" when possible
62
+ - If no transcript is available, focus on what the diff tells you
63
+ - Include file paths in backticks
64
+ - Strip any secrets or API keys from the output`;
65
+ /**
66
+ * Summarize a commit using the Anthropic LLM API.
67
+ *
68
+ * @throws Error if ANTHROPIC_API_KEY is not set
69
+ * @throws Error if the API call fails
70
+ */
71
+ async function summarizeWithLLM(git, session, diffContent, transcriptExcerpt, sessionMemories) {
72
+ const apiKey = process.env.ANTHROPIC_API_KEY;
73
+ if (!apiKey) {
74
+ throw new Error('ANTHROPIC_API_KEY is not set. LLM summarization requires an Anthropic API key.\n' +
75
+ 'Set it with: export ANTHROPIC_API_KEY=your-key\n' +
76
+ 'Or use --summarizer heuristic to skip LLM summarization.');
77
+ }
78
+ const client = new sdk_1.default({ apiKey });
79
+ // Build the user message with all available context
80
+ const parts = [];
81
+ parts.push('## Git Metadata');
82
+ parts.push(`- SHA: ${git.sha}`);
83
+ parts.push(`- Short SHA: ${git.shortSha}`);
84
+ parts.push(`- Branch: ${git.branch}`);
85
+ parts.push(`- Message: ${git.message}`);
86
+ parts.push(`- Author: ${git.author}`);
87
+ parts.push(`- Timestamp: ${git.timestamp}`);
88
+ parts.push(`- Files (${git.filesChanged.length}): ${git.filesChanged.slice(0, 20).join(', ')}`);
89
+ parts.push(`- Changes: +${git.insertions} -${git.deletions}`);
90
+ if (diffContent) {
91
+ parts.push('\n## Diff Content');
92
+ parts.push(diffContent);
93
+ }
94
+ if (session) {
95
+ parts.push('\n## AI Agent Session');
96
+ parts.push(`- Agent: ${session.agent}`);
97
+ if (session.model)
98
+ parts.push(`- Model: ${session.model}`);
99
+ if (session.totalToolCalls > 0) {
100
+ const tools = session.toolCalls
101
+ .slice(0, 8)
102
+ .map((t) => `${t.name}:${t.count}`)
103
+ .join(', ');
104
+ parts.push(`- Tool calls (${session.totalToolCalls}): ${tools}`);
105
+ }
106
+ if (session.errors.length > 0) {
107
+ parts.push(`- Errors: ${session.errors.join('; ')}`);
108
+ }
109
+ }
110
+ if (transcriptExcerpt) {
111
+ parts.push('\n## Transcript Excerpt');
112
+ parts.push(transcriptExcerpt);
113
+ }
114
+ if (sessionMemories) {
115
+ parts.push('\n## Recent Session Memories');
116
+ parts.push(sessionMemories);
117
+ }
118
+ const userMessage = (0, privacy_filter_1.sanitize)(parts.join('\n'));
119
+ const response = await client.messages.create({
120
+ model: MODEL,
121
+ max_tokens: MAX_OUTPUT_TOKENS,
122
+ system: DISTILLATION_PROMPT,
123
+ messages: [{ role: 'user', content: userMessage }],
124
+ });
125
+ // Extract text from response
126
+ const content = response.content
127
+ .filter((block) => block.type === 'text')
128
+ .map((block) => block.text)
129
+ .join('\n');
130
+ const sanitizedContent = (0, privacy_filter_1.sanitize)(content);
131
+ // Build context field
132
+ const agent = session?.agent || 'unknown';
133
+ const contextField = `commit:${git.shortSha} branch:${git.branch} agent:${agent}`.slice(0, 200);
134
+ // Build topics
135
+ const topics = ['commit-context', `branch:${git.branch}`];
136
+ return {
137
+ git,
138
+ session,
139
+ content: sanitizedContent,
140
+ contextField,
141
+ topics,
142
+ skipped: false,
143
+ };
144
+ }
145
+ //# sourceMappingURL=llm-summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-summarizer.js","sourceRoot":"","sources":["../../../src/lib/commit-context/llm-summarizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { CacheEntry } from './types';
2
+ /**
3
+ * Get the cache directory path for a project root.
4
+ */
5
+ export declare function getCacheDir(projectRoot: string): string;
6
+ /**
7
+ * Write a cache entry to disk.
8
+ */
9
+ export declare function writeCache(projectRoot: string, entry: CacheEntry): void;
10
+ /**
11
+ * Read a cache entry by short SHA.
12
+ * Returns undefined if not found.
13
+ */
14
+ export declare function readCache(projectRoot: string, shortSha: string): CacheEntry | undefined;
15
+ /**
16
+ * List all cached entries, optionally filtered by sync status.
17
+ * Returns entries sorted by timestamp (newest first).
18
+ */
19
+ export declare function listCache(projectRoot: string, options?: {
20
+ unsynced?: boolean;
21
+ limit?: number;
22
+ }): CacheEntry[];
23
+ /**
24
+ * Mark a cache entry as synced with a memory ID.
25
+ */
26
+ export declare function markSynced(projectRoot: string, shortSha: string, memoryId: string): void;
27
+ /**
28
+ * Mark a cache entry with a sync error.
29
+ */
30
+ export declare function markSyncError(projectRoot: string, shortSha: string, error: string): void;
31
+ /**
32
+ * Find the git project root by looking for .git directory.
33
+ */
34
+ export declare function findProjectRoot(cwd?: string): string | undefined;
35
+ //# sourceMappingURL=local-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-cache.d.ts","sourceRoot":"","sources":["../../../src/lib/commit-context/local-cache.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1C;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD;AAkBD;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAIvE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAQvF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,UAAU,EAAE,CA4Bd;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQxF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAOxF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,SAAS,CAS/E"}