@cortexkit/pi-magic-context 0.36.0 → 0.37.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.
@@ -5,7 +5,7 @@ import {
5
5
  getMagicContextStorageDir,
6
6
  log,
7
7
  sessionLog
8
- } from "./index-npnqc564.js";
8
+ } from "./index-hk6sj7dn.js";
9
9
  import {
10
10
  __commonJS,
11
11
  __export,
@@ -7696,10 +7696,10 @@ var require_stringify = __commonJS((exports, module) => {
7696
7696
  replacer = null;
7697
7697
  indent = EMPTY;
7698
7698
  };
7699
- var join6 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
7699
+ var join8 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
7700
7700
  var join_content = (inside, value, gap) => {
7701
7701
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
7702
- return join6(comment, inside, gap);
7702
+ return join8(comment, inside, gap);
7703
7703
  };
7704
7704
  var stringify_string = (holder, key, value) => {
7705
7705
  const raw = get_raw_string_literal(holder, key);
@@ -7721,13 +7721,13 @@ var require_stringify = __commonJS((exports, module) => {
7721
7721
  if (i !== 0) {
7722
7722
  inside += COMMA;
7723
7723
  }
7724
- const before = join6(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
7724
+ const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
7725
7725
  inside += before || LF + deeper_gap;
7726
7726
  inside += stringify(i, value, deeper_gap) || STR_NULL;
7727
7727
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
7728
7728
  after_comma = process_comments(value, AFTER(i), deeper_gap);
7729
7729
  }
7730
- inside += join6(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7730
+ inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7731
7731
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
7732
7732
  };
7733
7733
  var object_stringify = (value, gap) => {
@@ -7748,13 +7748,13 @@ var require_stringify = __commonJS((exports, module) => {
7748
7748
  inside += COMMA;
7749
7749
  }
7750
7750
  first = false;
7751
- const before = join6(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
7751
+ const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
7752
7752
  inside += before || LF + deeper_gap;
7753
7753
  inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
7754
7754
  after_comma = process_comments(value, AFTER(key), deeper_gap);
7755
7755
  };
7756
7756
  keys.forEach(iteratee);
7757
- inside += join6(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7757
+ inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7758
7758
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
7759
7759
  };
7760
7760
  function stringify(key, holder, gap) {
@@ -8292,6 +8292,7 @@ import path from "node:path";
8292
8292
  var GIT_TIMEOUT_MS = 5000;
8293
8293
  var TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
8294
8294
  var identityCache = new Map;
8295
+ var linkedGitWorktreeCache = new Map;
8295
8296
  var lastKnownGitIdentityCache = new Map;
8296
8297
  var directoryFallbackCache = new Map;
8297
8298
  var transientFailureCooldown = new Map;
@@ -8497,7 +8498,12 @@ function recordDubiousOwnershipFallback(canonical) {
8497
8498
  log(`[magic-context] ${formatDubiousOwnershipWarning(canonical)}`);
8498
8499
  }
8499
8500
  function canonicalUserHomeDirectory() {
8500
- return realpathSync.native(userHomeDirectoryForIdentity());
8501
+ const homeDirectory = userHomeDirectoryForIdentity();
8502
+ try {
8503
+ return realpathSync.native(homeDirectory);
8504
+ } catch {
8505
+ return homeDirectory;
8506
+ }
8501
8507
  }
8502
8508
  function isUserHomeDirectory(directory) {
8503
8509
  try {
@@ -8648,6 +8654,363 @@ function scheduleAfterBootQuiet(task, additionalDelayMs = 0) {
8648
8654
  return timer;
8649
8655
  }
8650
8656
 
8657
+ // ../plugin/src/hooks/magic-context/read-session-formatting.ts
8658
+ import { existsSync as existsSync3, readFileSync as readFileSync2, realpathSync as realpathSync2 } from "node:fs";
8659
+ import { createRequire } from "node:module";
8660
+ import { homedir as homedir3 } from "node:os";
8661
+ import { dirname as dirname2, join as join2, resolve } from "node:path";
8662
+ import { pathToFileURL } from "node:url";
8663
+
8664
+ // ../plugin/src/shared/commit-detection.ts
8665
+ var HASH_HEX = "[0-9a-f]{7,12}";
8666
+ var COMMIT_HASH_TEST_PATTERN = new RegExp(`\\b${HASH_HEX}\\b`, "i");
8667
+ var COMMIT_VERB_PATTERN = /\b(?:commit(?:ted|ting|s)?|cherry-?pick(?:ed|ing|s)?|merge[ds]?|merging|rebas(?:e|ed|es|ing))\b/i;
8668
+ function textMentionsRecentCommit(text) {
8669
+ return COMMIT_HASH_TEST_PATTERN.test(text) && COMMIT_VERB_PATTERN.test(text);
8670
+ }
8671
+ function createCommitHashExtractPattern() {
8672
+ return new RegExp(`\`?\\b(${HASH_HEX})\\b\`?`, "gi");
8673
+ }
8674
+
8675
+ // ../plugin/src/shared/internal-initiator-marker.ts
8676
+ var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
8677
+
8678
+ // ../plugin/src/shared/system-directive.ts
8679
+ var SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: MAGIC-CONTEXT";
8680
+ function isSystemDirective(text) {
8681
+ return text.trimStart().startsWith(SYSTEM_DIRECTIVE_PREFIX);
8682
+ }
8683
+ function removeSystemReminders(text) {
8684
+ return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, "").trim();
8685
+ }
8686
+
8687
+ // ../plugin/src/hooks/magic-context/read-session-formatting.ts
8688
+ var MAX_COMMITS_PER_BLOCK = 5;
8689
+ function hasMeaningfulUserText(parts) {
8690
+ for (const part of parts) {
8691
+ if (part === null || typeof part !== "object")
8692
+ continue;
8693
+ const candidate = part;
8694
+ if (candidate.type !== "text" || typeof candidate.text !== "string")
8695
+ continue;
8696
+ if (candidate.ignored === true)
8697
+ continue;
8698
+ const cleaned = removeSystemReminders(candidate.text).replace(OMO_INTERNAL_INITIATOR_MARKER, "").trim();
8699
+ if (!cleaned)
8700
+ continue;
8701
+ if (isSystemDirective(cleaned))
8702
+ continue;
8703
+ return true;
8704
+ }
8705
+ return false;
8706
+ }
8707
+ function extractTexts(parts) {
8708
+ const texts = [];
8709
+ for (const part of parts) {
8710
+ if (part === null || typeof part !== "object")
8711
+ continue;
8712
+ const p = part;
8713
+ if (p.type === "text" && typeof p.text === "string" && p.text.trim().length > 0) {
8714
+ texts.push(p.text.trim());
8715
+ }
8716
+ }
8717
+ return texts;
8718
+ }
8719
+ function extractToolCallSummaries(parts) {
8720
+ const summaries = [];
8721
+ for (const part of parts) {
8722
+ if (part === null || typeof part !== "object")
8723
+ continue;
8724
+ const p = part;
8725
+ if (p.type !== "tool" || typeof p.tool !== "string")
8726
+ continue;
8727
+ const state = p.state;
8728
+ if (!state || typeof state !== "object")
8729
+ continue;
8730
+ const input = state.input;
8731
+ const metadata = state.metadata;
8732
+ const description = input && typeof input.description === "string" && input.description || metadata && typeof metadata.description === "string" && metadata.description;
8733
+ if (description) {
8734
+ summaries.push(`TC: ${description}`);
8735
+ continue;
8736
+ }
8737
+ const toolName = p.tool;
8738
+ const keyArg = extractKeyArg(toolName, input);
8739
+ summaries.push(keyArg ? `TC: ${toolName}(${keyArg})` : `TC: ${toolName}`);
8740
+ }
8741
+ return summaries;
8742
+ }
8743
+ function extractKeyArg(_toolName, input) {
8744
+ if (!input)
8745
+ return null;
8746
+ if (typeof input.filePath === "string")
8747
+ return truncateArg(input.filePath);
8748
+ if (typeof input.path === "string")
8749
+ return truncateArg(input.path);
8750
+ if (typeof input.pattern === "string")
8751
+ return truncateArg(input.pattern);
8752
+ if (typeof input.query === "string")
8753
+ return truncateArg(input.query);
8754
+ if (typeof input.symbol === "string")
8755
+ return input.symbol;
8756
+ if (typeof input.module === "string")
8757
+ return input.module;
8758
+ if (typeof input.action === "string")
8759
+ return input.action;
8760
+ return null;
8761
+ }
8762
+ function truncateArg(value, maxLen = 60) {
8763
+ if (value.length <= maxLen)
8764
+ return value;
8765
+ return `${value.slice(0, maxLen)}…`;
8766
+ }
8767
+ var TOKENIZER_PACKAGE_DIRS = [
8768
+ ["@cortexkit", "opencode-magic-context"],
8769
+ ["@cortexkit", "pi-magic-context"]
8770
+ ];
8771
+ var tokenizer;
8772
+ var tokenizerLoadAttempted = false;
8773
+ var tokenizerLoadPromise;
8774
+ var tokenizerWarningSent = false;
8775
+ function tokenizerPackageRoots() {
8776
+ const cwd = process.cwd();
8777
+ const openCodeCache = join2(process.env.XDG_CACHE_HOME ?? join2(homedir3(), ".cache"), "opencode");
8778
+ const roots = [cwd, openCodeCache];
8779
+ const candidates = [];
8780
+ for (const root of roots) {
8781
+ for (const packageDir of TOKENIZER_PACKAGE_DIRS) {
8782
+ candidates.push(join2(root, "node_modules", ...packageDir, "node_modules", "ai-tokenizer"));
8783
+ }
8784
+ candidates.push(join2(root, "node_modules", "ai-tokenizer"));
8785
+ }
8786
+ let ancestor = process.argv[1] ? dirname2(resolve(process.argv[1])) : cwd;
8787
+ while (true) {
8788
+ candidates.push(join2(ancestor, "node_modules", "ai-tokenizer"));
8789
+ const parent = dirname2(ancestor);
8790
+ if (parent === ancestor)
8791
+ break;
8792
+ ancestor = parent;
8793
+ }
8794
+ return [...new Set(candidates)];
8795
+ }
8796
+ function packageImportTarget(value) {
8797
+ if (typeof value === "string")
8798
+ return value;
8799
+ if (!value || typeof value !== "object")
8800
+ return;
8801
+ const conditions = value;
8802
+ return packageImportTarget(conditions.import) ?? packageImportTarget(conditions.default);
8803
+ }
8804
+ function findTokenizerImportPaths() {
8805
+ for (const packageRoot of tokenizerPackageRoots()) {
8806
+ const packageJsonPath = join2(packageRoot, "package.json");
8807
+ if (!existsSync3(packageJsonPath))
8808
+ continue;
8809
+ try {
8810
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
8811
+ const tokenizerTarget = packageImportTarget(packageJson.exports?.["."]) ?? (typeof packageJson.module === "string" ? packageJson.module : undefined) ?? (typeof packageJson.main === "string" ? packageJson.main : undefined);
8812
+ const encodingTarget = packageImportTarget(packageJson.exports?.["./encoding/claude"]);
8813
+ if (!tokenizerTarget || !encodingTarget)
8814
+ continue;
8815
+ return {
8816
+ tokenizerPath: realpathSync2(join2(packageRoot, tokenizerTarget)),
8817
+ encodingPath: realpathSync2(join2(packageRoot, encodingTarget))
8818
+ };
8819
+ } catch {}
8820
+ }
8821
+ return;
8822
+ }
8823
+ function constructTokenizer(tokenizerModule, claudeEncoding) {
8824
+ const typedModule = tokenizerModule;
8825
+ const Tokenizer = typedModule.default ?? typedModule.Tokenizer;
8826
+ if (!Tokenizer) {
8827
+ throw new Error("ai-tokenizer does not expose a Tokenizer constructor");
8828
+ }
8829
+ return new Tokenizer(claudeEncoding);
8830
+ }
8831
+ function loadTokenizer() {
8832
+ const requireFromThisModule = createRequire(import.meta.url);
8833
+ return constructTokenizer(requireFromThisModule("ai-" + "tokenizer"), requireFromThisModule("ai-tokenizer/encoding/" + "claude"));
8834
+ }
8835
+ async function loadTokenizerFromInstalledPackage() {
8836
+ const installedPaths = findTokenizerImportPaths();
8837
+ if (!installedPaths) {
8838
+ throw new Error("ai-tokenizer was not found under the project, runtime, or OpenCode cache node_modules roots");
8839
+ }
8840
+ const [tokenizerModule, claudeEncoding] = await Promise.all([
8841
+ import(pathToFileURL(installedPaths.tokenizerPath).href),
8842
+ import(pathToFileURL(installedPaths.encodingPath).href)
8843
+ ]);
8844
+ return constructTokenizer(tokenizerModule, claudeEncoding);
8845
+ }
8846
+ function warnTokenizerFallback(error) {
8847
+ if (tokenizerWarningSent)
8848
+ return;
8849
+ tokenizerWarningSent = true;
8850
+ const reason = error instanceof Error ? error.message : String(error);
8851
+ console.warn("[magic-context] ai-tokenizer is unavailable; using approximate character-based token counts for this process. Token budgets, persisted per-message counts, and protected-tail/compartment boundaries may be less accurate until restart:", reason);
8852
+ }
8853
+ async function preloadTokenizer() {
8854
+ if (tokenizer)
8855
+ return true;
8856
+ if (tokenizerLoadAttempted)
8857
+ return false;
8858
+ if (tokenizerLoadPromise)
8859
+ return tokenizerLoadPromise;
8860
+ tokenizerLoadPromise = (async () => {
8861
+ try {
8862
+ try {
8863
+ tokenizer = loadTokenizer();
8864
+ } catch {
8865
+ tokenizer = await loadTokenizerFromInstalledPackage();
8866
+ }
8867
+ tokenizerLoadAttempted = true;
8868
+ return true;
8869
+ } catch (error) {
8870
+ tokenizerLoadAttempted = true;
8871
+ warnTokenizerFallback(error);
8872
+ return false;
8873
+ } finally {
8874
+ tokenizerLoadPromise = undefined;
8875
+ }
8876
+ })();
8877
+ return tokenizerLoadPromise;
8878
+ }
8879
+ function getTokenizer() {
8880
+ if (tokenizer || tokenizerLoadAttempted)
8881
+ return tokenizer;
8882
+ tokenizerLoadAttempted = true;
8883
+ try {
8884
+ tokenizer = loadTokenizer();
8885
+ } catch (error) {
8886
+ warnTokenizerFallback(error);
8887
+ }
8888
+ return tokenizer;
8889
+ }
8890
+ function estimateTokensHeuristically(text) {
8891
+ return Math.ceil(text.length / 3.5);
8892
+ }
8893
+ function estimateTokens(text) {
8894
+ if (!text)
8895
+ return 0;
8896
+ const activeTokenizer = getTokenizer();
8897
+ if (!activeTokenizer)
8898
+ return estimateTokensHeuristically(text);
8899
+ try {
8900
+ return activeTokenizer.encode(text, "all").length;
8901
+ } catch (error) {
8902
+ tokenizer = undefined;
8903
+ tokenizerLoadAttempted = true;
8904
+ warnTokenizerFallback(error);
8905
+ return estimateTokensHeuristically(text);
8906
+ }
8907
+ }
8908
+ function normalizeText(text) {
8909
+ return text.replace(/\s+/g, " ").trim();
8910
+ }
8911
+ function compactRole(role) {
8912
+ if (role === "assistant")
8913
+ return "A";
8914
+ if (role === "user")
8915
+ return "U";
8916
+ return role.slice(0, 1).toUpperCase() || "M";
8917
+ }
8918
+ function formatBlock(block) {
8919
+ const range = block.startOrdinal === block.endOrdinal ? `[${block.startOrdinal}]` : `[${block.startOrdinal}-${block.endOrdinal}]`;
8920
+ const commitSuffix = block.commitHashes.length > 0 ? ` commits: ${block.commitHashes.join(", ")}` : "";
8921
+ return `${range} ${block.role}:${commitSuffix} ${block.parts.join(" / ")}`;
8922
+ }
8923
+ function extractCommitHashes(text) {
8924
+ const hashes = [];
8925
+ const seen = new Set;
8926
+ for (const match of text.matchAll(createCommitHashExtractPattern())) {
8927
+ const hash = match[1]?.toLowerCase();
8928
+ if (!hash || seen.has(hash))
8929
+ continue;
8930
+ seen.add(hash);
8931
+ hashes.push(hash);
8932
+ if (hashes.length >= MAX_COMMITS_PER_BLOCK)
8933
+ break;
8934
+ }
8935
+ return hashes;
8936
+ }
8937
+ function compactTextForSummary(text, role) {
8938
+ const commitHashes = role === "assistant" ? extractCommitHashes(text) : [];
8939
+ if (commitHashes.length === 0 || !COMMIT_VERB_PATTERN.test(text)) {
8940
+ return { text, commitHashes };
8941
+ }
8942
+ const withoutHashes = text.replace(createCommitHashExtractPattern(), "").replace(/\(\s*\)/g, "").replace(/\s+,/g, ",").replace(/,\s*,+/g, ", ").replace(/\s{2,}/g, " ").replace(/\s+([,.;:])/g, "$1").trim();
8943
+ return {
8944
+ text: withoutHashes.length > 0 ? withoutHashes : text,
8945
+ commitHashes
8946
+ };
8947
+ }
8948
+ function mergeCommitHashes(existing, next) {
8949
+ if (next.length === 0)
8950
+ return existing;
8951
+ const merged = [...existing];
8952
+ for (const hash of next) {
8953
+ if (merged.includes(hash))
8954
+ continue;
8955
+ merged.push(hash);
8956
+ if (merged.length >= MAX_COMMITS_PER_BLOCK)
8957
+ break;
8958
+ }
8959
+ return merged;
8960
+ }
8961
+
8962
+ // ../plugin/src/shared/harness-provider-map.ts
8963
+ var CANONICAL_TO_PI_PROVIDER = {
8964
+ openai: "openai-codex",
8965
+ google: "google-antigravity"
8966
+ };
8967
+ var PI_TO_CANONICAL_PROVIDER = {
8968
+ "openai-codex": "openai",
8969
+ "google-antigravity": "google"
8970
+ };
8971
+ var CANONICAL_TO_OMP_PROVIDER = {
8972
+ openai: "openai-codex",
8973
+ google: "google-antigravity"
8974
+ };
8975
+ var OMP_TO_CANONICAL_PROVIDER = {
8976
+ "openai-codex": "openai",
8977
+ "google-antigravity": "google"
8978
+ };
8979
+ function remapProviderPrefix(ref, map) {
8980
+ if (typeof ref !== "string")
8981
+ return ref;
8982
+ const slash = ref.indexOf("/");
8983
+ if (slash <= 0)
8984
+ return ref;
8985
+ const provider = ref.slice(0, slash);
8986
+ if (!Object.hasOwn(map, provider))
8987
+ return ref;
8988
+ return `${map[provider]}${ref.slice(slash)}`;
8989
+ }
8990
+ function piModelRefToCanonical(ref) {
8991
+ return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
8992
+ }
8993
+ function resolveModelRefForPi(ref) {
8994
+ return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
8995
+ }
8996
+ function modelRefLookupOrder(ref) {
8997
+ const canonical = piModelRefToCanonical(ompModelRefToCanonical(ref));
8998
+ return [
8999
+ ...new Set([
9000
+ canonical,
9001
+ ref,
9002
+ resolveModelRefForPi(canonical),
9003
+ resolveModelRefForOmp(canonical)
9004
+ ])
9005
+ ];
9006
+ }
9007
+ function ompModelRefToCanonical(ref) {
9008
+ return remapProviderPrefix(ref, OMP_TO_CANONICAL_PROVIDER);
9009
+ }
9010
+ function resolveModelRefForOmp(ref) {
9011
+ return remapProviderPrefix(ompModelRefToCanonical(ref), CANONICAL_TO_OMP_PROVIDER);
9012
+ }
9013
+
8651
9014
  // ../plugin/src/shared/storage-permissions.ts
8652
9015
  var enforcePrivateStoragePermissions = true;
8653
9016
  function setStoragePrivatePermissionEnforcement(enforce) {
@@ -8662,14 +9025,14 @@ import {
8662
9025
  chmodSync,
8663
9026
  copyFileSync,
8664
9027
  cpSync,
8665
- existsSync as existsSync4,
9028
+ existsSync as existsSync5,
8666
9029
  mkdirSync as mkdirSync2,
8667
9030
  readdirSync,
8668
- readFileSync as readFileSync3,
9031
+ readFileSync as readFileSync4,
8669
9032
  statSync as statSync3,
8670
9033
  unlinkSync as unlinkSync2
8671
9034
  } from "node:fs";
8672
- import { basename as basename2, dirname as dirname2, join as join3 } from "node:path";
9035
+ import { basename as basename2, dirname as dirname3, join as join4 } from "node:path";
8673
9036
 
8674
9037
  // ../plugin/src/shared/error-message.ts
8675
9038
  function getErrorMessage(error) {
@@ -8749,23 +9112,28 @@ function safeString(value) {
8749
9112
 
8750
9113
  // ../plugin/src/shared/rpc-utils.ts
8751
9114
  import { execFileSync as execFileSync2 } from "node:child_process";
8752
- import { readFileSync as readFileSync2 } from "node:fs";
9115
+ import { readFileSync as readFileSync3 } from "node:fs";
8753
9116
  function isPidAlive(pid) {
8754
9117
  if (!Number.isInteger(pid) || pid <= 0)
8755
- return false;
9118
+ return "dead";
9119
+ if (rpcIdentityPlatform === "win32")
9120
+ return readWindowsProcess(pid).state;
8756
9121
  try {
8757
- process.kill(pid, 0);
8758
- return true;
8759
- } catch (err) {
8760
- return err.code === "EPERM";
9122
+ rpcIdentityProcessKill(pid, 0);
9123
+ return "alive";
9124
+ } catch (error) {
9125
+ return error.code === "ESRCH" ? "dead" : "inconclusive";
8761
9126
  }
8762
9127
  }
8763
9128
  var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000;
8764
9129
  var LINUX_CLOCK_TICKS_PER_SECOND = 100;
8765
9130
  var PS_PROBE_TIMEOUT_MS = 1000;
8766
9131
  var OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
8767
- var rpcIdentityReadFileSync = readFileSync2;
9132
+ var TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
9133
+ var rpcIdentityReadFileSync = readFileSync3;
8768
9134
  var rpcIdentityExecFileSync = execFileSync2;
9135
+ var rpcIdentityProcessKill = process.kill;
9136
+ var rpcProcessListExecFileSync = execFileSync2;
8769
9137
  var rpcIdentityPlatform = process.platform;
8770
9138
  var rpcIdentityNowMs = () => Date.now();
8771
9139
  function parseLinuxProcessStartTime(statContent, uptimeContent) {
@@ -8794,7 +9162,8 @@ function readPsProcessStartTime(pid) {
8794
9162
  try {
8795
9163
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
8796
9164
  encoding: "utf8",
8797
- timeout: PS_PROBE_TIMEOUT_MS
9165
+ timeout: PS_PROBE_TIMEOUT_MS,
9166
+ stdio: ["ignore", "pipe", "pipe"]
8798
9167
  });
8799
9168
  const processStartTime = Date.parse(String(output).trim());
8800
9169
  return Number.isFinite(processStartTime) ? processStartTime : null;
@@ -8802,6 +9171,70 @@ function readPsProcessStartTime(pid) {
8802
9171
  return null;
8803
9172
  }
8804
9173
  }
9174
+ function parseCsvLine(line) {
9175
+ const fields = [];
9176
+ let field = "";
9177
+ let quoted = false;
9178
+ for (let index = 0;index < line.length; index += 1) {
9179
+ const character = line[index];
9180
+ if (character === '"') {
9181
+ if (quoted && line[index + 1] === '"') {
9182
+ field += '"';
9183
+ index += 1;
9184
+ } else {
9185
+ quoted = !quoted;
9186
+ }
9187
+ } else if (character === "," && !quoted) {
9188
+ fields.push(field);
9189
+ field = "";
9190
+ } else {
9191
+ field += character;
9192
+ }
9193
+ }
9194
+ if (quoted)
9195
+ return null;
9196
+ fields.push(field);
9197
+ return fields;
9198
+ }
9199
+ function parseTasklistOutput(output) {
9200
+ const entries = [];
9201
+ let sawHeader = false;
9202
+ for (const rawLine of output.split(/\r?\n/)) {
9203
+ const line = rawLine.trim();
9204
+ if (!line)
9205
+ continue;
9206
+ if (TASKLIST_NO_TASKS_PATTERN.test(line))
9207
+ return [];
9208
+ const fields = parseCsvLine(line);
9209
+ if (!fields)
9210
+ continue;
9211
+ if (fields[1]?.trim().toLowerCase() === "pid") {
9212
+ sawHeader = true;
9213
+ continue;
9214
+ }
9215
+ const pid = Number(fields[1]);
9216
+ if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
9217
+ continue;
9218
+ entries.push({ pid, command: fields[0] });
9219
+ }
9220
+ return entries.length > 0 || sawHeader ? entries : null;
9221
+ }
9222
+ function readWindowsProcess(pid) {
9223
+ try {
9224
+ const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
9225
+ encoding: "utf8",
9226
+ timeout: PS_PROBE_TIMEOUT_MS,
9227
+ stdio: ["ignore", "pipe", "pipe"]
9228
+ });
9229
+ const entries = parseTasklistOutput(String(output));
9230
+ if (entries === null)
9231
+ return { state: "inconclusive" };
9232
+ const process2 = entries.find((entry) => entry.pid === pid);
9233
+ return process2 ? { state: "alive", command: process2.command } : { state: "dead" };
9234
+ } catch {
9235
+ return { state: "inconclusive" };
9236
+ }
9237
+ }
8805
9238
  function readLinuxProcessCommand(pid) {
8806
9239
  try {
8807
9240
  return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
@@ -8813,7 +9246,8 @@ function readPsProcessCommand(pid) {
8813
9246
  try {
8814
9247
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
8815
9248
  encoding: "utf8",
8816
- timeout: PS_PROBE_TIMEOUT_MS
9249
+ timeout: PS_PROBE_TIMEOUT_MS,
9250
+ stdio: ["ignore", "pipe", "pipe"]
8817
9251
  });
8818
9252
  return String(output);
8819
9253
  } catch {
@@ -8826,17 +9260,76 @@ function commandLooksLikeOpenCode(command) {
8826
9260
  }
8827
9261
  function isPidIdentityPlausible(record) {
8828
9262
  if (!Number.isInteger(record.pid) || record.pid <= 0)
8829
- return false;
9263
+ return "implausible";
8830
9264
  if (Number.isFinite(record.started_at) && record.started_at > 0) {
8831
- const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : readPsProcessStartTime(record.pid);
9265
+ const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record.pid);
8832
9266
  if (processStartTime === null)
8833
- return true;
8834
- return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
9267
+ return "inconclusive";
9268
+ return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
8835
9269
  }
8836
- const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : readPsProcessCommand(record.pid);
9270
+ const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record.pid).command ?? null : readPsProcessCommand(record.pid);
8837
9271
  if (command === null)
9272
+ return "inconclusive";
9273
+ return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
9274
+ }
9275
+ function commandLooksLikePi(command) {
9276
+ const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
9277
+ const tokens = normalized.split(/\s+/).filter(Boolean);
9278
+ const executableName = (token) => (token ?? "").split("/").at(-1) ?? "";
9279
+ const first = executableName(tokens[0]).replace(/\.exe$/, "");
9280
+ if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
8838
9281
  return true;
8839
- return commandLooksLikeOpenCode(command);
9282
+ if (["node", "bun", "deno"].includes(first)) {
9283
+ const script = executableName(tokens[1]);
9284
+ return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
9285
+ }
9286
+ return false;
9287
+ }
9288
+ function inspectLivePiProcesses() {
9289
+ if (false) {}
9290
+ try {
9291
+ const isWindows = rpcIdentityPlatform === "win32";
9292
+ const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
9293
+ encoding: "utf8",
9294
+ timeout: PS_PROBE_TIMEOUT_MS,
9295
+ stdio: ["ignore", "pipe", "pipe"]
9296
+ }));
9297
+ const pids = new Set;
9298
+ if (isWindows) {
9299
+ const entries = parseTasklistOutput(output);
9300
+ if (entries === null) {
9301
+ return {
9302
+ state: "unreadable",
9303
+ processIds: [],
9304
+ error: "tasklist output unavailable"
9305
+ };
9306
+ }
9307
+ for (const entry of entries) {
9308
+ if (entry.pid === process.pid)
9309
+ continue;
9310
+ if (commandLooksLikePi(entry.command))
9311
+ pids.add(entry.pid);
9312
+ }
9313
+ } else {
9314
+ for (const line of output.split(/\r?\n/)) {
9315
+ const match = /^\s*(\d+)\s+(.+)$/.exec(line);
9316
+ if (!match)
9317
+ continue;
9318
+ const pid = Number(match[1]);
9319
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
9320
+ continue;
9321
+ if (commandLooksLikePi(match[2]))
9322
+ pids.add(pid);
9323
+ }
9324
+ }
9325
+ return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
9326
+ } catch (error) {
9327
+ return {
9328
+ state: "unreadable",
9329
+ processIds: [],
9330
+ error: error instanceof Error ? error.message : String(error)
9331
+ };
9332
+ }
8840
9333
  }
8841
9334
  function parseRpcPortFile(content, fallbackPid = 0) {
8842
9335
  const trimmed = content.trim();
@@ -9282,6 +9775,8 @@ function healAllNullColumns(db) {
9282
9775
  ["stripped_placeholder_ids", ""],
9283
9776
  ["stale_reduce_stripped_ids", ""],
9284
9777
  ["processed_image_stripped_ids", ""],
9778
+ ["merged_reasoning_stripped_ids", ""],
9779
+ ["trailing_blank_decisions", ""],
9285
9780
  ["memory_block_cache", ""],
9286
9781
  ["memory_block_ids", ""],
9287
9782
  ["compaction_marker_state", ""],
@@ -9874,6 +10369,7 @@ var MIGRATIONS = [
9874
10369
  status TEXT NOT NULL DEFAULT 'active',
9875
10370
  promoted_at INTEGER NOT NULL,
9876
10371
  source_candidate_ids TEXT DEFAULT '[]',
10372
+ source_candidate_provenance TEXT,
9877
10373
  created_at INTEGER NOT NULL,
9878
10374
  updated_at INTEGER NOT NULL
9879
10375
  );
@@ -10900,6 +11396,7 @@ var MIGRATIONS = [
10900
11396
  last_observed_at INTEGER,
10901
11397
  answer_refreshed_at INTEGER,
10902
11398
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
11399
+ source_candidate_provenance TEXT,
10903
11400
  created_at INTEGER NOT NULL,
10904
11401
  updated_at INTEGER NOT NULL
10905
11402
  );
@@ -11709,6 +12206,37 @@ var MIGRATIONS = [
11709
12206
  ensureColumn(db, "notes", "compiled_at", "INTEGER");
11710
12207
  ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
11711
12208
  }
12209
+ },
12210
+ {
12211
+ version: 77,
12212
+ description: "persist scoped provenance for promoted user memories and primers",
12213
+ up(db) {
12214
+ if (tableExists2(db, "user_memories")) {
12215
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
12216
+ }
12217
+ if (tableExists2(db, "primers")) {
12218
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
12219
+ }
12220
+ }
12221
+ },
12222
+ {
12223
+ version: 78,
12224
+ description: "add migration_pending journal for crash-safe cross-harness session migration",
12225
+ up(db) {
12226
+ db.exec(`
12227
+ CREATE TABLE IF NOT EXISTS migration_pending (
12228
+ migration_key TEXT PRIMARY KEY,
12229
+ source_session_id TEXT NOT NULL,
12230
+ target_harness TEXT NOT NULL,
12231
+ pi_session_id TEXT NOT NULL,
12232
+ final_path TEXT NOT NULL,
12233
+ stage_path TEXT NOT NULL,
12234
+ content_sha256 TEXT NOT NULL,
12235
+ phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
12236
+ created_at INTEGER NOT NULL
12237
+ );
12238
+ `);
12239
+ }
11712
12240
  }
11713
12241
  ];
11714
12242
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -11803,7 +12331,7 @@ function runMigrations(db) {
11803
12331
  }
11804
12332
  async function runMigrationsWithRetry(db, options = {}) {
11805
12333
  const retryDelaysMs = options.retryDelaysMs ?? MIGRATION_LOCK_RETRY_DELAYS_MS;
11806
- const sleep = options.sleep ?? ((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));
12334
+ const sleep = options.sleep ?? ((delayMs) => new Promise((resolve2) => setTimeout(resolve2, delayMs)));
11807
12335
  const totalAttempts = retryDelaysMs.length + 1;
11808
12336
  for (let attempt = 1;attempt <= totalAttempts; attempt += 1) {
11809
12337
  log(`[migrations] migration lock check attempt ${attempt}/${totalAttempts}`);
@@ -11822,184 +12350,6 @@ async function runMigrationsWithRetry(db, options = {}) {
11822
12350
  }
11823
12351
  }
11824
12352
 
11825
- // ../plugin/src/hooks/magic-context/read-session-formatting.ts
11826
- import { createRequire } from "node:module";
11827
-
11828
- // ../plugin/src/shared/commit-detection.ts
11829
- var HASH_HEX = "[0-9a-f]{7,12}";
11830
- var COMMIT_HASH_TEST_PATTERN = new RegExp(`\\b${HASH_HEX}\\b`, "i");
11831
- var COMMIT_VERB_PATTERN = /\b(?:commit(?:ted|ting|s)?|cherry-?pick(?:ed|ing|s)?|merge[ds]?|merging|rebas(?:e|ed|es|ing))\b/i;
11832
- function textMentionsRecentCommit(text) {
11833
- return COMMIT_HASH_TEST_PATTERN.test(text) && COMMIT_VERB_PATTERN.test(text);
11834
- }
11835
- function createCommitHashExtractPattern() {
11836
- return new RegExp(`\`?\\b(${HASH_HEX})\\b\`?`, "gi");
11837
- }
11838
-
11839
- // ../plugin/src/shared/internal-initiator-marker.ts
11840
- var OMO_INTERNAL_INITIATOR_MARKER = "<!-- OMO_INTERNAL_INITIATOR -->";
11841
-
11842
- // ../plugin/src/shared/system-directive.ts
11843
- var SYSTEM_DIRECTIVE_PREFIX = "[SYSTEM DIRECTIVE: MAGIC-CONTEXT";
11844
- function isSystemDirective(text) {
11845
- return text.trimStart().startsWith(SYSTEM_DIRECTIVE_PREFIX);
11846
- }
11847
- function removeSystemReminders(text) {
11848
- return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/gi, "").trim();
11849
- }
11850
-
11851
- // ../plugin/src/hooks/magic-context/read-session-formatting.ts
11852
- var MAX_COMMITS_PER_BLOCK = 5;
11853
- function hasMeaningfulUserText(parts) {
11854
- for (const part of parts) {
11855
- if (part === null || typeof part !== "object")
11856
- continue;
11857
- const candidate = part;
11858
- if (candidate.type !== "text" || typeof candidate.text !== "string")
11859
- continue;
11860
- if (candidate.ignored === true)
11861
- continue;
11862
- const cleaned = removeSystemReminders(candidate.text).replace(OMO_INTERNAL_INITIATOR_MARKER, "").trim();
11863
- if (!cleaned)
11864
- continue;
11865
- if (isSystemDirective(cleaned))
11866
- continue;
11867
- return true;
11868
- }
11869
- return false;
11870
- }
11871
- function extractTexts(parts) {
11872
- const texts = [];
11873
- for (const part of parts) {
11874
- if (part === null || typeof part !== "object")
11875
- continue;
11876
- const p = part;
11877
- if (p.type === "text" && typeof p.text === "string" && p.text.trim().length > 0) {
11878
- texts.push(p.text.trim());
11879
- }
11880
- }
11881
- return texts;
11882
- }
11883
- function extractToolCallSummaries(parts) {
11884
- const summaries = [];
11885
- for (const part of parts) {
11886
- if (part === null || typeof part !== "object")
11887
- continue;
11888
- const p = part;
11889
- if (p.type !== "tool" || typeof p.tool !== "string")
11890
- continue;
11891
- const state = p.state;
11892
- if (!state || typeof state !== "object")
11893
- continue;
11894
- const input = state.input;
11895
- const metadata = state.metadata;
11896
- const description = input && typeof input.description === "string" && input.description || metadata && typeof metadata.description === "string" && metadata.description;
11897
- if (description) {
11898
- summaries.push(`TC: ${description}`);
11899
- continue;
11900
- }
11901
- const toolName = p.tool;
11902
- const keyArg = extractKeyArg(toolName, input);
11903
- summaries.push(keyArg ? `TC: ${toolName}(${keyArg})` : `TC: ${toolName}`);
11904
- }
11905
- return summaries;
11906
- }
11907
- function extractKeyArg(_toolName, input) {
11908
- if (!input)
11909
- return null;
11910
- if (typeof input.filePath === "string")
11911
- return truncateArg(input.filePath);
11912
- if (typeof input.path === "string")
11913
- return truncateArg(input.path);
11914
- if (typeof input.pattern === "string")
11915
- return truncateArg(input.pattern);
11916
- if (typeof input.query === "string")
11917
- return truncateArg(input.query);
11918
- if (typeof input.symbol === "string")
11919
- return input.symbol;
11920
- if (typeof input.module === "string")
11921
- return input.module;
11922
- if (typeof input.action === "string")
11923
- return input.action;
11924
- return null;
11925
- }
11926
- function truncateArg(value, maxLen = 60) {
11927
- if (value.length <= maxLen)
11928
- return value;
11929
- return `${value.slice(0, maxLen)}…`;
11930
- }
11931
- var requireFromThisModule = createRequire(import.meta.url);
11932
- var tokenizer;
11933
- function getTokenizer() {
11934
- if (tokenizer)
11935
- return tokenizer;
11936
- const tokenizerModule = requireFromThisModule("ai-" + "tokenizer");
11937
- const Tokenizer = tokenizerModule.default ?? tokenizerModule.Tokenizer;
11938
- if (!Tokenizer)
11939
- throw new Error("ai-tokenizer does not expose a Tokenizer constructor");
11940
- const claudeEncoding = requireFromThisModule("ai-tokenizer/encoding/" + "claude");
11941
- tokenizer = new Tokenizer(claudeEncoding);
11942
- return tokenizer;
11943
- }
11944
- function estimateTokens(text) {
11945
- if (!text)
11946
- return 0;
11947
- return getTokenizer().encode(text, "all").length;
11948
- }
11949
- function normalizeText(text) {
11950
- return text.replace(/\s+/g, " ").trim();
11951
- }
11952
- function compactRole(role) {
11953
- if (role === "assistant")
11954
- return "A";
11955
- if (role === "user")
11956
- return "U";
11957
- return role.slice(0, 1).toUpperCase() || "M";
11958
- }
11959
- function formatBlock(block) {
11960
- const range = block.startOrdinal === block.endOrdinal ? `[${block.startOrdinal}]` : `[${block.startOrdinal}-${block.endOrdinal}]`;
11961
- const commitSuffix = block.commitHashes.length > 0 ? ` commits: ${block.commitHashes.join(", ")}` : "";
11962
- return `${range} ${block.role}:${commitSuffix} ${block.parts.join(" / ")}`;
11963
- }
11964
- function extractCommitHashes(text) {
11965
- const hashes = [];
11966
- const seen = new Set;
11967
- for (const match of text.matchAll(createCommitHashExtractPattern())) {
11968
- const hash = match[1]?.toLowerCase();
11969
- if (!hash || seen.has(hash))
11970
- continue;
11971
- seen.add(hash);
11972
- hashes.push(hash);
11973
- if (hashes.length >= MAX_COMMITS_PER_BLOCK)
11974
- break;
11975
- }
11976
- return hashes;
11977
- }
11978
- function compactTextForSummary(text, role) {
11979
- const commitHashes = role === "assistant" ? extractCommitHashes(text) : [];
11980
- if (commitHashes.length === 0 || !COMMIT_VERB_PATTERN.test(text)) {
11981
- return { text, commitHashes };
11982
- }
11983
- const withoutHashes = text.replace(createCommitHashExtractPattern(), "").replace(/\(\s*\)/g, "").replace(/\s+,/g, ",").replace(/,\s*,+/g, ", ").replace(/\s{2,}/g, " ").replace(/\s+([,.;:])/g, "$1").trim();
11984
- return {
11985
- text: withoutHashes.length > 0 ? withoutHashes : text,
11986
- commitHashes
11987
- };
11988
- }
11989
- function mergeCommitHashes(existing, next) {
11990
- if (next.length === 0)
11991
- return existing;
11992
- const merged = [...existing];
11993
- for (const hash of next) {
11994
- if (merged.includes(hash))
11995
- continue;
11996
- merged.push(hash);
11997
- if (merged.length >= MAX_COMMITS_PER_BLOCK)
11998
- break;
11999
- }
12000
- return merged;
12001
- }
12002
-
12003
12353
  // ../plugin/src/shared/stable-json.ts
12004
12354
  function stableStringify(value, seen = new WeakSet) {
12005
12355
  if (value === undefined)
@@ -12054,12 +12404,12 @@ function loadToolDefinitionMeasurements(db) {
12054
12404
  }
12055
12405
 
12056
12406
  // ../plugin/src/features/magic-context/tool-owner-backfill.ts
12057
- import { existsSync as existsSync3 } from "node:fs";
12058
- import { join as join2 } from "node:path";
12407
+ import { existsSync as existsSync4 } from "node:fs";
12408
+ import { join as join3 } from "node:path";
12059
12409
  var LEASE_DURATION_MS = 5 * 60 * 1000;
12060
12410
  var LEASE_RENEWAL_MS = 60 * 1000;
12061
12411
  function resolveOpencodeDbPath() {
12062
- return join2(getDataDir(), "opencode", "opencode.db");
12412
+ return join3(getDataDir(), "opencode", "opencode.db");
12063
12413
  }
12064
12414
  function ensureBackfillStateTable(db) {
12065
12415
  db.exec(`
@@ -12094,7 +12444,7 @@ function runToolOwnerBackfill(db) {
12094
12444
  return result;
12095
12445
  }
12096
12446
  const opencodeDbPath = resolveOpencodeDbPath();
12097
- if (!existsSync3(opencodeDbPath)) {
12447
+ if (!existsSync4(opencodeDbPath)) {
12098
12448
  log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
12099
12449
  markAllUnbackfilledSessionsSkipped(db);
12100
12450
  result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
@@ -12321,7 +12671,7 @@ function getSchemaFenceRejection() {
12321
12671
  function getMigrationOnOpenRefusal() {
12322
12672
  return lastMigrationOnOpenRefusal;
12323
12673
  }
12324
- var LATEST_SUPPORTED_VERSION = 76;
12674
+ var LATEST_SUPPORTED_VERSION = 78;
12325
12675
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
12326
12676
  var defaultStoragePermissionFs = { chmodSync, mkdirSync: mkdirSync2 };
12327
12677
  var storagePermissionFs = defaultStoragePermissionFs;
@@ -12344,7 +12694,7 @@ function restrictDatabaseFilePermissions(dbPath) {
12344
12694
  return;
12345
12695
  for (const suffix of ["", "-wal", "-shm"]) {
12346
12696
  const file = `${dbPath}${suffix}`;
12347
- if (!existsSync4(file))
12697
+ if (!existsSync5(file))
12348
12698
  continue;
12349
12699
  try {
12350
12700
  storagePermissionFs.chmodSync(file, 384);
@@ -12355,20 +12705,20 @@ function restrictDatabaseFilePermissions(dbPath) {
12355
12705
  }
12356
12706
  function resolveDatabasePath(dbPathOverride) {
12357
12707
  if (dbPathOverride) {
12358
- return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
12708
+ return { dbDir: dirname3(dbPathOverride), dbPath: dbPathOverride };
12359
12709
  }
12360
12710
  const dbDir = getMagicContextStorageDir();
12361
- return { dbDir, dbPath: join3(dbDir, "context.db") };
12711
+ return { dbDir, dbPath: join4(dbDir, "context.db") };
12362
12712
  }
12363
12713
  function getDatabasePath(db) {
12364
12714
  return pathByDatabase.get(db) ?? null;
12365
12715
  }
12366
12716
  function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
12367
- if (existsSync4(targetDbPath))
12717
+ if (existsSync5(targetDbPath))
12368
12718
  return;
12369
12719
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
12370
- const legacyDbPath = join3(legacyDir, "context.db");
12371
- if (!existsSync4(legacyDbPath))
12720
+ const legacyDbPath = join4(legacyDir, "context.db");
12721
+ if (!existsSync5(legacyDbPath))
12372
12722
  return;
12373
12723
  log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
12374
12724
  ensureSecureStorageDir(targetDbDir);
@@ -12384,8 +12734,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
12384
12734
  }
12385
12735
  for (const suffix of ["", "-wal", "-shm"]) {
12386
12736
  const src = `${legacyDbPath}${suffix}`;
12387
- const dst = join3(targetDbDir, `context.db${suffix}`);
12388
- if (existsSync4(src)) {
12737
+ const dst = join4(targetDbDir, `context.db${suffix}`);
12738
+ if (existsSync5(src)) {
12389
12739
  try {
12390
12740
  copyFileSync(src, dst);
12391
12741
  } catch (error) {
@@ -12393,9 +12743,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
12393
12743
  }
12394
12744
  }
12395
12745
  }
12396
- const legacyModelsDir = join3(legacyDir, "models");
12397
- const targetModelsDir = join3(targetDbDir, "models");
12398
- if (existsSync4(legacyModelsDir) && !existsSync4(targetModelsDir)) {
12746
+ const legacyModelsDir = join4(legacyDir, "models");
12747
+ const targetModelsDir = join4(targetDbDir, "models");
12748
+ if (existsSync5(legacyModelsDir) && !existsSync5(targetModelsDir)) {
12399
12749
  try {
12400
12750
  cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
12401
12751
  } catch (error) {
@@ -12449,7 +12799,7 @@ function unreadableDiscovery(path2, arm) {
12449
12799
  var RPC_DISCOVERY_PARSE_GRACE_MS = 10 * 60 * 1000;
12450
12800
  var defaultRpcDiscoveryFs = {
12451
12801
  readdirSync: (path2, options) => options?.withFileTypes ? readdirSync(path2, { withFileTypes: true }) : readdirSync(path2),
12452
- readFileSync: (path2, encoding) => String(readFileSync3(path2, encoding)),
12802
+ readFileSync: (path2, encoding) => String(readFileSync4(path2, encoding)),
12453
12803
  statSync: (path2) => ({ mtimeMs: statSync3(path2).mtimeMs }),
12454
12804
  unlinkSync: (path2) => unlinkSync2(path2)
12455
12805
  };
@@ -12487,7 +12837,7 @@ function classifyJunkDiscovery(portFile, raw, staleFiles) {
12487
12837
  return null;
12488
12838
  }
12489
12839
  function inspectRpcServerDiscovery(storageDir) {
12490
- const rpcRoot = join3(storageDir, "rpc");
12840
+ const rpcRoot = join4(storageDir, "rpc");
12491
12841
  let projectEntries;
12492
12842
  try {
12493
12843
  projectEntries = rpcDiscoveryFs.readdirSync(rpcRoot, { withFileTypes: true });
@@ -12501,7 +12851,7 @@ function inspectRpcServerDiscovery(storageDir) {
12501
12851
  for (const projectEntry of projectEntries) {
12502
12852
  if (!projectEntry.isDirectory())
12503
12853
  continue;
12504
- const projectDir = join3(rpcRoot, projectEntry.name);
12854
+ const projectDir = join4(rpcRoot, projectEntry.name);
12505
12855
  let entries;
12506
12856
  try {
12507
12857
  entries = rpcDiscoveryFs.readdirSync(projectDir);
@@ -12512,7 +12862,7 @@ function inspectRpcServerDiscovery(storageDir) {
12512
12862
  }
12513
12863
  for (const entry of entries) {
12514
12864
  if (entry === "port" || entry.startsWith("port-") && entry.endsWith(".json")) {
12515
- portFiles.push(join3(projectDir, entry));
12865
+ portFiles.push(join4(projectDir, entry));
12516
12866
  }
12517
12867
  }
12518
12868
  }
@@ -12521,6 +12871,7 @@ function inspectRpcServerDiscovery(storageDir) {
12521
12871
  }
12522
12872
  const pids = new Set;
12523
12873
  const staleFiles = [];
12874
+ const inconclusivePids = new Set;
12524
12875
  for (const portFile of portFiles) {
12525
12876
  let raw;
12526
12877
  try {
@@ -12540,10 +12891,15 @@ function inspectRpcServerDiscovery(storageDir) {
12540
12891
  return junk;
12541
12892
  continue;
12542
12893
  }
12543
- if (isPidAlive(record.pid) && isPidIdentityPlausible(record))
12894
+ const liveness = isPidAlive(record.pid);
12895
+ const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record);
12896
+ if (liveness === "alive" && identity === "plausible") {
12544
12897
  pids.add(record.pid);
12545
- else
12898
+ } else if (liveness === "dead" || identity === "implausible") {
12546
12899
  staleFiles.push(portFile);
12900
+ } else {
12901
+ inconclusivePids.add(record.pid);
12902
+ }
12547
12903
  }
12548
12904
  for (const staleFile of staleFiles) {
12549
12905
  try {
@@ -12556,8 +12912,29 @@ function inspectRpcServerDiscovery(storageDir) {
12556
12912
  if (serverPids.length > 0) {
12557
12913
  return { state: "live", serverPids, staleFiles };
12558
12914
  }
12915
+ const uncertainPids = [...inconclusivePids].sort((a, b) => a - b);
12916
+ if (uncertainPids.length > 0) {
12917
+ return {
12918
+ state: "inconclusive",
12919
+ serverPids: [],
12920
+ staleFiles,
12921
+ inconclusivePids: uncertainPids
12922
+ };
12923
+ }
12559
12924
  return { state: "stale", serverPids: [], staleFiles };
12560
12925
  }
12926
+ function formatInconclusiveOpenCodeMigrationWarning(dbPath, pids) {
12927
+ return `[magic-context] storage warning: continuing migration for ${dbPath}; OpenCode server PID ${pids.join(", ")} was not confirmed because its liveness or identity check could not run. This commonly means an OS sandbox denied kill(0) or ps. No live OpenCode server was confirmed.`;
12928
+ }
12929
+ function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
12930
+ const uncertainPids = discovery.inconclusivePids ?? [];
12931
+ if (uncertainPids.length > 0) {
12932
+ log(formatInconclusiveOpenCodeMigrationWarning(dbPath, uncertainPids));
12933
+ }
12934
+ if (piProbeState === "unreadable") {
12935
+ log(`[magic-context] storage warning: continuing migration for ${dbPath}; the Pi/OMP process-list probe could not run, which commonly means an OS sandbox denied ps. No live Pi harness was confirmed.`);
12936
+ }
12937
+ }
12561
12938
  function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
12562
12939
  const persistedVersion = getPersistedSchemaVersion(db);
12563
12940
  if (persistedVersion >= latestSupportedVersion) {
@@ -12565,14 +12942,18 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
12565
12942
  return true;
12566
12943
  }
12567
12944
  const discovery = inspectRpcServerDiscovery(dbDir);
12568
- if (discovery.state === "absent" || discovery.state === "stale") {
12945
+ const piDiscovery = inspectLivePiProcesses();
12946
+ const piPids = piDiscovery.processIds;
12947
+ if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
12569
12948
  lastMigrationOnOpenRefusal = null;
12949
+ logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
12570
12950
  return true;
12571
12951
  }
12952
+ const blockingPids = [...new Set([...discovery.serverPids, ...piPids])].sort((left, right) => left - right);
12572
12953
  lastMigrationOnOpenRefusal = {
12573
12954
  persistedVersion,
12574
12955
  supportedVersion: latestSupportedVersion,
12575
- serverPids: discovery.serverPids,
12956
+ serverPids: blockingPids,
12576
12957
  ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
12577
12958
  ...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
12578
12959
  };
@@ -12582,7 +12963,11 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
12582
12963
  const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${unreadableFile} and retry.` : `Retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
12583
12964
  log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven. ${recovery}`);
12584
12965
  } else {
12585
- log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while live OpenCode server PID(s) ${discovery.serverPids.join(", ")} may still use the old plugin build. Restart OpenCode, then retry this process.`);
12966
+ const blockers = [
12967
+ ...discovery.serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
12968
+ ...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
12969
+ ];
12970
+ log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} still use the old plugin build. Restart the blocking harness, then retry this process.`);
12586
12971
  }
12587
12972
  return false;
12588
12973
  }
@@ -12806,6 +13191,7 @@ function initializeDatabase(db) {
12806
13191
  last_observed_at INTEGER,
12807
13192
  answer_refreshed_at INTEGER,
12808
13193
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
13194
+ source_candidate_provenance TEXT,
12809
13195
  created_at INTEGER NOT NULL,
12810
13196
  updated_at INTEGER NOT NULL
12811
13197
  );
@@ -13441,6 +13827,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13441
13827
  ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
13442
13828
  ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
13443
13829
  ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
13830
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
13831
+ const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
13832
+ if (hasUserMemoriesTable) {
13833
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
13834
+ }
13444
13835
  db.exec(`
13445
13836
  CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
13446
13837
  ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
@@ -13514,6 +13905,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
13514
13905
  ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
13515
13906
  ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
13516
13907
  ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
13908
+ ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
13909
+ ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
13517
13910
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
13518
13911
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
13519
13912
  ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
@@ -14161,7 +14554,7 @@ function persistCachedM0(db, sessionId, payload) {
14161
14554
  cached_m0_system_hash = ?,
14162
14555
  cached_m0_model_key = ?,
14163
14556
  cached_m0_project_identity = ?
14164
- WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ?? "", payload.projectIdentity ?? null, sessionId);
14557
+ WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.muralDataUrl ?? null, payload.muralHash ?? null, payload.projectMemoryEpoch, payload.workspaceFingerprint ?? null, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.modelKey ? piModelRefToCanonical(payload.modelKey) : "", payload.projectIdentity ?? null, sessionId);
14165
14558
  }
14166
14559
  function clearCachedM0M1(db, sessionId) {
14167
14560
  ensureSessionMetaRow(db, sessionId);
@@ -14938,7 +15331,7 @@ function clearHistorianFailureState(db, sessionId) {
14938
15331
  })();
14939
15332
  }
14940
15333
  function normalizeDetectedLimitModelKey(modelKey) {
14941
- return typeof modelKey === "string" && modelKey.length > 0 ? modelKey : null;
15334
+ return typeof modelKey === "string" && modelKey.length > 0 ? piModelRefToCanonical(modelKey) : null;
14942
15335
  }
14943
15336
  function normalizeEmergencyRecoveryOrigin(value) {
14944
15337
  return value === "provider_overflow" || value === "proactive_model_shrink" ? value : null;
@@ -15227,13 +15620,13 @@ function clearCompressionDepthRange(db, sessionId, startOrdinal, endOrdinal) {
15227
15620
  import { createHash as createHash4 } from "node:crypto";
15228
15621
 
15229
15622
  // ../plugin/src/hooks/magic-context/read-session-db.ts
15230
- import { existsSync as existsSync5 } from "node:fs";
15231
- import { join as join4 } from "node:path";
15623
+ import { existsSync as existsSync6 } from "node:fs";
15624
+ import { join as join5 } from "node:path";
15232
15625
  function getOpenCodeDbPath() {
15233
- return join4(getDataDir(), "opencode", "opencode.db");
15626
+ return join5(getDataDir(), "opencode", "opencode.db");
15234
15627
  }
15235
15628
  function openCodeDbExists() {
15236
- return existsSync5(getOpenCodeDbPath());
15629
+ return existsSync6(getOpenCodeDbPath());
15237
15630
  }
15238
15631
  var cachedReadOnlyDb = null;
15239
15632
  function closeCachedReadOnlyDb() {
@@ -17048,7 +17441,7 @@ function updateSessionMeta(db, sessionId, updates) {
17048
17441
  values.push(value ? 1 : 0);
17049
17442
  } else if (typeof value === "string" || typeof value === "number") {
17050
17443
  setClauses.push(`${column} = ?`);
17051
- values.push(value);
17444
+ values.push(key === "lastObservedModelKey" && typeof value === "string" ? piModelRefToCanonical(value) : value);
17052
17445
  }
17053
17446
  }
17054
17447
  if (setClauses.length === 0) {
@@ -17313,7 +17706,7 @@ function escapeXmlContent(s) {
17313
17706
  }
17314
17707
  // ../plugin/src/features/magic-context/project-docs-hash.ts
17315
17708
  import { createHash as createHash5 } from "node:crypto";
17316
- import { lstatSync, readFileSync as readFileSync4, statSync as statSync4 } from "node:fs";
17709
+ import { lstatSync, readFileSync as readFileSync5, statSync as statSync4 } from "node:fs";
17317
17710
  import path2 from "node:path";
17318
17711
  var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
17319
17712
  var PROJECT_DOCS_DELIMITER = `
@@ -17387,7 +17780,7 @@ function readCanonicalPieces(projectDirectory, files) {
17387
17780
  if (!safeToRead) {
17388
17781
  continue;
17389
17782
  }
17390
- const canonicalContent = canonicalizeDocContent(readFileSync4(filePath, "utf8"));
17783
+ const canonicalContent = canonicalizeDocContent(readFileSync5(filePath, "utf8"));
17391
17784
  hashPieces.push(`file:${filename}
17392
17785
  ${canonicalContent}`);
17393
17786
  renderedSections.push(`<file name="${escapeXmlAttr(filename)}">
@@ -17460,6 +17853,67 @@ function mapMessageId(filter, messageId) {
17460
17853
  return null;
17461
17854
  return filter.mapMessageId?.(messageId) ?? messageId;
17462
17855
  }
17856
+ function tableExists3(db, table) {
17857
+ const row = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
17858
+ return row !== null && row !== undefined;
17859
+ }
17860
+ function insertDynamicRow(db, table, row) {
17861
+ const names = Object.keys(row);
17862
+ const quoted = names.map((name) => `"${name.replaceAll('"', '""')}"`);
17863
+ const placeholders2 = names.map(() => "?").join(", ");
17864
+ db.prepare(`INSERT INTO "${table.replaceAll('"', '""')}" (${quoted.join(", ")}) VALUES (${placeholders2})`).run(...names.map((name) => row[name]));
17865
+ }
17866
+ function anchoredMessageId(blockId) {
17867
+ const separator = blockId.lastIndexOf("#");
17868
+ return separator > 0 ? blockId.slice(0, separator) : blockId;
17869
+ }
17870
+ function copyPiSessionNotesAndFacts(db, sourceSessionId, destinationSessionId, filter) {
17871
+ let notesCopied = 0;
17872
+ if (tableExists3(db, "notes")) {
17873
+ const sourceNotes = db.prepare("SELECT * FROM notes WHERE session_id = ? AND type = 'session' ORDER BY id ASC").all(sourceSessionId);
17874
+ for (const source of sourceNotes) {
17875
+ const row = {
17876
+ ...source,
17877
+ session_id: destinationSessionId
17878
+ };
17879
+ delete row.id;
17880
+ const blockId = typeof source.anchor_block_id === "string" ? source.anchor_block_id : "";
17881
+ if (blockId) {
17882
+ const sourceMessageId = anchoredMessageId(blockId);
17883
+ if (!filter.includeMessageId(sourceMessageId))
17884
+ continue;
17885
+ const mappedMessageId = mapMessageId(filter, sourceMessageId) ?? sourceMessageId;
17886
+ row.anchor_block_id = `${mappedMessageId}${blockId.slice(sourceMessageId.length)}`;
17887
+ const mappedOrdinal = filter.resolveBoundaryOrdinal(sourceMessageId);
17888
+ if (mappedOrdinal === undefined)
17889
+ continue;
17890
+ if ("anchor_ordinal" in row)
17891
+ row.anchor_ordinal = mappedOrdinal;
17892
+ } else if (typeof source.anchor_ordinal === "number" && filter.mapOrdinal) {
17893
+ const mappedOrdinal = filter.mapOrdinal(source.anchor_ordinal);
17894
+ if (mappedOrdinal === undefined)
17895
+ continue;
17896
+ row.anchor_ordinal = mappedOrdinal;
17897
+ }
17898
+ insertDynamicRow(db, "notes", row);
17899
+ notesCopied += 1;
17900
+ }
17901
+ }
17902
+ let factsCopied = 0;
17903
+ if (tableExists3(db, "session_facts")) {
17904
+ const sourceFacts = db.prepare("SELECT * FROM session_facts WHERE session_id = ? ORDER BY id ASC").all(sourceSessionId);
17905
+ for (const source of sourceFacts) {
17906
+ const row = {
17907
+ ...source,
17908
+ session_id: destinationSessionId
17909
+ };
17910
+ delete row.id;
17911
+ insertDynamicRow(db, "session_facts", row);
17912
+ factsCopied += 1;
17913
+ }
17914
+ }
17915
+ return { notesCopied, factsCopied };
17916
+ }
17463
17917
  function filterIdBlob(raw, filter) {
17464
17918
  if (!raw)
17465
17919
  return "";
@@ -17480,12 +17934,14 @@ function clampWatermark(value, maxCopiedTag) {
17480
17934
  }
17481
17935
  function copySessionStateForClone(db, sourceSessionId, destinationSessionId, filter) {
17482
17936
  return runImmediate(db, () => {
17483
- if (countRows(db, "compartments", destinationSessionId) > 0 || countRows(db, "tags", destinationSessionId) > 0) {
17937
+ if (countRows(db, "compartments", destinationSessionId) > 0 || countRows(db, "tags", destinationSessionId) > 0 || filter.copySessionNotesAndFacts === true && (tableExists3(db, "notes") && countRows(db, "notes", destinationSessionId) > 0 || tableExists3(db, "session_facts") && countRows(db, "session_facts", destinationSessionId) > 0)) {
17484
17938
  return {
17485
17939
  kind: "destination-not-empty",
17486
17940
  compartmentsCopied: 0,
17487
17941
  tagsCopied: 0,
17488
17942
  pendingOpsCopied: 0,
17943
+ notesCopied: 0,
17944
+ factsCopied: 0,
17489
17945
  pendingMarkerMigrated: false
17490
17946
  };
17491
17947
  }
@@ -17569,6 +18025,7 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
17569
18025
  insertPendingOp.run(destinationSessionId, destinationTagId, row.operation, row.queued_at, row.harness);
17570
18026
  }
17571
18027
  }
18028
+ const inherited = filter.copySessionNotesAndFacts === true ? copyPiSessionNotesAndFacts(db, sourceSessionId, destinationSessionId, filter) : { notesCopied: 0, factsCopied: 0 };
17572
18029
  const meta = db.prepare(`SELECT cleared_reasoning_through_tag, tool_reclaim_watermark,
17573
18030
  pi_stable_id_scheme, stripped_placeholder_ids,
17574
18031
  stale_reduce_stripped_ids, processed_image_stripped_ids,
@@ -17610,6 +18067,8 @@ function copySessionStateForClone(db, sourceSessionId, destinationSessionId, fil
17610
18067
  compartmentsCopied: copiedCompartments.length,
17611
18068
  tagsCopied: copiedTagNumbers.length,
17612
18069
  pendingOpsCopied: typeof pendingOpsRow?.count === "number" ? pendingOpsRow.count : 0,
18070
+ notesCopied: inherited.notesCopied,
18071
+ factsCopied: inherited.factsCopied,
17613
18072
  pendingMarkerMigrated: pendingMarker !== null
17614
18073
  };
17615
18074
  });
@@ -18192,6 +18651,76 @@ function parseCandidateIds(raw) {
18192
18651
  return [];
18193
18652
  }
18194
18653
  }
18654
+ function parsePrimerSourceProvenance(raw) {
18655
+ if (raw === null)
18656
+ return null;
18657
+ try {
18658
+ const parsed = JSON.parse(raw);
18659
+ if (!Array.isArray(parsed))
18660
+ return null;
18661
+ const provenance = [];
18662
+ for (const value of parsed) {
18663
+ if (!value || typeof value !== "object")
18664
+ return null;
18665
+ const source = value;
18666
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.project_path !== "string" || typeof source.harness !== "string" || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number" || typeof source.source_start_message_id !== "string" || typeof source.source_end_message_id !== "string") {
18667
+ return null;
18668
+ }
18669
+ provenance.push({
18670
+ candidateId: source.candidate_id,
18671
+ projectPath: source.project_path,
18672
+ harness: source.harness,
18673
+ sessionId: source.session_id,
18674
+ sourceCompartmentStart: source.source_compartment_start,
18675
+ sourceCompartmentEnd: source.source_compartment_end,
18676
+ sourceStartMessageId: source.source_start_message_id,
18677
+ sourceEndMessageId: source.source_end_message_id
18678
+ });
18679
+ }
18680
+ return provenance;
18681
+ } catch {
18682
+ return null;
18683
+ }
18684
+ }
18685
+ function loadPrimerSourceProvenance(db, candidateIds) {
18686
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
18687
+ if (ids.length === 0)
18688
+ return [];
18689
+ const placeholders3 = ids.map(() => "?").join(",");
18690
+ const rows = db.prepare(`SELECT id, project_path, harness, session_id,
18691
+ source_compartment_start, source_compartment_end,
18692
+ source_start_message_id, source_end_message_id
18693
+ FROM primer_candidates
18694
+ WHERE id IN (${placeholders3})
18695
+ ORDER BY id ASC`).all(...ids);
18696
+ return rows.map((row) => ({
18697
+ candidateId: row.id,
18698
+ projectPath: row.project_path,
18699
+ harness: row.harness,
18700
+ sessionId: row.session_id,
18701
+ sourceCompartmentStart: row.source_compartment_start,
18702
+ sourceCompartmentEnd: row.source_compartment_end,
18703
+ sourceStartMessageId: row.source_start_message_id,
18704
+ sourceEndMessageId: row.source_end_message_id
18705
+ }));
18706
+ }
18707
+ function serializePrimerSourceProvenance(provenance, sourceCandidateIds) {
18708
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
18709
+ return null;
18710
+ return JSON.stringify(provenance.map((source) => ({
18711
+ candidate_id: source.candidateId,
18712
+ project_path: source.projectPath,
18713
+ harness: source.harness,
18714
+ session_id: source.sessionId,
18715
+ source_compartment_start: source.sourceCompartmentStart,
18716
+ source_compartment_end: source.sourceCompartmentEnd,
18717
+ source_start_message_id: source.sourceStartMessageId,
18718
+ source_end_message_id: source.sourceEndMessageId
18719
+ })));
18720
+ }
18721
+ function normalizedCandidateIds(candidateIds) {
18722
+ return [...new Set(candidateIds)].sort((a, b) => a - b);
18723
+ }
18195
18724
  function toCandidate(row) {
18196
18725
  return {
18197
18726
  id: row.id,
@@ -18224,6 +18753,7 @@ function toPrimer(row) {
18224
18753
  lastObservedAt: row.last_observed_at,
18225
18754
  answerRefreshedAt: row.answer_refreshed_at,
18226
18755
  sourceCandidateIds: parseCandidateIds(row.source_candidate_ids),
18756
+ sourceProvenance: parsePrimerSourceProvenance(row.source_candidate_provenance),
18227
18757
  createdAt: row.created_at,
18228
18758
  updatedAt: row.updated_at
18229
18759
  };
@@ -18295,23 +18825,43 @@ function getActivePrimers(db, projectPath) {
18295
18825
  return rows.map(toPrimer);
18296
18826
  }
18297
18827
  function createPrimer(db, input) {
18298
- const now = input.now ?? Date.now();
18299
- const info = db.prepare(`INSERT INTO primers (
18300
- project_path, question, question_embedding, question_embedding_model_id, answer,
18301
- status, total_support, last_observed_at, answer_refreshed_at,
18302
- source_candidate_ids, created_at, updated_at
18303
- ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), now, now);
18304
- return Number(info.lastInsertRowid);
18828
+ return db.transaction(() => {
18829
+ const now = input.now ?? Date.now();
18830
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
18831
+ const sourceProvenance = loadPrimerSourceProvenance(db, sourceCandidateIds);
18832
+ const info = db.prepare(`INSERT INTO primers (
18833
+ project_path, question, question_embedding, question_embedding_model_id, answer,
18834
+ status, total_support, last_observed_at, answer_refreshed_at,
18835
+ source_candidate_ids, source_candidate_provenance, created_at, updated_at
18836
+ ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
18837
+ return Number(info.lastInsertRowid);
18838
+ })();
18305
18839
  }
18306
18840
  function updatePrimerSupport(db, input) {
18307
- db.prepare(`UPDATE primers
18308
- SET question_embedding = COALESCE(?, question_embedding),
18309
- question_embedding_model_id = COALESCE(?, question_embedding_model_id),
18310
- total_support = ?,
18311
- last_observed_at = ?,
18312
- source_candidate_ids = ?,
18313
- updated_at = ?
18314
- WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify([...new Set(input.sourceCandidateIds)].sort((a, b) => a - b)), input.now ?? Date.now(), input.primerId);
18841
+ db.transaction(() => {
18842
+ const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
18843
+ const allowedIds = new Set(sourceCandidateIds);
18844
+ const existingRow = db.prepare("SELECT source_candidate_provenance FROM primers WHERE id = ?").get(input.primerId);
18845
+ const provenanceByCandidateId = new Map;
18846
+ for (const source of parsePrimerSourceProvenance(existingRow?.source_candidate_provenance ?? null) ?? []) {
18847
+ if (allowedIds.has(source.candidateId)) {
18848
+ provenanceByCandidateId.set(source.candidateId, source);
18849
+ }
18850
+ }
18851
+ for (const source of loadPrimerSourceProvenance(db, sourceCandidateIds)) {
18852
+ provenanceByCandidateId.set(source.candidateId, source);
18853
+ }
18854
+ const sourceProvenance = [...provenanceByCandidateId.values()].sort((a, b) => a.candidateId - b.candidateId);
18855
+ db.prepare(`UPDATE primers
18856
+ SET question_embedding = COALESCE(?, question_embedding),
18857
+ question_embedding_model_id = COALESCE(?, question_embedding_model_id),
18858
+ total_support = ?,
18859
+ last_observed_at = ?,
18860
+ source_candidate_ids = ?,
18861
+ source_candidate_provenance = ?,
18862
+ updated_at = ?
18863
+ WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), input.now ?? Date.now(), input.primerId);
18864
+ })();
18315
18865
  }
18316
18866
  function updatePrimerAnswer(db, primerId, answer, refreshedAt = Date.now()) {
18317
18867
  db.prepare("UPDATE primers SET answer = ?, answer_refreshed_at = ?, updated_at = ? WHERE id = ?").run(answer, refreshedAt, refreshedAt, primerId);
@@ -19040,6 +19590,20 @@ function getTagsByNumbers(db, sessionId, tagNumbers) {
19040
19590
  const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number IN (${placeholders3}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
19041
19591
  return rows.map(toTagEntry);
19042
19592
  }
19593
+ function getDroppedTagsByNumbers(db, sessionId, tagNumbers) {
19594
+ if (tagNumbers.length === 0)
19595
+ return [];
19596
+ if (tagNumbers.length > 900) {
19597
+ const all = [];
19598
+ for (let i = 0;i < tagNumbers.length; i += 900) {
19599
+ all.push(...getDroppedTagsByNumbers(db, sessionId, tagNumbers.slice(i, i + 900)));
19600
+ }
19601
+ return all;
19602
+ }
19603
+ const placeholders3 = tagNumbers.map(() => "?").join(",");
19604
+ const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'dropped' AND tag_number IN (${placeholders3}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
19605
+ return rows.map(toTagEntry);
19606
+ }
19043
19607
  function getMaxDroppedTagNumber(db, sessionId) {
19044
19608
  const row = getMaxDroppedTagNumberStatement(db).get(sessionId);
19045
19609
  return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
@@ -19217,8 +19781,8 @@ function isTodoItem(value) {
19217
19781
  }
19218
19782
 
19219
19783
  // ../plugin/src/shared/prompt-surface-runtime.ts
19220
- import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync5 } from "node:fs";
19221
- import { dirname as dirname3, isAbsolute as isAbsolute2, resolve } from "node:path";
19784
+ import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync5 } from "node:fs";
19785
+ import { dirname as dirname4, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
19222
19786
 
19223
19787
  // ../plugin/src/tools/light-descriptions.ts
19224
19788
  var CTX_REDUCE_LIGHT_DESCRIPTION = `For ctx_reduce users, mark spent §N§ outputs discardable; release is QUEUED, not immediate, so content stays visible until space is needed. Newest tags stay protected until they age out. Released content becomes a placeholder; recover it only by rerunning the source or recovery tool, so mark only genuinely finished material. Mark analyzed, redundant, persisted, or merely confirmatory outputs; keep user messages, unresolved errors, unextracted evidence, and exact wording. NEVER blanket-mark a large range: review every tag first.`;
@@ -19228,7 +19792,7 @@ var CTX_MEMORY_LIGHT_DESCRIPTION = `For ctx_memory users, write one standalone d
19228
19792
  var CTX_SEARCH_LIGHT_DESCRIPTION = `For ctx_search users, retrieve only hidden recall: memories not already in <project-memory>, compacted messages outside the live tail, commits, and notes. Omit sources for broad search; select memory, message, git_commit, or note to target a source, or pass memory IDs to bypass text search. Message hits continue through ctx_expand.`;
19229
19793
 
19230
19794
  // ../plugin/src/shared/jsonc-parser.ts
19231
- import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
19795
+ import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
19232
19796
  function stripJsonComments(content) {
19233
19797
  let result = "";
19234
19798
  let inString = false;
@@ -19283,13 +19847,43 @@ function stripJsonComments(content) {
19283
19847
  }
19284
19848
  return result;
19285
19849
  }
19850
+ var PROTOTYPE_POLLUTION_KEYS = new Set(["__proto__", "constructor", "prototype"]);
19851
+ function isPrototypePollutionKey(key) {
19852
+ return PROTOTYPE_POLLUTION_KEYS.has(key);
19853
+ }
19854
+ function sanitizeParsedJson(value, options = {}, path3 = []) {
19855
+ if (Array.isArray(value)) {
19856
+ return value.map((entry, index) => sanitizeParsedJson(entry, options, [...path3, index]));
19857
+ }
19858
+ if (value === null || typeof value !== "object")
19859
+ return value;
19860
+ const source = value;
19861
+ const sourcePrototype = Object.getPrototypeOf(source);
19862
+ if (sourcePrototype !== null && sourcePrototype !== Object.prototype) {
19863
+ options.onRejectedKey?.([...path3, "__proto__"]);
19864
+ }
19865
+ const sanitized = {};
19866
+ for (const key of Object.keys(source)) {
19867
+ if (isPrototypePollutionKey(key)) {
19868
+ options.onRejectedKey?.([...path3, key]);
19869
+ continue;
19870
+ }
19871
+ Object.defineProperty(sanitized, key, {
19872
+ value: sanitizeParsedJson(source[key], options, [...path3, key]),
19873
+ enumerable: true,
19874
+ configurable: true,
19875
+ writable: true
19876
+ });
19877
+ }
19878
+ return sanitized;
19879
+ }
19286
19880
  function detectConfigFile(basePath) {
19287
19881
  const jsoncPath = `${basePath}.jsonc`;
19288
19882
  const jsonPath = `${basePath}.json`;
19289
- if (existsSync6(jsoncPath)) {
19883
+ if (existsSync7(jsoncPath)) {
19290
19884
  return { format: "jsonc", path: jsoncPath };
19291
19885
  }
19292
- if (existsSync6(jsonPath)) {
19886
+ if (existsSync7(jsonPath)) {
19293
19887
  return { format: "json", path: jsonPath };
19294
19888
  }
19295
19889
  return { format: "none", path: jsoncPath };
@@ -19300,7 +19894,9 @@ function isValidPromptSurfaceModelKey(key) {
19300
19894
  if (key.length === 0 || key.trim() !== key)
19301
19895
  return false;
19302
19896
  const slash = key.indexOf("/");
19303
- if (slash <= 0 || slash === key.length - 1)
19897
+ if (slash < 0)
19898
+ return !key.includes("*");
19899
+ if (slash === 0 || slash === key.length - 1)
19304
19900
  return false;
19305
19901
  const provider = key.slice(0, slash);
19306
19902
  const modelID = key.slice(slash + 1);
@@ -19319,16 +19915,25 @@ function modelKeyLookupOrder(modelKey) {
19319
19915
  return [];
19320
19916
  const provider = modelKey.slice(0, slash);
19321
19917
  let modelID = modelKey.slice(slash + 1);
19918
+ const providerRefs = modelRefLookupOrder(`${provider}/${modelID}`);
19322
19919
  const candidates = [];
19323
19920
  while (modelID.length > 0) {
19324
- candidates.push({ key: `${provider}/${modelID}`, source: "exact" });
19921
+ for (const providerRef of providerRefs) {
19922
+ const providerSlash = providerRef.indexOf("/");
19923
+ const providerPrefix = providerRef.slice(0, providerSlash);
19924
+ candidates.push({ key: `${providerPrefix}/${modelID}`, source: "exact" });
19925
+ }
19325
19926
  candidates.push({ key: modelID, source: "bare" });
19326
19927
  const lastDash = modelID.lastIndexOf("-");
19327
19928
  if (lastDash <= 0)
19328
19929
  break;
19329
19930
  modelID = modelID.slice(0, lastDash);
19330
19931
  }
19331
- candidates.push({ key: `${provider}/*`, source: "wildcard" });
19932
+ for (const providerRef of providerRefs) {
19933
+ const providerSlash = providerRef.indexOf("/");
19934
+ const providerPrefix = providerRef.slice(0, providerSlash);
19935
+ candidates.push({ key: `${providerPrefix}/*`, source: "wildcard" });
19936
+ }
19332
19937
  const seen = new Set;
19333
19938
  return candidates.filter((candidate) => {
19334
19939
  if (seen.has(candidate.key))
@@ -19351,7 +19956,7 @@ function resolveModelConfigValue(values, modelKey) {
19351
19956
  function resolvePromptSurface(config, modelKey) {
19352
19957
  const fallback = config?.default ?? "full";
19353
19958
  const match = resolveModelConfigValue(config?.models, modelKey);
19354
- if (match && match.source !== "bare") {
19959
+ if (match) {
19355
19960
  return { preset: match.value, source: match.source };
19356
19961
  }
19357
19962
  return { preset: fallback, source: "default" };
@@ -19384,17 +19989,17 @@ function promptSurfaceHashMaterial(systemContent, preset = "full") {
19384
19989
  var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
19385
19990
  function resolveUserConfigDirectory(options) {
19386
19991
  if (options.userConfigDirectory)
19387
- return resolve(options.userConfigDirectory);
19992
+ return resolve2(options.userConfigDirectory);
19388
19993
  const sharedBase = cortexKitUserConfigBasePath();
19389
19994
  const shared = detectConfigFile(sharedBase);
19390
19995
  if (shared.format !== "none")
19391
- return dirname3(shared.path);
19996
+ return dirname4(shared.path);
19392
19997
  if (options.harness) {
19393
- const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness).user.find((source) => existsSync7(source.path));
19998
+ const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness).user.find((source) => existsSync8(source.path));
19394
19999
  if (legacy)
19395
- return dirname3(legacy.path);
20000
+ return dirname4(legacy.path);
19396
20001
  }
19397
- return dirname3(sharedBase);
20002
+ return dirname4(sharedBase);
19398
20003
  }
19399
20004
  function markerCount(content) {
19400
20005
  return content.match(GUIDANCE_MARKER_LINE)?.length ?? 0;
@@ -19411,14 +20016,14 @@ function createPromptSurfaceRuntime(options) {
19411
20016
  const readGuidanceOverride = (configuredPath) => {
19412
20017
  if (!configuredPath)
19413
20018
  return;
19414
- const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve(userConfigDirectory, configuredPath);
20019
+ const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve2(userConfigDirectory, configuredPath);
19415
20020
  let content;
19416
20021
  try {
19417
20022
  if (!statSync5(path3).isFile()) {
19418
20023
  warnOnce(`guidance-not-file:${path3}`, `prompt_surface.guidance_override_path (${path3}) is not a file; using built-in guidance.`);
19419
20024
  return;
19420
20025
  }
19421
- content = readFileSync6(path3, "utf8");
20026
+ content = readFileSync7(path3, "utf8");
19422
20027
  } catch (error) {
19423
20028
  const reason = error instanceof Error ? error.message : String(error);
19424
20029
  warnOnce(`guidance-unreadable:${path3}:${reason}`, `prompt_surface.guidance_override_path (${path3}) could not be read (${reason}); using built-in guidance.`);
@@ -19471,12 +20076,13 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
19471
20076
  const epochs = new Map;
19472
20077
  return {
19473
20078
  resolve(sessionId, config, modelKey) {
20079
+ const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : undefined;
19474
20080
  const cached = epochs.get(sessionId);
19475
- if (cached && cached.config === config && cached.modelKey === modelKey) {
20081
+ if (cached && cached.config === config && cached.modelKey === canonicalModelKey) {
19476
20082
  return cached.selection;
19477
20083
  }
19478
- const selection = runtime.resolveGuidance(config, modelKey);
19479
- epochs.set(sessionId, { config, modelKey, selection });
20084
+ const selection = runtime.resolveGuidance(config, canonicalModelKey);
20085
+ epochs.set(sessionId, { config, modelKey: canonicalModelKey, selection });
19480
20086
  return selection;
19481
20087
  },
19482
20088
  clear(sessionId) {
@@ -19835,7 +20441,7 @@ function pruneNestedConfigLeaf(block, relativePath) {
19835
20441
  }
19836
20442
 
19837
20443
  // src/config/index.ts
19838
- import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
20444
+ import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
19839
20445
 
19840
20446
  // ../plugin/src/config/migrate-dreamer-v2.ts
19841
20447
  var OLD_VERIFY_TASK = "verify";
@@ -20146,7 +20752,7 @@ function migrateLegacyExperimental(rawConfig, warnings) {
20146
20752
  }
20147
20753
 
20148
20754
  // ../plugin/src/config/schema/magic-context.ts
20149
- import { homedir as homedir3 } from "node:os";
20755
+ import { homedir as homedir4 } from "node:os";
20150
20756
 
20151
20757
  // ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
20152
20758
  var exports_external = {};
@@ -34694,14 +35300,14 @@ var PiConfigSchema = exports_external.object({
34694
35300
  }).optional();
34695
35301
  var PromptSurfacePresetSchema = exports_external.enum(["full", "light"]);
34696
35302
  var PromptSurfaceModelKeySchema = exports_external.string().refine(isValidPromptSurfaceModelKey, {
34697
- message: "Use a non-empty provider/model key or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
35303
+ message: "Use a non-empty bare model key, provider/model key, or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
34698
35304
  });
34699
35305
  var PromptSurfaceToolKeySchema = exports_external.string().refine((value) => value.trim().length > 0, {
34700
35306
  message: "tool description keys must not be empty or whitespace-only"
34701
35307
  });
34702
35308
  var PromptSurfaceConfigSchema = exports_external.object({
34703
35309
  default: PromptSurfacePresetSchema.default("full").describe('Fallback prompt-surface preset ("full" or "light").'),
34704
- models: exports_external.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema).optional().describe("Literal per-model routing. Keys are provider/model or provider/*; matching is case-sensitive and preserves additional slashes in model IDs."),
35310
+ models: exports_external.record(PromptSurfaceModelKeySchema, PromptSurfacePresetSchema).optional().describe("Literal per-model routing. Keys are bare model IDs, provider/model, or provider/*; matching is case-sensitive and preserves additional slashes in model IDs."),
34705
35311
  guidance_override_path: exports_external.string().refine((value) => value.trim().length > 0, {
34706
35312
  message: "guidance_override_path must not be empty or whitespace-only"
34707
35313
  }).optional().describe("USER-LEVEL ONLY path to a complete primary guidance section. Relative paths resolve from the user config file."),
@@ -34785,9 +35391,9 @@ var EmbeddingFallbackProviderSchema = exports_external.enum(["local", "openai-co
34785
35391
  function expandConfigPath(value) {
34786
35392
  const trimmed = value.trim();
34787
35393
  if (trimmed === "~")
34788
- return homedir3();
35394
+ return homedir4();
34789
35395
  if (trimmed.startsWith("~/"))
34790
- return `${homedir3()}/${trimmed.slice(2)}`;
35396
+ return `${homedir4()}/${trimmed.slice(2)}`;
34791
35397
  return trimmed;
34792
35398
  }
34793
35399
  var BaseEmbeddingConfigSchema = exports_external.object({
@@ -34894,11 +35500,14 @@ var MagicContextConfigSchema = exports_external.object({
34894
35500
  retina_handoff: exports_external.boolean().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
34895
35501
  }).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
34896
35502
  cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" for lanes kept warm by an external keepwarm proxy — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time.'),
34897
- prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use the literal provider/model or provider/* routing grammar. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
35503
+ prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
34898
35504
  output_reserve: exports_external.union([
34899
35505
  exports_external.number().min(0),
34900
35506
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
34901
35507
  ]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
35508
+ models: exports_external.object({
35509
+ window_overlay_path: exports_external.string().trim().min(1).optional()
35510
+ }).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
34902
35511
  toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
34903
35512
  execute_threshold_percentage: exports_external.union([
34904
35513
  exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
@@ -35112,6 +35721,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
35112
35721
  delete projectRaw.output_reserve;
35113
35722
  warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
35114
35723
  }
35724
+ const models = projectRaw.models;
35725
+ if (isPlainObject3(models) && "window_overlay_path" in models) {
35726
+ delete models.window_overlay_path;
35727
+ warnings.push("Ignoring models.window_overlay_path from project config (security: only user-level config may select model geometry metadata).");
35728
+ }
35115
35729
  if ("language" in projectRaw) {
35116
35730
  delete projectRaw.language;
35117
35731
  warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
@@ -35334,18 +35948,18 @@ function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
35334
35948
  }
35335
35949
 
35336
35950
  // ../plugin/src/config/variable.ts
35337
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
35338
- import { homedir as homedir4 } from "node:os";
35339
- import { dirname as dirname4, isAbsolute as isAbsolute3, resolve as resolve2 } from "node:path";
35951
+ import { existsSync as existsSync9, readFileSync as readFileSync8 } from "node:fs";
35952
+ import { homedir as homedir5 } from "node:os";
35953
+ import { dirname as dirname5, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
35340
35954
  var ENV_PATTERN = /\{env:([^}]+)\}/g;
35341
35955
  var FILE_PATTERN = /\{file:([^}]+)\}/g;
35342
35956
  function sensitiveFilePathReason(resolvedPath) {
35343
- const home = homedir4();
35957
+ const home = homedir5();
35344
35958
  const sensitiveDirs = [
35345
- { dir: resolve2(home, ".ssh"), label: "SSH keys" },
35346
- { dir: resolve2(home, ".aws"), label: "AWS credentials" },
35347
- { dir: resolve2(home, ".gnupg"), label: "GnuPG keyring" },
35348
- { dir: resolve2(home, ".config", "gh"), label: "GitHub CLI auth" }
35959
+ { dir: resolve3(home, ".ssh"), label: "SSH keys" },
35960
+ { dir: resolve3(home, ".aws"), label: "AWS credentials" },
35961
+ { dir: resolve3(home, ".gnupg"), label: "GnuPG keyring" },
35962
+ { dir: resolve3(home, ".config", "gh"), label: "GitHub CLI auth" }
35349
35963
  ];
35350
35964
  for (const { dir, label } of sensitiveDirs) {
35351
35965
  if (resolvedPath === dir || resolvedPath.startsWith(`${dir}/`)) {
@@ -35385,7 +35999,7 @@ function substituteConfigVariables(input) {
35385
35999
  if (fileMatches.length === 0) {
35386
36000
  return { text, warnings };
35387
36001
  }
35388
- const configDir = input.configPath ? dirname4(input.configPath) : process.cwd();
36002
+ const configDir = input.configPath ? dirname5(input.configPath) : process.cwd();
35389
36003
  let output = "";
35390
36004
  let cursor = 0;
35391
36005
  for (const match of fileMatches) {
@@ -35403,21 +36017,21 @@ function substituteConfigVariables(input) {
35403
36017
  }
35404
36018
  let filePath = rawPath.trim();
35405
36019
  if (filePath.startsWith("~/")) {
35406
- filePath = resolve2(homedir4(), filePath.slice(2));
36020
+ filePath = resolve3(homedir5(), filePath.slice(2));
35407
36021
  } else if (!isAbsolute3(filePath)) {
35408
- filePath = resolve2(configDir, filePath);
36022
+ filePath = resolve3(configDir, filePath);
35409
36023
  }
35410
36024
  const sensitiveReason = sensitiveFilePathReason(filePath);
35411
36025
  if (sensitiveReason) {
35412
36026
  warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
35413
36027
  }
35414
- if (!existsSync8(filePath)) {
36028
+ if (!existsSync9(filePath)) {
35415
36029
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
35416
36030
  continue;
35417
36031
  }
35418
36032
  let contents;
35419
36033
  try {
35420
- contents = readFileSync7(filePath, "utf-8").trim();
36034
+ contents = readFileSync8(filePath, "utf-8").trim();
35421
36035
  } catch (error51) {
35422
36036
  const message = error51 instanceof Error ? error51.message : String(error51);
35423
36037
  warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
@@ -35430,48 +36044,394 @@ function substituteConfigVariables(input) {
35430
36044
  }
35431
36045
 
35432
36046
  // ../plugin/src/shared/models-dev-cache.ts
35433
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
35434
- import { join as join5 } from "node:path";
35435
-
35436
- // ../plugin/src/shared/harness-provider-map.ts
35437
- var CANONICAL_TO_PI_PROVIDER = {
35438
- openai: "openai-codex",
35439
- google: "google-antigravity"
35440
- };
35441
- var PI_TO_CANONICAL_PROVIDER = {
35442
- "openai-codex": "openai",
35443
- "google-antigravity": "google"
35444
- };
35445
- var CANONICAL_TO_OMP_PROVIDER = {
35446
- openai: "openai-codex",
35447
- google: "google-antigravity"
35448
- };
35449
- var OMP_TO_CANONICAL_PROVIDER = {
35450
- "openai-codex": "openai",
35451
- "google-antigravity": "google"
36047
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync10, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
36048
+ import { join as join7 } from "node:path";
36049
+
36050
+ // ../plugin/src/shared/window-geometry.ts
36051
+ import { readFileSync as readFileSync9 } from "node:fs";
36052
+ import { join as join6 } from "node:path";
36053
+ var WINDOW_OVERLAY_SCHEMA = "fusiform-window-overlay/v1";
36054
+ var PROMPT_WALL_MARGIN = 4096;
36055
+ var PI_OUTPUT_FLOOR = 4096;
36056
+ var OPENCODE_OUTPUT_CAP = 32000;
36057
+ var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
36058
+ var OUTPUT_RESERVE_CAP_RATIO = 0.25;
36059
+ var PROVIDER_GEOMETRY = {
36060
+ anthropic: "shared_truncating",
36061
+ xai: "shared_truncating",
36062
+ google: "separate",
36063
+ "google-antigravity": "separate"
35452
36064
  };
35453
- function remapProviderPrefix(ref, map2) {
35454
- if (typeof ref !== "string")
35455
- return ref;
35456
- const slash = ref.indexOf("/");
35457
- if (slash <= 0)
35458
- return ref;
35459
- const provider = ref.slice(0, slash);
35460
- if (!Object.hasOwn(map2, provider))
35461
- return ref;
35462
- return `${map2[provider]}${ref.slice(slash)}`;
36065
+ var GRADES = new Set([
36066
+ "provider_asserted_runtime",
36067
+ "measured",
36068
+ "provider_asserted_doc",
36069
+ "catalog",
36070
+ "unknown"
36071
+ ]);
36072
+ var UNITS = new Set(["provider", "estimate"]);
36073
+ var BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
36074
+ var UNKNOWN_REASONS = new Set([
36075
+ "placeholder_output_equals_context",
36076
+ "placeholder_zero",
36077
+ "never_measured",
36078
+ "not_single_valued_at_key",
36079
+ "retracted"
36080
+ ]);
36081
+ var NUMERIC_FACT_KEYS = new Set([
36082
+ "window.advertised",
36083
+ "window.enforced",
36084
+ "output.advertised",
36085
+ "output.enforced",
36086
+ "output.default"
36087
+ ]);
36088
+ var configuredOverlayPath;
36089
+ var loadedOverlayPath;
36090
+ var loadedOverlay;
36091
+ var geometryClampLogSeen = new Set;
36092
+ function isRecord2(value) {
36093
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35463
36094
  }
35464
- function piModelRefToCanonical(ref) {
35465
- return remapProviderPrefix(ref, PI_TO_CANONICAL_PROVIDER);
36095
+ function isFinitePositive(value) {
36096
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
35466
36097
  }
35467
- function resolveModelRefForPi(ref) {
35468
- return remapProviderPrefix(piModelRefToCanonical(ref), CANONICAL_TO_PI_PROVIDER);
36098
+ function modelKeyLookupOrder2(providerID, modelID) {
36099
+ const candidates = [...modelRefLookupOrder(`${providerID}/${modelID}`), modelID];
36100
+ const colon = modelID.lastIndexOf(":");
36101
+ if (colon > 0) {
36102
+ const bareModel = modelID.slice(0, colon);
36103
+ candidates.push(...modelRefLookupOrder(`${providerID}/${bareModel}`), bareModel);
36104
+ }
36105
+ return [...new Set(candidates)];
35469
36106
  }
35470
- function ompModelRefToCanonical(ref) {
35471
- return remapProviderPrefix(ref, OMP_TO_CANONICAL_PROVIDER);
36107
+ function configuredOutputReserve(config2, providerID, modelID) {
36108
+ if (typeof config2 === "number") {
36109
+ return Number.isFinite(config2) && config2 >= 0 ? config2 : undefined;
36110
+ }
36111
+ if (!config2)
36112
+ return;
36113
+ for (const candidate of modelKeyLookupOrder2(providerID, modelID)) {
36114
+ const value = config2[candidate];
36115
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0)
36116
+ return value;
36117
+ }
36118
+ return Number.isFinite(config2.default) && config2.default >= 0 ? config2.default : undefined;
35472
36119
  }
35473
- function resolveModelRefForOmp(ref) {
35474
- return remapProviderPrefix(ompModelRefToCanonical(ref), CANONICAL_TO_OMP_PROVIDER);
36120
+ function scalarizeFact(value) {
36121
+ if (value.kind === "stated")
36122
+ return isFinitePositive(value.value) ? value.value : undefined;
36123
+ if (value.kind === "bracket") {
36124
+ return isFinitePositive(value.at_least) ? value.at_least : undefined;
36125
+ }
36126
+ return;
36127
+ }
36128
+ function parseFactValue(value) {
36129
+ if (!isRecord2(value) || typeof value.kind !== "string")
36130
+ return;
36131
+ if (value.kind === "stated") {
36132
+ if ((typeof value.value !== "number" || !Number.isFinite(value.value)) && typeof value.value !== "string") {
36133
+ return;
36134
+ }
36135
+ return { kind: "stated", value: value.value };
36136
+ }
36137
+ if (value.kind === "bracket") {
36138
+ const atLeast = value.at_least;
36139
+ const below = value.below;
36140
+ if (atLeast === undefined && below === undefined)
36141
+ return { kind: "bracket" };
36142
+ if (atLeast !== undefined && !isFinitePositive(atLeast))
36143
+ return;
36144
+ if (below !== undefined && !isFinitePositive(below))
36145
+ return;
36146
+ if (isFinitePositive(atLeast) && isFinitePositive(below) && below <= atLeast) {
36147
+ return;
36148
+ }
36149
+ return {
36150
+ kind: "bracket",
36151
+ ...isFinitePositive(atLeast) ? { at_least: atLeast } : {},
36152
+ ...isFinitePositive(below) ? { below } : {}
36153
+ };
36154
+ }
36155
+ if (value.kind === "unknown" && UNKNOWN_REASONS.has(value.why)) {
36156
+ return { kind: "unknown", why: value.why };
36157
+ }
36158
+ return;
36159
+ }
36160
+ function parseFact(key, value) {
36161
+ if (!isRecord2(value))
36162
+ return;
36163
+ const parsedValue = parseFactValue(value.value);
36164
+ if (!parsedValue || !GRADES.has(value.grade) || !UNITS.has(value.units) || !BOUNDARIES.has(value.boundary) || typeof value.source_ref !== "string" || value.source_ref.length === 0 || typeof value.observed_at !== "string" || value.observed_at.length === 0) {
36165
+ return;
36166
+ }
36167
+ if (NUMERIC_FACT_KEYS.has(key) && parsedValue.kind === "stated" && !isFinitePositive(parsedValue.value)) {
36168
+ return;
36169
+ }
36170
+ if (key === "geometry" && parsedValue.kind === "stated" && !["shared_upfront", "shared_truncating", "separate"].includes(String(parsedValue.value))) {
36171
+ return;
36172
+ }
36173
+ return {
36174
+ ...value,
36175
+ value: parsedValue,
36176
+ grade: value.grade,
36177
+ units: value.units,
36178
+ boundary: value.boundary,
36179
+ source_ref: value.source_ref,
36180
+ observed_at: value.observed_at
36181
+ };
36182
+ }
36183
+ function parseWindowOverlay(value) {
36184
+ if (!isRecord2(value)) {
36185
+ return { badCells: 0, refusal: "overlay root is not an object" };
36186
+ }
36187
+ if (value.schema !== WINDOW_OVERLAY_SCHEMA) {
36188
+ return {
36189
+ badCells: 0,
36190
+ refusal: `unrecognized schema ${JSON.stringify(value.schema)}`
36191
+ };
36192
+ }
36193
+ if (typeof value.generated_at !== "string" || !Array.isArray(value.minted_provider_ids) || !value.minted_provider_ids.every((id) => typeof id === "string" && id.length > 0) || !Array.isArray(value.cells)) {
36194
+ return { badCells: 0, refusal: "invalid v1 envelope" };
36195
+ }
36196
+ const cells = [];
36197
+ let badCells = 0;
36198
+ for (const rawCell of value.cells) {
36199
+ if (!isRecord2(rawCell) || typeof rawCell.provider_id !== "string" || rawCell.provider_id.length === 0 || typeof rawCell.model_id !== "string" || rawCell.model_id.length === 0 || !isRecord2(rawCell.facts)) {
36200
+ badCells++;
36201
+ continue;
36202
+ }
36203
+ const facts = {};
36204
+ let valid = true;
36205
+ for (const [key, rawFact] of Object.entries(rawCell.facts)) {
36206
+ const fact = parseFact(key, rawFact);
36207
+ if (!fact) {
36208
+ valid = false;
36209
+ break;
36210
+ }
36211
+ facts[key] = fact;
36212
+ }
36213
+ if (!valid) {
36214
+ badCells++;
36215
+ continue;
36216
+ }
36217
+ cells.push({
36218
+ provider_id: rawCell.provider_id,
36219
+ model_id: rawCell.model_id,
36220
+ facts
36221
+ });
36222
+ }
36223
+ return {
36224
+ overlay: {
36225
+ schema: WINDOW_OVERLAY_SCHEMA,
36226
+ generated_at: value.generated_at,
36227
+ minted_provider_ids: [...value.minted_provider_ids],
36228
+ cells
36229
+ },
36230
+ badCells
36231
+ };
36232
+ }
36233
+ function defaultWindowOverlayPath() {
36234
+ return join6(getDataDir(), "fusiform", "window-overlay.json");
36235
+ }
36236
+ function readWindowOverlayFile(path3, log2 = (message) => sessionLog("global", message)) {
36237
+ let raw;
36238
+ try {
36239
+ raw = readFileSync9(path3, "utf8");
36240
+ } catch (error51) {
36241
+ if (error51.code === "ENOENT")
36242
+ return;
36243
+ log2(`window-overlay: unable to read ${path3}; overlay ignored`);
36244
+ return;
36245
+ }
36246
+ let decoded;
36247
+ try {
36248
+ decoded = JSON.parse(raw);
36249
+ } catch {
36250
+ log2(`window-overlay: invalid JSON in ${path3}; overlay ignored`);
36251
+ return;
36252
+ }
36253
+ const parsed = parseWindowOverlay(decoded);
36254
+ if (parsed.refusal) {
36255
+ log2(`window-overlay: ${parsed.refusal} in ${path3}; entire overlay ignored`);
36256
+ return;
36257
+ }
36258
+ if (parsed.badCells > 0) {
36259
+ log2(`window-overlay: skipped ${parsed.badCells} invalid cell(s) from ${path3}`);
36260
+ }
36261
+ return parsed.overlay;
36262
+ }
36263
+ function setWindowOverlayPath(path3) {
36264
+ configuredOverlayPath = path3;
36265
+ loadedOverlayPath = undefined;
36266
+ loadedOverlay = undefined;
36267
+ }
36268
+ function getWindowOverlay() {
36269
+ const path3 = configuredOverlayPath ?? defaultWindowOverlayPath();
36270
+ if (loadedOverlayPath === path3 && loadedOverlay !== undefined) {
36271
+ return loadedOverlay ?? undefined;
36272
+ }
36273
+ loadedOverlayPath = path3;
36274
+ loadedOverlay = readWindowOverlayFile(path3) ?? null;
36275
+ return loadedOverlay ?? undefined;
36276
+ }
36277
+ function resolveWindowOverlayFacts(providerID, modelID, overlay = getWindowOverlay()) {
36278
+ if (!overlay)
36279
+ return;
36280
+ const modelRefs = modelRefLookupOrder(`${providerID}/${modelID}`);
36281
+ const providerCandidates = new Set(modelRefs.map((ref) => ref.slice(0, ref.indexOf("/"))));
36282
+ const modelCandidates = new Set([
36283
+ modelID,
36284
+ ...modelRefs.map((ref) => ref.slice(ref.indexOf("/") + 1))
36285
+ ]);
36286
+ const colon = modelID.lastIndexOf(":");
36287
+ if (colon > 0)
36288
+ modelCandidates.add(modelID.slice(0, colon));
36289
+ const wildcardFacts = {};
36290
+ const specificFacts = {};
36291
+ for (const cell of overlay.cells) {
36292
+ if (!providerCandidates.has(cell.provider_id))
36293
+ continue;
36294
+ if (cell.model_id === "*")
36295
+ Object.assign(wildcardFacts, cell.facts);
36296
+ else if (modelCandidates.has(cell.model_id))
36297
+ Object.assign(specificFacts, cell.facts);
36298
+ }
36299
+ const facts = { ...wildcardFacts, ...specificFacts };
36300
+ return Object.keys(facts).length > 0 ? { facts } : undefined;
36301
+ }
36302
+ function numericOverlayFact(overlay, key) {
36303
+ const fact = overlay?.facts[key];
36304
+ return fact ? scalarizeFact(fact.value) : undefined;
36305
+ }
36306
+ function overlayGeometry(overlay) {
36307
+ const fact = overlay?.facts.geometry;
36308
+ if (fact === undefined)
36309
+ return;
36310
+ if (fact.value.kind === "unknown")
36311
+ return { kind: "unknown" };
36312
+ if (fact.value.kind !== "stated")
36313
+ return;
36314
+ const value = fact.value.value;
36315
+ return value === "shared_upfront" || value === "shared_truncating" || value === "separate" ? { kind: "stated", value } : undefined;
36316
+ }
36317
+ function placeholderFilteredOutput(output, context) {
36318
+ if (!isFinitePositive(output))
36319
+ return;
36320
+ if (isFinitePositive(context) && output >= context)
36321
+ return;
36322
+ return output;
36323
+ }
36324
+ function mergePositive(overlayValue, providerValue) {
36325
+ return isFinitePositive(providerValue) ? providerValue : overlayValue;
36326
+ }
36327
+ function logGeometryClampOnce(key, message, log2) {
36328
+ if (geometryClampLogSeen.has(key))
36329
+ return;
36330
+ geometryClampLogSeen.add(key);
36331
+ (log2 ?? ((entry) => sessionLog("global", `window-geometry: ${entry}`)))(message);
36332
+ }
36333
+ function deriveWindowGeometry(providerID, modelID, catalogLimit, options = {}) {
36334
+ if (!catalogLimit && !options.providerLimit)
36335
+ return;
36336
+ const providerLimit = options.providerLimit;
36337
+ const catalogContext = isFinitePositive(catalogLimit?.context) ? catalogLimit.context : undefined;
36338
+ const advertised = numericOverlayFact(options.overlay, "window.advertised");
36339
+ const enforced = numericOverlayFact(options.overlay, "window.enforced");
36340
+ let softContext = mergePositive(enforced ?? advertised ?? catalogContext, providerLimit?.context);
36341
+ let hardContext = mergePositive(enforced ?? softContext, providerLimit?.context);
36342
+ if (isFinitePositive(options.contextCap)) {
36343
+ softContext = isFinitePositive(softContext) ? Math.min(softContext, options.contextCap) : options.contextCap;
36344
+ hardContext = isFinitePositive(hardContext) ? Math.min(hardContext, options.contextCap) : options.contextCap;
36345
+ }
36346
+ const input = mergePositive(isFinitePositive(catalogLimit?.input) ? catalogLimit.input : undefined, providerLimit?.input);
36347
+ if (!isFinitePositive(softContext) && !isFinitePositive(input))
36348
+ return;
36349
+ const catalogOutput = options.overlay === undefined && options.providerLimit === undefined ? isFinitePositive(catalogLimit?.output) ? catalogLimit.output : undefined : placeholderFilteredOutput(catalogLimit?.output, softContext);
36350
+ const overlayOutput = placeholderFilteredOutput(numericOverlayFact(options.overlay, "output.enforced") ?? numericOverlayFact(options.overlay, "output.default") ?? numericOverlayFact(options.overlay, "output.advertised"), softContext);
36351
+ const providerOutput = placeholderFilteredOutput(providerLimit?.output, softContext);
36352
+ const output = providerOutput ?? overlayOutput ?? catalogOutput;
36353
+ const geometryFact = overlayGeometry(options.overlay);
36354
+ const geometry = geometryFact?.kind === "stated" ? geometryFact.value : geometryFact?.kind === "unknown" ? "shared_upfront" : PROVIDER_GEOMETRY[providerID] ?? "shared_upfront";
36355
+ const geometryOverride = geometryFact?.kind === "stated" ? geometryFact.value : undefined;
36356
+ let usableSoft;
36357
+ let softReserve = 0;
36358
+ let reserveSource = "none";
36359
+ if (isFinitePositive(input) && (!isFinitePositive(softContext) || input < softContext)) {
36360
+ usableSoft = input;
36361
+ if (isFinitePositive(softContext)) {
36362
+ softReserve = Math.max(0, softContext - input);
36363
+ reserveSource = "output_catalog";
36364
+ }
36365
+ } else if (isFinitePositive(softContext)) {
36366
+ const configuredReserve = configuredOutputReserve(options.reserveConfig, providerID, modelID);
36367
+ if (configuredReserve !== undefined) {
36368
+ softReserve = configuredReserve;
36369
+ reserveSource = "output_config";
36370
+ } else if (geometry === "separate" && (options.overlay === undefined || options.harness === "pi" || geometryOverride !== undefined)) {
36371
+ softReserve = 0;
36372
+ reserveSource = "none";
36373
+ } else {
36374
+ softReserve = output ?? 0;
36375
+ reserveSource = output === undefined ? "none" : "output_catalog";
36376
+ const cap = softContext * OUTPUT_RESERVE_CAP_RATIO;
36377
+ softReserve = Math.min(softReserve, options.harness === "pi" || options.overlay === undefined ? cap : Math.min(cap, OPENCODE_OUTPUT_CAP));
36378
+ }
36379
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, softContext * 0.5);
36380
+ const flooredReserve = Math.min(softReserve, Math.max(0, softContext - floor));
36381
+ if (flooredReserve < softReserve) {
36382
+ logGeometryClampOnce(`soft-floor|${providerID}/${modelID}|${softReserve}|${flooredReserve}`, `output reserve clamped by the half-window floor for ${providerID}/${modelID}: reserve ${softReserve} → ${flooredReserve} (catalog context/output pair is contradictory)`, options.log);
36383
+ }
36384
+ softReserve = flooredReserve;
36385
+ usableSoft = Math.floor(softContext - softReserve);
36386
+ } else {
36387
+ usableSoft = input;
36388
+ }
36389
+ const hardWindow = hardContext ?? softContext ?? input;
36390
+ if (!isFinitePositive(hardWindow))
36391
+ return;
36392
+ let usableHard;
36393
+ if (geometry === "separate") {
36394
+ usableHard = hardWindow;
36395
+ } else if (geometry === "shared_truncating") {
36396
+ usableHard = hardWindow - PROMPT_WALL_MARGIN;
36397
+ } else if (options.harness === "pi" && providerID !== "openai-codex") {
36398
+ usableHard = hardWindow - PI_OUTPUT_FLOOR;
36399
+ } else if (options.harness === "pi") {
36400
+ usableHard = hardWindow - (output ?? OPENCODE_OUTPUT_CAP);
36401
+ } else {
36402
+ const requestedOutput = Math.min(output ?? OPENCODE_OUTPUT_CAP, OPENCODE_OUTPUT_CAP);
36403
+ usableHard = hardWindow - requestedOutput;
36404
+ }
36405
+ usableHard = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, Math.floor(usableHard));
36406
+ if (usableHard < usableSoft) {
36407
+ logGeometryClampOnce(`${providerID}/${modelID}|${usableSoft}|${usableHard}`, `usable hard limit clamped for ${providerID}/${modelID}: ${usableHard} → ${usableSoft} (overlay/provider inversion)`, options.log);
36408
+ usableHard = usableSoft;
36409
+ }
36410
+ return {
36411
+ usableSoft,
36412
+ usableHard,
36413
+ geometry,
36414
+ derivation: {
36415
+ window: Math.floor(softContext ?? usableSoft),
36416
+ reserve: Math.floor(Math.max(0, (softContext ?? usableSoft) - usableSoft)),
36417
+ reserveSource,
36418
+ geometry
36419
+ }
36420
+ };
36421
+ }
36422
+ function formatWindowDerivationLine(inputTokens, result) {
36423
+ const percentage = result.usableSoft > 0 ? inputTokens / result.usableSoft * 100 : 0;
36424
+ const reserveLabel = result.derivation.reserveSource === "wall_margin" ? "wall margin" : result.derivation.reserveSource === "none" ? "reserve" : "output reserve";
36425
+ return `Context: ${formatCompactTokens(inputTokens)} / ${formatCompactTokens(result.usableSoft)} usable (${percentage.toFixed(1)}%) — window ${formatCompactTokens(result.derivation.window)} − ${formatCompactTokens(result.derivation.reserve)} ${reserveLabel} [${result.geometry}]`;
36426
+ }
36427
+ function formatCompactTokens(value) {
36428
+ if (Math.abs(value) >= 1e6) {
36429
+ return `${(value / 1e6).toFixed(1).replace(/\.0$/, "")}m`;
36430
+ }
36431
+ if (Math.abs(value) >= 1000) {
36432
+ return `${(value / 1000).toFixed(1).replace(/\.0$/, "")}k`;
36433
+ }
36434
+ return Math.round(value).toLocaleString();
35475
36435
  }
35476
36436
 
35477
36437
  // ../plugin/src/shared/models-dev-cache.ts
@@ -35481,21 +36441,21 @@ function isSaneLimit(limit) {
35481
36441
  return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
35482
36442
  }
35483
36443
  var SEPARATE_OUTPUT_QUOTA_PROVIDERS = new Set(["google", "google-antigravity"]);
35484
- var MIN_PLAUSIBLE_CONTEXT_LIMIT = 1024;
35485
- var OUTPUT_RESERVE_CAP_RATIO = 0.25;
36444
+ var MIN_PLAUSIBLE_CONTEXT_LIMIT2 = 1024;
36445
+ var OUTPUT_RESERVE_CAP_RATIO2 = 0.25;
35486
36446
  var outputReserveConfig;
35487
36447
  var reserveClampLogSeen = new Set;
35488
36448
  var apiCache = null;
35489
36449
  var persistSeedLoaded = false;
35490
36450
  function persistFilePath() {
35491
- return join5(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
36451
+ return join7(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
35492
36452
  }
35493
36453
  function loadPersistedApiCacheOnce() {
35494
36454
  if (persistSeedLoaded || apiCache !== null)
35495
36455
  return;
35496
36456
  persistSeedLoaded = true;
35497
36457
  try {
35498
- const raw = readFileSync8(persistFilePath(), "utf-8");
36458
+ const raw = readFileSync10(persistFilePath(), "utf-8");
35499
36459
  const obj = JSON.parse(raw);
35500
36460
  const map2 = new Map;
35501
36461
  for (const [key, persisted] of Object.entries(obj)) {
@@ -35509,7 +36469,7 @@ function loadPersistedApiCacheOnce() {
35509
36469
  limit: isSaneLimit(limit) ? limit : undefined,
35510
36470
  contextLimit: isSaneLimit(contextLimit) ? contextLimit : undefined,
35511
36471
  inputLimit: isSaneLimit(inputLimit) ? inputLimit : undefined,
35512
- outputLimit: isFinitePositive(outputLimit) ? outputLimit : undefined,
36472
+ outputLimit: isFinitePositive2(outputLimit) ? outputLimit : undefined,
35513
36473
  vision
35514
36474
  });
35515
36475
  }
@@ -35520,27 +36480,24 @@ function loadPersistedApiCacheOnce() {
35520
36480
  }
35521
36481
  } catch {}
35522
36482
  }
35523
- function isFinitePositive(value) {
36483
+ function isFinitePositive2(value) {
35524
36484
  return typeof value === "number" && Number.isFinite(value) && value > 0;
35525
36485
  }
35526
- function modelKeyLookupOrder2(providerID, modelID) {
35527
- const full = `${providerID}/${modelID}`;
35528
- const canonicalFull = piModelRefToCanonical(full);
35529
- const candidates = [full, canonicalFull, modelID];
36486
+ function modelKeyLookupOrder3(providerID, modelID) {
36487
+ const candidates = [...modelRefLookupOrder(`${providerID}/${modelID}`), modelID];
35530
36488
  const colon = modelID.lastIndexOf(":");
35531
36489
  if (colon > 0) {
35532
36490
  const bareModel = modelID.slice(0, colon);
35533
- const providerBare = `${providerID}/${bareModel}`;
35534
- candidates.push(providerBare, piModelRefToCanonical(providerBare), bareModel);
36491
+ candidates.push(...modelRefLookupOrder(`${providerID}/${bareModel}`), bareModel);
35535
36492
  }
35536
36493
  return [...new Set(candidates)];
35537
36494
  }
35538
- function configuredOutputReserve(config2, providerID, modelID) {
36495
+ function configuredOutputReserve2(config2, providerID, modelID) {
35539
36496
  if (typeof config2 === "number")
35540
36497
  return Number.isFinite(config2) && config2 >= 0 ? config2 : undefined;
35541
36498
  if (!config2)
35542
36499
  return;
35543
- for (const candidate of modelKeyLookupOrder2(providerID, modelID)) {
36500
+ for (const candidate of modelKeyLookupOrder3(providerID, modelID)) {
35544
36501
  const value = config2[candidate];
35545
36502
  if (typeof value === "number" && Number.isFinite(value) && value >= 0)
35546
36503
  return value;
@@ -35559,27 +36516,27 @@ function setOutputReserveConfig(config2) {
35559
36516
  function resolveLimit(limit, providerID, modelID, reserveConfig = outputReserveConfig) {
35560
36517
  if (!limit)
35561
36518
  return;
35562
- const context = isFinitePositive(limit.context) ? limit.context : undefined;
35563
- const input = isFinitePositive(limit.input) ? limit.input : undefined;
36519
+ const context = isFinitePositive2(limit.context) ? limit.context : undefined;
36520
+ const input = isFinitePositive2(limit.input) ? limit.input : undefined;
35564
36521
  if (input !== undefined && (context === undefined || input < context))
35565
36522
  return input;
35566
36523
  if (context === undefined)
35567
36524
  return;
35568
- const configuredReserve = configuredOutputReserve(reserveConfig, providerID, modelID);
36525
+ const configuredReserve = configuredOutputReserve2(reserveConfig, providerID, modelID);
35569
36526
  let reserve;
35570
36527
  if (configuredReserve !== undefined) {
35571
36528
  reserve = configuredReserve;
35572
36529
  } else if (SEPARATE_OUTPUT_QUOTA_PROVIDERS.has(providerID)) {
35573
36530
  reserve = 0;
35574
36531
  } else {
35575
- const output = isFinitePositive(limit.output) ? limit.output : 0;
35576
- const cap = context * OUTPUT_RESERVE_CAP_RATIO;
36532
+ const output = isFinitePositive2(limit.output) ? limit.output : 0;
36533
+ const cap = context * OUTPUT_RESERVE_CAP_RATIO2;
35577
36534
  reserve = Math.min(output, cap);
35578
36535
  if (output > cap) {
35579
36536
  logReserveClampOnce(`cap|${providerID}/${modelID}|${context}|${output}`, `output reserve capped at 25% for ${providerID}/${modelID}: ${output} → ${cap}`);
35580
36537
  }
35581
36538
  }
35582
- const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT, context * 0.5);
36539
+ const floor = Math.max(MIN_PLAUSIBLE_CONTEXT_LIMIT2, context * 0.5);
35583
36540
  const maxReserve = Math.max(0, context - floor);
35584
36541
  if (reserve > maxReserve) {
35585
36542
  logReserveClampOnce(`floor|${providerID}/${modelID}|${context}|${reserve}`, `output reserve clamped for ${providerID}/${modelID}: ${reserve} → ${maxReserve} (usable floor ${floor})`);
@@ -35587,15 +36544,46 @@ function resolveLimit(limit, providerID, modelID, reserveConfig = outputReserveC
35587
36544
  }
35588
36545
  return Math.floor(context - reserve);
35589
36546
  }
36547
+ function getSdkWindowGeometry(providerID, modelID, detectedContextLimit, options) {
36548
+ loadPersistedApiCacheOnce();
36549
+ const metadata = lookupMetadataWithTagFallback(apiCache, providerID, modelID);
36550
+ if (!metadata)
36551
+ return;
36552
+ const rawContext = metadata.contextLimit ?? metadata.limit;
36553
+ const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined;
36554
+ const result = deriveWindowGeometry(providerID, modelID, {
36555
+ context: rawContext,
36556
+ input: metadata.inputLimit,
36557
+ output: metadata.outputLimit
36558
+ }, {
36559
+ overlay: resolveWindowOverlayFacts(providerID, modelID, getWindowOverlay()),
36560
+ reserveConfig: outputReserveConfig,
36561
+ harness: options?.harness ?? "opencode",
36562
+ contextCap: promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined
36563
+ });
36564
+ if (!result || promptOnlyDetected === undefined)
36565
+ return result;
36566
+ const usableSoft = promptOnlyDetected;
36567
+ return {
36568
+ ...result,
36569
+ usableSoft,
36570
+ usableHard: Math.max(usableSoft, Math.min(result.usableHard, promptOnlyDetected))
36571
+ };
36572
+ }
35590
36573
  function getSdkContextLimit(providerID, modelID, detectedContextLimit, options) {
36574
+ if (options?.reservation !== "none") {
36575
+ return getSdkWindowGeometry(providerID, modelID, detectedContextLimit, {
36576
+ detectedLimitProvenance: options?.detectedLimitProvenance
36577
+ })?.usableSoft;
36578
+ }
35591
36579
  loadPersistedApiCacheOnce();
35592
36580
  const metadata = lookupMetadataWithTagFallback(apiCache, providerID, modelID);
35593
36581
  if (!metadata)
35594
36582
  return;
35595
36583
  const rawContext = metadata.contextLimit ?? metadata.limit;
35596
- const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive(detectedContextLimit) ? detectedContextLimit : undefined;
35597
- const context = promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) && isFinitePositive(rawContext) ? Math.min(rawContext, detectedContextLimit) : promptOnlyDetected === undefined && isFinitePositive(detectedContextLimit) ? detectedContextLimit : rawContext;
35598
- const inputCandidates = [metadata.inputLimit, promptOnlyDetected].filter(isFinitePositive);
36584
+ const promptOnlyDetected = options?.detectedLimitProvenance === "prompt_only" && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : undefined;
36585
+ const context = promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) && isFinitePositive2(rawContext) ? Math.min(rawContext, detectedContextLimit) : promptOnlyDetected === undefined && isFinitePositive2(detectedContextLimit) ? detectedContextLimit : rawContext;
36586
+ const inputCandidates = [metadata.inputLimit, promptOnlyDetected].filter(isFinitePositive2);
35599
36587
  const input = inputCandidates.length > 0 ? Math.min(...inputCandidates) : undefined;
35600
36588
  return resolveLimit({
35601
36589
  context,
@@ -35637,25 +36625,28 @@ function getUserConfigPaths() {
35637
36625
  return [`${basePath}.jsonc`, `${basePath}.json`];
35638
36626
  }
35639
36627
  function resolveFirstExisting(paths) {
35640
- return paths.find((path3) => existsSync9(path3));
36628
+ return paths.find((path3) => existsSync10(path3));
35641
36629
  }
35642
36630
  function resolvePiLegacyFallback(sources) {
35643
- return sources.find((source) => existsSync9(source.path)) ?? null;
36631
+ return sources.find((source) => existsSync10(source.path)) ?? null;
35644
36632
  }
35645
36633
  function loadConfigFile(path3, scope) {
35646
36634
  try {
35647
- const rawText = readFileSync9(path3, "utf-8");
36635
+ const rawText = readFileSync11(path3, "utf-8");
35648
36636
  const substituted = substituteConfigVariables({
35649
36637
  text: rawText,
35650
36638
  configPath: path3,
35651
36639
  isProjectConfig: scope === "project"
35652
36640
  });
36641
+ const rejectedKeyPaths = [];
36642
+ const config2 = sanitizeParsedJson(import_comment_json.parse(substituted.text), { onRejectedKey: (keyPath) => rejectedKeyPaths.push(keyPath.join(".")) });
36643
+ const unsafeKeyWarnings = rejectedKeyPaths.map((keyPath) => `Ignored unsafe config key "${keyPath}" (security: prototype-pollution keys are not allowed).`);
35653
36644
  return {
35654
36645
  path: path3,
35655
36646
  scope,
35656
- config: import_comment_json.parse(substituted.text),
35657
- warnings: substituted.warnings.map((warning) => `${path3}: ${warning}`),
35658
- loadOutcome: substituted.warnings.length > 0 ? "substitution-failure" : "ok"
36647
+ config: config2,
36648
+ warnings: [...substituted.warnings, ...unsafeKeyWarnings].map((warning) => `${path3}: ${warning}`),
36649
+ loadOutcome: rejectedKeyPaths.length > 0 ? "schema-recovery" : substituted.warnings.length > 0 ? "substitution-failure" : "ok"
35659
36650
  };
35660
36651
  } catch (error51) {
35661
36652
  const message = error51 instanceof Error ? error51.message : String(error51);
@@ -35693,11 +36684,28 @@ function redactConfigValue(value) {
35693
36684
  function isPlainObject4(value) {
35694
36685
  return typeof value === "object" && value !== null && !Array.isArray(value);
35695
36686
  }
36687
+ function defineOwnConfigValue(target, key, value) {
36688
+ Object.defineProperty(target, key, {
36689
+ value,
36690
+ enumerable: true,
36691
+ configurable: true,
36692
+ writable: true
36693
+ });
36694
+ }
35696
36695
  function mergeRawConfigs(base, override) {
35697
- const merged = { ...base };
35698
- for (const [key, overrideValue] of Object.entries(override)) {
35699
- const baseValue = merged[key];
35700
- merged[key] = isPlainObject4(baseValue) && isPlainObject4(overrideValue) ? mergeRawConfigs(baseValue, overrideValue) : overrideValue;
36696
+ const merged = {};
36697
+ for (const key of Object.keys(base)) {
36698
+ if (isPrototypePollutionKey(key))
36699
+ continue;
36700
+ defineOwnConfigValue(merged, key, base[key]);
36701
+ }
36702
+ for (const key of Object.keys(override)) {
36703
+ if (isPrototypePollutionKey(key))
36704
+ continue;
36705
+ const overrideValue = override[key];
36706
+ const baseValue = Object.hasOwn(base, key) ? base[key] : undefined;
36707
+ const mergedValue = isPlainObject4(baseValue) && isPlainObject4(overrideValue) ? mergeRawConfigs(baseValue, overrideValue) : overrideValue;
36708
+ defineOwnConfigValue(merged, key, mergedValue);
35701
36709
  }
35702
36710
  return merged;
35703
36711
  }
@@ -35777,7 +36785,7 @@ function loadPiConfig(opts = {}) {
35777
36785
  if (loaded)
35778
36786
  loadedFiles.push(loaded);
35779
36787
  }
35780
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync9(source.path));
36788
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync10(source.path));
35781
36789
  const userPath = resolveFirstExisting(getUserConfigPaths());
35782
36790
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
35783
36791
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -35786,7 +36794,7 @@ function loadPiConfig(opts = {}) {
35786
36794
  if (loaded)
35787
36795
  loadedFiles.push(loaded);
35788
36796
  }
35789
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync9(source.path));
36797
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync10(source.path));
35790
36798
  if (userLegacyFallback) {
35791
36799
  warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
35792
36800
  } else if (legacyUserUnmigrated) {
@@ -35830,6 +36838,7 @@ function loadPiConfig(opts = {}) {
35830
36838
  }
35831
36839
  const parsed = parsePiConfig(rawConfig);
35832
36840
  setOutputReserveConfig(parsed.config.output_reserve);
36841
+ setWindowOverlayPath(parsed.config.models?.window_overlay_path);
35833
36842
  warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
35834
36843
  return {
35835
36844
  config: parsed.config,
@@ -35897,7 +36906,7 @@ function loadPiConfigDetailed(opts = {}) {
35897
36906
  if (loaded)
35898
36907
  loadedFiles.push(loaded);
35899
36908
  }
35900
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync9(source.path));
36909
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync10(source.path));
35901
36910
  const userPath = resolveFirstExisting(getUserConfigPaths());
35902
36911
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
35903
36912
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -35906,7 +36915,7 @@ function loadPiConfigDetailed(opts = {}) {
35906
36915
  if (loaded)
35907
36916
  loadedFiles.push(loaded);
35908
36917
  }
35909
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync9(source.path));
36918
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync10(source.path));
35910
36919
  if (userLegacyFallback) {
35911
36920
  warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
35912
36921
  } else if (legacyUserUnmigrated) {
@@ -35951,6 +36960,7 @@ function loadPiConfigDetailed(opts = {}) {
35951
36960
  const recoveredTopLevelKeys = [];
35952
36961
  const parsed = parsePiConfig(rawConfig, recoveredTopLevelKeys);
35953
36962
  setOutputReserveConfig(parsed.config.output_reserve);
36963
+ setWindowOverlayPath(parsed.config.models?.window_overlay_path);
35954
36964
  warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
35955
36965
  const substitutionFailures = loadedFiles.flatMap(bindSubstitutionFailures);
35956
36966
  const userLoaded = loadedFiles.find((loaded) => loaded.scope === "user");
@@ -37046,7 +38056,7 @@ class SubcSocket {
37046
38056
  return this.sock.localPort ?? null;
37047
38057
  }
37048
38058
  static connect(host, port, deadlineMs) {
37049
- return new Promise((resolve3, reject) => {
38059
+ return new Promise((resolve4, reject) => {
37050
38060
  const sock = net.connect({ host, port });
37051
38061
  sock.setNoDelay(true);
37052
38062
  const timer = setTimeout(() => {
@@ -37055,7 +38065,7 @@ class SubcSocket {
37055
38065
  }, Math.max(0, deadlineMs - Date.now()));
37056
38066
  sock.once("connect", () => {
37057
38067
  clearTimeout(timer);
37058
- resolve3(new SubcSocket(sock));
38068
+ resolve4(new SubcSocket(sock));
37059
38069
  });
37060
38070
  sock.once("error", (err) => {
37061
38071
  clearTimeout(timer);
@@ -37087,7 +38097,7 @@ class SubcSocket {
37087
38097
  }
37088
38098
  if (n === 0)
37089
38099
  return Promise.resolve(new Uint8Array(0));
37090
- return new Promise((resolve3, reject) => {
38100
+ return new Promise((resolve4, reject) => {
37091
38101
  let timer = null;
37092
38102
  if (Number.isFinite(deadlineMs)) {
37093
38103
  const remaining = deadlineMs - Date.now();
@@ -37100,7 +38110,7 @@ class SubcSocket {
37100
38110
  reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
37101
38111
  }, remaining);
37102
38112
  }
37103
- this.waiter = { need: n, resolve: resolve3, reject, timer };
38113
+ this.waiter = { need: n, resolve: resolve4, reject, timer };
37104
38114
  this.tryServe();
37105
38115
  });
37106
38116
  }
@@ -37124,7 +38134,7 @@ class SubcSocket {
37124
38134
  let queued = false;
37125
38135
  let settled = false;
37126
38136
  let timer = null;
37127
- const completed = new Promise((resolve3, reject) => {
38137
+ const completed = new Promise((resolve4, reject) => {
37128
38138
  const settle = (run) => {
37129
38139
  if (settled)
37130
38140
  return;
@@ -37148,7 +38158,7 @@ class SubcSocket {
37148
38158
  if (err) {
37149
38159
  reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
37150
38160
  } else {
37151
- resolve3();
38161
+ resolve4();
37152
38162
  }
37153
38163
  });
37154
38164
  });
@@ -37364,14 +38374,14 @@ class SubcClient {
37364
38374
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
37365
38375
  const corr = this.allocateCorr();
37366
38376
  const key = pendingKey(handle, corr);
37367
- const closed = new Promise((resolve3, reject) => {
38377
+ const closed = new Promise((resolve4, reject) => {
37368
38378
  if (this.closedErr) {
37369
38379
  reject(this.closedErr);
37370
38380
  return;
37371
38381
  }
37372
38382
  this.pending.set(key, {
37373
38383
  handle,
37374
- resolve: () => resolve3(),
38384
+ resolve: () => resolve4(),
37375
38385
  reject,
37376
38386
  onProgress: onEvent,
37377
38387
  timer: null,
@@ -37456,11 +38466,11 @@ class SubcClient {
37456
38466
  const waiters = [];
37457
38467
  for (const pending of this.pending.values()) {
37458
38468
  if (pending.handle === handle && !pending.subscription) {
37459
- waiters.push(new Promise((resolve3) => {
38469
+ waiters.push(new Promise((resolve4) => {
37460
38470
  const previous = pending.onSettle;
37461
38471
  pending.onSettle = () => {
37462
38472
  previous?.();
37463
- resolve3();
38473
+ resolve4();
37464
38474
  };
37465
38475
  }));
37466
38476
  }
@@ -37516,11 +38526,11 @@ class SubcClient {
37516
38526
  const channel = handle?.channel ?? 0;
37517
38527
  const epoch = handle?.epoch ?? 0;
37518
38528
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
37519
- return new Promise((resolve3, reject) => {
38529
+ return new Promise((resolve4, reject) => {
37520
38530
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
37521
38531
  const pending = {
37522
38532
  handle,
37523
- resolve: resolve3,
38533
+ resolve: resolve4,
37524
38534
  reject,
37525
38535
  onProgress,
37526
38536
  timer: null,
@@ -37594,11 +38604,11 @@ class SubcClient {
37594
38604
  }
37595
38605
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
37596
38606
  };
37597
- return new Promise((resolve3, reject) => {
38607
+ return new Promise((resolve4, reject) => {
37598
38608
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
37599
38609
  const pending = {
37600
38610
  handle,
37601
- resolve: resolve3,
38611
+ resolve: resolve4,
37602
38612
  reject,
37603
38613
  onProgress,
37604
38614
  timer: null,
@@ -37986,7 +38996,7 @@ function normalizeConnectOptions(opts) {
37986
38996
  identity: opts.identity,
37987
38997
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
37988
38998
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
37989
- sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
38999
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms))),
37990
39000
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
37991
39001
  };
37992
39002
  }
@@ -38043,8 +39053,8 @@ class AsyncPermitPool {
38043
39053
  this.available -= 1;
38044
39054
  return this.releaseOnce();
38045
39055
  }
38046
- await new Promise((resolve3) => {
38047
- this.waiters.push(resolve3);
39056
+ await new Promise((resolve4) => {
39057
+ this.waiters.push(resolve4);
38048
39058
  });
38049
39059
  return this.releaseOnce();
38050
39060
  }
@@ -38100,8 +39110,8 @@ class SubcProvider {
38100
39110
  this.currentConn = currentConn;
38101
39111
  this.opts = opts;
38102
39112
  this.storage = storage;
38103
- this.closed = new Promise((resolve3) => {
38104
- this.resolveClosed = resolve3;
39113
+ this.closed = new Promise((resolve4) => {
39114
+ this.resolveClosed = resolve4;
38105
39115
  });
38106
39116
  this.readLoop(sock, this.generation);
38107
39117
  this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
@@ -38121,13 +39131,13 @@ class SubcProvider {
38121
39131
  const key = routeKey(handle, corr);
38122
39132
  const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
38123
39133
  const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
38124
- return await new Promise((resolve3, reject) => {
39134
+ return await new Promise((resolve4, reject) => {
38125
39135
  const timer = setTimeout(() => {
38126
39136
  if (this.pending.delete(key))
38127
39137
  reject(new SubcProviderError("reverse request timed out", "request_timeout"));
38128
39138
  }, timeoutMs);
38129
39139
  this.pending.set(key, {
38130
- resolve: (response) => resolve3(response.body),
39140
+ resolve: (response) => resolve4(response.body),
38131
39141
  reject,
38132
39142
  timer
38133
39143
  });
@@ -38599,7 +39609,7 @@ function normalizeProviderConnectOptions(opts) {
38599
39609
  onBound: opts.onBound,
38600
39610
  onRouteGone: opts.onRouteGone,
38601
39611
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
38602
- sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
39612
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms))),
38603
39613
  restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
38604
39614
  onConnectionState: opts.onConnectionState,
38605
39615
  launchNonce: opts.launchNonce
@@ -38644,7 +39654,7 @@ function errorCode2(err) {
38644
39654
  return;
38645
39655
  }
38646
39656
  async function pauseBeforeStateRetry() {
38647
- await new Promise((resolve3) => setTimeout(resolve3, 0));
39657
+ await new Promise((resolve4) => setTimeout(resolve4, 0));
38648
39658
  }
38649
39659
  function controlFlags() {
38650
39660
  return buildFlags(false, Priority.Passive, false);
@@ -38882,7 +39892,7 @@ function classifyError(value) {
38882
39892
  });
38883
39893
  }
38884
39894
  function wait(ms) {
38885
- return new Promise((resolve3) => setTimeout(resolve3, ms));
39895
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
38886
39896
  }
38887
39897
  function sha256(value) {
38888
39898
  return createHash9("sha256").update(value).digest("hex");
@@ -39361,8 +40371,8 @@ function getEmbeddingProviderIdentity(config2) {
39361
40371
  // ../plugin/src/features/magic-context/memory/embedding-local.ts
39362
40372
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync4 } from "node:fs";
39363
40373
  import { open, stat, unlink, writeFile } from "node:fs/promises";
39364
- import { dirname as dirname5, join as join6 } from "node:path";
39365
- import { pathToFileURL } from "node:url";
40374
+ import { dirname as dirname6, join as join8 } from "node:path";
40375
+ import { pathToFileURL as pathToFileURL2 } from "node:url";
39366
40376
  var LOCK_POLL_MS = 150;
39367
40377
  var STALE_LOCK_MS = 3 * 60000;
39368
40378
  var MAX_LOCK_WAIT_MS = 5 * 60000;
@@ -39401,7 +40411,7 @@ async function acquireModelLoadLock(lockPath) {
39401
40411
  if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
39402
40412
  throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
39403
40413
  }
39404
- await new Promise((resolve3) => setTimeout(resolve3, LOCK_POLL_MS));
40414
+ await new Promise((resolve4) => setTimeout(resolve4, LOCK_POLL_MS));
39405
40415
  }
39406
40416
  }
39407
40417
  }
@@ -39425,8 +40435,8 @@ async function injectWasmOrtForElectron() {
39425
40435
  const { createRequire: createRequireFn } = await import("node:module");
39426
40436
  const requireFn = createRequireFn(import.meta.url);
39427
40437
  const mainEntry = requireFn.resolve("onnxruntime-web");
39428
- const distDir = dirname5(mainEntry);
39429
- const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
40438
+ const distDir = dirname6(mainEntry);
40439
+ const wasmPathsPrefix = `${pathToFileURL2(distDir).href}/`;
39430
40440
  if (ortWeb.env?.wasm) {
39431
40441
  ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
39432
40442
  }
@@ -39562,7 +40572,7 @@ class LocalEmbeddingProvider {
39562
40572
  if (LogLevel && "ERROR" in LogLevel) {
39563
40573
  env.logLevel = LogLevel.ERROR;
39564
40574
  }
39565
- const modelCacheDir = join6(getMagicContextStorageDir(), "models");
40575
+ const modelCacheDir = join8(getMagicContextStorageDir(), "models");
39566
40576
  try {
39567
40577
  if (shouldEnforcePrivateStoragePermissions()) {
39568
40578
  mkdirSync4(modelCacheDir, { recursive: true, mode: 448 });
@@ -39579,7 +40589,7 @@ class LocalEmbeddingProvider {
39579
40589
  log("[magic-context] could not create model cache dir, using library default");
39580
40590
  }
39581
40591
  const createPipeline = transformersModule.pipeline;
39582
- const lockPath = join6(modelCacheDir, ".load.lock");
40592
+ const lockPath = join8(modelCacheDir, ".load.lock");
39583
40593
  const releaseLock = await acquireModelLoadLock(lockPath);
39584
40594
  const stopHeartbeat = startLockHeartbeat(lockPath);
39585
40595
  try {
@@ -39606,7 +40616,7 @@ class LocalEmbeddingProvider {
39606
40616
  }
39607
40617
  const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
39608
40618
  log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
39609
- await new Promise((resolve3) => setTimeout(resolve3, delayMs));
40619
+ await new Promise((resolve4) => setTimeout(resolve4, delayMs));
39610
40620
  }
39611
40621
  }
39612
40622
  if (this.pipeline) {
@@ -39639,8 +40649,8 @@ class LocalEmbeddingProvider {
39639
40649
  if (this.inFlight === 0) {
39640
40650
  return Promise.resolve();
39641
40651
  }
39642
- return new Promise((resolve3) => {
39643
- this.inFlightWaiters.push(resolve3);
40652
+ return new Promise((resolve4) => {
40653
+ this.inFlightWaiters.push(resolve4);
39644
40654
  });
39645
40655
  }
39646
40656
  finishInFlight() {
@@ -39795,9 +40805,14 @@ function blockedEmbeddingEndpointReason(endpoint) {
39795
40805
  function normalizeEndpoint3(endpoint) {
39796
40806
  return endpoint?.trim().replace(/\/+$/, "") ?? "";
39797
40807
  }
39798
- function embeddingModelsMatch(served, requested) {
39799
- const a = served.trim().toLowerCase();
39800
- const b = requested.trim().toLowerCase();
40808
+ function parseEmbeddingModel(model) {
40809
+ const lastColon = model.lastIndexOf(":");
40810
+ if (lastColon > model.lastIndexOf("/")) {
40811
+ return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
40812
+ }
40813
+ return { base: model };
40814
+ }
40815
+ function matchNormalizedEmbeddingModels(a, b) {
39801
40816
  if (a.length === 0 || b.length === 0)
39802
40817
  return true;
39803
40818
  if (a === b)
@@ -39811,6 +40826,16 @@ function embeddingModelsMatch(served, requested) {
39811
40826
  return true;
39812
40827
  return false;
39813
40828
  }
40829
+ function embeddingModelsMatch(served, requested) {
40830
+ const a = served.trim().toLowerCase();
40831
+ const b = requested.trim().toLowerCase();
40832
+ const servedModel = parseEmbeddingModel(a);
40833
+ const requestedModel = parseEmbeddingModel(b);
40834
+ if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
40835
+ return false;
40836
+ }
40837
+ return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
40838
+ }
39814
40839
  var FAILURE_THRESHOLD = 3;
39815
40840
  var FAILURE_WINDOW_MS = 60000;
39816
40841
  var OPEN_DURATION_MS = 5 * 60000;
@@ -39941,7 +40966,7 @@ class OpenAICompatibleEmbeddingProvider {
39941
40966
  const servedModel = typeof body.model === "string" ? body.model : "";
39942
40967
  if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
39943
40968
  if (!this.modelMismatchLogged) {
39944
- log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". The endpoint likely substituted a loaded model; load/select "${this.model}" on the endpoint, or set embedding.model to the served model.`);
40969
+ log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". Check that the endpoint serves the requested model; variant suffixes and vendor prefixes are matched automatically.`);
39945
40970
  this.modelMismatchLogged = true;
39946
40971
  }
39947
40972
  this.recordFailure(isProbe);
@@ -41338,7 +42363,7 @@ async function runShadowWorker() {
41338
42363
  }
41339
42364
  processed += item.ids.length;
41340
42365
  processedBytes += itemBytes;
41341
- await new Promise((resolve3) => setTimeout(resolve3, 0));
42366
+ await new Promise((resolve4) => setTimeout(resolve4, 0));
41342
42367
  }
41343
42368
  }
41344
42369
  function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
@@ -41699,7 +42724,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
41699
42724
  if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
41700
42725
  break;
41701
42726
  if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
41702
- await new Promise((resolve3) => setTimeout(resolve3, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
42727
+ await new Promise((resolve4) => setTimeout(resolve4, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
41703
42728
  }
41704
42729
  }
41705
42730
  embedded += persistedIds.size;
@@ -41784,7 +42809,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
41784
42809
  }
41785
42810
  embedded += n;
41786
42811
  options?.onProgress?.({ embedded: Math.min(embedded, total), total });
41787
- await new Promise((resolve3) => setTimeout(resolve3, 0));
42812
+ await new Promise((resolve4) => setTimeout(resolve4, 0));
41788
42813
  }
41789
42814
  } finally {
41790
42815
  clearInterval(renewal);
@@ -42526,7 +43551,7 @@ Two recovery modes for finer detail:
42526
43551
  var CTX_EXPAND_TOKEN_BUDGET = 15000;
42527
43552
 
42528
43553
  // ../plugin/src/tools/ctx-expand/render.ts
42529
- function isRecord2(value) {
43554
+ function isRecord3(value) {
42530
43555
  return value !== null && typeof value === "object" && !Array.isArray(value);
42531
43556
  }
42532
43557
  function roleLabel(role) {
@@ -42555,15 +43580,15 @@ function keyArg(input) {
42555
43580
  function asToolPart(part) {
42556
43581
  const type = typeof part.type === "string" ? part.type : "";
42557
43582
  if (type === "tool") {
42558
- const state = isRecord2(part.state) ? part.state : null;
43583
+ const state = isRecord3(part.state) ? part.state : null;
42559
43584
  const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
42560
- const metadata = state && isRecord2(state.metadata) ? state.metadata : null;
43585
+ const metadata = state && isRecord3(state.metadata) ? state.metadata : null;
42561
43586
  const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
42562
43587
  return {
42563
43588
  name: typeof part.tool === "string" ? part.tool : "tool",
42564
43589
  callId: typeof part.callID === "string" ? part.callID : "",
42565
43590
  title,
42566
- input: state && isRecord2(state.input) ? state.input : null,
43591
+ input: state && isRecord3(state.input) ? state.input : null,
42567
43592
  output
42568
43593
  };
42569
43594
  }
@@ -42572,7 +43597,7 @@ function asToolPart(part) {
42572
43597
  name: typeof part.name === "string" ? part.name : "tool",
42573
43598
  callId: typeof part.id === "string" ? part.id : "",
42574
43599
  title: null,
42575
- input: isRecord2(part.input) ? part.input : null,
43600
+ input: isRecord3(part.input) ? part.input : null,
42576
43601
  output: null
42577
43602
  };
42578
43603
  }
@@ -42601,7 +43626,7 @@ function reasoningOf(part) {
42601
43626
  return null;
42602
43627
  }
42603
43628
  function renderPartPreview(part) {
42604
- if (!isRecord2(part))
43629
+ if (!isRecord3(part))
42605
43630
  return null;
42606
43631
  const text = textOf(part);
42607
43632
  if (text !== null) {
@@ -42625,7 +43650,7 @@ function renderPartPreview(part) {
42625
43650
  return ` • [${type}]`;
42626
43651
  }
42627
43652
  function renderPartFull(part) {
42628
- if (!isRecord2(part))
43653
+ if (!isRecord3(part))
42629
43654
  return null;
42630
43655
  const text = textOf(part);
42631
43656
  if (text !== null) {
@@ -47732,25 +48757,6 @@ function getMaxMemoryIdForProjects(db, projectPaths, ownIdentities, shareCategor
47732
48757
  AND (expires_at IS NULL OR expires_at > ?)${sharingFilter.clause}`).get(...identities, expiryCutoff, ...sharingFilter.params);
47733
48758
  return typeof row?.max_id === "number" ? row.max_id : 0;
47734
48759
  }
47735
- function readNewMemoriesForM1Union(db, projectPaths, afterId, expiryCutoff, ownIdentities, shareCategories) {
47736
- const identities = uniqueValues(projectPaths);
47737
- if (identities.length === 0)
47738
- return [];
47739
- const sharingFilter = buildWorkspaceMemorySqlFilter({
47740
- identities,
47741
- ownIdentities,
47742
- shareCategories,
47743
- includeClassificationFields: hasMemoryShareableColumn(db) && hasMemoryScopeColumn(db)
47744
- });
47745
- const rows = db.prepare(`SELECT ${getMemorySelectColumns(db)}
47746
- FROM memories
47747
- WHERE project_path IN (${sqlPlaceholders(identities)})
47748
- AND id > ?
47749
- AND status IN ('active', 'permanent')
47750
- AND (expires_at IS NULL OR expires_at > ?)${sharingFilter.clause}
47751
- ORDER BY ${MEMORY_CATEGORY_ORDER_SQL}, id ASC`).all(...identities, afterId, expiryCutoff, ...sharingFilter.params).filter(isMemoryRow);
47752
- return rows.map(toMemory);
47753
- }
47754
48760
  function getAllActiveMemoriesForMigration(db, projectPath) {
47755
48761
  const rows = getActiveMemoriesNoExpiryStatement(db).all(projectPath).filter(isMemoryRow);
47756
48762
  return rows.map(toMemory);
@@ -48145,7 +49151,7 @@ function getMemoryVerifications(db, memoryIds) {
48145
49151
  }
48146
49152
  // ../plugin/src/features/magic-context/memory/verification-paths.ts
48147
49153
  import { execFile } from "node:child_process";
48148
- import { existsSync as existsSync10, realpathSync as realpathSync2, statSync as statSync7 } from "node:fs";
49154
+ import { existsSync as existsSync11, realpathSync as realpathSync3, statSync as statSync7 } from "node:fs";
48149
49155
  import path3 from "node:path";
48150
49156
  import { promisify } from "node:util";
48151
49157
  var execFileAsync = promisify(execFile);
@@ -48174,7 +49180,7 @@ function isWithin(root, candidate) {
48174
49180
  }
48175
49181
  function safeRealpath(value) {
48176
49182
  try {
48177
- return realpathSync2.native(value);
49183
+ return realpathSync3.native(value);
48178
49184
  } catch {
48179
49185
  return null;
48180
49186
  }
@@ -48252,7 +49258,7 @@ function verificationFileExists(baseRoot, filePath) {
48252
49258
  return false;
48253
49259
  const root = path3.resolve(baseRoot);
48254
49260
  const candidate = path3.resolve(root, filePath);
48255
- return isWithin(root, candidate) && existsSync10(candidate);
49261
+ return isWithin(root, candidate) && existsSync11(candidate);
48256
49262
  }
48257
49263
  async function normalizeVerificationFiles(args) {
48258
49264
  const cwd = path3.resolve(args.cwd);
@@ -48285,7 +49291,7 @@ async function normalizeVerificationFiles(args) {
48285
49291
  warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
48286
49292
  continue;
48287
49293
  }
48288
- if (existsSync10(candidate)) {
49294
+ if (existsSync11(candidate)) {
48289
49295
  try {
48290
49296
  if (statSync7(candidate).isDirectory()) {
48291
49297
  warnings.push(`Skipped verification path "${value}" because it is a directory.`);
@@ -48316,7 +49322,7 @@ async function normalizeVerificationFiles(args) {
48316
49322
  }
48317
49323
  normalized.push(tracked);
48318
49324
  } else {
48319
- if (!existsSync10(candidate)) {
49325
+ if (!existsSync11(candidate)) {
48320
49326
  warnings.push(`Skipped verification path "${value}" because it does not exist.`);
48321
49327
  continue;
48322
49328
  }
@@ -48806,13 +49812,13 @@ function createCtxMemoryTool(deps) {
48806
49812
  }
48807
49813
 
48808
49814
  // ../plugin/src/features/magic-context/smart-notes/condition-compiler.ts
48809
- import { existsSync as existsSync11 } from "node:fs";
49815
+ import { existsSync as existsSync12 } from "node:fs";
48810
49816
  import { isAbsolute as isAbsolute5 } from "node:path";
48811
49817
 
48812
49818
  // ../retina-local-fs/src/path-fence.ts
48813
49819
  import { lstat, readlink, realpath } from "node:fs/promises";
48814
- import { homedir as homedir5 } from "node:os";
48815
- import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute4, join as join7, relative, resolve as resolve3, sep } from "node:path";
49820
+ import { homedir as homedir6 } from "node:os";
49821
+ import { basename as basename3, dirname as dirname7, isAbsolute as isAbsolute4, join as join9, relative, resolve as resolve4, sep } from "node:path";
48816
49822
 
48817
49823
  // ../retina-local-fs/src/errors.ts
48818
49824
  class ProviderError extends Error {
@@ -48826,20 +49832,26 @@ class ProviderError extends Error {
48826
49832
 
48827
49833
  // ../retina-local-fs/src/path-fence.ts
48828
49834
  async function resolveAndFenceProviderPath(configuredPath, options) {
48829
- const configuredHomePath = resolve3(options.homeDirectory ?? process.env.HOME ?? homedir5());
49835
+ const { home, dataDirectory } = await resolveFenceRoots(options);
49836
+ const expanded = configuredPath.startsWith("~/") ? join9(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
49837
+ const absolute = isAbsolute4(expanded) ? resolve4(expanded) : resolve4(options.cwd ?? process.cwd(), expanded);
49838
+ const canonical = await canonicalPath(absolute, options.allowMissing);
49839
+ if (isFencedPath(canonical, home, dataDirectory)) {
49840
+ throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
49841
+ }
49842
+ return canonical;
49843
+ }
49844
+ async function resolveFenceRoots(options) {
49845
+ const configuredHomePath = resolve4(options.homeDirectory ?? process.env.HOME ?? homedir6());
48830
49846
  let home;
48831
49847
  try {
48832
49848
  home = await realpath(configuredHomePath);
48833
49849
  } catch (error51) {
48834
49850
  throw fsError(configuredHomePath, error51);
48835
49851
  }
48836
- const expanded = configuredPath.startsWith("~/") ? join7(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
48837
- const absolute = isAbsolute4(expanded) ? resolve3(expanded) : resolve3(options.cwd ?? process.cwd(), expanded);
48838
- const canonical = await canonicalPath(absolute, options.allowMissing);
48839
- if (isFencedPath(canonical, home)) {
48840
- throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
48841
- }
48842
- return canonical;
49852
+ const configuredDataDirectory = resolve4(options.dataDirectory ?? process.env.XDG_DATA_HOME ?? join9(home, ".local", "share"));
49853
+ const dataDirectory = await canonicalPath(configuredDataDirectory, true);
49854
+ return { home, dataDirectory };
48843
49855
  }
48844
49856
  async function canonicalPath(path4, allowMissing) {
48845
49857
  try {
@@ -48855,22 +49867,22 @@ async function canonicalPath(path4, allowMissing) {
48855
49867
  const metadata = await lstat(candidate);
48856
49868
  if (metadata.isSymbolicLink()) {
48857
49869
  const target2 = await readlink(candidate);
48858
- const resolvedTarget = resolve3(dirname6(candidate), target2);
48859
- return canonicalPath(join7(resolvedTarget, ...suffix), true);
49870
+ const resolvedTarget = resolve4(dirname7(candidate), target2);
49871
+ return canonicalPath(join9(resolvedTarget, ...suffix), true);
48860
49872
  }
48861
49873
  } catch (candidateError) {
48862
49874
  if (!isMissingError(candidateError)) {
48863
49875
  throw fsError(path4, candidateError);
48864
49876
  }
48865
49877
  }
48866
- const parent = dirname6(candidate);
49878
+ const parent = dirname7(candidate);
48867
49879
  if (parent === candidate) {
48868
49880
  throw fsError(path4, error51);
48869
49881
  }
48870
49882
  suffix.unshift(basename3(candidate));
48871
49883
  candidate = parent;
48872
49884
  try {
48873
- return join7(await realpath(candidate), ...suffix);
49885
+ return join9(await realpath(candidate), ...suffix);
48874
49886
  } catch (parentError) {
48875
49887
  if (!isMissingError(parentError)) {
48876
49888
  throw fsError(path4, parentError);
@@ -48879,9 +49891,8 @@ async function canonicalPath(path4, allowMissing) {
48879
49891
  }
48880
49892
  }
48881
49893
  }
48882
- function isFencedPath(canonicalPath2, homeDirectory) {
48883
- const home = resolve3(homeDirectory);
48884
- const cortexkitRoot = join7(home, ".local", "share", "cortexkit");
49894
+ function isFencedPath(canonicalPath2, homeDirectory, dataDirectory = process.env.XDG_DATA_HOME ?? join9(resolve4(homeDirectory), ".local", "share")) {
49895
+ const cortexkitRoot = join9(resolve4(dataDirectory), "cortexkit");
48885
49896
  const relativeToCortexkit = relative(cortexkitRoot, canonicalPath2);
48886
49897
  const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute4(relativeToCortexkit);
48887
49898
  const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
@@ -48890,10 +49901,11 @@ function isFencedPath(canonicalPath2, homeDirectory) {
48890
49901
  const catalogDirectoryCarveIn = pathParts.includes("catalog");
48891
49902
  const moduleBinCarveIn = parts.length >= 2 && parts[1] === "bin";
48892
49903
  const catalogJsonCarveIn = name.endsWith(".json") && name.includes("catalog");
48893
- if (catalogDirectoryCarveIn || moduleBinCarveIn || catalogJsonCarveIn) {
49904
+ const rootWithoutCarveIns = insideCortexkit && (parts[0] === "run" || parts[0] === "magic-context");
49905
+ if (!rootWithoutCarveIns && (catalogDirectoryCarveIn || moduleBinCarveIn || catalogJsonCarveIn)) {
48894
49906
  return false;
48895
49907
  }
48896
- const inFencedRoot = insideCortexkit && ["plexus", "claustrum", "staging"].includes(parts[0] ?? "");
49908
+ const inFencedRoot = insideCortexkit && ["plexus", "claustrum", "staging", "run", "magic-context"].includes(parts[0] ?? "");
48897
49909
  const fencedBasename = name.includes("binding-key") || name.endsWith(".handle");
48898
49910
  const plexusStore = insideCortexkit && parts[0] === "plexus" && name.startsWith("store.db");
48899
49911
  return inFencedRoot || fencedBasename || plexusStore;
@@ -49043,6 +50055,9 @@ function invalid(message) {
49043
50055
  var RETINA_LOCAL_FS_PROVIDER = "local-fs";
49044
50056
  var VALUE = String.raw`(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S+)`;
49045
50057
  async function compileSurfaceCondition(surfaceCondition, options) {
50058
+ const plainReason = unsafeGrammarReason(surfaceCondition);
50059
+ if (plainReason)
50060
+ return { status: "plain", reason: plainReason };
49046
50061
  const parsed = parseCondition(surfaceCondition, options.projectPath);
49047
50062
  if (parsed === null)
49048
50063
  return { status: "plain" };
@@ -49053,7 +50068,7 @@ async function compileSurfaceCondition(surfaceCondition, options) {
49053
50068
  homeDirectory: options.homeDirectory,
49054
50069
  cwd: options.projectPath
49055
50070
  });
49056
- return { path: resolved, exists: existsSync11(resolved) };
50071
+ return { path: resolved, exists: existsSync12(resolved) };
49057
50072
  });
49058
50073
  let predicates;
49059
50074
  try {
@@ -49124,23 +50139,27 @@ function parseCondition(surfaceCondition, projectPath) {
49124
50139
  return predicates.every((predicate) => predicate !== null) ? predicates : null;
49125
50140
  }
49126
50141
  function parseAtomicCondition(text, projectPath) {
49127
- const fileContains = text.match(new RegExp(`^(?:when\\s+)?file\\s+(${VALUE})\\s+(no longer contains|contains)\\s+(.+)$`, "i"));
50142
+ const fileContains = text.match(new RegExp(`^(?:when\\s+)?file\\s+(${VALUE})\\s+(no longer contains|contains)\\s+(${VALUE})$`, "i"));
49128
50143
  if (fileContains) {
50144
+ const path4 = unquote(fileContains[1]);
49129
50145
  const needle = unquote(fileContains[3].trim());
49130
- if (needle === null)
50146
+ if (path4 === null || needle === null)
49131
50147
  return null;
49132
50148
  return {
49133
50149
  kind: "file_contains",
49134
- path: unquote(fileContains[1]) ?? fileContains[1],
50150
+ path: path4,
49135
50151
  needle,
49136
50152
  ...fileContains[2].toLowerCase() === "no longer contains" ? { absent: true } : {}
49137
50153
  };
49138
50154
  }
49139
50155
  const commit = text.match(new RegExp(`^(?:when\\s+)?(?:repo(?:sitory)?\\s+)?(${VALUE})\\s+has\\s+a\\s+commit\\s+(?:after|newer than)\\s+([0-9a-f]{7,64})$`, "i"));
49140
50156
  if (commit) {
50157
+ const repoPath = unquote(commit[1]);
50158
+ if (repoPath === null)
50159
+ return null;
49141
50160
  return {
49142
50161
  kind: "git_commit_after",
49143
- repo_path: unquote(commit[1]) ?? commit[1],
50162
+ repo_path: repoPath,
49144
50163
  sha: commit[2]
49145
50164
  };
49146
50165
  }
@@ -49160,16 +50179,22 @@ function parseAtomicCondition(text, projectPath) {
49160
50179
  }
49161
50180
  const mtime = text.match(new RegExp(`^(?:when\\s+)?(?:file\\s+)?(${VALUE})\\s+(changes|is rebuilt|mtime moves)$`, "i"));
49162
50181
  if (mtime) {
50182
+ const path4 = unquote(mtime[1]);
50183
+ if (path4 === null)
50184
+ return null;
49163
50185
  return {
49164
50186
  kind: "mtime_after",
49165
- path: unquote(mtime[1]) ?? mtime[1]
50187
+ path: path4
49166
50188
  };
49167
50189
  }
49168
50190
  const pathExists = text.match(new RegExp(`^(?:when\\s+)?(?:path\\s+)?(${VALUE})\\s+(exists|is gone)$`, "i"));
49169
50191
  if (pathExists) {
50192
+ const path4 = unquote(pathExists[1]);
50193
+ if (path4 === null)
50194
+ return null;
49170
50195
  return {
49171
50196
  kind: "path_exists",
49172
- path: unquote(pathExists[1]) ?? pathExists[1],
50197
+ path: path4,
49173
50198
  ...pathExists[2].toLowerCase() === "is gone" ? { gone: true } : {}
49174
50199
  };
49175
50200
  }
@@ -49224,12 +50249,42 @@ function splitOrClauses(text) {
49224
50249
  clauses.push(text.slice(start).trim());
49225
50250
  return clauses.filter(Boolean);
49226
50251
  }
50252
+ function unsafeGrammarReason(value) {
50253
+ let quote = null;
50254
+ let escaped = false;
50255
+ for (const character of value) {
50256
+ if (escaped) {
50257
+ escaped = false;
50258
+ continue;
50259
+ }
50260
+ if (quote && character === "\\") {
50261
+ escaped = true;
50262
+ continue;
50263
+ }
50264
+ if (character === '"' || character === "'") {
50265
+ quote = quote === character ? null : quote === null ? character : quote;
50266
+ }
50267
+ }
50268
+ if (quote !== null)
50269
+ return "unbalanced quote; leaving condition dreamer-evaluated";
50270
+ if (/\bcontains\s+no(?:\s|$)/i.test(value)) {
50271
+ return "ambiguous negation after contains; leaving condition dreamer-evaluated";
50272
+ }
50273
+ const temporalSuffix = new RegExp(`\\bcontains\\s+${VALUE}\\s+(?:since|until|after|before|when|while|for|as\\s+of)\\b`, "i");
50274
+ if (temporalSuffix.test(value)) {
50275
+ return "temporal suffix after contains; leaving condition dreamer-evaluated";
50276
+ }
50277
+ return null;
50278
+ }
49227
50279
  function unquote(value) {
49228
- if (value.length < 2)
49229
- return value;
49230
50280
  const quote = value[0];
49231
- if (quote !== '"' && quote !== "'" || value.at(-1) !== quote)
50281
+ const final = value.at(-1);
50282
+ const startsQuoted = quote === '"' || quote === "'";
50283
+ const endsQuoted = final === '"' || final === "'";
50284
+ if (!startsQuoted && !endsQuoted)
49232
50285
  return value;
50286
+ if (!startsQuoted || final !== quote || value.length < 2)
50287
+ return null;
49233
50288
  if (quote === '"') {
49234
50289
  try {
49235
50290
  const parsed = JSON.parse(value);
@@ -49244,6 +50299,63 @@ function singleLine(value) {
49244
50299
  return value.replace(/\s+/g, " ").trim();
49245
50300
  }
49246
50301
 
50302
+ // ../plugin/src/features/magic-context/smart-notes/wake-plane.ts
50303
+ import { join as join10 } from "node:path";
50304
+ var WAKE_PLANE_CAPABILITY = "wake.create";
50305
+ var WAKE_PLANE_STATUS_TTL_MS = 5 * 60 * 1000;
50306
+ var WAKE_PLANE_HANDSHAKE_TIMEOUT_MS = 2000;
50307
+ var cachedStatus = null;
50308
+ var inFlightProbe = null;
50309
+ var catalogProbe = probeWakePlaneCatalog;
50310
+ var now = () => Date.now();
50311
+ function connectionFile() {
50312
+ return join10(getDataDir(), "cortexkit", "run", "subc-connection.json");
50313
+ }
50314
+ async function probeWakePlaneCatalog() {
50315
+ const file2 = connectionFile();
50316
+ if (!await connectionFileExists(file2)) {
50317
+ throw new Error("subc connection is not configured");
50318
+ }
50319
+ const client = await SubcClient.connect({
50320
+ connectionFile: file2,
50321
+ handshakeTimeoutMs: WAKE_PLANE_HANDSHAKE_TIMEOUT_MS
50322
+ });
50323
+ try {
50324
+ return await client.catalogList();
50325
+ } finally {
50326
+ client.close();
50327
+ }
50328
+ }
50329
+ function catalogHasWakePlane(entries) {
50330
+ return entries.some((entry) => Array.isArray(entry.control_ops) && entry.control_ops.includes(WAKE_PLANE_CAPABILITY));
50331
+ }
50332
+ async function probeStatus() {
50333
+ try {
50334
+ return catalogHasWakePlane(await catalogProbe()) ? "present" : "absent";
50335
+ } catch {
50336
+ return "unknown";
50337
+ }
50338
+ }
50339
+ async function wakePlaneStatus() {
50340
+ const cached2 = cachedStatus;
50341
+ if (cached2 && now() < cached2.expiresAt)
50342
+ return cached2.status;
50343
+ if (inFlightProbe)
50344
+ return await inFlightProbe;
50345
+ const startedAt = now();
50346
+ const probe = probeStatus().then((status) => {
50347
+ cachedStatus = { status, expiresAt: startedAt + WAKE_PLANE_STATUS_TTL_MS };
50348
+ return status;
50349
+ });
50350
+ inFlightProbe = probe;
50351
+ try {
50352
+ return await probe;
50353
+ } finally {
50354
+ if (inFlightProbe === probe)
50355
+ inFlightProbe = null;
50356
+ }
50357
+ }
50358
+
49247
50359
  // ../plugin/src/tools/ctx-note/constants.ts
49248
50360
  var CTX_NOTE_DESCRIPTION = `Working notes for this session's future — reminders, follow-ups, and things to revisit later.
49249
50361
 
@@ -49371,6 +50483,15 @@ function createCtxNoteTool(deps) {
49371
50483
  const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
49372
50484
  const surfaceCondition = params.surface_condition?.trim();
49373
50485
  if (surfaceCondition) {
50486
+ if (await wakePlaneStatus() === "present") {
50487
+ const note3 = addNote(deps.db, "session", {
50488
+ sessionId,
50489
+ content,
50490
+ anchorOrdinal
50491
+ });
50492
+ return ok3(`Saved session note #${note3.id}.
50493
+ wake plane active — create a scheduled wake instead; stored as a plain note.`);
50494
+ }
49374
50495
  if (dreamerEnabled !== true) {
49375
50496
  return err3("Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.");
49376
50497
  }
@@ -49685,9 +50806,9 @@ function createCtxReduceTool(deps) {
49685
50806
  }
49686
50807
  try {
49687
50808
  deps.db.transaction(() => {
49688
- const now = Date.now();
50809
+ const now2 = Date.now();
49689
50810
  for (const id of dropIds) {
49690
- queuePendingOp(deps.db, sessionId, id, "drop", now);
50811
+ queuePendingOp(deps.db, sessionId, id, "drop", now2);
49691
50812
  }
49692
50813
  })();
49693
50814
  } catch (error51) {
@@ -51900,11 +53021,11 @@ var USER_MEMORY_CANDIDATE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
51900
53021
  function insertUserMemoryCandidates(db, candidates2) {
51901
53022
  if (candidates2.length === 0)
51902
53023
  return;
51903
- const now = Date.now();
53024
+ const now2 = Date.now();
51904
53025
  const stmt = db.prepare("INSERT INTO user_memory_candidates (content, session_id, source_compartment_start, source_compartment_end, created_at) VALUES (?, ?, ?, ?, ?)");
51905
53026
  db.transaction(() => {
51906
53027
  for (const c of candidates2) {
51907
- stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now);
53028
+ stmt.run(c.content, c.sessionId, c.sourceCompartmentStart ?? null, c.sourceCompartmentEnd ?? null, now2);
51908
53029
  }
51909
53030
  })();
51910
53031
  }
@@ -51925,18 +53046,49 @@ function deleteUserMemoryCandidates(db, ids) {
51925
53046
  const placeholders4 = ids.map(() => "?").join(",");
51926
53047
  db.prepare(`DELETE FROM user_memory_candidates WHERE id IN (${placeholders4})`).run(...ids);
51927
53048
  }
51928
- function pruneExpiredUserMemoryCandidates(db, ttlMs, now = Date.now()) {
51929
- const cutoff = now - ttlMs;
53049
+ function pruneExpiredUserMemoryCandidates(db, ttlMs, now2 = Date.now()) {
53050
+ const cutoff = now2 - ttlMs;
51930
53051
  const result = db.prepare("DELETE FROM user_memory_candidates WHERE created_at < ?").run(cutoff);
51931
53052
  return Number(result.changes ?? 0);
51932
53053
  }
53054
+ function loadUserMemorySourceProvenance(db, candidateIds) {
53055
+ const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
53056
+ if (ids.length === 0)
53057
+ return [];
53058
+ const placeholders4 = ids.map(() => "?").join(",");
53059
+ const rows = db.prepare(`SELECT id, session_id, source_compartment_start, source_compartment_end
53060
+ FROM user_memory_candidates
53061
+ WHERE id IN (${placeholders4})
53062
+ ORDER BY id ASC`).all(...ids);
53063
+ return rows.map((row) => ({
53064
+ candidateId: row.id,
53065
+ sessionId: row.session_id,
53066
+ sourceCompartmentStart: row.source_compartment_start,
53067
+ sourceCompartmentEnd: row.source_compartment_end
53068
+ }));
53069
+ }
53070
+ function serializeUserMemorySourceProvenance(provenance, sourceCandidateIds) {
53071
+ if (provenance.length === 0 && sourceCandidateIds.length > 0)
53072
+ return null;
53073
+ return JSON.stringify(provenance.map((source) => ({
53074
+ candidate_id: source.candidateId,
53075
+ session_id: source.sessionId,
53076
+ source_compartment_start: source.sourceCompartmentStart,
53077
+ source_compartment_end: source.sourceCompartmentEnd
53078
+ })));
53079
+ }
51933
53080
  function insertUserMemory(db, content, sourceCandidateIds) {
51934
- const now = Date.now();
51935
- const result = db.prepare("INSERT INTO user_memories (content, status, promoted_at, source_candidate_ids, created_at, updated_at) VALUES (?, 'active', ?, ?, ?, ?)").run(content, now, JSON.stringify(sourceCandidateIds), now, now);
51936
- return Number(result.lastInsertRowid);
53081
+ return db.transaction(() => {
53082
+ const now2 = Date.now();
53083
+ const sourceProvenance = loadUserMemorySourceProvenance(db, sourceCandidateIds);
53084
+ const result = db.prepare(`INSERT INTO user_memories
53085
+ (content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at)
53086
+ VALUES (?, 'active', ?, ?, ?, ?, ?)`).run(content, now2, JSON.stringify(sourceCandidateIds), serializeUserMemorySourceProvenance(sourceProvenance, sourceCandidateIds), now2, now2);
53087
+ return Number(result.lastInsertRowid);
53088
+ })();
51937
53089
  }
51938
53090
  function getActiveUserMemories(db) {
51939
- const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
53091
+ const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
51940
53092
  return rows.map(parseUserMemoryRow);
51941
53093
  }
51942
53094
  function updateUserMemoryContent(db, id, content) {
@@ -51945,17 +53097,49 @@ function updateUserMemoryContent(db, id, content) {
51945
53097
  function dismissUserMemory(db, id) {
51946
53098
  db.prepare("UPDATE user_memories SET status = 'dismissed', updated_at = ? WHERE id = ?").run(Date.now(), id);
51947
53099
  }
51948
- function parseUserMemoryRow(row) {
51949
- let candidateIds = [];
53100
+ function parseCandidateIds2(raw) {
51950
53101
  try {
51951
- candidateIds = JSON.parse(row.source_candidate_ids);
51952
- } catch {}
53102
+ const parsed = JSON.parse(raw);
53103
+ return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "number" && Number.isFinite(id)) : [];
53104
+ } catch {
53105
+ return [];
53106
+ }
53107
+ }
53108
+ function parseUserMemorySourceProvenance(raw) {
53109
+ if (raw === null)
53110
+ return null;
53111
+ try {
53112
+ const parsed = JSON.parse(raw);
53113
+ if (!Array.isArray(parsed))
53114
+ return null;
53115
+ const provenance = [];
53116
+ for (const value of parsed) {
53117
+ if (!value || typeof value !== "object")
53118
+ return null;
53119
+ const source = value;
53120
+ if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number") {
53121
+ return null;
53122
+ }
53123
+ provenance.push({
53124
+ candidateId: source.candidate_id,
53125
+ sessionId: source.session_id,
53126
+ sourceCompartmentStart: source.source_compartment_start,
53127
+ sourceCompartmentEnd: source.source_compartment_end
53128
+ });
53129
+ }
53130
+ return provenance;
53131
+ } catch {
53132
+ return null;
53133
+ }
53134
+ }
53135
+ function parseUserMemoryRow(row) {
51953
53136
  return {
51954
53137
  id: row.id,
51955
53138
  content: row.content,
51956
53139
  status: row.status === "dismissed" ? "dismissed" : "active",
51957
53140
  promotedAt: row.promoted_at,
51958
- sourceCandidateIds: candidateIds,
53141
+ sourceCandidateIds: parseCandidateIds2(row.source_candidate_ids),
53142
+ sourceProvenance: parseUserMemorySourceProvenance(row.source_candidate_provenance),
51959
53143
  createdAt: row.created_at,
51960
53144
  updatedAt: row.updated_at
51961
53145
  };
@@ -52008,8 +53192,8 @@ class BoundedSessionMap {
52008
53192
 
52009
53193
  // ../plugin/src/features/magic-context/compaction-marker.ts
52010
53194
  import { createHash as createHash16 } from "node:crypto";
52011
- import { existsSync as existsSync12 } from "node:fs";
52012
- import { join as join8 } from "node:path";
53195
+ import { existsSync as existsSync13 } from "node:fs";
53196
+ import { join as join11 } from "node:path";
52013
53197
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
52014
53198
  var ID_PREFIX_HEX_LENGTH = 12;
52015
53199
  var ID_SUFFIX_LENGTH = 14;
@@ -52035,7 +53219,7 @@ function generatePartId(timestampMs, counter = 0n, identity = "") {
52035
53219
  return generateId("prt", timestampMs, counter, identity);
52036
53220
  }
52037
53221
  function getOpenCodeDbPath2() {
52038
- return join8(getDataDir(), "opencode", "opencode.db");
53222
+ return join11(getDataDir(), "opencode", "opencode.db");
52039
53223
  }
52040
53224
  var cachedWriteDb = null;
52041
53225
  var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
@@ -52080,7 +53264,7 @@ function getWritableOpenCodeDb() {
52080
53264
  closeQuietly(cachedWriteDb.db);
52081
53265
  } catch {}
52082
53266
  }
52083
- if (!existsSync12(dbPath)) {
53267
+ if (!existsSync13(dbPath)) {
52084
53268
  throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
52085
53269
  }
52086
53270
  const db = new Database(dbPath);
@@ -52356,24 +53540,52 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
52356
53540
  // ../plugin/src/hooks/magic-context/compartment-render-epoch.ts
52357
53541
  var COMPARTMENT_RENDER_EPOCH = "cre2";
52358
53542
  var EPOCH_COMPONENT_PREFIX = "|compartment-render:";
52359
- function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH) {
52360
- if (compartmentRenderEpoch === null)
52361
- return upgradeState;
52362
- return `${upgradeState ?? ""}${EPOCH_COMPONENT_PREFIX}${compartmentRenderEpoch}`;
53543
+ var MURAL_COMPONENT_PREFIX = "|mural-enabled:";
53544
+ var BUDGET_COMPONENT_PREFIX = "|render-budgets:";
53545
+ function encodeCachedM0UpgradeIdentity(upgradeState, compartmentRenderEpoch = COMPARTMENT_RENDER_EPOCH, muralEnabled = null, renderBudgetIdentity = null) {
53546
+ let encoded = upgradeState ?? "";
53547
+ if (compartmentRenderEpoch !== null) {
53548
+ encoded += `${EPOCH_COMPONENT_PREFIX}${compartmentRenderEpoch}`;
53549
+ }
53550
+ if (muralEnabled !== null) {
53551
+ encoded += `${MURAL_COMPONENT_PREFIX}${muralEnabled ? "1" : "0"}`;
53552
+ }
53553
+ if (renderBudgetIdentity !== null) {
53554
+ encoded += `${BUDGET_COMPONENT_PREFIX}${renderBudgetIdentity}`;
53555
+ }
53556
+ return encoded.length > 0 ? encoded : null;
53557
+ }
53558
+ function component(value, prefix) {
53559
+ const start = value.lastIndexOf(prefix);
53560
+ if (start < 0)
53561
+ return null;
53562
+ const valueStart = start + prefix.length;
53563
+ const end = value.indexOf("|", valueStart);
53564
+ const result = value.slice(valueStart, end < 0 ? value.length : end);
53565
+ return result.length > 0 ? result : null;
52363
53566
  }
52364
53567
  function decodeCachedM0UpgradeIdentity(value) {
52365
53568
  if (value === null) {
52366
- return { upgradeState: null, compartmentRenderEpoch: null };
52367
- }
52368
- const componentIndex = value.lastIndexOf(EPOCH_COMPONENT_PREFIX);
52369
- if (componentIndex < 0) {
52370
- return { upgradeState: value, compartmentRenderEpoch: null };
53569
+ return {
53570
+ upgradeState: null,
53571
+ compartmentRenderEpoch: null,
53572
+ muralEnabled: null,
53573
+ renderBudgetIdentity: null
53574
+ };
52371
53575
  }
52372
- const upgradeState = value.slice(0, componentIndex);
52373
- const compartmentRenderEpoch = value.slice(componentIndex + EPOCH_COMPONENT_PREFIX.length);
53576
+ const componentIndexes = [
53577
+ value.indexOf(EPOCH_COMPONENT_PREFIX),
53578
+ value.indexOf(MURAL_COMPONENT_PREFIX),
53579
+ value.indexOf(BUDGET_COMPONENT_PREFIX)
53580
+ ].filter((index) => index >= 0);
53581
+ const identityEnd = componentIndexes.length > 0 ? Math.min(...componentIndexes) : value.length;
53582
+ const upgradeState = value.slice(0, identityEnd);
53583
+ const muralComponent = component(value, MURAL_COMPONENT_PREFIX);
52374
53584
  return {
52375
53585
  upgradeState: upgradeState.length > 0 ? upgradeState : null,
52376
- compartmentRenderEpoch: compartmentRenderEpoch.length > 0 ? compartmentRenderEpoch : null
53586
+ compartmentRenderEpoch: component(value, EPOCH_COMPONENT_PREFIX),
53587
+ muralEnabled: muralComponent === "1" ? true : muralComponent === "0" ? false : null,
53588
+ renderBudgetIdentity: component(value, BUDGET_COMPONENT_PREFIX)
52377
53589
  };
52378
53590
  }
52379
53591
 
@@ -53193,4 +54405,4 @@ function registerMagicContextTools(pi, opts) {
53193
54405
  }
53194
54406
  }
53195
54407
 
53196
- export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, isCompartmentLeaseHeld, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, copySessionStateForClone, getErrorMessage, describeError, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, setSessionWorkMetrics, getSessionWorkMetrics, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, updateTagByteSize, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, BoundedSessionMap, piModelRefToCanonical, resolveModelRefForPi, ompModelRefToCanonical, resolveModelRefForOmp, isSaneLimit, resolveLimit, getSdkContextLimit, resolveModelConfigOrDefault, normalizeTodoStateJson, buildSyntheticTodoPart, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, registerMagicContextTools };
54408
+ export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, Database, closeQuietly, isMidTurn, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, isRecord, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, isCompartmentLeaseHeld, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, ompModelRefToCanonical, resolveModelRefForOmp, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, parseCompartmentOutput, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, copySessionStateForClone, getErrorMessage, describeError, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, setChannel2NudgeState, casChannel2NudgeState, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, getHistorianFailureState, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, setSessionWorkMetrics, getSessionWorkMetrics, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, updateTagByteSize, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, BoundedSessionMap, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, formatWindowDerivationLine, isSaneLimit, getSdkContextLimit, resolveModelConfigOrDefault, normalizeTodoStateJson, buildSyntheticTodoPart, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, isMidTurnPi, readPiSessionMessages, findLastModelKeyFromBranch, convertEntriesToRawMessages, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getOpenCodeDbPath2 as getOpenCodeDbPath, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, registerMagicContextTools };