@cortexkit/magic-context 0.16.2 → 0.17.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 +1037 -295
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -11053,7 +11053,7 @@ function printNextSteps(adapter) {
11053
11053
  if (adapter.kind === "opencode") {
11054
11054
  note([
11055
11055
  "Restart OpenCode (or reload your session) so the plugin loads.",
11056
- "Verify with: bunx --bun @cortexkit/magic-context@latest doctor"
11056
+ "Verify with: npx @cortexkit/magic-context@latest doctor"
11057
11057
  ].join(`
11058
11058
  `), "Next steps");
11059
11059
  return;
@@ -11061,7 +11061,7 @@ function printNextSteps(adapter) {
11061
11061
  if (adapter.kind === "pi") {
11062
11062
  note([
11063
11063
  "Restart your Pi session so the extension registers.",
11064
- "Verify with: bunx --bun @cortexkit/magic-context@latest doctor --harness pi"
11064
+ "Verify with: npx @cortexkit/magic-context@latest doctor --harness pi"
11065
11065
  ].join(`
11066
11066
  `), "Next steps");
11067
11067
  }
@@ -11096,14 +11096,384 @@ function getOpenCodeCacheDir() {
11096
11096
  }
11097
11097
  var init_data_path = () => {};
11098
11098
 
11099
+ // ../../node_modules/.bun/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
11100
+ function parseTar(data, opts) {
11101
+ const buffer = data.buffer || data;
11102
+ const files = [];
11103
+ let offset = 0;
11104
+ let nextExtendedHeader;
11105
+ let globalExtendedHeader;
11106
+ while (offset < buffer.byteLength - 512) {
11107
+ let name = _readString(buffer, offset, 100);
11108
+ if (name.length === 0) {
11109
+ break;
11110
+ }
11111
+ if (nextExtendedHeader) {
11112
+ const longName = nextExtendedHeader.path || nextExtendedHeader.linkpath;
11113
+ if (longName) {
11114
+ name = longName;
11115
+ }
11116
+ }
11117
+ const mode = _readString(buffer, offset + 100, 8).trim();
11118
+ const uid = Number.parseInt(_readString(buffer, offset + 108, 8));
11119
+ const gid = Number.parseInt(_readString(buffer, offset + 116, 8));
11120
+ const size = _readNumber(buffer, offset + 124, 12);
11121
+ const seek = 512 + 512 * Math.trunc(size / 512) + (size % 512 ? 512 : 0);
11122
+ const mtime = _readNumber(buffer, offset + 136, 12);
11123
+ const _type = _readString(buffer, offset + 156, 1) || "0";
11124
+ const type = tarItemTypeMap[_type] || _type;
11125
+ switch (type) {
11126
+ case "extendedHeader":
11127
+ case "globalExtendedHeader": {
11128
+ const headers = _parseExtendedHeaders(new Uint8Array(buffer, offset + 512, size));
11129
+ if (type === "extendedHeader") {
11130
+ nextExtendedHeader = headers;
11131
+ } else {
11132
+ nextExtendedHeader = undefined;
11133
+ globalExtendedHeader = {
11134
+ ...globalExtendedHeader,
11135
+ ...headers
11136
+ };
11137
+ }
11138
+ offset += seek;
11139
+ continue;
11140
+ }
11141
+ case "gnuLongFileName":
11142
+ case "gnuOldLongFileName":
11143
+ case "gnuLongLinkName": {
11144
+ nextExtendedHeader = { path: _readString(buffer, offset + 512, size) };
11145
+ offset += seek;
11146
+ continue;
11147
+ }
11148
+ }
11149
+ const user = _readString(buffer, offset + 265, 32);
11150
+ const group = _readString(buffer, offset + 297, 32);
11151
+ name = _sanitizePath(name);
11152
+ const meta = {
11153
+ name,
11154
+ type,
11155
+ size,
11156
+ attrs: {
11157
+ ...globalExtendedHeader,
11158
+ ...nextExtendedHeader,
11159
+ mode,
11160
+ uid,
11161
+ gid,
11162
+ mtime,
11163
+ user,
11164
+ group
11165
+ }
11166
+ };
11167
+ nextExtendedHeader = undefined;
11168
+ if (opts?.filter && !opts.filter(meta)) {
11169
+ offset += seek;
11170
+ continue;
11171
+ }
11172
+ if (opts?.metaOnly) {
11173
+ files.push(meta);
11174
+ offset += seek;
11175
+ continue;
11176
+ }
11177
+ const data2 = size === 0 ? undefined : new Uint8Array(buffer, offset + 512, size);
11178
+ files.push({
11179
+ ...meta,
11180
+ data: data2,
11181
+ get text() {
11182
+ return new TextDecoder().decode(this.data);
11183
+ }
11184
+ });
11185
+ offset += seek;
11186
+ }
11187
+ return files;
11188
+ }
11189
+ async function parseTarGzip(data, opts = {}) {
11190
+ const stream = new ReadableStream({
11191
+ start(controller) {
11192
+ controller.enqueue(new Uint8Array(data));
11193
+ controller.close();
11194
+ }
11195
+ }).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
11196
+ const decompressedData = await new Response(stream).arrayBuffer();
11197
+ return parseTar(decompressedData, opts);
11198
+ }
11199
+ function _sanitizePath(path2) {
11200
+ let normalized = path2.replace(/\\/g, "/");
11201
+ normalized = normalized.replace(/^[a-zA-Z]:\//, "");
11202
+ normalized = normalized.replace(/^\/+/, "");
11203
+ const hasLeadingDotSlash = normalized.startsWith("./");
11204
+ const parts = normalized.split("/");
11205
+ const resolved = [];
11206
+ for (const part of parts) {
11207
+ if (part === "..") {
11208
+ resolved.pop();
11209
+ } else if (part !== "." && part !== "") {
11210
+ resolved.push(part);
11211
+ }
11212
+ }
11213
+ let result = resolved.join("/");
11214
+ if (hasLeadingDotSlash && !result.startsWith("./")) {
11215
+ result = "./" + result;
11216
+ }
11217
+ if (path2.endsWith("/") && !result.endsWith("/")) {
11218
+ result += "/";
11219
+ }
11220
+ return result;
11221
+ }
11222
+ function _readString(buffer, offset, size) {
11223
+ const view = new Uint8Array(buffer, offset, size);
11224
+ const i = view.indexOf(0);
11225
+ const td = new TextDecoder;
11226
+ return td.decode(i === -1 ? view : view.slice(0, i));
11227
+ }
11228
+ function _readNumber(buffer, offset, size) {
11229
+ const view = new Uint8Array(buffer, offset, size);
11230
+ let str = "";
11231
+ for (let i = 0;i < size; i++) {
11232
+ str += String.fromCodePoint(view[i]);
11233
+ }
11234
+ return Number.parseInt(str, 8);
11235
+ }
11236
+ function _parseExtendedHeaders(data) {
11237
+ const dataStr = new TextDecoder().decode(data);
11238
+ const headers = {};
11239
+ for (const line of dataStr.split(`
11240
+ `)) {
11241
+ const s = line.split(" ")[1]?.split("=");
11242
+ if (s) {
11243
+ headers[s[0]] = s[1];
11244
+ }
11245
+ }
11246
+ return headers;
11247
+ }
11248
+ var tarItemTypeMap;
11249
+ var init_dist3 = __esm(() => {
11250
+ tarItemTypeMap = {
11251
+ "0": "file",
11252
+ "1": "hardLink",
11253
+ "2": "symbolicLink",
11254
+ "3": "characterDevice",
11255
+ "4": "blockDevice",
11256
+ "5": "directory",
11257
+ "6": "fifo",
11258
+ "7": "contiguousFile",
11259
+ g: "globalExtendedHeader",
11260
+ x: "extendedHeader",
11261
+ D: "gnuDirectory",
11262
+ I: "gnuInodeMetadata",
11263
+ K: "gnuLongLinkName",
11264
+ L: "gnuLongFileName",
11265
+ N: "gnuOldLongFileName",
11266
+ M: "gnuMultiVolume",
11267
+ S: "gnuSparseFile",
11268
+ E: "gnuExtendedSparse",
11269
+ A: "solarisAcl",
11270
+ V: "solarisVolumeLabel",
11271
+ X: "solarisOldExtendedHeader"
11272
+ };
11273
+ });
11274
+
11275
+ // ../plugin/src/shared/logger.ts
11276
+ import * as fs from "node:fs";
11277
+ import * as os2 from "node:os";
11278
+ import * as path2 from "node:path";
11279
+ function flush() {
11280
+ if (flushTimer) {
11281
+ clearTimeout(flushTimer);
11282
+ flushTimer = null;
11283
+ }
11284
+ if (buffer.length === 0)
11285
+ return;
11286
+ const data = buffer.join("");
11287
+ buffer = [];
11288
+ try {
11289
+ fs.appendFileSync(logFile, data);
11290
+ } catch {}
11291
+ }
11292
+ function scheduleFlush() {
11293
+ if (flushTimer)
11294
+ return;
11295
+ flushTimer = setTimeout(() => {
11296
+ flushTimer = null;
11297
+ flush();
11298
+ }, FLUSH_INTERVAL_MS);
11299
+ }
11300
+ function log2(message, data) {
11301
+ if (isTestEnv)
11302
+ return;
11303
+ try {
11304
+ const timestamp = new Date().toISOString();
11305
+ const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
11306
+ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
11307
+ buffer.push(`[${timestamp}] ${message}${serialized}
11308
+ `);
11309
+ if (buffer.length >= BUFFER_SIZE_LIMIT) {
11310
+ flush();
11311
+ } else {
11312
+ scheduleFlush();
11313
+ }
11314
+ } catch {}
11315
+ }
11316
+ var logFile, isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
11317
+ var init_logger = __esm(() => {
11318
+ logFile = path2.join(os2.tmpdir(), "magic-context.log");
11319
+ buffer = [];
11320
+ if (!isTestEnv) {
11321
+ process.on("exit", flush);
11322
+ }
11323
+ });
11324
+
11325
+ // ../plugin/src/shared/native-binding.ts
11326
+ var exports_native_binding = {};
11327
+ __export(exports_native_binding, {
11328
+ resolveBetterSqliteNativeBinding: () => resolveBetterSqliteNativeBinding
11329
+ });
11330
+ import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
11331
+ import { createRequire as createRequire2 } from "node:module";
11332
+ import * as path3 from "node:path";
11333
+ function logInfo(message) {
11334
+ log2(`${PREFIX} ${message}`);
11335
+ }
11336
+ function logWarn(message) {
11337
+ log2(`${PREFIX} WARN ${message}`);
11338
+ }
11339
+ function probeAbi(binaryPath) {
11340
+ const expected = process.versions.modules;
11341
+ try {
11342
+ const sandbox = { exports: {} };
11343
+ process.dlopen(sandbox, binaryPath);
11344
+ return { ok: true };
11345
+ } catch (err) {
11346
+ const message = err instanceof Error ? err.message : String(err);
11347
+ const pair = message.match(/NODE_MODULE_VERSION (\d+).*NODE_MODULE_VERSION (\d+)/s);
11348
+ if (pair?.[1] && pair[2]) {
11349
+ return { ok: false, expected: pair[2], actual: pair[1] };
11350
+ }
11351
+ const single = message.match(/NODE_MODULE_VERSION[ =:]+(\d+)/);
11352
+ if (single?.[1]) {
11353
+ return { ok: false, expected, actual: single[1] };
11354
+ }
11355
+ logWarn(`could not parse ABI from dlopen error: ${message}`);
11356
+ return { ok: false, expected, actual: null };
11357
+ }
11358
+ }
11359
+ function resolveBetterSqlite3OnDisk(requireFn) {
11360
+ try {
11361
+ const pkgJsonPath = requireFn.resolve("better-sqlite3/package.json");
11362
+ const pkgDir = path3.dirname(pkgJsonPath);
11363
+ const pkgJson = requireFn(pkgJsonPath);
11364
+ const binaryPath = path3.join(pkgDir, "build", "Release", "better_sqlite3.node");
11365
+ return { binaryPath, pkgVersion: pkgJson.version };
11366
+ } catch (err) {
11367
+ logWarn(`could not resolve better-sqlite3 in node_modules: ${err instanceof Error ? err.message : String(err)}`);
11368
+ return null;
11369
+ }
11370
+ }
11371
+ function getCachedBinaryPath(pkgVersion, abi) {
11372
+ return path3.join(getCacheDir(), "cortexkit", "native-bindings", "better-sqlite3", `v${pkgVersion}`, `electron-v${abi}-${process.platform}-${process.arch}`, "better_sqlite3.node");
11373
+ }
11374
+ async function downloadElectronPrebuild(pkgVersion, abi) {
11375
+ const filename = `better-sqlite3-v${pkgVersion}-electron-v${abi}-${process.platform}-${process.arch}.tar.gz`;
11376
+ const url = `https://github.com/WiseLibs/better-sqlite3/releases/download/v${pkgVersion}/${filename}`;
11377
+ logInfo(`downloading ${url}`);
11378
+ const response = await fetch(url, {
11379
+ redirect: "follow",
11380
+ headers: { "User-Agent": "magic-context-plugin/native-binding" }
11381
+ });
11382
+ if (!response.ok) {
11383
+ throw new Error(`failed to download Electron prebuild (HTTP ${response.status} ${response.statusText}) from ${url}`);
11384
+ }
11385
+ const tarballBytes = new Uint8Array(await response.arrayBuffer());
11386
+ logInfo(`downloaded ${(tarballBytes.length / 1024).toFixed(1)} KB; extracting`);
11387
+ const files = await parseTarGzip(tarballBytes);
11388
+ const nodeFile = files.find((f) => f.name.endsWith("better_sqlite3.node"));
11389
+ if (!nodeFile?.data) {
11390
+ const names = files.map((f) => f.name).join(", ");
11391
+ throw new Error(`Electron prebuild tarball did not contain better_sqlite3.node; got: [${names}]`);
11392
+ }
11393
+ return nodeFile.data instanceof Uint8Array ? nodeFile.data : new Uint8Array(nodeFile.data);
11394
+ }
11395
+ async function resolveBetterSqliteNativeBinding() {
11396
+ if (!process.versions.electron) {
11397
+ return null;
11398
+ }
11399
+ if (inFlight) {
11400
+ return inFlight;
11401
+ }
11402
+ const promise = (async () => {
11403
+ const expected = process.versions.modules;
11404
+ logInfo(`Electron detected (v${process.versions.electron}, NODE_MODULE_VERSION ${expected}); verifying better-sqlite3 binding`);
11405
+ const requireFn = createRequire2(import.meta.url);
11406
+ const resolved = resolveBetterSqlite3OnDisk(requireFn);
11407
+ if (!resolved) {
11408
+ return null;
11409
+ }
11410
+ const { binaryPath: diskPath, pkgVersion } = resolved;
11411
+ if (existsSync9(diskPath)) {
11412
+ const diskProbe = probeAbi(diskPath);
11413
+ if (diskProbe.ok) {
11414
+ logInfo(`on-disk binary already matches Electron ABI v${expected}; using default bindings() lookup`);
11415
+ return null;
11416
+ }
11417
+ logInfo(`on-disk binary ABI ${diskProbe.actual ?? "unknown"} != required ${expected}; will use Electron prebuild`);
11418
+ } else {
11419
+ logWarn(`expected better-sqlite3 binary not found at ${diskPath}; will fetch Electron prebuild anyway`);
11420
+ }
11421
+ const cachedPath = getCachedBinaryPath(pkgVersion, expected);
11422
+ if (existsSync9(cachedPath)) {
11423
+ const cachedProbe = probeAbi(cachedPath);
11424
+ if (cachedProbe.ok) {
11425
+ logInfo(`using cached Electron prebuild at ${cachedPath}`);
11426
+ return cachedPath;
11427
+ }
11428
+ logWarn(`cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`);
11429
+ }
11430
+ mkdirSync4(path3.dirname(cachedPath), { recursive: true });
11431
+ const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
11432
+ writeFileSync6(cachedPath, nodeFileBytes);
11433
+ logInfo(`cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`);
11434
+ const finalProbe = probeAbi(cachedPath);
11435
+ if (!finalProbe.ok) {
11436
+ throw new Error(`downloaded Electron prebuild has wrong ABI (${finalProbe.actual ?? "unknown"} != ${expected}); refusing to use`);
11437
+ }
11438
+ return cachedPath;
11439
+ })();
11440
+ inFlight = promise;
11441
+ try {
11442
+ return await promise;
11443
+ } finally {
11444
+ if (inFlight === promise) {
11445
+ inFlight = null;
11446
+ }
11447
+ }
11448
+ }
11449
+ var PREFIX = "[native-binding]", inFlight = null;
11450
+ var init_native_binding = __esm(() => {
11451
+ init_dist3();
11452
+ init_data_path();
11453
+ init_logger();
11454
+ });
11455
+
11099
11456
  // ../plugin/src/shared/sqlite.ts
11100
- var isBun, bunSpec, betterSpec, sqliteModule, DatabaseImpl, Database;
11457
+ var isBun, bunSpec, betterSpec, electronNativeBinding, sqliteModule, RawDatabaseImpl, DatabaseImpl, Database;
11101
11458
  var init_sqlite = __esm(async () => {
11102
11459
  isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
11103
11460
  bunSpec = "bun:" + "sqlite";
11104
11461
  betterSpec = "better-" + "sqlite3";
11462
+ electronNativeBinding = isBun ? null : await (async () => {
11463
+ const mod = await Promise.resolve().then(() => (init_native_binding(), exports_native_binding));
11464
+ return mod.resolveBetterSqliteNativeBinding();
11465
+ })();
11105
11466
  sqliteModule = isBun ? await import(bunSpec) : await import(betterSpec);
11106
- DatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
11467
+ RawDatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
11468
+ DatabaseImpl = electronNativeBinding == null ? RawDatabaseImpl : class DatabaseWithElectronBinding extends RawDatabaseImpl {
11469
+ constructor(filename, options) {
11470
+ const fallback = electronNativeBinding;
11471
+ super(filename, {
11472
+ ...options,
11473
+ nativeBinding: options?.nativeBinding ?? fallback
11474
+ });
11475
+ }
11476
+ };
11107
11477
  Database = DatabaseImpl;
11108
11478
  });
11109
11479
 
@@ -11119,20 +11489,20 @@ __export(exports_migrate, {
11119
11489
  formatPiFilenameTimestamp: () => formatPiFilenameTimestamp
11120
11490
  });
11121
11491
  import { randomBytes } from "node:crypto";
11122
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
11492
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
11123
11493
  import { homedir as homedir5 } from "node:os";
11124
- import { join as join7 } from "node:path";
11494
+ import { join as join9 } from "node:path";
11125
11495
  function defaultOpenCodeDbPath() {
11126
- return join7(homedir5(), ".local", "share", "opencode", "opencode.db");
11496
+ return join9(homedir5(), ".local", "share", "opencode", "opencode.db");
11127
11497
  }
11128
11498
  function defaultCortexkitDbPath() {
11129
- return join7(getMagicContextStorageDir(), "context.db");
11499
+ return join9(getMagicContextStorageDir(), "context.db");
11130
11500
  }
11131
11501
  function defaultPiSessionsRoot() {
11132
- return join7(homedir5(), ".pi", "agent", "sessions");
11502
+ return join9(homedir5(), ".pi", "agent", "sessions");
11133
11503
  }
11134
11504
  function defaultFs() {
11135
- return { existsSync: existsSync9, mkdirSync: mkdirSync4, writeFileSync: writeFileSync6 };
11505
+ return { existsSync: existsSync10, mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 };
11136
11506
  }
11137
11507
  function stmt(db, sql) {
11138
11508
  return db.prepare(sql);
@@ -11529,7 +11899,7 @@ function ensureValidOptions(opts) {
11529
11899
  }
11530
11900
  }
11531
11901
  function migrateOpenCodeSessionToPi(opts) {
11532
- const fs = opts.fs ?? defaultFs();
11902
+ const fs2 = opts.fs ?? defaultFs();
11533
11903
  const now = opts.now ?? new Date;
11534
11904
  const opencodeDbPath = opts.opencodeDbPath ?? defaultOpenCodeDbPath();
11535
11905
  const piSessionsRoot = opts.piSessionsRoot ?? defaultPiSessionsRoot();
@@ -11555,7 +11925,7 @@ function migrateOpenCodeSessionToPi(opts) {
11555
11925
  const provider = opts.provider ?? model.provider;
11556
11926
  const modelId = opts.modelId ?? model.modelId;
11557
11927
  const cwd = session.directory ?? session.path ?? process.cwd();
11558
- const outputDir = join7(piSessionsRoot, projectPathToPiDirSlug(cwd));
11928
+ const outputDir = join9(piSessionsRoot, projectPathToPiDirSlug(cwd));
11559
11929
  const buildResult = buildPiEntries({
11560
11930
  session,
11561
11931
  messages,
@@ -11581,14 +11951,14 @@ function migrateOpenCodeSessionToPi(opts) {
11581
11951
  });
11582
11952
  }
11583
11953
  const compactionMarker = insertCompactionMarker(buildResult.entries, copyResult.lastCompartmentEndPiEntryId);
11584
- const outputPath = join7(outputDir, `${formatPiFilenameTimestamp(now)}_${buildResult.piSessionId}.jsonl`);
11954
+ const outputPath = join9(outputDir, `${formatPiFilenameTimestamp(now)}_${buildResult.piSessionId}.jsonl`);
11585
11955
  const jsonl = `${buildResult.entries.map((entry) => JSON.stringify(entry)).join(`
11586
11956
  `)}
11587
11957
  `;
11588
11958
  if (!opts.dryRun) {
11589
- if (!fs.existsSync(outputDir))
11590
- fs.mkdirSync(outputDir, { recursive: true });
11591
- fs.writeFileSync(outputPath, jsonl);
11959
+ if (!fs2.existsSync(outputDir))
11960
+ fs2.mkdirSync(outputDir, { recursive: true });
11961
+ fs2.writeFileSync(outputPath, jsonl);
11592
11962
  }
11593
11963
  return {
11594
11964
  outputPath,
@@ -11651,7 +12021,7 @@ function printMigrateHelp() {
11651
12021
  --from opencode --to pi
11652
12022
 
11653
12023
  Usage:
11654
- bunx --bun @cortexkit/opencode-magic-context@latest doctor migrate \\
12024
+ npx @cortexkit/opencode-magic-context@latest doctor migrate \\
11655
12025
  --from opencode --to pi --session ses_xxx [--max-messages N] [--dry-run]
11656
12026
 
11657
12027
  Fidelity:
@@ -11955,10 +12325,10 @@ function mergeDefs(...defs) {
11955
12325
  function cloneDef(schema) {
11956
12326
  return mergeDefs(schema._zod.def);
11957
12327
  }
11958
- function getElementAtPath(obj, path2) {
11959
- if (!path2)
12328
+ function getElementAtPath(obj, path4) {
12329
+ if (!path4)
11960
12330
  return obj;
11961
- return path2.reduce((acc, key) => acc?.[key], obj);
12331
+ return path4.reduce((acc, key) => acc?.[key], obj);
11962
12332
  }
11963
12333
  function promiseAllObject(promisesObj) {
11964
12334
  const keys = Object.keys(promisesObj);
@@ -12269,11 +12639,11 @@ function aborted(x3, startIndex = 0) {
12269
12639
  }
12270
12640
  return false;
12271
12641
  }
12272
- function prefixIssues(path2, issues) {
12642
+ function prefixIssues(path4, issues) {
12273
12643
  return issues.map((iss) => {
12274
12644
  var _a;
12275
12645
  (_a = iss).path ?? (_a.path = []);
12276
- iss.path.unshift(path2);
12646
+ iss.path.unshift(path4);
12277
12647
  return iss;
12278
12648
  });
12279
12649
  }
@@ -12511,7 +12881,7 @@ function formatError(error, mapper = (issue2) => issue2.message) {
12511
12881
  }
12512
12882
  function treeifyError(error, mapper = (issue2) => issue2.message) {
12513
12883
  const result = { errors: [] };
12514
- const processError = (error2, path2 = []) => {
12884
+ const processError = (error2, path4 = []) => {
12515
12885
  var _a, _b;
12516
12886
  for (const issue2 of error2.issues) {
12517
12887
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -12521,7 +12891,7 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
12521
12891
  } else if (issue2.code === "invalid_element") {
12522
12892
  processError({ issues: issue2.issues }, issue2.path);
12523
12893
  } else {
12524
- const fullpath = [...path2, ...issue2.path];
12894
+ const fullpath = [...path4, ...issue2.path];
12525
12895
  if (fullpath.length === 0) {
12526
12896
  result.errors.push(mapper(issue2));
12527
12897
  continue;
@@ -12553,8 +12923,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
12553
12923
  }
12554
12924
  function toDotPath(_path) {
12555
12925
  const segs = [];
12556
- const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12557
- for (const seg of path2) {
12926
+ const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
12927
+ for (const seg of path4) {
12558
12928
  if (typeof seg === "number")
12559
12929
  segs.push(`[${seg}]`);
12560
12930
  else if (typeof seg === "symbol")
@@ -24829,13 +25199,13 @@ function resolveRef(ref, ctx) {
24829
25199
  if (!ref.startsWith("#")) {
24830
25200
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
24831
25201
  }
24832
- const path2 = ref.slice(1).split("/").filter(Boolean);
24833
- if (path2.length === 0) {
25202
+ const path4 = ref.slice(1).split("/").filter(Boolean);
25203
+ if (path4.length === 0) {
24834
25204
  return ctx.rootSchema;
24835
25205
  }
24836
25206
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
24837
- if (path2[0] === defsKey) {
24838
- const key = path2[1];
25207
+ if (path4[0] === defsKey) {
25208
+ const key = path4[1];
24839
25209
  if (!key || !ctx.defs[key]) {
24840
25210
  throw new Error(`Reference not found: ${ref}`);
24841
25211
  }
@@ -25790,9 +26160,9 @@ var init_magic_context = __esm(() => {
25790
26160
  });
25791
26161
 
25792
26162
  // ../plugin/src/config/variable.ts
25793
- import { existsSync as existsSync10, readFileSync as readFileSync6 } from "node:fs";
26163
+ import { existsSync as existsSync11, readFileSync as readFileSync6 } from "node:fs";
25794
26164
  import { homedir as homedir6 } from "node:os";
25795
- import { dirname as dirname6, isAbsolute, resolve as resolve2 } from "node:path";
26165
+ import { dirname as dirname7, isAbsolute, resolve as resolve2 } from "node:path";
25796
26166
  function substituteConfigVariables(input) {
25797
26167
  const warnings = [];
25798
26168
  let text2 = input.text;
@@ -25809,7 +26179,7 @@ function substituteConfigVariables(input) {
25809
26179
  if (fileMatches.length === 0) {
25810
26180
  return { text: text2, warnings };
25811
26181
  }
25812
- const configDir = input.configPath ? dirname6(input.configPath) : process.cwd();
26182
+ const configDir = input.configPath ? dirname7(input.configPath) : process.cwd();
25813
26183
  let output = "";
25814
26184
  let cursor = 0;
25815
26185
  for (const match of fileMatches) {
@@ -25831,7 +26201,7 @@ function substituteConfigVariables(input) {
25831
26201
  } else if (!isAbsolute(filePath)) {
25832
26202
  filePath = resolve2(configDir, filePath);
25833
26203
  }
25834
- if (!existsSync10(filePath)) {
26204
+ if (!existsSync11(filePath)) {
25835
26205
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
25836
26206
  continue;
25837
26207
  }
@@ -25855,19 +26225,19 @@ var init_variable = __esm(() => {
25855
26225
  });
25856
26226
 
25857
26227
  // ../plugin/src/config/index.ts
25858
- import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
26228
+ import { existsSync as existsSync12, readFileSync as readFileSync7 } from "node:fs";
25859
26229
  import { homedir as homedir7 } from "node:os";
25860
- import { join as join8 } from "node:path";
26230
+ import { join as join10 } from "node:path";
25861
26231
  function getUserConfigBasePath() {
25862
- const configRoot = process.env.XDG_CONFIG_HOME ?? join8(homedir7(), ".config");
25863
- return join8(configRoot, "opencode", CONFIG_FILE_BASENAME);
26232
+ const configRoot = process.env.XDG_CONFIG_HOME ?? join10(homedir7(), ".config");
26233
+ return join10(configRoot, "opencode", CONFIG_FILE_BASENAME);
25864
26234
  }
25865
26235
  function getProjectConfigBasePath(directory) {
25866
- return join8(directory, ".opencode", CONFIG_FILE_BASENAME);
26236
+ return join10(directory, ".opencode", CONFIG_FILE_BASENAME);
25867
26237
  }
25868
26238
  function loadConfigFile(configPath) {
25869
26239
  try {
25870
- if (!existsSync11(configPath)) {
26240
+ if (!existsSync12(configPath)) {
25871
26241
  return null;
25872
26242
  }
25873
26243
  const rawText = readFileSync7(configPath, "utf-8");
@@ -26044,7 +26414,7 @@ function parsePluginConfig(rawConfig) {
26044
26414
  }
26045
26415
  function loadPluginConfig(directory) {
26046
26416
  const userDetected = detectConfigFile(getUserConfigBasePath());
26047
- const rootDetected = detectConfigFile(join8(directory, CONFIG_FILE_BASENAME));
26417
+ const rootDetected = detectConfigFile(join10(directory, CONFIG_FILE_BASENAME));
26048
26418
  const dotOpenCodeDetected = detectConfigFile(getProjectConfigBasePath(directory));
26049
26419
  const projectDetected = rootDetected.format !== "none" ? rootDetected : dotOpenCodeDetected;
26050
26420
  const userLoaded = userDetected.format === "none" ? null : loadConfigFile(userDetected.path);
@@ -26187,59 +26557,9 @@ function truncate(text2) {
26187
26557
  }
26188
26558
  var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
26189
26559
 
26190
- // ../plugin/src/shared/logger.ts
26191
- import * as fs from "node:fs";
26192
- import * as os2 from "node:os";
26193
- import * as path2 from "node:path";
26194
- function flush() {
26195
- if (flushTimer) {
26196
- clearTimeout(flushTimer);
26197
- flushTimer = null;
26198
- }
26199
- if (buffer.length === 0)
26200
- return;
26201
- const data = buffer.join("");
26202
- buffer = [];
26203
- try {
26204
- fs.appendFileSync(logFile, data);
26205
- } catch {}
26206
- }
26207
- function scheduleFlush() {
26208
- if (flushTimer)
26209
- return;
26210
- flushTimer = setTimeout(() => {
26211
- flushTimer = null;
26212
- flush();
26213
- }, FLUSH_INTERVAL_MS);
26214
- }
26215
- function log2(message, data) {
26216
- if (isTestEnv)
26217
- return;
26218
- try {
26219
- const timestamp = new Date().toISOString();
26220
- const serialized = data === undefined ? "" : data instanceof Error ? ` ${data.message}${data.stack ? `
26221
- ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
26222
- buffer.push(`[${timestamp}] ${message}${serialized}
26223
- `);
26224
- if (buffer.length >= BUFFER_SIZE_LIMIT) {
26225
- flush();
26226
- } else {
26227
- scheduleFlush();
26228
- }
26229
- } catch {}
26230
- }
26231
- var logFile, isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50;
26232
- var init_logger = __esm(() => {
26233
- logFile = path2.join(os2.tmpdir(), "magic-context.log");
26234
- buffer = [];
26235
- if (!isTestEnv) {
26236
- process.on("exit", flush);
26237
- }
26238
- });
26239
-
26240
26560
  // ../plugin/src/shared/tui-config.ts
26241
- import { existsSync as existsSync12, mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
26242
- import { dirname as dirname7, join as join10 } from "node:path";
26561
+ import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync8 } from "node:fs";
26562
+ import { dirname as dirname8, join as join11 } from "node:path";
26243
26563
  function isMagicContextEntry(entry) {
26244
26564
  if (!entry)
26245
26565
  return false;
@@ -26253,11 +26573,11 @@ function isMagicContextEntry(entry) {
26253
26573
  }
26254
26574
  function resolveTuiConfigPath() {
26255
26575
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
26256
- const jsoncPath = join10(configDir, "tui.jsonc");
26257
- const jsonPath = join10(configDir, "tui.json");
26258
- if (existsSync12(jsoncPath))
26576
+ const jsoncPath = join11(configDir, "tui.jsonc");
26577
+ const jsonPath = join11(configDir, "tui.json");
26578
+ if (existsSync13(jsoncPath))
26259
26579
  return jsoncPath;
26260
- if (existsSync12(jsonPath))
26580
+ if (existsSync13(jsonPath))
26261
26581
  return jsonPath;
26262
26582
  return jsonPath;
26263
26583
  }
@@ -26265,7 +26585,7 @@ function ensureTuiPluginEntry() {
26265
26585
  try {
26266
26586
  const configPath = resolveTuiConfigPath();
26267
26587
  let config2 = {};
26268
- if (existsSync12(configPath)) {
26588
+ if (existsSync13(configPath)) {
26269
26589
  const raw = readFileSync8(configPath, "utf-8");
26270
26590
  config2 = import_comment_json5.parse(raw) ?? {};
26271
26591
  }
@@ -26285,8 +26605,8 @@ function ensureTuiPluginEntry() {
26285
26605
  plugins.push(PLUGIN_ENTRY3);
26286
26606
  }
26287
26607
  config2.plugin = plugins;
26288
- mkdirSync5(dirname7(configPath), { recursive: true });
26289
- writeFileSync7(configPath, `${import_comment_json5.stringify(config2, null, 2)}
26608
+ mkdirSync6(dirname8(configPath), { recursive: true });
26609
+ writeFileSync8(configPath, `${import_comment_json5.stringify(config2, null, 2)}
26290
26610
  `);
26291
26611
  log2(`[magic-context] updated TUI plugin entry in ${configPath}`);
26292
26612
  return true;
@@ -26354,12 +26674,12 @@ var init_compartment_parser = __esm(() => {
26354
26674
  });
26355
26675
 
26356
26676
  // src/lib/diagnostics-opencode.ts
26357
- import { existsSync as existsSync13, readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
26358
- import { createRequire as createRequire2 } from "node:module";
26677
+ import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
26678
+ import { createRequire as createRequire3 } from "node:module";
26359
26679
  import { homedir as homedir8, tmpdir as tmpdir3, userInfo } from "node:os";
26360
- import { join as join11 } from "node:path";
26680
+ import { join as join12 } from "node:path";
26361
26681
  function getSelfVersion() {
26362
- const require2 = createRequire2(import.meta.url);
26682
+ const require2 = createRequire3(import.meta.url);
26363
26683
  for (const relPath of ["../../package.json", "../package.json"]) {
26364
26684
  try {
26365
26685
  const pkg = require2(relPath);
@@ -26371,26 +26691,26 @@ function getSelfVersion() {
26371
26691
  return "unknown";
26372
26692
  }
26373
26693
  function getPluginCacheInfo() {
26374
- const path3 = join11(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
26694
+ const path4 = join12(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
26375
26695
  let cached2;
26376
26696
  try {
26377
- const installedPkgPath = join11(path3, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
26378
- if (existsSync13(installedPkgPath)) {
26697
+ const installedPkgPath = join12(path4, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
26698
+ if (existsSync14(installedPkgPath)) {
26379
26699
  const pkg = JSON.parse(readFileSync9(installedPkgPath, "utf-8"));
26380
26700
  cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
26381
26701
  }
26382
26702
  } catch {
26383
26703
  cached2 = undefined;
26384
26704
  }
26385
- return { path: path3, cached: cached2, latest: getSelfVersion() };
26705
+ return { path: path4, cached: cached2, latest: getSelfVersion() };
26386
26706
  }
26387
26707
  function getStorageDir() {
26388
- const dataHome = process.env.XDG_DATA_HOME || join11(homedir8(), ".local", "share");
26389
- return join11(dataHome, "cortexkit", "magic-context");
26708
+ const dataHome = process.env.XDG_DATA_HOME || join12(homedir8(), ".local", "share");
26709
+ return join12(dataHome, "cortexkit", "magic-context");
26390
26710
  }
26391
- function fileSize(path3) {
26711
+ function fileSize(path4) {
26392
26712
  try {
26393
- return existsSync13(path3) ? statSync2(path3).size : 0;
26713
+ return existsSync14(path4) ? statSync2(path4).size : 0;
26394
26714
  } catch {
26395
26715
  return 0;
26396
26716
  }
@@ -26423,11 +26743,11 @@ function sanitizeValue(value) {
26423
26743
  }
26424
26744
  return value;
26425
26745
  }
26426
- function readConfig2(path3) {
26427
- if (!existsSync13(path3))
26746
+ function readConfig2(path4) {
26747
+ if (!existsSync14(path4))
26428
26748
  return { value: null };
26429
26749
  try {
26430
- const raw = readFileSync9(path3, "utf-8");
26750
+ const raw = readFileSync9(path4, "utf-8");
26431
26751
  const value = import_comment_json6.parse(raw);
26432
26752
  return { value };
26433
26753
  } catch (error48) {
@@ -26448,9 +26768,9 @@ function configHasPluginEntry(config2) {
26448
26768
  return false;
26449
26769
  });
26450
26770
  }
26451
- function parseHistorianDumpMeta(path3) {
26771
+ function parseHistorianDumpMeta(path4) {
26452
26772
  try {
26453
- const xml = readFileSync9(path3, "utf-8");
26773
+ const xml = readFileSync9(path4, "utf-8");
26454
26774
  const parsed = parseCompartmentOutput(xml);
26455
26775
  const factCountByCategory = {};
26456
26776
  for (const fact of parsed.facts) {
@@ -26483,13 +26803,13 @@ function parseHistorianDumpMeta(path3) {
26483
26803
  }
26484
26804
  }
26485
26805
  function collectHistorianDumps() {
26486
- const dir = join11(tmpdir3(), "magic-context-historian");
26487
- if (!existsSync13(dir)) {
26806
+ const dir = join12(tmpdir3(), "magic-context-historian");
26807
+ if (!existsSync14(dir)) {
26488
26808
  return { dir, count: 0, recent: [] };
26489
26809
  }
26490
26810
  try {
26491
26811
  const entries = readdirSync2(dir).filter((name) => name.endsWith(".xml")).map((name) => {
26492
- const stat = statSync2(join11(dir, name));
26812
+ const stat = statSync2(join12(dir, name));
26493
26813
  return {
26494
26814
  name,
26495
26815
  mtime: stat.mtimeMs,
@@ -26498,7 +26818,7 @@ function collectHistorianDumps() {
26498
26818
  }).sort((a, b) => b.mtime - a.mtime);
26499
26819
  const now = Date.now();
26500
26820
  const recent = entries.slice(0, 5).map((entry) => {
26501
- const meta3 = parseHistorianDumpMeta(join11(dir, entry.name));
26821
+ const meta3 = parseHistorianDumpMeta(join12(dir, entry.name));
26502
26822
  const summary = {
26503
26823
  name: entry.name,
26504
26824
  ageMinutes: Math.round((now - entry.mtime) / 60000),
@@ -26517,8 +26837,8 @@ function collectHistorianDumps() {
26517
26837
  }
26518
26838
  }
26519
26839
  async function collectHistorianFailures(storageDirPath) {
26520
- const contextDbPath = join11(storageDirPath, "context.db");
26521
- if (!existsSync13(contextDbPath))
26840
+ const contextDbPath = join12(storageDirPath, "context.db");
26841
+ if (!existsSync14(contextDbPath))
26522
26842
  return [];
26523
26843
  if (typeof globalThis.Bun === "undefined") {
26524
26844
  return [];
@@ -26557,9 +26877,9 @@ async function collectDiagnostics() {
26557
26877
  const tuiConfig = readConfig2(configPaths.tuiConfig);
26558
26878
  const magicContextConfig = readConfig2(configPaths.magicContextConfig);
26559
26879
  const storageDirPath = getStorageDir();
26560
- const contextDbPath = join11(storageDirPath, "context.db");
26561
- const logPath = join11(tmpdir3(), "magic-context.log");
26562
- const logFileSize = existsSync13(logPath) ? statSync2(logPath).size : 0;
26880
+ const contextDbPath = join12(storageDirPath, "context.db");
26881
+ const logPath = join12(tmpdir3(), "magic-context.log");
26882
+ const logFileSize = existsSync14(logPath) ? statSync2(logPath).size : 0;
26563
26883
  const conflictResult = detectConflicts(process.cwd());
26564
26884
  return {
26565
26885
  timestamp: new Date().toISOString(),
@@ -26573,14 +26893,14 @@ async function collectDiagnostics() {
26573
26893
  opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
26574
26894
  tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
26575
26895
  magicContextConfig: {
26576
- exists: existsSync13(configPaths.magicContextConfig),
26896
+ exists: existsSync14(configPaths.magicContextConfig),
26577
26897
  ...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
26578
26898
  flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
26579
26899
  },
26580
26900
  pluginCache: getPluginCacheInfo(),
26581
26901
  storageDir: {
26582
26902
  path: storageDirPath,
26583
- exists: existsSync13(storageDirPath),
26903
+ exists: existsSync14(storageDirPath),
26584
26904
  contextDbSizeBytes: fileSize(contextDbPath)
26585
26905
  },
26586
26906
  conflicts: {
@@ -26589,7 +26909,7 @@ async function collectDiagnostics() {
26589
26909
  },
26590
26910
  logFile: {
26591
26911
  path: logPath,
26592
- exists: existsSync13(logPath),
26912
+ exists: existsSync14(logPath),
26593
26913
  sizeKb: Math.round(logFileSize / 1024)
26594
26914
  },
26595
26915
  historianDumps: collectHistorianDumps(),
@@ -26690,9 +27010,9 @@ var init_diagnostics_opencode = __esm(() => {
26690
27010
  });
26691
27011
 
26692
27012
  // src/lib/logs-opencode.ts
26693
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "node:fs";
27013
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "node:fs";
26694
27014
  import { homedir as homedir9, userInfo as userInfo2 } from "node:os";
26695
- import { join as join12 } from "node:path";
27015
+ import { join as join13 } from "node:path";
26696
27016
  function escapeRegex3(value) {
26697
27017
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
26698
27018
  }
@@ -26783,10 +27103,10 @@ async function bundleIssueReport(report, description, _title) {
26783
27103
  "```"
26784
27104
  ].join(`
26785
27105
  `);
26786
- const path3 = join12(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
26787
- writeFileSync8(path3, `${bodyMarkdown}
27106
+ const path4 = join13(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
27107
+ writeFileSync9(path4, `${bodyMarkdown}
26788
27108
  `);
26789
- return { path: path3, bodyMarkdown };
27109
+ return { path: path4, bodyMarkdown };
26790
27110
  }
26791
27111
  var SECRET_PATTERNS, HISTORIAN_LOG_PATTERNS;
26792
27112
  var init_logs_opencode = __esm(() => {
@@ -26871,10 +27191,10 @@ var init_logs_opencode = __esm(() => {
26871
27191
 
26872
27192
  // src/commands/doctor-opencode.ts
26873
27193
  import { execSync as execSync3, spawnSync as spawnSync2 } from "node:child_process";
26874
- import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync as readFileSync11, rmSync, statSync as statSync3, writeFileSync as writeFileSync9 } from "node:fs";
26875
- import { createRequire as createRequire3 } from "node:module";
27194
+ import { existsSync as existsSync15, readdirSync as readdirSync3, readFileSync as readFileSync11, rmSync, statSync as statSync3, writeFileSync as writeFileSync10 } from "node:fs";
27195
+ import { createRequire as createRequire4 } from "node:module";
26876
27196
  import { homedir as homedir10, tmpdir as tmpdir4 } from "node:os";
26877
- import { join as join13 } from "node:path";
27197
+ import { join as join14 } from "node:path";
26878
27198
  async function fetchNpmLatest(pkg, timeoutMs = 5000) {
26879
27199
  try {
26880
27200
  const controller = new AbortController;
@@ -26896,7 +27216,7 @@ async function fetchNpmLatest(pkg, timeoutMs = 5000) {
26896
27216
  }
26897
27217
  }
26898
27218
  function getSelfVersion2() {
26899
- const req = createRequire3(import.meta.url);
27219
+ const req = createRequire4(import.meta.url);
26900
27220
  for (const relPath of ["../../package.json", "../package.json"]) {
26901
27221
  try {
26902
27222
  const pkg = req(relPath);
@@ -26924,21 +27244,21 @@ function compareVersions(a, b) {
26924
27244
  }
26925
27245
  async function clearPluginCache(force = false) {
26926
27246
  const cacheDir = getOpenCodeCacheDir();
26927
- const pluginCacheDir = join13(cacheDir, "packages", PLUGIN_ENTRY_WITH_VERSION2);
26928
- if (!existsSync14(pluginCacheDir)) {
27247
+ const pluginCacheDir = join14(cacheDir, "packages", PLUGIN_ENTRY_WITH_VERSION2);
27248
+ if (!existsSync15(pluginCacheDir)) {
26929
27249
  return { action: "not_found", path: pluginCacheDir };
26930
27250
  }
26931
27251
  let cachedVersion;
26932
27252
  try {
26933
- const installedPkgPath = join13(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
26934
- if (existsSync14(installedPkgPath)) {
27253
+ const installedPkgPath = join14(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
27254
+ if (existsSync15(installedPkgPath)) {
26935
27255
  const pkg = JSON.parse(readFileSync11(installedPkgPath, "utf-8"));
26936
27256
  if (typeof pkg?.version === "string") {
26937
27257
  cachedVersion = pkg.version;
26938
27258
  }
26939
27259
  }
26940
27260
  } catch {}
26941
- const require2 = createRequire3(import.meta.url);
27261
+ const require2 = createRequire4(import.meta.url);
26942
27262
  let selfVersion;
26943
27263
  for (const relPath of ["../../package.json", "../package.json"]) {
26944
27264
  try {
@@ -27044,7 +27364,7 @@ async function runIssueFlow() {
27044
27364
  }
27045
27365
  }
27046
27366
  async function checkEmbeddingConfig(magicContextConfigPath) {
27047
- if (!existsSync14(magicContextConfigPath)) {
27367
+ if (!existsSync15(magicContextConfigPath)) {
27048
27368
  return { issues: 0 };
27049
27369
  }
27050
27370
  let rawText;
@@ -27197,7 +27517,7 @@ async function runDoctor(options = {}) {
27197
27517
  } else {
27198
27518
  pass(`OpenCode config: ${paths.opencodeConfig}`);
27199
27519
  }
27200
- if (existsSync14(paths.magicContextConfig)) {
27520
+ if (existsSync15(paths.magicContextConfig)) {
27201
27521
  pass(`Magic Context config: ${paths.magicContextConfig}`);
27202
27522
  try {
27203
27523
  const raw = readFileSync11(paths.magicContextConfig, "utf-8");
@@ -27225,7 +27545,7 @@ async function runDoctor(options = {}) {
27225
27545
  warn(`No magic-context.jsonc found — using defaults`);
27226
27546
  log.info(" Run 'setup' to create one with model recommendations");
27227
27547
  }
27228
- if (existsSync14(paths.magicContextConfig)) {
27548
+ if (existsSync15(paths.magicContextConfig)) {
27229
27549
  try {
27230
27550
  const mcRaw = readFileSync11(paths.magicContextConfig, "utf-8");
27231
27551
  const mcConfig = import_comment_json7.parse(mcRaw);
@@ -27303,7 +27623,7 @@ async function runDoctor(options = {}) {
27303
27623
  fixed++;
27304
27624
  }
27305
27625
  if (mcChanged) {
27306
- writeFileSync9(paths.magicContextConfig, `${import_comment_json7.stringify(mcConfig, null, 2)}
27626
+ writeFileSync10(paths.magicContextConfig, `${import_comment_json7.stringify(mcConfig, null, 2)}
27307
27627
  `);
27308
27628
  }
27309
27629
  } catch {
@@ -27344,7 +27664,7 @@ async function runDoctor(options = {}) {
27344
27664
  rawPlugins[existingIdx] = PLUGIN_ENTRY_WITH_VERSION2;
27345
27665
  }
27346
27666
  config2.plugin = rawPlugins;
27347
- writeFileSync9(paths.opencodeConfig, `${import_comment_json7.stringify(config2, null, 2)}
27667
+ writeFileSync10(paths.opencodeConfig, `${import_comment_json7.stringify(config2, null, 2)}
27348
27668
  `);
27349
27669
  pass(`Upgraded plugin entry in ${configName}: ${oldEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
27350
27670
  fixed++;
@@ -27353,7 +27673,7 @@ async function runDoctor(options = {}) {
27353
27673
  } else {
27354
27674
  rawPlugins.push(PLUGIN_ENTRY_WITH_VERSION2);
27355
27675
  config2.plugin = rawPlugins;
27356
- writeFileSync9(paths.opencodeConfig, `${import_comment_json7.stringify(config2, null, 2)}
27676
+ writeFileSync10(paths.opencodeConfig, `${import_comment_json7.stringify(config2, null, 2)}
27357
27677
  `);
27358
27678
  pass(`Added plugin to ${configName}`);
27359
27679
  fixed++;
@@ -27384,7 +27704,7 @@ async function runDoctor(options = {}) {
27384
27704
  pass("Added TUI sidebar plugin to tui.json");
27385
27705
  warn("Restart OpenCode to see the sidebar");
27386
27706
  fixed++;
27387
- } else if (existsSync14(paths.tuiConfig)) {
27707
+ } else if (existsSync15(paths.tuiConfig)) {
27388
27708
  try {
27389
27709
  const tuiRaw = readFileSync11(paths.tuiConfig, "utf-8");
27390
27710
  const tuiConfig = import_comment_json7.parse(tuiRaw);
@@ -27415,7 +27735,7 @@ async function runDoctor(options = {}) {
27415
27735
  tuiRawPlugins[tuiIdx] = PLUGIN_ENTRY_WITH_VERSION2;
27416
27736
  }
27417
27737
  tuiConfig.plugin = tuiRawPlugins;
27418
- writeFileSync9(paths.tuiConfig, `${import_comment_json7.stringify(tuiConfig, null, 2)}
27738
+ writeFileSync10(paths.tuiConfig, `${import_comment_json7.stringify(tuiConfig, null, 2)}
27419
27739
  `);
27420
27740
  pass(`Upgraded TUI plugin: ${tuiEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
27421
27741
  fixed++;
@@ -27432,7 +27752,7 @@ async function runDoctor(options = {}) {
27432
27752
  } else {
27433
27753
  pass("TUI sidebar plugin configured (tui.json created)");
27434
27754
  }
27435
- if (existsSync14(paths.magicContextConfig)) {
27755
+ if (existsSync15(paths.magicContextConfig)) {
27436
27756
  try {
27437
27757
  const mcRaw = readFileSync11(paths.magicContextConfig, "utf-8");
27438
27758
  const mcConfig = import_comment_json7.parse(mcRaw);
@@ -27452,8 +27772,8 @@ async function runDoctor(options = {}) {
27452
27772
  failCount += embeddingCheck.issues;
27453
27773
  else
27454
27774
  passCount++;
27455
- const dbPath = join13(getMagicContextStorageDir(), "context.db");
27456
- if (!existsSync14(dbPath)) {
27775
+ const dbPath = join14(getMagicContextStorageDir(), "context.db");
27776
+ if (!existsSync15(dbPath)) {
27457
27777
  log.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
27458
27778
  } else {
27459
27779
  pass(`Shared context DB exists at ${dbPath}`);
@@ -27514,8 +27834,8 @@ async function runDoctor(options = {}) {
27514
27834
  }
27515
27835
  {
27516
27836
  const ageWarnings = [];
27517
- const npmrcPath = join13(homedir10(), ".npmrc");
27518
- if (existsSync14(npmrcPath)) {
27837
+ const npmrcPath = join14(homedir10(), ".npmrc");
27838
+ if (existsSync15(npmrcPath)) {
27519
27839
  try {
27520
27840
  const npmrc = readFileSync11(npmrcPath, "utf-8");
27521
27841
  for (const line of npmrc.split(`
@@ -27530,23 +27850,8 @@ async function runDoctor(options = {}) {
27530
27850
  }
27531
27851
  } catch {}
27532
27852
  }
27533
- const bunfigPath = join13(homedir10(), ".bunfig.toml");
27534
- if (existsSync14(bunfigPath)) {
27535
- try {
27536
- const bunfig = readFileSync11(bunfigPath, "utf-8");
27537
- for (const line of bunfig.split(`
27538
- `)) {
27539
- const trimmed = line.trim();
27540
- if (trimmed.startsWith("#"))
27541
- continue;
27542
- if (/minimumReleaseAge\s*=/.test(trimmed)) {
27543
- ageWarnings.push(`~/.bunfig.toml has '${trimmed}'`);
27544
- }
27545
- }
27546
- } catch {}
27547
- }
27548
27853
  if (ageWarnings.length > 0) {
27549
- log.warn("Package manager min-release-age restriction detected — this can prevent OpenCode from installing the latest plugin version");
27854
+ log.warn("npm min-release-age restriction detected — this can prevent OpenCode from installing the latest plugin version");
27550
27855
  for (const w of ageWarnings) {
27551
27856
  log.info(` ${w}`);
27552
27857
  }
@@ -27555,20 +27860,20 @@ async function runDoctor(options = {}) {
27555
27860
  issues++;
27556
27861
  }
27557
27862
  }
27558
- const logPath = join13(tmpdir4(), "magic-context.log");
27559
- if (existsSync14(logPath)) {
27863
+ const logPath = join14(tmpdir4(), "magic-context.log");
27864
+ if (existsSync15(logPath)) {
27560
27865
  const logStat = statSync3(logPath);
27561
27866
  const sizeKb = (logStat.size / 1024).toFixed(0);
27562
27867
  log.info(`Log file: ${logPath} (${sizeKb} KB)`);
27563
27868
  } else {
27564
27869
  log.info(`Log file: ${logPath} (not yet created)`);
27565
27870
  }
27566
- const historianDumpDir = join13(tmpdir4(), "magic-context-historian");
27567
- if (existsSync14(historianDumpDir)) {
27871
+ const historianDumpDir = join14(tmpdir4(), "magic-context-historian");
27872
+ if (existsSync15(historianDumpDir)) {
27568
27873
  try {
27569
27874
  const dumps = readdirSync3(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({
27570
27875
  name: f,
27571
- mtime: statSync3(join13(historianDumpDir, f)).mtimeMs
27876
+ mtime: statSync3(join14(historianDumpDir, f)).mtimeMs
27572
27877
  })).sort((a, b) => b.mtime - a.mtime);
27573
27878
  if (dumps.length > 0) {
27574
27879
  warn(`Historian debug dumps: ${dumps.length} file(s) in ${historianDumpDir}`);
@@ -28005,7 +28310,7 @@ var Tokenizer = class {
28005
28310
  return this.encode(input).length;
28006
28311
  }
28007
28312
  }, NO_RANK = 4294967295, textEncoder, textDecoder, src_default;
28008
- var init_dist3 = __esm(() => {
28313
+ var init_dist4 = __esm(() => {
28009
28314
  textEncoder = new TextEncoder;
28010
28315
  textDecoder = new TextDecoder("utf-8");
28011
28316
  src_default = Tokenizer;
@@ -160099,7 +160404,7 @@ var init_claude = __esm(() => {
160099
160404
  // ../plugin/src/hooks/magic-context/read-session-formatting.ts
160100
160405
  var tokenizer;
160101
160406
  var init_read_session_formatting = __esm(() => {
160102
- init_dist3();
160407
+ init_dist4();
160103
160408
  init_claude();
160104
160409
  tokenizer = new src_default(exports_claude);
160105
160410
  });
@@ -160114,18 +160419,77 @@ var init_tag_part_guards = __esm(() => {
160114
160419
  init_tag_content_primitives();
160115
160420
  });
160116
160421
 
160422
+ // ../plugin/src/shared/record-type-guard.ts
160423
+ function isRecord2(value) {
160424
+ return typeof value === "object" && value !== null && !Array.isArray(value);
160425
+ }
160426
+
160427
+ // ../plugin/src/hooks/magic-context/tool-drop-target.ts
160428
+ function hasMeaningfulPart(part) {
160429
+ if (!isRecord2(part))
160430
+ return false;
160431
+ const type = part.type;
160432
+ if (type === "text") {
160433
+ return typeof part.text === "string" && part.text.trim().length > 0;
160434
+ }
160435
+ if (typeof type !== "string")
160436
+ return false;
160437
+ if (IGNORE_PART_TYPES.has(type))
160438
+ return false;
160439
+ return true;
160440
+ }
160441
+
160442
+ class ToolMutationBatch {
160443
+ partsToRemove = new Set;
160444
+ affectedMessages = new Set;
160445
+ messages;
160446
+ constructor(messages) {
160447
+ this.messages = messages;
160448
+ }
160449
+ markForRemoval(occurrence) {
160450
+ this.partsToRemove.add(occurrence.part);
160451
+ this.affectedMessages.add(occurrence.message);
160452
+ }
160453
+ finalize() {
160454
+ if (this.partsToRemove.size === 0)
160455
+ return;
160456
+ for (const message of this.affectedMessages) {
160457
+ message.parts = message.parts.filter((p) => !this.partsToRemove.has(p));
160458
+ }
160459
+ for (let i = this.messages.length - 1;i >= 0; i -= 1) {
160460
+ if (!this.messages[i].parts.some(hasMeaningfulPart)) {
160461
+ this.messages.splice(i, 1);
160462
+ }
160463
+ }
160464
+ this.partsToRemove.clear();
160465
+ this.affectedMessages.clear();
160466
+ }
160467
+ }
160468
+ var IGNORE_PART_TYPES;
160469
+ var init_tool_drop_target = __esm(() => {
160470
+ IGNORE_PART_TYPES = new Set([
160471
+ "thinking",
160472
+ "reasoning",
160473
+ "redacted_thinking",
160474
+ "meta",
160475
+ "step-start",
160476
+ "step-finish"
160477
+ ]);
160478
+ });
160479
+
160117
160480
  // ../plugin/src/hooks/magic-context/read-session-chunk.ts
160118
160481
  var sessionProviders;
160119
160482
  var init_read_session_chunk = __esm(async () => {
160120
160483
  init_read_session_formatting();
160121
160484
  init_tag_part_guards();
160485
+ init_tool_drop_target();
160122
160486
  init_read_session_formatting();
160123
160487
  await init_read_session_db();
160124
160488
  sessionProviders = new Map;
160125
160489
  });
160126
160490
 
160127
160491
  // ../plugin/src/features/magic-context/message-index.ts
160128
- var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements;
160492
+ var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements, indexedMessageIdStatements;
160129
160493
  var init_message_index = __esm(async () => {
160130
160494
  init_compression_depth_storage();
160131
160495
  await init_read_session_chunk();
@@ -160135,6 +160499,7 @@ var init_message_index = __esm(async () => {
160135
160499
  deleteFtsStatements = new WeakMap;
160136
160500
  deleteIndexStatements = new WeakMap;
160137
160501
  countIndexedMessageStatements = new WeakMap;
160502
+ indexedMessageIdStatements = new WeakMap;
160138
160503
  });
160139
160504
 
160140
160505
  // ../plugin/src/shared/error-message.ts
@@ -160156,22 +160521,51 @@ function getCurrentVersion(db) {
160156
160521
  const row = db.prepare("SELECT MAX(version) as version FROM schema_migrations").get();
160157
160522
  return row?.version ?? 0;
160158
160523
  }
160524
+ function isSiblingMigrationConflict(error48, version2) {
160525
+ if (!(error48 instanceof Error))
160526
+ return false;
160527
+ const code = error48.code;
160528
+ if (code !== "SQLITE_CONSTRAINT_PRIMARYKEY" && code !== "SQLITE_CONSTRAINT_UNIQUE") {
160529
+ return false;
160530
+ }
160531
+ const msg = error48.message;
160532
+ if (!msg.includes("schema_migrations"))
160533
+ return false;
160534
+ if (!msg.toLowerCase().includes("version"))
160535
+ return false;
160536
+ return true;
160537
+ }
160159
160538
  function runMigrations(db) {
160160
160539
  ensureMigrationsTable(db);
160161
- const currentVersion = getCurrentVersion(db);
160162
- const pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
160540
+ let currentVersion = getCurrentVersion(db);
160541
+ let pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
160163
160542
  if (pendingMigrations.length === 0) {
160164
160543
  return;
160165
160544
  }
160166
160545
  log2(`[migrations] current schema version: ${currentVersion}, applying ${pendingMigrations.length} migration(s)`);
160167
- for (const migration of pendingMigrations) {
160546
+ let migrationIndex = 0;
160547
+ while (migrationIndex < pendingMigrations.length) {
160548
+ const migration = pendingMigrations[migrationIndex];
160168
160549
  try {
160169
160550
  db.transaction(() => {
160170
160551
  migration.up(db);
160171
160552
  db.prepare("INSERT INTO schema_migrations (version, description, applied_at) VALUES (?, ?, ?)").run(migration.version, migration.description, Date.now());
160172
160553
  })();
160173
160554
  log2(`[migrations] applied v${migration.version}: ${migration.description}`);
160555
+ migrationIndex += 1;
160174
160556
  } catch (error48) {
160557
+ if (isSiblingMigrationConflict(error48, migration.version)) {
160558
+ log2(`[migrations] v${migration.version} already applied by sibling instance — resuming with re-read version`);
160559
+ const reReadVersion = getCurrentVersion(db);
160560
+ if (reReadVersion <= currentVersion) {
160561
+ log2(`[migrations] FAILED v${migration.version}: sibling-conflict shape but version not advanced (${reReadVersion} <= ${currentVersion}) — failing closed`);
160562
+ throw new Error(`Migration v${migration.version} failed: sibling conflict reported but version did not advance. Database may need manual repair.`);
160563
+ }
160564
+ currentVersion = reReadVersion;
160565
+ pendingMigrations = MIGRATIONS.filter((m) => m.version > currentVersion);
160566
+ migrationIndex = 0;
160567
+ continue;
160568
+ }
160175
160569
  log2(`[migrations] FAILED v${migration.version}: ${migration.description} — ${error48 instanceof Error ? error48.message : String(error48)}`);
160176
160570
  throw new Error(`Migration v${migration.version} failed: ${error48 instanceof Error ? error48.message : String(error48)}. Database may need manual repair.`);
160177
160571
  }
@@ -160383,30 +160777,361 @@ var init_migrations = __esm(async () => {
160383
160777
  db.exec("ALTER TABLE notes ADD COLUMN harness TEXT NOT NULL DEFAULT 'opencode'");
160384
160778
  }
160385
160779
  }
160780
+ },
160781
+ {
160782
+ version: 8,
160783
+ description: "Add partial indexes on tags(session_id, tag_number) for active and dropped",
160784
+ up: (db) => {
160785
+ db.exec(`
160786
+ CREATE INDEX IF NOT EXISTS idx_tags_active_session_tag_number
160787
+ ON tags(session_id, tag_number)
160788
+ WHERE status = 'active';
160789
+
160790
+ CREATE INDEX IF NOT EXISTS idx_tags_dropped_session_tag_number
160791
+ ON tags(session_id, tag_number)
160792
+ WHERE status = 'dropped';
160793
+ `);
160794
+ db.exec("ANALYZE tags;");
160795
+ }
160796
+ },
160797
+ {
160798
+ version: 9,
160799
+ description: "Persist tool_definition_measurements across plugin restarts",
160800
+ up: (db) => {
160801
+ db.exec(`
160802
+ CREATE TABLE IF NOT EXISTS tool_definition_measurements (
160803
+ provider_id TEXT NOT NULL,
160804
+ model_id TEXT NOT NULL,
160805
+ agent_name TEXT NOT NULL,
160806
+ tool_id TEXT NOT NULL,
160807
+ token_count INTEGER NOT NULL,
160808
+ recorded_at INTEGER NOT NULL,
160809
+ PRIMARY KEY (provider_id, model_id, agent_name, tool_id)
160810
+ );
160811
+ `);
160812
+ }
160813
+ },
160814
+ {
160815
+ version: 10,
160816
+ description: "Add tool_owner_message_id column to tags + composite identity indexes",
160817
+ up: (db) => {
160818
+ const cols = db.prepare("PRAGMA table_info(tags)").all();
160819
+ if (!cols.some((c) => c.name === "tool_owner_message_id")) {
160820
+ db.exec("ALTER TABLE tags ADD COLUMN tool_owner_message_id TEXT DEFAULT NULL");
160821
+ }
160822
+ db.exec(`
160823
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_tool_composite
160824
+ ON tags(session_id, message_id, tool_owner_message_id)
160825
+ WHERE type = 'tool' AND tool_owner_message_id IS NOT NULL;
160826
+
160827
+ CREATE INDEX IF NOT EXISTS idx_tags_tool_null_owner
160828
+ ON tags(session_id, message_id)
160829
+ WHERE type = 'tool' AND tool_owner_message_id IS NULL;
160830
+ `);
160831
+ }
160386
160832
  }
160387
160833
  ];
160388
160834
  });
160389
160835
 
160836
+ // ../plugin/src/features/magic-context/tool-definition-tokens.ts
160837
+ function keyFor(providerID, modelID, agentName) {
160838
+ const agent = agentName && agentName.length > 0 ? agentName : "default";
160839
+ return `${providerID}/${modelID}/${agent}`;
160840
+ }
160841
+ function setDatabase(db) {
160842
+ persistenceDb = db;
160843
+ }
160844
+ function loadToolDefinitionMeasurements(db) {
160845
+ let rows = [];
160846
+ try {
160847
+ rows = db.prepare("SELECT provider_id, model_id, agent_name, tool_id, token_count FROM tool_definition_measurements").all();
160848
+ } catch {
160849
+ return;
160850
+ }
160851
+ for (const row of rows) {
160852
+ const key = keyFor(row.provider_id, row.model_id, row.agent_name);
160853
+ let inner = measurements.get(key);
160854
+ if (!inner) {
160855
+ inner = new Map;
160856
+ measurements.set(key, inner);
160857
+ }
160858
+ inner.set(row.tool_id, row.token_count);
160859
+ }
160860
+ }
160861
+ var measurements, persistenceDb = null;
160862
+ var init_tool_definition_tokens = __esm(() => {
160863
+ init_read_session_formatting();
160864
+ measurements = new Map;
160865
+ });
160866
+
160867
+ // ../plugin/src/features/magic-context/tool-owner-backfill.ts
160868
+ import { existsSync as existsSync16 } from "node:fs";
160869
+ import { join as join15 } from "node:path";
160870
+ function resolveOpencodeDbPath() {
160871
+ return join15(getDataDir(), "opencode", "opencode.db");
160872
+ }
160873
+ function ensureBackfillStateTable(db) {
160874
+ db.exec(`
160875
+ CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
160876
+ session_id TEXT PRIMARY KEY,
160877
+ status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'completed', 'skipped')),
160878
+ started_at INTEGER,
160879
+ lease_expires_at INTEGER,
160880
+ completed_at INTEGER,
160881
+ last_error TEXT
160882
+ );
160883
+ CREATE INDEX IF NOT EXISTS idx_tool_owner_backfill_state_status
160884
+ ON tool_owner_backfill_state(status);
160885
+ `);
160886
+ }
160887
+ function runToolOwnerBackfill(db) {
160888
+ const startedAt = performance.now();
160889
+ ensureBackfillStateTable(db);
160890
+ const result = {
160891
+ sessionsProcessed: 0,
160892
+ sessionsSkippedNoOcDb: 0,
160893
+ sessionsSkippedNoMatches: 0,
160894
+ sessionsCompleted: 0,
160895
+ sessionsBlockedByLease: 0,
160896
+ sessionsErrored: 0,
160897
+ rowsUpdated: 0,
160898
+ rowsLeftNull: 0,
160899
+ durationMs: 0
160900
+ };
160901
+ if (!isToolOwnerBackfillNeeded(db)) {
160902
+ result.durationMs = performance.now() - startedAt;
160903
+ return result;
160904
+ }
160905
+ const opencodeDbPath = resolveOpencodeDbPath();
160906
+ if (!existsSync16(opencodeDbPath)) {
160907
+ log2(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
160908
+ markAllUnbackfilledSessionsSkipped(db);
160909
+ result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
160910
+ result.durationMs = performance.now() - startedAt;
160911
+ return result;
160912
+ }
160913
+ db.exec(`ATTACH '${opencodeDbPath}' AS oc_backfill`);
160914
+ try {
160915
+ backfillToolOwnersInChunks(db, result);
160916
+ } finally {
160917
+ try {
160918
+ db.exec("DETACH DATABASE oc_backfill");
160919
+ } catch (error48) {
160920
+ log2(`[backfill] failed to detach oc_backfill database: ${error48 instanceof Error ? error48.message : String(error48)}`);
160921
+ }
160922
+ }
160923
+ result.durationMs = performance.now() - startedAt;
160924
+ log2(`[backfill] sessions=${result.sessionsProcessed} completed=${result.sessionsCompleted} skipped_no_oc=${result.sessionsSkippedNoOcDb} skipped_no_matches=${result.sessionsSkippedNoMatches} blocked_by_lease=${result.sessionsBlockedByLease} errored=${result.sessionsErrored} rows_updated=${result.rowsUpdated} rows_left_null=${result.rowsLeftNull} duration_ms=${Math.round(result.durationMs)}`);
160925
+ return result;
160926
+ }
160927
+ function isToolOwnerBackfillNeeded(db) {
160928
+ ensureBackfillStateTable(db);
160929
+ const row = db.prepare(`SELECT 1 AS hit
160930
+ FROM tags
160931
+ WHERE type = 'tool' AND tool_owner_message_id IS NULL
160932
+ AND NOT EXISTS (
160933
+ SELECT 1 FROM tool_owner_backfill_state s
160934
+ WHERE s.session_id = tags.session_id
160935
+ AND s.status IN ('completed', 'skipped')
160936
+ )
160937
+ LIMIT 1`).get();
160938
+ return row !== null && row !== undefined;
160939
+ }
160940
+ function markAllUnbackfilledSessionsSkipped(db) {
160941
+ const now = Date.now();
160942
+ db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, completed_at, last_error)
160943
+ SELECT DISTINCT session_id, 'skipped', NULL, ?, NULL
160944
+ FROM tags
160945
+ WHERE type = 'tool' AND tool_owner_message_id IS NULL
160946
+ ON CONFLICT(session_id) DO UPDATE SET
160947
+ status = 'skipped',
160948
+ completed_at = excluded.completed_at,
160949
+ last_error = NULL
160950
+ WHERE tool_owner_backfill_state.status NOT IN ('completed', 'running')`).run(now);
160951
+ }
160952
+ function countSessionsByStatus(db, status) {
160953
+ const row = db.prepare("SELECT COUNT(*) AS c FROM tool_owner_backfill_state WHERE status = ?").get(status);
160954
+ return row.c;
160955
+ }
160956
+ function acquireSessionLease(db, sessionId, now) {
160957
+ const expiresAt = now + LEASE_DURATION_MS;
160958
+ const result = db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, started_at, lease_expires_at)
160959
+ VALUES (?, 'running', ?, ?)
160960
+ ON CONFLICT(session_id) DO UPDATE SET
160961
+ status = 'running',
160962
+ started_at = excluded.started_at,
160963
+ lease_expires_at = excluded.lease_expires_at,
160964
+ last_error = NULL
160965
+ WHERE tool_owner_backfill_state.status IN ('pending', 'skipped')
160966
+ OR (tool_owner_backfill_state.status = 'running'
160967
+ AND tool_owner_backfill_state.lease_expires_at < ?)`).run(sessionId, now, expiresAt, now);
160968
+ return (result.changes ?? 0) === 1;
160969
+ }
160970
+ function renewSessionLease(db, sessionId, now) {
160971
+ const expiresAt = now + LEASE_DURATION_MS;
160972
+ db.prepare(`UPDATE tool_owner_backfill_state
160973
+ SET lease_expires_at = ?
160974
+ WHERE session_id = ? AND status = 'running'`).run(expiresAt, sessionId);
160975
+ }
160976
+ function markSessionCompleted(db, sessionId, now) {
160977
+ db.prepare(`UPDATE tool_owner_backfill_state
160978
+ SET status = 'completed', completed_at = ?, lease_expires_at = NULL, last_error = NULL
160979
+ WHERE session_id = ?`).run(now, sessionId);
160980
+ }
160981
+ function markSessionSkipped(db, sessionId, now, reason) {
160982
+ db.prepare(`INSERT INTO tool_owner_backfill_state(session_id, status, completed_at, last_error)
160983
+ VALUES (?, 'skipped', ?, ?)
160984
+ ON CONFLICT(session_id) DO UPDATE SET
160985
+ status = 'skipped',
160986
+ completed_at = excluded.completed_at,
160987
+ last_error = excluded.last_error,
160988
+ lease_expires_at = NULL`).run(sessionId, now, reason);
160989
+ }
160990
+ function markSessionErrored(db, sessionId, error48) {
160991
+ const message = error48 instanceof Error ? error48.message : String(error48);
160992
+ db.prepare(`UPDATE tool_owner_backfill_state
160993
+ SET last_error = ?, lease_expires_at = NULL
160994
+ WHERE session_id = ?`).run(message, sessionId);
160995
+ }
160996
+ function getSessionsNeedingBackfill(db) {
160997
+ const rows = db.prepare(`SELECT DISTINCT t.session_id
160998
+ FROM tags t
160999
+ LEFT JOIN tool_owner_backfill_state s ON s.session_id = t.session_id
161000
+ WHERE t.type = 'tool' AND t.tool_owner_message_id IS NULL
161001
+ AND (s.status IS NULL OR s.status NOT IN ('completed', 'skipped'))
161002
+ ORDER BY t.session_id ASC`).all();
161003
+ return rows.map((r) => r.session_id);
161004
+ }
161005
+ function buildSessionOwnerMap(db, sessionId) {
161006
+ const rows = db.prepare(`SELECT
161007
+ COALESCE(
161008
+ CASE WHEN json_extract(p.data, '$.type') = 'tool_use'
161009
+ THEN json_extract(p.data, '$.id')
161010
+ END,
161011
+ json_extract(p.data, '$.callID')
161012
+ ) AS callid,
161013
+ m.id AS owner_id,
161014
+ m.time_created AS owner_t_created,
161015
+ p.id AS part_id,
161016
+ p.time_created AS part_t_created
161017
+ FROM oc_backfill.message m
161018
+ INNER JOIN oc_backfill.part p ON p.message_id = m.id
161019
+ WHERE m.session_id = ?
161020
+ AND json_extract(m.data, '$.role') = 'assistant'
161021
+ AND (
161022
+ (json_extract(p.data, '$.type') IN ('tool', 'tool-invocation')
161023
+ AND json_extract(p.data, '$.callID') IS NOT NULL)
161024
+ OR (json_extract(p.data, '$.type') = 'tool_use'
161025
+ AND json_extract(p.data, '$.id') IS NOT NULL)
161026
+ )
161027
+ ORDER BY
161028
+ m.time_created ASC,
161029
+ m.id ASC,
161030
+ p.time_created ASC,
161031
+ p.id ASC`).all(sessionId);
161032
+ const oldestByCallId = new Map;
161033
+ for (const r of rows) {
161034
+ if (typeof r.callid !== "string" || r.callid.length === 0)
161035
+ continue;
161036
+ if (!oldestByCallId.has(r.callid)) {
161037
+ oldestByCallId.set(r.callid, r.owner_id);
161038
+ }
161039
+ }
161040
+ return oldestByCallId;
161041
+ }
161042
+ function applyOwnersForSession(db, sessionId, ownersByCallId) {
161043
+ if (ownersByCallId.size === 0) {
161044
+ const leftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
161045
+ WHERE session_id = ? AND type = 'tool'
161046
+ AND tool_owner_message_id IS NULL`).get(sessionId).c;
161047
+ return { rowsUpdated: 0, rowsLeftNull: leftNull };
161048
+ }
161049
+ const findOrphanStmt = db.prepare(`SELECT id FROM tags
161050
+ WHERE session_id = ? AND message_id = ? AND type = 'tool'
161051
+ AND tool_owner_message_id IS NULL
161052
+ ORDER BY tag_number ASC
161053
+ LIMIT 1`);
161054
+ const updateRowStmt = db.prepare(`UPDATE tags
161055
+ SET tool_owner_message_id = ?
161056
+ WHERE id = ? AND tool_owner_message_id IS NULL`);
161057
+ let rowsUpdated = 0;
161058
+ db.transaction(() => {
161059
+ for (const [callId, ownerId] of ownersByCallId) {
161060
+ const orphan = findOrphanStmt.get(sessionId, callId);
161061
+ if (!orphan)
161062
+ continue;
161063
+ const result = updateRowStmt.run(ownerId, orphan.id);
161064
+ rowsUpdated += result.changes ?? 0;
161065
+ }
161066
+ })();
161067
+ const rowsLeftNull = db.prepare(`SELECT COUNT(*) AS c FROM tags
161068
+ WHERE session_id = ? AND type = 'tool'
161069
+ AND tool_owner_message_id IS NULL`).get(sessionId).c;
161070
+ return { rowsUpdated, rowsLeftNull };
161071
+ }
161072
+ function backfillToolOwnersInChunks(db, result) {
161073
+ const sessionIds = getSessionsNeedingBackfill(db);
161074
+ let lastRenewedAt = Date.now();
161075
+ for (const sessionId of sessionIds) {
161076
+ const now = Date.now();
161077
+ result.sessionsProcessed += 1;
161078
+ const acquired = acquireSessionLease(db, sessionId, now);
161079
+ if (!acquired) {
161080
+ result.sessionsBlockedByLease += 1;
161081
+ continue;
161082
+ }
161083
+ try {
161084
+ const owners = buildSessionOwnerMap(db, sessionId);
161085
+ const { rowsUpdated, rowsLeftNull } = applyOwnersForSession(db, sessionId, owners);
161086
+ result.rowsUpdated += rowsUpdated;
161087
+ result.rowsLeftNull += rowsLeftNull;
161088
+ if (owners.size === 0) {
161089
+ markSessionSkipped(db, sessionId, Date.now(), "no_oc_matches");
161090
+ result.sessionsSkippedNoMatches += 1;
161091
+ } else {
161092
+ markSessionCompleted(db, sessionId, Date.now());
161093
+ result.sessionsCompleted += 1;
161094
+ }
161095
+ } catch (error48) {
161096
+ log2(`[backfill] session=${sessionId} errored: ${error48 instanceof Error ? error48.message : String(error48)}`);
161097
+ markSessionErrored(db, sessionId, error48);
161098
+ result.sessionsErrored += 1;
161099
+ }
161100
+ const sinceRenew = Date.now() - lastRenewedAt;
161101
+ if (sinceRenew > LEASE_RENEWAL_MS) {
161102
+ renewSessionLease(db, sessionId, Date.now());
161103
+ lastRenewedAt = Date.now();
161104
+ }
161105
+ }
161106
+ }
161107
+ var LEASE_DURATION_MS, LEASE_RENEWAL_MS;
161108
+ var init_tool_owner_backfill = __esm(() => {
161109
+ init_data_path();
161110
+ init_logger();
161111
+ LEASE_DURATION_MS = 5 * 60 * 1000;
161112
+ LEASE_RENEWAL_MS = 60 * 1000;
161113
+ });
161114
+
160390
161115
  // ../plugin/src/features/magic-context/storage-db.ts
160391
- import { copyFileSync, cpSync, existsSync as existsSync15, mkdirSync as mkdirSync6 } from "node:fs";
160392
- import { join as join14 } from "node:path";
161116
+ import { copyFileSync, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync7 } from "node:fs";
161117
+ import { join as join16 } from "node:path";
160393
161118
  function resolveDatabasePath() {
160394
161119
  const dbDir = getMagicContextStorageDir();
160395
- return { dbDir, dbPath: join14(dbDir, "context.db") };
161120
+ return { dbDir, dbPath: join16(dbDir, "context.db") };
160396
161121
  }
160397
161122
  function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
160398
- if (existsSync15(targetDbPath))
161123
+ if (existsSync17(targetDbPath))
160399
161124
  return;
160400
161125
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
160401
- const legacyDbPath = join14(legacyDir, "context.db");
160402
- if (!existsSync15(legacyDbPath))
161126
+ const legacyDbPath = join16(legacyDir, "context.db");
161127
+ if (!existsSync17(legacyDbPath))
160403
161128
  return;
160404
161129
  log2(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
160405
- mkdirSync6(targetDbDir, { recursive: true });
161130
+ mkdirSync7(targetDbDir, { recursive: true });
160406
161131
  for (const suffix of ["", "-wal", "-shm"]) {
160407
161132
  const src = `${legacyDbPath}${suffix}`;
160408
- const dst = join14(targetDbDir, `context.db${suffix}`);
160409
- if (existsSync15(src)) {
161133
+ const dst = join16(targetDbDir, `context.db${suffix}`);
161134
+ if (existsSync17(src)) {
160410
161135
  try {
160411
161136
  copyFileSync(src, dst);
160412
161137
  } catch (error48) {
@@ -160414,9 +161139,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
160414
161139
  }
160415
161140
  }
160416
161141
  }
160417
- const legacyModelsDir = join14(legacyDir, "models");
160418
- const targetModelsDir = join14(targetDbDir, "models");
160419
- if (existsSync15(legacyModelsDir) && !existsSync15(targetModelsDir)) {
161142
+ const legacyModelsDir = join16(legacyDir, "models");
161143
+ const targetModelsDir = join16(targetDbDir, "models");
161144
+ if (existsSync17(legacyModelsDir) && !existsSync17(targetModelsDir)) {
160420
161145
  try {
160421
161146
  cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
160422
161147
  } catch (error48) {
@@ -160702,6 +161427,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
160702
161427
  ensureColumn(db, "tags", "tool_name", "TEXT");
160703
161428
  ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
160704
161429
  ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
161430
+ ensureColumn(db, "tags", "tool_owner_message_id", "TEXT DEFAULT NULL");
160705
161431
  ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
160706
161432
  ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
160707
161433
  ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
@@ -160796,10 +161522,17 @@ function openDatabase() {
160796
161522
  }
160797
161523
  try {
160798
161524
  migrateLegacyStorageIfNeeded(dbPath, dbDir);
160799
- mkdirSync6(dbDir, { recursive: true });
161525
+ mkdirSync7(dbDir, { recursive: true });
160800
161526
  const db = new Database(dbPath);
160801
161527
  initializeDatabase(db);
160802
161528
  runMigrations(db);
161529
+ try {
161530
+ runToolOwnerBackfill(db);
161531
+ } catch (error48) {
161532
+ log2(`[magic-context] tool-owner backfill failed (continuing with lazy adoption fallback): ${getErrorMessage(error48)}`);
161533
+ }
161534
+ setDatabase(db);
161535
+ loadToolDefinitionMeasurements(db);
160803
161536
  databases.set(dbPath, db);
160804
161537
  persistenceByDatabase.set(db, true);
160805
161538
  persistenceErrorByDatabase.delete(db);
@@ -160828,6 +161561,8 @@ var databases, persistenceByDatabase, persistenceErrorByDatabase;
160828
161561
  var init_storage_db = __esm(async () => {
160829
161562
  init_data_path();
160830
161563
  init_logger();
161564
+ init_tool_definition_tokens();
161565
+ init_tool_owner_backfill();
160831
161566
  await __promiseAll([
160832
161567
  init_sqlite(),
160833
161568
  init_migrations()
@@ -160892,7 +161627,7 @@ var init_storage_ops = __esm(() => {
160892
161627
  var init_storage_source = () => {};
160893
161628
 
160894
161629
  // ../plugin/src/features/magic-context/storage-tags.ts
160895
- var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements;
161630
+ var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, getOwnerScopedToolTagNumbersStatements, getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
160896
161631
  var init_storage_tags = __esm(() => {
160897
161632
  insertTagStatements = new WeakMap;
160898
161633
  updateTagStatusStatements = new WeakMap;
@@ -160904,6 +161639,13 @@ var init_storage_tags = __esm(() => {
160904
161639
  getTagNumberByMessageIdStatements = new WeakMap;
160905
161640
  updateTagByteSizeStatements = new WeakMap;
160906
161641
  updateTagInputByteSizeStatements = new WeakMap;
161642
+ getOwnerScopedToolTagNumbersStatements = new WeakMap;
161643
+ getActiveTagsBySessionStatements = new WeakMap;
161644
+ getMaxDroppedTagNumberStatements = new WeakMap;
161645
+ getToolTagNumberByOwnerStatements = new WeakMap;
161646
+ getNullOwnerToolTagStatements = new WeakMap;
161647
+ adoptNullOwnerToolTagStatements = new WeakMap;
161648
+ deleteToolTagsByOwnerStatements = new WeakMap;
160907
161649
  });
160908
161650
 
160909
161651
  // ../plugin/src/features/magic-context/storage.ts
@@ -160922,42 +161664,42 @@ var init_storage = __esm(async () => {
160922
161664
  });
160923
161665
 
160924
161666
  // ../pi-plugin/src/config/index.ts
160925
- import { existsSync as existsSync16, readFileSync as readFileSync12 } from "node:fs";
161667
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
160926
161668
  import { homedir as homedir11 } from "node:os";
160927
- import { join as join15 } from "node:path";
161669
+ import { join as join17 } from "node:path";
160928
161670
  function getProjectConfigPaths(cwd) {
160929
- const basePath = join15(cwd, ".pi", CONFIG_FILE_NAME);
161671
+ const basePath = join17(cwd, ".pi", CONFIG_FILE_NAME);
160930
161672
  return [`${basePath}.jsonc`, `${basePath}.json`];
160931
161673
  }
160932
161674
  function getUserConfigPaths() {
160933
161675
  const home = process.env.HOME ?? homedir11();
160934
- const basePath = join15(home, ".pi", "agent", CONFIG_FILE_NAME);
161676
+ const basePath = join17(home, ".pi", "agent", CONFIG_FILE_NAME);
160935
161677
  return [`${basePath}.jsonc`, `${basePath}.json`];
160936
161678
  }
160937
161679
  function resolveFirstExisting(paths) {
160938
- return paths.find((path3) => existsSync16(path3));
161680
+ return paths.find((path4) => existsSync18(path4));
160939
161681
  }
160940
- function loadConfigFile2(path3, scope) {
161682
+ function loadConfigFile2(path4, scope) {
160941
161683
  try {
160942
- const rawText = readFileSync12(path3, "utf-8");
161684
+ const rawText = readFileSync12(path4, "utf-8");
160943
161685
  const substituted = substituteConfigVariables({
160944
161686
  text: rawText,
160945
- configPath: path3
161687
+ configPath: path4
160946
161688
  });
160947
161689
  return {
160948
- path: path3,
161690
+ path: path4,
160949
161691
  scope,
160950
161692
  config: import_comment_json8.parse(substituted.text),
160951
- warnings: substituted.warnings.map((warning) => `${path3}: ${warning}`)
161693
+ warnings: substituted.warnings.map((warning) => `${path4}: ${warning}`)
160952
161694
  };
160953
161695
  } catch (error48) {
160954
161696
  const message = error48 instanceof Error ? error48.message : String(error48);
160955
161697
  return {
160956
- path: path3,
161698
+ path: path4,
160957
161699
  scope,
160958
161700
  config: {},
160959
161701
  warnings: [
160960
- `${path3}: failed to load config: ${message}; using defaults for this file.`
161702
+ `${path4}: failed to load config: ${message}; using defaults for this file.`
160961
161703
  ]
160962
161704
  };
160963
161705
  }
@@ -161069,12 +161811,12 @@ var init_config2 = __esm(() => {
161069
161811
 
161070
161812
  // src/lib/diagnostics-pi.ts
161071
161813
  import { createHash } from "node:crypto";
161072
- import { existsSync as existsSync17, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
161073
- import { createRequire as createRequire4 } from "node:module";
161814
+ import { existsSync as existsSync19, readFileSync as readFileSync13, statSync as statSync4 } from "node:fs";
161815
+ import { createRequire as createRequire5 } from "node:module";
161074
161816
  import { homedir as homedir12, tmpdir as tmpdir5, userInfo as userInfo3 } from "node:os";
161075
- import { join as join16 } from "node:path";
161817
+ import { join as join18 } from "node:path";
161076
161818
  function getSelfVersion3() {
161077
- const req = createRequire4(import.meta.url);
161819
+ const req = createRequire5(import.meta.url);
161078
161820
  for (const relPath of ["../../package.json", "../package.json"]) {
161079
161821
  try {
161080
161822
  const pkg = req(relPath);
@@ -161085,9 +161827,9 @@ function getSelfVersion3() {
161085
161827
  }
161086
161828
  return "unknown";
161087
161829
  }
161088
- function fileSize2(path3) {
161830
+ function fileSize2(path4) {
161089
161831
  try {
161090
- return existsSync17(path3) ? statSync4(path3).size : 0;
161832
+ return existsSync19(path4) ? statSync4(path4).size : 0;
161091
161833
  } catch {
161092
161834
  return 0;
161093
161835
  }
@@ -161136,12 +161878,12 @@ function sanitizeValue2(value, key = "") {
161136
161878
  }
161137
161879
  return value;
161138
161880
  }
161139
- function readJsonc3(path3) {
161140
- if (!existsSync17(path3))
161881
+ function readJsonc3(path4) {
161882
+ if (!existsSync19(path4))
161141
161883
  return { value: {} };
161142
161884
  try {
161143
161885
  return {
161144
- value: import_comment_json9.parse(readFileSync13(path3, "utf-8"))
161886
+ value: import_comment_json9.parse(readFileSync13(path4, "utf-8"))
161145
161887
  };
161146
161888
  } catch (error48) {
161147
161889
  return {
@@ -161151,13 +161893,13 @@ function readJsonc3(path3) {
161151
161893
  }
161152
161894
  }
161153
161895
  function getProjectConfigPath(cwd) {
161154
- return join16(cwd, ".pi", "magic-context.jsonc");
161896
+ return join18(cwd, ".pi", "magic-context.jsonc");
161155
161897
  }
161156
- function readConfigDiagnostic(path3) {
161157
- const parsed = readJsonc3(path3);
161898
+ function readConfigDiagnostic(path4) {
161899
+ const parsed = readJsonc3(path4);
161158
161900
  return {
161159
- path: path3,
161160
- exists: existsSync17(path3),
161901
+ path: path4,
161902
+ exists: existsSync19(path4),
161161
161903
  ...parsed.parseError ? { parseError: parsed.parseError } : {},
161162
161904
  flags: sanitizeValue2(parsed.value)
161163
161905
  };
@@ -161177,9 +161919,9 @@ async function collectDiagnostics2(cwd = process.cwd()) {
161177
161919
  const projectConfigPath = getProjectConfigPath(cwd);
161178
161920
  const loaded = loadPiConfig({ cwd });
161179
161921
  const storageDirPath = getMagicContextStorageDir();
161180
- const dbPath = join16(storageDirPath, "context.db");
161181
- const logPath = join16(tmpdir5(), "magic-context.log");
161182
- const logFileSize = existsSync17(logPath) ? statSync4(logPath).size : 0;
161922
+ const dbPath = join18(storageDirPath, "context.db");
161923
+ const logPath = join18(tmpdir5(), "magic-context.log");
161924
+ const logFileSize = existsSync19(logPath) ? statSync4(logPath).size : 0;
161183
161925
  const otherPiExtensions = packages.filter((entry) => !hasMagicContextPackage([entry]));
161184
161926
  return {
161185
161927
  timestamp: new Date().toISOString(),
@@ -161192,7 +161934,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
161192
161934
  piVersion: pi ? getPiVersion(pi.path) : null,
161193
161935
  settings: {
161194
161936
  path: settingsPath,
161195
- exists: existsSync17(settingsPath),
161937
+ exists: existsSync19(settingsPath),
161196
161938
  ...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
161197
161939
  hasMagicContextPackage: hasMagicContextPackage(packages),
161198
161940
  packages: packages.map(sanitizeString2)
@@ -161208,7 +161950,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
161208
161950
  loadWarnings: loaded.warnings.map(sanitizeString2),
161209
161951
  storageDir: {
161210
161952
  path: storageDirPath,
161211
- exists: existsSync17(storageDirPath),
161953
+ exists: existsSync19(storageDirPath),
161212
161954
  contextDbSizeBytes: fileSize2(dbPath)
161213
161955
  },
161214
161956
  conflicts: {
@@ -161217,7 +161959,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
161217
161959
  },
161218
161960
  logFile: {
161219
161961
  path: logPath,
161220
- exists: existsSync17(logPath),
161962
+ exists: existsSync19(logPath),
161221
161963
  sizeKb: Math.round(logFileSize / 1024)
161222
161964
  }
161223
161965
  };
@@ -161271,7 +162013,7 @@ function renderDiagnosticsMarkdown2(report) {
161271
162013
  "```",
161272
162014
  "",
161273
162015
  "### Loaded config paths",
161274
- report.loadedConfigPaths.length === 0 ? "_No config files loaded; defaults are in use._" : report.loadedConfigPaths.map((path3) => `- ${path3}`).join(`
162016
+ report.loadedConfigPaths.length === 0 ? "_No config files loaded; defaults are in use._" : report.loadedConfigPaths.map((path4) => `- ${path4}`).join(`
161275
162017
  `),
161276
162018
  "",
161277
162019
  "### Config load warnings",
@@ -161306,8 +162048,8 @@ var init_diagnostics_pi = __esm(() => {
161306
162048
  });
161307
162049
 
161308
162050
  // src/lib/logs-pi.ts
161309
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
161310
- import { join as join17 } from "node:path";
162051
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "node:fs";
162052
+ import { join as join19 } from "node:path";
161311
162053
  function sanitizeLogContent2(content) {
161312
162054
  return sanitizeString2(content);
161313
162055
  }
@@ -161351,10 +162093,10 @@ async function bundleIssueReport2(report, description, title, options = {}) {
161351
162093
  ].join(`
161352
162094
  `);
161353
162095
  const cwd = options.cwd ?? process.cwd();
161354
- const path3 = join17(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
161355
- writeFileSync10(path3, `${bodyMarkdown}
162096
+ const path4 = join19(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
162097
+ writeFileSync11(path4, `${bodyMarkdown}
161356
162098
  `);
161357
- return { path: path3, bodyMarkdown };
162099
+ return { path: path4, bodyMarkdown };
161358
162100
  }
161359
162101
  var init_logs_pi = __esm(() => {
161360
162102
  init_diagnostics_pi();
@@ -161363,17 +162105,17 @@ var init_logs_pi = __esm(() => {
161363
162105
  // src/commands/doctor-pi.ts
161364
162106
  import { execFileSync as execFileSync3, spawnSync as spawnSync3 } from "node:child_process";
161365
162107
  import {
161366
- existsSync as existsSync18,
161367
- mkdirSync as mkdirSync7,
162108
+ existsSync as existsSync20,
162109
+ mkdirSync as mkdirSync8,
161368
162110
  readdirSync as readdirSync4,
161369
162111
  readFileSync as readFileSync15,
161370
162112
  rmSync as rmSync2,
161371
162113
  statSync as statSync5,
161372
- writeFileSync as writeFileSync11
162114
+ writeFileSync as writeFileSync12
161373
162115
  } from "node:fs";
161374
- import { createRequire as createRequire5 } from "node:module";
162116
+ import { createRequire as createRequire6 } from "node:module";
161375
162117
  import { homedir as homedir13, tmpdir as tmpdir6 } from "node:os";
161376
- import { dirname as dirname8, join as join18 } from "node:path";
162118
+ import { dirname as dirname9, join as join20 } from "node:path";
161377
162119
  function depsFrom(options) {
161378
162120
  return {
161379
162121
  ...DEFAULT_DEPS,
@@ -161394,7 +162136,7 @@ function printDoctorHelp() {
161394
162136
  console.log("");
161395
162137
  }
161396
162138
  function selfVersion() {
161397
- const req = createRequire5(import.meta.url);
162139
+ const req = createRequire6(import.meta.url);
161398
162140
  for (const relPath of ["../../package.json", "../package.json"]) {
161399
162141
  try {
161400
162142
  const pkg = req(relPath);
@@ -161457,10 +162199,10 @@ function summarize(results) {
161457
162199
  fail: results.filter((result) => result.status === "fail").length
161458
162200
  };
161459
162201
  }
161460
- function readJsonc4(path3) {
162202
+ function readJsonc4(path4) {
161461
162203
  try {
161462
162204
  return {
161463
- value: import_comment_json10.parse(readFileSync15(path3, "utf-8"))
162205
+ value: import_comment_json10.parse(readFileSync15(path4, "utf-8"))
161464
162206
  };
161465
162207
  } catch (error48) {
161466
162208
  return {
@@ -161476,16 +162218,16 @@ function hasPiPackage(packages) {
161476
162218
  return packages.some((entry) => entry === PI_PACKAGE_SOURCE || entry === PACKAGE_NAME2 || entry.includes("pi-magic-context"));
161477
162219
  }
161478
162220
  function projectConfigPath(cwd) {
161479
- return join18(cwd, ".pi", "magic-context.jsonc");
162221
+ return join20(cwd, ".pi", "magic-context.jsonc");
161480
162222
  }
161481
- function readConfigForEmbedding(path3) {
161482
- if (!existsSync18(path3))
162223
+ function readConfigForEmbedding(path4) {
162224
+ if (!existsSync20(path4))
161483
162225
  return null;
161484
162226
  try {
161485
- const rawText = readFileSync15(path3, "utf-8");
162227
+ const rawText = readFileSync15(path4, "utf-8");
161486
162228
  const substituted = substituteConfigVariables({
161487
162229
  text: rawText,
161488
- configPath: path3
162230
+ configPath: path4
161489
162231
  });
161490
162232
  return import_comment_json10.parse(substituted.text);
161491
162233
  } catch {
@@ -161541,51 +162283,51 @@ function countTable(db, table) {
161541
162283
  }
161542
162284
  function cacheRoots() {
161543
162285
  const home = homedir13();
161544
- const cacheHome = process.env.XDG_CACHE_HOME || join18(home, ".cache");
162286
+ const cacheHome = process.env.XDG_CACHE_HOME || join20(home, ".cache");
161545
162287
  return [
161546
- join18(home, ".pi", "cache", "extensions"),
161547
- join18(home, ".pi", "cache", "packages"),
161548
- join18(cacheHome, "pi", "extensions"),
161549
- join18(cacheHome, "pi", "packages"),
161550
- join18(getPiAgentConfigDir(), "cache", "extensions")
162288
+ join20(home, ".pi", "cache", "extensions"),
162289
+ join20(home, ".pi", "cache", "packages"),
162290
+ join20(cacheHome, "pi", "extensions"),
162291
+ join20(cacheHome, "pi", "packages"),
162292
+ join20(getPiAgentConfigDir(), "cache", "extensions")
161551
162293
  ];
161552
162294
  }
161553
162295
  function findPiMagicContextCacheDirs(self, force = false) {
161554
162296
  const found = new Map;
161555
- const visit = (path3, depth) => {
161556
- if (depth < 0 || !existsSync18(path3))
162297
+ const visit = (path4, depth) => {
162298
+ if (depth < 0 || !existsSync20(path4))
161557
162299
  return;
161558
162300
  let stat;
161559
162301
  try {
161560
- stat = statSync5(path3);
162302
+ stat = statSync5(path4);
161561
162303
  } catch {
161562
162304
  return;
161563
162305
  }
161564
162306
  if (!stat.isDirectory())
161565
162307
  return;
161566
- const packageJson = join18(path3, "package.json");
161567
- if (existsSync18(packageJson)) {
162308
+ const packageJson = join20(path4, "package.json");
162309
+ if (existsSync20(packageJson)) {
161568
162310
  try {
161569
162311
  const pkg = JSON.parse(readFileSync15(packageJson, "utf-8"));
161570
162312
  const name2 = typeof pkg.name === "string" ? pkg.name : "";
161571
162313
  const version2 = typeof pkg.version === "string" ? pkg.version : undefined;
161572
- if (name2 === PACKAGE_NAME2 || path3.includes("pi-magic-context")) {
162314
+ if (name2 === PACKAGE_NAME2 || path4.includes("pi-magic-context")) {
161573
162315
  if (force || !version2 || version2 !== self)
161574
- found.set(path3, { path: path3, version: version2 });
162316
+ found.set(path4, { path: path4, version: version2 });
161575
162317
  }
161576
162318
  } catch {
161577
- if (path3.includes("pi-magic-context"))
161578
- found.set(path3, { path: path3 });
162319
+ if (path4.includes("pi-magic-context"))
162320
+ found.set(path4, { path: path4 });
161579
162321
  }
161580
162322
  }
161581
162323
  let entries = [];
161582
162324
  try {
161583
- entries = readdirSync4(path3);
162325
+ entries = readdirSync4(path4);
161584
162326
  } catch {
161585
162327
  return;
161586
162328
  }
161587
162329
  for (const entry of entries)
161588
- visit(join18(path3, entry), depth - 1);
162330
+ visit(join20(path4, entry), depth - 1);
161589
162331
  };
161590
162332
  for (const root of cacheRoots())
161591
162333
  visit(root, 5);
@@ -161622,7 +162364,7 @@ async function runHealthChecks(options) {
161622
162364
  }
161623
162365
  const settingsPath = getPiUserExtensionsPath();
161624
162366
  let packages = [];
161625
- if (!existsSync18(settingsPath)) {
162367
+ if (!existsSync20(settingsPath)) {
161626
162368
  add(results, "warn", `Pi settings not found at ${settingsPath}`);
161627
162369
  repairPlan.addPackageEntry = true;
161628
162370
  } else {
@@ -161642,24 +162384,24 @@ async function runHealthChecks(options) {
161642
162384
  }
161643
162385
  const userConfigPath = getPiUserConfigPath();
161644
162386
  const projectPath = projectConfigPath(options.cwd);
161645
- for (const [label, path3, required2] of [
162387
+ for (const [label, path4, required2] of [
161646
162388
  ["user", userConfigPath, true],
161647
162389
  ["project", projectPath, false]
161648
162390
  ]) {
161649
- if (!existsSync18(path3)) {
162391
+ if (!existsSync20(path4)) {
161650
162392
  if (required2) {
161651
- add(results, "warn", `No ${label} magic-context.jsonc found at ${path3}`);
162393
+ add(results, "warn", `No ${label} magic-context.jsonc found at ${path4}`);
161652
162394
  repairPlan.writeUserConfig = true;
161653
162395
  } else {
161654
- add(results, "info", `No project Pi magic-context.jsonc found at ${path3}`);
162396
+ add(results, "info", `No project Pi magic-context.jsonc found at ${path4}`);
161655
162397
  }
161656
162398
  continue;
161657
162399
  }
161658
- const parsed = readJsonc4(path3);
162400
+ const parsed = readJsonc4(path4);
161659
162401
  if (parsed.error)
161660
162402
  add(results, "fail", `${label} magic-context.jsonc is invalid JSONC: ${parsed.error}`);
161661
162403
  else
161662
- add(results, "pass", `${label} magic-context.jsonc is valid JSONC: ${path3}`);
162404
+ add(results, "pass", `${label} magic-context.jsonc is valid JSONC: ${path4}`);
161663
162405
  }
161664
162406
  const loadedConfig = loadPiConfig({ cwd: options.cwd });
161665
162407
  if (loadedConfig.warnings.length > 0) {
@@ -161679,8 +162421,8 @@ async function runHealthChecks(options) {
161679
162421
  add(results, "pass", `historian.model "${historianModel}" has thinking_level "${historianThinkingLevel}" configured`);
161680
162422
  }
161681
162423
  const storageDir = getMagicContextStorageDir();
161682
- const dbPath = join18(storageDir, "context.db");
161683
- const existedBeforeOpen = existsSync18(dbPath);
162424
+ const dbPath = join20(storageDir, "context.db");
162425
+ const existedBeforeOpen = existsSync20(dbPath);
161684
162426
  if (existedBeforeOpen)
161685
162427
  add(results, "pass", `Shared context DB exists at ${dbPath}`);
161686
162428
  else
@@ -161756,8 +162498,8 @@ async function runHealthChecks(options) {
161756
162498
  } else {
161757
162499
  add(results, "pass", "Pi extension cache clean (no stale cached package found)");
161758
162500
  }
161759
- const logPath = join18(tmpdir6(), "magic-context.log");
161760
- if (existsSync18(logPath)) {
162501
+ const logPath = join20(tmpdir6(), "magic-context.log");
162502
+ if (existsSync20(logPath)) {
161761
162503
  const stat = statSync5(logPath);
161762
162504
  const sizeKb = (stat.size / 1024).toFixed(0);
161763
162505
  const lines = readFileSync15(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -161766,10 +162508,10 @@ async function runHealthChecks(options) {
161766
162508
  } else {
161767
162509
  add(results, "info", `No plugin log file yet at ${logPath}`);
161768
162510
  }
161769
- const historianDumpDir = join18(tmpdir6(), "magic-context-historian");
161770
- if (existsSync18(historianDumpDir)) {
162511
+ const historianDumpDir = join20(tmpdir6(), "magic-context-historian");
162512
+ if (existsSync20(historianDumpDir)) {
161771
162513
  try {
161772
- const dumps = readdirSync4(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({ name: f, mtime: statSync5(join18(historianDumpDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
162514
+ const dumps = readdirSync4(historianDumpDir).filter((f) => f.endsWith(".xml")).map((f) => ({ name: f, mtime: statSync5(join20(historianDumpDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
161773
162515
  if (dumps.length > 0) {
161774
162516
  add(results, "warn", `Historian debug dumps: ${dumps.length} file(s) in ${historianDumpDir}`);
161775
162517
  for (const dump of dumps.slice(0, 3)) {
@@ -161789,13 +162531,13 @@ async function runHealthChecks(options) {
161789
162531
  }
161790
162532
  return { results, repairPlan, ...summarize(results) };
161791
162533
  }
161792
- function writeDefaultMagicContextConfig(path3) {
161793
- mkdirSync7(dirname8(path3), { recursive: true });
162534
+ function writeDefaultMagicContextConfig(path4) {
162535
+ mkdirSync8(dirname9(path4), { recursive: true });
161794
162536
  const config2 = {
161795
162537
  $schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
161796
162538
  ...MagicContextConfigSchema.parse({})
161797
162539
  };
161798
- writeFileSync11(path3, `${import_comment_json10.stringify(config2, null, 2)}
162540
+ writeFileSync12(path4, `${import_comment_json10.stringify(config2, null, 2)}
161799
162541
  `);
161800
162542
  }
161801
162543
  function repair(plan, prompts) {
@@ -161812,7 +162554,7 @@ function repair(plan, prompts) {
161812
162554
  }
161813
162555
  if (plan.writeUserConfig) {
161814
162556
  const configPath = getPiUserConfigPath();
161815
- if (!existsSync18(configPath)) {
162557
+ if (!existsSync20(configPath)) {
161816
162558
  try {
161817
162559
  writeDefaultMagicContextConfig(configPath);
161818
162560
  prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
@@ -161822,13 +162564,13 @@ function repair(plan, prompts) {
161822
162564
  }
161823
162565
  }
161824
162566
  }
161825
- for (const path3 of plan.clearCachePaths) {
162567
+ for (const path4 of plan.clearCachePaths) {
161826
162568
  try {
161827
- rmSync2(path3, { recursive: true, force: true });
161828
- prompts.log.success(`Cleared stale Pi extension cache: ${path3}`);
162569
+ rmSync2(path4, { recursive: true, force: true });
162570
+ prompts.log.success(`Cleared stale Pi extension cache: ${path4}`);
161829
162571
  fixed += 1;
161830
162572
  } catch (error48) {
161831
- console.error(`FAIL Could not clear ${path3}: ${error48 instanceof Error ? error48.message : String(error48)}`);
162573
+ console.error(`FAIL Could not clear ${path4}: ${error48 instanceof Error ? error48.message : String(error48)}`);
161832
162574
  }
161833
162575
  }
161834
162576
  return fixed;
@@ -161973,7 +162715,7 @@ var exports_doctor = {};
161973
162715
  __export(exports_doctor, {
161974
162716
  runDoctor: () => runDoctor3
161975
162717
  });
161976
- import { existsSync as existsSync19, rmSync as rmSync3 } from "node:fs";
162718
+ import { existsSync as existsSync21, rmSync as rmSync3 } from "node:fs";
161977
162719
  async function runDoctor3(options) {
161978
162720
  if (options.clear)
161979
162721
  return runClear();
@@ -162057,7 +162799,7 @@ async function runClear() {
162057
162799
  const s = spinner();
162058
162800
  s.start(`Clearing ${item.path}`);
162059
162801
  try {
162060
- if (existsSync19(item.path)) {
162802
+ if (existsSync21(item.path)) {
162061
162803
  rmSync3(item.path, { recursive: true, force: true });
162062
162804
  }
162063
162805
  s.stop(`Cleared ${item.path}`);
@@ -162090,9 +162832,9 @@ var init_doctor = __esm(async () => {
162090
162832
  });
162091
162833
 
162092
162834
  // src/index.ts
162093
- import { createRequire as createRequire6 } from "node:module";
162835
+ import { createRequire as createRequire7 } from "node:module";
162094
162836
  function getVersion() {
162095
- const req = createRequire6(import.meta.url);
162837
+ const req = createRequire7(import.meta.url);
162096
162838
  for (const relPath of ["../../package.json", "../package.json"]) {
162097
162839
  try {
162098
162840
  const pkg = req(relPath);
@@ -162122,10 +162864,10 @@ function printUsage() {
162122
162864
  console.log(" (default: auto-detect, prompt if multiple installed)");
162123
162865
  console.log("");
162124
162866
  console.log(" Usage:");
162125
- console.log(" bunx --bun @cortexkit/magic-context@latest setup");
162126
- console.log(" bunx --bun @cortexkit/magic-context@latest doctor");
162127
- console.log(" bunx --bun @cortexkit/magic-context@latest doctor --issue");
162128
- console.log(" bunx --bun @cortexkit/magic-context@latest doctor migrate \\");
162867
+ console.log(" npx @cortexkit/magic-context@latest setup");
162868
+ console.log(" npx @cortexkit/magic-context@latest doctor");
162869
+ console.log(" npx @cortexkit/magic-context@latest doctor --issue");
162870
+ console.log(" npx @cortexkit/magic-context@latest doctor migrate \\");
162129
162871
  console.log(" --from opencode --to pi --session ses_xxx --dry-run");
162130
162872
  console.log("");
162131
162873
  }