@xopcai/xopc 0.0.139 → 0.0.140

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 (80) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DaKR5VFJ.js → agent-avatar-dicebear-DtONoxBN.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agents-BWPLvVAX.js → agents-Dl9EWnUh.js} +1 -1
  5. package/dist/gateway/static/root/assets/{app-management-settings-panel-C1yCcfAr.js → app-management-settings-panel-BRBxLECY.js} +1 -1
  6. package/dist/gateway/static/root/assets/{appearance-settings-C7epTkvN.js → appearance-settings-ChvyuSEt.js} +1 -1
  7. package/dist/gateway/static/root/assets/{apps-page-C7RhWR_g.js → apps-page-DgHWTnjs.js} +1 -1
  8. package/dist/gateway/static/root/assets/{archive-plugin-uYiq_pCm.js → archive-plugin-CdIoagem.js} +1 -1
  9. package/dist/gateway/static/root/assets/{attachment-load-tTRlOS85.js → attachment-load-Ch411Kht.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automation-suggestion-card-CrsQD0rW.js → automation-suggestion-card-SVq27yw2.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-page-Ceq-gjQY.js → automations-page-CFt5Ik4q.js} +1 -1
  12. package/dist/gateway/static/root/assets/{binary-plugins-C48c9Gom.js → binary-plugins-D8cV-emn.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-otkTsVAj.js → block-editor-CXDkby6y.js} +1 -1
  14. package/dist/gateway/static/root/assets/{browser-settings-page-DfTmJ6vD.js → browser-settings-page-ColJPwer.js} +1 -1
  15. package/dist/gateway/static/root/assets/{capability-presets-api-DcsHBLTW.js → capability-presets-api-DLxI--Ge.js} +1 -1
  16. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-APCDv5lF.js → capability-presets-settings-panel-DKyRbnlH.js} +1 -1
  17. package/dist/gateway/static/root/assets/{channels-settings-DiffHkSo.js → channels-settings-BDLHV3Jx.js} +1 -1
  18. package/dist/gateway/static/root/assets/{connectors-page-BtpP4slN.js → connectors-page-CA752gY8.js} +1 -1
  19. package/dist/gateway/static/root/assets/{desktop-pet-CFOzVp9k.js → desktop-pet-Bz9ommjr.js} +1 -1
  20. package/dist/gateway/static/root/assets/{desktop-pet-settings-B_n2hP1Y.js → desktop-pet-settings-BnLgxgoR.js} +1 -1
  21. package/dist/gateway/static/root/assets/{directory-picker-path-field-D70qdEFn.js → directory-picker-path-field-DLsCwFaf.js} +1 -1
  22. package/dist/gateway/static/root/assets/{dreaming-settings-Cf1djhWv.js → dreaming-settings-BzkF1-XT.js} +1 -1
  23. package/dist/gateway/static/root/assets/{extension-debug-page-vq1KzRUr.js → extension-debug-page-CdERvf3L.js} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-page-76tQc0Em.js → extension-page-D1fz474Z.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-settings-page-Dd9rQaPO.js → extension-settings-page-DoQMkNOK.js} +1 -1
  26. package/dist/gateway/static/root/assets/{gateway-config-api-BUE3TEuI.js → gateway-config-api-Rygo8UAs.js} +1 -1
  27. package/dist/gateway/static/root/assets/{gateway-settings-Csn16qoE.js → gateway-settings-kb8KIeQL.js} +1 -1
  28. package/dist/gateway/static/root/assets/{goal-create-dialog-DSqSnAl7.js → goal-create-dialog-DVAHnifk.js} +1 -1
  29. package/dist/gateway/static/root/assets/{goal-detail-page-CMCq_woY.js → goal-detail-page-BuOEQZn_.js} +1 -1
  30. package/dist/gateway/static/root/assets/{goals-config-api-nJpdQNoE.js → goals-config-api-BuY6-l0a.js} +1 -1
  31. package/dist/gateway/static/root/assets/{goals-page-D6Vpf5-E.js → goals-page-WV4cHvD-.js} +1 -1
  32. package/dist/gateway/static/root/assets/{goals-settings-jrmfg0HO.js → goals-settings-DoH5fZWo.js} +1 -1
  33. package/dist/gateway/static/root/assets/{heartbeat-settings-KL9DRMjL.js → heartbeat-settings-BqDs48B-.js} +1 -1
  34. package/dist/gateway/static/root/assets/{index-YWf7ByKE.js → index-CrPRlGMg.js} +6 -6
  35. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-pIQ37X35.js → keyboard-shortcuts-settings-D51yogNZ.js} +1 -1
  36. package/dist/gateway/static/root/assets/{logs-page-BmdFLgTD.js → logs-page-CL22jleU.js} +1 -1
  37. package/dist/gateway/static/root/assets/{markdown-split-DnZL-Ckh.js → markdown-split-CSt32FWE.js} +1 -1
  38. package/dist/gateway/static/root/assets/{media-plugins-MxdJOcLY.js → media-plugins-ByItHxBj.js} +1 -1
  39. package/dist/gateway/static/root/assets/{models-hub-panel-DnQ03TQ8.js → models-hub-panel-BkV9hDc-.js} +1 -1
  40. package/dist/gateway/static/root/assets/{notes-page-BDuJYhFX.js → notes-page-BK9yydrL.js} +1 -1
  41. package/dist/gateway/static/root/assets/{notes-workbench-DzPGnk2x.js → notes-workbench-Dd0v-hK2.js} +2 -2
  42. package/dist/gateway/static/root/assets/{page-tabs-CH8nMJUm.js → page-tabs-DOfMaq_L.js} +1 -1
  43. package/dist/gateway/static/root/assets/{preview-open-alternatives-Dob0DX_p.js → preview-open-alternatives-BArxASu7.js} +1 -1
  44. package/dist/gateway/static/root/assets/{project-detail-page-CyChMpWm.js → project-detail-page-DSPhB3do.js} +1 -1
  45. package/dist/gateway/static/root/assets/{projects-page-eqKeClp0.js → projects-page-C-fZk1f7.js} +1 -1
  46. package/dist/gateway/static/root/assets/{remote-access-hub-DYUBreXP.js → remote-access-hub-BGaVc3t7.js} +1 -1
  47. package/dist/gateway/static/root/assets/{save-bar-controls-C1Rb4FUZ.js → save-bar-controls-BRxlkhG8.js} +1 -1
  48. package/dist/gateway/static/root/assets/{schedule-field-Fjw3-jca.js → schedule-field-BzM1iyOc.js} +1 -1
  49. package/dist/gateway/static/root/assets/{schema-form-B3mv0qnM.js → schema-form-ChVcm0DX.js} +1 -1
  50. package/dist/gateway/static/root/assets/{sessions-page-DROyxOSO.js → sessions-page-DbnzgQOP.js} +1 -1
  51. package/dist/gateway/static/root/assets/settings-advanced-gate-CuDBoz5k.js +1 -0
  52. package/dist/gateway/static/root/assets/{settings-collapsible-section-TNRY46vl.js → settings-collapsible-section-BcD9xrvY.js} +1 -1
  53. package/dist/gateway/static/root/assets/{settings-form-section-SlP81d-d.js → settings-form-section-Cu30CXVl.js} +1 -1
  54. package/dist/gateway/static/root/assets/{settings-loading-skeleton-hhP-2fj4.js → settings-loading-skeleton-Cfd37IYb.js} +1 -1
  55. package/dist/gateway/static/root/assets/{settings-page-B064FDr_.js → settings-page-EINHyzLo.js} +1 -1
  56. package/dist/gateway/static/root/assets/{settings-page-layout-CLxmpeP0.js → settings-page-layout-C15zixct.js} +1 -1
  57. package/dist/gateway/static/root/assets/{setup-status-panel-D2vFjWe1.js → setup-status-panel-Bu7SdpD4.js} +1 -1
  58. package/dist/gateway/static/root/assets/{share-preview-page-CFKOGhyl.js → share-preview-page-CjjAFV-v.js} +1 -1
  59. package/dist/gateway/static/root/assets/{shares-settings-B8Yx9E_Z.js → shares-settings-06IYvwDt.js} +1 -1
  60. package/dist/gateway/static/root/assets/skill-reload-api-0ODH0DXl.js +1 -0
  61. package/dist/gateway/static/root/assets/{skills-page-C23qF1by.js → skills-page-3W2-wDyO.js} +1 -1
  62. package/dist/gateway/static/root/assets/{system-settings-panel-CA97ApVu.js → system-settings-panel-DlQMtzPf.js} +1 -1
  63. package/dist/gateway/static/root/assets/{typed-models-lib-D2qodBzJ.js → typed-models-lib-BS1BwExE.js} +1 -1
  64. package/dist/gateway/static/root/assets/{user-profile-settings-panel-BRfmfG5A.js → user-profile-settings-panel-B7RCdmSp.js} +1 -1
  65. package/dist/gateway/static/root/assets/{utils-ClF36Dfd.js → utils-BrhEgVaa.js} +1 -1
  66. package/dist/gateway/static/root/assets/{voice-api-key-field-DBy_63L1.js → voice-api-key-field-BPn1ZEga.js} +1 -1
  67. package/dist/gateway/static/root/assets/{work-item-detail-page-DiZzNQOW.js → work-item-detail-page-BQGTTsz1.js} +1 -1
  68. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BVC8Pt1v.js → workflow-run-setup-panel-na-N4jZ6.js} +1 -1
  69. package/dist/gateway/static/root/assets/{workflow-start-dialog-B2ErVQ-D.js → workflow-start-dialog-BZCY7N42.js} +1 -1
  70. package/dist/gateway/static/root/assets/{workflows-page-VmWTqyyW.js → workflows-page-CjeVDs4h.js} +1 -1
  71. package/dist/gateway/static/root/index.html +1 -1
  72. package/dist/package.js +1 -1
  73. package/dist/src/agent/code-intelligence/binary.d.ts +4 -3
  74. package/dist/src/agent/code-intelligence/binary.js +215 -34
  75. package/dist/src/agent/code-intelligence/binary.js.map +1 -1
  76. package/dist/src/config/agent-profile.js +1 -1
  77. package/dist/src/gateway/agents-admin.js +1 -1
  78. package/package.json +1 -1
  79. package/dist/gateway/static/root/assets/settings-advanced-gate-Cir7UEDe.js +0 -1
  80. package/dist/gateway/static/root/assets/skill-reload-api-loLlXXAj.js +0 -1
