@cortexkit/pi-magic-context 0.42.4 → 0.42.6

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.
@@ -6834,6 +6834,7 @@ var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
6834
6834
  var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 90% for cache safety: output capacity is reserved from the usable context window, and the remaining 10% absorbs mid-turn growth before the absolute 95% emergency wall. Use a value between 20 and 90.";
6835
6835
  var DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
6836
6836
  var DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
6837
+ var PROTECTED_TOKENS_MIN = 4000;
6837
6838
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
6838
6839
  var PiThinkingLevelSchema = _enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]).optional();
6839
6840
  var OmpThinkingLevelSchema = _enum(["off", "minimal", "low", "medium", "high", "xhigh", "max", "inherit", "auto"]).optional();
@@ -7203,8 +7204,8 @@ var MagicContextConfigSchema = object({
7203
7204
  smart_notes: object({
7204
7205
  retina_handoff: boolean2().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
7205
7206
  }).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
7206
- cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "model-id": "10m" }). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
7207
- prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. On OpenCode and Pi, per-model routing applies to the guidance block only: tool descriptions are registered once per process, so they follow the default preset (a v1 plugin-surface limitation; per-model tool descriptions are planned for the OpenCode v2 plugin API once the SDK stabilizes)."),
7207
+ cache_ttl: union([string2(), object({ default: string2() }).catchall(string2())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
7208
+ prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model."),
7208
7209
  output_reserve: union([
7209
7210
  number2().min(0),
7210
7211
  object({ default: number2().min(0) }).catchall(number2().min(0))
@@ -7220,7 +7221,7 @@ var MagicContextConfigSchema = object({
7220
7221
  execute_threshold_tokens: object({
7221
7222
  default: number2().min(5000).max(2000000).optional()
7222
7223
  }).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
7223
- protected_tokens: number2().int().min(4000).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
7224
+ protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
7224
7225
  protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
7225
7226
  clear_reasoning_age: number2().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
7226
7227
  history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
@@ -8934,6 +8935,25 @@ function extractTexts(parts) {
8934
8935
  }
8935
8936
  return texts;
8936
8937
  }
8938
+ function extractToolResultBodyTokens(parts) {
8939
+ let tokens = 0;
8940
+ for (const part of parts) {
8941
+ if (part === null || typeof part !== "object")
8942
+ continue;
8943
+ const p = part;
8944
+ if (p.type !== "tool")
8945
+ continue;
8946
+ const state = p.state;
8947
+ if (!state || typeof state !== "object")
8948
+ continue;
8949
+ const body = state.output ?? state.error;
8950
+ if (body === undefined)
8951
+ continue;
8952
+ const text = typeof body === "string" ? body : JSON.stringify(body);
8953
+ tokens += Math.ceil(text.length / 4);
8954
+ }
8955
+ return tokens;
8956
+ }
8937
8957
  function extractToolCallSummaries(parts) {
8938
8958
  const summaries = [];
8939
8959
  for (const part of parts) {
@@ -10947,6 +10967,28 @@ async function pullAndApplyMirrorPageWithStatus(args) {
10947
10967
  limit
10948
10968
  });
10949
10969
  const nextCursor = applyMirrorPage({ db: args.db, page: response.page });
10970
+ if (args.domain === "memories" && args.module.memoryIdentityAck) {
10971
+ const rowsByProject = new Map;
10972
+ for (const feed of response.page.rows) {
10973
+ if (feed.domain !== "memories" || feed.op === "tombstone")
10974
+ continue;
10975
+ const project = rowString(feed.full_row_snapshot, "project_path");
10976
+ if (!project)
10977
+ continue;
10978
+ const identity = mirrorIdentity(args.db, "memories", project, feed.module_row_id);
10979
+ if (!identity)
10980
+ continue;
10981
+ const rows = rowsByProject.get(project) ?? [];
10982
+ rows.push({
10983
+ module_row_id: feed.module_row_id,
10984
+ context_row_id: identity.context_row_id
10985
+ });
10986
+ rowsByProject.set(project, rows);
10987
+ }
10988
+ for (const [project, rows] of rowsByProject) {
10989
+ await args.module.memoryIdentityAck({ project, rows });
10990
+ }
10991
+ }
10950
10992
  return {
10951
10993
  cursor: nextCursor,
10952
10994
  hasMore: response.page.has_more,
@@ -11717,6 +11759,114 @@ function isSqliteLockError(error) {
11717
11759
  function tableExists2(db, name) {
11718
11760
  return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
11719
11761
  }
11762
+ function tableHasHarnessColumn(db, name) {
11763
+ if (!tableExists2(db, name))
11764
+ return false;
11765
+ return db.prepare(`PRAGMA table_info(${name})`).all().some((column) => column.name === "harness");
11766
+ }
11767
+ var V85_OPENCODE2_RELABEL_TABLES = [
11768
+ "tags",
11769
+ "pending_ops",
11770
+ "source_contents",
11771
+ "compartments",
11772
+ "compartment_chunk_embeddings",
11773
+ "session_projects",
11774
+ "compartment_events",
11775
+ "compression_depth",
11776
+ "session_facts",
11777
+ "primer_candidates",
11778
+ "notes",
11779
+ "message_history_index",
11780
+ "message_history_source",
11781
+ "pending_session_cleanup",
11782
+ "message_history_orphan_sweep",
11783
+ "session_meta",
11784
+ "subagent_invocations",
11785
+ "historian_runs",
11786
+ "transform_decisions",
11787
+ "recomp_compartments",
11788
+ "recomp_facts"
11789
+ ];
11790
+ var V85_OPTIONAL_OPENCODE2_RELABEL_TABLES = ["session_project_backfill_state"];
11791
+ function deleteLosingOpenCode2Twin(db, table, joinColumns, newerPredicate) {
11792
+ if (!tableHasHarnessColumn(db, table))
11793
+ return;
11794
+ const naturalJoin = joinColumns.map((column) => `oc.${column} = o2.${column}`).join(" AND ");
11795
+ const o2On = naturalJoin ? `${naturalJoin} AND oc.harness = 'opencode'` : `oc.harness = 'opencode'`;
11796
+ const ocOn = naturalJoin ? `${naturalJoin} AND o2.harness = 'opencode2'` : `o2.harness = 'opencode2'`;
11797
+ db.exec(`
11798
+ DELETE FROM ${table}
11799
+ WHERE rowid IN (
11800
+ SELECT o2.rowid
11801
+ FROM ${table} AS o2
11802
+ JOIN ${table} AS oc
11803
+ ON ${o2On}
11804
+ WHERE o2.harness = 'opencode2'
11805
+ AND NOT (${newerPredicate})
11806
+ );
11807
+ DELETE FROM ${table}
11808
+ WHERE rowid IN (
11809
+ SELECT oc.rowid
11810
+ FROM ${table} AS oc
11811
+ JOIN ${table} AS o2
11812
+ ON ${ocOn}
11813
+ WHERE oc.harness = 'opencode'
11814
+ AND (${newerPredicate})
11815
+ );
11816
+ `);
11817
+ }
11818
+ function relabelOpenCode2HarnessRows(db) {
11819
+ deleteLosingOpenCode2Twin(db, "session_projects", ["session_id"], "o2.updated_at > oc.updated_at");
11820
+ deleteLosingOpenCode2Twin(db, "primer_candidates", ["project_path", "session_id", "source_start_message_id", "source_end_message_id"], "o2.created_at > oc.created_at");
11821
+ deleteLosingOpenCode2Twin(db, "transform_decisions", ["session_id", "message_id"], "o2.ts_ms > oc.ts_ms");
11822
+ deleteLosingOpenCode2Twin(db, "message_history_orphan_sweep", [], "COALESCE(o2.last_swept_at, -1) > COALESCE(oc.last_swept_at, -1)");
11823
+ if (tableHasHarnessColumn(db, "session_project_backfill_state")) {
11824
+ db.exec(`
11825
+ DELETE FROM session_project_backfill_state
11826
+ WHERE harness = 'opencode2'
11827
+ AND EXISTS (
11828
+ SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode'
11829
+ )
11830
+ AND NOT (
11831
+ (status = 'completed'
11832
+ AND (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
11833
+ != 'completed')
11834
+ OR (
11835
+ status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode')
11836
+ AND COALESCE(started_at, -1) > COALESCE(
11837
+ (SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode'),
11838
+ -1
11839
+ )
11840
+ )
11841
+ );
11842
+ DELETE FROM session_project_backfill_state
11843
+ WHERE harness = 'opencode'
11844
+ AND EXISTS (
11845
+ SELECT 1 FROM session_project_backfill_state WHERE harness = 'opencode2'
11846
+ )
11847
+ AND (
11848
+ ((SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2') = 'completed'
11849
+ AND status != 'completed')
11850
+ OR (
11851
+ status = (SELECT status FROM session_project_backfill_state WHERE harness = 'opencode2')
11852
+ AND COALESCE(
11853
+ (SELECT started_at FROM session_project_backfill_state WHERE harness = 'opencode2'),
11854
+ -1
11855
+ ) > COALESCE(started_at, -1)
11856
+ )
11857
+ );
11858
+ `);
11859
+ }
11860
+ const tables = new Set([
11861
+ ...V85_OPENCODE2_RELABEL_TABLES,
11862
+ ...V85_OPTIONAL_OPENCODE2_RELABEL_TABLES
11863
+ ]);
11864
+ for (const table of tables) {
11865
+ if (!tableHasHarnessColumn(db, table))
11866
+ continue;
11867
+ db.exec(`UPDATE ${table} SET harness = 'opencode' WHERE harness = 'opencode2'`);
11868
+ }
11869
+ }
11720
11870
  function healMismatchedTierClose(db, table, hasLegacy) {
11721
11871
  if (!tableExists2(db, table))
11722
11872
  return;
@@ -13879,6 +14029,13 @@ var MIGRATIONS = [
13879
14029
  ensureColumn(db, "session_meta", "protected_tokens_effective", "INTEGER");
13880
14030
  ensureColumn(db, "session_meta", "protected_tokens_pre_snapshot", "TEXT");
13881
14031
  }
14032
+ },
14033
+ {
14034
+ version: 85,
14035
+ description: "relabel OpenCode 1.x mis-tagged opencode2 session rows",
14036
+ up(db) {
14037
+ relabelOpenCode2HarnessRows(db);
14038
+ }
13882
14039
  }
13883
14040
  ];
13884
14041
  var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
@@ -14067,15 +14224,16 @@ import { isAbsolute as isAbsolute3, join as join4 } from "node:path";
14067
14224
  var cachedResolution = null;
14068
14225
  var lastReadFailure = null;
14069
14226
  var claimedDiagnostics = new Set;
14070
- function openCodeDataDir() {
14071
- return join4(process.env.XDG_DATA_HOME ?? join4(homedir7(), ".local", "share"), "opencode");
14227
+ function openCodeDataDir(env = process.env, dataHome) {
14228
+ return join4(dataHome ?? env.XDG_DATA_HOME ?? join4(homedir7(), ".local", "share"), "opencode");
14072
14229
  }
14073
- function environmentKey(dataDir) {
14230
+ function environmentKey(dataDir, hostGeneration, channel, env) {
14074
14231
  return [
14232
+ hostGeneration,
14075
14233
  dataDir,
14076
- process.env.OPENCODE_DB ?? "",
14077
- process.env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
14078
- process.env.OPENCODE_CHANNEL ?? ""
14234
+ env.OPENCODE_DB ?? "",
14235
+ env.OPENCODE_DISABLE_CHANNEL_DB ?? "",
14236
+ channel ?? env.OPENCODE_CHANNEL ?? ""
14079
14237
  ].join("\x00");
14080
14238
  }
14081
14239
  function channelPath(dataDir, channel) {
@@ -14107,8 +14265,8 @@ function discoverOpenCodeDb(dataDir) {
14107
14265
  const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
14108
14266
  return { path: existing.path, source: "discovered", channel };
14109
14267
  }
14110
- function resolveFresh(dataDir) {
14111
- const explicit = process.env.OPENCODE_DB;
14268
+ function resolveV1Fresh(dataDir, env = process.env) {
14269
+ const explicit = env.OPENCODE_DB;
14112
14270
  if (explicit !== undefined && explicit.length > 0) {
14113
14271
  if (explicit === ":memory:") {
14114
14272
  return { path: explicit, source: "OPENCODE_DB", channel: null };
@@ -14119,24 +14277,47 @@ function resolveFresh(dataDir) {
14119
14277
  channel: null
14120
14278
  };
14121
14279
  }
14122
- const disableChannelDb = process.env.OPENCODE_DISABLE_CHANNEL_DB;
14280
+ const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
14123
14281
  if (disableChannelDb === "1" || disableChannelDb === "true") {
14124
14282
  return { path: join4(dataDir, "opencode.db"), source: "default", channel: null };
14125
14283
  }
14126
- const channel = process.env.OPENCODE_CHANNEL;
14284
+ const channel = env.OPENCODE_CHANNEL;
14127
14285
  if (channel !== undefined && channel.length > 0) {
14128
14286
  return { path: channelPath(dataDir, channel), source: "channel", channel };
14129
14287
  }
14130
14288
  return discoverOpenCodeDb(dataDir);
14131
14289
  }
14132
- function resolveOpenCodeDbPath() {
14133
- const dataDir = openCodeDataDir();
14134
- const key = environmentKey(dataDir);
14290
+ function sourceOpenCodeDatabaseFilename(hostGeneration, channel, env = process.env) {
14291
+ if (hostGeneration === "v1") {
14292
+ const explicit = env.OPENCODE_DB;
14293
+ if (explicit !== undefined && explicit.length > 0)
14294
+ return explicit;
14295
+ if (env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true") {
14296
+ return "opencode.db";
14297
+ }
14298
+ return ["latest", "beta", "prod"].includes(channel) ? "opencode.db" : `opencode-${channel}.db`;
14299
+ }
14300
+ return env.OPENCODE_DB ?? (["latest", "dev", "beta", "next", "prod"].includes(channel) || env.OPENCODE_DISABLE_CHANNEL_DB === "1" || env.OPENCODE_DISABLE_CHANNEL_DB === "true" ? "opencode.db" : `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "")}.db`);
14301
+ }
14302
+ function resolveV2Fresh(dataDir, channel, env) {
14303
+ const filename = sourceOpenCodeDatabaseFilename("v2", channel, env);
14304
+ const explicit = env.OPENCODE_DB !== undefined;
14305
+ return {
14306
+ path: filename === ":memory:" ? filename : join4(dataDir, filename),
14307
+ source: explicit ? "OPENCODE_DB" : env.OPENCODE_CHANNEL ? "channel" : "default",
14308
+ channel: explicit ? null : channel
14309
+ };
14310
+ }
14311
+ function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
14312
+ const env = options.env ?? process.env;
14313
+ const dataDir = openCodeDataDir(env, options.dataHome);
14314
+ const channel = options.channel ?? env.OPENCODE_CHANNEL;
14315
+ const key = environmentKey(dataDir, hostGeneration, channel, env);
14135
14316
  if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync5(cachedResolution.resolution.path))) {
14136
14317
  if (cachedResolution.existed)
14137
14318
  return cachedResolution.resolution;
14138
14319
  }
14139
- const resolution = resolveFresh(dataDir);
14320
+ const resolution = hostGeneration === "v2" ? resolveV2Fresh(dataDir, channel ?? "latest", env) : resolveV1Fresh(dataDir, env);
14140
14321
  cachedResolution = {
14141
14322
  key,
14142
14323
  resolution,
@@ -14144,6 +14325,29 @@ function resolveOpenCodeDbPath() {
14144
14325
  };
14145
14326
  return resolution;
14146
14327
  }
14328
+ function schemaTableNames(db, schema = "main") {
14329
+ const rows = db.prepare(`SELECT name FROM ${schema}.sqlite_master WHERE type = 'table' AND name IN ('message', 'part', 'session', 'project', 'session_message')`).all();
14330
+ return new Set(rows.flatMap((row) => typeof row.name === "string" ? [row.name] : []));
14331
+ }
14332
+ function detectOpenCodeStoreGeneration(db, schema = "main") {
14333
+ const tables = schemaTableNames(db, schema);
14334
+ const hasV1Messages = tables.has("message") && tables.has("part");
14335
+ if (hasV1Messages)
14336
+ return "v1";
14337
+ if (tables.has("session_message"))
14338
+ return "v2";
14339
+ if (tables.has("session") || tables.has("project"))
14340
+ return "v1";
14341
+ return "unknown";
14342
+ }
14343
+ function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
14344
+ const actual = detectOpenCodeStoreGeneration(db, schema);
14345
+ if (actual === expected)
14346
+ return;
14347
+ if (actual === "unknown")
14348
+ return;
14349
+ throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
14350
+ }
14147
14351
  function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
14148
14352
  return resolution.path !== ":memory:" && existsSync5(resolution.path);
14149
14353
  }
@@ -14213,6 +14417,7 @@ function runToolOwnerBackfill(db) {
14213
14417
  const escapedDbPath = opencodeDbPath.replaceAll("'", "''");
14214
14418
  db.exec(`ATTACH '${escapedDbPath}' AS oc_backfill`);
14215
14419
  try {
14420
+ assertOpenCodeStoreGeneration(db, "v1", opencodeDbPath, "oc_backfill");
14216
14421
  backfillToolOwnersInChunks(db, result);
14217
14422
  } finally {
14218
14423
  try {
@@ -14431,7 +14636,7 @@ function getSchemaFenceRejection() {
14431
14636
  function getMigrationOnOpenRefusal() {
14432
14637
  return lastMigrationOnOpenRefusal;
14433
14638
  }
14434
- var LATEST_SUPPORTED_VERSION = 84;
14639
+ var LATEST_SUPPORTED_VERSION = 85;
14435
14640
  var BOOT_SQLITE_BUSY_TIMEOUT_MS = 5000;
14436
14641
  var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
14437
14642
  var defaultStoragePermissionFs = { chmodSync: chmodSync2, mkdirSync: mkdirSync4 };
@@ -14897,7 +15102,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
14897
15102
  tag_id INTEGER,
14898
15103
  session_id TEXT,
14899
15104
  content TEXT,
14900
- created_at INTEGER,
15105
+ created_at INTEGER, -- epoch ms; Date.now() on source writes, preserved on session clones
14901
15106
  harness TEXT NOT NULL DEFAULT 'opencode',
14902
15107
  PRIMARY KEY(session_id, tag_id)
14903
15108
  );
@@ -14921,7 +15126,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
14921
15126
  p1_embedding BLOB,
14922
15127
  p1_embedding_model_id TEXT,
14923
15128
  legacy INTEGER NOT NULL DEFAULT 0,
14924
- created_at INTEGER NOT NULL,
15129
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
14925
15130
  harness TEXT NOT NULL DEFAULT 'opencode',
14926
15131
  UNIQUE(session_id, sequence)
14927
15132
  );
@@ -14940,7 +15145,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
14940
15145
  model_id TEXT NOT NULL,
14941
15146
  dims INTEGER NOT NULL,
14942
15147
  vector BLOB NOT NULL,
14943
- created_at INTEGER NOT NULL,
15148
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
14944
15149
  UNIQUE(compartment_id, model_id, window_index)
14945
15150
  );
14946
15151
  CREATE INDEX IF NOT EXISTS idx_cce_session ON compartment_chunk_embeddings(session_id);
@@ -14963,7 +15168,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
14963
15168
  kind TEXT NOT NULL,
14964
15169
  at_compartment INTEGER,
14965
15170
  fields_json TEXT NOT NULL DEFAULT '{}',
14966
- created_at INTEGER NOT NULL,
15171
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
14967
15172
  harness TEXT NOT NULL DEFAULT 'opencode'
14968
15173
  );
14969
15174
  CREATE INDEX IF NOT EXISTS idx_compartment_events_session
@@ -14992,7 +15197,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
14992
15197
  session_id TEXT NOT NULL,
14993
15198
  category TEXT NOT NULL,
14994
15199
  content TEXT NOT NULL,
14995
- created_at INTEGER NOT NULL,
15200
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
14996
15201
  updated_at INTEGER NOT NULL,
14997
15202
  harness TEXT NOT NULL DEFAULT 'opencode'
14998
15203
  );
@@ -15011,7 +15216,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
15011
15216
  source_message_time INTEGER NOT NULL,
15012
15217
  question_embedding BLOB,
15013
15218
  question_embedding_model_id TEXT,
15014
- created_at INTEGER NOT NULL,
15219
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
15015
15220
  UNIQUE(project_path, harness, session_id, source_start_message_id, source_end_message_id)
15016
15221
  );
15017
15222
  CREATE INDEX IF NOT EXISTS idx_primer_candidates_project_time
@@ -15034,7 +15239,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
15034
15239
  answer_refreshed_at INTEGER,
15035
15240
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
15036
15241
  source_candidate_provenance TEXT,
15037
- created_at INTEGER NOT NULL,
15242
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
15038
15243
  updated_at INTEGER NOT NULL
15039
15244
  );
15040
15245
  CREATE INDEX IF NOT EXISTS idx_primers_project_status_observed
@@ -15147,7 +15352,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
15147
15352
  job_id TEXT,
15148
15353
  cursor TEXT,
15149
15354
  status TEXT NOT NULL DEFAULT 'pending',
15150
- created_at INTEGER NOT NULL DEFAULT 0,
15355
+ created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
15151
15356
  updated_at INTEGER NOT NULL DEFAULT 0,
15152
15357
  UNIQUE(session_id, request_key)
15153
15358
  );
@@ -15188,7 +15393,7 @@ function initializeDatabase(db, busyTimeoutMs = BOOT_SQLITE_BUSY_TIMEOUT_MS) {
15188
15393
  shadow_epoch INTEGER NOT NULL DEFAULT 0,
15189
15394
  corpus_hash TEXT NOT NULL DEFAULT '',
15190
15395
  coverage_json TEXT NOT NULL DEFAULT '{}',
15191
- created_at INTEGER NOT NULL DEFAULT 0,
15396
+ created_at INTEGER NOT NULL DEFAULT 0, -- epoch ms (Date.now())
15192
15397
  UNIQUE(dedup_key, cohort_key)
15193
15398
  );
15194
15399
  CREATE INDEX IF NOT EXISTS idx_embedding_measurement_session
@@ -15611,7 +15816,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
15611
15816
  importance_avg REAL,
15612
15817
  discarded_last INTEGER NOT NULL DEFAULT 0,
15613
15818
  legacy INTEGER NOT NULL DEFAULT 0,
15614
- created_at INTEGER NOT NULL
15819
+ created_at INTEGER NOT NULL -- epoch ms (Date.now())
15615
15820
  );
15616
15821
  CREATE INDEX IF NOT EXISTS idx_historian_runs_session
15617
15822
  ON historian_runs(session_id, created_at DESC);
@@ -15664,7 +15869,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
15664
15869
  importance INTEGER NOT NULL DEFAULT 50,
15665
15870
  episode_type TEXT,
15666
15871
  pass_number INTEGER NOT NULL,
15667
- created_at INTEGER NOT NULL,
15872
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
15668
15873
  harness TEXT NOT NULL DEFAULT 'opencode',
15669
15874
  UNIQUE(session_id, sequence)
15670
15875
  );
@@ -15675,7 +15880,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
15675
15880
  category TEXT NOT NULL,
15676
15881
  content TEXT NOT NULL,
15677
15882
  pass_number INTEGER NOT NULL,
15678
- created_at INTEGER NOT NULL,
15883
+ created_at INTEGER NOT NULL, -- epoch ms (Date.now())
15679
15884
  harness TEXT NOT NULL DEFAULT 'opencode'
15680
15885
  );
15681
15886
 
@@ -19655,6 +19860,12 @@ function getReadOnlySessionDb() {
19655
19860
  }
19656
19861
  closeCachedReadOnlyDb();
19657
19862
  const db = new Database(dbPath, { readonly: true });
19863
+ try {
19864
+ assertOpenCodeStoreGeneration(db, "v1", dbPath);
19865
+ } catch (error) {
19866
+ closeQuietly(db);
19867
+ throw error;
19868
+ }
19658
19869
  cachedReadOnlyDb = { path: dbPath, db };
19659
19870
  clearOpenCodeDbReadFailure();
19660
19871
  return db;
@@ -21273,6 +21484,14 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21273
21484
  const totalMessageCount = getCachedAbsoluteMessageCount(sessionId) ?? messages.length;
21274
21485
  const startOrdinal = Math.max(1, offset);
21275
21486
  const completedToolArcs = buildToolArcs(messages).flatMap((arc) => arc.resOrdinal === null ? [] : [{ start: arc.invOrdinal, end: arc.resOrdinal }]);
21487
+ const completedToolComponents = [];
21488
+ for (const arc of completedToolArcs) {
21489
+ const component = completedToolComponents[completedToolComponents.length - 1];
21490
+ if (component && arc.start <= component.end)
21491
+ component.end = Math.max(component.end, arc.end);
21492
+ else
21493
+ completedToolComponents.push({ ...arc });
21494
+ }
21276
21495
  const lines = [];
21277
21496
  const lineMeta = [];
21278
21497
  const flushedToolOnlyBlocks = [];
@@ -21286,6 +21505,25 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21286
21505
  let pendingNoiseMeta = [];
21287
21506
  let commitClusters = 0;
21288
21507
  let lastFlushedRole = "";
21508
+ let admittedOversizeComponentEnd = null;
21509
+ let currentBlockApproxTokens = 0;
21510
+ let formattedBudgetCrossed = false;
21511
+ let sourceCharacters = 0;
21512
+ const toolResultBoundaries = [];
21513
+ function pinComponentWhenFormattedBudgetCrosses(ordinal, appendedText) {
21514
+ if (admittedOversizeComponentEnd !== null || formattedBudgetCrossed || !currentBlock)
21515
+ return;
21516
+ currentBlockApproxTokens += estimateTokens(appendedText) + (currentBlock.parts.length > 1 ? 1 : 0);
21517
+ if (totalTokens + currentBlockApproxTokens + 64 <= tokenBudget)
21518
+ return;
21519
+ const previewTokens = totalTokens + estimateTokens(formatBlock(currentBlock));
21520
+ if (previewTokens <= tokenBudget)
21521
+ return;
21522
+ formattedBudgetCrossed = true;
21523
+ const component = completedToolComponents.find((candidate) => candidate.start <= ordinal && candidate.end >= ordinal);
21524
+ if (component)
21525
+ admittedOversizeComponentEnd = component.end;
21526
+ }
21289
21527
  function recordFilteredNoise(meta) {
21290
21528
  pendingNoiseMeta.push(meta);
21291
21529
  if (!currentBlock) {
@@ -21312,7 +21550,23 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21312
21550
  highestScannedOrdinal = Math.max(highestScannedOrdinal, lastOrdinal);
21313
21551
  lastMessageId = currentBlock.meta[currentBlock.meta.length - 1]?.messageId ?? "";
21314
21552
  messagesProcessed += currentBlock.meta.length;
21553
+ const lineStart = sourceCharacters + (lines.length > 0 ? 1 : 0);
21554
+ const renderedParts = currentBlock.parts.join(" / ");
21555
+ let partOffset = lineStart + (blockText.length - renderedParts.length);
21556
+ for (let index = 0;index < currentBlock.parts.length; index++) {
21557
+ const part = currentBlock.parts[index] ?? "";
21558
+ const partMeta = currentBlock.partMeta[index];
21559
+ if (partMeta && partMeta.toolResultBodyTokens > 0) {
21560
+ toolResultBoundaries.push({
21561
+ ordinal: partMeta.ordinal,
21562
+ sourceOffset: partOffset,
21563
+ bodyTokens: partMeta.toolResultBodyTokens
21564
+ });
21565
+ }
21566
+ partOffset += part.length + (index + 1 < currentBlock.parts.length ? 3 : 0);
21567
+ }
21315
21568
  lines.push(blockText);
21569
+ sourceCharacters = lineStart + blockText.length;
21316
21570
  lineMeta.push(...currentBlock.meta);
21317
21571
  totalTokens += blockTokens;
21318
21572
  if (currentBlock.isToolOnly) {
@@ -21322,11 +21576,15 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21322
21576
  });
21323
21577
  }
21324
21578
  currentBlock = null;
21579
+ currentBlockApproxTokens = 0;
21325
21580
  return true;
21326
21581
  }
21327
21582
  for (const msg of messages) {
21328
21583
  if (eligibleEndOrdinal !== undefined && msg.ordinal >= eligibleEndOrdinal)
21329
21584
  break;
21585
+ if (admittedOversizeComponentEnd !== null && msg.ordinal > admittedOversizeComponentEnd) {
21586
+ break;
21587
+ }
21330
21588
  if (msg.ordinal < startOrdinal)
21331
21589
  continue;
21332
21590
  const meta = { ordinal: msg.ordinal, messageId: msg.id };
@@ -21340,6 +21598,10 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21340
21598
  if (currentBlock && currentBlock.role === "A") {
21341
21599
  currentBlock.endOrdinal = msg.ordinal;
21342
21600
  currentBlock.parts.push(tcText);
21601
+ currentBlock.partMeta.push({
21602
+ ordinal: msg.ordinal,
21603
+ toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
21604
+ });
21343
21605
  currentBlock.meta.push(...pendingNoiseMeta, meta);
21344
21606
  pendingNoiseMeta = [];
21345
21607
  } else {
@@ -21350,12 +21612,19 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21350
21612
  startOrdinal: pendingNoiseMeta[0]?.ordinal ?? msg.ordinal,
21351
21613
  endOrdinal: msg.ordinal,
21352
21614
  parts: [tcText],
21615
+ partMeta: [
21616
+ {
21617
+ ordinal: msg.ordinal,
21618
+ toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
21619
+ }
21620
+ ],
21353
21621
  meta: [...pendingNoiseMeta, meta],
21354
21622
  commitHashes: [],
21355
21623
  isToolOnly: true
21356
21624
  };
21357
21625
  pendingNoiseMeta = [];
21358
21626
  }
21627
+ pinComponentWhenFormattedBudgetCrosses(msg.ordinal, tcText);
21359
21628
  continue;
21360
21629
  }
