gitmem-mcp 0.2.0 → 1.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.
- package/CHANGELOG.md +17 -1
- package/CLAUDE.md.template +63 -55
- package/README.md +149 -120
- package/bin/gitmem.js +377 -25
- package/bin/init-wizard.js +642 -0
- package/bin/uninstall.js +288 -0
- package/dist/commands/check.js +20 -20
- package/dist/commands/check.js.map +1 -1
- package/dist/constants/closing-questions.d.ts +6 -0
- package/dist/constants/closing-questions.d.ts.map +1 -1
- package/dist/constants/closing-questions.js +65 -0
- package/dist/constants/closing-questions.js.map +1 -1
- package/dist/hooks/format-utils.d.ts +52 -0
- package/dist/hooks/format-utils.d.ts.map +1 -0
- package/dist/hooks/format-utils.js +89 -0
- package/dist/hooks/format-utils.js.map +1 -0
- package/dist/hooks/quick-retrieve.d.ts +30 -0
- package/dist/hooks/quick-retrieve.d.ts.map +1 -0
- package/dist/hooks/quick-retrieve.js +149 -0
- package/dist/hooks/quick-retrieve.js.map +1 -0
- package/dist/index.js +0 -0
- package/dist/schemas/active-sessions.d.ts +8 -8
- package/dist/schemas/analyze.d.ts +3 -3
- package/dist/schemas/common.d.ts +2 -2
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +1 -1
- package/dist/schemas/common.js.map +1 -1
- package/dist/schemas/create-decision.d.ts +3 -3
- package/dist/schemas/create-learning.d.ts +13 -13
- package/dist/schemas/log.d.ts +3 -3
- package/dist/schemas/prepare-context.d.ts +3 -3
- package/dist/schemas/recall.d.ts +3 -3
- package/dist/schemas/record-scar-usage-batch.d.ts +8 -3
- package/dist/schemas/record-scar-usage-batch.d.ts.map +1 -1
- package/dist/schemas/record-scar-usage.d.ts +3 -0
- package/dist/schemas/record-scar-usage.d.ts.map +1 -1
- package/dist/schemas/record-scar-usage.js +1 -0
- package/dist/schemas/record-scar-usage.js.map +1 -1
- package/dist/schemas/registry.d.ts +18 -0
- package/dist/schemas/registry.d.ts.map +1 -0
- package/dist/schemas/registry.js +158 -0
- package/dist/schemas/registry.js.map +1 -0
- package/dist/schemas/save-transcript.d.ts +3 -3
- package/dist/schemas/search-transcripts.d.ts +33 -0
- package/dist/schemas/search-transcripts.d.ts.map +1 -0
- package/dist/schemas/search-transcripts.js +26 -0
- package/dist/schemas/search-transcripts.js.map +1 -0
- package/dist/schemas/search.d.ts +3 -3
- package/dist/schemas/session-close.d.ts +43 -15
- package/dist/schemas/session-close.d.ts.map +1 -1
- package/dist/schemas/session-close.js +7 -2
- package/dist/schemas/session-close.js.map +1 -1
- package/dist/schemas/session-start.d.ts +3 -3
- package/dist/schemas/thread.d.ts +3 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +82 -28
- package/dist/server.js.map +1 -1
- package/dist/services/active-sessions.d.ts +2 -1
- package/dist/services/active-sessions.d.ts.map +1 -1
- package/dist/services/active-sessions.js +130 -84
- package/dist/services/active-sessions.js.map +1 -1
- package/dist/services/analytics.d.ts.map +1 -1
- package/dist/services/analytics.js +1 -0
- package/dist/services/analytics.js.map +1 -1
- package/dist/services/behavioral-decay.d.ts +40 -0
- package/dist/services/behavioral-decay.d.ts.map +1 -0
- package/dist/services/behavioral-decay.js +110 -0
- package/dist/services/behavioral-decay.js.map +1 -0
- package/dist/services/bm25.d.ts +39 -0
- package/dist/services/bm25.d.ts.map +1 -0
- package/dist/services/bm25.js +132 -0
- package/dist/services/bm25.js.map +1 -0
- package/dist/services/cache.d.ts.map +1 -1
- package/dist/services/cache.js +9 -8
- package/dist/services/cache.js.map +1 -1
- package/dist/services/cache.test.js +17 -17
- package/dist/services/cache.test.js.map +1 -1
- package/dist/services/compliance-validator.d.ts.map +1 -1
- package/dist/services/compliance-validator.js +12 -1
- package/dist/services/compliance-validator.js.map +1 -1
- package/dist/services/display-protocol.d.ts +31 -0
- package/dist/services/display-protocol.d.ts.map +1 -0
- package/dist/services/display-protocol.js +73 -0
- package/dist/services/display-protocol.js.map +1 -0
- package/dist/services/effect-tracker.d.ts +81 -0
- package/dist/services/effect-tracker.d.ts.map +1 -0
- package/dist/services/effect-tracker.js +181 -0
- package/dist/services/effect-tracker.js.map +1 -0
- package/dist/services/file-lock.d.ts +31 -0
- package/dist/services/file-lock.d.ts.map +1 -0
- package/dist/services/file-lock.js +124 -0
- package/dist/services/file-lock.js.map +1 -0
- package/dist/services/gitmem-dir.d.ts +7 -0
- package/dist/services/gitmem-dir.d.ts.map +1 -1
- package/dist/services/gitmem-dir.js +21 -0
- package/dist/services/gitmem-dir.js.map +1 -1
- package/dist/services/local-file-storage.d.ts +3 -2
- package/dist/services/local-file-storage.d.ts.map +1 -1
- package/dist/services/local-file-storage.js +30 -43
- package/dist/services/local-file-storage.js.map +1 -1
- package/dist/services/local-vector-search.d.ts +10 -9
- package/dist/services/local-vector-search.d.ts.map +1 -1
- package/dist/services/local-vector-search.js +28 -23
- package/dist/services/local-vector-search.js.map +1 -1
- package/dist/services/metrics.d.ts +7 -2
- package/dist/services/metrics.d.ts.map +1 -1
- package/dist/services/metrics.js +41 -33
- package/dist/services/metrics.js.map +1 -1
- package/dist/services/session-state.d.ts +8 -0
- package/dist/services/session-state.d.ts.map +1 -1
- package/dist/services/session-state.js +9 -2
- package/dist/services/session-state.js.map +1 -1
- package/dist/services/startup.d.ts +12 -13
- package/dist/services/startup.d.ts.map +1 -1
- package/dist/services/startup.js +104 -57
- package/dist/services/startup.js.map +1 -1
- package/dist/services/supabase-client.d.ts +2 -1
- package/dist/services/supabase-client.d.ts.map +1 -1
- package/dist/services/supabase-client.js +22 -16
- package/dist/services/supabase-client.js.map +1 -1
- package/dist/services/thread-dedup.d.ts +9 -0
- package/dist/services/thread-dedup.d.ts.map +1 -1
- package/dist/services/thread-dedup.js +27 -0
- package/dist/services/thread-dedup.js.map +1 -1
- package/dist/services/thread-manager.d.ts.map +1 -1
- package/dist/services/thread-manager.js +38 -16
- package/dist/services/thread-manager.js.map +1 -1
- package/dist/services/thread-suggestions.d.ts.map +1 -1
- package/dist/services/thread-suggestions.js +1 -1
- package/dist/services/thread-suggestions.js.map +1 -1
- package/dist/services/thread-supabase.d.ts +0 -1
- package/dist/services/thread-supabase.d.ts.map +1 -1
- package/dist/services/thread-supabase.js +83 -54
- package/dist/services/thread-supabase.js.map +1 -1
- package/dist/services/timezone.d.ts.map +1 -1
- package/dist/services/timezone.js +1 -0
- package/dist/services/timezone.js.map +1 -1
- package/dist/services/transcript-chunker.d.ts.map +1 -1
- package/dist/services/transcript-chunker.js +18 -4
- package/dist/services/transcript-chunker.js.map +1 -1
- package/dist/services/variant-generation.d.ts +41 -0
- package/dist/services/variant-generation.d.ts.map +1 -0
- package/dist/services/variant-generation.js +263 -0
- package/dist/services/variant-generation.js.map +1 -0
- package/dist/tools/absorb-observations.d.ts.map +1 -1
- package/dist/tools/absorb-observations.js +9 -0
- package/dist/tools/absorb-observations.js.map +1 -1
- package/dist/tools/analyze.d.ts.map +1 -1
- package/dist/tools/analyze.js +13 -2
- package/dist/tools/analyze.js.map +1 -1
- package/dist/tools/archive-learning.d.ts +28 -0
- package/dist/tools/archive-learning.d.ts.map +1 -0
- package/dist/tools/archive-learning.js +81 -0
- package/dist/tools/archive-learning.js.map +1 -0
- package/dist/tools/cleanup-threads.d.ts +1 -0
- package/dist/tools/cleanup-threads.d.ts.map +1 -1
- package/dist/tools/cleanup-threads.js +111 -18
- package/dist/tools/cleanup-threads.js.map +1 -1
- package/dist/tools/confirm-scars.d.ts.map +1 -1
- package/dist/tools/confirm-scars.js +8 -2
- package/dist/tools/confirm-scars.js.map +1 -1
- package/dist/tools/create-decision.d.ts.map +1 -1
- package/dist/tools/create-decision.js +11 -8
- package/dist/tools/create-decision.js.map +1 -1
- package/dist/tools/create-learning.d.ts.map +1 -1
- package/dist/tools/create-learning.js +35 -11
- package/dist/tools/create-learning.js.map +1 -1
- package/dist/tools/create-linear-issue.d.ts +18 -0
- package/dist/tools/create-linear-issue.d.ts.map +1 -0
- package/dist/tools/create-linear-issue.js +197 -0
- package/dist/tools/create-linear-issue.js.map +1 -0
- package/dist/tools/create-thread.d.ts +2 -1
- package/dist/tools/create-thread.d.ts.map +1 -1
- package/dist/tools/create-thread.js +9 -4
- package/dist/tools/create-thread.js.map +1 -1
- package/dist/tools/definitions.d.ts +785 -34
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +239 -95
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/dismiss-suggestion.d.ts +1 -0
- package/dist/tools/dismiss-suggestion.d.ts.map +1 -1
- package/dist/tools/dismiss-suggestion.js +4 -0
- package/dist/tools/dismiss-suggestion.js.map +1 -1
- package/dist/tools/graph-traverse.d.ts +1 -0
- package/dist/tools/graph-traverse.d.ts.map +1 -1
- package/dist/tools/graph-traverse.js +24 -9
- package/dist/tools/graph-traverse.js.map +1 -1
- package/dist/tools/list-threads.d.ts.map +1 -1
- package/dist/tools/list-threads.js +49 -5
- package/dist/tools/list-threads.js.map +1 -1
- package/dist/tools/log.d.ts +1 -0
- package/dist/tools/log.d.ts.map +1 -1
- package/dist/tools/log.js +84 -17
- package/dist/tools/log.js.map +1 -1
- package/dist/tools/prepare-context.d.ts +1 -0
- package/dist/tools/prepare-context.d.ts.map +1 -1
- package/dist/tools/prepare-context.js +15 -85
- package/dist/tools/prepare-context.js.map +1 -1
- package/dist/tools/promote-suggestion.d.ts +1 -0
- package/dist/tools/promote-suggestion.d.ts.map +1 -1
- package/dist/tools/promote-suggestion.js +5 -0
- package/dist/tools/promote-suggestion.js.map +1 -1
- package/dist/tools/recall.d.ts +2 -0
- package/dist/tools/recall.d.ts.map +1 -1
- package/dist/tools/recall.js +43 -10
- package/dist/tools/recall.js.map +1 -1
- package/dist/tools/recall.test.js +6 -6
- package/dist/tools/recall.test.js.map +1 -1
- package/dist/tools/record-scar-usage-batch.d.ts.map +1 -1
- package/dist/tools/record-scar-usage-batch.js +13 -0
- package/dist/tools/record-scar-usage-batch.js.map +1 -1
- package/dist/tools/record-scar-usage.d.ts.map +1 -1
- package/dist/tools/record-scar-usage.js +6 -0
- package/dist/tools/record-scar-usage.js.map +1 -1
- package/dist/tools/resolve-thread.d.ts.map +1 -1
- package/dist/tools/resolve-thread.js +57 -6
- package/dist/tools/resolve-thread.js.map +1 -1
- package/dist/tools/save-transcript.d.ts +1 -0
- package/dist/tools/save-transcript.d.ts.map +1 -1
- package/dist/tools/save-transcript.js +3 -1
- package/dist/tools/save-transcript.js.map +1 -1
- package/dist/tools/search-transcripts.d.ts +44 -0
- package/dist/tools/search-transcripts.d.ts.map +1 -0
- package/dist/tools/search-transcripts.js +158 -0
- package/dist/tools/search-transcripts.js.map +1 -0
- package/dist/tools/search.d.ts +1 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +74 -3
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/session-close.d.ts.map +1 -1
- package/dist/tools/session-close.js +563 -326
- package/dist/tools/session-close.js.map +1 -1
- package/dist/tools/session-start.d.ts +10 -6
- package/dist/tools/session-start.d.ts.map +1 -1
- package/dist/tools/session-start.js +317 -426
- package/dist/tools/session-start.js.map +1 -1
- package/dist/types/index.d.ts +37 -4
- package/dist/types/index.d.ts.map +1 -1
- package/hooks/.claude-plugin/plugin.json +8 -0
- package/hooks/README.md +107 -0
- package/hooks/hooks/hooks.json +123 -0
- package/hooks/scripts/auto-retrieve-hook.sh +163 -0
- package/hooks/scripts/post-tool-use.sh +112 -0
- package/hooks/scripts/recall-check.sh +213 -0
- package/hooks/scripts/session-close-check.sh +116 -0
- package/hooks/scripts/session-start.sh +233 -0
- package/hooks/tests/test-hooks.sh +577 -0
- package/package.json +4 -2
- package/schema/setup.sql +1 -1
package/bin/gitmem.js
CHANGED
|
@@ -4,15 +4,30 @@
|
|
|
4
4
|
* GitMem CLI
|
|
5
5
|
*
|
|
6
6
|
* Commands:
|
|
7
|
-
* gitmem
|
|
8
|
-
* gitmem
|
|
9
|
-
* gitmem
|
|
10
|
-
* gitmem
|
|
7
|
+
* gitmem init — Interactive setup wizard (detects, prompts, merges)
|
|
8
|
+
* gitmem uninstall — Clean reverse of everything init did
|
|
9
|
+
* gitmem setup — Output SQL to paste into Supabase SQL Editor (pro/dev)
|
|
10
|
+
* gitmem configure — Generate .mcp.json entry for Claude Code
|
|
11
|
+
* gitmem check — Run diagnostic health check
|
|
12
|
+
* gitmem install-hooks — Install Claude Code hooks plugin
|
|
13
|
+
* gitmem uninstall-hooks — Remove Claude Code hooks plugin
|
|
14
|
+
* gitmem server — Start MCP server (default)
|
|
11
15
|
*/
|
|
12
16
|
|
|
13
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
readFileSync,
|
|
19
|
+
writeFileSync,
|
|
20
|
+
mkdirSync,
|
|
21
|
+
existsSync,
|
|
22
|
+
cpSync,
|
|
23
|
+
rmSync,
|
|
24
|
+
readdirSync,
|
|
25
|
+
chmodSync,
|
|
26
|
+
statSync,
|
|
27
|
+
} from "fs";
|
|
14
28
|
import { dirname, join } from "path";
|
|
15
29
|
import { fileURLToPath } from "url";
|
|
30
|
+
import { homedir } from "os";
|
|
16
31
|
|
|
17
32
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
33
|
const command = process.argv[2];
|
|
@@ -22,26 +37,32 @@ function printUsage() {
|
|
|
22
37
|
GitMem — Institutional Memory for AI Coding
|
|
23
38
|
|
|
24
39
|
Usage:
|
|
25
|
-
npx gitmem setup
|
|
26
|
-
npx gitmem init
|
|
27
|
-
npx gitmem
|
|
28
|
-
npx gitmem
|
|
29
|
-
npx gitmem
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
npx gitmem init Interactive setup wizard (recommended)
|
|
41
|
+
npx gitmem init --yes Non-interactive setup (accept all defaults)
|
|
42
|
+
npx gitmem init --dry-run Show what would be configured
|
|
43
|
+
npx gitmem uninstall Clean removal of gitmem from project
|
|
44
|
+
npx gitmem uninstall --all Also delete .gitmem/ data directory
|
|
45
|
+
|
|
46
|
+
Other commands:
|
|
47
|
+
npx gitmem setup Output SQL for Supabase schema setup (pro/dev tier)
|
|
48
|
+
npx gitmem configure Generate .mcp.json config for Claude Code
|
|
49
|
+
npx gitmem check Run diagnostic health check
|
|
50
|
+
npx gitmem check --full Full diagnostic with benchmarks
|
|
51
|
+
npx gitmem install-hooks Install Claude Code hooks (standalone)
|
|
52
|
+
npx gitmem uninstall-hooks Remove Claude Code hooks (standalone)
|
|
53
|
+
npx gitmem server Start MCP server (default)
|
|
54
|
+
npx gitmem help Show this help message
|
|
55
|
+
|
|
56
|
+
Quick Start:
|
|
57
|
+
npx gitmem init One command sets up everything
|
|
58
|
+
npx gitmem uninstall One command removes everything
|
|
36
59
|
|
|
37
60
|
Pro Tier (with Supabase):
|
|
38
61
|
1. Create free Supabase project → database.new
|
|
39
62
|
2. npx gitmem setup (copy SQL → Supabase SQL Editor)
|
|
40
|
-
3.
|
|
41
|
-
4. npx gitmem
|
|
42
|
-
5.
|
|
43
|
-
6. Copy CLAUDE.md.template into your project
|
|
44
|
-
7. Start coding — memory is active!
|
|
63
|
+
3. Set SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY env vars
|
|
64
|
+
4. npx gitmem init (auto-detects pro tier)
|
|
65
|
+
5. Start coding — memory is active!
|
|
45
66
|
`);
|
|
46
67
|
}
|
|
47
68
|
|
|
@@ -64,6 +85,10 @@ async function cmdInit() {
|
|
|
64
85
|
const supabaseUrl = process.env.SUPABASE_URL;
|
|
65
86
|
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
66
87
|
|
|
88
|
+
// Parse --project flag
|
|
89
|
+
const projectIdx = process.argv.indexOf("--project");
|
|
90
|
+
const projectArg = projectIdx !== -1 ? process.argv[projectIdx + 1] : null;
|
|
91
|
+
|
|
67
92
|
let starterScars;
|
|
68
93
|
try {
|
|
69
94
|
const scarsPath = join(__dirname, "..", "schema", "starter-scars.json");
|
|
@@ -83,6 +108,29 @@ async function cmdInit() {
|
|
|
83
108
|
mkdirSync(gitmemDir, { recursive: true });
|
|
84
109
|
}
|
|
85
110
|
|
|
111
|
+
// Write config.json (with project if specified via --project)
|
|
112
|
+
const configPath = join(gitmemDir, "config.json");
|
|
113
|
+
if (!existsSync(configPath)) {
|
|
114
|
+
const config = {};
|
|
115
|
+
if (projectArg) config.project = projectArg;
|
|
116
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
117
|
+
if (projectArg) {
|
|
118
|
+
console.log(` + Created .gitmem/config.json (project: "${projectArg}")`);
|
|
119
|
+
} else {
|
|
120
|
+
console.log(" + Created .gitmem/config.json");
|
|
121
|
+
}
|
|
122
|
+
} else if (projectArg) {
|
|
123
|
+
// Config exists — update project field
|
|
124
|
+
try {
|
|
125
|
+
const existing = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
126
|
+
existing.project = projectArg;
|
|
127
|
+
writeFileSync(configPath, JSON.stringify(existing, null, 2));
|
|
128
|
+
console.log(` + Updated .gitmem/config.json project: "${projectArg}"`);
|
|
129
|
+
} catch {
|
|
130
|
+
console.warn(" (Could not update config.json)");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
86
134
|
const learningsPath = join(gitmemDir, "learnings.json");
|
|
87
135
|
let existing = [];
|
|
88
136
|
if (existsSync(learningsPath)) {
|
|
@@ -116,6 +164,29 @@ async function cmdInit() {
|
|
|
116
164
|
}
|
|
117
165
|
}
|
|
118
166
|
|
|
167
|
+
// Auto-allow gitmem MCP tools in Claude Code project settings
|
|
168
|
+
const claudeDir = join(process.cwd(), ".claude");
|
|
169
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
170
|
+
try {
|
|
171
|
+
let settings = {};
|
|
172
|
+
if (existsSync(settingsPath)) {
|
|
173
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
174
|
+
} else {
|
|
175
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
176
|
+
}
|
|
177
|
+
const permissions = settings.permissions || {};
|
|
178
|
+
const allow = permissions.allow || [];
|
|
179
|
+
const pattern = "mcp__gitmem__*";
|
|
180
|
+
if (!allow.includes(pattern)) {
|
|
181
|
+
allow.push(pattern);
|
|
182
|
+
settings.permissions = { ...permissions, allow };
|
|
183
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
184
|
+
console.log(" + Auto-allowed gitmem tools in .claude/settings.json");
|
|
185
|
+
}
|
|
186
|
+
} catch (err) {
|
|
187
|
+
console.warn(" (Could not update .claude/settings.json — you may need to allow gitmem tools manually)");
|
|
188
|
+
}
|
|
189
|
+
|
|
119
190
|
console.log("");
|
|
120
191
|
console.log(`Done: ${added} new scars added to .gitmem/learnings.json`);
|
|
121
192
|
console.log("");
|
|
@@ -127,6 +198,23 @@ async function cmdInit() {
|
|
|
127
198
|
return;
|
|
128
199
|
}
|
|
129
200
|
|
|
201
|
+
// Write/update .gitmem/config.json if --project specified
|
|
202
|
+
if (projectArg) {
|
|
203
|
+
const gitmemDir = join(process.cwd(), ".gitmem");
|
|
204
|
+
if (!existsSync(gitmemDir)) {
|
|
205
|
+
mkdirSync(gitmemDir, { recursive: true });
|
|
206
|
+
}
|
|
207
|
+
const configPath = join(gitmemDir, "config.json");
|
|
208
|
+
let config = {};
|
|
209
|
+
if (existsSync(configPath)) {
|
|
210
|
+
try { config = JSON.parse(readFileSync(configPath, "utf-8")); } catch {}
|
|
211
|
+
}
|
|
212
|
+
config.project = projectArg;
|
|
213
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
214
|
+
console.log(` + Set project: "${projectArg}" in .gitmem/config.json`);
|
|
215
|
+
console.log("");
|
|
216
|
+
}
|
|
217
|
+
|
|
130
218
|
// Pro/Dev tier: load into Supabase via REST API
|
|
131
219
|
const tablePrefix = process.env.GITMEM_TABLE_PREFIX || "gitmem_";
|
|
132
220
|
const restUrl = `${supabaseUrl}/rest/v1/${tablePrefix}learnings`;
|
|
@@ -164,6 +252,29 @@ async function cmdInit() {
|
|
|
164
252
|
}
|
|
165
253
|
}
|
|
166
254
|
|
|
255
|
+
// Auto-allow gitmem MCP tools in Claude Code project settings
|
|
256
|
+
const claudeDir = join(process.cwd(), ".claude");
|
|
257
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
258
|
+
try {
|
|
259
|
+
let settings = {};
|
|
260
|
+
if (existsSync(settingsPath)) {
|
|
261
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
262
|
+
} else {
|
|
263
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
264
|
+
}
|
|
265
|
+
const permissions = settings.permissions || {};
|
|
266
|
+
const allow = permissions.allow || [];
|
|
267
|
+
const pattern = "mcp__gitmem__*";
|
|
268
|
+
if (!allow.includes(pattern)) {
|
|
269
|
+
allow.push(pattern);
|
|
270
|
+
settings.permissions = { ...permissions, allow };
|
|
271
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
272
|
+
console.log(" + Auto-allowed gitmem tools in .claude/settings.json");
|
|
273
|
+
}
|
|
274
|
+
} catch (err) {
|
|
275
|
+
console.warn(" (Could not update .claude/settings.json — you may need to allow gitmem tools manually)");
|
|
276
|
+
}
|
|
277
|
+
|
|
167
278
|
console.log("");
|
|
168
279
|
console.log(`Done: ${loaded} loaded, ${failed} failed`);
|
|
169
280
|
|
|
@@ -183,7 +294,7 @@ function cmdConfigure() {
|
|
|
183
294
|
mcpServers: {
|
|
184
295
|
gitmem: {
|
|
185
296
|
command: "npx",
|
|
186
|
-
args: ["-y", "
|
|
297
|
+
args: ["-y", "gitmem-mcp"],
|
|
187
298
|
},
|
|
188
299
|
},
|
|
189
300
|
};
|
|
@@ -202,7 +313,7 @@ function cmdConfigure() {
|
|
|
202
313
|
mcpServers: {
|
|
203
314
|
gitmem: {
|
|
204
315
|
command: "npx",
|
|
205
|
-
args: ["-y", "
|
|
316
|
+
args: ["-y", "gitmem-mcp"],
|
|
206
317
|
env: {
|
|
207
318
|
SUPABASE_URL: "https://YOUR_PROJECT.supabase.co",
|
|
208
319
|
SUPABASE_SERVICE_ROLE_KEY: "eyJ...",
|
|
@@ -238,7 +349,7 @@ function cmdConfigure() {
|
|
|
238
349
|
*/
|
|
239
350
|
async function cmdSessionStart() {
|
|
240
351
|
const args = process.argv.slice(3);
|
|
241
|
-
let project =
|
|
352
|
+
let project = undefined;
|
|
242
353
|
let agentIdentity = undefined;
|
|
243
354
|
|
|
244
355
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -347,16 +458,257 @@ async function cmdSessionRefresh() {
|
|
|
347
458
|
}
|
|
348
459
|
}
|
|
349
460
|
|
|
461
|
+
/**
|
|
462
|
+
* Install gitmem hooks as project-level hooks in .claude/settings.json
|
|
463
|
+
*
|
|
464
|
+
* Writes hook entries pointing to scripts in node_modules/gitmem-mcp/hooks/scripts/.
|
|
465
|
+
* No plugin registration needed — Claude Code reads hooks directly from settings.
|
|
466
|
+
* Use --force to overwrite existing hook entries.
|
|
467
|
+
*/
|
|
468
|
+
function cmdInstallHooks() {
|
|
469
|
+
const force = process.argv.includes("--force");
|
|
470
|
+
const scriptsDir = join(__dirname, "..", "hooks", "scripts");
|
|
471
|
+
const claudeDir = join(process.cwd(), ".claude");
|
|
472
|
+
const settingsPath = join(claudeDir, "settings.json");
|
|
473
|
+
|
|
474
|
+
console.log("GitMem Hooks — Install");
|
|
475
|
+
console.log("======================");
|
|
476
|
+
console.log("");
|
|
477
|
+
|
|
478
|
+
// Verify bundled scripts exist
|
|
479
|
+
if (!existsSync(scriptsDir) || !existsSync(join(scriptsDir, "session-start.sh"))) {
|
|
480
|
+
console.error("Error: Hook scripts not found at:", scriptsDir);
|
|
481
|
+
console.error("Ensure gitmem-mcp is installed correctly.");
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Make scripts executable
|
|
486
|
+
for (const file of readdirSync(scriptsDir)) {
|
|
487
|
+
if (file.endsWith(".sh")) {
|
|
488
|
+
chmodSync(join(scriptsDir, file), 0o755);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Build hook entries using node_modules path (resolved from CWD)
|
|
493
|
+
const relScripts = "node_modules/gitmem-mcp/hooks/scripts";
|
|
494
|
+
const gitmemHooks = {
|
|
495
|
+
SessionStart: [
|
|
496
|
+
{
|
|
497
|
+
hooks: [
|
|
498
|
+
{
|
|
499
|
+
type: "command",
|
|
500
|
+
command: `bash ${relScripts}/session-start.sh`,
|
|
501
|
+
statusMessage: "Initializing GitMem session...",
|
|
502
|
+
timeout: 5000,
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
PreToolUse: [
|
|
508
|
+
{ matcher: "Bash", hooks: [{ type: "command", command: `bash ${relScripts}/recall-check.sh`, timeout: 5000 }] },
|
|
509
|
+
{ matcher: "Write", hooks: [{ type: "command", command: `bash ${relScripts}/recall-check.sh`, timeout: 5000 }] },
|
|
510
|
+
{ matcher: "Edit", hooks: [{ type: "command", command: `bash ${relScripts}/recall-check.sh`, timeout: 5000 }] },
|
|
511
|
+
],
|
|
512
|
+
PostToolUse: [
|
|
513
|
+
{ matcher: "mcp__gitmem__recall", hooks: [{ type: "command", command: `bash ${relScripts}/post-tool-use.sh`, timeout: 3000 }] },
|
|
514
|
+
{ matcher: "mcp__gitmem__search", hooks: [{ type: "command", command: `bash ${relScripts}/post-tool-use.sh`, timeout: 3000 }] },
|
|
515
|
+
{ matcher: "Bash", hooks: [{ type: "command", command: `bash ${relScripts}/post-tool-use.sh`, timeout: 3000 }] },
|
|
516
|
+
{ matcher: "Write", hooks: [{ type: "command", command: `bash ${relScripts}/post-tool-use.sh`, timeout: 3000 }] },
|
|
517
|
+
{ matcher: "Edit", hooks: [{ type: "command", command: `bash ${relScripts}/post-tool-use.sh`, timeout: 3000 }] },
|
|
518
|
+
],
|
|
519
|
+
Stop: [
|
|
520
|
+
{
|
|
521
|
+
hooks: [
|
|
522
|
+
{
|
|
523
|
+
type: "command",
|
|
524
|
+
command: `bash ${relScripts}/session-close-check.sh`,
|
|
525
|
+
timeout: 5000,
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
},
|
|
529
|
+
],
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
// Read existing settings or create new
|
|
533
|
+
let settings = {};
|
|
534
|
+
if (existsSync(settingsPath)) {
|
|
535
|
+
try {
|
|
536
|
+
settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
537
|
+
} catch {
|
|
538
|
+
console.warn(" Warning: Could not parse existing .claude/settings.json, creating fresh");
|
|
539
|
+
}
|
|
540
|
+
} else {
|
|
541
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Check if hooks already exist
|
|
545
|
+
if (settings.hooks && !force) {
|
|
546
|
+
const hasGitmem = JSON.stringify(settings.hooks).includes("gitmem");
|
|
547
|
+
if (hasGitmem) {
|
|
548
|
+
console.log("GitMem hooks already installed in .claude/settings.json");
|
|
549
|
+
console.log("");
|
|
550
|
+
console.log("To reinstall (overwrite), run:");
|
|
551
|
+
console.log(" npx gitmem install-hooks --force");
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Merge hooks into settings (replace hooks section entirely)
|
|
557
|
+
settings.hooks = gitmemHooks;
|
|
558
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
559
|
+
|
|
560
|
+
console.log("Hooks written to .claude/settings.json");
|
|
561
|
+
console.log(`Scripts at: ${relScripts}/`);
|
|
562
|
+
console.log("");
|
|
563
|
+
|
|
564
|
+
// Verify gitmem MCP is configured
|
|
565
|
+
let mcpFound = false;
|
|
566
|
+
const mcpPaths = [
|
|
567
|
+
join(process.cwd(), ".mcp.json"),
|
|
568
|
+
join(process.cwd(), ".claude", "mcp.json"),
|
|
569
|
+
join(homedir(), ".claude.json"),
|
|
570
|
+
];
|
|
571
|
+
for (const p of mcpPaths) {
|
|
572
|
+
if (existsSync(p)) {
|
|
573
|
+
try {
|
|
574
|
+
const cfg = JSON.parse(readFileSync(p, "utf-8"));
|
|
575
|
+
const servers = cfg.mcpServers || {};
|
|
576
|
+
if (servers.gitmem || servers["gitmem-mcp"]) {
|
|
577
|
+
mcpFound = true;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
} catch {
|
|
581
|
+
// ignore parse errors
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
if (!mcpFound) {
|
|
587
|
+
console.log("WARNING: gitmem MCP server not detected in .mcp.json.");
|
|
588
|
+
console.log(" Hooks will be silent until gitmem MCP is configured.");
|
|
589
|
+
console.log(" Run: npx gitmem configure");
|
|
590
|
+
console.log("");
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
console.log("Installed! Hooks will activate on next Claude Code session.");
|
|
594
|
+
console.log("");
|
|
595
|
+
console.log("To update after a gitmem version bump:");
|
|
596
|
+
console.log(" npx gitmem install-hooks --force");
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Uninstall gitmem hooks from .claude/settings.json
|
|
601
|
+
*
|
|
602
|
+
* Removes the hooks section, cleans up legacy plugin directories,
|
|
603
|
+
* and removes temp state directories.
|
|
604
|
+
*/
|
|
605
|
+
function cmdUninstallHooks() {
|
|
606
|
+
console.log("GitMem Hooks — Uninstall");
|
|
607
|
+
console.log("========================");
|
|
608
|
+
console.log("");
|
|
609
|
+
|
|
610
|
+
// Remove hooks from .claude/settings.json
|
|
611
|
+
const settingsPath = join(process.cwd(), ".claude", "settings.json");
|
|
612
|
+
if (existsSync(settingsPath)) {
|
|
613
|
+
try {
|
|
614
|
+
const cfg = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
615
|
+
if (cfg.hooks) {
|
|
616
|
+
delete cfg.hooks;
|
|
617
|
+
writeFileSync(settingsPath, JSON.stringify(cfg, null, 2));
|
|
618
|
+
console.log("[uninstall] Removed hooks from .claude/settings.json");
|
|
619
|
+
} else {
|
|
620
|
+
console.log("[uninstall] No hooks found in .claude/settings.json");
|
|
621
|
+
}
|
|
622
|
+
// Also clean legacy enabledPlugins
|
|
623
|
+
if (cfg.enabledPlugins) {
|
|
624
|
+
for (const key of Object.keys(cfg.enabledPlugins)) {
|
|
625
|
+
if (key.startsWith("gitmem-hooks")) {
|
|
626
|
+
delete cfg.enabledPlugins[key];
|
|
627
|
+
writeFileSync(settingsPath, JSON.stringify(cfg, null, 2));
|
|
628
|
+
console.log("[cleanup] Removed legacy enabledPlugins entry");
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
} catch {
|
|
633
|
+
// ignore parse errors
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Clean legacy plugin directory (from old install-hooks)
|
|
638
|
+
const pluginDir = join(homedir(), ".claude", "plugins", "gitmem-hooks");
|
|
639
|
+
if (existsSync(pluginDir)) {
|
|
640
|
+
rmSync(pluginDir, { recursive: true, force: true });
|
|
641
|
+
console.log("[cleanup] Removed legacy plugin directory:", pluginDir);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Clean temp state directories
|
|
645
|
+
let cleaned = 0;
|
|
646
|
+
try {
|
|
647
|
+
const tmpDir = "/tmp";
|
|
648
|
+
for (const entry of readdirSync(tmpDir)) {
|
|
649
|
+
if (entry.startsWith("gitmem-hooks-")) {
|
|
650
|
+
const fullPath = join(tmpDir, entry);
|
|
651
|
+
try {
|
|
652
|
+
if (statSync(fullPath).isDirectory()) {
|
|
653
|
+
rmSync(fullPath, { recursive: true, force: true });
|
|
654
|
+
cleaned++;
|
|
655
|
+
}
|
|
656
|
+
} catch {
|
|
657
|
+
// ignore permission errors on other users' temp dirs
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
} catch {
|
|
662
|
+
// /tmp read error — not critical
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (cleaned > 0) {
|
|
666
|
+
console.log(`[cleanup] Removed ${cleaned} temp state director(ies) from /tmp/`);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Clean debug log
|
|
670
|
+
const debugLog = "/tmp/gitmem-hooks-plugin-debug.log";
|
|
671
|
+
if (existsSync(debugLog)) {
|
|
672
|
+
rmSync(debugLog, { force: true });
|
|
673
|
+
console.log("[cleanup] Removed debug log");
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
console.log("");
|
|
677
|
+
console.log("Uninstall complete.");
|
|
678
|
+
console.log("");
|
|
679
|
+
console.log("Notes:");
|
|
680
|
+
console.log(" - gitmem MCP server config (.mcp.json) was NOT modified");
|
|
681
|
+
console.log(" - Restart Claude Code for changes to take effect");
|
|
682
|
+
console.log(" - To reinstall: npx gitmem install-hooks");
|
|
683
|
+
}
|
|
684
|
+
|
|
350
685
|
switch (command) {
|
|
351
686
|
case "setup":
|
|
352
687
|
cmdSetup();
|
|
353
688
|
break;
|
|
354
689
|
case "init":
|
|
690
|
+
// New interactive wizard (replaces old cmdInit for CLI usage)
|
|
691
|
+
import("./init-wizard.js");
|
|
692
|
+
break;
|
|
693
|
+
case "uninstall":
|
|
694
|
+
import("./uninstall.js");
|
|
695
|
+
break;
|
|
696
|
+
case "init-scars":
|
|
697
|
+
// Legacy: load starter scars only (old init behavior)
|
|
355
698
|
cmdInit();
|
|
356
699
|
break;
|
|
357
700
|
case "configure":
|
|
358
701
|
cmdConfigure();
|
|
359
702
|
break;
|
|
703
|
+
case "check":
|
|
704
|
+
import("../dist/commands/check.js").then((m) => m.main(process.argv.slice(3)));
|
|
705
|
+
break;
|
|
706
|
+
case "install-hooks":
|
|
707
|
+
cmdInstallHooks();
|
|
708
|
+
break;
|
|
709
|
+
case "uninstall-hooks":
|
|
710
|
+
cmdUninstallHooks();
|
|
711
|
+
break;
|
|
360
712
|
case "session-start":
|
|
361
713
|
cmdSessionStart();
|
|
362
714
|
break;
|
|
@@ -373,7 +725,7 @@ switch (command) {
|
|
|
373
725
|
printUsage();
|
|
374
726
|
break;
|
|
375
727
|
case undefined:
|
|
376
|
-
// Default: start MCP server (npx
|
|
728
|
+
// Default: start MCP server (npx gitmem-mcp should start serving)
|
|
377
729
|
import("../dist/index.js");
|
|
378
730
|
break;
|
|
379
731
|
default:
|