dsh-mnemon 0.1.1 → 0.1.3

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 (176) hide show
  1. package/README.en.md +88 -120
  2. package/README.md +89 -121
  3. package/cordis.patch.yml +1 -0
  4. package/docs/assets/diagrams/en/memory-system-flow.png +0 -0
  5. package/docs/assets/diagrams/zh-CN/memory-system-flow.png +0 -0
  6. package/docs/assets/media/dsh-mnemon-memory-system-demo-poster.jpg +0 -0
  7. package/docs/assets/media/dsh-mnemon-memory-system-demo.gif +0 -0
  8. package/docs/assets/media/dsh-mnemon-memory-system-demo.mp4 +0 -0
  9. package/docs/assets/screenshots/conversation-memory-jump.png +0 -0
  10. package/docs/assets/screenshots/conversation-save-dialog.png +0 -0
  11. package/docs/assets/screenshots/conversation-turn-memory.png +0 -0
  12. package/docs/assets/screenshots/document-create-dialog.png +0 -0
  13. package/docs/assets/screenshots/documents-markdown.png +0 -0
  14. package/docs/assets/screenshots/entities-context.png +0 -0
  15. package/docs/assets/screenshots/memory-content.png +0 -0
  16. package/docs/assets/screenshots/overview-memory-graph.png +0 -0
  17. package/docs/assets/screenshots/recall-agent-answer.png +0 -0
  18. package/docs/assets/screenshots/remember-dialog.png +0 -0
  19. package/docs/assets/screenshots/runtime-memory-add.png +0 -0
  20. package/docs/assets/screenshots/runtime-memory.png +0 -0
  21. package/docs/assets/screenshots/settings-memory-system.png +0 -0
  22. package/docs/assets/screenshots/status-overview.png +0 -0
  23. package/docs/assets/screenshots/version-check.png +0 -0
  24. package/docs/en/README.md +38 -32
  25. package/docs/en/architecture.md +3 -1
  26. package/docs/en/configuration.md +13 -9
  27. package/docs/en/development.md +24 -4
  28. package/docs/en/getting-started.md +78 -86
  29. package/docs/en/interfaces.md +99 -89
  30. package/docs/en/operations.md +103 -92
  31. package/docs/en/project-overview.md +82 -196
  32. package/docs/en/roadmap.md +1 -1
  33. package/docs/en/storage-model.md +1 -1
  34. package/docs/en/ui-guide.md +156 -0
  35. package/docs/zh-CN/README.md +35 -29
  36. package/docs/zh-CN/architecture.md +3 -1
  37. package/docs/zh-CN/configuration.md +13 -9
  38. package/docs/zh-CN/development.md +24 -4
  39. package/docs/zh-CN/getting-started.md +71 -79
  40. package/docs/zh-CN/interfaces.md +84 -74
  41. package/docs/zh-CN/operations.md +96 -85
  42. package/docs/zh-CN/project-overview.md +78 -192
  43. package/docs/zh-CN/roadmap.md +1 -1
  44. package/docs/zh-CN/storage-model.md +1 -1
  45. package/docs/zh-CN/ui-guide.md +160 -0
  46. package/lib/client.js +2836 -2041
  47. package/lib/client.js.map +1 -1
  48. package/lib/index.js +715 -124
  49. package/lib/types/channels.d.ts +4 -0
  50. package/lib/types/channels.d.ts.map +1 -0
  51. package/lib/types/channels.js +4 -0
  52. package/lib/types/channels.js.map +1 -0
  53. package/lib/types/client/MnemonSaveAction.d.ts.map +1 -1
  54. package/lib/types/client/MnemonSaveAction.js +4 -55
  55. package/lib/types/client/MnemonSaveAction.js.map +1 -1
  56. package/lib/types/client/MnemonSettingsCard.d.ts +1 -3
  57. package/lib/types/client/MnemonSettingsCard.d.ts.map +1 -1
  58. package/lib/types/client/MnemonSettingsCard.js +13 -31
  59. package/lib/types/client/MnemonSettingsCard.js.map +1 -1
  60. package/lib/types/client/MnemonTurnTail.d.ts +3 -0
  61. package/lib/types/client/MnemonTurnTail.d.ts.map +1 -1
  62. package/lib/types/client/MnemonTurnTail.js +15 -3
  63. package/lib/types/client/MnemonTurnTail.js.map +1 -1
  64. package/lib/types/client/MnemonView.d.ts +17 -0
  65. package/lib/types/client/MnemonView.d.ts.map +1 -1
  66. package/lib/types/client/MnemonView.js +431 -96
  67. package/lib/types/client/MnemonView.js.map +1 -1
  68. package/lib/types/client/MnemonViewAppearance.d.ts +21 -0
  69. package/lib/types/client/MnemonViewAppearance.d.ts.map +1 -0
  70. package/lib/types/client/MnemonViewAppearance.js +67 -0
  71. package/lib/types/client/MnemonViewAppearance.js.map +1 -0
  72. package/lib/types/client/anchor.d.ts +1 -1
  73. package/lib/types/client/anchor.js +1 -1
  74. package/lib/types/client/api.d.ts +7 -1
  75. package/lib/types/client/api.d.ts.map +1 -1
  76. package/lib/types/client/api.js +41 -24
  77. package/lib/types/client/api.js.map +1 -1
  78. package/lib/types/client/index.d.ts +1 -1
  79. package/lib/types/client/index.d.ts.map +1 -1
  80. package/lib/types/client/index.js +63 -53
  81. package/lib/types/client/index.js.map +1 -1
  82. package/lib/types/client/locales.d.ts +158 -306
  83. package/lib/types/client/locales.d.ts.map +1 -1
  84. package/lib/types/client/locales.js +180 -328
  85. package/lib/types/client/locales.js.map +1 -1
  86. package/lib/types/client/settings.d.ts +1 -1
  87. package/lib/types/client/settings.d.ts.map +1 -1
  88. package/lib/types/client/settings.js +1 -1
  89. package/lib/types/client/settings.js.map +1 -1
  90. package/lib/types/client/sidebar-entry.d.ts +6 -0
  91. package/lib/types/client/sidebar-entry.d.ts.map +1 -0
  92. package/lib/types/client/sidebar-entry.js +134 -0
  93. package/lib/types/client/sidebar-entry.js.map +1 -0
  94. package/lib/types/client/workspace-controller.d.ts +15 -0
  95. package/lib/types/client/workspace-controller.d.ts.map +1 -0
  96. package/lib/types/client/workspace-controller.js +21 -0
  97. package/lib/types/client/workspace-controller.js.map +1 -0
  98. package/lib/types/client/workspace-mount.d.ts +8 -0
  99. package/lib/types/client/workspace-mount.d.ts.map +1 -0
  100. package/lib/types/client/workspace-mount.js +138 -0
  101. package/lib/types/client/workspace-mount.js.map +1 -0
  102. package/lib/types/commands.d.ts +10 -2
  103. package/lib/types/commands.d.ts.map +1 -1
  104. package/lib/types/commands.js +5 -1
  105. package/lib/types/commands.js.map +1 -1
  106. package/lib/types/config.d.ts +6 -5
  107. package/lib/types/config.d.ts.map +1 -1
  108. package/lib/types/config.js +12 -12
  109. package/lib/types/config.js.map +1 -1
  110. package/lib/types/contracts.d.ts +11 -0
  111. package/lib/types/contracts.d.ts.map +1 -1
  112. package/lib/types/documents.d.ts.map +1 -1
  113. package/lib/types/documents.js +6 -14
  114. package/lib/types/documents.js.map +1 -1
  115. package/lib/types/guidance.d.ts +3 -1
  116. package/lib/types/guidance.d.ts.map +1 -1
  117. package/lib/types/guidance.js +12 -0
  118. package/lib/types/guidance.js.map +1 -1
  119. package/lib/types/index.d.ts +2 -1
  120. package/lib/types/index.d.ts.map +1 -1
  121. package/lib/types/index.js +9 -8
  122. package/lib/types/index.js.map +1 -1
  123. package/lib/types/lifecycle.d.ts +9 -2
  124. package/lib/types/lifecycle.d.ts.map +1 -1
  125. package/lib/types/lifecycle.js +11 -4
  126. package/lib/types/lifecycle.js.map +1 -1
  127. package/lib/types/live-runtime.d.ts +26 -2
  128. package/lib/types/live-runtime.d.ts.map +1 -1
  129. package/lib/types/live-runtime.js +73 -3
  130. package/lib/types/live-runtime.js.map +1 -1
  131. package/lib/types/memory-bodies.d.ts +1 -0
  132. package/lib/types/memory-bodies.d.ts.map +1 -1
  133. package/lib/types/memory-bodies.js +7 -0
  134. package/lib/types/memory-bodies.js.map +1 -1
  135. package/lib/types/rpc.d.ts +7 -6
  136. package/lib/types/rpc.d.ts.map +1 -1
  137. package/lib/types/rpc.js +139 -22
  138. package/lib/types/rpc.js.map +1 -1
  139. package/lib/types/runner.d.ts +1 -1
  140. package/lib/types/runner.d.ts.map +1 -1
  141. package/lib/types/runner.js +2 -2
  142. package/lib/types/runner.js.map +1 -1
  143. package/lib/types/service.d.ts +18 -0
  144. package/lib/types/service.d.ts.map +1 -1
  145. package/lib/types/service.js +4 -0
  146. package/lib/types/service.js.map +1 -1
  147. package/lib/types/settings.d.ts.map +1 -1
  148. package/lib/types/settings.js +2 -3
  149. package/lib/types/settings.js.map +1 -1
  150. package/lib/types/subagent.d.ts +11 -2
  151. package/lib/types/subagent.d.ts.map +1 -1
  152. package/lib/types/subagent.js +34 -29
  153. package/lib/types/subagent.js.map +1 -1
  154. package/lib/types/tools.d.ts +11 -1
  155. package/lib/types/tools.d.ts.map +1 -1
  156. package/lib/types/tools.js +27 -16
  157. package/lib/types/tools.js.map +1 -1
  158. package/lib/types/version-updates.d.ts +61 -0
  159. package/lib/types/version-updates.d.ts.map +1 -0
  160. package/lib/types/version-updates.js +377 -0
  161. package/lib/types/version-updates.js.map +1 -0
  162. package/package.json +4 -1
  163. package/docs/zh-CN/assets/screenshots/conversation-recall.png +0 -0
  164. package/docs/zh-CN/assets/screenshots/conversation-writeback.png +0 -0
  165. package/docs/zh-CN/assets/screenshots/documents-markdown.png +0 -0
  166. package/docs/zh-CN/assets/screenshots/entities-context.png +0 -0
  167. package/docs/zh-CN/assets/screenshots/memory-content.png +0 -0
  168. package/docs/zh-CN/assets/screenshots/overview-memory-graph.png +0 -0
  169. package/docs/zh-CN/assets/screenshots/recall-agent-answer.png +0 -0
  170. package/docs/zh-CN/assets/screenshots/runtime-memory.png +0 -0
  171. package/lib/types/client/MnemonToolviews.d.ts +0 -19
  172. package/lib/types/client/MnemonToolviews.d.ts.map +0 -1
  173. package/lib/types/client/MnemonToolviews.js +0 -172
  174. package/lib/types/client/MnemonToolviews.js.map +0 -1
  175. /package/docs/{en/assets → assets/diagrams/en}/project-architecture.svg +0 -0
  176. /package/docs/{zh-CN/assets → assets/diagrams/zh-CN}/project-architecture.svg +0 -0
package/lib/index.js CHANGED
@@ -1,19 +1,19 @@
1
1
  import z from "schemastery";
