dsh-mnemon 0.1.2 → 0.1.4

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 (138) hide show
  1. package/README.md +103 -129
  2. package/README.zh-CN.md +173 -0
  3. package/SECURITY.md +2 -2
  4. package/docs/README.md +4 -4
  5. package/docs/assets/diagrams/en/memory-system-flow.png +0 -0
  6. package/docs/assets/diagrams/zh-CN/memory-system-flow.png +0 -0
  7. package/docs/assets/media/dsh-mnemon-memory-system-demo-poster.jpg +0 -0
  8. package/docs/assets/media/dsh-mnemon-memory-system-demo.gif +0 -0
  9. package/docs/assets/media/dsh-mnemon-memory-system-demo.mp4 +0 -0
  10. package/docs/assets/screenshots/conversation-memory-jump.png +0 -0
  11. package/docs/assets/screenshots/conversation-save-dialog.png +0 -0
  12. package/docs/assets/screenshots/conversation-turn-memory.png +0 -0
  13. package/docs/assets/screenshots/document-create-dialog.png +0 -0
  14. package/docs/assets/screenshots/documents-markdown.png +0 -0
  15. package/docs/assets/screenshots/entities-context.png +0 -0
  16. package/docs/assets/screenshots/memory-content.png +0 -0
  17. package/docs/assets/screenshots/overview-memory-graph.png +0 -0
  18. package/docs/assets/screenshots/recall-agent-answer.png +0 -0
  19. package/docs/assets/screenshots/remember-dialog.png +0 -0
  20. package/docs/assets/screenshots/runtime-memory-add.png +0 -0
  21. package/docs/assets/screenshots/runtime-memory.png +0 -0
  22. package/docs/assets/screenshots/settings-memory-system.png +0 -0
  23. package/docs/assets/screenshots/status-overview.png +0 -0
  24. package/docs/assets/screenshots/version-check.png +0 -0
  25. package/docs/en/README.md +40 -32
  26. package/docs/en/architecture.md +6 -2
  27. package/docs/en/configuration.md +15 -6
  28. package/docs/en/development.md +24 -4
  29. package/docs/en/getting-started.md +77 -87
  30. package/docs/en/interfaces.md +98 -90
  31. package/docs/en/operations.md +103 -93
  32. package/docs/en/project-overview.md +90 -194
  33. package/docs/en/storage-model.md +6 -0
  34. package/docs/en/ui-guide.md +156 -0
  35. package/docs/zh-CN/README.md +37 -29
  36. package/docs/zh-CN/architecture.md +6 -2
  37. package/docs/zh-CN/configuration.md +15 -6
  38. package/docs/zh-CN/development.md +24 -4
  39. package/docs/zh-CN/getting-started.md +70 -80
  40. package/docs/zh-CN/interfaces.md +84 -76
  41. package/docs/zh-CN/operations.md +96 -86
  42. package/docs/zh-CN/project-overview.md +86 -190
  43. package/docs/zh-CN/storage-model.md +6 -0
  44. package/docs/zh-CN/ui-guide.md +160 -0
  45. package/lib/client.js +2354 -1944
  46. package/lib/client.js.map +1 -1
  47. package/lib/index.js +446 -39
  48. package/lib/types/channels.d.ts +4 -0
  49. package/lib/types/channels.d.ts.map +1 -0
  50. package/lib/types/channels.js +4 -0
  51. package/lib/types/channels.js.map +1 -0
  52. package/lib/types/client/MnemonSaveAction.d.ts.map +1 -1
  53. package/lib/types/client/MnemonSaveAction.js +4 -55
  54. package/lib/types/client/MnemonSaveAction.js.map +1 -1
  55. package/lib/types/client/MnemonSettingsCard.d.ts.map +1 -1
  56. package/lib/types/client/MnemonSettingsCard.js +4 -5
  57. package/lib/types/client/MnemonSettingsCard.js.map +1 -1
  58. package/lib/types/client/MnemonTurnTail.d.ts +3 -0
  59. package/lib/types/client/MnemonTurnTail.d.ts.map +1 -1
  60. package/lib/types/client/MnemonTurnTail.js +15 -3
  61. package/lib/types/client/MnemonTurnTail.js.map +1 -1
  62. package/lib/types/client/MnemonView.d.ts +4 -0
  63. package/lib/types/client/MnemonView.d.ts.map +1 -1
  64. package/lib/types/client/MnemonView.js +424 -97
  65. package/lib/types/client/MnemonView.js.map +1 -1
  66. package/lib/types/client/MnemonViewAppearance.d.ts +21 -0
  67. package/lib/types/client/MnemonViewAppearance.d.ts.map +1 -0
  68. package/lib/types/client/MnemonViewAppearance.js +67 -0
  69. package/lib/types/client/MnemonViewAppearance.js.map +1 -0
  70. package/lib/types/client/anchor.d.ts +1 -1
  71. package/lib/types/client/anchor.js +1 -1
  72. package/lib/types/client/api.d.ts +4 -0
  73. package/lib/types/client/api.d.ts.map +1 -1
  74. package/lib/types/client/api.js +10 -1
  75. package/lib/types/client/api.js.map +1 -1
  76. package/lib/types/client/index.d.ts.map +1 -1
  77. package/lib/types/client/index.js +22 -25
  78. package/lib/types/client/index.js.map +1 -1
  79. package/lib/types/client/locales.d.ts +126 -294
  80. package/lib/types/client/locales.d.ts.map +1 -1
  81. package/lib/types/client/locales.js +140 -308
  82. package/lib/types/client/locales.js.map +1 -1
  83. package/lib/types/client/settings.d.ts +1 -1
  84. package/lib/types/client/settings.d.ts.map +1 -1
  85. package/lib/types/client/settings.js +1 -1
  86. package/lib/types/client/settings.js.map +1 -1
  87. package/lib/types/client/sidebar-entry.d.ts +1 -1
  88. package/lib/types/client/sidebar-entry.d.ts.map +1 -1
  89. package/lib/types/client/sidebar-entry.js +3 -1
  90. package/lib/types/client/sidebar-entry.js.map +1 -1
  91. package/lib/types/client/workspace-mount.d.ts.map +1 -1
  92. package/lib/types/client/workspace-mount.js +8 -5
  93. package/lib/types/client/workspace-mount.js.map +1 -1
  94. package/lib/types/config.d.ts +1 -3
  95. package/lib/types/config.d.ts.map +1 -1
  96. package/lib/types/config.js +10 -12
  97. package/lib/types/config.js.map +1 -1
  98. package/lib/types/index.d.ts +2 -1
  99. package/lib/types/index.d.ts.map +1 -1
  100. package/lib/types/index.js +2 -1
  101. package/lib/types/index.js.map +1 -1
  102. package/lib/types/lifecycle.js +3 -3
  103. package/lib/types/lifecycle.js.map +1 -1
  104. package/lib/types/memory-bodies.d.ts +1 -0
  105. package/lib/types/memory-bodies.d.ts.map +1 -1
  106. package/lib/types/memory-bodies.js +7 -0
  107. package/lib/types/memory-bodies.js.map +1 -1
  108. package/lib/types/rpc.d.ts +5 -7
  109. package/lib/types/rpc.d.ts.map +1 -1
  110. package/lib/types/rpc.js +28 -8
  111. package/lib/types/rpc.js.map +1 -1
  112. package/lib/types/service.d.ts +2 -0
  113. package/lib/types/service.d.ts.map +1 -1
  114. package/lib/types/service.js +4 -0
  115. package/lib/types/service.js.map +1 -1
  116. package/lib/types/settings.d.ts.map +1 -1
  117. package/lib/types/settings.js +1 -2
  118. package/lib/types/settings.js.map +1 -1
  119. package/lib/types/version-updates.d.ts +61 -0
  120. package/lib/types/version-updates.d.ts.map +1 -0
  121. package/lib/types/version-updates.js +377 -0
  122. package/lib/types/version-updates.js.map +1 -0
  123. package/package.json +23 -8
  124. package/README.en.md +0 -199
  125. package/docs/zh-CN/assets/screenshots/conversation-recall.png +0 -0
  126. package/docs/zh-CN/assets/screenshots/conversation-writeback.png +0 -0
  127. package/docs/zh-CN/assets/screenshots/documents-markdown.png +0 -0
  128. package/docs/zh-CN/assets/screenshots/entities-context.png +0 -0
  129. package/docs/zh-CN/assets/screenshots/memory-content.png +0 -0
  130. package/docs/zh-CN/assets/screenshots/overview-memory-graph.png +0 -0
  131. package/docs/zh-CN/assets/screenshots/recall-agent-answer.png +0 -0
  132. package/docs/zh-CN/assets/screenshots/runtime-memory.png +0 -0
  133. package/lib/types/client/MnemonToolviews.d.ts +0 -19
  134. package/lib/types/client/MnemonToolviews.d.ts.map +0 -1
  135. package/lib/types/client/MnemonToolviews.js +0 -172
  136. package/lib/types/client/MnemonToolviews.js.map +0 -1
  137. /package/docs/{en/assets → assets/diagrams/en}/project-architecture.svg +0 -0
  138. /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([
@@ -42,19 +42,18 @@ const Config = z.object({
42
42
  idleReviewMs: z.number().step(1).min(5e3).max(6e5).default(DEFAULT_IDLE_REVIEW_MS),
43
43
  conversationInteraction: z.object({
44
44
  toolviews: z.boolean().default(false),
45
- turnBar: z.boolean().default(false),
46
- saveAction: z.boolean().default(false)
45
+ turnBar: z.boolean().default(true),
46
+ saveAction: z.boolean().default(true)
47
47
  }).default({
48
48
  toolviews: false,
49
- turnBar: false,
50
- saveAction: false
49
+ turnBar: true,
50
+ saveAction: true
51
51
  })
52
52
  });
53
53
  function resolveInteractionConfig(config = {}) {
54
54
  return {
55
- toolviews: config.toolviews ?? false,
56
- turnBar: config.turnBar ?? false,
57
- saveAction: config.saveAction ?? false
55
+ turnBar: config.turnBar ?? true,
56
+ saveAction: config.saveAction ?? true
58
57
  };
59
58
  }
60
59
  function optionalText$1(value) {
@@ -127,8 +126,8 @@ function resolveConfig(config = {}) {
127
126
  idleReviewMs: config.idleReviewMs ?? 3e4,
128
127
  conversationInteraction: {
129
128
  toolviews: config.conversationInteraction?.toolviews ?? false,
130
- turnBar: config.conversationInteraction?.turnBar ?? false,
131
- saveAction: config.conversationInteraction?.saveAction ?? false
129
+ turnBar: config.conversationInteraction?.turnBar ?? true,
130
+ saveAction: config.conversationInteraction?.saveAction ?? true
132
131
  }
133
132
  };
134
133
  }
@@ -2089,7 +2088,7 @@ function expandHome$1(path) {
2089
2088
  if (path === "~") return homedir();
2090
2089
  return path.startsWith("~/") ? join(homedir(), path.slice(2)) : path;
2091
2090
  }
2092
- function executable(path) {
2091
+ function executable$1(path) {
2093
2092
  try {
2094
2093
  accessSync(path, constants.X_OK);
2095
2094
  return true;
@@ -2103,7 +2102,7 @@ function findMnemonCommand(config) {
2103
2102
  const envPath = process.env.MNEMON_CLI_PATH?.trim();
2104
2103
  if (envPath !== void 0 && envPath !== "") {
2105
2104
  const path = expandHome$1(envPath);
2106
- if (executable(path)) return path;
2105
+ if (executable$1(path)) return path;
2107
2106
  }
2108
2107
  for (const directory of (process.env.PATH ?? "").split(delimiter)) {
2109
2108
  if (directory === "") continue;
@@ -2113,12 +2112,12 @@ function findMnemonCommand(config) {
2113
2112
  "mnemon"
2114
2113
  ] : ["mnemon"]) {
2115
2114
  const path = join(directory, name);
2116
- if (executable(path)) return path;
2115
+ if (executable$1(path)) return path;
2117
2116
  }
2118
2117
  }
2119
2118
  for (const candidate of COMMON_CLI_PATHS) {
2120
2119
  const path = expandHome$1(candidate);
2121
- if (executable(path)) return path;
2120
+ if (executable$1(path)) return path;
2122
2121
  }
2123
2122
  }
2124
2123
  var MnemonCliError = class extends Error {
@@ -2173,7 +2172,7 @@ function createRunner(config, processRunner = runProcess, workspaceRoot) {
2173
2172
  };
2174
2173
  return {
2175
2174
  command,
2176
- commandFound: found !== void 0 && executable(found),
2175
+ commandFound: found !== void 0 && executable$1(found),
2177
2176
  config,
2178
2177
  async runJson(args, options) {
2179
2178
  const stdout = await execute(args, options);
@@ -2300,6 +2299,20 @@ var MemoryBodyRegistry = class {
2300
2299
  this.save();
2301
2300
  return this.view(body);
2302
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
+ }
2303
2316
  setActive(id, active) {
2304
2317
  return this.update(id, { active });
2305
2318
  }
@@ -2785,6 +2798,10 @@ var MnemonService = class {
2785
2798
  this.assertWritable();
2786
2799
  return this.memoryBodies.update(id, request);
2787
2800
  }
2801
+ async deleteBody(id, signal) {
2802
+ this.assertWritable();
2803
+ return this.memoryBodies.remove(id, signal);
2804
+ }
2788
2805
  async mergeBodies(targetBodyId, sourceBodyIds, deactivateSources = true, signal) {
2789
2806
  this.assertWritable();
2790
2807
  const target = this.memoryBodies.get(targetBodyId);
@@ -4293,13 +4310,13 @@ function completedToolActivity(events, turn) {
4293
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)))
4294
4311
  };
4295
4312
  }
4296
- /** 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. */
4297
4314
  function assistantMessageText(events, messageId) {
4298
4315
  for (const event of events) {
4299
4316
  if (event.type !== "assistant/message") continue;
4300
4317
  const message = event.data.message;
4301
4318
  if (message === void 0 || typeof message !== "object" || message.id !== messageId) continue;
4302
- 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();
4303
4320
  return text === "" ? null : {
4304
4321
  messageId,
4305
4322
  text
@@ -4681,6 +4698,391 @@ var MnemonLifecycle = class {
4681
4698
  }
4682
4699
  };
4683
4700
  //#endregion
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
5082
+ const MNEMON_READ_CHANNEL = "/dsh-mnemon-read";
5083
+ const MNEMON_WRITE_CHANNEL = "/dsh-mnemon-write";
5084
+ const MNEMON_PACK_CHANNEL = "/dsh-mnemon-pack";
5085
+ //#endregion
4684
5086
  //#region lib/types/rpc.js
4685
5087
  function isRoutedRuntime(value) {
4686
5088
  return "route" in value && typeof value.route === "function";
@@ -4717,9 +5119,6 @@ function runtimeFor(input, payload, runtimeMemory, storage) {
4717
5119
  function requireAligned(route) {
4718
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");
4719
5121
  }
4720
- const MNEMON_READ_CHANNEL = "/dsh-mnemon-read";
4721
- const MNEMON_WRITE_CHANNEL = "/dsh-mnemon-write";
4722
- const MNEMON_PACK_CHANNEL = "/dsh-mnemon-pack";
4723
5122
  function object$1(value) {
4724
5123
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("payload must be an object");
4725
5124
  return value;
@@ -4750,10 +5149,14 @@ function badRequest$1(message) {
4750
5149
  }
4751
5150
  };
4752
5151
  }
4753
- function createReadHandler(input, lifecycle, runtimeMemory, storage) {
5152
+ function createReadHandler(input, lifecycle, runtimeMemory, storage, versions) {
4754
5153
  return async (endpoint, rawPayload) => {
4755
5154
  try {
4756
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
+ }
4757
5160
  const resolved = runtimeFor(input, payload, runtimeMemory, storage);
4758
5161
  const { service } = resolved.graph;
4759
5162
  const selectedWorkspace = resolved.route?.selectedWorkspace;
@@ -4773,6 +5176,7 @@ function createReadHandler(input, lifecycle, runtimeMemory, storage) {
4773
5176
  } catch {}
4774
5177
  return success$1({
4775
5178
  ...await service.status(),
5179
+ ...versions === void 0 ? {} : { dshMnemonVersion: versions.currentDshMnemonVersion },
4776
5180
  ...lifecycle === void 0 ? {} : { lifecycle: lifecycle.snapshot(payload.sessionId === void 0 ? void 0 : String(payload.sessionId)) },
4777
5181
  ...documents === void 0 ? {} : { documents },
4778
5182
  ...resolved.graph.storage === void 0 ? {} : { storage: resolved.graph.storage.catalog(selectedWorkspace?.path ?? lifecycle?.workspaceRoot(sessionId)) },
@@ -4861,10 +5265,16 @@ function createReadHandler(input, lifecycle, runtimeMemory, storage) {
4861
5265
  }
4862
5266
  };
4863
5267
  }
4864
- function createWriteHandler(input, lifecycle, runtimeMemory) {
5268
+ function createWriteHandler(input, lifecycle, runtimeMemory, versions) {
4865
5269
  return async (endpoint, rawPayload) => {
4866
5270
  try {
4867
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
+ }
4868
5278
  const resolved = runtimeFor(input, payload, runtimeMemory);
4869
5279
  const { service } = resolved.graph;
4870
5280
  if (!service.config.writeEnabled) throw new Error("dsh-mnemon is configured read-only (writeEnabled: false)");
@@ -4962,6 +5372,7 @@ function createWriteHandler(input, lifecycle, runtimeMemory) {
4962
5372
  ...payload.description === void 0 ? {} : { description: String(payload.description) },
4963
5373
  ...payload.active === void 0 ? {} : { active: Boolean(payload.active) }
4964
5374
  }));
5375
+ case "body-delete": return success$1(await service.deleteBody(String(payload.memoryBodyId ?? "")));
4965
5376
  default: return badRequest$1(`unknown write endpoint: ${endpoint}`);
4966
5377
  }
4967
5378
  } catch (error) {
@@ -4988,13 +5399,17 @@ function createPackHandler(manager, writeEnabled = true) {
4988
5399
  };
4989
5400
  }
4990
5401
  /** Read operations are available to trusted Web hosts; local mutations stay loopback-only. */
4991
- function registerRpc(connection, input, lifecycle, runtimeMemory, storage, packs) {
4992
- connection.rpc.handle(MNEMON_READ_CHANNEL, createReadHandler(input, lifecycle, runtimeMemory, storage), { authority: "trusted-host" });
4993
- connection.rpc.handle(MNEMON_WRITE_CHANNEL, createWriteHandler(input, lifecycle, runtimeMemory), { 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" });
4994
5406
  const packManager = isRoutedRuntime(input) ? input.packs : packs;
4995
5407
  const config = input.config;
4996
5408
  if (packManager !== void 0) connection.rpc.handle(MNEMON_PACK_CHANNEL, createPackHandler(packManager, () => config.writeEnabled), { authority: "loopback" });
4997
5409
  }
5410
+ function findVersionCli(input) {
5411
+ return input.config.cliPath;
5412
+ }
4998
5413
  //#endregion
4999
5414
  //#region lib/types/settings.js
5000
5415
  const MNEMON_SETTINGS_CHANNEL = "/dsh-mnemon-settings";
@@ -5062,16 +5477,8 @@ const MUTABLE_FIELDS = [
5062
5477
  "writeEnabled"
5063
5478
  ];
5064
5479
  /** Nested paths of the live in-conversation interaction toggles. */
5065
- const INTERACTION_PATHS = [
5066
- ["conversationInteraction", "toolviews"],
5067
- ["conversationInteraction", "turnBar"],
5068
- ["conversationInteraction", "saveAction"]
5069
- ];
5070
- const UI_FIELDS = [
5071
- "toolviews",
5072
- "turnBar",
5073
- "saveAction"
5074
- ];
5480
+ const INTERACTION_PATHS = [["conversationInteraction", "turnBar"], ["conversationInteraction", "saveAction"]];
5481
+ const UI_FIELDS = ["turnBar", "saveAction"];
5075
5482
  function namespaceOf(payload) {
5076
5483
  const namespace = payload.namespace === void 0 ? MNEMON_SETTINGS_NAMESPACE : String(payload.namespace);
5077
5484
  if (namespace !== "mnemon" && namespace !== "mnemon-ui") throw new Error(`unsupported Mnemon settings namespace: ${namespace}`);
@@ -5785,4 +6192,4 @@ function apply(rawContext, config = {}) {
5785
6192
  });
5786
6193
  }
5787
6194
  //#endregion
5788
- 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 };
@@ -0,0 +1,4 @@
1
+ export declare const MNEMON_READ_CHANNEL = "/dsh-mnemon-read";
2
+ export declare const MNEMON_WRITE_CHANNEL = "/dsh-mnemon-write";
3
+ export declare const MNEMON_PACK_CHANNEL = "/dsh-mnemon-pack";
4
+ //# sourceMappingURL=channels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/channels.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,qBAAqB,CAAA;AACrD,eAAO,MAAM,oBAAoB,sBAAsB,CAAA;AACvD,eAAO,MAAM,mBAAmB,qBAAqB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export const MNEMON_READ_CHANNEL = '/dsh-mnemon-read';
2
+ export const MNEMON_WRITE_CHANNEL = '/dsh-mnemon-write';
3
+ export const MNEMON_PACK_CHANNEL = '/dsh-mnemon-pack';
4
+ //# sourceMappingURL=channels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/channels.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAA;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAA;AACvD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"MnemonSaveAction.d.ts","sourceRoot":"","sources":["../../../src/client/MnemonSaveAction.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,sBAAsB,CAAA;IAClC,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;CAChE;AASD,2GAA2G;AAC3G,eAAO,MAAM,gBAAgB,6DAsK3B,CAAA"}
1
+ {"version":3,"file":"MnemonSaveAction.d.ts","sourceRoot":"","sources":["../../../src/client/MnemonSaveAction.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAE7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,sBAAsB,CAAA;IAClC,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;CAChE;AASD,2GAA2G;AAC3G,eAAO,MAAM,gBAAgB,6DAgI3B,CAAA"}