@@ -1,15 +1,16 @@
1
1
  import { resolveStateDir } from "../../config/paths-state.js";
2
2
  import { createLogger } from "../../utils/logger/index.js";
3
3
  import { init_logger } from "../../utils/logger.js";
4
- import { init_paths } from "../../config/paths.js";
4
+ import { init_paths, resolveBinDir } from "../../config/paths.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { tmpdir } from "node:os";
7
7
  import { dirname, join, resolve } from "node:path";
8
- import { accessSync, chmodSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, mkdirSync, mkdtempSync, realpathSync, renameSync, rmSync } from "node:fs";
8
+ import { accessSync, chmodSync, constants, copyFileSync, createReadStream, createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
9
9
  import { execFile } from "node:child_process";
10
- import { createHash } from "node:crypto";
10
+ import { createHash, randomBytes } from "node:crypto";
11
11
  import { promisify } from "node:util";
12
12
  import { Readable } from "node:stream";
13
+ import lockfile from "proper-lockfile";
13
14
  import { pipeline } from "node:stream/promises";
14
15
  //#region src/agent/code-intelligence/binary.ts
15
16
  init_paths();
@@ -17,6 +18,7 @@ init_logger();
17
18
  const require = createRequire(import.meta.url);
18
19
  const log = createLogger("CodeIntelligenceBinary");
19
20
  const CBM_VERSION = "0.9.0";
21
+ const CACHE_SCHEMA_VERSION = 1;
20
22
  const DOWNLOAD_TIMEOUT_MS = 2 * 6e4;
21
23
  const RELEASE_BASE_URL = `https://github.com/DeusData/codebase-memory-mcp/releases/download/v${CBM_VERSION}`;
22
24
  const execFileAsync = promisify(execFile);
@@ -38,8 +40,8 @@ function architectureName() {
38
40
  default: throw new Error(`Code intelligence is not supported on ${process.arch}`);
39
41
  }
40
42
  }
