@cortexkit/opencode-magic-context 0.34.1 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +3 -1
  2. package/dist/agents/magic-context-prompt.d.ts +2 -1
  3. package/dist/agents/magic-context-prompt.d.ts.map +1 -1
  4. package/dist/config/index.d.ts +3 -0
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/project-security.d.ts +3 -0
  7. package/dist/config/project-security.d.ts.map +1 -1
  8. package/dist/config/schema/magic-context.d.ts +42 -1
  9. package/dist/config/schema/magic-context.d.ts.map +1 -1
  10. package/dist/{conflict-warning-hook-fvpfvt0w.js → conflict-warning-hook-p2pmhvn7.js} +2 -1
  11. package/dist/features/magic-context/context-authority.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +15 -0
  13. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -0
  14. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts +9 -5
  15. package/dist/features/magic-context/dreamer/storage-task-schedule.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/verify-gate.d.ts +8 -2
  19. package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/verify.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  22. package/dist/features/magic-context/fail-closed-block.d.ts +2 -0
  23. package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
  24. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  25. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  26. package/dist/features/magic-context/mural/compress-cues.d.ts +13 -5
  27. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  28. package/dist/features/magic-context/mural/cue-validation.d.ts +7 -7
  29. package/dist/features/magic-context/mural/cue-validation.d.ts.map +1 -1
  30. package/dist/features/magic-context/mural/storage-mural-cues.d.ts +17 -7
  31. package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -1
  32. package/dist/features/magic-context/storage-db.d.ts +21 -3
  33. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  34. package/dist/features/magic-context/storage-meta-persisted.d.ts +1 -0
  35. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  36. package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -14
  37. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  38. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/compartment-runner-validation.d.ts +16 -2
  40. package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/event-handler.d.ts +1 -0
  42. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/hook.d.ts +10 -3
  45. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/module-state-sync.d.ts +1 -1
  47. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/module-transport.d.ts +2 -1
  49. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  51. package/dist/hooks/magic-context/read-session-chunk.d.ts +5 -0
  52. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  53. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +2 -0
  54. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/rust-mode-transform.d.ts +22 -0
  56. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/system-prompt-hash.d.ts +19 -5
  58. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/transform-context-state.d.ts +1 -0
  60. package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/transform.d.ts +4 -0
  62. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  63. package/dist/index-0c9dmw9m.js +116 -0
  64. package/dist/{index-x8spt5wy.js → index-4anesz49.js} +849 -633
  65. package/dist/{index-dtas91s5.js → index-8aaadh98.js} +7 -119
  66. package/dist/{index-b563sga5.js → index-h8mk7vpa.js} +541 -7
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1010 -840
  69. package/dist/plugin/hooks/create-session-hooks.d.ts +12 -0
  70. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  71. package/dist/plugin/rpc-handlers.d.ts +1 -0
  72. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  73. package/dist/plugin/tool-registry.d.ts +4 -0
  74. package/dist/plugin/tool-registry.d.ts.map +1 -1
  75. package/dist/{recomp-orchestrator-k72ejkkh.js → recomp-orchestrator-zc915ceq.js} +3 -2
  76. package/dist/shared/index.d.ts +2 -0
  77. package/dist/shared/index.d.ts.map +1 -1
  78. package/dist/shared/prompt-surface-runtime.d.ts +43 -0
  79. package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
  80. package/dist/shared/prompt-surface.d.ts +49 -0
  81. package/dist/shared/prompt-surface.d.ts.map +1 -0
  82. package/dist/{storage-meta-session-xt41zbw4.js → storage-meta-session-53cjs6mr.js} +1 -1
  83. package/dist/tools/ctx-expand/tools.d.ts +1 -0
  84. package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
  85. package/dist/tools/ctx-memory/tools.d.ts +1 -0
  86. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  87. package/dist/tools/ctx-note/tools.d.ts +1 -0
  88. package/dist/tools/ctx-note/tools.d.ts.map +1 -1
  89. package/dist/tools/ctx-reduce/tools.d.ts +1 -0
  90. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  91. package/dist/tools/ctx-search/tools.d.ts +1 -0
  92. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  93. package/dist/tools/light-descriptions.d.ts +6 -0
  94. package/dist/tools/light-descriptions.d.ts.map +1 -0
  95. package/package.json +1 -1
  96. package/src/agents/magic-context-prompt.test.ts +144 -0
  97. package/src/agents/magic-context-prompt.ts +53 -2
  98. package/src/config/index.test.ts +53 -0
  99. package/src/config/index.ts +4 -0
  100. package/src/config/project-security.test.ts +20 -0
  101. package/src/config/project-security.ts +23 -0
  102. package/src/config/schema/magic-context.test.ts +58 -0
  103. package/src/config/schema/magic-context.ts +61 -1
  104. package/src/shared/index.ts +2 -0
  105. package/src/shared/prompt-surface-a1-golden.md +458 -0
  106. package/src/shared/prompt-surface-runtime.test.ts +141 -0
  107. package/src/shared/prompt-surface-runtime.ts +250 -0
  108. package/src/shared/prompt-surface.test.ts +109 -0
  109. package/src/shared/prompt-surface.ts +138 -0
@@ -13,11 +13,16 @@ import {
13
13
  sendIgnoredMessage
14
14
  } from "./index-cn960ffd.js";
15
15
  import {
16
+ buildToolArcs,
17
+ buildTrueRawTokenIndex,
16
18
  clearCachedM0M1,
17
19
  clearCompressionDepth,
18
20
  clearCompressionDepthRange,
21
+ completedToolArcCrossesBoundary,
22
+ computeRawRangeFingerprint,
19
23
  ensureSessionMetaRow,
20
24
  estimateTokens,
25
+ fenceBoundaryForToolArcs,
21
26
  getCachedAbsoluteMessageCount,
22
27
  getLegacyProtectedTailStartOrdinal,
23
28
  getRawSessionMessageCount,
@@ -28,14 +33,18 @@ import {
28
33
  persistCachedM0,
29
34
  readRawSessionMessages,
30
35
  readSessionChunk,
36
+ stableStringify,
31
37
  updateSessionMeta
32
- } from "./index-b563sga5.js";
38
+ } from "./index-h8mk7vpa.js";
33
39
  import {
34
40
  Database,
35
41
  closeQuietly,
36
42
  getMessageTimesFromOpenCodeDb,
37
43
  withPrivilegedWriter
38
44
  } from "./index-fcyvznch.js";
45
+ import {
46
+ detectConfigFile
47
+ } from "./index-0c9dmw9m.js";
39
48
  import {
40
49
  pushNotification
41
50
  } from "./index-d62ypazr.js";
@@ -390,6 +399,7 @@ import {
390
399
  mkdtempSync,
391
400
  readdirSync,
392
401
  readFileSync as readFileSync2,
402
+ statSync as statSync2,
393
403
  unlinkSync
394
404
  } from "node:fs";
395
405
  import { basename, dirname, join as join3 } from "node:path";
@@ -1082,7 +1092,11 @@ var MEMORY_SNAPSHOT_COLUMNS = [
1082
1092
  "merged_from",
1083
1093
  "metadata_json",
1084
1094
  "context_store_uuid",
1085
- "context_row_id"
1095
+ "context_row_id",
1096
+ "mural_cue",
1097
+ "mural_cue_hash",
1098
+ "mural_cue_at",
1099
+ "mural_cue_rejection_count"
1086
1100
  ];
