@pcircle/memesh 4.8.5 → 4.9.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 (226) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/mcp.json +6 -4
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/AGENTS.md +60 -14
  6. package/README.de.md +83 -556
  7. package/README.md +83 -582
  8. package/README.zh-TW.md +84 -573
  9. package/dashboard/dist/index.html +10 -10
  10. package/dist/cli/view-live.d.ts.map +1 -1
  11. package/dist/cli/view-live.js +154 -384
  12. package/dist/cli/view-live.js.map +1 -1
  13. package/dist/core/agent-router.d.ts +11 -10
  14. package/dist/core/agent-router.d.ts.map +1 -1
  15. package/dist/core/agent-router.js +29 -14
  16. package/dist/core/agent-router.js.map +1 -1
  17. package/dist/core/agent-scope-id.d.ts.map +1 -1
  18. package/dist/core/agent-scope-id.js.map +1 -1
  19. package/dist/core/analytics.d.ts.map +1 -1
  20. package/dist/core/analytics.js.map +1 -1
  21. package/dist/core/config.d.ts +4 -40
  22. package/dist/core/config.d.ts.map +1 -1
  23. package/dist/core/config.js +75 -141
  24. package/dist/core/config.js.map +1 -1
  25. package/dist/core/demo.d.ts.map +1 -1
  26. package/dist/core/demo.js +6 -6
  27. package/dist/core/demo.js.map +1 -1
  28. package/dist/core/doctor.d.ts +1 -6
  29. package/dist/core/doctor.d.ts.map +1 -1
  30. package/dist/core/doctor.js +55 -227
  31. package/dist/core/doctor.js.map +1 -1
  32. package/dist/core/dreamer.d.ts +32 -47
  33. package/dist/core/dreamer.d.ts.map +1 -1
  34. package/dist/core/dreamer.js +211 -703
  35. package/dist/core/dreamer.js.map +1 -1
  36. package/dist/core/install-channel.d.ts.map +1 -1
  37. package/dist/core/install-channel.js +4 -47
  38. package/dist/core/install-channel.js.map +1 -1
  39. package/dist/core/install-id.d.ts.map +1 -1
  40. package/dist/core/install-id.js.map +1 -1
  41. package/dist/core/kg-backfill.d.ts.map +1 -1
  42. package/dist/core/kg-backfill.js.map +1 -1
  43. package/dist/core/lesson-engine.d.ts +0 -5
  44. package/dist/core/lesson-engine.d.ts.map +1 -1
  45. package/dist/core/lesson-engine.js +0 -25
  46. package/dist/core/lesson-engine.js.map +1 -1
  47. package/dist/core/lifecycle.d.ts.map +1 -1
  48. package/dist/core/lifecycle.js +54 -48
  49. package/dist/core/lifecycle.js.map +1 -1
  50. package/dist/core/memory-tool.d.ts.map +1 -1
  51. package/dist/core/memory-tool.js +17 -17
  52. package/dist/core/memory-tool.js.map +1 -1
  53. package/dist/core/operations.d.ts +2 -26
  54. package/dist/core/operations.d.ts.map +1 -1
  55. package/dist/core/operations.js +9 -244
  56. package/dist/core/operations.js.map +1 -1
  57. package/dist/core/paths.d.ts +4 -1
  58. package/dist/core/paths.d.ts.map +1 -1
  59. package/dist/core/paths.js +88 -14
  60. package/dist/core/paths.js.map +1 -1
  61. package/dist/core/product-improvements.js +2 -2
  62. package/dist/core/product-improvements.js.map +1 -1
  63. package/dist/core/schema-export.d.ts.map +1 -1
  64. package/dist/core/schema-export.js +10 -0
  65. package/dist/core/schema-export.js.map +1 -1
  66. package/dist/core/semver.d.ts +7 -0
  67. package/dist/core/semver.d.ts.map +1 -0
  68. package/dist/core/semver.js +49 -0
  69. package/dist/core/semver.js.map +1 -0
  70. package/dist/core/serializer.d.ts.map +1 -1
  71. package/dist/core/serializer.js +69 -57
  72. package/dist/core/serializer.js.map +1 -1
  73. package/dist/core/signal-scorer.d.ts.map +1 -1
  74. package/dist/core/signal-scorer.js.map +1 -1
  75. package/dist/core/transcript-extractor.d.ts +1 -85
  76. package/dist/core/transcript-extractor.d.ts.map +1 -1
  77. package/dist/core/transcript-extractor.js +5 -364
  78. package/dist/core/transcript-extractor.js.map +1 -1
  79. package/dist/core/transcript-source.d.ts +22 -6
  80. package/dist/core/transcript-source.d.ts.map +1 -1
  81. package/dist/core/transcript-source.js +108 -69
  82. package/dist/core/transcript-source.js.map +1 -1
  83. package/dist/core/types.d.ts +1 -17
  84. package/dist/core/types.d.ts.map +1 -1
  85. package/dist/core/version-check.d.ts.map +1 -1
  86. package/dist/core/version-check.js +11 -1
  87. package/dist/core/version-check.js.map +1 -1
  88. package/dist/db.d.ts +0 -34
  89. package/dist/db.d.ts.map +1 -1
  90. package/dist/db.js +3 -287
  91. package/dist/db.js.map +1 -1
  92. package/dist/host-runtime/acp.d.ts.map +1 -1
  93. package/dist/host-runtime/acp.js +2 -2
  94. package/dist/host-runtime/acp.js.map +1 -1
  95. package/dist/host-runtime/claude.d.ts.map +1 -1
  96. package/dist/host-runtime/claude.js +9 -7
  97. package/dist/host-runtime/claude.js.map +1 -1
  98. package/dist/host-runtime/codex-session.d.ts +9 -1
  99. package/dist/host-runtime/codex-session.d.ts.map +1 -1
  100. package/dist/host-runtime/codex-session.js +474 -29
  101. package/dist/host-runtime/codex-session.js.map +1 -1
  102. package/dist/host-runtime/codex.d.ts.map +1 -1
  103. package/dist/host-runtime/codex.js +2 -2
  104. package/dist/host-runtime/codex.js.map +1 -1
  105. package/dist/host-runtime/config.d.ts +1 -0
  106. package/dist/host-runtime/config.d.ts.map +1 -1
  107. package/dist/host-runtime/config.js +4 -0
  108. package/dist/host-runtime/config.js.map +1 -1
  109. package/dist/host-runtime/router-client.d.ts.map +1 -1
  110. package/dist/host-runtime/router-client.js +62 -15
  111. package/dist/host-runtime/router-client.js.map +1 -1
  112. package/dist/host-runtime/router.js +2 -2
  113. package/dist/host-runtime/router.js.map +1 -1
  114. package/dist/knowledge-graph.d.ts.map +1 -1
  115. package/dist/knowledge-graph.js +54 -45
  116. package/dist/knowledge-graph.js.map +1 -1
  117. package/dist/mcp/THIRD_PARTY_NOTICES.txt +217 -0
  118. package/dist/mcp/server.js +30685 -38
  119. package/dist/mcp/server.js.map +6 -1
  120. package/dist/skills-manifest.json +22 -22
  121. package/dist/storage/entity-index.d.ts +0 -1
  122. package/dist/storage/entity-index.d.ts.map +1 -1
  123. package/dist/storage/entity-index.js +0 -7
  124. package/dist/storage/entity-index.js.map +1 -1
  125. package/dist/storage/fts-index.d.ts.map +1 -1
  126. package/dist/storage/fts-index.js +6 -7
  127. package/dist/storage/fts-index.js.map +1 -1
  128. package/dist/storage/graph-repairs.d.ts +0 -5
  129. package/dist/storage/graph-repairs.d.ts.map +1 -1
  130. package/dist/storage/graph-repairs.js +4 -91
  131. package/dist/storage/graph-repairs.js.map +1 -1
  132. package/dist/storage/schema.d.ts +1 -1
  133. package/dist/storage/schema.d.ts.map +1 -1
  134. package/dist/storage/schema.js +1 -2
  135. package/dist/storage/schema.js.map +1 -1
  136. package/dist/storage/sqlite.d.ts +0 -1
  137. package/dist/storage/sqlite.d.ts.map +1 -1
  138. package/dist/storage/sqlite.js.map +1 -1
  139. package/dist/transports/agent-messaging.d.ts.map +1 -1
  140. package/dist/transports/agent-messaging.js +5 -7
  141. package/dist/transports/agent-messaging.js.map +1 -1
  142. package/dist/transports/cli/cli.d.ts.map +1 -1
  143. package/dist/transports/cli/cli.js +52 -674
  144. package/dist/transports/cli/cli.js.map +1 -1
  145. package/dist/transports/http/retired-routes.js +1 -1
  146. package/dist/transports/http/retired-routes.js.map +1 -1
  147. package/dist/transports/http/server.d.ts.map +1 -1
  148. package/dist/transports/http/server.js +13 -232
  149. package/dist/transports/http/server.js.map +1 -1
  150. package/dist/transports/mcp/handlers.d.ts +127 -1
  151. package/dist/transports/mcp/handlers.d.ts.map +1 -1
  152. package/dist/transports/mcp/handlers.js +53 -4
  153. package/dist/transports/mcp/handlers.js.map +1 -1
  154. package/dist/transports/schemas.d.ts +52 -0
  155. package/dist/transports/schemas.d.ts.map +1 -1
  156. package/dist/transports/schemas.js +39 -0
  157. package/dist/transports/schemas.js.map +1 -1
  158. package/docs/platforms/README.md +5 -4
  159. package/docs/platforms/agent-messaging.md +124 -60
  160. package/hooks/hooks.json +13 -2
  161. package/llms-install.md +62 -30
  162. package/package.json +4 -5
  163. package/scripts/hooks/_generated/core-paths.js +88 -14
  164. package/scripts/hooks/_generated/fts-index.js +6 -7
  165. package/scripts/hooks/_generated/schema.js +1 -2
  166. package/scripts/hooks/_shared.js +14 -20
  167. package/scripts/hooks/session-start.js +8 -6
  168. package/scripts/hooks/session-summary.js +19 -374
  169. package/skills/memesh/SKILL.md +19 -14
  170. package/skills/memesh-review/SKILL.md +7 -6
  171. package/dist/core/auto-tagger.d.ts +0 -10
  172. package/dist/core/auto-tagger.d.ts.map +0 -1
  173. package/dist/core/auto-tagger.js +0 -63
  174. package/dist/core/auto-tagger.js.map +0 -1
  175. package/dist/core/conflict-candidates.d.ts +0 -20
  176. package/dist/core/conflict-candidates.d.ts.map +0 -1
  177. package/dist/core/conflict-candidates.js +0 -71
  178. package/dist/core/conflict-candidates.js.map +0 -1
  179. package/dist/core/conflict-judge.d.ts +0 -58
  180. package/dist/core/conflict-judge.d.ts.map +0 -1
  181. package/dist/core/conflict-judge.js +0 -189
  182. package/dist/core/conflict-judge.js.map +0 -1
  183. package/dist/core/digest-validator.d.ts +0 -18
  184. package/dist/core/digest-validator.d.ts.map +0 -1
  185. package/dist/core/digest-validator.js +0 -85
  186. package/dist/core/digest-validator.js.map +0 -1
  187. package/dist/core/embedder.d.ts +0 -20
  188. package/dist/core/embedder.d.ts.map +0 -1
  189. package/dist/core/embedder.js +0 -245
  190. package/dist/core/embedder.js.map +0 -1
  191. package/dist/core/failure-analyzer.d.ts +0 -19
  192. package/dist/core/failure-analyzer.d.ts.map +0 -1
  193. package/dist/core/failure-analyzer.js +0 -83
  194. package/dist/core/failure-analyzer.js.map +0 -1
  195. package/dist/core/json-utils.d.ts +0 -3
  196. package/dist/core/json-utils.d.ts.map +0 -1
  197. package/dist/core/json-utils.js +0 -46
  198. package/dist/core/json-utils.js.map +0 -1
  199. package/dist/core/llm-client.d.ts +0 -22
  200. package/dist/core/llm-client.d.ts.map +0 -1
  201. package/dist/core/llm-client.js +0 -203
  202. package/dist/core/llm-client.js.map +0 -1
  203. package/dist/core/llm-telemetry.d.ts +0 -47
  204. package/dist/core/llm-telemetry.d.ts.map +0 -1
  205. package/dist/core/llm-telemetry.js +0 -117
  206. package/dist/core/llm-telemetry.js.map +0 -1
  207. package/dist/core/llm-validator.d.ts +0 -20
  208. package/dist/core/llm-validator.d.ts.map +0 -1
  209. package/dist/core/llm-validator.js +0 -231
  210. package/dist/core/llm-validator.js.map +0 -1
  211. package/dist/core/ollama-host.d.ts +0 -6
  212. package/dist/core/ollama-host.d.ts.map +0 -1
  213. package/dist/core/ollama-host.js +0 -62
  214. package/dist/core/ollama-host.js.map +0 -1
  215. package/dist/core/output-language.d.ts +0 -6
  216. package/dist/core/output-language.d.ts.map +0 -1
  217. package/dist/core/output-language.js +0 -25
  218. package/dist/core/output-language.js.map +0 -1
  219. package/dist/core/prompt-safety.d.ts +0 -4
  220. package/dist/core/prompt-safety.d.ts.map +0 -1
  221. package/dist/core/prompt-safety.js +0 -20
  222. package/dist/core/prompt-safety.js.map +0 -1
  223. package/dist/storage/vector-index.d.ts +0 -3
  224. package/dist/storage/vector-index.d.ts.map +0 -1
  225. package/dist/storage/vector-index.js +0 -13
  226. package/dist/storage/vector-index.js.map +0 -1