41
- function releaseUrl() {
42
- return `${RELEASE_BASE_URL}/${archiveName()}`;
43
+ function platformKey() {
44
+ return `${platformName()}-${architectureName()}`;
43
45
  }
44
46
  function archiveName() {
45
47
  const platform = platformName();
@@ -47,9 +49,36 @@ function archiveName() {
47
49
  const linuxPortable = platform === "linux" ? "-portable" : "";
48
50
  return `codebase-memory-mcp-${platform}-${architectureName()}${linuxPortable}.${extension}`;
49
51
  }
52
+ function releaseUrl() {
53
+ return `${RELEASE_BASE_URL}/${archiveName()}`;
54
+ }
50
55
  function archiveExtension() {
51
56
  return platformName() === "windows" ? "zip" : "tar.gz";
52
57
  }
58
+ function cacheVersionRoot() {
59
+ return join(resolveBinDir(), "codebase-memory-mcp", `v${CBM_VERSION}`);
60
+ }
61
+ function cacheDir() {
62
+ return join(cacheVersionRoot(), platformKey());
63
+ }
64
+ function cacheBinaryPath() {
65
+ return join(cacheDir(), binaryName());
66
+ }
67
+ function cacheManifestPath(dir = cacheDir()) {
68
+ return join(dir, "manifest.json");
69
+ }
70
+ function legacyManagedBinaryPath() {
71
+ return join(resolveStateDir(), "code-intelligence", "bin", `v${CBM_VERSION}`, platformKey(), binaryName());
72
+ }
73
+ function isUsableBinary(path) {
74
+ if (!existsSync(path)) return false;
75
+ try {
76
+ accessSync(path, process.platform === "win32" ? constants.F_OK : constants.X_OK);
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
53
82
  function expectedSha256(checksums, filename) {
54
83
  for (const line of checksums.split(/\r?\n/)) {
55
84
  const match = /^([a-f0-9]{64})\s+\*?(.+)$/i.exec(line.trim());
@@ -67,16 +96,33 @@ async function sha256(path) {
67
96
  });
68
97
  return hash.digest("hex");
69
98
  }
70
- function managedBinaryPath(stateDir = resolveStateDir()) {
71
- return join(stateDir, "code-intelligence", "bin", `v${CBM_VERSION}`, `${platformName()}-${architectureName()}`, binaryName());
99
+ function readManagedManifest(dir = cacheDir()) {
100
+ try {
101
+ const parsed = JSON.parse(readFileSync(cacheManifestPath(dir), "utf8"));
102
+ if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION || parsed.component !== "codebase-memory-mcp" || parsed.cbmVersion !== CBM_VERSION || parsed.platform !== platformName() || parsed.arch !== architectureName() || parsed.binaryName !== binaryName() || typeof parsed.binarySha256 !== "string" || typeof parsed.binarySize !== "number") return;
103
+ return parsed;
104
+ } catch {
105
+ return;
106
+ }
72
107
  }
73
- function isUsableBinary(path) {
74
- if (!existsSync(path)) return false;
108
+ function resolveSharedCachedBinary() {
109
+ const binary = cacheBinaryPath();
110
+ const manifest = readManagedManifest();
111
+ if (!manifest || !isUsableBinary(binary)) return void 0;
75
112
  try {
76
- accessSync(path, process.platform === "win32" ? constants.F_OK : constants.X_OK);
77
- return true;
113
+ return statSync(binary).size === manifest.binarySize ? realpathSync(binary) : void 0;
78
114
  } catch {
79
- return false;
115
+ return;
116
+ }
117
+ }
118
+ async function verifySharedCachedBinary() {
119
+ const binary = resolveSharedCachedBinary();
120
+ const manifest = readManagedManifest();
121
+ if (!binary || !manifest) return void 0;
122
+ try {
123
+ return await sha256(binary) === manifest.binarySha256 ? binary : void 0;
124
+ } catch {
125
+ return;
80
126
  }
81
127
  }
82
128
  function packageBinaryPath() {
@@ -86,21 +132,139 @@ function packageBinaryPath() {
86
132
  return;
87
133
  }
88
134
  }
89
- function resolveCodebaseMemoryBinary(explicitPath) {
90
- const resourcesPath = process.resourcesPath;
91
- const candidates = [
92
- explicitPath,
93
- process.env.XOPC_CBM_BINARY,
94
- resourcesPath ? join(resourcesPath, "bin", binaryName()) : void 0,
95
- packageBinaryPath()
96
- ].filter((value) => Boolean(value?.trim()));
97
- for (const candidate of candidates) {
135
+ function overrideBinaryPath(explicitPath) {
136
+ for (const candidate of [explicitPath, process.env.XOPC_CBM_BINARY]) {
137
+ if (!candidate?.trim()) continue;
98
138
  const absolute = resolve(candidate);
99
139
  if (isUsableBinary(absolute)) return realpathSync(absolute);
100
140
  }
101
- throw new Error(`codebase-memory-mcp binary is unavailable; checked ${candidates.join(", ") || "no candidate paths"}`);
102
141
  }
103
- /** Download the CBM executable into its final path atomically. */
142
+ function bundledBinaryCandidates() {
143
+ const bundledPath = process.env.XOPC_CBM_BUNDLED_PATH?.trim();
144
+ const bundledManifestPath = process.env.XOPC_CBM_BUNDLED_MANIFEST_PATH?.trim();
145
+ const resourcesPath = process.resourcesPath;
146
+ const resourcePath = resourcesPath ? join(resourcesPath, "bin", binaryName()) : void 0;
147
+ const packagePath = packageBinaryPath();
148
+ const candidates = [];
149
+ if (bundledPath) candidates.push({
150
+ path: bundledPath,
151
+ source: "electron-bundle",
152
+ manifestPath: bundledManifestPath || join(dirname(bundledPath), "codebase-memory-mcp.manifest.json")
153
+ });
154
+ if (resourcePath && resourcePath !== bundledPath) candidates.push({
155
+ path: resourcePath,
156
+ source: "electron-bundle",
157
+ manifestPath: join(dirname(resourcePath), "codebase-memory-mcp.manifest.json")
158
+ });
159
+ if (packagePath) candidates.push({
160
+ path: packagePath,
161
+ source: "package-bundle"
162
+ });
163
+ candidates.push({
164
+ path: legacyManagedBinaryPath(),
165
+ source: "legacy-cache"
166
+ });
167
+ return candidates;
168
+ }
169
+ async function verifyBundledSource(candidate) {
170
+ if (!isUsableBinary(candidate.path)) throw new Error(`source binary is unavailable at ${candidate.path}`);
171
+ if (candidate.source !== "electron-bundle") return;
172
+ if (!candidate.manifestPath) throw new Error("Electron CBM manifest path is missing");
173
+ let manifest;
174
+ try {
175
+ manifest = JSON.parse(readFileSync(candidate.manifestPath, "utf8"));
176
+ } catch (error) {
177
+ throw new Error(`Electron CBM manifest is unreadable: ${error instanceof Error ? error.message : String(error)}`);
178
+ }
179
+ if (manifest.cbmVersion !== CBM_VERSION || manifest.platform !== platformName() || manifest.arch !== architectureName() || !/^[a-f0-9]{64}$/i.test(manifest.binarySha256)) throw new Error("Electron CBM manifest does not match this runtime");
180
+ const actual = await sha256(candidate.path);
181
+ if (actual !== manifest.binarySha256.toLowerCase()) throw new Error(`Electron CBM checksum mismatch: expected ${manifest.binarySha256}, got ${actual}`);
182
+ }
183
+ async function withCacheLock(fn) {
184
+ const versionRoot = cacheVersionRoot();
185
+ mkdirSync(versionRoot, { recursive: true });
186
+ const release = await lockfile.lock(versionRoot, {
187
+ realpath: false,
188
+ lockfilePath: join(versionRoot, `.${platformKey()}.install.lock`),
189
+ stale: 10 * 6e4,
190
+ retries: {
191
+ retries: 30,
192
+ factor: 1.2,
193
+ minTimeout: 100,
194
+ maxTimeout: 1e3
195
+ }
196
+ });
197
+ try {
198
+ return await fn();
199
+ } finally {
200
+ await release();
201
+ }
202
+ }
203
+ function cleanupStaleStaging(versionRoot) {
204
+ const prefix = `.${platformKey()}.staging-`;
205
+ const cutoff = Date.now() - 60 * 6e4;
206
+ try {
207
+ for (const entry of readdirSync(versionRoot)) {
208
+ if (!entry.startsWith(prefix)) continue;
209
+ const path = join(versionRoot, entry);
210
+ if (statSync(path).mtimeMs < cutoff) rmSync(path, {
211
+ recursive: true,
212
+ force: true
213
+ });
214
+ }
215
+ } catch {}
216
+ }
217
+ async function installInSharedCache(source, populate) {
218
+ const versionRoot = cacheVersionRoot();
219
+ const targetDir = cacheDir();
220
+ const stagingDir = join(versionRoot, `.${platformKey()}.staging-${process.pid}-${randomBytes(6).toString("hex")}`);
221
+ const stagingBinary = join(stagingDir, binaryName());
222
+ mkdirSync(stagingDir, { recursive: true });
223
+ try {
224
+ await populate(stagingBinary);
225
+ if (!isUsableBinary(stagingBinary)) throw new Error("staged codebase-memory-mcp binary is not executable");
226
+ if (process.platform !== "win32") chmodSync(stagingBinary, 493);
227
+ const binarySha256 = await sha256(stagingBinary);
228
+ const manifest = {
229
+ schemaVersion: CACHE_SCHEMA_VERSION,
230
+ component: "codebase-memory-mcp",
231
+ cbmVersion: CBM_VERSION,
232
+ platform: platformName(),
233
+ arch: architectureName(),
234
+ binaryName: binaryName(),
235
+ binarySha256,
236
+ binarySize: statSync(stagingBinary).size,
237
+ source,
238
+ installedAt: (/* @__PURE__ */ new Date()).toISOString()
239
+ };
240
+ writeFileSync(cacheManifestPath(stagingDir), `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
241
+ rmSync(targetDir, {
242
+ recursive: true,
243
+ force: true
244
+ });
245
+ renameSync(stagingDir, targetDir);
246
+ return realpathSync(cacheBinaryPath());
247
+ } catch (error) {
248
+ rmSync(stagingDir, {
249
+ recursive: true,
250
+ force: true
251
+ });
252
+ throw error;
253
+ }
254
+ }
255
+ /** Resolve an explicit, shared, or bundled binary synchronously when already present. */
256
+ function resolveCodebaseMemoryBinary(explicitPath) {
257
+ const overridden = overrideBinaryPath(explicitPath);
258
+ if (overridden) return overridden;
259
+ const shared = resolveSharedCachedBinary();
260
+ if (shared) return shared;
261
+ for (const candidate of bundledBinaryCandidates()) {
262
+ const absolute = resolve(candidate.path);
263
+ if (isUsableBinary(absolute)) return realpathSync(absolute);
264
+ }
265
+ throw new Error("codebase-memory-mcp binary is unavailable");
266
+ }
267
+ /** Download and checksum-verify the CBM executable into a caller-provided path. */
104
268
  async function downloadCodebaseMemoryBinary(destination, options = {}) {
105
269
  const fetchImplementation = options.fetchImplementation ?? fetch;
106
270
  const timeoutMs = options.timeoutMs ?? DOWNLOAD_TIMEOUT_MS;
@@ -170,22 +334,39 @@ async function downloadCodebaseMemoryBinary(destination, options = {}) {
170
334
  }
171
335
  }
172
336
  /**
173
- * Resolve a bundled or explicit binary first, then lazily download one for npm installs.
174
- * This deliberately keeps large GitHub Release downloads out of npm lifecycle scripts.
337
+ * Resolve a shared, versioned user cache. Electron seeds it from its bundled binary;
338
+ * CLI seeds it from a verified release download. This keeps both surfaces on one binary.
175
339
  */
176
340
  async function ensureCodebaseMemoryBinary(explicitPath) {
177
- try {
178
- return resolveCodebaseMemoryBinary(explicitPath);
179
- } catch {
180
- const destination = managedBinaryPath();
181
- if (isUsableBinary(destination)) return realpathSync(destination);
341
+ const overridden = overrideBinaryPath(explicitPath);
342
+ if (overridden) return overridden;
343
+ const cached = await verifySharedCachedBinary();
344
+ if (cached) return cached;
345
+ return withCacheLock(async () => {
346
+ cleanupStaleStaging(cacheVersionRoot());
347
+ const afterLock = await verifySharedCachedBinary();
348
+ if (afterLock) return afterLock;
349
+ for (const candidate of bundledBinaryCandidates()) try {
350
+ await verifyBundledSource(candidate);
351
+ return await installInSharedCache(candidate.source, async (destination) => {
352
+ copyFileSync(candidate.path, destination);
353
+ });
354
+ } catch (error) {
355
+ log.warn({
356
+ err: error,
357
+ source: candidate.source,
358
+ path: candidate.path
359
+ }, "Code intelligence binary source was not usable");
360
+ }
182
361
  log.info({
183
- destination,
362
+ destination: cacheBinaryPath(),
184
363
  version: CBM_VERSION,
185
364
  timeoutMs: DOWNLOAD_TIMEOUT_MS
186
- }, "Downloading code intelligence binary on demand");
187
- return downloadCodebaseMemoryBinary(destination);
188
- }
365
+ }, "Downloading code intelligence binary into shared cache");
366
+ return installInSharedCache("github-release", async (destination) => {
367
+ await downloadCodebaseMemoryBinary(destination);
368
+ });
369
+ });
189
370
  }
190
371
  //#endregion
191
372
  export { downloadCodebaseMemoryBinary, ensureCodebaseMemoryBinary, resolveCodebaseMemoryBinary };
@@ -1 +1 @@
1
- {"version":3,"file":"binary.js","names":[],"sources":["../../../../src/agent/code-intelligence/binary.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport {\n accessSync,\n chmodSync,\n constants,\n copyFileSync,\n createReadStream,\n createWriteStream,\n existsSync,\n mkdirSync,\n mkdtempSync,\n realpathSync,\n renameSync,\n rmSync,\n} from 'node:fs';\nimport { execFile } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport { tmpdir } from 'node:os';\nimport { pipeline } from 'node:stream/promises';\nimport { Readable } from 'node:stream';\nimport { dirname, join, resolve } from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\nconst log = createLogger('CodeIntelligenceBinary');\n\nconst CBM_VERSION = '0.9.0';\nconst DOWNLOAD_TIMEOUT_MS = 2 * 60_000;\nconst RELEASE_BASE_URL = `https://github.com/DeusData/codebase-memory-mcp/releases/download/v${CBM_VERSION}`;\nconst execFileAsync = promisify(execFile);\n\ntype FetchImplementation = typeof fetch;\n\nexport interface DownloadCodebaseMemoryBinaryOptions {\n fetchImplementation?: FetchImplementation;\n timeoutMs?: number;\n}\n\nfunction binaryName(): string {\n return process.platform === 'win32' ? 'codebase-memory-mcp.exe' : 'codebase-memory-mcp';\n}\n\nfunction platformName(): string {\n switch (process.platform) {\n case 'darwin':\n return 'darwin';\n case 'linux':\n return 'linux';\n case 'win32':\n return 'windows';\n default:\n throw new Error(`Code intelligence is not supported on ${process.platform}`);\n }\n}\n\nfunction architectureName(): string {\n switch (process.arch) {\n case 'arm64':\n return 'arm64';\n case 'x64':\n return 'amd64';\n default:\n throw new Error(`Code intelligence is not supported on ${process.arch}`);\n }\n}\n\nfunction releaseUrl(): string {\n return `${RELEASE_BASE_URL}/${archiveName()}`;\n}\n\nfunction archiveName(): string {\n const platform = platformName();\n const extension = platform === 'windows' ? 'zip' : 'tar.gz';\n const linuxPortable = platform === 'linux' ? '-portable' : '';\n return `codebase-memory-mcp-${platform}-${architectureName()}${linuxPortable}.${extension}`;\n}\n\nfunction archiveExtension(): 'zip' | 'tar.gz' {\n return platformName() === 'windows' ? 'zip' : 'tar.gz';\n}\n\nfunction expectedSha256(checksums: string, filename: string): string {\n for (const line of checksums.split(/\\r?\\n/)) {\n const match = /^([a-f0-9]{64})\\s+\\*?(.+)$/i.exec(line.trim());\n if (match?.[2] === filename) return match[1].toLowerCase();\n }\n throw new Error(`checksums.txt does not contain ${filename}`);\n}\n\nasync function sha256(path: string): Promise<string> {\n const hash = createHash('sha256');\n await new Promise<void>((resolvePromise, reject) => {\n const input = createReadStream(path);\n input.on('data', (chunk: Buffer) => hash.update(chunk));\n input.once('error', reject);\n input.once('end', resolvePromise);\n });\n return hash.digest('hex');\n}\n\nfunction managedBinaryPath(stateDir = resolveStateDir()): string {\n return join(\n stateDir,\n 'code-intelligence',\n 'bin',\n `v${CBM_VERSION}`,\n `${platformName()}-${architectureName()}`,\n binaryName(),\n );\n}\n\nfunction isUsableBinary(path: string): boolean {\n if (!existsSync(path)) return false;\n try {\n accessSync(path, process.platform === 'win32' ? constants.F_OK : constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction packageBinaryPath(): string | undefined {\n try {\n const packageJson = require.resolve('codebase-memory-mcp/package.json');\n return join(dirname(packageJson), 'bin', binaryName());\n } catch {\n return undefined;\n }\n}\n\nexport function resolveCodebaseMemoryBinary(explicitPath?: string): string {\n const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath;\n const candidates = [\n explicitPath,\n process.env.XOPC_CBM_BINARY,\n resourcesPath ? join(resourcesPath, 'bin', binaryName()) : undefined,\n packageBinaryPath(),\n ].filter((value): value is string => Boolean(value?.trim()));\n\n for (const candidate of candidates) {\n const absolute = resolve(candidate);\n if (isUsableBinary(absolute)) {\n return realpathSync(absolute);\n }\n }\n\n throw new Error(\n `codebase-memory-mcp binary is unavailable; checked ${candidates.join(', ') || 'no candidate paths'}`,\n );\n}\n\n/** Download the CBM executable into its final path atomically. */\nexport async function downloadCodebaseMemoryBinary(\n destination: string,\n options: DownloadCodebaseMemoryBinaryOptions = {},\n): Promise<string> {\n const fetchImplementation = options.fetchImplementation ?? fetch;\n const timeoutMs = options.timeoutMs ?? DOWNLOAD_TIMEOUT_MS;\n const temporaryPath = `${destination}.${process.pid}.part`;\n const abortController = new AbortController();\n const tempDir = mkdtempSync(join(tmpdir(), 'xopc-cbm-'));\n const archivePath = join(tempDir, `cbm.${archiveExtension()}`);\n let timedOut = false;\n let rejectTimeout: ((error: Error) => void) | undefined;\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n rejectTimeout = reject;\n });\n const timer = setTimeout(() => {\n timedOut = true;\n abortController.abort();\n rejectTimeout?.(new Error(`download timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n mkdirSync(dirname(destination), { recursive: true });\n rmSync(temporaryPath, { force: true });\n await Promise.race([\n (async () => {\n const checksumsResponse = await fetchImplementation(`${RELEASE_BASE_URL}/checksums.txt`, {\n redirect: 'follow',\n signal: abortController.signal,\n });\n if (!checksumsResponse.ok) {\n throw new Error(`GitHub Releases returned HTTP ${checksumsResponse.status} for checksums.txt`);\n }\n const expectedChecksum = expectedSha256(await checksumsResponse.text(), archiveName());\n const response = await fetchImplementation(releaseUrl(), {\n redirect: 'follow',\n signal: abortController.signal,\n });\n if (!response.ok) {\n throw new Error(`GitHub Releases returned HTTP ${response.status}`);\n }\n if (!response.body) {\n throw new Error('GitHub Releases returned an empty response body');\n }\n\n await pipeline(\n Readable.fromWeb(response.body as import('node:stream/web').ReadableStream),\n createWriteStream(archivePath, { mode: 0o600 }),\n );\n const actualChecksum = await sha256(archivePath);\n if (actualChecksum !== expectedChecksum) {\n throw new Error(\n `checksum mismatch for ${archiveName()}: expected ${expectedChecksum}, got ${actualChecksum}`,\n );\n }\n if (archiveExtension() === 'tar.gz') {\n await execFileAsync('tar', ['-xzf', archivePath, '-C', tempDir, '--no-same-owner']);\n } else {\n await execFileAsync('powershell', [\n '-NoProfile',\n '-Command',\n `Expand-Archive -Path '${archivePath}' -DestinationPath '${tempDir}' -Force`,\n ]);\n }\n\n const extracted = join(tempDir, binaryName());\n if (!isUsableBinary(extracted)) {\n throw new Error(`binary was not present after extracting ${archiveExtension()} archive`);\n }\n copyFileSync(extracted, temporaryPath);\n })(),\n timeoutPromise,\n ]);\n if (timedOut) throw new Error(`download timed out after ${timeoutMs}ms`);\n if (process.platform !== 'win32') chmodSync(temporaryPath, 0o755);\n renameSync(temporaryPath, destination);\n return realpathSync(destination);\n } catch (error) {\n const reason = timedOut\n ? `download timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : String(error);\n throw new Error(\n `Unable to download codebase-memory-mcp from GitHub Releases: ${reason}. ` +\n 'Check network access or set XOPC_CBM_BINARY to a trusted executable.',\n );\n } finally {\n clearTimeout(timer);\n rmSync(temporaryPath, { force: true });\n rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Resolve a bundled or explicit binary first, then lazily download one for npm installs.\n * This deliberately keeps large GitHub Release downloads out of npm lifecycle scripts.\n */\nexport async function ensureCodebaseMemoryBinary(explicitPath?: string): Promise<string> {\n try {\n return resolveCodebaseMemoryBinary(explicitPath);\n } catch {\n const destination = managedBinaryPath();\n if (isUsableBinary(destination)) return realpathSync(destination);\n\n log.info(\n { destination, version: CBM_VERSION, timeoutMs: DOWNLOAD_TIMEOUT_MS },\n 'Downloading code intelligence binary on demand',\n );\n return downloadCodebaseMemoryBinary(destination);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"binary.js","names":[],"sources":["../../../../src/agent/code-intelligence/binary.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport { createHash, randomBytes } from 'node:crypto';\nimport {\n accessSync,\n chmodSync,\n constants,\n copyFileSync,\n createReadStream,\n createWriteStream,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { tmpdir } from 'node:os';\nimport { dirname, join, resolve } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { promisify } from 'node:util';\n\nimport lockfile from 'proper-lockfile';\n\nimport { resolveBinDir, resolveStateDir } from '../../config/paths.js';\nimport { createLogger } from '../../utils/logger.js';\n\nconst require = createRequire(import.meta.url);\nconst log = createLogger('CodeIntelligenceBinary');\n\nconst CBM_VERSION = '0.9.0';\nconst CACHE_SCHEMA_VERSION = 1;\nconst DOWNLOAD_TIMEOUT_MS = 2 * 60_000;\nconst RELEASE_BASE_URL = `https://github.com/DeusData/codebase-memory-mcp/releases/download/v${CBM_VERSION}`;\nconst execFileAsync = promisify(execFile);\n\ntype FetchImplementation = typeof fetch;\ntype ManagedBinarySource = 'github-release' | 'electron-bundle' | 'package-bundle' | 'legacy-cache';\n\ninterface ManagedBinaryManifest {\n schemaVersion: number;\n component: 'codebase-memory-mcp';\n cbmVersion: string;\n platform: string;\n arch: string;\n binaryName: string;\n binarySha256: string;\n binarySize: number;\n source: ManagedBinarySource;\n installedAt: string;\n}\n\ninterface BundledBinaryManifest {\n cbmVersion: string;\n platform: string;\n arch: string;\n binarySha256: string;\n}\n\ninterface BinarySourceCandidate {\n path: string;\n source: Exclude<ManagedBinarySource, 'github-release'>;\n manifestPath?: string;\n}\n\nexport interface DownloadCodebaseMemoryBinaryOptions {\n fetchImplementation?: FetchImplementation;\n timeoutMs?: number;\n}\n\nfunction binaryName(): string {\n return process.platform === 'win32' ? 'codebase-memory-mcp.exe' : 'codebase-memory-mcp';\n}\n\nfunction platformName(): string {\n switch (process.platform) {\n case 'darwin':\n return 'darwin';\n case 'linux':\n return 'linux';\n case 'win32':\n return 'windows';\n default:\n throw new Error(`Code intelligence is not supported on ${process.platform}`);\n }\n}\n\nfunction architectureName(): string {\n switch (process.arch) {\n case 'arm64':\n return 'arm64';\n case 'x64':\n return 'amd64';\n default:\n throw new Error(`Code intelligence is not supported on ${process.arch}`);\n }\n}\n\nfunction platformKey(): string {\n return `${platformName()}-${architectureName()}`;\n}\n\nfunction archiveName(): string {\n const platform = platformName();\n const extension = platform === 'windows' ? 'zip' : 'tar.gz';\n const linuxPortable = platform === 'linux' ? '-portable' : '';\n return `codebase-memory-mcp-${platform}-${architectureName()}${linuxPortable}.${extension}`;\n}\n\nfunction releaseUrl(): string {\n return `${RELEASE_BASE_URL}/${archiveName()}`;\n}\n\nfunction archiveExtension(): 'zip' | 'tar.gz' {\n return platformName() === 'windows' ? 'zip' : 'tar.gz';\n}\n\nfunction cacheVersionRoot(): string {\n return join(resolveBinDir(), 'codebase-memory-mcp', `v${CBM_VERSION}`);\n}\n\nfunction cacheDir(): string {\n return join(cacheVersionRoot(), platformKey());\n}\n\nfunction cacheBinaryPath(): string {\n return join(cacheDir(), binaryName());\n}\n\nfunction cacheManifestPath(dir = cacheDir()): string {\n return join(dir, 'manifest.json');\n}\n\nfunction legacyManagedBinaryPath(): string {\n return join(\n resolveStateDir(),\n 'code-intelligence',\n 'bin',\n `v${CBM_VERSION}`,\n platformKey(),\n binaryName(),\n );\n}\n\nfunction isUsableBinary(path: string): boolean {\n if (!existsSync(path)) return false;\n try {\n accessSync(path, process.platform === 'win32' ? constants.F_OK : constants.X_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction expectedSha256(checksums: string, filename: string): string {\n for (const line of checksums.split(/\\r?\\n/)) {\n const match = /^([a-f0-9]{64})\\s+\\*?(.+)$/i.exec(line.trim());\n if (match?.[2] === filename) return match[1].toLowerCase();\n }\n throw new Error(`checksums.txt does not contain ${filename}`);\n}\n\nasync function sha256(path: string): Promise<string> {\n const hash = createHash('sha256');\n await new Promise<void>((resolvePromise, reject) => {\n const input = createReadStream(path);\n input.on('data', (chunk: Buffer) => hash.update(chunk));\n input.once('error', reject);\n input.once('end', resolvePromise);\n });\n return hash.digest('hex');\n}\n\nfunction readManagedManifest(dir = cacheDir()): ManagedBinaryManifest | undefined {\n try {\n const parsed = JSON.parse(readFileSync(cacheManifestPath(dir), 'utf8')) as Partial<ManagedBinaryManifest>;\n if (\n parsed.schemaVersion !== CACHE_SCHEMA_VERSION ||\n parsed.component !== 'codebase-memory-mcp' ||\n parsed.cbmVersion !== CBM_VERSION ||\n parsed.platform !== platformName() ||\n parsed.arch !== architectureName() ||\n parsed.binaryName !== binaryName() ||\n typeof parsed.binarySha256 !== 'string' ||\n typeof parsed.binarySize !== 'number'\n ) {\n return undefined;\n }\n return parsed as ManagedBinaryManifest;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveSharedCachedBinary(): string | undefined {\n const binary = cacheBinaryPath();\n const manifest = readManagedManifest();\n if (!manifest || !isUsableBinary(binary)) return undefined;\n try {\n return statSync(binary).size === manifest.binarySize ? realpathSync(binary) : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function verifySharedCachedBinary(): Promise<string | undefined> {\n const binary = resolveSharedCachedBinary();\n const manifest = readManagedManifest();\n if (!binary || !manifest) return undefined;\n try {\n return (await sha256(binary)) === manifest.binarySha256 ? binary : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction packageBinaryPath(): string | undefined {\n try {\n const packageJson = require.resolve('codebase-memory-mcp/package.json');\n return join(dirname(packageJson), 'bin', binaryName());\n } catch {\n return undefined;\n }\n}\n\nfunction overrideBinaryPath(explicitPath?: string): string | undefined {\n for (const candidate of [explicitPath, process.env.XOPC_CBM_BINARY]) {\n if (!candidate?.trim()) continue;\n const absolute = resolve(candidate);\n if (isUsableBinary(absolute)) return realpathSync(absolute);\n }\n return undefined;\n}\n\nfunction bundledBinaryCandidates(): BinarySourceCandidate[] {\n const bundledPath = process.env.XOPC_CBM_BUNDLED_PATH?.trim();\n const bundledManifestPath = process.env.XOPC_CBM_BUNDLED_MANIFEST_PATH?.trim();\n const resourcesPath = (process as NodeJS.Process & { resourcesPath?: string }).resourcesPath;\n const resourcePath = resourcesPath ? join(resourcesPath, 'bin', binaryName()) : undefined;\n const packagePath = packageBinaryPath();\n const candidates: BinarySourceCandidate[] = [];\n\n if (bundledPath) {\n candidates.push({\n path: bundledPath,\n source: 'electron-bundle',\n manifestPath: bundledManifestPath || join(dirname(bundledPath), 'codebase-memory-mcp.manifest.json'),\n });\n }\n if (resourcePath && resourcePath !== bundledPath) {\n candidates.push({\n path: resourcePath,\n source: 'electron-bundle',\n manifestPath: join(dirname(resourcePath), 'codebase-memory-mcp.manifest.json'),\n });\n }\n if (packagePath) candidates.push({ path: packagePath, source: 'package-bundle' });\n candidates.push({ path: legacyManagedBinaryPath(), source: 'legacy-cache' });\n return candidates;\n}\n\nasync function verifyBundledSource(candidate: BinarySourceCandidate): Promise<void> {\n if (!isUsableBinary(candidate.path)) {\n throw new Error(`source binary is unavailable at ${candidate.path}`);\n }\n if (candidate.source !== 'electron-bundle') return;\n if (!candidate.manifestPath) throw new Error('Electron CBM manifest path is missing');\n\n let manifest: BundledBinaryManifest;\n try {\n manifest = JSON.parse(readFileSync(candidate.manifestPath, 'utf8')) as BundledBinaryManifest;\n } catch (error) {\n throw new Error(\n `Electron CBM manifest is unreadable: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n if (\n manifest.cbmVersion !== CBM_VERSION ||\n manifest.platform !== platformName() ||\n manifest.arch !== architectureName() ||\n !/^[a-f0-9]{64}$/i.test(manifest.binarySha256)\n ) {\n throw new Error('Electron CBM manifest does not match this runtime');\n }\n const actual = await sha256(candidate.path);\n if (actual !== manifest.binarySha256.toLowerCase()) {\n throw new Error(`Electron CBM checksum mismatch: expected ${manifest.binarySha256}, got ${actual}`);\n }\n}\n\nasync function withCacheLock<T>(fn: () => Promise<T>): Promise<T> {\n const versionRoot = cacheVersionRoot();\n mkdirSync(versionRoot, { recursive: true });\n const release = await lockfile.lock(versionRoot, {\n realpath: false,\n lockfilePath: join(versionRoot, `.${platformKey()}.install.lock`),\n stale: 10 * 60_000,\n retries: { retries: 30, factor: 1.2, minTimeout: 100, maxTimeout: 1_000 },\n });\n try {\n return await fn();\n } finally {\n await release();\n }\n}\n\nfunction cleanupStaleStaging(versionRoot: string): void {\n const prefix = `.${platformKey()}.staging-`;\n const cutoff = Date.now() - 60 * 60_000;\n try {\n for (const entry of readdirSync(versionRoot)) {\n if (!entry.startsWith(prefix)) continue;\n const path = join(versionRoot, entry);\n if (statSync(path).mtimeMs < cutoff) rmSync(path, { recursive: true, force: true });\n }\n } catch {\n // Best-effort cleanup; installation remains safe under the cache lock.\n }\n}\n\nasync function installInSharedCache(\n source: ManagedBinarySource,\n populate: (destination: string) => Promise<void>,\n): Promise<string> {\n const versionRoot = cacheVersionRoot();\n const targetDir = cacheDir();\n const stagingDir = join(versionRoot, `.${platformKey()}.staging-${process.pid}-${randomBytes(6).toString('hex')}`);\n const stagingBinary = join(stagingDir, binaryName());\n mkdirSync(stagingDir, { recursive: true });\n\n try {\n await populate(stagingBinary);\n if (!isUsableBinary(stagingBinary)) {\n throw new Error('staged codebase-memory-mcp binary is not executable');\n }\n if (process.platform !== 'win32') chmodSync(stagingBinary, 0o755);\n const binarySha256 = await sha256(stagingBinary);\n const manifest: ManagedBinaryManifest = {\n schemaVersion: CACHE_SCHEMA_VERSION,\n component: 'codebase-memory-mcp',\n cbmVersion: CBM_VERSION,\n platform: platformName(),\n arch: architectureName(),\n binaryName: binaryName(),\n binarySha256,\n binarySize: statSync(stagingBinary).size,\n source,\n installedAt: new Date().toISOString(),\n };\n writeFileSync(cacheManifestPath(stagingDir), `${JSON.stringify(manifest, null, 2)}\\n`, 'utf8');\n\n rmSync(targetDir, { recursive: true, force: true });\n renameSync(stagingDir, targetDir);\n return realpathSync(cacheBinaryPath());\n } catch (error) {\n rmSync(stagingDir, { recursive: true, force: true });\n throw error;\n }\n}\n\n/** Resolve an explicit, shared, or bundled binary synchronously when already present. */\nexport function resolveCodebaseMemoryBinary(explicitPath?: string): string {\n const overridden = overrideBinaryPath(explicitPath);\n if (overridden) return overridden;\n\n const shared = resolveSharedCachedBinary();\n if (shared) return shared;\n\n for (const candidate of bundledBinaryCandidates()) {\n const absolute = resolve(candidate.path);\n if (isUsableBinary(absolute)) return realpathSync(absolute);\n }\n\n throw new Error('codebase-memory-mcp binary is unavailable');\n}\n\n/** Download and checksum-verify the CBM executable into a caller-provided path. */\nexport async function downloadCodebaseMemoryBinary(\n destination: string,\n options: DownloadCodebaseMemoryBinaryOptions = {},\n): Promise<string> {\n const fetchImplementation = options.fetchImplementation ?? fetch;\n const timeoutMs = options.timeoutMs ?? DOWNLOAD_TIMEOUT_MS;\n const temporaryPath = `${destination}.${process.pid}.part`;\n const abortController = new AbortController();\n const tempDir = mkdtempSync(join(tmpdir(), 'xopc-cbm-'));\n const archivePath = join(tempDir, `cbm.${archiveExtension()}`);\n let timedOut = false;\n let rejectTimeout: ((error: Error) => void) | undefined;\n const timeoutPromise = new Promise<never>((_resolve, reject) => {\n rejectTimeout = reject;\n });\n const timer = setTimeout(() => {\n timedOut = true;\n abortController.abort();\n rejectTimeout?.(new Error(`download timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n mkdirSync(dirname(destination), { recursive: true });\n rmSync(temporaryPath, { force: true });\n await Promise.race([\n (async () => {\n const checksumsResponse = await fetchImplementation(`${RELEASE_BASE_URL}/checksums.txt`, {\n redirect: 'follow',\n signal: abortController.signal,\n });\n if (!checksumsResponse.ok) {\n throw new Error(`GitHub Releases returned HTTP ${checksumsResponse.status} for checksums.txt`);\n }\n const expectedChecksum = expectedSha256(await checksumsResponse.text(), archiveName());\n const response = await fetchImplementation(releaseUrl(), {\n redirect: 'follow',\n signal: abortController.signal,\n });\n if (!response.ok) throw new Error(`GitHub Releases returned HTTP ${response.status}`);\n if (!response.body) throw new Error('GitHub Releases returned an empty response body');\n\n await pipeline(\n Readable.fromWeb(response.body as import('node:stream/web').ReadableStream),\n createWriteStream(archivePath, { mode: 0o600 }),\n );\n const actualChecksum = await sha256(archivePath);\n if (actualChecksum !== expectedChecksum) {\n throw new Error(\n `checksum mismatch for ${archiveName()}: expected ${expectedChecksum}, got ${actualChecksum}`,\n );\n }\n if (archiveExtension() === 'tar.gz') {\n await execFileAsync('tar', ['-xzf', archivePath, '-C', tempDir, '--no-same-owner']);\n } else {\n await execFileAsync('powershell', [\n '-NoProfile',\n '-Command',\n `Expand-Archive -Path '${archivePath}' -DestinationPath '${tempDir}' -Force`,\n ]);\n }\n\n const extracted = join(tempDir, binaryName());\n if (!isUsableBinary(extracted)) {\n throw new Error(`binary was not present after extracting ${archiveExtension()} archive`);\n }\n copyFileSync(extracted, temporaryPath);\n })(),\n timeoutPromise,\n ]);\n if (timedOut) throw new Error(`download timed out after ${timeoutMs}ms`);\n if (process.platform !== 'win32') chmodSync(temporaryPath, 0o755);\n renameSync(temporaryPath, destination);\n return realpathSync(destination);\n } catch (error) {\n const reason = timedOut\n ? `download timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : String(error);\n throw new Error(\n `Unable to download codebase-memory-mcp from GitHub Releases: ${reason}. ` +\n 'Check network access or set XOPC_CBM_BINARY to a trusted executable.',\n );\n } finally {\n clearTimeout(timer);\n rmSync(temporaryPath, { force: true });\n rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Resolve a shared, versioned user cache. Electron seeds it from its bundled binary;\n * CLI seeds it from a verified release download. This keeps both surfaces on one binary.\n */\nexport async function ensureCodebaseMemoryBinary(explicitPath?: string): Promise<string> {\n const overridden = overrideBinaryPath(explicitPath);\n if (overridden) return overridden;\n\n const cached = await verifySharedCachedBinary();\n if (cached) return cached;\n\n return withCacheLock(async () => {\n cleanupStaleStaging(cacheVersionRoot());\n const afterLock = await verifySharedCachedBinary();\n if (afterLock) return afterLock;\n\n for (const candidate of bundledBinaryCandidates()) {\n try {\n await verifyBundledSource(candidate);\n return await installInSharedCache(candidate.source, async (destination) => {\n copyFileSync(candidate.path, destination);\n });\n } catch (error) {\n log.warn(\n { err: error, source: candidate.source, path: candidate.path },\n 'Code intelligence binary source was not usable',\n );\n }\n }\n\n log.info(\n { destination: cacheBinaryPath(), version: CBM_VERSION, timeoutMs: DOWNLOAD_TIMEOUT_MS },\n 'Downloading code intelligence binary into shared cache',\n );\n return installInSharedCache('github-release', async (destination) => {\n await downloadCodebaseMemoryBinary(destination);\n });\n });\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
1
2
  import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
3
  import "../agent-manifest/index.js";
3
- import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
4
4
  import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
6
6
  //#region src/config/agent-profile.ts
@@ -1,5 +1,5 @@
1
- import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
+ import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
3
3
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
4
  import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.139",
3
+ "version": "0.0.140",
4
4
  "description": "Local-first AI system that remembers context, coordinates AI, and sustains long-term progress.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -1 +0,0 @@
1
- import{hr as e}from"./index-YWf7ByKE.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};
@@ -1 +0,0 @@
1
- import{n as e}from"./rolldown-runtime-aKtaBQYM.js";import{o as t,t as n}from"./fetch-BID89uCH.js";import{pr as r}from"./index-YWf7ByKE.js";var i=e({reloadSkills:()=>a});async function a(){let e=await n(t(`/api/skills/reload`),{method:`POST`});if(!e.ok)throw Error(await r(e))}export{i as n,a as t};