@cortexkit/magic-context 0.36.1 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +725 -169
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -12847,15 +12847,16 @@ Edit those files directly, then rerun setup.`);
12847
12847
  // ../plugin/src/shared/logger.ts
12848
12848
  import * as fs from "node:fs";
12849
12849
  import * as path2 from "node:path";
12850
- function ensureDir4(filePath) {
12851
- const dir = path2.dirname(filePath);
12852
- if (dir === lastEnsuredDir)
12853
- return;
12850
+ function recordSwallowedWrite(error) {
12854
12851
  try {
12855
- fs.mkdirSync(dir, { recursive: true });
12856
- lastEnsuredDir = dir;
12852
+ swallowedWriteCount++;
12853
+ lastErrorMessage = error instanceof Error ? error.message : String(error);
12854
+ lastErrorTime = new Date().toISOString();
12857
12855
  } catch {}
12858
12856
  }
12857
+ function ensureDir4(filePath) {
12858
+ fs.mkdirSync(path2.dirname(filePath), { recursive: true });
12859
+ }
12859
12860
  function flush() {
12860
12861
  if (flushTimer) {
12861
12862
  clearTimeout(flushTimer);
@@ -12869,7 +12870,9 @@ function flush() {
12869
12870
  const logFile = getMagicContextLogPath();
12870
12871
  ensureDir4(logFile);
12871
12872
  fs.appendFileSync(logFile, data);
12872
- } catch {}
12873
+ } catch (error) {
12874
+ recordSwallowedWrite(error);
12875
+ }
12873
12876
  }
12874
12877
  function scheduleFlush() {
12875
12878
  if (flushTimer)
@@ -12895,7 +12898,7 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
12895
12898
  }
12896
12899
  } catch {}
12897
12900
  }
12898
- var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
12901
+ var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, swallowedWriteCount = 0, lastErrorMessage = null, lastErrorTime = null;
12899
12902
  var init_logger = __esm(() => {
12900
12903
  init_data_path();
12901
12904
  buffer = [];
@@ -12903,6 +12906,43 @@ var init_logger = __esm(() => {
12903
12906
  process.on("exit", flush);
12904
12907
  }
12905
12908
  });
12909
+ // ../plugin/src/shared/window-geometry.ts
12910
+ function setWindowOverlayPath(path3) {
12911
+ configuredOverlayPath = path3;
12912
+ loadedOverlayPath = undefined;
12913
+ loadedOverlay = undefined;
12914
+ }
12915
+ var GRADES, UNITS, BOUNDARIES, UNKNOWN_REASONS, NUMERIC_FACT_KEYS, configuredOverlayPath, loadedOverlayPath, loadedOverlay, geometryClampLogSeen;
12916
+ var init_window_geometry = __esm(() => {
12917
+ init_data_path();
12918
+ init_harness_provider_map();
12919
+ init_logger();
12920
+ GRADES = new Set([
12921
+ "provider_asserted_runtime",
12922
+ "measured",
12923
+ "provider_asserted_doc",
12924
+ "catalog",
12925
+ "unknown"
12926
+ ]);
12927
+ UNITS = new Set(["provider", "estimate"]);
12928
+ BOUNDARIES = new Set(["Observed", "Asserted", "Corrected"]);
12929
+ UNKNOWN_REASONS = new Set([
12930
+ "placeholder_output_equals_context",
12931
+ "placeholder_zero",
12932
+ "never_measured",
12933
+ "not_single_valued_at_key",
12934
+ "retracted"
12935
+ ]);
12936
+ NUMERIC_FACT_KEYS = new Set([
12937
+ "window.advertised",
12938
+ "window.enforced",
12939
+ "output.advertised",
12940
+ "output.enforced",
12941
+ "output.default"
12942
+ ]);
12943
+ geometryClampLogSeen = new Set;
12944
+ });
12945
+
12906
12946
  // ../plugin/src/shared/models-dev-cache.ts
12907
12947
  function setOutputReserveConfig(config) {
12908
12948
  outputReserveConfig = config;
@@ -12912,6 +12952,7 @@ var init_models_dev_cache = __esm(() => {
12912
12952
  init_data_path();
12913
12953
  init_harness_provider_map();
12914
12954
  init_logger();
12955
+ init_window_geometry();
12915
12956
  SEPARATE_OUTPUT_QUOTA_PROVIDERS = new Set(["google", "google-antigravity"]);
12916
12957
  reserveClampLogSeen = new Set;
12917
12958
  });
@@ -27951,6 +27992,9 @@ function isValidPromptSurfaceModelKey(key) {
27951
27992
  return true;
27952
27993
  return modelID.length > 0 && !modelID.startsWith("/") && !modelID.endsWith("/") && !modelID.includes("//");
27953
27994
  }
27995
+ var init_prompt_surface = __esm(() => {
27996
+ init_harness_provider_map();
27997
+ });
27954
27998
 
27955
27999
  // ../plugin/src/config/schema/agent-overrides.ts
27956
28000
  var PermissionValueSchema, PermissionSchema, AgentOverrideConfigSchema;
@@ -28005,6 +28049,7 @@ var init_magic_context = __esm(() => {
28005
28049
  init_zod();
28006
28050
  init_language_directive();
28007
28051
  init_cron();
28052
+ init_prompt_surface();
28008
28053
  init_agent_overrides();
28009
28054
  PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh", "max"]).optional();
28010
28055
  PiConfigSchema = exports_external.object({
@@ -28201,6 +28246,9 @@ var init_magic_context = __esm(() => {
28201
28246
  exports_external.number().min(0),
28202
28247
  exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
28203
28248
  ]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
28249
+ models: exports_external.object({
28250
+ window_overlay_path: exports_external.string().trim().min(1).optional()
28251
+ }).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
28204
28252
  toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
28205
28253
  execute_threshold_percentage: exports_external.union([
28206
28254
  exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
@@ -28407,6 +28455,11 @@ function stripUnsafeProjectConfigFields(projectRaw) {
28407
28455
  delete projectRaw.output_reserve;
28408
28456
  warnings.push("Ignoring output_reserve from project config (security: output-token reservation only honors user-level config).");
28409
28457
  }
28458
+ const models = projectRaw.models;
28459
+ if (isPlainObject2(models) && "window_overlay_path" in models) {
28460
+ delete models.window_overlay_path;
28461
+ warnings.push("Ignoring models.window_overlay_path from project config (security: only user-level config may select model geometry metadata).");
28462
+ }
28410
28463
  if ("language" in projectRaw) {
28411
28464
  delete projectRaw.language;
28412
28465
  warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
@@ -29085,6 +29138,7 @@ function loadPluginConfigDetailed(directory) {
29085
29138
  const recoveredTopLevelKeys = [];
29086
29139
  const config2 = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
29087
29140
  setOutputReserveConfig(config2.output_reserve);
29141
+ setWindowOverlayPath(config2.models?.window_overlay_path);
29088
29142
  if (config2.configWarnings?.length) {
29089
29143
  allWarnings.push(...config2.configWarnings.map((w) => {
29090
29144
  if (userLoaded && projectLoaded)
@@ -29126,6 +29180,7 @@ function loadPluginConfigDetailed(directory) {
29126
29180
  var init_config = __esm(() => {
29127
29181
  init_jsonc_parser();
29128
29182
  init_models_dev_cache();
29183
+ init_window_geometry();
29129
29184
  init_agent_disable();
29130
29185
  init_migrate_config_location();
29131
29186
  init_migrate_dreamer_v2();
@@ -29176,14 +29231,17 @@ function detectConflicts(directory, options) {
29176
29231
  omoAnthropicRecovery: false
29177
29232
  };
29178
29233
  const reasons = [];
29179
- const compactionResult = checkCompaction(directory);
29234
+ let compactionResult = options?.resolvedCompaction ?? checkCompaction(directory);
29235
+ if (process.env.OPENCODE_DISABLE_AUTOCOMPACT) {
29236
+ compactionResult = { auto: false, prune: false };
29237
+ }
29180
29238
  if (compactionEnabled && compactionResult.auto) {
29181
29239
  conflicts.compactionAuto = true;
29182
- reasons.push("OpenCode auto-compaction is enabled (compaction.auto=true)");
29240
+ reasons.push(options?.resolvedCompaction ? "OpenCode auto-compaction is enabled (compaction.auto=true) (resolved config)" : "OpenCode auto-compaction is enabled (compaction.auto=true)");
29183
29241
  }
29184
29242
  if (compactionEnabled && compactionResult.prune) {
29185
29243
  conflicts.compactionPrune = true;
29186
- reasons.push("OpenCode prune is enabled (compaction.prune=true)");
29244
+ reasons.push(options?.resolvedCompaction ? "OpenCode prune is enabled (compaction.prune=true) (resolved config)" : "OpenCode prune is enabled (compaction.prune=true)");
29187
29245
  }
29188
29246
  const dcpFound = checkDcpPlugin(directory);
29189
29247
  if (dcpFound) {
@@ -29371,6 +29429,7 @@ function readOmoDisabledHooks(directory) {
29371
29429
  var DCP_PACKAGE_NAMES, OMO_PACKAGE_NAMES;
29372
29430
  var init_conflict_detector = __esm(() => {
29373
29431
  init_jsonc_parser();
29432
+ init_logger();
29374
29433
  init_opencode_config_dir();
29375
29434
  DCP_PACKAGE_NAMES = new Set(["@tarquinen/opencode-dcp"]);
29376
29435
  OMO_PACKAGE_NAMES = new Set(["oh-my-opencode", "oh-my-openagent"]);
@@ -30671,6 +30730,7 @@ function prepareMirrorPageStatements(db) {
30671
30730
  return {
30672
30731
  identityByModule: db.prepare("SELECT context_row_id FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
30673
30732
  insertIdentity: db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)"),
30733
+ deleteIdentityByContext: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?"),
30674
30734
  deleteLiveMemory: db.prepare("DELETE FROM mirror_live_memory_rows WHERE module_project = ? AND module_row_id = ?"),
30675
30735
  deletePendingReferencesForMemory: db.prepare("DELETE FROM mirror_pending_references WHERE domain = ? AND module_project = ? AND (module_row_id = ? OR target_module_row_id = ?)"),
30676
30736
  deleteIdentity: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
@@ -30722,7 +30782,7 @@ function prepareMirrorPageStatements(db) {
30722
30782
  check_quarantined_until = ?, check_next_due_at = ?, check_compiled_at = ?, check_false_since_at = ?,
30723
30783
  check_last_liveness_at = ?, last_checked_at = ?, check_status = ?, check_version = ?,
30724
30784
  policy_version = ?, anchor_block_id = ?, anchor_ordinal = ?, created_at = ?, updated_at = ? WHERE id = ?`),