@@ -11,6 +11,8 @@ import os from 'os';
11
11
  import path from 'path';
12
12
  import { createHash } from 'crypto';
13
13
  import { execFileSync } from 'child_process';
14
+ export const AGENT_ROUTER_SOCKET_FILENAME = 'agent-router-v2.sock';
15
+ const LEGACY_AGENT_ROUTER_SOCKET_FILENAME = 'agent-router.sock';
14
16
  export function homeDir() {
15
17
  const home = process.env.HOME;
16
18
  if (home && home.length > 0)
@@ -31,6 +33,15 @@ export function getMemeshDirFromDbPath() {
31
33
  ? path.dirname(process.env.MEMESH_DB_PATH)
32
34
  : memeshDir();
33
35
  }
36
+ export function getAgentRouterSocketPath() {
37
+ return path.join(getMemeshDirFromDbPath(), AGENT_ROUTER_SOCKET_FILENAME);
38
+ }
39
+ export function normalizeAgentRouterSocketPath(socketPath) {
40
+ const dataDir = getMemeshDirFromDbPath();
41
+ return socketPath === path.join(dataDir, LEGACY_AGENT_ROUTER_SOCKET_FILENAME)
42
+ ? getAgentRouterSocketPath()
43
+ : socketPath;
44
+ }
34
45
  export function getProjectName(cwdInput) {
35
46
  const cwd = cwdInput && cwdInput.length > 0 ? cwdInput : process.cwd();
36
47
  const cached = projectNameCache.get(cwd);
@@ -44,22 +55,36 @@ const projectNameCache = new Map();
44
55
  function resolveProjectIdentity(cwd) {
45
56
  const remote = tryGit(cwd, ['config', '--get', 'remote.origin.url']);
46
57
  if (remote) {
47
- const slug = slugFromRemoteUrl(remote);
48
- if (slug)
49
- return slug;
58
+ const locator = canonicalRemoteLocator(remote);
59
+ if (locator) {
60
+ const label = path.posix.basename(locator).replace(/\.git$/i, '');
61
+ return projectIdentity(label, locator);
62
+ }
50
63
  }
51
64
  const root = tryGit(cwd, ['rev-parse', '--show-toplevel']);
52
- if (root)
53
- return path.basename(root);
65
+ const commonDir = root
66
+ ? tryGit(cwd, ['rev-parse', '--git-common-dir'])
67
+ : null;
68
+ const absoluteCommonDir = commonDir ? path.resolve(cwd, commonDir) : null;
69
+ const localPath = absoluteCommonDir && path.basename(absoluteCommonDir) === '.git'
70
+ ? path.dirname(absoluteCommonDir)
71
+ : (root ?? cwd);
54
72
  let real;
55
73
  try {
56
- real = fs.realpathSync.native(cwd);
74
+ real = fs.realpathSync.native(localPath);
57
75
  }
58
76
  catch {
59
- real = path.resolve(cwd);
77
+ real = path.resolve(localPath);
60
78
  }
61
- const suffix = createHash('sha256').update(real).digest('hex').slice(0, 8);
62
- return `${path.basename(real)}-${suffix}`;
79
+ return projectIdentity(path.basename(real), real);
80
+ }
81
+ const PROJECT_HASH_HEX_LENGTH = 32;
82
+ const PROJECT_ID_MAX_LENGTH = 200;
83
+ const PROJECT_LABEL_MAX_LENGTH = PROJECT_ID_MAX_LENGTH - PROJECT_HASH_HEX_LENGTH - 1;
84
+ function projectIdentity(label, locator) {
85
+ const readable = label.normalize('NFC').slice(0, PROJECT_LABEL_MAX_LENGTH) || 'project';
86
+ const suffix = createHash('sha256').update(locator).digest('hex').slice(0, PROJECT_HASH_HEX_LENGTH);
87
+ return `${readable}~${suffix}`;
63
88
  }
64
89
  function tryGit(cwd, args) {
65
90
  try {
@@ -75,12 +100,61 @@ function tryGit(cwd, args) {
75
100
  return null;
76
101
  }
77
102
  }
78
- export function slugFromRemoteUrl(url) {
79
- const cleaned = url.trim().replace(/\.git$/i, '').replace(/[/\\]+$/, '');
80
- if (!cleaned)
103
+ export function canonicalRemoteLocator(remote) {
104
+ const value = remote.trim();
105
+ if (!value)
106
+ return null;
107
+ if (path.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || /^\\\\/.test(value))
108
+ return null;
109
+ let host;
110
+ let port = '';
111
+ let user;
112
+ let remotePath;
113
+ let transport;
114
+ if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(value)) {
115
+ let parsed;
116
+ try {
117
+ parsed = new URL(value);
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ if (parsed.protocol === 'file:' || !parsed.hostname)
123
+ return null;
124
+ host = parsed.hostname.toLowerCase();
125
+ port = parsed.port;
126
+ const protocol = parsed.protocol.toLowerCase();
127
+ if ((protocol === 'ssh:' || protocol === 'git+ssh:') && port === '22')
128
+ port = '';
129
+ user = parsed.username;
130
+ remotePath = parsed.pathname;
131
+ transport = protocol === 'ssh:' || protocol === 'git+ssh:'
132
+ ? 'ssh-absolute'
133
+ : protocol.slice(0, -1);
134
+ }
135
+ else {
136
+ const scp = /^(?:([^@]+)@)?(\[[^\]]+\]|[^:/]+):(.+)$/.exec(value);
137
+ if (!scp)
138
+ return null;
139
+ user = scp[1] ?? '';
140
+ host = scp[2].toLowerCase();
141
+ remotePath = scp[3];
142
+ transport = remotePath.startsWith('/') ? 'ssh-absolute' : 'ssh-relative';
143
+ }
144
+ const pathWithoutSlashes = remotePath.replace(/^\/+|\/+$/g, '');
145
+ if (!host || !pathWithoutSlashes)
81
146
  return null;
82
- const seg = cleaned.split(/[/:\\]/).filter(Boolean).pop();
83
- return seg && seg.length > 0 ? seg : null;
147
+ const endpoint = `${host}${port ? `:${port}` : ''}`;
148
+ const standardGithub = host === 'github.com'
149
+ && port === ''
150
+ && (transport === 'https' || ((transport === 'ssh-relative' || transport === 'ssh-absolute') && user === 'git'));
151
+ const normalizedPath = standardGithub
152
+ ? pathWithoutSlashes.replace(/\.git$/i, '')
153
+ : pathWithoutSlashes;
154
+ if (standardGithub)
155
+ return `${endpoint}/${normalizedPath}`;
156
+ const authority = transport.startsWith('ssh-') && user ? `${user}@${endpoint}` : endpoint;
157
+ return `${transport}://${authority}/${normalizedPath}`;
84
158
  }
85
159
  export function _clearProjectNameCache() {
86
160
  projectNameCache.clear();
@@ -75,15 +75,14 @@ export function removeFromFts(db, entityId, name, prevObsText, prevTitle) {
75
75
  db.prepare("INSERT INTO entities_fts (entities_fts, rowid, name, observations) VALUES('delete', ?, ?, ?)").run(entityId, toIndexForm(name), toIndexForm(foldTitleIntoObservations(prevTitle, prevObsText)));
76
76
  }
77
77
  catch (err) {
78
- if (isBenignFtsDeleteError(err))
79
- return;
80
- process.stderr.write(`[memesh fts-index] removeFromFts(rowid=${entityId}) failed: ${err instanceof Error ? err.message : String(err)}\n`);
78
+ try {
79
+ process.stderr.write(`[memesh fts-index] removeFromFts(rowid=${entityId}) failed: ${err instanceof Error ? err.message : String(err)}\n`);
80
+ }
81
+ catch {
82
+ }
83
+ throw err;
81
84
  }
82
85
  }
83
- function isBenignFtsDeleteError(err) {
84
- const msg = err?.message ?? '';
85
- return /no such rowid|values do not match|no such row\b/i.test(msg);
86
- }
87
86
  export function joinIndexedObservations(contents) {
88
87
  return contents.join(' ');
89
88
  }
@@ -56,8 +56,7 @@ CREATE INDEX IF NOT EXISTS idx_relations_from ON relations(from_entity_id);
56
56
  CREATE INDEX IF NOT EXISTS idx_relations_to ON relations(to_entity_id);
57
57
  CREATE INDEX IF NOT EXISTS idx_entities_type_created ON entities(type, created_at);
58
58
 
59
- -- Migration markers and small bits of persistent state (index segmentation
60
- -- version, embedding dimension, pending-reindex flags, backfill markers).
59
+ -- Migration markers and small bits of persistent state.
61
60
  --
62
61
  -- This used to be created ad hoc by each helper that needed it — four inline
63
62
  -- CREATE TABLE IF NOT EXISTS copies in src/db.ts, none of them visible to
@@ -31,7 +31,7 @@ import {
31
31
  getMemeshDirFromDbPath,
32
32
  getProjectName,
33
33
  redactSecrets,
34
- slugFromRemoteUrl,
34
+ canonicalRemoteLocator,
35
35
  } from './_generated/core-paths.js';
36
36
  import { autoCaptureDecision } from './_generated/capture-flag.js';
37
37
  export { assembleTopologyBlock, buildReferenceContext, extractCitedMemoryIds, DEFAULT_TOPOLOGY_BUDGET, GLOBAL_TOPOLOGY_LIMIT, SNIPPET_FETCH_CHARS, TOPOLOGY_CANDIDATE_CAP } from './_generated/work-topology.js';
@@ -126,15 +126,15 @@ import {
126
126
  tokenizeQuery,
127
127
  } from './_generated/fts-index.js';
128
128
 
129
- export { homeDir, memeshDir, getDbPath, getMemeshDirFromDbPath, getProjectName, redactSecrets, slugFromRemoteUrl };
129
+ export { homeDir, memeshDir, getDbPath, getMemeshDirFromDbPath, getProjectName, redactSecrets, canonicalRemoteLocator };
130
130
 
131
131
  /**
132
132
  * Resolve the package root from a hook file's `import.meta.url`.
133
133
  *
134
134
  * Hooks live at `<pkgRoot>/scripts/hooks/<file>.js`, so the path needs
135
135
  * three `dirname()` hops to reach `<pkgRoot>`. Centralising this here
136
- * prevents the off-by-one regression that silently disabled noise
137
- * compression and LLM failure analysis between 4.0.4–4.1.0 (the inline
136
+ * prevents the off-by-one regression that silently disabled hook-to-core
137
+ * imports between 4.0.4–4.1.0 (the inline
138
138
  * `dirname(dirname(...))` only reached `<pkgRoot>/scripts`, and the
139
139
  * surrounding `catch` swallowed the resulting ENOENT).
140
140
  *
@@ -163,7 +163,7 @@ export function resolvePluginRoot(metaUrl) {
163
163
  *
164
164
  * That error is caught by each caller's surrounding try/catch and only
165
165
  * traced to stderr, so on Windows every hook that reaches for a dist module
166
- * — LLM failure analysis, lesson creation, dream auto-trigger, auto-decay —
166
+ * — lifecycle reads, lesson creation, and auto-decay —
167
167
  * silently did nothing, while macOS/Linux and `memesh doctor` stayed green.
168
168
  * A textbook fake-working boundary: the discipline of converting the path
169
169
  * (already applied to the install-channel import above via
@@ -363,19 +363,15 @@ export function openHookDb(env = process.env, opts = {}) {
363
363
  const dbDir = env.MEMESH_DB_PATH ? dirname(env.MEMESH_DB_PATH) : memeshDir();
364
364
  if (!existsSync(dbDir)) mkdirSync(dbDir, { recursive: true });
365
365
 
366
- // `allowExtension` matches src/db.ts: it only permits a later
367
- // `enableLoadExtension(true)`, and session-summary.js needs one to load
368
- // sqlite-vec through this handle. The switch itself stays off.
369
- const db = new MemeshDatabase(dbPath, { allowExtension: true });
366
+ const db = new MemeshDatabase(dbPath);
370
367
  db.pragma('journal_mode = WAL');
371
368
  db.pragma('foreign_keys = ON');
372
369
  // A hook waits for a held write lock for less time than Claude Code will
373
370
  // wait for the hook.
374
371
  //
375
- // `MemeshDatabase` sets `busy_timeout = 30000`, and that number is right
376
- // for the processes it was chosen for: a 30k-vector `swapVectorGeneration`
377
- // holds the write lock for ~9s, and the CLI, the MCP server and the HTTP
378
- // server should WAIT for it rather than fail. A hook cannot. Its budget in
372
+ // `MemeshDatabase` sets `busy_timeout = 30000`, which lets ordinary CLI,
373
+ // MCP and HTTP operations wait through brief write contention. A hook
374
+ // cannot use that whole budget. Its timeout in
379
375
  // `hooks/hooks.json` is 3s (UserPromptSubmit) to 10s (Stop, PreCompact),
380
376
  // so a 30s wait has exactly one possible ending: the harness kills the
381
377
  // hook. The capture is lost either way — the difference is that the user
@@ -559,9 +555,8 @@ export { truncateTitle } from './_generated/title.js';
559
555
  * as two implementations of the same contract).
560
556
  *
561
557
  * The caller MUST open its DB with `openHookDb(env, { fts: true })` so the FTS
562
- * table is guaranteed present. Embeddings + auto-tagging + signal-scoring are
563
- * deliberately NOT done here: hooks are cheap always-on capture, and those are
564
- * the heavier, user-initiated `remember` concerns (core owns them).
558
+ * table is guaranteed present. Signal scoring is deliberately not done here:
559
+ * hooks stay a cheap always-on capture path and core owns later enrichment.
565
560
  *
566
561
  * @param {import('./_generated/sqlite.js').MemeshDatabase} db - an open hook DB handle
567
562
  * @param {{name: string, type: string, observations?: string[], tags?: string[], title?: string | null, metadata?: Record<string, unknown>}} entity
@@ -601,10 +596,9 @@ function captureEntityInner(db, { name, type, observations, tags, title, metadat
601
596
  // earlier writer (possibly another host, via MCP) already recorded.
602
597
  //
603
598
  // title_source: every title a hook writes is machine-derived, so it is
604
- // marked 'heuristic'. The mark is what lets a later LLM titling pass
605
- // (dreamer backfill) know which titles it may replace an UNMARKED title
606
- // is treated as human-provided and never touched, so omitting the mark
607
- // here would make today's date+verb titles permanent.
599
+ // marked 'heuristic'. The mark distinguishes generated display text from an
600
+ // unmarked human-provided title, so later reviewed edits can preserve the
601
+ // ownership boundary.
608
602
  const insertMetadata = { ...(metadata ?? {}), provenance: { source_host: 'claude-code' } };
609
603
  if (title != null) insertMetadata.title_source = 'heuristic';
610
604
  const insertResult = db
@@ -1042,7 +1042,7 @@ process.stdin.on('end', async () => {
1042
1042
  // nothing — a fenced block containing only a branch name tells the
1043
1043
  // agent something it can already see. briefing.test.ts's parity case
1044
1044
  // is what keeps this identical to the tool side.
1045
- let memoryContext = '';
1045
+ let memoryContext = workPackageGuidance;
1046
1046
  if (memoryLines.length > 0) {
1047
1047
  const repoLines = repoStateLines(readRepoState(data.cwd));
1048
1048
  if (repoLines.length > 0) memoryLines.unshift(...repoLines, '');
@@ -1055,7 +1055,7 @@ process.stdin.on('end', async () => {
1055
1055
  // charges task state plus project/foreign sections against the main
1056
1056
  // ceiling and global context against its small additive ceiling. It
1057
1057
  // returns whole lines only, so the closing fence cannot be cut.
1058
- memoryContext = buildReferenceContext(memoryLines);
1058
+ memoryContext = buildReferenceContext(memoryLines) + '\n\n' + workPackageGuidance;
1059
1059
  // The citation contract — OUTSIDE the fence on purpose: the fence
1060
1060
  // declares its content "background data, not instructions", and
1061
1061
  // this line IS an instruction. One line is the entire write side of
@@ -1221,9 +1221,9 @@ process.stdin.on('end', async () => {
1221
1221
  } catch (err) {
1222
1222
  // Non-critical — noise compression failed, will retry next session.
1223
1223
  // Trace because this catch previously hid an off-by-one regression
1224
- // in resolvePluginRoot (4.0.4-4.1.0) that silently disabled both
1225
- // noise compression AND LLM failure analysis for three minor
1226
- // releases. A one-line stderr would have surfaced it on day 1.
1224
+ // in resolvePluginRoot (4.0.4-4.1.0) that silently disabled noise
1225
+ // compression for three minor releases. A one-line stderr would have
1226
+ // surfaced it on day 1.
1227
1227
  try { process.stderr.write(`[memesh session-start] noise-compression: ${err?.message || err}\n`); } catch {}
1228
1228
  }
1229
1229
 
@@ -1267,7 +1267,9 @@ process.stdin.on('end', async () => {
1267
1267
  *
1268
1268
  * The shape is asserted by tests/helpers/hook-output-contract.ts.
1269
1269
  */
1270
- function output(text, memoryContext) {
1270
+ const workPackageGuidance = 'Work packages: check work_package prepare for this project (digest or transcript). When available, offer a concise host-native interactive choice in the user’s conversation language: dispatch an agent task, later (defer not_now), or stop suggesting for this session. Never dispatch without the user choosing it. The Dashboard cannot dispatch agents, and no durable opt-out is implied.';
1271
+
1272
+ function output(text, memoryContext = workPackageGuidance) {
1271
1273
  const payload = { systemMessage: text };
1272
1274
  if (memoryContext) {
1273
1275
  payload.hookSpecificOutput = {