@pcircle/memesh 4.5.0 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/.claude-plugin/marketplace.json +5 -3
  2. package/.claude-plugin/plugin.json +6 -4
  3. package/.mcp.json +1 -1
  4. package/AGENTS.md +95 -0
  5. package/README.de.md +130 -39
  6. package/README.md +188 -43
  7. package/README.zh-TW.md +133 -41
  8. package/dashboard/dist/index.html +9 -9
  9. package/dist/cli/view-live.js +3 -3
  10. package/dist/core/analytics.d.ts +3 -3
  11. package/dist/core/analytics.d.ts.map +1 -1
  12. package/dist/core/analytics.js.map +1 -1
  13. package/dist/core/auto-tagger.d.ts.map +1 -1
  14. package/dist/core/auto-tagger.js +4 -9
  15. package/dist/core/auto-tagger.js.map +1 -1
  16. package/dist/core/briefing.d.ts +8 -0
  17. package/dist/core/briefing.d.ts.map +1 -0
  18. package/dist/core/briefing.js +91 -0
  19. package/dist/core/briefing.js.map +1 -0
  20. package/dist/core/capture-flag.d.ts +5 -0
  21. package/dist/core/capture-flag.d.ts.map +1 -0
  22. package/dist/core/capture-flag.js +10 -0
  23. package/dist/core/capture-flag.js.map +1 -0
  24. package/dist/core/config.d.ts +0 -1
  25. package/dist/core/config.d.ts.map +1 -1
  26. package/dist/core/config.js +2 -1
  27. package/dist/core/config.js.map +1 -1
  28. package/dist/core/conflict-candidates.d.ts +20 -0
  29. package/dist/core/conflict-candidates.d.ts.map +1 -0
  30. package/dist/core/conflict-candidates.js +79 -0
  31. package/dist/core/conflict-candidates.js.map +1 -0
  32. package/dist/core/conflict-judge.d.ts +47 -0
  33. package/dist/core/conflict-judge.d.ts.map +1 -0
  34. package/dist/core/conflict-judge.js +189 -0
  35. package/dist/core/conflict-judge.js.map +1 -0
  36. package/dist/core/demo.d.ts +2 -2
  37. package/dist/core/demo.d.ts.map +1 -1
  38. package/dist/core/demo.js.map +1 -1
  39. package/dist/core/digest-validator.d.ts.map +1 -1
  40. package/dist/core/digest-validator.js +3 -5
  41. package/dist/core/digest-validator.js.map +1 -1
  42. package/dist/core/doctor.d.ts +3 -0
  43. package/dist/core/doctor.d.ts.map +1 -1
  44. package/dist/core/doctor.js +207 -85
  45. package/dist/core/doctor.js.map +1 -1
  46. package/dist/core/dreamer.d.ts +20 -9
  47. package/dist/core/dreamer.d.ts.map +1 -1
  48. package/dist/core/dreamer.js +416 -58
  49. package/dist/core/dreamer.js.map +1 -1
  50. package/dist/core/embedder.d.ts +7 -5
  51. package/dist/core/embedder.d.ts.map +1 -1
  52. package/dist/core/embedder.js +38 -9
  53. package/dist/core/embedder.js.map +1 -1
  54. package/dist/core/extractor.d.ts.map +1 -1
  55. package/dist/core/extractor.js +2 -1
  56. package/dist/core/extractor.js.map +1 -1
  57. package/dist/core/failure-analyzer.d.ts.map +1 -1
  58. package/dist/core/failure-analyzer.js +7 -12
  59. package/dist/core/failure-analyzer.js.map +1 -1
  60. package/dist/core/graph.d.ts +4 -4
  61. package/dist/core/graph.d.ts.map +1 -1
  62. package/dist/core/graph.js.map +1 -1
  63. package/dist/core/install-channel.d.ts +1 -1
  64. package/dist/core/install-channel.d.ts.map +1 -1
  65. package/dist/core/install-channel.js +16 -5
  66. package/dist/core/install-channel.js.map +1 -1
  67. package/dist/core/install-hooks.d.ts +6 -0
  68. package/dist/core/install-hooks.d.ts.map +1 -1
  69. package/dist/core/install-hooks.js +0 -0
  70. package/dist/core/install-hooks.js.map +1 -1
  71. package/dist/core/json-utils.d.ts +1 -0
  72. package/dist/core/json-utils.d.ts.map +1 -1
  73. package/dist/core/json-utils.js +19 -10
  74. package/dist/core/json-utils.js.map +1 -1
  75. package/dist/core/kg-backfill.d.ts +3 -4
  76. package/dist/core/kg-backfill.d.ts.map +1 -1
  77. package/dist/core/kg-backfill.js +1 -4
  78. package/dist/core/kg-backfill.js.map +1 -1
  79. package/dist/core/lesson-engine.d.ts +1 -0
  80. package/dist/core/lesson-engine.d.ts.map +1 -1
  81. package/dist/core/lesson-engine.js +1 -0
  82. package/dist/core/lesson-engine.js.map +1 -1
  83. package/dist/core/lifecycle.d.ts +4 -4
  84. package/dist/core/lifecycle.d.ts.map +1 -1
  85. package/dist/core/lifecycle.js +15 -22
  86. package/dist/core/lifecycle.js.map +1 -1
  87. package/dist/core/llm-client.d.ts.map +1 -1
  88. package/dist/core/llm-client.js +3 -6
  89. package/dist/core/llm-client.js.map +1 -1
  90. package/dist/core/llm-telemetry.d.ts +4 -4
  91. package/dist/core/llm-telemetry.d.ts.map +1 -1
  92. package/dist/core/llm-telemetry.js +1 -1
  93. package/dist/core/llm-telemetry.js.map +1 -1
  94. package/dist/core/memory-tool.d.ts.map +1 -1
  95. package/dist/core/memory-tool.js +8 -4
  96. package/dist/core/memory-tool.js.map +1 -1
  97. package/dist/core/operations.d.ts.map +1 -1
  98. package/dist/core/operations.js +41 -17
  99. package/dist/core/operations.js.map +1 -1
  100. package/dist/core/paths.d.ts +3 -0
  101. package/dist/core/paths.d.ts.map +1 -1
  102. package/dist/core/paths.js +67 -1
  103. package/dist/core/paths.js.map +1 -1
  104. package/dist/core/patterns.d.ts +2 -2
  105. package/dist/core/patterns.d.ts.map +1 -1
  106. package/dist/core/patterns.js.map +1 -1
  107. package/dist/core/project-tags.d.ts +3 -3
  108. package/dist/core/project-tags.d.ts.map +1 -1
  109. package/dist/core/project-tags.js.map +1 -1
  110. package/dist/core/projects.d.ts +2 -2
  111. package/dist/core/projects.d.ts.map +1 -1
  112. package/dist/core/projects.js.map +1 -1
  113. package/dist/core/prompt-safety.d.ts +1 -0
  114. package/dist/core/prompt-safety.d.ts.map +1 -1
  115. package/dist/core/prompt-safety.js +7 -0
  116. package/dist/core/prompt-safety.js.map +1 -1
  117. package/dist/core/schema-export.d.ts.map +1 -1
  118. package/dist/core/schema-export.js +27 -30
  119. package/dist/core/schema-export.js.map +1 -1
  120. package/dist/core/serializer.d.ts.map +1 -1
  121. package/dist/core/serializer.js +45 -4
  122. package/dist/core/serializer.js.map +1 -1
  123. package/dist/core/setup.d.ts +29 -0
  124. package/dist/core/setup.d.ts.map +1 -0
  125. package/dist/core/setup.js +127 -0
  126. package/dist/core/setup.js.map +1 -0
  127. package/dist/core/stats.d.ts +2 -2
  128. package/dist/core/stats.d.ts.map +1 -1
  129. package/dist/core/stats.js.map +1 -1
  130. package/dist/core/task-state-store.d.ts +17 -0
  131. package/dist/core/task-state-store.d.ts.map +1 -0
  132. package/dist/core/task-state-store.js +45 -0
  133. package/dist/core/task-state-store.js.map +1 -0
  134. package/dist/core/task-state.d.ts +19 -0
  135. package/dist/core/task-state.d.ts.map +1 -0
  136. package/dist/core/task-state.js +91 -0
  137. package/dist/core/task-state.js.map +1 -0
  138. package/dist/core/time-utils.d.ts +2 -0
  139. package/dist/core/time-utils.d.ts.map +1 -0
  140. package/dist/core/time-utils.js +14 -0
  141. package/dist/core/time-utils.js.map +1 -0
  142. package/dist/core/title.d.ts +5 -0
  143. package/dist/core/title.d.ts.map +1 -0
  144. package/dist/core/title.js +14 -0
  145. package/dist/core/title.js.map +1 -0
  146. package/dist/core/transcript-extractor.d.ts +5 -6
  147. package/dist/core/transcript-extractor.d.ts.map +1 -1
  148. package/dist/core/transcript-extractor.js +4 -24
  149. package/dist/core/transcript-extractor.js.map +1 -1
  150. package/dist/core/transcript-source.d.ts.map +1 -1
  151. package/dist/core/transcript-source.js +2 -3
  152. package/dist/core/transcript-source.js.map +1 -1
  153. package/dist/core/types.d.ts +21 -7
  154. package/dist/core/types.d.ts.map +1 -1
  155. package/dist/core/types.js +2 -0
  156. package/dist/core/types.js.map +1 -1
  157. package/dist/core/work-topology.d.ts +33 -0
  158. package/dist/core/work-topology.d.ts.map +1 -0
  159. package/dist/core/work-topology.js +183 -0
  160. package/dist/core/work-topology.js.map +1 -0
  161. package/dist/db.d.ts +5 -10
  162. package/dist/db.d.ts.map +1 -1
  163. package/dist/db.js +194 -196
  164. package/dist/db.js.map +1 -1
  165. package/dist/knowledge-graph.d.ts +4 -2
  166. package/dist/knowledge-graph.d.ts.map +1 -1
  167. package/dist/knowledge-graph.js +68 -49
  168. package/dist/knowledge-graph.js.map +1 -1
  169. package/dist/mcp/server.js +2 -1
  170. package/dist/mcp/server.js.map +1 -1
  171. package/dist/skills-manifest.json +61 -36
  172. package/dist/storage/conflicts.d.ts +3 -3
  173. package/dist/storage/conflicts.d.ts.map +1 -1
  174. package/dist/storage/conflicts.js +2 -7
  175. package/dist/storage/conflicts.js.map +1 -1
  176. package/dist/storage/fts-index.d.ts +6 -4
  177. package/dist/storage/fts-index.d.ts.map +1 -1
  178. package/dist/storage/fts-index.js +16 -4
  179. package/dist/storage/fts-index.js.map +1 -1
  180. package/dist/storage/schema.d.ts +20 -0
  181. package/dist/storage/schema.d.ts.map +1 -0
  182. package/dist/storage/schema.js +274 -0
  183. package/dist/storage/schema.js.map +1 -0
  184. package/dist/storage/sqlite.d.ts +20 -0
  185. package/dist/storage/sqlite.d.ts.map +1 -0
  186. package/dist/storage/sqlite.js +64 -0
  187. package/dist/storage/sqlite.js.map +1 -0
  188. package/dist/storage/vector-index.d.ts +3 -0
  189. package/dist/storage/vector-index.d.ts.map +1 -0
  190. package/dist/storage/vector-index.js +7 -0
  191. package/dist/storage/vector-index.js.map +1 -0
  192. package/dist/transports/cli/cli.d.ts +1 -4
  193. package/dist/transports/cli/cli.d.ts.map +1 -1
  194. package/dist/transports/cli/cli.js +494 -76
  195. package/dist/transports/cli/cli.js.map +1 -1
  196. package/dist/transports/http/retired-routes.d.ts.map +1 -1
  197. package/dist/transports/http/retired-routes.js +1 -0
  198. package/dist/transports/http/retired-routes.js.map +1 -1
  199. package/dist/transports/http/server.d.ts.map +1 -1
  200. package/dist/transports/http/server.js +243 -323
  201. package/dist/transports/http/server.js.map +1 -1
  202. package/dist/transports/mcp/handlers.d.ts +48 -94
  203. package/dist/transports/mcp/handlers.d.ts.map +1 -1
  204. package/dist/transports/mcp/handlers.js +77 -56
  205. package/dist/transports/mcp/handlers.js.map +1 -1
  206. package/dist/transports/schemas.d.ts +31 -40
  207. package/dist/transports/schemas.d.ts.map +1 -1
  208. package/dist/transports/schemas.js +31 -37
  209. package/dist/transports/schemas.js.map +1 -1
  210. package/hooks/hooks.json +0 -10
  211. package/llms-install.md +138 -0
  212. package/package.json +19 -18
  213. package/scripts/hooks/_generated/capture-flag.js +17 -0
  214. package/scripts/hooks/_generated/core-paths.js +67 -1
  215. package/scripts/hooks/_generated/fts-index.js +16 -4
  216. package/scripts/hooks/_generated/schema.js +281 -0
  217. package/scripts/hooks/_generated/sqlite.js +71 -0
  218. package/scripts/hooks/_generated/task-state.js +98 -0
  219. package/scripts/hooks/_generated/time-utils.js +21 -0
  220. package/scripts/hooks/_generated/title.js +21 -0
  221. package/scripts/hooks/_generated/work-topology.js +190 -0
  222. package/scripts/hooks/_shared.js +269 -534
  223. package/scripts/hooks/post-commit.js +55 -10
  224. package/scripts/hooks/pre-compact.js +22 -7
  225. package/scripts/hooks/pre-edit-recall.js +9 -11
  226. package/scripts/hooks/session-start.js +230 -106
  227. package/scripts/hooks/session-summary.js +176 -73
  228. package/scripts/hooks/user-prompt-intent.js +3 -2
  229. package/skills/memesh/SKILL.md +97 -77
  230. package/README.es.md +0 -470
  231. package/README.fr.md +0 -462
  232. package/README.ja.md +0 -470
  233. package/README.ko.md +0 -470
  234. package/README.pt.md +0 -462
  235. package/README.th.md +0 -463
  236. package/README.vi.md +0 -462
  237. package/README.zh-CN.md +0 -469
  238. package/dist/cli/view.d.ts +0 -3
  239. package/dist/cli/view.d.ts.map +0 -1
  240. package/dist/cli/view.js +0 -523
  241. package/dist/cli/view.js.map +0 -1
  242. package/dist/core/skill-usage-log.d.ts +0 -11
  243. package/dist/core/skill-usage-log.d.ts.map +0 -1
  244. package/dist/core/skill-usage-log.js +0 -125
  245. package/dist/core/skill-usage-log.js.map +0 -1
  246. package/dist/core/verifier.d.ts +0 -40
  247. package/dist/core/verifier.d.ts.map +0 -1
  248. package/dist/core/verifier.js +0 -206
  249. package/dist/core/verifier.js.map +0 -1
  250. package/dist/mcp/launcher.d.ts +0 -3
  251. package/dist/mcp/launcher.d.ts.map +0 -1
  252. package/dist/mcp/launcher.js +0 -37
  253. package/dist/mcp/launcher.js.map +0 -1
  254. package/scripts/hooks/pre-bash-orchestration-nudge.js +0 -155
  255. package/scripts/postinstall-rebuild.mjs +0 -41
  256. package/skills/agentic-orchestration/SKILL.md +0 -399