21361
21630
  const role = compactRole(msg.role);
@@ -21372,11 +21641,16 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21372
21641
  if (currentBlock && currentBlock.role === role) {
21373
21642
  currentBlock.endOrdinal = msg.ordinal;
21374
21643
  currentBlock.parts.push(text);
21644
+ currentBlock.partMeta.push({
21645
+ ordinal: msg.ordinal,
21646
+ toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
21647
+ });
21375
21648
  currentBlock.meta.push(...pendingNoiseMeta, meta);
21376
21649
  currentBlock.commitHashes = mergeCommitHashes(currentBlock.commitHashes, compacted.commitHashes);
21377
21650
  if (msgHasNarrative)
21378
21651
  currentBlock.isToolOnly = false;
21379
21652
  pendingNoiseMeta = [];
21653
+ pinComponentWhenFormattedBudgetCrosses(msg.ordinal, text);
21380
21654
  continue;
21381
21655
  }
21382
21656
  if (!flushCurrentBlock())
@@ -21386,11 +21660,18 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21386
21660
  startOrdinal: pendingNoiseMeta[0]?.ordinal ?? msg.ordinal,
21387
21661
  endOrdinal: msg.ordinal,
21388
21662
  parts: [text],
21663
+ partMeta: [
21664
+ {
21665
+ ordinal: msg.ordinal,
21666
+ toolResultBodyTokens: extractToolResultBodyTokens(msg.parts)
21667
+ }
21668
+ ],
21389
21669
  meta: [...pendingNoiseMeta, meta],
