@cortexkit/magic-context 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +635 -390
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2253,6 +2253,7 @@ __export(exports_data_path, {
2253
2253
  getMagicContextHistorianDir: () => getMagicContextHistorianDir,
2254
2254
  getMagicContextLogPath: () => getMagicContextLogPath,
2255
2255
  getMagicContextStorageDir: () => getMagicContextStorageDir,
2256
+ getMagicContextStorageResolution: () => getMagicContextStorageResolution,
2256
2257
  getMagicContextTempDir: () => getMagicContextTempDir,
2257
2258
  getOpenCodeCacheDir: () => getOpenCodeCacheDir,
2258
2259
  getOpenCodeStorageDir: () => getOpenCodeStorageDir,
@@ -2308,15 +2309,43 @@ function getProjectMagicContextHistorianDir(directory) {
2308
2309
  function getOpenCodeStorageDir() {
2309
2310
  return path.join(getDataDir(), "opencode", "storage");
2310
2311
  }
2311
- function getMagicContextStorageDir() {
2312
- if (!process.env.XDG_DATA_HOME) {
2313
- const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR;
2314
- if (testDataDir) {
2315
- return path.join(testDataDir, "cortexkit", "magic-context");
2312
+ function getMagicContextStorageResolution() {
2313
+ const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR?.trim();
2314
+ if (testDataDir) {
2315
+ const perTestDataHome = process.env.XDG_DATA_HOME?.trim();
2316
+ if (perTestDataHome && path.resolve(perTestDataHome) !== path.resolve(testDataDir)) {
2317
+ return {
2318
+ path: path.join(perTestDataHome, "cortexkit", "magic-context"),
2319
+ source: "test isolation"
2320
+ };
2316
2321
  }
2317
- if (false) {}
2322
+ return {
2323
+ path: path.join(testDataDir, "cortexkit", "magic-context"),
2324
+ source: "test isolation"
2325
+ };
2318
2326
  }
2319
- return path.join(getDataDir(), "cortexkit", "magic-context");
2327
+ if (false) {}
2328
+ const explicitStorageDir = process.env.MAGIC_CONTEXT_STORAGE_DIR?.trim();
2329
+ if (explicitStorageDir) {
2330
+ if (!path.isAbsolute(explicitStorageDir)) {
2331
+ throw new Error("MAGIC_CONTEXT_STORAGE_DIR must be an absolute path");
2332
+ }
2333
+ return { path: explicitStorageDir, source: "environment override" };
2334
+ }
2335
+ const xdgDataHome = process.env.XDG_DATA_HOME?.trim();
2336
+ if (xdgDataHome) {
2337
+ return {
2338
+ path: path.join(xdgDataHome, "cortexkit", "magic-context"),
2339
+ source: "XDG_DATA_HOME"
2340
+ };
2341
+ }
2342
+ return {
2343
+ path: path.join(os.homedir(), ".local", "share", "cortexkit", "magic-context"),
2344
+ source: "platform default"
2345
+ };
2346
+ }
2347
+ function getMagicContextStorageDir() {
2348
+ return getMagicContextStorageResolution().path;
2320
2349
  }
2321
2350
  function getLegacyOpenCodeMagicContextStorageDir() {
2322
2351
  return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
@@ -2333,7 +2362,7 @@ var init_data_path = () => {};
2333
2362
  // src/lib/paths.ts
2334
2363
  import { existsSync as existsSync4, readdirSync, statSync as statSync3 } from "node:fs";
2335
2364
  import { homedir as homedir3 } from "node:os";
2336
- import { delimiter as delimiter2, dirname as dirname2, join as join4, resolve } from "node:path";
2365
+ import { delimiter as delimiter2, dirname as dirname2, join as join4, resolve as resolve2 } from "node:path";
2337
2366
  function getOpenCodeConfigDir() {
2338
2367
  const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
2339
2368
  if (envDir)
@@ -2431,7 +2460,7 @@ function resolveOmpPaths() {
2431
2460
  const configRoot = profile ? join4(baseConfigRoot, "profiles", profile) : baseConfigRoot;
2432
2461
  const defaultAgentDir = join4(configRoot, "agent");
2433
2462
  const override = profile ? undefined : process.env.PI_CODING_AGENT_DIR?.trim();
2434
- const agentDir = override ? resolve(override) : defaultAgentDir;
2463
+ const agentDir = override ? resolve2(override) : defaultAgentDir;
2435
2464
  const canUseXdg = (process.platform === "linux" || process.platform === "darwin") && agentDir === defaultAgentDir;
2436
2465
  let dataRoot = configRoot;
2437
2466
  if (canUseXdg) {
@@ -2469,18 +2498,18 @@ function getOmpPackageDir() {
2469
2498
  if (value === "~")
2470
2499
  return envFirstHomeDir();
2471
2500
  if (value.startsWith("~/") || value.startsWith("~\\")) {
2472
- return resolve(envFirstHomeDir(), value.slice(2));
2501
+ return resolve2(envFirstHomeDir(), value.slice(2));
2473
2502
  }
2474
- return resolve(value);
2503
+ return resolve2(value);
2475
2504
  }
2476
2505
  function getOmpNonGlobalConfigSources(cwd = process.cwd()) {
2477
2506
  const sources = process.env.PI_CONFIG_FILES?.split(delimiter2).map((entry) => entry.trim()).filter(Boolean).map((entry) => {
2478
2507
  if (entry === "~")
2479
2508
  return envFirstHomeDir();
2480
2509
  const expanded = entry.startsWith("~/") || entry.startsWith("~\\") ? join4(envFirstHomeDir(), entry.slice(2)) : entry;
2481
- return resolve(cwd, expanded);
2510
+ return resolve2(cwd, expanded);
2482
2511
  }) ?? [];
2483
- const projectConfig = resolve(cwd, ".omp", "config.yml");
2512
+ const projectConfig = resolve2(cwd, ".omp", "config.yml");
2484
2513
  if (existsSync4(projectConfig))
2485
2514
  sources.push(projectConfig);
2486
2515
  return [...new Set(sources)];
@@ -10959,7 +10988,7 @@ var init_opencode_plugin_cache = __esm(() => {
10959
10988
 
10960
10989
  // src/adapters/opencode.ts
10961
10990
  import { existsSync as existsSync8, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
10962
- import { dirname as dirname4, isAbsolute as isAbsolute2, parse as parsePath, resolve as resolve2 } from "node:path";
10991
+ import { dirname as dirname4, isAbsolute as isAbsolute3, parse as parsePath, resolve as resolve3 } from "node:path";
10963
10992
  import { fileURLToPath } from "node:url";
10964
10993
 
10965
10994
  class OpenCodeAdapter {
@@ -11157,7 +11186,7 @@ function isLocalPathPluginEntry(entry) {
11157
11186
  const candidate = typeof entry === "string" ? entry : Array.isArray(entry) && typeof entry[0] === "string" ? entry[0] : null;
11158
11187
  if (!candidate)
11159
11188
  return false;
11160
- return candidate.startsWith("file://") || isAbsolute2(candidate) || candidate.startsWith("./") || candidate.startsWith("../");
11189
+ return candidate.startsWith("file://") || isAbsolute3(candidate) || candidate.startsWith("./") || candidate.startsWith("../");
11161
11190
  }
11162
11191
  function isDevPathPluginEntry(entry) {
11163
11192
  const candidate = typeof entry === "string" ? entry : Array.isArray(entry) && typeof entry[0] === "string" ? entry[0] : null;
@@ -11168,13 +11197,13 @@ function isDevPathPluginEntry(entry) {
11168
11197
  if (candidate.startsWith("file://")) {
11169
11198
  localPath = fileURLToPath(candidate);
11170
11199
  } else {
11171
- localPath = resolve2(candidate);
11200
+ localPath = resolve3(candidate);
11172
11201
  }
11173
11202
  if (statSync5(localPath).isFile())
11174
11203
  localPath = dirname4(localPath);
11175
11204
  const root = parsePath(localPath).root;
11176
11205
  while (localPath !== root) {
11177
- const packagePath = resolve2(localPath, "package.json");
11206
+ const packagePath = resolve3(localPath, "package.json");
11178
11207
  if (existsSync8(packagePath)) {
11179
11208
  const pkg = JSON.parse(readFileSync5(packagePath, "utf8"));
11180
11209
  return pkg.name === OPENCODE_PLUGIN_NAME;
@@ -14480,13 +14509,199 @@ var init_setup_omp = __esm(() => {
14480
14509
  OMP_HOST = createOmpHost(DEFAULT_DEPS2);
14481
14510
  });
14482
14511
 
14512
+ // ../plugin/src/shared/redaction.ts
14513
+ import { homedir as homedir7, userInfo } from "node:os";
14514
+ function escapeRegex(value) {
14515
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14516
+ }
14517
+ function redactionTypeForKey(key) {
14518
+ const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "_");
14519
+ const suffix = normalized.split(".").filter(Boolean).at(-1) ?? normalized;
14520
+ return suffix || "secret";
14521
+ }
14522
+ function isNonSecretScalarValue(value) {
14523
+ const v = value.trim();
14524
+ if (v === "true" || v === "false" || v === "null" || v === "undefined")
14525
+ return true;
14526
+ return /^[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(v);
14527
+ }
14528
+ function isSecretKey(key) {
14529
+ const segments = key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[._-]+/).filter(Boolean);
14530
+ if (segments.length === 0)
14531
+ return false;
14532
+ if (segments.length === 1) {
14533
+ const first = segments[0];
14534
+ return Boolean(first && SECRET_SEGMENT_PATTERN.test(first));
14535
+ }
14536
+ for (let i2 = 0;i2 < segments.length; i2++) {
14537
+ const seg = segments[i2];
14538
+ if (!seg || !SECRET_SEGMENT_PATTERN.test(seg))
14539
+ continue;
14540
+ let trailingOk = true;
14541
+ for (let j = i2 + 1;j < segments.length; j++) {
14542
+ const tail = segments[j];
14543
+ if (!tail)
14544
+ continue;
14545
+ if (TRAILING_DESCRIPTORS.has(tail))
14546
+ continue;
14547
+ if (SECRET_SEGMENT_PATTERN.test(tail))
14548
+ continue;
14549
+ trailingOk = false;
14550
+ break;
14551
+ }
14552
+ if (!trailingOk)
14553
+ continue;
14554
+ for (let k = i2 - 1;k >= 0; k--) {
14555
+ const lead = segments[k];
14556
+ if (lead && SECRET_QUALIFIERS.has(lead))
14557
+ return true;
14558
+ }
14559
+ }
14560
+ return false;
14561
+ }
14562
+ function sanitizePathString(value) {
14563
+ const home = process.env.HOME || process.env.USERPROFILE || homedir7();
14564
+ const username = userInfo().username;
14565
+ let sanitized = value;
14566
+ if (home) {
14567
+ sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
14568
+ }
14569
+ sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
14570
+ sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
14571
+ sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
14572
+ if (username) {
14573
+ sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
14574
+ }
14575
+ return sanitized;
14576
+ }
14577
+ function redactSecretText(value) {
14578
+ let redacted = value;
14579
+ for (const { pattern, replacement } of SECRET_TEXT_PATTERNS) {
14580
+ if (typeof replacement === "string") {
14581
+ redacted = redacted.replace(pattern, replacement);
14582
+ } else {
14583
+ redacted = redacted.replace(pattern, replacement);
14584
+ }
14585
+ }
14586
+ return redacted;
14587
+ }
14588
+ function sanitizeDiagnosticText(value) {
14589
+ return redactSecretText(sanitizePathString(value));
14590
+ }
14591
+ function sanitizeConfigValue(value, keyPath = []) {
14592
+ if (value === null || typeof value === "number" || typeof value === "boolean")
14593
+ return value;
14594
+ const key = keyPath.at(-1) ?? "";
14595
+ if (key && isSecretKey(key)) {
14596
+ return `<REDACTED:${redactionTypeForKey(key)}>`;
14597
+ }
14598
+ if (typeof value === "string")
14599
+ return sanitizeDiagnosticText(value);
14600
+ if (Array.isArray(value)) {
14601
+ return value.map((entry, index) => sanitizeConfigValue(entry, [...keyPath, String(index)]));
14602
+ }
14603
+ if (value && typeof value === "object") {
14604
+ return Object.fromEntries(Object.entries(value).map(([entryKey, entry]) => [
14605
+ entryKey,
14606
+ sanitizeConfigValue(entry, [...keyPath, entryKey])
14607
+ ]));
14608
+ }
14609
+ return value;
14610
+ }
14611
+ var SECRET_WORDS, SECRET_SEGMENT_PATTERN, TRAILING_DESCRIPTORS, SECRET_QUALIFIERS, SECRET_TEXT_PATTERNS;
14612
+ var init_redaction = __esm(() => {
14613
+ SECRET_WORDS = [
14614
+ "key",
14615
+ "token",
14616
+ "secret",
14617
+ "password",
14618
+ "auth",
14619
+ "authorization",
14620
+ "bearer",
14621
+ "credential"
14622
+ ];
14623
+ SECRET_SEGMENT_PATTERN = new RegExp(`^(?:${SECRET_WORDS.map((w) => `${w}s?`).join("|")})$`, "i");
14624
+ TRAILING_DESCRIPTORS = new Set(["id", "ids", "value", "values", "header", "headers"]);
14625
+ SECRET_QUALIFIERS = new Set([
14626
+ "api",
14627
+ "access",
14628
+ "private",
14629
+ "client",
14630
+ "auth",
14631
+ "authorization",
14632
+ "secret",
14633
+ "bearer",
14634
+ "session",
14635
+ "refresh",
14636
+ "service",
14637
+ "x",
14638
+ "openai",
14639
+ "anthropic",
14640
+ "google",
14641
+ "github",
14642
+ "huggingface",
14643
+ "aws",
14644
+ "azure"
14645
+ ]);
14646
+ SECRET_TEXT_PATTERNS = [
14647
+ {
14648
+ pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
14649
+ replacement: "<ANTHROPIC_API_KEY_REDACTED>"
14650
+ },
14651
+ {
14652
+ pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{12,}/g,
14653
+ replacement: "<OPENAI_API_KEY_REDACTED>"
14654
+ },
14655
+ {
14656
+ pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
14657
+ replacement: "<GITHUB_PAT_REDACTED>"
14658
+ },
14659
+ {
14660
+ pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
14661
+ replacement: "<GITHUB_TOKEN_REDACTED>"
14662
+ },
14663
+ {
14664
+ pattern: /\bhf_[A-Za-z0-9]{30,}/g,
14665
+ replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
14666
+ },
14667
+ {
14668
+ pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
14669
+ replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
14670
+ },
14671
+ {
14672
+ pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
14673
+ replacement: "<SLACK_TOKEN_REDACTED>"
14674
+ },
14675
+ {
14676
+ pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
14677
+ replacement: "<GOOGLE_API_KEY_REDACTED>"
14678
+ },
14679
+ {
14680
+ pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{8,})/gi,
14681
+ replacement: (_full, prefix) => `${prefix}<REDACTED:bearer>`
14682
+ },
14683
+ {
14684
+ pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
14685
+ replacement: "<JWT_REDACTED>"
14686
+ },
14687
+ {
14688
+ pattern: /(["'])([^"']*(?:key|token|secret|password|auth|bearer|credential)[^"']*)\1(\s*:\s*)(["'])([^"']*)\4/gi,
14689
+ replacement: (full, quote, key, separator, valueQuote, value) => isNonSecretScalarValue(value) ? full : `${quote}${key}${quote}${separator}${valueQuote}<REDACTED:${redactionTypeForKey(key)}>${valueQuote}`
14690
+ },
14691
+ {
14692
+ pattern: /\b([A-Za-z0-9_.-]*(?:key|token|secret|password|auth|bearer|credential)[A-Za-z0-9_.-]*)\s*=\s*([^\s'"`]+)/gi,
14693
+ replacement: (full, key, value) => isNonSecretScalarValue(value) ? full : `${key}=<REDACTED:${redactionTypeForKey(key)}>`
14694
+ }
14695
+ ];
14696
+ });
14697
+
14483
14698
  // ../plugin/src/shared/logger.ts
14484
14699
  import * as fs from "node:fs";
14485
14700
  import * as path2 from "node:path";
14486
14701
  function recordSwallowedWrite(error) {
14487
14702
  try {
14488
14703
  swallowedWriteCount++;
14489
- lastErrorMessage = error instanceof Error ? error.message : String(error);
14704
+ lastErrorMessage = sanitizeDiagnosticText(error instanceof Error ? error.message : String(error));
14490
14705
  lastErrorTime = new Date().toISOString();
14491
14706
  } catch {}
14492
14707
  }
@@ -14523,9 +14738,9 @@ function log3(message, data) {
14523
14738
  return;
14524
14739
  try {
14525
14740
  const timestamp = new Date().toISOString();
14526
- const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
14527
- ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
14528
- buffer.push(`[${timestamp}] ${message}${serialized}
14741
+ const serialized = data === undefined ? "" : data instanceof Error ? ` ${sanitizeDiagnosticText(`${data.message}${data.stack ? `
14742
+ ${data.stack}` : ""}`)}` : ` ${JSON.stringify(sanitizeConfigValue(data))}`;
14743
+ buffer.push(`[${timestamp}] ${sanitizeDiagnosticText(message)}${serialized}
14529
14744
  `);
14530
14745
  if (buffer.length >= BUFFER_SIZE_LIMIT) {
14531
14746
  flush();
@@ -14537,6 +14752,7 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
14537
14752
  var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, swallowedWriteCount = 0, lastErrorMessage = null, lastErrorTime = null;
14538
14753
  var init_logger = __esm(() => {
14539
14754
  init_data_path();
14755
+ init_redaction();
14540
14756
  buffer = [];
14541
14757
  if (!isTestEnv) {
14542
14758
  process.on("exit", flush);
@@ -15054,7 +15270,7 @@ __export(exports_util, {
15054
15270
  createTransparentProxy: () => createTransparentProxy,
15055
15271
  defineLazy: () => defineLazy,
15056
15272
  esc: () => esc,
15057
- escapeRegex: () => escapeRegex,
15273
+ escapeRegex: () => escapeRegex2,
15058
15274
  explicitlyAborted: () => explicitlyAborted,
15059
15275
  extend: () => extend,
15060
15276
  finalizeIssue: () => finalizeIssue,
@@ -15261,7 +15477,7 @@ function numKeys(data) {
15261
15477
  }
15262
15478
  return keyCount;
15263
15479
  }
15264
- function escapeRegex(str) {
15480
+ function escapeRegex2(str) {
15265
15481
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15266
15482
  }
15267
15483
  function clone(inst, def, params) {
@@ -16045,7 +16261,7 @@ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uui
16045
16261
  return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
16046
16262
  return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
16047
16263
  }, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter3) => {
16048
- const escapedDelim = escapeRegex(delimiter3 ?? ":");
16264
+ const escapedDelim = escapeRegex2(delimiter3 ?? ":");
16049
16265
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
16050
16266
  }, cidrv4, cidrv6, base64, base64url, hostname, domain, httpProtocol, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string = (params) => {
16051
16267
  const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
@@ -16553,7 +16769,7 @@ var init_checks = __esm(() => {
16553
16769
  });
16554
16770
  $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst, def) => {
16555
16771
  $ZodCheck.init(inst, def);
16556
- const escapedRegex = escapeRegex(def.includes);
16772
+ const escapedRegex = escapeRegex2(def.includes);
16557
16773
  const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
16558
16774
  def.pattern = pattern;
16559
16775
  inst._zod.onattach.push((inst2) => {
@@ -16577,7 +16793,7 @@ var init_checks = __esm(() => {
16577
16793
  });
16578
16794
  $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (inst, def) => {
16579
16795
  $ZodCheck.init(inst, def);
16580
- const pattern = new RegExp(`^${escapeRegex(def.prefix)}.*`);
16796
+ const pattern = new RegExp(`^${escapeRegex2(def.prefix)}.*`);
16581
16797
  def.pattern ?? (def.pattern = pattern);
16582
16798
  inst._zod.onattach.push((inst2) => {
16583
16799
  const bag = inst2._zod.bag;
@@ -16600,7 +16816,7 @@ var init_checks = __esm(() => {
16600
16816
  });
16601
16817
  $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst, def) => {
16602
16818
  $ZodCheck.init(inst, def);
16603
- const pattern = new RegExp(`.*${escapeRegex(def.suffix)}$`);
16819
+ const pattern = new RegExp(`.*${escapeRegex2(def.suffix)}$`);
16604
16820
  def.pattern ?? (def.pattern = pattern);
16605
16821
  inst._zod.onattach.push((inst2) => {
16606
16822
  const bag = inst2._zod.bag;
@@ -18330,7 +18546,7 @@ var init_schemas = __esm(() => {
18330
18546
  const values = getEnumValues(def.entries);
18331
18547
  const valuesSet = new Set(values);
18332
18548
  inst._zod.values = valuesSet;
18333
- inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o2) => typeof o2 === "string" ? escapeRegex(o2) : o2.toString()).join("|")})$`);
18549
+ inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o2) => typeof o2 === "string" ? escapeRegex2(o2) : o2.toString()).join("|")})$`);
18334
18550
  inst._zod.parse = (payload, _ctx) => {
18335
18551
  const input = payload.value;
18336
18552
  if (valuesSet.has(input)) {
@@ -18352,7 +18568,7 @@ var init_schemas = __esm(() => {
18352
18568
  }
18353
18569
  const values = new Set(def.values);
18354
18570
  inst._zod.values = values;
18355
- inst._zod.pattern = new RegExp(`^(${def.values.map((o2) => typeof o2 === "string" ? escapeRegex(o2) : o2 ? escapeRegex(o2.toString()) : String(o2)).join("|")})$`);
18571
+ inst._zod.pattern = new RegExp(`^(${def.values.map((o2) => typeof o2 === "string" ? escapeRegex2(o2) : o2 ? escapeRegex2(o2.toString()) : String(o2)).join("|")})$`);
18356
18572
  inst._zod.parse = (payload, _ctx) => {
18357
18573
  const input = payload.value;
18358
18574
  if (values.has(input)) {
@@ -18656,7 +18872,7 @@ var init_schemas = __esm(() => {
18656
18872
  const end = source.endsWith("$") ? source.length - 1 : source.length;
18657
18873
  regexParts.push(source.slice(start, end));
18658
18874
  } else if (part === null || primitiveTypes.has(typeof part)) {
18659
- regexParts.push(escapeRegex(`${part}`));
18875
+ regexParts.push(escapeRegex2(`${part}`));
18660
18876
  } else {
18661
18877
  throw new Error(`Invalid template literal part: ${part}`);
18662
18878
  }
@@ -29663,7 +29879,7 @@ var init_agent_overrides = __esm(() => {
29663
29879
  });
29664
29880
 
29665
29881
  // ../plugin/src/config/schema/magic-context.ts
29666
- import { homedir as homedir7 } from "node:os";
29882
+ import { homedir as homedir8 } from "node:os";
29667
29883
  function defaultTaskConfig(task) {
29668
29884
  const base = { schedule: DEFAULT_TASK_SCHEDULES2[task] };
29669
29885
  if (task === "review-user-memories")
@@ -29675,9 +29891,9 @@ function defaultTaskConfig(task) {
29675
29891
  function expandConfigPath(value) {
29676
29892
  const trimmed = value.trim();
29677
29893
  if (trimmed === "~")
29678
- return homedir7();
29894
+ return homedir8();
29679
29895
  if (trimmed.startsWith("~/"))
29680
- return `${homedir7()}/${trimmed.slice(2)}`;
29896
+ return `${homedir8()}/${trimmed.slice(2)}`;
29681
29897
  return trimmed;
29682
29898
  }
29683
29899
  var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.", DEFAULT_HISTORIAN_TIMEOUT_MS = 600000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", PiThinkingLevelSchema, PiConfigSchema, PromptSurfacePresetSchema, PromptSurfaceModelKeySchema, PromptSurfaceToolKeySchema, PromptSurfaceConfigSchema, PER_HARNESS_MIGRATION_INVENTORY, OcEntryObjectSchema, OcEntrySchema, PiEntryObjectSchema, PiEntrySchema, OpenCodeHarnessBlockSchema, PiHarnessBlockSchema, OpenCodeTaskExecutionSchema, PiTaskExecutionSchema, DreamerOpenCodeHarnessBlockSchema, DreamerPiHarnessBlockSchema, ProfileOpenCodeModelBlockSchema, ProfilePiModelBlockSchema, ProfileHistorianSchema, ProfileDreamerSchema, ProfileSidekickSchema, ConfigProfileSchema, ConfigProfilesSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES2, DreamTasksSchema, AgentMetadataSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, EmbeddingFallbackProviderSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
@@ -30654,15 +30870,15 @@ var RUST_COMPACTION_OFF_WARNING = "compaction-off mode does not support rust tra
30654
30870
 
30655
30871
  // ../plugin/src/config/variable.ts
30656
30872
  import { existsSync as existsSync14, readFileSync as readFileSync9 } from "node:fs";
30657
- import { homedir as homedir8 } from "node:os";
30658
- import { dirname as dirname9, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
30873
+ import { homedir as homedir9 } from "node:os";
30874
+ import { dirname as dirname9, isAbsolute as isAbsolute4, resolve as resolve4 } from "node:path";
30659
30875
  function sensitiveFilePathReason(resolvedPath) {
30660
- const home = homedir8();
30876
+ const home = homedir9();
30661
30877
  const sensitiveDirs = [
30662
- { dir: resolve3(home, ".ssh"), label: "SSH keys" },
30663
- { dir: resolve3(home, ".aws"), label: "AWS credentials" },
30664
- { dir: resolve3(home, ".gnupg"), label: "GnuPG keyring" },
30665
- { dir: resolve3(home, ".config", "gh"), label: "GitHub CLI auth" }
30878
+ { dir: resolve4(home, ".ssh"), label: "SSH keys" },
30879
+ { dir: resolve4(home, ".aws"), label: "AWS credentials" },
30880
+ { dir: resolve4(home, ".gnupg"), label: "GnuPG keyring" },
30881
+ { dir: resolve4(home, ".config", "gh"), label: "GitHub CLI auth" }
30666
30882
  ];
30667
30883
  for (const { dir, label } of sensitiveDirs) {
30668
30884
  if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
@@ -30720,9 +30936,9 @@ function substituteConfigVariables(input) {
30720
30936
  }
30721
30937
  let filePath = rawPath.trim();
30722
30938
  if (filePath.startsWith("~/")) {
30723
- filePath = resolve3(homedir8(), filePath.slice(2));
30724
- } else if (!isAbsolute3(filePath)) {
30725
- filePath = resolve3(configDir, filePath);
30939
+ filePath = resolve4(homedir9(), filePath.slice(2));
30940
+ } else if (!isAbsolute4(filePath)) {
30941
+ filePath = resolve4(configDir, filePath);
30726
30942
  }
30727
30943
  const sensitiveReason = sensitiveFilePathReason(filePath);
30728
30944
  if (sensitiveReason) {
@@ -31127,17 +31343,17 @@ var init_config = __esm(() => {
31127
31343
  });
31128
31344
 
31129
31345
  // ../plugin/src/shared/opencode-config-dir.ts
31130
- import { homedir as homedir9 } from "node:os";
31131
- import { join as join11, resolve as resolve4 } from "node:path";
31346
+ import { homedir as homedir10 } from "node:os";
31347
+ import { join as join11, resolve as resolve5 } from "node:path";
31132
31348
  function getCliConfigDir() {
31133
31349
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
31134
31350
  if (envConfigDir) {
31135
- return resolve4(envConfigDir);
31351
+ return resolve5(envConfigDir);
31136
31352
  }
31137
31353
  if (process.platform === "win32") {
31138
- return join11(homedir9(), ".config", "opencode");
31354
+ return join11(homedir10(), ".config", "opencode");
31139
31355
  }
31140
- return join11(process.env.XDG_CONFIG_HOME || join11(homedir9(), ".config"), "opencode");
31356
+ return join11(process.env.XDG_CONFIG_HOME || join11(homedir10(), ".config"), "opencode");
31141
31357
  }
31142
31358
  function getOpenCodeConfigDir2(_options) {
31143
31359
  return getCliConfigDir();
@@ -31155,7 +31371,7 @@ function getOpenCodeConfigPaths(options) {
31155
31371
  var init_opencode_config_dir = () => {};
31156
31372
 
31157
31373
  // ../plugin/src/shared/conflict-detector.ts
31158
- import { homedir as homedir10 } from "node:os";
31374
+ import { homedir as homedir11 } from "node:os";
31159
31375
  import { join as join12 } from "node:path";
31160
31376
  function detectConflicts(directory, options) {
31161
31377
  const compactionEnabled = options?.compactionEnabled ?? true;
@@ -31343,7 +31559,7 @@ function readOmoDisabledHooks(directory) {
31343
31559
  }
31344
31560
  }
31345
31561
  }
31346
- const homeDir2 = process.env.HOME || homedir10();
31562
+ const homeDir2 = process.env.HOME || homedir11();
31347
31563
  const omoHomeDir = join12(homeDir2, ".omo");
31348
31564
  for (const name of ["omo.jsonc", "omo.json"]) {
31349
31565
  const config2 = readJsoncFile(join12(omoHomeDir, name));
@@ -31374,7 +31590,7 @@ var init_conflict_detector = __esm(() => {
31374
31590
 
31375
31591
  // ../plugin/src/shared/conflict-fixer.ts
31376
31592
  import { existsSync as existsSync16, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "node:fs";
31377
- import { homedir as homedir11 } from "node:os";
31593
+ import { homedir as homedir12 } from "node:os";
31378
31594
  import { join as join13 } from "node:path";
31379
31595
  function isRecord2(value) {
31380
31596
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -31434,7 +31650,7 @@ function collectOmoConfigPaths(directory) {
31434
31650
  paths.add(projectPath);
31435
31651
  }
31436
31652
  }
31437
- const homeDir2 = process.env.HOME || homedir11();
31653
+ const homeDir2 = process.env.HOME || homedir12();
31438
31654
  const omoHomeDir = join13(homeDir2, ".omo");
31439
31655
  for (const name of OMO_UNIFIED_NAMES) {
31440
31656
  const userPath = join13(omoHomeDir, name);
@@ -32256,6 +32472,9 @@ async function drainAuthority(args) {
32256
32472
  if (next === cursor3)
32257
32473
  break;
32258
32474
  }
32475
+ if (args.domain === "memories") {
32476
+ resolvePendingMemoryReferencesForDrain(args.db);
32477
+ }
32259
32478
  for (const step of [
32260
32479
  "seed",
32261
32480
  "memories",
@@ -32376,6 +32595,47 @@ function rowNullableString(row, key) {
32376
32595
  const value = row[key];
32377
32596
  return typeof value === "string" ? value : null;
32378
32597
  }
32598
+ function memorySnapshotTimestamp(row, key) {
32599
+ const value = row[key];
32600
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
32601
+ }
32602
+ function parsedMemorySnapshot(snapshotJson, fallback) {
32603
+ try {
32604
+ const parsed = JSON.parse(snapshotJson);
32605
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : fallback;
32606
+ } catch {
32607
+ return fallback;
32608
+ }
32609
+ }
32610
+ function guardMemorySnapshotByRecency(args) {
32611
+ const effectiveRow = { ...args.row };
32612
+ if (!args.existing) {
32613
+ return { effectiveRow, hostUpdatedNewer: false, hostVerificationNewer: false };
32614
+ }
32615
+ const existing = args.existing;
32616
+ const preserve = (columns) => {
32617
+ for (const column of columns) {
32618
+ if (Object.hasOwn(existing, column)) {
32619
+ effectiveRow[column] = existing[column];
32620
+ }
32621
+ }
32622
+ };
32623
+ preserve(IMMUTABLE_MEMORY_SNAPSHOT_COLUMNS);
32624
+ const hostUpdatedNewer = memorySnapshotTimestamp(existing, "updated_at") > memorySnapshotTimestamp(args.snapshot, "updated_at");
32625
+ const hostClassificationNewer = hostUpdatedNewer || memorySnapshotTimestamp(existing, "classified_at") > memorySnapshotTimestamp(args.snapshot, "classified_at");
32626
+ const snapshotCarriesUpdatedAt = hasSnapshotField(args.snapshot, "updated_at");
32627
+ const hostVerificationNewer = hostUpdatedNewer && snapshotCarriesUpdatedAt;
32628
+ const hostMuralNewer = hostUpdatedNewer && snapshotCarriesUpdatedAt;
32629
+ if (hostUpdatedNewer)
32630
+ preserve(UPDATED_MEMORY_SNAPSHOT_COLUMNS);
32631
+ if (hostClassificationNewer)
32632
+ preserve(CLASSIFICATION_MEMORY_SNAPSHOT_COLUMNS);
32633
+ if (hostVerificationNewer)
32634
+ preserve(VERIFICATION_MEMORY_SNAPSHOT_COLUMNS);
32635
+ if (hostMuralNewer)
32636
+ preserve(MURAL_MEMORY_SNAPSHOT_COLUMNS);
32637
+ return { effectiveRow, hostUpdatedNewer, hostVerificationNewer };
32638
+ }
32379
32639
  function hasSnapshotField(row, key) {
32380
32640
  return Object.prototype.hasOwnProperty.call(row, key);
32381
32641
  }
@@ -32520,11 +32780,11 @@ function prepareMirrorPageStatements(db) {
32520
32780
  verification_status = ?, verified_at = ?, classified_at = ?, superseded_by_memory_id = ?,
32521
32781
  merged_from = ?, metadata_json = ?, mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?,
32522
32782
  mural_cue_rejection_count = ? WHERE id = ?`),
32523
- updateSuperseded: db.prepare("UPDATE memories SET superseded_by_memory_id = ? WHERE id = ?"),
32783
+ updateSuperseded: db.prepare("UPDATE memories SET superseded_by_memory_id = ?, updated_at = ? WHERE id = ?"),
32524
32784
  deletePendingReference: db.prepare("DELETE FROM mirror_pending_references WHERE domain = 'memories' AND module_project = ? AND module_row_id = ?"),
32525
32785
  upsertPendingReference: db.prepare("INSERT INTO mirror_pending_references(domain, module_project, module_row_id, target_module_row_id) VALUES ('memories', ?, ?, ?) ON CONFLICT(domain, module_project, module_row_id) DO UPDATE SET target_module_row_id = excluded.target_module_row_id"),
32526
32786
  deleteMemoryVerifications: db.prepare("DELETE FROM memory_verifications WHERE memory_id = ?"),
32527
- insertMemoryVerification: db.prepare("INSERT INTO memory_verifications(memory_id, file_path, verified_at, mapped_at) VALUES (?, ?, ?, ?)"),
32787
+ insertMemoryVerification: db.prepare("INSERT INTO memory_verifications(memory_id, file_path, verified_at, mapped_at, mapping_origin) VALUES (?, ?, ?, ?, ?)"),
32528
32788
  noteById: db.prepare("SELECT * FROM notes WHERE id = ?"),
32529
32789
  noteIdByStoreId: db.prepare("SELECT id FROM notes WHERE id = ? AND type = 'smart' AND project_path = ?"),
32530
32790
  insertNote: db.prepare("INSERT INTO notes (type, status, content, project_path, session_id, created_at, updated_at) VALUES ('smart', 'active', '', ?, ?, 0, 0)"),
@@ -32552,7 +32812,8 @@ function prepareMirrorPageStatements(db) {
32552
32812
  AND target.module_row_id = pending.target_module_row_id
32553
32813
  WHERE pending.domain = 'memories'
32554
32814
  AND source.context_row_id = memories.id
32555
- )
32815
+ ),
32816
+ updated_at = ?
32556
32817
  WHERE id IN (
32557
32818
  SELECT source.context_row_id
32558
32819
  FROM mirror_pending_references pending
@@ -32582,7 +32843,7 @@ function prepareMirrorPageStatements(db) {
32582
32843
  repairPending: db.prepare("SELECT dirty FROM mirror_memory_repair_state WHERE id = 1"),
32583
32844
  markRepairPending: db.prepare("UPDATE mirror_memory_repair_state SET dirty = 1, updated_at = ? WHERE id = 1"),
32584
32845
  clearRepairPending: db.prepare("UPDATE mirror_memory_repair_state SET dirty = 0, updated_at = ? WHERE id = 1"),
32585
- repairCandidates: db.prepare(`SELECT memory.id, live.full_row_snapshot
32846
+ repairCandidates: db.prepare(`SELECT memory.id, memory.updated_at, memory.classified_at, live.full_row_snapshot
32586
32847
  FROM memories memory
32587
32848
  JOIN mirror_identity identity
32588
32849
  ON identity.domain = 'memories'
@@ -32596,9 +32857,14 @@ function prepareMirrorPageStatements(db) {
32596
32857
  WHERE (memory.source_type IS NULL OR memory.importance IS NULL)
32597
32858
  AND live.full_row_snapshot IS NOT NULL`),
32598
32859
  repairMemory: db.prepare(`UPDATE memories
32599
- SET source_type = COALESCE(?, source_type),
32600
- importance = COALESCE(?, importance)
32601
- WHERE id = ?`),
32860
+ SET source_type = COALESCE(source_type, ?),
32861
+ importance = COALESCE(importance, ?),
32862
+ updated_at = ?
32863
+ WHERE id = ?
32864
+ AND COALESCE(updated_at, 0) <= ?
32865
+ AND COALESCE(classified_at, 0) <= ?
32866
+ AND ((source_type IS NULL AND ? IS NOT NULL)
32867
+ OR (importance IS NULL AND ? IS NOT NULL))`),
32602
32868
  updateCursor: db.prepare("INSERT INTO mirror_cursors(domain, cursor, updated_at) VALUES (?, ?, ?) ON CONFLICT(domain) DO UPDATE SET cursor = excluded.cursor, updated_at = excluded.updated_at"),
32603
32869
  contextStoreUuid: getContextStoreUuid(db)
32604
32870
  };
@@ -32682,37 +32948,46 @@ function applyMemoryRow(db, feed, statements) {
32682
32948
  log3(`[magic-context] skipping memory mirror update for module ${moduleProject}/${feed.module_row_id}: context row ${contextId} belongs to ${existing.project_path}`);
32683
32949
  return;
32684
32950
  }
32951
+ const retainedRecencySnapshot = parsedMemorySnapshot(snapshotJson, row);
32952
+ const recencySnapshot = hasSnapshotField(row, "updated_at") ? row : hasSnapshotField(row, "classified_at") ? { ...retainedRecencySnapshot, classified_at: row.classified_at } : retainedRecencySnapshot;
32953
+ const recencyGuard = guardMemorySnapshotByRecency({
32954
+ row,
32955
+ snapshot: recencySnapshot,
32956
+ existing
32957
+ });
32958
+ const projectedRow = recencyGuard.effectiveRow;
32685
32959
  const has = (key) => hasSnapshotField(row, key);
32686
- const nullableNumber = (key, previous) => has(key) ? typeof row[key] === "number" && Number.isFinite(row[key]) ? row[key] : null : previous ?? null;
32687
- const nullableString = (key, previous) => has(key) ? rowNullableString(row, key) : previous ?? null;
32688
- const hasSuperseded = has("superseded_by_memory_id");
32960
+ const nullableNumber = (key, previous) => has(key) ? typeof projectedRow[key] === "number" && Number.isFinite(projectedRow[key]) ? projectedRow[key] : null : previous ?? null;
32961
+ const nullableString = (key, previous) => has(key) ? rowNullableString(projectedRow, key) : previous ?? null;
32962
+ const hasSuperseded = has("superseded_by_memory_id") && !recencyGuard.hostUpdatedNewer;
32689
32963
  const previousHash = existing?.normalized_hash;
32690
- statements.updateMemory.run(has("project_path") ? rowString(row, "project_path") : existing?.project_path ?? moduleProject, has("category") ? rowString(row, "category", "CONSTRAINTS") : existing?.category ?? "CONSTRAINTS", has("content") ? rowString(row, "content") : existing?.content ?? "", has("normalized_hash") ? rowString(row, "normalized_hash") : existing?.normalized_hash ?? "", has("importance") ? typeof row.importance === "number" && Number.isFinite(row.importance) ? row.importance : null : existing?.importance ?? null, has("scope") ? rowString(row, "scope", "project") : existing?.scope ?? "project", has("shareable") ? rowNumber(row, "shareable") : existing?.shareable ?? 0, nullableString("source_session_id", existing?.source_session_id), nullableString("source_type", existing?.source_type), has("seen_count") ? rowNumber(row, "seen_count", 1) : existing?.seen_count ?? 1, has("retrieval_count") ? rowNumber(row, "retrieval_count") : existing?.retrieval_count ?? 0, has("first_seen_at") ? rowNumber(row, "first_seen_at") : existing?.first_seen_at ?? 0, has("created_at") ? rowNumber(row, "created_at") : existing?.created_at ?? 0, has("updated_at") ? rowNumber(row, "updated_at") : existing?.updated_at ?? 0, has("last_seen_at") ? rowNumber(row, "last_seen_at") : existing?.last_seen_at ?? 0, nullableNumber("last_retrieved_at", existing?.last_retrieved_at), has("status") ? rowString(row, "status", "active") : existing?.status ?? "active", nullableNumber("expires_at", existing?.expires_at), has("verification_status") ? rowString(row, "verification_status", "unverified") : existing?.verification_status ?? "unverified", nullableNumber("verified_at", existing?.verified_at), nullableNumber("classified_at", existing?.classified_at), hasSuperseded ? null : existing?.superseded_by_memory_id ?? null, nullableString("merged_from", existing?.merged_from), nullableString("metadata_json", existing?.metadata_json), nullableString("mural_cue", existing?.mural_cue), nullableString("mural_cue_hash", existing?.mural_cue_hash), nullableNumber("mural_cue_at", existing?.mural_cue_at), has("mural_cue_rejection_count") ? rowNumber(row, "mural_cue_rejection_count") : existing?.mural_cue_rejection_count ?? 0, contextId);
32691
- if (hasSuperseded && typeof row.superseded_by_memory_id === "number") {
32692
- const translated = mirrorIdentity(db, "memories", moduleProject, row.superseded_by_memory_id, statements);
32964
+ statements.updateMemory.run(has("project_path") ? rowString(projectedRow, "project_path") : existing?.project_path ?? moduleProject, has("category") ? rowString(projectedRow, "category", "CONSTRAINTS") : existing?.category ?? "CONSTRAINTS", has("content") ? rowString(projectedRow, "content") : existing?.content ?? "", has("normalized_hash") ? rowString(projectedRow, "normalized_hash") : existing?.normalized_hash ?? "", has("importance") ? typeof projectedRow.importance === "number" && Number.isFinite(projectedRow.importance) ? projectedRow.importance : null : existing?.importance ?? null, has("scope") ? rowString(projectedRow, "scope", "project") : existing?.scope ?? "project", has("shareable") ? rowNumber(projectedRow, "shareable") : existing?.shareable ?? 0, nullableString("source_session_id", existing?.source_session_id), nullableString("source_type", existing?.source_type), has("seen_count") ? rowNumber(projectedRow, "seen_count", 1) : existing?.seen_count ?? 1, has("retrieval_count") ? rowNumber(projectedRow, "retrieval_count") : existing?.retrieval_count ?? 0, has("first_seen_at") ? rowNumber(projectedRow, "first_seen_at") : existing?.first_seen_at ?? 0, has("created_at") ? rowNumber(projectedRow, "created_at") : existing?.created_at ?? 0, has("updated_at") ? rowNumber(projectedRow, "updated_at") : existing?.updated_at ?? 0, has("last_seen_at") ? rowNumber(projectedRow, "last_seen_at") : existing?.last_seen_at ?? 0, nullableNumber("last_retrieved_at", existing?.last_retrieved_at), has("status") ? rowString(projectedRow, "status", "active") : existing?.status ?? "active", nullableNumber("expires_at", existing?.expires_at), has("verification_status") ? rowString(projectedRow, "verification_status", "unverified") : existing?.verification_status ?? "unverified", nullableNumber("verified_at", existing?.verified_at), nullableNumber("classified_at", existing?.classified_at), hasSuperseded ? null : existing?.superseded_by_memory_id ?? null, nullableString("merged_from", existing?.merged_from), nullableString("metadata_json", existing?.metadata_json), nullableString("mural_cue", existing?.mural_cue), nullableString("mural_cue_hash", existing?.mural_cue_hash), nullableNumber("mural_cue_at", existing?.mural_cue_at), has("mural_cue_rejection_count") ? rowNumber(projectedRow, "mural_cue_rejection_count") : existing?.mural_cue_rejection_count ?? 0, contextId);
32965
+ if (hasSuperseded && typeof projectedRow.superseded_by_memory_id === "number") {
32966
+ const translated = mirrorIdentity(db, "memories", moduleProject, projectedRow.superseded_by_memory_id, statements);
32693
32967
  if (translated) {
32694
- statements.updateSuperseded.run(translated.context_row_id, contextId);
32968
+ statements.updateSuperseded.run(translated.context_row_id, Date.now(), contextId);
32695
32969
  statements.deletePendingReference.run(moduleProject, feed.module_row_id);
32696
32970
  } else {
32697
- statements.upsertPendingReference.run(moduleProject, feed.module_row_id, row.superseded_by_memory_id);
32971
+ statements.upsertPendingReference.run(moduleProject, feed.module_row_id, projectedRow.superseded_by_memory_id);
32698
32972
  }
32699
32973
  } else if (hasSuperseded) {
32700
32974
  statements.deletePendingReference.run(moduleProject, feed.module_row_id);
32701
32975
  }
32702
- const appliedHash = has("normalized_hash") ? rowString(row, "normalized_hash") : previousHash;
32976
+ const appliedHash = has("normalized_hash") ? rowString(projectedRow, "normalized_hash") : previousHash;
32703
32977
  if (previousHash !== appliedHash && appliedHash !== undefined) {
32704
32978
  statements.deleteMemoryEmbeddings.run(contextId);
32705
32979
  }
32706
- if (has("mapping")) {
32980
+ if (has("mapping") && !recencyGuard.hostVerificationNewer) {
32707
32981
  statements.deleteMemoryVerifications.run(contextId);
32708
- if (Array.isArray(row.mapping)) {
32982
+ if (Array.isArray(projectedRow.mapping)) {
32709
32983
  const files = [
32710
- ...new Set(row.mapping.filter((file2) => typeof file2 === "string").sort())
32984
+ ...new Set(projectedRow.mapping.filter((file2) => typeof file2 === "string").sort())
32711
32985
  ];
32712
- const verifiedAt = rowNumber(row, "verified_at");
32713
- const mappedAt = rowNumber(row, "updated_at", Date.now());
32986
+ const verifiedAt = rowNumber(projectedRow, "verified_at");
32987
+ const mappedAt = rowNumber(projectedRow, "updated_at", Date.now());
32988
+ const mappingOrigin = projectedRow.mapping_origin === "host_rejected_fallback" ? "host_rejected_fallback" : "mapper";
32714
32989
  for (const file2 of files.length > 0 ? files : [""]) {
32715
- statements.insertMemoryVerification.run(contextId, file2, verifiedAt, mappedAt);
32990
+ statements.insertMemoryVerification.run(contextId, file2, verifiedAt, mappedAt, mappingOrigin);
32716
32991
  }
32717
32992
  }
32718
32993
  }
@@ -32738,7 +33013,11 @@ function repairNullClobberedMemoryRows(statements) {
32738
33013
  const importance = hasSnapshotField(snapshot, "importance") && typeof snapshot.importance === "number" && Number.isFinite(snapshot.importance) ? snapshot.importance : null;
32739
33014
  if (sourceType === null && importance === null)
32740
33015
  continue;
32741
- statements.repairMemory.run(sourceType, importance, candidate.id);
33016
+ const snapshotVintage = Math.max(memorySnapshotTimestamp(snapshot, "updated_at"), memorySnapshotTimestamp(snapshot, "classified_at"));
33017
+ const hostVintage = Math.max(candidate.updated_at ?? 0, candidate.classified_at ?? 0);
33018
+ if (hostVintage > snapshotVintage)
33019
+ continue;
33020
+ statements.repairMemory.run(sourceType, importance, Date.now(), candidate.id, snapshotVintage, snapshotVintage, sourceType, importance);
32742
33021
  }
32743
33022
  statements.clearRepairPending.run(Date.now());
32744
33023
  }
@@ -32763,9 +33042,17 @@ function contextNoteId(db, feed, moduleProject, statements) {
32763
33042
  return contextId;
32764
33043
  }
32765
33044
  function translateMemoryReferences(statements) {
32766
- statements.translateMemoryReferences.run();
33045
+ statements.translateMemoryReferences.run(Date.now());
32767
33046
  statements.clearTranslatedReferences.run();
32768
33047
  }
33048
+ function resolvePendingMemoryReferencesForDrain(db) {
33049
+ withPrivilegedWriter(db, () => {
33050
+ db.transaction(() => {
33051
+ const statements = prepareMirrorPageStatements(db);
33052
+ translateMemoryReferences(statements);
33053
+ }).immediate();
33054
+ });
33055
+ }
32769
33056
  function applyNoteRow(db, feed, statements) {
32770
33057
  const row = feed.full_row_snapshot;
32771
33058
  const moduleProject = rowString(row, "project_path");
@@ -32944,11 +33231,12 @@ async function ensureLiveMemoryResnapshot(args) {
32944
33231
  }).immediate();
32945
33232
  });
32946
33233
  }
32947
- var AUTHORITY_DOMAINS, moduleNoteEvaluationBridges, MAX_DRAIN_RECAPTURE_ATTEMPTS = 5, MAX_AUTHORITY_SEED_FRAME_BYTES, MEMORY_SNAPSHOT_COLUMNS, mirrorFlights;
33234
+ var AUTHORITY_DOMAINS, observedAuthorityRoutingByProject, moduleNoteEvaluationBridges, MAX_DRAIN_RECAPTURE_ATTEMPTS = 5, MAX_AUTHORITY_SEED_FRAME_BYTES, MEMORY_SNAPSHOT_COLUMNS, IMMUTABLE_MEMORY_SNAPSHOT_COLUMNS, CLASSIFICATION_MEMORY_SNAPSHOT_COLUMNS, VERIFICATION_MEMORY_SNAPSHOT_COLUMNS, MURAL_MEMORY_SNAPSHOT_COLUMNS, UPDATED_MEMORY_SNAPSHOT_COLUMNS, mirrorFlights;
32948
33235
  var init_context_authority = __esm(async () => {
32949
33236
  init_logger();
32950
33237
  await init_sqlite();
32951
33238
  AUTHORITY_DOMAINS = ["memories", "notes"];
33239
+ observedAuthorityRoutingByProject = new Map;
32952
33240
  moduleNoteEvaluationBridges = new Map;
32953
33241
  MAX_AUTHORITY_SEED_FRAME_BYTES = 900 * 1024;
32954
33242
  MEMORY_SNAPSHOT_COLUMNS = [
@@ -32984,6 +33272,42 @@ var init_context_authority = __esm(async () => {
32984
33272
  "mural_cue_at",
32985
33273
  "mural_cue_rejection_count"
32986
33274
  ];
33275
+ IMMUTABLE_MEMORY_SNAPSHOT_COLUMNS = ["project_path", "first_seen_at", "created_at"];
33276
+ CLASSIFICATION_MEMORY_SNAPSHOT_COLUMNS = [
33277
+ "importance",
33278
+ "scope",
33279
+ "shareable",
33280
+ "source_type",
33281
+ "classified_at"
33282
+ ];
33283
+ VERIFICATION_MEMORY_SNAPSHOT_COLUMNS = [
33284
+ "verification_status",
33285
+ "verified_at",
33286
+ "mapping",
33287
+ "mapping_origin"
33288
+ ];
33289
+ MURAL_MEMORY_SNAPSHOT_COLUMNS = [
33290
+ "mural_cue",
33291
+ "mural_cue_hash",
33292
+ "mural_cue_at",
33293
+ "mural_cue_rejection_count"
33294
+ ];
33295
+ UPDATED_MEMORY_SNAPSHOT_COLUMNS = [
33296
+ "category",
33297
+ "content",
33298
+ "normalized_hash",
33299
+ "source_session_id",
33300
+ "seen_count",
33301
+ "retrieval_count",
33302
+ "updated_at",
33303
+ "last_seen_at",
33304
+ "last_retrieved_at",
33305
+ "status",
33306
+ "expires_at",
33307
+ "superseded_by_memory_id",
33308
+ "merged_from",
33309
+ "metadata_json"
33310
+ ];
32987
33311
  mirrorFlights = new WeakMap;
32988
33312
  });
32989
33313
 
@@ -33645,7 +33969,7 @@ class SubcSocket {
33645
33969
  return this.sock.localPort ?? null;
33646
33970
  }
33647
33971
  static connect(host, port, deadlineMs) {
33648
- return new Promise((resolve5, reject) => {
33972
+ return new Promise((resolve6, reject) => {
33649
33973
  const sock = net.connect({ host, port });
33650
33974
  sock.setNoDelay(true);
33651
33975
  const timer = setTimeout(() => {
@@ -33654,7 +33978,7 @@ class SubcSocket {
33654
33978
  }, Math.max(0, deadlineMs - Date.now()));
33655
33979
  sock.once("connect", () => {
33656
33980
  clearTimeout(timer);
33657
- resolve5(new SubcSocket(sock));
33981
+ resolve6(new SubcSocket(sock));
33658
33982
  });
33659
33983
  sock.once("error", (err) => {
33660
33984
  clearTimeout(timer);
@@ -33686,7 +34010,7 @@ class SubcSocket {
33686
34010
  }
33687
34011
  if (n2 === 0)
33688
34012
  return Promise.resolve(new Uint8Array(0));
33689
- return new Promise((resolve5, reject) => {
34013
+ return new Promise((resolve6, reject) => {
33690
34014
  let timer = null;
33691
34015
  if (Number.isFinite(deadlineMs)) {
33692
34016
  const remaining = deadlineMs - Date.now();
@@ -33699,7 +34023,7 @@ class SubcSocket {
33699
34023
  reject(new SocketTimeoutError(`timed out waiting for ${n2} bytes`));
33700
34024
  }, remaining);
33701
34025
  }
33702
- this.waiter = { need: n2, resolve: resolve5, reject, timer };
34026
+ this.waiter = { need: n2, resolve: resolve6, reject, timer };
33703
34027
  this.tryServe();
33704
34028
  });
33705
34029
  }
@@ -33723,7 +34047,7 @@ class SubcSocket {
33723
34047
  let queued = false;
33724
34048
  let settled = false;
33725
34049
  let timer = null;
33726
- const completed = new Promise((resolve5, reject) => {
34050
+ const completed = new Promise((resolve6, reject) => {
33727
34051
  const settle = (run) => {
33728
34052
  if (settled)
33729
34053
  return;
@@ -33747,7 +34071,7 @@ class SubcSocket {
33747
34071
  if (err) {
33748
34072
  reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
33749
34073
  } else {
33750
- resolve5();
34074
+ resolve6();
33751
34075
  }
33752
34076
  });
33753
34077
  });
@@ -33948,14 +34272,14 @@ class SubcClient {
33948
34272
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
33949
34273
  const corr = this.allocateCorr();
33950
34274
  const key = pendingKey(handle, corr);
33951
- const closed = new Promise((resolve5, reject) => {
34275
+ const closed = new Promise((resolve6, reject) => {
33952
34276
  if (this.closedErr) {
33953
34277
  reject(this.closedErr);
33954
34278
  return;
33955
34279
  }
33956
34280
  this.pending.set(key, {
33957
34281
  handle,
33958
- resolve: () => resolve5(),
34282
+ resolve: () => resolve6(),
33959
34283
  reject,
33960
34284
  onProgress: onEvent,
33961
34285
  timer: null,
@@ -34040,11 +34364,11 @@ class SubcClient {
34040
34364
  const waiters = [];
34041
34365
  for (const pending of this.pending.values()) {
34042
34366
  if (pending.handle === handle && !pending.subscription) {
34043
- waiters.push(new Promise((resolve5) => {
34367
+ waiters.push(new Promise((resolve6) => {
34044
34368
  const previous = pending.onSettle;
34045
34369
  pending.onSettle = () => {
34046
34370
  previous?.();
34047
- resolve5();
34371
+ resolve6();
34048
34372
  };
34049
34373
  }));
34050
34374
  }
@@ -34100,11 +34424,11 @@ class SubcClient {
34100
34424
  const channel = handle?.channel ?? 0;
34101
34425
  const epoch = handle?.epoch ?? 0;
34102
34426
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
34103
- return new Promise((resolve5, reject) => {
34427
+ return new Promise((resolve6, reject) => {
34104
34428
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
34105
34429
  const pending = {
34106
34430
  handle,
34107
- resolve: resolve5,
34431
+ resolve: resolve6,
34108
34432
  reject,
34109
34433
  onProgress,
34110
34434
  timer: null,
@@ -34178,11 +34502,11 @@ class SubcClient {
34178
34502
  }
34179
34503
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
34180
34504
  };
34181
- return new Promise((resolve5, reject) => {
34505
+ return new Promise((resolve6, reject) => {
34182
34506
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
34183
34507
  const pending = {
34184
34508
  handle,
34185
- resolve: resolve5,
34509
+ resolve: resolve6,
34186
34510
  reject,
34187
34511
  onProgress,
34188
34512
  timer: null,
@@ -34562,7 +34886,7 @@ function normalizeConnectOptions(opts) {
34562
34886
  identity: opts.identity,
34563
34887
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
34564
34888
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
34565
- sleep: opts.sleep ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms))),
34889
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve6) => setTimeout(resolve6, ms))),
34566
34890
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
34567
34891
  };
34568
34892
  }
@@ -34715,6 +35039,12 @@ function isConnectionFailure(error51) {
34715
35039
  ].includes(code) || /\bclient closed\b|\bconnection closed\b|\bclosed the connection\b/i.test(message);
34716
35040
  });
34717
35041
  }
35042
+ function routeOpenWithoutAmbientConsumerIdentity(client, target, identity, options = {}) {
35043
+ return client.routeOpen(target, identity, {
35044
+ ...options,
35045
+ consumerIdentity: null
35046
+ });
35047
+ }
34718
35048
 
34719
35049
  class SubcModuleTransport {
34720
35050
  connectionFile;
@@ -34861,7 +35191,7 @@ class SubcModuleTransport {
34861
35191
  if (this.queuedLaneWaiters >= SERIAL_LANE_MAX_WAITERS || lane.waiters.length >= SERIAL_LANE_MAX_WAITERS_PER_SESSION) {
34862
35192
  return Promise.reject(this.queueFullError());
34863
35193
  }
34864
- return new Promise((resolve5, reject) => {
35194
+ return new Promise((resolve6, reject) => {
34865
35195
  const waiter = {};
34866
35196
  const removeAndReject = (error51) => {
34867
35197
  if (waiter.settled)
@@ -34879,7 +35209,7 @@ class SubcModuleTransport {
34879
35209
  };
34880
35210
  waiter.signal = signal;
34881
35211
  waiter.deadlineMs = deadlineMs;
34882
- waiter.resolve = resolve5;
35212
+ waiter.resolve = resolve6;
34883
35213
  waiter.reject = reject;
34884
35214
  waiter.settled = false;
34885
35215
  waiter.onAbort = () => removeAndReject(signal?.reason ?? new Error("module transport call aborted"));
@@ -35088,7 +35418,7 @@ class SubcModuleTransport {
35088
35418
  harness: getHarness(),
35089
35419
  session: `${this.routeSessionPrefix}${sessionId}`
35090
35420
  };
35091
- const route = await this.beforeDeadline(client.routeOpen(target, identity), deadlineMs, "opening the module route");
35421
+ const route = await this.beforeDeadline(routeOpenWithoutAmbientConsumerIdentity(client, target, identity), deadlineMs, "opening the module route");
35092
35422
  if (this.client !== client || generation !== this.connectionGeneration) {
35093
35423
  await client.closeRoute(route).catch(() => {
35094
35424
  return;
@@ -35146,7 +35476,7 @@ class SubcModuleTransport {
35146
35476
  return error51;
35147
35477
  }
35148
35478
  sleepAbortable(durationMs, signal) {
35149
- return new Promise((resolve5, reject) => {
35479
+ return new Promise((resolve6, reject) => {
35150
35480
  if (signal?.aborted) {
35151
35481
  reject(signal.reason ?? new Error("module transport call aborted"));
35152
35482
  return;
@@ -35158,7 +35488,7 @@ class SubcModuleTransport {
35158
35488
  };
35159
35489
  const timer = setTimeout(() => {
35160
35490
  signal?.removeEventListener("abort", onAbort);
35161
- resolve5();
35491
+ resolve6();
35162
35492
  }, Math.max(0, durationMs));
35163
35493
  signal?.addEventListener("abort", onAbort, { once: true });
35164
35494
  });
@@ -35539,192 +35869,6 @@ var init_rpc_utils = __esm(() => {
35539
35869
  rpcProcessListExecFileSync = execFileSync4;
35540
35870
  rpcIdentityPlatform = process.platform;
35541
35871
  });
35542
- // ../plugin/src/shared/redaction.ts
35543
- import { homedir as homedir12, userInfo } from "node:os";
35544
- function escapeRegex2(value) {
35545
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
35546
- }
35547
- function redactionTypeForKey(key) {
35548
- const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "_");
35549
- const suffix = normalized.split(".").filter(Boolean).at(-1) ?? normalized;
35550
- return suffix || "secret";
35551
- }
35552
- function isNonSecretScalarValue(value) {
35553
- const v = value.trim();
35554
- if (v === "true" || v === "false" || v === "null" || v === "undefined")
35555
- return true;
35556
- return /^[+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(v);
35557
- }
35558
- function isSecretKey(key) {
35559
- const segments = key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().split(/[._-]+/).filter(Boolean);
35560
- if (segments.length === 0)
35561
- return false;
35562
- if (segments.length === 1) {
35563
- const first = segments[0];
35564
- return Boolean(first && SECRET_SEGMENT_PATTERN.test(first));
35565
- }
35566
- for (let i2 = 0;i2 < segments.length; i2++) {
35567
- const seg = segments[i2];
35568
- if (!seg || !SECRET_SEGMENT_PATTERN.test(seg))
35569
- continue;
35570
- let trailingOk = true;
35571
- for (let j = i2 + 1;j < segments.length; j++) {
35572
- const tail = segments[j];
35573
- if (!tail)
35574
- continue;
35575
- if (TRAILING_DESCRIPTORS.has(tail))
35576
- continue;
35577
- if (SECRET_SEGMENT_PATTERN.test(tail))
35578
- continue;
35579
- trailingOk = false;
35580
- break;
35581
- }
35582
- if (!trailingOk)
35583
- continue;
35584
- for (let k = i2 - 1;k >= 0; k--) {
35585
- const lead = segments[k];
35586
- if (lead && SECRET_QUALIFIERS.has(lead))
35587
- return true;
35588
- }
35589
- }
35590
- return false;
35591
- }
35592
- function sanitizePathString(value) {
35593
- const home = homedir12();
35594
- const username = userInfo().username;
35595
- let sanitized = value;
35596
- if (home) {
35597
- sanitized = sanitized.replace(new RegExp(escapeRegex2(home), "g"), "~");
35598
- }
35599
- sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
35600
- sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
35601
- sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
35602
- if (username) {
35603
- sanitized = sanitized.replace(new RegExp(escapeRegex2(username), "g"), "<USER>");
35604
- }
35605
- return sanitized;
35606
- }
35607
- function redactSecretText(value) {
35608
- let redacted = value;
35609
- for (const { pattern, replacement } of SECRET_TEXT_PATTERNS) {
35610
- if (typeof replacement === "string") {
35611
- redacted = redacted.replace(pattern, replacement);
35612
- } else {
35613
- redacted = redacted.replace(pattern, replacement);
35614
- }
35615
- }
35616
- return redacted;
35617
- }
35618
- function sanitizeDiagnosticText(value) {
35619
- return redactSecretText(sanitizePathString(value));
35620
- }
35621
- function sanitizeConfigValue(value, keyPath = []) {
35622
- if (value === null || typeof value === "number" || typeof value === "boolean")
35623
- return value;
35624
- const key = keyPath.at(-1) ?? "";
35625
- if (key && isSecretKey(key)) {
35626
- return `<REDACTED:${redactionTypeForKey(key)}>`;
35627
- }
35628
- if (typeof value === "string")
35629
- return sanitizeDiagnosticText(value);
35630
- if (Array.isArray(value)) {
35631
- return value.map((entry, index) => sanitizeConfigValue(entry, [...keyPath, String(index)]));
35632
- }
35633
- if (value && typeof value === "object") {
35634
- return Object.fromEntries(Object.entries(value).map(([entryKey, entry]) => [
35635
- entryKey,
35636
- sanitizeConfigValue(entry, [...keyPath, entryKey])
35637
- ]));
35638
- }
35639
- return value;
35640
- }
35641
- var SECRET_WORDS, SECRET_SEGMENT_PATTERN, TRAILING_DESCRIPTORS, SECRET_QUALIFIERS, SECRET_TEXT_PATTERNS;
35642
- var init_redaction = __esm(() => {
35643
- SECRET_WORDS = [
35644
- "key",
35645
- "token",
35646
- "secret",
35647
- "password",
35648
- "auth",
35649
- "authorization",
35650
- "bearer",
35651
- "credential"
35652
- ];
35653
- SECRET_SEGMENT_PATTERN = new RegExp(`^(?:${SECRET_WORDS.map((w) => `${w}s?`).join("|")})$`, "i");
35654
- TRAILING_DESCRIPTORS = new Set(["id", "ids", "value", "values", "header", "headers"]);
35655
- SECRET_QUALIFIERS = new Set([
35656
- "api",
35657
- "access",
35658
- "private",
35659
- "client",
35660
- "auth",
35661
- "authorization",
35662
- "secret",
35663
- "bearer",
35664
- "session",
35665
- "refresh",
35666
- "service",
35667
- "x",
35668
- "openai",
35669
- "anthropic",
35670
- "google",
35671
- "github",
35672
- "huggingface",
35673
- "aws",
35674
- "azure"
35675
- ]);
35676
- SECRET_TEXT_PATTERNS = [
35677
- {
35678
- pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
35679
- replacement: "<ANTHROPIC_API_KEY_REDACTED>"
35680
- },
35681
- {
35682
- pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g,
35683
- replacement: "<OPENAI_API_KEY_REDACTED>"
35684
- },
35685
- {
35686
- pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
35687
- replacement: "<GITHUB_PAT_REDACTED>"
35688
- },
35689
- {
35690
- pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
35691
- replacement: "<GITHUB_TOKEN_REDACTED>"
35692
- },
35693
- {
35694
- pattern: /\bhf_[A-Za-z0-9]{30,}/g,
35695
- replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
35696
- },
35697
- {
35698
- pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
35699
- replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
35700
- },
35701
- {
35702
- pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
35703
- replacement: "<SLACK_TOKEN_REDACTED>"
35704
- },
35705
- {
35706
- pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
35707
- replacement: "<GOOGLE_API_KEY_REDACTED>"
35708
- },
35709
- {
35710
- pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{8,})/gi,
35711
- replacement: (_full, prefix) => `${prefix}<REDACTED:bearer>`
35712
- },
35713
- {
35714
- pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
35715
- replacement: "<JWT_REDACTED>"
35716
- },
35717
- {
35718
- pattern: /(["'])([^"']*(?:key|token|secret|password|auth|bearer|credential)[^"']*)\1(\s*:\s*)(["'])([^"']*)\4/gi,
35719
- replacement: (full, quote, key, separator, valueQuote, value) => isNonSecretScalarValue(value) ? full : `${quote}${key}${quote}${separator}${valueQuote}<REDACTED:${redactionTypeForKey(key)}>${valueQuote}`
35720
- },
35721
- {
35722
- pattern: /\b([A-Za-z0-9_.-]*(?:key|token|secret|password|auth|bearer|credential)[A-Za-z0-9_.-]*)\s*=\s*([^\s'"`]+)/gi,
35723
- replacement: (full, key, value) => isNonSecretScalarValue(value) ? full : `${key}=<REDACTED:${redactionTypeForKey(key)}>`
35724
- }
35725
- ];
35726
- });
35727
-
35728
35872
  // ../plugin/src/features/magic-context/fail-closed-block.ts
35729
35873
  function attachFailClosedBlockingProcessEvidence(process3, evidence) {
35730
35874
  Object.defineProperties(process3, {
@@ -36043,6 +36187,20 @@ var init_compartment_parser = __esm(() => {
36043
36187
  EVENT_FIELD_REGEX = /<([a-z_]+)\s*>(.*?)<\/\1>/gs;
36044
36188
  });
36045
36189
 
36190
+ // ../plugin/src/shared/write-transaction-timing.ts
36191
+ function logSlowWriteTransaction(site, startedAt, thresholdMs = SLOW_WRITE_TRANSACTION_THRESHOLD_MS) {
36192
+ try {
36193
+ const durationMs = performance.now() - startedAt;
36194
+ if (durationMs < thresholdMs)
36195
+ return;
36196
+ log3(`[magic-context] slow write transaction: site=${site} held=${durationMs.toFixed(1)}ms`);
36197
+ } catch {}
36198
+ }
36199
+ var SLOW_WRITE_TRANSACTION_THRESHOLD_MS = 1000;
36200
+ var init_write_transaction_timing = __esm(() => {
36201
+ init_logger();
36202
+ });
36203
+
36046
36204
  // ../plugin/src/features/magic-context/storage-schema-helpers.ts
36047
36205
  function ensureColumn(db, table, column, definition) {
36048
36206
  if (!/^[a-z][a-z0-9_]*$/.test(table) || !/^[a-z][a-z0-9_]*$/.test(column) || !/^[A-Z0-9_"'(),[\]\s]+$/i.test(definition)) {
@@ -36374,6 +36532,7 @@ function runMigrations(db) {
36374
36532
  let migration;
36375
36533
  let currentVersion = 0;
36376
36534
  try {
36535
+ const transactionStartedAt = performance.now();
36377
36536
  const applied = db.transaction(() => {
36378
36537
  currentVersion = getCurrentVersion(db);
36379
36538
  migration = MIGRATIONS.find((candidate) => candidate.version > currentVersion && !isMigrationApplied(db, candidate.version));
@@ -36388,6 +36547,7 @@ function runMigrations(db) {
36388
36547
  db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
36389
36548
  return true;
36390
36549
  }).immediate();
36550
+ logSlowWriteTransaction("migration-runner", transactionStartedAt);
36391
36551
  if (!applied || !migration)
36392
36552
  break;
36393
36553
  if (migration.version <= 61)
@@ -36412,7 +36572,9 @@ function runMigrations(db) {
36412
36572
  }
36413
36573
  if (touchedLegacyAuthorityBatch) {
36414
36574
  try {
36575
+ const transactionStartedAt = performance.now();
36415
36576
  db.transaction(() => installLatestAuthorityTriggers(db)).immediate();
36577
+ logSlowWriteTransaction("migration-runner", transactionStartedAt);
36416
36578
  } catch (error51) {
36417
36579
  throw new Error(`Migration authority-trigger postcondition failed: ${error51 instanceof Error ? error51.message : String(error51)}. Database may need manual repair.`);
36418
36580
  }
@@ -36425,6 +36587,7 @@ var FORK_MIGRATION_VERSION_FLOOR = 1e4, MigrationLockBusyError, MIGRATIONS, LATE
36425
36587
  var init_migrations = __esm(() => {
36426
36588
  init_compartment_parser();
36427
36589
  init_logger();
36590
+ init_write_transaction_timing();
36428
36591
  init_workspaces();
36429
36592
  MigrationLockBusyError = class MigrationLockBusyError extends Error {
36430
36593
  constructor(message) {
@@ -38451,6 +38614,15 @@ var init_migrations = __esm(() => {
38451
38614
  );
38452
38615
  `);
38453
38616
  }
38617
+ },
38618
+ {
38619
+ version: 82,
38620
+ description: "record the origin of memory file-independent mappings",
38621
+ up(db) {
38622
+ if (!tableExists(db, "memory_verifications"))
38623
+ return;
38624
+ ensureColumn(db, "memory_verifications", "mapping_origin", "TEXT NOT NULL DEFAULT 'mapper'");
38625
+ }
38454
38626
  }
38455
38627
  ];
38456
38628
  LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m3) => Math.max(max, m3.version), 0);
@@ -38494,7 +38666,7 @@ import {
38494
38666
  statSync as statSync8,
38495
38667
  unlinkSync as unlinkSync3
38496
38668
  } from "node:fs";
38497
- import { basename as basename4, dirname as dirname11, join as join15, resolve as resolve5 } from "node:path";
38669
+ import { basename as basename4, dirname as dirname11, join as join15, resolve as resolve6 } from "node:path";
38498
38670
  function getPersistedSchemaVersion(db) {
38499
38671
  const hasMigrationsTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'schema_migrations'").get();
38500
38672
  if (!hasMigrationsTable) {
@@ -39025,8 +39197,10 @@ function initializeDatabase(db) {
39025
39197
  -- verified_at=0 means "mapped (files known) but not yet content-verified".
39026
39198
  -- map-memories sets mapped_at + verified_at=0; verify sets verified_at=now.
39027
39199
  verified_at INTEGER NOT NULL,
39028
- mapped_at INTEGER NOT NULL DEFAULT 0,
39029
- PRIMARY KEY (memory_id, file_path)
39200
+ mapped_at INTEGER NOT NULL DEFAULT 0,
39201
+ -- Distinguishes mapper-authored independence from a host rejection fallback.
39202
+ mapping_origin TEXT NOT NULL DEFAULT 'mapper',
39203
+ PRIMARY KEY (memory_id, file_path)
39030
39204
  );
39031
39205
  CREATE INDEX IF NOT EXISTS idx_memory_verifications_memory ON memory_verifications(memory_id);
39032
39206
 
@@ -39218,8 +39392,6 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
39218
39392
  updated_at INTEGER NOT NULL,
39219
39393
  harness TEXT NOT NULL DEFAULT 'opencode'
39220
39394
  );
39221
- CREATE INDEX IF NOT EXISTS idx_message_history_index_orphan_sweep
39222
- ON message_history_index(harness, session_id, updated_at);
39223
39395
 
39224
39396
  CREATE TABLE IF NOT EXISTS message_history_source (
39225
39397
  session_id TEXT NOT NULL,
@@ -39806,9 +39978,13 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
39806
39978
  ensureColumn(db, "recomp_compartments", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
39807
39979
  ensureColumn(db, "recomp_facts", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
39808
39980
  ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
39981
+ db.exec(`
39982
+ CREATE INDEX IF NOT EXISTS idx_message_history_index_orphan_sweep
39983
+ ON message_history_index(harness, session_id, updated_at);
39984
+ `);
39809
39985
  ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
39810
39986
  }
39811
- var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 81, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS;
39987
+ var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 82, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS;
39812
39988
  var init_storage_db = __esm(async () => {
39813
39989
  init_data_path();
39814
39990
  init_logger();
@@ -40186,13 +40362,14 @@ function mergeMemoryRow(db, row, fromIdentity, toIdentity, mergedAt) {
40186
40362
  LIMIT 1`).get(toIdentity, row.category, row.normalized_hash, sourceId);
40187
40363
  if (collision && typeof collision.id === "number") {
40188
40364
  const targetId = collision.id;
40189
- const mergedSeen = Math.max(Number(collision.seen_count ?? 1), Number(row.seen_count ?? 1));
40365
+ const targetSeen = Number(collision.seen_count ?? 1);
40366
+ const mergedSeen = Math.max(targetSeen, Number(row.seen_count ?? 1));
40190
40367
  const sourceClassifiedAt = Number(row.classified_at ?? 0);
40191
40368
  const targetClassifiedAt = Number(collision.classified_at ?? 0);
40192
40369
  if (sourceClassifiedAt > targetClassifiedAt) {
40193
40370
  db.prepare(`UPDATE memories
40194
- SET importance = ?, scope = ?, shareable = ?, classified_at = ?
40195
- WHERE id = ?`).run(row.importance, row.scope, row.shareable, row.classified_at, targetId);
40371
+ SET importance = ?, scope = ?, shareable = ?, classified_at = ?, updated_at = ?
40372
+ WHERE id = ?`).run(row.importance, row.scope, row.shareable, row.classified_at, mergedAt, targetId);
40196
40373
  }
40197
40374
  const sourceHasCue = typeof row.mural_cue === "string" && row.mural_cue.length > 0;
40198
40375
  const targetHasCue = typeof collision.mural_cue === "string" && collision.mural_cue.length > 0;
@@ -40200,19 +40377,27 @@ function mergeMemoryRow(db, row, fromIdentity, toIdentity, mergedAt) {
40200
40377
  const targetCueAt = Number(collision.mural_cue_at ?? 0);
40201
40378
  if (sourceHasCue && (!targetHasCue || sourceCueAt > targetCueAt)) {
40202
40379
  db.prepare(`UPDATE memories
40203
- SET mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?,
40204
- mural_cue_rejection_count = ?
40205
- WHERE id = ?`).run(row.mural_cue, row.mural_cue_hash, row.mural_cue_at, row.mural_cue_rejection_count, targetId);
40206
- }
40207
- db.prepare(`INSERT INTO memory_verifications (memory_id, file_path, verified_at, mapped_at)
40208
- SELECT ?, file_path, verified_at, mapped_at
40209
- FROM memory_verifications
40210
- WHERE memory_id = ?
40211
- ON CONFLICT(memory_id, file_path) DO UPDATE SET
40212
- verified_at = MAX(memory_verifications.verified_at, excluded.verified_at),
40213
- mapped_at = MAX(memory_verifications.mapped_at, excluded.mapped_at)`).run(targetId, sourceId);
40380
+ SET mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?,
40381
+ mural_cue_rejection_count = ?, updated_at = ?
40382
+ WHERE id = ?`).run(row.mural_cue, row.mural_cue_hash, row.mural_cue_at, row.mural_cue_rejection_count, mergedAt, targetId);
40383
+ }
40384
+ db.prepare(`INSERT INTO memory_verifications
40385
+ (memory_id, file_path, verified_at, mapped_at, mapping_origin)
40386
+ SELECT ?, file_path, verified_at, mapped_at, mapping_origin
40387
+ FROM memory_verifications
40388
+ WHERE memory_id = ?
40389
+ ON CONFLICT(memory_id, file_path) DO UPDATE SET
40390
+ verified_at = MAX(memory_verifications.verified_at, excluded.verified_at),
40391
+ mapped_at = MAX(memory_verifications.mapped_at, excluded.mapped_at),
40392
+ mapping_origin = CASE
40393
+ WHEN excluded.mapped_at >= memory_verifications.mapped_at
40394
+ THEN excluded.mapping_origin
40395
+ ELSE memory_verifications.mapping_origin
40396
+ END`).run(targetId, sourceId);
40214
40397
  db.prepare("DELETE FROM memory_verifications WHERE memory_id = ?").run(sourceId);
40215
- db.prepare("UPDATE memories SET seen_count = ?, status = COALESCE(status, 'active') WHERE id = ?").run(mergedSeen, targetId);
40398
+ if (mergedSeen !== targetSeen || collision.status === null || collision.status === undefined) {
40399
+ db.prepare("UPDATE memories SET seen_count = ?, status = COALESCE(status, 'active'), updated_at = ? WHERE id = ?").run(mergedSeen, mergedAt, targetId);
40400
+ }
40216
40401
  db.prepare(`UPDATE memories
40217
40402
  SET status = 'archived',
40218
40403
  superseded_by_memory_id = ?,
@@ -40228,7 +40413,7 @@ function mergeMemoryRow(db, row, fromIdentity, toIdentity, mergedAt) {
40228
40413
  logRow(db, fromIdentity, toIdentity, "memories", String(sourceId), "superseded", String(targetId), mergedAt);
40229
40414
  return true;
40230
40415
  }
40231
- const result = db.prepare("UPDATE memories SET project_path = ? WHERE id = ? AND project_path = ?").run(toIdentity, sourceId, fromIdentity);
40416
+ const result = db.prepare("UPDATE memories SET project_path = ?, updated_at = ? WHERE id = ? AND project_path = ?").run(toIdentity, mergedAt, sourceId, fromIdentity);
40232
40417
  if ((result.changes ?? 0) === 0)
40233
40418
  return false;
40234
40419
  logRow(db, fromIdentity, toIdentity, "memories", String(sourceId), "rekeyed", null, mergedAt);
@@ -41034,6 +41219,18 @@ function migrationKeyFor(sourceSessionId, targetHarness) {
41034
41219
  return createHash3("sha256").update(`${sourceSessionId}
41035
41220
  ${targetHarness}`).digest("hex");
41036
41221
  }
41222
+ function moduleManagedProjectForSession(db, sessionId) {
41223
+ const tables = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('authority_managed', 'session_projects')").all();
41224
+ const names = new Set(tables.flatMap((row2) => typeof row2.name === "string" ? [row2.name] : []));
41225
+ if (!names.has("authority_managed") || !names.has("session_projects"))
41226
+ return null;
41227
+ const row = db.prepare(`SELECT am.project_path
41228
+ FROM authority_managed am
41229
+ JOIN session_projects sp ON sp.project_path = am.project_path
41230
+ WHERE sp.session_id = ? AND sp.harness = 'opencode'
41231
+ LIMIT 1`).get(sessionId);
41232
+ return typeof row?.project_path === "string" ? row.project_path : null;
41233
+ }
41037
41234
  function hasMigrationJournal(db) {
41038
41235
  return Boolean(stmt(db, "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'migration_pending'").get());
41039
41236
  }
@@ -41594,6 +41791,10 @@ function migrateOpenCodeSessionToPi(opts) {
41594
41791
  const cwd = session.directory ?? session.path ?? process.cwd();
41595
41792
  const outputDir = join19(piSessionsRoot, projectPathToPiDirSlug(cwd));
41596
41793
  const targetHarness = opts.targetHarness ?? "pi";
41794
+ const moduleManagedProject = cortexkitDb === null ? null : moduleManagedProjectForSession(cortexkitDb, session.id);
41795
+ if (moduleManagedProject) {
41796
+ throw new Error(`Migration refused: source session ${session.id} belongs to module-managed project ${moduleManagedProject}; context.db may contain only host mirrors, not the Rust engine truth. Drain authority to TypeScript with \`magic-context doctor drain-authority ${cwd}\`, then retry.`);
41797
+ }
41597
41798
  const journalActive = cortexkitDb !== null && !opts.dryRun;
41598
41799
  let recovery;
41599
41800
  let migrationKey;
@@ -43007,7 +43208,7 @@ var init_redaction2 = __esm(() => {
43007
43208
  import { execFileSync as execFileSync5, spawnSync as spawnSync5 } from "node:child_process";
43008
43209
  import { existsSync as existsSync25, mkdirSync as mkdirSync9, readFileSync as readFileSync15 } from "node:fs";
43009
43210
  import { createRequire as createRequire2 } from "node:module";
43010
- import { dirname as dirname14, join as join21, resolve as resolve6 } from "node:path";
43211
+ import { dirname as dirname14, join as join21, resolve as resolve7 } from "node:path";
43011
43212
  function parseSemver(value) {
43012
43213
  const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
43013
43214
  return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
@@ -43133,8 +43334,8 @@ async function runHealthChecks(options) {
43133
43334
  if (!reportedAgentDir.ok) {
43134
43335
  add(results, "warn", "Could not verify OMP active agent directory");
43135
43336
  } else {
43136
- const reportedPath = resolve6(reportedAgentDir.stdout);
43137
- const expectedPath = resolve6(getOmpAgentDir());
43337
+ const reportedPath = resolve7(reportedAgentDir.stdout);
43338
+ const expectedPath = resolve7(getOmpAgentDir());
43138
43339
  if (reportedPath === expectedPath) {
43139
43340
  add(results, "pass", `OMP agent directory resolved to ${getOmpAgentDir()}`);
43140
43341
  } else {
@@ -43159,7 +43360,9 @@ async function runHealthChecks(options) {
43159
43360
  else
43160
43361
  for (const warning of loaded.warnings.slice(0, 5))
43161
43362
  add(results, "warn", warning);
43162
- const dbPath = join21(getMagicContextStorageDir(), "context.db");
43363
+ const storage = getMagicContextStorageResolution();
43364
+ const dbPath = join21(storage.path, "context.db");
43365
+ add(results, "info", `Shared storage: ${storage.path} (source: ${storage.source})`);
43163
43366
  if (!existsSync25(dbPath))
43164
43367
  add(results, "info", `Shared context DB will be created at ${dbPath}`);
43165
43368
  else {
@@ -43630,9 +43833,8 @@ function getPluginCacheInfo() {
43630
43833
  }
43631
43834
  return { path: path6, cached: cached2, latest: getSelfVersion() };
43632
43835
  }
43633
- function getStorageDir() {
43634
- const dataHome = process.env.XDG_DATA_HOME || join23(homedir15(), ".local", "share");
43635
- return join23(dataHome, "cortexkit", "magic-context");
43836
+ function getStorageResolution() {
43837
+ return getMagicContextStorageResolution();
43636
43838
  }
43637
43839
  function fileSize(path6) {
43638
43840
  try {
@@ -43963,7 +44165,8 @@ async function collectDiagnostics() {
43963
44165
  const opencodeConfig = readConfig3(configPaths.opencodeConfig);
43964
44166
  const tuiConfig = readConfig3(configPaths.tuiConfig);
43965
44167
  const magicContextConfig = readConfig3(configPaths.magicContextConfig);
43966
- const storageDirPath = getStorageDir();
44168
+ const storageResolution = getStorageResolution();
44169
+ const storageDirPath = storageResolution.path;
43967
44170
  const contextDbPath = join23(storageDirPath, "context.db");
43968
44171
  const logPath = getMagicContextLogPath2("opencode");
43969
44172
  const logFileSize = existsSync27(logPath) ? statSync11(logPath).size : 0;
@@ -44001,6 +44204,7 @@ async function collectDiagnostics() {
44001
44204
  pluginCache: getPluginCacheInfo(),
44002
44205
  storageDir: {
44003
44206
  path: storageDirPath,
44207
+ source: storageResolution.source,
44004
44208
  exists: existsSync27(storageDirPath),
44005
44209
  contextDbSizeBytes: fileSize(contextDbPath)
44006
44210
  },
@@ -44047,6 +44251,7 @@ function renderDiagnosticsMarkdown(report) {
44047
44251
  };
44048
44252
  const storage = {
44049
44253
  path: sanitizeString(report.storageDir.path),
44254
+ source: report.storageDir.source ?? "unknown",
44050
44255
  exists: report.storageDir.exists,
44051
44256
  context_db_size: formatBytes(report.storageDir.contextDbSizeBytes)
44052
44257
  };
@@ -44265,12 +44470,23 @@ function probeOnnxRuntimeNodeLoad(packageDir) {
44265
44470
  reason: `probe returned no JSON verdict${stdoutSuffix(result)}${stderrSuffix(result)}`
44266
44471
  };
44267
44472
  }
44268
- function isLocalEmbeddingRuntimeBroken(status) {
44473
+ function isNativeLocalEmbeddingRuntimeFailure(status) {
44269
44474
  return status.state === "package-missing" || status.state === "binary-missing" || status.state === "load-failed";
44270
44475
  }
44476
+ function describeNativeFailure(status) {
44477
+ return status.state === "package-missing" ? "package is not installed" : status.state === "binary-missing" ? "expected platform binding file is absent" : `binding failed to load: ${status.reason}`;
44478
+ }
44479
+ function isLocalEmbeddingRuntimeBroken(status) {
44480
+ return status.state === "both-broken" || isNativeLocalEmbeddingRuntimeFailure(status);
44481
+ }
44271
44482
  function formatLocalEmbeddingRuntimeDoctorWarning(status) {
44272
- const cause = status.state === "package-missing" ? "package is not installed" : status.state === "binary-missing" ? "expected platform binding file is absent" : `binding failed to load: ${status.reason}`;
44273
- return "Embedding provider: local — onnxruntime-node native binding missing — " + `${cause}; its postinstall likely failed. Embeddings will not work. ` + "Reinstall with network access to the npm registry and GitHub releases, " + "or switch `embedding.provider` to an HTTP endpoint (`openai-compatible`).";
44483
+ if (status.state !== "both-broken") {
44484
+ return "Embedding provider: local — onnxruntime-node native binding missing — " + `${describeNativeFailure(status)}; its postinstall likely failed. Embeddings will not work. ` + "Reinstall with network access to the npm registry and GitHub releases, " + "or switch `embedding.provider` to an HTTP endpoint (`openai-compatible`).";
44485
+ }
44486
+ return "Embedding provider: local — native runtime and WASM fallback both unavailable — " + `native: ${describeNativeFailure(status.nativeFailure)}; WASM: ${status.wasmReason}; ` + "their install or postinstall likely failed. Reinstall with network access to the npm registry and GitHub releases, " + "or switch `embedding.provider` to an HTTP endpoint (`openai-compatible`).";
44487
+ }
44488
+ function formatLocalEmbeddingRuntimeWasmFallback(status) {
44489
+ return "Embedding provider: local — onnxruntime-node native binding failed " + `(${describeNativeFailure(status.nativeFailure)}); using onnxruntime-web (WASM) at ${status.wasmPath}. ` + "WASM inference is slower than native; a remote `openai-compatible` provider may be faster.";
44274
44490
  }
44275
44491
  function expectedBinaryRelPath(platform, arch) {
44276
44492
  const supportedPlatform = platform === "linux" || platform === "darwin" || platform === "win32";
@@ -44279,20 +44495,52 @@ function expectedBinaryRelPath(platform, arch) {
44279
44495
  return null;
44280
44496
  return join24("bin", "napi-v6", platform, arch, "onnxruntime_binding.node");
44281
44497
  }
44498
+ function probeWasmRuntimeFromRequire(requireFn) {
44499
+ try {
44500
+ const resolved = requireFn.resolve("onnxruntime-web");
44501
+ const packageDir = packageDirFromResolved(resolved, "onnxruntime-web");
44502
+ const loadFailure = probeOnnxRuntimeNodeLoad(packageDir);
44503
+ if (loadFailure === null)
44504
+ return { state: "ok", wasmPath: packageDir };
44505
+ return { state: "failed", reason: loadFailure.reason };
44506
+ } catch (error51) {
44507
+ return {
44508
+ state: "failed",
44509
+ reason: `onnxruntime-web is not resolvable: ${describeError(error51)}`
44510
+ };
44511
+ }
44512
+ }
44513
+ function withWasmFallback(native, probeWasm) {
44514
+ if (!isNativeLocalEmbeddingRuntimeFailure(native))
44515
+ return native;
44516
+ const wasm = probeWasm();
44517
+ if (wasm.state === "ok") {
44518
+ return { state: "wasm-fallback", nativeFailure: native, wasmPath: wasm.wasmPath };
44519
+ }
44520
+ return { state: "both-broken", nativeFailure: native, wasmReason: wasm.reason };
44521
+ }
44522
+ function probeWasmRuntimeAt(installRoot) {
44523
+ const requireFn = createRequire4(join24(installRoot, "package.json"));
44524
+ return probeWasmRuntimeFromRequire(requireFn);
44525
+ }
44282
44526
  function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch) {
44283
44527
  const packageDir = join24(installRoot, "node_modules", "onnxruntime-node");
44528
+ let native;
44284
44529
  if (!existsSync28(join24(packageDir, "package.json"))) {
44285
- return { state: "package-missing", packageDir };
44286
- }
44287
- const rel = expectedBinaryRelPath(platform, arch);
44288
- if (rel === null) {
44289
- return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath: packageDir };
44290
- }
44291
- const binaryPath = join24(packageDir, rel);
44292
- if (!existsSync28(binaryPath)) {
44293
- return { state: "binary-missing", packageDir, expectedBinary: binaryPath };
44530
+ native = { state: "package-missing", packageDir };
44531
+ } else {
44532
+ const rel = expectedBinaryRelPath(platform, arch);
44533
+ if (rel === null) {
44534
+ native = probeOnnxRuntimeNodeLoad(packageDir) ?? {
44535
+ state: "ok",
44536
+ binaryPath: packageDir
44537
+ };
44538
+ } else {
44539
+ const binaryPath = join24(packageDir, rel);
44540
+ native = existsSync28(binaryPath) ? probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath } : { state: "binary-missing", packageDir, expectedBinary: binaryPath };
44541
+ }
44294
44542
  }
44295
- return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath };
44543
+ return withWasmFallback(native, () => probeWasmRuntimeAt(installRoot));
44296
44544
  }
44297
44545
  function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch) {
44298
44546
  const existing = installRoots.filter((root) => existsSync28(root));
@@ -44302,21 +44550,44 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
44302
44550
  reason: "no installed plugin tree found to inspect"
44303
44551
  };
44304
44552
  }
44553
+ let firstFallback = null;
44305
44554
  let firstFailure = null;
44306
44555
  for (const root of existing) {
44307
44556
  const status = checkLocalEmbeddingRuntimeAt(root, platform, arch);
44308
44557
  if (status.state === "ok")
44309
44558
  return status;
44559
+ if (status.state === "wasm-fallback") {
44560
+ if (firstFallback === null)
44561
+ firstFallback = status;
44562
+ continue;
44563
+ }
44310
44564
  if (firstFailure === null)
44311
44565
  firstFailure = status;
44312
44566
  }
44313
- return firstFailure ?? { state: "unknown", reason: "no candidate roots" };
44567
+ return firstFallback ?? firstFailure ?? { state: "unknown", reason: "no candidate roots" };
44314
44568
  }
44315
44569
  function packageDirFromResolved(resolvedPath, packageName) {
44316
44570
  const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
44317
44571
  const idx = resolvedPath.indexOf(marker);
44318
44572
  return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname16(resolvedPath);
44319
44573
  }
44574
+ function probeWasmRuntimeByResolution(pluginDir) {
44575
+ try {
44576
+ const reqPlugin = createRequire4(join24(pluginDir, "package.json"));
44577
+ const direct = probeWasmRuntimeFromRequire(reqPlugin);
44578
+ if (direct.state === "ok" || !direct.reason.startsWith("onnxruntime-web is not resolvable")) {
44579
+ return direct;
44580
+ }
44581
+ const tfResolved = reqPlugin.resolve("@huggingface/transformers");
44582
+ const tfDir = packageDirFromResolved(tfResolved, "@huggingface/transformers");
44583
+ return probeWasmRuntimeFromRequire(createRequire4(join24(tfDir, "package.json")));
44584
+ } catch (error51) {
44585
+ return {
44586
+ state: "failed",
44587
+ reason: `could not resolve onnxruntime-web (${describeError(error51)})`
44588
+ };
44589
+ }
44590
+ }
44320
44591
  function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch) {
44321
44592
  if (!existsSync28(join24(pluginDir, "package.json"))) {
44322
44593
  return { state: "unknown", reason: "plugin package dir not found" };
@@ -44336,10 +44607,10 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
44336
44607
  } catch (error51) {
44337
44608
  resolveError = error51?.code;
44338
44609
  if (resolveError === "ERR_MODULE_NOT_FOUND" || resolveError === "MODULE_NOT_FOUND") {
44339
- return {
44610
+ return withWasmFallback({
44340
44611
  state: "package-missing",
44341
44612
  packageDir: join24(pluginDir, "node_modules", "onnxruntime-node")
44342
- };
44613
+ }, () => probeWasmRuntimeByResolution(pluginDir));
44343
44614
  }
44344
44615
  return {
44345
44616
  state: "unknown",
@@ -44350,14 +44621,14 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
44350
44621
  return { state: "unknown", reason: "onnxruntime-node resolution produced no path" };
44351
44622
  }
44352
44623
  const rel = expectedBinaryRelPath(platform, arch);
44624
+ let native;
44353
44625
  if (rel === null) {
44354
- return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
44355
- }
44356
- const binaryPath = join24(onnxDir, rel);
44357
- if (!existsSync28(binaryPath)) {
44358
- return { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
44626
+ native = probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
44627
+ } else {
44628
+ const binaryPath = join24(onnxDir, rel);
44629
+ native = existsSync28(binaryPath) ? probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath } : { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
44359
44630
  }
44360
- return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath };
44631
+ return withWasmFallback(native, () => probeWasmRuntimeByResolution(pluginDir));
44361
44632
  }
44362
44633
  var ONNX_LOAD_PROBE_TIMEOUT_MS = 1e4, ONNX_LOAD_PROBE_OUTPUT_LIMIT = 800, ONNX_LOAD_PROBE_PACKAGE_DIR_ENV = "MAGIC_CONTEXT_ONNX_RUNTIME_NODE_PACKAGE_DIR", ONNX_RUNTIME_NODE_LOAD_PROBE_SCRIPT, runOnnxRuntimeNodeLoadProbeChildForRuntime;
44363
44634
  var init_embedding_runtime = __esm(() => {
@@ -44903,7 +45174,7 @@ import {
44903
45174
  statSync as statSync12,
44904
45175
  writeFileSync as writeFileSync9
44905
45176
  } from "node:fs";
44906
- import { dirname as dirname17, isAbsolute as isAbsolute4, join as join27, resolve as resolve7 } from "node:path";
45177
+ import { dirname as dirname17, isAbsolute as isAbsolute5, join as join27, resolve as resolve8 } from "node:path";
44907
45178
  function warn(message) {
44908
45179
  log3(`WARN: ${message}`);
44909
45180
  }
@@ -45557,6 +45828,10 @@ async function runIssueFlow2() {
45557
45828
  }
45558
45829
  function checkLocalEmbeddingRuntimeForDoctor() {
45559
45830
  const runtime = checkLocalEmbeddingRuntime(getOpenCodePluginCacheRoots());
45831
+ if (runtime.state === "wasm-fallback") {
45832
+ log2.warn(formatLocalEmbeddingRuntimeWasmFallback(runtime));
45833
+ return { issues: 0 };
45834
+ }
45560
45835
  if (isLocalEmbeddingRuntimeBroken(runtime)) {
45561
45836
  log2.warn(formatLocalEmbeddingRuntimeDoctorWarning(runtime));
45562
45837
  return { issues: 1, localRuntimeBroken: true };
@@ -45565,7 +45840,7 @@ function checkLocalEmbeddingRuntimeForDoctor() {
45565
45840
  log2.warn(`Local embedding runtime unverified: ${runtime.reason}`);
45566
45841
  return { issues: 0, unverified: true };
45567
45842
  }
45568
- log2.success("Embedding provider: local (Xenova/all-MiniLM-L6-v2 bundled)");
45843
+ log2.success("Embedding provider: local (native runtime OK; Xenova/all-MiniLM-L6-v2 bundled)");
45569
45844
  return { issues: 0 };
45570
45845
  }
45571
45846
  async function checkEmbeddingConfig(magicContextConfigPath) {
@@ -46092,7 +46367,9 @@ async function runDoctor2(options = {}) {
46092
46367
  warnCount++;
46093
46368
  else
46094
46369
  passCount++;
46095
- const dbPath = join29(getMagicContextStorageDir(), "context.db");
46370
+ const storage = getMagicContextStorageResolution();
46371
+ const dbPath = join29(storage.path, "context.db");
46372
+ log2.info(`Shared storage: ${storage.path} (source: ${storage.source})`);
46096
46373
  if (!existsSync32(dbPath)) {
46097
46374
  log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
46098
46375
  } else {
@@ -46298,10 +46575,8 @@ var init_doctor_opencode = __esm(async () => {
46298
46575
  });
46299
46576
 
46300
46577
  // src/lib/diagnostics-pi.ts
46301
- import { createHash as createHash5 } from "node:crypto";
46302
46578
  import { existsSync as existsSync33, readdirSync as readdirSync5, readFileSync as readFileSync23, statSync as statSync14 } from "node:fs";
46303
46579
  import { createRequire as createRequire6 } from "node:module";
46304
- import { homedir as homedir18, userInfo as userInfo2 } from "node:os";
46305
46580
  import { join as join30 } from "node:path";
46306
46581
  function getSelfVersion3() {
46307
46582
  const req = createRequire6(import.meta.url);
@@ -46322,51 +46597,11 @@ function fileSize2(path6) {
46322
46597
  return 0;
46323
46598
  }
46324
46599
  }
46325
- function escapeRegex3(value) {
46326
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
46327
- }
46328
- function currentUserHash() {
46329
- const username = userInfo2().username || "unknown";
46330
- return createHash5("sha256").update(username).digest("hex").slice(0, 12);
46331
- }
46332
- function redactSecretString(value) {
46333
- return redactSecretText(value).replace(/Bearer\s+[A-Za-z0-9._~+\-/=]+/g, "Bearer <REDACTED>").replace(/sk-[A-Za-z0-9_-]{12,}/g, "sk-<REDACTED>").replace(/api[_-]?key=([^\s&]+)/gi, "api_key=<REDACTED>").replace(/token=([^\s&]+)/gi, "token=<REDACTED>");
46334
- }
46335
46600
  function sanitizeString2(value) {
46336
- const home = process.env.HOME || homedir18();
46337
- const username = userInfo2().username;
46338
- const userHash = `<USER:${currentUserHash()}>`;
46339
- let sanitized = redactSecretString(value);
46340
- if (home) {
46341
- sanitized = sanitized.replace(new RegExp(escapeRegex3(home), "g"), "<HOME>");
46342
- }
46343
- sanitized = sanitized.replace(/\/Users\/[^/]+\//g, `/Users/${userHash}/`);
46344
- sanitized = sanitized.replace(/\/home\/[^/]+\//g, `/home/${userHash}/`);
46345
- sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, `C:\\Users\\${userHash}\\`);
46346
- if (username) {
46347
- sanitized = sanitized.replace(new RegExp(escapeRegex3(username), "g"), userHash);
46348
- }
46349
- return sanitized;
46350
- }
46351
- function shouldRedactKey(key) {
46352
- return /api[_-]?key|token|secret|password|authorization|cookie/i.test(key);
46601
+ return sanitizeDiagnosticText(value);
46353
46602
  }
46354
- function sanitizeValue2(value, key = "") {
46355
- if (value === null || typeof value === "number" || typeof value === "boolean")
46356
- return value;
46357
- if (shouldRedactKey(key))
46358
- return "<REDACTED>";
46359
- if (typeof value === "string")
46360
- return sanitizeString2(value);
46361
- if (Array.isArray(value))
46362
- return value.map((entry) => sanitizeValue2(entry));
46363
- if (value && typeof value === "object") {
46364
- return Object.fromEntries(Object.entries(value).map(([entryKey, entry]) => [
46365
- entryKey,
46366
- sanitizeValue2(entry, entryKey)
46367
- ]));
46368
- }
46369
- return value;
46603
+ function sanitizeValue2(value) {
46604
+ return sanitizeConfigValue(value);
46370
46605
  }
46371
46606
  function readJsonc(path6) {
46372
46607
  if (!existsSync33(path6))
@@ -46551,7 +46786,8 @@ async function collectDiagnostics2(cwd = process.cwd()) {
46551
46786
  const userConfigPath = getPiUserConfigPath();
46552
46787
  const projectConfigPath = getProjectConfigPath(cwd);
46553
46788
  const loaded = loadPiConfig({ cwd });
46554
- const storageDirPath = getMagicContextStorageDir();
46789
+ const storageResolution = getMagicContextStorageResolution();
46790
+ const storageDirPath = storageResolution.path;
46555
46791
  const dbPath = join30(storageDirPath, "context.db");
46556
46792
  const logPath = getMagicContextLogPath2("pi");
46557
46793
  const logFileSize = existsSync33(logPath) ? statSync14(logPath).size : 0;
@@ -46585,6 +46821,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
46585
46821
  loadWarnings: loaded.warnings.map(sanitizeString2),
46586
46822
  storageDir: {
46587
46823
  path: storageDirPath,
46824
+ source: storageResolution.source,
46588
46825
  exists: existsSync33(storageDirPath),
46589
46826
  contextDbSizeBytes: fileSize2(dbPath)
46590
46827
  },
@@ -46615,6 +46852,7 @@ function renderDiagnosticsMarkdown2(report) {
46615
46852
  const settings2 = sanitizeValue2(report.settings);
46616
46853
  const storage = {
46617
46854
  path: sanitizeString2(report.storageDir.path),
46855
+ source: report.storageDir.source ?? "unknown",
46618
46856
  exists: report.storageDir.exists,
46619
46857
  context_db_size: formatBytes2(report.storageDir.contextDbSizeBytes)
46620
46858
  };
@@ -46774,8 +47012,8 @@ var init_logs_pi = __esm(() => {
46774
47012
  import { execFileSync as execFileSync6, spawnSync as spawnSync8 } from "node:child_process";
46775
47013
  import { existsSync as existsSync34, mkdirSync as mkdirSync11, readdirSync as readdirSync6, readFileSync as readFileSync25, rmSync as rmSync4, statSync as statSync15 } from "node:fs";
46776
47014
  import { createRequire as createRequire7 } from "node:module";
46777
- import { homedir as homedir19 } from "node:os";
46778
- import { dirname as dirname18, isAbsolute as isAbsolute5, join as join32 } from "node:path";
47015
+ import { homedir as homedir18 } from "node:os";
47016
+ import { dirname as dirname18, isAbsolute as isAbsolute6, join as join32 } from "node:path";
46779
47017
  function depsFrom(options) {
46780
47018
  return {
46781
47019
  ...DEFAULT_DEPS5,
@@ -46897,7 +47135,7 @@ function piPluginDirCandidates(packages, cwd) {
46897
47135
  const spec = typeof entry === "string" ? entry.trim() : "";
46898
47136
  if (!spec || spec.startsWith("npm:"))
46899
47137
  continue;
46900
- const resolved = isAbsolute5(spec) ? spec : join32(agentDir, spec);
47138
+ const resolved = isAbsolute6(spec) ? spec : join32(agentDir, spec);
46901
47139
  dirs.push(resolved);
46902
47140
  }
46903
47141
  dirs.push(join32(agentDir, "npm", "node_modules", PACKAGE_NAME2));
@@ -46994,7 +47232,7 @@ function pinnedVersionFromPackageSpecifier(specifier) {
46994
47232
  }
46995
47233
  function cacheRoots(cwd) {
46996
47234
  const home = process.env.HOME?.trim();
46997
- const cacheHome = process.env.XDG_CACHE_HOME || join32(home || homedir19(), ".cache");
47235
+ const cacheHome = process.env.XDG_CACHE_HOME || join32(home || homedir18(), ".cache");
46998
47236
  const piCacheRoot = getPiCacheRoot();
46999
47237
  return [
47000
47238
  join32(piCacheRoot, "extensions"),
@@ -47149,8 +47387,10 @@ async function runHealthChecks2(options) {
47149
47387
  } else if (historianModel.startsWith("github-copilot/") && historianThinkingLevel) {
47150
47388
  add2(results, "pass", `historian.model "${historianModel}" has thinking_level "${historianThinkingLevel}" configured`);
47151
47389
  }
47152
- const storageDir = getMagicContextStorageDir();
47390
+ const storage = getMagicContextStorageResolution();
47391
+ const storageDir = storage.path;
47153
47392
  const dbPath = join32(storageDir, "context.db");
47393
+ add2(results, "info", `Shared storage: ${storageDir} (source: ${storage.source})`);
47154
47394
  const existedBeforeOpen = existsSync34(dbPath);
47155
47395
  if (existedBeforeOpen)
47156
47396
  add2(results, "pass", `Shared context DB exists at ${dbPath}`);
@@ -47249,7 +47489,12 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
47249
47489
  for (const pluginDir of piPluginDirCandidates(packages, options.cwd)) {
47250
47490
  const runtime = checkLocalEmbeddingRuntimeByResolution(pluginDir);
47251
47491
  if (runtime.state === "ok") {
47252
- add2(results, "pass", `Embedding provider: ${loadedConfig.config.embedding.provider} (native runtime present)`);
47492
+ add2(results, "pass", `Embedding provider: ${loadedConfig.config.embedding.provider} (native runtime OK)`);
47493
+ runtimeReported = true;
47494
+ break;
47495
+ }
47496
+ if (runtime.state === "wasm-fallback") {
47497
+ add2(results, "warn", formatLocalEmbeddingRuntimeWasmFallback(runtime));
47253
47498
  runtimeReported = true;
47254
47499
  break;
47255
47500
  }