@@ -1,13 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { execFileSync } from 'child_process';
4
- import { captureEntity, getProjectName, openHookDb } from './_shared.js';
4
+ import { AUTO_CAPTURE_TAG, captureEntity, getProjectName, isAutoCaptureEnabled, openHookDb, recordHookRun, truncateTitle } from './_shared.js';
5
5
 
6
6
  let input = '';
7
7
  process.stdin.setEncoding('utf8');
8
8
  process.stdin.on('data', (chunk) => { input += chunk; });
9
9
  process.stdin.on('end', () => {
10
10
  try {
11
+ // Opt-out check (env > config > default-on). This hook skipped it for
12
+ // years while its two siblings honoured it — with capture disabled it
13
+ // kept writing commit entities AND stamping the heartbeat, which made
14
+ // doctor's "capture is off, hook silence is expected" message false.
15
+ if (!isAutoCaptureEnabled(process.env)) return exit0();
16
+
11
17
  const data = JSON.parse(input);
12
18
 
13
19
  // tool_name absent is a schema-flip signal (Claude Code has done
@@ -50,6 +56,20 @@ process.stdin.on('end', () => {
50
56
  const commitMatch = toolOutput.match(/\[[\w/.-]+(?: \([\w -]+\))? ([a-f0-9]{7,})\] (.+)/);
51
57
  if (!commitMatch) return exit0();
52
58
 
59
+ // The OUTPUT looking like a commit is not evidence that a commit happened.
60
+ // This hook stopped at the regex above, so any Bash output containing a
61
+ // commit-shaped line produced a permanent memory. Measured: a payload whose
62
+ // command was `cat docs/release-notes.md` wrote entity `commit-9f3c2a1`
63
+ // for a hash `git cat-file -t` rejects as "Not a valid object name".
64
+ // Reading a changelog, tailing a build log, or quoting a commit line was
65
+ // enough — and the fake then surfaced through session-start and
66
+ // pre-edit-recall as if it had happened.
67
+ const issuedCommand = typeof data.tool_input?.command === 'string' ? data.tool_input.command : '';
68
+ if (!/\bgit\b[^|;&]*\bcommit\b/.test(issuedCommand)) {
69
+ try { process.stderr.write(`[memesh post-commit] output looks like a commit but the command was not a git commit; skipping ${commitMatch[1]}\n`); } catch {}
70
+ return exit0();
71
+ }
72
+
53
73
  const branchMatch = commitMatch[0].match(/^\[([^\s]+)\s/);
54
74
  const branch = branchMatch ? branchMatch[1] : 'unknown';
55
75
 
@@ -66,17 +86,28 @@ process.stdin.on('end', () => {
66
86
  try { process.stderr.write(`[memesh post-commit] data.cwd absent — cannot resolve project / repo; skipping commit ${commitHash}\n`); } catch {}
67
87
  return exit0();
68
88
  }
89
+ // And the commit has to actually be in THIS repository.
90
+ //
91
+ // `cat-file -e <hash>^{commit}` answers exactly one question — does this
92
+ // resolve to a commit object here — in milliseconds, before anything is
93
+ // written. Deliberately separate from the `git show` below, whose failure
94
+ // (git absent, timeout on a huge diff) says nothing about the commit and
95
+ // must NOT veto.
96
+ try {
97
+ execFileSync('git', ['-C', data.cwd, 'cat-file', '-e', `${commitHash}^{commit}`], {
98
+ timeout: 5000,
99
+ stdio: ['ignore', 'ignore', 'pipe'],
100
+ });
101
+ } catch {
102
+ try { process.stderr.write(`[memesh post-commit] ${commitHash} is not a commit in ${data.cwd}; nothing written\n`); } catch {}
103
+ return exit0();
104
+ }
105
+
69
106
  const projectName = getProjectName(data.cwd);
70
107
 
71
108
  // Open DB via shared helper — applies SCHEMA_SQL + status migration.
72
109
  // Pass fts:true so the FTS5 entity-search index is also available.
73
- // Returns null when the better-sqlite3 native module is unavailable
74
- // (e.g. plugin-marketplace cache install with no node_modules); in
75
- // that case silently skip — a sibling registered hook copy with
76
- // proper deps still records the commit.
77
- const handle = openHookDb(process.env, { fts: true });
78
- if (!handle) return;
79
- const { db } = handle;
110
+ const { db } = openHookDb(process.env, { fts: true });
80
111
  try {
81
112
  const entityName = `commit-${commitHash}`;
82
113
 
@@ -103,12 +134,26 @@ process.stdin.on('end', () => {
103
134
  }
104
135
 
105
136
  // Shared write dance — upsert entity + observations + tags AND reindex FTS.
106
- captureEntity(db, {
137
+ //
138
+ // `source:auto-capture` is the provenance marker every capture hook
139
+ // writes (session-summary, pre-compact and the extractor already did;
140
+ // this one did not). `memesh doctor` counts it to answer "is the
141
+ // auto-capture loop alive" — a question it used to answer from entity
142
+ // TYPE, which a hand-typed `memesh learn` satisfied all by itself.
143
+ // The commit subject IS the title — git authors already wrote a
144
+ // one-line human summary; nothing to synthesize.
145
+ const written = captureEntity(db, {
107
146
  name: entityName,
108
147
  type: 'commit',
109
148
  observations,
110
- tags: [`project:${projectName}`],
149
+ tags: [AUTO_CAPTURE_TAG, `project:${projectName}`],
150
+ title: truncateTitle(commitMsg),
111
151
  });
152
+
153
+ // Heartbeat AFTER capture, so the stamp certifies "the capture loop
154
+ // completed", not "a database handle existed". A throw above skips it,
155
+ // and so does a null return (the write did not land).
156
+ if (written) recordHookRun(db, 'post-commit');
112
157
  } finally {
113
158
  db.close();
114
159
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { basename } from 'path';
4
4
  import { existsSync, readFileSync } from 'fs';
5
- import { captureEntity, getProjectName, isAutoCaptureEnabled, openHookDb } from './_shared.js';
5
+ import { AUTO_CAPTURE_TAG, captureEntity, getProjectName, isAutoCaptureEnabled, openHookDb, recordHookRun, truncateTitle } from './_shared.js';
6
6
 
7
7
  // Timeout guard: always exit within 10 seconds
8
8
  const TIMEOUT_MS = 10000;
@@ -95,17 +95,24 @@ process.stdin.on('end', () => {
95
95
 
96
96
  // Build observation content
97
97
  const obsLines = [`Compaction reason: ${reason}`, `Tool calls: ${toolCallCount}`];
98
+
99
+ // No free-form human text exists for a pre-compact save (unlike a commit
100
+ // subject) — same date+project+verb heuristic as session-summary.js.
101
+ // This hook was the one missed by the original design (it hand-rolls the
102
+ // same captureEntity dance as its two siblings but was overlooked as a
103
+ // "write hook" until a code audit found it), so its entities were the
104
+ // clearest case of a raw machine key (`pre-compact-<sessionId>`) with a
105
+ // terse observation ("Compaction reason: manual") standing in as the
106
+ // display label.
107
+ const titleDate = new Date().toISOString().slice(0, 10);
108
+ const title = truncateTitle(`${titleDate} ${projectName}: ${reason} compaction (${toolCallCount} tool calls)`);
98
109
  if (editedFiles.size > 0) {
99
110
  obsLines.push(`Files edited: ${Array.from(editedFiles).join(', ')}`);
100
111
  }
101
112
 
102
113
  // Open DB via shared helper — applies SCHEMA_SQL + status migration.
103
114
  // FTS5 needed for the entity-search index updates below.
104
- // Returns null on plugin-marketplace cache installs without node_modules;
105
- // silently skip in that case (sibling registered copy handles it).
106
- const handle = openHookDb(process.env, { fts: true });
107
- if (!handle) return;
108
- const { db } = handle;
115
+ const { db } = openHookDb(process.env, { fts: true });
109
116
  let written = null;
110
117
  try {
111
118
  // Shared write dance — upsert entity + observations + tags AND reindex FTS
@@ -114,8 +121,16 @@ process.stdin.on('end', () => {
114
121
  name: entityName,
115
122
  type: 'session-summary',
116
123
  observations: obsLines,
117
- tags: ['source:auto-capture', 'urgency:pre-compact', `project:${projectName}`],
124
+ tags: [AUTO_CAPTURE_TAG, 'urgency:pre-compact', `project:${projectName}`],
125
+ title,
118
126
  });
127
+
128
+ // Heartbeat AFTER capture, so the stamp certifies "the capture loop
129
+ // completed", not "a database handle existed". A throw above skips it,
130
+ // and so does a null return — captureEntity's null means the write did
131
+ // not land, and this very hook tells the user "could not save" below;
132
+ // stamping would say "alive" to doctor about the same failed run.
133
+ if (written) recordHookRun(db, 'pre-compact');
119
134
  } finally {
120
135
  db.close();
121
136
  }
@@ -13,10 +13,10 @@ import {
13
13
  getMemeshDirFromDbPath,
14
14
  getProjectName,
15
15
  isTrustedForAutoContext,
16
- tryRequireBetterSqlite,
17
16
  writePrivateJson,
18
17
  hookMatchExpression,
19
18
  } from './_shared.js';
19
+ import { MemeshDatabase } from './_generated/sqlite.js';
20
20
 
21
21
  const dbPath = getDbPath();
22
22
  const memeshDir = getMemeshDirFromDbPath();
@@ -43,9 +43,6 @@ process.stdin.on('end', () => {
43
43
  return pass();
44
44
  }
45
45
 
46
- // Get project name from cwd for project-scoped filtering
47
- const projectName = getProjectName(data.cwd);
48
-
49
46
  // Throttle: skip if we already recalled for this file
50
47
  const fileKey = filePath.toLowerCase();
51
48
  let seenFiles = [];
@@ -64,13 +61,14 @@ process.stdin.on('end', () => {
64
61
 
65
62
  if (!existsSync(dbPath)) return pass();
66
63
 
67
- // tryRequireBetterSqlite() returns null on plugin-marketplace cache
68
- // installs that ship without node_modules; pass-through silently in
69
- // that case so a sibling registered hook copy can still inject
70
- // recall context.
71
- const Database = tryRequireBetterSqlite();
72
- if (!Database) return pass();
73
- const db = new Database(dbPath, { readonly: true });
64
+ // Get project name from cwd for project-scoped filtering.
65
+ // After the throttle/db checks: this spawns 1-2 git subprocesses, and the
66
+ // throttled path (every repeat edit of the same file) must not pay for it.
67
+ const projectName = getProjectName(data.cwd);
68
+
69
+ // `readOnly`, not `readonly`: node:sqlite ignores the lowercase spelling
70
+ // and hands back a WRITABLE handle. This hook only reads.
71
+ const db = new MemeshDatabase(dbPath, { readOnly: true });
74
72
  try {
75
73
 
76
74
  // Check if entities table exists