21390
21670
  commitHashes: [...compacted.commitHashes],
21391
21671
  isToolOnly: !msgHasNarrative
21392
21672
  };
21393
21673
  pendingNoiseMeta = [];
21674
+ pinComponentWhenFormattedBudgetCrosses(msg.ordinal, text);
21394
21675
  }
21395
21676
  if (flushCurrentBlock() && pendingNoiseMeta.length > 0) {
21396
21677
  highestScannedOrdinal = Math.max(highestScannedOrdinal, pendingNoiseMeta[pendingNoiseMeta.length - 1]?.ordinal ?? highestScannedOrdinal);
@@ -21421,7 +21702,8 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
21421
21702
  ...messagesProcessed === 0 && text.length === 0 ? { filteredNoiseLines: pendingNoiseMeta } : {},
21422
21703
  commitClusterCount: commitClusters,
21423
21704
  toolOnlyRanges,
21424
- completedToolArcs
21705
+ completedToolArcs,
21706
+ toolResultBoundaries
21425
21707
  };
21426
21708
  }
21427
21709
 
@@ -21771,19 +22053,25 @@ function indexMessagesAfterOrdinal(db, sessionId, messages, _lastIndexedOrdinal,
21771
22053
  }
21772
22054
  return inserted;
21773
22055
  }