1087
1101
  function hasSnapshotField(row, key) {
1088
1102
  return Object.prototype.hasOwnProperty.call(row, key);
@@ -1200,9 +1214,10 @@ function prepareMirrorPageStatements(db) {
1200
1214
  memoryById: db.prepare(`SELECT project_path, category, content, normalized_hash, importance, scope, shareable,
1201
1215
  source_session_id, source_type, seen_count, retrieval_count, first_seen_at,
1202
1216
  created_at, updated_at, last_seen_at, last_retrieved_at, status, expires_at,
1203
- verification_status, verified_at, classified_at, superseded_by_memory_id,
1204
- merged_from, metadata_json
1205
- FROM memories WHERE id = ?`),
1217
+ verification_status, verified_at, classified_at, superseded_by_memory_id,
1218
+ merged_from, metadata_json, mural_cue, mural_cue_hash, mural_cue_at,
1219
+ mural_cue_rejection_count
1220
+ FROM memories WHERE id = ?`),
1206
1221
  memoryIdByStoreId: db.prepare("SELECT id FROM memories WHERE id = ? AND project_path = ?"),
1207
1222
  memoryCandidates: db.prepare("SELECT id FROM memories WHERE project_path = ? AND category = ? AND normalized_hash = ? ORDER BY id"),
1208
1223
  insertMemory: db.prepare("INSERT INTO memories (project_path, category, content, normalized_hash, first_seen_at, created_at, updated_at, last_seen_at) VALUES (?, ?, '', '', 0, 0, 0, 0)"),
@@ -1223,8 +1238,9 @@ function prepareMirrorPageStatements(db) {
1223
1238
  importance = ?, scope = ?, shareable = ?, source_session_id = ?, source_type = ?,
1224
1239
  seen_count = ?, retrieval_count = ?, first_seen_at = ?, created_at = ?, updated_at = ?,
1225
1240
  last_seen_at = ?, last_retrieved_at = ?, status = ?, expires_at = ?,
1226
- verification_status = ?, verified_at = ?, classified_at = ?, superseded_by_memory_id = ?,
1227
- merged_from = ?, metadata_json = ? WHERE id = ?`),
1241
+ verification_status = ?, verified_at = ?, classified_at = ?, superseded_by_memory_id = ?,
1242
+ merged_from = ?, metadata_json = ?, mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?,
1243
+ mural_cue_rejection_count = ? WHERE id = ?`),
1228
1244
  updateSuperseded: db.prepare("UPDATE memories SET superseded_by_memory_id = ? WHERE id = ?"),
1229
1245
  deletePendingReference: db.prepare("DELETE FROM mirror_pending_references WHERE domain = 'memories' AND module_project = ? AND module_row_id = ?"),
1230
1246
  upsertPendingReference: db.prepare("INSERT INTO mirror_pending_references(domain, module_project, module_row_id, target_module_row_id) VALUES ('memories', ?, ?, ?) ON CONFLICT(domain, module_project, module_row_id) DO UPDATE SET target_module_row_id = excluded.target_module_row_id"),
@@ -1388,7 +1404,7 @@ function applyMemoryRow(db, feed, statements) {
1388
1404
  const nullableString = (key, previous) => has(key) ? rowNullableString(row, key) : previous ?? null;
1389
1405
  const hasSuperseded = has("superseded_by_memory_id");
1390
1406
  const previousHash = existing?.normalized_hash;
1391
- statements.updateMemory.run(has("project_path") ? rowString(row, "project_path") : existing?.project_path ?? moduleProject, has("category") ? rowString(row, "category", "CONSTRAINTS") : existing?.category ?? "CONSTRAINTS", has("content") ? rowString(row, "content") : existing?.content ?? "", has("normalized_hash") ? rowString(row, "normalized_hash") : existing?.normalized_hash ?? "", has("importance") ? typeof row.importance === "number" && Number.isFinite(row.importance) ? row.importance : null : existing?.importance ?? null, has("scope") ? rowString(row, "scope", "project") : existing?.scope ?? "project", has("shareable") ? rowNumber(row, "shareable") : existing?.shareable ?? 0, nullableString("source_session_id", existing?.source_session_id), nullableString("source_type", existing?.source_type), has("seen_count") ? rowNumber(row, "seen_count", 1) : existing?.seen_count ?? 1, has("retrieval_count") ? rowNumber(row, "retrieval_count") : existing?.retrieval_count ?? 0, has("first_seen_at") ? rowNumber(row, "first_seen_at") : existing?.first_seen_at ?? 0, has("created_at") ? rowNumber(row, "created_at") : existing?.created_at ?? 0, has("updated_at") ? rowNumber(row, "updated_at") : existing?.updated_at ?? 0, has("last_seen_at") ? rowNumber(row, "last_seen_at") : existing?.last_seen_at ?? 0, nullableNumber("last_retrieved_at", existing?.last_retrieved_at), has("status") ? rowString(row, "status", "active") : existing?.status ?? "active", nullableNumber("expires_at", existing?.expires_at), has("verification_status") ? rowString(row, "verification_status", "unverified") : existing?.verification_status ?? "unverified", nullableNumber("verified_at", existing?.verified_at), nullableNumber("classified_at", existing?.classified_at), hasSuperseded ? null : existing?.superseded_by_memory_id ?? null, nullableString("merged_from", existing?.merged_from), nullableString("metadata_json", existing?.metadata_json), contextId);
1407
+ statements.updateMemory.run(has("project_path") ? rowString(row, "project_path") : existing?.project_path ?? moduleProject, has("category") ? rowString(row, "category", "CONSTRAINTS") : existing?.category ?? "CONSTRAINTS", has("content") ? rowString(row, "content") : existing?.content ?? "", has("normalized_hash") ? rowString(row, "normalized_hash") : existing?.normalized_hash ?? "", has("importance") ? typeof row.importance === "number" && Number.isFinite(row.importance) ? row.importance : null : existing?.importance ?? null, has("scope") ? rowString(row, "scope", "project") : existing?.scope ?? "project", has("shareable") ? rowNumber(row, "shareable") : existing?.shareable ?? 0, nullableString("source_session_id", existing?.source_session_id), nullableString("source_type", existing?.source_type), has("seen_count") ? rowNumber(row, "seen_count", 1) : existing?.seen_count ?? 1, has("retrieval_count") ? rowNumber(row, "retrieval_count") : existing?.retrieval_count ?? 0, has("first_seen_at") ? rowNumber(row, "first_seen_at") : existing?.first_seen_at ?? 0, has("created_at") ? rowNumber(row, "created_at") : existing?.created_at ?? 0, has("updated_at") ? rowNumber(row, "updated_at") : existing?.updated_at ?? 0, has("last_seen_at") ? rowNumber(row, "last_seen_at") : existing?.last_seen_at ?? 0, nullableNumber("last_retrieved_at", existing?.last_retrieved_at), has("status") ? rowString(row, "status", "active") : existing?.status ?? "active", nullableNumber("expires_at", existing?.expires_at), has("verification_status") ? rowString(row, "verification_status", "unverified") : existing?.verification_status ?? "unverified", nullableNumber("verified_at", existing?.verified_at), nullableNumber("classified_at", existing?.classified_at), hasSuperseded ? null : existing?.superseded_by_memory_id ?? null, nullableString("merged_from", existing?.merged_from), nullableString("metadata_json", existing?.metadata_json), nullableString("mural_cue", existing?.mural_cue), nullableString("mural_cue_hash", existing?.mural_cue_hash), nullableNumber("mural_cue_at", existing?.mural_cue_at), has("mural_cue_rejection_count") ? rowNumber(row, "mural_cue_rejection_count") : existing?.mural_cue_rejection_count ?? 0, contextId);
1392
1408
  if (hasSuperseded && typeof row.superseded_by_memory_id === "number") {
1393
1409
  const translated = mirrorIdentity(db, "memories", moduleProject, row.superseded_by_memory_id, statements);
1394
1410
  if (translated) {
@@ -4656,6 +4672,15 @@ var MIGRATIONS = [
4656
4672
  ensureColumn(db, "session_meta", "detected_context_limit_provenance", "TEXT NOT NULL DEFAULT 'unknown'");
4657
4673
  }
4658
4674
  }
4675
+ },
4676
+ {
4677
+ version: 75,
4678
+ description: "persist mural cue validation rejection latches",
4679
+ up(db) {
4680
+ if (!tableExists2(db, "memories"))
4681
+ return;
4682
+ ensureColumn(db, "memories", "mural_cue_rejection_count", "INTEGER NOT NULL DEFAULT 0");
4683
+ }
4659
4684
  }
4660
4685
  ];
4661
4686
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -4771,30 +4796,6 @@ async function runMigrationsWithRetry(db, options = {}) {
4771
4796
 
4772
4797
  // src/features/magic-context/tool-definition-tokens.ts
4773
4798
  import { createHash as createHash5 } from "node:crypto";
4774
-
4775
- // src/shared/stable-json.ts
4776
- function stableStringify(value, seen = new WeakSet) {
4777
- if (value === undefined)
4778
- return "undefined";
4779
- if (value === null || typeof value !== "object")
4780
- return JSON.stringify(value) ?? String(value);
4781
- if (seen.has(value))
4782
- return '"[Circular]"';
4783
- seen.add(value);
4784
- if (Array.isArray(value)) {
4785
- return `[${value.map((item) => stableStringify(item, seen)).join(",")}]`;
4786
- }
4787
- const entries = Object.entries(value).sort(([a], [b]) => {
4788
- if (a < b)
4789
- return -1;
4790
- if (a > b)
4791
- return 1;
4792
- return 0;
4793
- });
4794
- return `{${entries.map(([key, child]) => `${JSON.stringify(key)}:${stableStringify(child, seen)}`).join(",")}}`;
4795
- }
4796
-
4797
- // src/features/magic-context/tool-definition-tokens.ts
4798
4799
  var measurements = new Map;
4799
4800
  var fingerprints = new Map;
4800
4801
  var persistenceDb = null;
@@ -5147,7 +5148,7 @@ function getSchemaFenceRejection() {
5147
5148
  function getMigrationOnOpenRefusal() {
5148
5149
  return lastMigrationOnOpenRefusal;
5149
5150
  }
5150
- var LATEST_SUPPORTED_VERSION = 74;
5151
+ var LATEST_SUPPORTED_VERSION = 75;
5151
5152
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
5152
5153
  var defaultStoragePermissionFs = { chmodSync, mkdirSync };
5153
5154
  var storagePermissionFs = defaultStoragePermissionFs;
@@ -5269,24 +5270,65 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
5269
5270
  log(`[magic-context] storage fatal: refusing to open ${dbPath}; upstream migration lane v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}). A pinned or stale plugin is likely sharing this database with a newer instance; update or unpin Magic Context with 'npx @cortexkit/magic-context@latest doctor --force', then restart.`);
5270
5271
  return false;
5271
5272
  }
5272
- function unreadableDiscovery(path2) {
5273
+ function unreadableDiscovery(path2, arm) {
5273
5274
  return {
5274
5275
  state: "unreadable",
5275
5276
  serverPids: [],
5276
5277
  staleFiles: [],
5277
- unreadableFile: path2
5278
+ unreadableFile: path2,
5279
+ unreadableArm: arm
5278
5280
  };
5279
5281
  }
5282
+ var RPC_DISCOVERY_PARSE_GRACE_MS = 10 * 60 * 1000;
5283
+ var defaultRpcDiscoveryFs = {
5284
+ readdirSync: (path2, options) => options?.withFileTypes ? readdirSync(path2, { withFileTypes: true }) : readdirSync(path2),
5285
+ readFileSync: (path2, encoding) => String(readFileSync2(path2, encoding)),
5286
+ statSync: (path2) => ({ mtimeMs: statSync2(path2).mtimeMs }),
5287
+ unlinkSync: (path2) => unlinkSync(path2)
5288
+ };
5289
+ var rpcDiscoveryFs = defaultRpcDiscoveryFs;
5290
+ function invalidDiscoveryReason(raw) {
5291
+ const trimmed = raw.trim();
5292
+ if (trimmed.startsWith("{")) {
5293
+ try {
5294
+ const parsed = JSON.parse(trimmed);
5295
+ if ("pid" in parsed) {
5296
+ const pid = Number(parsed.pid);
5297
+ if (!Number.isInteger(pid) || pid <= 0)
5298
+ return "invalid-pid";
5299
+ }
5300
+ } catch {}
5301
+ }
5302
+ return "parse-invalid";
5303
+ }
5304
+ function classifyJunkDiscovery(portFile, raw, staleFiles) {
5305
+ let mtimeMs;
5306
+ try {
5307
+ mtimeMs = rpcDiscoveryFs.statSync(portFile).mtimeMs;
5308
+ } catch (error) {
5309
+ if (error.code === "ENOENT")
5310
+ return null;
5311
+ return unreadableDiscovery(portFile, "io");
5312
+ }
5313
+ const ageMs = Date.now() - mtimeMs;
5314
+ if (!Number.isFinite(ageMs) || ageMs < RPC_DISCOVERY_PARSE_GRACE_MS) {
5315
+ return unreadableDiscovery(portFile, "parse");
5316
+ }
5317
+ staleFiles.push(portFile);
5318
+ const reason = invalidDiscoveryReason(raw);
5319
+ log(`[magic-context] removing stale RPC discovery file ${portFile}: ${reason} record older than 10 minutes`);
5320
+ return null;
5321
+ }
5280
5322
  function inspectRpcServerDiscovery(storageDir) {
5281
5323
  const rpcRoot = join3(storageDir, "rpc");
5282
5324
  let projectEntries;
5283
5325
  try {
5284
- projectEntries = readdirSync(rpcRoot, { withFileTypes: true });
5326
+ projectEntries = rpcDiscoveryFs.readdirSync(rpcRoot, { withFileTypes: true });
5285
5327
  } catch (error) {
5286
5328
  if (error.code === "ENOENT") {
5287
5329
  return { state: "absent", serverPids: [], staleFiles: [] };
5288
5330
  }
5289
- return unreadableDiscovery(rpcRoot);
5331
+ return unreadableDiscovery(rpcRoot, "io");
5290
5332
  }
5291
5333
  const portFiles = [];
5292
5334
  for (const projectEntry of projectEntries) {
@@ -5295,9 +5337,11 @@ function inspectRpcServerDiscovery(storageDir) {
5295
5337
  const projectDir = join3(rpcRoot, projectEntry.name);
5296
5338
  let entries;
5297
5339
  try {
5298
- entries = readdirSync(projectDir);
5299
- } catch {
5300
- return unreadableDiscovery(projectDir);
5340
+ entries = rpcDiscoveryFs.readdirSync(projectDir);
5341
+ } catch (error) {
5342
+ if (error.code === "ENOENT")
5343
+ continue;
5344
+ return unreadableDiscovery(projectDir, "io");
5301
5345
  }
5302
5346
  for (const entry of entries) {
5303
5347
  if (entry === "port" || entry.startsWith("port-") && entry.endsWith(".json")) {
@@ -5313,15 +5357,21 @@ function inspectRpcServerDiscovery(storageDir) {
5313
5357
  for (const portFile of portFiles) {
5314
5358
  let raw;
5315
5359
  try {
5316
- raw = readFileSync2(portFile, "utf8");
5317
- } catch {
5318
- return unreadableDiscovery(portFile);
5360
+ raw = rpcDiscoveryFs.readFileSync(portFile, "utf8");
5361
+ } catch (error) {
5362
+ if (error.code === "ENOENT")
5363
+ continue;
5364
+ return unreadableDiscovery(portFile, "io");
5319
5365
  }
5320
5366
  const filename = basename(portFile);
5321
5367
  const pidFromName = /^port-(\d+)/.exec(filename)?.[1];
5322
- const record = parseRpcPortFile(raw, pidFromName ? Number(pidFromName) : 0);
5368
+ const fallbackPid = pidFromName ? Number(pidFromName) : 0;
5369
+ const record = parseRpcPortFile(raw, fallbackPid);
5323
5370
  if (!record || !Number.isInteger(record.pid) || record.pid <= 0) {
5324
- return unreadableDiscovery(portFile);
5371
+ const junk = classifyJunkDiscovery(portFile, raw, staleFiles);
5372
+ if (junk)
5373
+ return junk;
5374
+ continue;
5325
5375
  }
5326
5376
  if (isPidAlive(record.pid) && isPidIdentityPlausible(record))
5327
5377
  pids.add(record.pid);
@@ -5330,9 +5380,9 @@ function inspectRpcServerDiscovery(storageDir) {
5330
5380
  }
5331
5381
  for (const staleFile of staleFiles) {
5332
5382
  try {
5333
- unlinkSync(staleFile);
5383
+ rpcDiscoveryFs.unlinkSync(staleFile);
5334
5384
  } catch {
5335
- return unreadableDiscovery(staleFile);
5385
+ return unreadableDiscovery(staleFile, "io");
5336
5386
  }
5337
5387
  }
5338
5388
  const serverPids = [...pids].sort((a, b) => a - b);
@@ -5356,10 +5406,14 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
5356
5406
  persistedVersion,
5357
5407
  supportedVersion: latestSupportedVersion,
5358
5408
  serverPids: discovery.serverPids,
5359
- ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {}
5409
+ ...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
5410
+ ...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
5360
5411
  };
5361
5412
  if (discovery.state === "unreadable") {
5362
- log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${discovery.unreadableFile ?? "<unknown>"} is unreadable or invalid, so the absence of a live OpenCode server cannot be proven. Restart OpenCode, remove or repair the named discovery file, then retry this process.`);
5413
+ const unreadableFile = discovery.unreadableFile ?? "<unknown>";
5414
+ const arm = discovery.unreadableArm ?? "io";
5415
+ 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.`;
5416
+ 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}`);
5363
5417
  } else {
5364
5418
  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.`);
5365
5419
  }
@@ -5653,6 +5707,7 @@ function initializeDatabase(db) {
5653
5707
  mural_cue TEXT,
5654
5708
  mural_cue_hash TEXT,
5655
5709
  mural_cue_at INTEGER,
5710
+ mural_cue_rejection_count INTEGER NOT NULL DEFAULT 0,
5656
5711
  UNIQUE(project_path, category, normalized_hash)
5657
5712
  );
5658
5713
 
@@ -6676,7 +6731,7 @@ function probeChildSpawnFence(db) {
6676
6731
  }
6677
6732
  // src/features/magic-context/project-docs-hash.ts
6678
6733
  import { createHash as createHash6 } from "node:crypto";
6679
- import { lstatSync, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
6734
+ import { lstatSync, readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
6680
6735
  import path2 from "node:path";
6681
6736
  var PROJECT_DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
6682
6737
  var PROJECT_DOCS_DELIMITER = `
@@ -6707,7 +6762,7 @@ function fingerprintFile(filePath) {
6707
6762
  }
6708
6763
  function readDirectoryMtimeMs(projectDirectory) {
6709
6764
  try {
6710
- return statSync2(projectDirectory).mtimeMs;
6765
+ return statSync3(projectDirectory).mtimeMs;
6711
6766
  } catch {
6712
6767
  return 0;
6713
6768
  }
@@ -7074,6 +7129,7 @@ function escalationBands(effectiveThresholdPercentage) {
7074
7129
 
7075
7130
  // src/features/magic-context/storage-meta-persisted.ts
7076
7131
  var emergencyRecoveryArmedSessions = new Set;
7132
+ var emergencyRecoveryArmedAtBySession = new Map;
7077
7133
  var providerOverflowReconfirmedSessions = new Set;
7078
7134
  function isEmergencyRecoveryArmed(sessionId) {
7079
7135
  return emergencyRecoveryArmedSessions.has(sessionId);
@@ -7081,6 +7137,9 @@ function isEmergencyRecoveryArmed(sessionId) {
7081
7137
  function isProviderOverflowReconfirmed(sessionId) {
7082
7138
  return providerOverflowReconfirmedSessions.has(sessionId);
7083
7139
  }
7140
+ function getEmergencyRecoveryArmedAt(sessionId) {
7141
+ return emergencyRecoveryArmedAtBySession.get(sessionId) ?? null;
7142
+ }
7084
7143
  var CAS_RETRY_LIMIT = 5;
7085
7144
  var AUTO_SEARCH_NO_HINT_REASONS = new Set([
7086
7145
  "below-threshold",
@@ -7942,6 +8001,7 @@ function getOverflowState(db, sessionId, modelKey) {
7942
8001
  }
7943
8002
  function recordOverflowDetected(db, sessionId, reportedLimit, modelKey, origin = "provider_overflow", provenance = "unknown") {
7944
8003
  emergencyRecoveryArmedSessions.add(sessionId);
8004
+ emergencyRecoveryArmedAtBySession.set(sessionId, Date.now());
7945
8005
  db.transaction(() => {
7946
8006
  ensureSessionMetaRow(db, sessionId);
7947
8007
  const prior = db.prepare("SELECT needs_emergency_recovery FROM session_meta WHERE session_id = ?").get(sessionId);
@@ -7973,6 +8033,7 @@ function clearEmergencyRecovery(db, sessionId) {
7973
8033
  }
7974
8034
  })();
7975
8035
  emergencyRecoveryArmedSessions.delete(sessionId);
8036
+ emergencyRecoveryArmedAtBySession.delete(sessionId);
7976
8037
  providerOverflowReconfirmedSessions.delete(sessionId);
7977
8038
  }
7978
8039
  function clearDetectedContextLimit(db, sessionId) {
@@ -9702,6 +9763,583 @@ function normalizeSDKResponse(response, fallback, options) {
9702
9763
  }
9703
9764
  return fallback;
9704
9765
  }
9766
+ // src/shared/prompt-surface.ts
9767
+ function isValidPromptSurfaceModelKey(key) {
9768
+ if (key.length === 0 || key.trim() !== key)
9769
+ return false;
9770
+ const slash = key.indexOf("/");
9771
+ if (slash <= 0 || slash === key.length - 1)
9772
+ return false;
9773
+ const provider = key.slice(0, slash);
9774
+ const modelID = key.slice(slash + 1);
9775
+ if (provider.trim() !== provider || modelID.trim() !== modelID || provider.includes("*") || modelID.includes("*") && modelID !== "*") {
9776
+ return false;
9777
+ }
9778
+ if (modelID === "*")
9779
+ return true;
9780
+ return modelID.length > 0 && !modelID.startsWith("/") && !modelID.endsWith("/") && !modelID.includes("//");
9781
+ }
9782
+ function modelKeyLookupOrder(modelKey) {
9783
+ if (!modelKey)
9784
+ return [];
9785
+ const slash = modelKey.indexOf("/");
9786
+ if (slash <= 0 || slash === modelKey.length - 1)
9787
+ return [];
9788
+ const provider = modelKey.slice(0, slash);
9789
+ let modelID = modelKey.slice(slash + 1);
9790
+ const candidates = [];
9791
+ while (modelID.length > 0) {
9792
+ candidates.push({ key: `${provider}/${modelID}`, source: "exact" });
9793
+ candidates.push({ key: modelID, source: "bare" });
9794
+ const lastDash = modelID.lastIndexOf("-");
9795
+ if (lastDash <= 0)
9796
+ break;
9797
+ modelID = modelID.slice(0, lastDash);
9798
+ }
9799
+ candidates.push({ key: `${provider}/*`, source: "wildcard" });
9800
+ const seen = new Set;
9801
+ return candidates.filter((candidate) => {
9802
+ if (seen.has(candidate.key))
9803
+ return false;
9804
+ seen.add(candidate.key);
9805
+ return true;
9806
+ });
9807
+ }
9808
+ function resolveModelConfigValue(values, modelKey) {
9809
+ if (!values)
9810
+ return;
9811
+ for (const candidate of modelKeyLookupOrder(modelKey)) {
9812
+ const value = values[candidate.key];
9813
+ if (value !== undefined) {
9814
+ return { value, source: candidate.source };
9815
+ }
9816
+ }
9817
+ return;
9818
+ }
9819
+ function resolvePromptSurface(config, modelKey) {
9820
+ const fallback = config?.default ?? "full";
9821
+ const match = resolveModelConfigValue(config?.models, modelKey);
9822
+ if (match && match.source !== "bare") {
9823
+ return { preset: match.value, source: match.source };
9824
+ }
9825
+ return { preset: fallback, source: "default" };
9826
+ }
9827
+ function resolveModelConfigOrDefault(values, modelKey, fallback) {
9828
+ return resolveModelConfigValue(values, modelKey)?.value ?? fallback;
9829
+ }
9830
+ // src/shared/prompt-surface-runtime.ts
9831
+ import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
9832
+ import { dirname as dirname3, isAbsolute as isAbsolute2, resolve } from "node:path";
9833
+
9834
+ // src/config/migrate-config-location.ts
9835
+ import {
9836
+ closeSync,
9837
+ existsSync as existsSync4,
9838
+ mkdirSync as mkdirSync2,
9839
+ openSync,
9840
+ readFileSync as readFileSync4,
9841
+ renameSync,
9842
+ rmSync,
9843
+ statSync as statSync4,
9844
+ unlinkSync as unlinkSync2,
9845
+ writeFileSync
9846
+ } from "node:fs";
9847
+ import { homedir as homedir2 } from "node:os";
9848
+ import { basename as basename2, dirname as dirname2, isAbsolute, join as join4 } from "node:path";
9849
+ var CONFIG_FILE_BASENAME = "magic-context";
9850
+ var MOVED_MARKER_SUFFIX = ".MOVED_READPLEASE";
9851
+ function homeDir() {
9852
+ if (process.platform === "win32") {
9853
+ return process.env.USERPROFILE || process.env.HOME || homedir2();
9854
+ }
9855
+ return process.env.HOME || homedir2();
9856
+ }
9857
+ function configHome() {
9858
+ const xdg = process.env.XDG_CONFIG_HOME;
9859
+ if (xdg && isAbsolute(xdg))
9860
+ return xdg;
9861
+ return join4(homeDir(), ".config");
9862
+ }
9863
+ function cortexKitUserConfigBasePath() {
9864
+ return join4(configHome(), "cortexkit", CONFIG_FILE_BASENAME);
9865
+ }
9866
+ function cortexKitProjectConfigBasePath(directory) {
9867
+ return join4(directory, ".cortexkit", CONFIG_FILE_BASENAME);
9868
+ }
9869
+ function resolveCortexKitUserConfigPath() {
9870
+ return `${cortexKitUserConfigBasePath()}.jsonc`;
9871
+ }
9872
+ function resolveCortexKitProjectConfigPath(directory) {
9873
+ return `${cortexKitProjectConfigBasePath(directory)}.jsonc`;
9874
+ }
9875
+ function legacySourcesForBase(basePath, label) {
9876
+ return [
9877
+ { path: `${basePath}.jsonc`, label: `${label} magic-context.jsonc` },
9878
+ { path: `${basePath}.json`, label: `${label} magic-context.json` }
9879
+ ];
9880
+ }
9881
+ function userScopeConfigPaths() {
9882
+ return new Set([
9883
+ `${cortexKitUserConfigBasePath()}.jsonc`,
9884
+ `${cortexKitUserConfigBasePath()}.json`,
9885
+ join4(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.jsonc`),
9886
+ join4(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.json`),
9887
+ join4(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.jsonc`),
9888
+ join4(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.json`)
9889
+ ]);
9890
+ }
9891
+ function resolveLegacyConfigSources(directory) {
9892
+ const userPaths = userScopeConfigPaths();
9893
+ return {
9894
+ user: [
9895
+ ...legacySourcesForBase(join4(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
9896
+ ...legacySourcesForBase(join4(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user")
9897
+ ],
9898
+ project: [
9899
+ ...legacySourcesForBase(join4(directory, CONFIG_FILE_BASENAME), "project root"),
9900
+ ...legacySourcesForBase(join4(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project"),
9901
+ ...legacySourcesForBase(join4(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
9902
+ ].filter((source) => !userPaths.has(source.path))
9903
+ };
9904
+ }
9905
+ function resolveLegacyConfigSourcesForHarness(directory, harness) {
9906
+ if (harness === "pi") {
9907
+ return {
9908
+ user: legacySourcesForBase(join4(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user"),
9909
+ project: legacySourcesForBase(join4(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
9910
+ };
9911
+ }
9912
+ return {
9913
+ user: legacySourcesForBase(join4(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
9914
+ project: [
9915
+ ...legacySourcesForBase(join4(directory, CONFIG_FILE_BASENAME), "project root"),
9916
+ ...legacySourcesForBase(join4(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project")
9917
+ ]
9918
+ };
9919
+ }
9920
+ function stripJsoncForParse(input) {
9921
+ let out = "";
9922
+ let inString = false;
9923
+ let escaped = false;
9924
+ for (let i = 0;i < input.length; i++) {
9925
+ const ch = input[i];
9926
+ const next = input[i + 1];
9927
+ if (inString) {
9928
+ out += ch;
9929
+ if (escaped)
9930
+ escaped = false;
9931
+ else if (ch === "\\")
9932
+ escaped = true;
9933
+ else if (ch === '"')
9934
+ inString = false;
9935
+ continue;
9936
+ }
9937
+ if (ch === '"') {
9938
+ inString = true;
9939
+ out += ch;
9940
+ continue;
9941
+ }
9942
+ if (ch === "/" && next === "/") {
9943
+ while (i < input.length && input[i] !== `
9944
+ `)
9945
+ i++;
9946
+ out += `
9947
+ `;
9948
+ continue;
9949
+ }
9950
+ if (ch === "/" && next === "*") {
9951
+ i += 2;
9952
+ while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
9953
+ i++;
9954
+ i++;
9955
+ out += " ";
9956
+ continue;
9957
+ }
9958
+ out += ch;
9959
+ }
9960
+ let withoutTrailingCommas = "";
9961
+ inString = false;
9962
+ escaped = false;
9963
+ for (let i = 0;i < out.length; i++) {
9964
+ const ch = out[i];
9965
+ if (inString) {
9966
+ withoutTrailingCommas += ch;
9967
+ if (escaped)
9968
+ escaped = false;
9969
+ else if (ch === "\\")
9970
+ escaped = true;
9971
+ else if (ch === '"')
9972
+ inString = false;
9973
+ continue;
9974
+ }
9975
+ if (ch === '"') {
9976
+ inString = true;
9977
+ withoutTrailingCommas += ch;
9978
+ continue;
9979
+ }
9980
+ if (ch === ",") {
9981
+ let j = i + 1;
9982
+ while (j < out.length && /\s/.test(out[j]))
9983
+ j++;
9984
+ if (out[j] === "}" || out[j] === "]")
9985
+ continue;
9986
+ }
9987
+ withoutTrailingCommas += ch;
9988
+ }
9989
+ return withoutTrailingCommas;
9990
+ }
9991
+ function sortJson(value) {
9992
+ if (Array.isArray(value))
9993
+ return value.map(sortJson);
9994
+ if (value && typeof value === "object") {
9995
+ const sorted = {};
9996
+ for (const key of Object.keys(value).sort()) {
9997
+ sorted[key] = sortJson(value[key]);
9998
+ }
9999
+ return sorted;
10000
+ }
10001
+ return value;
10002
+ }
10003
+ function normalizedJsoncSemantics(content) {
10004
+ return JSON.stringify(sortJson(JSON.parse(stripJsoncForParse(content))));
10005
+ }
10006
+ function fileSemanticsMatch(a, b) {
10007
+ try {
10008
+ return normalizedJsoncSemantics(a) === normalizedJsoncSemantics(b);
10009
+ } catch {
10010
+ return a === b;
10011
+ }
10012
+ }
10013
+ var CONFIG_LOCK_STALE_MS = 4000;
10014
+ function acquireConfigMigrationLock(lockDir) {
10015
+ for (let attempt = 0;attempt < 2; attempt++) {
10016
+ try {
10017
+ mkdirSync2(lockDir, { recursive: false });
10018
+ return () => {
10019
+ try {
10020
+ rmSync(lockDir, { recursive: true, force: true });
10021
+ } catch {}
10022
+ };
10023
+ } catch (err) {
10024
+ const code = err?.code;
10025
+ if (code !== "EEXIST")
10026
+ throw err;
10027
+ try {
10028
+ const ageMs = Date.now() - statSync4(lockDir).mtimeMs;
10029
+ if (ageMs > CONFIG_LOCK_STALE_MS) {
10030
+ rmSync(lockDir, { recursive: true, force: true });
10031
+ continue;
10032
+ }
10033
+ } catch {
10034
+ continue;
10035
+ }
10036
+ return null;
10037
+ }
10038
+ }
10039
+ return null;
10040
+ }
10041
+ function atomicCopyConfigFile(sourcePath, targetPath) {
10042
+ mkdirSync2(dirname2(targetPath), { recursive: true });
10043
+ const tmpPath = join4(dirname2(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
10044
+ let fd = null;
10045
+ try {
10046
+ fd = openSync(tmpPath, "wx", 384);
10047
+ writeFileSync(fd, readFileSync4(sourcePath));
10048
+ closeSync(fd);
10049
+ fd = null;
10050
+ renameSync(tmpPath, targetPath);
10051
+ } catch (err) {
10052
+ if (fd !== null) {
10053
+ try {
10054
+ closeSync(fd);
10055
+ } catch {}
10056
+ }
10057
+ try {
10058
+ unlinkSync2(tmpPath);
10059
+ } catch {}
10060
+ throw err;
10061
+ }
10062
+ }
10063
+ function atomicWriteConfigFile(targetPath, content) {
10064
+ mkdirSync2(dirname2(targetPath), { recursive: true });
10065
+ const tmpPath = join4(dirname2(targetPath), `.${basename2(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
10066
+ let fd = null;
10067
+ try {
10068
+ fd = openSync(tmpPath, "wx", 384);
10069
+ writeFileSync(fd, content);
10070
+ closeSync(fd);
10071
+ fd = null;
10072
+ renameSync(tmpPath, targetPath);
10073
+ } catch (err) {
10074
+ if (fd !== null) {
10075
+ try {
10076
+ closeSync(fd);
10077
+ } catch {}
10078
+ }
10079
+ try {
10080
+ unlinkSync2(tmpPath);
10081
+ } catch {}
10082
+ throw err;
10083
+ }
10084
+ }
10085
+ function movedMarkerContent(targetPath, originalName, originalContent) {
10086
+ const header = [
10087
+ "// Magic Context configuration moved.",
10088
+ "//",
10089
+ "// Magic Context now reads its configuration from one shared CortexKit",
10090
+ "// location instead of a per-agent path. The settings that were in this",
10091
+ "// file have been moved to:",
10092
+ "//",
10093
+ `// ${targetPath}`,
10094
+ "//",
10095
+ "// Edit that file to change Magic Context settings. This location is no",
10096
+ "// longer read by Magic Context.",
10097
+ "//",
10098
+ `// To undo, rename this file back to "${originalName}" (and remove the`,
10099
+ "// CortexKit copy above if you want this location to take precedence).",
10100
+ "//",
10101
+ "// Your original settings are preserved below for reference.",
10102
+ "",
10103
+ ""
10104
+ ].join(`
10105
+ `);
10106
+ return `${header}${originalContent}`;
10107
+ }
10108
+ function markLegacySourcesMovedAside(sources, targetPath, logger) {
10109
+ const warnings = [];
10110
+ const info = logger?.info ?? logger?.log;
10111
+ for (const source of sources) {
10112
+ const markerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
10113
+ try {
10114
+ const original = readFileSync4(source.path, "utf-8");
10115
+ atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename2(source.path), original));
10116
+ unlinkSync2(source.path);
10117
+ info?.(`Moved legacy Magic Context config ${source.path} aside to ${markerPath}; now reading ${targetPath}`);
10118
+ } catch (err) {
10119
+ const msg = err instanceof Error ? err.message : String(err);
10120
+ warnings.push(`Magic Context could not move legacy config ${source.path} aside (${msg}); it is now stale and ignored. Delete it manually — config is read from ${targetPath}.`);
10121
+ logger?.warn?.(`Could not move legacy Magic Context config ${source.path} aside (${msg}); reading ${targetPath}`);
10122
+ }
10123
+ }
10124
+ return warnings;
10125
+ }
10126
+ function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
10127
+ const uniquePaths = [...new Set([targetPath, ...paths])];
10128
+ return `Magic Context ${scope} config migration refused: ${reason}. ` + `Legacy and CortexKit config paths collapse to one file, but Magic Context will not overwrite or merge them automatically. ` + `Please consolidate manually into ${targetPath}. Paths: ${uniquePaths.join(" ; ")}`;
10129
+ }
10130
+ function migrateConfigFile(opts) {
10131
+ const warnings = [];
10132
+ const existingSources = opts.legacySources.filter((source) => existsSync4(source.path));
10133
+ const info = opts.logger?.info ?? opts.logger?.log;
10134
+ if (existingSources.length === 0) {
10135
+ return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
10136
+ }
10137
+ mkdirSync2(dirname2(opts.targetPath), { recursive: true });
10138
+ const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
10139
+ if (!release) {
10140
+ warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
10141
+ return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
10142
+ }
10143
+ try {
10144
+ const sources = existingSources.map((source) => ({
10145
+ ...source,
10146
+ content: readFileSync4(source.path, "utf-8")
10147
+ }));
10148
+ if (existsSync4(opts.targetPath)) {
10149
+ const targetContent = readFileSync4(opts.targetPath, "utf-8");
10150
+ const differing2 = sources.filter((source) => !fileSemanticsMatch(source.content, targetContent));
10151
+ if (differing2.length > 0) {
10152
+ const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, differing2.map((source) => source.path), "the CortexKit target already exists with different settings");
10153
+ warnings.push(message);
10154
+ opts.logger?.warn?.(message);
10155
+ return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
10156
+ }
10157
+ info?.(`Magic Context ${opts.scope} config already present at ${opts.targetPath}; legacy copies match`);
10158
+ warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
10159
+ return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
10160
+ }
10161
+ const first = sources[0];
10162
+ const differing = sources.filter((source) => !fileSemanticsMatch(source.content, first.content));
10163
+ if (differing.length > 0) {
10164
+ const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, sources.map((source) => source.path), "multiple legacy sources have different settings");
10165
+ warnings.push(message);
10166
+ opts.logger?.warn?.(message);
10167
+ return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
10168
+ }
10169
+ atomicCopyConfigFile(first.path, opts.targetPath);
10170
+ info?.(`Migrated Magic Context ${opts.scope} config from ${first.path} to ${opts.targetPath}`);
10171
+ warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
10172
+ return {
10173
+ migrated: true,
10174
+ conflict: false,
10175
+ sourcePath: first.path,
10176
+ targetPath: opts.targetPath,
10177
+ warnings
10178
+ };
10179
+ } catch (err) {
10180
+ const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, existingSources.map((source) => source.path), `migration failed (${err instanceof Error ? err.message : String(err)})`);
10181
+ warnings.push(message);
10182
+ opts.logger?.warn?.(message);
10183
+ return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
10184
+ } finally {
10185
+ release();
10186
+ }
10187
+ }
10188
+ function migrateMagicContextConfigLocations(directory, logger) {
10189
+ const warnings = [];
10190
+ const legacy = resolveLegacyConfigSources(directory);
10191
+ try {
10192
+ warnings.push(...migrateConfigFile({
10193
+ scope: "user",
10194
+ targetPath: resolveCortexKitUserConfigPath(),
10195
+ legacySources: legacy.user,
10196
+ logger
10197
+ }).warnings);
10198
+ warnings.push(...migrateConfigFile({
10199
+ scope: "project",
10200
+ targetPath: resolveCortexKitProjectConfigPath(directory),
10201
+ legacySources: legacy.project,
10202
+ logger
10203
+ }).warnings);
10204
+ } catch (err) {
10205
+ const msg = err instanceof Error ? err.message : String(err);
10206
+ logger?.warn?.(`Magic Context config-location migration error (continuing): ${msg}`);
10207
+ warnings.push(`Magic Context config-location migration error: ${msg}`);
10208
+ }
10209
+ return warnings;
10210
+ }
10211
+
10212
+ // src/tools/light-descriptions.ts
10213
+ 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.`;
10214
+ var CTX_EXPAND_LIGHT_DESCRIPTION = `For ctx_expand users, recover compacted conversation by passing a session-history heading's inclusive start/end ordinals. Results are raw [N] U:/A: transcript capped near 15K tokens; oversized ranges return the head and a continuation. Use verbose=true to list each message ordinal, part previews, and tool-output sizes; use message=N for one complete stored message and its tool exchanges. NEVER expand ranges after the last compartment because that live tail is already visible.`;
10215
+ var CTX_NOTE_LIGHT_DESCRIPTION = `For ctx_note users, write saves, read lists, update changes, and dismiss retires future session notes; surface_condition creates a smart note. For smart notes, NEVER use a condition tied to this conversation or an unobservable future action because the background checker can inspect only external GitHub, disk, git, or web signals.`;
10216
+ var CTX_MEMORY_LIGHT_DESCRIPTION = `For ctx_memory users, write one standalone durable fact with category and content; update one ID, archive one or more IDs, merge two or more IDs, or get one to twenty numeric IDs. get reads memories in every status; list remains dreamer-only, so primary agents must NEVER assume bulk-list access.`;
10217
+ 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.`;
10218
+
10219
+ // src/shared/prompt-surface-runtime.ts
10220
+ var GUIDANCE_MARKER = "## Magic Context";
10221
+ var GUIDANCE_MARKER_LINE = /^## Magic Context[\t ]*\r?$/gm;
10222
+ var PROMPT_SURFACE_TOOL_IDS = [
10223
+ "ctx_reduce",
10224
+ "ctx_expand",
10225
+ "ctx_note",
10226
+ "ctx_memory",
10227
+ "ctx_search"
10228
+ ];
10229
+ var LIGHT_TOOL_DESCRIPTIONS = {
10230
+ ctx_reduce: CTX_REDUCE_LIGHT_DESCRIPTION,
10231
+ ctx_expand: CTX_EXPAND_LIGHT_DESCRIPTION,
10232
+ ctx_note: CTX_NOTE_LIGHT_DESCRIPTION,
10233
+ ctx_memory: CTX_MEMORY_LIGHT_DESCRIPTION,
10234
+ ctx_search: CTX_SEARCH_LIGHT_DESCRIPTION
10235
+ };
10236
+ function promptSurfaceHashMaterial(systemContent, preset = "full") {
10237
+ return preset === "full" ? systemContent : `${systemContent}
10238
+ \x00magic-context-prompt-surface:${preset}`;
10239
+ }
10240
+ var PROMPT_SURFACE_TOOL_ID_SET = new Set(PROMPT_SURFACE_TOOL_IDS);
10241
+ function resolveUserConfigDirectory(options) {
10242
+ if (options.userConfigDirectory)
10243
+ return resolve(options.userConfigDirectory);
10244
+ const sharedBase = cortexKitUserConfigBasePath();
10245
+ const shared = detectConfigFile(sharedBase);
10246
+ if (shared.format !== "none")
10247
+ return dirname3(shared.path);
10248
+ if (options.harness) {
10249
+ const legacy = resolveLegacyConfigSourcesForHarness(options.directory ?? process.cwd(), options.harness).user.find((source) => existsSync5(source.path));
10250
+ if (legacy)
10251
+ return dirname3(legacy.path);
10252
+ }
10253
+ return dirname3(sharedBase);
10254
+ }
10255
+ function markerCount(content) {
10256
+ return content.match(GUIDANCE_MARKER_LINE)?.length ?? 0;
10257
+ }
10258
+ function createPromptSurfaceRuntime(options) {
10259
+ const userConfigDirectory = resolveUserConfigDirectory(options);
10260
+ const warned = new Set;
10261
+ const warnOnce = (key, message) => {
10262
+ if (warned.has(key))
10263
+ return;
10264
+ warned.add(key);
10265
+ options.warn(message);
10266
+ };
10267
+ const readGuidanceOverride = (configuredPath) => {
10268
+ if (!configuredPath)
10269
+ return;
10270
+ const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve(userConfigDirectory, configuredPath);
10271
+ let content;
10272
+ try {
10273
+ if (!statSync5(path3).isFile()) {
10274
+ warnOnce(`guidance-not-file:${path3}`, `prompt_surface.guidance_override_path (${path3}) is not a file; using built-in guidance.`);
10275
+ return;
10276
+ }
10277
+ content = readFileSync5(path3, "utf8");
10278
+ } catch (error) {
10279
+ const reason = error instanceof Error ? error.message : String(error);
10280
+ warnOnce(`guidance-unreadable:${path3}:${reason}`, `prompt_surface.guidance_override_path (${path3}) could not be read (${reason}); using built-in guidance.`);
10281
+ return;
10282
+ }
10283
+ if (content.trim().length === 0) {
10284
+ warnOnce(`guidance-empty:${path3}`, `prompt_surface.guidance_override_path (${path3}) is empty; using built-in guidance.`);
10285
+ return;
10286
+ }
10287
+ const markers = markerCount(content);
10288
+ if (markers !== 1) {
10289
+ warnOnce(`guidance-marker-count:${path3}:${markers}`, `prompt_surface.guidance_override_path (${path3}) must contain exactly one ${JSON.stringify(GUIDANCE_MARKER)} section marker; found ${markers}. Using built-in guidance.`);
10290
+ return;
10291
+ }
10292
+ return content;
10293
+ };
10294
+ return {
10295
+ resolveRegistration(config) {
10296
+ const { preset } = resolvePromptSurface(config, undefined);
10297
+ const overrides = config?.tool_descriptions ?? {};
10298
+ for (const [toolId, description] of Object.entries(overrides)) {
10299
+ if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId)) {
10300
+ warnOnce(`unknown-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is not a known ctx_* tool ID; the override was ignored.`);
10301
+ } else if (description.trim().length === 0) {
10302
+ warnOnce(`empty-tool:${toolId}`, `prompt_surface.tool_descriptions.${toolId} is empty; the override was ignored.`);
10303
+ }
10304
+ }
10305
+ return {
10306
+ preset,
10307
+ descriptionFor(toolId, fullDescription) {
10308
+ if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId))
10309
+ return fullDescription;
10310
+ const override = overrides[toolId];
10311
+ if (override !== undefined && override.trim().length > 0)
10312
+ return override;
10313
+ return preset === "light" ? LIGHT_TOOL_DESCRIPTIONS[toolId] : fullDescription;
10314
+ }
10315
+ };
10316
+ },
10317
+ resolveGuidance(config, modelKey) {
10318
+ const { preset } = resolvePromptSurface(config, modelKey);
10319
+ return {
10320
+ preset,
10321
+ primaryOverride: readGuidanceOverride(config?.guidance_override_path)
10322
+ };
10323
+ }
10324
+ };
10325
+ }
10326
+ function createPromptSurfaceGuidanceEpochCache(runtime) {
10327
+ const epochs = new Map;
10328
+ return {
10329
+ resolve(sessionId, config, modelKey) {
10330
+ const cached = epochs.get(sessionId);
10331
+ if (cached && cached.config === config && cached.modelKey === modelKey) {
10332
+ return cached.selection;
10333
+ }
10334
+ const selection = runtime.resolveGuidance(config, modelKey);
10335
+ epochs.set(sessionId, { config, modelKey, selection });
10336
+ return selection;
10337
+ },
10338
+ clear(sessionId) {
10339
+ epochs.delete(sessionId);
10340
+ }
10341
+ };
10342
+ }
9705
10343
  // src/shared/assistant-message-extractor.ts
9706
10344
  function asSessionMessage(value) {
9707
10345
  if (!isRecord(value))
@@ -9837,6 +10475,7 @@ function computeCueContentHash(content) {
9837
10475
  return createHash8("sha256").update(content).digest("hex");
9838
10476
  }
9839
10477
  var muralCueColumnCache = new WeakMap;
10478
+ var muralCueRejectionColumnCache = new WeakMap;
9840
10479
  function hasMuralCueColumns(db) {
9841
10480
  const cached = muralCueColumnCache.get(db);
9842
10481
  if (cached !== undefined)
@@ -9846,6 +10485,15 @@ function hasMuralCueColumns(db) {
9846
10485
  muralCueColumnCache.set(db, present);
9847
10486
  return present;
9848
10487
  }
10488
+ function hasMuralCueRejectionCountColumn(db) {
10489
+ const cached = muralCueRejectionColumnCache.get(db);
10490
+ if (cached !== undefined)
10491
+ return cached;
10492
+ const columns = db.prepare("PRAGMA table_info(memories)").all();
10493
+ const present = columns.some((column) => column.name === "mural_cue_rejection_count");
10494
+ muralCueRejectionColumnCache.set(db, present);
10495
+ return present;
10496
+ }
9849
10497
  function getMuralCueState(db, memoryIds) {
9850
10498
  const out = new Map;
9851
10499
  if (!hasMuralCueColumns(db))
@@ -9854,9 +10502,14 @@ function getMuralCueState(db, memoryIds) {
9854
10502
  if (ids.length === 0)
9855
10503
  return out;
9856
10504
  const placeholders3 = ids.map(() => "?").join(", ");
9857
- const rows = db.prepare(`SELECT id, mural_cue, mural_cue_hash FROM memories WHERE id IN (${placeholders3})`).all(...ids);
10505
+ const rejectionCountColumn = hasMuralCueRejectionCountColumn(db) ? "COALESCE(mural_cue_rejection_count, 0) AS mural_cue_rejection_count" : "0 AS mural_cue_rejection_count";
10506
+ const rows = db.prepare(`SELECT id, mural_cue, mural_cue_hash, ${rejectionCountColumn} FROM memories WHERE id IN (${placeholders3})`).all(...ids);
9858
10507
  for (const row of rows) {
9859
- out.set(row.id, { cue: row.mural_cue ?? null, hash: row.mural_cue_hash ?? null });
10508
+ out.set(row.id, {
10509
+ cue: row.mural_cue ?? null,
10510
+ hash: row.mural_cue_hash ?? null,
10511
+ ...row.mural_cue_rejection_count > 0 ? { rejectionCount: row.mural_cue_rejection_count } : {}
10512
+ });
9860
10513
  }
9861
10514
  return out;
9862
10515
  }
@@ -9873,8 +10526,24 @@ function setMuralCue(db, projectPath, id, cue, contentHash) {
9873
10526
  if (!owned) {
9874
10527
  throw new Error(`Memory ${id} does not belong to project ${projectPath}`);
9875
10528
  }
9876
- db.prepare("UPDATE memories SET mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ? WHERE id = ? AND project_path = ?").run(cue, contentHash, Date.now(), id, projectPath);
10529
+ const rejectionReset = hasMuralCueRejectionCountColumn(db) ? ", mural_cue_rejection_count = 0" : "";
10530
+ db.prepare(`UPDATE memories SET mural_cue = ?, mural_cue_hash = ?, mural_cue_at = ?${rejectionReset} WHERE id = ? AND project_path = ?`).run(cue, contentHash, Date.now(), id, projectPath);
10531
+ });
10532
+ }
10533
+ function recordMuralCueRejection(db, projectPath, id, contentHash) {
10534
+ if (!hasMuralCueColumns(db) || !hasMuralCueRejectionCountColumn(db))
10535
+ return 0;
10536
+ let count = 0;
10537
+ withPrivilegedWriter(db, () => {
10538
+ const owned = db.prepare("SELECT 1 FROM memories WHERE id = ? AND project_path = ?").get(id, projectPath);
10539
+ if (!owned) {
10540
+ throw new Error(`Memory ${id} does not belong to project ${projectPath}`);
10541
+ }
10542
+ const row = db.prepare("SELECT mural_cue_hash, mural_cue_rejection_count FROM memories WHERE id = ?").get(id);
10543
+ count = row?.mural_cue_hash === contentHash ? (row.mural_cue_rejection_count ?? 0) + 1 : 1;
10544
+ db.prepare("UPDATE memories SET mural_cue = NULL, mural_cue_hash = ?, mural_cue_at = ?, mural_cue_rejection_count = ? WHERE id = ? AND project_path = ?").run(contentHash, Date.now(), count, id, projectPath);
9877
10545
  });
10546
+ return count;
9878
10547
  }
9879
10548
 
9880
10549
  // src/features/magic-context/memory/storage-memory-embeddings.ts
@@ -11655,7 +12324,7 @@ function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelI
11655
12324
  import { createHash as createHash12, randomUUID as randomUUID2 } from "node:crypto";
11656
12325
 
11657
12326
  // src/config/schema/magic-context.ts
11658
- import { homedir as homedir2 } from "node:os";
12327
+ import { homedir as homedir3 } from "node:os";
11659
12328
 
11660
12329
  // ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
11661
12330
  var exports_external = {};
@@ -26112,6 +26781,23 @@ var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "med
26112
26781
  var PiConfigSchema = exports_external.object({
26113
26782
  subagent_extensions: exports_external.array(exports_external.string().trim().min(1)).optional().describe("User-only allowlist of Pi extensions for Magic Context subagent children. When set, children use --no-extensions and load only these entries (plus Magic Context's scoped child extension where applicable). Relative paths resolve from ~/.pi/agent, matching Pi's settings.json package location. Unset preserves normal Pi extension discovery.")
26114
26783
  }).optional();
26784
+ var PromptSurfacePresetSchema = exports_external.enum(["full", "light"]);
26785
+ var PromptSurfaceModelKeySchema = exports_external.string().refine(isValidPromptSurfaceModelKey, {
26786
+ message: "Use a non-empty provider/model key or the literal provider/* wildcard; model IDs may contain additional slashes and matching is case-sensitive."
26787
+ });
26788
+ var PromptSurfaceToolKeySchema = exports_external.string().refine((value) => value.trim().length > 0, {
26789
+ message: "tool description keys must not be empty or whitespace-only"
26790
+ });
26791
+ var PromptSurfaceConfigSchema = exports_external.object({
26792
+ default: PromptSurfacePresetSchema.default("full").describe('Fallback prompt-surface preset ("full" or "light").'),
26793
+ 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."),
26794
+ guidance_override_path: exports_external.string().refine((value) => value.trim().length > 0, {
26795
+ message: "guidance_override_path must not be empty or whitespace-only"
26796
+ }).optional().describe("USER-LEVEL ONLY path to a complete primary guidance section. Relative paths resolve from the user config file."),
26797
+ tool_descriptions: exports_external.record(PromptSurfaceToolKeySchema, exports_external.string().refine((value) => value.trim().length > 0, {
26798
+ message: "tool description values must not be empty or whitespace-only"
26799
+ })).optional().describe("USER-LEVEL ONLY top-level description overrides keyed by ctx_* tool ID; parameter schemas and descriptions are unchanged.")
26800
+ }).describe("Prompt-surface preset routing. Project config may select default/models, while guidance_override_path and tool_descriptions are user-level only.");
26115
26801
  var CronScheduleSchema = exports_external.string().refine((s) => s.trim() === "" || isValidCron(s), {
26116
26802
  message: 'Invalid schedule: use a 5-field cron expression (e.g. "0 3 * * *" for 3am daily, "0 3 * * 0" for Sunday 3am, "0 */6 * * *" every 6h) or "" to disable.'
26117
26803
  }).describe('5-field cron schedule (e.g. "0 3 * * *"), or "" to disable this task.');
@@ -26188,9 +26874,9 @@ var EmbeddingFallbackProviderSchema = exports_external.enum(["local", "openai-co
26188
26874
  function expandConfigPath(value) {
26189
26875
  const trimmed = value.trim();
26190
26876
  if (trimmed === "~")
26191
- return homedir2();
26877
+ return homedir3();
26192
26878
  if (trimmed.startsWith("~/"))
26193
- return `${homedir2()}/${trimmed.slice(2)}`;
26879
+ return `${homedir3()}/${trimmed.slice(2)}`;
26194
26880
  return trimmed;
26195
26881
  }
26196
26882
  var BaseEmbeddingConfigSchema = exports_external.object({
@@ -26294,6 +26980,7 @@ var MagicContextConfigSchema = exports_external.object({
26294
26980
  historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
26295
26981
  dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
26296
26982
  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.'),
26983
+ 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)."),
26297
26984
  output_reserve: exports_external.union([
26298
26985
  exports_external.number().min(0),
26299
26986
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
@@ -26342,7 +27029,7 @@ var MagicContextConfigSchema = exports_external.object({
26342
27029
  keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
26343
27030
  fail_closed_blocking: exports_external.boolean().default(true).describe("When Magic Context cannot operate (schema fence mismatch, storage open/migration failure), block the primary-session prompt with a loud recovery error instead of silently degrading to native compaction. Default true. Set false only to restore the old degrade-silently behavior (not recommended). USER-LEVEL ONLY — ignored in project config for security. Requires a restart."),
26344
27031
  compaction: exports_external.object({
26345
- enabled: exports_external.boolean().default(true).describe("When false, Magic Context stops managing the context window and keeps its knowledge layer: memory and docs/user-profile/key-files injection through additive m[0]/m[1], raw-message FTS indexing, dreamer, notes, ctx_search, ctx_expand, ctx_memory, and /ctx-embed remain available. MC's historian/compartment preparation, tagging, markers, pruning, folding, drops, strips, splicing, synthetic context-management todos, temporal markers, nudges, and fail-closed blocking stop; ctx_expand remains a knowledge-surface tool. fail_closed_blocking is inert: a transform failure passes the input messages through without blocking or cancelling. This setting does not enable native compaction: OpenCode's compaction.auto / compaction.prune or Pi's equivalent owns the window, or nothing does. MC's compaction.enabled in magic-context.jsonc is distinct from OpenCode's compaction.auto / compaction.prune in opencode.jsonc; they are different files and different owners. On the first turn after disabling, a long session may trigger one native compaction cycle; MC removes only its own marker boundary, leaves native boundaries and stored compartments intact, and does no pre-trimming mitigation. Marker cleanup is lazy per session, so an unresumed session is cleaned when it is next resumed. If compaction is enabled again, run /ctx-wrapup when the historian is runnable to catch up. OpenCode peer verification against v1.18.4 confirms native compaction covers child sessions: subagents receive additive memory/docs injection and no MC reclaim in this mode, so keep subagent tasks small or leave compaction.enabled on for long subagent runs. If transform_mode is rust, compaction-off resolves to the TypeScript transform and emits one frozen boot warning because there is no Rust reduced-mode contract. This is boot-resolved and requires a process restart; project-tier compaction.enabled is stripped so a cloned repository cannot disable the user's setting. The sidebar reports raw usage as Context: <pct>% · native compaction or Context: <pct>% · no active compaction and does not show an MC execute-threshold fill. /ctx-wrapup, /ctx-recomp, /ctx-flush, and /ctx-session-upgrade refuse without context-management side effects; /ctx-embed remains functional. Raw content hidden by a native boundary before Magic Context's first pass is not retroactively indexed.")
27032
+ enabled: exports_external.boolean().default(true).describe("When false, Magic Context stops managing the context window and keeps its knowledge layer: memory and docs/user-profile/key-files injection through additive m[0]/m[1], raw-message FTS indexing, dreamer, notes, ctx_search, ctx_expand, ctx_memory, and /ctx-embed remain available. MC's historian/compartment preparation, tagging, markers, pruning, folding, drops, strips, splicing, synthetic context-management todos, temporal markers, nudges, and fail-closed blocking stop; ctx_expand remains a knowledge-surface tool. fail_closed_blocking is inert: a transform failure passes the input messages through without blocking or cancelling. This setting does not enable native compaction: OpenCode's compaction.auto / compaction.prune or Pi's equivalent owns the window, or nothing does. MC's compaction.enabled in magic-context.jsonc is distinct from OpenCode's compaction.auto / compaction.prune in opencode.jsonc; they are different files and different owners. On the first turn after disabling, a long session may trigger one native compaction cycle; MC removes only its own marker boundary, leaves native boundaries and stored compartments intact, and does no pre-trimming mitigation. Marker cleanup is lazy per session, so an unresumed session is cleaned when it is next resumed. If compaction is enabled again, run /ctx-wrapup when the historian is runnable to catch up. OpenCode peer verification against v1.18.4 confirms native compaction covers child sessions: subagents receive additive memory/docs injection and no MC reclaim in this mode, so keep subagent tasks small or leave compaction.enabled on for long subagent runs. This is boot-resolved and requires a process restart; project-tier compaction.enabled is stripped so a cloned repository cannot disable the user's setting. The sidebar reports raw usage as Context: <pct>% · native compaction or Context: <pct>% · no active compaction and does not show an MC execute-threshold fill. /ctx-wrapup, /ctx-recomp, /ctx-flush, and /ctx-session-upgrade refuse without context-management side effects; /ctx-embed remains functional. Raw content hidden by a native boundary before Magic Context's first pass is not retroactively indexed.")
26346
27033
  }).default({ enabled: true }).describe("Compaction-off mode gate. Default true (MC manages the context window as today). Set compaction.enabled=false to keep the knowledge layer while letting native compaction (or nothing) own the window. Boot-resolved; requires a restart to change."),
26347
27034
  todowrite: exports_external.object({
26348
27035
  enabled: exports_external.boolean().default(true).describe("Pi only: register Magic Context's todowrite task-list tool. Disable if you use your own todo extension. OpenCode ships its own built-in todowrite; this setting has no effect there."),
@@ -27075,7 +27762,7 @@ class SubcSocket {
27075
27762
  return this.sock.localPort ?? null;
27076
27763
  }
27077
27764
  static connect(host, port, deadlineMs) {
27078
- return new Promise((resolve, reject) => {
27765
+ return new Promise((resolve2, reject) => {
27079
27766
  const sock = net.connect({ host, port });
27080
27767
  sock.setNoDelay(true);
27081
27768
  const timer = setTimeout(() => {
@@ -27084,7 +27771,7 @@ class SubcSocket {
27084
27771
  }, Math.max(0, deadlineMs - Date.now()));
27085
27772
  sock.once("connect", () => {
27086
27773
  clearTimeout(timer);
27087
- resolve(new SubcSocket(sock));
27774
+ resolve2(new SubcSocket(sock));
27088
27775
  });
27089
27776
  sock.once("error", (err) => {
27090
27777
  clearTimeout(timer);
@@ -27116,7 +27803,7 @@ class SubcSocket {
27116
27803
  }
27117
27804
  if (n === 0)
27118
27805
  return Promise.resolve(new Uint8Array(0));
27119
- return new Promise((resolve, reject) => {
27806
+ return new Promise((resolve2, reject) => {
27120
27807
  let timer = null;
27121
27808
  if (Number.isFinite(deadlineMs)) {
27122
27809
  const remaining = deadlineMs - Date.now();
@@ -27129,7 +27816,7 @@ class SubcSocket {
27129
27816
  reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
27130
27817
  }, remaining);
27131
27818
  }
27132
- this.waiter = { need: n, resolve, reject, timer };
27819
+ this.waiter = { need: n, resolve: resolve2, reject, timer };
27133
27820
  this.tryServe();
27134
27821
  });
27135
27822
  }
@@ -27153,7 +27840,7 @@ class SubcSocket {
27153
27840
  let queued = false;
27154
27841
  let settled = false;
27155
27842
  let timer = null;
27156
- const completed = new Promise((resolve, reject) => {
27843
+ const completed = new Promise((resolve2, reject) => {
27157
27844
  const settle = (run) => {
27158
27845
  if (settled)
27159
27846
  return;
@@ -27177,7 +27864,7 @@ class SubcSocket {
27177
27864
  if (err) {
27178
27865
  reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
27179
27866
  } else {
27180
- resolve();
27867
+ resolve2();
27181
27868
  }
27182
27869
  });
27183
27870
  });
@@ -27393,14 +28080,14 @@ class SubcClient {
27393
28080
  const admission = opts.admissionClass ?? AdmissionClass.Normal;
27394
28081
  const corr = this.allocateCorr();
27395
28082
  const key = pendingKey(handle, corr);
27396
- const closed = new Promise((resolve, reject) => {
28083
+ const closed = new Promise((resolve2, reject) => {
27397
28084
  if (this.closedErr) {
27398
28085
  reject(this.closedErr);
27399
28086
  return;
27400
28087
  }
27401
28088
  this.pending.set(key, {
27402
28089
  handle,
27403
- resolve: () => resolve(),
28090
+ resolve: () => resolve2(),
27404
28091
  reject,
27405
28092
  onProgress: onEvent,
27406
28093
  timer: null,
@@ -27485,11 +28172,11 @@ class SubcClient {
27485
28172
  const waiters = [];
27486
28173
  for (const pending of this.pending.values()) {
27487
28174
  if (pending.handle === handle && !pending.subscription) {
27488
- waiters.push(new Promise((resolve) => {
28175
+ waiters.push(new Promise((resolve2) => {
27489
28176
  const previous = pending.onSettle;
27490
28177
  pending.onSettle = () => {
27491
28178
  previous?.();
27492
- resolve();
28179
+ resolve2();
27493
28180
  };
27494
28181
  }));
27495
28182
  }
@@ -27545,11 +28232,11 @@ class SubcClient {
27545
28232
  const channel = handle?.channel ?? 0;
27546
28233
  const epoch = handle?.epoch ?? 0;
27547
28234
  const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
27548
- return new Promise((resolve, reject) => {
28235
+ return new Promise((resolve2, reject) => {
27549
28236
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
27550
28237
  const pending = {
27551
28238
  handle,
27552
- resolve,
28239
+ resolve: resolve2,
27553
28240
  reject,
27554
28241
  onProgress,
27555
28242
  timer: null,
@@ -27623,11 +28310,11 @@ class SubcClient {
27623
28310
  }
27624
28311
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
27625
28312
  };
27626
- return new Promise((resolve, reject) => {
28313
+ return new Promise((resolve2, reject) => {
27627
28314
  const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
27628
28315
  const pending = {
27629
28316
  handle,
27630
- resolve,
28317
+ resolve: resolve2,
27631
28318
  reject,
27632
28319
  onProgress,
27633
28320
  timer: null,
@@ -28015,7 +28702,7 @@ function normalizeConnectOptions(opts) {
28015
28702
  identity: opts.identity,
28016
28703
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
28017
28704
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
28018
- sleep: opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
28705
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms))),
28019
28706
  timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
28020
28707
  };
28021
28708
  }
@@ -28072,8 +28759,8 @@ class AsyncPermitPool {
28072
28759
  this.available -= 1;
28073
28760
  return this.releaseOnce();
28074
28761
  }
28075
- await new Promise((resolve) => {
28076
- this.waiters.push(resolve);
28762
+ await new Promise((resolve2) => {
28763
+ this.waiters.push(resolve2);
28077
28764
  });
28078
28765
  return this.releaseOnce();
28079
28766
  }
@@ -28129,8 +28816,8 @@ class SubcProvider {
28129
28816
  this.currentConn = currentConn;
28130
28817
  this.opts = opts;
28131
28818
  this.storage = storage;
28132
- this.closed = new Promise((resolve) => {
28133
- this.resolveClosed = resolve;
28819
+ this.closed = new Promise((resolve2) => {
28820
+ this.resolveClosed = resolve2;
28134
28821
  });
28135
28822
  this.readLoop(sock, this.generation);
28136
28823
  this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
@@ -28150,13 +28837,13 @@ class SubcProvider {
28150
28837
  const key = routeKey(handle, corr);
28151
28838
  const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
28152
28839
  const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
28153
- return await new Promise((resolve, reject) => {
28840
+ return await new Promise((resolve2, reject) => {
28154
28841
  const timer = setTimeout(() => {
28155
28842
  if (this.pending.delete(key))
28156
28843
  reject(new SubcProviderError("reverse request timed out", "request_timeout"));
28157
28844
  }, timeoutMs);
28158
28845
  this.pending.set(key, {
28159
- resolve: (response) => resolve(response.body),
28846
+ resolve: (response) => resolve2(response.body),
28160
28847
  reject,
28161
28848
  timer
28162
28849
  });
@@ -28628,7 +29315,7 @@ function normalizeProviderConnectOptions(opts) {
28628
29315
  onBound: opts.onBound,
28629
29316
  onRouteGone: opts.onRouteGone,
28630
29317
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
28631
- sleep: opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
29318
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms))),
28632
29319
  restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
28633
29320
  onConnectionState: opts.onConnectionState,
28634
29321
  launchNonce: opts.launchNonce
@@ -28673,7 +29360,7 @@ function errorCode2(err) {
28673
29360
  return;
28674
29361
  }
28675
29362
  async function pauseBeforeStateRetry() {
28676
- await new Promise((resolve) => setTimeout(resolve, 0));
29363
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
28677
29364
  }
28678
29365
  function controlFlags() {
28679
29366
  return buildFlags(false, Priority.Passive, false);
@@ -28911,7 +29598,7 @@ function classifyError(value) {
28911
29598
  });
28912
29599
  }
28913
29600
  function wait(ms) {
28914
- return new Promise((resolve) => setTimeout(resolve, ms));
29601
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
28915
29602
  }
28916
29603
  function sha256(value) {
28917
29604
  return createHash11("sha256").update(value).digest("hex");
@@ -29378,9 +30065,9 @@ function getEmbeddingProviderIdentity(config2) {
29378
30065
  }
29379
30066
 
29380
30067
  // src/features/magic-context/memory/embedding-local.ts
29381
- import { chmodSync as chmodSync2, mkdirSync as mkdirSync2 } from "node:fs";
30068
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "node:fs";
29382
30069
  import { open, stat, unlink, writeFile } from "node:fs/promises";
29383
- import { dirname as dirname2, join as join4 } from "node:path";
30070
+ import { dirname as dirname4, join as join5 } from "node:path";
29384
30071
  import { pathToFileURL } from "node:url";
29385
30072
  var LOCK_POLL_MS = 150;
29386
30073
  var STALE_LOCK_MS = 3 * 60000;
@@ -29420,7 +30107,7 @@ async function acquireModelLoadLock(lockPath) {
29420
30107
  if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
29421
30108
  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.`);
29422
30109
  }
29423
- await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_MS));
30110
+ await new Promise((resolve2) => setTimeout(resolve2, LOCK_POLL_MS));
29424
30111
  }
29425
30112
  }
29426
30113
  }
@@ -29444,7 +30131,7 @@ async function injectWasmOrtForElectron() {
29444
30131
  const { createRequire: createRequireFn } = await import("node:module");
29445
30132
  const requireFn = createRequireFn(import.meta.url);
29446
30133
  const mainEntry = requireFn.resolve("onnxruntime-web");
29447
- const distDir = dirname2(mainEntry);
30134
+ const distDir = dirname4(mainEntry);
29448
30135
  const wasmPathsPrefix = `${pathToFileURL(distDir).href}/`;
29449
30136
  if (ortWeb.env?.wasm) {
29450
30137
  ortWeb.env.wasm.wasmPaths = wasmPathsPrefix;
@@ -29581,24 +30268,24 @@ class LocalEmbeddingProvider {
29581
30268
  if (LogLevel && "ERROR" in LogLevel) {
29582
30269
  env.logLevel = LogLevel.ERROR;
29583
30270
  }
29584
- const modelCacheDir = join4(getMagicContextStorageDir(), "models");
30271
+ const modelCacheDir = join5(getMagicContextStorageDir(), "models");
29585
30272
  try {
29586
30273
  if (shouldEnforcePrivateStoragePermissions()) {
29587
- mkdirSync2(modelCacheDir, { recursive: true, mode: 448 });
30274
+ mkdirSync3(modelCacheDir, { recursive: true, mode: 448 });
29588
30275
  if (process.platform !== "win32") {
29589
30276
  try {
29590
30277
  chmodSync2(modelCacheDir, 448);
29591
30278
  } catch {}
29592
30279
  }
29593
30280
  } else {
29594
- mkdirSync2(modelCacheDir, { recursive: true });
30281
+ mkdirSync3(modelCacheDir, { recursive: true });
29595
30282
  }
29596
30283
  env.cacheDir = modelCacheDir;
29597
30284
  } catch {
29598
30285
  log("[magic-context] could not create model cache dir, using library default");
29599
30286
  }
29600
30287
  const createPipeline = transformersModule.pipeline;
29601
- const lockPath = join4(modelCacheDir, ".load.lock");
30288
+ const lockPath = join5(modelCacheDir, ".load.lock");
29602
30289
  const releaseLock = await acquireModelLoadLock(lockPath);
29603
30290
  const stopHeartbeat = startLockHeartbeat(lockPath);
29604
30291
  try {
@@ -29625,7 +30312,7 @@ class LocalEmbeddingProvider {
29625
30312
  }
29626
30313
  const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
29627
30314
  log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
29628
- await new Promise((resolve) => setTimeout(resolve, delayMs));
30315
+ await new Promise((resolve2) => setTimeout(resolve2, delayMs));
29629
30316
  }
29630
30317
  }
29631
30318
  if (this.pipeline) {
@@ -29658,8 +30345,8 @@ class LocalEmbeddingProvider {
29658
30345
  if (this.inFlight === 0) {
29659
30346
  return Promise.resolve();
29660
30347
  }
29661
- return new Promise((resolve) => {
29662
- this.inFlightWaiters.push(resolve);
30348
+ return new Promise((resolve2) => {
30349
+ this.inFlightWaiters.push(resolve2);
29663
30350
  });
29664
30351
  }
29665
30352
  finishInFlight() {
@@ -31035,7 +31722,7 @@ async function runShadowWorker() {
31035
31722
  }
31036
31723
  processed += item.ids.length;
31037
31724
  processedBytes += itemBytes;
31038
- await new Promise((resolve) => setTimeout(resolve, 0));
31725
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
31039
31726
  }
31040
31727
  }
31041
31728
  function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
@@ -31396,7 +32083,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
31396
32083
  if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
31397
32084
  break;
31398
32085
  if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
31399
- await new Promise((resolve) => setTimeout(resolve, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
32086
+ await new Promise((resolve2) => setTimeout(resolve2, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
31400
32087
  }
31401
32088
  }
31402
32089
  embedded += persistedIds.size;
@@ -31481,7 +32168,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
31481
32168
  }
31482
32169
  embedded += n;
31483
32170
  options?.onProgress?.({ embedded: Math.min(embedded, total), total });
31484
- await new Promise((resolve) => setTimeout(resolve, 0));
32171
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
31485
32172
  }
31486
32173
  } finally {
31487
32174
  clearInterval(renewal);
@@ -31625,12 +32312,12 @@ function parseFields(json2) {
31625
32312
  }
31626
32313
 
31627
32314
  // src/hooks/magic-context/historian-state-file.ts
31628
- import { mkdirSync as mkdirSync3, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
32315
+ import { mkdirSync as mkdirSync4, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
31629
32316
  function cleanupHistorianStateFile(path3) {
31630
32317
  if (!path3)
31631
32318
  return;
31632
32319
  try {
31633
- unlinkSync2(path3);
32320
+ unlinkSync3(path3);
31634
32321
  } catch {}
31635
32322
  }
31636
32323
  // src/features/magic-context/memory/cosine-similarity.ts
@@ -31952,7 +32639,7 @@ function getMemoryVerifications(db, memoryIds) {
31952
32639
  }
31953
32640
  // src/features/magic-context/memory/verification-paths.ts
31954
32641
  import { execFile } from "node:child_process";
31955
- import { existsSync as existsSync4, realpathSync as realpathSync2, statSync as statSync3 } from "node:fs";
32642
+ import { existsSync as existsSync6, realpathSync as realpathSync2, statSync as statSync6 } from "node:fs";
31956
32643
  import path3 from "node:path";
31957
32644
  import { promisify } from "node:util";
31958
32645
  var execFileAsync = promisify(execFile);
@@ -32059,7 +32746,7 @@ function verificationFileExists(baseRoot, filePath) {
32059
32746
  return false;
32060
32747
  const root = path3.resolve(baseRoot);
32061
32748
  const candidate = path3.resolve(root, filePath);
32062
- return isWithin(root, candidate) && existsSync4(candidate);
32749
+ return isWithin(root, candidate) && existsSync6(candidate);
32063
32750
  }
32064
32751
  async function normalizeVerificationFiles(args) {
32065
32752
  const cwd = path3.resolve(args.cwd);
@@ -32092,9 +32779,9 @@ async function normalizeVerificationFiles(args) {
32092
32779
  warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
32093
32780
  continue;
32094
32781
  }
32095
- if (existsSync4(candidate)) {
32782
+ if (existsSync6(candidate)) {
32096
32783
  try {
32097
- if (statSync3(candidate).isDirectory()) {
32784
+ if (statSync6(candidate).isDirectory()) {
32098
32785
  warnings.push(`Skipped verification path "${value}" because it is a directory.`);
32099
32786
  continue;
32100
32787
  }
@@ -32123,7 +32810,7 @@ async function normalizeVerificationFiles(args) {
32123
32810
  }
32124
32811
  normalized.push(tracked);
32125
32812
  } else {
32126
- if (!existsSync4(candidate)) {
32813
+ if (!existsSync6(candidate)) {
32127
32814
  warnings.push(`Skipped verification path "${value}" because it does not exist.`);
32128
32815
  continue;
32129
32816
  }
@@ -32183,12 +32870,12 @@ function tallyFactsByCategory(facts) {
32183
32870
  }
32184
32871
 
32185
32872
  // src/hooks/magic-context/compaction-marker-manager.ts
32186
- import { join as join6 } from "node:path";
32873
+ import { join as join7 } from "node:path";
32187
32874
 
32188
32875
  // src/features/magic-context/compaction-marker.ts
32189
32876
  import { createHash as createHash13 } from "node:crypto";
32190
- import { existsSync as existsSync5 } from "node:fs";
32191
- import { join as join5 } from "node:path";
32877
+ import { existsSync as existsSync7 } from "node:fs";
32878
+ import { join as join6 } from "node:path";
32192
32879
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
32193
32880
  var ID_PREFIX_HEX_LENGTH = 12;
32194
32881
  var ID_SUFFIX_LENGTH = 14;
@@ -32214,7 +32901,7 @@ function generatePartId(timestampMs, counter = 0n, identity = "") {
32214
32901
  return generateId("prt", timestampMs, counter, identity);
32215
32902
  }
32216
32903
  function getOpenCodeDbPath() {
32217
- return join5(getDataDir(), "opencode", "opencode.db");
32904
+ return join6(getDataDir(), "opencode", "opencode.db");
32218
32905
  }
32219
32906
  var cachedWriteDb = null;
32220
32907
  var REQUIRED_MESSAGE_COLUMNS = ["id", "session_id", "time_created", "time_updated", "data"];
@@ -32259,7 +32946,7 @@ function getWritableOpenCodeDb() {
32259
32946
  closeQuietly(cachedWriteDb.db);
32260
32947
  } catch {}
32261
32948
  }
32262
- if (!existsSync5(dbPath)) {
32949
+ if (!existsSync7(dbPath)) {
32263
32950
  throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
32264
32951
  }
32265
32952
  const db = new Database(dbPath);
@@ -32882,7 +33569,7 @@ function reconcileForkOrphanedCompactionMarkers(db, sessionId) {
32882
33569
  }
32883
33570
  }
32884
33571
  function checkCompactionMarkerConsistency(db) {
32885
- const opencodeDbPath = join6(getDataDir(), "opencode", "opencode.db");
33572
+ const opencodeDbPath = join7(getDataDir(), "opencode", "opencode.db");
32886
33573
  let opencodeDb;
32887
33574
  try {
32888
33575
  opencodeDb = new Database(opencodeDbPath, { readonly: true });
@@ -33860,8 +34547,8 @@ function queueDropsForCompartmentalizedMessages(db, sessionId, upToMessageIndex)
33860
34547
  }
33861
34548
 
33862
34549
  // src/hooks/magic-context/compartment-runner-historian.ts
33863
- import { mkdirSync as mkdirSync4, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
33864
- import { join as join7 } from "node:path";
34550
+ import { mkdirSync as mkdirSync5, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
34551
+ import { join as join8 } from "node:path";
33865
34552
 
33866
34553
  // src/features/magic-context/subagent-token-capture.ts
33867
34554
  function asNumber(value) {
@@ -33991,6 +34678,7 @@ function mapParsedCompartmentsToChunk(compartments, chunk, sequenceOffset) {
33991
34678
 
33992
34679
  // src/hooks/magic-context/compartment-runner-validation.ts
33993
34680
  var MIN_RECOMP_CHUNK_TOKEN_BUDGET = 20;
34681
+ var HISTORIAN_BOUNDARY_HEALING_SLACK = 2;
33994
34682
  function healCompartmentGaps(compartments, toolOnlyRanges = []) {
33995
34683
  for (let i = 1;i < compartments.length; i++) {
33996
34684
  const prev = compartments[i - 1];
@@ -34006,6 +34694,36 @@ function healCompartmentGaps(compartments, toolOnlyRanges = []) {
34006
34694
  }
34007
34695
  }
34008
34696
  }
34697
+ function boundarySplitsCompletedToolArc(boundary, arcs = []) {
34698
+ return arcs.some((arc) => completedToolArcCrossesBoundary(arc.start, arc.end, boundary));
34699
+ }
34700
+ function healTerminalCompletedToolArc(compartments, unprocessedFrom, arcs = [], chunkEnd) {
34701
+ const last = compartments[compartments.length - 1];
34702
+ if (!last)
34703
+ return unprocessedFrom;
34704
+ const originalEnd = last.endMessage;
34705
+ for (let pass = 0;pass <= arcs.length; pass += 1) {
34706
+ const boundary = last.endMessage + 1;
34707
+ let nextEnd = last.endMessage;
34708
+ for (const arc of arcs) {
34709
+ if (arc.end <= chunkEnd && completedToolArcCrossesBoundary(arc.start, arc.end, boundary)) {
34710
+ nextEnd = Math.max(nextEnd, arc.end);
34711
+ }
34712
+ }
34713
+ if (nextEnd === last.endMessage)
34714
+ break;
34715
+ last.endMessage = nextEnd;
34716
+ }
34717
+ return last.endMessage !== originalEnd && unprocessedFrom !== null ? last.endMessage + 1 : unprocessedFrom;
34718
+ }
34719
+ function shouldDiscardLastHistorianCompartment(compartments, chunk) {
34720
+ if (compartments.length < 2)
34721
+ return false;
34722
+ const last = compartments[compartments.length - 1];
34723
+ const previous = compartments[compartments.length - 2];
34724
+ const lookaheadMargin = chunk.endIndex - last.endMessage;
34725
+ return lookaheadMargin <= HISTORIAN_BOUNDARY_HEALING_SLACK && !boundarySplitsCompletedToolArc(previous.endMessage + 1, chunk.completedToolArcs);
34726
+ }
34009
34727
  function validateHistorianOutput(text, _sessionId, chunk, _priorCompartments, sequenceOffset) {
34010
34728
  const parsed = parseCompartmentOutput(text);
34011
34729
  if (parsed.compartments.length === 0) {
@@ -34015,6 +34733,7 @@ function validateHistorianOutput(text, _sessionId, chunk, _priorCompartments, se
34015
34733
  };
34016
34734
  }
34017
34735
  healCompartmentGaps(parsed.compartments, chunk.toolOnlyRanges);
34736
+ parsed.unprocessedFrom = healTerminalCompletedToolArc(parsed.compartments, parsed.unprocessedFrom, chunk.completedToolArcs, chunk.endIndex);
34018
34737
  const mapped = mapParsedCompartmentsToChunk(parsed.compartments, chunk, sequenceOffset);
34019
34738
  if (!mapped.ok) {
34020
34739
  return {
@@ -34029,6 +34748,13 @@ function validateHistorianOutput(text, _sessionId, chunk, _priorCompartments, se
34029
34748
  error: `Historian returned invalid compartment output: ${parsedValidationError}`
34030
34749
  };
34031
34750
  }
34751
+ const last = parsed.compartments[parsed.compartments.length - 1];
34752
+ if (last && boundarySplitsCompletedToolArc(last.endMessage + 1, chunk.completedToolArcs)) {
34753
+ return {
34754
+ ok: false,
34755
+ error: "Historian terminal boundary splits a completed tool invocation/result arc"
34756
+ };
34757
+ }
34032
34758
  return {
34033
34759
  ok: true,
34034
34760
  compartments: mapped.compartments,
@@ -34471,15 +35197,15 @@ function isTransientHistorianPromptError(message) {
34471
35197
  ].some((token) => normalized.includes(token));
34472
35198
  }
34473
35199
  function sleep(ms) {
34474
- return new Promise((resolve) => {
34475
- setTimeout(resolve, ms);
35200
+ return new Promise((resolve2) => {
35201
+ setTimeout(resolve2, ms);
34476
35202
  });
34477
35203
  }
34478
35204
  function cleanupHistorianDump(sessionId, dumpPath) {
34479
35205
  if (!dumpPath)
34480
35206
  return;
34481
35207
  try {
34482
- unlinkSync3(dumpPath);
35208
+ unlinkSync4(dumpPath);
34483
35209
  } catch (error51) {
34484
35210
  sessionLog(sessionId, "compartment agent: failed to remove historian response dump", {
34485
35211
  dumpPath,
@@ -34490,12 +35216,12 @@ function cleanupHistorianDump(sessionId, dumpPath) {
34490
35216
  function dumpHistorianResponse(sessionId, directory, label, text) {
34491
35217
  try {
34492
35218
  const dumpDir = historianResponseDumpDir(directory);
34493
- mkdirSync4(dumpDir, { recursive: true });
35219
+ mkdirSync5(dumpDir, { recursive: true });
34494
35220
  ensureCortexKitArtifactGitignore(directory);
34495
35221
  const safeSessionId = sanitizeDumpName(sessionId);
34496
35222
  const safeLabel = sanitizeDumpName(label);
34497
- const dumpPath = join7(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
34498
- writeFileSync2(dumpPath, text, "utf8");
35223
+ const dumpPath = join8(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
35224
+ writeFileSync3(dumpPath, text, "utf8");
34499
35225
  sessionLog(sessionId, "compartment agent: historian response dumped", {
34500
35226
  label,
34501
35227
  dumpPath
@@ -37453,513 +38179,6 @@ function clearNoteNudgeTriggerOnly(db, sessionId) {
37453
38179
  db.prepare("UPDATE session_meta SET note_nudge_trigger_pending = 0, note_nudge_trigger_message_id = '' WHERE session_id = ?").run(sessionId);
37454
38180
  }
37455
38181
 
37456
- // src/hooks/magic-context/read-session-true-raw-tokens.ts
37457
- var MAX_MESSAGE_CACHE_ENTRIES = 1e5;
37458
- var MAX_MESSAGE_CACHE_KEY_BYTES = 64 * 1024 * 1024;
37459
- var FNV1A_32_OFFSET = 2166136261;
37460
- var FNV1A_32_PRIME = 16777619;
37461
- var messageEstimateCache = new Map;
37462
- var messageEstimateCacheBytes = 0;
37463
- var EMPTY_BREAKDOWN = {
37464
- text: 0,
37465
- reasoning: 0,
37466
- toolInput: 0,
37467
- toolOutput: 0,
37468
- image: 0,
37469
- other: 0,
37470
- total: 0
37471
- };
37472
- function addBreakdown(target, kind, value) {
37473
- if (kind === "total")
37474
- return;
37475
- const safeValue = Number.isFinite(value) && value > 0 ? Math.round(value) : 0;
37476
- target[kind] += safeValue;
37477
- target.total += safeValue;
37478
- }
37479
- function estimateStructured(value) {
37480
- if (typeof value === "string")
37481
- return estimateTokens(value);
37482
- if (value === undefined || value === null)
37483
- return 0;
37484
- return estimateTokens(stableStringify(value));
37485
- }
37486
- function firstStringField(record2, fields) {
37487
- for (const field of fields) {
37488
- const value = record2[field];
37489
- if (typeof value === "string" && value.length > 0)
37490
- return value;
37491
- }
37492
- return null;
37493
- }
37494
- function stringValue(value) {
37495
- if (typeof value === "string")
37496
- return value;
37497
- if (value === undefined || value === null)
37498
- return "";
37499
- return stableStringify(value);
37500
- }
37501
- function textFromToolResultContent(content) {
37502
- if (typeof content === "string")
37503
- return content;
37504
- if (Array.isArray(content)) {
37505
- const pieces = [];
37506
- for (const entry of content) {
37507
- if (typeof entry === "string") {
37508
- pieces.push(entry);
37509
- } else if (isRecord(entry)) {
37510
- const text = firstStringField(entry, ["text", "content", "value"]);
37511
- pieces.push(text ?? stableStringify(entry));
37512
- } else if (entry !== null && entry !== undefined) {
37513
- pieces.push(String(entry));
37514
- }
37515
- }
37516
- return pieces.join(`
37517
- `);
37518
- }
37519
- return stringValue(content);
37520
- }
37521
- function looksImageLike(part) {
37522
- const type = typeof part.type === "string" ? part.type.toLowerCase() : "";
37523
- const mime = typeof part.mime === "string" ? part.mime.toLowerCase() : "";
37524
- const mediaType = typeof part.mediaType === "string" ? part.mediaType.toLowerCase() : "";
37525
- return type.includes("image") || mime.startsWith("image/") || mediaType.startsWith("image/") || part.image_url !== undefined || part.imageUrl !== undefined || part.image !== undefined;
37526
- }
37527
- function defaultImageTokenHeuristic(part) {
37528
- if (isRecord(part)) {
37529
- const width = part.width;
37530
- const height = part.height;
37531
- if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
37532
- return Math.max(256, Math.min(4096, Math.ceil(width * height / 750)));
37533
- }
37534
- }
37535
- return 1024;
37536
- }
37537
- function partType(part) {
37538
- return typeof part.type === "string" ? part.type : "";
37539
- }
37540
- function hasOwn(record2, key) {
37541
- return Object.hasOwn(record2, key);
37542
- }
37543
- function recursiveByteLength(value) {
37544
- if (value === null || value === undefined)
37545
- return 0;
37546
- if (typeof value === "string")
37547
- return value.length;
37548
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
37549
- return String(value).length;
37550
- }
37551
- if (Array.isArray(value)) {
37552
- return value.reduce((sum, item) => sum + recursiveByteLength(item), value.length);
37553
- }
37554
- if (isRecord(value)) {
37555
- let total = Object.keys(value).length;
37556
- for (const [key, child] of Object.entries(value)) {
37557
- total += key.length + recursiveByteLength(child);
37558
- }
37559
- return total;
37560
- }
37561
- return String(value).length;
37562
- }
37563
- function updateFnv1a32(hash2, text) {
37564
- let next = hash2;
37565
- for (let index = 0;index < text.length; index += 1) {
37566
- next ^= text.charCodeAt(index);
37567
- next = Math.imul(next, FNV1A_32_PRIME) >>> 0;
37568
- }
37569
- return next;
37570
- }
37571
- function contentStringsHash(fields) {
37572
- let hash2 = FNV1A_32_OFFSET;
37573
- for (const field of fields) {
37574
- hash2 = updateFnv1a32(hash2, `${field.length}:`);
37575
- hash2 = updateFnv1a32(hash2, field);
37576
- hash2 = updateFnv1a32(hash2, "\x00");
37577
- }
37578
- return hash2.toString(16).padStart(8, "0");
37579
- }
37580
- function rawPartVersion(part) {
37581
- return part.__magicContextPartUpdatedAt ?? part.updated_at ?? part.updatedAt ?? part.version ?? part.revision ?? "";
37582
- }
37583
- function callIdFromPart(part) {
37584
- const direct = firstStringField(part, ["callID", "callId", "toolCallId", "tool_call_id", "id"]);
37585
- if (direct)
37586
- return direct;
37587
- const state2 = isRecord(part.state) ? part.state : null;
37588
- return state2 ? firstStringField(state2, ["callID", "callId", "toolCallId", "tool_call_id", "id"]) ?? "" : "";
37589
- }
37590
- function toolSignalFromPart(part) {
37591
- if (!isRecord(part))
37592
- return null;
37593
- const type = partType(part);
37594
- const state2 = isRecord(part.state) ? part.state : null;
37595
- const callId = callIdFromPart(part);
37596
- if (!callId && type !== "tool")
37597
- return null;
37598
- if (type === "tool") {
37599
- const hasInput = state2 !== null && hasOwn(state2, "input");
37600
- const outputKey = state2 ? hasOwn(state2, "output") ? "output" : hasOwn(state2, "error") ? "error" : hasOwn(state2, "result") ? "result" : null : null;
37601
- const hasOutput = outputKey !== null;
37602
- const outputValue = outputKey && state2 ? state2[outputKey] : undefined;
37603
- const providerExecuted = part.providerExecuted === true;
37604
- const openInvocation = !providerExecuted && !hasOutput;
37605
- return {
37606
- callId,
37607
- hasInput: hasInput || openInvocation,
37608
- hasOutput,
37609
- inputText: hasInput && state2 ? stringValue(state2.input) : "",
37610
- outputText: hasOutput ? stringValue(outputValue) : ""
37611
- };
37612
- }
37613
- if (type === "tool-invocation") {
37614
- const args = part.args ?? part.input;
37615
- return {
37616
- callId,
37617
- hasInput: args !== undefined,
37618
- hasOutput: false,
37619
- inputText: args !== undefined ? stringValue(args) : "",
37620
- outputText: ""
37621
- };
37622
- }
37623
- if (type === "tool_use") {
37624
- const input = part.input;
37625
- return {
37626
- callId,
37627
- hasInput: input !== undefined,
37628
- hasOutput: false,
37629
- inputText: input !== undefined ? stringValue(input) : "",
37630
- outputText: ""
37631
- };
37632
- }
37633
- if (type === "tool_result") {
37634
- const content = part.content ?? part.output ?? part.result;
37635
- return {
37636
- callId,
37637
- hasInput: false,
37638
- hasOutput: content !== undefined,
37639
- inputText: "",
37640
- outputText: content !== undefined ? textFromToolResultContent(content) : ""
37641
- };
37642
- }
37643
- return null;
37644
- }
37645
- function partCheapFingerprint(part) {
37646
- if (!isRecord(part))
37647
- return `${typeof part}:${recursiveByteLength(part)}`;
37648
- const version2 = rawPartVersion(part);
37649
- const type = typeof part.type === "string" ? part.type : "";
37650
- return `${type}:${String(version2)}:${recursiveByteLength(part)}`;
37651
- }
37652
- function messageCacheKey(message, options) {
37653
- const namespace = "cacheNamespace" in options ? options.cacheNamespace : "estimate";
37654
- const cheapFingerprint = message.parts.map(partCheapFingerprint).join("|");
37655
- return [
37656
- namespace,
37657
- options.providerShapeVersion,
37658
- message.id || `ordinal:${message.ordinal}`,
37659
- message.role,
37660
- message.parts.length,
37661
- cheapFingerprint
37662
- ].join("\x00");
37663
- }
37664
- function setCachedEstimate(key, breakdown) {
37665
- const keyEstimateBytes = key.length * 2 + 64;
37666
- const existing = messageEstimateCache.get(key);
37667
- if (existing)
37668
- messageEstimateCacheBytes -= existing.keyEstimateBytes;
37669
- messageEstimateCache.set(key, { breakdown, keyEstimateBytes });
37670
- messageEstimateCacheBytes += keyEstimateBytes;
37671
- while (messageEstimateCache.size > MAX_MESSAGE_CACHE_ENTRIES || messageEstimateCacheBytes > MAX_MESSAGE_CACHE_KEY_BYTES) {
37672
- const first = messageEstimateCache.keys().next().value;
37673
- if (typeof first !== "string")
37674
- break;
37675
- const removed = messageEstimateCache.get(first);
37676
- if (removed)
37677
- messageEstimateCacheBytes -= removed.keyEstimateBytes;
37678
- messageEstimateCache.delete(first);
37679
- }
37680
- }
37681
- function cloneBreakdown(value) {
37682
- return { ...value };
37683
- }
37684
- function estimateNonToolPart(part, options, breakdown) {
37685
- if (!isRecord(part)) {
37686
- if (part !== null && part !== undefined)
37687
- addBreakdown(breakdown, "other", estimateStructured(part));
37688
- return true;
37689
- }
37690
- const type = partType(part);
37691
- if (type === "step-start" || type === "step-finish" || type === "meta" && Object.keys(part).length <= 1) {
37692
- return true;
37693
- }
37694
- if (type === "text") {
37695
- const text = firstStringField(part, ["text", "content"]);
37696
- if (text)
37697
- addBreakdown(breakdown, "text", estimateTokens(text));
37698
- return true;
37699
- }
37700
- if (type === "reasoning" || type === "thinking" || type === "redacted_thinking") {
37701
- const text = firstStringField(part, ["thinking", "text", "content", "reasoning"]);
37702
- if (text) {
37703
- addBreakdown(breakdown, "reasoning", estimateTokens(text));
37704
- } else {
37705
- addBreakdown(breakdown, "other", estimateStructured(part));
37706
- }
37707
- return true;
37708
- }
37709
- const reasoningText = firstStringField(part, ["thinking", "reasoning"]);
37710
- if (reasoningText && type.length === 0) {
37711
- addBreakdown(breakdown, "reasoning", estimateTokens(reasoningText));
37712
- return true;
37713
- }
37714
- if (looksImageLike(part)) {
37715
- addBreakdown(breakdown, "image", options.imageTokenHeuristic?.(part) ?? defaultImageTokenHeuristic(part));
37716
- const altText = firstStringField(part, ["alt", "text", "description"]);
37717
- if (altText)
37718
- addBreakdown(breakdown, "text", estimateTokens(altText));
37719
- return true;
37720
- }
37721
- if (type.includes("file") || type === "source") {
37722
- const content = firstStringField(part, ["content", "text", "source"]);
37723
- if (content)
37724
- addBreakdown(breakdown, "text", estimateTokens(content));
37725
- else
37726
- addBreakdown(breakdown, "other", estimateStructured(part));
37727
- return true;
37728
- }
37729
- return false;
37730
- }
37731
- function estimateTrueRawMessageTokens(message, options) {
37732
- const breakdown = cloneBreakdown(EMPTY_BREAKDOWN);
37733
- const countedInput = new Set;
37734
- const countedOutput = new Set;
37735
- let ordinalToolIndex = 0;
37736
- for (const part of message.parts) {
37737
- const signal = toolSignalFromPart(part);
37738
- if (signal) {
37739
- const localKey = `${signal.callId || "tool"}:${message.ordinal}:${ordinalToolIndex}`;
37740
- ordinalToolIndex += 1;
37741
- if (signal.hasInput) {
37742
- const key = `${signal.callId}:input:${message.ordinal}`;
37743
- if (!countedInput.has(key)) {
37744
- countedInput.add(key);
37745
- addBreakdown(breakdown, "toolInput", estimateTokens(signal.inputText));
37746
- }
37747
- }
37748
- if (signal.hasOutput) {
37749
- const key = `${signal.callId}:output:${message.ordinal}:${localKey}`;
37750
- if (!countedOutput.has(key)) {
37751
- countedOutput.add(key);
37752
- addBreakdown(breakdown, "toolOutput", estimateTokens(signal.outputText));
37753
- }
37754
- }
37755
- continue;
37756
- }
37757
- if (!estimateNonToolPart(part, options, breakdown)) {
37758
- addBreakdown(breakdown, "other", estimateStructured(part));
37759
- }
37760
- }
37761
- return breakdown;
37762
- }
37763
- function buildToolArcs(messages) {
37764
- const openQueues = new Map;
37765
- const arcs = [];
37766
- for (const message of messages) {
37767
- for (const part of message.parts) {
37768
- const signal = toolSignalFromPart(part);
37769
- if (!signal || signal.callId.length === 0)
37770
- continue;
37771
- if (signal.hasInput && signal.hasOutput) {
37772
- arcs.push({
37773
- callId: signal.callId,
37774
- invOrdinal: message.ordinal,
37775
- resOrdinal: message.ordinal
37776
- });
37777
- continue;
37778
- }
37779
- if (signal.hasInput) {
37780
- const queue = openQueues.get(signal.callId) ?? [];
37781
- queue.push(message.ordinal);
37782
- openQueues.set(signal.callId, queue);
37783
- continue;
37784
- }
37785
- if (signal.hasOutput) {
37786
- const queue = openQueues.get(signal.callId) ?? [];
37787
- const invOrdinal = queue.shift();
37788
- if (queue.length === 0)
37789
- openQueues.delete(signal.callId);
37790
- else
37791
- openQueues.set(signal.callId, queue);
37792
- if (invOrdinal !== undefined) {
37793
- arcs.push({ callId: signal.callId, invOrdinal, resOrdinal: message.ordinal });
37794
- }
37795
- }
37796
- }
37797
- }
37798
- for (const [callId, queue] of openQueues) {
37799
- for (const invOrdinal of queue) {
37800
- arcs.push({ callId, invOrdinal, resOrdinal: null });
37801
- }
37802
- }
37803
- return arcs.sort((a, b) => a.invOrdinal - b.invOrdinal || (a.resOrdinal ?? Number.MAX_SAFE_INTEGER) - (b.resOrdinal ?? Number.MAX_SAFE_INTEGER));
37804
- }
37805
- function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal, recentOpenArcCutoff) {
37806
- let boundary = candidate;
37807
- for (const arc of arcs) {
37808
- if (arc.resOrdinal !== null) {
37809
- if (arc.invOrdinal < boundary && boundary <= arc.resOrdinal) {
37810
- boundary = arc.resOrdinal + 1;
37811
- }
37812
- continue;
37813
- }
37814
- if (arc.invOrdinal < recentOpenArcCutoff)
37815
- continue;
37816
- if (arc.invOrdinal >= lastCompartmentEndOrdinal + 1 && arc.invOrdinal < boundary) {
37817
- return arc.invOrdinal;
37818
- }
37819
- if (arc.invOrdinal >= boundary) {
37820
- return arc.invOrdinal;
37821
- }
37822
- }
37823
- return boundary;
37824
- }
37825
- function tokenForMessage(message, options) {
37826
- const key = messageCacheKey(message, options);
37827
- const cached2 = messageEstimateCache.get(key);
37828
- if (cached2)
37829
- return cloneBreakdown(cached2.breakdown);
37830
- const breakdown = estimateTrueRawMessageTokens(message, options);
37831
- setCachedEstimate(key, breakdown);
37832
- return cloneBreakdown(breakdown);
37833
- }
37834
- function buildTrueRawTokenIndex(sessionId, messages, options) {
37835
- const ordered = [...messages].sort((a, b) => a.ordinal - b.ordinal);
37836
- const sliceCount = ordered.length;
37837
- const firstOrdinal = ordered.length > 0 ? ordered[0].ordinal : 1;
37838
- const terminalOrdinal = ordered.length > 0 ? ordered[ordered.length - 1].ordinal : 0;
37839
- const rawMessageCount = Math.max(sliceCount, terminalOrdinal, options.absoluteMessageCount ?? sliceCount);
37840
- const ordinalSpan = terminalOrdinal >= firstOrdinal ? terminalOrdinal - firstOrdinal + 1 : 0;
37841
- const tokensByOrdinal = new Map;
37842
- const idsByOrdinal = new Map;
37843
- const prefix = new Array(ordinalSpan + 1).fill(0);
37844
- for (const message of ordered) {
37845
- const stored = options.storedTotalForMessage?.(message);
37846
- const total = stored !== undefined && stored !== null ? stored : tokenForMessage(message, options).total;
37847
- tokensByOrdinal.set(message.ordinal, total);
37848
- idsByOrdinal.set(message.ordinal, message.id);
37849
- const relative = message.ordinal - firstOrdinal + 1;
37850
- if (relative >= 1 && relative <= ordinalSpan) {
37851
- prefix[relative] = total;
37852
- }
37853
- }
37854
- for (let k = 1;k <= ordinalSpan; k += 1) {
37855
- prefix[k] += prefix[k - 1];
37856
- }
37857
- const ordinalToIndex = (ordinal) => Math.max(0, Math.min(ordinalSpan, ordinal - firstOrdinal));
37858
- return {
37859
- sessionId,
37860
- providerShapeVersion: options.providerShapeVersion,
37861
- rawMessageCount,
37862
- tokenForOrdinal(ordinal) {
37863
- return tokensByOrdinal.get(ordinal) ?? 0;
37864
- },
37865
- messageIdAtOrdinal(ordinal) {
37866
- return idsByOrdinal.get(ordinal) ?? null;
37867
- },
37868
- suffixTokensFromOrdinal(ordinal) {
37869
- if (ordinal <= firstOrdinal)
37870
- return prefix[ordinalSpan];
37871
- if (ordinal > terminalOrdinal)
37872
- return 0;
37873
- return prefix[ordinalSpan] - prefix[ordinalToIndex(ordinal)];
37874
- },
37875
- rangeTokens(startInclusive, endExclusive) {
37876
- const start = Math.max(firstOrdinal, startInclusive);
37877
- const end = Math.max(start, Math.min(terminalOrdinal + 1, endExclusive));
37878
- return prefix[end - firstOrdinal] - prefix[start - firstOrdinal];
37879
- },
37880
- findSuffixStartForTokens(tokens) {
37881
- if (!Number.isFinite(tokens) || tokens <= 0)
37882
- return terminalOrdinal + 1;
37883
- const target = Math.max(0, Math.floor(tokens));
37884
- const total = prefix[ordinalSpan];
37885
- if (total < target)
37886
- return firstOrdinal;
37887
- const cut = total - target;
37888
- let lo = 0;
37889
- let hi = ordinalSpan;
37890
- let best = 0;
37891
- while (lo <= hi) {
37892
- const mid = lo + hi >> 1;
37893
- if (prefix[mid] <= cut) {
37894
- best = mid;
37895
- lo = mid + 1;
37896
- } else {
37897
- hi = mid - 1;
37898
- }
37899
- }
37900
- return firstOrdinal + best;
37901
- },
37902
- findHeadEndForCap(startInclusive, endExclusive, capTokens) {
37903
- const start = Math.max(firstOrdinal, Math.min(terminalOrdinal + 1, startInclusive));
37904
- const end = Math.max(start, Math.min(terminalOrdinal + 1, endExclusive));
37905
- if (!Number.isFinite(capTokens) || capTokens <= 0)
37906
- return start;
37907
- const startIndex = start - firstOrdinal;
37908
- const endIndex = end - firstOrdinal;
37909
- const cut = prefix[startIndex] + Math.floor(capTokens);
37910
- let lo = startIndex + 1;
37911
- let hi = endIndex;
37912
- let bestEndIndex = startIndex;
37913
- while (lo <= hi) {
37914
- const mid = lo + hi >> 1;
37915
- if (prefix[mid] <= cut) {
37916
- bestEndIndex = mid;
37917
- lo = mid + 1;
37918
- } else {
37919
- hi = mid - 1;
37920
- }
37921
- }
37922
- let bestEnd = firstOrdinal + bestEndIndex;
37923
- if (bestEnd === start && start < end)
37924
- bestEnd = start + 1;
37925
- return Math.min(bestEnd, end);
37926
- }
37927
- };
37928
- }
37929
- function partContentFingerprint(part) {
37930
- if (!isRecord(part))
37931
- return `${typeof part}:${recursiveByteLength(part)}`;
37932
- const tool = toolSignalFromPart(part);
37933
- if (tool) {
37934
- return contentStringsHash([tool.inputText, tool.outputText]);
37935
- }
37936
- const text = firstStringField(part, ["text", "thinking", "reasoning", "content", "url"]) ?? "";
37937
- return contentStringsHash([text]);
37938
- }
37939
- function computeRawRangeFingerprint(messages, startInclusive, endExclusive) {
37940
- const pieces = [];
37941
- for (const message of messages) {
37942
- if (message.ordinal < startInclusive || message.ordinal >= endExclusive)
37943
- continue;
37944
- const partFingerprint = message.parts.map(partContentFingerprint).join(",");
37945
- pieces.push(`${message.ordinal}:${message.id}:${message.parts.length}:${partFingerprint}`);
37946
- }
37947
- return pieces.join("|");
37948
- }
37949
- function invalidateTrueRawTokenCache(args) {
37950
- const sessionNeedle = args.sessionId ? `${args.sessionId}` : null;
37951
- const messageNeedle = args.messageId ? `\x00${args.messageId}\x00` : null;
37952
- for (const [key, value] of messageEstimateCache) {
37953
- const sessionMatches = sessionNeedle === null || key.includes(sessionNeedle);
37954
- const messageMatches = messageNeedle === null || key.includes(messageNeedle);
37955
- if (sessionMatches && messageMatches) {
37956
- messageEstimateCache.delete(key);
37957
- messageEstimateCacheBytes -= value.keyEstimateBytes;
37958
- }
37959
- }
37960
- args.reason;
37961
- }
37962
-
37963
38182
  // src/hooks/magic-context/protected-tail-boundary.ts
37964
38183
  var ALPHA = 0.3;
37965
38184
  var FLOOR_RATIO = 0.08;
@@ -38081,7 +38300,7 @@ function fenceWrapupBoundaryForToolArcs(args) {
38081
38300
  if (arc.resOrdinal === null) {
38082
38301
  continue;
38083
38302
  }
38084
- if (arc.invOrdinal >= args.lastCompartmentEndOrdinal + 1 && arc.invOrdinal < next && next <= arc.resOrdinal) {
38303
+ if (arc.invOrdinal >= args.lastCompartmentEndOrdinal + 1 && completedToolArcCrossesBoundary(arc.invOrdinal, arc.resOrdinal, next)) {
38085
38304
  next = arc.invOrdinal;
38086
38305
  }
38087
38306
  }
@@ -40601,17 +40820,14 @@ ${chunkText}`,
40601
40820
  }
40602
40821
  retainDrainReservationForRetryThrottle = false;
40603
40822
  const emittedCompartments = validatedPass.compartments;
40604
- const BOUNDARY_HEALING_SLACK = 2;
40605
40823
  const inEmergency = getOverflowState(db, sessionId).needsEmergencyRecovery;
40606
40824
  let persistedCompartments = emittedCompartments;
40607
- if (!inEmergency && !forceKeepLastCompartmentForChunk && emittedCompartments.length >= 2) {
40825
+ if (!inEmergency && !forceKeepLastCompartmentForChunk && shouldDiscardLastHistorianCompartment(emittedCompartments, chunk)) {
40608
40826
  const lastEmitted = emittedCompartments[emittedCompartments.length - 1];
40609
40827
  const lookaheadMargin = chunk.endIndex - lastEmitted.endMessage;
40610
- if (lookaheadMargin <= BOUNDARY_HEALING_SLACK) {
40611
- persistedCompartments = emittedCompartments.slice(0, -1);
40612
- telemetry.discardedLast = true;
40613
- sessionLog(sessionId, `historian discard-last: dropped provisional compartment ${lastEmitted.startMessage}-${lastEmitted.endMessage} (lookaheadMargin=${lookaheadMargin} <= ${BOUNDARY_HEALING_SLACK}); will re-derive from raw next run`);
40614
- }
40828
+ persistedCompartments = emittedCompartments.slice(0, -1);
40829
+ telemetry.discardedLast = true;
40830
+ sessionLog(sessionId, `historian discard-last: dropped provisional compartment ${lastEmitted.startMessage}-${lastEmitted.endMessage} (lookaheadMargin=${lookaheadMargin} <= ${HISTORIAN_BOUNDARY_HEALING_SLACK}); will re-derive from raw next run`);
40615
40831
  }
40616
40832
  const newCompartments = persistedCompartments;
40617
40833
  const lastNewEnd = newCompartments[newCompartments.length - 1]?.endMessage ?? 0;
@@ -42088,4 +42304,4 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
42088
42304
  }
42089
42305
  }
42090
42306
 
42091
- export { withContentLanguageDirective, buildPrimaryLanguageDirective, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, estimateTrueRawMessageTokens, invalidateTrueRawTokenCache, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };
42307
+ export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };