@cortexkit/magic-context 0.32.1 → 0.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +325 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12833,6 +12833,17 @@ var init_setup = __esm(() => {
12833
12833
  init_setup_pi();
12834
12834
  });
12835
12835
 
12836
+ // ../plugin/src/plugin/boot-quiet.ts
12837
+ function bootQuietRemainingMs(now = Date.now()) {
12838
+ return Math.max(0, bootQuietUntilMs - now);
12839
+ }
12840
+ function scheduleAfterBootQuiet(task, additionalDelayMs = 0) {
12841
+ const timer = setTimeout(task, bootQuietRemainingMs() + Math.max(0, additionalDelayMs));
12842
+ timer.unref?.();
12843
+ return timer;
12844
+ }
12845
+ var bootQuietUntilMs = 0;
12846
+
12836
12847
  // ../plugin/src/shared/error-message.ts
12837
12848
  function getErrorMessage(error) {
12838
12849
  return error instanceof Error ? error.message : String(error);
@@ -13447,6 +13458,14 @@ var init_workspaces = __esm(() => {
13447
13458
  });
13448
13459
 
13449
13460
  // ../plugin/src/features/magic-context/migrations.ts
13461
+ function isSqliteLockError(error) {
13462
+ if (!error || typeof error !== "object")
13463
+ return false;
13464
+ const candidate = error;
13465
+ if (candidate.code === "SQLITE_BUSY" || candidate.code === "SQLITE_LOCKED")
13466
+ return true;
13467
+ return typeof candidate.message === "string" && /database is locked|sqlite_(busy|locked)/i.test(candidate.message);
13468
+ }
13450
13469
  function tableExists(db, name) {
13451
13470
  return Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name));
13452
13471
  }
@@ -13481,7 +13500,14 @@ function isSiblingMigrationConflict(db, error, version) {
13481
13500
  return confirmed != null;
13482
13501
  }
13483
13502
  function runMigrations(db) {
13484
- ensureMigrationsTable(db);
13503
+ try {
13504
+ ensureMigrationsTable(db);
13505
+ } catch (error) {
13506
+ if (isSqliteLockError(error)) {
13507
+ throw new MigrationLockBusyError(`failed to prepare migration lock: ${error instanceof Error ? error.message : String(error)}`);
13508
+ }
13509
+ throw error;
13510
+ }
13485
13511
  let loggedPlan = false;
13486
13512
  while (true) {
13487
13513
  let migration;
@@ -13505,6 +13531,9 @@ function runMigrations(db) {
13505
13531
  break;
13506
13532
  log3(`[migrations] applied v${migration.version}: ${migration.description}`);
13507
13533
  } catch (error) {
13534
+ if (!migration && isSqliteLockError(error)) {
13535
+ throw new MigrationLockBusyError(`failed to acquire migration write lock: ${error instanceof Error ? error.message : String(error)}`);
13536
+ }
13508
13537
  if (migration && isSiblingMigrationConflict(db, error, migration.version)) {
13509
13538
  log3(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
13510
13539
  const reReadVersion = getCurrentVersion(db);
@@ -13522,10 +13551,16 @@ function runMigrations(db) {
13522
13551
  log3(`[migrations] schema version now: ${MIGRATIONS[MIGRATIONS.length - 1].version}`);
13523
13552
  }
13524
13553
  }
13525
- var MIGRATIONS, LATEST_MIGRATION_VERSION;
13554
+ var MigrationLockBusyError, MIGRATIONS, LATEST_MIGRATION_VERSION;
13526
13555
  var init_migrations = __esm(() => {
13527
13556
  init_logger();
13528
13557
  init_workspaces();
13558
+ MigrationLockBusyError = class MigrationLockBusyError extends Error {
13559
+ constructor(message) {
13560
+ super(message);
13561
+ this.name = "MigrationLockBusyError";
13562
+ }
13563
+ };
13529
13564
  MIGRATIONS = [
13530
13565
  {
13531
13566
  version: 1,
@@ -14876,6 +14911,80 @@ var init_migrations = __esm(() => {
14876
14911
  ensureColumn(db, "session_meta", "emergency_recovery_origin", "TEXT DEFAULT ''");
14877
14912
  }
14878
14913
  }
14914
+ },
14915
+ {
14916
+ version: 53,
14917
+ description: "add Synapse batch, shadow, and measurement storage",
14918
+ up(db) {
14919
+ db.exec(`
14920
+ CREATE TABLE IF NOT EXISTS embedding_registrations (
14921
+ project_path TEXT PRIMARY KEY,
14922
+ provider_identity TEXT NOT NULL DEFAULT '',
14923
+ model_id TEXT NOT NULL DEFAULT '',
14924
+ chunk_model_id TEXT NOT NULL DEFAULT '',
14925
+ fingerprint TEXT NOT NULL DEFAULT '',
14926
+ table_epoch INTEGER NOT NULL DEFAULT 0,
14927
+ dims INTEGER NOT NULL DEFAULT 0,
14928
+ provenance_json TEXT NOT NULL DEFAULT '{}',
14929
+ generation INTEGER NOT NULL DEFAULT 0,
14930
+ updated_at INTEGER NOT NULL DEFAULT 0
14931
+ );
14932
+ CREATE TABLE IF NOT EXISTS synapse_batch_ledger (
14933
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
14934
+ session_id TEXT NOT NULL,
14935
+ project_path TEXT NOT NULL DEFAULT '',
14936
+ scope TEXT NOT NULL DEFAULT '',
14937
+ manifest_json TEXT NOT NULL DEFAULT '{}',
14938
+ request_key TEXT NOT NULL DEFAULT '',
14939
+ job_id TEXT,
14940
+ cursor TEXT,
14941
+ status TEXT NOT NULL DEFAULT 'pending',
14942
+ created_at INTEGER NOT NULL DEFAULT 0,
14943
+ updated_at INTEGER NOT NULL DEFAULT 0,
14944
+ UNIQUE(session_id, request_key)
14945
+ );
14946
+ CREATE INDEX IF NOT EXISTS idx_synapse_batch_ledger_session
14947
+ ON synapse_batch_ledger(session_id, updated_at);
14948
+ CREATE TABLE IF NOT EXISTS shadow_embedding_registrations (
14949
+ project_path TEXT NOT NULL,
14950
+ scope TEXT NOT NULL CHECK(scope IN ('memory', 'commit', 'chunk')),
14951
+ model_id TEXT NOT NULL,
14952
+ generation INTEGER NOT NULL DEFAULT 0,
14953
+ fingerprint TEXT NOT NULL DEFAULT '',
14954
+ table_epoch INTEGER NOT NULL DEFAULT 0,
14955
+ dims INTEGER NOT NULL DEFAULT 0,
14956
+ provenance_json TEXT NOT NULL DEFAULT '{}',
14957
+ updated_at INTEGER NOT NULL DEFAULT 0,
14958
+ PRIMARY KEY(project_path, scope, model_id)
14959
+ );
14960
+ CREATE TABLE IF NOT EXISTS embedding_measurement_corpus (
14961
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
14962
+ session_id TEXT NOT NULL,
14963
+ project_path TEXT NOT NULL DEFAULT '',
14964
+ dedup_key TEXT NOT NULL DEFAULT '',
14965
+ cohort_key TEXT NOT NULL DEFAULT '',
14966
+ query_text_hash TEXT NOT NULL DEFAULT '',
14967
+ primary_result_ids_json TEXT NOT NULL DEFAULT '[]',
14968
+ shadow_result_ids_json TEXT NOT NULL DEFAULT '[]',
14969
+ primary_latency_ms INTEGER,
14970
+ shadow_latency_ms INTEGER,
14971
+ primary_failed INTEGER NOT NULL DEFAULT 0,
14972
+ shadow_failed INTEGER NOT NULL DEFAULT 0,
14973
+ primary_model_id TEXT NOT NULL DEFAULT '',
14974
+ shadow_model_id TEXT NOT NULL DEFAULT '',
14975
+ primary_fingerprint TEXT NOT NULL DEFAULT '',
14976
+ shadow_fingerprint TEXT NOT NULL DEFAULT '',
14977
+ primary_epoch INTEGER NOT NULL DEFAULT 0,
14978
+ shadow_epoch INTEGER NOT NULL DEFAULT 0,
14979
+ corpus_hash TEXT NOT NULL DEFAULT '',
14980
+ coverage_json TEXT NOT NULL DEFAULT '{}',
14981
+ created_at INTEGER NOT NULL DEFAULT 0,
14982
+ UNIQUE(dedup_key, cohort_key)
14983
+ );
14984
+ CREATE INDEX IF NOT EXISTS idx_embedding_measurement_session
14985
+ ON embedding_measurement_corpus(session_id, created_at);
14986
+ `);
14987
+ }
14879
14988
  }
14880
14989
  ];
14881
14990
  LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m3) => Math.max(max, m3.version), 0);
@@ -147748,6 +147857,34 @@ function applySqliteTuningPragmas(db) {
147748
147857
  db.exec(`PRAGMA mmap_size=${Math.round(sqlitePragmaConfig.mmapSizeMb * 1024 * 1024)}`);
147749
147858
  db.exec("PRAGMA analysis_limit=400");
147750
147859
  }
147860
+ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion) {
147861
+ if (!enforceSchemaFence(db, dbPath, latestSupportedVersion)) {
147862
+ closeQuietly(db);
147863
+ return null;
147864
+ }
147865
+ healWedgedChannel2Claims(db);
147866
+ if (!explicitDbPath) {
147867
+ const runBackfill = () => {
147868
+ try {
147869
+ runToolOwnerBackfill(db);
147870
+ } catch (error) {
147871
+ log3(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error)}`);
147872
+ }
147873
+ };
147874
+ if (bootQuietRemainingMs() > 0)
147875
+ scheduleAfterBootQuiet(runBackfill);
147876
+ else
147877
+ runBackfill();
147878
+ }
147879
+ setDatabase(db);
147880
+ loadToolDefinitionMeasurements(db);
147881
+ restrictDatabaseFilePermissions(dbPath);
147882
+ databases.set(dbPath, db);
147883
+ pathByDatabase.set(db, dbPath);
147884
+ persistenceByDatabase.set(db, true);
147885
+ persistenceErrorByDatabase.delete(db);
147886
+ return db;
147887
+ }
147751
147888
  function initializeDatabase(db) {
147752
147889
  db.exec("PRAGMA busy_timeout=5000");
147753
147890
  db.exec("PRAGMA foreign_keys=ON");
@@ -148005,6 +148142,76 @@ function initializeDatabase(db) {
148005
148142
  PRIMARY KEY(project_path, scope, model_id)
148006
148143
  );
148007
148144
 
148145
+ CREATE TABLE IF NOT EXISTS embedding_registrations (
148146
+ project_path TEXT PRIMARY KEY,
148147
+ provider_identity TEXT NOT NULL DEFAULT '',
148148
+ model_id TEXT NOT NULL DEFAULT '',
148149
+ chunk_model_id TEXT NOT NULL DEFAULT '',
148150
+ fingerprint TEXT NOT NULL DEFAULT '',
148151
+ table_epoch INTEGER NOT NULL DEFAULT 0,
148152
+ dims INTEGER NOT NULL DEFAULT 0,
148153
+ provenance_json TEXT NOT NULL DEFAULT '{}',
148154
+ generation INTEGER NOT NULL DEFAULT 0,
148155
+ updated_at INTEGER NOT NULL DEFAULT 0
148156
+ );
148157
+
148158
+ CREATE TABLE IF NOT EXISTS synapse_batch_ledger (
148159
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
148160
+ session_id TEXT NOT NULL,
148161
+ project_path TEXT NOT NULL DEFAULT '',
148162
+ scope TEXT NOT NULL DEFAULT '',
148163
+ manifest_json TEXT NOT NULL DEFAULT '{}',
148164
+ request_key TEXT NOT NULL DEFAULT '',
148165
+ job_id TEXT,
148166
+ cursor TEXT,
148167
+ status TEXT NOT NULL DEFAULT 'pending',
148168
+ created_at INTEGER NOT NULL DEFAULT 0,
148169
+ updated_at INTEGER NOT NULL DEFAULT 0,
148170
+ UNIQUE(session_id, request_key)
148171
+ );
148172
+ CREATE INDEX IF NOT EXISTS idx_synapse_batch_ledger_session
148173
+ ON synapse_batch_ledger(session_id, updated_at);
148174
+
148175
+ CREATE TABLE IF NOT EXISTS shadow_embedding_registrations (
148176
+ project_path TEXT NOT NULL,
148177
+ scope TEXT NOT NULL CHECK(scope IN ('memory', 'commit', 'chunk')),
148178
+ model_id TEXT NOT NULL,
148179
+ generation INTEGER NOT NULL DEFAULT 0,
148180
+ fingerprint TEXT NOT NULL DEFAULT '',
148181
+ table_epoch INTEGER NOT NULL DEFAULT 0,
148182
+ dims INTEGER NOT NULL DEFAULT 0,
148183
+ provenance_json TEXT NOT NULL DEFAULT '{}',
148184
+ updated_at INTEGER NOT NULL DEFAULT 0,
148185
+ PRIMARY KEY(project_path, scope, model_id)
148186
+ );
148187
+
148188
+ CREATE TABLE IF NOT EXISTS embedding_measurement_corpus (
148189
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
148190
+ session_id TEXT NOT NULL,
148191
+ project_path TEXT NOT NULL DEFAULT '',
148192
+ dedup_key TEXT NOT NULL DEFAULT '',
148193
+ cohort_key TEXT NOT NULL DEFAULT '',
148194
+ query_text_hash TEXT NOT NULL DEFAULT '',
148195
+ primary_result_ids_json TEXT NOT NULL DEFAULT '[]',
148196
+ shadow_result_ids_json TEXT NOT NULL DEFAULT '[]',
148197
+ primary_latency_ms INTEGER,
148198
+ shadow_latency_ms INTEGER,
148199
+ primary_failed INTEGER NOT NULL DEFAULT 0,
148200
+ shadow_failed INTEGER NOT NULL DEFAULT 0,
148201
+ primary_model_id TEXT NOT NULL DEFAULT '',
148202
+ shadow_model_id TEXT NOT NULL DEFAULT '',
148203
+ primary_fingerprint TEXT NOT NULL DEFAULT '',
148204
+ shadow_fingerprint TEXT NOT NULL DEFAULT '',
148205
+ primary_epoch INTEGER NOT NULL DEFAULT 0,
148206
+ shadow_epoch INTEGER NOT NULL DEFAULT 0,
148207
+ corpus_hash TEXT NOT NULL DEFAULT '',
148208
+ coverage_json TEXT NOT NULL DEFAULT '{}',
148209
+ created_at INTEGER NOT NULL DEFAULT 0,
148210
+ UNIQUE(dedup_key, cohort_key)
148211
+ );
148212
+ CREATE INDEX IF NOT EXISTS idx_embedding_measurement_session
148213
+ ON embedding_measurement_corpus(session_id, created_at);
148214
+
148008
148215
  CREATE TABLE IF NOT EXISTS memory_verifications (
148009
148216
  memory_id INTEGER NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
148010
148217
  file_path TEXT NOT NULL,
@@ -148744,26 +148951,7 @@ function openDatabase(dbPathOrOptions) {
148744
148951
  }
148745
148952
  initializeDatabase(db);
148746
148953
  runMigrations(db);
148747
- if (!enforceSchemaFence(db, dbPath, latestSupportedVersion)) {
148748
- closeQuietly(db);
148749
- return null;
148750
- }
148751
- healWedgedChannel2Claims(db);
148752
- if (!explicitDbPath) {
148753
- try {
148754
- runToolOwnerBackfill(db);
148755
- } catch (error) {
148756
- log3(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error)}`);
148757
- }
148758
- }
148759
- setDatabase(db);
148760
- loadToolDefinitionMeasurements(db);
148761
- restrictDatabaseFilePermissions(dbPath);
148762
- databases.set(dbPath, db);
148763
- pathByDatabase.set(db, dbPath);
148764
- persistenceByDatabase.set(db, true);
148765
- persistenceErrorByDatabase.delete(db);
148766
- return db;
148954
+ return finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion);
148767
148955
  } catch (error) {
148768
148956
  const detail = getErrorMessage(error);
148769
148957
  log3(`[magic-context] storage fatal: failed to open ${dbPath}: ${detail}`);
@@ -148771,6 +148959,7 @@ function openDatabase(dbPathOrOptions) {
148771
148959
  }
148772
148960
  }
148773
148961
  function closeDatabase() {
148962
+ pendingAsyncOpens.clear();
148774
148963
  for (const [key, db] of databases) {
148775
148964
  try {
148776
148965
  closeQuietly(db);
@@ -148781,7 +148970,7 @@ function closeDatabase() {
148781
148970
  }
148782
148971
  }
148783
148972
  }
148784
- var databases, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 52, PERMISSIONS_ENFORCEABLE, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS = 120000;
148973
+ var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 53, PERMISSIONS_ENFORCEABLE, sqlitePragmaConfig, CHANNEL2_CLAIM_TTL_MS = 120000;
148785
148974
  var init_storage_db = __esm(async () => {
148786
148975
  init_data_path();
148787
148976
  init_logger();
@@ -148790,6 +148979,7 @@ var init_storage_db = __esm(async () => {
148790
148979
  init_tool_owner_backfill();
148791
148980
  await init_sqlite();
148792
148981
  databases = new Map;
148982
+ pendingAsyncOpens = new Map;
148793
148983
  persistenceByDatabase = new WeakMap;
148794
148984
  persistenceErrorByDatabase = new WeakMap;
148795
148985
  pathByDatabase = new WeakMap;
@@ -150417,6 +150607,9 @@ var init_project_docs_hash = __esm(() => {
150417
150607
 
150418
150608
  // ../plugin/src/features/magic-context/storage-clone.ts
150419
150609
  var init_storage_clone = () => {};
150610
+
150611
+ // ../plugin/src/features/magic-context/storage-embedding-measurements.ts
150612
+ var init_storage_embedding_measurements = () => {};
150420
150613
  // ../plugin/src/features/magic-context/storage-m0-mutation-log.ts
150421
150614
  var M0_MUTATION_TYPES;
150422
150615
  var init_storage_m0_mutation_log = __esm(() => {
@@ -150436,10 +150629,11 @@ var init_storage_memory_mutation_log = __esm(() => {
150436
150629
  });
150437
150630
 
150438
150631
  // ../plugin/src/features/magic-context/storage-meta-persisted.ts
150439
- var AUTO_SEARCH_NO_HINT_REASONS, DRAIN_WINDOW_MS, WRAPUP_IN_PROGRESS_TTL_MS, EMERGENCY_DRAIN_MAX_LATCH_MS;
150632
+ var emergencyRecoveryArmedSessions, AUTO_SEARCH_NO_HINT_REASONS, DRAIN_WINDOW_MS, WRAPUP_IN_PROGRESS_TTL_MS, EMERGENCY_DRAIN_MAX_LATCH_MS;
150440
150633
  var init_storage_meta_persisted = __esm(() => {
150441
150634
  init_logger();
150442
150635
  init_storage_meta_shared();
150636
+ emergencyRecoveryArmedSessions = new Set;
150443
150637
  AUTO_SEARCH_NO_HINT_REASONS = new Set([
150444
150638
  "below-threshold",
150445
150639
  "timeout",
@@ -150558,6 +150752,7 @@ var init_storage = __esm(async () => {
150558
150752
  init_project_docs_hash();
150559
150753
  init_project_identity2();
150560
150754
  init_storage_clone();
150755
+ init_storage_embedding_measurements();
150561
150756
  init_storage_m0_mutation_log();
150562
150757
  init_storage_memory_mutation_log();
150563
150758
  init_storage_meta_shared();
@@ -165830,6 +166025,7 @@ var init_agent_overrides = __esm(() => {
165830
166025
  });
165831
166026
 
165832
166027
  // ../plugin/src/config/schema/magic-context.ts
166028
+ import { homedir as homedir9 } from "node:os";
165833
166029
  function defaultTaskConfig(task) {
165834
166030
  const base = { schedule: DEFAULT_TASK_SCHEDULES2[task] };
165835
166031
  if (task === "review-user-memories")
@@ -165838,7 +166034,15 @@ function defaultTaskConfig(task) {
165838
166034
  base.promotion_threshold = 2;
165839
166035
  return base;
165840
166036
  }
165841
- var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 80% for cache safety: a single large agent step can overflow the context window before Magic Context can compact between turns, forcing OpenCode's native compaction (hard to recover from). 80% also leaves headroom below the 85%/95% emergency bands. Use a value between 20 and 80.", DEFAULT_HISTORIAN_TIMEOUT_MS = 300000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", DreamingTaskSchema, PiThinkingLevelSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES2, DreamTasksSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
166037
+ function expandConfigPath(value) {
166038
+ const trimmed = value.trim();
166039
+ if (trimmed === "~")
166040
+ return homedir9();
166041
+ if (trimmed.startsWith("~/"))
166042
+ return `${homedir9()}/${trimmed.slice(2)}`;
166043
+ return trimmed;
166044
+ }
166045
+ var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 80% for cache safety: a single large agent step can overflow the context window before Magic Context can compact between turns, forcing OpenCode's native compaction (hard to recover from). 80% also leaves headroom below the 85%/95% emergency bands. Use a value between 20 and 80.", DEFAULT_HISTORIAN_TIMEOUT_MS = 300000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", DreamingTaskSchema, PiThinkingLevelSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES2, DreamTasksSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, EmbeddingFallbackProviderSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
165842
166046
  var init_magic_context = __esm(() => {
165843
166047
  init_zod();
165844
166048
  init_language_directive();
@@ -165909,8 +166113,10 @@ var init_magic_context = __esm(() => {
165909
166113
  thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh"),
165910
166114
  disallowed_tools: exports_external.array(exports_external.enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"])).default([]).describe(`OpenCode only. Tools to REMOVE from the historian's default allow-list [read, aft_outline, aft_zoom, aft_search]. Applies to both historian and historian-editor agents. Use ["*"] to strip all tool definitions from the model request — this prevents weak instruction-following models (e.g. mistral-small-latest) from entering tool-calling loops. Individual tool names remove just that tool. Note: a user-supplied historian.permission override can re-allow a tool that disallowed_tools removed — disallowed_tools sets the baseline, permission overrides take precedence. (default: [])`)
165911
166115
  }).optional();
166116
+ EmbeddingFallbackProviderSchema = exports_external.enum(["local", "openai-compatible", "off"]);
165912
166117
  BaseEmbeddingConfigSchema = exports_external.object({
165913
- provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'off' disables embeddings."),
166118
+ provider: exports_external.enum(["local", "openai-compatible", "off", "synapse"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'synapse' uses the certified local Synapse lane with an explicit fallback provider, and 'off' disables embeddings."),
166119
+ fallback_provider: EmbeddingFallbackProviderSchema.optional().describe("Fallback provider for the Synapse lane. Required when provider is 'synapse'; local, openai-compatible, and off are valid."),
165914
166120
  model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
165915
166121
  endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
165916
166122
  api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
@@ -165919,14 +166125,15 @@ var init_magic_context = __esm(() => {
165919
166125
  truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset."),
165920
166126
  max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted.")
165921
166127
  }).superRefine((data, ctx) => {
165922
- if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
166128
+ const validationProvider = data.provider === "synapse" ? data.fallback_provider : data.provider;
166129
+ if (validationProvider === "openai-compatible" && !data.endpoint?.trim()) {
165923
166130
  ctx.addIssue({
165924
166131
  code: "custom",
165925
166132
  path: ["endpoint"],
165926
166133
  message: "endpoint is required when embedding.provider is openai-compatible"
165927
166134
  });
165928
166135
  }
165929
- if (data.provider === "openai-compatible" && !data.model?.trim()) {
166136
+ if (validationProvider === "openai-compatible" && !data.model?.trim()) {
165930
166137
  ctx.addIssue({
165931
166138
  code: "custom",
165932
166139
  path: ["model"],
@@ -165935,6 +166142,25 @@ var init_magic_context = __esm(() => {
165935
166142
  }
165936
166143
  });
165937
166144
  EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
166145
+ if (data.provider === "synapse") {
166146
+ const model = data.model?.trim();
166147
+ const endpoint = data.endpoint?.trim();
166148
+ const apiKey = data.api_key?.trim();
166149
+ const inputType = data.input_type?.trim();
166150
+ const queryInputType = data.query_input_type?.trim();
166151
+ const truncate = data.truncate?.trim();
166152
+ return {
166153
+ provider: "synapse",
166154
+ ...data.fallback_provider ? { fallback_provider: data.fallback_provider } : {},
166155
+ ...model ? { model } : {},
166156
+ ...endpoint ? { endpoint } : {},
166157
+ ...apiKey ? { api_key: apiKey } : {},
166158
+ ...inputType ? { input_type: inputType } : {},
166159
+ ...queryInputType ? { query_input_type: queryInputType } : {},
166160
+ ...truncate ? { truncate } : {},
166161
+ ...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
166162
+ };
166163
+ }
165938
166164
  if (data.provider === "local") {
165939
166165
  return {
165940
166166
  provider: "local",
@@ -165962,6 +166188,7 @@ var init_magic_context = __esm(() => {
165962
166188
  });
165963
166189
  MagicContextConfigSchema = exports_external.object({
165964
166190
  enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
166191
+ transform_mode: exports_external.enum(["ts", "rust"]).default("ts").describe('Experimental: routes the entire Magic Context runtime for the project through the ck-mc Rust module over subc (requires user-level `subc` config); "ts" is the current TypeScript pipeline.'),
165965
166192
  auto_update: exports_external.boolean().optional().describe("Enable automatic npm self-update checks for the OpenCode plugin. Security: USER-only in config loader, so hostile project configs cannot suppress updates."),
165966
166193
  language: exports_external.string().trim().toLowerCase().refine((s) => isValidLanguageCode(s), 'language must be a 2-letter ISO 639-1 code (e.g. "tr", "es", "de")').optional().describe("Output language for Magic Context's generated content and guidance, as a " + '2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' + "historian, dreamer, sidekick, and the agent-guidance block instruct the model to " + "write its PROSE in this language while keeping all structural tokens (XML tags, " + "the five memory category names, code identifiers, file paths) in English. " + "USER-LEVEL ONLY (ignored in project config for security). Unset = today's " + "behavior (model mirrors the conversation; English scaffolding). Changing it " + "triggers one cache re-materialization; existing compartments/memories keep their " + "original language until naturally rewritten."),
165967
166194
  historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
@@ -165998,6 +166225,12 @@ var init_magic_context = __esm(() => {
165998
166225
  provider: "local",
165999
166226
  model: DEFAULT_LOCAL_EMBEDDING_MODEL
166000
166227
  }).describe("Embedding provider configuration"),
166228
+ subc: exports_external.object({
166229
+ connection_file: exports_external.string().trim().min(1).transform(expandConfigPath).describe("Path to the owner-only subc connection file.")
166230
+ }).optional().describe("User-only Synapse daemon connection settings."),
166231
+ shadow_embedding: exports_external.object({
166232
+ enabled: exports_external.boolean().default(false).describe("Developer-only Synapse shadow embedding lane switch.")
166233
+ }).default({ enabled: false }).describe("Developer-only Synapse shadow embedding lane."),
166001
166234
  temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add compact date ranges to compartment headings. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
166002
166235
  keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
166003
166236
  shadow_transform: exports_external.object({
@@ -166157,6 +166390,12 @@ function stripUnsafeProjectConfigFields(projectRaw) {
166157
166390
  delete projectRaw.shadow_transform;
166158
166391
  warnings.push("Ignoring shadow_transform from project config (security: this developer-only mirror lane is user-level only).");
166159
166392
  }
166393
+ for (const field of ["subc", "shadow_embedding"]) {
166394
+ if (field in projectRaw) {
166395
+ delete projectRaw[field];
166396
+ warnings.push(`Ignoring ${field} from project config (security: daemon routing and developer-only embedding traffic are user-level settings).`);
166397
+ }
166398
+ }
166160
166399
  const embedding = projectRaw.embedding;
166161
166400
  if (isPlainObject2(embedding)) {
166162
166401
  const removed = [];
@@ -166335,7 +166574,7 @@ var init_project_security = __esm(() => {
166335
166574
  HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
166336
166575
  HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
166337
166576
  AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
166338
- EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider"];
166577
+ EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
166339
166578
  });
166340
166579
 
166341
166580
  // ../plugin/src/config/prune-config-leaf.ts
@@ -166370,12 +166609,38 @@ function pruneNestedConfigLeaf(block2, relativePath) {
166370
166609
  return { block: result, removed: relativePath.map(String).join(".") };
166371
166610
  }
166372
166611
 
166612
+ // ../plugin/src/config/transform-mode.ts
166613
+ function resolveTransformMode(args) {
166614
+ if (args.configured === "rust" && !args.userTierHasSubc) {
166615
+ return {
166616
+ mode: "ts",
166617
+ warnings: [RUST_REQUIRES_USER_SUBC_WARNING]
166618
+ };
166619
+ }
166620
+ const warnings = [];
166621
+ if (args.configured === "rust" && args.shadowTransformEnabled) {
166622
+ const projectKey = args.projectKey ?? "<unspecified-project>";
166623
+ if (!warnedShadowProjects.has(projectKey)) {
166624
+ warnedShadowProjects.add(projectKey);
166625
+ warnings.push(SHADOW_TRANSFORM_WARNING);
166626
+ }
166627
+ }
166628
+ if (args.configured === "rust" && args.cavemanCompressionEnabled) {
166629
+ warnings.push(CAVEMAN_RUST_WARNING);
166630
+ }
166631
+ return { mode: args.configured, warnings };
166632
+ }
166633
+ var warnedShadowProjects, RUST_REQUIRES_USER_SUBC_WARNING = "rust mode requires user-level subc configuration; running ts.", SHADOW_TRANSFORM_WARNING = 'shadow_transform is ignored while transform_mode is "rust" (a session cannot shadow itself); shadow disabled for these sessions.', CAVEMAN_RUST_WARNING = "caveman_text_compression is TS-only and inert in rust mode.";
166634
+ var init_transform_mode = __esm(() => {
166635
+ warnedShadowProjects = new Set;
166636
+ });
166637
+
166373
166638
  // ../plugin/src/config/variable.ts
166374
166639
  import { existsSync as existsSync18, readFileSync as readFileSync6 } from "node:fs";
166375
- import { homedir as homedir9 } from "node:os";
166640
+ import { homedir as homedir10 } from "node:os";
166376
166641
  import { dirname as dirname10, isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
166377
166642
  function sensitiveFilePathReason(resolvedPath) {
166378
- const home = homedir9();
166643
+ const home = homedir10();
166379
166644
  const sensitiveDirs = [
166380
166645
  { dir: resolve3(home, ".ssh"), label: "SSH keys" },
166381
166646
  { dir: resolve3(home, ".aws"), label: "AWS credentials" },
@@ -166438,7 +166703,7 @@ function substituteConfigVariables(input) {
166438
166703
  }
166439
166704
  let filePath = rawPath.trim();
166440
166705
  if (filePath.startsWith("~/")) {
166441
- filePath = resolve3(homedir9(), filePath.slice(2));
166706
+ filePath = resolve3(homedir10(), filePath.slice(2));
166442
166707
  } else if (!isAbsolute3(filePath)) {
166443
166708
  filePath = resolve3(configDir, filePath);
166444
166709
  }
@@ -166649,6 +166914,13 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
166649
166914
  function loadPluginConfig(directory) {
166650
166915
  return loadPluginConfigDetailed(directory).config;
166651
166916
  }
166917
+ function hasUserTierSubcConfig(config2) {
166918
+ const subc = config2?.subc;
166919
+ if (typeof subc !== "object" || subc === null || Array.isArray(subc))
166920
+ return false;
166921
+ const connectionFile = subc.connection_file;
166922
+ return typeof connectionFile === "string" && connectionFile.trim().length > 0;
166923
+ }
166652
166924
  function collectEmptyStringPaths(value, prefix = "") {
166653
166925
  if (typeof value === "string") {
166654
166926
  return value === "" && prefix ? [prefix] : [];
@@ -166747,6 +167019,15 @@ function loadPluginConfigDetailed(directory) {
166747
167019
  return `[project config] ${w}`;
166748
167020
  }));
166749
167021
  }
167022
+ const resolvedTransformMode = resolveTransformMode({
167023
+ configured: config2.transform_mode,
167024
+ userTierHasSubc: hasUserTierSubcConfig(userLoaded?.config),
167025
+ shadowTransformEnabled: config2.shadow_transform.enabled,
167026
+ cavemanCompressionEnabled: config2.caveman_text_compression.enabled,
167027
+ projectKey: directory
167028
+ });
167029
+ config2.transform_mode = resolvedTransformMode.mode;
167030
+ allWarnings.push(...resolvedTransformMode.warnings.map((warning) => `[config] ${warning}`));
166750
167031
  if (allWarnings.length > 0) {
166751
167032
  config2.configWarnings = allWarnings;
166752
167033
  } else if ("configWarnings" in config2) {
@@ -166774,6 +167055,7 @@ var init_config = __esm(() => {
166774
167055
  init_migrate_dreamer_v2();
166775
167056
  init_project_security();
166776
167057
  init_magic_context();
167058
+ init_transform_mode();
166777
167059
  init_variable();
166778
167060
  });
166779
167061
 
@@ -167162,7 +167444,7 @@ var init_compartment_parser = __esm(() => {
167162
167444
  });
167163
167445
 
167164
167446
  // ../plugin/src/shared/redaction.ts
167165
- import { homedir as homedir10, userInfo } from "node:os";
167447
+ import { homedir as homedir11, userInfo } from "node:os";
167166
167448
  function escapeRegex3(value) {
167167
167449
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
167168
167450
  }
@@ -167212,7 +167494,7 @@ function isSecretKey(key) {
167212
167494
  return false;
167213
167495
  }
167214
167496
  function sanitizePathString(value) {
167215
- const home = homedir10();
167497
+ const home = homedir11();
167216
167498
  const username = userInfo().username;
167217
167499
  let sanitized = value;
167218
167500
  if (home) {
@@ -167372,7 +167654,7 @@ var init_redaction2 = __esm(() => {
167372
167654
  // src/lib/diagnostics-opencode.ts
167373
167655
  import { existsSync as existsSync21, readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync8 } from "node:fs";
167374
167656
  import { createRequire as createRequire2 } from "node:module";
167375
- import { homedir as homedir11 } from "node:os";
167657
+ import { homedir as homedir12 } from "node:os";
167376
167658
  import { join as join18 } from "node:path";
167377
167659
  function getSelfVersion() {
167378
167660
  const require2 = createRequire2(import.meta.url);
@@ -167404,7 +167686,7 @@ function getPluginCacheInfo() {
167404
167686
  return { path: path6, cached: cached2, latest: getSelfVersion() };
167405
167687
  }
167406
167688
  function getStorageDir() {
167407
- const dataHome = process.env.XDG_DATA_HOME || join18(homedir11(), ".local", "share");
167689
+ const dataHome = process.env.XDG_DATA_HOME || join18(homedir12(), ".local", "share");
167408
167690
  return join18(dataHome, "cortexkit", "magic-context");
167409
167691
  }
167410
167692
  function fileSize(path6) {
@@ -167550,7 +167832,7 @@ function collectHistorianDumps(recentSessions) {
167550
167832
  };
167551
167833
  }
167552
167834
  async function collectRecentSessions() {
167553
- const dataHome = process.env.XDG_DATA_HOME || join18(process.env.HOME || homedir11(), ".local", "share");
167835
+ const dataHome = process.env.XDG_DATA_HOME || join18(process.env.HOME || homedir12(), ".local", "share");
167554
167836
  const opencodeDbPath = join18(dataHome, "opencode", "opencode.db");
167555
167837
  if (!existsSync21(opencodeDbPath))
167556
167838
  return [];
@@ -168627,7 +168909,7 @@ var init_doctor_opencode_cache = __esm(() => {
168627
168909
  import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
168628
168910
  import { existsSync as existsSync24, readFileSync as readFileSync12, statSync as statSync9 } from "node:fs";
168629
168911
  import { createRequire as createRequire4 } from "node:module";
168630
- import { homedir as homedir12 } from "node:os";
168912
+ import { homedir as homedir13 } from "node:os";
168631
168913
  import { join as join21 } from "node:path";
168632
168914
  function migrateLegacyAgentEnabledConfigForDoctor(mcConfig, logs) {
168633
168915
  let changed = false;
@@ -168718,7 +169000,7 @@ function getUserNpmrcPath() {
168718
169000
  if (custom2)
168719
169001
  return custom2;
168720
169002
  const home = process.env.HOME?.trim();
168721
- return join21(home || homedir12(), ".npmrc");
169003
+ return join21(home || homedir13(), ".npmrc");
168722
169004
  }
168723
169005
  function collectNpmReleaseAgeWarnings() {
168724
169006
  const ageWarnings = [];
@@ -169727,7 +170009,7 @@ var init_config2 = __esm(() => {
169727
170009
  import { createHash as createHash3 } from "node:crypto";
169728
170010
  import { existsSync as existsSync26, readdirSync as readdirSync3, readFileSync as readFileSync14, statSync as statSync10 } from "node:fs";
169729
170011
  import { createRequire as createRequire5 } from "node:module";
169730
- import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
170012
+ import { homedir as homedir14, userInfo as userInfo2 } from "node:os";
169731
170013
  import { join as join22 } from "node:path";
169732
170014
  function getSelfVersion3() {
169733
170015
  const req = createRequire5(import.meta.url);
@@ -169759,7 +170041,7 @@ function redactSecretString(value) {
169759
170041
  return redactSecretText(value).replace(/Bearer\s+[A-Za-z0-9._~+\-/=]+/g, "Bearer <REDACTED>").replace(/sk-[A-Za-z0-9_-]{12,}/g, "sk-<REDACTED>").replace(/api[_-]?key=([^\s&]+)/gi, "api_key=<REDACTED>").replace(/token=([^\s&]+)/gi, "token=<REDACTED>");
169760
170042
  }
169761
170043
  function sanitizeString2(value) {
169762
- const home = process.env.HOME || homedir13();
170044
+ const home = process.env.HOME || homedir14();
169763
170045
  const username = userInfo2().username;
169764
170046
  const userHash = `<USER:${currentUserHash()}>`;
169765
170047
  let sanitized = redactSecretString(value);
@@ -170194,7 +170476,7 @@ var init_logs_pi = __esm(() => {
170194
170476
  import { execFileSync as execFileSync4, spawnSync as spawnSync4 } from "node:child_process";
170195
170477
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync16, rmSync as rmSync3, statSync as statSync11 } from "node:fs";
170196
170478
  import { createRequire as createRequire6 } from "node:module";
170197
- import { homedir as homedir14 } from "node:os";
170479
+ import { homedir as homedir15 } from "node:os";
170198
170480
  import { dirname as dirname13, isAbsolute as isAbsolute4, join as join24 } from "node:path";
170199
170481
  function depsFrom(options) {
170200
170482
  return {
@@ -170389,7 +170671,7 @@ function pinnedVersionFromPackageSpecifier(specifier) {
170389
170671
  }
170390
170672
  function cacheRoots(cwd) {
170391
170673
  const home = process.env.HOME?.trim();
170392
- const cacheHome = process.env.XDG_CACHE_HOME || join24(home || homedir14(), ".cache");
170674
+ const cacheHome = process.env.XDG_CACHE_HOME || join24(home || homedir15(), ".cache");
170393
170675
  const piCacheRoot = getPiCacheRoot();
170394
170676
  return [
170395
170677
  join24(piCacheRoot, "extensions"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/magic-context",
3
- "version": "0.32.1",
3
+ "version": "0.32.2",
4
4
  "description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode and Pi",
5
5
  "keywords": [
6
6
  "opencode",