2
2
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
- import { accessSync, closeSync, constants, existsSync, fstatSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
4
+ import { accessSync, closeSync, constants, existsSync, fstatSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { homedir, tmpdir } from "node:os";
6
6
  import { strToU8, unzipSync, zipSync } from "fflate";
7
7
  import { spawn } from "node:child_process";
8
+ import { fileURLToPath } from "node:url";
8
9
  //#region lib/types/config-values.js
9
10
  const DEFAULT_TIMEOUT_MS = 1e4;
10
11
  const DEFAULT_IDLE_REVIEW_MS = 3e4;
11
12
  //#endregion
12
13
  //#region lib/types/config.js
13
14
  const InteractionConfig = z.object({
14
- toolviews: z.boolean().default(false),
15
- turnBar: z.boolean().default(false),
16
- saveAction: z.boolean().default(false)
15
+ turnBar: z.boolean().default(true),
16
+ saveAction: z.boolean().default(true)
17
17
  });
18
18
  const Config = z.object({
19
19
  storageScope: z.union([
@@ -33,6 +33,7 @@ const Config = z.object({
33
33
  timeoutMs: z.number().step(1).min(100).max(12e4).default(DEFAULT_TIMEOUT_MS),
34
34
  defaultRecallLimit: z.number().step(1).min(1).max(50).default(10),
35
35
  routingGuidance: z.boolean().default(true),
36
+ displayMode: z.union(["sidebar", "buildin"]).default("sidebar"),
36
37
  tabEnabled: z.boolean().default(true),
37
38
  writeEnabled: z.boolean().default(true),
38
39
  lifecycleEnabled: z.boolean().default(true),
@@ -41,19 +42,18 @@ const Config = z.object({
41
42
  idleReviewMs: z.number().step(1).min(5e3).max(6e5).default(DEFAULT_IDLE_REVIEW_MS),
42
43
  conversationInteraction: z.object({
43
44
  toolviews: z.boolean().default(false),
44
- turnBar: z.boolean().default(false),
45
- saveAction: z.boolean().default(false)
45
+ turnBar: z.boolean().default(true),
46
+ saveAction: z.boolean().default(true)
46
47
  }).default({
47
48
  toolviews: false,
48
- turnBar: false,
49
- saveAction: false
49
+ turnBar: true,
50
+ saveAction: true
50
51
  })
51
52
  });
52
53
  function resolveInteractionConfig(config = {}) {
53
54
  return {
54
- toolviews: config.toolviews ?? false,
55
- turnBar: config.turnBar ?? false,
56
- saveAction: config.saveAction ?? false
55
+ turnBar: config.turnBar ?? true,
56
+ saveAction: config.saveAction ?? true
57
57
  };
58
58
  }
59
59
  function optionalText$1(value) {
@@ -117,6 +117,7 @@ function resolveConfig(config = {}) {
117
117
  timeoutMs: config.timeoutMs ?? 1e4,
118
118
  defaultRecallLimit: config.defaultRecallLimit ?? 10,
119
119
  routingGuidance: config.routingGuidance ?? true,
120
+ displayMode: config.displayMode ?? "sidebar",
120
121
  tabEnabled: config.tabEnabled ?? true,
121
122
  writeEnabled: config.writeEnabled ?? true,
122
123
  lifecycleEnabled: config.lifecycleEnabled ?? true,
@@ -125,13 +126,16 @@ function resolveConfig(config = {}) {
125
126
  idleReviewMs: config.idleReviewMs ?? 3e4,
126
127
  conversationInteraction: {
127
128
  toolviews: config.conversationInteraction?.toolviews ?? false,
128
- turnBar: config.conversationInteraction?.turnBar ?? false,
129
- saveAction: config.conversationInteraction?.saveAction ?? false
129
+ turnBar: config.conversationInteraction?.turnBar ?? true,
130
+ saveAction: config.conversationInteraction?.saveAction ?? true
130
131
  }
131
132
  };
132
133
  }
133
134
  //#endregion
134
135
  //#region lib/types/commands.js
136
+ function isAgentServiceSource(value) {
137
+ return "forAgent" in value && typeof value.forAgent === "function";
138
+ }
135
139
  const USAGE = "用法:/mnemon [status|recall <查询>|related <ID>|remember <内容>|forget <ID>]";
136
140
  function error(text) {
137
141
  return {
@@ -166,7 +170,8 @@ function splitInput(rawInput) {
166
170
  argument: input.slice(separator).trim()
167
171
  };
168
172
  }
169
- async function execute(service, coordinator, invocation) {
173
+ async function execute(serviceOrSource, coordinator, invocation) {
174
+ const service = isAgentServiceSource(serviceOrSource) ? serviceOrSource.forAgent(invocation.agent).service : serviceOrSource;
170
175
  const { verb, argument } = splitInput(invocation.rawInput);
171
176
  switch (verb) {
172
177
  case "status": {
@@ -762,26 +767,19 @@ var DocumentManager = class {
762
767
  }
763
768
  forWorkspace(workspaceRoot) {
764
769
  const root = resolve(workspaceRoot);
765
- let controller = this.controllers.get(root);
770
+ const storageRoot = this.storageRoot?.();
771
+ const key = storageRoot === void 0 ? root : `${resolve(storageRoot)}\0${root}`;
772
+ let controller = this.controllers.get(key);
766
773
  if (controller === void 0) {
767
- controller = new DocumentController(root, this.limitBytes, this.now);
768
- this.controllers.set(root, controller);
774
+ controller = new DocumentController(root, this.limitBytes, this.now, storageRoot);
775
+ this.controllers.set(key, controller);
769
776
  }
770
777
  return controller;
771
778
  }
772
779
  forAgent(agent) {
773
780
  const cwd = agent.session.header?.cwd;
774
781
  if (cwd === void 0 || cwd.trim() === "") throw new Error("the current DSH session has no workspace for Mnemon Documents");
775
- if (this.storageRoot === void 0) return this.forWorkspace(cwd);
776
- const storageRoot = resolve(this.storageRoot());
777
- const root = resolve(cwd);
778
- const key = `${storageRoot}\0${root}`;
779
- let controller = this.controllers.get(key);
780
- if (controller === void 0) {
781
- controller = new DocumentController(root, this.limitBytes, this.now, storageRoot);
782
- this.controllers.set(key, controller);
783
- }
784
- return controller;
782
+ return this.forWorkspace(cwd);
785
783
  }
786
784
  };
787
785
  //#endregion
@@ -792,6 +790,9 @@ const ROUTING_GUIDANCE = "Use memory only by need. For substantial project recor
792
790
  function systemPrompt(ctx) {
793
791
  return ctx.get("systemPrompt");
794
792
  }
793
+ function scopedSystemPrompt(agent) {
794
+ return agent.ctx.get?.("systemPrompt");
795
+ }
795
796
  function registerGuidance(ctx, config) {
796
797
  systemPrompt(ctx)?.section?.({
797
798
  name: GUIDANCE_SECTION_NAME,
@@ -807,6 +808,15 @@ function registerRuntimeMemoryContext(ctx, runtimeMemory) {
807
808
  text: () => runtimeMemory.contextText()
808
809
  });
809
810
  }
811
+ /** Shadow the global fallback with the current Agent workspace's hot memory. */
812
+ function registerAgentRuntimeMemoryContext(agent, runtimeMemory) {
813
+ const dispose = scopedSystemPrompt(agent)?.section?.({
814
+ name: RUNTIME_MEMORY_SECTION_NAME,
815
+ order: 145,
816
+ text: () => runtimeMemory().contextText()
817
+ });
818
+ return typeof dispose === "function" ? dispose : () => {};
819
+ }
810
820
  const RUNTIME_ENTRY_DELIMITER = "\n§\n";
811
821
  const RUNTIME_MEMORY_LIMITS = {
812
822
  memory: 10240,
@@ -2078,7 +2088,7 @@ function expandHome$1(path) {
2078
2088
  if (path === "~") return homedir();
2079
2089
  return path.startsWith("~/") ? join(homedir(), path.slice(2)) : path;
2080
2090
  }
2081
- function executable(path) {
2091
+ function executable$1(path) {
2082
2092
  try {
2083
2093
  accessSync(path, constants.X_OK);
2084
2094
  return true;
@@ -2092,7 +2102,7 @@ function findMnemonCommand(config) {
2092
2102
  const envPath = process.env.MNEMON_CLI_PATH?.trim();
2093
2103
  if (envPath !== void 0 && envPath !== "") {
2094
2104
  const path = expandHome$1(envPath);
2095
- if (executable(path)) return path;
2105
+ if (executable$1(path)) return path;
2096
2106
  }
2097
2107
  for (const directory of (process.env.PATH ?? "").split(delimiter)) {
2098
2108
  if (directory === "") continue;
@@ -2102,12 +2112,12 @@ function findMnemonCommand(config) {
2102
2112
  "mnemon"
2103
2113
  ] : ["mnemon"]) {
2104
2114
  const path = join(directory, name);
2105
- if (executable(path)) return path;
2115
+ if (executable$1(path)) return path;
2106
2116
  }
2107
2117
  }
2108
2118
  for (const candidate of COMMON_CLI_PATHS) {
2109
2119
  const path = expandHome$1(candidate);
2110
- if (executable(path)) return path;
2120
+ if (executable$1(path)) return path;
2111
2121
  }
2112
2122
  }
2113
2123
  var MnemonCliError = class extends Error {
@@ -2120,7 +2130,7 @@ var MnemonCliError = class extends Error {
2120
2130
  this.stderr = stderr;
2121
2131
  }
2122
2132
  };
2123
- function createRunner(config, processRunner = runProcess) {
2133
+ function createRunner(config, processRunner = runProcess, workspaceRoot) {
2124
2134
  const found = findMnemonCommand(config);
2125
2135
  const command = found ?? config.cliPath ?? "mnemon";
2126
2136
  let processQueue = Promise.resolve();
@@ -2132,7 +2142,7 @@ function createRunner(config, processRunner = runProcess) {
2132
2142
  return args;
2133
2143
  };
2134
2144
  const effectiveDataDir = () => {
2135
- if (config.storageScope === "workspace") return resolve(process.cwd(), ".mnemon");
2145
+ if (config.storageScope === "workspace") return resolve(workspaceRoot ?? process.cwd(), ".mnemon");
2136
2146
  if (config.storageScope === "custom") return expandHome$1(config.dataDir);
2137
2147
  return expandHome$1(process.env.MNEMON_DATA_DIR?.trim() || "~/.mnemon");
2138
2148
  };
@@ -2162,7 +2172,7 @@ function createRunner(config, processRunner = runProcess) {
2162
2172
  };
2163
2173
  return {
2164
2174
  command,
2165
- commandFound: found !== void 0 && executable(found),
2175
+ commandFound: found !== void 0 && executable$1(found),
2166
2176
  config,
2167
2177
  async runJson(args, options) {
2168
2178
  const stdout = await execute(args, options);
@@ -2289,6 +2299,20 @@ var MemoryBodyRegistry = class {
2289
2299
  this.save();
2290
2300
  return this.view(body);
2291
2301
  }
2302
+ async remove(id, signal) {
2303
+ const body = this.get(id);
2304
+ await this.runner.runText([
2305
+ "store",
2306
+ "remove",
2307
+ body.id
2308
+ ], {
2309
+ ...signal === void 0 ? {} : { signal },
2310
+ store: body.id
2311
+ });
2312
+ this.bodies = this.bodies.filter((entry) => entry.id !== body.id);
2313
+ this.save();
2314
+ return body;
2315
+ }
2292
2316
  setActive(id, active) {
2293
2317
  return this.update(id, { active });
2294
2318
  }
@@ -2774,6 +2798,10 @@ var MnemonService = class {
2774
2798
  this.assertWritable();
2775
2799
  return this.memoryBodies.update(id, request);
2776
2800
  }
2801
+ async deleteBody(id, signal) {
2802
+ this.assertWritable();
2803
+ return this.memoryBodies.remove(id, signal);
2804
+ }
2777
2805
  async mergeBodies(targetBodyId, sourceBodyIds, deactivateSources = true, signal) {
2778
2806
  this.assertWritable();
2779
2807
  const target = this.memoryBodies.get(targetBodyId);
@@ -3223,8 +3251,8 @@ var StorageScopeInspector = class {
3223
3251
  * validate and initialize the selected storage root, so a failed candidate is
3224
3252
  * rejected by DSH settings validation without disturbing the active graph.
3225
3253
  */
3226
- function createRuntimeGraph(config) {
3227
- const runner = createRunner(config);
3254
+ function createRuntimeGraph(config, workspaceRoot) {
3255
+ const runner = createRunner(config, void 0, workspaceRoot);
3228
3256
  const service = new MnemonService(runner, config);
3229
3257
  return {
3230
3258
  config,
@@ -3268,7 +3296,10 @@ function liveProxy(resolve) {
3268
3296
  * generation until that invocation settles.
3269
3297
  */
3270
3298
  var LiveMnemonRuntime = class {
3299
+ workspaceRegistry;
3300
+ agents;
3271
3301
  current;
3302
+ workspaceGraphs = /* @__PURE__ */ new Map();
3272
3303
  config;
3273
3304
  runner;
3274
3305
  service;
@@ -3276,7 +3307,9 @@ var LiveMnemonRuntime = class {
3276
3307
  documents;
3277
3308
  storage;
3278
3309
  packs;
3279
- constructor(initial) {
3310
+ constructor(initial, workspaceRegistry, agents) {
3311
+ this.workspaceRegistry = workspaceRegistry;
3312
+ this.agents = agents;
3280
3313
  this.current = initial;
3281
3314
  this.config = liveProxy(() => this.current.config);
3282
3315
  this.runner = liveProxy(() => this.current.runner);
@@ -3288,13 +3321,72 @@ var LiveMnemonRuntime = class {
3288
3321
  }
3289
3322
  swap(next) {
3290
3323
  this.current = next;
3324
+ this.workspaceGraphs.clear();
3291
3325
  }
3292
3326
  snapshot() {
3293
3327
  return this.current;
3294
3328
  }
3329
+ /** Resolve the runtime that must serve one Agent execution. */
3330
+ forAgent(agent) {
3331
+ if (this.current.config.storageScope !== "workspace") return this.current;
3332
+ const cwd = agent.session.header?.cwd?.trim();
3333
+ if (cwd === void 0 || cwd === "") throw new Error("the current DSH session has no workspace for Mnemon");
3334
+ return this.forWorkspacePath(cwd);
3335
+ }
3336
+ /** Resolve an authorized DSH workspace selected by the Web workbench. */
3337
+ forWorkspaceId(workspaceId) {
3338
+ const workspace = this.requireWorkspace(workspaceId);
3339
+ return this.current.config.storageScope === "workspace" ? this.forWorkspacePath(workspace.path) : this.current;
3340
+ }
3341
+ /** Resolve a Web request, preferring its explicit inspection workspace. */
3342
+ route(request) {
3343
+ const effectiveAgent = this.agent(request.sessionId);
3344
+ const effectiveWorkspace = effectiveAgent === void 0 ? void 0 : this.workspaceForPath(effectiveAgent.session.header?.cwd);
3345
+ const selectedWorkspace = request.workspaceId === void 0 || request.workspaceId.trim() === "" ? effectiveWorkspace : this.requireWorkspace(request.workspaceId);
3346
+ const graph = selectedWorkspace === void 0 ? effectiveAgent === void 0 ? this.current : this.forAgent(effectiveAgent) : this.current.config.storageScope === "workspace" ? this.forWorkspacePath(selectedWorkspace.path) : this.current;
3347
+ const effectiveGraph = effectiveAgent === void 0 ? this.current : this.forAgent(effectiveAgent);
3348
+ const selectedRoot = resolve(graph.runner.effectiveDataDir());
3349
+ const effectiveRoot = resolve(effectiveGraph.runner.effectiveDataDir());
3350
+ return {
3351
+ graph,
3352
+ ...selectedWorkspace === void 0 ? {} : { selectedWorkspace },
3353
+ ...effectiveWorkspace === void 0 ? {} : { effectiveWorkspace },
3354
+ selectedRoot,
3355
+ effectiveRoot,
3356
+ aligned: selectedRoot === effectiveRoot
3357
+ };
3358
+ }
3359
+ forWorkspacePath(workspaceRoot) {
3360
+ const key = resolve(workspaceRoot);
3361
+ let graph = this.workspaceGraphs.get(key);
3362
+ if (graph === void 0) {
3363
+ graph = createRuntimeGraph(this.current.config, key);
3364
+ this.workspaceGraphs.set(key, graph);
3365
+ }
3366
+ return graph;
3367
+ }
3368
+ agent(sessionId) {
3369
+ const normalized = sessionId?.trim();
3370
+ return normalized === void 0 || normalized === "" ? void 0 : this.agents?.get(normalized);
3371
+ }
3372
+ requireWorkspace(workspaceId) {
3373
+ const normalized = workspaceId.trim();
3374
+ const workspace = normalized === "" ? void 0 : this.workspaceRegistry?.get(normalized);
3375
+ if (workspace === void 0) throw new Error("selected DSH workspace is unavailable");
3376
+ return workspace;
3377
+ }
3378
+ workspaceForPath(path) {
3379
+ const normalized = path?.trim();
3380
+ if (normalized === void 0 || normalized === "") return void 0;
3381
+ const canonical = resolve(normalized);
3382
+ return this.workspaceRegistry?.list().find((workspace) => resolve(workspace.path) === canonical);
3383
+ }
3295
3384
  };
3296
3385
  //#endregion
3297
3386
  //#region lib/types/subagent.js
3387
+ function isAgentRuntimeSource$1(value) {
3388
+ return typeof value === "object" && value !== null && "forAgent" in value && typeof value.forAgent === "function";
3389
+ }
3298
3390
  const READ_TOOLS = [
3299
3391
  "mnemon_memory_bodies",
3300
3392
  "mnemon_recall",
@@ -3679,7 +3771,7 @@ function isSubagent(agent) {
3679
3771
  /** Delegates memory judgment and execution to a fresh, tool-scoped DSH child. */
3680
3772
  var MnemonSubagentCoordinator = class {
3681
3773
  subagents;
3682
- runtimeMemory;
3774
+ runtimeMemoryOrSource;
3683
3775
  documents;
3684
3776
  counters = {
3685
3777
  recalls: 0,
@@ -3693,25 +3785,22 @@ var MnemonSubagentCoordinator = class {
3693
3785
  };
3694
3786
  runtimeQueue = Promise.resolve();
3695
3787
  documentQueue = Promise.resolve();
3696
- constructor(subagents, runtimeMemory, documents) {
3788
+ constructor(subagents, runtimeMemoryOrSource, documents) {
3697
3789
  this.subagents = subagents;
3698
- this.runtimeMemory = runtimeMemory;
3790
+ this.runtimeMemoryOrSource = runtimeMemoryOrSource;
3699
3791
  this.documents = documents;
3700
3792
  }
3701
3793
  snapshot() {
3702
3794
  return { ...this.counters };
3703
3795
  }
3704
3796
  documentsSnapshot(parent) {
3705
- if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
3706
- return this.documents.forAgent(parent).snapshot();
3797
+ return this.documentsFor(parent).forAgent(parent).snapshot();
3707
3798
  }
3708
3799
  documentGet(parent, id) {
3709
- if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
3710
- return this.documents.forAgent(parent).get(id);
3800
+ return this.documentsFor(parent).forAgent(parent).get(id);
3711
3801
  }
3712
3802
  documentSearch(parent, query, includeArchived = false, limit) {
3713
- if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
3714
- return this.documents.forAgent(parent).search(query, {
3803
+ return this.documentsFor(parent).forAgent(parent).search(query, {
3715
3804
  includeArchived,
3716
3805
  ...limit === void 0 ? {} : { limit }
3717
3806
  });
@@ -3811,8 +3900,7 @@ ${naturalRequest(request)}`;
3811
3900
  };
3812
3901
  }
3813
3902
  async documentLocked(parent, request, signal) {
3814
- if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
3815
- const controller = this.documents.forAgent(parent);
3903
+ const controller = this.documentsFor(parent).forAgent(parent);
3816
3904
  const archivedDocumentIds = [];
3817
3905
  const memoryBodyIds = /* @__PURE__ */ new Set();
3818
3906
  let lastArchive;
@@ -3848,8 +3936,7 @@ ${naturalRequest(request)}`;
3848
3936
  };
3849
3937
  }
3850
3938
  async archiveDocumentLocked(parent, id, signal) {
3851
- if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
3852
- const controller = this.documents.forAgent(parent);
3939
+ const controller = this.documentsFor(parent).forAgent(parent);
3853
3940
  const document = controller.get(id);
3854
3941
  if (document.status !== "active") throw new Error("only active documents can be archived");
3855
3942
  const { provider, runId, result } = await this.delegate(parent, "document-archive", "Archive managed document", "Archive this managed document now.", DOCUMENT_ARCHIVE_TOOLS, DOCUMENT_ARCHIVE_SCHEMA, signal, "spawn", documentArchivePersona(document));
@@ -3872,14 +3959,14 @@ ${naturalRequest(request)}`;
3872
3959
  };
3873
3960
  }
3874
3961
  async runtimeLocked(parent, request, signal) {
3875
- if (this.runtimeMemory === void 0) throw new Error("runtime memory control plane is unavailable");
3962
+ const runtimeMemory = this.runtimeMemoryFor(parent);
3876
3963
  try {
3877
- return await this.runtimeMemory.mutate(request);
3964
+ return await runtimeMemory.mutate(request);
3878
3965
  } catch (error) {
3879
3966
  if (!(error instanceof RuntimeMemoryCapacityError) || request.action !== "add") throw error;
3880
3967
  }
3881
3968
  if (request.target === "user") return this.compactUserAndRetry(parent, request, signal);
3882
- const snapshot = this.runtimeMemory.snapshot();
3969
+ const snapshot = runtimeMemory.snapshot();
3883
3970
  const targetView = snapshot.targets[request.target];
3884
3971
  const targetEntries = snapshot.entries.filter((entry) => entry.target === request.target);
3885
3972
  if (targetEntries.length === 0) throw new Error("runtime memory capacity was exceeded without entries available for archival");
@@ -3906,9 +3993,9 @@ ${indentedText(request.content ?? "")}`;
3906
3993
  importance: item.importance
3907
3994
  };
3908
3995
  }) : [];
3909
- await this.runtimeMemory.compactTarget(snapshot.revision, request.target, compactedEntries, compactedBudget);
3996
+ await runtimeMemory.compactTarget(snapshot.revision, request.target, compactedEntries, compactedBudget);
3910
3997
  return {
3911
- ...await this.runtimeMemory.mutate(request),
3998
+ ...await runtimeMemory.mutate(request),
3912
3999
  maintenance: {
3913
4000
  kind: "mnemon-archive",
3914
4001
  runId,
@@ -3919,8 +4006,8 @@ ${indentedText(request.content ?? "")}`;
3919
4006
  };
3920
4007
  }
3921
4008
  async compactUserAndRetry(parent, request, signal) {
3922
- if (this.runtimeMemory === void 0) throw new Error("runtime memory control plane is unavailable");
3923
- const snapshot = this.runtimeMemory.snapshot();
4009
+ const runtimeMemory = this.runtimeMemoryFor(parent);
4010
+ const snapshot = runtimeMemory.snapshot();
3924
4011
  const targetEntries = snapshot.entries.filter((entry) => entry.target === "user");
3925
4012
  if (targetEntries.length === 0) throw new Error("USER.md capacity was exceeded without entries available for compaction");
3926
4013
  const targetView = snapshot.targets.user;
@@ -3973,9 +4060,9 @@ ${indentedText(request.content ?? "")}`;
3973
4060
  }));
3974
4061
  const candidateBytes = Buffer.byteLength(candidates.map((entry) => entry.content.trim().replace(/\s+/gu, " ")).join(RUNTIME_ENTRY_DELIMITER), "utf8");
3975
4062
  if (candidateBytes > compactedBudget) throw new Error(`USER.md compaction did not fit the host budget (${candidateBytes} > ${compactedBudget} bytes)`);
3976
- await this.runtimeMemory.compactTarget(snapshot.revision, "user", candidates, compactedBudget);
4063
+ await runtimeMemory.compactTarget(snapshot.revision, "user", candidates, compactedBudget);
3977
4064
  return {
3978
- ...await this.runtimeMemory.mutate(request),
4065
+ ...await runtimeMemory.mutate(request),
3979
4066
  maintenance: {
3980
4067
  kind: "local-compaction",
3981
4068
  runId,
@@ -4043,6 +4130,16 @@ ${indentedText(request.content ?? "")}`;
4043
4130
  if (selected === void 0) throw new Error("dsh-mnemon requires a DSH subagent provider with structured output, tool filtering, persona, and depth limiting");
4044
4131
  return selected;
4045
4132
  }
4133
+ runtimeMemoryFor(parent) {
4134
+ if (isAgentRuntimeSource$1(this.runtimeMemoryOrSource)) return this.runtimeMemoryOrSource.forAgent(parent).runtimeMemory;
4135
+ if (this.runtimeMemoryOrSource === void 0) throw new Error("runtime memory control plane is unavailable");
4136
+ return this.runtimeMemoryOrSource;
4137
+ }
4138
+ documentsFor(parent) {
4139
+ if (isAgentRuntimeSource$1(this.runtimeMemoryOrSource)) return this.runtimeMemoryOrSource.forAgent(parent).documents;
4140
+ if (this.documents === void 0) throw new Error("Mnemon Documents control plane is unavailable");
4141
+ return this.documents;
4142
+ }
4046
4143
  };
4047
4144
  //#endregion
4048
4145
  //#region lib/types/review-activity.js
@@ -4213,13 +4310,13 @@ function completedToolActivity(events, turn) {
4213
4310
  names: new Set(events.filter((event) => event.type === "tool/call" && eventTurn(event) === turn && typeof event.data.name === "string").map((event) => String(event.data.name)))
4214
4311
  };
4215
4312
  }
4216
- /** Join the text blocks of an `assistant/message` event whose message id matches. */
4313
+ /** Join the text content of an `assistant/message` event whose message id matches. */
4217
4314
  function assistantMessageText(events, messageId) {
4218
4315
  for (const event of events) {
4219
4316
  if (event.type !== "assistant/message") continue;
4220
4317
  const message = event.data.message;
4221
4318
  if (message === void 0 || typeof message !== "object" || message.id !== messageId) continue;
4222
- const text = (Array.isArray(message.blocks) ? message.blocks : []).filter((block) => block.type === "text" && typeof block.text === "string").map((block) => String(block.text)).join("\n\n").trim();
4319
+ const text = (Array.isArray(message.content) ? message.content : []).filter((block) => block.type === "text" && typeof block.text === "string").map((block) => String(block.text)).join("\n\n").trim();
4223
4320
  return text === "" ? null : {
4224
4321
  messageId,
4225
4322
  text
@@ -4436,6 +4533,7 @@ var MnemonLifecycle = class {
4436
4533
  ctx;
4437
4534
  coordinator;
4438
4535
  config;
4536
+ runtimeSource;
4439
4537
  owners = /* @__PURE__ */ new Map();
4440
4538
  counters = {
4441
4539
  primes: 0,
@@ -4446,10 +4544,11 @@ var MnemonLifecycle = class {
4446
4544
  };
4447
4545
  /** Bounded process-local replay fence for finalized-message write actions. */
4448
4546
  supervisedWritebacks = /* @__PURE__ */ new Map();
4449
- constructor(ctx, coordinator, config) {
4547
+ constructor(ctx, coordinator, config, runtimeSource) {
4450
4548
  this.ctx = ctx;
4451
4549
  this.coordinator = coordinator;
4452
4550
  this.config = config;
4551
+ this.runtimeSource = runtimeSource;
4453
4552
  }
4454
4553
  start() {
4455
4554
  const stopCreated = this.ctx.on("agent/created", (({ agent }) => {
@@ -4585,7 +4684,9 @@ var MnemonLifecycle = class {
4585
4684
  let dispose;
4586
4685
  dispose = agent.ctx.effect(() => {
4587
4686
  const stop = lifecycle.start();
4687
+ const stopRuntimeContext = this.runtimeSource === void 0 ? () => {} : registerAgentRuntimeMemoryContext(agent, () => this.runtimeSource.forAgent(agent).runtimeMemory);
4588
4688
  return () => {
4689
+ stopRuntimeContext();
4589
4690
  stop();
4590
4691
  if (this.owners.get(agent)?.dispose === dispose) this.owners.delete(agent);
4591
4692
  };
@@ -4597,10 +4698,427 @@ var MnemonLifecycle = class {
4597
4698
  }
4598
4699
  };
4599
4700
  //#endregion
4600
- //#region lib/types/rpc.js
4701
+ //#region lib/types/version-updates.js
4702
+ const DSH_MNEMON_PACKAGE = "dsh-mnemon";
4703
+ const MNEMON_MODULE = "github.com/mnemon-dev/mnemon";
4704
+ const PACKAGE_MANIFEST_PATH = fileURLToPath(new URL("../package.json", import.meta.url));
4705
+ const CHECK_TIMEOUT_MS = 1e4;
4706
+ const UPDATE_TIMEOUT_MS = 6e5;
4707
+ const MAX_UPDATE_OUTPUT_BYTES = 16384;
4708
+ async function settledWithin(promise, fallback, timeoutMs = 11e3) {
4709
+ let timer;
4710
+ try {
4711
+ return await Promise.race([promise.catch(() => fallback), new Promise((resolve) => {
4712
+ timer = setTimeout(() => resolve(fallback), timeoutMs);
4713
+ })]);
4714
+ } finally {
4715
+ if (timer !== void 0) clearTimeout(timer);
4716
+ }
4717
+ }
4718
+ function manifest(path) {
4719
+ try {
4720
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
4721
+ return typeof parsed === "object" && parsed !== null ? parsed : void 0;
4722
+ } catch {
4723
+ return;
4724
+ }
4725
+ }
4726
+ function executable(path) {
4727
+ try {
4728
+ accessSync(path, constants.X_OK);
4729
+ return true;
4730
+ } catch {
4731
+ return false;
4732
+ }
4733
+ }
4734
+ /** Resolve one executable without invoking a shell. */
4735
+ function resolveExecutable(command) {
4736
+ if (command.includes("/") || command.includes("\\")) {
4737
+ const path = command.startsWith("~/") ? join(homedir(), command.slice(2)) : resolve(command);
4738
+ return executable(path) ? path : void 0;
4739
+ }
4740
+ const names = process.platform === "win32" ? [
4741
+ `${command}.exe`,
4742
+ `${command}.cmd`,
4743
+ command
4744
+ ] : [command];
4745
+ for (const directory of (process.env.PATH ?? "").split(delimiter)) {
4746
+ if (directory === "") continue;
4747
+ for (const name of names) {
4748
+ const path = join(directory, name);
4749
+ if (executable(path)) return path;
4750
+ }
4751
+ }
4752
+ }
4753
+ function parseSemver(value) {
4754
+ const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value.trim());
4755
+ if (match === null) return void 0;
4756
+ return {
4757
+ major: Number(match[1]),
4758
+ minor: Number(match[2]),
4759
+ patch: Number(match[3]),
4760
+ prerelease: match[4] === void 0 ? [] : match[4].split(".")
4761
+ };
4762
+ }
4763
+ function compareVersions(a, b) {
4764
+ const left = parseSemver(a);
4765
+ const right = parseSemver(b);
4766
+ if (left === void 0 && right === void 0) return 0;
4767
+ if (left === void 0) return -1;
4768
+ if (right === void 0) return 1;
4769
+ for (const field of [
4770
+ "major",
4771
+ "minor",
4772
+ "patch"
4773
+ ]) if (left[field] !== right[field]) return left[field] < right[field] ? -1 : 1;
4774
+ if (left.prerelease.length === 0 && right.prerelease.length === 0) return 0;
4775
+ if (left.prerelease.length === 0) return 1;
4776
+ if (right.prerelease.length === 0) return -1;
4777
+ for (let index = 0; index < Math.max(left.prerelease.length, right.prerelease.length); index++) {
4778
+ const aPart = left.prerelease[index];
4779
+ const bPart = right.prerelease[index];
4780
+ if (aPart === void 0) return -1;
4781
+ if (bPart === void 0) return 1;
4782
+ if (aPart === bPart) continue;
4783
+ const aNumber = /^\d+$/.test(aPart);
4784
+ const bNumber = /^\d+$/.test(bPart);
4785
+ if (aNumber && bNumber) return Number(aPart) < Number(bPart) ? -1 : 1;
4786
+ if (aNumber) return -1;
4787
+ if (bNumber) return 1;
4788
+ return aPart < bPart ? -1 : 1;
4789
+ }
4790
+ return 0;
4791
+ }
4792
+ function versionFrom(text) {
4793
+ return text.match(/\bv?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)\b/)?.[1];
4794
+ }
4795
+ async function fetchJson(url) {
4796
+ const controller = new AbortController();
4797
+ const timeout = setTimeout(() => {
4798
+ controller.abort();
4799
+ }, CHECK_TIMEOUT_MS);
4800
+ try {
4801
+ const response = await fetch(url, {
4802
+ signal: controller.signal,
4803
+ headers: {
4804
+ accept: "application/json",
4805
+ "user-agent": "dsh-mnemon-version-check"
4806
+ }
4807
+ });
4808
+ if (!response.ok) return void 0;
4809
+ return await response.json();
4810
+ } catch {
4811
+ return;
4812
+ } finally {
4813
+ clearTimeout(timeout);
4814
+ }
4815
+ }
4816
+ async function fetchNpmLatest(name) {
4817
+ const body = await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(name)}/latest`);
4818
+ if (typeof body !== "object" || body === null) return void 0;
4819
+ const version = body.version;
4820
+ return typeof version === "string" ? version : void 0;
4821
+ }
4822
+ async function fetchMnemonLatest() {
4823
+ const body = await fetchJson("https://api.github.com/repos/mnemon-dev/mnemon/releases/latest");
4824
+ if (typeof body !== "object" || body === null) return void 0;
4825
+ const tag = body.tag_name;
4826
+ return typeof tag === "string" ? tag.replace(/^v/, "") : void 0;
4827
+ }
4828
+ function dependencySpec(profile) {
4829
+ return profile?.dependencies?.[DSH_MNEMON_PACKAGE] ?? profile?.devDependencies?.[DSH_MNEMON_PACKAGE];
4830
+ }
4831
+ function isLinkSpec(spec) {
4832
+ return spec !== void 0 && /^(?:link|file|workspace):|^\.{1,2}(?:[/\\]|$)/.test(spec);
4833
+ }
4834
+ function linkedTarget(profileDir, spec) {
4835
+ const value = spec.replace(/^(?:link|file):/, "");
4836
+ if (value.startsWith("workspace:")) return void 0;
4837
+ return isAbsolute(value) ? resolve(value) : resolve(profileDir, value);
4838
+ }
4839
+ function profileFromAncestor(packageManifestPath) {
4840
+ let directory = dirname(packageManifestPath);
4841
+ for (let depth = 0; depth < 12; depth++) {
4842
+ const profile = manifest(join(directory, "package.json"));
4843
+ if (profile?.name?.startsWith("dsh-profile-") === true) return {
4844
+ mode: isLinkSpec(dependencySpec(profile)) ? "link" : "npm",
4845
+ profileName: profile.name.slice(12),
4846
+ profileDir: directory
4847
+ };
4848
+ const parent = dirname(directory);
4849
+ if (parent === directory) break;
4850
+ directory = parent;
4851
+ }
4852
+ }
4853
+ function linkedProfile(packageManifestPath, dshHome) {
4854
+ const profilesDir = join(dshHome, "profiles");
4855
+ if (!existsSync(profilesDir)) return void 0;
4856
+ const packageRoot = realpathSync(dirname(packageManifestPath));
4857
+ const matches = [];
4858
+ for (const entry of readdirSync(profilesDir, { withFileTypes: true })) {
4859
+ if (!entry.isDirectory()) continue;
4860
+ const profileDir = join(profilesDir, entry.name);
4861
+ const spec = dependencySpec(manifest(join(profileDir, "package.json")));
4862
+ if (!isLinkSpec(spec)) continue;
4863
+ const target = spec === void 0 ? void 0 : linkedTarget(profileDir, spec);
4864
+ if (target === void 0 || !existsSync(target)) continue;
4865
+ try {
4866
+ if (realpathSync(target) === packageRoot) matches.push({
4867
+ name: entry.name,
4868
+ dir: profileDir
4869
+ });
4870
+ } catch {}
4871
+ }
4872
+ const match = matches[0];
4873
+ return match === void 0 ? void 0 : {
4874
+ mode: "link",
4875
+ profileName: match.name,
4876
+ profileDir: match.dir
4877
+ };
4878
+ }
4879
+ function inspectDshInstall(packageManifestPath, dshHome) {
4880
+ return profileFromAncestor(packageManifestPath) ?? linkedProfile(packageManifestPath, dshHome) ?? { mode: "manual" };
4881
+ }
4882
+ async function resultOrThrow(runner, command, args, timeoutMs) {
4883
+ const result = await runner(command, args, {
4884
+ timeoutMs,
4885
+ maxOutputBytes: MAX_UPDATE_OUTPUT_BYTES
4886
+ });
4887
+ if (result.exitCode !== 0) {
4888
+ const detail = result.stderr.trim() || result.stdout.trim() || `exit ${String(result.exitCode)}`;
4889
+ throw new Error(detail);
4890
+ }
4891
+ return result;
4892
+ }
4893
+ function updateOutput(result) {
4894
+ const output = [result.stdout.trim(), result.stderr.trim()].filter(Boolean).join("\n").trim();
4895
+ return output === "" ? void 0 : output.slice(-4e3);
4896
+ }
4897
+ var VersionUpdateManager = class {
4898
+ dshMnemonVersion;
4899
+ packageManifestPath;
4900
+ dshHome;
4901
+ mnemonCliPath;
4902
+ processRunner;
4903
+ executable;
4904
+ fetchNpmLatest;
4905
+ fetchMnemonLatest;
4906
+ constructor(dependencies = {}) {
4907
+ this.packageManifestPath = dependencies.packageManifestPath ?? PACKAGE_MANIFEST_PATH;
4908
+ this.dshMnemonVersion = manifest(this.packageManifestPath)?.version ?? "0.0.0";
4909
+ this.dshHome = dependencies.dshHome ?? (process.env.DSH_HOME?.trim() || join(homedir(), ".dsh"));
4910
+ this.mnemonCliPath = dependencies.mnemonCliPath ?? (() => findMnemonCommand({}));
4911
+ this.processRunner = dependencies.processRunner ?? runProcess;
4912
+ this.executable = dependencies.resolveExecutable ?? resolveExecutable;
4913
+ this.fetchNpmLatest = dependencies.fetchNpmLatest ?? fetchNpmLatest;
4914
+ this.fetchMnemonLatest = dependencies.fetchMnemonLatest ?? fetchMnemonLatest;
4915
+ }
4916
+ get currentDshMnemonVersion() {
4917
+ return this.dshMnemonVersion;
4918
+ }
4919
+ async inspectMnemon() {
4920
+ const configured = this.mnemonCliPath() ?? findMnemonCommand({});
4921
+ const command = configured === void 0 ? void 0 : this.executable(configured);
4922
+ if (command === void 0) return { install: { mode: "missing" } };
4923
+ let current;
4924
+ try {
4925
+ current = versionFrom((await resultOrThrow(this.processRunner, command, ["--version"], CHECK_TIMEOUT_MS)).stdout);
4926
+ } catch {
4927
+ return { install: {
4928
+ mode: "manual",
4929
+ command
4930
+ } };
4931
+ }
4932
+ let realCommand = command;
4933
+ try {
4934
+ realCommand = realpathSync(command);
4935
+ } catch {}
4936
+ if (realCommand.includes("/Caskroom/mnemon/")) {
4937
+ const brew = this.executable("brew");
4938
+ return {
4939
+ ...current === void 0 ? {} : { current },
4940
+ install: {
4941
+ mode: "homebrew",
4942
+ command,
4943
+ ...brew === void 0 ? {} : {
4944
+ updateCommand: brew,
4945
+ updateArgs: [
4946
+ "upgrade",
4947
+ "--cask",
4948
+ "mnemon"
4949
+ ]
4950
+ }
4951
+ }
4952
+ };
4953
+ }
4954
+ if (realCommand.includes("/Cellar/mnemon/")) {
4955
+ const brew = this.executable("brew");
4956
+ return {
4957
+ ...current === void 0 ? {} : { current },
4958
+ install: {
4959
+ mode: "homebrew",
4960
+ command,
4961
+ ...brew === void 0 ? {} : {
4962
+ updateCommand: brew,
4963
+ updateArgs: ["upgrade", "mnemon-dev/tap/mnemon"]
4964
+ }
4965
+ }
4966
+ };
4967
+ }
4968
+ const go = this.executable("go");
4969
+ if (go !== void 0) try {
4970
+ if ((await resultOrThrow(this.processRunner, go, [
4971
+ "version",
4972
+ "-m",
4973
+ command
4974
+ ], CHECK_TIMEOUT_MS)).stdout.includes(MNEMON_MODULE)) return {
4975
+ ...current === void 0 ? {} : { current },
4976
+ install: {
4977
+ mode: "go",
4978
+ command,
4979
+ updateCommand: go,
4980
+ updateArgs: ["install", `${MNEMON_MODULE}@latest`]
4981
+ }
4982
+ };
4983
+ } catch {}
4984
+ return {
4985
+ ...current === void 0 ? {} : { current },
4986
+ install: {
4987
+ mode: "manual",
4988
+ command
4989
+ }
4990
+ };
4991
+ }
4992
+ async check() {
4993
+ const [mnemonLocal, mnemonLatest, dshLatest] = await Promise.all([
4994
+ settledWithin(this.inspectMnemon(), { install: { mode: "missing" } }),
4995
+ settledWithin(this.fetchMnemonLatest(), void 0),
4996
+ settledWithin(this.fetchNpmLatest(DSH_MNEMON_PACKAGE), void 0)
4997
+ ]);
4998
+ const dshInstall = inspectDshInstall(this.packageManifestPath, this.dshHome);
4999
+ const pnpm = this.executable("pnpm");
5000
+ const mnemonOutdated = mnemonLocal.current !== void 0 && mnemonLatest !== void 0 && compareVersions(mnemonLocal.current, mnemonLatest) < 0;
5001
+ const dshOutdated = dshLatest !== void 0 && compareVersions(this.currentDshMnemonVersion, dshLatest) < 0;
5002
+ const mnemonSupported = mnemonLocal.install.updateCommand !== void 0;
5003
+ const dshSupported = dshInstall.mode === "npm" && dshInstall.profileDir !== void 0 && pnpm !== void 0;
5004
+ return {
5005
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
5006
+ components: [{
5007
+ id: "mnemon",
5008
+ name: "Mnemon CLI",
5009
+ ...mnemonLocal.current === void 0 ? {} : { current: mnemonLocal.current },
5010
+ ...mnemonLatest === void 0 ? {} : { latest: mnemonLatest },
5011
+ outdated: mnemonOutdated,
5012
+ installMode: mnemonLocal.install.mode,
5013
+ updateSupported: mnemonSupported,
5014
+ updateHint: mnemonLocal.install.mode === "homebrew" ? mnemonSupported ? "brew" : "brew-missing" : mnemonLocal.install.mode === "go" ? "go" : mnemonLocal.install.mode === "missing" ? "install" : "manual",
5015
+ ...mnemonLatest === void 0 ? { checkError: "latest-unavailable" } : {}
5016
+ }, {
5017
+ id: "dsh-mnemon",
5018
+ name: "dsh-mnemon",
5019
+ current: this.currentDshMnemonVersion,
5020
+ ...dshLatest === void 0 ? {} : { latest: dshLatest },
5021
+ outdated: dshOutdated,
5022
+ installMode: dshInstall.mode,
5023
+ updateSupported: dshSupported,
5024
+ updateHint: dshInstall.mode === "npm" ? dshSupported ? "pnpm" : "pnpm-missing" : dshInstall.mode === "link" ? "link" : "manual",
5025
+ ...dshLatest === void 0 ? { checkError: "latest-unavailable" } : {}
5026
+ }]
5027
+ };
5028
+ }
5029
+ async update(component) {
5030
+ if (component === "mnemon") {
5031
+ const before = await this.inspectMnemon();
5032
+ const latest = await this.fetchMnemonLatest();
5033
+ if (before.current === void 0) throw new Error("Mnemon CLI is unavailable");
5034
+ if (latest === void 0) throw new Error("Unable to verify the latest Mnemon release");
5035
+ if (compareVersions(before.current, latest) >= 0) return {
5036
+ component,
5037
+ previousVersion: before.current,
5038
+ currentVersion: before.current,
5039
+ updated: false,
5040
+ restartRequired: false
5041
+ };
5042
+ if (before.install.updateCommand === void 0 || before.install.updateArgs === void 0) throw new Error("This Mnemon installation cannot be updated automatically");
5043
+ const output = await resultOrThrow(this.processRunner, before.install.updateCommand, before.install.updateArgs, UPDATE_TIMEOUT_MS);
5044
+ const after = await this.inspectMnemon();
5045
+ const outputText = updateOutput(output);
5046
+ return {
5047
+ component,
5048
+ previousVersion: before.current,
5049
+ currentVersion: after.current ?? latest,
5050
+ updated: true,
5051
+ restartRequired: false,
5052
+ ...outputText === void 0 ? {} : { output: outputText }
5053
+ };
5054
+ }
5055
+ if (component !== "dsh-mnemon") throw new Error(`Unknown version component: ${String(component)}`);
5056
+ const latest = await this.fetchNpmLatest(DSH_MNEMON_PACKAGE);
5057
+ if (latest === void 0) throw new Error("Unable to verify the latest dsh-mnemon release");
5058
+ if (compareVersions(this.currentDshMnemonVersion, latest) >= 0) return {
5059
+ component,
5060
+ previousVersion: this.currentDshMnemonVersion,
5061
+ currentVersion: this.currentDshMnemonVersion,
5062
+ updated: false,
5063
+ restartRequired: false
5064
+ };
5065
+ const install = inspectDshInstall(this.packageManifestPath, this.dshHome);
5066
+ const pnpm = this.executable("pnpm");
5067
+ if (install.mode !== "npm" || install.profileDir === void 0 || pnpm === void 0) throw new Error("This dsh-mnemon installation cannot be updated automatically");
5068
+ const outputText = updateOutput(await resultOrThrow(this.processRunner, pnpm, ["update", DSH_MNEMON_PACKAGE], UPDATE_TIMEOUT_MS));
5069
+ this.dshMnemonVersion = latest;
5070
+ return {
5071
+ component,
5072
+ previousVersion: this.currentDshMnemonVersion,
5073
+ currentVersion: latest,
5074
+ updated: true,
5075
+ restartRequired: true,
5076
+ ...outputText === void 0 ? {} : { output: outputText }
5077
+ };
5078
+ }
5079
+ };
5080
+ //#endregion
5081
+ //#region lib/types/channels.js
4601
5082
  const MNEMON_READ_CHANNEL = "/dsh-mnemon-read";
4602
5083
  const MNEMON_WRITE_CHANNEL = "/dsh-mnemon-write";
4603
5084
  const MNEMON_PACK_CHANNEL = "/dsh-mnemon-pack";
5085
+ //#endregion
5086
+ //#region lib/types/rpc.js
5087
+ function isRoutedRuntime(value) {
5088
+ return "route" in value && typeof value.route === "function";
5089
+ }
5090
+ function requestedScope(payload) {
5091
+ const workspaceId = payload.workspaceId === void 0 ? void 0 : String(payload.workspaceId).trim();
5092
+ const sessionId = payload.sessionId === void 0 ? void 0 : String(payload.sessionId).trim();
5093
+ return {
5094
+ ...workspaceId === void 0 || workspaceId === "" ? {} : { workspaceId },
5095
+ ...sessionId === void 0 || sessionId === "" ? {} : { sessionId }
5096
+ };
5097
+ }
5098
+ function runtimeFor(input, payload, runtimeMemory, storage) {
5099
+ if (isRoutedRuntime(input)) {
5100
+ const scope = requestedScope(payload);
5101
+ const route = input.route(scope);
5102
+ return {
5103
+ graph: route.graph,
5104
+ route,
5105
+ explicitWorkspace: scope.workspaceId !== void 0 && route.graph.config.storageScope === "workspace"
5106
+ };
5107
+ }
5108
+ return {
5109
+ graph: {
5110
+ service: input,
5111
+ runtimeMemory,
5112
+ documents: void 0,
5113
+ storage,
5114
+ packs: void 0
5115
+ },
5116
+ explicitWorkspace: false
5117
+ };
5118
+ }
5119
+ function requireAligned(route) {
5120
+ if (route?.aligned === false) throw new Error("the selected memory workspace differs from the current session; align the workbench before running an Agent-backed operation");
5121
+ }
4604
5122
  function object$1(value) {
4605
5123
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("payload must be an object");
4606
5124
  return value;
@@ -4631,34 +5149,60 @@ function badRequest$1(message) {
4631
5149
  }
4632
5150
  };
4633
5151
  }
4634
- function createReadHandler(service, lifecycle, runtimeMemory, storage) {
5152
+ function createReadHandler(input, lifecycle, runtimeMemory, storage, versions) {
4635
5153
  return async (endpoint, rawPayload) => {
4636
5154
  try {
4637
5155
  const payload = object$1(rawPayload);
5156
+ if (endpoint === "versions") {
5157
+ if (versions === void 0) throw new Error("version checks are unavailable");
5158
+ return success$1(await versions.check());
5159
+ }
5160
+ const resolved = runtimeFor(input, payload, runtimeMemory, storage);
5161
+ const { service } = resolved.graph;
5162
+ const selectedWorkspace = resolved.route?.selectedWorkspace;
5163
+ const documentController = resolved.explicitWorkspace && selectedWorkspace !== void 0 ? resolved.graph.documents.forWorkspace(selectedWorkspace.path) : void 0;
4638
5164
  switch (endpoint) {
4639
5165
  case "runtime-memory":
4640
- if (runtimeMemory === void 0) throw new Error("runtime memory is unavailable");
4641
- return success$1(runtimeMemory.snapshot());
5166
+ if (resolved.graph.runtimeMemory === void 0) throw new Error("runtime memory is unavailable");
5167
+ return success$1(resolved.graph.runtimeMemory.snapshot());
4642
5168
  case "status": {
4643
5169
  const sessionId = payload.sessionId === void 0 ? "" : String(payload.sessionId).trim();
4644
5170
  let documents;
4645
- if (lifecycle !== void 0 && sessionId !== "") try {
5171
+ if (documentController !== void 0) try {
5172
+ documents = documentController.snapshot();
5173
+ } catch {}
5174
+ else if (lifecycle !== void 0 && sessionId !== "") try {
4646
5175
  documents = lifecycle.documents(sessionId);
4647
5176
  } catch {}
4648
5177
  return success$1({
4649
5178
  ...await service.status(),
5179
+ ...versions === void 0 ? {} : { dshMnemonVersion: versions.currentDshMnemonVersion },
4650
5180
  ...lifecycle === void 0 ? {} : { lifecycle: lifecycle.snapshot(payload.sessionId === void 0 ? void 0 : String(payload.sessionId)) },
4651
5181
  ...documents === void 0 ? {} : { documents },
4652
- ...storage === void 0 ? {} : { storage: storage.catalog(lifecycle?.workspaceRoot(sessionId)) }
5182
+ ...resolved.graph.storage === void 0 ? {} : { storage: resolved.graph.storage.catalog(selectedWorkspace?.path ?? lifecycle?.workspaceRoot(sessionId)) },
5183
+ ...resolved.route === void 0 ? {} : { workspaceContext: {
5184
+ mode: service.config.storageScope,
5185
+ selectedRoot: resolved.route.selectedRoot,
5186
+ effectiveRoot: resolved.route.effectiveRoot,
5187
+ aligned: resolved.route.aligned,
5188
+ ...resolved.route.selectedWorkspace === void 0 ? {} : { selectedWorkspace: resolved.route.selectedWorkspace },
5189
+ ...resolved.route.effectiveWorkspace === void 0 ? {} : { effectiveWorkspace: resolved.route.effectiveWorkspace }
5190
+ } }
4653
5191
  });
4654
5192
  }
4655
5193
  case "documents":
5194
+ if (documentController !== void 0) return success$1(documentController.snapshot());
4656
5195
  if (lifecycle === void 0) throw new Error("Mnemon Documents require lifecycle integration");
4657
5196
  return success$1(lifecycle.documents(String(payload.sessionId ?? "")));
4658
5197
  case "document":
5198
+ if (documentController !== void 0) return success$1(documentController.get(String(payload.id ?? "")));
4659
5199
  if (lifecycle === void 0) throw new Error("Mnemon Documents require lifecycle integration");
4660
5200
  return success$1(lifecycle.document(String(payload.sessionId ?? ""), String(payload.id ?? "")));
4661
5201
  case "document-search":
5202
+ if (documentController !== void 0) return success$1(await documentController.search(String(payload.query ?? ""), {
5203
+ includeArchived: payload.includeArchived === true,
5204
+ ...payload.limit === void 0 ? {} : { limit: Number(payload.limit) }
5205
+ }));
4662
5206
  if (lifecycle === void 0) throw new Error("Mnemon Documents require lifecycle integration");
4663
5207
  return success$1(await lifecycle.searchDocuments(String(payload.sessionId ?? ""), String(payload.query ?? ""), payload.includeArchived === true, payload.limit === void 0 ? void 0 : Number(payload.limit)));
4664
5208
  case "graph": return success$1(await service.graph(void 0, Array.isArray(payload.memoryBodyIds) ? payload.memoryBodyIds.map(String) : void 0));
@@ -4721,14 +5265,26 @@ function createReadHandler(service, lifecycle, runtimeMemory, storage) {
4721
5265
  }
4722
5266
  };
4723
5267
  }
4724
- function createWriteHandler(service, lifecycle, runtimeMemory) {
5268
+ function createWriteHandler(input, lifecycle, runtimeMemory, versions) {
4725
5269
  return async (endpoint, rawPayload) => {
4726
5270
  try {
4727
- if (!service.config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
4728
5271
  const payload = object$1(rawPayload);
5272
+ if (endpoint === "version-update") {
5273
+ if (versions === void 0) throw new Error("version updates are unavailable");
5274
+ const component = String(payload.component ?? "");
5275
+ if (component !== "mnemon" && component !== "dsh-mnemon") return badRequest$1(`unknown version component: ${component}`);
5276
+ return success$1(await versions.update(component));
5277
+ }
5278
+ const resolved = runtimeFor(input, payload, runtimeMemory);
5279
+ const { service } = resolved.graph;
5280
+ if (!service.config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
5281
+ const selectedWorkspace = resolved.route?.selectedWorkspace;
5282
+ const documentController = resolved.explicitWorkspace && selectedWorkspace !== void 0 ? resolved.graph.documents.forWorkspace(selectedWorkspace.path) : void 0;
5283
+ const inspectionDiverged = resolved.explicitWorkspace && resolved.route?.aligned === false;
5284
+ const alignedSession = resolved.explicitWorkspace && resolved.route?.aligned === true && resolved.route.effectiveWorkspace !== void 0;
4729
5285
  switch (endpoint) {
4730
5286
  case "runtime-memory":
4731
- if (runtimeMemory === void 0) throw new Error("runtime memory is unavailable");
5287
+ if (resolved.graph.runtimeMemory === void 0) throw new Error("runtime memory is unavailable");
4732
5288
  {
4733
5289
  const request = {
4734
5290
  action: String(payload.action ?? ""),
@@ -4738,36 +5294,57 @@ function createWriteHandler(service, lifecycle, runtimeMemory) {
4738
5294
  ...payload.importance === void 0 ? {} : { importance: String(payload.importance) }
4739
5295
  };
4740
5296
  const sessionId = String(payload.sessionId ?? "").trim();
4741
- return success$1(lifecycle === void 0 || sessionId === "" ? await runtimeMemory.mutate(request) : await lifecycle.runtime(sessionId, request));
5297
+ return success$1(inspectionDiverged || lifecycle === void 0 || sessionId === "" || resolved.explicitWorkspace && !alignedSession ? await resolved.graph.runtimeMemory.mutate(request) : await lifecycle.runtime(sessionId, request));
4742
5298
  }
4743
5299
  case "supervise":
4744
5300
  if (lifecycle === void 0) throw new Error("Mnemon lifecycle integration is unavailable");
5301
+ requireAligned(resolved.route);
4745
5302
  return success$1(await lifecycle.supervise(String(payload.sessionId ?? ""), String(payload.content ?? ""), payload.idempotencyKey === void 0 ? void 0 : String(payload.idempotencyKey)));
4746
- case "document":
4747
- if (lifecycle === void 0) throw new Error("Mnemon Documents require lifecycle integration");
4748
- {
4749
- const action = String(payload.action ?? "");
4750
- const sessionId = String(payload.sessionId ?? "");
4751
- if (action === "archive") return success$1(await lifecycle.archiveDocument(sessionId, String(payload.id ?? "")));
4752
- if (action === "create") return success$1(await lifecycle.mutateDocument(sessionId, {
5303
+ case "document": {
5304
+ const action = String(payload.action ?? "");
5305
+ const sessionId = String(payload.sessionId ?? "");
5306
+ if (documentController !== void 0 && action !== "archive" && (!alignedSession || lifecycle === void 0)) {
5307
+ const sessionIds = resolved.route?.aligned === true && sessionId.trim() !== "" ? [sessionId] : [];
5308
+ if (action === "create") return success$1(await documentController.mutate({
4753
5309
  action: "create",
4754
5310
  title: String(payload.title ?? ""),
4755
5311
  content: String(payload.content ?? ""),
4756
5312
  ...payload.description === void 0 ? {} : { description: String(payload.description) },
4757
5313
  ...Array.isArray(payload.sourcePaths) ? { sourcePaths: payload.sourcePaths.map(String) } : {},
4758
- sessionIds: [sessionId]
5314
+ sessionIds
4759
5315
  }));
4760
- if (action === "update") return success$1(await lifecycle.mutateDocument(sessionId, {
5316
+ if (action === "update") return success$1(await documentController.mutate({
4761
5317
  action: "update",
4762
5318
  id: String(payload.id ?? ""),
4763
5319
  ...payload.title === void 0 ? {} : { title: String(payload.title) },
4764
5320
  ...payload.description === void 0 ? {} : { description: String(payload.description) },
4765
5321
  ...payload.content === void 0 ? {} : { content: String(payload.content) },
4766
5322
  ...Array.isArray(payload.sourcePaths) ? { sourcePaths: payload.sourcePaths.map(String) } : {},
4767
- sessionIds: [sessionId]
5323
+ sessionIds
4768
5324
  }));
4769
- return badRequest$1(`unknown document action: ${action}`);
4770
5325
  }
5326
+ if (lifecycle === void 0) throw new Error("Mnemon Documents require lifecycle integration");
5327
+ if (resolved.explicitWorkspace) requireAligned(resolved.route);
5328
+ if (action === "archive") return success$1(await lifecycle.archiveDocument(sessionId, String(payload.id ?? "")));
5329
+ if (action === "create") return success$1(await lifecycle.mutateDocument(sessionId, {
5330
+ action: "create",
5331
+ title: String(payload.title ?? ""),
5332
+ content: String(payload.content ?? ""),
5333
+ ...payload.description === void 0 ? {} : { description: String(payload.description) },
5334
+ ...Array.isArray(payload.sourcePaths) ? { sourcePaths: payload.sourcePaths.map(String) } : {},
5335
+ sessionIds: [sessionId]
5336
+ }));
5337
+ if (action === "update") return success$1(await lifecycle.mutateDocument(sessionId, {
5338
+ action: "update",
5339
+ id: String(payload.id ?? ""),
5340
+ ...payload.title === void 0 ? {} : { title: String(payload.title) },
5341
+ ...payload.description === void 0 ? {} : { description: String(payload.description) },
5342
+ ...payload.content === void 0 ? {} : { content: String(payload.content) },
5343
+ ...Array.isArray(payload.sourcePaths) ? { sourcePaths: payload.sourcePaths.map(String) } : {},
5344
+ sessionIds: [sessionId]
5345
+ }));
5346
+ return badRequest$1(`unknown document action: ${action}`);
5347
+ }
4771
5348
  case "remember": {
4772
5349
  const request = {
4773
5350
  content: String(payload.content ?? ""),
@@ -4778,10 +5355,10 @@ function createWriteHandler(service, lifecycle, runtimeMemory) {
4778
5355
  ...payload.memoryBodyId === void 0 ? {} : { memoryBodyId: String(payload.memoryBodyId) },
4779
5356
  source: "user"
4780
5357
  };
4781
- return success$1(lifecycle === void 0 ? await service.remember(request) : await lifecycle.remember(String(payload.sessionId ?? ""), request));
5358
+ return success$1(inspectionDiverged || lifecycle === void 0 || resolved.explicitWorkspace && !alignedSession ? await service.remember(request) : await lifecycle.remember(String(payload.sessionId ?? ""), request));
4782
5359
  }
4783
- case "link": return success$1(lifecycle === void 0 ? await service.link(String(payload.sourceId ?? ""), String(payload.targetId ?? ""), payload.type, payload.weight === void 0 ? .5 : Number(payload.weight), payload.reason === void 0 ? void 0 : String(payload.reason), void 0, payload.memoryBodyId === void 0 ? void 0 : String(payload.memoryBodyId)) : await lifecycle.mutate(String(payload.sessionId ?? ""), "link", payload));
4784
- case "forget": return success$1(lifecycle === void 0 ? await service.forget(String(payload.id ?? ""), void 0, payload.memoryBodyId === void 0 ? void 0 : String(payload.memoryBodyId)) : await lifecycle.mutate(String(payload.sessionId ?? ""), "forget", {
5360
+ case "link": return success$1(inspectionDiverged || lifecycle === void 0 || resolved.explicitWorkspace && !alignedSession ? await service.link(String(payload.sourceId ?? ""), String(payload.targetId ?? ""), payload.type, payload.weight === void 0 ? .5 : Number(payload.weight), payload.reason === void 0 ? void 0 : String(payload.reason), void 0, payload.memoryBodyId === void 0 ? void 0 : String(payload.memoryBodyId)) : await lifecycle.mutate(String(payload.sessionId ?? ""), "link", payload));
5361
+ case "forget": return success$1(inspectionDiverged || lifecycle === void 0 || resolved.explicitWorkspace && !alignedSession ? await service.forget(String(payload.id ?? ""), void 0, payload.memoryBodyId === void 0 ? void 0 : String(payload.memoryBodyId)) : await lifecycle.mutate(String(payload.sessionId ?? ""), "forget", {
4785
5362
  id: String(payload.id ?? ""),
4786
5363
  ...payload.memoryBodyId === void 0 ? {} : { memoryBodyId: String(payload.memoryBodyId) }
4787
5364
  }));
@@ -4795,6 +5372,7 @@ function createWriteHandler(service, lifecycle, runtimeMemory) {
4795
5372
  ...payload.description === void 0 ? {} : { description: String(payload.description) },
4796
5373
  ...payload.active === void 0 ? {} : { active: Boolean(payload.active) }
4797
5374
  }));
5375
+ case "body-delete": return success$1(await service.deleteBody(String(payload.memoryBodyId ?? "")));
4798
5376
  default: return badRequest$1(`unknown write endpoint: ${endpoint}`);
4799
5377
  }
4800
5378
  } catch (error) {
@@ -4821,10 +5399,16 @@ function createPackHandler(manager, writeEnabled = true) {
4821
5399
  };
4822
5400
  }
4823
5401
  /** Read operations are available to trusted Web hosts; local mutations stay loopback-only. */
4824
- function registerRpc(connection, service, lifecycle, runtimeMemory, storage, packs) {
4825
- connection.rpc.handle(MNEMON_READ_CHANNEL, createReadHandler(service, lifecycle, runtimeMemory, storage), { authority: "trusted-host" });
4826
- connection.rpc.handle(MNEMON_WRITE_CHANNEL, createWriteHandler(service, lifecycle, runtimeMemory), { authority: "loopback" });
4827
- if (packs !== void 0) connection.rpc.handle(MNEMON_PACK_CHANNEL, createPackHandler(packs, () => service.config.writeEnabled), { authority: "loopback" });
5402
+ function registerRpc(connection, input, lifecycle, runtimeMemory, storage, packs, versions) {
5403
+ const versionManager = versions ?? new VersionUpdateManager({ mnemonCliPath: () => findVersionCli(input) });
5404
+ connection.rpc.handle(MNEMON_READ_CHANNEL, createReadHandler(input, lifecycle, runtimeMemory, storage, versionManager), { authority: "trusted-host" });
5405
+ connection.rpc.handle(MNEMON_WRITE_CHANNEL, createWriteHandler(input, lifecycle, runtimeMemory, versionManager), { authority: "loopback" });
5406
+ const packManager = isRoutedRuntime(input) ? input.packs : packs;
5407
+ const config = input.config;
5408
+ if (packManager !== void 0) connection.rpc.handle(MNEMON_PACK_CHANNEL, createPackHandler(packManager, () => config.writeEnabled), { authority: "loopback" });
5409
+ }
5410
+ function findVersionCli(input) {
5411
+ return input.config.cliPath;
4828
5412
  }
4829
5413
  //#endregion
4830
5414
  //#region lib/types/settings.js
@@ -4888,20 +5472,13 @@ const MUTABLE_FIELDS = [
4888
5472
  "recallMode",
4889
5473
  "writebackMode",
4890
5474
  "idleReviewMs",
5475
+ "displayMode",
4891
5476
  "tabEnabled",
4892
5477
  "writeEnabled"
4893
5478
  ];
4894
5479
  /** Nested paths of the live in-conversation interaction toggles. */
4895
- const INTERACTION_PATHS = [
4896
- ["conversationInteraction", "toolviews"],
4897
- ["conversationInteraction", "turnBar"],
4898
- ["conversationInteraction", "saveAction"]
4899
- ];
4900
- const UI_FIELDS = [
4901
- "toolviews",
4902
- "turnBar",
4903
- "saveAction"
4904
- ];
5480
+ const INTERACTION_PATHS = [["conversationInteraction", "turnBar"], ["conversationInteraction", "saveAction"]];
5481
+ const UI_FIELDS = ["turnBar", "saveAction"];
4905
5482
  function namespaceOf(payload) {
4906
5483
  const namespace = payload.namespace === void 0 ? MNEMON_SETTINGS_NAMESPACE : String(payload.namespace);
4907
5484
  if (namespace !== "mnemon" && namespace !== "mnemon-ui") throw new Error(`unsupported Mnemon settings namespace: ${namespace}`);
@@ -4967,8 +5544,21 @@ function requireAgent(exec) {
4967
5544
  if (exec.agent === void 0) throw new Error("Mnemon semantic operations require a live DSH agent");
4968
5545
  return exec.agent;
4969
5546
  }
5547
+ function isAgentRuntimeSource(value) {
5548
+ return "forAgent" in value && typeof value.forAgent === "function";
5549
+ }
4970
5550
  /** Root calls delegate to a bounded child; memory-worker calls reach the deterministic service. */
4971
- function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5551
+ function registerTools(ctx, serviceOrSource, coordinator, runtimeMemory, documents) {
5552
+ const runtimeFor = (exec) => {
5553
+ if (isAgentRuntimeSource(serviceOrSource)) return serviceOrSource.forAgent(requireAgent(exec));
5554
+ if (runtimeMemory === void 0 || documents === void 0) throw new Error("Mnemon runtime control plane is unavailable");
5555
+ return {
5556
+ service: serviceOrSource,
5557
+ runtimeMemory,
5558
+ documents
5559
+ };
5560
+ };
5561
+ const config = serviceOrSource.config;
4972
5562
  ctx.tools.register(definition({
4973
5563
  name: "mnemon_memory_bodies",
4974
5564
  description: "List the global Mnemon Memory Space catalog, including each space id, name, description, activation state, database path, and statistics. Read only. Use this before choosing a write target, or when the Prime summary is insufficient. Recall may only read active spaces; writes may target any space.",
@@ -4980,7 +5570,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
4980
5570
  schema: JSON_OBJECT_OUTPUT,
4981
5571
  render: (_args, value) => text(value)
4982
5572
  },
4983
- execute: (_args, exec) => service.bodies(exec.signal),
5573
+ execute: (_args, exec) => runtimeFor(exec).service.bodies(exec.signal),
4984
5574
  presentCall: () => ({
4985
5575
  card: "generic",
4986
5576
  title: "Inspect Mnemon Memory Spaces",
@@ -5039,7 +5629,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5039
5629
  render: (_args, value) => text(value)
5040
5630
  },
5041
5631
  async execute(args, exec) {
5042
- return isSubagent(exec.agent) ? service.search(args, exec.signal) : coordinator.recall(requireAgent(exec), args, exec.signal);
5632
+ return isSubagent(exec.agent) ? runtimeFor(exec).service.search(args, exec.signal) : coordinator.recall(requireAgent(exec), args, exec.signal);
5043
5633
  },
5044
5634
  presentCall: (args) => ({
5045
5635
  card: "generic",
@@ -5083,7 +5673,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5083
5673
  },
5084
5674
  async execute(args, exec) {
5085
5675
  if (!isSubagent(exec.agent)) return coordinator.related(requireAgent(exec), args.id, args.memoryBodyId, exec.signal);
5086
- const results = await service.related(args.id, args.depth, args.edge, exec.signal, args.memoryBodyId);
5676
+ const results = await runtimeFor(exec).service.related(args.id, args.depth, args.edge, exec.signal, args.memoryBodyId);
5087
5677
  return {
5088
5678
  id: args.id,
5089
5679
  depth: args.depth ?? 2,
@@ -5114,7 +5704,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5114
5704
  schema: JSON_OBJECT_OUTPUT,
5115
5705
  render: (_args, value) => text(value)
5116
5706
  },
5117
- execute: (_args, exec) => service.status(exec.signal),
5707
+ execute: (_args, exec) => runtimeFor(exec).service.status(exec.signal),
5118
5708
  presentCall: () => ({
5119
5709
  card: "generic",
5120
5710
  title: "Check Mnemon status",
@@ -5151,7 +5741,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5151
5741
  render: (_args, value) => text(value)
5152
5742
  },
5153
5743
  async execute(args, exec) {
5154
- const controller = documents.forAgent(requireAgent(exec));
5744
+ const controller = runtimeFor(exec).documents.forAgent(requireAgent(exec));
5155
5745
  const result = await controller.search(args.query, {
5156
5746
  ...args.includeArchived === void 0 ? {} : { includeArchived: args.includeArchived },
5157
5747
  limit: Math.min(8, args.limit ?? 8)
@@ -5229,7 +5819,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5229
5819
  render: (_args, value) => text(value)
5230
5820
  },
5231
5821
  execute: (args, exec) => {
5232
- if (!service.config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
5822
+ if (!config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
5233
5823
  const agent = requireAgent(exec);
5234
5824
  if (args.action === "archive") {
5235
5825
  if (isSubagent(agent)) throw new Error("idle document workers cannot cold-archive directly");
@@ -5252,7 +5842,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5252
5842
  ...args.sourcePaths === void 0 ? {} : { sourcePaths: args.sourcePaths },
5253
5843
  sessionIds: [agent.id]
5254
5844
  };
5255
- return isSubagent(agent) ? documents.forAgent(agent).mutate(request) : coordinator.document(agent, request, exec.signal);
5845
+ return isSubagent(agent) ? runtimeFor(exec).documents.forAgent(agent).mutate(request) : coordinator.document(agent, request, exec.signal);
5256
5846
  },
5257
5847
  presentCall: (args) => ({
5258
5848
  card: "generic",
@@ -5310,7 +5900,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5310
5900
  render: (_args, value) => text(value)
5311
5901
  },
5312
5902
  execute: (args, exec) => {
5313
- if (!service.config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
5903
+ if (!config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
5314
5904
  const request = {
5315
5905
  action: args.action,
5316
5906
  target: args.target,
@@ -5318,7 +5908,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5318
5908
  ...args.old_text === void 0 ? {} : { oldText: args.old_text },
5319
5909
  ...args.importance === void 0 ? {} : { importance: args.importance }
5320
5910
  };
5321
- return isSubagent(exec.agent) ? runtimeMemory.mutate(request) : coordinator.runtime(requireAgent(exec), request, exec.signal);
5911
+ return isSubagent(exec.agent) ? runtimeFor(exec).runtimeMemory.mutate(request) : coordinator.runtime(requireAgent(exec), request, exec.signal);
5322
5912
  },
5323
5913
  presentCall: (args) => ({
5324
5914
  card: "generic",
@@ -5379,7 +5969,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5379
5969
  ...args,
5380
5970
  source: args.source ?? "agent"
5381
5971
  };
5382
- return isSubagent(exec.agent) ? service.remember(request, exec.signal) : coordinator.remember(requireAgent(exec), request, exec.signal);
5972
+ return isSubagent(exec.agent) ? runtimeFor(exec).service.remember(request, exec.signal) : coordinator.remember(requireAgent(exec), request, exec.signal);
5383
5973
  },
5384
5974
  presentCall: () => ({
5385
5975
  card: "generic",
@@ -5420,7 +6010,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5420
6010
  render: (_args, value) => text(value)
5421
6011
  },
5422
6012
  async execute(args, exec) {
5423
- return isSubagent(exec.agent) ? service.link(args.sourceId, args.targetId, args.type, args.weight, args.reason, exec.signal, args.memoryBodyId) : coordinator.write(requireAgent(exec), "link", args, exec.signal);
6013
+ return isSubagent(exec.agent) ? runtimeFor(exec).service.link(args.sourceId, args.targetId, args.type, args.weight, args.reason, exec.signal, args.memoryBodyId) : coordinator.write(requireAgent(exec), "link", args, exec.signal);
5424
6014
  },
5425
6015
  presentCall: () => ({
5426
6016
  card: "generic",
@@ -5450,7 +6040,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5450
6040
  schema: JSON_OBJECT_OUTPUT,
5451
6041
  render: (_args, value) => text(value)
5452
6042
  },
5453
- execute: (args, exec) => isSubagent(exec.agent) ? service.forget(args.id, exec.signal, args.memoryBodyId) : coordinator.write(requireAgent(exec), "forget", args, exec.signal),
6043
+ execute: (args, exec) => isSubagent(exec.agent) ? runtimeFor(exec).service.forget(args.id, exec.signal, args.memoryBodyId) : coordinator.write(requireAgent(exec), "forget", args, exec.signal),
5454
6044
  presentCall: (args) => ({
5455
6045
  card: "generic",
5456
6046
  title: "Forget Mnemon insight",
@@ -5483,7 +6073,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5483
6073
  schema: JSON_OBJECT_OUTPUT,
5484
6074
  render: (_args, value) => text(value)
5485
6075
  },
5486
- execute: (args, exec) => isSubagent(exec.agent) ? service.createBody(args, exec.signal) : coordinator.write(requireAgent(exec), "create-memory-body", args, exec.signal),
6076
+ execute: (args, exec) => isSubagent(exec.agent) ? runtimeFor(exec).service.createBody(args, exec.signal) : coordinator.write(requireAgent(exec), "create-memory-body", args, exec.signal),
5487
6077
  presentCall: () => ({
5488
6078
  card: "generic",
5489
6079
  title: "Create Mnemon Memory Space",
@@ -5511,7 +6101,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5511
6101
  schema: JSON_OBJECT_OUTPUT,
5512
6102
  render: (_args, value) => text(value)
5513
6103
  },
5514
- execute: (args, exec) => isSubagent(exec.agent) ? service.updateBody(args.memoryBodyId, args) : coordinator.write(requireAgent(exec), "update-memory-body", args, exec.signal),
6104
+ execute: (args, exec) => isSubagent(exec.agent) ? runtimeFor(exec).service.updateBody(args.memoryBodyId, args) : coordinator.write(requireAgent(exec), "update-memory-body", args, exec.signal),
5515
6105
  presentCall: () => ({
5516
6106
  card: "generic",
5517
6107
  title: "Update Mnemon Memory Space",
@@ -5545,7 +6135,7 @@ function registerTools(ctx, service, coordinator, runtimeMemory, documents) {
5545
6135
  schema: JSON_OBJECT_OUTPUT,
5546
6136
  render: (_args, value) => text(value)
5547
6137
  },
5548
- execute: (args, exec) => isSubagent(exec.agent) ? service.mergeBodies(args.targetMemoryBodyId, args.sourceMemoryBodyIds, args.deactivateSources ?? true, exec.signal) : coordinator.write(requireAgent(exec), "merge-memory-bodies", args, exec.signal),
6138
+ execute: (args, exec) => isSubagent(exec.agent) ? runtimeFor(exec).service.mergeBodies(args.targetMemoryBodyId, args.sourceMemoryBodyIds, args.deactivateSources ?? true, exec.signal) : coordinator.write(requireAgent(exec), "merge-memory-bodies", args, exec.signal),
5549
6139
  presentCall: () => ({
5550
6140
  card: "generic",
5551
6141
  title: "Merge Mnemon Memory Spaces",
@@ -5565,7 +6155,8 @@ const inject = [
5565
6155
  "settings",
5566
6156
  "commands",
5567
6157
  "agents",
5568
- "subagents"
6158
+ "subagents",
6159
+ "workspaceRegistry"
5569
6160
  ];
5570
6161
  /** Mount native model tools on every DSH surface and UI RPC only when Web connection exists. */
5571
6162
  function apply(rawContext, config = {}) {
@@ -5578,7 +6169,7 @@ function apply(rawContext, config = {}) {
5578
6169
  prepared.set(value, createRuntimeGraph(resolveConfig(value)));
5579
6170
  }
5580
6171
  }).get();
5581
- const runtime = new LiveMnemonRuntime(prepared.get(initialSettings) ?? createRuntimeGraph(resolveConfig(initialSettings)));
6172
+ const runtime = new LiveMnemonRuntime(prepared.get(initialSettings) ?? createRuntimeGraph(resolveConfig(initialSettings)), ctx.workspaceRegistry, ctx.agents);
5582
6173
  const resolved = runtime.config;
5583
6174
  ctx.on("settings/updated", ((namespace, next) => {
5584
6175
  if (namespace !== "mnemon") return;
@@ -5588,17 +6179,17 @@ function apply(rawContext, config = {}) {
5588
6179
  base: resolveInteractionConfig(resolved.conversationInteraction),
5589
6180
  applies: "live"
5590
6181
  });
5591
- const coordinator = new MnemonSubagentCoordinator(ctx.subagents, runtime.runtimeMemory, runtime.documents);
5592
- const lifecycle = new MnemonLifecycle(ctx, coordinator, resolved);
6182
+ const coordinator = new MnemonSubagentCoordinator(ctx.subagents, runtime);
6183
+ const lifecycle = new MnemonLifecycle(ctx, coordinator, runtime.config, runtime);
5593
6184
  ctx.effect(() => lifecycle.start(), "dsh-mnemon.lifecycle-root()");
5594
- registerTools(ctx, runtime.service, coordinator, runtime.runtimeMemory, runtime.documents);
5595
- registerCommands(ctx.commands, runtime.service, coordinator);
6185
+ registerTools(ctx, runtime, coordinator);
6186
+ registerCommands(ctx.commands, runtime, coordinator);
5596
6187
  registerGuidance(ctx, resolved);
5597
6188
  registerRuntimeMemoryContext(ctx, runtime.runtimeMemory);
5598
6189
  ctx.inject(["connection"], (webContext) => {
5599
- registerRpc(webContext.connection, runtime.service, lifecycle, runtime.runtimeMemory, runtime.storage, runtime.packs);
6190
+ registerRpc(webContext.connection, runtime, lifecycle);
5600
6191
  registerSettingsRpc(webContext.connection, ctx.settings);
5601
6192
  });
5602
6193
  }
5603
6194
  //#endregion
5604
- export { Config, DocumentManager, InteractionConfig, LiveMnemonRuntime, MnemonLifecycle, MnemonPackManager, MnemonService, MnemonSubagentCoordinator, RuntimeMemoryController, StorageScopeInspector, apply, createRunner, createRuntimeGraph, inject, name, resolveConfig, resolveInteractionConfig };
6195
+ export { Config, DocumentManager, InteractionConfig, LiveMnemonRuntime, MnemonLifecycle, MnemonPackManager, MnemonService, MnemonSubagentCoordinator, RuntimeMemoryController, StorageScopeInspector, VersionUpdateManager, apply, createRunner, createRuntimeGraph, inject, name, resolveConfig, resolveInteractionConfig };