30725
- upsertNoteRevision: db.prepare("INSERT INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?) ON CONFLICT(module_project, module_row_id) DO UPDATE SET context_row_id = excluded.context_row_id, status_version = excluded.status_version"),
30785
+ upsertNoteRevision: db.prepare("INSERT OR REPLACE INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)"),
30726
30786
  translateMemoryReferences: db.prepare(`UPDATE memories
30727
30787
  SET superseded_by_memory_id = (
30728
30788
  SELECT target.context_row_id
@@ -30795,6 +30855,9 @@ function rememberIdentity(db, domain2, moduleProject, moduleRowId, contextRowId,
30795
30855
  const existing = mirrorIdentity(db, domain2, moduleProject, moduleRowId, statements);
30796
30856
  if (existing)
30797
30857
  return;
30858
+ if (domain2 === "notes") {
30859
+ (statements?.deleteIdentityByContext ?? db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?")).run(domain2, contextRowId);
30860
+ }
30798
30861
  (statements?.insertIdentity ?? db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)")).run(domain2, moduleProject, moduleRowId, contextRowId);
30799
30862
  }
30800
30863
  function contextMemoryId(db, domain2, moduleProject, row, moduleRowId, statements) {
@@ -31427,11 +31490,12 @@ function gitRootInAncestorChain(startDirectory) {
31427
31490
  function hasGitDirInAncestorChain(startDirectory) {
31428
31491
  return gitRootInAncestorChain(startDirectory) !== null;
31429
31492
  }
31430
- var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, execFileSyncForIdentity, nowMs = () => Date.now(), ProjectIdentityError;
31493
+ var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, execFileSyncForIdentity, nowMs = () => Date.now(), ProjectIdentityError;
31431
31494
  var init_project_identity = __esm(() => {
31432
31495
  init_logger();
31433
31496
  TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
31434
31497
  identityCache = new Map;
31498
+ linkedGitWorktreeCache = new Map;
31435
31499
  lastKnownGitIdentityCache = new Map;
31436
31500
  directoryFallbackCache = new Map;
31437
31501
  transientFailureCooldown = new Map;
@@ -33731,6 +33795,7 @@ class SubcModuleTransport {
33731
33795
  return error51;
33732
33796
  }
33733
33797
  async beforeDeadline(operation, deadlineMs, detail) {
33798
+ operation.catch(() => {});
33734
33799
  const remainingMs = deadlineMs - Date.now();
33735
33800
  if (remainingMs <= 0)
33736
33801
  throw this.deadlineError(detail);
@@ -34145,12 +34210,14 @@ import { execFileSync as execFileSync4 } from "node:child_process";
34145
34210
  import { readFileSync as readFileSync12 } from "node:fs";
34146
34211
  function isPidAlive(pid) {
34147
34212
  if (!Number.isInteger(pid) || pid <= 0)
34148
- return false;
34213
+ return "dead";
34214
+ if (rpcIdentityPlatform === "win32")
34215
+ return readWindowsProcess(pid).state;
34149
34216
  try {
34150
- process.kill(pid, 0);
34151
- return true;
34152
- } catch (err) {
34153
- return err.code === "EPERM";
34217
+ rpcIdentityProcessKill(pid, 0);
34218
+ return "alive";
34219
+ } catch (error51) {
34220
+ return error51.code === "ESRCH" ? "dead" : "inconclusive";
34154
34221
  }
34155
34222
  }
34156
34223
  function parseLinuxProcessStartTime(statContent, uptimeContent) {
@@ -34179,7 +34246,8 @@ function readPsProcessStartTime(pid) {
34179
34246
  try {
34180
34247
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
34181
34248
  encoding: "utf8",
34182
- timeout: PS_PROBE_TIMEOUT_MS
34249
+ timeout: PS_PROBE_TIMEOUT_MS,
34250
+ stdio: ["ignore", "pipe", "pipe"]
34183
34251
  });
34184
34252
  const processStartTime = Date.parse(String(output).trim());
34185
34253
  return Number.isFinite(processStartTime) ? processStartTime : null;
@@ -34187,6 +34255,70 @@ function readPsProcessStartTime(pid) {
34187
34255
  return null;
34188
34256
  }
34189
34257
  }
34258
+ function parseCsvLine(line) {
34259
+ const fields = [];
34260
+ let field = "";
34261
+ let quoted = false;
34262
+ for (let index = 0;index < line.length; index += 1) {
34263
+ const character = line[index];
34264
+ if (character === '"') {
34265
+ if (quoted && line[index + 1] === '"') {
34266
+ field += '"';
34267
+ index += 1;
34268
+ } else {
34269
+ quoted = !quoted;
34270
+ }
34271
+ } else if (character === "," && !quoted) {
34272
+ fields.push(field);
34273
+ field = "";
34274
+ } else {
34275
+ field += character;
34276
+ }
34277
+ }
34278
+ if (quoted)
34279
+ return null;
34280
+ fields.push(field);
34281
+ return fields;
34282
+ }
34283
+ function parseTasklistOutput(output) {
34284
+ const entries = [];
34285
+ let sawHeader = false;
34286
+ for (const rawLine of output.split(/\r?\n/)) {
34287
+ const line = rawLine.trim();
34288
+ if (!line)
34289
+ continue;
34290
+ if (TASKLIST_NO_TASKS_PATTERN.test(line))
34291
+ return [];
34292
+ const fields = parseCsvLine(line);
34293
+ if (!fields)
34294
+ continue;
34295
+ if (fields[1]?.trim().toLowerCase() === "pid") {
34296
+ sawHeader = true;
34297
+ continue;
34298
+ }
34299
+ const pid = Number(fields[1]);
34300
+ if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
34301
+ continue;
34302
+ entries.push({ pid, command: fields[0] });
34303
+ }
34304
+ return entries.length > 0 || sawHeader ? entries : null;
34305
+ }
34306
+ function readWindowsProcess(pid) {
34307
+ try {
34308
+ const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
34309
+ encoding: "utf8",
34310
+ timeout: PS_PROBE_TIMEOUT_MS,
34311
+ stdio: ["ignore", "pipe", "pipe"]
34312
+ });
34313
+ const entries = parseTasklistOutput(String(output));
34314
+ if (entries === null)
34315
+ return { state: "inconclusive" };
34316
+ const process3 = entries.find((entry) => entry.pid === pid);
34317
+ return process3 ? { state: "alive", command: process3.command } : { state: "dead" };
34318
+ } catch {
34319
+ return { state: "inconclusive" };
34320
+ }
34321
+ }
34190
34322
  function readLinuxProcessCommand(pid) {
34191
34323
  try {
34192
34324
  return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
@@ -34198,7 +34330,8 @@ function readPsProcessCommand(pid) {
34198
34330
  try {
34199
34331
  const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
34200
34332
  encoding: "utf8",
34201
- timeout: PS_PROBE_TIMEOUT_MS
34333
+ timeout: PS_PROBE_TIMEOUT_MS,
34334
+ stdio: ["ignore", "pipe", "pipe"]
34202
34335
  });
34203
34336
  return String(output);
34204
34337
  } catch {
@@ -34211,17 +34344,17 @@ function commandLooksLikeOpenCode(command) {
34211
34344
  }
34212
34345
  function isPidIdentityPlausible(record2) {
34213
34346
  if (!Number.isInteger(record2.pid) || record2.pid <= 0)
34214
- return false;
34347
+ return "implausible";
34215
34348
  if (Number.isFinite(record2.started_at) && record2.started_at > 0) {
34216
- const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record2.pid) : readPsProcessStartTime(record2.pid);
34349
+ const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record2.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record2.pid);
34217
34350
  if (processStartTime === null)
34218
- return true;
34219
- return processStartTime <= record2.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
34351
+ return "inconclusive";
34352
+ return processStartTime <= record2.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
34220
34353
  }
34221
- const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record2.pid) : readPsProcessCommand(record2.pid);
34354
+ const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record2.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record2.pid).command ?? null : readPsProcessCommand(record2.pid);
34222
34355
  if (command === null)
34223
- return true;
34224
- return commandLooksLikeOpenCode(command);
34356
+ return "inconclusive";
34357
+ return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
34225
34358
  }
34226
34359
  function commandLooksLikePi(command) {
34227
34360
  const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
@@ -34239,20 +34372,39 @@ function commandLooksLikePi(command) {
34239
34372
  function inspectLivePiProcesses() {
34240
34373
  if (false) {}
34241
34374
  try {
34242
- const output = String(rpcProcessListExecFileSync("ps", ["-axo", "pid=,command="], {
34375
+ const isWindows = rpcIdentityPlatform === "win32";
34376
+ const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
34243
34377
  encoding: "utf8",
34244
- timeout: PS_PROBE_TIMEOUT_MS
34378
+ timeout: PS_PROBE_TIMEOUT_MS,
34379
+ stdio: ["ignore", "pipe", "pipe"]
34245
34380
  }));
34246
34381
  const pids = new Set;
34247
- for (const line of output.split(/\r?\n/)) {
34248
- const match = /^\s*(\d+)\s+(.+)$/.exec(line);
34249
- if (!match)
34250
- continue;
34251
- const pid = Number(match[1]);
34252
- if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
34253
- continue;
34254
- if (commandLooksLikePi(match[2]))
34255
- pids.add(pid);
34382
+ if (isWindows) {
34383
+ const entries = parseTasklistOutput(output);
34384
+ if (entries === null) {
34385
+ return {
34386
+ state: "unreadable",
34387
+ processIds: [],
34388
+ error: "tasklist output unavailable"
34389
+ };
34390
+ }
34391
+ for (const entry of entries) {
34392
+ if (entry.pid === process.pid)
34393
+ continue;
34394
+ if (commandLooksLikePi(entry.command))
34395
+ pids.add(entry.pid);
34396
+ }
34397
+ } else {
34398
+ for (const line of output.split(/\r?\n/)) {
34399
+ const match = /^\s*(\d+)\s+(.+)$/.exec(line);
34400
+ if (!match)
34401
+ continue;
34402
+ const pid = Number(match[1]);
34403
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
34404
+ continue;
34405
+ if (commandLooksLikePi(match[2]))
34406
+ pids.add(pid);
34407
+ }
34256
34408
  }
34257
34409
  return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
34258
34410
  } catch (error51) {
@@ -34297,11 +34449,13 @@ function parseRpcPortFile(content, fallbackPid = 0) {
34297
34449
  function isValidPort(port) {
34298
34450
  return Number.isInteger(port) && port > 0 && port <= 65535;
34299
34451
  }
34300
- var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, OPEN_CODE_COMMAND_MARKERS, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now();
34452
+ var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000, LINUX_CLOCK_TICKS_PER_SECOND = 100, PS_PROBE_TIMEOUT_MS = 1000, OPEN_CODE_COMMAND_MARKERS, TASKLIST_NO_TASKS_PATTERN, rpcIdentityReadFileSync, rpcIdentityExecFileSync, rpcIdentityProcessKill, rpcProcessListExecFileSync, rpcIdentityPlatform, rpcIdentityNowMs = () => Date.now();
34301
34453
  var init_rpc_utils = __esm(() => {
34302
34454
  OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
34455
+ TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
34303
34456
  rpcIdentityReadFileSync = readFileSync12;
34304
34457
  rpcIdentityExecFileSync = execFileSync4;
34458
+ rpcIdentityProcessKill = process.kill;
34305
34459
  rpcProcessListExecFileSync = execFileSync4;
34306
34460
  rpcIdentityPlatform = process.platform;
34307
34461
  });
@@ -34528,6 +34682,8 @@ function healAllNullColumns(db) {
34528
34682
  ["stripped_placeholder_ids", ""],
34529
34683
  ["stale_reduce_stripped_ids", ""],
34530
34684
  ["processed_image_stripped_ids", ""],
34685
+ ["merged_reasoning_stripped_ids", ""],
34686
+ ["trailing_blank_decisions", ""],
34531
34687
  ["memory_block_cache", ""],
34532
34688
  ["memory_block_ids", ""],
34533
34689
  ["compaction_marker_state", ""],
@@ -34981,6 +35137,7 @@ var init_migrations = __esm(() => {
34981
35137
  status TEXT NOT NULL DEFAULT 'active',
34982
35138
  promoted_at INTEGER NOT NULL,
34983
35139
  source_candidate_ids TEXT DEFAULT '[]',
35140
+ source_candidate_provenance TEXT,
34984
35141
  created_at INTEGER NOT NULL,
34985
35142
  updated_at INTEGER NOT NULL
34986
35143
  );
@@ -36007,6 +36164,7 @@ var init_migrations = __esm(() => {
36007
36164
  last_observed_at INTEGER,
36008
36165
  answer_refreshed_at INTEGER,
36009
36166
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
36167
+ source_candidate_provenance TEXT,
36010
36168
  created_at INTEGER NOT NULL,
36011
36169
  updated_at INTEGER NOT NULL
36012
36170
  );
@@ -36816,6 +36974,37 @@ var init_migrations = __esm(() => {
36816
36974
  ensureColumn(db, "notes", "compiled_at", "INTEGER");
36817
36975
  ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
36818
36976
  }
36977
+ },
36978
+ {
36979
+ version: 77,
36980
+ description: "persist scoped provenance for promoted user memories and primers",
36981
+ up(db) {
36982
+ if (tableExists(db, "user_memories")) {
36983
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
36984
+ }
36985
+ if (tableExists(db, "primers")) {
36986
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
36987
+ }
36988
+ }
36989
+ },
36990
+ {
36991
+ version: 78,
36992
+ description: "add migration_pending journal for crash-safe cross-harness session migration",
36993
+ up(db) {
36994
+ db.exec(`
36995
+ CREATE TABLE IF NOT EXISTS migration_pending (
36996
+ migration_key TEXT PRIMARY KEY,
36997
+ source_session_id TEXT NOT NULL,
36998
+ target_harness TEXT NOT NULL,
36999
+ pi_session_id TEXT NOT NULL,
37000
+ final_path TEXT NOT NULL,
37001
+ stage_path TEXT NOT NULL,
37002
+ content_sha256 TEXT NOT NULL,
37003
+ phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
37004
+ created_at INTEGER NOT NULL
37005
+ );
37006
+ `);
37007
+ }
36819
37008
  }
36820
37009
  ];
36821
37010
  LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m3) => Math.max(max, m3.version), 0);
@@ -36944,6 +37133,7 @@ function inspectRpcServerDiscovery(storageDir) {
36944
37133
  }
36945
37134
  const pids = new Set;
36946
37135
  const staleFiles = [];
37136
+ const inconclusivePids = new Set;
36947
37137
  for (const portFile of portFiles) {
36948
37138
  let raw;
36949
37139
  try {
@@ -36963,10 +37153,15 @@ function inspectRpcServerDiscovery(storageDir) {
36963
37153
  return junk;
36964
37154
  continue;
36965
37155
  }
36966
- if (isPidAlive(record2.pid) && isPidIdentityPlausible(record2))
37156
+ const liveness = isPidAlive(record2.pid);
37157
+ const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record2);
37158
+ if (liveness === "alive" && identity === "plausible") {
36967
37159
  pids.add(record2.pid);
36968
- else
37160
+ } else if (liveness === "dead" || identity === "implausible") {
36969
37161
  staleFiles.push(portFile);
37162
+ } else {
37163
+ inconclusivePids.add(record2.pid);
37164
+ }
36970
37165
  }
36971
37166
  for (const staleFile of staleFiles) {
36972
37167
  try {
@@ -36979,6 +37174,15 @@ function inspectRpcServerDiscovery(storageDir) {
36979
37174
  if (serverPids.length > 0) {
36980
37175
  return { state: "live", serverPids, staleFiles };
36981
37176
  }
37177
+ const uncertainPids = [...inconclusivePids].sort((a3, b2) => a3 - b2);
37178
+ if (uncertainPids.length > 0) {
37179
+ return {
37180
+ state: "inconclusive",
37181
+ serverPids: [],
37182
+ staleFiles,
37183
+ inconclusivePids: uncertainPids
37184
+ };
37185
+ }
36982
37186
  return { state: "stale", serverPids: [], staleFiles };
36983
37187
  }
36984
37188
  function getLiveMigrationBlockingProcesses(storageDir) {
@@ -37163,6 +37367,7 @@ function initializeDatabase(db) {
37163
37367
  last_observed_at INTEGER,
37164
37368
  answer_refreshed_at INTEGER,
37165
37369
  source_candidate_ids TEXT NOT NULL DEFAULT '[]',
37370
+ source_candidate_provenance TEXT,
37166
37371
  created_at INTEGER NOT NULL,
37167
37372
  updated_at INTEGER NOT NULL
37168
37373
  );
@@ -37798,6 +38003,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
37798
38003
  ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
37799
38004
  ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
37800
38005
  ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
38006
+ ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
38007
+ const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
38008
+ if (hasUserMemoriesTable) {
38009
+ ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
38010
+ }
37801
38011
  db.exec(`
37802
38012
  CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
37803
38013
  ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
@@ -37871,6 +38081,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
37871
38081
  ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
37872
38082
  ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
37873
38083
  ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
38084
+ ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
38085
+ ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
37874
38086
  ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
37875
38087
  ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
37876
38088
  ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
@@ -38089,7 +38301,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
38089
38301
  ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
38090
38302
  ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
38091
38303
  }
38092
- var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 76, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig;
38304
+ var databases, pendingAsyncOpens, persistenceByDatabase, persistenceErrorByDatabase, pathByDatabase, LATEST_SUPPORTED_VERSION = 78, PERMISSIONS_ENFORCEABLE, RPC_DISCOVERY_PARSE_GRACE_MS, defaultRpcDiscoveryFs, rpcDiscoveryFs, sqlitePragmaConfig;
38093
38305
  var init_storage_db = __esm(async () => {
38094
38306
  init_data_path();
38095
38307
  init_logger();
@@ -38224,8 +38436,44 @@ var init_database_access = __esm(async () => {
38224
38436
  var exports_doctor_authority = {};
38225
38437
  __export(exports_doctor_authority, {
38226
38438
  runDoctorDrainAuthority: () => runDoctorDrainAuthority,
38227
- reportAuthorityMarkers: () => reportAuthorityMarkers
38439
+ reportAuthorityMarkers: () => reportAuthorityMarkers,
38440
+ authorityDrainCommand: () => authorityDrainCommand,
38441
+ assertProjectsUseTsAuthority: () => assertProjectsUseTsAuthority
38228
38442
  });
38443
+ function authorityDrainCommand(project) {
38444
+ return `magic-context doctor drain-authority ${project.projectRoot ?? `<${project.role} project root>`}`;
38445
+ }
38446
+ async function assertProjectsUseTsAuthority(args) {
38447
+ const markers = listAuthorityManagedMarkers(args.db);
38448
+ const markerByProject = new Map(markers.map((marker) => [marker.project_path, marker]));
38449
+ for (const project of args.projects) {
38450
+ const marker = markerByProject.get(project.projectPath);
38451
+ if (!marker)
38452
+ continue;
38453
+ const projectRoot = project.projectRoot;
38454
+ if (!projectRoot) {
38455
+ throw new Error(`Migration refused: durable module authority for ${project.role} project ${project.projectPath} cannot be checked because its project directory is unavailable. ` + `Writes remain fenced. Drain it first: ${authorityDrainCommand(project)}`);
38456
+ }
38457
+ let statuses;
38458
+ try {
38459
+ statuses = await Promise.all(AUTHORITY_DOMAINS.map((domain2) => args.module.authorityStatus({
38460
+ context_store_uuid: marker.context_store_uuid,
38461
+ project: project.projectPath,
38462
+ projectRoot,
38463
+ domain: domain2
38464
+ })));
38465
+ } catch (error51) {
38466
+ throw new Error(`Migration refused: module unreachable while checking ${project.role} project ${project.projectPath}; writes remain fenced. ` + `Drain it first: ${authorityDrainCommand(project)}. ` + `Module error: ${error51 instanceof Error ? error51.message : String(error51)}`);
38467
+ }
38468
+ for (const [index, status] of statuses.entries()) {
38469
+ const state = status.authority?.state ?? "TS";
38470
+ if (state === "TS")
38471
+ continue;
38472
+ throw new Error(`Migration refused: ${project.role} project ${project.projectPath} has ${AUTHORITY_DOMAINS[index]} authority in ${state} mode; writes remain fenced. ` + `Drain it first: ${authorityDrainCommand(project)}`);
38473
+ }
38474
+ }
38475
+ return { markers };
38476
+ }
38229
38477
  function authorityClient(transport, projectRoot) {
38230
38478
  return {
38231
38479
  authorityStatus: (request) => transport.authorityStatus({ ...request, projectRoot }),
@@ -38258,12 +38506,12 @@ async function reportAuthorityMarkers(args) {
38258
38506
  }
38259
38507
  try {
38260
38508
  const module = authorityClient(transport, process.cwd());
38261
- const statuses = await Promise.all(DOMAINS.map((domain2) => module.authorityStatus({
38509
+ const statuses = await Promise.all(AUTHORITY_DOMAINS.map((domain2) => module.authorityStatus({
38262
38510
  context_store_uuid: ensureContextStoreUuid(args.db),
38263
38511
  project: marker.project_path,
38264
38512
  domain: domain2
38265
38513
  })));
38266
- args.info(` ${marker.project_path}: ${statuses.map((status, index) => `${DOMAINS[index]}=${status.authority?.state ?? "TS"}`).join(", ")}`);
38514
+ args.info(` ${marker.project_path}: ${statuses.map((status, index) => `${AUTHORITY_DOMAINS[index]}=${status.authority?.state ?? "TS"}`).join(", ")}`);
38267
38515
  } catch {
38268
38516
  args.warn(` ${marker.project_path}: module unreachable — writes fenced; run with rust mode or restore subc connectivity`);
38269
38517
  }
@@ -38283,7 +38531,7 @@ async function runDoctorDrainAuthority(projectRoot, dbPath) {
38283
38531
  }
38284
38532
  const module = authorityClient(new SubcModuleTransport, projectRoot);
38285
38533
  let drainedAny = false;
38286
- for (const domain2 of DOMAINS) {
38534
+ for (const domain2 of AUTHORITY_DOMAINS) {
38287
38535
  const status = await module.authorityStatus({
38288
38536
  context_store_uuid: ensureContextStoreUuid(db),
38289
38537
  project: projectPath,
@@ -38327,7 +38575,6 @@ async function runDoctorDrainAuthority(projectRoot, dbPath) {
38327
38575
  db.close();
38328
38576
  }
38329
38577
  }
38330
- var DOMAINS;
38331
38578
  var init_doctor_authority = __esm(async () => {
38332
38579
  init_project_identity();
38333
38580
  init_storage_project_state();
@@ -38336,7 +38583,6 @@ var init_doctor_authority = __esm(async () => {
38336
38583
  init_context_authority(),
38337
38584
  init_database_access()
38338
38585
  ]);
38339
- DOMAINS = ["memories", "notes"];
38340
38586
  });
38341
38587
 
38342
38588
  // ../plugin/src/features/magic-context/storage-identity-merge.ts
@@ -39225,17 +39471,20 @@ var init_migration_paths = () => {};
39225
39471
  // src/commands/migrate.ts
39226
39472
  var exports_migrate = {};
39227
39473
  __export(exports_migrate, {
39474
+ sweepPendingMigrations: () => sweepPendingMigrations,
39228
39475
  runMigrateCli: () => runMigrateCli,
39229
39476
  projectPathToPiDirSlug: () => projectPathToPiDirSlug,
39230
39477
  printMigrateHelp: () => printMigrateHelp,
39231
39478
  parseMigrateArgs: () => parseMigrateArgs,
39479
+ migrationKeyFor: () => migrationKeyFor,
39232
39480
  migrateOpenCodeSessionToPi: () => migrateOpenCodeSessionToPi,
39233
39481
  generateUuidV7: () => generateUuidV7,
39234
- formatPiFilenameTimestamp: () => formatPiFilenameTimestamp
39482
+ formatPiFilenameTimestamp: () => formatPiFilenameTimestamp,
39483
+ formatMigrationSweepLines: () => formatMigrationSweepLines
39235
39484
  });
39236
- import { randomBytes as randomBytes2 } from "node:crypto";
39237
- import { unlinkSync as unlinkSync3 } from "node:fs";
39238
- import { join as join18 } from "node:path";
39485
+ import { createHash as createHash3, randomBytes as randomBytes2 } from "node:crypto";
39486
+ import { existsSync as existsSync21, mkdirSync as mkdirSync8, renameSync as renameSync4, unlinkSync as unlinkSync3 } from "node:fs";
39487
+ import { dirname as dirname12, join as join18 } from "node:path";
39239
39488
  function defaultOpenCodeDbPath() {
39240
39489
  return getOpenCodeDatabasePath();
39241
39490
  }
@@ -39246,7 +39495,7 @@ function defaultPiSessionsRoot() {
39246
39495
  return getPiSessionsRoot();
39247
39496
  }
39248
39497
  function defaultFs() {
39249
- return { writeFileAtomic, unlinkSync: unlinkSync3 };
39498
+ return { writeFileAtomic, unlinkSync: unlinkSync3, existsSync: existsSync21, renameSync: renameSync4, mkdirSync: mkdirSync8 };
39250
39499
  }
39251
39500
  function stmt(db, sql) {
39252
39501
  return db.prepare(sql);
@@ -39272,6 +39521,74 @@ function generateUuidV7(date5 = new Date) {
39272
39521
  function shortId() {
39273
39522
  return randomBytes2(4).toString("hex");
39274
39523
  }
39524
+ function migrationKeyFor(sourceSessionId, targetHarness) {
39525
+ return createHash3("sha256").update(`${sourceSessionId}
39526
+ ${targetHarness}`).digest("hex");
39527
+ }
39528
+ function hasMigrationJournal(db) {
39529
+ return Boolean(stmt(db, "SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'migration_pending'").get());
39530
+ }
39531
+ function sweepPendingMigrations(db, fs3 = defaultFs()) {
39532
+ const report = {
39533
+ completed: 0,
39534
+ rolledForward: 0,
39535
+ rolledBack: 0,
39536
+ lost: []
39537
+ };
39538
+ if (!hasMigrationJournal(db))
39539
+ return report;
39540
+ const rows = stmt(db, `SELECT migration_key, source_session_id, target_harness, pi_session_id,
39541
+ final_path, stage_path, content_sha256, phase, created_at
39542
+ FROM migration_pending
39543
+ ORDER BY created_at ASC`).all();
39544
+ for (const row of rows) {
39545
+ if (fs3.existsSync(row.final_path)) {
39546
+ stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
39547
+ report.completed += 1;
39548
+ continue;
39549
+ }
39550
+ if (row.phase === "db_committed") {
39551
+ if (fs3.existsSync(row.stage_path)) {
39552
+ fs3.mkdirSync(dirname12(row.final_path), { recursive: true });
39553
+ fs3.renameSync(row.stage_path, row.final_path);
39554
+ stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
39555
+ report.rolledForward += 1;
39556
+ } else {
39557
+ report.lost.push(row);
39558
+ }
39559
+ continue;
39560
+ }
39561
+ try {
39562
+ fs3.unlinkSync(row.stage_path);
39563
+ } catch {}
39564
+ stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
39565
+ report.rolledBack += 1;
39566
+ }
39567
+ return report;
39568
+ }
39569
+ function readPendingMigration(db, migrationKey) {
39570
+ return stmt(db, JOURNAL_SELECT_SQL).get(migrationKey);
39571
+ }
39572
+ function claimJournalIdentity(args) {
39573
+ const existing = readPendingMigration(args.db, args.migrationKey);
39574
+ if (existing) {
39575
+ return { row: existing, resumed: true };
39576
+ }
39577
+ const piSessionId = generateUuidV7(new Date(args.now));
39578
+ stmt(args.db, `INSERT INTO migration_pending (
39579
+ migration_key, source_session_id, target_harness, pi_session_id,
39580
+ final_path, stage_path, content_sha256, phase, created_at
39581
+ ) VALUES (?, ?, ?, ?, ?, ?, '', 'staged', ?)
39582
+ ON CONFLICT(migration_key) DO NOTHING`).run(args.migrationKey, args.sourceSessionId, args.targetHarness, piSessionId, args.finalPathFor(piSessionId), join18(args.stageDir, `${args.migrationKey}.jsonl`), args.now);
39583
+ const row = readPendingMigration(args.db, args.migrationKey);
39584
+ if (!row) {
39585
+ throw new Error("migration journal row disappeared during insert; aborting migration");
39586
+ }
39587
+ return { row, resumed: row.pi_session_id !== piSessionId };
39588
+ }
39589
+ function commitStagedChecksum(db, migrationKey, contentSha256) {
39590
+ stmt(db, "UPDATE migration_pending SET content_sha256 = ? WHERE migration_key = ?").run(contentSha256, migrationKey);
39591
+ }
39275
39592
  function parseJsonObject(text3) {
39276
39593
  const parsed = JSON.parse(text3);
39277
39594
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -39431,7 +39748,7 @@ function convertPartToEntries(ctx) {
39431
39748
  }
39432
39749
  }
39433
39750
  function buildPiEntries(params) {
39434
- const sessionUuid = generateUuidV7(params.now);
39751
+ const sessionUuid = params.piSessionId;
39435
39752
  const nowIso = params.now.toISOString();
39436
39753
  const entries = [
39437
39754
  {
@@ -39467,6 +39784,7 @@ The following conversation was migrated from a different harness. Reasoning cont
39467
39784
  list.push(part);
39468
39785
  partsByMessage.set(part.message_id, list);
39469
39786
  }
39787
+ const messageIdToFirstPiEntryId = new Map;
39470
39788
  const messageIdToLastPiEntryId = new Map;
39471
39789
  const orderedSourceMessageIds = [];
39472
39790
  let parentId = boundary.id;
@@ -39477,6 +39795,7 @@ The following conversation was migrated from a different harness. Reasoning cont
39477
39795
  const timestamp2 = isoFromMs(message.time_created, params.now);
39478
39796
  const tokens = tokensFromMessage(message);
39479
39797
  const usage = tokensToPiUsage(tokens);
39798
+ let firstEntryIdForMessage = null;
39480
39799
  let lastEntryIdForMessage = null;
39481
39800
  for (const part of partsByMessage.get(message.id) ?? []) {
39482
39801
  const newEntries = convertPartToEntries({
@@ -39491,10 +39810,13 @@ The following conversation was migrated from a different harness. Reasoning cont
39491
39810
  entry.parentId = parentId;
39492
39811
  entries.push(entry);
39493
39812
  parentId = entry.id;
39813
+ if (firstEntryIdForMessage === null)
39814
+ firstEntryIdForMessage = parentId;
39494
39815
  lastEntryIdForMessage = parentId;
39495
39816
  }
39496
39817
  }
39497
- if (lastEntryIdForMessage !== null) {
39818
+ if (lastEntryIdForMessage !== null && firstEntryIdForMessage !== null) {
39819
+ messageIdToFirstPiEntryId.set(message.id, firstEntryIdForMessage);
39498
39820
  messageIdToLastPiEntryId.set(message.id, lastEntryIdForMessage);
39499
39821
  orderedSourceMessageIds.push(message.id);
39500
39822
  }
@@ -39502,6 +39824,7 @@ The following conversation was migrated from a different harness. Reasoning cont
39502
39824
  return {
39503
39825
  entries,
39504
39826
  piSessionId: sessionUuid,
39827
+ messageIdToFirstPiEntryId,
39505
39828
  messageIdToLastPiEntryId,
39506
39829
  orderedSourceMessageIds
39507
39830
  };
@@ -39539,8 +39862,9 @@ function fetchRows(db, sessionId, maxMessages) {
39539
39862
  throw error51;
39540
39863
  }
39541
39864
  }
39542
- function remapBoundaryId(openCodeMessageId, messageIdToLastPiEntryId, orderedSourceMessageIds) {
39543
- const direct = messageIdToLastPiEntryId.get(openCodeMessageId);
39865
+ function remapBoundaryId(openCodeMessageId, edge, messageIdToFirstPiEntryId, messageIdToLastPiEntryId, orderedSourceMessageIds) {
39866
+ const directMap = edge === "start" ? messageIdToFirstPiEntryId : messageIdToLastPiEntryId;
39867
+ const direct = directMap.get(openCodeMessageId);
39544
39868
  if (direct !== undefined)
39545
39869
  return { piEntryId: direct, exact: true };
39546
39870
  let nearestAtOrBefore;
@@ -39601,8 +39925,8 @@ function copyMagicContextState(args) {
39601
39925
  let boundariesApproximated = 0;
39602
39926
  const remappedCompartments = [];
39603
39927
  for (const c3 of sourceCompartments) {
39604
- const startRemap = remapBoundaryId(c3.start_message_id, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
39605
- const endRemap = remapBoundaryId(c3.end_message_id, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
39928
+ const startRemap = remapBoundaryId(c3.start_message_id, "start", args.messageIdToFirstPiEntryId, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
39929
+ const endRemap = remapBoundaryId(c3.end_message_id, "end", args.messageIdToFirstPiEntryId, args.messageIdToLastPiEntryId, args.orderedSourceMessageIds);
39606
39930
  if (!startRemap || !endRemap)
39607
39931
  continue;
39608
39932
  if (!startRemap.exact || !endRemap.exact)
@@ -39631,9 +39955,9 @@ function copyMagicContextState(args) {
39631
39955
  lastCompartmentEndPiEntryId: remappedCompartments.at(-1)?.end_message_id
39632
39956
  };
39633
39957
  if (args.dryRun) {
39634
- return { ...result, commit: () => {} };
39958
+ return { ...result, remappedCompartments, commit: () => {} };
39635
39959
  }
39636
- const commit = () => {
39960
+ const commit = (journalKey) => {
39637
39961
  const insertCompartment = stmt(args.cortexkitDb, `INSERT INTO compartments (
39638
39962
  session_id, sequence, start_message, end_message,
39639
39963
  start_message_id, end_message_id, title, content,
@@ -39645,19 +39969,72 @@ function copyMagicContextState(args) {
39645
39969
  ) VALUES (?, ?, ?, ?, ?, 'pi')`);
39646
39970
  args.cortexkitDb.exec("BEGIN IMMEDIATE");
39647
39971
  try {
39972
+ stmt(args.cortexkitDb, "DELETE FROM compartments WHERE session_id = ? AND harness = 'pi'").run(args.piSessionId);
39973
+ stmt(args.cortexkitDb, "DELETE FROM session_facts WHERE session_id = ? AND harness = 'pi'").run(args.piSessionId);
39648
39974
  for (const c3 of remappedCompartments) {
39649
39975
  insertCompartment.run(args.piSessionId, c3.sequence, c3.start_message, c3.end_message, c3.start_message_id, c3.end_message_id, c3.title, c3.content, c3.p1, c3.p2, c3.p3, c3.p4, typeof c3.importance === "number" ? c3.importance : 50, c3.episode_type, c3.legacy, args.now);
39650
39976
  }
39651
39977
  for (const f2 of sourceFacts) {
39652
39978
  insertFact.run(args.piSessionId, f2.category, f2.content, f2.created_at, f2.updated_at);
39653
39979
  }
39980
+ if (journalKey !== undefined) {
39981
+ stmt(args.cortexkitDb, "UPDATE migration_pending SET phase = 'db_committed' WHERE migration_key = ?").run(journalKey);
39982
+ }
39654
39983
  args.cortexkitDb.exec("COMMIT");
39655
39984
  } catch (error51) {
39656
39985
  args.cortexkitDb.exec("ROLLBACK");
39657
39986
  throw error51;
39658
39987
  }
39659
39988
  };
39660
- return { ...result, commit };
39989
+ return { ...result, remappedCompartments, commit };
39990
+ }
39991
+ function derivePiRuntimeOrdinals(entries) {
39992
+ const ordinalByEntryId = new Map;
39993
+ let nextOrdinal = 1;
39994
+ const pendingToolResultIds = [];
39995
+ const foldPendingInto = (ordinal) => {
39996
+ for (const id of pendingToolResultIds)
39997
+ ordinalByEntryId.set(id, ordinal);
39998
+ pendingToolResultIds.length = 0;
39999
+ };
40000
+ for (const entry of entries) {
40001
+ const message = entry.message;
40002
+ if (entry.type !== "message" || typeof entry.id !== "string" || message === null || typeof message !== "object") {
40003
+ continue;
40004
+ }
40005
+ const role = message.role;
40006
+ if (role === "toolResult") {
40007
+ pendingToolResultIds.push(entry.id);
40008
+ continue;
40009
+ }
40010
+ if (role === "assistant" && pendingToolResultIds.length > 0) {
40011
+ foldPendingInto(nextOrdinal);
40012
+ nextOrdinal += 1;
40013
+ }
40014
+ const ordinal = nextOrdinal;
40015
+ nextOrdinal += 1;
40016
+ if (role === "user" && pendingToolResultIds.length > 0) {
40017
+ foldPendingInto(ordinal);
40018
+ }
40019
+ ordinalByEntryId.set(entry.id, ordinal);
40020
+ }
40021
+ if (pendingToolResultIds.length > 0) {
40022
+ foldPendingInto(nextOrdinal);
40023
+ }
40024
+ return ordinalByEntryId;
40025
+ }
40026
+ function applyRuntimeOrdinals(remappedCompartments, entries) {
40027
+ const ordinals = derivePiRuntimeOrdinals(entries);
40028
+ for (const compartment of remappedCompartments) {
40029
+ const startOrdinal = ordinals.get(compartment.start_message_id);
40030
+ const endOrdinal = ordinals.get(compartment.end_message_id);
40031
+ if (startOrdinal === undefined || endOrdinal === undefined) {
40032
+ const missing = startOrdinal === undefined ? compartment.start_message_id : compartment.end_message_id;
40033
+ throw new Error(`Migration boundary entry ${missing} has no runtime ordinal; migrator invariant violated`);
40034
+ }
40035
+ compartment.start_message = startOrdinal;
40036
+ compartment.end_message = endOrdinal;
40037
+ }
39661
40038
  }
39662
40039
  function ensureValidOptions(opts) {
39663
40040
  if (!opts.from)
@@ -39707,52 +40084,88 @@ function migrateOpenCodeSessionToPi(opts) {
39707
40084
  const modelId = opts.modelId ?? model.modelId;
39708
40085
  const cwd = session.directory ?? session.path ?? process.cwd();
39709
40086
  const outputDir = join18(piSessionsRoot, projectPathToPiDirSlug(cwd));
40087
+ const targetHarness = opts.targetHarness ?? "pi";
40088
+ const journalActive = cortexkitDb !== null && !opts.dryRun;
40089
+ let recovery;
40090
+ let migrationKey;
40091
+ let journalResumed = false;
40092
+ let piSessionId;
40093
+ let finalPath;
40094
+ let stagePath;
40095
+ if (journalActive && cortexkitDb !== null) {
40096
+ if (!hasMigrationJournal(cortexkitDb)) {
40097
+ throw new Error("context.db has no migration_pending journal (shared schema older than v78). Run a harness session once so the plugin can upgrade the schema, then retry doctor migrate.");
40098
+ }
40099
+ recovery = sweepPendingMigrations(cortexkitDb, fs3);
40100
+ migrationKey = migrationKeyFor(session.id, targetHarness);
40101
+ const claimed = claimJournalIdentity({
40102
+ db: cortexkitDb,
40103
+ migrationKey,
40104
+ sourceSessionId: session.id,
40105
+ targetHarness,
40106
+ finalPathFor: (id) => join18(outputDir, `${formatPiFilenameTimestamp(now)}_${id}.jsonl`),
40107
+ stageDir: join18(dirname12(piSessionsRoot), MIGRATION_STAGE_DIRNAME),
40108
+ now: now.getTime()
40109
+ });
40110
+ piSessionId = claimed.row.pi_session_id;
40111
+ finalPath = claimed.row.final_path;
40112
+ stagePath = claimed.row.stage_path;
40113
+ journalResumed = claimed.resumed;
40114
+ } else {
40115
+ piSessionId = generateUuidV7(now);
40116
+ finalPath = join18(outputDir, `${formatPiFilenameTimestamp(now)}_${piSessionId}.jsonl`);
40117
+ stagePath = "";
40118
+ }
39710
40119
  const buildResult = buildPiEntries({
39711
40120
  session,
39712
40121
  messages,
39713
40122
  parts,
39714
40123
  now,
39715
40124
  provider,
39716
- modelId
40125
+ modelId,
40126
+ piSessionId
39717
40127
  });
39718
40128
  let copyResult = {
39719
40129
  compartmentsCopied: 0,
39720
40130
  factsCopied: 0,
39721
40131
  boundariesApproximated: 0
39722
40132
  };
39723
- let commitMagicContextState = null;
40133
+ let plan = null;
39724
40134
  if (cortexkitDb !== null) {
39725
- const plan = copyMagicContextState({
40135
+ plan = copyMagicContextState({
39726
40136
  cortexkitDb,
39727
40137
  sourceSessionId: session.id,
39728
- piSessionId: buildResult.piSessionId,
40138
+ piSessionId,
40139
+ messageIdToFirstPiEntryId: buildResult.messageIdToFirstPiEntryId,
39729
40140
  messageIdToLastPiEntryId: buildResult.messageIdToLastPiEntryId,
39730
40141
  orderedSourceMessageIds: buildResult.orderedSourceMessageIds,
39731
40142
  now: now.getTime(),
39732
40143
  dryRun: Boolean(opts.dryRun)
39733
40144
  });
39734
40145
  copyResult = plan;
39735
- commitMagicContextState = plan.commit;
39736
40146
  }
39737
40147
  const compactionMarker = insertCompactionMarker(buildResult.entries, copyResult.lastCompartmentEndPiEntryId);
39738
- const outputPath = join18(outputDir, `${formatPiFilenameTimestamp(now)}_${buildResult.piSessionId}.jsonl`);
40148
+ if (plan)
40149
+ applyRuntimeOrdinals(plan.remappedCompartments, buildResult.entries);
39739
40150
  const jsonl = `${buildResult.entries.map((entry) => JSON.stringify(entry)).join(`
39740
40151
  `)}
39741
40152
  `;
39742
40153
  if (!opts.dryRun) {
39743
- fs3.writeFileAtomic(outputPath, jsonl);
39744
- try {
39745
- commitMagicContextState?.();
39746
- } catch (commitError) {
39747
- try {
39748
- fs3.unlinkSync(outputPath);
39749
- } catch {}
39750
- throw commitError;
40154
+ if (journalActive && cortexkitDb !== null && migrationKey !== undefined && plan) {
40155
+ const contentSha256 = createHash3("sha256").update(jsonl, "utf8").digest("hex");
40156
+ commitStagedChecksum(cortexkitDb, migrationKey, contentSha256);
40157
+ fs3.writeFileAtomic(stagePath, jsonl);
40158
+ plan.commit(migrationKey);
40159
+ fs3.mkdirSync(dirname12(finalPath), { recursive: true });
40160
+ fs3.renameSync(stagePath, finalPath);
40161
+ stmt(cortexkitDb, "DELETE FROM migration_pending WHERE migration_key = ?").run(migrationKey);
40162
+ } else {
40163
+ fs3.writeFileAtomic(finalPath, jsonl);
39751
40164
  }
39752
40165
  }
39753
40166
  return {
39754
- outputPath,
39755
- piSessionId: buildResult.piSessionId,
40167
+ outputPath: finalPath,
40168
+ piSessionId,
39756
40169
  messageCount: buildResult.entries.length - 2,
39757
40170
  byteCount: Buffer.byteLength(jsonl, "utf8"),
39758
40171
  sourceMessageCount,
@@ -39762,6 +40175,9 @@ function migrateOpenCodeSessionToPi(opts) {
39762
40175
  compactionMarkerWritten: compactionMarker.written,
39763
40176
  compactionBoundaryEntryId: compactionMarker.boundaryEntryId,
39764
40177
  compactionFirstKeptEntryId: compactionMarker.firstKeptEntryId,
40178
+ ...migrationKey !== undefined ? { migrationKey } : {},
40179
+ ...journalActive ? { journalResumed } : {},
40180
+ ...recovery !== undefined ? { recovery } : {},
39765
40181
  ...cortexkitSchemaVersionBefore !== null && cortexkitDb !== null ? {
39766
40182
  cortexkitSchemaVersionBefore,
39767
40183
  cortexkitSchemaVersionAfter: getPersistedSchemaVersion2(cortexkitDb)
@@ -39828,9 +40244,32 @@ function printMigrateHelp() {
39828
40244
  - compartments + session_facts are copied to the new Pi session_id;
39829
40245
  compartment boundary message IDs are remapped to the corresponding
39830
40246
  Pi entry IDs (nearest-at-or-before for boundaries that don't have
39831
- a direct message-level Pi entry)
40247
+ a direct message-level Pi entry), and compartment start/end ordinals
40248
+ are recomputed in the ordinal basis the Pi runtime reader produces
40249
+
40250
+ Crash safety:
40251
+ - each migration is tracked in the shared DB's migration_pending journal
40252
+ and staged outside the sessions tree; an interrupted run is reconciled
40253
+ by phase on the next 'doctor migrate' or plain 'doctor' run, reusing the
40254
+ original Pi session id instead of minting a second one
39832
40255
  `);
39833
40256
  }
40257
+ function formatMigrationSweepLines(report) {
40258
+ const lines = [];
40259
+ if (report.rolledForward > 0) {
40260
+ lines.push(`Recovered ${report.rolledForward} interrupted session migration(s) by completing the staged file rename.`);
40261
+ }
40262
+ if (report.rolledBack > 0) {
40263
+ lines.push(`Rolled back ${report.rolledBack} incomplete session migration(s) that never committed shared state.`);
40264
+ }
40265
+ if (report.completed > 0) {
40266
+ lines.push(`Cleared ${report.completed} finished session-migration journal row(s).`);
40267
+ }
40268
+ for (const row of report.lost) {
40269
+ lines.push(`LOST session migration content: source ${row.source_session_id} → ${row.target_harness} session ${row.pi_session_id}; expected file ${row.final_path} (sha256 ${row.content_sha256}). Re-run doctor migrate for this session to rebuild it.`);
40270
+ }
40271
+ return lines;
40272
+ }
39834
40273
  async function runMigrateCli(args) {
39835
40274
  try {
39836
40275
  const parsed = parseMigrateArgs(args);
@@ -39840,8 +40279,14 @@ async function runMigrateCli(args) {
39840
40279
  sessionId: parsed.session,
39841
40280
  maxMessages: parsed.maxMessages,
39842
40281
  dryRun: parsed.dryRun,
39843
- piSessionsRoot: parsed.to === "omp" ? getOmpSessionsRoot() : undefined
40282
+ piSessionsRoot: parsed.to === "omp" ? getOmpSessionsRoot() : undefined,
40283
+ targetHarness: parsed.to === "omp" ? "omp" : "pi"
39844
40284
  });
40285
+ if (result.recovery) {
40286
+ for (const line of formatMigrationSweepLines(result.recovery)) {
40287
+ console.log(line);
40288
+ }
40289
+ }
39845
40290
  const action = result.dryRun ? "Would write" : "Wrote";
39846
40291
  console.log(`${action} ${target} session JSONL:`);
39847
40292
  console.log(` path: ${result.outputPath}`);
@@ -39858,6 +40303,9 @@ async function runMigrateCli(args) {
39858
40303
  if (result.boundariesApproximated > 0) {
39859
40304
  console.log(` boundaries approximated: ${result.boundariesApproximated} (nearest-at-or-before)`);
39860
40305
  }
40306
+ if (result.migrationKey !== undefined) {
40307
+ console.log(` journal: ${result.migrationKey.slice(0, 12)}…${result.journalResumed ? " (resumed interrupted attempt)" : ""}`);
40308
+ }
39861
40309
  if (!result.dryRun) {
39862
40310
  console.log(`${target} may need to be restarted to pick up the new session file.`);
39863
40311
  if (result.cortexkitSchemaVersionBefore !== undefined) {
@@ -39875,7 +40323,9 @@ async function runMigrateCli(args) {
39875
40323
  return 1;
39876
40324
  }
39877
40325
  }
39878
- var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMPACTION_SUMMARY = "Magic Context compacted prior conversation. See <session-history> block for the structured summary.", PART_LOOKUP_CHUNK_SIZE = 900;
40326
+ var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMPACTION_SUMMARY = "Magic Context compacted prior conversation. See <session-history> block for the structured summary.", PART_LOOKUP_CHUNK_SIZE = 900, MIGRATION_STAGE_DIRNAME = ".mc-migrations", JOURNAL_SELECT_SQL = `SELECT migration_key, source_session_id, target_harness, pi_session_id,
40327
+ final_path, stage_path, content_sha256, phase, created_at
40328
+ FROM migration_pending WHERE migration_key = ?`;
39879
40329
  var init_migrate = __esm(async () => {
39880
40330
  init_data_path();
39881
40331
  init_atomic_write();
@@ -39979,15 +40429,72 @@ var exports_migrate_session = {};
39979
40429
  __export(exports_migrate_session, {
39980
40430
  runMigrateSessionCli: () => runMigrateSessionCli,
39981
40431
  planMigrateSession: () => planMigrateSession,
40432
+ assertMigrateSessionIsSafeToRehome: () => assertMigrateSessionIsSafeToRehome,
39982
40433
  applyMigrateSession: () => applyMigrateSession
39983
40434
  });
39984
- import { existsSync as existsSync21, realpathSync as realpathSync4 } from "node:fs";
40435
+ import { existsSync as existsSync22, realpathSync as realpathSync4 } from "node:fs";
39985
40436
  import { homedir as homedir13 } from "node:os";
39986
40437
  import path4, { join as join19 } from "node:path";
39987
40438
  function existingSessionColumns(db) {
39988
40439
  const rows = db.prepare("PRAGMA table_info(session)").all();
39989
40440
  return new Set(rows.map((r2) => r2.name).filter((n2) => typeof n2 === "string"));
39990
40441
  }
40442
+ function isModuleCacheStatePresent(status) {
40443
+ if (!status || typeof status !== "object")
40444
+ return false;
40445
+ const rowVersion = status.row_version;
40446
+ return typeof rowVersion === "number";
40447
+ }
40448
+ function drainCommandsForMarkers(markers, projects) {
40449
+ const byProject = new Map(projects.map((project) => [project.projectPath, project]));
40450
+ return [
40451
+ ...new Set(markers.map((marker) => authorityDrainCommand(byProject.get(marker.project_path) ?? {
40452
+ role: "marked",
40453
+ projectPath: marker.project_path,
40454
+ projectRoot: null
40455
+ })))
40456
+ ].join("; ");
40457
+ }
40458
+ async function assertMigrateSessionIsSafeToRehome(args) {
40459
+ const projects = [
40460
+ {
40461
+ role: "source",
40462
+ projectPath: args.plan.fromMcIdentity,
40463
+ projectRoot: args.plan.currentDirectory
40464
+ },
40465
+ {
40466
+ role: "target",
40467
+ projectPath: args.plan.toMcIdentity,
40468
+ projectRoot: args.plan.targetDirectory
40469
+ }
40470
+ ];
40471
+ const authority = await assertProjectsUseTsAuthority({
40472
+ db: args.contextDb,
40473
+ projects,
40474
+ module: args.module
40475
+ });
40476
+ let sessionStatus;
40477
+ try {
40478
+ sessionStatus = await args.module.sessionStatus({
40479
+ sessionId: args.plan.sessionId,
40480
+ projectRoot: args.plan.currentDirectory ?? args.plan.targetDirectory
40481
+ });
40482
+ } catch (error51) {
40483
+ const message = error51 instanceof Error ? error51.message : String(error51);
40484
+ if (authority.markers.length === 0) {
40485
+ return {
40486
+ warnings: [
40487
+ `Module session-cache state was not checked because the module is unreachable: ${message}. No durable authority markers exist, so continuing for this pure-TypeScript installation.`
40488
+ ]
40489
+ };
40490
+ }
40491
+ throw new Error("Migration refused: module session-cache state is unreachable while durable authority markers exist; writes remain fenced. " + `Drain marked projects first: ${drainCommandsForMarkers(authority.markers, projects)}. ` + `Module error: ${message}`);
40492
+ }
40493
+ if (isModuleCacheStatePresent(sessionStatus)) {
40494
+ throw new Error(`Migration refused: the module still holds transform cache state for session ${args.plan.sessionId}. ` + "Use TypeScript transform mode for the session's project, or run `ck session delete` after preserving any needed state, then re-run this migration.");
40495
+ }
40496
+ return { warnings: [] };
40497
+ }
39991
40498
  function planMigrateSession(sessionId, rawTargetDirectory, deps) {
39992
40499
  const sessionRow = deps.opencodeDb.prepare("SELECT id, directory FROM session WHERE id = ?").get(sessionId);
39993
40500
  if (!sessionRow) {
@@ -40144,7 +40651,7 @@ function realDeps(opencodeDb, contextDb) {
40144
40651
  opencodeDb,
40145
40652
  contextDb,
40146
40653
  resolveIdentity: resolveProjectIdentity,
40147
- hasGitDir: (dir) => existsSync21(join19(dir, ".git")),
40654
+ hasGitDir: (dir) => existsSync22(join19(dir, ".git")),
40148
40655
  realpath: (p2) => realpathSync4(p2)
40149
40656
  };
40150
40657
  }
@@ -40223,7 +40730,7 @@ async function runMigrateSessionCli(args) {
40223
40730
  return 1;
40224
40731
  }
40225
40732
  const expandedTo = toDir.startsWith("~") ? join19(homedir13(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
40226
- if (!existsSync21(expandedTo)) {
40733
+ if (!existsSync22(expandedTo)) {
40227
40734
  console.error(`Target directory does not exist: ${expandedTo}`);
40228
40735
  return 1;
40229
40736
  }
@@ -40249,6 +40756,27 @@ async function runMigrateSessionCli(args) {
40249
40756
  } catch {}
40250
40757
  const deps = realDeps(opencodeDb, contextDb);
40251
40758
  const plan = planMigrateSession(sessionId, expandedTo, deps);
40759
+ const transport = new SubcModuleTransport;
40760
+ const safety = await assertMigrateSessionIsSafeToRehome({
40761
+ plan,
40762
+ contextDb,
40763
+ module: {
40764
+ authorityStatus: (request) => transport.authorityStatus(request),
40765
+ sessionStatus: ({ sessionId: statusSessionId, projectRoot }) => transport.call({
40766
+ sessionId: statusSessionId,
40767
+ projectRoot,
40768
+ method: "session.status",
40769
+ body: {
40770
+ method: "session.status",
40771
+ v: 1,
40772
+ session_id: statusSessionId
40773
+ }
40774
+ })
40775
+ }
40776
+ });
40777
+ for (const warning of safety.warnings) {
40778
+ promptIO.log.warn(warning);
40779
+ }
40252
40780
  promptIO.note([
40253
40781
  `session: ${plan.sessionId}`,
40254
40782
  `from: ${plan.currentDirectory ?? "(unknown)"}`,
@@ -40332,10 +40860,14 @@ var init_migrate_session = __esm(async () => {
40332
40860
  init_project_identity();
40333
40861
  init_relocate_memory();
40334
40862
  init_storage_project_state();
40863
+ init_module_transport();
40335
40864
  init_data_path();
40336
40865
  init_migration_paths();
40337
40866
  init_prompts();
40338
- await init_database_access();
40867
+ await __promiseAll([
40868
+ init_database_access(),
40869
+ init_doctor_authority()
40870
+ ]);
40339
40871
  VALID_MEMORY_ACTIONS = new Set([
40340
40872
  "move-all",
40341
40873
  "move-originated",
@@ -40346,7 +40878,7 @@ var init_migrate_session = __esm(async () => {
40346
40878
  });
40347
40879
 
40348
40880
  // ../plugin/src/features/magic-context/v22-deferred-backfill.ts
40349
- import { createHash as createHash3 } from "node:crypto";
40881
+ import { createHash as createHash4 } from "node:crypto";
40350
40882
  import { realpathSync as realpathSync5 } from "node:fs";
40351
40883
  import path5 from "node:path";
40352
40884
  function readMeta(db, key) {
@@ -40395,7 +40927,7 @@ function computeLegacyRustDirIdentity(rawProjectPath) {
40395
40927
  } catch {
40396
40928
  canonical = path5.isAbsolute(rawProjectPath) ? rawProjectPath : path5.join(process.cwd(), rawProjectPath);
40397
40929
  }
40398
- return `dir:${createHash3("sha256").update(canonical, "utf8").digest("hex")}`;
40930
+ return `dir:${createHash4("sha256").update(canonical, "utf8").digest("hex")}`;
40399
40931
  }
40400
40932
  function upsertRekeyMap(db, oldProjectPath, newProjectPath, rekeyedAt) {
40401
40933
  db.prepare(`INSERT INTO v22_identity_rekey_map (old_project_path, new_project_path, rekeyed_at)
@@ -40580,7 +41112,7 @@ var init_v22_backfill_commands = __esm(async () => {
40580
41112
  });
40581
41113
 
40582
41114
  // ../pi-plugin/src/config/index.ts
40583
- import { existsSync as existsSync22, readFileSync as readFileSync14 } from "node:fs";
41115
+ import { existsSync as existsSync23, readFileSync as readFileSync14 } from "node:fs";
40584
41116
  function getProjectConfigPaths(cwd) {
40585
41117
  const basePath = cortexKitProjectConfigBasePath(cwd);
40586
41118
  return [`${basePath}.jsonc`, `${basePath}.json`];
@@ -40590,10 +41122,10 @@ function getUserConfigPaths() {
40590
41122
  return [`${basePath}.jsonc`, `${basePath}.json`];
40591
41123
  }
40592
41124
  function resolveFirstExisting(paths) {
40593
- return paths.find((path6) => existsSync22(path6));
41125
+ return paths.find((path6) => existsSync23(path6));
40594
41126
  }
40595
41127
  function resolvePiLegacyFallback(sources) {
40596
- return sources.find((source) => existsSync22(source.path)) ?? null;
41128
+ return sources.find((source) => existsSync23(source.path)) ?? null;
40597
41129
  }
40598
41130
  function loadConfigFile(path6, scope) {
40599
41131
  try {
@@ -40750,7 +41282,7 @@ function loadPiConfig(opts = {}) {
40750
41282
  if (loaded)
40751
41283
  loadedFiles.push(loaded);
40752
41284
  }
40753
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync22(source.path));
41285
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync23(source.path));
40754
41286
  const userPath = resolveFirstExisting(getUserConfigPaths());
40755
41287
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
40756
41288
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -40759,7 +41291,7 @@ function loadPiConfig(opts = {}) {
40759
41291
  if (loaded)
40760
41292
  loadedFiles.push(loaded);
40761
41293
  }
40762
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync22(source.path));
41294
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync23(source.path));
40763
41295
  if (userLegacyFallback) {
40764
41296
  warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
40765
41297
  } else if (legacyUserUnmigrated) {
@@ -40803,6 +41335,7 @@ function loadPiConfig(opts = {}) {
40803
41335
  }
40804
41336
  const parsed = parsePiConfig(rawConfig);
40805
41337
  setOutputReserveConfig(parsed.config.output_reserve);
41338
+ setWindowOverlayPath(parsed.config.models?.window_overlay_path);
40806
41339
  warnings.push(...parsed.warnings.map((warning) => `[merged config] ${warning}`));
40807
41340
  return {
40808
41341
  config: parsed.config,
@@ -40821,6 +41354,7 @@ var init_config2 = __esm(() => {
40821
41354
  init_variable();
40822
41355
  init_jsonc_parser();
40823
41356
  init_models_dev_cache();
41357
+ init_window_geometry();
40824
41358
  import_comment_json7 = __toESM(require_src3(), 1);
40825
41359
  });
40826
41360
 
@@ -41040,9 +41574,9 @@ var init_redaction2 = __esm(() => {
41040
41574
 
41041
41575
  // src/commands/doctor-omp.ts
41042
41576
  import { execFileSync as execFileSync5, spawnSync as spawnSync4 } from "node:child_process";
41043
- import { existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync15 } from "node:fs";
41577
+ import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync15 } from "node:fs";
41044
41578
  import { createRequire as createRequire2 } from "node:module";
41045
- import { dirname as dirname12, join as join20, resolve as resolve5 } from "node:path";
41579
+ import { dirname as dirname13, join as join20, resolve as resolve5 } from "node:path";
41046
41580
  function parseSemver(value) {
41047
41581
  const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
41048
41582
  return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
@@ -41084,7 +41618,7 @@ function selfVersion() {
41084
41618
  return "unknown";
41085
41619
  }
41086
41620
  function readConfig2(path6) {
41087
- if (!existsSync23(path6))
41621
+ if (!existsSync24(path6))
41088
41622
  return {};
41089
41623
  try {
41090
41624
  const parsed = import_comment_json8.parse(readFileSync15(path6, "utf-8"));
@@ -41178,7 +41712,7 @@ async function runHealthChecks(options) {
41178
41712
  }
41179
41713
  }
41180
41714
  const userConfigPath = getOmpUserConfigPath();
41181
- if (!existsSync23(userConfigPath)) {
41715
+ if (!existsSync24(userConfigPath)) {
41182
41716
  add(results, "warn", `No Magic Context user config at ${userConfigPath}`);
41183
41717
  repairPlan.writeUserConfig = true;
41184
41718
  } else {
@@ -41195,7 +41729,7 @@ async function runHealthChecks(options) {
41195
41729
  for (const warning of loaded.warnings.slice(0, 5))
41196
41730
  add(results, "warn", warning);
41197
41731
  const dbPath = join20(getMagicContextStorageDir(), "context.db");
41198
- if (!existsSync23(dbPath))
41732
+ if (!existsSync24(dbPath))
41199
41733
  add(results, "info", `Shared context DB will be created at ${dbPath}`);
41200
41734
  else {
41201
41735
  let db = null;
@@ -41224,7 +41758,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
41224
41758
  add(results, "info", `OMP non-global config: ${source}`);
41225
41759
  }
41226
41760
  const logPath = getMagicContextLogPath2("pi");
41227
- add(results, "info", `Pi-compatible runtime log: ${logPath}${existsSync23(logPath) ? "" : " (not created yet)"}`);
41761
+ add(results, "info", `Pi-compatible runtime log: ${logPath}${existsSync24(logPath) ? "" : " (not created yet)"}`);
41228
41762
  if (!options.quiet)
41229
41763
  for (const result of results)
41230
41764
  printResult(options.prompts, result);
@@ -41237,7 +41771,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
41237
41771
  };
41238
41772
  }
41239
41773
  function writeDefaultConfig(path6) {
41240
- mkdirSync8(dirname12(path6), { recursive: true });
41774
+ mkdirSync9(dirname13(path6), { recursive: true });
41241
41775
  const config2 = {
41242
41776
  $schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
41243
41777
  ...MagicContextConfigSchema.parse({})
@@ -41247,7 +41781,7 @@ function writeDefaultConfig(path6) {
41247
41781
  }
41248
41782
  async function repair(plan, deps, prompts, cwd) {
41249
41783
  let fixed = 0;
41250
- if (plan.writeUserConfig && !existsSync23(getOmpUserConfigPath())) {
41784
+ if (plan.writeUserConfig && !existsSync24(getOmpUserConfigPath())) {
41251
41785
  writeDefaultConfig(getOmpUserConfigPath());
41252
41786
  prompts.log.success(`Wrote default Magic Context config to ${getOmpUserConfigPath()}`);
41253
41787
  fixed += 1;
@@ -41510,14 +42044,14 @@ var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
41510
42044
  // ../plugin/src/shared/tui-config.ts
41511
42045
  import {
41512
42046
  chmodSync as chmodSync4,
41513
- existsSync as existsSync24,
41514
- mkdirSync as mkdirSync9,
42047
+ existsSync as existsSync25,
42048
+ mkdirSync as mkdirSync10,
41515
42049
  readFileSync as readFileSync16,
41516
- renameSync as renameSync4,
42050
+ renameSync as renameSync5,
41517
42051
  statSync as statSync9,
41518
42052
  writeFileSync as writeFileSync6
41519
42053
  } from "node:fs";
41520
- import { dirname as dirname13, join as join21 } from "node:path";
42054
+ import { dirname as dirname14, join as join21 } from "node:path";
41521
42055
  function pluginEntryId(entry) {
41522
42056
  if (typeof entry === "string")
41523
42057
  return entry;
@@ -41554,15 +42088,15 @@ function writeTuiConfigAtomic(configPath, config2) {
41554
42088
  chmodSync4(tmpPath, statSync9(configPath).mode & 511);
41555
42089
  }
41556
42090
  } catch {}
41557
- renameSync4(tmpPath, configPath);
42091
+ renameSync5(tmpPath, configPath);
41558
42092
  }
41559
42093
  function resolveTuiConfigPath(configDirOverride) {
41560
42094
  const configDir = configDirOverride ?? getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
41561
42095
  const jsoncPath = join21(configDir, "tui.jsonc");
41562
42096
  const jsonPath = join21(configDir, "tui.json");
41563
- if (existsSync24(jsoncPath))
42097
+ if (existsSync25(jsoncPath))
41564
42098
  return jsoncPath;
41565
- if (existsSync24(jsonPath))
42099
+ if (existsSync25(jsonPath))
41566
42100
  return jsonPath;
41567
42101
  return jsoncPath;
41568
42102
  }
@@ -41570,7 +42104,7 @@ function ensureTuiPluginEntry(options = {}) {
41570
42104
  try {
41571
42105
  const configPath = resolveTuiConfigPath(options.configDir);
41572
42106
  let config2 = {};
41573
- if (existsSync24(configPath)) {
42107
+ if (existsSync25(configPath)) {
41574
42108
  const raw = readFileSync16(configPath, "utf-8");
41575
42109
  config2 = import_comment_json9.parse(raw) ?? {};
41576
42110
  }
@@ -41605,7 +42139,7 @@ function ensureTuiPluginEntry(options = {}) {
41605
42139
  }
41606
42140
  }
41607
42141
  config2.plugin = plugins;
41608
- mkdirSync9(dirname13(configPath), { recursive: true });
42142
+ mkdirSync10(dirname14(configPath), { recursive: true });
41609
42143
  writeTuiConfigAtomic(configPath, config2);
41610
42144
  log3(`[magic-context] updated TUI plugin entry in ${configPath}`);
41611
42145
  return true;
@@ -41623,7 +42157,7 @@ var init_tui_config = __esm(() => {
41623
42157
  });
41624
42158
 
41625
42159
  // src/lib/diagnostics-opencode.ts
41626
- import { existsSync as existsSync25, readdirSync as readdirSync3, readFileSync as readFileSync17, statSync as statSync10 } from "node:fs";
42160
+ import { existsSync as existsSync26, readdirSync as readdirSync3, readFileSync as readFileSync17, statSync as statSync10 } from "node:fs";
41627
42161
  import { createRequire as createRequire3 } from "node:module";
41628
42162
  import { homedir as homedir15 } from "node:os";
41629
42163
  import { join as join22 } from "node:path";
@@ -41644,7 +42178,7 @@ function getPluginCacheInfo() {
41644
42178
  let cached2;
41645
42179
  for (const installedPkgPath of getOpenCodePluginPackageJsonPaths()) {
41646
42180
  try {
41647
- if (existsSync25(installedPkgPath)) {
42181
+ if (existsSync26(installedPkgPath)) {
41648
42182
  const pkg = JSON.parse(readFileSync17(installedPkgPath, "utf-8"));
41649
42183
  cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
41650
42184
  if (cached2)
@@ -41662,7 +42196,7 @@ function getStorageDir() {
41662
42196
  }
41663
42197
  function fileSize(path6) {
41664
42198
  try {
41665
- return existsSync25(path6) ? statSync10(path6).size : 0;
42199
+ return existsSync26(path6) ? statSync10(path6).size : 0;
41666
42200
  } catch {
41667
42201
  return 0;
41668
42202
  }
@@ -41674,7 +42208,7 @@ function sanitizeValue(value) {
41674
42208
  return sanitizeConfigValue(value);
41675
42209
  }
41676
42210
  function readConfig3(path6) {
41677
- if (!existsSync25(path6))
42211
+ if (!existsSync26(path6))
41678
42212
  return { value: null };
41679
42213
  try {
41680
42214
  const raw = readFileSync17(path6, "utf-8");
@@ -41735,7 +42269,7 @@ function parseHistorianDumpMeta(path6) {
41735
42269
  }
41736
42270
  }
41737
42271
  function listDumpsInDir(dir, limit) {
41738
- if (!existsSync25(dir))
42272
+ if (!existsSync26(dir))
41739
42273
  return { count: 0, recent: [] };
41740
42274
  try {
41741
42275
  const entries = readdirSync3(dir).filter((name) => name.endsWith(".xml")).map((name) => {
@@ -41805,7 +42339,7 @@ function collectHistorianDumps(recentSessions) {
41805
42339
  async function collectRecentSessions() {
41806
42340
  const dataHome = process.env.XDG_DATA_HOME || join22(process.env.HOME || homedir15(), ".local", "share");
41807
42341
  const opencodeDbPath = join22(dataHome, "opencode", "opencode.db");
41808
- if (!existsSync25(opencodeDbPath))
42342
+ if (!existsSync26(opencodeDbPath))
41809
42343
  return [];
41810
42344
  if (typeof globalThis.Bun === "undefined") {
41811
42345
  return [];
@@ -41840,7 +42374,7 @@ async function collectRecentSessions() {
41840
42374
  }
41841
42375
  async function collectHistorianFailures(storageDirPath) {
41842
42376
  const contextDbPath = join22(storageDirPath, "context.db");
41843
- if (!existsSync25(contextDbPath))
42377
+ if (!existsSync26(contextDbPath))
41844
42378
  return [];
41845
42379
  if (typeof globalThis.Bun === "undefined") {
41846
42380
  return [];
@@ -41874,7 +42408,7 @@ async function collectHistorianFailures(storageDirPath) {
41874
42408
  }
41875
42409
  async function collectHistorianRuns(storageDirPath) {
41876
42410
  const contextDbPath = join22(storageDirPath, "context.db");
41877
- if (!existsSync25(contextDbPath))
42411
+ if (!existsSync26(contextDbPath))
41878
42412
  return [];
41879
42413
  if (typeof globalThis.Bun === "undefined")
41880
42414
  return [];
@@ -41945,7 +42479,7 @@ async function collectDiagnostics() {
41945
42479
  const storageDirPath = getStorageDir();
41946
42480
  const contextDbPath = join22(storageDirPath, "context.db");
41947
42481
  const logPath = getMagicContextLogPath2("opencode");
41948
- const logFileSize = existsSync25(logPath) ? statSync10(logPath).size : 0;
42482
+ const logFileSize = existsSync26(logPath) ? statSync10(logPath).size : 0;
41949
42483
  let compactionEnabled = false;
41950
42484
  try {
41951
42485
  compactionEnabled = isCompactionEnabled(loadPluginConfig(process.cwd()));
@@ -41973,14 +42507,14 @@ async function collectDiagnostics() {
41973
42507
  opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
41974
42508
  tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
41975
42509
  magicContextConfig: {
41976
- exists: existsSync25(configPaths.magicContextConfig),
42510
+ exists: existsSync26(configPaths.magicContextConfig),
41977
42511
  ...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
41978
42512
  flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
41979
42513
  },
41980
42514
  pluginCache: getPluginCacheInfo(),
41981
42515
  storageDir: {
41982
42516
  path: storageDirPath,
41983
- exists: existsSync25(storageDirPath),
42517
+ exists: existsSync26(storageDirPath),
41984
42518
  contextDbSizeBytes: fileSize(contextDbPath)
41985
42519
  },
41986
42520
  conflicts: {
@@ -41991,7 +42525,7 @@ async function collectDiagnostics() {
41991
42525
  },
41992
42526
  logFile: {
41993
42527
  path: logPath,
41994
- exists: existsSync25(logPath),
42528
+ exists: existsSync26(logPath),
41995
42529
  sizeKb: Math.round(logFileSize / 1024)
41996
42530
  },
41997
42531
  recentSessions,
@@ -42144,9 +42678,9 @@ var init_diagnostics_opencode = __esm(() => {
42144
42678
 
42145
42679
  // src/lib/embedding-runtime.ts
42146
42680
  import { spawnSync as spawnSync5 } from "node:child_process";
42147
- import { existsSync as existsSync26 } from "node:fs";
42681
+ import { existsSync as existsSync27 } from "node:fs";
42148
42682
  import { createRequire as createRequire4 } from "node:module";
42149
- import { dirname as dirname14, join as join23, sep } from "node:path";
42683
+ import { dirname as dirname15, join as join23, sep } from "node:path";
42150
42684
  function describeError(error51) {
42151
42685
  const message = error51 instanceof Error ? error51.message : String(error51 ?? "unknown error");
42152
42686
  const code = error51?.code;
@@ -42259,7 +42793,7 @@ function expectedBinaryRelPath(platform, arch) {
42259
42793
  }
42260
42794
  function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch) {
42261
42795
  const packageDir = join23(installRoot, "node_modules", "onnxruntime-node");
42262
- if (!existsSync26(join23(packageDir, "package.json"))) {
42796
+ if (!existsSync27(join23(packageDir, "package.json"))) {
42263
42797
  return { state: "package-missing", packageDir };
42264
42798
  }
42265
42799
  const rel = expectedBinaryRelPath(platform, arch);
@@ -42267,13 +42801,13 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
42267
42801
  return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath: packageDir };
42268
42802
  }
42269
42803
  const binaryPath = join23(packageDir, rel);
42270
- if (!existsSync26(binaryPath)) {
42804
+ if (!existsSync27(binaryPath)) {
42271
42805
  return { state: "binary-missing", packageDir, expectedBinary: binaryPath };
42272
42806
  }
42273
42807
  return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath };
42274
42808
  }
42275
42809
  function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch) {
42276
- const existing = installRoots.filter((root) => existsSync26(root));
42810
+ const existing = installRoots.filter((root) => existsSync27(root));
42277
42811
  if (existing.length === 0) {
42278
42812
  return {
42279
42813
  state: "unknown",
@@ -42293,10 +42827,10 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
42293
42827
  function packageDirFromResolved(resolvedPath, packageName) {
42294
42828
  const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
42295
42829
  const idx = resolvedPath.indexOf(marker);
42296
- return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname14(resolvedPath);
42830
+ return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname15(resolvedPath);
42297
42831
  }
42298
42832
  function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch) {
42299
- if (!existsSync26(join23(pluginDir, "package.json"))) {
42833
+ if (!existsSync27(join23(pluginDir, "package.json"))) {
42300
42834
  return { state: "unknown", reason: "plugin package dir not found" };
42301
42835
  }
42302
42836
  let onnxDir = null;
@@ -42332,7 +42866,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
42332
42866
  return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
42333
42867
  }
42334
42868
  const binaryPath = join23(onnxDir, rel);
42335
- if (!existsSync26(binaryPath)) {
42869
+ if (!existsSync27(binaryPath)) {
42336
42870
  return { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
42337
42871
  }
42338
42872
  return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath };
@@ -42927,11 +43461,11 @@ var init_storage_versions = __esm(async () => {
42927
43461
  });
42928
43462
 
42929
43463
  // src/commands/doctor-opencode-cache.ts
42930
- import { existsSync as existsSync27, readFileSync as readFileSync19, rmSync as rmSync3 } from "node:fs";
43464
+ import { existsSync as existsSync28, readFileSync as readFileSync19, rmSync as rmSync3 } from "node:fs";
42931
43465
  function readCachedPluginVersion(pluginCacheDir) {
42932
43466
  try {
42933
43467
  const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
42934
- if (!existsSync27(installedPkgPath))
43468
+ if (!existsSync28(installedPkgPath))
42935
43469
  return;
42936
43470
  const pkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
42937
43471
  return typeof pkg.version === "string" ? pkg.version : undefined;
@@ -42942,7 +43476,7 @@ function readCachedPluginVersion(pluginCacheDir) {
42942
43476
  async function clearPluginCache(options = {}, deps = {}) {
42943
43477
  const remove = deps.remove ?? ((path6) => rmSync3(path6, { recursive: true, force: true }));
42944
43478
  const pluginCacheRoots = getOpenCodePluginCacheRoots();
42945
- const existingRoots = pluginCacheRoots.filter((root) => existsSync27(root));
43479
+ const existingRoots = pluginCacheRoots.filter((root) => existsSync28(root));
42946
43480
  if (existingRoots.length === 0) {
42947
43481
  return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
42948
43482
  }
@@ -43010,7 +43544,7 @@ var init_doctor_opencode_cache = __esm(() => {
43010
43544
 
43011
43545
  // src/commands/doctor-opencode.ts
43012
43546
  import { execSync as execSync2, spawnSync as spawnSync6 } from "node:child_process";
43013
- import { existsSync as existsSync28, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
43547
+ import { existsSync as existsSync29, readFileSync as readFileSync20, statSync as statSync11 } from "node:fs";
43014
43548
  import { createRequire as createRequire5 } from "node:module";
43015
43549
  import { homedir as homedir16 } from "node:os";
43016
43550
  import { join as join25 } from "node:path";
@@ -43117,7 +43651,7 @@ function getUserNpmrcPath() {
43117
43651
  function collectNpmReleaseAgeWarnings() {
43118
43652
  const ageWarnings = [];
43119
43653
  const npmrcPath = getUserNpmrcPath();
43120
- if (!existsSync28(npmrcPath))
43654
+ if (!existsSync29(npmrcPath))
43121
43655
  return ageWarnings;
43122
43656
  try {
43123
43657
  const npmrc = readFileSync20(npmrcPath, "utf-8");
@@ -43259,7 +43793,7 @@ function checkLocalEmbeddingRuntimeForDoctor() {
43259
43793
  return { issues: 0 };
43260
43794
  }
43261
43795
  async function checkEmbeddingConfig(magicContextConfigPath) {
43262
- if (!existsSync28(magicContextConfigPath)) {
43796
+ if (!existsSync29(magicContextConfigPath)) {
43263
43797
  return checkLocalEmbeddingRuntimeForDoctor();
43264
43798
  }
43265
43799
  let rawText;
@@ -43470,7 +44004,7 @@ async function runDoctor2(options = {}) {
43470
44004
  } else {
43471
44005
  pass(`OpenCode config: ${paths.opencodeConfig}`);
43472
44006
  }
43473
- if (existsSync28(paths.magicContextConfig)) {
44007
+ if (existsSync29(paths.magicContextConfig)) {
43474
44008
  pass(`Magic Context config: ${paths.magicContextConfig}`);
43475
44009
  try {
43476
44010
  const raw = readFileSync20(paths.magicContextConfig, "utf-8");
@@ -43498,7 +44032,7 @@ async function runDoctor2(options = {}) {
43498
44032
  warn(`No magic-context.jsonc found — using defaults`);
43499
44033
  log2.info(" Run 'setup' to create one with model recommendations");
43500
44034
  }
43501
- if (existsSync28(paths.magicContextConfig)) {
44035
+ if (existsSync29(paths.magicContextConfig)) {
43502
44036
  try {
43503
44037
  const mcRaw = readFileSync20(paths.magicContextConfig, "utf-8");
43504
44038
  const mcConfig = import_comment_json11.parse(mcRaw);
@@ -43674,6 +44208,7 @@ async function runDoctor2(options = {}) {
43674
44208
  const cwd = process.cwd();
43675
44209
  const compactionEnabled = resolveCompactionEnabledForDoctor();
43676
44210
  const conflictResult = detectConflicts(cwd, { compactionEnabled });
44211
+ log2.info("Compaction check: file-based; the running server's resolved config may differ — `opencode debug config` is authoritative");
43677
44212
  if (conflictResult.hasConflict) {
43678
44213
  for (const reason of conflictResult.reasons) {
43679
44214
  fail(`Conflict: ${reason}`);
@@ -43702,7 +44237,7 @@ async function runDoctor2(options = {}) {
43702
44237
  pass("Added TUI sidebar plugin to tui.json");
43703
44238
  warn("Restart OpenCode to see the sidebar");
43704
44239
  fixed++;
43705
- } else if (existsSync28(paths.tuiConfig)) {
44240
+ } else if (existsSync29(paths.tuiConfig)) {
43706
44241
  try {
43707
44242
  const tuiRaw = readFileSync20(paths.tuiConfig, "utf-8");
43708
44243
  const tuiConfig = import_comment_json11.parse(tuiRaw);
@@ -43753,7 +44288,7 @@ async function runDoctor2(options = {}) {
43753
44288
  } else {
43754
44289
  fail("Could not create or verify the TUI sidebar config");
43755
44290
  }
43756
- if (existsSync28(paths.magicContextConfig)) {
44291
+ if (existsSync29(paths.magicContextConfig)) {
43757
44292
  try {
43758
44293
  const mcRaw = readFileSync20(paths.magicContextConfig, "utf-8");
43759
44294
  const mcConfig = import_comment_json11.parse(mcRaw);
@@ -43773,7 +44308,7 @@ async function runDoctor2(options = {}) {
43773
44308
  else
43774
44309
  passCount++;
43775
44310
  const dbPath = join25(getMagicContextStorageDir(), "context.db");
43776
- if (!existsSync28(dbPath)) {
44311
+ if (!existsSync29(dbPath)) {
43777
44312
  log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
43778
44313
  } else {
43779
44314
  log2.info(`Shared context DB exists at ${dbPath}`);
@@ -43880,7 +44415,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
43880
44415
  }
43881
44416
  }
43882
44417
  const logPath = getMagicContextLogPath2("opencode");
43883
- if (existsSync28(logPath)) {
44418
+ if (existsSync29(logPath)) {
43884
44419
  const logStat = statSync11(logPath);
43885
44420
  const sizeKb = (logStat.size / 1024).toFixed(0);
43886
44421
  log2.info(`Log file: ${logPath} (${sizeKb} KB)`);
@@ -43960,8 +44495,8 @@ var init_doctor_opencode = __esm(async () => {
43960
44495
  });
43961
44496
 
43962
44497
  // src/lib/diagnostics-pi.ts
43963
- import { createHash as createHash4 } from "node:crypto";
43964
- import { existsSync as existsSync29, readdirSync as readdirSync4, readFileSync as readFileSync21, statSync as statSync12 } from "node:fs";
44498
+ import { createHash as createHash5 } from "node:crypto";
44499
+ import { existsSync as existsSync30, readdirSync as readdirSync4, readFileSync as readFileSync21, statSync as statSync12 } from "node:fs";
43965
44500
  import { createRequire as createRequire6 } from "node:module";
43966
44501
  import { homedir as homedir17, userInfo as userInfo2 } from "node:os";
43967
44502
  import { join as join26 } from "node:path";
@@ -43979,7 +44514,7 @@ function getSelfVersion3() {
43979
44514
  }
43980
44515
  function fileSize2(path6) {
43981
44516
  try {
43982
- return existsSync29(path6) ? statSync12(path6).size : 0;
44517
+ return existsSync30(path6) ? statSync12(path6).size : 0;
43983
44518
  } catch {
43984
44519
  return 0;
43985
44520
  }
@@ -43989,7 +44524,7 @@ function escapeRegex3(value) {
43989
44524
  }
43990
44525
  function currentUserHash() {
43991
44526
  const username = userInfo2().username || "unknown";
43992
- return createHash4("sha256").update(username).digest("hex").slice(0, 12);
44527
+ return createHash5("sha256").update(username).digest("hex").slice(0, 12);
43993
44528
  }
43994
44529
  function redactSecretString(value) {
43995
44530
  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>");
@@ -44031,7 +44566,7 @@ function sanitizeValue2(value, key = "") {
44031
44566
  return value;
44032
44567
  }
44033
44568
  function readJsonc(path6) {
44034
- if (!existsSync29(path6))
44569
+ if (!existsSync30(path6))
44035
44570
  return { value: {} };
44036
44571
  try {
44037
44572
  return {
@@ -44051,7 +44586,7 @@ function readConfigDiagnostic(path6) {
44051
44586
  const parsed = readJsonc(path6);
44052
44587
  return {
44053
44588
  path: path6,
44054
- exists: existsSync29(path6),
44589
+ exists: existsSync30(path6),
44055
44590
  ...parsed.parseError ? { parseError: parsed.parseError } : {},
44056
44591
  flags: sanitizeValue2(parsed.value)
44057
44592
  };
@@ -44069,7 +44604,7 @@ function reverseSlugToDirectory(slug) {
44069
44604
  }
44070
44605
  function collectPiRecentSessions() {
44071
44606
  const sessionsRoot = getPiSessionsRoot();
44072
- if (!existsSync29(sessionsRoot))
44607
+ if (!existsSync30(sessionsRoot))
44073
44608
  return [];
44074
44609
  try {
44075
44610
  const slugs = readdirSync4(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -44138,7 +44673,7 @@ function parseHistorianDumpMeta2(path6) {
44138
44673
  }
44139
44674
  }
44140
44675
  function listDumpsInDir2(dir, limit) {
44141
- if (!existsSync29(dir))
44676
+ if (!existsSync30(dir))
44142
44677
  return { count: 0, recent: [] };
44143
44678
  try {
44144
44679
  const entries = readdirSync4(dir).filter((name) => name.endsWith(".xml")).map((name) => {
@@ -44216,7 +44751,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
44216
44751
  const storageDirPath = getMagicContextStorageDir();
44217
44752
  const dbPath = join26(storageDirPath, "context.db");
44218
44753
  const logPath = getMagicContextLogPath2("pi");
44219
- const logFileSize = existsSync29(logPath) ? statSync12(logPath).size : 0;
44754
+ const logFileSize = existsSync30(logPath) ? statSync12(logPath).size : 0;
44220
44755
  const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
44221
44756
  const recentSessions = collectPiRecentSessions();
44222
44757
  const historianDumps = collectPiHistorianDumps(recentSessions);
@@ -44231,7 +44766,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
44231
44766
  piVersion: pi ? getPiVersion(pi.path) : null,
44232
44767
  settings: {
44233
44768
  path: settingsPath,
44234
- exists: existsSync29(settingsPath),
44769
+ exists: existsSync30(settingsPath),
44235
44770
  ...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
44236
44771
  hasMagicContextPackage: hasPiMagicContextPackage(packages),
44237
44772
  packages: sanitizeValue2(packages)
@@ -44247,7 +44782,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
44247
44782
  loadWarnings: loaded.warnings.map(sanitizeString2),
44248
44783
  storageDir: {
44249
44784
  path: storageDirPath,
44250
- exists: existsSync29(storageDirPath),
44785
+ exists: existsSync30(storageDirPath),
44251
44786
  contextDbSizeBytes: fileSize2(dbPath)
44252
44787
  },
44253
44788
  conflicts: {
@@ -44256,7 +44791,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
44256
44791
  },
44257
44792
  logFile: {
44258
44793
  path: logPath,
44259
- exists: existsSync29(logPath),
44794
+ exists: existsSync30(logPath),
44260
44795
  sizeKb: Math.round(logFileSize / 1024)
44261
44796
  },
44262
44797
  recentSessions,
@@ -44428,10 +44963,10 @@ var init_logs_pi = __esm(() => {
44428
44963
 
44429
44964
  // src/commands/doctor-pi.ts
44430
44965
  import { execFileSync as execFileSync6, spawnSync as spawnSync7 } from "node:child_process";
44431
- import { existsSync as existsSync30, mkdirSync as mkdirSync10, readdirSync as readdirSync5, readFileSync as readFileSync23, rmSync as rmSync4, statSync as statSync13 } from "node:fs";
44966
+ import { existsSync as existsSync31, mkdirSync as mkdirSync11, readdirSync as readdirSync5, readFileSync as readFileSync23, rmSync as rmSync4, statSync as statSync13 } from "node:fs";
44432
44967
  import { createRequire as createRequire7 } from "node:module";
44433
44968
  import { homedir as homedir18 } from "node:os";
44434
- import { dirname as dirname15, isAbsolute as isAbsolute4, join as join28 } from "node:path";
44969
+ import { dirname as dirname16, isAbsolute as isAbsolute4, join as join28 } from "node:path";
44435
44970
  function depsFrom(options) {
44436
44971
  return {
44437
44972
  ...DEFAULT_DEPS3,
@@ -44545,13 +45080,13 @@ function piPluginDirCandidates(packages, cwd) {
44545
45080
  }
44546
45081
  dirs.push(join28(agentDir, "npm", "node_modules", PACKAGE_NAME));
44547
45082
  dirs.push(join28(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME));
44548
- return dirs.filter((dir) => existsSync30(join28(dir, "package.json")));
45083
+ return dirs.filter((dir) => existsSync31(join28(dir, "package.json")));
44549
45084
  }
44550
45085
  function projectConfigPath(cwd) {
44551
45086
  return resolveCortexKitProjectConfigPath(cwd);
44552
45087
  }
44553
45088
  function readConfigForEmbedding(path6, isProjectConfig) {
44554
- if (!existsSync30(path6))
45089
+ if (!existsSync31(path6))
44555
45090
  return null;
44556
45091
  try {
44557
45092
  const rawText = readFileSync23(path6, "utf-8");
@@ -44647,7 +45182,7 @@ function cacheRoots(cwd) {
44647
45182
  function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
44648
45183
  const found = new Map;
44649
45184
  const visit = (path6, depth) => {
44650
- if (depth < 0 || !existsSync30(path6))
45185
+ if (depth < 0 || !existsSync31(path6))
44651
45186
  return;
44652
45187
  let stat;
44653
45188
  try {
@@ -44658,7 +45193,7 @@ function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
44658
45193
  if (!stat.isDirectory())
44659
45194
  return;
44660
45195
  const packageJson = join28(path6, "package.json");
44661
- if (existsSync30(packageJson)) {
45196
+ if (existsSync31(packageJson)) {
44662
45197
  try {
44663
45198
  const pkg = JSON.parse(readFileSync23(packageJson, "utf-8"));
44664
45199
  const name = typeof pkg.name === "string" ? pkg.name : "";
@@ -44725,7 +45260,7 @@ async function runHealthChecks2(options) {
44725
45260
  }
44726
45261
  const settingsPath = getPiUserExtensionsPath();
44727
45262
  let packages = [];
44728
- if (!existsSync30(settingsPath)) {
45263
+ if (!existsSync31(settingsPath)) {
44729
45264
  add2(results, "fail", `Pi settings not found at ${settingsPath}`);
44730
45265
  repairPlan.addPackageEntry = true;
44731
45266
  } else {
@@ -44749,7 +45284,7 @@ async function runHealthChecks2(options) {
44749
45284
  ["user", userConfigPath, true],
44750
45285
  ["project", projectPath, false]
44751
45286
  ]) {
44752
- if (!existsSync30(path6)) {
45287
+ if (!existsSync31(path6)) {
44753
45288
  if (required2) {
44754
45289
  add2(results, "warn", `No ${label} magic-context.jsonc found at ${path6}`);
44755
45290
  if (userConfigMigrationRefused) {
@@ -44787,7 +45322,7 @@ async function runHealthChecks2(options) {
44787
45322
  }
44788
45323
  const storageDir = getMagicContextStorageDir();
44789
45324
  const dbPath = join28(storageDir, "context.db");
44790
- const existedBeforeOpen = existsSync30(dbPath);
45325
+ const existedBeforeOpen = existsSync31(dbPath);
44791
45326
  if (existedBeforeOpen)
44792
45327
  add2(results, "pass", `Shared context DB exists at ${dbPath}`);
44793
45328
  else
@@ -44924,7 +45459,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
44924
45459
  add2(results, "pass", "Pi extension cache clean (no stale cached package found)");
44925
45460
  }
44926
45461
  const logPath = getMagicContextLogPath2("pi");
44927
- if (existsSync30(logPath)) {
45462
+ if (existsSync31(logPath)) {
44928
45463
  const stat = statSync13(logPath);
44929
45464
  const sizeKb = (stat.size / 1024).toFixed(0);
44930
45465
  const lines = readFileSync23(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -44962,7 +45497,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
44962
45497
  return { results, repairPlan, ...summarize(results) };
44963
45498
  }
44964
45499
  function writeDefaultMagicContextConfig(path6) {
44965
- mkdirSync10(dirname15(path6), { recursive: true });
45500
+ mkdirSync11(dirname16(path6), { recursive: true });
44966
45501
  const config2 = {
44967
45502
  $schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
44968
45503
  ...MagicContextConfigSchema.parse({})
@@ -44984,7 +45519,7 @@ function repair2(plan, prompts) {
44984
45519
  }
44985
45520
  if (plan.writeUserConfig) {
44986
45521
  const configPath = getPiUserConfigPath();
44987
- if (!existsSync30(configPath)) {
45522
+ if (!existsSync31(configPath)) {
44988
45523
  try {
44989
45524
  writeDefaultMagicContextConfig(configPath);
44990
45525
  prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
@@ -45216,7 +45751,7 @@ var exports_doctor = {};
45216
45751
  __export(exports_doctor, {
45217
45752
  runDoctor: () => runDoctor4
45218
45753
  });
45219
- import { existsSync as existsSync31, rmSync as rmSync5 } from "node:fs";
45754
+ import { existsSync as existsSync32, rmSync as rmSync5 } from "node:fs";
45220
45755
  import { join as join29 } from "node:path";
45221
45756
  async function runDoctor4(options) {
45222
45757
  if (options.clear)
@@ -45248,6 +45783,27 @@ async function runDoctor4(options) {
45248
45783
  if (result.handled)
45249
45784
  return result.exitCode;
45250
45785
  }
45786
+ const { sweepPendingMigrations: sweepPendingMigrations2, formatMigrationSweepLines: formatMigrationSweepLines2 } = await init_migrate().then(() => exports_migrate);
45787
+ const sweepDbPath = join29(getMagicContextStorageDir(), "context.db");
45788
+ let sweepDb = null;
45789
+ try {
45790
+ sweepDb = openExistingContextDatabaseForMutation(sweepDbPath);
45791
+ } catch {}
45792
+ if (sweepDb !== null) {
45793
+ try {
45794
+ const report = sweepPendingMigrations2(sweepDb);
45795
+ for (const line of formatMigrationSweepLines2(report)) {
45796
+ if (line.startsWith("LOST"))
45797
+ log2.error(line);
45798
+ else
45799
+ log2.info(line);
45800
+ }
45801
+ } catch (error51) {
45802
+ log2.warn(`Session-migration recovery sweep failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
45803
+ } finally {
45804
+ sweepDb.close();
45805
+ }
45806
+ }
45251
45807
  let anyFailure = false;
45252
45808
  for (const adapter of adapters) {
45253
45809
  log2.step(`Running doctor for ${adapter.displayName}…`);
@@ -45324,7 +45880,7 @@ async function runClear() {
45324
45880
  const s = spinner2();
45325
45881
  s.start(`Clearing ${item.path}`);
45326
45882
  try {
45327
- if (existsSync31(item.path)) {
45883
+ if (existsSync32(item.path)) {
45328
45884
  rmSync5(item.path, { recursive: true, force: true });
45329
45885
  }
45330
45886
  s.stop(`Cleared ${item.path}`);
@@ -45340,9 +45896,9 @@ async function runClear() {
45340
45896
  function formatSize(bytes) {
45341
45897
  if (bytes < 1024)
45342
45898
  return `${bytes} B`;
45343
- if (bytes < 1024 * 1024)
45899
+ if (bytes < 1048576)
45344
45900
  return `${(bytes / 1024).toFixed(1)} KB`;
45345
- if (bytes < 1024 * 1024 * 1024)
45901
+ if (bytes < 1073741824)
45346
45902
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
45347
45903
  return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`;
45348
45904
  }