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.
Files changed (249) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/CLAUDE.md.template +63 -55
  3. package/README.md +149 -120
  4. package/bin/gitmem.js +377 -25
  5. package/bin/init-wizard.js +642 -0
  6. package/bin/uninstall.js +288 -0
  7. package/dist/commands/check.js +20 -20
  8. package/dist/commands/check.js.map +1 -1
  9. package/dist/constants/closing-questions.d.ts +6 -0
  10. package/dist/constants/closing-questions.d.ts.map +1 -1
  11. package/dist/constants/closing-questions.js +65 -0
  12. package/dist/constants/closing-questions.js.map +1 -1
  13. package/dist/hooks/format-utils.d.ts +52 -0
  14. package/dist/hooks/format-utils.d.ts.map +1 -0
  15. package/dist/hooks/format-utils.js +89 -0
  16. package/dist/hooks/format-utils.js.map +1 -0
  17. package/dist/hooks/quick-retrieve.d.ts +30 -0
  18. package/dist/hooks/quick-retrieve.d.ts.map +1 -0
  19. package/dist/hooks/quick-retrieve.js +149 -0
  20. package/dist/hooks/quick-retrieve.js.map +1 -0
  21. package/dist/index.js +0 -0
  22. package/dist/schemas/active-sessions.d.ts +8 -8
  23. package/dist/schemas/analyze.d.ts +3 -3
  24. package/dist/schemas/common.d.ts +2 -2
  25. package/dist/schemas/common.d.ts.map +1 -1
  26. package/dist/schemas/common.js +1 -1
  27. package/dist/schemas/common.js.map +1 -1
  28. package/dist/schemas/create-decision.d.ts +3 -3
  29. package/dist/schemas/create-learning.d.ts +13 -13
  30. package/dist/schemas/log.d.ts +3 -3
  31. package/dist/schemas/prepare-context.d.ts +3 -3
  32. package/dist/schemas/recall.d.ts +3 -3
  33. package/dist/schemas/record-scar-usage-batch.d.ts +8 -3
  34. package/dist/schemas/record-scar-usage-batch.d.ts.map +1 -1
  35. package/dist/schemas/record-scar-usage.d.ts +3 -0
  36. package/dist/schemas/record-scar-usage.d.ts.map +1 -1
  37. package/dist/schemas/record-scar-usage.js +1 -0
  38. package/dist/schemas/record-scar-usage.js.map +1 -1
  39. package/dist/schemas/registry.d.ts +18 -0
  40. package/dist/schemas/registry.d.ts.map +1 -0
  41. package/dist/schemas/registry.js +158 -0
  42. package/dist/schemas/registry.js.map +1 -0
  43. package/dist/schemas/save-transcript.d.ts +3 -3
  44. package/dist/schemas/search-transcripts.d.ts +33 -0
  45. package/dist/schemas/search-transcripts.d.ts.map +1 -0
  46. package/dist/schemas/search-transcripts.js +26 -0
  47. package/dist/schemas/search-transcripts.js.map +1 -0
  48. package/dist/schemas/search.d.ts +3 -3
  49. package/dist/schemas/session-close.d.ts +43 -15
  50. package/dist/schemas/session-close.d.ts.map +1 -1
  51. package/dist/schemas/session-close.js +7 -2
  52. package/dist/schemas/session-close.js.map +1 -1
  53. package/dist/schemas/session-start.d.ts +3 -3
  54. package/dist/schemas/thread.d.ts +3 -3
  55. package/dist/server.d.ts.map +1 -1
  56. package/dist/server.js +82 -28
  57. package/dist/server.js.map +1 -1
  58. package/dist/services/active-sessions.d.ts +2 -1
  59. package/dist/services/active-sessions.d.ts.map +1 -1
  60. package/dist/services/active-sessions.js +130 -84
  61. package/dist/services/active-sessions.js.map +1 -1
  62. package/dist/services/analytics.d.ts.map +1 -1
  63. package/dist/services/analytics.js +1 -0
  64. package/dist/services/analytics.js.map +1 -1
  65. package/dist/services/behavioral-decay.d.ts +40 -0
  66. package/dist/services/behavioral-decay.d.ts.map +1 -0
  67. package/dist/services/behavioral-decay.js +110 -0
  68. package/dist/services/behavioral-decay.js.map +1 -0
  69. package/dist/services/bm25.d.ts +39 -0
  70. package/dist/services/bm25.d.ts.map +1 -0
  71. package/dist/services/bm25.js +132 -0
  72. package/dist/services/bm25.js.map +1 -0
  73. package/dist/services/cache.d.ts.map +1 -1
  74. package/dist/services/cache.js +9 -8
  75. package/dist/services/cache.js.map +1 -1
  76. package/dist/services/cache.test.js +17 -17
  77. package/dist/services/cache.test.js.map +1 -1
  78. package/dist/services/compliance-validator.d.ts.map +1 -1
  79. package/dist/services/compliance-validator.js +12 -1
  80. package/dist/services/compliance-validator.js.map +1 -1
  81. package/dist/services/display-protocol.d.ts +31 -0
  82. package/dist/services/display-protocol.d.ts.map +1 -0
  83. package/dist/services/display-protocol.js +73 -0
  84. package/dist/services/display-protocol.js.map +1 -0
  85. package/dist/services/effect-tracker.d.ts +81 -0
  86. package/dist/services/effect-tracker.d.ts.map +1 -0
  87. package/dist/services/effect-tracker.js +181 -0
  88. package/dist/services/effect-tracker.js.map +1 -0
  89. package/dist/services/file-lock.d.ts +31 -0
  90. package/dist/services/file-lock.d.ts.map +1 -0
  91. package/dist/services/file-lock.js +124 -0
  92. package/dist/services/file-lock.js.map +1 -0
  93. package/dist/services/gitmem-dir.d.ts +7 -0
  94. package/dist/services/gitmem-dir.d.ts.map +1 -1
  95. package/dist/services/gitmem-dir.js +21 -0
  96. package/dist/services/gitmem-dir.js.map +1 -1
  97. package/dist/services/local-file-storage.d.ts +3 -2
  98. package/dist/services/local-file-storage.d.ts.map +1 -1
  99. package/dist/services/local-file-storage.js +30 -43
  100. package/dist/services/local-file-storage.js.map +1 -1
  101. package/dist/services/local-vector-search.d.ts +10 -9
  102. package/dist/services/local-vector-search.d.ts.map +1 -1
  103. package/dist/services/local-vector-search.js +28 -23
  104. package/dist/services/local-vector-search.js.map +1 -1
  105. package/dist/services/metrics.d.ts +7 -2
  106. package/dist/services/metrics.d.ts.map +1 -1
  107. package/dist/services/metrics.js +41 -33
  108. package/dist/services/metrics.js.map +1 -1
  109. package/dist/services/session-state.d.ts +8 -0
  110. package/dist/services/session-state.d.ts.map +1 -1
  111. package/dist/services/session-state.js +9 -2
  112. package/dist/services/session-state.js.map +1 -1
  113. package/dist/services/startup.d.ts +12 -13
  114. package/dist/services/startup.d.ts.map +1 -1
  115. package/dist/services/startup.js +104 -57
  116. package/dist/services/startup.js.map +1 -1
  117. package/dist/services/supabase-client.d.ts +2 -1
  118. package/dist/services/supabase-client.d.ts.map +1 -1
  119. package/dist/services/supabase-client.js +22 -16
  120. package/dist/services/supabase-client.js.map +1 -1
  121. package/dist/services/thread-dedup.d.ts +9 -0
  122. package/dist/services/thread-dedup.d.ts.map +1 -1
  123. package/dist/services/thread-dedup.js +27 -0
  124. package/dist/services/thread-dedup.js.map +1 -1
  125. package/dist/services/thread-manager.d.ts.map +1 -1
  126. package/dist/services/thread-manager.js +38 -16
  127. package/dist/services/thread-manager.js.map +1 -1
  128. package/dist/services/thread-suggestions.d.ts.map +1 -1
  129. package/dist/services/thread-suggestions.js +1 -1
  130. package/dist/services/thread-suggestions.js.map +1 -1
  131. package/dist/services/thread-supabase.d.ts +0 -1
  132. package/dist/services/thread-supabase.d.ts.map +1 -1
  133. package/dist/services/thread-supabase.js +83 -54
  134. package/dist/services/thread-supabase.js.map +1 -1
  135. package/dist/services/timezone.d.ts.map +1 -1
  136. package/dist/services/timezone.js +1 -0
  137. package/dist/services/timezone.js.map +1 -1
  138. package/dist/services/transcript-chunker.d.ts.map +1 -1
  139. package/dist/services/transcript-chunker.js +18 -4
  140. package/dist/services/transcript-chunker.js.map +1 -1
  141. package/dist/services/variant-generation.d.ts +41 -0
  142. package/dist/services/variant-generation.d.ts.map +1 -0
  143. package/dist/services/variant-generation.js +263 -0
  144. package/dist/services/variant-generation.js.map +1 -0
  145. package/dist/tools/absorb-observations.d.ts.map +1 -1
  146. package/dist/tools/absorb-observations.js +9 -0
  147. package/dist/tools/absorb-observations.js.map +1 -1
  148. package/dist/tools/analyze.d.ts.map +1 -1
  149. package/dist/tools/analyze.js +13 -2
  150. package/dist/tools/analyze.js.map +1 -1
  151. package/dist/tools/archive-learning.d.ts +28 -0
  152. package/dist/tools/archive-learning.d.ts.map +1 -0
  153. package/dist/tools/archive-learning.js +81 -0
  154. package/dist/tools/archive-learning.js.map +1 -0
  155. package/dist/tools/cleanup-threads.d.ts +1 -0
  156. package/dist/tools/cleanup-threads.d.ts.map +1 -1
  157. package/dist/tools/cleanup-threads.js +111 -18
  158. package/dist/tools/cleanup-threads.js.map +1 -1
  159. package/dist/tools/confirm-scars.d.ts.map +1 -1
  160. package/dist/tools/confirm-scars.js +8 -2
  161. package/dist/tools/confirm-scars.js.map +1 -1
  162. package/dist/tools/create-decision.d.ts.map +1 -1
  163. package/dist/tools/create-decision.js +11 -8
  164. package/dist/tools/create-decision.js.map +1 -1
  165. package/dist/tools/create-learning.d.ts.map +1 -1
  166. package/dist/tools/create-learning.js +35 -11
  167. package/dist/tools/create-learning.js.map +1 -1
  168. package/dist/tools/create-linear-issue.d.ts +18 -0
  169. package/dist/tools/create-linear-issue.d.ts.map +1 -0
  170. package/dist/tools/create-linear-issue.js +197 -0
  171. package/dist/tools/create-linear-issue.js.map +1 -0
  172. package/dist/tools/create-thread.d.ts +2 -1
  173. package/dist/tools/create-thread.d.ts.map +1 -1
  174. package/dist/tools/create-thread.js +9 -4
  175. package/dist/tools/create-thread.js.map +1 -1
  176. package/dist/tools/definitions.d.ts +785 -34
  177. package/dist/tools/definitions.d.ts.map +1 -1
  178. package/dist/tools/definitions.js +239 -95
  179. package/dist/tools/definitions.js.map +1 -1
  180. package/dist/tools/dismiss-suggestion.d.ts +1 -0
  181. package/dist/tools/dismiss-suggestion.d.ts.map +1 -1
  182. package/dist/tools/dismiss-suggestion.js +4 -0
  183. package/dist/tools/dismiss-suggestion.js.map +1 -1
  184. package/dist/tools/graph-traverse.d.ts +1 -0
  185. package/dist/tools/graph-traverse.d.ts.map +1 -1
  186. package/dist/tools/graph-traverse.js +24 -9
  187. package/dist/tools/graph-traverse.js.map +1 -1
  188. package/dist/tools/list-threads.d.ts.map +1 -1
  189. package/dist/tools/list-threads.js +49 -5
  190. package/dist/tools/list-threads.js.map +1 -1
  191. package/dist/tools/log.d.ts +1 -0
  192. package/dist/tools/log.d.ts.map +1 -1
  193. package/dist/tools/log.js +84 -17
  194. package/dist/tools/log.js.map +1 -1
  195. package/dist/tools/prepare-context.d.ts +1 -0
  196. package/dist/tools/prepare-context.d.ts.map +1 -1
  197. package/dist/tools/prepare-context.js +15 -85
  198. package/dist/tools/prepare-context.js.map +1 -1
  199. package/dist/tools/promote-suggestion.d.ts +1 -0
  200. package/dist/tools/promote-suggestion.d.ts.map +1 -1
  201. package/dist/tools/promote-suggestion.js +5 -0
  202. package/dist/tools/promote-suggestion.js.map +1 -1
  203. package/dist/tools/recall.d.ts +2 -0
  204. package/dist/tools/recall.d.ts.map +1 -1
  205. package/dist/tools/recall.js +43 -10
  206. package/dist/tools/recall.js.map +1 -1
  207. package/dist/tools/recall.test.js +6 -6
  208. package/dist/tools/recall.test.js.map +1 -1
  209. package/dist/tools/record-scar-usage-batch.d.ts.map +1 -1
  210. package/dist/tools/record-scar-usage-batch.js +13 -0
  211. package/dist/tools/record-scar-usage-batch.js.map +1 -1
  212. package/dist/tools/record-scar-usage.d.ts.map +1 -1
  213. package/dist/tools/record-scar-usage.js +6 -0
  214. package/dist/tools/record-scar-usage.js.map +1 -1
  215. package/dist/tools/resolve-thread.d.ts.map +1 -1
  216. package/dist/tools/resolve-thread.js +57 -6
  217. package/dist/tools/resolve-thread.js.map +1 -1
  218. package/dist/tools/save-transcript.d.ts +1 -0
  219. package/dist/tools/save-transcript.d.ts.map +1 -1
  220. package/dist/tools/save-transcript.js +3 -1
  221. package/dist/tools/save-transcript.js.map +1 -1
  222. package/dist/tools/search-transcripts.d.ts +44 -0
  223. package/dist/tools/search-transcripts.d.ts.map +1 -0
  224. package/dist/tools/search-transcripts.js +158 -0
  225. package/dist/tools/search-transcripts.js.map +1 -0
  226. package/dist/tools/search.d.ts +1 -0
  227. package/dist/tools/search.d.ts.map +1 -1
  228. package/dist/tools/search.js +74 -3
  229. package/dist/tools/search.js.map +1 -1
  230. package/dist/tools/session-close.d.ts.map +1 -1
  231. package/dist/tools/session-close.js +563 -326
  232. package/dist/tools/session-close.js.map +1 -1
  233. package/dist/tools/session-start.d.ts +10 -6
  234. package/dist/tools/session-start.d.ts.map +1 -1
  235. package/dist/tools/session-start.js +317 -426
  236. package/dist/tools/session-start.js.map +1 -1
  237. package/dist/types/index.d.ts +37 -4
  238. package/dist/types/index.d.ts.map +1 -1
  239. package/hooks/.claude-plugin/plugin.json +8 -0
  240. package/hooks/README.md +107 -0
  241. package/hooks/hooks/hooks.json +123 -0
  242. package/hooks/scripts/auto-retrieve-hook.sh +163 -0
  243. package/hooks/scripts/post-tool-use.sh +112 -0
  244. package/hooks/scripts/recall-check.sh +213 -0
  245. package/hooks/scripts/session-close-check.sh +116 -0
  246. package/hooks/scripts/session-start.sh +233 -0
  247. package/hooks/tests/test-hooks.sh +577 -0
  248. package/package.json +4 -2
  249. 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 setup Output SQL to paste into Supabase SQL Editor (pro/dev)
8
- * gitmem init Load starter scars (local JSON or Supabase)
9
- * gitmem configure Generate .mcp.json entry for Claude Code
10
- * gitmem server Start MCP server (default)
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 { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
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 Output SQL for Supabase schema setup (pro/dev tier)
26
- npx gitmem init Load starter scars (auto-detects tier)
27
- npx gitmem configure Generate .mcp.json config for Claude Code
28
- npx gitmem server Start MCP server (default)
29
- npx gitmem help Show this help message
30
-
31
- Free Tier (zero config):
32
- 1. npx gitmem init
33
- 2. npx gitmem configure
34
- 3. Copy CLAUDE.md.template into your project
35
- 4. Start coding memory is active!
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. Get API key for embeddings (OpenAI, OpenRouter, or Ollama)
41
- 4. npx gitmem configure
42
- 5. npx gitmem init (load starter scars into Supabase)
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", "@nteg-dev/gitmem"],
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", "@nteg-dev/gitmem"],
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 = "orchestra_dev";
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 @nteg-dev/gitmem should start serving)
728
+ // Default: start MCP server (npx gitmem-mcp should start serving)
377
729
  import("../dist/index.js");
378
730
  break;
379
731
  default: