@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.
- package/dist/index.js +1037 -295
- 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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
11494
|
+
import { join as join9 } from "node:path";
|
|
11125
11495
|
function defaultOpenCodeDbPath() {
|
|
11126
|
-
return
|
|
11496
|
+
return join9(homedir5(), ".local", "share", "opencode", "opencode.db");
|
|
11127
11497
|
}
|
|
11128
11498
|
function defaultCortexkitDbPath() {
|
|
11129
|
-
return
|
|
11499
|
+
return join9(getMagicContextStorageDir(), "context.db");
|
|
11130
11500
|
}
|
|
11131
11501
|
function defaultPiSessionsRoot() {
|
|
11132
|
-
return
|
|
11502
|
+
return join9(homedir5(), ".pi", "agent", "sessions");
|
|
11133
11503
|
}
|
|
11134
11504
|
function defaultFs() {
|
|
11135
|
-
return { existsSync:
|
|
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
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
11590
|
-
|
|
11591
|
-
|
|
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
|
-
|
|
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,
|
|
11959
|
-
if (!
|
|
12328
|
+
function getElementAtPath(obj, path4) {
|
|
12329
|
+
if (!path4)
|
|
11960
12330
|
return obj;
|
|
11961
|
-
return
|
|
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(
|
|
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(
|
|
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,
|
|
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 = [...
|
|
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
|
|
12557
|
-
for (const seg of
|
|
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
|
|
24833
|
-
if (
|
|
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 (
|
|
24838
|
-
const key =
|
|
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
|
|
26163
|
+
import { existsSync as existsSync11, readFileSync as readFileSync6 } from "node:fs";
|
|
25794
26164
|
import { homedir as homedir6 } from "node:os";
|
|
25795
|
-
import { dirname as
|
|
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 ?
|
|
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 (!
|
|
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
|
|
26228
|
+
import { existsSync as existsSync12, readFileSync as readFileSync7 } from "node:fs";
|
|
25859
26229
|
import { homedir as homedir7 } from "node:os";
|
|
25860
|
-
import { join as
|
|
26230
|
+
import { join as join10 } from "node:path";
|
|
25861
26231
|
function getUserConfigBasePath() {
|
|
25862
|
-
const configRoot = process.env.XDG_CONFIG_HOME ??
|
|
25863
|
-
return
|
|
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
|
|
26236
|
+
return join10(directory, ".opencode", CONFIG_FILE_BASENAME);
|
|
25867
26237
|
}
|
|
25868
26238
|
function loadConfigFile(configPath) {
|
|
25869
26239
|
try {
|
|
25870
|
-
if (!
|
|
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(
|
|
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
|
|
26242
|
-
import { dirname as
|
|
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 =
|
|
26257
|
-
const jsonPath =
|
|
26258
|
-
if (
|
|
26576
|
+
const jsoncPath = join11(configDir, "tui.jsonc");
|
|
26577
|
+
const jsonPath = join11(configDir, "tui.json");
|
|
26578
|
+
if (existsSync13(jsoncPath))
|
|
26259
26579
|
return jsoncPath;
|
|
26260
|
-
if (
|
|
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 (
|
|
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
|
-
|
|
26289
|
-
|
|
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
|
|
26358
|
-
import { createRequire as
|
|
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
|
|
26680
|
+
import { join as join12 } from "node:path";
|
|
26361
26681
|
function getSelfVersion() {
|
|
26362
|
-
const require2 =
|
|
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
|
|
26694
|
+
const path4 = join12(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
|
|
26375
26695
|
let cached2;
|
|
26376
26696
|
try {
|
|
26377
|
-
const installedPkgPath =
|
|
26378
|
-
if (
|
|
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:
|
|
26705
|
+
return { path: path4, cached: cached2, latest: getSelfVersion() };
|
|
26386
26706
|
}
|
|
26387
26707
|
function getStorageDir() {
|
|
26388
|
-
const dataHome = process.env.XDG_DATA_HOME ||
|
|
26389
|
-
return
|
|
26708
|
+
const dataHome = process.env.XDG_DATA_HOME || join12(homedir8(), ".local", "share");
|
|
26709
|
+
return join12(dataHome, "cortexkit", "magic-context");
|
|
26390
26710
|
}
|
|
26391
|
-
function fileSize(
|
|
26711
|
+
function fileSize(path4) {
|
|
26392
26712
|
try {
|
|
26393
|
-
return
|
|
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(
|
|
26427
|
-
if (!
|
|
26746
|
+
function readConfig2(path4) {
|
|
26747
|
+
if (!existsSync14(path4))
|
|
26428
26748
|
return { value: null };
|
|
26429
26749
|
try {
|
|
26430
|
-
const raw = readFileSync9(
|
|
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(
|
|
26771
|
+
function parseHistorianDumpMeta(path4) {
|
|
26452
26772
|
try {
|
|
26453
|
-
const xml = readFileSync9(
|
|
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 =
|
|
26487
|
-
if (!
|
|
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(
|
|
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(
|
|
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 =
|
|
26521
|
-
if (!
|
|
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 =
|
|
26561
|
-
const logPath =
|
|
26562
|
-
const logFileSize =
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
26787
|
-
|
|
27106
|
+
const path4 = join13(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
|
|
27107
|
+
writeFileSync9(path4, `${bodyMarkdown}
|
|
26788
27108
|
`);
|
|
26789
|
-
return { path:
|
|
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
|
|
26875
|
-
import { createRequire as
|
|
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
|
|
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 =
|
|
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 =
|
|
26928
|
-
if (!
|
|
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 =
|
|
26934
|
-
if (
|
|
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 =
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
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 =
|
|
27456
|
-
if (!
|
|
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 =
|
|
27518
|
-
if (
|
|
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("
|
|
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 =
|
|
27559
|
-
if (
|
|
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 =
|
|
27567
|
-
if (
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
160162
|
-
|
|
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
|
-
|
|
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
|
|
160392
|
-
import { join as
|
|
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:
|
|
161120
|
+
return { dbDir, dbPath: join16(dbDir, "context.db") };
|
|
160396
161121
|
}
|
|
160397
161122
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
160398
|
-
if (
|
|
161123
|
+
if (existsSync17(targetDbPath))
|
|
160399
161124
|
return;
|
|
160400
161125
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
160401
|
-
const legacyDbPath =
|
|
160402
|
-
if (!
|
|
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
|
-
|
|
161130
|
+
mkdirSync7(targetDbDir, { recursive: true });
|
|
160406
161131
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
160407
161132
|
const src = `${legacyDbPath}${suffix}`;
|
|
160408
|
-
const dst =
|
|
160409
|
-
if (
|
|
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 =
|
|
160418
|
-
const targetModelsDir =
|
|
160419
|
-
if (
|
|
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
|
-
|
|
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
|
|
161667
|
+
import { existsSync as existsSync18, readFileSync as readFileSync12 } from "node:fs";
|
|
160926
161668
|
import { homedir as homedir11 } from "node:os";
|
|
160927
|
-
import { join as
|
|
161669
|
+
import { join as join17 } from "node:path";
|
|
160928
161670
|
function getProjectConfigPaths(cwd) {
|
|
160929
|
-
const basePath =
|
|
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 =
|
|
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((
|
|
161680
|
+
return paths.find((path4) => existsSync18(path4));
|
|
160939
161681
|
}
|
|
160940
|
-
function loadConfigFile2(
|
|
161682
|
+
function loadConfigFile2(path4, scope) {
|
|
160941
161683
|
try {
|
|
160942
|
-
const rawText = readFileSync12(
|
|
161684
|
+
const rawText = readFileSync12(path4, "utf-8");
|
|
160943
161685
|
const substituted = substituteConfigVariables({
|
|
160944
161686
|
text: rawText,
|
|
160945
|
-
configPath:
|
|
161687
|
+
configPath: path4
|
|
160946
161688
|
});
|
|
160947
161689
|
return {
|
|
160948
|
-
path:
|
|
161690
|
+
path: path4,
|
|
160949
161691
|
scope,
|
|
160950
161692
|
config: import_comment_json8.parse(substituted.text),
|
|
160951
|
-
warnings: substituted.warnings.map((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:
|
|
161698
|
+
path: path4,
|
|
160957
161699
|
scope,
|
|
160958
161700
|
config: {},
|
|
160959
161701
|
warnings: [
|
|
160960
|
-
`${
|
|
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
|
|
161073
|
-
import { createRequire as
|
|
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
|
|
161817
|
+
import { join as join18 } from "node:path";
|
|
161076
161818
|
function getSelfVersion3() {
|
|
161077
|
-
const req =
|
|
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(
|
|
161830
|
+
function fileSize2(path4) {
|
|
161089
161831
|
try {
|
|
161090
|
-
return
|
|
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(
|
|
161140
|
-
if (!
|
|
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(
|
|
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
|
|
161896
|
+
return join18(cwd, ".pi", "magic-context.jsonc");
|
|
161155
161897
|
}
|
|
161156
|
-
function readConfigDiagnostic(
|
|
161157
|
-
const parsed = readJsonc3(
|
|
161898
|
+
function readConfigDiagnostic(path4) {
|
|
161899
|
+
const parsed = readJsonc3(path4);
|
|
161158
161900
|
return {
|
|
161159
|
-
path:
|
|
161160
|
-
exists:
|
|
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 =
|
|
161181
|
-
const logPath =
|
|
161182
|
-
const logFileSize =
|
|
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:
|
|
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:
|
|
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:
|
|
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((
|
|
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
|
|
161310
|
-
import { join as
|
|
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
|
|
161355
|
-
|
|
162096
|
+
const path4 = join19(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
162097
|
+
writeFileSync11(path4, `${bodyMarkdown}
|
|
161356
162098
|
`);
|
|
161357
|
-
return { path:
|
|
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
|
|
161367
|
-
mkdirSync as
|
|
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
|
|
162114
|
+
writeFileSync as writeFileSync12
|
|
161373
162115
|
} from "node:fs";
|
|
161374
|
-
import { createRequire as
|
|
162116
|
+
import { createRequire as createRequire6 } from "node:module";
|
|
161375
162117
|
import { homedir as homedir13, tmpdir as tmpdir6 } from "node:os";
|
|
161376
|
-
import { dirname as
|
|
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 =
|
|
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(
|
|
162202
|
+
function readJsonc4(path4) {
|
|
161461
162203
|
try {
|
|
161462
162204
|
return {
|
|
161463
|
-
value: import_comment_json10.parse(readFileSync15(
|
|
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
|
|
162221
|
+
return join20(cwd, ".pi", "magic-context.jsonc");
|
|
161480
162222
|
}
|
|
161481
|
-
function readConfigForEmbedding(
|
|
161482
|
-
if (!
|
|
162223
|
+
function readConfigForEmbedding(path4) {
|
|
162224
|
+
if (!existsSync20(path4))
|
|
161483
162225
|
return null;
|
|
161484
162226
|
try {
|
|
161485
|
-
const rawText = readFileSync15(
|
|
162227
|
+
const rawText = readFileSync15(path4, "utf-8");
|
|
161486
162228
|
const substituted = substituteConfigVariables({
|
|
161487
162229
|
text: rawText,
|
|
161488
|
-
configPath:
|
|
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 ||
|
|
162286
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join20(home, ".cache");
|
|
161545
162287
|
return [
|
|
161546
|
-
|
|
161547
|
-
|
|
161548
|
-
|
|
161549
|
-
|
|
161550
|
-
|
|
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 = (
|
|
161556
|
-
if (depth < 0 || !
|
|
162297
|
+
const visit = (path4, depth) => {
|
|
162298
|
+
if (depth < 0 || !existsSync20(path4))
|
|
161557
162299
|
return;
|
|
161558
162300
|
let stat;
|
|
161559
162301
|
try {
|
|
161560
|
-
stat = statSync5(
|
|
162302
|
+
stat = statSync5(path4);
|
|
161561
162303
|
} catch {
|
|
161562
162304
|
return;
|
|
161563
162305
|
}
|
|
161564
162306
|
if (!stat.isDirectory())
|
|
161565
162307
|
return;
|
|
161566
|
-
const packageJson =
|
|
161567
|
-
if (
|
|
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 ||
|
|
162314
|
+
if (name2 === PACKAGE_NAME2 || path4.includes("pi-magic-context")) {
|
|
161573
162315
|
if (force || !version2 || version2 !== self)
|
|
161574
|
-
found.set(
|
|
162316
|
+
found.set(path4, { path: path4, version: version2 });
|
|
161575
162317
|
}
|
|
161576
162318
|
} catch {
|
|
161577
|
-
if (
|
|
161578
|
-
found.set(
|
|
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(
|
|
162325
|
+
entries = readdirSync4(path4);
|
|
161584
162326
|
} catch {
|
|
161585
162327
|
return;
|
|
161586
162328
|
}
|
|
161587
162329
|
for (const entry of entries)
|
|
161588
|
-
visit(
|
|
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 (!
|
|
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,
|
|
162387
|
+
for (const [label, path4, required2] of [
|
|
161646
162388
|
["user", userConfigPath, true],
|
|
161647
162389
|
["project", projectPath, false]
|
|
161648
162390
|
]) {
|
|
161649
|
-
if (!
|
|
162391
|
+
if (!existsSync20(path4)) {
|
|
161650
162392
|
if (required2) {
|
|
161651
|
-
add(results, "warn", `No ${label} magic-context.jsonc found at ${
|
|
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 ${
|
|
162396
|
+
add(results, "info", `No project Pi magic-context.jsonc found at ${path4}`);
|
|
161655
162397
|
}
|
|
161656
162398
|
continue;
|
|
161657
162399
|
}
|
|
161658
|
-
const parsed = readJsonc4(
|
|
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: ${
|
|
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 =
|
|
161683
|
-
const existedBeforeOpen =
|
|
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 =
|
|
161760
|
-
if (
|
|
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 =
|
|
161770
|
-
if (
|
|
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(
|
|
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(
|
|
161793
|
-
|
|
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
|
-
|
|
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 (!
|
|
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
|
|
162567
|
+
for (const path4 of plan.clearCachePaths) {
|
|
161826
162568
|
try {
|
|
161827
|
-
rmSync2(
|
|
161828
|
-
prompts.log.success(`Cleared stale Pi extension cache: ${
|
|
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 ${
|
|
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
|
|
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 (
|
|
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
|
|
162835
|
+
import { createRequire as createRequire7 } from "node:module";
|
|
162094
162836
|
function getVersion() {
|
|
162095
|
-
const req =
|
|
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("
|
|
162126
|
-
console.log("
|
|
162127
|
-
console.log("
|
|
162128
|
-
console.log("
|
|
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
|
}
|