21774
- function getMessageHistoryOrphanSweepState(db) {
21775
- return db.prepare("SELECT cursor_session_id, last_swept_at FROM message_history_orphan_sweep WHERE harness = 'opencode'").get() ?? {};
22056
+ function openCodeSweepHarness() {
22057
+ const harness = getHarness();
22058
+ if (harness === "opencode" || harness === "opencode2")
22059
+ return harness;
22060
+ throw new Error(`OpenCode orphan sweep cannot read a ${harness} host store`);
22061
+ }
22062
+ function getMessageHistoryOrphanSweepState(db, harness) {
22063
+ return db.prepare("SELECT cursor_session_id, last_swept_at FROM message_history_orphan_sweep WHERE harness = ?").get(harness) ?? {};
21776
22064
  }
21777
- function persistMessageHistoryOrphanSweepState(db, cursor, lastSweptAt) {
22065
+ function persistMessageHistoryOrphanSweepState(db, cursor, lastSweptAt, harness) {
21778
22066
  db.prepare(`INSERT INTO message_history_orphan_sweep (harness, cursor_session_id, last_swept_at)
21779
- VALUES ('opencode', ?, ?)
22067
+ VALUES (?, ?, ?)
21780
22068
  ON CONFLICT(harness) DO UPDATE SET
21781
22069
  cursor_session_id = excluded.cursor_session_id,
21782
- last_swept_at = excluded.last_swept_at`).run(cursor, lastSweptAt);
22070
+ last_swept_at = excluded.last_swept_at`).run(harness, cursor, lastSweptAt);
21783
22071
  }
21784
- function getOpenCodeSessionScopedCandidateSourceSql() {
22072
+ function getOpenCodeSessionScopedCandidateSourceSql(harness) {
21785
22073
  return SESSION_SCOPED_TABLES.filter((definition) => definition.harnessScoped === true).map((definition) => {
21786
- const predicates = ["session_id IS NOT NULL", "harness = 'opencode'"];
22074
+ const predicates = ["session_id IS NOT NULL", `harness = '${harness}'`];
21787
22075
  if (definition.extraPredicate)
21788
22076
  predicates.push(definition.extraPredicate);
21789
22077
  return `SELECT session_id FROM ${definition.table} WHERE ${predicates.join(" AND ")}`;
@@ -21797,7 +22085,8 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
21797
22085
  const safetyAgeMs = Math.max(0, options.safetyAgeMs ?? MESSAGE_HISTORY_ORPHAN_SAFETY_AGE_MS);
21798
22086
  const cooldownMs = Math.max(0, options.cooldownMs ?? MESSAGE_HISTORY_ORPHAN_SWEEP_COOLDOWN_MS);
21799
22087
  const unavailableReprobeMs = Math.max(cooldownMs, options.unavailableReprobeMs ?? MESSAGE_HISTORY_ORPHAN_UNAVAILABLE_REPROBE_MS);
21800
- const state = getMessageHistoryOrphanSweepState(db);
22088
+ const harness = openCodeSweepHarness();
22089
+ const state = getMessageHistoryOrphanSweepState(db, harness);
21801
22090
  const cursor = typeof state.cursor_session_id === "string" ? state.cursor_session_id : "";
21802
22091
  if (typeof state.last_swept_at === "number" && state.last_swept_at + cooldownMs > now) {
21803
22092
  return { status: "cooldown", scanned: 0, deleted: 0, cursor };
@@ -21809,12 +22098,12 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
21809
22098
  openCodeDb = null;
21810
22099
  }
21811
22100
  if (!openCodeDb) {
21812
- persistMessageHistoryOrphanSweepState(db, cursor, now + unavailableReprobeMs - cooldownMs);
22101
+ persistMessageHistoryOrphanSweepState(db, cursor, now + unavailableReprobeMs - cooldownMs, harness);
21813
22102
  return { status: "source_unavailable", scanned: 0, deleted: 0, cursor };
21814
22103
  }
21815
22104
  try {
21816
22105
  const cutoff = now - safetyAgeMs;
21817
- const candidateSourceSql = getOpenCodeSessionScopedCandidateSourceSql();
22106
+ const candidateSourceSql = getOpenCodeSessionScopedCandidateSourceSql(harness);
21818
22107
  const candidates = db.prepare(`SELECT session_id
21819
22108
  FROM (${candidateSourceSql}) AS session_candidates
21820
22109
  WHERE session_id > ?
@@ -21822,7 +22111,7 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
21822
22111
  SELECT 1
21823
22112
  FROM message_history_index
21824
22113
  WHERE message_history_index.session_id = session_candidates.session_id
21825
- AND message_history_index.harness = 'opencode'
22114
+ AND message_history_index.harness = '${harness}'
21826
22115
  AND message_history_index.updated_at > ?
21827
22116
  )
21828
22117
  ORDER BY session_id ASC
@@ -21843,13 +22132,13 @@ function sweepOrphanedOpenCodeMessageIndexes(db, openReadableOpenCodeDb, options
21843
22132
  SELECT 1
21844
22133
  FROM message_history_index
21845
22134
  WHERE message_history_index.session_id = session_candidates.session_id
21846
- AND message_history_index.harness = 'opencode'
22135
+ AND message_history_index.harness = '${harness}'
21847
22136
  AND message_history_index.updated_at > ?
21848
22137
  )
21849
22138
  LIMIT 1`);
21850
22139
  const eligibleSessionIds = missingSessionIds.filter((sessionId) => stillEligible.get(sessionId, cutoff));
21851
- deleted = deleteSessionScopedRows(db, eligibleSessionIds, "opencode");
21852
- persistMessageHistoryOrphanSweepState(db, nextCursor, completedAt);
22140
+ deleted = deleteSessionScopedRows(db, eligibleSessionIds, harness);
22141
+ persistMessageHistoryOrphanSweepState(db, nextCursor, completedAt, harness);
21853
22142
  db.exec("COMMIT");
21854
22143
  committed = true;
21855
22144
  logSlowWriteTransaction("message_index_orphan_sweep", transactionStartedAt);
@@ -23888,9 +24177,9 @@ import { existsSync as existsSync9, readFileSync as readFileSync9, statSync as s
23888
24177
  import { dirname as dirname5, isAbsolute as isAbsolute4, resolve as resolve4 } from "node:path";
23889
24178
 
23890
24179
  // ../plugin/src/tools/light-descriptions.ts
23891
- 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.`;
24180
+ var CTX_REDUCE_LIGHT_DESCRIPTION = `Marking QUEUES content for release. It stays fully visible to you until it is actually released, which may be the next turn or many turns later. Newest tags stay protected until they age out. Release leaves a placeholder; recover only by rerunning the source or recovery tool. Mark only finished material. Mark analyzed, redundant, saved, or confirmatory outputs; keep user messages, unresolved errors, unextracted evidence, and exact wording. NEVER blanket-mark a large range: review every tag first.`;
23892
24181
  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.`;
23893
- var CTX_NOTE_LIGHT_DESCRIPTION = `For ctx_note: write saves, read lists, update changes, dismiss retires one note_id or 1–50 note_ids (choose one); surface_condition makes a smart note. Smart-note conditions must be externally verifiable via GitHub, disk, git, or web—not this conversation or future actions.`;
24182
+ var CTX_NOTE_LIGHT_DESCRIPTION = `For ctx_note: write saves, read lists, update changes one note (note_ids=[N]), dismiss retires 1–50 (note_ids); surface_condition makes a smart note. Smart-note conditions must be externally verifiable via GitHub, disk, git, or web—not this conversation or future actions.`;
23894
24183
  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.`;
23895
24184
  var CTX_SEARCH_LIGHT_DESCRIPTION = `For ctx_search users, retrieve only hidden recall: memories not in <project-memory>, compacted messages outside the live tail, commits, and notes; phrase query as a question carrying exact terms. Omit sources for broad search; select memory, message, git_commit, or note, or pass memory IDs directly. Hits expand through ctx_expand.`;
23896
24185
 
@@ -24157,8 +24446,8 @@ function createPromptSurfaceRuntime(options) {
24157
24446
  return content;
24158
24447
  };
24159
24448
  return {
24160
- resolveRegistration(config) {
24161
- const { preset } = resolvePromptSurface(config, undefined);
24449
+ resolveRegistration(config, modelKey) {
24450
+ const { preset } = resolvePromptSurface(config, modelKey);
24162
24451
  const overrides = config?.tool_descriptions ?? {};
24163
24452
  for (const [toolId, description] of Object.entries(overrides)) {
24164
24453
  if (!PROMPT_SURFACE_TOOL_ID_SET.has(toolId)) {
@@ -25762,6 +26051,11 @@ function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
25762
26051
  }
25763
26052
  delete patched[key];
25764
26053
  const defaultValue = defaults[key];
26054
+ const invalidRawValue = rawConfig[key];
26055
+ if (key === "protected_tokens" && typeof invalidRawValue === "number" && invalidRawValue < PROTECTED_TOKENS_MIN) {
26056
+ warnings.push(`protected_tokens is a token floor (minimum ${PROTECTED_TOKENS_MIN}, default derived from the context window); ${invalidRawValue} looks like the old protected_tags count. Remove the key to use the default, or set a token count such as 16000.`);
26057
+ continue;
26058
+ }
25765
26059
  warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultValue)}.`);
25766
26060
  }
25767
26061
  const retryParsed = MagicContextConfigSchema.safeParse(patched);
@@ -27558,6 +27852,27 @@ var embeddingRowMetadata = new WeakMap;
27558
27852
  function isSynapseEmbeddingTruncated(vector) {
27559
27853
  return embeddingRowMetadata.get(vector)?.truncated === true;
27560
27854
  }
27855
+ function toSynapseLaneDescriptor(metadata) {
27856
+ const tokenBudget = metadata.recommended_token_budget;
27857
+ return {
27858
+ lane: metadata.model,
27859
+ ...metadata.device_class ? { device_class: metadata.device_class } : {},
27860
+ max_tokens: metadata.max_tokens,
27861
+ max_tokens_source: metadata.max_tokens_source,
27862
+ ...metadata.bucket_ladder ? { bucket_ladder: [...metadata.bucket_ladder] } : {},
27863
+ ...metadata.dims ? { dims: metadata.dims } : {},
27864
+ ...metadata.dtype ? { dtype: metadata.dtype } : {},
27865
+ ...typeof metadata.certified === "boolean" ? { certified: metadata.certified } : {},
27866
+ ...metadata.warm_load_cost_hint_ms !== undefined ? { warm_load_cost_hint_ms: metadata.warm_load_cost_hint_ms } : {},
27867
+ ...metadata.recommended_batch ? {
27868
+ recommended_batch: {
27869
+ rows: metadata.recommended_batch,
27870
+ ...tokenBudget !== undefined ? { token_budget: tokenBudget } : {}
27871
+ }
27872
+ } : {},
27873
+ warm: metadata.max_tokens_source === "runtime_bucket" || metadata.max_tokens_source === "worker_bucket"
27874
+ };
27875
+ }
27561
27876
  function formatSynapseLaneDescriptor(descriptor) {
27562
27877
  const certified = descriptor.certified === undefined ? "unknown" : String(descriptor.certified);
27563
27878
  return `lane=${descriptor.lane}; device_class=${descriptor.device_class ?? "unknown"}; ` + `max_tokens=${descriptor.max_tokens} (${descriptor.max_tokens_source}); ` + `certified=${certified}; warm=${descriptor.warm ? "yes" : "no"}; ` + `warm_load_cost_hint_ms=${descriptor.warm_load_cost_hint_ms ?? "unknown"}`;
@@ -29308,16 +29623,27 @@ function startLockHeartbeat(lockPath) {
29308
29623
  timer.unref?.();
29309
29624
  return () => clearInterval(timer);
29310
29625
  }
29626
+ var ONNX_RUNTIME_WEB_SPECIFIER = "onnxruntime-web";
29311
29627
  var localEmbeddingRuntimeMode = "native";
29312
29628
  var localEmbeddingProcessFailure = null;
29313
29629
  var wasmRuntimeInjected = false;
29314
29630
  var localEmbeddingHostForRuntime = currentLocalEmbeddingHost;
29631
+ var resolveWasmOrtForRuntime = () => {
29632
+ try {
29633
+ return typeof import.meta.resolve === "function" ? import.meta.resolve(ONNX_RUNTIME_WEB_SPECIFIER) : undefined;
29634
+ } catch {
29635
+ return;
29636
+ }
29637
+ };
29638
+ var importWasmOrtModule = async (specifier) => await import(specifier);
29639
+ var importWasmOrtModuleForRuntime = importWasmOrtModule;
29315
29640
  var importWasmOrtForRuntime = async () => {
29316
29641
  const { createRequire: createRequireFn } = await import("node:module");
29317
29642
  const requireFn = createRequireFn(import.meta.url);
29318
- const ortEntry = requireFn.resolve("onnxruntime-web");
29643
+ const ortEntry = requireFn.resolve(ONNX_RUNTIME_WEB_SPECIFIER);
29644
+ const ortSpecifier = resolveWasmOrtForRuntime() ?? ONNX_RUNTIME_WEB_SPECIFIER;
29319
29645
  return {
29320
- module: await import("onnxruntime-web"),
29646
+ module: await importWasmOrtModuleForRuntime(ortSpecifier),
29321
29647
  entryPath: ortEntry
29322
29648
  };
29323
29649
  };
@@ -29351,6 +29677,7 @@ async function injectWasmOrt() {
29351
29677
  try {
29352
29678
  const { module: ortWeb, entryPath } = await importWasmOrtForRuntime();
29353
29679
  if (ortWeb.env?.wasm) {
29680
+ ortWeb.env.wasm.numThreads = 1;
29354
29681
  ortWeb.env.wasm.wasmPaths = `${pathToFileURL2(dirname8(entryPath)).href}/`;
29355
29682
  }
29356
29683
  globalThis[Symbol.for("onnxruntime")] = ortWeb;
@@ -30862,6 +31189,13 @@ function updatePersistedShadowBackfillState(db, projectIdentity, scope, modelId,
30862
31189
  SET provenance_json = ?
30863
31190
  WHERE project_path = ? AND scope = ? AND model_id = ?`).run(JSON.stringify(provenance), projectIdentity, scope, modelId);
30864
31191
  }
31192
+ function shadowDescriptorProvenanceJson(db, projectIdentity, scope, modelId, synapseProvenance) {
31193
+ const provenance = typeof synapseProvenance === "object" && synapseProvenance !== null && !Array.isArray(synapseProvenance) ? { ...synapseProvenance } : synapseProvenance === undefined ? {} : { synapse_provenance: synapseProvenance };
31194
+ const existing = getPersistedShadowBackfillState(db, projectIdentity, scope, modelId);
31195
+ if (existing)
31196
+ provenance[SHADOW_BACKFILL_PROVENANCE_KEY2] = existing;
31197
+ return JSON.stringify(provenance);
31198
+ }
30865
31199
  function persistPrimaryDescriptor(db, registration) {
30866
31200
  const descriptorTable = db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'embedding_registrations'").get();
30867
31201
  if (!descriptorTable)
@@ -30881,6 +31215,43 @@ function persistPrimaryDescriptor(db, registration) {
30881
31215
  generation = excluded.generation,
30882
31216
  updated_at = excluded.updated_at`).run(registration.projectIdentity, registration.providerIdentity, registration.modelId, registration.chunkModelId, fields.fingerprint ?? "", fields.tableEpoch ?? 0, fields.dims ?? 0, JSON.stringify(fields.provenance ?? {}), registration.generation, Date.now());
30883
31217
  }
31218
+ function persistShadowDescriptor(db, registration) {
31219
+ const descriptorTable = db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'shadow_embedding_registrations'").get();
31220
+ if (!descriptorTable)
31221
+ return;
31222
+ const fields = synapseConfigFields(registration.config);
31223
+ const now = Date.now();
31224
+ db.prepare(`INSERT INTO shadow_embedding_registrations
31225
+ (project_path, scope, model_id, generation, fingerprint, table_epoch, dims, provenance_json, updated_at)
31226
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
31227
+ ON CONFLICT(project_path, scope, model_id) DO UPDATE SET
31228
+ generation = excluded.generation,
31229
+ fingerprint = excluded.fingerprint,
31230
+ table_epoch = excluded.table_epoch,
31231
+ dims = excluded.dims,
31232
+ provenance_json = excluded.provenance_json,
31233
+ updated_at = excluded.updated_at`).run(registration.projectIdentity, "memory", registration.modelId, registration.generation, fields.fingerprint ?? "", fields.tableEpoch ?? 0, fields.dims ?? 0, shadowDescriptorProvenanceJson(db, registration.projectIdentity, "memory", registration.modelId, fields.provenance), now);
31234
+ db.prepare(`INSERT INTO shadow_embedding_registrations
31235
+ (project_path, scope, model_id, generation, fingerprint, table_epoch, dims, provenance_json, updated_at)
31236
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
31237
+ ON CONFLICT(project_path, scope, model_id) DO UPDATE SET
31238
+ generation = excluded.generation,
31239
+ fingerprint = excluded.fingerprint,
31240
+ table_epoch = excluded.table_epoch,
31241
+ dims = excluded.dims,
31242
+ provenance_json = excluded.provenance_json,
31243
+ updated_at = excluded.updated_at`).run(registration.projectIdentity, "commit", registration.modelId, registration.generation, fields.fingerprint ?? "", fields.tableEpoch ?? 0, fields.dims ?? 0, shadowDescriptorProvenanceJson(db, registration.projectIdentity, "commit", registration.modelId, fields.provenance), now);
31244
+ db.prepare(`INSERT INTO shadow_embedding_registrations
31245
+ (project_path, scope, model_id, generation, fingerprint, table_epoch, dims, provenance_json, updated_at)
31246
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
31247
+ ON CONFLICT(project_path, scope, model_id) DO UPDATE SET
31248
+ generation = excluded.generation,
31249
+ fingerprint = excluded.fingerprint,
31250
+ table_epoch = excluded.table_epoch,
31251
+ dims = excluded.dims,
31252
+ provenance_json = excluded.provenance_json,
31253
+ updated_at = excluded.updated_at`).run(registration.projectIdentity, "chunk", registration.chunkModelId, registration.generation, fields.fingerprint ?? "", fields.tableEpoch ?? 0, fields.dims ?? 0, shadowDescriptorProvenanceJson(db, registration.projectIdentity, "chunk", registration.chunkModelId, fields.provenance), now);
31254
+ }
30884
31255
  function resolveEmbeddingConfig(config) {
30885
31256
  if (!config || config.provider === "local") {
30886
31257
  return {
@@ -31304,6 +31675,91 @@ function registerProjectEmbedding(db, projectIdentity, config, features, sourceD
31304
31675
  }
31305
31676
  return snapshotFor(registration);
31306
31677
  }
31678
+ function registerProjectShadowEmbedding(db, projectIdentity, config, sourceDirectory, options = {}) {
31679
+ const resolvedConfig = resolveEmbeddingConfig(config);
31680
+ if (resolvedConfig.provider !== "synapse") {
31681
+ throw new Error("Shadow embedding registration requires the synapse provider");
31682
+ }
31683
+ const providerIdentity = getEmbeddingProviderIdentity(resolvedConfig);
31684
+ const chunkModelId = getChunkEmbeddingModelId(resolvedConfig, providerIdentity);
31685
+ const provider = createProvider(resolvedConfig, {
31686
+ projectRoot: sourceDirectory,
31687
+ session: `shadow:${projectIdentity}`
31688
+ });
31689
+ if (!provider)
31690
+ return null;
31691
+ const prior = shadowRegistrations.get(projectIdentity);
31692
+ if (prior && prior.providerIdentity === providerIdentity) {
31693
+ provider.dispose();
31694
+ dbForShadowQueue.set(projectIdentity, db);
31695
+ persistShadowDescriptor(db, prior);
31696
+ const backfillAlreadyArmed = hasPendingShadowBackfill(projectIdentity) || shadowQueue.some((item) => item.projectIdentity === projectIdentity);
31697
+ if (!backfillAlreadyArmed || options.manualBackfill === true) {
31698
+ maybeArmShadowBackfill(db, projectIdentity, prior, options.manualBackfill === true);
31699
+ }
31700
+ return {
31701
+ ...snapshotFor({
31702
+ projectIdentity,
31703
+ sourceDirectory,
31704
+ config: prior.config,
31705
+ providerIdentity: prior.providerIdentity,
31706
+ runtimeFingerprint: `shadow:${prior.providerIdentity}`,
31707
+ provider: prior.provider,
31708
+ generation: prior.generation,
31709
+ features: { memoryEnabled: true, gitCommitEnabled: true },
31710
+ modelId: prior.modelId,
31711
+ chunkModelId: prior.chunkModelId,
31712
+ observationMode: false
31713
+ }),
31714
+ provider: "synapse"
31715
+ };
31716
+ }
31717
+ const generation = ++globalRegistrationGeneration;
31718
+ const registration = {
31719
+ projectIdentity,
31720
+ sourceDirectory,
31721
+ config: resolvedConfig,
31722
+ provider,
31723
+ providerIdentity,
31724
+ modelId: providerIdentity,
31725
+ chunkModelId,
31726
+ generation
31727
+ };
31728
+ shadowRegistrations.set(projectIdentity, registration);
31729
+ dbForShadowQueue.set(projectIdentity, db);
31730
+ if (prior) {
31731
+ disposeProvider(prior.provider);
31732
+ for (const scope of ["memory", "commit", "chunk"]) {
31733
+ const scopeKey = `${projectIdentity}:${scope}`;
31734
+ shadowBackfillLastIds.delete(scopeKey);
31735
+ shadowBackfillStopReasons.delete(scopeKey);
31736
+ shadowBackfillLastWriteOutcomes.delete(scopeKey);
31737
+ }
31738
+ }
31739
+ db.transaction(() => {
31740
+ const now = Date.now();
31741
+ recordScopeActiveIdentity(db, projectIdentity, "memory", registration.modelId, now);
31742
+ recordScopeActiveIdentity(db, projectIdentity, "commit", registration.modelId, now);
31743
+ recordScopeActiveIdentity(db, projectIdentity, "chunk", registration.chunkModelId, now);
31744
+ persistShadowDescriptor(db, registration);
31745
+ })();
31746
+ maybeArmShadowBackfill(db, projectIdentity, registration, options.manualBackfill === true);
31747
+ return {
31748
+ projectIdentity,
31749
+ sourceDirectory,
31750
+ providerIdentity,
31751
+ runtimeFingerprint: `shadow:${providerIdentity}`,
31752
+ generation,
31753
+ features: { memoryEnabled: true, gitCommitEnabled: true },
31754
+ enabled: true,
31755
+ gitCommitEnabled: true,
31756
+ modelId: registration.modelId,
31757
+ chunkModelId: registration.chunkModelId,
31758
+ model: "model" in resolvedConfig && typeof resolvedConfig.model === "string" ? resolvedConfig.model : registration.modelId,
31759
+ provider: "synapse",
31760
+ ...synapseDescriptorFromConfig(resolvedConfig) ? { synapseDescriptor: synapseDescriptorFromConfig(resolvedConfig) } : {}
31761
+ };
31762
+ }
31307
31763
  function startShadowWorker() {
31308
31764
  if (shadowWorker)
31309
31765
  return;
@@ -31491,6 +31947,56 @@ function pumpShadowBackfill() {
31491
31947
  pendingShadowBackfills.delete(projectIdentity);
31492
31948
  }
31493
31949
  }
31950
+ function maybeArmShadowBackfill(db, projectIdentity, shadow, manualBackfill = false) {
31951
+ if (untrustedLoadProjects.has(projectIdentity))
31952
+ return;
31953
+ const primary = projectRegistrations.get(projectIdentity);
31954
+ if (!primary)
31955
+ return;
31956
+ const pending = new Set;
31957
+ for (const scope of ["memory", "commit", "chunk"]) {
31958
+ const primaryModelId = shadowModelIdForScope(primary, scope);
31959
+ const shadowModelId = shadowModelIdForScope(shadow, scope);
31960
+ const stallKey = `${projectIdentity}:${scope}`;
31961
+ if (primaryModelId === "off" || shadowModelId === "off")
31962
+ continue;
31963
+ const batch = shadowBackfillCandidateBatch(db, projectIdentity, scope, primaryModelId, shadow, SHADOW_MAX_ITEMS_PER_TICK);
31964
+ const persisted = getPersistedShadowBackfillState(db, projectIdentity, scope, shadowModelId);
31965
+ if (batch.ids.length === 0) {
31966
+ if (persisted?.stopReason === "stalled_no_progress") {
31967
+ shadowBackfillStopReasons.set(stallKey, "drained");
31968
+ updatePersistedShadowBackfillState(db, projectIdentity, scope, shadowModelId, (state) => ({
31969
+ ...state,
31970
+ stopReason: "drained",
31971
+ candidateSignature: undefined,
31972
+ writeRefusalReason: undefined,
31973
+ stoppedAt: shadowBackfillNow()
31974
+ }));
31975
+ }
31976
+ continue;
31977
+ }
31978
+ if (!manualBackfill && persisted?.stopReason === "stalled_no_progress" && persisted.candidateSignature === batch.signature) {
31979
+ shadowBackfillStopReasons.set(stallKey, "stalled_no_progress");
31980
+ continue;
31981
+ }
31982
+ shadowBackfillStopReasons.delete(stallKey);
31983
+ shadowBackfillLastIds.delete(stallKey);
31984
+ shadowBackfillLastWriteOutcomes.delete(stallKey);
31985
+ updatePersistedShadowBackfillState(db, projectIdentity, scope, shadowModelId, (state) => ({
31986
+ ...state,
31987
+ stopReason: undefined,
31988
+ candidateSignature: undefined,
31989
+ writeRefusalReason: undefined,
31990
+ stoppedAt: undefined
31991
+ }));
31992
+ pending.add(scope);
31993
+ }
31994
+ if (pending.size === 0)
31995
+ return;
31996
+ pendingShadowBackfills.set(projectIdentity, pending);
31997
+ pumpShadowBackfill();
31998
+ startShadowWorker();
31999
+ }
31494
32000
  async function embedShadowItems(registration, items, db, scope) {
31495
32001
  const raw = registration.config;
31496
32002
  const fingerprint = typeof raw.synapse_fingerprint === "string" ? raw.synapse_fingerprint : "";
@@ -31748,6 +32254,26 @@ function registerProjectInObservationMode(db, projectIdentity, sourceDirectory,
31748
32254
  disposeProvider(prior?.provider ?? null);
31749
32255
  return snapshotFor(registration);
31750
32256
  }
32257
+ function unregisterProjectShadowEmbedding(projectIdentity) {
32258
+ const shadow = shadowRegistrations.get(projectIdentity);
32259
+ shadowRegistrations.delete(projectIdentity);
32260
+ dbForShadowQueue.delete(projectIdentity);
32261
+ pendingShadowBackfills.delete(projectIdentity);
32262
+ for (let index = shadowQueue.length - 1;index >= 0; index -= 1) {
32263
+ if (shadowQueue[index].projectIdentity === projectIdentity)
32264
+ shadowQueue.splice(index, 1);
32265
+ }
32266
+ for (const scope of ["memory", "commit", "chunk"]) {
32267
+ const key = `${projectIdentity}:${scope}`;
32268
+ shadowBackfillLastIds.delete(key);
32269
+ shadowBackfillStopReasons.delete(key);
32270
+ shadowBackfillLastWriteOutcomes.delete(key);
32271
+ }
32272
+ const primaryProvider = projectRegistrations.get(projectIdentity)?.provider ?? null;
32273
+ if (shadow?.provider && shadow.provider !== primaryProvider) {
32274
+ disposeProvider(shadow.provider);
32275
+ }
32276
+ }
31751
32277
  function getProjectEmbeddingSnapshot(projectIdentity) {
31752
32278
  const registration = projectRegistrations.get(projectIdentity);
31753
32279
  return registration ? snapshotFor(registration) : null;
@@ -32435,6 +32961,133 @@ function handleUntrustedLoad(db, projectIdentity, directory, detailed) {
32435
32961
  return true;
32436
32962
  }
32437
32963
 
32964
+ // ../plugin/src/plugin/embedding-routing.ts
32965
+ var SYNAPSE_PROBE_TTL_MS = 60000;
32966
+ var synapseProbeCache = new Map;
32967
+ function fallbackConfig(config, provider) {
32968
+ const raw = config;
32969
+ const model = typeof raw.model === "string" ? raw.model.trim() : "";
32970
+ const endpoint = typeof raw.endpoint === "string" ? raw.endpoint.trim() : "";
32971
+ const apiKey = typeof raw.api_key === "string" ? raw.api_key.trim() : "";
32972
+ const inputType = typeof raw.input_type === "string" ? raw.input_type.trim() : "";
32973
+ const queryInputType = typeof raw.query_input_type === "string" ? raw.query_input_type.trim() : "";
32974
+ const queryInstruction = typeof raw.query_instruction === "string" || raw.query_instruction === false ? raw.query_instruction : undefined;
32975
+ const documentPrefix = typeof raw.document_prefix === "string" ? raw.document_prefix : undefined;
32976
+ const truncate = typeof raw.truncate === "string" ? raw.truncate.trim() : "";
32977
+ const maxInputTokens = typeof raw.max_input_tokens === "number" ? raw.max_input_tokens : undefined;
32978
+ if (provider === "off")
32979
+ return { provider: "off" };
32980
+ if (provider === "openai-compatible") {
32981
+ return {
32982
+ provider: "openai-compatible",
32983
+ model,
32984
+ endpoint,
32985
+ ...apiKey ? { api_key: apiKey } : {},
32986
+ ...inputType ? { input_type: inputType } : {},
32987
+ ...queryInputType ? { query_input_type: queryInputType } : {},
32988
+ ...queryInstruction !== undefined ? { query_instruction: queryInstruction } : {},
32989
+ ...documentPrefix !== undefined ? { document_prefix: documentPrefix } : {},
32990
+ ...truncate ? { truncate } : {},
32991
+ ...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
32992
+ };
32993
+ }
32994
+ return {
32995
+ provider: "local",
32996
+ model: model || DEFAULT_LOCAL_EMBEDDING_MODEL,
32997
+ local_runtime: raw.local_runtime === "native" || raw.local_runtime === "wasm" ? raw.local_runtime : "auto",
32998
+ ...maxInputTokens !== undefined ? { max_input_tokens: maxInputTokens } : {}
32999
+ };
33000
+ }
33001
+ function synapseOptions(config, subc, projectRoot, session, metadata) {
33002
+ return {
33003
+ connectionFile: subc.connection_file,
33004
+ projectRoot,
33005
+ session,
33006
+ model: metadata?.model ?? (config.provider === "synapse" && "model" in config ? config.model : undefined) ?? SYNAPSE_DEFAULT_MODEL,
33007
+ ...metadata ? {
33008
+ metadata
33009
+ } : {}
33010
+ };
33011
+ }
33012
+ function probeKey(subc, config) {
33013
+ const model = config.provider === "synapse" && "model" in config ? config.model : SYNAPSE_DEFAULT_MODEL;
33014
+ return `${subc.connection_file}\x00${model ?? SYNAPSE_DEFAULT_MODEL}`;
33015
+ }
33016
+ function discoverSynapseLane(config, subc, projectRoot, session) {
33017
+ const key = probeKey(subc, config);
33018
+ const cached = synapseProbeCache.get(key);
33019
+ if (cached && cached.expiresAt > Date.now())
33020
+ return cached.promise;
33021
+ const promise = SynapseEmbeddingProvider.discover(synapseOptions(config, subc, projectRoot, session));
33022
+ synapseProbeCache.set(key, { expiresAt: Date.now() + SYNAPSE_PROBE_TTL_MS, promise });
33023
+ promise.catch(() => {
33024
+ return;
33025
+ });
33026
+ return promise;
33027
+ }
33028
+ function resolvedSynapseConfig(subc, metadata, projectRoot, session) {
33029
+ return {
33030
+ provider: "synapse",
33031
+ model: metadata.model,
33032
+ max_input_tokens: metadata.max_tokens,
33033
+ synapse_connection_file: subc.connection_file,
33034
+ synapse_fingerprint: metadata.fingerprint,
33035
+ synapse_table_epoch: metadata.table_epoch,
33036
+ ...typeof metadata.dims === "number" ? { synapse_dims: metadata.dims } : {},
33037
+ ...metadata.recommended_batch ? { synapse_recommended_batch: metadata.recommended_batch } : {},
33038
+ ...metadata.recommended_token_budget ? { synapse_recommended_token_budget: metadata.recommended_token_budget } : {},
33039
+ synapse_descriptor: toSynapseLaneDescriptor(metadata),
33040
+ ...metadata.provenance !== undefined ? { synapse_provenance: metadata.provenance } : {}
33041
+ };
33042
+ }
33043
+ async function resolveEmbeddingRouting(args) {
33044
+ const config = args.config.embedding;
33045
+ const subc = args.config.subc;
33046
+ const shadowEnabled = args.config.shadow_embedding?.enabled === true;
33047
+ const warnings = [];
33048
+ if (config.provider !== "synapse") {
33049
+ let shadow = null;
33050
+ if (shadowEnabled && config.provider === "off") {
33051
+ warnings.push("shadow_embedding is ignored when embedding.provider is off");
33052
+ } else if (shadowEnabled && !subc) {
33053
+ warnings.push("shadow_embedding requires a subc block; shadow lane is disabled");
33054
+ } else if (shadowEnabled && subc) {
33055
+ try {
33056
+ const metadata = await discoverSynapseLane(config, subc, args.projectRoot, args.session ?? "routing");
33057
+ shadow = resolvedSynapseConfig(subc, metadata, args.projectRoot, args.session ?? "routing");
33058
+ } catch (error) {
33059
+ warnings.push(`shadow_embedding is unavailable; using the primary ${config.provider} lane: ${error instanceof Error ? error.message : String(error)}`);
33060
+ }
33061
+ }
33062
+ return { primary: config, shadow, warnings };
33063
+ }
33064
+ if (shadowEnabled) {
33065
+ warnings.push("shadow_embedding is ignored when the primary provider is synapse");
33066
+ }
33067
+ const fallbackProvider = config.fallback_provider;
33068
+ const fallback = fallbackConfig(config, fallbackProvider);
33069
+ if (!subc) {
33070
+ warnings.push("embedding.provider synapse requires a subc block; using fallback provider");
33071
+ return { primary: fallback, shadow: null, warnings };
33072
+ }
33073
+ if (!fallbackProvider) {
33074
+ warnings.push("embedding.provider synapse requires embedding.fallback_provider; using local fallback");
33075
+ return { primary: fallbackConfig(config, "local"), shadow: null, warnings };
33076
+ }
33077
+ try {
33078
+ const metadata = await discoverSynapseLane(config, subc, args.projectRoot, args.session ?? "routing");
33079
+ return {
33080
+ primary: resolvedSynapseConfig(subc, metadata, args.projectRoot, args.session ?? "routing"),
33081
+ shadow: null,
33082
+ warnings
33083
+ };
33084
+ } catch (error) {
33085
+ warnings.push(`Synapse is not ready; using embedding.fallback_provider=${fallbackProvider}: ${error instanceof Error ? error.message : String(error)}`);
33086
+ log(`[magic-context] Synapse routing fell back: ${warnings.at(-1)}`);
33087
+ return { primary: fallback, shadow: null, warnings };
33088
+ }
33089
+ }
33090
+
32438
33091
  // src/embedding-bootstrap.ts
32439
33092
  var registrationFingerprintsByDatabase = new WeakMap;
32440
33093
  function configCandidatePaths(directory, loadedPaths) {
@@ -32475,16 +33128,36 @@ async function ensureProjectRegisteredFromPiDirectory(directory, db) {
32475
33128
  handleUntrustedLoad(db, projectIdentity, directory, detailed);
32476
33129
  return;
32477
33130
  }
33131
+ const routing = await resolveEmbeddingRouting({
33132
+ config: detailed.config,
33133
+ projectRoot: directory,
33134
+ session: `bootstrap:${projectIdentity}`
33135
+ });
33136
+ for (const warning of routing.warnings) {
33137
+ log(`[magic-context] ${warning}`);
33138
+ }
32478
33139
  const features = {
32479
33140
  memoryEnabled: detailed.config.memory.enabled,
32480
33141
  gitCommitEnabled: detailed.config.memory.git_commit_indexing.enabled
32481
33142
  };
32482
- registerProjectEmbedding(db, projectIdentity, detailed.config.embedding, features, directory);
32483
- const fingerprintPaths = configCandidatePaths(directory, detailed.loadedFromPaths);
32484
- registrationFingerprints.set(projectIdentity, {
32485
- paths: fingerprintPaths,
32486
- fingerprint: configFingerprint(fingerprintPaths)
32487
- });
33143
+ registerProjectEmbedding(db, projectIdentity, routing.primary, features, directory);
33144
+ if (routing.shadow) {
33145
+ registerProjectShadowEmbedding(db, projectIdentity, routing.shadow, directory);
33146
+ } else {
33147
+ unregisterProjectShadowEmbedding(projectIdentity);
33148
+ }
33149
+ const configuredProvider = detailed.config.embedding.provider;
33150
+ const canDiscover = Boolean(detailed.config.subc) && (configuredProvider === "synapse" ? Boolean(detailed.config.embedding.fallback_provider) : configuredProvider !== "off" && detailed.config.shadow_embedding?.enabled === true);
33151
+ const discoveryFailed = canDiscover && (configuredProvider === "synapse" ? routing.primary.provider !== "synapse" : routing.shadow === null);
33152
+ if (!discoveryFailed) {
33153
+ const fingerprintPaths = configCandidatePaths(directory, detailed.loadedFromPaths);
33154
+ registrationFingerprints.set(projectIdentity, {
33155
+ paths: fingerprintPaths,
33156
+ fingerprint: configFingerprint(fingerprintPaths)
33157
+ });
33158
+ } else {
33159
+ registrationFingerprints.delete(projectIdentity);
33160
+ }
32488
33161
  }
32489
33162
 
32490
33163
  // src/pi-harness-kind.ts
@@ -33113,6 +33786,46 @@ Two recovery modes for finer detail:
33113
33786
  - ctx_expand(message=138) — returns the FULL untruncated content of the message at that ordinal: every text part, and every tool call's complete input + output, read from stored history. This is the cheap way to get back a tool output you dropped with ctx_reduce — the original is still in storage even though the wire shows [dropped §N§]. If the message was deleted from history (session prune/revert), it says so.`;
33114
33787
  var CTX_EXPAND_TOKEN_BUDGET = 15000;
33115
33788
 
33789
+ // ../plugin/src/tools/ctx-expand/mode.ts
33790
+ function isInt(value) {
33791
+ return typeof value === "number" && Number.isInteger(value);
33792
+ }
33793
+ function minOrdinal(domain) {
33794
+ return domain === "non-negative" ? 0 : 1;
33795
+ }
33796
+ function messageError(domain) {
33797
+ return domain === "non-negative" ? "Error: message must be a non-negative integer." : "Error: message must be a positive integer.";
33798
+ }
33799
+ function rangeError(domain) {
33800
+ return domain === "non-negative" ? "Error: provide either message=<ordinal>, or start and end (non-negative integers, start <= end)." : "Error: provide either message=<ordinal>, or start and end (positive integers, start <= end).";
33801
+ }
33802
+ function resolveCtxExpandMode(args, domain) {
33803
+ const min = minOrdinal(domain);
33804
+ const messagePresent = args.message !== undefined && args.message !== null;
33805
+ const message = isInt(args.message) ? args.message : undefined;
33806
+ const start = isInt(args.start) ? args.start : undefined;
33807
+ const end = isInt(args.end) ? args.end : undefined;
33808
+ const messageValid = message !== undefined && message >= min;
33809
+ const rangeValid = start !== undefined && end !== undefined && start >= min && end >= start;
33810
+ const fillerPair = start === 0 && end === 0;
33811
+ const rangeNamed = rangeValid && !fillerPair;
33812
+ if (messageValid && !rangeNamed) {
33813
+ return { kind: "message", message };
33814
+ }
33815
+ if (messagePresent && !messageValid && !rangeNamed) {
33816
+ return { kind: "error", message: messageError(domain) };
33817
+ }
33818
+ if (rangeValid) {
33819
+ return {
33820
+ kind: "range",
33821
+ start,
33822
+ end,
33823
+ verbose: args.verbose === true
33824
+ };
33825
+ }
33826
+ return { kind: "error", message: rangeError(domain) };
33827
+ }
33828
+
33116
33829
  // ../plugin/src/tools/ctx-expand/render.ts
33117
33830
  function isRecord4(value) {
33118
33831
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -33709,27 +34422,26 @@ function createCtxExpandTool(deps) {
33709
34422
  readMessages: () => readPiSessionMessages(ctx)
33710
34423
  });
33711
34424
  try {
33712
- if (params.message !== undefined) {
33713
- if (typeof params.message !== "number" || !Number.isInteger(params.message) || params.message < 1) {
33714
- return err("Error: message must be a positive integer.");
33715
- }
33716
- return ok(renderMessageByOrdinal(sessionId, params.message));
34425
+ const mode = resolveCtxExpandMode(params, "positive");
34426
+ if (mode.kind === "error") {
34427
+ return err(mode.message);
33717
34428
  }
33718
- if (typeof params.start !== "number" || typeof params.end !== "number" || !Number.isInteger(params.start) || !Number.isInteger(params.end) || params.start < 1 || params.end < params.start) {
33719
- return err("Error: provide either message=<ordinal>, or start and end (positive integers, start <= end).");
34429
+ if (mode.kind === "message") {
34430
+ return ok(renderMessageByOrdinal(sessionId, mode.message));
33720
34431
  }
34432
+ const { start, end, verbose } = mode;
33721
34433
  const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
33722
- if (lastCompartmentEnd >= 0 && params.start > lastCompartmentEnd) {
33723
- return ok(`Range ${params.start}-${params.end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`);
34434
+ if (lastCompartmentEnd >= 0 && start > lastCompartmentEnd) {
34435
+ return ok(`Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`);
33724
34436
  }
33725
- const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(params.end, lastCompartmentEnd) : params.end;
33726
- if (params.verbose === true) {
33727
- const v = renderVerboseRange(sessionId, params.start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
34437
+ const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
34438
+ if (verbose) {
34439
+ const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
33728
34440
  if (!v.text) {
33729
- return ok(`No messages found in range ${params.start}-${effectiveEnd}. The range may be outside this session's history.`);
34441
+ return ok(`No messages found in range ${start}-${effectiveEnd}. The range may be outside this session's history.`);
33730
34442
  }
33731
34443
  const out = [
33732
- `Messages ${params.start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
34444
+ `Messages ${start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
33733
34445
  "",
33734
34446
  v.text
33735
34447
  ];
@@ -33739,9 +34451,9 @@ function createCtxExpandTool(deps) {
33739
34451
  return ok(out.join(`
33740
34452
  `));
33741
34453
  }
33742
- const chunk = readSessionChunk(sessionId, CTX_EXPAND_TOKEN_BUDGET, params.start, effectiveEnd + 1);
34454
+ const chunk = readSessionChunk(sessionId, CTX_EXPAND_TOKEN_BUDGET, start, effectiveEnd + 1);
33743
34455
  if (!chunk.text || chunk.messageCount === 0) {
33744
- return ok(`No messages found in range ${params.start}-${params.end}. The range may be outside this session's history.`);
34456
+ return ok(`No messages found in range ${start}-${end}. The range may be outside this session's history.`);
33745
34457
  }
33746
34458
  const lines = [];
33747
34459
  lines.push(`Messages ${chunk.startIndex}-${chunk.endIndex} (${chunk.messageCount} messages, ~${chunk.tokenEstimate} tokens):`);
@@ -33760,6 +34472,174 @@ function createCtxExpandTool(deps) {
33760
34472
  };
33761
34473
  }
33762
34474
 
34475
+ // ../plugin/src/features/magic-context/dreamer/storage-task-schedule.ts
34476
+ function toRow(r) {
34477
+ return {
34478
+ projectPath: r.project_path,
34479
+ task: r.task,
34480
+ lastRunAt: r.last_run_at,
34481
+ nextDueAt: r.next_due_at,
34482
+ schedule: r.schedule ?? null,
34483
+ lastStatus: r.last_status ?? null,
34484
+ lastError: r.last_error,
34485
+ retryCount: r.retry_count ?? 0,
34486
+ taskStateJson: r.last_checked_commit ?? null,
34487
+ lastCheckedCommit: r.last_checked_commit ?? null,
34488
+ lastBroadRunAt: r.last_broad_run_at ?? null,
34489
+ retrospectiveWatermarkMs: r.retrospective_watermark_ms ?? null
34490
+ };
34491
+ }
34492
+ var SELECT_COLUMNS = "project_path, task, last_run_at, next_due_at, schedule, last_status, last_error, retry_count, last_checked_commit, last_broad_run_at, retrospective_watermark_ms";
34493
+ function getTaskScheduleState(db, projectPath, task) {
34494
+ const row = db.prepare(`SELECT ${SELECT_COLUMNS} FROM task_schedule_state WHERE project_path = ? AND task = ?`).get(projectPath, task);
34495
+ return row ? toRow(row) : null;
34496
+ }
34497
+ function getMostRecentTaskRunAt(db, projectPath) {
34498
+ const row = db.prepare("SELECT MAX(last_run_at) AS max_at FROM task_schedule_state WHERE project_path = ?").get(projectPath);
34499
+ const value = row?.max_at ?? null;
34500
+ return typeof value === "number" && value > 0 ? value : null;
34501
+ }
34502
+ function pruneNonCanonicalTaskRows(db, projectPath, canonicalTasks) {
34503
+ if (canonicalTasks.length === 0)
34504
+ return 0;
34505
+ const placeholders = canonicalTasks.map(() => "?").join(", ");
34506
+ const result = db.prepare(`DELETE FROM task_schedule_state WHERE project_path = ? AND task NOT IN (${placeholders})`).run(projectPath, ...canonicalTasks);
34507
+ return Number(result.changes ?? 0);
34508
+ }
34509
+ function deleteTaskScheduleRowsForProject(db, projectPath) {
34510
+ const result = db.prepare("DELETE FROM task_schedule_state WHERE project_path = ?").run(projectPath);
34511
+ return Number(result.changes ?? 0);
34512
+ }
34513
+ function seedTaskScheduleState(db, projectPath, task, nextDueAt, lastRunAt, schedule) {
34514
+ db.prepare("INSERT INTO task_schedule_state (project_path, task, last_run_at, next_due_at, schedule, last_status, last_error, retry_count) VALUES (?, ?, ?, ?, ?, NULL, NULL, 0) ON CONFLICT(project_path, task) DO NOTHING").run(projectPath, task, lastRunAt, nextDueAt, schedule);
34515
+ }
34516
+ function writeTaskScheduleState(db, row) {
34517
+ const broadCycleUpdate = row.lastBroadRunAt === undefined ? "last_broad_run_at = task_schedule_state.last_broad_run_at" : "last_broad_run_at = excluded.last_broad_run_at";
34518
+ db.prepare(`INSERT INTO task_schedule_state
34519
+ (project_path, task, last_run_at, next_due_at, schedule, last_status, last_error, retry_count, last_checked_commit, last_broad_run_at, retrospective_watermark_ms)
34520
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
34521
+ ON CONFLICT(project_path, task) DO UPDATE SET
34522
+ last_run_at = excluded.last_run_at,
34523
+ next_due_at = excluded.next_due_at,
34524
+ schedule = excluded.schedule,
34525
+ last_status = excluded.last_status,
34526
+ last_error = excluded.last_error,
34527
+ retry_count = excluded.retry_count,
34528
+ last_checked_commit = COALESCE(excluded.last_checked_commit, task_schedule_state.last_checked_commit),
34529
+ ${broadCycleUpdate},
34530
+ retrospective_watermark_ms = COALESCE(excluded.retrospective_watermark_ms, task_schedule_state.retrospective_watermark_ms)`).run(row.projectPath, row.task, row.lastRunAt, row.nextDueAt, row.schedule, row.lastStatus, row.lastError, row.retryCount, row.taskStateJson ?? row.lastCheckedCommit ?? null, row.lastBroadRunAt ?? null, row.retrospectiveWatermarkMs ?? null);
34531
+ }
34532
+ function writeTaskStateJson(db, projectPath, task, taskStateJson) {
34533
+ db.prepare(`INSERT INTO task_schedule_state (project_path, task, last_checked_commit)
34534
+ VALUES (?, ?, ?)
34535
+ ON CONFLICT(project_path, task) DO UPDATE SET last_checked_commit = excluded.last_checked_commit`).run(projectPath, task, taskStateJson);
34536
+ }
34537
+ function isRetrospectiveWindowProcessed(db, projectPath, windowKey) {
34538
+ const row = db.prepare("SELECT 1 AS one FROM retrospective_processed_windows WHERE project_path = ? AND window_key = ?").get(projectPath, windowKey);
34539
+ return row != null;
34540
+ }
34541
+ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
34542
+ db.prepare("INSERT INTO retrospective_processed_windows (project_path, window_key, processed_at) VALUES (?, ?, ?) ON CONFLICT(project_path, window_key) DO NOTHING").run(projectPath, windowKey, Date.now());
34543
+ }
34544
+
34545
+ // ../plugin/src/features/magic-context/dreamer/curate-category-rotation.ts
34546
+ var CURATE_MEMORY_CATEGORIES = [
34547
+ "PROJECT_RULES",
34548
+ "ARCHITECTURE",
34549
+ "CONSTRAINTS",
34550
+ "CONFIG_VALUES",
34551
+ "NAMING"
34552
+ ];
34553
+ var LEGACY_CURATE_CATEGORY_BUCKETS = {
34554
+ ARCHITECTURE_DECISIONS: "ARCHITECTURE",
34555
+ CONFIG_DEFAULTS: "CONFIG_VALUES",
34556
+ ENVIRONMENT: "CONFIG_VALUES",
34557
+ KNOWN_ISSUES: "CONSTRAINTS",
34558
+ USER_DIRECTIVES: "PROJECT_RULES",
34559
+ USER_PREFERENCES: "PROJECT_RULES",
34560
+ WORKFLOW_RULES: "PROJECT_RULES"
34561
+ };
34562
+ function curateCategoryForMemoryCategory(category) {
34563
+ return isCurateMemoryCategory(category) ? category : LEGACY_CURATE_CATEGORY_BUCKETS[category] ?? null;
34564
+ }
34565
+ function isCurateMemoryCategory(value) {
34566
+ return CURATE_MEMORY_CATEGORIES.includes(value);
34567
+ }
34568
+ function parseTaskState(raw) {
34569
+ if (!raw)
34570
+ return {};
34571
+ try {
34572
+ const parsed = JSON.parse(raw);
34573
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
34574
+ } catch {
34575
+ return {};
34576
+ }
34577
+ }
34578
+ function normalizedCursor(value) {
34579
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value % CURATE_MEMORY_CATEGORIES.length : 0;
34580
+ }
34581
+ function readState(db, projectIdentity) {
34582
+ return parseTaskState(getTaskScheduleState(db, projectIdentity, "curate")?.taskStateJson);
34583
+ }
34584
+ function categoryStartIndex(state, populated) {
34585
+ const active = state.curate?.activeCategory;
34586
+ if (isCurateMemoryCategory(active)) {
34587
+ const activeIndex = CURATE_MEMORY_CATEGORIES.indexOf(active);
34588
+ return populated.has(active) ? activeIndex : (activeIndex + 1) % CURATE_MEMORY_CATEGORIES.length;
34589
+ }
34590
+ return normalizedCursor(state.curate?.cursor);
34591
+ }
34592
+ function peekCurateCategoryScope(db, projectIdentity, memories) {
34593
+ const populated = new Set(memories.map((memory) => curateCategoryForMemoryCategory(memory.category)).filter((category) => category !== null));
34594
+ const start = categoryStartIndex(readState(db, projectIdentity), populated);
34595
+ for (let offset = 0;offset < CURATE_MEMORY_CATEGORIES.length; offset += 1) {
34596
+ const category = CURATE_MEMORY_CATEGORIES[(start + offset) % CURATE_MEMORY_CATEGORIES.length];
34597
+ const scoped = memories.filter((memory) => curateCategoryForMemoryCategory(memory.category) === category);
34598
+ if (scoped.length > 0)
34599
+ return { category, memories: scoped };
34600
+ }
34601
+ return null;
34602
+ }
34603
+ function beginCurateCategoryRun(db, projectIdentity, memories) {
34604
+ const scope = peekCurateCategoryScope(db, projectIdentity, memories);
34605
+ if (!scope)
34606
+ return null;
34607
+ const state = readState(db, projectIdentity);
34608
+ writeTaskStateJson(db, projectIdentity, "curate", JSON.stringify({
34609
+ ...state,
34610
+ curate: {
34611
+ cursor: normalizedCursor(state.curate?.cursor),
34612
+ activeCategory: scope.category
34613
+ }
34614
+ }));
34615
+ return scope;
34616
+ }
34617
+ function curateTaskStateAfterSuccess(db, projectIdentity, category) {
34618
+ const state = readState(db, projectIdentity);
34619
+ return JSON.stringify({
34620
+ ...state,
34621
+ curate: {
34622
+ cursor: (CURATE_MEMORY_CATEGORIES.indexOf(category) + 1) % CURATE_MEMORY_CATEGORIES.length
34623
+ }
34624
+ });
34625
+ }
34626
+ function getActiveCurateCategory(db, projectIdentity) {
34627
+ const active = readState(db, projectIdentity).curate?.activeCategory;
34628
+ return isCurateMemoryCategory(active) ? active : null;
34629
+ }
34630
+ function getCurateCategoryScopeRefusal(args) {
34631
+ if (args.requestedCategory && args.requestedCategory !== args.scope) {
34632
+ return `Error: Curate scope is ${args.scope}; ${args.action} cannot target category ${args.requestedCategory}.`;
34633
+ }
34634
+ for (const id of args.ids ?? []) {
34635
+ const category = args.categoryForId(id);
34636
+ if (category && category !== args.scope) {
34637
+ return `Error: Curate scope is ${args.scope}; memory ID ${id} is outside the scoped category.`;
34638
+ }
34639
+ }
34640
+ return null;
34641
+ }
34642
+
33763
34643
  // ../plugin/src/features/magic-context/dreamer/memory-claim-safety.ts
33764
34644
  var POLICY_SENTENCE_START = /(?:^|[.!?]\s+|\n\s*)(?:[-*]\s+|\d+[.)]\s+)?(?:you\s+|we\s+)?(?:must(?:\s+not)?|never|always|do\s+not|don't|shall\s+not)\b/i;
33765
34645
  var ACTOR_POLICY = /\b(?:you|we|agents?|masons?|workers?|operators?|users?|maintainers?)\s+(?:must(?:\s+not)?|should(?:\s+not)?|need\s+to|shall(?:\s+not)?|cannot|can't|may\s+not)\b/i;
@@ -35197,7 +36077,7 @@ function err2(text) {
35197
36077
  };
35198
36078
  }
35199
36079
  function normalizeLimit(limit) {
35200
- if (typeof limit !== "number" || !Number.isFinite(limit))
36080
+ if (typeof limit !== "number" || !Number.isFinite(limit) || limit === 0)
35201
36081
  return DEFAULT_LIST_LIMIT;
35202
36082
  return Math.max(1, Math.floor(limit));
35203
36083
  }
@@ -35272,8 +36152,8 @@ function formatGetOutput(args) {
35272
36152
 
35273
36153
  `);
35274
36154
  }
35275
- function updateMemoryContentInCurrentTransaction(db, memory, content, normalizedHash) {
35276
- db.prepare("UPDATE memories SET content = ?, normalized_hash = ?, updated_at = ? WHERE id = ?").run(content, normalizedHash, Date.now(), memory.id);
36155
+ function updateMemoryContentInCurrentTransaction(db, memory, content, normalizedHash, category) {
36156
+ db.prepare("UPDATE memories SET content = ?, normalized_hash = ?, category = ?, updated_at = ? WHERE id = ?").run(content, normalizedHash, category, Date.now(), memory.id);
35277
36157
  if (hasMemoryShareableColumn(db)) {
35278
36158
  db.prepare("UPDATE memories SET shareable = 0 WHERE id = ?").run(memory.id);
35279
36159
  }
@@ -35332,6 +36212,27 @@ function createCtxMemoryTool(deps) {
35332
36212
  return err2("Error: Could not resolve project identity for memory action.");
35333
36213
  }
35334
36214
  await deps.ensureProjectRegistered?.(ctx.cwd, deps.db);
36215
+ const activeCurateCategory = dreamerAllowed ? getActiveCurateCategory(deps.db, projectIdentity) : null;
36216
+ if (activeCurateCategory) {
36217
+ const usesCategory = ["write", "update", "merge", "list"].includes(params.action);
36218
+ const usesIds = ["update", "archive", "merge", "get"].includes(params.action);
36219
+ const usesSuccessor = params.action === "update" || params.action === "archive";
36220
+ const scopeRefusal = getCurateCategoryScopeRefusal({
36221
+ scope: activeCurateCategory,
36222
+ action: params.action,
36223
+ requestedCategory: usesCategory ? params.category : undefined,
36224
+ ids: usesIds ? [
36225
+ ...params.ids ?? [],
36226
+ ...usesSuccessor && Number.isInteger(params.superseded_by) ? [params.superseded_by] : []
36227
+ ] : [],
36228
+ categoryForId: (id) => {
36229
+ const category = getMemoryById(deps.db, id)?.category;
36230
+ return category ? curateCategoryForMemoryCategory(category) : null;
36231
+ }
36232
+ });
36233
+ if (scopeRefusal)
36234
+ return err2(scopeRefusal);
36235
+ }
35335
36236
  const workspaceIdentitySet = resolveWorkspaceIdentitySet(deps.db, projectIdentity);
35336
36237
  const expandedWorkspace = expandWorkspaceIdentitySetWithAliases(deps.db, workspaceIdentitySet.identities);
35337
36238
  const workspaceVisibleIdentities = workspaceIdentitySet.identities.length > 1 ? expandedWorkspace.expandedIdentities : workspaceIdentitySet.identities;
@@ -35420,7 +36321,7 @@ function createCtxMemoryTool(deps) {
35420
36321
  const limit = normalizeLimit(params.limit);
35421
36322
  const filtered = getMemoriesByProject(deps.db, projectIdentity);
35422
36323
  const category = params.category;
35423
- const filtered2 = category ? filtered.filter((m) => m.category === category) : filtered;
36324
+ const filtered2 = activeCurateCategory ? filtered.filter((memory) => curateCategoryForMemoryCategory(memory.category) === activeCurateCategory) : category ? filtered.filter((memory) => memory.category === category) : filtered;
35424
36325
  return ok2(formatMemoryList(filtered2.slice(0, limit)));
35425
36326
  }
35426
36327
  if (params.action === "get") {
@@ -35458,18 +36359,19 @@ function createCtxMemoryTool(deps) {
35458
36359
  return err2(inactiveMemoryError(updateId, "updating"));
35459
36360
  }
35460
36361
  const normalizedHash = computeNormalizedHash(content);
36362
+ const targetCategory = params.category ?? memory.category;
35461
36363
  const targetIdentity = targetIdentityForStoredPath(memory.projectPath);
35462
- const duplicate = getMemoryByHash(deps.db, targetIdentity, memory.category, normalizedHash);
36364
+ const duplicate = getMemoryByHash(deps.db, targetIdentity, targetCategory, normalizedHash);
35463
36365
  if (duplicate && duplicate.id !== memory.id) {
35464
36366
  return err2(`Error: Memory content already exists as ID ${duplicate.id}; merge or archive duplicates instead.`);
35465
36367
  }
35466
36368
  runImmediateTransaction(deps.db, () => {
35467
- updateMemoryContentInCurrentTransaction(deps.db, memory, content, normalizedHash);
36369
+ updateMemoryContentInCurrentTransaction(deps.db, memory, content, normalizedHash, targetCategory);
35468
36370
  queueMemoryMutation(deps.db, {
35469
36371
  projectPath: targetIdentity,
35470
36372
  mutationType: "update",
35471
36373
  targetMemoryId: memory.id,
35472
- category: memory.category,
36374
+ category: targetCategory,
35473
36375
  newContent: content
35474
36376
  });
35475
36377
  });
@@ -35479,7 +36381,7 @@ function createCtxMemoryTool(deps) {
35479
36381
  memoryId: memory.id,
35480
36382
  content
35481
36383
  });
35482
- return ok2(`Updated memory [ID: ${memory.id}] in ${memory.category}.`);
36384
+ return ok2(`Updated memory [ID: ${memory.id}] in ${targetCategory}.`);
35483
36385
  }
35484
36386
  if (params.action === "merge") {
35485
36387
  const ids = params.ids;
@@ -36201,7 +37103,7 @@ Use a note when something matters LATER but not in the next few steps: "revisit
36201
37103
  Actions:
36202
37104
  - write: save a note (content). Add surface_condition to make it a smart note (below).
36203
37105
  - read: list notes, newest first. Default: latest active session notes + ready smart notes; page older ones with limit/offset, or inspect other states with filter.
36204
- - update: change a note by note_id. dismiss: retire one by note_id or 1–50 by note_ids; provide exactly one.
37106
+ - update: change one note (note_ids=[N]). dismiss: retire 1–50 notes (note_ids=[...]).
36205
37107
 
36206
37108
  Smart notes: pass surface_condition and the note stays hidden until a background checker confirms the condition — using ONLY externally verifiable signals (GitHub state via gh, files on disk, git history, web pages). It cannot see this conversation, so the condition must be checkable from outside:
36207
37109
  ✓ "When PR #42 in cortexkit/magic-context is merged"
@@ -36234,13 +37136,10 @@ var ParamsSchema2 = _Object_({
36234
37136
  surface_condition: Optional(String2({
36235
37137
  description: "Externally verifiable condition for smart notes. A background checker verifies it using ONLY outside signals (GitHub state via gh, files on disk, git history, web) — it cannot see this conversation. Use for PR/issue state, release tags, file contents, workflow runs. NOT for 'when the user mentions X' / 'when we revisit Y' — write a regular note instead."
36236
37138
  })),
36237
- note_id: Optional(Number2({
36238
- description: "Note ID (required for 'dismiss' and 'update' actions)."
36239
- })),
36240
37139
  note_ids: Optional(_Array_(Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }), {
36241
37140
  minItems: 1,
36242
37141
  maxItems: 50,
36243
- description: "One to fifty note ids for 'dismiss' only; do not combine with note_id."
37142
+ description: "Note ids: exactly one for 'update', one to fifty for 'dismiss'. Ignored by 'write' and 'read'."
36244
37143
  })),
36245
37144
  filter: Optional(Union(FILTER_VALUES.map((value) => Literal(value)), {
36246
37145
  description: "Optional read filter. Defaults to active session notes + ready smart notes. Use 'all' to inspect every status or 'pending' to inspect unsurfaced smart notes."
@@ -36285,16 +37184,17 @@ function formatNoteLine(note) {
36285
37184
  }
36286
37185
  var DISMISS_FOOTER = `
36287
37186
 
36288
- To dismiss a stale note: ctx_note(action="dismiss", note_id=N) or note_ids=[N,...]`;
37187
+ To dismiss a stale note: ctx_note(action="dismiss", note_ids=[N])`;
36289
37188
  function formatDismissResults(results) {
36290
37189
  const dismissedCount = results.filter((result) => result.outcome === "dismissed").length;
36291
37190
  return `Dismissed ${dismissedCount} of ${results.length} notes.
36292
37191
  ${results.map((result) => `- Note #${result.noteId}: ${result.outcome}`).join(`
36293
37192
  `)}`;
36294
37193
  }
36295
- function parseDismissNoteIds(value) {
36296
- if (!Array.isArray(value) || value.length < 1 || value.length > 50 || value.some((id) => typeof id !== "number" || !Number.isInteger(id) || id <= 0)) {
36297
- return "Error: 'note_ids' must contain 1 to 50 positive integer ids when action is 'dismiss'.";
37194
+ function parseNoteIds(action, value) {
37195
+ const max = action === "update" ? 1 : 50;
37196
+ if (!Array.isArray(value) || value.length < 1 || value.length > max || value.some((id) => typeof id !== "number" || !Number.isInteger(id) || id <= 0)) {
37197
+ return action === "update" ? "Error: 'note_ids' must contain exactly one positive integer id when action is 'update'." : "Error: 'note_ids' must contain 1 to 50 positive integer ids when action is 'dismiss'.";
36298
37198
  }
36299
37199
  return value;
36300
37200
  }
@@ -36322,7 +37222,6 @@ function createCtxNoteTool(deps) {
36322
37222
  },
36323
37223
  content: "string",
36324
37224
  surface_condition: "string",
36325
- note_id: "number",
36326
37225
  note_ids: { type: "array", items: "number", maxItems: 50 },
36327
37226
  filter: { type: "enum", values: FILTER_VALUES },
36328
37227
  limit: "number",
@@ -36331,17 +37230,9 @@ function createCtxNoteTool(deps) {
36331
37230
  const sessionId = ctx.sessionManager.getSessionId();
36332
37231
  const dreamerEnabled = deps.resolveDreamerEnabled?.(ctx) ?? deps.dreamerEnabled;
36333
37232
  const action = params.action ?? (params.content?.trim() ? "write" : "read");
36334
- const hasNoteId = params.note_id !== undefined;
36335
- const hasNoteIds = params.note_ids !== undefined;
36336
- if (hasNoteId && hasNoteIds) {
36337
- return err3("Error: 'note_id' and 'note_ids' cannot be used together; provide one or the other.");
36338
- }
36339
- if (hasNoteIds && action !== "dismiss") {
36340
- return err3("Error: 'note_ids' is only valid when action is 'dismiss'.");
36341
- }
36342
- const dismissNoteIds = action === "dismiss" && hasNoteIds ? parseDismissNoteIds(params.note_ids) : undefined;
36343
- if (typeof dismissNoteIds === "string")
36344
- return err3(dismissNoteIds);
37233
+ const noteIds = action === "dismiss" || action === "update" ? parseNoteIds(action, params.note_ids) : undefined;
37234
+ if (typeof noteIds === "string")
37235
+ return err3(noteIds);
36345
37236
  if (action === "write") {
36346
37237
  const content = params.content?.trim();
36347
37238
  if (!content)
@@ -36392,25 +37283,21 @@ wake plane active — create a scheduled wake instead; stored as a plain note.`)
36392
37283
  if (!projectIdentity) {
36393
37284
  return err3("Error: Could not resolve project identity for note dismiss.");
36394
37285
  }
36395
- if (dismissNoteIds) {
36396
- return ok3(formatDismissResults(dismissNotes(deps.db, dismissNoteIds, {
37286
+ const ids = noteIds;
37287
+ if (ids.length > 1) {
37288
+ return ok3(formatDismissResults(dismissNotes(deps.db, ids, {
36397
37289
  projectPath: projectIdentity,
36398
37290
  sessionId
36399
37291
  })));
36400
37292
  }
36401
- if (typeof params.note_id !== "number") {
36402
- return err3("Error: 'note_id' is required when action is 'dismiss'.");
36403
- }
36404
- const dismissed = dismissNote(deps.db, params.note_id, {
37293
+ const dismissed = dismissNote(deps.db, ids[0], {
36405
37294
  projectPath: projectIdentity,
36406
37295
  sessionId
36407
37296
  });
36408
- return dismissed ? ok3(`Note #${params.note_id} dismissed.`) : err3(`Error: Note #${params.note_id} not found in your session/project or already dismissed.`);
37297
+ return dismissed ? ok3(`Note #${ids[0]} dismissed.`) : err3(`Error: Note #${ids[0]} not found in your session/project or already dismissed.`);
36409
37298
  }
36410
37299
  if (action === "update") {
36411
- if (typeof params.note_id !== "number") {
36412
- return err3("Error: 'note_id' is required when action is 'update'.");
36413
- }
37300
+ const noteId = noteIds[0];
36414
37301
  const updates = {};
36415
37302
  if (params.content?.trim())
36416
37303
  updates.content = params.content.trim();
@@ -36430,19 +37317,19 @@ wake plane active — create a scheduled wake instead; stored as a plain note.`)
36430
37317
  if (!projectIdentity) {
36431
37318
  return err3("Error: Could not resolve project identity for note update.");
36432
37319
  }
36433
- const updated = updateNote(deps.db, params.note_id, updates, {
37320
+ const updated = updateNote(deps.db, noteId, updates, {
36434
37321
  projectPath: projectIdentity,
36435
37322
  sessionId
36436
37323
  });
36437
37324
  if (!updated) {
36438
- return err3(`Error: Note #${params.note_id} not found in your session/project.`);
37325
+ return err3(`Error: Note #${noteId} not found in your session/project.`);
36439
37326
  }
36440
37327
  const parts = [];
36441
37328
  if (updates.content)
36442
37329
  parts.push(`content: ${updates.content}`);
36443
37330
  if (updates.surfaceCondition)
36444
37331
  parts.push(`condition: ${updates.surfaceCondition}`);
36445
- return ok3(`Updated note #${params.note_id}
37332
+ return ok3(`Updated note #${noteId}
36446
37333
  - ${parts.join(`
36447
37334
  - `)}${compilation ? conditionCompileReplySuffix(compilation) : ""}`);
36448
37335
  }
@@ -36602,7 +37489,7 @@ function parseInteger(str) {
36602
37489
  var CTX_REDUCE_DESCRIPTION = `Mark spent tagged content as discardable to reclaim context space. This is NOT an immediate delete. Use §N§ identifiers visible in the conversation. The \`drop\` param accepts ranges: "3-5", "1,2,9", "1-5,8".
36603
37490
 
36604
37491
  How it works:
36605
- - Marking QUEUES content for release. It stays fully visible to you until context space is actually needed — which may be as soon as the next turn if you are already under pressure, or many turns later if not. So mark spent outputs as soon as you finish with them; don't hoard the call for the end of the turn.
37492
+ - Marking QUEUES content for release. It stays fully visible to you until it is actually released, which may be the next turn or many turns later. Mark spent outputs as soon as you finish with them; don't hoard the call for the end of the turn.
36606
37493
  - The newest tags are protected: marking one just queues it until it ages out of the recent window, so marking recent output is harmless.
36607
37494
  - When content is finally released it becomes a short placeholder, and re-running the tool is the only way to get it back. So mark only what you are genuinely DONE with — the test is "have I extracted what I need from this?", not "is it safe / do I have time before it drops?".
36608
37495
 
@@ -39391,6 +40278,12 @@ function getWritableOpenCodeDb() {
39391
40278
  throw new Error(`OpenCode database not found at ${dbPath} (source=${resolution.source}; is OpenCode installed?)`);
39392
40279
  }
39393
40280
  const db = new Database(dbPath);
40281
+ try {
40282
+ assertOpenCodeStoreGeneration(db, "v1", dbPath);
40283
+ } catch (error) {
40284
+ closeQuietly(db);
40285
+ throw error;
40286
+ }
39394
40287
  db.exec("PRAGMA busy_timeout=5000");
39395
40288
  db.exec("PRAGMA journal_mode=WAL");
39396
40289
  cachedWriteDb = { path: dbPath, db };
@@ -40243,10 +41136,15 @@ var ParamsSchema4 = _Object_({
40243
41136
  }))
40244
41137
  }, { additionalProperties: true });
40245
41138
  function normalizeLimit3(limit) {
40246
- if (typeof limit !== "number" || !Number.isFinite(limit))
41139
+ if (typeof limit !== "number" || !Number.isFinite(limit) || limit === 0)
40247
41140
  return DEFAULT_LIMIT;
40248
41141
  return Math.max(1, Math.floor(limit));
40249
41142
  }
41143
+ function normalizeSources(sources) {
41144
+ if (sources === undefined || sources.length === 0)
41145
+ return;
41146
+ return sources;
41147
+ }
40250
41148
  function createCtxSearchTool(deps) {
40251
41149
  const resolveProject = deps.resolveProjectIdentity ?? resolveProjectIdentityForSession;
40252
41150
  return {
@@ -40329,7 +41227,7 @@ function createCtxSearchTool(deps) {
40329
41227
  isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
40330
41228
  maxMessageOrdinal: messageOrdinalCutoff,
40331
41229
  gitCommitsEnabled,
40332
- sources: params.sources,
41230
+ sources: normalizeSources(params.sources),
40333
41231
  visibleMemoryIds,
40334
41232
  diagnostics,
40335
41233
  gitRepositoryAvailable: directoryHasGitMetadata(ctx.cwd),
@@ -40463,4 +41361,4 @@ function registerMagicContextTools(pi, opts) {
40463
41361
  }
40464
41362
  }
40465
41363
 
40466
- export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, parseCron, nextOccurrence, nextDueAtMs, canonicalModelIdentity, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, ompModelRefToCanonical, resolveModelRefForOmp, resolveModelConfigValue, resolveModelConfigOrDefault, DEFAULT_HISTORIAN_TIMEOUT_MS, getProtectedTokensTierOverrides, sanitizeDiagnosticText, hasShareabilitySensitiveText, FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, createFailClosedController, setHarness, getHarness, ensureCortexKitArtifactGitignore, getProjectMagicContextHistorianDir, getMagicContextStorageResolution, getMagicContextStorageDir, log, sessionLog, flushLogger, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, CTX_REDUCE_KEEP, newestCtxReduceTagNumbers, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isRecord, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, updateTagByteSize, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getAssignableTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, resolveOpenCodeDbPath, openCodeDbPathExists, recordOpenCodeDbReadFailure, clearOpenCodeDbReadFailure, claimOpenCodeDbDiagnosticOnce, Database, closeQuietly, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, DROPPED_INPUT_MESSAGE, droppedInputMarker, containsDroppedInputPlaceholder, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, logSlowWriteTransaction, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, drainMirrorPages, parseCompartmentOutput, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, encodePiContentDecision, getPiContentDecisions, freezePiContentDecision, getNativeReplayState, saveNativeToolInputs, addNativeReasoningIds, copySessionStateForClone, getErrorMessage, describeError, piHarnessKindFromExecutable, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, computeProtectionWindow, readEpochFloorSnapshot, getProtectionWindowForSession, isProviderOverflowFailClosedProven, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, NEWEST_REASONING_BEARING_ASSISTANT, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, thinkingBindingRecoveryFrozenId, getThinkingBindingRecoveryTarget, armThinkingBindingRecovery, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, setSessionWorkMetrics, getSessionWorkMetrics, resolveEpochFloorForPass, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, BoundedSessionMap, MIN_PLAUSIBLE_CONTEXT_LIMIT, reloadWindowOverlay, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkContextLimit, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, readPiSessionSnapshot, readPiSessionMessages, readPiSessionMessagePage, findLastModelKeyFromBranch, convertEntriesToRawMessages, convertEntriesToRawMessagePage, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, formatSynapseLaneDescriptor, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, describeShadowBackfillWriteRefusal, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolvePiHarnessDetection, resolvePiHarnessKind, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };
41364
+ export { COMPACTION_ENABLED_PATH, isDreamerRunnable, isCompactionEnabled, migrateMagicContextConfigLocations, withContentLanguageDirective, withMigrationLanguageDirective, buildPrimaryLanguageDirective, parseCron, nextOccurrence, nextDueAtMs, canonicalModelIdentity, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, ompModelRefToCanonical, resolveModelRefForOmp, resolveModelConfigValue, resolveModelConfigOrDefault, DEFAULT_HISTORIAN_TIMEOUT_MS, getProtectedTokensTierOverrides, sanitizeDiagnosticText, hasShareabilitySensitiveText, FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, createFailClosedController, setHarness, getHarness, ensureCortexKitArtifactGitignore, getProjectMagicContextHistorianDir, getMagicContextStorageResolution, getMagicContextStorageDir, log, sessionLog, flushLogger, ProjectIdentityError, resolveProjectIdentityStrict, resolveProjectIdentity, resolveProjectIdentityForSession, beginBootQuietPeriod, scheduleAfterBootQuiet, CTX_REDUCE_KEEP, newestCtxReduceTagNumbers, textMentionsRecentCommit, hasMeaningfulUserText, extractTexts, extractToolCallSummaries, preloadTokenizer, estimateTokens, normalizeText, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isRecord, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, updateTagByteSize, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getAssignableTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, resolveOpenCodeDbPath, assertOpenCodeStoreGeneration, openCodeDbPathExists, recordOpenCodeDbReadFailure, clearOpenCodeDbReadFailure, claimOpenCodeDbDiagnosticOnce, Database, closeQuietly, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, DROPPED_INPUT_MESSAGE, droppedInputMarker, containsDroppedInputPlaceholder, isEditTool, applyEditMarkerToInput, setRawMessageProvider, withRawMessageProvider, cleanUserText, withRawSessionMessageCache, readRawSessionMessages, primeTailRawMessageCache, getCachedAbsoluteMessageCount, primeInMemoryTailRawMessageCache, getRawSessionMessageCount, getRawSessionTagKeysThrough, getLegacyProtectedTailStartOrdinal, readSessionChunk, logSlowWriteTransaction, clearCompressionDepth, clearCompressionDepthRange, getMessageIndexSourceIdentity, isMessageIndexSourceCurrent, getLastIndexedOrdinal, getMessageIndexReconciliationStartOrdinal, isMessageIndexReconciledThrough, indexSingleMessage, indexMessagesAfterOrdinal, sweepOrphanedOpenCodeMessageIndexes, recordSessionProjectIdentity, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, releaseCompartmentLeaseBestEffort, isCompartmentLeaseHeld, isNoContentCompartment, HAS_COMPARTMENT_CONTENT_SQL, persistCachedM0, clearCachedM0M1, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, getCompartmentsByEndMessageId, appendCompartments, saveRecompStagingPass, getRecompStaging, clearRecompStaging, getRecompPartialRange, setRecompPartialRange, escapeXmlAttr, escapeXmlContent, getModuleNoteEvaluationBridge, getContextStoreUuid, drainMirrorPages, parseCompartmentOutput, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, sourceNameForMemory, computeWorkspaceEpochFingerprint, bumpEpochsForWorkspaceMembers, readProjectDocsCanonical, encodePiContentDecision, getPiContentDecisions, freezePiContentDecision, getNativeReplayState, saveNativeToolInputs, addNativeReasoningIds, copySessionStateForClone, getErrorMessage, describeError, piHarnessKindFromExecutable, setStoragePrivatePermissionEnforcement, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, applySqliteTuningPragmas, runSqliteOptimize, openDatabase, openDatabaseAsync, queueM0Mutation, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRender, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationId, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, computeProtectionWindow, readEpochFloorSnapshot, getProtectionWindowForSession, isProviderOverflowFailClosedProven, describeProtectedTailDrainBudgetSkip, loadProtectedTailMeta, markProtectedTailPolicyV3Seeded, recordProtectedTailPublicationFloor, recordProtectedTailNoEligibleHead, getWrapupInProgressState, isWrapupInProgress, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, reserveProtectedTailDrainTokens, clearEmergencyDrainLatch, recordHistorianDrainFailure, clearHistorianDrainFailure, rollbackProtectedTailDrainReservation, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getChannel1NudgeState, setChannel1NudgeState, markChannel1PostReduceGracePending, captureChannel1PostReduceGraceBaseline, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, setPersistedNoteNudgeTrigger, setPersistedNoteNudgeTriggerMessageId, getNoteNudgeAnchors, getAutoSearchHintDecisions, deliverNoteNudgeAtomic, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, getNoteLastReadAt, incrementHistorianFailure, clearHistorianFailureState, getOverflowState, recordOverflowDetected, clearEmergencyRecovery, clearDetectedContextLimit, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, NEWEST_REASONING_BEARING_ASSISTANT, THINKING_BINDING_RECOVERY_FROZEN_PREFIX, thinkingBindingRecoveryFrozenId, getThinkingBindingRecoveryTarget, armThinkingBindingRecovery, clearThinkingBindingRecoveryIf, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, getPendingPiCompactionMarkerState, setPendingPiCompactionMarkerState, clearPendingPiCompactionMarkerStateIf, getSessionsWithPendingPiMarker, setSessionWorkMetrics, getSessionWorkMetrics, resolveEpochFloorForPass, getOrCreateSessionMeta, updateSessionMeta, advanceToolReclaimWatermark, retryPendingSessionCleanups, retryPendingRustSessionCleanupsForProject, getNotes, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectUserProfileVersion, saveSourceContent, getSourceContents, recordSubagentInvocation, getLatestHistorianInvocationId, BoundedSessionMap, MIN_PLAUSIBLE_CONTEXT_LIMIT, reloadWindowOverlay, getWindowOverlay, resolveWindowOverlayFacts, deriveWindowGeometry, hasTrustedAbsoluteWall, applyProvenInputFloor, formatWindowDerivationLine, isSaneLimit, resolveOutputReserve, getSdkContextLimit, formatConfigParseStatusLine, formatConfigParseNotice, claimConfigParseFailuresOnce, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, SYNTH_USER_ID_PREFIX, resolvePiStableId, readPiSessionSnapshot, readPiSessionMessages, readPiSessionMessagePage, findLastModelKeyFromBranch, convertEntriesToRawMessages, convertEntriesToRawMessagePage, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, invalidateMemory, computeNormalizedHash, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, insertMemory, getMemoryByHash, getMemoriesByProject, getMemoriesByProjects, getMaxMemoryIdForProjects, getAllActiveMemoriesForMigration, getMemoryById, setMemoryClassification, archiveMemory, deleteMemory, getMemoryCount, getMemoryCountsByStatus, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, getTaskScheduleState, getMostRecentTaskRunAt, pruneNonCanonicalTaskRows, deleteTaskScheduleRowsForProject, seedTaskScheduleState, writeTaskScheduleState, isRetrospectiveWindowProcessed, recordRetrospectiveWindowProcessed, curateCategoryForMemoryCategory, peekCurateCategoryScope, beginCurateCategoryRun, curateTaskStateAfterSuccess, formatSynapseLaneDescriptor, buildCanonicalChunkTextFromFts, buildCompartmentSummaryFallbackText, canonicalizeInMemoryChunkTextForEmbedding, chunkCanonicalText, chunkEmbeddingWindowsAreCurrent, replaceCompartmentChunkEmbeddings, cosineSimilarity, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, describeShadowBackfillWriteRefusal, contentSha256, sweepStaleEmbeddingIdentitiesForProject, enqueueShadowEmbeddingItems, getProjectEmbeddingSnapshot, getProjectChunkEmbeddingModelId, getProjectEmbeddingMaxInputTokens, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, isDirectiveShapedProjectRule, takeCurateSafetyRefusalCount, wakePlaneStatus, indexCommitsForProject, embedUnembeddedCommits, loadPiConfig, ensureProjectRegisteredFromPiDirectory, resolvePiHarnessDetection, resolvePiHarnessKind, resolveMuralWire, updateCompactionMarkerAfterPublication, COMPARTMENT_RENDER_EPOCH, encodeCachedM0UpgradeIdentity, decodeCachedM0UpgradeIdentity, DEFAULT_HISTORY_BUDGET_TOKENS, renderCompartmentAtTier, renderDecayedCompartments, extractM0Block, TEMPORAL_MARKER_PATTERN, temporalMarkerPrefix, clearInjectionCache, getVisibleMemoryIds, renderMemoryBlock, DEFAULT_MEMORY_BUDGET_TOKENS, DEFAULT_USER_PROFILE_BUDGET_TOKENS, trimMemoriesToBudgetV2, trimWorkspaceMemoriesToBudgetV2, trimUserMemoriesToBudget, renderMemoryBlockV2, stripMemoryMuralBlock, unifiedSearch, rememberTodowriteToolCallTodos, parseTodos, setTodoSnapshot, registerTodoOverlay, registerTodoStateLifecycle, syncCtxMemoryToolEnabled, registerMagicContextTools };