@cortexkit/magic-context 0.49.2 → 0.49.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1373 -710
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13668,9 +13668,549 @@ var init_sqlite = __esm(async () => {
13668
13668
  indexCoordinationState = new Int32Array(indexCoordinationBuffer);
13669
13669
  });
13670
13670
 
13671
+ // src/lib/dashboard-install.ts
13672
+ import { execFile } from "node:child_process";
13673
+ import { createHash, createPublicKey, verify as cryptoVerify } from "node:crypto";
13674
+ import {
13675
+ accessSync,
13676
+ chmodSync as chmodSync3,
13677
+ constants,
13678
+ existsSync as existsSync6,
13679
+ mkdirSync as mkdirSync3,
13680
+ mkdtempSync,
13681
+ readFileSync as readFileSync5,
13682
+ renameSync as renameSync3,
13683
+ rmSync as rmSync3,
13684
+ statSync as statSync5,
13685
+ writeFileSync as writeFileSync3
13686
+ } from "node:fs";
13687
+ import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
13688
+ import { dirname as dirname6, join as join5 } from "node:path";
13689
+ import { promisify } from "node:util";
13690
+ import { gunzipSync } from "node:zlib";
13691
+ function resolveDashboardChoice(argv, interactive) {
13692
+ if (argv.includes("--no-dashboard"))
13693
+ return "skip-flag";
13694
+ if (argv.includes("--dashboard"))
13695
+ return "install";
13696
+ return interactive ? "ask" : "skip-noninteractive";
13697
+ }
13698
+ function selectDashboardTarget(platform, arch) {
13699
+ if (arch !== "x64" && arch !== "arm64")
13700
+ return null;
13701
+ switch (platform) {
13702
+ case "darwin":
13703
+ return {
13704
+ platform: "macos",
13705
+ assetName: `magic-context-dashboard-darwin-${arch}.app.tar.gz`
13706
+ };
13707
+ case "linux":
13708
+ return {
13709
+ platform: "linux",
13710
+ assetName: `magic-context-dashboard-linux-${arch}.AppImage`
13711
+ };
13712
+ case "win32":
13713
+ return {
13714
+ platform: "windows",
13715
+ assetName: `magic-context-dashboard-windows-${arch}.exe`
13716
+ };
13717
+ default:
13718
+ return null;
13719
+ }
13720
+ }
13721
+ function compareVersions(a, b) {
13722
+ const parts = (value) => value.replace(/^v/, "").split(/[-+]/)[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
13723
+ const left = parts(a);
13724
+ const right = parts(b);
13725
+ for (let i = 0;i < Math.max(left.length, right.length, 3); i++) {
13726
+ const diff = (left[i] ?? 0) - (right[i] ?? 0);
13727
+ if (diff !== 0)
13728
+ return diff;
13729
+ }
13730
+ return 0;
13731
+ }
13732
+ function formatSize(bytes) {
13733
+ return `${(bytes / 1e6).toFixed(1)} MB`;
13734
+ }
13735
+ function errorMessage(error) {
13736
+ if (error instanceof Error) {
13737
+ if (error.name === "TimeoutError")
13738
+ return "the request timed out";
13739
+ return error.message;
13740
+ }
13741
+ return String(error);
13742
+ }
13743
+ function verifyTauriSignature(data, signatureFile, publicKeyFile) {
13744
+ const decodeLines = (value) => Buffer.from(value.trim(), "base64").toString("utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
13745
+ const keyLine = decodeLines(publicKeyFile).find((line) => !line.startsWith("untrusted comment:"));
13746
+ const key = Buffer.from(keyLine ?? "", "base64");
13747
+ if (key.length !== 42 || key.subarray(0, 2).toString("latin1") !== "Ed") {
13748
+ return { ok: false, reason: "the public key is malformed" };
13749
+ }
13750
+ const keyId = key.subarray(2, 10);
13751
+ const publicKey = createPublicKey({
13752
+ key: Buffer.concat([ED25519_SPKI_PREFIX, key.subarray(10)]),
13753
+ format: "der",
13754
+ type: "spki"
13755
+ });
13756
+ const lines = decodeLines(signatureFile);
13757
+ const [untrusted, signatureLine, trustedLine, globalLine] = lines;
13758
+ if (lines.length < 4 || !untrusted?.startsWith("untrusted comment:") || !trustedLine?.startsWith("trusted comment: ")) {
13759
+ return { ok: false, reason: "the signature file is malformed" };
13760
+ }
13761
+ const signatureBlob = Buffer.from(signatureLine ?? "", "base64");
13762
+ const algorithm = signatureBlob.subarray(0, 2).toString("latin1");
13763
+ if (signatureBlob.length !== 74 || algorithm !== "ED" && algorithm !== "Ed") {
13764
+ return { ok: false, reason: "the signature file is malformed" };
13765
+ }
13766
+ if (!signatureBlob.subarray(2, 10).equals(keyId)) {
13767
+ return { ok: false, reason: "it was signed by a different key" };
13768
+ }
13769
+ const signature = signatureBlob.subarray(10);
13770
+ const message = algorithm === "ED" ? createHash("blake2b512").update(data).digest() : Buffer.from(data);
13771
+ if (!cryptoVerify(null, message, publicKey, signature)) {
13772
+ return { ok: false, reason: "the signature does not match the file" };
13773
+ }
13774
+ const trustedComment = Buffer.from(trustedLine.slice("trusted comment: ".length), "utf8");
13775
+ const globalSignature = Buffer.from(globalLine ?? "", "base64");
13776
+ if (globalSignature.length !== 64 || !cryptoVerify(null, Buffer.concat([signature, trustedComment]), publicKey, globalSignature)) {
13777
+ return { ok: false, reason: "the signature's trusted comment does not match" };
13778
+ }
13779
+ return { ok: true };
13780
+ }
13781
+ async function fetchLatestDashboardRelease(deps) {
13782
+ const response = await deps.fetch(deps.releasesApiUrl, {
13783
+ headers: { Accept: "application/vnd.github+json", "User-Agent": USER_AGENT },
13784
+ signal: AbortSignal.timeout(deps.apiTimeoutMs)
13785
+ });
13786
+ if (!response.ok) {
13787
+ throw new Error(`the GitHub releases API answered HTTP ${response.status}`);
13788
+ }
13789
+ const body = await response.json();
13790
+ if (!Array.isArray(body))
13791
+ throw new Error("the GitHub releases API returned an unexpected body");
13792
+ let best = null;
13793
+ for (const entry of body) {
13794
+ if (entry.draft === true || entry.prerelease === true)
13795
+ continue;
13796
+ const tag = typeof entry.tag_name === "string" ? entry.tag_name : "";
13797
+ const match = TAG_PATTERN.exec(tag);
13798
+ if (!match?.[1])
13799
+ continue;
13800
+ const version = match[1];
13801
+ if (best && compareVersions(version, best.version) <= 0)
13802
+ continue;
13803
+ const assets = [];
13804
+ for (const asset of entry.assets ?? []) {
13805
+ if (typeof asset.name !== "string" || typeof asset.browser_download_url !== "string") {
13806
+ continue;
13807
+ }
13808
+ assets.push({
13809
+ name: asset.name,
13810
+ size: typeof asset.size === "number" ? asset.size : 0,
13811
+ url: asset.browser_download_url
13812
+ });
13813
+ }
13814
+ best = {
13815
+ tag,
13816
+ version,
13817
+ htmlUrl: typeof entry.html_url === "string" ? entry.html_url : `${DASHBOARD_RELEASES_PAGE}/tag/${tag}`,
13818
+ assets
13819
+ };
13820
+ }
13821
+ if (!best)
13822
+ throw new Error("no published dashboard-v* release was found");
13823
+ return best;
13824
+ }
13825
+ async function download(deps, asset) {
13826
+ const response = await deps.fetch(asset.url, {
13827
+ headers: { "User-Agent": USER_AGENT },
13828
+ redirect: "follow",
13829
+ signal: AbortSignal.timeout(deps.downloadTimeoutMs)
13830
+ });
13831
+ if (!response.ok)
13832
+ throw new Error(`downloading ${asset.name} failed with HTTP ${response.status}`);
13833
+ return Buffer.from(await response.arrayBuffer());
13834
+ }
13835
+ function readMacAppVersion(appPath) {
13836
+ try {
13837
+ const plist = readFileSync5(join5(appPath, "Contents", "Info.plist"), "utf8");
13838
+ const match = /<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(plist);
13839
+ return match?.[1]?.trim() ?? null;
13840
+ } catch {
13841
+ return null;
13842
+ }
13843
+ }
13844
+ function macApplicationDirs(deps) {
13845
+ return [deps.macSystemApplicationsDir, join5(deps.homeDir, "Applications")];
13846
+ }
13847
+ function linuxVersionMarkerPath(homeDir) {
13848
+ return join5(homeDir, ".local", "share", "cortexkit", "dashboard-appimage.json");
13849
+ }
13850
+ function linuxAppImagePath(homeDir) {
13851
+ return join5(homeDir, ".local", "bin", DASHBOARD_APPIMAGE_NAME);
13852
+ }
13853
+ async function detectInstalledDashboard(target, deps) {
13854
+ switch (target.platform) {
13855
+ case "macos":
13856
+ for (const dir of macApplicationDirs(deps)) {
13857
+ const location = join5(dir, DASHBOARD_MAC_APP_NAME);
13858
+ if (existsSync6(location))
13859
+ return { location, version: readMacAppVersion(location) };
13860
+ }
13861
+ return null;
13862
+ case "linux": {
13863
+ const location = linuxAppImagePath(deps.homeDir);
13864
+ if (existsSync6(location)) {
13865
+ let version = null;
13866
+ try {
13867
+ const marker = JSON.parse(readFileSync5(linuxVersionMarkerPath(deps.homeDir), "utf8"));
13868
+ if (typeof marker.version === "string")
13869
+ version = marker.version;
13870
+ } catch {
13871
+ version = null;
13872
+ }
13873
+ return { location, version };
13874
+ }
13875
+ if (existsSync6(deps.linuxSystemBinaryPath)) {
13876
+ return { location: deps.linuxSystemBinaryPath, version: null };
13877
+ }
13878
+ return null;
13879
+ }
13880
+ case "windows":
13881
+ return deps.readWindowsInstall();
13882
+ }
13883
+ }
13884
+ function isWritableDir(path) {
13885
+ try {
13886
+ if (!statSync5(path).isDirectory())
13887
+ return false;
13888
+ accessSync(path, constants.W_OK);
13889
+ return true;
13890
+ } catch {
13891
+ return false;
13892
+ }
13893
+ }
13894
+ function unsafeArchivePath(path) {
13895
+ if (path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:/.test(path))
13896
+ return true;
13897
+ return path.split(/[/\\]/).some((segment) => segment === "..");
13898
+ }
13899
+ function tarString(block, start, length) {
13900
+ const field = block.subarray(start, start + length);
13901
+ const end = field.indexOf(0);
13902
+ return field.subarray(0, end === -1 ? field.length : end).toString("utf8");
13903
+ }
13904
+ function tarSize(block) {
13905
+ const field = block.subarray(124, 136);
13906
+ if ((field[0] ?? 0) & 128) {
13907
+ let value = (field[0] ?? 0) & 127;
13908
+ for (const byte of field.subarray(1))
13909
+ value = value * 256 + byte;
13910
+ return value;
13911
+ }
13912
+ const text = tarString(block, 124, 12).trim();
13913
+ return text === "" ? 0 : Number.parseInt(text, 8);
13914
+ }
13915
+ function paxRecords(data) {
13916
+ const records = new Map;
13917
+ let offset = 0;
13918
+ while (offset < data.length) {
13919
+ const space = data.indexOf(32, offset);
13920
+ if (space === -1)
13921
+ break;
13922
+ const length = Number.parseInt(data.subarray(offset, space).toString("utf8"), 10);
13923
+ if (!Number.isFinite(length) || length <= 0)
13924
+ break;
13925
+ const record = data.subarray(space + 1, offset + length - 1).toString("utf8");
13926
+ const equals = record.indexOf("=");
13927
+ if (equals !== -1)
13928
+ records.set(record.slice(0, equals), record.slice(equals + 1));
13929
+ offset += length;
13930
+ }
13931
+ return records;
13932
+ }
13933
+ function findUnsafeTarEntry(tar) {
13934
+ const globalPax = new Map;
13935
+ let nextPax = new Map;
13936
+ let longName = null;
13937
+ let longLink = null;
13938
+ let offset = 0;
13939
+ while (offset + 512 <= tar.length) {
13940
+ const header = tar.subarray(offset, offset + 512);
13941
+ if (header.every((byte) => byte === 0))
13942
+ return null;
13943
+ const size = tarSize(header);
13944
+ if (!Number.isFinite(size) || size < 0)
13945
+ return "an entry has an unreadable size";
13946
+ const dataStart = offset + 512;
13947
+ const data = tar.subarray(dataStart, dataStart + size);
13948
+ offset = dataStart + Math.ceil(size / 512) * 512;
13949
+ const type = String.fromCharCode(header[156] ?? 0);
13950
+ if (type === "x" || type === "g") {
13951
+ const records = paxRecords(data);
13952
+ const target = type === "g" ? globalPax : nextPax;
13953
+ for (const [key, value] of records)
13954
+ target.set(key, value);
13955
+ continue;
13956
+ }
13957
+ if (type === "L" || type === "K") {
13958
+ const value = tarString(data, 0, data.length);
13959
+ if (type === "L")
13960
+ longName = value;
13961
+ else
13962
+ longLink = value;
13963
+ continue;
13964
+ }
13965
+ const prefix = tarString(header, 345, 155);
13966
+ const isUstar = header.subarray(257, 262).toString("latin1") === "ustar";
13967
+ const headerName = tarString(header, 0, 100);
13968
+ const name = nextPax.get("path") ?? longName ?? globalPax.get("path") ?? (isUstar && prefix ? `${prefix}/${headerName}` : headerName);
13969
+ const link = nextPax.get("linkpath") ?? longLink ?? globalPax.get("linkpath") ?? tarString(header, 157, 100);
13970
+ nextPax = new Map;
13971
+ longName = null;
13972
+ longLink = null;
13973
+ if (unsafeArchivePath(name))
13974
+ return `entry "${name}" points outside the archive`;
13975
+ switch (type) {
13976
+ case "0":
13977
+ case "\x00":
13978
+ case "7":
13979
+ case "5":
13980
+ break;
13981
+ case "1":
13982
+ case "2":
13983
+ if (link === "" || unsafeArchivePath(link)) {
13984
+ return `link "${name}" -> "${link}" points outside the archive`;
13985
+ }
13986
+ break;
13987
+ default:
13988
+ return `entry "${name}" has unsupported type "${type}"`;
13989
+ }
13990
+ }
13991
+ return offset === tar.length ? null : "the archive is truncated";
13992
+ }
13993
+ async function installMac(data, deps, installed) {
13994
+ let destinationDir;
13995
+ if (installed) {
13996
+ destinationDir = dirname6(installed.location);
13997
+ } else if (isWritableDir(deps.macSystemApplicationsDir)) {
13998
+ destinationDir = deps.macSystemApplicationsDir;
13999
+ } else {
14000
+ destinationDir = join5(deps.homeDir, "Applications");
14001
+ deps.log.info(`${deps.macSystemApplicationsDir} is not writable, so the app goes to ${destinationDir} (setup never asks for sudo).`);
14002
+ }
14003
+ const unsafe = findUnsafeTarEntry(gunzipSync(data));
14004
+ if (unsafe)
14005
+ throw new Error(`the app archive is unsafe to extract: ${unsafe}`);
14006
+ mkdirSync3(destinationDir, { recursive: true });
14007
+ const staging = mkdtempSync(join5(destinationDir, ".magic-context-dashboard-"));
14008
+ try {
14009
+ const archive = join5(staging, "dashboard.app.tar.gz");
14010
+ writeFileSync3(archive, data);
14011
+ const extractDir = join5(staging, "extracted");
14012
+ mkdirSync3(extractDir);
14013
+ await deps.extractTarGz(archive, extractDir);
14014
+ const extracted = join5(extractDir, DASHBOARD_MAC_APP_NAME);
14015
+ if (!existsSync6(extracted)) {
14016
+ throw new Error(`the archive did not contain ${DASHBOARD_MAC_APP_NAME}`);
14017
+ }
14018
+ const finalPath = join5(destinationDir, DASHBOARD_MAC_APP_NAME);
14019
+ const previous = join5(staging, "previous.app");
14020
+ const hadPrevious = existsSync6(finalPath);
14021
+ if (hadPrevious)
14022
+ renameSync3(finalPath, previous);
14023
+ try {
14024
+ renameSync3(extracted, finalPath);
14025
+ } catch (error) {
14026
+ if (hadPrevious)
14027
+ renameSync3(previous, finalPath);
14028
+ throw error;
14029
+ }
14030
+ return finalPath;
14031
+ } finally {
14032
+ rmSync3(staging, { recursive: true, force: true });
14033
+ }
14034
+ }
14035
+ function installLinux(data, version, deps) {
14036
+ const finalPath = linuxAppImagePath(deps.homeDir);
14037
+ mkdirSync3(dirname6(finalPath), { recursive: true });
14038
+ const partial = `${finalPath}.partial-${process.pid}`;
14039
+ try {
14040
+ writeFileSync3(partial, data, { mode: 493 });
14041
+ chmodSync3(partial, 493);
14042
+ renameSync3(partial, finalPath);
14043
+ } finally {
14044
+ rmSync3(partial, { force: true });
14045
+ }
14046
+ const marker = linuxVersionMarkerPath(deps.homeDir);
14047
+ mkdirSync3(dirname6(marker), { recursive: true });
14048
+ writeFileSync3(marker, `${JSON.stringify({ version, path: finalPath }, null, 2)}
14049
+ `);
14050
+ return finalPath;
14051
+ }
14052
+ async function installWindows(data, asset, deps) {
14053
+ const dir = mkdtempSync(join5(deps.tempRoot, "magic-context-dashboard-"));
14054
+ try {
14055
+ const installer = join5(dir, asset.name);
14056
+ writeFileSync3(installer, data);
14057
+ deps.log.info("Running the dashboard installer (per-user install, no administrator rights).");
14058
+ await deps.runWindowsInstaller(installer);
14059
+ } finally {
14060
+ try {
14061
+ rmSync3(dir, { recursive: true, force: true });
14062
+ } catch {}
14063
+ }
14064
+ const installed = await deps.readWindowsInstall().catch(() => null);
14065
+ return installed?.location ?? "the Start menu";
14066
+ }
14067
+ async function runOffer(argv, deps, state) {
14068
+ const choice = resolveDashboardChoice(argv, deps.interactive);
14069
+ if (choice === "skip-flag") {
14070
+ deps.log.info("Skipping the Magic Context Dashboard (--no-dashboard).");
14071
+ return;
14072
+ }
14073
+ if (choice === "skip-noninteractive") {
14074
+ deps.log.info(`Skipped the Magic Context Dashboard offer (non-interactive run). Pass --dashboard to install it, or download it from ${DASHBOARD_RELEASES_PAGE}`);
14075
+ return;
14076
+ }
14077
+ const target = selectDashboardTarget(deps.platform, deps.arch);
14078
+ if (!target) {
14079
+ deps.log.info(`No Magic Context Dashboard build exists for ${deps.platform}/${deps.arch}; see ${DASHBOARD_RELEASES_PAGE}`);
14080
+ return;
14081
+ }
14082
+ const release = await fetchLatestDashboardRelease(deps);
14083
+ state.link = release.htmlUrl;
14084
+ const asset = release.assets.find((candidate) => candidate.name === target.assetName);
14085
+ if (!asset)
14086
+ throw new Error(`release ${release.tag} has no ${target.assetName}`);
14087
+ const signatureAsset = release.assets.find((candidate) => candidate.name === `${target.assetName}.sig`);
14088
+ if (!signatureAsset) {
14089
+ throw new Error(`release ${release.tag} publishes no signature for ${target.assetName}, so it cannot be verified`);
14090
+ }
14091
+ const installed = await detectInstalledDashboard(target, deps);
14092
+ const size = formatSize(asset.size);
14093
+ let question;
14094
+ if (installed) {
14095
+ if (installed.version === null) {
14096
+ deps.log.info(`Magic Context Dashboard is already installed at ${installed.location} (version unknown); it updates itself from inside the app.`);
14097
+ return;
14098
+ }
14099
+ if (compareVersions(installed.version, release.version) >= 0) {
14100
+ deps.log.info(`Magic Context Dashboard v${installed.version} is already installed at ${installed.location} (latest release: v${release.version}).`);
14101
+ return;
14102
+ }
14103
+ deps.log.info(`Magic Context Dashboard v${installed.version} is installed at ${installed.location}; v${release.version} is available.`);
14104
+ question = `Update the Magic Context Dashboard to v${release.version}? (${size} download)`;
14105
+ } else {
14106
+ question = `Install the Magic Context Dashboard (desktop app for memories, sessions and settings)? v${release.version}, ${size} download`;
14107
+ }
14108
+ if (choice === "ask" && !await deps.confirm(question, true)) {
14109
+ deps.log.info(`Skipped the Magic Context Dashboard. It is available at ${release.htmlUrl}`);
14110
+ return;
14111
+ }
14112
+ deps.log.step(`Downloading ${asset.name} (${size})…`);
14113
+ const [data, signature] = await Promise.all([
14114
+ download(deps, asset),
14115
+ download(deps, signatureAsset)
14116
+ ]);
14117
+ const verdict = verifyTauriSignature(data, signature.toString("utf8"), deps.publicKey);
14118
+ if (!verdict.ok) {
14119
+ throw new Error(`${asset.name} failed signature verification (${verdict.reason}); nothing was installed`);
14120
+ }
14121
+ deps.log.info(`Verified ${asset.name} against the dashboard's updater signing key.`);
14122
+ let location;
14123
+ switch (target.platform) {
14124
+ case "macos":
14125
+ location = await installMac(data, deps, installed);
14126
+ break;
14127
+ case "linux":
14128
+ deps.log.info("Installing the AppImage to ~/.local/bin: it needs no root, runs on any distribution, and is what the app's own updater replaces (the .deb/.rpm packages would need sudo).");
14129
+ location = installLinux(data, release.version, deps);
14130
+ break;
14131
+ case "windows":
14132
+ location = await installWindows(data, asset, deps);
14133
+ break;
14134
+ }
14135
+ deps.log.success(`Installed Magic Context Dashboard v${release.version} → ${location}`);
14136
+ }
14137
+ function isInteractiveTerminal(stdinIsTTY, stdoutIsTTY, env) {
14138
+ const ci = env.CI?.trim().toLowerCase();
14139
+ const isCi = ci !== undefined && ci !== "" && ci !== "0" && ci !== "false";
14140
+ return Boolean(stdinIsTTY && stdoutIsTTY) && !isCi;
14141
+ }
14142
+ async function readWindowsInstallFromRegistry() {
14143
+ for (const hive of ["HKCU", "HKLM"]) {
14144
+ const key = `${hive}\\${WINDOWS_UNINSTALL_KEY}`;
14145
+ try {
14146
+ const { stdout } = await execFileAsync("reg", ["query", key], { windowsHide: true });
14147
+ const values = new Map;
14148
+ for (const line of stdout.split(/\r?\n/)) {
14149
+ const match = /^\s+(\S+)\s+REG_\w+\s+(.*)$/.exec(line);
14150
+ if (match?.[1] && match[2] !== undefined)
14151
+ values.set(match[1], match[2].trim());
14152
+ }
14153
+ return {
14154
+ location: values.get("InstallLocation") || key,
14155
+ version: values.get("DisplayVersion") || null
14156
+ };
14157
+ } catch {}
14158
+ }
14159
+ return null;
14160
+ }
14161
+ function defaultDashboardInstallDeps() {
14162
+ return {
14163
+ log: log3,
14164
+ confirm: (message, defaultYes) => confirm2(message, defaultYes),
14165
+ interactive: isInteractiveTerminal(process.stdin.isTTY, process.stdout.isTTY, process.env),
14166
+ platform: process.platform,
14167
+ arch: process.arch,
14168
+ homeDir: homedir6(),
14169
+ fetch: globalThis.fetch,
14170
+ releasesApiUrl: DASHBOARD_RELEASES_API,
14171
+ publicKey: DASHBOARD_UPDATER_PUBLIC_KEY,
14172
+ apiTimeoutMs: 15000,
14173
+ downloadTimeoutMs: 10 * 60000,
14174
+ macSystemApplicationsDir: "/Applications",
14175
+ linuxSystemBinaryPath: "/usr/bin/magic-context-dashboard",
14176
+ tempRoot: tmpdir2(),
14177
+ extractTarGz: async (archive, destinationDir) => {
14178
+ await execFileAsync("tar", ["-xzf", archive, "-C", destinationDir], {
14179
+ windowsHide: true
14180
+ });
14181
+ },
14182
+ runWindowsInstaller: async (installerPath) => {
14183
+ await execFileAsync(installerPath, ["/P"], { windowsHide: false });
14184
+ },
14185
+ readWindowsInstall: readWindowsInstallFromRegistry
14186
+ };
14187
+ }
14188
+ async function offerDashboardInstall(argv, overrides = {}) {
14189
+ const deps = { ...defaultDashboardInstallDeps(), ...overrides };
14190
+ const state = { link: DASHBOARD_RELEASES_PAGE };
14191
+ try {
14192
+ await runOffer(argv, deps, state);
14193
+ } catch (error) {
14194
+ if (isPromptCancelledError(error)) {
14195
+ deps.log.info("Skipped the Magic Context Dashboard.");
14196
+ return;
14197
+ }
14198
+ deps.log.warn(`Magic Context Dashboard was not installed: ${errorMessage(error)}. Install it manually from ${state.link}`);
14199
+ }
14200
+ }
14201
+ var execFileAsync, DASHBOARD_RELEASES_PAGE = "https://github.com/cortexkit/magic-context/releases", DASHBOARD_RELEASES_API = "https://api.github.com/repos/cortexkit/magic-context/releases?per_page=100", DASHBOARD_UPDATER_PUBLIC_KEY = "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDY5MUNBMDIxNjUxMEM2MkYKUldRdnhoQmxJYUFjYVU0SlNNbzRWMGJ3MndKOENIVDR0N0N6b0Jyd1l6TUNFTlpZTzV3RXlRYkEK", DASHBOARD_PRODUCT_NAME = "Magic Context Dashboard", DASHBOARD_MAC_APP_NAME, DASHBOARD_APPIMAGE_NAME = "magic-context-dashboard.AppImage", USER_AGENT = "magic-context-setup", TAG_PATTERN, ED25519_SPKI_PREFIX, WINDOWS_UNINSTALL_KEY;
14202
+ var init_dashboard_install = __esm(() => {
14203
+ init_prompts();
14204
+ execFileAsync = promisify(execFile);
14205
+ DASHBOARD_MAC_APP_NAME = `${DASHBOARD_PRODUCT_NAME}.app`;
14206
+ TAG_PATTERN = /^dashboard-v(\d+\.\d+\.\d+)$/;
14207
+ ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
14208
+ WINDOWS_UNINSTALL_KEY = `Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${DASHBOARD_PRODUCT_NAME}`;
14209
+ });
14210
+
13671
14211
  // src/lib/docs-proposal-gitignore.ts
13672
- import { appendFileSync as appendFileSync2, existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
13673
- import { join as join5 } from "node:path";
14212
+ import { appendFileSync as appendFileSync2, existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
14213
+ import { join as join6 } from "node:path";
13674
14214
  function coversProposalState(line) {
13675
14215
  const rule = line.trim();
13676
14216
  if (rule === "" || rule.startsWith("#") || rule.startsWith("!"))
@@ -13679,16 +14219,16 @@ function coversProposalState(line) {
13679
14219
  return COVERING_PATHS.has(normalized);
13680
14220
  }
13681
14221
  function ensureDocsProposalGitignore(projectDir) {
13682
- if (!existsSync6(join5(projectDir, ".git")))
14222
+ if (!existsSync7(join6(projectDir, ".git")))
13683
14223
  return { status: "not-a-repository" };
13684
- const path = join5(projectDir, ".gitignore");
14224
+ const path = join6(projectDir, ".gitignore");
13685
14225
  try {
13686
- const text = existsSync6(path) ? readFileSync5(path, "utf8") : "";
14226
+ const text = existsSync7(path) ? readFileSync6(path, "utf8") : "";
13687
14227
  if (text.split(/\r?\n/).some(coversProposalState))
13688
14228
  return { status: "covered" };
13689
- const nestedPath = join5(projectDir, ".cortexkit", ".gitignore");
13690
- if (existsSync6(nestedPath)) {
13691
- const nested = readFileSync5(nestedPath, "utf8").split(/\r?\n/);
14229
+ const nestedPath = join6(projectDir, ".cortexkit", ".gitignore");
14230
+ if (existsSync7(nestedPath)) {
14231
+ const nested = readFileSync6(nestedPath, "utf8").split(/\r?\n/);
13692
14232
  if (nested.some((line) => /^\/?magic-context(\/(\*\*?)?)?$/.test(line.trim()))) {
13693
14233
  return { status: "covered" };
13694
14234
  }
@@ -13712,8 +14252,8 @@ var init_docs_proposal_gitignore = __esm(() => {
13712
14252
  });
13713
14253
 
13714
14254
  // src/lib/find-on-path.ts
13715
- import { accessSync, constants, existsSync as existsSync7, statSync as statSync5 } from "node:fs";
13716
- import { delimiter, join as join6 } from "node:path";
14255
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync8, statSync as statSync6 } from "node:fs";
14256
+ import { delimiter, join as join7 } from "node:path";
13717
14257
  function findOnPath(binary) {
13718
14258
  const PATH = process.env.PATH;
13719
14259
  if (typeof PATH !== "string" || PATH.length === 0)
@@ -13725,7 +14265,7 @@ function findOnPath(binary) {
13725
14265
  if (!dir)
13726
14266
  continue;
13727
14267
  for (const candidate of candidates) {
13728
- const fullPath = join6(dir, candidate);
14268
+ const fullPath = join7(dir, candidate);
13729
14269
  if (isExecutableFile(fullPath, isWindows))
13730
14270
  return fullPath;
13731
14271
  }
@@ -13734,15 +14274,15 @@ function findOnPath(binary) {
13734
14274
  }
13735
14275
  function isExecutableFile(path, isWindows = process.platform === "win32") {
13736
14276
  try {
13737
- if (!existsSync7(path))
14277
+ if (!existsSync8(path))
13738
14278
  return false;
13739
- const st = statSync5(path);
14279
+ const st = statSync6(path);
13740
14280
  if (!st.isFile())
13741
14281
  return false;
13742
14282
  if (isWindows) {
13743
14283
  return true;
13744
14284
  }
13745
- accessSync(path, constants.X_OK);
14285
+ accessSync2(path, constants2.X_OK);
13746
14286
  return true;
13747
14287
  } catch {
13748
14288
  return false;
@@ -13751,28 +14291,28 @@ function isExecutableFile(path, isWindows = process.platform === "win32") {
13751
14291
  var init_find_on_path = () => {};
13752
14292
 
13753
14293
  // src/lib/paths.ts
13754
- import { existsSync as existsSync8, readdirSync as readdirSync2, statSync as statSync6 } from "node:fs";
13755
- import { homedir as homedir6 } from "node:os";
13756
- import { delimiter as delimiter2, dirname as dirname6, join as join7, resolve as resolve3 } from "node:path";
14294
+ import { existsSync as existsSync9, readdirSync as readdirSync2, statSync as statSync7 } from "node:fs";
14295
+ import { homedir as homedir7 } from "node:os";
14296
+ import { delimiter as delimiter2, dirname as dirname7, join as join8, resolve as resolve3 } from "node:path";
13757
14297
  function getOpenCodeConfigDir() {
13758
14298
  const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
13759
14299
  if (envDir)
13760
14300
  return envDir;
13761
14301
  if (process.platform === "win32") {
13762
- return join7(homedir6(), ".config", "opencode");
14302
+ return join8(homedir7(), ".config", "opencode");
13763
14303
  }
13764
- const xdgConfig = process.env.XDG_CONFIG_HOME || join7(homedir6(), ".config");
13765
- return join7(xdgConfig, "opencode");
14304
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join8(homedir7(), ".config");
14305
+ return join8(xdgConfig, "opencode");
13766
14306
  }
13767
14307
  function findOmoConfig(configDir) {
13768
14308
  const locations = [
13769
- join7(configDir, "oh-my-openagent.jsonc"),
13770
- join7(configDir, "oh-my-openagent.json"),
13771
- join7(configDir, "oh-my-opencode.jsonc"),
13772
- join7(configDir, "oh-my-opencode.json")
14309
+ join8(configDir, "oh-my-openagent.jsonc"),
14310
+ join8(configDir, "oh-my-openagent.json"),
14311
+ join8(configDir, "oh-my-opencode.jsonc"),
14312
+ join8(configDir, "oh-my-opencode.json")
13773
14313
  ];
13774
14314
  for (const loc of locations) {
13775
- if (existsSync8(loc))
14315
+ if (existsSync9(loc))
13776
14316
  return loc;
13777
14317
  }
13778
14318
  return null;
@@ -13783,24 +14323,24 @@ function detectConfigPaths() {
13783
14323
  let opencodeConfigFormat;
13784
14324
  let tuiConfig;
13785
14325
  let tuiConfigFormat;
13786
- const jsoncPath = join7(configDir, "opencode.jsonc");
13787
- const jsonPath = join7(configDir, "opencode.json");
13788
- if (existsSync8(jsoncPath)) {
14326
+ const jsoncPath = join8(configDir, "opencode.jsonc");
14327
+ const jsonPath = join8(configDir, "opencode.json");
14328
+ if (existsSync9(jsoncPath)) {
13789
14329
  opencodeConfig = jsoncPath;
13790
14330
  opencodeConfigFormat = "jsonc";
13791
- } else if (existsSync8(jsonPath)) {
14331
+ } else if (existsSync9(jsonPath)) {
13792
14332
  opencodeConfig = jsonPath;
13793
14333
  opencodeConfigFormat = "json";
13794
14334
  } else {
13795
14335
  opencodeConfig = jsoncPath;
13796
14336
  opencodeConfigFormat = "none";
13797
14337
  }
13798
- const tuiJsoncPath = join7(configDir, "tui.jsonc");
13799
- const tuiJsonPath = join7(configDir, "tui.json");
13800
- if (existsSync8(tuiJsoncPath)) {
14338
+ const tuiJsoncPath = join8(configDir, "tui.jsonc");
14339
+ const tuiJsonPath = join8(configDir, "tui.json");
14340
+ if (existsSync9(tuiJsoncPath)) {
13801
14341
  tuiConfig = tuiJsoncPath;
13802
14342
  tuiConfigFormat = "jsonc";
13803
- } else if (existsSync8(tuiJsonPath)) {
14343
+ } else if (existsSync9(tuiJsonPath)) {
13804
14344
  tuiConfig = tuiJsonPath;
13805
14345
  tuiConfigFormat = "json";
13806
14346
  } else {
@@ -13819,37 +14359,37 @@ function detectConfigPaths() {
13819
14359
  }
13820
14360
  function envFirstHomeDir() {
13821
14361
  const home = process.env.HOME?.trim();
13822
- return home || homedir6();
14362
+ return home || homedir7();
13823
14363
  }
13824
14364
  function getPiAgentDir() {
13825
14365
  const envDir = process.env.PI_CODING_AGENT_DIR?.trim();
13826
14366
  if (envDir)
13827
14367
  return envDir;
13828
- return join7(envFirstHomeDir(), ".pi", "agent");
14368
+ return join8(envFirstHomeDir(), ".pi", "agent");
13829
14369
  }
13830
14370
  function getPiAgentConfigDir() {
13831
14371
  return getPiAgentDir();
13832
14372
  }
13833
14373
  function getPiSessionsRoot() {
13834
- return join7(getPiAgentDir(), "sessions");
14374
+ return join8(getPiAgentDir(), "sessions");
13835
14375
  }
13836
14376
  function getPiCacheRoot() {
13837
- return join7(dirname6(getPiAgentDir()), "cache");
14377
+ return join8(dirname7(getPiAgentDir()), "cache");
13838
14378
  }
13839
14379
  function getPiUserConfigPath() {
13840
14380
  return resolveCortexKitUserConfigPath();
13841
14381
  }
13842
14382
  function getPiUserExtensionsPath() {
13843
- return join7(getPiAgentConfigDir(), "settings.json");
14383
+ return join8(getPiAgentConfigDir(), "settings.json");
13844
14384
  }
13845
14385
  function resolveOmpPaths() {
13846
14386
  const rawProfile = process.env.OMP_PROFILE ?? process.env.PI_PROFILE;
13847
14387
  const normalizedProfile = rawProfile?.trim();
13848
14388
  const profile = normalizedProfile && normalizedProfile !== "default" && /^[a-z0-9][a-z0-9._-]{0,63}$/.test(normalizedProfile) ? normalizedProfile : undefined;
13849
14389
  const configDirName = process.env.PI_CONFIG_DIR?.trim() || ".omp";
13850
- const baseConfigRoot = join7(envFirstHomeDir(), configDirName);
13851
- const configRoot = profile ? join7(baseConfigRoot, "profiles", profile) : baseConfigRoot;
13852
- const defaultAgentDir = join7(configRoot, "agent");
14390
+ const baseConfigRoot = join8(envFirstHomeDir(), configDirName);
14391
+ const configRoot = profile ? join8(baseConfigRoot, "profiles", profile) : baseConfigRoot;
14392
+ const defaultAgentDir = join8(configRoot, "agent");
13853
14393
  const override = profile ? undefined : process.env.PI_CODING_AGENT_DIR?.trim();
13854
14394
  const agentDir = override ? resolve3(override) : defaultAgentDir;
13855
14395
  const canUseXdg = (process.platform === "linux" || process.platform === "darwin") && agentDir === defaultAgentDir;
@@ -13857,9 +14397,9 @@ function resolveOmpPaths() {
13857
14397
  if (canUseXdg) {
13858
14398
  const xdgDataHome = process.env.XDG_DATA_HOME?.trim();
13859
14399
  if (xdgDataHome) {
13860
- const appRoot = join7(xdgDataHome, "omp");
13861
- const candidate = profile ? join7(appRoot, "profiles", profile) : appRoot;
13862
- if (existsSync8(candidate))
14400
+ const appRoot = join8(xdgDataHome, "omp");
14401
+ const candidate = profile ? join8(appRoot, "profiles", profile) : appRoot;
14402
+ if (existsSync9(candidate))
13863
14403
  dataRoot = candidate;
13864
14404
  }
13865
14405
  }
@@ -13869,8 +14409,8 @@ function resolveOmpPaths() {
13869
14409
  agentDir,
13870
14410
  dataRoot,
13871
14411
  dataAgentRoot,
13872
- pluginsDir: join7(dataRoot, "plugins"),
13873
- sessionsRoot: join7(dataAgentRoot, "sessions")
14412
+ pluginsDir: join8(dataRoot, "plugins"),
14413
+ sessionsRoot: join8(dataAgentRoot, "sessions")
13874
14414
  };
13875
14415
  }
13876
14416
  function getOmpAgentDir() {
@@ -13880,7 +14420,7 @@ function getOmpSessionsRoot() {
13880
14420
  return resolveOmpPaths().sessionsRoot;
13881
14421
  }
13882
14422
  function getOmpConfigPath() {
13883
- return join7(resolveOmpPaths().agentDir, "config.yml");
14423
+ return join8(resolveOmpPaths().agentDir, "config.yml");
13884
14424
  }
13885
14425
  function getOmpPackageDir() {
13886
14426
  const value = process.env.PI_PACKAGE_DIR?.trim();
@@ -13897,11 +14437,11 @@ function getOmpNonGlobalConfigSources(cwd = process.cwd()) {
13897
14437
  const sources = process.env.PI_CONFIG_FILES?.split(delimiter2).map((entry) => entry.trim()).filter(Boolean).map((entry) => {
13898
14438
  if (entry === "~")
13899
14439
  return envFirstHomeDir();
13900
- const expanded = entry.startsWith("~/") || entry.startsWith("~\\") ? join7(envFirstHomeDir(), entry.slice(2)) : entry;
14440
+ const expanded = entry.startsWith("~/") || entry.startsWith("~\\") ? join8(envFirstHomeDir(), entry.slice(2)) : entry;
13901
14441
  return resolve3(cwd, expanded);
13902
14442
  }) ?? [];
13903
14443
  const projectConfig = resolve3(cwd, ".omp", "config.yml");
13904
- if (existsSync8(projectConfig))
14444
+ if (existsSync9(projectConfig))
13905
14445
  sources.push(projectConfig);
13906
14446
  return [...new Set(sources)];
13907
14447
  }
@@ -13909,7 +14449,7 @@ function getOmpPluginsDir() {
13909
14449
  return resolveOmpPaths().pluginsDir;
13910
14450
  }
13911
14451
  function getOmpPluginsLockPath() {
13912
- return join7(resolveOmpPaths().pluginsDir, "omp-plugins.lock.json");
14452
+ return join8(resolveOmpPaths().pluginsDir, "omp-plugins.lock.json");
13913
14453
  }
13914
14454
  function getOmpUserConfigPath() {
13915
14455
  return resolveCortexKitUserConfigPath();
@@ -13921,16 +14461,16 @@ function getMagicContextHistorianDir2(harness) {
13921
14461
  return getMagicContextHistorianDir(harness);
13922
14462
  }
13923
14463
  function getOpenCodePluginCacheDir() {
13924
- const xdg = process.env.XDG_CACHE_HOME || join7(homedir6(), ".cache");
13925
- return join7(xdg, "opencode", "packages");
14464
+ const xdg = process.env.XDG_CACHE_HOME || join8(homedir7(), ".cache");
14465
+ return join8(xdg, "opencode", "packages");
13926
14466
  }
13927
14467
  function getOpenCodeV2NpmCacheDir() {
13928
- const xdg = process.env.XDG_CACHE_HOME || join7(homedir6(), ".cache");
13929
- return join7(xdg, "opencode", "npm");
14468
+ const xdg = process.env.XDG_CACHE_HOME || join8(homedir7(), ".cache");
14469
+ return join8(xdg, "opencode", "npm");
13930
14470
  }
13931
14471
  function isDir(path) {
13932
14472
  try {
13933
- return statSync6(path).isDirectory();
14473
+ return statSync7(path).isDirectory();
13934
14474
  } catch {
13935
14475
  return false;
13936
14476
  }
@@ -13947,12 +14487,12 @@ function dirSizeBytes(path) {
13947
14487
  try {
13948
14488
  const entries = readdirSync2(cur, { withFileTypes: true });
13949
14489
  for (const entry of entries) {
13950
- const child = join7(cur, entry.name);
14490
+ const child = join8(cur, entry.name);
13951
14491
  if (entry.isDirectory()) {
13952
14492
  stack.push(child);
13953
14493
  } else if (entry.isFile()) {
13954
14494
  try {
13955
- total += statSync6(child).size;
14495
+ total += statSync7(child).size;
13956
14496
  } catch {}
13957
14497
  }
13958
14498
  }
@@ -13967,8 +14507,8 @@ var init_paths = __esm(() => {
13967
14507
 
13968
14508
  // src/lib/pi-helpers.ts
13969
14509
  import { execFileSync, spawnSync } from "node:child_process";
13970
- import { homedir as homedir7 } from "node:os";
13971
- import { extname, join as join8 } from "node:path";
14510
+ import { homedir as homedir8 } from "node:os";
14511
+ import { extname, join as join9 } from "node:path";
13972
14512
  function getPiCommandInvocation(piPath, args) {
13973
14513
  const extension = extname(piPath).toLowerCase();
13974
14514
  if (extension !== ".cmd" && extension !== ".bat") {
@@ -13981,8 +14521,8 @@ function detectPiBinary() {
13981
14521
  const fromPath = findOnPath("pi");
13982
14522
  if (fromPath)
13983
14523
  return { path: fromPath, source: "path" };
13984
- const home = process.env.HOME?.trim() || homedir7();
13985
- const homeCandidate = process.platform === "win32" ? join8(home, ".pi", "bin", "pi.cmd") : join8(home, ".pi", "bin", "pi");
14524
+ const home = process.env.HOME?.trim() || homedir8();
14525
+ const homeCandidate = process.platform === "win32" ? join9(home, ".pi", "bin", "pi.cmd") : join9(home, ".pi", "bin", "pi");
13986
14526
  if (isExecutableFile(homeCandidate))
13987
14527
  return { path: homeCandidate, source: "home" };
13988
14528
  return null;
@@ -14071,9 +14611,9 @@ var init_pi_helpers = __esm(() => {
14071
14611
 
14072
14612
  // src/lib/omp-helpers.ts
14073
14613
  import { spawnSync as spawnSync2 } from "node:child_process";
14074
- import { existsSync as existsSync9, readFileSync as readFileSync6 } from "node:fs";
14075
- import { homedir as homedir8 } from "node:os";
14076
- import { extname as extname2, join as join9 } from "node:path";
14614
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
14615
+ import { homedir as homedir9 } from "node:os";
14616
+ import { extname as extname2, join as join10 } from "node:path";
14077
14617
  function detectOmpPackageCli() {
14078
14618
  const packageDir = getOmpPackageDir();
14079
14619
  if (!packageDir)
@@ -14081,11 +14621,11 @@ function detectOmpPackageCli() {
14081
14621
  if (!findOnPath("bun"))
14082
14622
  return null;
14083
14623
  try {
14084
- const manifest = JSON.parse(readFileSync6(join9(packageDir, "package.json"), "utf-8"));
14624
+ const manifest = JSON.parse(readFileSync7(join10(packageDir, "package.json"), "utf-8"));
14085
14625
  if (manifest.name !== "@oh-my-pi/pi-coding-agent")
14086
14626
  return null;
14087
- const cli = join9(packageDir, "dist", "cli.js");
14088
- return existsSync9(cli) ? cli : null;
14627
+ const cli = join10(packageDir, "dist", "cli.js");
14628
+ return existsSync10(cli) ? cli : null;
14089
14629
  } catch {
14090
14630
  return null;
14091
14631
  }
@@ -14100,13 +14640,13 @@ function getOmpCommandInvocation(ompPath, args) {
14100
14640
  }
14101
14641
  function getOmpFallbackCandidates(platform, home, appData) {
14102
14642
  if (platform !== "win32") {
14103
- return [join9(home, ".bun", "bin", "omp"), join9(home, ".local", "bin", "omp")];
14643
+ return [join10(home, ".bun", "bin", "omp"), join10(home, ".local", "bin", "omp")];
14104
14644
  }
14105
14645
  const npmRoot = appData?.trim();
14106
14646
  return [
14107
- ...npmRoot ? [join9(npmRoot, "npm", "omp.cmd"), join9(npmRoot, "npm", "omp.exe")] : [],
14108
- join9(home, ".bun", "bin", "omp.exe"),
14109
- join9(home, ".bun", "bin", "omp.cmd")
14647
+ ...npmRoot ? [join10(npmRoot, "npm", "omp.cmd"), join10(npmRoot, "npm", "omp.exe")] : [],
14648
+ join10(home, ".bun", "bin", "omp.exe"),
14649
+ join10(home, ".bun", "bin", "omp.cmd")
14110
14650
  ];
14111
14651
  }
14112
14652
  function detectOmpBinary() {
@@ -14116,7 +14656,7 @@ function detectOmpBinary() {
14116
14656
  const fromPackage = detectOmpPackageCli();
14117
14657
  if (fromPackage)
14118
14658
  return { path: fromPackage, source: "package" };
14119
- const home = process.env.HOME?.trim() || homedir8();
14659
+ const home = process.env.HOME?.trim() || homedir9();
14120
14660
  const candidates = getOmpFallbackCandidates(process.platform, home, process.env.APPDATA);
14121
14661
  const candidate = candidates.find((path) => isExecutableFile(path));
14122
14662
  return candidate ? { path: candidate, source: "home" } : null;
@@ -14229,8 +14769,8 @@ var init_omp_helpers = __esm(() => {
14229
14769
  });
14230
14770
 
14231
14771
  // src/adapters/omp.ts
14232
- import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
14233
- import { join as join10 } from "node:path";
14772
+ import { existsSync as existsSync11, readFileSync as readFileSync8 } from "node:fs";
14773
+ import { join as join11 } from "node:path";
14234
14774
 
14235
14775
  class OmpAdapter {
14236
14776
  kind = "omp";
@@ -14330,8 +14870,8 @@ class OmpAdapter {
14330
14870
  return "Install OMP: https://omp.sh (npm: @oh-my-pi/pi-coding-agent)";
14331
14871
  }
14332
14872
  getPluginCacheInfo() {
14333
- const path = join10(getOmpPluginsDir(), "cache");
14334
- return [{ path, exists: existsSync10(path), sizeBytes: dirSizeBytes(path) }];
14873
+ const path = join11(getOmpPluginsDir(), "cache");
14874
+ return [{ path, exists: existsSync11(path), sizeBytes: dirSizeBytes(path) }];
14335
14875
  }
14336
14876
  getLogPath() {
14337
14877
  return getMagicContextLogPath2("omp");
@@ -14344,7 +14884,7 @@ class OmpAdapter {
14344
14884
  }
14345
14885
  readRuntimeEnabled(configPath) {
14346
14886
  try {
14347
- const lock = JSON.parse(readFileSync7(configPath, "utf-8"));
14887
+ const lock = JSON.parse(readFileSync8(configPath, "utf-8"));
14348
14888
  const enabled = lock.plugins?.[OMP_PLUGIN_PACKAGE]?.enabled;
14349
14889
  return typeof enabled === "boolean" ? enabled : undefined;
14350
14890
  } catch {
@@ -14372,9 +14912,9 @@ var init_omp = __esm(() => {
14372
14912
  });
14373
14913
 
14374
14914
  // ../plugin/src/shared/opencode-db-path.ts
14375
- import { existsSync as existsSync11, readdirSync as readdirSync3, statSync as statSync7 } from "node:fs";
14376
- import { homedir as homedir9 } from "node:os";
14377
- import { isAbsolute as isAbsolute4, join as join11, resolve as resolve4 } from "node:path";
14915
+ import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as statSync8 } from "node:fs";
14916
+ import { homedir as homedir10 } from "node:os";
14917
+ import { isAbsolute as isAbsolute4, join as join12, resolve as resolve4 } from "node:path";
14378
14918
  function openCodeHostGenerationFromVersion(version) {
14379
14919
  const text = version ?? "";
14380
14920
  if (/(?:^|\s|v)0\.0\.0-(?:beta|dev)-/.test(text))
@@ -14383,7 +14923,7 @@ function openCodeHostGenerationFromVersion(version) {
14383
14923
  return Number.isFinite(major) && major >= 2 ? "v2" : "v1";
14384
14924
  }
14385
14925
  function openCodeDataDir(env = process.env, dataHome) {
14386
- return join11(dataHome ?? env.XDG_DATA_HOME ?? join11(homedir9(), ".local", "share"), "opencode");
14926
+ return join12(dataHome ?? env.XDG_DATA_HOME ?? join12(homedir10(), ".local", "share"), "opencode");
14387
14927
  }
14388
14928
  function environmentKey(dataDir, hostGeneration, channel, env) {
14389
14929
  return [
@@ -14395,7 +14935,7 @@ function environmentKey(dataDir, hostGeneration, channel, env) {
14395
14935
  ].join("\x00");
14396
14936
  }
14397
14937
  function channelPath(dataDir, channel) {
14398
- return ["latest", "beta", "prod"].includes(channel) ? join11(dataDir, "opencode.db") : join11(dataDir, `opencode-${channel}.db`);
14938
+ return ["latest", "beta", "prod"].includes(channel) ? join12(dataDir, "opencode.db") : join12(dataDir, `opencode-${channel}.db`);
14399
14939
  }
14400
14940
  function discoveredCandidateNames(dataDir) {
14401
14941
  const names = ["opencode.db", "opencode-local.db", "opencode-dev.db"];
@@ -14407,9 +14947,9 @@ function discoveredCandidateNames(dataDir) {
14407
14947
  }
14408
14948
  function discoverOpenCodeDb(dataDir) {
14409
14949
  const candidates = discoveredCandidateNames(dataDir).map((name, order) => {
14410
- const path = join11(dataDir, name);
14950
+ const path = join12(dataDir, name);
14411
14951
  try {
14412
- const metadata = statSync7(path);
14952
+ const metadata = statSync8(path);
14413
14953
  return metadata.isFile() ? { path, order, mtimeMs: metadata.mtimeMs } : null;
14414
14954
  } catch {
14415
14955
  return null;
@@ -14417,7 +14957,7 @@ function discoverOpenCodeDb(dataDir) {
14417
14957
  });
14418
14958
  const existing = candidates.filter((candidate) => candidate !== null).sort((left, right) => right.mtimeMs - left.mtimeMs || left.order - right.order)[0];
14419
14959
  if (!existing) {
14420
- return { path: join11(dataDir, "opencode.db"), source: "default", channel: null };
14960
+ return { path: join12(dataDir, "opencode.db"), source: "default", channel: null };
14421
14961
  }
14422
14962
  const name = existing.path.slice(dataDir.length + 1);
14423
14963
  const channel = name === "opencode.db" ? null : name.slice("opencode-".length, -".db".length) || null;
@@ -14430,14 +14970,14 @@ function resolveV1Fresh(dataDir, env = process.env) {
14430
14970
  return { path: explicit, source: "OPENCODE_DB", channel: null };
14431
14971
  }
14432
14972
  return {
14433
- path: isAbsolute4(explicit) ? explicit : join11(dataDir, explicit),
14973
+ path: isAbsolute4(explicit) ? explicit : join12(dataDir, explicit),
14434
14974
  source: "OPENCODE_DB",
14435
14975
  channel: null
14436
14976
  };
14437
14977
  }
14438
14978
  const disableChannelDb = env.OPENCODE_DISABLE_CHANNEL_DB;
14439
14979
  if (disableChannelDb === "1" || disableChannelDb === "true") {
14440
- return { path: join11(dataDir, "opencode.db"), source: "default", channel: null };
14980
+ return { path: join12(dataDir, "opencode.db"), source: "default", channel: null };
14441
14981
  }
14442
14982
  const channel = env.OPENCODE_CHANNEL;
14443
14983
  if (channel !== undefined && channel.length > 0) {
@@ -14471,7 +15011,7 @@ function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
14471
15011
  const dataDir = openCodeDataDir(env, options.dataHome);
14472
15012
  const channel = options.channel ?? env.OPENCODE_CHANNEL;
14473
15013
  const key = environmentKey(dataDir, hostGeneration, channel, env);
14474
- if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync11(cachedResolution.resolution.path))) {
15014
+ if (cachedResolution?.key === key && (!cachedResolution.existed || existsSync12(cachedResolution.resolution.path))) {
14475
15015
  if (cachedResolution.existed)
14476
15016
  return cachedResolution.resolution;
14477
15017
  }
@@ -14479,7 +15019,7 @@ function resolveOpenCodeDbPath(hostGeneration = "v1", options = {}) {
14479
15019
  cachedResolution = {
14480
15020
  key,
14481
15021
  resolution,
14482
- existed: resolution.path !== ":memory:" && existsSync11(resolution.path)
15022
+ existed: resolution.path !== ":memory:" && existsSync12(resolution.path)
14483
15023
  };
14484
15024
  return resolution;
14485
15025
  }
@@ -14519,7 +15059,7 @@ function assertOpenCodeStoreGeneration(db, expected, path, schema = "main") {
14519
15059
  throw new Error(`OpenCode store generation mismatch at ${path}: expected ${expected}, found ${actual}; refusing generation-specific database access`);
14520
15060
  }
14521
15061
  function openCodeDbPathExists(resolution = resolveOpenCodeDbPath()) {
14522
- return resolution.path !== ":memory:" && existsSync11(resolution.path);
15062
+ return resolution.path !== ":memory:" && existsSync12(resolution.path);
14523
15063
  }
14524
15064
  function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
14525
15065
  if (resolution.source === "OPENCODE_DB")
@@ -14529,10 +15069,10 @@ function getOpenCodeDbProbeDescriptions(resolution = resolveOpenCodeDbPath()) {
14529
15069
  }
14530
15070
  const dataDir = openCodeDataDir();
14531
15071
  return [
14532
- join11(dataDir, "opencode.db"),
14533
- join11(dataDir, "opencode-local.db"),
14534
- join11(dataDir, "opencode-dev.db"),
14535
- join11(dataDir, "opencode-<channel>.db")
15072
+ join12(dataDir, "opencode.db"),
15073
+ join12(dataDir, "opencode-local.db"),
15074
+ join12(dataDir, "opencode-dev.db"),
15075
+ join12(dataDir, "opencode-<channel>.db")
14536
15076
  ];
14537
15077
  }
14538
15078
  function lookedForText(resolution) {
@@ -22437,8 +22977,8 @@ function projectDirectoryKey(directory) {
22437
22977
  var init_project_directory_key = () => {};
22438
22978
 
22439
22979
  // ../plugin/src/shared/rpc-utils.ts
22440
- import { execFile, execFileSync as execFileSync2 } from "node:child_process";
22441
- import { readFileSync as readFileSync8 } from "node:fs";
22980
+ import { execFile as execFile2, execFileSync as execFileSync2 } from "node:child_process";
22981
+ import { readFileSync as readFileSync9 } from "node:fs";
22442
22982
  function isOwnRpcServerRecord(record) {
22443
22983
  return record.pid === process.pid && record.instance_id !== undefined && ownRpcServerInstanceIds.has(record.instance_id);
22444
22984
  }
@@ -23033,7 +23573,7 @@ var init_rpc_utils = __esm(() => {
23033
23573
  "cljs/dist",
23034
23574
  "dist/bundle/cli"
23035
23575
  ];
23036
- rpcIdentityReadFileSync = readFileSync8;
23576
+ rpcIdentityReadFileSync = readFileSync9;
23037
23577
  rpcIdentityExecFileSync = execFileSync2;
23038
23578
  rpcIdentityProcessKill = process.kill;
23039
23579
  rpcProcessListExecFileSync = execFileSync2;
@@ -23074,23 +23614,23 @@ var init_opencode_plugin_registration = __esm(() => {
23074
23614
  });
23075
23615
 
23076
23616
  // src/lib/opencode-plugin-cache.ts
23077
- import { readdirSync as readdirSync4, readFileSync as readFileSync9 } from "node:fs";
23078
- import { join as join12 } from "node:path";
23617
+ import { readdirSync as readdirSync4, readFileSync as readFileSync10 } from "node:fs";
23618
+ import { join as join13 } from "node:path";
23079
23619
  function getOpenCodePluginCacheRoots() {
23080
23620
  const cacheDir = getOpenCodePluginCacheDir();
23081
23621
  return [
23082
- join12(cacheDir, OPENCODE_PLUGIN_ENTRY_WITH_VERSION),
23083
- join12(cacheDir, OPENCODE_PLUGIN_NAME)
23622
+ join13(cacheDir, OPENCODE_PLUGIN_ENTRY_WITH_VERSION),
23623
+ join13(cacheDir, OPENCODE_PLUGIN_NAME)
23084
23624
  ];
23085
23625
  }
23086
23626
  function getOpenCodePluginPackageJsonPath(pluginCacheRoot) {
23087
- return join12(pluginCacheRoot, "node_modules", ...OPENCODE_PLUGIN_NAME.split("/"), "package.json");
23627
+ return join13(pluginCacheRoot, "node_modules", ...OPENCODE_PLUGIN_NAME.split("/"), "package.json");
23088
23628
  }
23089
23629
  function getOpenCodePluginPackageJsonPaths() {
23090
23630
  return getOpenCodePluginCacheRoots().map(getOpenCodePluginPackageJsonPath);
23091
23631
  }
23092
23632
  function getOpenCodeV2PluginCacheSlot(npmCacheDir = getOpenCodeV2NpmCacheDir(), spec = "latest") {
23093
- return join12(npmCacheDir, ...`${OPENCODE_PLUGIN_NAME}@${spec}`.split("/"));
23633
+ return join13(npmCacheDir, ...`${OPENCODE_PLUGIN_NAME}@${spec}`.split("/"));
23094
23634
  }
23095
23635
  function openCodeV2PluginSpecOf(specifier) {
23096
23636
  if (specifier === OPENCODE_PLUGIN_NAME)
@@ -23143,7 +23683,7 @@ function pluginEntrySpecifier(entry) {
23143
23683
  }
23144
23684
  function listOpenCodeV2PluginCacheSlots(npmCacheDir = getOpenCodeV2NpmCacheDir()) {
23145
23685
  const [scope = "", name = ""] = OPENCODE_PLUGIN_NAME.split("/");
23146
- const scopeDir = join12(npmCacheDir, scope);
23686
+ const scopeDir = join13(npmCacheDir, scope);
23147
23687
  let names;
23148
23688
  try {
23149
23689
  names = readdirSync4(scopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.startsWith(`${name}@`)).map((entry) => entry.name);
@@ -23151,7 +23691,7 @@ function listOpenCodeV2PluginCacheSlots(npmCacheDir = getOpenCodeV2NpmCacheDir()
23151
23691
  return [];
23152
23692
  }
23153
23693
  return names.map((dirName) => {
23154
- const slot = join12(scopeDir, dirName);
23694
+ const slot = join13(scopeDir, dirName);
23155
23695
  return {
23156
23696
  spec: dirName.slice(name.length + 1),
23157
23697
  slot,
@@ -23167,7 +23707,7 @@ function getOpenCodeV2ActiveGeneration(slot) {
23167
23707
  try {
23168
23708
  const generations = readdirSync4(slot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && /^\d+$/.test(entry.name)).map((entry) => entry.name).sort((a, b) => Number(a) - Number(b));
23169
23709
  const newest = generations.at(-1);
23170
- return newest === undefined ? undefined : join12(slot, newest);
23710
+ return newest === undefined ? undefined : join13(slot, newest);
23171
23711
  } catch {
23172
23712
  return;
23173
23713
  }
@@ -23177,7 +23717,7 @@ function readOpenCodeV2CachedPluginVersion(slot) {
23177
23717
  if (!generation)
23178
23718
  return;
23179
23719
  try {
23180
- const pkg = JSON.parse(readFileSync9(getOpenCodePluginPackageJsonPath(generation), "utf-8"));
23720
+ const pkg = JSON.parse(readFileSync10(getOpenCodePluginPackageJsonPath(generation), "utf-8"));
23181
23721
  return typeof pkg.version === "string" ? pkg.version : undefined;
23182
23722
  } catch {
23183
23723
  return;
@@ -23191,7 +23731,7 @@ var init_opencode_plugin_cache = __esm(() => {
23191
23731
  });
23192
23732
 
23193
23733
  // src/commands/doctor-windows-holders.ts
23194
- import { existsSync as existsSync12 } from "node:fs";
23734
+ import { existsSync as existsSync13 } from "node:fs";
23195
23735
  function assertWindowsStoresClosed(paths, processes) {
23196
23736
  if (processes.pi.state !== "known" || processes.pi.processIds.length > 0 || (processes.pi.inconclusivePids?.length ?? 0) > 0 || processes.processSnapshot?.source !== "cim") {
23197
23737
  throw new Error(`Windows process probe could not rule out OpenCode, Pi or ck-mc holders${processes.pi.processIds.length || processes.pi.inconclusivePids?.length ? ` (PID ${[...processes.pi.processIds, ...processes.pi.inconclusivePids ?? []].join(", ")})` : ""}`);
@@ -23207,7 +23747,7 @@ function assertWindowsStoresClosed(paths, processes) {
23207
23747
  if (blockers.length)
23208
23748
  throw new Error(`OpenCode, Pi or ck-mc process is running (${blockers.map(({ pid, imageName, commandLine }) => `${imageName ?? commandLine} PID ${pid}`).join(", ")})`);
23209
23749
  for (const path of [...new Set(paths)]) {
23210
- if (!existsSync12(path))
23750
+ if (!existsSync13(path))
23211
23751
  continue;
23212
23752
  let db;
23213
23753
  let locked = false;
@@ -23231,7 +23771,7 @@ var init_doctor_windows_holders = __esm(async () => {
23231
23771
 
23232
23772
  // src/commands/doctor-opencode2-cache.ts
23233
23773
  import { spawnSync as spawnSync3 } from "node:child_process";
23234
- import { existsSync as existsSync13, rmSync as rmSync3 } from "node:fs";
23774
+ import { existsSync as existsSync14, rmSync as rmSync4 } from "node:fs";
23235
23775
  function runLsof(args, spawn) {
23236
23776
  const result = spawn("lsof", args, { encoding: "utf-8", timeout: 15000, windowsHide: true });
23237
23777
  if (result.error)
@@ -23246,7 +23786,7 @@ function probeHostProcessesUsing(targets, spawn = spawnSync3) {
23246
23786
  if (process.platform === "win32") {
23247
23787
  try {
23248
23788
  assertWindowsStoresClosed(targets.files.filter((path) => !/-(?:wal|shm)$/.test(path)), inspectWindowsProcessesSync());
23249
- if (targets.directories.some(existsSync13))
23789
+ if (targets.directories.some(existsSync14))
23250
23790
  return {
23251
23791
  status: "unknown",
23252
23792
  reason: "Windows cannot rule out open files in plugin cache directories"
@@ -23259,8 +23799,8 @@ function probeHostProcessesUsing(targets, spawn = spawnSync3) {
23259
23799
  };
23260
23800
  }
23261
23801
  }
23262
- const files = targets.files.filter((file) => existsSync13(file));
23263
- const directories = targets.directories.filter((directory) => existsSync13(directory));
23802
+ const files = targets.files.filter((file) => existsSync14(file));
23803
+ const directories = targets.directories.filter((directory) => existsSync14(directory));
23264
23804
  const queries = [];
23265
23805
  if (files.length > 0)
23266
23806
  queries.push(["-w", "-t", "--", ...files]);
@@ -23335,7 +23875,7 @@ function removeOpenCodeV2PluginCacheSlot(slot, hostFiles, deps = {}) {
23335
23875
  return { action: "in_use", pids: use.pids };
23336
23876
  if (use.status === "unknown")
23337
23877
  return { action: "in_use_unknown", reason: use.reason };
23338
- const remove = deps.remove ?? ((path) => rmSync3(path, { recursive: true, force: true }));
23878
+ const remove = deps.remove ?? ((path) => rmSync4(path, { recursive: true, force: true }));
23339
23879
  try {
23340
23880
  remove(slot);
23341
23881
  } catch (err) {
@@ -23355,9 +23895,9 @@ function checkOpenCodeV2PluginCache(options, deps = {}) {
23355
23895
  const slot = deps.slot ?? getOpenCodeV2PluginCacheSlot(undefined, distTag ?? "latest");
23356
23896
  const tagged = distTag ? { distTag } : {};
23357
23897
  if (options.referencedSpecs !== undefined && !options.referencedSpecs.has(distTag ?? "latest")) {
23358
- return existsSync13(slot) ? { action: "unused", slot, cached: readOpenCodeV2CachedPluginVersion(slot), ...tagged } : { action: "not_found", slot, unused: true, ...tagged };
23898
+ return existsSync14(slot) ? { action: "unused", slot, cached: readOpenCodeV2CachedPluginVersion(slot), ...tagged } : { action: "not_found", slot, unused: true, ...tagged };
23359
23899
  }
23360
- if (!existsSync13(slot))
23900
+ if (!existsSync14(slot))
23361
23901
  return { action: "not_found", slot, ...tagged };
23362
23902
  const cached = readOpenCodeV2CachedPluginVersion(slot);
23363
23903
  const latest = options.latestVersion ?? undefined;
@@ -23450,21 +23990,21 @@ var init_doctor_opencode2_cache = __esm(async () => {
23450
23990
  import { randomBytes as randomBytes2 } from "node:crypto";
23451
23991
  import {
23452
23992
  lstatSync as lstatSync2,
23453
- mkdirSync as mkdirSync3,
23993
+ mkdirSync as mkdirSync4,
23454
23994
  readlinkSync as readlinkSync2,
23455
- renameSync as renameSync3,
23456
- rmSync as rmSync4,
23457
- statSync as statSync8,
23458
- writeFileSync as writeFileSync3
23995
+ renameSync as renameSync4,
23996
+ rmSync as rmSync5,
23997
+ statSync as statSync9,
23998
+ writeFileSync as writeFileSync4
23459
23999
  } from "node:fs";
23460
- import { dirname as dirname7, resolve as resolve5 } from "node:path";
24000
+ import { dirname as dirname8, resolve as resolve5 } from "node:path";
23461
24001
  function resolveWriteTarget(targetPath) {
23462
24002
  let current = resolve5(targetPath);
23463
24003
  for (let hop = 0;hop < MAX_SYMLINK_HOPS; hop++) {
23464
24004
  const stat = lstatSync2(current, { throwIfNoEntry: false });
23465
24005
  if (!stat?.isSymbolicLink())
23466
24006
  return current;
23467
- current = resolve5(dirname7(current), readlinkSync2(current));
24007
+ current = resolve5(dirname8(current), readlinkSync2(current));
23468
24008
  }
23469
24009
  throw new Error(`Too many levels of symbolic links resolving ${targetPath}`);
23470
24010
  }
@@ -23474,19 +24014,19 @@ function writeFileAtomic(targetPath, data, options = {}) {
23474
24014
  writeStorageFileAtomicSync(finalPath, data, true);
23475
24015
  return;
23476
24016
  }
23477
- mkdirSync3(dirname7(finalPath), { recursive: true });
23478
- const existing = statSync8(finalPath, { throwIfNoEntry: false });
24017
+ mkdirSync4(dirname8(finalPath), { recursive: true });
24018
+ const existing = statSync9(finalPath, { throwIfNoEntry: false });
23479
24019
  const mode = existing?.isFile() ? existing.mode & 511 : undefined;
23480
24020
  const tmpPath = `${finalPath}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
23481
24021
  try {
23482
- writeFileSync3(tmpPath, data, {
24022
+ writeFileSync4(tmpPath, data, {
23483
24023
  encoding: "utf-8",
23484
24024
  flag: "wx",
23485
24025
  ...mode !== undefined ? { mode } : {}
23486
24026
  });
23487
- renameSync3(tmpPath, finalPath);
24027
+ renameSync4(tmpPath, finalPath);
23488
24028
  } catch (error) {
23489
- rmSync4(tmpPath, { force: true });
24029
+ rmSync5(tmpPath, { force: true });
23490
24030
  throw error;
23491
24031
  }
23492
24032
  }
@@ -23496,7 +24036,7 @@ var init_atomic_write = __esm(() => {
23496
24036
  });
23497
24037
 
23498
24038
  // src/lib/jsonc-config.ts
23499
- import { existsSync as existsSync14, readFileSync as readFileSync10 } from "node:fs";
24039
+ import { existsSync as existsSync15, readFileSync as readFileSync11 } from "node:fs";
23500
24040
  function parseErrorLocation(content, error) {
23501
24041
  const lines = content.split(`
23502
24042
  `);
@@ -23512,9 +24052,9 @@ function parseErrorLocation(content, error) {
23512
24052
  return { line: messageLine ? Number.parseInt(messageLine, 10) : 1, column: 1 };
23513
24053
  }
23514
24054
  function readJsoncConfig(path) {
23515
- if (!existsSync14(path))
24055
+ if (!existsSync15(path))
23516
24056
  return { kind: "missing" };
23517
- const content = readFileSync10(path, "utf-8");
24057
+ const content = readFileSync11(path, "utf-8");
23518
24058
  try {
23519
24059
  const rejectedKeyPaths = [];
23520
24060
  const parsed = sanitizeParsedJson(import_comment_json.parse(content), {
@@ -23540,7 +24080,7 @@ function readJsoncConfigForUpdate(path) {
23540
24080
  return result.value;
23541
24081
  }
23542
24082
  function readJsoncTextForEdit(configPath) {
23543
- const raw = readFileSync10(configPath, "utf-8");
24083
+ const raw = readFileSync11(configPath, "utf-8");
23544
24084
  return raw.startsWith(BYTE_ORDER_MARK) ? { bom: BYTE_ORDER_MARK, text: raw.slice(BYTE_ORDER_MARK.length) } : { bom: "", text: raw };
23545
24085
  }
23546
24086
  function assertJsoncConfigsParseable(paths) {
@@ -23629,15 +24169,15 @@ var init_jsonc_config = __esm(() => {
23629
24169
  });
23630
24170
 
23631
24171
  // src/lib/opencode-detect.ts
23632
- import { existsSync as existsSync15, realpathSync as realpathSync2 } from "node:fs";
23633
- import { homedir as homedir10 } from "node:os";
23634
- import { join as join13 } from "node:path";
24172
+ import { existsSync as existsSync16, realpathSync as realpathSync2 } from "node:fs";
24173
+ import { homedir as homedir11 } from "node:os";
24174
+ import { join as join14 } from "node:path";
23635
24175
  function defaultDeps(overrides = {}) {
23636
24176
  const env = overrides.env ?? process.env;
23637
24177
  return {
23638
- exists: overrides.exists ?? existsSync15,
24178
+ exists: overrides.exists ?? existsSync16,
23639
24179
  isExecutable: overrides.isExecutable ?? isExecutableFile,
23640
- home: overrides.home ?? (env.HOME?.trim() || homedir10()),
24180
+ home: overrides.home ?? (env.HOME?.trim() || homedir11()),
23641
24181
  platform: overrides.platform ?? process.platform,
23642
24182
  env,
23643
24183
  onPath: overrides.onPath ?? findOnPath,
@@ -23645,7 +24185,7 @@ function defaultDeps(overrides = {}) {
23645
24185
  };
23646
24186
  }
23647
24187
  function stockCliBinary(d) {
23648
- return d.platform === "win32" ? join13(d.home, ".opencode", "bin", "opencode.exe") : join13(d.home, ".opencode", "bin", "opencode");
24188
+ return d.platform === "win32" ? join14(d.home, ".opencode", "bin", "opencode.exe") : join14(d.home, ".opencode", "bin", "opencode");
23649
24189
  }
23650
24190
  function extraCliCandidates(d) {
23651
24191
  if (d.platform === "win32") {
@@ -23654,25 +24194,25 @@ function extraCliCandidates(d) {
23654
24194
  const userprofile = d.env.USERPROFILE ?? d.home;
23655
24195
  const out = [];
23656
24196
  if (appdata) {
23657
- out.push(join13(appdata, "npm", "opencode.cmd"));
23658
- out.push(join13(appdata, "npm", "opencode.exe"));
24197
+ out.push(join14(appdata, "npm", "opencode.cmd"));
24198
+ out.push(join14(appdata, "npm", "opencode.exe"));
23659
24199
  }
23660
24200
  if (localappdata) {
23661
- out.push(join13(localappdata, "Microsoft", "WinGet", "Links", "opencode.exe"));
23662
- out.push(join13(localappdata, "opencode", "bin", "opencode.exe"));
24201
+ out.push(join14(localappdata, "Microsoft", "WinGet", "Links", "opencode.exe"));
24202
+ out.push(join14(localappdata, "opencode", "bin", "opencode.exe"));
23663
24203
  }
23664
24204
  if (userprofile) {
23665
- out.push(join13(userprofile, "scoop", "shims", "opencode.exe"));
24205
+ out.push(join14(userprofile, "scoop", "shims", "opencode.exe"));
23666
24206
  }
23667
24207
  return out;
23668
24208
  }
23669
24209
  return [
23670
24210
  "/usr/local/bin/opencode",
23671
24211
  "/opt/homebrew/bin/opencode",
23672
- join13(d.home, ".local", "bin", "opencode"),
23673
- join13(d.home, ".local", "share", "mise", "shims", "opencode"),
23674
- join13(d.home, ".asdf", "shims", "opencode"),
23675
- join13(d.home, ".volta", "bin", "opencode")
24212
+ join14(d.home, ".local", "bin", "opencode"),
24213
+ join14(d.home, ".local", "share", "mise", "shims", "opencode"),
24214
+ join14(d.home, ".asdf", "shims", "opencode"),
24215
+ join14(d.home, ".volta", "bin", "opencode")
23676
24216
  ];
23677
24217
  }
23678
24218
  function openChamberCliCandidates(d) {
@@ -23680,8 +24220,8 @@ function openChamberCliCandidates(d) {
23680
24220
  return [];
23681
24221
  const bundled = ["Contents", "Resources", "opencode-cli", "opencode"];
23682
24222
  return [
23683
- join13("/Applications", "OpenChamber.app", ...bundled),
23684
- join13(d.home, "Applications", "OpenChamber.app", ...bundled)
24223
+ join14("/Applications", "OpenChamber.app", ...bundled),
24224
+ join14(d.home, "Applications", "OpenChamber.app", ...bundled)
23685
24225
  ];
23686
24226
  }
23687
24227
  function canonicalPath(d, path) {
@@ -23702,29 +24242,29 @@ function xdgConfigHome(d) {
23702
24242
  const xdg = d.env.XDG_CONFIG_HOME;
23703
24243
  if (xdg && xdg.length > 0)
23704
24244
  return xdg;
23705
- return join13(d.home, ".config");
24245
+ return join14(d.home, ".config");
23706
24246
  }
23707
24247
  function desktopUserDataDir(d, appId) {
23708
24248
  switch (d.platform) {
23709
24249
  case "darwin":
23710
- return join13(d.home, "Library", "Application Support", appId);
24250
+ return join14(d.home, "Library", "Application Support", appId);
23711
24251
  case "win32":
23712
- return join13(d.env.APPDATA ?? join13(d.home, "AppData", "Roaming"), appId);
24252
+ return join14(d.env.APPDATA ?? join14(d.home, "AppData", "Roaming"), appId);
23713
24253
  default:
23714
- return join13(xdgConfigHome(d), appId);
24254
+ return join14(xdgConfigHome(d), appId);
23715
24255
  }
23716
24256
  }
23717
24257
  function desktopAppPaths(d) {
23718
24258
  switch (d.platform) {
23719
24259
  case "darwin":
23720
- return ["/Applications/OpenCode.app", join13(d.home, "Applications", "OpenCode.app")];
24260
+ return ["/Applications/OpenCode.app", join14(d.home, "Applications", "OpenCode.app")];
23721
24261
  case "win32": {
23722
- const localappdata = d.env.LOCALAPPDATA ?? join13(d.home, "AppData", "Local");
23723
- return [join13(localappdata, "Programs", "OpenCode", "OpenCode.exe")];
24262
+ const localappdata = d.env.LOCALAPPDATA ?? join14(d.home, "AppData", "Local");
24263
+ return [join14(localappdata, "Programs", "OpenCode", "OpenCode.exe")];
23724
24264
  }
23725
24265
  default: {
23726
- const dataHome = d.env.XDG_DATA_HOME && d.env.XDG_DATA_HOME.length > 0 ? d.env.XDG_DATA_HOME : join13(d.home, ".local", "share");
23727
- return OPENCODE_DESKTOP_APP_IDS.map((appId) => join13(dataHome, "applications", `${appId}.desktop`));
24266
+ const dataHome = d.env.XDG_DATA_HOME && d.env.XDG_DATA_HOME.length > 0 ? d.env.XDG_DATA_HOME : join14(d.home, ".local", "share");
24267
+ return OPENCODE_DESKTOP_APP_IDS.map((appId) => join14(dataHome, "applications", `${appId}.desktop`));
23728
24268
  }
23729
24269
  }
23730
24270
  }
@@ -23751,7 +24291,7 @@ function detectOpenCodeInstallations(deps) {
23751
24291
  }
23752
24292
  }
23753
24293
  for (const appId of OPENCODE_DESKTOP_APP_IDS) {
23754
- const marker = join13(desktopUserDataDir(d, appId), OPENCODE_DESKTOP_SETTINGS_FILE);
24294
+ const marker = join14(desktopUserDataDir(d, appId), OPENCODE_DESKTOP_SETTINGS_FILE);
23755
24295
  if (d.exists(marker)) {
23756
24296
  addCandidate(installations, seenRealpaths, d, marker, "desktop", "desktop");
23757
24297
  }
@@ -23849,8 +24389,8 @@ var OPENCODE_BINARY_ENV = "MAGIC_CONTEXT_OPENCODE_BINARY", OPENCODE_VERSION_PROB
23849
24389
  var init_opencode_helpers = () => {};
23850
24390
 
23851
24391
  // src/adapters/opencode.ts
23852
- import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync9 } from "node:fs";
23853
- import { dirname as dirname8, isAbsolute as isAbsolute5, parse as parsePath, resolve as resolve6 } from "node:path";
24392
+ import { existsSync as existsSync17, readFileSync as readFileSync12, statSync as statSync10 } from "node:fs";
24393
+ import { dirname as dirname9, isAbsolute as isAbsolute5, parse as parsePath, resolve as resolve6 } from "node:path";
23854
24394
  import { fileURLToPath as fileURLToPath2 } from "node:url";
23855
24395
 
23856
24396
  class OpenCodeAdapter {
@@ -23881,7 +24421,7 @@ class OpenCodeAdapter {
23881
24421
  if (paths.opencodeConfigFormat === "none")
23882
24422
  return false;
23883
24423
  try {
23884
- const raw = readFileSync11(paths.opencodeConfig, "utf-8");
24424
+ const raw = readFileSync12(paths.opencodeConfig, "utf-8");
23885
24425
  const cfg = import_comment_json2.parse(raw);
23886
24426
  return readPluginEntries(cfg).some(({ entry }) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME));
23887
24427
  } catch {
@@ -23917,7 +24457,7 @@ class OpenCodeAdapter {
23917
24457
  configPath: target
23918
24458
  };
23919
24459
  }
23920
- const raw = readFileSync11(target, "utf-8");
24460
+ const raw = readFileSync12(target, "utf-8");
23921
24461
  const cfg = import_comment_json2.parse(raw);
23922
24462
  if (cfg === null || typeof cfg !== "object") {
23923
24463
  return {
@@ -23929,7 +24469,7 @@ class OpenCodeAdapter {
23929
24469
  }
23930
24470
  const entries = readPluginEntries(cfg);
23931
24471
  const existing = entries.find(({ entry }) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME));
23932
- const existingDev = entries.find(({ entry }) => isDevPathPluginEntry(entry, dirname8(target)));
24472
+ const existingDev = entries.find(({ entry }) => isDevPathPluginEntry(entry, dirname9(target)));
23933
24473
  if (!existing && !existingDev) {
23934
24474
  const list = Array.isArray(cfg[this.writeKey]) ? cfg[this.writeKey] : [];
23935
24475
  list.push(OPENCODE_PLUGIN_ENTRY_WITH_VERSION);
@@ -23992,7 +24532,7 @@ class OpenCodeAdapter {
23992
24532
  };
23993
24533
  }
23994
24534
  try {
23995
- const raw = readFileSync11(target, "utf-8");
24535
+ const raw = readFileSync12(target, "utf-8");
23996
24536
  const cfg = import_comment_json2.parse(raw);
23997
24537
  if (cfg === null || typeof cfg !== "object") {
23998
24538
  return {
@@ -24043,9 +24583,9 @@ class OpenCodeAdapter {
24043
24583
  }
24044
24584
  getPluginCacheInfo() {
24045
24585
  const legacyPath = getOpenCodePluginCacheDir();
24046
- const legacyExists = existsSync16(legacyPath);
24586
+ const legacyExists = existsSync17(legacyPath);
24047
24587
  const slot = getOpenCodeV2PluginCacheSlot();
24048
- const slotExists = existsSync16(slot);
24588
+ const slotExists = existsSync17(slot);
24049
24589
  const caches = [];
24050
24590
  if (legacyExists || !slotExists) {
24051
24591
  caches.push({
@@ -24103,7 +24643,7 @@ class OpenCodeAdapter {
24103
24643
  if (paths.opencodeConfigFormat === "none")
24104
24644
  return "latest";
24105
24645
  try {
24106
- const cfg = import_comment_json2.parse(readFileSync11(paths.opencodeConfig, "utf-8"));
24646
+ const cfg = import_comment_json2.parse(readFileSync12(paths.opencodeConfig, "utf-8"));
24107
24647
  return readConfiguredOpenCodePluginSpec(cfg);
24108
24648
  } catch {
24109
24649
  return "latest";
@@ -24115,10 +24655,10 @@ class OpenCodeAdapter {
24115
24655
  return readOpenCodeV2CachedPluginVersion(slot) ?? null;
24116
24656
  }
24117
24657
  for (const candidate of getOpenCodePluginPackageJsonPaths()) {
24118
- if (!existsSync16(candidate))
24658
+ if (!existsSync17(candidate))
24119
24659
  continue;
24120
24660
  try {
24121
- const raw = readFileSync11(candidate, "utf-8");
24661
+ const raw = readFileSync12(candidate, "utf-8");
24122
24662
  const pkg = JSON.parse(raw);
24123
24663
  if (typeof pkg.version === "string")
24124
24664
  return pkg.version;
@@ -24156,16 +24696,16 @@ function isDevPathPluginEntry(entry, configDir) {
24156
24696
  } else {
24157
24697
  localPath = resolve6(configDir, candidate);
24158
24698
  }
24159
- if (statSync9(localPath).isFile())
24160
- localPath = dirname8(localPath);
24699
+ if (statSync10(localPath).isFile())
24700
+ localPath = dirname9(localPath);
24161
24701
  const root = parsePath(localPath).root;
24162
24702
  while (localPath !== root) {
24163
24703
  const packagePath = resolve6(localPath, "package.json");
24164
- if (existsSync16(packagePath)) {
24165
- const pkg = JSON.parse(readFileSync11(packagePath, "utf8"));
24704
+ if (existsSync17(packagePath)) {
24705
+ const pkg = JSON.parse(readFileSync12(packagePath, "utf8"));
24166
24706
  return pkg.name === OPENCODE_PLUGIN_NAME;
24167
24707
  }
24168
- localPath = dirname8(localPath);
24708
+ localPath = dirname9(localPath);
24169
24709
  }
24170
24710
  } catch {}
24171
24711
  return false;
@@ -24181,8 +24721,8 @@ function matchesPluginEntry(entry, pkgName) {
24181
24721
  return head === pkgName;
24182
24722
  }
24183
24723
  function ensureDir2(filePath) {
24184
- const dir = dirname8(filePath);
24185
- if (!existsSync16(dir)) {
24724
+ const dir = dirname9(filePath);
24725
+ if (!existsSync17(dir)) {
24186
24726
  const { mkdirSync } = __require("node:fs");
24187
24727
  mkdirSync(dir, { recursive: true });
24188
24728
  }
@@ -24203,8 +24743,8 @@ var init_opencode = __esm(async () => {
24203
24743
  });
24204
24744
 
24205
24745
  // src/lib/pi-package-entry.ts
24206
- import { existsSync as existsSync17, readFileSync as readFileSync12 } from "node:fs";
24207
- import { isAbsolute as isAbsolute6, join as join14 } from "node:path";
24746
+ import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
24747
+ import { isAbsolute as isAbsolute6, join as join15 } from "node:path";
24208
24748
  function stripNpmPrefix(value) {
24209
24749
  return value.startsWith("npm:") ? value.slice("npm:".length) : value;
24210
24750
  }
@@ -24259,11 +24799,11 @@ function hasPiMagicContextPackage(entries, agentDir = getPiAgentConfigDir()) {
24259
24799
  return entries.some((entry) => isConfiguredPiMagicContextEntry(entry, agentDir));
24260
24800
  }
24261
24801
  function isPiMagicContextPackageDir(dir) {
24262
- const packageJson = join14(dir, "package.json");
24263
- if (!existsSync17(packageJson))
24802
+ const packageJson = join15(dir, "package.json");
24803
+ if (!existsSync18(packageJson))
24264
24804
  return false;
24265
24805
  try {
24266
- const pkg = JSON.parse(readFileSync12(packageJson, "utf-8"));
24806
+ const pkg = JSON.parse(readFileSync13(packageJson, "utf-8"));
24267
24807
  return typeof pkg.name === "string" && pkg.name === PI_MAGIC_CONTEXT_PACKAGE_NAME;
24268
24808
  } catch {
24269
24809
  return false;
@@ -24275,7 +24815,7 @@ function localPiMagicContextPackageDir(entry, agentDir) {
24275
24815
  if (!spec || spec.startsWith("npm:"))
24276
24816
  return null;
24277
24817
  const path = spec.startsWith("file:") ? spec.slice("file:".length) : spec;
24278
- const dir = isAbsolute6(path) ? path : join14(agentDir, path);
24818
+ const dir = isAbsolute6(path) ? path : join15(agentDir, path);
24279
24819
  return isPiMagicContextPackageDir(dir) ? dir : null;
24280
24820
  }
24281
24821
  function isConfiguredPiMagicContextEntry(entry, agentDir) {
@@ -24299,8 +24839,8 @@ var init_pi_package_entry = __esm(() => {
24299
24839
  });
24300
24840
 
24301
24841
  // src/adapters/pi.ts
24302
- import { existsSync as existsSync18 } from "node:fs";
24303
- import { dirname as dirname9 } from "node:path";
24842
+ import { existsSync as existsSync19 } from "node:fs";
24843
+ import { dirname as dirname10 } from "node:path";
24304
24844
 
24305
24845
  class PiAdapter {
24306
24846
  kind = "pi";
@@ -24437,8 +24977,8 @@ function writePiSettings(settings) {
24437
24977
  `);
24438
24978
  }
24439
24979
  function ensureDir3(filePath) {
24440
- const dir = dirname9(filePath);
24441
- if (!existsSync18(dir)) {
24980
+ const dir = dirname10(filePath);
24981
+ if (!existsSync19(dir)) {
24442
24982
  const { mkdirSync } = __require("node:fs");
24443
24983
  mkdirSync(dir, { recursive: true });
24444
24984
  }
@@ -24756,7 +25296,7 @@ var init_fail_closed_block = __esm(() => {
24756
25296
  });
24757
25297
 
24758
25298
  // ../plugin/src/features/magic-context/message-fts-rowid-map.ts
24759
- import { createHash } from "node:crypto";
25299
+ import { createHash as createHash2 } from "node:crypto";
24760
25300
  function getUpsertMapStatement(db) {
24761
25301
  let statement = upsertMapStatements.get(db);
24762
25302
  if (!statement) {
@@ -24858,7 +25398,7 @@ var MESSAGE_FTS_ROWID_MAP_BACKFILL_BATCH_SIZE = 100, BACKFILL_STATE_ID = 1, EMPT
24858
25398
  var init_message_fts_rowid_map = __esm(async () => {
24859
25399
  init_write_transaction_timing();
24860
25400
  await init_sqlite();
24861
- EMPTY_INDEX_CONTENT_HASH = createHash("sha256").update("").digest("hex");
25401
+ EMPTY_INDEX_CONTENT_HASH = createHash2("sha256").update("").digest("hex");
24862
25402
  upsertMapStatements = new WeakMap;
24863
25403
  rangeReadyStatements = new WeakMap;
24864
25404
  updateTimeStatements = new WeakMap;
@@ -24866,7 +25406,7 @@ var init_message_fts_rowid_map = __esm(async () => {
24866
25406
  });
24867
25407
 
24868
25408
  // ../plugin/src/features/magic-context/lkg-prefix-chunks.ts
24869
- import { createHash as createHash2 } from "node:crypto";
25409
+ import { createHash as createHash3 } from "node:crypto";
24870
25410
  function splitLkgPrefix(jsonPrefix) {
24871
25411
  const chunks = [];
24872
25412
  let start = 0;
@@ -24883,10 +25423,10 @@ function splitLkgPrefix(jsonPrefix) {
24883
25423
  return chunks;
24884
25424
  }
24885
25425
  function hashLkgChunk(body) {
24886
- return createHash2("sha256").update(body).digest("hex");
25426
+ return createHash3("sha256").update(body).digest("hex");
24887
25427
  }
24888
25428
  function hashLkgChunkList(chunkHashes) {
24889
- return createHash2("sha256").update(chunkHashes.join(`
25429
+ return createHash3("sha256").update(chunkHashes.join(`
24890
25430
  `)).digest("hex");
24891
25431
  }
24892
25432
  function layoutLkgPrefix(jsonPrefix) {
@@ -26015,11 +26555,11 @@ function installCompartmentHistoryVersions(db) {
26015
26555
  }
26016
26556
 
26017
26557
  // ../plugin/src/features/magic-context/memory/project-identity-cache.ts
26018
- import { createHash as createHash3 } from "node:crypto";
26019
- import { readFileSync as readFileSync13 } from "node:fs";
26558
+ import { createHash as createHash4 } from "node:crypto";
26559
+ import { readFileSync as readFileSync14 } from "node:fs";
26020
26560
  import path4 from "node:path";
26021
26561
  function cachePath(directory, storageDir = getMagicContextStorageDir()) {
26022
- const hash = createHash3("sha256").update(projectDirectoryKey(directory)).digest("hex");
26562
+ const hash = createHash4("sha256").update(projectDirectoryKey(directory)).digest("hex");
26023
26563
  return path4.join(storageDir, "project-identities", `${hash}.json`);
26024
26564
  }
26025
26565
  function rememberGitIdentity(directory, identity) {
@@ -26030,7 +26570,7 @@ function rememberGitIdentity(directory, identity) {
26030
26570
  }
26031
26571
  function readRememberedGitIdentity(directory, storageDir) {
26032
26572
  try {
26033
- const record = JSON.parse(readFileSync13(cachePath(directory, storageDir), "utf8"));
26573
+ const record = JSON.parse(readFileSync14(cachePath(directory, storageDir), "utf8"));
26034
26574
  if (record.directory === projectDirectoryKey(directory) && /^git:[0-9a-f]{7,64}$/.test(record.identity))
26035
26575
  return record.identity;
26036
26576
  } catch {}
@@ -26044,9 +26584,9 @@ var init_project_identity_cache = __esm(() => {
26044
26584
 
26045
26585
  // ../plugin/src/features/magic-context/memory/project-identity.ts
26046
26586
  import { execFileSync as execFileSync4 } from "node:child_process";
26047
- import { createHash as createHash4 } from "node:crypto";
26048
- import { existsSync as existsSync19, realpathSync as realpathSync3, statSync as statSync10 } from "node:fs";
26049
- import { homedir as homedir11 } from "node:os";
26587
+ import { createHash as createHash5 } from "node:crypto";
26588
+ import { existsSync as existsSync20, realpathSync as realpathSync3, statSync as statSync11 } from "node:fs";
26589
+ import { homedir as homedir12 } from "node:os";
26050
26590
  import path5 from "node:path";
26051
26591
  function asError(error) {
26052
26592
  return error instanceof Error ? error : undefined;
@@ -26086,7 +26626,7 @@ function getErrorStderr(error) {
26086
26626
  }
26087
26627
  function directoryFallback(directory) {
26088
26628
  const canonical = path5.resolve(directory);
26089
- const hash = createHash4("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
26629
+ const hash = createHash5("md5").update(canonical, "utf8").digest("hex").slice(0, 12);
26090
26630
  return `dir:${hash}`;
26091
26631
  }
26092
26632
  function rememberedIdentityOrDirectoryFallback(canonical) {
@@ -26094,7 +26634,7 @@ function rememberedIdentityOrDirectoryFallback(canonical) {
26094
26634
  }
26095
26635
  function assertDirectoryUsable(canonicalDirectory, rawDirectory) {
26096
26636
  try {
26097
- const stat = statSync10(canonicalDirectory);
26637
+ const stat = statSync11(canonicalDirectory);
26098
26638
  if (!stat.isDirectory()) {
26099
26639
  throw new ProjectIdentityError("unknown", rawDirectory, `Project path is not a directory: ${canonicalDirectory}`);
26100
26640
  }
@@ -26155,10 +26695,10 @@ function classifyGitError(error, rawDirectory) {
26155
26695
  }
26156
26696
  return new ProjectIdentityError("unknown", rawDirectory, "git rev-list failed while resolving project identity", asError(error));
26157
26697
  }
26158
- function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectPermission) {
26698
+ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectPermission, options = {}) {
26159
26699
  assertProjectAllowed(directory, allowHomeProject);
26160
26700
  const canonical = path5.resolve(directory);
26161
- const cached = identityCache.get(canonical);
26701
+ const cached = options.cache === false ? undefined : identityCache.get(canonical);
26162
26702
  if (cached !== undefined) {
26163
26703
  return cached;
26164
26704
  }
@@ -26189,6 +26729,8 @@ function resolveProjectIdentityStrict(directory, allowHomeProject = homeProjectP
26189
26729
  throw new ProjectIdentityError("unknown", directory, "git rev-list returned no valid root commit hash");
26190
26730
  }
26191
26731
  const identity = `git:${rootCommit}`;
26732
+ if (options.cache === false)
26733
+ return identity;
26192
26734
  identityCache.set(canonical, identity);
26193
26735
  lastKnownGitIdentityCache.set(canonical, identity);
26194
26736
  rememberGitIdentity(canonical, identity);
@@ -26224,7 +26766,7 @@ function nearestLastKnownGitIdentity(canonical) {
26224
26766
  const cached = lastKnownGitIdentity(current);
26225
26767
  if (cached !== undefined)
26226
26768
  return { identity: cached, source: current };
26227
- if (existsSync19(path5.join(current, ".git")))
26769
+ if (existsSync20(path5.join(current, ".git")))
26228
26770
  break;
26229
26771
  const parent = path5.dirname(current);
26230
26772
  if (parent === current)
@@ -26347,7 +26889,7 @@ function hasGitDir(canonical) {
26347
26889
  function gitRootInAncestorChain(startDirectory) {
26348
26890
  let current = startDirectory;
26349
26891
  while (true) {
26350
- if (existsSync19(path5.join(current, ".git"))) {
26892
+ if (existsSync20(path5.join(current, ".git"))) {
26351
26893
  try {
26352
26894
  return realpathSync3.native(current);
26353
26895
  } catch {
@@ -26375,7 +26917,7 @@ function gitRootDirectory(canonical) {
26375
26917
  return null;
26376
26918
  }
26377
26919
  }
26378
- var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, pausedIdentityReasons, pausedIdentityLogged, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir11(), nowMs = () => Date.now(), ProjectIdentityError;
26920
+ var GIT_TIMEOUT_MS = 5000, TRANSIENT_FAILURE_COOLDOWN_MS, identityCache, linkedGitWorktreeCache, lastKnownGitIdentityCache, directoryFallbackCache, transientFailureCooldown, dubiousOwnershipFallbackDirectories, dubiousOwnershipLoggedDirectories, dubiousOwnershipWarnedDirectories, transientGitIdentityReuseLoggedDirectories, sessionIdentityCache, homeProjectPermission = false, pausedIdentityReasons, pausedIdentityLogged, execFileSyncForIdentity, userHomeDirectoryForIdentity = () => homedir12(), nowMs = () => Date.now(), ProjectIdentityError;
26379
26921
  var init_project_identity = __esm(() => {
26380
26922
  init_logger();
26381
26923
  init_project_identity_cache();
@@ -29659,7 +30201,7 @@ var init_tool_definition_tokens = __esm(() => {
29659
30201
  });
29660
30202
 
29661
30203
  // ../plugin/src/features/magic-context/tool-owner-backfill.ts
29662
- import { existsSync as existsSync20 } from "node:fs";
30204
+ import { existsSync as existsSync21 } from "node:fs";
29663
30205
  function resolveOpencodeDbPath() {
29664
30206
  return resolveOpenCodeDbPath().path;
29665
30207
  }
@@ -29696,7 +30238,7 @@ function runToolOwnerBackfill(db) {
29696
30238
  return result;
29697
30239
  }
29698
30240
  const opencodeDbPath = resolveOpencodeDbPath();
29699
- if (!existsSync20(opencodeDbPath)) {
30241
+ if (!existsSync21(opencodeDbPath)) {
29700
30242
  log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
29701
30243
  markAllUnbackfilledSessionsSkipped(db);
29702
30244
  result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
@@ -30300,7 +30842,10 @@ function isRecord2(value) {
30300
30842
  }
30301
30843
 
30302
30844
  // ../plugin/src/shared/tag-owner-id.ts
30303
- var init_tag_owner_id = () => {};
30845
+ var PI_FALLBACK_PREFIXES_JSON;
30846
+ var init_tag_owner_id = __esm(() => {
30847
+ PI_FALLBACK_PREFIXES_JSON = JSON.stringify([..."pi-msg-"].reduce((prefixes, char) => prefixes.flatMap((prefix) => /[a-z]/.test(char) ? [prefix + char, prefix + char.toUpperCase()] : [prefix + char]), [""]));
30848
+ });
30304
30849
 
30305
30850
  // ../plugin/src/hooks/magic-context/image-token-estimate.ts
30306
30851
  var JPEG_SCAN_LIMIT_BYTES;
@@ -31666,6 +32211,8 @@ function runSessionWarmupWorker(input, options) {
31666
32211
  finish({ delta: reply.delta });
31667
32212
  else if (reply.kind === "indexed")
31668
32213
  finish({ inserted: reply.inserted, measurements: reply.measurements });
32214
+ else if (reply.kind === "orphan-sweep")
32215
+ finish({ orphanSweep: reply.result });
31669
32216
  else
31670
32217
  finish({ failure: "worker-error", detail: reply.error });
31671
32218
  });
@@ -33193,6 +33740,14 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
33193
33740
  pinComponentWhenFormattedBudgetCrosses(msg.ordinal, text);
33194
33741
  }
33195
33742
  if (flushCurrentBlock() && pendingNoiseMeta.length > 0) {
33743
+ const lastNoise = pendingNoiseMeta[pendingNoiseMeta.length - 1];
33744
+ if (messagesProcessed > 0 && lastNoise) {
33745
+ lineMeta.push(...pendingNoiseMeta);
33746
+ messagesProcessed += pendingNoiseMeta.length;
33747
+ lastOrdinal = lastNoise.ordinal;
33748
+ lastMessageId = lastNoise.messageId;
33749
+ pendingNoiseMeta = [];
33750
+ }
33196
33751
  highestScannedOrdinal = Math.max(highestScannedOrdinal, pendingNoiseMeta[pendingNoiseMeta.length - 1]?.ordinal ?? highestScannedOrdinal);
33197
33752
  }
33198
33753
  const toolOnlyRanges = [];
@@ -33396,14 +33951,14 @@ var init_message_time_backfill = __esm(async () => {
33396
33951
 
33397
33952
  // ../plugin/src/features/magic-context/storage-db.ts
33398
33953
  import {
33399
- existsSync as existsSync21,
33954
+ existsSync as existsSync22,
33400
33955
  readdirSync as readdirSync5,
33401
- readFileSync as readFileSync14,
33956
+ readFileSync as readFileSync15,
33402
33957
  rmdirSync,
33403
- statSync as statSync11,
33958
+ statSync as statSync12,
33404
33959
  unlinkSync as unlinkSync3
33405
33960
  } from "node:fs";
33406
- import { basename as basename3, dirname as dirname10, join as join15, resolve as resolve7 } from "node:path";
33961
+ import { basename as basename3, dirname as dirname11, join as join16, resolve as resolve7 } from "node:path";
33407
33962
  function ensureSecureStorageDir(dir) {
33408
33963
  ensureStorageDirectorySync(dir);
33409
33964
  }
@@ -33424,17 +33979,17 @@ function installBootBusyTimeout(db, dbPath, timeoutMs, report = log) {
33424
33979
  }
33425
33980
  function resolveDatabasePath(dbPathOverride) {
33426
33981
  if (dbPathOverride) {
33427
- return { dbDir: dirname10(dbPathOverride), dbPath: dbPathOverride };
33982
+ return { dbDir: dirname11(dbPathOverride), dbPath: dbPathOverride };
33428
33983
  }
33429
33984
  const dbDir = getMagicContextStorageDir();
33430
- return { dbDir, dbPath: join15(dbDir, "context.db") };
33985
+ return { dbDir, dbPath: join16(dbDir, "context.db") };
33431
33986
  }
33432
33987
  function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
33433
- if (existsSync21(targetDbPath))
33988
+ if (existsSync22(targetDbPath))
33434
33989
  return;
33435
33990
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
33436
- const legacyDbPath = join15(legacyDir, "context.db");
33437
- if (!existsSync21(legacyDbPath))
33991
+ const legacyDbPath = join16(legacyDir, "context.db");
33992
+ if (!existsSync22(legacyDbPath))
33438
33993
  return;
33439
33994
  log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
33440
33995
  ensureSecureStorageDir(targetDbDir);
@@ -33451,8 +34006,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
33451
34006
  }
33452
34007
  for (const suffix of ["", "-wal", "-shm"]) {
33453
34008
  const src = `${legacyDbPath}${suffix}`;
33454
- const dst = join15(targetDbDir, `context.db${suffix}`);
33455
- if (existsSync21(src)) {
34009
+ const dst = join16(targetDbDir, `context.db${suffix}`);
34010
+ if (existsSync22(src)) {
33456
34011
  try {
33457
34012
  copyStorageFileSync(src, dst);
33458
34013
  } catch (error) {
@@ -33460,9 +34015,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
33460
34015
  }
33461
34016
  }
33462
34017
  }
33463
- const legacyModelsDir = join15(legacyDir, "models");
33464
- const targetModelsDir = join15(targetDbDir, "models");
33465
- if (existsSync21(legacyModelsDir) && !existsSync21(targetModelsDir)) {
34018
+ const legacyModelsDir = join16(legacyDir, "models");
34019
+ const targetModelsDir = join16(targetDbDir, "models");
34020
+ if (existsSync22(legacyModelsDir) && !existsSync22(targetModelsDir)) {
33466
34021
  try {
33467
34022
  copyStorageTreeSync(legacyModelsDir, targetModelsDir);
33468
34023
  } catch (error) {
@@ -33570,7 +34125,7 @@ function classifyJunkDiscovery(portFile, raw, staleFiles) {
33570
34125
  function inspectRpcServerDiscovery(storageDir, processes, options) {
33571
34126
  const deadline = options?.deadlineMs === undefined ? Number.POSITIVE_INFINITY : Date.now() + options.deadlineMs;
33572
34127
  let progressAt = Date.now() + 3000;
33573
- const rpcRoot = join15(storageDir, "rpc");
34128
+ const rpcRoot = join16(storageDir, "rpc");
33574
34129
  let projectEntries;
33575
34130
  try {
33576
34131
  projectEntries = rpcDiscoveryFs.readdirSync(rpcRoot, { withFileTypes: true });
@@ -33584,7 +34139,7 @@ function inspectRpcServerDiscovery(storageDir, processes, options) {
33584
34139
  for (const projectEntry of projectEntries) {
33585
34140
  if (!projectEntry.isDirectory())
33586
34141
  continue;
33587
- const projectDir = join15(rpcRoot, projectEntry.name);
34142
+ const projectDir = join16(rpcRoot, projectEntry.name);
33588
34143
  let entries;
33589
34144
  try {
33590
34145
  entries = rpcDiscoveryFs.readdirSync(projectDir);
@@ -33595,7 +34150,7 @@ function inspectRpcServerDiscovery(storageDir, processes, options) {
33595
34150
  }
33596
34151
  for (const entry of entries) {
33597
34152
  if (entry === "port" || entry.startsWith("port-") && entry.endsWith(".json")) {
33598
- portFiles.push(join15(projectDir, entry));
34153
+ portFiles.push(join16(projectDir, entry));
33599
34154
  }
33600
34155
  }
33601
34156
  }
@@ -33698,7 +34253,7 @@ function inspectRpcServerDiscovery(storageDir, processes, options) {
33698
34253
  return { state: "stale", serverPids: [], staleFiles };
33699
34254
  }
33700
34255
  function pruneEmptyRpcDiscoveryDirs(storageDir) {
33701
- const rpcRoot = join15(storageDir, "rpc");
34256
+ const rpcRoot = join16(storageDir, "rpc");
33702
34257
  let entries;
33703
34258
  try {
33704
34259
  entries = rpcDiscoveryFs.readdirSync(rpcRoot, { withFileTypes: true });
@@ -33710,7 +34265,7 @@ function pruneEmptyRpcDiscoveryDirs(storageDir) {
33710
34265
  for (const entry of entries) {
33711
34266
  if (!entry.isDirectory())
33712
34267
  continue;
33713
- const projectDir = join15(rpcRoot, entry.name);
34268
+ const projectDir = join16(rpcRoot, entry.name);
33714
34269
  try {
33715
34270
  if (rpcDiscoveryFs.readdirSync(projectDir).length > 0)
33716
34271
  continue;
@@ -33724,12 +34279,12 @@ function pruneEmptyRpcDiscoveryDirs(storageDir) {
33724
34279
  return removed;
33725
34280
  }
33726
34281
  function removeRpcDiscoveryRecords(storageDir, files) {
33727
- const rpcRoot = resolve7(join15(storageDir, "rpc"));
34282
+ const rpcRoot = resolve7(join16(storageDir, "rpc"));
33728
34283
  const removed = [];
33729
34284
  const failed = [];
33730
34285
  for (const file of files) {
33731
- const projectDir = dirname10(resolve7(file));
33732
- if (dirname10(projectDir) !== rpcRoot || !basename3(file).startsWith("port")) {
34286
+ const projectDir = dirname11(resolve7(file));
34287
+ if (dirname11(projectDir) !== rpcRoot || !basename3(file).startsWith("port")) {
33733
34288
  failed.push({ file, error: "not an RPC discovery record" });
33734
34289
  continue;
33735
34290
  }
@@ -33776,7 +34331,7 @@ function isDefaultSharedDatabasePath(dbPath) {
33776
34331
  if (!process.env.XDG_DATA_HOME && (process.env.MAGIC_CONTEXT_TEST_DATA_DIR || false)) {
33777
34332
  return false;
33778
34333
  }
33779
- return resolve7(dbPath) === resolve7(join15(getMagicContextStorageDir(), "context.db"));
34334
+ return resolve7(dbPath) === resolve7(join16(getMagicContextStorageDir(), "context.db"));
33780
34335
  }
33781
34336
  function migrationBlockingPiPids(dbPath, discovery, discoveredPiPids) {
33782
34337
  if (isDefaultSharedDatabasePath(dbPath))
@@ -33886,7 +34441,7 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
33886
34441
  }
33887
34442
  setDatabase(db);
33888
34443
  loadToolDefinitionMeasurements(db);
33889
- tightenStorageTree(dirname10(dbPath));
34444
+ tightenStorageTree(dirname11(dbPath));
33890
34445
  databases.set(dbPath, db);
33891
34446
  pathByDatabase.set(db, dbPath);
33892
34447
  persistenceByDatabase.set(db, true);
@@ -35181,7 +35736,7 @@ function openDatabase(dbPathOrOptions) {
35181
35736
  }
35182
35737
  ensureSecureStorageDir(dbDir);
35183
35738
  tightenStorageTree(dbDir);
35184
- if (!existsSync21(dbPath) && shouldEnforcePrivateStoragePermissions()) {
35739
+ if (!existsSync22(dbPath) && shouldEnforcePrivateStoragePermissions()) {
35185
35740
  try {
35186
35741
  writeStorageFileSync(dbPath, new Uint8Array, { flag: "wx" });
35187
35742
  } catch (error) {
@@ -35267,8 +35822,8 @@ var init_storage_db = __esm(async () => {
35267
35822
  RPC_DISCOVERY_PARSE_GRACE_MS = 10 * 60 * 1000;
35268
35823
  defaultRpcDiscoveryFs = {
35269
35824
  readdirSync: (path, options) => options?.withFileTypes ? readdirSync5(path, { withFileTypes: true }) : readdirSync5(path),
35270
- readFileSync: (path, encoding) => String(readFileSync14(path, encoding)),
35271
- statSync: (path) => ({ mtimeMs: statSync11(path).mtimeMs }),
35825
+ readFileSync: (path, encoding) => String(readFileSync15(path, encoding)),
35826
+ statSync: (path) => ({ mtimeMs: statSync12(path).mtimeMs }),
35272
35827
  unlinkSync: (path) => unlinkSync3(path),
35273
35828
  rmdirSync: (path) => rmdirSync(path)
35274
35829
  };
@@ -35282,14 +35837,14 @@ var init_storage_db = __esm(async () => {
35282
35837
  });
35283
35838
 
35284
35839
  // src/lib/database-access.ts
35285
- import { existsSync as existsSync22, rmSync as rmSync5 } from "node:fs";
35286
- import { dirname as dirname11 } from "node:path";
35840
+ import { existsSync as existsSync23, rmSync as rmSync6 } from "node:fs";
35841
+ import { dirname as dirname12 } from "node:path";
35287
35842
  import { pathToFileURL } from "node:url";
35288
35843
  function getPersistedSchemaVersion2(db) {
35289
35844
  return getPersistedSchemaVersion(db);
35290
35845
  }
35291
35846
  function openExistingDatabase(path, options) {
35292
- if (!existsSync22(path))
35847
+ if (!existsSync23(path))
35293
35848
  return null;
35294
35849
  if (options.readonly) {
35295
35850
  const db = new Database(path, { readonly: true });
@@ -35338,7 +35893,7 @@ function openExistingContextDatabaseForMutation(path) {
35338
35893
  async function backupDatabaseSnapshot(db, sourcePath, destination) {
35339
35894
  const serializable = db;
35340
35895
  if (typeof serializable.serialize === "function") {
35341
- ensureStorageDirectorySync(dirname11(destination));
35896
+ ensureStorageDirectorySync(dirname12(destination));
35342
35897
  writeStorageFileSync(destination, serializable.serialize(), { flag: "wx" });
35343
35898
  return;
35344
35899
  }
@@ -35347,7 +35902,7 @@ async function backupDatabaseSnapshot(db, sourcePath, destination) {
35347
35902
  if (typeof sqlite.backup !== "function") {
35348
35903
  throw new Error("The active SQLite runtime does not provide a snapshot backup API");
35349
35904
  }
35350
- if (existsSync22(destination)) {
35905
+ if (existsSync23(destination)) {
35351
35906
  throw new Error(`Refusing to overwrite existing backup ${destination}`);
35352
35907
  }
35353
35908
  const reader = new Database(sourcePath, { readonly: true });
@@ -35355,7 +35910,7 @@ async function backupDatabaseSnapshot(db, sourcePath, destination) {
35355
35910
  try {
35356
35911
  await sqlite.backup(reader, destination);
35357
35912
  } catch (error) {
35358
- rmSync5(destination, { force: true });
35913
+ rmSync6(destination, { force: true });
35359
35914
  throw error;
35360
35915
  } finally {
35361
35916
  reader.close();
@@ -35633,11 +36188,11 @@ var init_dreamer_setup = __esm(() => {
35633
36188
  });
35634
36189
 
35635
36190
  // src/commands/setup-pi.ts
35636
- import { existsSync as existsSync23, mkdirSync as mkdirSync4 } from "node:fs";
35637
- import { dirname as dirname12 } from "node:path";
36191
+ import { existsSync as existsSync24, mkdirSync as mkdirSync5 } from "node:fs";
36192
+ import { dirname as dirname13 } from "node:path";
35638
36193
  function ensureDir4(path) {
35639
- if (!existsSync23(path))
35640
- mkdirSync4(path, { recursive: true });
36194
+ if (!existsSync24(path))
36195
+ mkdirSync5(path, { recursive: true });
35641
36196
  }
35642
36197
  async function getDefaultPrompts() {
35643
36198
  await Promise.resolve().then(() => init_prompts());
@@ -35669,7 +36224,7 @@ function comparePiVersion(a, b) {
35669
36224
  }
35670
36225
  function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE) {
35671
36226
  const settings = readJsoncConfigForUpdate(settingsPath);
35672
- ensureDir4(dirname12(settingsPath));
36227
+ ensureDir4(dirname13(settingsPath));
35673
36228
  if (settings.packages !== undefined && !Array.isArray(settings.packages)) {
35674
36229
  throw new Error(`Refusing to rewrite ${settingsPath}: "packages" is ${typeof settings.packages}, expected an array. Fix it by hand, then rerun setup.`);
35675
36230
  }
@@ -35700,7 +36255,7 @@ function removePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE
35700
36255
  }
35701
36256
  function writeMagicContextConfig(configPath, options) {
35702
36257
  const config = readMagicContextConfigForSetup(configPath);
35703
- ensureDir4(dirname12(configPath));
36258
+ ensureDir4(dirname13(configPath));
35704
36259
  if (!config.$schema) {
35705
36260
  config.$schema = "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json";
35706
36261
  }
@@ -36091,16 +36646,16 @@ var init_setup_omp = __esm(() => {
36091
36646
  });
36092
36647
 
36093
36648
  // ../plugin/src/shared/opencode-config-dir.ts
36094
- import { homedir as homedir12 } from "node:os";
36095
- import { join as join16, resolve as resolve8 } from "node:path";
36649
+ import { homedir as homedir13 } from "node:os";
36650
+ import { join as join17, resolve as resolve8 } from "node:path";
36096
36651
  function resolveHomeDir() {
36097
- return process.env.HOME?.trim() || homedir12();
36652
+ return process.env.HOME?.trim() || homedir13();
36098
36653
  }
36099
36654
  function getOpenCodeGlobalConfigDir() {
36100
36655
  if (process.platform === "win32") {
36101
- return join16(resolveHomeDir(), ".config", "opencode");
36656
+ return join17(resolveHomeDir(), ".config", "opencode");
36102
36657
  }
36103
- return join16(process.env.XDG_CONFIG_HOME || join16(resolveHomeDir(), ".config"), "opencode");
36658
+ return join17(process.env.XDG_CONFIG_HOME || join17(resolveHomeDir(), ".config"), "opencode");
36104
36659
  }
36105
36660
  function getEnvConfigDir() {
36106
36661
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
@@ -36116,14 +36671,14 @@ function getOpenCodeConfigPaths(options) {
36116
36671
  const configDir = getOpenCodeConfigDir2(options);
36117
36672
  return {
36118
36673
  configDir,
36119
- configJson: join16(configDir, "opencode.json"),
36120
- configJsonc: join16(configDir, "opencode.jsonc"),
36121
- packageJson: join16(configDir, "package.json"),
36122
- omoConfig: join16(configDir, "magic-context.jsonc")
36674
+ configJson: join17(configDir, "opencode.json"),
36675
+ configJsonc: join17(configDir, "opencode.jsonc"),
36676
+ packageJson: join17(configDir, "package.json"),
36677
+ omoConfig: join17(configDir, "magic-context.jsonc")
36123
36678
  };
36124
36679
  }
36125
36680
  function getOpenCodeConfigDirs() {
36126
- const dirs = [getOpenCodeGlobalConfigDir(), join16(resolveHomeDir(), ".opencode")];
36681
+ const dirs = [getOpenCodeGlobalConfigDir(), join17(resolveHomeDir(), ".opencode")];
36127
36682
  const envDir = getEnvConfigDir();
36128
36683
  if (envDir)
36129
36684
  dirs.push(envDir);
@@ -36132,8 +36687,8 @@ function getOpenCodeConfigDirs() {
36132
36687
  var init_opencode_config_dir = () => {};
36133
36688
 
36134
36689
  // ../plugin/src/shared/conflict-detector.ts
36135
- import { homedir as homedir13 } from "node:os";
36136
- import { join as join17 } from "node:path";
36690
+ import { homedir as homedir14 } from "node:os";
36691
+ import { join as join18 } from "node:path";
36137
36692
  function detectConflicts(directory, options) {
36138
36693
  const compactionEnabled = options?.compactionEnabled ?? true;
36139
36694
  const hostGeneration = options?.hostGeneration ?? "v1";
@@ -36200,19 +36755,19 @@ function checkCompaction(directory, hostGeneration) {
36200
36755
  function openCodeConfigFileChain(directory, hostGeneration) {
36201
36756
  const globalDir = getOpenCodeGlobalConfigDir();
36202
36757
  const wellKnown = [
36203
- join17(globalDir, "config.json"),
36204
- join17(globalDir, "opencode.json"),
36205
- join17(globalDir, "opencode.jsonc")
36758
+ join18(globalDir, "config.json"),
36759
+ join18(globalDir, "opencode.json"),
36760
+ join18(globalDir, "opencode.jsonc")
36206
36761
  ];
36207
- const globalSupplementary = getOpenCodeConfigDirs().filter((dir) => dir !== globalDir).flatMap((dir) => [join17(dir, "opencode.json"), join17(dir, "opencode.jsonc")]);
36762
+ const globalSupplementary = getOpenCodeConfigDirs().filter((dir) => dir !== globalDir).flatMap((dir) => [join18(dir, "opencode.json"), join18(dir, "opencode.jsonc")]);
36208
36763
  const explicitConfig = process.env.OPENCODE_CONFIG?.trim();
36209
36764
  const explicit = explicitConfig ? [explicitConfig] : [];
36210
36765
  const disableProjectConfig = process.env.OPENCODE_DISABLE_PROJECT_CONFIG?.toLowerCase();
36211
36766
  const skipProject = hostGeneration === "v1" && (disableProjectConfig === "true" || disableProjectConfig === "1");
36212
- const direct = skipProject ? [] : [join17(directory, "opencode.json"), join17(directory, "opencode.jsonc")];
36767
+ const direct = skipProject ? [] : [join18(directory, "opencode.json"), join18(directory, "opencode.jsonc")];
36213
36768
  const projectSupplementary = skipProject ? [] : [
36214
- join17(directory, ".opencode", "opencode.json"),
36215
- join17(directory, ".opencode", "opencode.jsonc")
36769
+ join18(directory, ".opencode", "opencode.json"),
36770
+ join18(directory, ".opencode", "opencode.jsonc")
36216
36771
  ];
36217
36772
  const files = hostGeneration === "v2" ? [
36218
36773
  ...wellKnown,
@@ -36299,10 +36854,10 @@ function collectPluginEntries(directory) {
36299
36854
  }
36300
36855
  };
36301
36856
  for (const configPath of [
36302
- join17(directory, ".opencode", "opencode.jsonc"),
36303
- join17(directory, ".opencode", "opencode.json"),
36304
- join17(directory, "opencode.jsonc"),
36305
- join17(directory, "opencode.json")
36857
+ join18(directory, ".opencode", "opencode.jsonc"),
36858
+ join18(directory, ".opencode", "opencode.json"),
36859
+ join18(directory, "opencode.jsonc"),
36860
+ join18(directory, "opencode.json")
36306
36861
  ]) {
36307
36862
  const config = readJsoncFile(configPath);
36308
36863
  pushFrom(config?.plugin);
@@ -36312,7 +36867,7 @@ function collectPluginEntries(directory) {
36312
36867
  for (const dir of getOpenCodeConfigDirs()) {
36313
36868
  const names = dir === globalDir ? ["config.json", "opencode.json", "opencode.jsonc"] : ["opencode.json", "opencode.jsonc"];
36314
36869
  for (const name of names) {
36315
- const config = readJsoncFile(join17(dir, name));
36870
+ const config = readJsoncFile(join18(dir, name));
36316
36871
  pushFrom(config?.plugin);
36317
36872
  }
36318
36873
  }
@@ -36346,7 +36901,7 @@ function readOmoDisabledHooks(directory) {
36346
36901
  try {
36347
36902
  for (const dir of getOpenCodeConfigDirs()) {
36348
36903
  for (const name of configNames) {
36349
- const config = readJsoncFile(join17(dir, name));
36904
+ const config = readJsoncFile(join18(dir, name));
36350
36905
  if (config?.disabled_hooks) {
36351
36906
  for (const hook of config.disabled_hooks) {
36352
36907
  disabled.add(hook);
@@ -36356,17 +36911,17 @@ function readOmoDisabledHooks(directory) {
36356
36911
  }
36357
36912
  } catch {}
36358
36913
  for (const name of configNames) {
36359
- const config = readJsoncFile(join17(directory, name));
36914
+ const config = readJsoncFile(join18(directory, name));
36360
36915
  if (config?.disabled_hooks) {
36361
36916
  for (const hook of config.disabled_hooks) {
36362
36917
  disabled.add(hook);
36363
36918
  }
36364
36919
  }
36365
36920
  }
36366
- const homeDir = process.env.HOME || homedir13();
36367
- const omoHomeDir = join17(homeDir, ".omo");
36921
+ const homeDir = process.env.HOME || homedir14();
36922
+ const omoHomeDir = join18(homeDir, ".omo");
36368
36923
  for (const name of ["omo.jsonc", "omo.json"]) {
36369
- const config = readJsoncFile(join17(omoHomeDir, name));
36924
+ const config = readJsoncFile(join18(omoHomeDir, name));
36370
36925
  if (config?.["[opencode]"]?.disabled_hooks) {
36371
36926
  for (const hook of config["[opencode]"].disabled_hooks) {
36372
36927
  disabled.add(hook);
@@ -36374,7 +36929,7 @@ function readOmoDisabledHooks(directory) {
36374
36929
  }
36375
36930
  }
36376
36931
  for (const name of ["omo.jsonc", "omo.json"]) {
36377
- const config = readJsoncFile(join17(directory, ".omo", name));
36932
+ const config = readJsoncFile(join18(directory, ".omo", name));
36378
36933
  if (config?.["[opencode]"]?.disabled_hooks) {
36379
36934
  for (const hook of config["[opencode]"].disabled_hooks) {
36380
36935
  disabled.add(hook);
@@ -36393,9 +36948,9 @@ var init_conflict_detector = __esm(() => {
36393
36948
  });
36394
36949
 
36395
36950
  // ../plugin/src/shared/conflict-fixer.ts
36396
- import { existsSync as existsSync24, readFileSync as readFileSync15, writeFileSync as writeFileSync4 } from "node:fs";
36397
- import { homedir as homedir14 } from "node:os";
36398
- import { join as join18 } from "node:path";
36951
+ import { existsSync as existsSync25, readFileSync as readFileSync16, writeFileSync as writeFileSync5 } from "node:fs";
36952
+ import { homedir as homedir15 } from "node:os";
36953
+ import { join as join19 } from "node:path";
36399
36954
  function isRecord3(value) {
36400
36955
  return typeof value === "object" && value !== null && !Array.isArray(value);
36401
36956
  }
@@ -36403,11 +36958,11 @@ function asStringArray(value) {
36403
36958
  return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
36404
36959
  }
36405
36960
  function readConfig(filePath) {
36406
- if (!existsSync24(filePath)) {
36961
+ if (!existsSync25(filePath)) {
36407
36962
  return null;
36408
36963
  }
36409
36964
  try {
36410
- const text = readFileSync15(filePath, "utf-8");
36965
+ const text = readFileSync16(filePath, "utf-8");
36411
36966
  const parsed = import_comment_json5.parse(text);
36412
36967
  return isRecord3(parsed) ? { config: parsed, text } : null;
36413
36968
  } catch {
@@ -36415,27 +36970,27 @@ function readConfig(filePath) {
36415
36970
  }
36416
36971
  }
36417
36972
  function writeConfig(filePath, text) {
36418
- writeFileSync4(filePath, text);
36973
+ writeFileSync5(filePath, text);
36419
36974
  }
36420
36975
  function resolveUserOpenCodeConfigPath() {
36421
36976
  const paths = getOpenCodeConfigPaths({ binary: "opencode" });
36422
- if (existsSync24(paths.configJsonc))
36977
+ if (existsSync25(paths.configJsonc))
36423
36978
  return paths.configJsonc;
36424
36979
  return paths.configJson;
36425
36980
  }
36426
36981
  function collectOpenCodeConfigPaths(directory) {
36427
36982
  const paths = new Set;
36428
36983
  const userConfig = resolveUserOpenCodeConfigPath();
36429
- if (existsSync24(userConfig)) {
36984
+ if (existsSync25(userConfig)) {
36430
36985
  paths.add(userConfig);
36431
36986
  }
36432
36987
  for (const filePath of [
36433
- join18(directory, ".opencode", "opencode.jsonc"),
36434
- join18(directory, ".opencode", "opencode.json"),
36435
- join18(directory, "opencode.jsonc"),
36436
- join18(directory, "opencode.json")
36988
+ join19(directory, ".opencode", "opencode.jsonc"),
36989
+ join19(directory, ".opencode", "opencode.json"),
36990
+ join19(directory, "opencode.jsonc"),
36991
+ join19(directory, "opencode.json")
36437
36992
  ]) {
36438
- if (existsSync24(filePath)) {
36993
+ if (existsSync25(filePath)) {
36439
36994
  paths.add(filePath);
36440
36995
  }
36441
36996
  }
@@ -36445,26 +37000,26 @@ function collectOmoConfigPaths(directory) {
36445
37000
  const paths = new Set;
36446
37001
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
36447
37002
  for (const fileName of OMO_CONFIG_NAMES) {
36448
- const userPath = join18(configDir, fileName);
36449
- const projectPath = join18(directory, fileName);
36450
- if (existsSync24(userPath)) {
37003
+ const userPath = join19(configDir, fileName);
37004
+ const projectPath = join19(directory, fileName);
37005
+ if (existsSync25(userPath)) {
36451
37006
  paths.add(userPath);
36452
37007
  }
36453
- if (existsSync24(projectPath)) {
37008
+ if (existsSync25(projectPath)) {
36454
37009
  paths.add(projectPath);
36455
37010
  }
36456
37011
  }
36457
- const homeDir = process.env.HOME || homedir14();
36458
- const omoHomeDir = join18(homeDir, ".omo");
37012
+ const homeDir = process.env.HOME || homedir15();
37013
+ const omoHomeDir = join19(homeDir, ".omo");
36459
37014
  for (const name of OMO_UNIFIED_NAMES) {
36460
- const userPath = join18(omoHomeDir, name);
36461
- if (existsSync24(userPath)) {
37015
+ const userPath = join19(omoHomeDir, name);
37016
+ if (existsSync25(userPath)) {
36462
37017
  paths.add(userPath);
36463
37018
  }
36464
37019
  }
36465
37020
  for (const name of OMO_UNIFIED_NAMES) {
36466
- const projectPath = join18(directory, ".omo", name);
36467
- if (existsSync24(projectPath)) {
37021
+ const projectPath = join19(directory, ".omo", name);
37022
+ if (existsSync25(projectPath)) {
36468
37023
  paths.add(projectPath);
36469
37024
  }
36470
37025
  }
@@ -36592,8 +37147,8 @@ var init_conflict_fixer = __esm(() => {
36592
37147
  });
36593
37148
 
36594
37149
  // src/commands/setup-opencode.ts
36595
- import { existsSync as existsSync25 } from "node:fs";
36596
- import { basename as basename4, dirname as dirname13 } from "node:path";
37150
+ import { existsSync as existsSync26 } from "node:fs";
37151
+ import { basename as basename4, dirname as dirname14 } from "node:path";
36597
37152
  function resolveCompactionEnabledForWriter() {
36598
37153
  try {
36599
37154
  const config = loadPluginConfig(process.cwd());
@@ -36608,7 +37163,7 @@ function isPlainObject5(value) {
36608
37163
  }
36609
37164
  function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabled = true, hostGeneration = "v1") {
36610
37165
  const registrationKey = pluginConfigKeyFor(hostGeneration);
36611
- const existsAtCommit = existsSync25(configPath);
37166
+ const existsAtCommit = existsSync26(configPath);
36612
37167
  const existing = existsAtCommit ? readJsoncConfigForUpdate(configPath) : {};
36613
37168
  if (!existsAtCommit) {
36614
37169
  const created = { [registrationKey]: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION] };
@@ -36623,7 +37178,7 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
36623
37178
  let changed = false;
36624
37179
  const rawPlugins = readPluginEntries(existing).map(({ entry }) => entry);
36625
37180
  const retainedPlugins = removeDcp ? rawPlugins.filter((plugin) => !matchesPluginEntry(plugin, DCP_PLUGIN_NAME)) : rawPlugins;
36626
- if (retainedPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname13(configPath)))) {
37181
+ if (retainedPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname14(configPath)))) {
36627
37182
  log3.warn("An unverifiable local OpenCode plugin path was ignored; its package name is not Magic Context.");
36628
37183
  }
36629
37184
  if (removeDcp) {
@@ -36638,7 +37193,7 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
36638
37193
  }
36639
37194
  }
36640
37195
  const hasNpmEntry = retainedPlugins.some((plugin) => matchesPluginEntry(plugin, OPENCODE_PLUGIN_NAME));
36641
- const hasDevEntry = retainedPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname13(configPath)));
37196
+ const hasDevEntry = retainedPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname14(configPath)));
36642
37197
  if (!hasNpmEntry && !hasDevEntry) {
36643
37198
  text = Array.isArray(existing[registrationKey]) ? appendJsoncArrayValues(text, [registrationKey], [OPENCODE_PLUGIN_ENTRY_WITH_VERSION]) : setJsoncValue(text, [registrationKey], [OPENCODE_PLUGIN_ENTRY_WITH_VERSION]);
36644
37199
  changed = true;
@@ -36664,18 +37219,18 @@ function planOpenCodeConfigUpdate(configPath, removeDcp = false, compactionEnabl
36664
37219
  return changed ? document.bom + text : null;
36665
37220
  }
36666
37221
  function planTuiConfigUpdate(configPath) {
36667
- const existsAtCommit = existsSync25(configPath);
37222
+ const existsAtCommit = existsSync26(configPath);
36668
37223
  const existing = existsAtCommit ? readJsoncConfigForUpdate(configPath) : {};
36669
37224
  if (!existsAtCommit) {
36670
37225
  return `${import_comment_json6.stringify({ plugin: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION] }, null, 2)}
36671
37226
  `;
36672
37227
  }
36673
37228
  const rawPlugins = Array.isArray(existing.plugin) ? existing.plugin : [];
36674
- if (rawPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname13(configPath)))) {
37229
+ if (rawPlugins.some((plugin) => isLocalPathPluginEntry(plugin) && String(plugin).includes("magic-context") && !isDevPathPluginEntry(plugin, dirname14(configPath)))) {
36675
37230
  log3.warn("An unverifiable local TUI plugin path was ignored; its package name is not Magic Context.");
36676
37231
  }
36677
37232
  const hasNpmEntry = rawPlugins.some((plugin) => matchesPluginEntry(plugin, OPENCODE_PLUGIN_NAME));
36678
- const hasDevEntry = rawPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname13(configPath)));
37233
+ const hasDevEntry = rawPlugins.some((plugin) => isDevPathPluginEntry(plugin, dirname14(configPath)));
36679
37234
  if (hasNpmEntry || hasDevEntry)
36680
37235
  return null;
36681
37236
  const document = readJsoncTextForEdit(configPath);
@@ -36791,7 +37346,7 @@ async function runSetup3(dryRun = false) {
36791
37346
  log3.warn("You can configure models manually in magic-context.jsonc later");
36792
37347
  }
36793
37348
  const paths = detectConfigPaths();
36794
- const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync25(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
37349
+ const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync26(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
36795
37350
  if (!dryRun) {
36796
37351
  try {
36797
37352
  assertJsoncConfigsParseable([
@@ -37031,6 +37586,8 @@ async function runSetup4(argv) {
37031
37586
  outro2("Setup finished with warnings — see above.");
37032
37587
  return 1;
37033
37588
  }
37589
+ if (!dryRun)
37590
+ await offerDashboardInstall(argv);
37034
37591
  outro2(dryRun ? "Dry run done — no changes were made." : "Done.");
37035
37592
  return 0;
37036
37593
  }
@@ -37069,6 +37626,7 @@ function printNextSteps(adapter) {
37069
37626
  }
37070
37627
  }
37071
37628
  var init_setup = __esm(async () => {
37629
+ init_dashboard_install();
37072
37630
  init_docs_proposal_gitignore();
37073
37631
  init_prompts();
37074
37632
  init_setup_omp();
@@ -37080,26 +37638,55 @@ var init_setup = __esm(async () => {
37080
37638
  ]);
37081
37639
  });
37082
37640
 
37641
+ // src/lib/disk-space.ts
37642
+ import { existsSync as existsSync27, statfsSync, statSync as statSync13 } from "node:fs";
37643
+ import { dirname as dirname15, resolve as resolve9 } from "node:path";
37644
+ function availableDiskBytes(path) {
37645
+ const filesystem = statfsSync(path);
37646
+ return filesystem.bavail * filesystem.bsize;
37647
+ }
37648
+ function checkDiskSpace(path, bytes, freeBytes) {
37649
+ const requiredBytes = Math.ceil(bytes * 1.1);
37650
+ const availableBytes = freeBytes(path);
37651
+ return {
37652
+ requiredBytes,
37653
+ availableBytes,
37654
+ sufficient: availableBytes >= requiredBytes
37655
+ };
37656
+ }
37657
+ function existingDirectoryAncestor(path) {
37658
+ let current = resolve9(path);
37659
+ for (;; ) {
37660
+ if (existsSync27(current) && statSync13(current).isDirectory())
37661
+ return current;
37662
+ const parent = dirname15(current);
37663
+ if (parent === current)
37664
+ throw new Error(`No existing directory for ${path}`);
37665
+ current = parent;
37666
+ }
37667
+ }
37668
+ var init_disk_space = () => {};
37669
+
37083
37670
  // ../plugin/src/hooks/auto-update-checker/constants.ts
37084
- import { homedir as homedir15, platform } from "node:os";
37085
- import { join as join19 } from "node:path";
37671
+ import { homedir as homedir16, platform } from "node:os";
37672
+ import { join as join20 } from "node:path";
37086
37673
  function getOpenCodeCacheRoot() {
37087
37674
  if (platform() === "win32") {
37088
- return join19(process.env.LOCALAPPDATA ?? homedir15(), "opencode");
37675
+ return join20(process.env.LOCALAPPDATA ?? homedir16(), "opencode");
37089
37676
  }
37090
- return join19(homedir15(), ".cache", "opencode");
37677
+ return join20(homedir16(), ".cache", "opencode");
37091
37678
  }
37092
37679
  function getOpenCodeConfigRoot() {
37093
37680
  if (platform() === "win32") {
37094
- return join19(process.env.APPDATA ?? join19(homedir15(), "AppData", "Roaming"), "opencode");
37681
+ return join20(process.env.APPDATA ?? join20(homedir16(), "AppData", "Roaming"), "opencode");
37095
37682
  }
37096
- return join19(process.env.XDG_CONFIG_HOME ?? join19(homedir15(), ".config"), "opencode");
37683
+ return join20(process.env.XDG_CONFIG_HOME ?? join20(homedir16(), ".config"), "opencode");
37097
37684
  }
37098
37685
  var PACKAGE_NAME = "@cortexkit/opencode-magic-context", CACHE_DIR, USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC;
37099
37686
  var init_constants2 = __esm(() => {
37100
- CACHE_DIR = join19(getOpenCodeCacheRoot(), "packages");
37101
- USER_OPENCODE_CONFIG = join19(getOpenCodeConfigRoot(), "opencode.json");
37102
- USER_OPENCODE_CONFIG_JSONC = join19(getOpenCodeConfigRoot(), "opencode.jsonc");
37687
+ CACHE_DIR = join20(getOpenCodeCacheRoot(), "packages");
37688
+ USER_OPENCODE_CONFIG = join20(getOpenCodeConfigRoot(), "opencode.json");
37689
+ USER_OPENCODE_CONFIG_JSONC = join20(getOpenCodeConfigRoot(), "opencode.jsonc");
37103
37690
  });
37104
37691
 
37105
37692
  // ../plugin/src/hooks/auto-update-checker/types.ts
@@ -37122,15 +37709,15 @@ var init_types = __esm(() => {
37122
37709
 
37123
37710
  // ../plugin/src/hooks/auto-update-checker/checker.ts
37124
37711
  import {
37125
- accessSync as accessSync2,
37126
- existsSync as existsSync26,
37712
+ accessSync as accessSync3,
37713
+ existsSync as existsSync28,
37127
37714
  constants as fsConstants,
37128
- readFileSync as readFileSync16,
37129
- renameSync as renameSync4,
37130
- statSync as statSync12,
37131
- writeFileSync as writeFileSync5
37715
+ readFileSync as readFileSync17,
37716
+ renameSync as renameSync5,
37717
+ statSync as statSync14,
37718
+ writeFileSync as writeFileSync6
37132
37719
  } from "node:fs";
37133
- import { dirname as dirname14, isAbsolute as isAbsolute7, join as join20, resolve as resolve9 } from "node:path";
37720
+ import { dirname as dirname16, isAbsolute as isAbsolute7, join as join21, resolve as resolve10 } from "node:path";
37134
37721
  function warn(message) {
37135
37722
  log(`WARN: ${message}`);
37136
37723
  }
@@ -37156,17 +37743,17 @@ function parseJsonConfig(content) {
37156
37743
  }
37157
37744
  function getSurfaceConfigPaths(directory, surface) {
37158
37745
  const name = surface === "server" ? "opencode" : "tui";
37159
- const globalDir = dirname14(USER_OPENCODE_CONFIG);
37746
+ const globalDir = dirname16(USER_OPENCODE_CONFIG);
37160
37747
  const dirs = [
37161
37748
  globalDir,
37162
37749
  directory,
37163
- join20(directory, ".opencode"),
37750
+ join21(directory, ".opencode"),
37164
37751
  process.env.OPENCODE_CONFIG_DIR
37165
37752
  ].filter((value) => Boolean(value));
37166
37753
  const paths = [];
37167
37754
  for (const dir of dirs) {
37168
37755
  for (const extension of ["json", "jsonc"]) {
37169
- const path = join20(dir, `${name}.${extension}`);
37756
+ const path = join21(dir, `${name}.${extension}`);
37170
37757
  if (!paths.includes(path))
37171
37758
  paths.push(path);
37172
37759
  }
@@ -37177,9 +37764,9 @@ function getWinningConfig(directory, surface) {
37177
37764
  let winner = null;
37178
37765
  for (const path of getSurfaceConfigPaths(directory, surface)) {
37179
37766
  try {
37180
- if (!existsSync26(path))
37767
+ if (!existsSync28(path))
37181
37768
  continue;
37182
- const parsed = parseJsonConfig(readFileSync16(path, "utf-8"));
37769
+ const parsed = parseJsonConfig(readFileSync17(path, "utf-8"));
37183
37770
  const entries = getPluginEntries(parsed);
37184
37771
  if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
37185
37772
  if (winner) {
@@ -37215,14 +37802,14 @@ var init_checker = __esm(() => {
37215
37802
  });
37216
37803
 
37217
37804
  // src/lib/opencode-plugin-schema-fence.ts
37218
- import { existsSync as existsSync27, readdirSync as readdirSync6, readFileSync as readFileSync17 } from "node:fs";
37219
- import { join as join21 } from "node:path";
37220
- import { gunzipSync } from "node:zlib";
37805
+ import { existsSync as existsSync29, readdirSync as readdirSync6, readFileSync as readFileSync18 } from "node:fs";
37806
+ import { join as join22 } from "node:path";
37807
+ import { gunzipSync as gunzipSync2 } from "node:zlib";
37221
37808
  function readPackageVersion(packageJsonPath) {
37222
37809
  try {
37223
- if (!existsSync27(packageJsonPath))
37810
+ if (!existsSync29(packageJsonPath))
37224
37811
  return null;
37225
- const packageJson = JSON.parse(readFileSync17(packageJsonPath, "utf-8"));
37812
+ const packageJson = JSON.parse(readFileSync18(packageJsonPath, "utf-8"));
37226
37813
  if (packageJson.name !== OPENCODE_PLUGIN_NAME || typeof packageJson.version !== "string") {
37227
37814
  return null;
37228
37815
  }
@@ -37241,8 +37828,8 @@ function readFenceValue(text) {
37241
37828
  return values.size === 1 ? [...values][0] ?? null : null;
37242
37829
  }
37243
37830
  function readFenceFromDist(packageDirectory) {
37244
- const distDirectory = join21(packageDirectory, "dist");
37245
- if (!existsSync27(distDirectory))
37831
+ const distDirectory = join22(packageDirectory, "dist");
37832
+ if (!existsSync29(distDirectory))
37246
37833
  return null;
37247
37834
  const pending = [distDirectory];
37248
37835
  const fenceValues = new Set;
@@ -37252,14 +37839,14 @@ function readFenceFromDist(packageDirectory) {
37252
37839
  continue;
37253
37840
  try {
37254
37841
  for (const entry of readdirSync6(directory, { withFileTypes: true })) {
37255
- const path = join21(directory, entry.name);
37842
+ const path = join22(directory, entry.name);
37256
37843
  if (entry.isDirectory()) {
37257
37844
  pending.push(path);
37258
37845
  continue;
37259
37846
  }
37260
37847
  if (!entry.isFile() || !/\.(?:[cm]?js|ts)$/.test(entry.name))
37261
37848
  continue;
37262
- const fence = readFenceValue(readFileSync17(path, "utf-8"));
37849
+ const fence = readFenceValue(readFileSync18(path, "utf-8"));
37263
37850
  if (fence !== null)
37264
37851
  fenceValues.add(fence);
37265
37852
  }
@@ -37270,20 +37857,20 @@ function readFenceFromDist(packageDirectory) {
37270
37857
  return fenceValues.size === 1 ? [...fenceValues][0] ?? null : null;
37271
37858
  }
37272
37859
  function findInstalledPluginPackage(cacheDirectory, specifier, requestedVersion) {
37273
- const directCacheRoot = join21(cacheDirectory, specifier);
37860
+ const directCacheRoot = join22(cacheDirectory, specifier);
37274
37861
  const candidates = [directCacheRoot];
37275
37862
  try {
37276
37863
  for (const entry of readdirSync6(cacheDirectory, { withFileTypes: true })) {
37277
37864
  if (!entry.isDirectory())
37278
37865
  continue;
37279
- const candidate = join21(cacheDirectory, entry.name);
37866
+ const candidate = join22(cacheDirectory, entry.name);
37280
37867
  if (!candidates.includes(candidate))
37281
37868
  candidates.push(candidate);
37282
37869
  }
37283
37870
  } catch {}
37284
37871
  for (const cacheRoot of candidates) {
37285
- const directory = join21(cacheRoot, "node_modules", ...PACKAGE_PATH_SEGMENTS);
37286
- const version = readPackageVersion(join21(directory, "package.json"));
37872
+ const directory = join22(cacheRoot, "node_modules", ...PACKAGE_PATH_SEGMENTS);
37873
+ const version = readPackageVersion(join22(directory, "package.json"));
37287
37874
  if (!version)
37288
37875
  continue;
37289
37876
  if (cacheRoot === directCacheRoot || EXACT_VERSION_PATTERN.test(requestedVersion) && version === requestedVersion) {
@@ -37309,7 +37896,7 @@ function readTarOctal(bytes, offset, length) {
37309
37896
  function readFenceFromNpmTarball(tarball) {
37310
37897
  let archive;
37311
37898
  try {
37312
- archive = gunzipSync(tarball);
37899
+ archive = gunzipSync2(tarball);
37313
37900
  } catch {
37314
37901
  return null;
37315
37902
  }
@@ -37428,13 +38015,13 @@ var init_opencode_plugin_schema_fence = __esm(() => {
37428
38015
  });
37429
38016
 
37430
38017
  // src/commands/doctor-opencode-cache.ts
37431
- import { existsSync as existsSync28, readFileSync as readFileSync18, rmSync as rmSync6 } from "node:fs";
38018
+ import { existsSync as existsSync30, readFileSync as readFileSync19, rmSync as rmSync7 } from "node:fs";
37432
38019
  function readCachedPluginVersion(pluginCacheDir) {
37433
38020
  try {
37434
38021
  const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
37435
- if (!existsSync28(installedPkgPath))
38022
+ if (!existsSync30(installedPkgPath))
37436
38023
  return;
37437
- const pkg = JSON.parse(readFileSync18(installedPkgPath, "utf-8"));
38024
+ const pkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
37438
38025
  return typeof pkg.version === "string" ? pkg.version : undefined;
37439
38026
  } catch {
37440
38027
  return;
@@ -37459,9 +38046,9 @@ function readOpenCodePluginConfigUse(config, configDir) {
37459
38046
  return use;
37460
38047
  }
37461
38048
  async function clearPluginCache(options = {}, deps = {}) {
37462
- const remove = deps.remove ?? ((path) => rmSync6(path, { recursive: true, force: true }));
38049
+ const remove = deps.remove ?? ((path) => rmSync7(path, { recursive: true, force: true }));
37463
38050
  const pluginCacheRoots = getOpenCodePluginCacheRoots();
37464
- const existingRoots = pluginCacheRoots.filter((root) => existsSync28(root));
38051
+ const existingRoots = pluginCacheRoots.filter((root) => existsSync30(root));
37465
38052
  if (existingRoots.length === 0) {
37466
38053
  return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
37467
38054
  }
@@ -37558,8 +38145,8 @@ var init_doctor_opencode_cache = __esm(async () => {
37558
38145
  });
37559
38146
 
37560
38147
  // src/commands/doctor-cached-plugin-fence.ts
37561
- import { existsSync as existsSync29 } from "node:fs";
37562
- import { dirname as dirname15 } from "node:path";
38148
+ import { existsSync as existsSync31 } from "node:fs";
38149
+ import { dirname as dirname17 } from "node:path";
37563
38150
  function isReferenced(sources, host, spec) {
37564
38151
  const specs = sources.referencedSpecs?.[host];
37565
38152
  return specs === undefined || specs.has(spec);
@@ -37569,13 +38156,13 @@ function listCachedOpenCodePluginFences(sources = {}) {
37569
38156
  const v1Referenced = isReferenced(sources, "opencode1", "latest");
37570
38157
  for (const root of v1Referenced ? sources.openCodeV1Roots ?? getOpenCodePluginCacheRoots() : []) {
37571
38158
  const packageJson = getOpenCodePluginPackageJsonPath(root);
37572
- if (!existsSync29(packageJson))
38159
+ if (!existsSync31(packageJson))
37573
38160
  continue;
37574
38161
  fences.push({
37575
38162
  host: "opencode1",
37576
38163
  directory: root,
37577
38164
  version: readCachedPluginVersion(root),
37578
- supportedVersion: readFenceFromDist(dirname15(packageJson))
38165
+ supportedVersion: readFenceFromDist(dirname17(packageJson))
37579
38166
  });
37580
38167
  }
37581
38168
  for (const slot of listOpenCodeV2PluginCacheSlots(sources.openCodeV2NpmCacheDir)) {
@@ -37591,7 +38178,7 @@ function listCachedOpenCodePluginFences(sources = {}) {
37591
38178
  directory: slot.slot,
37592
38179
  spec: slot.spec,
37593
38180
  version: slot.version,
37594
- supportedVersion: readFenceFromDist(dirname15(getOpenCodePluginPackageJsonPath(generation)))
38181
+ supportedVersion: readFenceFromDist(dirname17(getOpenCodePluginPackageJsonPath(generation)))
37595
38182
  });
37596
38183
  }
37597
38184
  return fences;
@@ -37774,13 +38361,13 @@ var init_doctor_prune_discovery = __esm(async () => {
37774
38361
 
37775
38362
  // src/commands/doctor-storage-holders.ts
37776
38363
  import { execFileSync as execFileSync5 } from "node:child_process";
37777
- import { readFileSync as readFileSync19, realpathSync as realpathSync4 } from "node:fs";
37778
- import { join as join22, resolve as resolve10 } from "node:path";
38364
+ import { readFileSync as readFileSync20, realpathSync as realpathSync4 } from "node:fs";
38365
+ import { join as join23, resolve as resolve11 } from "node:path";
37779
38366
  function canonicalStoragePath(path) {
37780
38367
  try {
37781
38368
  return realpathSync4(path);
37782
38369
  } catch {
37783
- return resolve10(path);
38370
+ return resolve11(path);
37784
38371
  }
37785
38372
  }
37786
38373
  function textReferencesStorage(text, storageDir) {
@@ -37792,7 +38379,7 @@ function textReferencesStorage(text, storageDir) {
37792
38379
  continue;
37793
38380
  if (canonicalStoragePath(value) === target)
37794
38381
  return true;
37795
- if (token.startsWith("XDG_DATA_HOME=") && canonicalStoragePath(join22(value, "cortexkit", "magic-context")) === target)
38382
+ if (token.startsWith("XDG_DATA_HOME=") && canonicalStoragePath(join23(value, "cortexkit", "magic-context")) === target)
37796
38383
  return true;
37797
38384
  }
37798
38385
  return false;
@@ -37802,7 +38389,7 @@ function processReferencesStorage(pid, storageDir) {
37802
38389
  if (process.platform === "linux") {
37803
38390
  for (const name of ["cmdline", "environ"]) {
37804
38391
  try {
37805
- texts.push(readFileSync19(`/proc/${pid}/${name}`, "utf8"));
38392
+ texts.push(readFileSync20(`/proc/${pid}/${name}`, "utf8"));
37806
38393
  } catch {}
37807
38394
  }
37808
38395
  } else {
@@ -37824,12 +38411,12 @@ var init_doctor_storage_holders = () => {};
37824
38411
 
37825
38412
  // src/commands/doctor-repair-db.ts
37826
38413
  import { spawnSync as spawnSync4 } from "node:child_process";
37827
- import { closeSync as closeSync4, existsSync as existsSync30, openSync as openSync4, renameSync as renameSync5, rmSync as rmSync7 } from "node:fs";
37828
- import { homedir as homedir16 } from "node:os";
37829
- import { dirname as dirname16, join as join23 } from "node:path";
38414
+ import { closeSync as closeSync4, existsSync as existsSync32, openSync as openSync4, renameSync as renameSync6, rmSync as rmSync8, statSync as statSync15 } from "node:fs";
38415
+ import { homedir as homedir17 } from "node:os";
38416
+ import { dirname as dirname18, join as join24 } from "node:path";
37830
38417
  function defaultInspectHolders(storageDir, overrides = {}) {
37831
38418
  const deps = {
37832
- defaultStorageDir: join23(homedir16(), ".local", "share", "cortexkit", "magic-context"),
38419
+ defaultStorageDir: join24(homedir17(), ".local", "share", "cortexkit", "magic-context"),
37833
38420
  inspectRpc: inspectRpcServerDiscovery,
37834
38421
  inspectPi: inspectLivePiProcesses,
37835
38422
  probeFiles: probeHostProcessesUsing,
@@ -37846,7 +38433,7 @@ function defaultInspectHolders(storageDir, overrides = {}) {
37846
38433
  return {
37847
38434
  safe: false,
37848
38435
  blockers: [],
37849
- uncertainty: `RPC discovery ${rpc.unreadableFile ?? join23(storageDir, "rpc")} ${arm}`
38436
+ uncertainty: `RPC discovery ${rpc.unreadableFile ?? join24(storageDir, "rpc")} ${arm}`
37850
38437
  };
37851
38438
  }
37852
38439
  const blockers = rpc.state === "live" ? rpc.serverPids.map((pid) => `OpenCode server (PID ${pid})`) : [];
@@ -37859,7 +38446,7 @@ function defaultInspectHolders(storageDir, overrides = {}) {
37859
38446
  const pi = overrides.inspectPi ? deps.inspectPi() : processes?.pi ?? deps.inspectPi();
37860
38447
  if (canonicalStoragePath(storageDir) !== canonicalStoragePath(deps.defaultStorageDir)) {
37861
38448
  const holders = deps.probeFiles({
37862
- files: ["context.db", "store.db"].flatMap((name) => DATABASE_SUFFIXES.map((suffix) => join23(storageDir, `${name}${suffix}`))),
38449
+ files: ["context.db", "store.db"].flatMap((name) => DATABASE_SUFFIXES.map((suffix) => join24(storageDir, `${name}${suffix}`))),
37863
38450
  directories: []
37864
38451
  });
37865
38452
  if (holders.status === "unknown") {
@@ -37892,11 +38479,11 @@ function timestamp(date) {
37892
38479
  return date.toISOString().replaceAll("-", "").replaceAll(":", "").replace(".", "");
37893
38480
  }
37894
38481
  function uniqueBase(preferred) {
37895
- if (!DATABASE_SUFFIXES.some((suffix) => existsSync30(`${preferred}${suffix}`)))
38482
+ if (!DATABASE_SUFFIXES.some((suffix) => existsSync32(`${preferred}${suffix}`)))
37896
38483
  return preferred;
37897
38484
  for (let attempt = 1;attempt < 1e4; attempt++) {
37898
38485
  const candidate = `${preferred}-${attempt}`;
37899
- if (!DATABASE_SUFFIXES.some((suffix) => existsSync30(`${candidate}${suffix}`)))
38486
+ if (!DATABASE_SUFFIXES.some((suffix) => existsSync32(`${candidate}${suffix}`)))
37900
38487
  return candidate;
37901
38488
  }
37902
38489
  throw new Error(`Could not allocate a unique recovery path beside ${preferred}`);
@@ -37906,14 +38493,23 @@ function copyBackupBundle(dbPath, stamp) {
37906
38493
  const copiedPaths = copyDatabaseBundle(dbPath, basePath);
37907
38494
  return { basePath, copiedPaths };
37908
38495
  }
37909
- function copyDatabaseBundle(sourceBase, destinationBase) {
38496
+ function databaseBundleSizeBytes(sourceBase) {
38497
+ let size = 0;
38498
+ for (const suffix of DATABASE_SUFFIXES) {
38499
+ const source = `${sourceBase}${suffix}`;
38500
+ if (existsSync32(source))
38501
+ size += statSync15(source).size;
38502
+ }
38503
+ return size;
38504
+ }
38505
+ function copyDatabaseBundle(sourceBase, destinationBase, forcePrivate = false) {
37910
38506
  const copiedPaths = [];
37911
38507
  for (const suffix of DATABASE_SUFFIXES) {
37912
38508
  const source = `${sourceBase}${suffix}`;
37913
- if (!existsSync30(source))
38509
+ if (!existsSync32(source))
37914
38510
  continue;
37915
38511
  const destination = `${destinationBase}${suffix}`;
37916
- copyStorageFileSync(source, destination);
38512
+ copyStorageFileSync(source, destination, forcePrivate);
37917
38513
  copiedPaths.push(destination);
37918
38514
  }
37919
38515
  return copiedPaths;
@@ -38026,7 +38622,7 @@ function runRecoverShell(sqliteExecutable, sourcePath, recoveredPath, dumpPath)
38026
38622
  } finally {
38027
38623
  if (dumpWriteFd !== null)
38028
38624
  closeSync4(dumpWriteFd);
38029
- rmSync7(dumpPath, { force: true });
38625
+ rmSync8(dumpPath, { force: true });
38030
38626
  }
38031
38627
  }
38032
38628
  function schemaMigrationWarning(schemaVersionBefore, fences) {
@@ -38125,25 +38721,25 @@ function prepareFreshDatabase(path) {
38125
38721
  }
38126
38722
  function removeRecoveryBundle(basePath) {
38127
38723
  for (const suffix of DATABASE_SUFFIXES)
38128
- rmSync7(`${basePath}${suffix}`, { force: true });
38724
+ rmSync8(`${basePath}${suffix}`, { force: true });
38129
38725
  }
38130
38726
  function activateReplacement(dbPath, replacementPath, originalAsidePath) {
38131
38727
  const movedOriginals = [];
38132
38728
  try {
38133
38729
  for (const suffix of DATABASE_SUFFIXES) {
38134
38730
  const from = `${dbPath}${suffix}`;
38135
- if (!existsSync30(from))
38731
+ if (!existsSync32(from))
38136
38732
  continue;
38137
38733
  const to = `${originalAsidePath}${suffix}`;
38138
- renameSync5(from, to);
38734
+ renameSync6(from, to);
38139
38735
  movedOriginals.push({ from, to });
38140
38736
  }
38141
- renameSync5(replacementPath, dbPath);
38737
+ renameSync6(replacementPath, dbPath);
38142
38738
  return movedOriginals.map(({ to }) => to);
38143
38739
  } catch (error) {
38144
38740
  for (const moved of movedOriginals.reverse()) {
38145
- if (existsSync30(moved.to) && !existsSync30(moved.from))
38146
- renameSync5(moved.to, moved.from);
38741
+ if (existsSync32(moved.to) && !existsSync32(moved.from))
38742
+ renameSync6(moved.to, moved.from);
38147
38743
  }
38148
38744
  throw error;
38149
38745
  }
@@ -38173,12 +38769,12 @@ function printHelp() {
38173
38769
  async function runRepairDb(options = {}) {
38174
38770
  const prompts = options.prompts ?? promptIO;
38175
38771
  const deps = { ...DEFAULT_DEPS3, ...options.deps };
38176
- const storageDir = options.storageDir ?? dirname16(options.dbPath ?? join23(getMagicContextStorageDir(), "context.db"));
38177
- const dbPath = options.dbPath ?? join23(storageDir, "context.db");
38772
+ const storageDir = options.storageDir ?? dirname18(options.dbPath ?? join24(getMagicContextStorageDir(), "context.db"));
38773
+ const dbPath = options.dbPath ?? join24(storageDir, "context.db");
38178
38774
  const stamp = timestamp(deps.now());
38179
38775
  prompts.intro("Magic Context — Repair shared database");
38180
38776
  prompts.log.info(`Database: ${dbPath}`);
38181
- if (!existsSync30(dbPath)) {
38777
+ if (!existsSync32(dbPath)) {
38182
38778
  prompts.log.error(`Database not found: ${dbPath}`);
38183
38779
  prompts.log.info("Backup: not created (database does not exist)");
38184
38780
  prompts.outro("Database repair failed");
@@ -38388,13 +38984,13 @@ var init_doctor_repair_db = __esm(async () => {
38388
38984
 
38389
38985
  // src/commands/doctor-single-store-repair.ts
38390
38986
  import { spawnSync as spawnSync5 } from "node:child_process";
38391
- import { existsSync as existsSync31, statfsSync, statSync as statSync13 } from "node:fs";
38392
- import { homedir as homedir17 } from "node:os";
38393
- import { dirname as dirname17, join as join24, resolve as resolve11 } from "node:path";
38987
+ import { existsSync as existsSync33, statfsSync as statfsSync2, statSync as statSync16 } from "node:fs";
38988
+ import { homedir as homedir18 } from "node:os";
38989
+ import { dirname as dirname19, join as join25, resolve as resolve12 } from "node:path";
38394
38990
  function existingAncestor(path) {
38395
- let current = resolve11(path);
38396
- while (!existsSync31(current))
38397
- current = dirname17(current);
38991
+ let current = resolve12(path);
38992
+ while (!existsSync33(current))
38993
+ current = dirname19(current);
38398
38994
  return current;
38399
38995
  }
38400
38996
  function describe2(plan, print) {
@@ -38417,7 +39013,7 @@ function runDoctorSingleStoreRepair(options, overrides = {}) {
38417
39013
  inspectHolders: defaultInspectHolders,
38418
39014
  lsofSpawn: spawnSync5,
38419
39015
  freeBytes: (path) => {
38420
- const fs = statfsSync(path);
39016
+ const fs = statfsSync2(path);
38421
39017
  return fs.bavail * fs.bsize;
38422
39018
  },
38423
39019
  print: console.log,
@@ -38429,15 +39025,15 @@ function runDoctorSingleStoreRepair(options, overrides = {}) {
38429
39025
  };
38430
39026
  try {
38431
39027
  const { dbPath: context, dbDir: data } = resolveDatabasePath();
38432
- const store = join24(data, "store.db");
38433
- if (!existsSync31(context) || !existsSync31(store))
39028
+ const store = join25(data, "store.db");
39029
+ if (!existsSync33(context) || !existsSync33(store))
38434
39030
  return refuse("repair_missing_database", `Both ${context} and ${store} must exist.`);
38435
39031
  if (!options.fromBackup)
38436
39032
  return refuse("repair_usage", "--from-backup <dir> is required");
38437
- const fromBackup = resolve11(options.fromBackup);
39033
+ const fromBackup = resolve12(options.fromBackup);
38438
39034
  for (const name of ["context.db", "store.db"])
38439
- if (!existsSync31(join24(fromBackup, name)))
38440
- return refuse("repair_backup_missing", `${join24(fromBackup, name)} does not exist`);
39035
+ if (!existsSync33(join25(fromBackup, name)))
39036
+ return refuse("repair_backup_missing", `${join25(fromBackup, name)} does not exist`);
38441
39037
  const sessions = options.sessions ?? [];
38442
39038
  if (options.live && sessions.length === 0)
38443
39039
  return refuse("repair_usage", "--live repairs named sessions only; pass --session <id>");
@@ -38464,16 +39060,16 @@ function runDoctorSingleStoreRepair(options, overrides = {}) {
38464
39060
  `));
38465
39061
  deps.print(`Repairing while hosts hold the stores (--live): ${blockers.join("; ") || "holders unknown"}`);
38466
39062
  }
38467
- const backupRoot = resolve11(options.backupRoot ?? join24(data, "backups"));
38468
- const need = Math.ceil((statSync13(context).size + statSync13(store).size) * 1.1);
39063
+ const backupRoot = resolve12(options.backupRoot ?? join25(data, "backups"));
39064
+ const need = Math.ceil((statSync16(context).size + statSync16(store).size) * 1.1);
38469
39065
  const volume = existingAncestor(backupRoot);
38470
39066
  const have = deps.freeBytes(volume);
38471
39067
  if (have < need)
38472
39068
  return refuse("repair_disk_space", `the backup needs ${need} bytes; have ${have} bytes on ${volume}`);
38473
- backupDir = join24(backupRoot, `repair-history-${deps.now().toISOString().replaceAll(":", "-")}`);
39069
+ backupDir = join25(backupRoot, `repair-history-${deps.now().toISOString().replaceAll(":", "-")}`);
38474
39070
  deps.print(`Backing up the live stores to ${backupDir} before any write.`);
38475
39071
  }
38476
- const binary = options.ckMc ?? join24(homedir17(), ".local", "share", "cortexkit", "bin", "ck-mc");
39072
+ const binary = options.ckMc ?? join25(homedir18(), ".local", "share", "cortexkit", "bin", "ck-mc");
38477
39073
  const args = [
38478
39074
  "single-store-repair-history",
38479
39075
  "--context-db",
@@ -38561,28 +39157,22 @@ var init_doctor_single_store_repair = __esm(async () => {
38561
39157
 
38562
39158
  // src/commands/doctor-single-store.ts
38563
39159
  import { spawnSync as spawnSync6 } from "node:child_process";
38564
- import { existsSync as existsSync32, realpathSync as realpathSync5, statfsSync as statfsSync2, statSync as statSync14 } from "node:fs";
38565
- import { homedir as homedir18 } from "node:os";
38566
- import { dirname as dirname18, join as join25, resolve as resolve12 } from "node:path";
39160
+ import { existsSync as existsSync34, realpathSync as realpathSync5, statSync as statSync17 } from "node:fs";
39161
+ import { homedir as homedir19 } from "node:os";
39162
+ import { join as join26, resolve as resolve13 } from "node:path";
38567
39163
  function engineContextPath() {
38568
39164
  const value = (key) => process.env[key]?.trim() || undefined;
38569
39165
  const test = value("MAGIC_CONTEXT_TEST_DATA_DIR");
38570
39166
  const xdg = value("XDG_DATA_HOME");
38571
- const dir = test ? join25(xdg && xdg !== test ? xdg : test, "cortexkit", "magic-context") : value("MAGIC_CONTEXT_STORAGE_DIR") ?? join25(xdg ?? join25(value("HOME") ?? ".", ".local", "share"), "cortexkit", "magic-context");
38572
- return join25(dir, "context.db");
38573
- }
38574
- function existingAncestor2(path) {
38575
- let current = resolve12(path);
38576
- while (!existsSync32(current))
38577
- current = dirname18(current);
38578
- return current;
39167
+ const dir = test ? join26(xdg && xdg !== test ? xdg : test, "cortexkit", "magic-context") : value("MAGIC_CONTEXT_STORAGE_DIR") ?? join26(xdg ?? join26(value("HOME") ?? ".", ".local", "share"), "cortexkit", "magic-context");
39168
+ return join26(dir, "context.db");
38579
39169
  }
38580
39170
  function undo(backup, data, print) {
38581
39171
  const quote = (s) => `'${s.replaceAll("'", "'\\''")}'`;
38582
39172
  print(`Backup: ${backup}`);
38583
39173
  print("To undo: quit every host, then");
38584
- print(` rm -f ${["context.db-wal", "context.db-shm", "store.db-wal", "store.db-shm"].map((name) => quote(join25(data, name))).join(" ")}`);
38585
- print(` cp ${quote(join25(backup, "context.db"))} ${quote(join25(backup, "store.db"))} ${quote(data + "/")}`);
39174
+ print(` rm -f ${["context.db-wal", "context.db-shm", "store.db-wal", "store.db-shm"].map((name) => quote(join26(data, name))).join(" ")}`);
39175
+ print(` cp ${quote(join26(backup, "context.db"))} ${quote(join26(backup, "store.db"))} ${quote(data + "/")}`);
38586
39176
  print("This restores the unmigrated stores. Keep the current plugin and ck-mc: TypeScript mode works as before, and Rust mode will refuse with MC-C14 until you run this command again.");
38587
39177
  }
38588
39178
  function runDoctorSingleStore(options = {}, overrides = {}) {
@@ -38590,10 +39180,7 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
38590
39180
  now: () => new Date,
38591
39181
  inspectHolders: defaultInspectHolders,
38592
39182
  lsofSpawn: spawnSync6,
38593
- freeBytes: (path) => {
38594
- const fs = statfsSync2(path);
38595
- return fs.bavail * fs.bsize;
38596
- },
39183
+ freeBytes: availableDiskBytes,
38597
39184
  print: console.log,
38598
39185
  ...overrides
38599
39186
  };
@@ -38603,8 +39190,8 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
38603
39190
  };
38604
39191
  try {
38605
39192
  const { dbPath: context, dbDir: data } = resolveDatabasePath();
38606
- const store = join25(data, "store.db");
38607
- if (!existsSync32(context) || !existsSync32(store))
39193
+ const store = join26(data, "store.db");
39194
+ if (!existsSync34(context) || !existsSync34(store))
38608
39195
  return refuse("single_store_missing_database", `Both ${context} and ${store} must exist.`);
38609
39196
  const probe = probeHostProcessesUsing({ files: [context, store].flatMap((p) => SUFFIXES2.map((s) => p + s)), directories: [] }, deps.lsofSpawn);
38610
39197
  const holders = deps.inspectHolders(data);
@@ -38619,9 +39206,9 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
38619
39206
  return refuse("single_store_files_in_use", [...lines, STOP].join(`
38620
39207
  `));
38621
39208
  }
38622
- if (!existsSync32(engineContextPath()) || realpathSync5(context) !== realpathSync5(engineContextPath()))
39209
+ if (!existsSync34(engineContextPath()) || realpathSync5(context) !== realpathSync5(engineContextPath()))
38623
39210
  return refuse("single_store_path_mismatch", `CLI ${context}; engine ${engineContextPath()}`);
38624
- const backupRoot = resolve12(options.backupRoot ?? join25(data, "backups"));
39211
+ const backupRoot = resolve13(options.backupRoot ?? join26(data, "backups"));
38625
39212
  const contextDb = new Database(context, { readonly: true });
38626
39213
  const storeDb = new Database(store, { readonly: true });
38627
39214
  let contextVersion;
@@ -38648,17 +39235,17 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
38648
39235
  }
38649
39236
  if (contextVersion > LATEST_SUPPORTED_VERSION || storeVersion !== 60)
38650
39237
  return refuse("single_store_version_mismatch", `context.db v${contextVersion}; store.db v${storeVersion}; need context.db v${LATEST_SUPPORTED_VERSION} and store.db v60 (apply current plugin migrations to context.db; upgrade store.db with ck-mc first)`);
38651
- const backupBytes = statSync14(context).size + statSync14(store).size;
38652
- const workingBytes = 2 * statSync14(store).size;
38653
- const backupVolume = existingAncestor2(backupRoot);
38654
- const sameVolume = statSync14(data).dev === statSync14(backupVolume).dev;
38655
- const need = Math.ceil((workingBytes + (sameVolume ? backupBytes : 0)) * 1.1);
38656
- const have = deps.freeBytes(data);
38657
- if (have < need)
38658
- return refuse("single_store_disk_space", `need ${need} bytes; have ${have} bytes on ${data}`);
38659
- if (!sameVolume && deps.freeBytes(backupVolume) < Math.ceil(backupBytes * 1.1))
38660
- return refuse("single_store_disk_space", `backup needs ${Math.ceil(backupBytes * 1.1)} bytes; have ${deps.freeBytes(backupVolume)} bytes on ${backupVolume}`);
38661
- const backupDir = join25(backupRoot, `single-store-${deps.now().toISOString().replaceAll(":", "-")}`);
39238
+ const backupBytes = statSync17(context).size + statSync17(store).size;
39239
+ const workingBytes = 2 * statSync17(store).size;
39240
+ const backupVolume = existingDirectoryAncestor(backupRoot);
39241
+ const sameVolume = statSync17(data).dev === statSync17(backupVolume).dev;
39242
+ const dataSpace = checkDiskSpace(data, workingBytes + (sameVolume ? backupBytes : 0), deps.freeBytes);
39243
+ if (!dataSpace.sufficient)
39244
+ return refuse("single_store_disk_space", `need ${dataSpace.requiredBytes} bytes; have ${dataSpace.availableBytes} bytes on ${data}`);
39245
+ const backupSpace = sameVolume ? undefined : checkDiskSpace(backupVolume, backupBytes, deps.freeBytes);
39246
+ if (backupSpace && !backupSpace.sufficient)
39247
+ return refuse("single_store_disk_space", `backup needs ${backupSpace.requiredBytes} bytes; have ${backupSpace.availableBytes} bytes on ${backupVolume}`);
39248
+ const backupDir = join26(backupRoot, `single-store-${deps.now().toISOString().replaceAll(":", "-")}`);
38662
39249
  undo(backupDir, data, deps.print);
38663
39250
  const opened = openDatabase(context);
38664
39251
  if (!opened)
@@ -38670,7 +39257,7 @@ function runDoctorSingleStore(options = {}, overrides = {}) {
38670
39257
  }
38671
39258
  if (contextVersion !== LATEST_SUPPORTED_VERSION)
38672
39259
  return refuse("single_store_version_mismatch", `context.db v${contextVersion}; store.db v${storeVersion}`);
38673
- const binary = options.ckMc ?? join25(homedir18(), ".local", "share", "cortexkit", "bin", "ck-mc");
39260
+ const binary = options.ckMc ?? join26(homedir19(), ".local", "share", "cortexkit", "bin", "ck-mc");
38674
39261
  const args = [
38675
39262
  "single-store-migrate",
38676
39263
  "--context-db",
@@ -38786,6 +39373,7 @@ function runDoctorSingleStoreCli(args) {
38786
39373
  }
38787
39374
  var STOP = "quit OpenCode, Pi and ck-mc (`ck stop magic-context`) and run again", SUFFIXES2;
38788
39375
  var init_doctor_single_store = __esm(async () => {
39376
+ init_disk_space();
38789
39377
  await __promiseAll([
38790
39378
  init_storage_db(),
38791
39379
  init_sqlite(),
@@ -39160,18 +39748,18 @@ var init_storage_identity_merge = __esm(() => {
39160
39748
 
39161
39749
  // src/commands/doctor-identity-splits.ts
39162
39750
  import { execFileSync as execFileSync6 } from "node:child_process";
39163
- import { createHash as createHash5 } from "node:crypto";
39164
- import { existsSync as existsSync33, readdirSync as readdirSync7, realpathSync as realpathSync6, statSync as statSync15 } from "node:fs";
39165
- import { dirname as dirname19, join as join26, resolve as resolve13 } from "node:path";
39751
+ import { createHash as createHash6 } from "node:crypto";
39752
+ import { existsSync as existsSync35, readdirSync as readdirSync7, realpathSync as realpathSync6, statSync as statSync18 } from "node:fs";
39753
+ import { dirname as dirname20, join as join27, resolve as resolve14 } from "node:path";
39166
39754
  function tableExists5(db, table) {
39167
39755
  return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table);
39168
39756
  }
39169
39757
  function hasGitMetadataInAncestors(directory) {
39170
- let current = resolve13(directory);
39758
+ let current = resolve14(directory);
39171
39759
  while (true) {
39172
- if (existsSync33(join26(current, ".git")))
39760
+ if (existsSync35(join27(current, ".git")))
39173
39761
  return true;
39174
- const parent = dirname19(current);
39762
+ const parent = dirname20(current);
39175
39763
  if (parent === current)
39176
39764
  return false;
39177
39765
  current = parent;
@@ -39180,7 +39768,7 @@ function hasGitMetadataInAncestors(directory) {
39180
39768
  function orphanedPathReason(directory) {
39181
39769
  let entries;
39182
39770
  try {
39183
- if (!statSync15(directory).isDirectory())
39771
+ if (!statSync18(directory).isDirectory())
39184
39772
  return "path is no longer a directory";
39185
39773
  entries = readdirSync7(directory);
39186
39774
  } catch (error) {
@@ -39255,7 +39843,7 @@ function findIdentitySplits(db, host, includeSingles = false) {
39255
39843
  const gitIdentities = new Map;
39256
39844
  for (const [directoryKey, spellings] of directorySpellings) {
39257
39845
  for (const directory of spellings) {
39258
- const dirIdentity = `dir:${createHash5("md5").update(resolve13(directory), "utf8").digest("hex").slice(0, 12)}`;
39846
+ const dirIdentity = `dir:${createHash6("md5").update(resolve14(directory), "utf8").digest("hex").slice(0, 12)}`;
39259
39847
  const hasData = [
39260
39848
  "memories",
39261
39849
  "notes",
@@ -39324,7 +39912,7 @@ function identityLines(split) {
39324
39912
  return split.identities.map((row) => ` ${row.identity}: ${row.sessions} sessions, ${row.memories} memories, ${row.notes} notes, ${row.dreamer} dreamer rows (identity-wide counts)`);
39325
39913
  }
39326
39914
  function diagnoseIdentitySplits() {
39327
- const db = openExistingContextDatabase(join26(getMagicContextStorageDir(), "context.db"), {
39915
+ const db = openExistingContextDatabase(join27(getMagicContextStorageDir(), "context.db"), {
39328
39916
  readonly: true
39329
39917
  });
39330
39918
  if (!db)
@@ -39349,15 +39937,15 @@ var init_doctor_identity_splits = __esm(async () => {
39349
39937
 
39350
39938
  // src/commands/doctor-merge-identity.ts
39351
39939
  import { execFileSync as execFileSync7 } from "node:child_process";
39352
- import { createHash as createHash6 } from "node:crypto";
39353
- import { existsSync as existsSync34, mkdtempSync, readdirSync as readdirSync8, readFileSync as readFileSync20 } from "node:fs";
39354
- import { dirname as dirname20, join as join27 } from "node:path";
39940
+ import { createHash as createHash7 } from "node:crypto";
39941
+ import { existsSync as existsSync36, mkdtempSync as mkdtempSync2, readdirSync as readdirSync8, readFileSync as readFileSync21, statSync as statSync19 } from "node:fs";
39942
+ import { dirname as dirname21, join as join28, resolve as resolve15 } from "node:path";
39355
39943
  function parseMergeIdentityArgs(args) {
39356
39944
  const values = {};
39357
- const switches = new Set(["--apply", "--force", "--dry-run", "--yes"]);
39945
+ const switches = new Set(["--apply", "--force", "--dry-run", "--yes", "--verbose"]);
39358
39946
  for (let i = 0;i < args.length; i++) {
39359
39947
  const flag = args[i];
39360
- if (["--from", "--to", "--db", "--host-db"].includes(flag)) {
39948
+ if (["--from", "--to", "--db", "--host-db", "--backup-root"].includes(flag)) {
39361
39949
  const value = args[++i];
39362
39950
  if (!value || value.startsWith("--"))
39363
39951
  throw new Error(`${flag} requires a value`);
@@ -39377,9 +39965,11 @@ function parseMergeIdentityArgs(args) {
39377
39965
  to: values["--to"],
39378
39966
  dbPath: values["--db"],
39379
39967
  hostPath: values["--host-db"],
39968
+ backupRoot: values["--backup-root"],
39380
39969
  dryRun: !apply,
39381
39970
  yes: apply,
39382
- force: args.includes("--force")
39971
+ force: args.includes("--force"),
39972
+ verbose: args.includes("--verbose")
39383
39973
  };
39384
39974
  }
39385
39975
  function printReport(report) {
@@ -39399,7 +39989,7 @@ function printReport(report) {
39399
39989
  console.log(" No writes. Review this preview, then repeat with --apply to confirm.");
39400
39990
  }
39401
39991
  function resolveReadOnly(directory) {
39402
- if (!existsSync34(directory))
39992
+ if (!existsSync36(directory))
39403
39993
  return;
39404
39994
  try {
39405
39995
  const roots = execFileSync7("git", ["rev-list", "--max-parents=0", "HEAD"], {
@@ -39424,14 +40014,23 @@ function resolveReadOnly(directory) {
39424
40014
  return;
39425
40015
  } catch (error) {
39426
40016
  if (String(error.stderr).includes("not a git repository"))
39427
- return `dir:${createHash6("md5").update(projectDirectoryKey(directory)).digest("hex").slice(0, 12)}`;
40017
+ return `dir:${createHash7("md5").update(projectDirectoryKey(directory)).digest("hex").slice(0, 12)}`;
39428
40018
  }
39429
40019
  return;
39430
40020
  }
39431
40021
  function canonicalIdentity(directory, storageDir) {
39432
40022
  return readRememberedGitIdentity(directory, storageDir) ?? (orphanedPathReason(directory) ? undefined : resolveReadOnly(directory));
39433
40023
  }
40024
+ function directoryDoesNotExist(directory) {
40025
+ try {
40026
+ statSync19(directory);
40027
+ } catch (error) {
40028
+ return error.code === "ENOENT";
40029
+ }
40030
+ return false;
40031
+ }
39434
40032
  function assertMergePairSafe(db, observed, storageDir, from, to) {
40033
+ const allowances = [];
39435
40034
  if (from.startsWith("git:") && !to.startsWith("git:"))
39436
40035
  throw new Error(`Refusing merge: ${from} is a repository-wide identity shared by every checkout and worktree of its repository. It can only be a merge target, never merged into the directory identity ${to}.`);
39437
40036
  const sourceRows = countIdentityRows(db, from);
@@ -39444,11 +40043,54 @@ function assertMergePairSafe(db, observed, storageDir, from, to) {
39444
40043
  const persisted = readRememberedGitIdentity(row.directory, storageDir);
39445
40044
  if (!persisted)
39446
40045
  continue;
39447
- if (persisted === from)
40046
+ if (persisted === from) {
40047
+ let live;
40048
+ const orphaned = directoryDoesNotExist(row.directory);
40049
+ if (!orphaned) {
40050
+ try {
40051
+ live = resolveProjectIdentityStrict(row.directory, undefined, { cache: false });
40052
+ } catch {}
40053
+ }
40054
+ if (orphaned || live === to) {
40055
+ allowances.push({
40056
+ directory: row.directory,
40057
+ reason: orphaned ? "orphaned" : `live root now resolves to ${to}`,
40058
+ liveIdentity: live
40059
+ });
40060
+ continue;
40061
+ }
39448
40062
  throw new Error(`Refusing merge: ${from} is the identity the plugin persisted for ${row.directory}; merging away from it would contradict the plugin's own resolution of that path.`);
40063
+ }
39449
40064
  if (persisted !== to)
39450
40065
  throw new Error(`Refusing merge: the plugin persisted ${persisted} for ${row.directory}, where ${involved.map((item) => item.identity).join(" and ")} was observed. That persisted identity is canonical for the path; merge into ${persisted} instead of ${to}.`);
39451
40066
  }
40067
+ return allowances;
40068
+ }
40069
+ function assertMergeDirectoriesSafe(db, from, to, sourceDirs, targetDirs, allowances) {
40070
+ const alreadyMerged = auditIdentityMerge(db, from, to).changedRows === 0 && db.prepare("SELECT 1 FROM v22_identity_rekey_map WHERE old_project_path = ? AND new_project_path = ?").get(from, to);
40071
+ const allowedDirs = new Set(allowances.map((item) => item.directory));
40072
+ const missingSourceDirs = sourceDirs.filter((directory) => !targetDirs.includes(directory) && directoryDoesNotExist(directory));
40073
+ for (const directory of missingSourceDirs)
40074
+ allowedDirs.add(directory);
40075
+ const sourceDirsAllowed = allowedDirs.size > 0 && sourceDirs.every((directory) => targetDirs.includes(directory) || allowedDirs.has(directory));
40076
+ if (!alreadyMerged && from.startsWith("git:") && to.startsWith("git:") && (!sourceDirs.length || !targetDirs.length || !sourceDirsAllowed && (sourceDirs.some((dir) => !targetDirs.includes(dir)) || targetDirs.some((dir) => !sourceDirs.includes(dir)))))
40077
+ throw new Error(`Refusing different directories for ${from} (${sourceDirs.join(", ") || "unknown"}) and ${to} (${targetDirs.join(", ") || "unknown"})`);
40078
+ return missingSourceDirs;
40079
+ }
40080
+ function printSidecarPreview(allowances, missingSourceDirs, to, verbose) {
40081
+ const missing = new Set(missingSourceDirs);
40082
+ const orphanPins = allowances.filter((item) => missing.has(item.directory));
40083
+ if (missingSourceDirs.length) {
40084
+ console.log(` ${missingSourceDirs.length} source-only folders no longer exist: allowed${orphanPins.length ? ` (${orphanPins.length} orphaned sidecar(s) will be rewritten to ${to})` : ""}.${verbose ? "" : " Use --verbose for the full list."}`);
40085
+ if (verbose) {
40086
+ for (const directory of missingSourceDirs)
40087
+ if (!orphanPins.some((item) => item.directory === directory))
40088
+ console.log(` ${directory} (orphaned; no persisted sidecar)`);
40089
+ }
40090
+ }
40091
+ for (const item of allowances)
40092
+ if (verbose || !missing.has(item.directory))
40093
+ console.log(` Sidecar for ${item.directory}: overwrite with ${to} (${item.reason}; sidecar will be rewritten).`);
39452
40094
  }
39453
40095
  function printSuggestion(db, split, storageDir) {
39454
40096
  const rows = new Map(split.identities.map((row) => [row.identity, countIdentityRows(db, row.identity)]));
@@ -39503,13 +40145,13 @@ function observations(db, hostPath, storageDir) {
39503
40145
  if (!row.identities.some((item) => item.identity === identity))
39504
40146
  row.identities.push({ identity, sessions: 0, memories: 0, notes: 0, dreamer: 0 });
39505
40147
  };
39506
- const sidecars = join27(storageDir, "project-identities");
39507
- if (existsSync34(sidecars))
40148
+ const sidecars = join28(storageDir, "project-identities");
40149
+ if (existsSync36(sidecars))
39508
40150
  for (const file of readdirSync8(sidecars)) {
39509
40151
  if (!file.endsWith(".json"))
39510
40152
  continue;
39511
40153
  try {
39512
- const record = JSON.parse(readFileSync20(join27(sidecars, file), "utf8"));
40154
+ const record = JSON.parse(readFileSync21(join28(sidecars, file), "utf8"));
39513
40155
  if (typeof record.directory === "string" && typeof record.identity === "string")
39514
40156
  add(record.directory, record.identity);
39515
40157
  } catch {}
@@ -39520,9 +40162,9 @@ function observations(db, hostPath, storageDir) {
39520
40162
  }
39521
40163
  function runMergeIdentityCli(args, deps = {}) {
39522
40164
  const options = parseMergeIdentityArgs(args);
39523
- const dbPath = options.dbPath ?? join27(getMagicContextStorageDir(), "context.db");
39524
- const storageDir = dirname20(dbPath);
39525
- const hostPath = options.hostPath ?? (options.dbPath ? join27(storageDir, "host.db") : resolveOpenCodeDbPath().path);
40165
+ const dbPath = options.dbPath ?? join28(getMagicContextStorageDir(), "context.db");
40166
+ const storageDir = dirname21(dbPath);
40167
+ const hostPath = options.hostPath ?? (options.dbPath ? join28(storageDir, "host.db") : resolveOpenCodeDbPath().path);
39526
40168
  let db = openExistingContextDatabase(dbPath, {
39527
40169
  readonly: true,
39528
40170
  minimumSupportedVersion: CLI_SCHEMA_FLOOR_VERSION
@@ -39542,7 +40184,7 @@ function runMergeIdentityCli(args, deps = {}) {
39542
40184
  }
39543
40185
  if (options.from === options.to)
39544
40186
  throw new Error(`Source and target identities must differ: ${options.from}`);
39545
- assertMergePairSafe(db, observed, storageDir, options.from, options.to);
40187
+ const allowances = assertMergePairSafe(db, observed, storageDir, options.from, options.to);
39546
40188
  for (const identity of [options.from, options.to]) {
39547
40189
  const known = auditIdentityMerge(db, identity, options.to).changedRows > 0 || db.prepare("SELECT 1 FROM v22_identity_rekey_map WHERE old_project_path = ? OR new_project_path = ?").get(identity, identity);
39548
40190
  if (!known)
@@ -39551,12 +40193,11 @@ function runMergeIdentityCli(args, deps = {}) {
39551
40193
  const sourceDirs = observed.filter((row) => row.identities.some((item) => item.identity === options.from)).map((row) => row.directory);
39552
40194
  const targetDirs = observed.filter((row) => row.identities.some((item) => item.identity === options.to)).map((row) => row.directory);
39553
40195
  directories = [...new Set([...sourceDirs, ...targetDirs])];
39554
- const alreadyMerged = auditIdentityMerge(db, options.from, options.to).changedRows === 0 && db.prepare("SELECT 1 FROM v22_identity_rekey_map WHERE old_project_path = ? AND new_project_path = ?").get(options.from, options.to);
39555
- if (!alreadyMerged && options.from.startsWith("git:") && options.to.startsWith("git:") && (!sourceDirs.length || !targetDirs.length || sourceDirs.some((dir) => !targetDirs.includes(dir)) || targetDirs.some((dir) => !sourceDirs.includes(dir))))
39556
- throw new Error(`Refusing different directories for ${options.from} (${sourceDirs.join(", ") || "unknown"}) and ${options.to} (${targetDirs.join(", ") || "unknown"})`);
39557
- if (!options.force && !directories.some((directory) => canonicalIdentity(directory, storageDir) === options.to))
40196
+ const missingSourceDirs = assertMergeDirectoriesSafe(db, options.from, options.to, sourceDirs, targetDirs, allowances);
40197
+ if (!options.force && !directories.some((directory) => canonicalIdentity(directory, storageDir) === options.to || allowances.some((item) => item.directory === directory && item.liveIdentity === options.to)))
39558
40198
  throw new Error(`Target ${options.to} does not resolve for any observed directory on this machine; use --force only after reviewing the identity.`);
39559
40199
  const preview = mergeProjectIdentities(db, options.from, options.to, { dryRun: true });
40200
+ printSidecarPreview(allowances, missingSourceDirs, options.to, options.verbose);
39560
40201
  printReport(preview);
39561
40202
  if (options.dryRun)
39562
40203
  return 0;
@@ -39574,47 +40215,64 @@ function runMergeIdentityCli(args, deps = {}) {
39574
40215
  });
39575
40216
  if (!holders.safe || probe.status !== "free")
39576
40217
  throw new Error(`Refusing merge: close OpenCode, Pi, OpenCode 2 and ck-mc. ${holders.blockers.join(", ")} ${holders.uncertainty ?? ""} ${probe.status === "in_use" ? `context.db holders: ${probe.pids.join(", ")}` : probe.status === "unknown" ? probe.reason : ""}`);
39577
- const backup = mkdtempSync(join27(storageDir, "identity-merge-backup-"));
40218
+ const backupRoot = resolve15(options.backupRoot ?? storageDir);
40219
+ const backupVolume = existingDirectoryAncestor(backupRoot);
40220
+ const sidecarRoot = join28(storageDir, "project-identities");
40221
+ const sidecarEntries = existsSync36(sidecarRoot) ? readdirSync8(sidecarRoot).filter((entry) => entry.endsWith(".json")) : [];
40222
+ const sidecarBytes = sidecarEntries.reduce((size, entry) => size + statSync19(join28(sidecarRoot, entry)).size, 0);
40223
+ const diskSpace = checkDiskSpace(backupVolume, databaseBundleSizeBytes(dbPath) + sidecarBytes, deps.freeBytes ?? availableDiskBytes);
40224
+ if (!diskSpace.sufficient)
40225
+ throw new Error(`merge_identity_disk_space: refusing identity merge: backup needs ${diskSpace.requiredBytes} bytes; have ${diskSpace.availableBytes} bytes on ${backupVolume}. Use --backup-root <dir> to choose a volume with enough free space.`);
40226
+ ensureStorageDirectorySync(backupRoot, true);
40227
+ const backup = mkdtempSync2(join28(backupRoot, "identity-merge-backup-"));
39578
40228
  const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
39579
40229
  console.log(`Backup directory: ${backup}`);
39580
- console.log(`Restore with hosts closed: rm -f ${quote(`${dbPath}-wal`)} ${quote(`${dbPath}-shm`)}; cp ${quote(join27(backup, "context.db"))} ${quote(dbPath)}; if test -f ${quote(join27(backup, "context.db-wal"))}; then cp ${quote(join27(backup, "context.db-wal"))} ${quote(`${dbPath}-wal`)}; fi`);
39581
- const sidecarRoot = join27(storageDir, "project-identities");
39582
- const sidecarBackup = join27(backup, "project-identities");
39583
- ensureStorageDirectorySync(sidecarBackup);
39584
- if (existsSync34(sidecarRoot)) {
39585
- for (const entry of readdirSync8(sidecarRoot)) {
39586
- if (!entry.endsWith(".json"))
39587
- continue;
39588
- writeStorageFileAtomicSync(join27(sidecarBackup, entry), readFileSync20(join27(sidecarRoot, entry)));
39589
- }
40230
+ console.log(`Restore with hosts closed: rm -f ${quote(`${dbPath}-wal`)} ${quote(`${dbPath}-shm`)}; cp ${quote(join28(backup, "context.db"))} ${quote(dbPath)}; if test -f ${quote(join28(backup, "context.db-wal"))}; then cp ${quote(join28(backup, "context.db-wal"))} ${quote(`${dbPath}-wal`)}; fi`);
40231
+ const sidecarBackup = join28(backup, "project-identities");
40232
+ ensureStorageDirectorySync(sidecarBackup, true);
40233
+ let backupBytes = 0;
40234
+ for (const entry of sidecarEntries) {
40235
+ const content = readFileSync21(join28(sidecarRoot, entry));
40236
+ writeStorageFileAtomicSync(join28(sidecarBackup, entry), content, true);
40237
+ backupBytes += content.byteLength;
39590
40238
  }
39591
40239
  console.log(`Restore identity sidecars too: rm -rf ${quote(sidecarRoot)}; cp -R ${quote(sidecarBackup)} ${quote(sidecarRoot)}`);
39592
- copyDatabaseBundle(dbPath, join27(backup, "context.db"));
40240
+ const copiedDatabaseFiles = copyDatabaseBundle(dbPath, join28(backup, "context.db"), true);
40241
+ backupBytes += copiedDatabaseFiles.reduce((size, path) => size + statSync19(path).size, 0);
39593
40242
  db = openExistingDatabase(dbPath, { readonly: false });
39594
40243
  if (!db)
39595
40244
  throw new Error(`Context database disappeared: ${dbPath}`);
39596
40245
  try {
39597
40246
  configureContextDatabasePragmas(db);
39598
- assertMergePairSafe(db, observed, storageDir, from, to);
40247
+ observed = observations(db, hostPath, storageDir);
40248
+ const allowances = assertMergePairSafe(db, observed, storageDir, from, to);
40249
+ const sourceDirs = observed.filter((row) => row.identities.some((item) => item.identity === from)).map((row) => row.directory);
40250
+ const targetDirs = observed.filter((row) => row.identities.some((item) => item.identity === to)).map((row) => row.directory);
40251
+ assertMergeDirectoriesSafe(db, from, to, sourceDirs, targetDirs, allowances);
40252
+ directories = [...new Set([...sourceDirs, ...targetDirs])];
39599
40253
  printReport(mergeProjectIdentities(db, from, to));
39600
40254
  } finally {
39601
40255
  db.close();
39602
40256
  }
39603
40257
  if (to.startsWith("git:"))
39604
40258
  for (const directory of directories) {
39605
- const root = join27(storageDir, "project-identities");
40259
+ const root = join28(storageDir, "project-identities");
39606
40260
  ensureStorageDirectorySync(root);
39607
- const path = join27(root, `${createHash6("sha256").update(projectDirectoryKey(directory)).digest("hex")}.json`);
40261
+ const path = join28(root, `${createHash7("sha256").update(projectDirectoryKey(directory)).digest("hex")}.json`);
39608
40262
  writeStorageFileAtomicSync(path, JSON.stringify({ directory: projectDirectoryKey(directory), identity: options.to }));
39609
40263
  }
40264
+ console.log(`Backup: ${backup} (${backupBytes} bytes)`);
40265
+ console.log("This backup can be deleted once the merge has been confirmed.");
39610
40266
  return 0;
39611
40267
  }
39612
40268
  var init_doctor_merge_identity = __esm(async () => {
40269
+ init_project_identity();
39613
40270
  init_project_identity_cache();
39614
40271
  init_storage_identity_merge();
39615
40272
  init_data_path();
39616
40273
  init_opencode_db_path();
39617
40274
  init_storage_permissions();
40275
+ init_disk_space();
39618
40276
  await __promiseAll([
39619
40277
  init_database_access(),
39620
40278
  init_doctor_identity_splits(),
@@ -39624,8 +40282,8 @@ var init_doctor_merge_identity = __esm(async () => {
39624
40282
  });
39625
40283
 
39626
40284
  // src/commands/doctor-git-fts-map.ts
39627
- import { existsSync as existsSync35, mkdtempSync as mkdtempSync2, statSync as statSync16 } from "node:fs";
39628
- import { join as join28, resolve as resolve14 } from "node:path";
40285
+ import { existsSync as existsSync37, mkdtempSync as mkdtempSync3, statSync as statSync20 } from "node:fs";
40286
+ import { join as join29, resolve as resolve16 } from "node:path";
39629
40287
  function inspectGitFtsMap(db) {
39630
40288
  const has = (name) => Boolean(db.prepare("SELECT 1 FROM sqlite_master WHERE name=? AND type='table'").get(name));
39631
40289
  const indexed = has("git_commits_fts");
@@ -39678,8 +40336,8 @@ function runDoctorGitFtsMap(options = {}, overrides = {}) {
39678
40336
  verify: verifyInventory,
39679
40337
  ...overrides
39680
40338
  };
39681
- const context = join28(deps.storageDir, "context.db");
39682
- const store = join28(deps.storageDir, "store.db");
40339
+ const context = join29(deps.storageDir, "context.db");
40340
+ const store = join29(deps.storageDir, "store.db");
39683
40341
  let db = null, storeDb = null;
39684
40342
  let contextLocked = false, storeLocked = false;
39685
40343
  try {
@@ -39701,9 +40359,9 @@ function runDoctorGitFtsMap(options = {}, overrides = {}) {
39701
40359
  deps.print(`Stop every host, then run \`${GIT_FTS_MAP_REPAIR_COMMAND}\`. The repair backs up context.db and store.db first.`);
39702
40360
  return damaged ? 1 : 0;
39703
40361
  }
39704
- if (!existsSync35(context) || !existsSync35(store))
40362
+ if (!existsSync37(context) || !existsSync37(store))
39705
40363
  throw new Error("Both context.db and store.db must exist before paired-backup repair; no replacement store will be created");
39706
- const cstat = statSync16(context), sstat = statSync16(store);
40364
+ const cstat = statSync20(context), sstat = statSync20(store);
39707
40365
  if (cstat.dev === sstat.dev && cstat.ino === sstat.ino)
39708
40366
  throw new Error("context.db and store.db must be distinct files");
39709
40367
  const holders = deps.inspectHolders(deps.storageDir);
@@ -39731,12 +40389,12 @@ function runDoctorGitFtsMap(options = {}, overrides = {}) {
39731
40389
  const stillFree = deps.inspectHolders(deps.storageDir);
39732
40390
  if (!stillFree.safe)
39733
40391
  throw new Error(`A host appeared before backup: ${[...stillFree.blockers, stillFree.uncertainty].filter(Boolean).join("; ")}`);
39734
- const backupRoot = resolve14(options.backupRoot ?? join28(deps.storageDir, "backups"));
40392
+ const backupRoot = resolve16(options.backupRoot ?? join29(deps.storageDir, "backups"));
39735
40393
  ensureStorageDirectorySync(backupRoot, true);
39736
- const backup = mkdtempSync2(join28(backupRoot, "git-fts-map-"));
39737
- snapshot(context, join28(backup, "context.db"));
39738
- snapshot(store, join28(backup, "store.db"));
39739
- writeStorageFileSync(join28(backup, "manifest.json"), JSON.stringify({
40394
+ const backup = mkdtempSync3(join29(backupRoot, "git-fts-map-"));
40395
+ snapshot(context, join29(backup, "context.db"));
40396
+ snapshot(store, join29(backup, "store.db"));
40397
+ writeStorageFileSync(join29(backup, "manifest.json"), JSON.stringify({
39740
40398
  contextVersion: version,
39741
40399
  createdAt: new Date().toISOString(),
39742
40400
  repair: "git-fts-map",
@@ -39903,20 +40561,20 @@ function assertNoUnmigratedAuthority(db) {
39903
40561
  var SINGLE_STORE_REQUIRED = "Magic Context's Rust mode needs a one-time migration of its store. Quit OpenCode and every ck-mc process, then run `magic-context doctor single-store migrate`. (MC-C14)";
39904
40562
 
39905
40563
  // src/commands/migrate.ts
39906
- import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
39907
- import { existsSync as existsSync36, mkdirSync as mkdirSync5, renameSync as renameSync6, unlinkSync as unlinkSync4 } from "node:fs";
39908
- import { dirname as dirname21, join as join29 } from "node:path";
40564
+ import { createHash as createHash8, randomBytes as randomBytes3 } from "node:crypto";
40565
+ import { existsSync as existsSync38, mkdirSync as mkdirSync6, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
40566
+ import { dirname as dirname22, join as join30 } from "node:path";
39909
40567
  function defaultOpenCodeDbPath() {
39910
40568
  return getOpenCodeDatabasePath();
39911
40569
  }
39912
40570
  function defaultCortexkitDbPath() {
39913
- return join29(getMagicContextStorageDir(), "context.db");
40571
+ return join30(getMagicContextStorageDir(), "context.db");
39914
40572
  }
39915
40573
  function defaultPiSessionsRoot() {
39916
40574
  return getPiSessionsRoot();
39917
40575
  }
39918
40576
  function defaultFs() {
39919
- return { writeFileAtomic, unlinkSync: unlinkSync4, existsSync: existsSync36, renameSync: renameSync6, mkdirSync: mkdirSync5 };
40577
+ return { writeFileAtomic, unlinkSync: unlinkSync4, existsSync: existsSync38, renameSync: renameSync7, mkdirSync: mkdirSync6 };
39920
40578
  }
39921
40579
  function stmt(db, sql) {
39922
40580
  return db.prepare(sql);
@@ -39943,7 +40601,7 @@ function shortId() {
39943
40601
  return randomBytes3(4).toString("hex");
39944
40602
  }
39945
40603
  function migrationKeyFor(sourceSessionId, targetHarness) {
39946
- return createHash7("sha256").update(`${sourceSessionId}
40604
+ return createHash8("sha256").update(`${sourceSessionId}
39947
40605
  ${targetHarness}`).digest("hex");
39948
40606
  }
39949
40607
  function hasMigrationJournal(db) {
@@ -39970,7 +40628,7 @@ function sweepPendingMigrations(db, fs = defaultFs()) {
39970
40628
  }
39971
40629
  if (row.phase === "db_committed") {
39972
40630
  if (fs.existsSync(row.stage_path)) {
39973
- fs.mkdirSync(dirname21(row.final_path), { recursive: true });
40631
+ fs.mkdirSync(dirname22(row.final_path), { recursive: true });
39974
40632
  fs.renameSync(row.stage_path, row.final_path);
39975
40633
  stmt(db, "DELETE FROM migration_pending WHERE migration_key = ?").run(row.migration_key);
39976
40634
  report.rolledForward += 1;
@@ -40000,7 +40658,7 @@ function claimJournalIdentity(args) {
40000
40658
  migration_key, source_session_id, target_harness, pi_session_id,
40001
40659
  final_path, stage_path, content_sha256, phase, created_at
40002
40660
  ) VALUES (?, ?, ?, ?, ?, ?, '', 'staged', ?)
40003
- ON CONFLICT(migration_key) DO NOTHING`).run(args.migrationKey, args.sourceSessionId, args.targetHarness, piSessionId, args.finalPathFor(piSessionId), join29(args.stageDir, `${args.migrationKey}.jsonl`), args.now);
40661
+ ON CONFLICT(migration_key) DO NOTHING`).run(args.migrationKey, args.sourceSessionId, args.targetHarness, piSessionId, args.finalPathFor(piSessionId), join30(args.stageDir, `${args.migrationKey}.jsonl`), args.now);
40004
40662
  const row = readPendingMigration(args.db, args.migrationKey);
40005
40663
  if (!row) {
40006
40664
  throw new Error("migration journal row disappeared during insert; aborting migration");
@@ -40508,7 +41166,7 @@ function migrateOpenCodeSessionToPi(opts) {
40508
41166
  const provider = opts.provider ?? model.provider;
40509
41167
  const modelId = opts.modelId ?? model.modelId;
40510
41168
  const cwd = session.directory ?? session.path ?? process.cwd();
40511
- const outputDir = join29(piSessionsRoot, projectPathToPiDirSlug(cwd));
41169
+ const outputDir = join30(piSessionsRoot, projectPathToPiDirSlug(cwd));
40512
41170
  const targetHarness = opts.targetHarness ?? "pi";
40513
41171
  if (cortexkitDb !== null) {
40514
41172
  assertNoUnmigratedAuthority(cortexkitDb);
@@ -40535,8 +41193,8 @@ function migrateOpenCodeSessionToPi(opts) {
40535
41193
  migrationKey,
40536
41194
  sourceSessionId: session.id,
40537
41195
  targetHarness,
40538
- finalPathFor: (id) => join29(outputDir, `${formatPiFilenameTimestamp(now)}_${id}.jsonl`),
40539
- stageDir: join29(dirname21(piSessionsRoot), MIGRATION_STAGE_DIRNAME),
41196
+ finalPathFor: (id) => join30(outputDir, `${formatPiFilenameTimestamp(now)}_${id}.jsonl`),
41197
+ stageDir: join30(dirname22(piSessionsRoot), MIGRATION_STAGE_DIRNAME),
40540
41198
  now: now.getTime()
40541
41199
  });
40542
41200
  piSessionId = claimed.row.pi_session_id;
@@ -40545,7 +41203,7 @@ function migrateOpenCodeSessionToPi(opts) {
40545
41203
  journalResumed = claimed.resumed;
40546
41204
  } else {
40547
41205
  piSessionId = generateUuidV7(now);
40548
- finalPath = join29(outputDir, `${formatPiFilenameTimestamp(now)}_${piSessionId}.jsonl`);
41206
+ finalPath = join30(outputDir, `${formatPiFilenameTimestamp(now)}_${piSessionId}.jsonl`);
40549
41207
  stagePath = "";
40550
41208
  }
40551
41209
  const buildResult = buildPiEntries({
@@ -40584,11 +41242,11 @@ function migrateOpenCodeSessionToPi(opts) {
40584
41242
  `;
40585
41243
  if (!opts.dryRun) {
40586
41244
  if (journalActive && cortexkitDb !== null && migrationKey !== undefined && plan) {
40587
- const contentSha256 = createHash7("sha256").update(jsonl, "utf8").digest("hex");
41245
+ const contentSha256 = createHash8("sha256").update(jsonl, "utf8").digest("hex");
40588
41246
  commitStagedChecksum(cortexkitDb, migrationKey, contentSha256);
40589
41247
  fs.writeFileAtomic(stagePath, jsonl);
40590
41248
  plan.commit(migrationKey);
40591
- fs.mkdirSync(dirname21(finalPath), { recursive: true });
41249
+ fs.mkdirSync(dirname22(finalPath), { recursive: true });
40592
41250
  fs.renameSync(stagePath, finalPath);
40593
41251
  stmt(cortexkitDb, "DELETE FROM migration_pending WHERE migration_key = ?").run(migrationKey);
40594
41252
  } else {
@@ -42483,7 +43141,7 @@ var init_dist5 = __esm(() => {
42483
43141
  });
42484
43142
 
42485
43143
  // ../plugin/src/hooks/magic-context/reply-pages.ts
42486
- import { createHash as createHash8 } from "node:crypto";
43144
+ import { createHash as createHash9 } from "node:crypto";
42487
43145
  function fail() {
42488
43146
  throw Object.assign(new Error("Incomplete or invalid module reply; abandon this pass"), {
42489
43147
  code: "reply_page_invalid"
@@ -42518,7 +43176,7 @@ async function assembleReplyPages(response, fetchPage) {
42518
43176
  if (received !== bytes)
42519
43177
  fail();
42520
43178
  const rebuilt = Buffer.concat(chunks, received);
42521
- if (createHash8("sha256").update(rebuilt).digest("hex") !== id)
43179
+ if (createHash9("sha256").update(rebuilt).digest("hex") !== id)
42522
43180
  fail();
42523
43181
  return JSON.parse(rebuilt.toString("utf8"));
42524
43182
  }
@@ -42894,9 +43552,9 @@ var init_store_ahead_refusal = __esm(() => {
42894
43552
 
42895
43553
  // ../plugin/src/hooks/magic-context/module-transport.ts
42896
43554
  import { realpathSync as realpathSync7 } from "node:fs";
42897
- import { join as join30 } from "node:path";
43555
+ import { join as join31 } from "node:path";
42898
43556
  function getDefaultSubcConnectionFile() {
42899
- return join30(getDataDir(), "cortexkit", "run", "subc-connection.json");
43557
+ return join31(getDataDir(), "cortexkit", "run", "subc-connection.json");
42900
43558
  }
42901
43559
  function errorChainSome(error, predicate) {
42902
43560
  let current = error;
@@ -43504,9 +44162,9 @@ var init_module_transport = __esm(() => {
43504
44162
  });
43505
44163
 
43506
44164
  // src/commands/migrate-session.ts
43507
- import { existsSync as existsSync37, realpathSync as realpathSync8 } from "node:fs";
43508
- import { homedir as homedir19 } from "node:os";
43509
- import path6, { join as join31 } from "node:path";
44165
+ import { existsSync as existsSync39, realpathSync as realpathSync8 } from "node:fs";
44166
+ import { homedir as homedir20 } from "node:os";
44167
+ import path6, { join as join32 } from "node:path";
43510
44168
  function existingSessionColumns(db) {
43511
44169
  const rows = db.prepare("PRAGMA table_info(session)").all();
43512
44170
  return new Set(rows.map((r) => r.name).filter((n) => typeof n === "string"));
@@ -43687,14 +44345,14 @@ function defaultOpenCodeDbPath2() {
43687
44345
  return getOpenCodeDatabasePath();
43688
44346
  }
43689
44347
  function defaultContextDbPath() {
43690
- return join31(getMagicContextStorageDir(), "context.db");
44348
+ return join32(getMagicContextStorageDir(), "context.db");
43691
44349
  }
43692
44350
  function realDeps(opencodeDb, contextDb) {
43693
44351
  return {
43694
44352
  opencodeDb,
43695
44353
  contextDb,
43696
44354
  resolveIdentity: resolveProjectIdentity,
43697
- hasGitDir: (dir) => existsSync37(join31(dir, ".git")),
44355
+ hasGitDir: (dir) => existsSync39(join32(dir, ".git")),
43698
44356
  realpath: (p) => realpathSync8(p)
43699
44357
  };
43700
44358
  }
@@ -43772,8 +44430,8 @@ async function runMigrateSessionCli(args) {
43772
44430
  printMigrateSessionHelp();
43773
44431
  return 1;
43774
44432
  }
43775
- const expandedTo = toDir.startsWith("~") ? join31(homedir19(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
43776
- if (!existsSync37(expandedTo)) {
44433
+ const expandedTo = toDir.startsWith("~") ? join32(homedir20(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
44434
+ if (!existsSync39(expandedTo)) {
43777
44435
  console.error(`Target directory does not exist: ${expandedTo}`);
43778
44436
  return 1;
43779
44437
  }
@@ -43924,7 +44582,7 @@ var init_migrate_session = __esm(async () => {
43924
44582
  });
43925
44583
 
43926
44584
  // ../plugin/src/features/magic-context/v22-deferred-backfill.ts
43927
- import { createHash as createHash9 } from "node:crypto";
44585
+ import { createHash as createHash10 } from "node:crypto";
43928
44586
  import { realpathSync as realpathSync9 } from "node:fs";
43929
44587
  import path7 from "node:path";
43930
44588
  function readMeta(db, key) {
@@ -43973,7 +44631,7 @@ function computeLegacyRustDirIdentity(rawProjectPath) {
43973
44631
  } catch {
43974
44632
  canonical = path7.isAbsolute(rawProjectPath) ? rawProjectPath : path7.join(process.cwd(), rawProjectPath);
43975
44633
  }
43976
- return `dir:${createHash9("sha256").update(canonical, "utf8").digest("hex")}`;
44634
+ return `dir:${createHash10("sha256").update(canonical, "utf8").digest("hex")}`;
43977
44635
  }
43978
44636
  function upsertRekeyMap(db, oldProjectPath, newProjectPath, rekeyedAt) {
43979
44637
  db.prepare(`INSERT INTO v22_identity_rekey_map (old_project_path, new_project_path, rekeyed_at)
@@ -44194,7 +44852,7 @@ var init_tick_failure = __esm(() => {
44194
44852
  });
44195
44853
 
44196
44854
  // ../pi-plugin/src/config/index.ts
44197
- import { existsSync as existsSync38 } from "node:fs";
44855
+ import { existsSync as existsSync40 } from "node:fs";
44198
44856
  function getProjectConfigPaths(cwd) {
44199
44857
  const basePath = cortexKitProjectConfigBasePath(cwd);
44200
44858
  return [`${basePath}.jsonc`, `${basePath}.json`];
@@ -44204,10 +44862,10 @@ function getUserConfigPaths() {
44204
44862
  return [`${basePath}.jsonc`, `${basePath}.json`];
44205
44863
  }
44206
44864
  function resolveFirstExisting(paths) {
44207
- return paths.find((path) => existsSync38(path));
44865
+ return paths.find((path) => existsSync40(path));
44208
44866
  }
44209
44867
  function resolvePiLegacyFallback(sources) {
44210
- return sources.find((source) => existsSync38(source.path)) ?? null;
44868
+ return sources.find((source) => existsSync40(source.path)) ?? null;
44211
44869
  }
44212
44870
  function loadConfigFile(path, scope) {
44213
44871
  let raw;
@@ -44518,7 +45176,7 @@ function loadPiConfigDetailed(opts = {}, applyRuntimeGlobals = true) {
44518
45176
  if (loaded)
44519
45177
  loadedFiles.push(loaded);
44520
45178
  }
44521
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync38(source.path));
45179
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync40(source.path));
44522
45180
  const userPath = resolveFirstExisting(getUserConfigPaths());
44523
45181
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
44524
45182
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -44527,7 +45185,7 @@ function loadPiConfigDetailed(opts = {}, applyRuntimeGlobals = true) {
44527
45185
  if (loaded)
44528
45186
  loadedFiles.push(loaded);
44529
45187
  }
44530
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync38(source.path));
45188
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync40(source.path));
44531
45189
  if (userLegacyFallback) {
44532
45190
  warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
44533
45191
  } else if (legacyUserUnmigrated) {
@@ -44665,7 +45323,7 @@ var DATABASE_REPAIR_COMMAND = "bunx @cortexkit/magic-context@latest doctor repai
44665
45323
 
44666
45324
  // src/lib/github-issue.ts
44667
45325
  import { spawnSync as spawnSync7 } from "node:child_process";
44668
- import { readFileSync as readFileSync21 } from "node:fs";
45326
+ import { readFileSync as readFileSync22 } from "node:fs";
44669
45327
  function runGhCommand(args) {
44670
45328
  try {
44671
45329
  const result = spawnSync7("gh", args, {
@@ -44692,7 +45350,7 @@ function failed(result) {
44692
45350
  function submitGithubIssue(title, bodyPath, runner = runGhCommand) {
44693
45351
  let body;
44694
45352
  try {
44695
- body = readFileSync21(bodyPath, "utf-8");
45353
+ body = readFileSync22(bodyPath, "utf-8");
44696
45354
  } catch (error) {
44697
45355
  return {
44698
45356
  ok: false,
@@ -44750,9 +45408,9 @@ var MAX_GITHUB_ISSUE_BODY_CHARS = 65536;
44750
45408
  var init_github_issue = () => {};
44751
45409
 
44752
45410
  // src/lib/log-lines.ts
44753
- import { existsSync as existsSync39, readFileSync as readFileSync22, statSync as statSync17 } from "node:fs";
44754
- import { tmpdir as tmpdir2 } from "node:os";
44755
- import { join as join32 } from "node:path";
45411
+ import { existsSync as existsSync41, readFileSync as readFileSync23, statSync as statSync21 } from "node:fs";
45412
+ import { tmpdir as tmpdir3 } from "node:os";
45413
+ import { join as join33 } from "node:path";
44756
45414
  function tokenize(input, limit = Number.POSITIVE_INFINITY) {
44757
45415
  const tokens = [];
44758
45416
  let index = 0;
@@ -45038,20 +45696,20 @@ function parseLogLine(line) {
45038
45696
  }
45039
45697
  function getMagicContextLogPaths(harness, options = {}) {
45040
45698
  const override = options.override === undefined ? process.env.MAGIC_CONTEXT_LOG_PATH?.trim() : options.override?.trim();
45041
- const storageLogs = join32(options.storageDir ?? getMagicContextStorageDir(), "logs");
45699
+ const storageLogs = join33(options.storageDir ?? getMagicContextStorageDir(), "logs");
45042
45700
  return [
45043
45701
  ...override ? [override] : [],
45044
- join32(options.tempDir ?? tmpdir2(), harness, "magic-context", "magic-context.log"),
45045
- join32(storageLogs, `magic-context.${harness}.log`),
45046
- join32(storageLogs, "magic-context.log")
45702
+ join33(options.tempDir ?? tmpdir3(), harness, "magic-context", "magic-context.log"),
45703
+ join33(storageLogs, `magic-context.${harness}.log`),
45704
+ join33(storageLogs, "magic-context.log")
45047
45705
  ].filter((path, index, paths) => paths.indexOf(path) === index);
45048
45706
  }
45049
45707
  function inspectLogFile(path) {
45050
- if (!existsSync39(path)) {
45708
+ if (!existsSync41(path)) {
45051
45709
  return { path, exists: false, sizeKb: 0, lineCount: 0, grammar: "unknown" };
45052
45710
  }
45053
45711
  try {
45054
- const content = readFileSync22(path, "utf8");
45712
+ const content = readFileSync23(path, "utf8");
45055
45713
  const lines = content.split(/\r?\n/).filter((line) => line.length > 0);
45056
45714
  const grammars = new Set(lines.flatMap((line) => {
45057
45715
  const parsed = parseLogLine(line);
@@ -45061,7 +45719,7 @@ function inspectLogFile(path) {
45061
45719
  return {
45062
45720
  path,
45063
45721
  exists: true,
45064
- sizeKb: Math.round(statSync17(path).size / 1024),
45722
+ sizeKb: Math.round(statSync21(path).size / 1024),
45065
45723
  lineCount: lines.length,
45066
45724
  grammar
45067
45725
  };
@@ -45078,7 +45736,7 @@ function readLogLines(files) {
45078
45736
  return [];
45079
45737
  try {
45080
45738
  let precedingTimestamp = "";
45081
- return readFileSync22(file.path, "utf8").split(/\r?\n/).filter((line) => line.length > 0).map((line, lineIndex) => {
45739
+ return readFileSync23(file.path, "utf8").split(/\r?\n/).filter((line) => line.length > 0).map((line, lineIndex) => {
45082
45740
  precedingTimestamp = parseLogLine(line)?.ts ?? precedingTimestamp;
45083
45741
  return { line, timestamp: precedingTimestamp, fileIndex, lineIndex };
45084
45742
  });
@@ -45273,9 +45931,9 @@ var init_redaction2 = __esm(() => {
45273
45931
 
45274
45932
  // src/commands/doctor-omp.ts
45275
45933
  import { execFileSync as execFileSync8, spawnSync as spawnSync8 } from "node:child_process";
45276
- import { existsSync as existsSync40, readFileSync as readFileSync23 } from "node:fs";
45934
+ import { existsSync as existsSync42, readFileSync as readFileSync24 } from "node:fs";
45277
45935
  import { createRequire as createRequire3 } from "node:module";
45278
- import { isAbsolute as isAbsolute8, join as join33, resolve as resolve15 } from "node:path";
45936
+ import { isAbsolute as isAbsolute8, join as join34, resolve as resolve17 } from "node:path";
45279
45937
  function parseSemver(value) {
45280
45938
  const match = value?.match(/(\d+)\.(\d+)\.(\d+)/);
45281
45939
  return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
@@ -45317,10 +45975,10 @@ function selfVersion() {
45317
45975
  return "unknown";
45318
45976
  }
45319
45977
  function readConfig2(path) {
45320
- if (!existsSync40(path))
45978
+ if (!existsSync42(path))
45321
45979
  return {};
45322
45980
  try {
45323
- const parsed = import_comment_json8.parse(readFileSync23(path, "utf-8"));
45981
+ const parsed = import_comment_json8.parse(readFileSync24(path, "utf-8"));
45324
45982
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? {} : { error: "top level is not an object" };
45325
45983
  } catch (error) {
45326
45984
  return { error: error instanceof Error ? error.message : String(error) };
@@ -45330,7 +45988,7 @@ function pluginDeclaresOmp(path) {
45330
45988
  if (!path)
45331
45989
  return null;
45332
45990
  try {
45333
- const pkg = JSON.parse(readFileSync23(join33(path, "package.json"), "utf-8"));
45991
+ const pkg = JSON.parse(readFileSync24(join34(path, "package.json"), "utf-8"));
45334
45992
  return Array.isArray(pkg.omp?.extensions) || Array.isArray(pkg.pi?.extensions);
45335
45993
  } catch {
45336
45994
  return null;
@@ -45405,8 +46063,8 @@ async function runHealthChecks(options) {
45405
46063
  if (!reportedAgentDir.ok) {
45406
46064
  add(results, "warn", "Could not verify OMP active agent directory");
45407
46065
  } else {
45408
- const reportedPath = resolve15(reportedAgentDir.stdout);
45409
- const expectedPath = resolve15(getOmpAgentDir());
46066
+ const reportedPath = resolve17(reportedAgentDir.stdout);
46067
+ const expectedPath = resolve17(getOmpAgentDir());
45410
46068
  if (reportedPath === expectedPath) {
45411
46069
  add(results, "pass", `OMP agent directory resolved to ${getOmpAgentDir()}`);
45412
46070
  } else {
@@ -45417,7 +46075,7 @@ async function runHealthChecks(options) {
45417
46075
  }
45418
46076
  }
45419
46077
  const userConfigPath = getOmpUserConfigPath();
45420
- if (!existsSync40(userConfigPath)) {
46078
+ if (!existsSync42(userConfigPath)) {
45421
46079
  add(results, "warn", `No Magic Context user config at ${userConfigPath}`);
45422
46080
  repairPlan.writeUserConfig = true;
45423
46081
  } else {
@@ -45434,9 +46092,9 @@ async function runHealthChecks(options) {
45434
46092
  for (const warning of loaded.warnings.slice(0, 5))
45435
46093
  add(results, "warn", warning);
45436
46094
  const storage = getMagicContextStorageResolution();
45437
- const dbPath = join33(storage.path, "context.db");
46095
+ const dbPath = join34(storage.path, "context.db");
45438
46096
  add(results, "info", `Shared storage: ${storage.path} (source: ${storage.source})`);
45439
- if (!existsSync40(dbPath))
46097
+ if (!existsSync42(dbPath))
45440
46098
  add(results, "info", `Shared context DB will be created at ${dbPath}`);
45441
46099
  else {
45442
46100
  let db = null;
@@ -45501,7 +46159,7 @@ function writeDefaultConfig(path) {
45501
46159
  }
45502
46160
  async function repair(plan, deps, prompts, cwd) {
45503
46161
  let fixed = 0;
45504
- if (plan.writeUserConfig && !existsSync40(getOmpUserConfigPath())) {
46162
+ if (plan.writeUserConfig && !existsSync42(getOmpUserConfigPath())) {
45505
46163
  writeDefaultConfig(getOmpUserConfigPath());
45506
46164
  prompts.log.success(`Wrote default Magic Context config to ${getOmpUserConfigPath()}`);
45507
46165
  fixed += 1;
@@ -45617,7 +46275,7 @@ function runGhCommandWithDeps(deps, args) {
45617
46275
  async function runIssueFlow(options) {
45618
46276
  if (options.reportPath) {
45619
46277
  const report = await runHealthChecks({ ...options, quiet: true });
45620
- const path = isAbsolute8(options.reportPath) ? options.reportPath : join33(options.cwd, options.reportPath);
46278
+ const path = isAbsolute8(options.reportPath) ? options.reportPath : join34(options.cwd, options.reportPath);
45621
46279
  const bundle = writeOmpIssueReport(path, ompIssueBody("Generated non-interactively by `doctor --issue --report`.", report, readLogLines(report.logFiles), null));
45622
46280
  options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
45623
46281
  return 0;
@@ -45644,7 +46302,7 @@ async function runIssueFlow(options) {
45644
46302
  ]);
45645
46303
  sessionFilter = choice === "__all__" ? null : choice;
45646
46304
  }
45647
- const path = join33(options.cwd, `magic-context-omp-issue-${timestamp2(options.deps.now())}.md`);
46305
+ const path = join34(options.cwd, `magic-context-omp-issue-${timestamp2(options.deps.now())}.md`);
45648
46306
  const bundle = writeOmpIssueReport(path, ompIssueBody(description, report, logLines, sessionFilter));
45649
46307
  options.prompts.log.success(bundle.fullPath ? `Sanitized report written to ${bundle.path}; full report at ${bundle.fullPath}` : `Sanitized report written to ${bundle.path}`);
45650
46308
  if (await options.prompts.confirm("Submit this issue on GitHub now?", false)) {
@@ -45831,7 +46489,7 @@ function truncate2(text) {
45831
46489
  var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
45832
46490
 
45833
46491
  // ../plugin/src/features/magic-context/memory/embedding-synapse.ts
45834
- import { createHash as createHash10 } from "node:crypto";
46492
+ import { createHash as createHash11 } from "node:crypto";
45835
46493
  function toSynapseLaneDescriptor(metadata) {
45836
46494
  const tokenBudget = metadata.recommended_token_budget;
45837
46495
  return {
@@ -45971,7 +46629,7 @@ function wait(ms) {
45971
46629
  return new Promise((resolve) => setTimeout(resolve, ms));
45972
46630
  }
45973
46631
  function sha256(value) {
45974
- return createHash10("sha256").update(value).digest("hex");
46632
+ return createHash11("sha256").update(value).digest("hex");
45975
46633
  }
45976
46634
  function stableJson2(value) {
45977
46635
  if (Array.isArray(value))
@@ -46615,12 +47273,12 @@ function listShadowBackfillStalls(db, projectIdentity) {
46615
47273
  var SHADOW_BACKFILL_PROVENANCE_KEY = "_magicContextShadowBackfill";
46616
47274
 
46617
47275
  // ../plugin/src/shared/auto-update-provenance.ts
46618
- import { existsSync as existsSync41, readFileSync as readFileSync24 } from "node:fs";
47276
+ import { existsSync as existsSync43, readFileSync as readFileSync25 } from "node:fs";
46619
47277
  function readAutoUpdateCheckState(path) {
46620
- if (!existsSync41(path))
47278
+ if (!existsSync43(path))
46621
47279
  return null;
46622
47280
  try {
46623
- const value = JSON.parse(readFileSync24(path, "utf-8"));
47281
+ const value = JSON.parse(readFileSync25(path, "utf-8"));
46624
47282
  if (!value || typeof value !== "object" || Array.isArray(value))
46625
47283
  return null;
46626
47284
  const raw = value;
@@ -46647,15 +47305,15 @@ var init_auto_update_provenance = () => {};
46647
47305
 
46648
47306
  // ../plugin/src/shared/tui-config.ts
46649
47307
  import {
46650
- chmodSync as chmodSync3,
46651
- existsSync as existsSync42,
46652
- mkdirSync as mkdirSync6,
46653
- readFileSync as readFileSync25,
46654
- renameSync as renameSync7,
46655
- statSync as statSync18,
46656
- writeFileSync as writeFileSync6
47308
+ chmodSync as chmodSync4,
47309
+ existsSync as existsSync44,
47310
+ mkdirSync as mkdirSync7,
47311
+ readFileSync as readFileSync26,
47312
+ renameSync as renameSync8,
47313
+ statSync as statSync22,
47314
+ writeFileSync as writeFileSync7
46657
47315
  } from "node:fs";
46658
- import { dirname as dirname22, join as join34 } from "node:path";
47316
+ import { dirname as dirname23, join as join35 } from "node:path";
46659
47317
  function pluginEntryId(entry) {
46660
47318
  if (typeof entry === "string")
46661
47319
  return entry;
@@ -46686,21 +47344,21 @@ function writeTuiConfigAtomic(configPath, config) {
46686
47344
  const body = `${import_comment_json9.stringify(config, null, 2)}
46687
47345
  `;
46688
47346
  const tmpPath = `${configPath}.tmp`;
46689
- writeFileSync6(tmpPath, body);
47347
+ writeFileSync7(tmpPath, body);
46690
47348
  try {
46691
- if (statSync18(configPath, { throwIfNoEntry: false })?.isFile()) {
46692
- chmodSync3(tmpPath, statSync18(configPath).mode & 511);
47349
+ if (statSync22(configPath, { throwIfNoEntry: false })?.isFile()) {
47350
+ chmodSync4(tmpPath, statSync22(configPath).mode & 511);
46693
47351
  }
46694
47352
  } catch {}
46695
- renameSync7(tmpPath, configPath);
47353
+ renameSync8(tmpPath, configPath);
46696
47354
  }
46697
47355
  function resolveTuiConfigPath(configDirOverride) {
46698
47356
  const configDir = configDirOverride ?? getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
46699
- const jsoncPath = join34(configDir, "tui.jsonc");
46700
- const jsonPath = join34(configDir, "tui.json");
46701
- if (existsSync42(jsoncPath))
47357
+ const jsoncPath = join35(configDir, "tui.jsonc");
47358
+ const jsonPath = join35(configDir, "tui.json");
47359
+ if (existsSync44(jsoncPath))
46702
47360
  return jsoncPath;
46703
- if (existsSync42(jsonPath))
47361
+ if (existsSync44(jsonPath))
46704
47362
  return jsonPath;
46705
47363
  return jsoncPath;
46706
47364
  }
@@ -46708,8 +47366,8 @@ function ensureTuiPluginEntry(options = {}) {
46708
47366
  try {
46709
47367
  const configPath = resolveTuiConfigPath(options.configDir);
46710
47368
  let config = {};
46711
- if (existsSync42(configPath)) {
46712
- const raw = readFileSync25(configPath, "utf-8");
47369
+ if (existsSync44(configPath)) {
47370
+ const raw = readFileSync26(configPath, "utf-8");
46713
47371
  config = import_comment_json9.parse(raw) ?? {};
46714
47372
  }
46715
47373
  const plugins = Array.isArray(config.plugin) ? [...config.plugin] : [];
@@ -46743,7 +47401,7 @@ function ensureTuiPluginEntry(options = {}) {
46743
47401
  }
46744
47402
  }
46745
47403
  config.plugin = plugins;
46746
- mkdirSync6(dirname22(configPath), { recursive: true });
47404
+ mkdirSync7(dirname23(configPath), { recursive: true });
46747
47405
  writeTuiConfigAtomic(configPath, config);
46748
47406
  log(`[magic-context] updated TUI plugin entry in ${configPath}`);
46749
47407
  return true;
@@ -46761,9 +47419,9 @@ var init_tui_config = __esm(() => {
46761
47419
  });
46762
47420
 
46763
47421
  // src/lib/diagnostics-opencode.ts
46764
- import { existsSync as existsSync43, readdirSync as readdirSync9, readFileSync as readFileSync26, statSync as statSync19 } from "node:fs";
47422
+ import { existsSync as existsSync45, readdirSync as readdirSync9, readFileSync as readFileSync27, statSync as statSync23 } from "node:fs";
46765
47423
  import { createRequire as createRequire4 } from "node:module";
46766
- import { join as join35 } from "node:path";
47424
+ import { join as join36 } from "node:path";
46767
47425
  function getSelfVersion() {
46768
47426
  const require2 = createRequire4(import.meta.url);
46769
47427
  for (const relPath of ["../../package.json", "../package.json"]) {
@@ -46778,7 +47436,7 @@ function getSelfVersion() {
46778
47436
  }
46779
47437
  function readLegacyCachedVersion(root) {
46780
47438
  try {
46781
- const pkg = JSON.parse(readFileSync26(getOpenCodePluginPackageJsonPath(root), "utf-8"));
47439
+ const pkg = JSON.parse(readFileSync27(getOpenCodePluginPackageJsonPath(root), "utf-8"));
46782
47440
  return typeof pkg.version === "string" ? pkg.version : undefined;
46783
47441
  } catch {
46784
47442
  return;
@@ -46787,7 +47445,7 @@ function readLegacyCachedVersion(root) {
46787
47445
  function collectOpenCodePluginCacheReport(hostGeneration, opencodeConfig) {
46788
47446
  const installs = [];
46789
47447
  for (const root of getOpenCodePluginCacheRoots()) {
46790
- if (!existsSync43(root))
47448
+ if (!existsSync45(root))
46791
47449
  continue;
46792
47450
  const spec = root.endsWith("@latest") ? "latest" : "(bare)";
46793
47451
  installs.push({
@@ -46821,7 +47479,7 @@ function getStorageResolution() {
46821
47479
  }
46822
47480
  function fileSize(path) {
46823
47481
  try {
46824
- return existsSync43(path) ? statSync19(path).size : 0;
47482
+ return existsSync45(path) ? statSync23(path).size : 0;
46825
47483
  } catch {
46826
47484
  return 0;
46827
47485
  }
@@ -46833,10 +47491,10 @@ function sanitizeValue(value) {
46833
47491
  return sanitizeConfigValue(value);
46834
47492
  }
46835
47493
  function readConfig3(path) {
46836
- if (!existsSync43(path))
47494
+ if (!existsSync45(path))
46837
47495
  return { value: null };
46838
47496
  try {
46839
- const raw = readFileSync26(path, "utf-8");
47497
+ const raw = readFileSync27(path, "utf-8");
46840
47498
  const value = import_comment_json10.parse(raw);
46841
47499
  return { value };
46842
47500
  } catch (error) {
@@ -46861,7 +47519,7 @@ function configHasPluginEntry(config) {
46861
47519
  }
46862
47520
  function parseHistorianDumpMeta(path) {
46863
47521
  try {
46864
- const xml = readFileSync26(path, "utf-8");
47522
+ const xml = readFileSync27(path, "utf-8");
46865
47523
  const parsed = parseCompartmentOutput(xml);
46866
47524
  const factCountByCategory = {};
46867
47525
  for (const fact of parsed.facts) {
@@ -46894,11 +47552,11 @@ function parseHistorianDumpMeta(path) {
46894
47552
  }
46895
47553
  }
46896
47554
  function listDumpsInDir(dir, limit) {
46897
- if (!existsSync43(dir))
47555
+ if (!existsSync45(dir))
46898
47556
  return { count: 0, recent: [] };
46899
47557
  try {
46900
47558
  const entries = readdirSync9(dir).filter((name) => name.endsWith(".xml")).map((name) => {
46901
- const stat = statSync19(join35(dir, name));
47559
+ const stat = statSync23(join36(dir, name));
46902
47560
  return {
46903
47561
  name,
46904
47562
  mtime: stat.mtimeMs,
@@ -46907,7 +47565,7 @@ function listDumpsInDir(dir, limit) {
46907
47565
  }).sort((a, b) => b.mtime - a.mtime);
46908
47566
  const now = Date.now();
46909
47567
  const recent = entries.slice(0, limit).map((entry) => {
46910
- const meta = parseHistorianDumpMeta(join35(dir, entry.name));
47568
+ const meta = parseHistorianDumpMeta(join36(dir, entry.name));
46911
47569
  const summary = {
46912
47570
  name: entry.name,
46913
47571
  ageMinutes: Math.round((now - entry.mtime) / 60000),
@@ -47018,7 +47676,7 @@ function collectRecentSessionsFromDatabase(database) {
47018
47676
  });
47019
47677
  }
47020
47678
  async function collectDatabaseRows(path, read) {
47021
- if (!existsSync43(path))
47679
+ if (!existsSync45(path))
47022
47680
  return { available: false, reason: "path missing" };
47023
47681
  let backend;
47024
47682
  try {
@@ -47050,7 +47708,7 @@ async function collectRecentSessions(resolution, hostGeneration) {
47050
47708
  });
47051
47709
  }
47052
47710
  async function collectHistorianFailures(storageDirPath) {
47053
- return collectDatabaseRows(join35(storageDirPath, "context.db"), (db) => {
47711
+ return collectDatabaseRows(join36(storageDirPath, "context.db"), (db) => {
47054
47712
  const rows = db.prepare("SELECT session_id, historian_failure_count, historian_last_error, historian_last_failure_at FROM session_meta WHERE historian_failure_count > 0 ORDER BY historian_last_failure_at DESC LIMIT 10").all();
47055
47713
  return rows.map((row) => {
47056
47714
  const sessionId = typeof row.session_id === "string" ? row.session_id : "<unknown>";
@@ -47063,7 +47721,7 @@ async function collectHistorianFailures(storageDirPath) {
47063
47721
  });
47064
47722
  }
47065
47723
  async function collectHistorianRuns(storageDirPath) {
47066
- return collectDatabaseRows(join35(storageDirPath, "context.db"), (db) => {
47724
+ return collectDatabaseRows(join36(storageDirPath, "context.db"), (db) => {
47067
47725
  const aggRows = db.prepare(`SELECT session_id,
47068
47726
  COUNT(*) AS total,
47069
47727
  SUM(CASE WHEN status='success' THEN 1 ELSE 0 END) AS success,
@@ -47117,7 +47775,7 @@ async function collectDiagnostics() {
47117
47775
  const magicContextConfig = readConfig3(configPaths.magicContextConfig);
47118
47776
  const storageResolution = getStorageResolution();
47119
47777
  const storageDirPath = storageResolution.path;
47120
- const contextDbPath = join35(storageDirPath, "context.db");
47778
+ const contextDbPath = join36(storageDirPath, "context.db");
47121
47779
  let compactionEnabled = false;
47122
47780
  try {
47123
47781
  compactionEnabled = isCompactionEnabled(loadPluginConfig(process.cwd()));
@@ -47149,7 +47807,7 @@ async function collectDiagnostics() {
47149
47807
  opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
47150
47808
  tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
47151
47809
  magicContextConfig: {
47152
- exists: existsSync43(configPaths.magicContextConfig),
47810
+ exists: existsSync45(configPaths.magicContextConfig),
47153
47811
  ...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
47154
47812
  flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
47155
47813
  },
@@ -47157,7 +47815,7 @@ async function collectDiagnostics() {
47157
47815
  storageDir: {
47158
47816
  path: storageDirPath,
47159
47817
  source: storageResolution.source,
47160
- exists: existsSync43(storageDirPath),
47818
+ exists: existsSync45(storageDirPath),
47161
47819
  contextDbSizeBytes: fileSize(contextDbPath)
47162
47820
  },
47163
47821
  openCodeDatabase: {
@@ -47407,9 +48065,9 @@ var init_embedding_local = __esm(() => {
47407
48065
 
47408
48066
  // src/lib/embedding-runtime.ts
47409
48067
  import { spawnSync as spawnSync9 } from "node:child_process";
47410
- import { existsSync as existsSync44, readFileSync as readFileSync27 } from "node:fs";
48068
+ import { existsSync as existsSync46, readFileSync as readFileSync28 } from "node:fs";
47411
48069
  import { createRequire as createRequire5 } from "node:module";
47412
- import { dirname as dirname23, join as join36, sep } from "node:path";
48070
+ import { dirname as dirname24, join as join37, sep } from "node:path";
47413
48071
  function describeError(error) {
47414
48072
  const message = error instanceof Error ? error.message : String(error ?? "unknown error");
47415
48073
  const code = error?.code;
@@ -47551,11 +48209,11 @@ function expectedBinaryRelPath(platform, arch) {
47551
48209
  const supportedArch = arch === "x64" || arch === "arm64";
47552
48210
  if (!supportedPlatform || !supportedArch)
47553
48211
  return null;
47554
- return join36("bin", "napi-v6", platform, arch, "onnxruntime_binding.node");
48212
+ return join37("bin", "napi-v6", platform, arch, "onnxruntime_binding.node");
47555
48213
  }
47556
48214
  function onnxRuntimeNodeVersion(packageDir) {
47557
48215
  try {
47558
- const parsed = JSON.parse(readFileSync27(join36(packageDir, "package.json"), "utf8"));
48216
+ const parsed = JSON.parse(readFileSync28(join37(packageDir, "package.json"), "utf8"));
47559
48217
  return typeof parsed.version === "string" ? parsed.version : undefined;
47560
48218
  } catch {
47561
48219
  return;
@@ -47604,7 +48262,7 @@ function formatLocalEmbeddingRuntimeWasmSelected(status) {
47604
48262
  function requireNodeWasmBundle(probe, candidates) {
47605
48263
  if (probe.state === "failed")
47606
48264
  return probe;
47607
- const bundlePath = candidates.find((candidate) => existsSync44(candidate));
48265
+ const bundlePath = candidates.find((candidate) => existsSync46(candidate));
47608
48266
  return bundlePath ? probe : {
47609
48267
  state: "failed",
47610
48268
  reason: `functional Node WASM Transformers bundle is missing (checked ${candidates.join(", ")})`
@@ -47612,13 +48270,13 @@ function requireNodeWasmBundle(probe, candidates) {
47612
48270
  }
47613
48271
  function nodeWasmBundleCandidates(installRoot) {
47614
48272
  return [
47615
- join36(installRoot, "dist", "transformers-node-wasm.js"),
47616
- join36(installRoot, "node_modules", "@cortexkit", "opencode-magic-context", "dist", "transformers-node-wasm.js"),
47617
- join36(installRoot, "node_modules", "@cortexkit", "pi-magic-context", "dist", "transformers-node-wasm.js")
48273
+ join37(installRoot, "dist", "transformers-node-wasm.js"),
48274
+ join37(installRoot, "node_modules", "@cortexkit", "opencode-magic-context", "dist", "transformers-node-wasm.js"),
48275
+ join37(installRoot, "node_modules", "@cortexkit", "pi-magic-context", "dist", "transformers-node-wasm.js")
47618
48276
  ];
47619
48277
  }
47620
48278
  function probeWasmRuntimeAt(installRoot) {
47621
- const requireFn = createRequire5(join36(installRoot, "package.json"));
48279
+ const requireFn = createRequire5(join37(installRoot, "package.json"));
47622
48280
  return requireNodeWasmBundle(probeWasmRuntimeFromRequire(requireFn), nodeWasmBundleCandidates(installRoot));
47623
48281
  }
47624
48282
  function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
@@ -47627,9 +48285,9 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
47627
48285
  const wasm = probeWasmRuntimeAt(installRoot);
47628
48286
  return wasm.state === "ok" ? { state: "wasm-selected", wasmPath: wasm.wasmPath } : { state: "wasm-broken", wasmReason: wasm.reason };
47629
48287
  }
47630
- const packageDir = join36(installRoot, "node_modules", "onnxruntime-node");
48288
+ const packageDir = join37(installRoot, "node_modules", "onnxruntime-node");
47631
48289
  let native;
47632
- if (!existsSync44(join36(packageDir, "package.json"))) {
48290
+ if (!existsSync46(join37(packageDir, "package.json"))) {
47633
48291
  native = { state: "package-missing", packageDir };
47634
48292
  } else {
47635
48293
  const rel = expectedBinaryRelPath(platform, arch);
@@ -47639,8 +48297,8 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
47639
48297
  binaryPath: packageDir
47640
48298
  };
47641
48299
  } else {
47642
- const binaryPath = join36(packageDir, rel);
47643
- native = existsSync44(binaryPath) ? probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath } : {
48300
+ const binaryPath = join37(packageDir, rel);
48301
+ native = existsSync46(binaryPath) ? probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath } : {
47644
48302
  state: "binary-missing",
47645
48303
  packageDir,
47646
48304
  expectedBinary: binaryPath,
@@ -47651,7 +48309,7 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
47651
48309
  return withWasmFallback(native, () => probeWasmRuntimeAt(installRoot));
47652
48310
  }
47653
48311
  function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
47654
- const existing = installRoots.filter((root) => existsSync44(root));
48312
+ const existing = installRoots.filter((root) => existsSync46(root));
47655
48313
  if (existing.length === 0) {
47656
48314
  return {
47657
48315
  state: "unknown",
@@ -47677,19 +48335,19 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
47677
48335
  function packageDirFromResolved(resolvedPath, packageName) {
47678
48336
  const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
47679
48337
  const idx = resolvedPath.indexOf(marker);
47680
- return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname23(resolvedPath);
48338
+ return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname24(resolvedPath);
47681
48339
  }
47682
48340
  function probeWasmRuntimeByResolution(pluginDir) {
47683
48341
  try {
47684
- const reqPlugin = createRequire5(join36(pluginDir, "package.json"));
48342
+ const reqPlugin = createRequire5(join37(pluginDir, "package.json"));
47685
48343
  const direct = probeWasmRuntimeFromRequire(reqPlugin);
47686
48344
  let probe = direct;
47687
48345
  if (direct.state === "failed" && direct.reason.startsWith("onnxruntime-web is not resolvable")) {
47688
48346
  const tfResolved = reqPlugin.resolve("@huggingface/transformers");
47689
48347
  const tfDir = packageDirFromResolved(tfResolved, "@huggingface/transformers");
47690
- probe = probeWasmRuntimeFromRequire(createRequire5(join36(tfDir, "package.json")));
48348
+ probe = probeWasmRuntimeFromRequire(createRequire5(join37(tfDir, "package.json")));
47691
48349
  }
47692
- return requireNodeWasmBundle(probe, [join36(pluginDir, "dist", "transformers-node-wasm.js")]);
48350
+ return requireNodeWasmBundle(probe, [join37(pluginDir, "dist", "transformers-node-wasm.js")]);
47693
48351
  } catch (error) {
47694
48352
  return {
47695
48353
  state: "failed",
@@ -47698,7 +48356,7 @@ function probeWasmRuntimeByResolution(pluginDir) {
47698
48356
  }
47699
48357
  }
47700
48358
  function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch, runtimePreference = "auto", host) {
47701
- if (!existsSync44(join36(pluginDir, "package.json"))) {
48359
+ if (!existsSync46(join37(pluginDir, "package.json"))) {
47702
48360
  return { state: "unknown", reason: "plugin package dir not found" };
47703
48361
  }
47704
48362
  const selectedRuntime = resolveLocalEmbeddingWorkerRuntime(runtimePreference, host);
@@ -47709,13 +48367,13 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
47709
48367
  let onnxDir = null;
47710
48368
  let resolveError;
47711
48369
  try {
47712
- const reqPlugin = createRequire5(join36(pluginDir, "package.json"));
48370
+ const reqPlugin = createRequire5(join37(pluginDir, "package.json"));
47713
48371
  try {
47714
48372
  onnxDir = packageDirFromResolved(reqPlugin.resolve("onnxruntime-node"), "onnxruntime-node");
47715
48373
  } catch {
47716
48374
  const tfResolved = reqPlugin.resolve("@huggingface/transformers");
47717
48375
  const tfDir = packageDirFromResolved(tfResolved, "@huggingface/transformers");
47718
- const reqTf = createRequire5(join36(tfDir, "package.json"));
48376
+ const reqTf = createRequire5(join37(tfDir, "package.json"));
47719
48377
  onnxDir = packageDirFromResolved(reqTf.resolve("onnxruntime-node"), "onnxruntime-node");
47720
48378
  }
47721
48379
  } catch (error) {
@@ -47723,7 +48381,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
47723
48381
  if (resolveError === "ERR_MODULE_NOT_FOUND" || resolveError === "MODULE_NOT_FOUND") {
47724
48382
  return withWasmFallback({
47725
48383
  state: "package-missing",
47726
- packageDir: join36(pluginDir, "node_modules", "onnxruntime-node")
48384
+ packageDir: join37(pluginDir, "node_modules", "onnxruntime-node")
47727
48385
  }, () => probeWasmRuntimeByResolution(pluginDir));
47728
48386
  }
47729
48387
  return {
@@ -47739,8 +48397,8 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
47739
48397
  if (rel === null) {
47740
48398
  native = probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
47741
48399
  } else {
47742
- const binaryPath = join36(onnxDir, rel);
47743
- native = existsSync44(binaryPath) ? probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath } : {
48400
+ const binaryPath = join37(onnxDir, rel);
48401
+ native = existsSync46(binaryPath) ? probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath } : {
47744
48402
  state: "binary-missing",
47745
48403
  packageDir: onnxDir,
47746
48404
  expectedBinary: binaryPath,
@@ -47775,8 +48433,8 @@ var init_embedding_runtime = __esm(() => {
47775
48433
  });
47776
48434
 
47777
48435
  // src/lib/logs-opencode.ts
47778
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "node:fs";
47779
- import { dirname as dirname24, join as join37 } from "node:path";
48436
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
48437
+ import { dirname as dirname25, join as join38 } from "node:path";
47780
48438
  function sanitizeLogContent(content) {
47781
48439
  return sanitizeDiagnosticText(content);
47782
48440
  }
@@ -47869,13 +48527,13 @@ async function bundleIssueReport(report, description, title, sessionFilter = nul
47869
48527
  const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
47870
48528
  const truncated = bodyMarkdown !== rawBodyMarkdown;
47871
48529
  const timestamp = formatTimestamp(new Date);
47872
- const path = options.outputPath ?? join37(process.cwd(), `magic-context-issue-${timestamp}.md`);
47873
- mkdirSync7(dirname24(path), { recursive: true });
47874
- writeFileSync7(path, `${bodyMarkdown}
48530
+ const path = options.outputPath ?? join38(process.cwd(), `magic-context-issue-${timestamp}.md`);
48531
+ mkdirSync8(dirname25(path), { recursive: true });
48532
+ writeFileSync8(path, `${bodyMarkdown}
47875
48533
  `);
47876
- const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join37(process.cwd(), `magic-context-issue-${timestamp}-full.md`) : undefined;
48534
+ const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join38(process.cwd(), `magic-context-issue-${timestamp}-full.md`) : undefined;
47877
48535
  if (fullPath)
47878
- writeFileSync7(fullPath, `${rawBodyMarkdown}
48536
+ writeFileSync8(fullPath, `${rawBodyMarkdown}
47879
48537
  `);
47880
48538
  return { path, bodyMarkdown, ...fullPath ? { fullPath } : {}, truncated };
47881
48539
  }
@@ -48686,10 +49344,10 @@ function removeDeprecatedReasoningAge(config) {
48686
49344
 
48687
49345
  // src/commands/doctor-opencode.ts
48688
49346
  import { spawnSync as spawnSync10 } from "node:child_process";
48689
- import { existsSync as existsSync45, mkdtempSync as mkdtempSync3, readFileSync as readFileSync28, rmSync as rmSync8 } from "node:fs";
49347
+ import { existsSync as existsSync47, mkdtempSync as mkdtempSync4, readFileSync as readFileSync29, rmSync as rmSync9 } from "node:fs";
48690
49348
  import { createRequire as createRequire6 } from "node:module";
48691
- import { homedir as homedir20, tmpdir as tmpdir3 } from "node:os";
48692
- import { dirname as dirname25, join as join38, resolve as resolve16 } from "node:path";
49349
+ import { homedir as homedir21, tmpdir as tmpdir4 } from "node:os";
49350
+ import { dirname as dirname26, join as join39, resolve as resolve18 } from "node:path";
48693
49351
  function formatSharedDbRowCounts(db) {
48694
49352
  return SHARED_DB_ROW_COUNT_TABLES.map((table) => {
48695
49353
  try {
@@ -48758,7 +49416,7 @@ function checkConfiguredVariantCatalog(config, hostGeneration, warn, run = (args
48758
49416
  }
48759
49417
  if (models.length === 0)
48760
49418
  return;
48761
- const tempRoot = mkdtempSync3(join38(tmpdir3(), "magic-context-opencode-catalog-"));
49419
+ const tempRoot = mkdtempSync4(join39(tmpdir4(), "magic-context-opencode-catalog-"));
48762
49420
  try {
48763
49421
  const command = hostGeneration === "v2" ? ["api", "model.list", "--param", `directory=${projectDir}`] : ["models", "--verbose"];
48764
49422
  const guidance = `opencode ${command.join(" ")}`;
@@ -48777,7 +49435,7 @@ function checkConfiguredVariantCatalog(config, hostGeneration, warn, run = (args
48777
49435
  warn(`${entry.agent} model ${entry.model} requests variant '${entry.variant}', which this host does not offer. Remove the variant or choose one listed by ${guidance}.`);
48778
49436
  }
48779
49437
  } finally {
48780
- rmSync8(tempRoot, { recursive: true, force: true });
49438
+ rmSync9(tempRoot, { recursive: true, force: true });
48781
49439
  }
48782
49440
  }
48783
49441
  function parseOpenCodeV2ModelCatalog(output) {
@@ -48934,7 +49592,7 @@ function getSelfVersion2() {
48934
49592
  function describeAutoUpdateStall(specifier, autoUpdateEnabled, storageDir = getMagicContextStorageDir()) {
48935
49593
  if (!autoUpdateEnabled || !isPinnedOpenCodePluginSpecifier(specifier))
48936
49594
  return null;
48937
- const state = readAutoUpdateCheckState(join38(storageDir, AUTO_UPDATE_CHECK_STATE_FILENAME));
49595
+ const state = readAutoUpdateCheckState(join39(storageDir, AUTO_UPDATE_CHECK_STATE_FILENAME));
48938
49596
  const owner = isUpdaterPinnedSpec(state, specifier) ? "updater" : "you";
48939
49597
  return `auto-update: stalled — config pinned to ${specifier} (by ${owner})`;
48940
49598
  }
@@ -48943,15 +49601,15 @@ function getUserNpmrcPath() {
48943
49601
  if (custom)
48944
49602
  return custom;
48945
49603
  const home = process.env.HOME?.trim();
48946
- return join38(home || homedir20(), ".npmrc");
49604
+ return join39(home || homedir21(), ".npmrc");
48947
49605
  }
48948
49606
  function collectNpmReleaseAgeWarnings() {
48949
49607
  const ageWarnings = [];
48950
49608
  const npmrcPath = getUserNpmrcPath();
48951
- if (!existsSync45(npmrcPath))
49609
+ if (!existsSync47(npmrcPath))
48952
49610
  return ageWarnings;
48953
49611
  try {
48954
- const npmrc = readFileSync28(npmrcPath, "utf-8");
49612
+ const npmrc = readFileSync29(npmrcPath, "utf-8");
48955
49613
  for (const line of npmrc.split(`
48956
49614
  `)) {
48957
49615
  const trimmed = line.trim();
@@ -48965,7 +49623,7 @@ function collectNpmReleaseAgeWarnings() {
48965
49623
  } catch {}
48966
49624
  return ageWarnings;
48967
49625
  }
48968
- function compareVersions(a, b) {
49626
+ function compareVersions2(a, b) {
48969
49627
  return compareSemverPrecedence(a, b);
48970
49628
  }
48971
49629
  function openBrowser(url) {
@@ -48992,7 +49650,7 @@ async function runIssueFlow2(options = {}, deps = { collectDiagnostics }) {
48992
49650
  if (options.reportPath) {
48993
49651
  try {
48994
49652
  const report = await deps.collectDiagnostics();
48995
- const bundled = await bundleIssueReport(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", null, { outputPath: resolve16(process.cwd(), options.reportPath) });
49653
+ const bundled = await bundleIssueReport(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", null, { outputPath: resolve18(process.cwd(), options.reportPath) });
48996
49654
  log3.info(bundled.fullPath ? `Report written to ${bundled.path}; full bundle at ${bundled.fullPath}` : `Report written to ${bundled.path}`);
48997
49655
  return 0;
48998
49656
  } catch (error) {
@@ -49086,7 +49744,7 @@ function checkLocalEmbeddingRuntimeForDoctor(runtimePreference = "auto") {
49086
49744
  return { issues: 0 };
49087
49745
  }
49088
49746
  async function checkEmbeddingConfig(magicContextConfigPath) {
49089
- if (!existsSync45(magicContextConfigPath)) {
49747
+ if (!existsSync47(magicContextConfigPath)) {
49090
49748
  return checkLocalEmbeddingRuntimeForDoctor();
49091
49749
  }
49092
49750
  let rawText;
@@ -49244,7 +49902,7 @@ function getOpenCodePluginHostStatus(hostLabel, hostVersion, installed) {
49244
49902
  message: `${hostLabel} found; Magic Context is not installed there (run setup to add it)`
49245
49903
  };
49246
49904
  }
49247
- if (openCodeHostGenerationFromVersion(hostVersion) === "v2" && compareVersions(hostVersion, "2.0.22") === -1) {
49905
+ if (openCodeHostGenerationFromVersion(hostVersion) === "v2" && compareVersions2(hostVersion, "2.0.22") === -1) {
49248
49906
  return {
49249
49907
  status: "fail",
49250
49908
  message: describeOpenCode2SessionAPIRequirement(hostVersion)
@@ -49261,7 +49919,7 @@ async function runDoctor2(options = {}) {
49261
49919
  const v22Result = await runV22BackfillCommands({
49262
49920
  name: "OpenCode",
49263
49921
  openDatabase: (readonly = true) => {
49264
- const dbPath = join38(getMagicContextStorageDir(), "context.db");
49922
+ const dbPath = join39(getMagicContextStorageDir(), "context.db");
49265
49923
  v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
49266
49924
  return v22Db;
49267
49925
  },
@@ -49293,7 +49951,7 @@ async function runDoctor2(options = {}) {
49293
49951
  failCount++;
49294
49952
  issues++;
49295
49953
  };
49296
- const authorityDbPath = join38(getMagicContextStorageDir(), "context.db");
49954
+ const authorityDbPath = join39(getMagicContextStorageDir(), "context.db");
49297
49955
  let authorityDb = null;
49298
49956
  try {
49299
49957
  authorityDb = openExistingContextDatabase(authorityDbPath, { readonly: true });
@@ -49332,8 +49990,8 @@ async function runDoctor2(options = {}) {
49332
49990
  let magicContextStatusKnown = paths.opencodeConfigFormat === "none";
49333
49991
  if (!magicContextStatusKnown) {
49334
49992
  try {
49335
- const config = import_comment_json11.parse(readFileSync28(paths.opencodeConfig, "utf-8"));
49336
- magicContextInstalled = isOpenCodePluginRegistered(config, dirname25(paths.opencodeConfig));
49993
+ const config = import_comment_json11.parse(readFileSync29(paths.opencodeConfig, "utf-8"));
49994
+ magicContextInstalled = isOpenCodePluginRegistered(config, dirname26(paths.opencodeConfig));
49337
49995
  magicContextStatusKnown = true;
49338
49996
  } catch {}
49339
49997
  }
@@ -49452,7 +50110,7 @@ async function runDoctor2(options = {}) {
49452
50110
  }
49453
50111
  const selfVersion = getSelfVersion2();
49454
50112
  const npmLatest = await fetchNpmLatest(CLI_PACKAGE_NAME);
49455
- const cliComparison = npmLatest ? compareVersions(selfVersion, npmLatest) : null;
50113
+ const cliComparison = npmLatest ? compareVersions2(selfVersion, npmLatest) : null;
49456
50114
  if (!npmLatest) {
49457
50115
  log3.info(`Magic Context CLI v${selfVersion}; npm latest check unavailable`);
49458
50116
  } else if (cliComparison === null) {
@@ -49468,7 +50126,7 @@ async function runDoctor2(options = {}) {
49468
50126
  pass(`OpenCode config: ${paths.opencodeConfig}`);
49469
50127
  }
49470
50128
  let autoUpdateEnabled = true;
49471
- if (existsSync45(paths.magicContextConfig)) {
50129
+ if (existsSync47(paths.magicContextConfig)) {
49472
50130
  pass(`Magic Context config: ${paths.magicContextConfig}`);
49473
50131
  try {
49474
50132
  const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
@@ -49504,7 +50162,7 @@ async function runDoctor2(options = {}) {
49504
50162
  warn(`No magic-context.jsonc found — using defaults`);
49505
50163
  log3.info(" Run 'setup' to create one with model recommendations");
49506
50164
  }
49507
- if (existsSync45(paths.magicContextConfig)) {
50165
+ if (existsSync47(paths.magicContextConfig)) {
49508
50166
  try {
49509
50167
  const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
49510
50168
  if (!raw)
@@ -49644,10 +50302,10 @@ async function runDoctor2(options = {}) {
49644
50302
  };
49645
50303
  if (paths.opencodeConfigFormat !== "none") {
49646
50304
  try {
49647
- const raw = readFileSync28(paths.opencodeConfig, "utf-8");
50305
+ const raw = readFileSync29(paths.opencodeConfig, "utf-8");
49648
50306
  const config = import_comment_json11.parse(raw);
49649
50307
  const configName = paths.opencodeConfigFormat === "jsonc" ? "opencode.jsonc" : "opencode.json";
49650
- const configDir = dirname25(paths.opencodeConfig);
50308
+ const configDir = dirname26(paths.opencodeConfig);
49651
50309
  magicContextInstalled = isOpenCodePluginRegistered(config, configDir);
49652
50310
  magicContextStatusKnown = true;
49653
50311
  if (magicContextInstalled) {
@@ -49737,11 +50395,11 @@ async function runDoctor2(options = {}) {
49737
50395
  pass("Added TUI sidebar plugin to tui.json");
49738
50396
  warn("Restart OpenCode to see the sidebar");
49739
50397
  fixed++;
49740
- } else if (existsSync45(paths.tuiConfig)) {
50398
+ } else if (existsSync47(paths.tuiConfig)) {
49741
50399
  try {
49742
- const tuiRaw = readFileSync28(paths.tuiConfig, "utf-8");
50400
+ const tuiRaw = readFileSync29(paths.tuiConfig, "utf-8");
49743
50401
  const tuiConfig = import_comment_json11.parse(tuiRaw);
49744
- const tuiConfigDir = dirname25(paths.tuiConfig);
50402
+ const tuiConfigDir = dirname26(paths.tuiConfig);
49745
50403
  const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
49746
50404
  const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, OPENCODE_PLUGIN_NAME) || isDevPathPluginEntry(entry, tuiConfigDir));
49747
50405
  if (tuiRawPlugins.some((entry) => isLocalPathPluginEntry(entry) && String(entry).includes("magic-context") && !isDevPathPluginEntry(entry, tuiConfigDir))) {
@@ -49778,7 +50436,7 @@ async function runDoctor2(options = {}) {
49778
50436
  fail("Could not create or verify the TUI sidebar config");
49779
50437
  }
49780
50438
  }
49781
- if (existsSync45(paths.magicContextConfig)) {
50439
+ if (existsSync47(paths.magicContextConfig)) {
49782
50440
  try {
49783
50441
  const raw = loadRawConfigFile({ configPath: paths.magicContextConfig, tier: "user" });
49784
50442
  if (!raw)
@@ -49800,9 +50458,9 @@ async function runDoctor2(options = {}) {
49800
50458
  else
49801
50459
  passCount++;
49802
50460
  const storage = getMagicContextStorageResolution();
49803
- const dbPath = join38(storage.path, "context.db");
50461
+ const dbPath = join39(storage.path, "context.db");
49804
50462
  log3.info(`Shared storage: ${storage.path} (source: ${storage.source})`);
49805
- if (!existsSync45(dbPath)) {
50463
+ if (!existsSync47(dbPath)) {
49806
50464
  log3.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
49807
50465
  } else {
49808
50466
  log3.info(`Shared context DB exists at ${dbPath}`);
@@ -49885,7 +50543,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
49885
50543
  let pluginConfigUse;
49886
50544
  if (paths.opencodeConfigFormat !== "none") {
49887
50545
  try {
49888
- pluginConfigUse = readOpenCodePluginConfigUse(import_comment_json11.parse(readFileSync28(paths.opencodeConfig, "utf-8")), dirname25(paths.opencodeConfig));
50546
+ pluginConfigUse = readOpenCodePluginConfigUse(import_comment_json11.parse(readFileSync29(paths.opencodeConfig, "utf-8")), dirname26(paths.opencodeConfig));
49889
50547
  } catch {}
49890
50548
  }
49891
50549
  const cacheResult = await clearPluginCache({
@@ -49937,7 +50595,7 @@ ${formatDatabaseRepairGuidance(dbPath)}`);
49937
50595
  let v2DistTag;
49938
50596
  if (paths.opencodeConfigFormat !== "none") {
49939
50597
  try {
49940
- v2DistTag = configuredOpenCodeV2DistTag(import_comment_json11.parse(readFileSync28(paths.opencodeConfig, "utf-8")));
50598
+ v2DistTag = configuredOpenCodeV2DistTag(import_comment_json11.parse(readFileSync29(paths.opencodeConfig, "utf-8")));
49941
50599
  } catch {}
49942
50600
  }
49943
50601
  const v2Cache = reportOpenCodeV2PluginCache(checkOpenCodeV2PluginCache({
@@ -50318,9 +50976,9 @@ var init_model_chain_health = __esm(() => {
50318
50976
  });
50319
50977
 
50320
50978
  // src/lib/diagnostics-pi.ts
50321
- import { existsSync as existsSync46, readdirSync as readdirSync10, readFileSync as readFileSync29, statSync as statSync20 } from "node:fs";
50979
+ import { existsSync as existsSync48, readdirSync as readdirSync10, readFileSync as readFileSync30, statSync as statSync24 } from "node:fs";
50322
50980
  import { createRequire as createRequire7 } from "node:module";
50323
- import { join as join39 } from "node:path";
50981
+ import { join as join40 } from "node:path";
50324
50982
  function getSelfVersion3() {
50325
50983
  const req = createRequire7(import.meta.url);
50326
50984
  for (const relPath of ["../../package.json", "../package.json"]) {
@@ -50335,7 +50993,7 @@ function getSelfVersion3() {
50335
50993
  }
50336
50994
  function fileSize2(path) {
50337
50995
  try {
50338
- return existsSync46(path) ? statSync20(path).size : 0;
50996
+ return existsSync48(path) ? statSync24(path).size : 0;
50339
50997
  } catch {
50340
50998
  return 0;
50341
50999
  }
@@ -50347,11 +51005,11 @@ function sanitizeValue2(value) {
50347
51005
  return sanitizeConfigValue(value);
50348
51006
  }
50349
51007
  function readJsonc(path) {
50350
- if (!existsSync46(path))
51008
+ if (!existsSync48(path))
50351
51009
  return { value: {} };
50352
51010
  try {
50353
51011
  return {
50354
- value: import_comment_json12.parse(readFileSync29(path, "utf-8"))
51012
+ value: import_comment_json12.parse(readFileSync30(path, "utf-8"))
50355
51013
  };
50356
51014
  } catch (error) {
50357
51015
  return {
@@ -50367,7 +51025,7 @@ function readConfigDiagnostic(path) {
50367
51025
  const parsed = readJsonc(path);
50368
51026
  return {
50369
51027
  path,
50370
- exists: existsSync46(path),
51028
+ exists: existsSync48(path),
50371
51029
  ...parsed.parseError ? { parseError: parsed.parseError } : {},
50372
51030
  flags: sanitizeValue2(parsed.value)
50373
51031
  };
@@ -50385,7 +51043,7 @@ function reverseSlugToDirectory(slug) {
50385
51043
  }
50386
51044
  function collectPiRecentSessions() {
50387
51045
  const sessionsRoot = getPiSessionsRoot();
50388
- if (!existsSync46(sessionsRoot))
51046
+ if (!existsSync48(sessionsRoot))
50389
51047
  return [];
50390
51048
  try {
50391
51049
  const slugs = readdirSync10(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -50394,7 +51052,7 @@ function collectPiRecentSessions() {
50394
51052
  const directory = reverseSlugToDirectory(slug);
50395
51053
  if (!directory)
50396
51054
  continue;
50397
- const slugDir = join39(sessionsRoot, slug);
51055
+ const slugDir = join40(sessionsRoot, slug);
50398
51056
  let files;
50399
51057
  try {
50400
51058
  files = readdirSync10(slugDir).filter((name) => name.endsWith(".jsonl"));
@@ -50403,7 +51061,7 @@ function collectPiRecentSessions() {
50403
51061
  }
50404
51062
  for (const file of files) {
50405
51063
  try {
50406
- const mtime = statSync20(join39(slugDir, file)).mtimeMs;
51064
+ const mtime = statSync24(join40(slugDir, file)).mtimeMs;
50407
51065
  const sessionId = file.replace(/\.jsonl$/, "");
50408
51066
  candidates.push({ sessionId, directory, mtime });
50409
51067
  } catch {}
@@ -50421,7 +51079,7 @@ function collectPiRecentSessions() {
50421
51079
  }
50422
51080
  function parseHistorianDumpMeta2(path) {
50423
51081
  try {
50424
- const xml = readFileSync29(path, "utf-8");
51082
+ const xml = readFileSync30(path, "utf-8");
50425
51083
  const parsed = parseCompartmentOutput(xml);
50426
51084
  const factCountByCategory = {};
50427
51085
  for (const fact of parsed.facts) {
@@ -50454,11 +51112,11 @@ function parseHistorianDumpMeta2(path) {
50454
51112
  }
50455
51113
  }
50456
51114
  function listDumpsInDir2(dir, limit) {
50457
- if (!existsSync46(dir))
51115
+ if (!existsSync48(dir))
50458
51116
  return { count: 0, recent: [] };
50459
51117
  try {
50460
51118
  const entries = readdirSync10(dir).filter((name) => name.endsWith(".xml")).map((name) => {
50461
- const stat = statSync20(join39(dir, name));
51119
+ const stat = statSync24(join40(dir, name));
50462
51120
  return {
50463
51121
  name,
50464
51122
  mtime: stat.mtimeMs,
@@ -50467,7 +51125,7 @@ function listDumpsInDir2(dir, limit) {
50467
51125
  }).sort((a, b) => b.mtime - a.mtime);
50468
51126
  const now = Date.now();
50469
51127
  const recent = entries.slice(0, limit).map((entry) => {
50470
- const meta = parseHistorianDumpMeta2(join39(dir, entry.name));
51128
+ const meta = parseHistorianDumpMeta2(join40(dir, entry.name));
50471
51129
  const summary = {
50472
51130
  name: entry.name,
50473
51131
  ageMinutes: Math.round((now - entry.mtime) / 60000),
@@ -50531,7 +51189,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
50531
51189
  const loaded = loadPiConfig({ cwd });
50532
51190
  const storageResolution = getMagicContextStorageResolution();
50533
51191
  const storageDirPath = storageResolution.path;
50534
- const dbPath = join39(storageDirPath, "context.db");
51192
+ const dbPath = join40(storageDirPath, "context.db");
50535
51193
  const logFiles = inspectMagicContextLogs("pi");
50536
51194
  const primaryLog = logFiles.find((file) => file.exists) ?? logFiles[0];
50537
51195
  const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
@@ -50548,7 +51206,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
50548
51206
  piVersion: pi ? getPiVersion(pi.path) : null,
50549
51207
  settings: {
50550
51208
  path: settingsPath,
50551
- exists: existsSync46(settingsPath),
51209
+ exists: existsSync48(settingsPath),
50552
51210
  ...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
50553
51211
  hasMagicContextPackage: hasPiMagicContextPackage(packages),
50554
51212
  packages: sanitizeValue2(packages)
@@ -50565,7 +51223,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
50565
51223
  storageDir: {
50566
51224
  path: storageDirPath,
50567
51225
  source: storageResolution.source,
50568
- exists: existsSync46(storageDirPath),
51226
+ exists: existsSync48(storageDirPath),
50569
51227
  contextDbSizeBytes: fileSize2(dbPath)
50570
51228
  },
50571
51229
  conflicts: {
@@ -50670,8 +51328,8 @@ var init_diagnostics_pi = __esm(() => {
50670
51328
  });
50671
51329
 
50672
51330
  // src/lib/logs-pi.ts
50673
- import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "node:fs";
50674
- import { dirname as dirname26, join as join40 } from "node:path";
51331
+ import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "node:fs";
51332
+ import { dirname as dirname27, join as join41 } from "node:path";
50675
51333
  function sanitizeLogContent2(content) {
50676
51334
  return sanitizeString2(content);
50677
51335
  }
@@ -50727,13 +51385,13 @@ async function bundleIssueReport2(report, description, title, options = {}) {
50727
51385
  const truncated = bodyMarkdown !== rawBodyMarkdown;
50728
51386
  const cwd = options.cwd ?? process.cwd();
50729
51387
  const timestamp = formatTimestamp2(options.now ?? new Date);
50730
- const path = options.outputPath ?? join40(cwd, `magic-context-pi-issue-${timestamp}.md`);
50731
- mkdirSync8(dirname26(path), { recursive: true });
50732
- writeFileSync8(path, `${bodyMarkdown}
51388
+ const path = options.outputPath ?? join41(cwd, `magic-context-pi-issue-${timestamp}.md`);
51389
+ mkdirSync9(dirname27(path), { recursive: true });
51390
+ writeFileSync9(path, `${bodyMarkdown}
50733
51391
  `);
50734
- const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join40(cwd, `magic-context-pi-issue-${timestamp}-full.md`) : undefined;
51392
+ const fullPath = truncated ? options.outputPath ? `${options.outputPath}.full.md` : join41(cwd, `magic-context-pi-issue-${timestamp}-full.md`) : undefined;
50735
51393
  if (fullPath)
50736
- writeFileSync8(fullPath, `${rawBodyMarkdown}
51394
+ writeFileSync9(fullPath, `${rawBodyMarkdown}
50737
51395
  `);
50738
51396
  return { path, bodyMarkdown, ...fullPath ? { fullPath } : {}, truncated };
50739
51397
  }
@@ -50745,10 +51403,10 @@ var init_logs_pi = __esm(() => {
50745
51403
 
50746
51404
  // src/commands/doctor-pi.ts
50747
51405
  import { execFileSync as execFileSync9, spawnSync as spawnSync11 } from "node:child_process";
50748
- import { existsSync as existsSync47, readdirSync as readdirSync11, readFileSync as readFileSync30, rmSync as rmSync9, statSync as statSync21 } from "node:fs";
51406
+ import { existsSync as existsSync49, readdirSync as readdirSync11, readFileSync as readFileSync31, rmSync as rmSync10, statSync as statSync25 } from "node:fs";
50749
51407
  import { createRequire as createRequire8 } from "node:module";
50750
- import { homedir as homedir21 } from "node:os";
50751
- import { isAbsolute as isAbsolute9, join as join41 } from "node:path";
51408
+ import { homedir as homedir22 } from "node:os";
51409
+ import { isAbsolute as isAbsolute9, join as join42 } from "node:path";
50752
51410
  function depsFrom(options) {
50753
51411
  return {
50754
51412
  ...DEFAULT_DEPS5,
@@ -50840,7 +51498,7 @@ function summarize(results) {
50840
51498
  function readJsonc2(path) {
50841
51499
  try {
50842
51500
  return {
50843
- value: import_comment_json13.parse(readFileSync30(path, "utf-8"))
51501
+ value: import_comment_json13.parse(readFileSync31(path, "utf-8"))
50844
51502
  };
50845
51503
  } catch (error) {
50846
51504
  return {
@@ -50890,15 +51548,15 @@ function piPluginDirCandidates(packages, cwd) {
50890
51548
  if (resolved)
50891
51549
  dirs.push(resolved);
50892
51550
  }
50893
- dirs.push(join41(agentDir, "npm", "node_modules", PACKAGE_NAME2));
50894
- dirs.push(join41(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2));
50895
- return dirs.filter((dir) => existsSync47(join41(dir, "package.json")));
51551
+ dirs.push(join42(agentDir, "npm", "node_modules", PACKAGE_NAME2));
51552
+ dirs.push(join42(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2));
51553
+ return dirs.filter((dir) => existsSync49(join42(dir, "package.json")));
50896
51554
  }
50897
51555
  function projectConfigPath(cwd) {
50898
51556
  return resolveCortexKitProjectConfigPath(cwd);
50899
51557
  }
50900
51558
  function readConfigForEmbedding(path, isProjectConfig) {
50901
- if (!existsSync47(path))
51559
+ if (!existsSync49(path))
50902
51560
  return null;
50903
51561
  try {
50904
51562
  const raw = loadRawConfigFile({
@@ -50984,35 +51642,35 @@ function pinnedVersionFromPackageSpecifier(specifier) {
50984
51642
  }
50985
51643
  function cacheRoots(cwd) {
50986
51644
  const home = process.env.HOME?.trim();
50987
- const cacheHome = process.env.XDG_CACHE_HOME || join41(home || homedir21(), ".cache");
51645
+ const cacheHome = process.env.XDG_CACHE_HOME || join42(home || homedir22(), ".cache");
50988
51646
  const piCacheRoot = getPiCacheRoot();
50989
51647
  return [
50990
- join41(piCacheRoot, "extensions"),
50991
- join41(piCacheRoot, "packages"),
50992
- join41(cacheHome, "pi", "extensions"),
50993
- join41(cacheHome, "pi", "packages"),
50994
- join41(getPiAgentConfigDir(), "cache", "extensions"),
50995
- join41(getPiAgentConfigDir(), "npm", "node_modules", PACKAGE_NAME2),
50996
- join41(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2)
51648
+ join42(piCacheRoot, "extensions"),
51649
+ join42(piCacheRoot, "packages"),
51650
+ join42(cacheHome, "pi", "extensions"),
51651
+ join42(cacheHome, "pi", "packages"),
51652
+ join42(getPiAgentConfigDir(), "cache", "extensions"),
51653
+ join42(getPiAgentConfigDir(), "npm", "node_modules", PACKAGE_NAME2),
51654
+ join42(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME2)
50997
51655
  ];
50998
51656
  }
50999
51657
  function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
51000
51658
  const found = new Map;
51001
51659
  const visit = (path, depth) => {
51002
- if (depth < 0 || !existsSync47(path))
51660
+ if (depth < 0 || !existsSync49(path))
51003
51661
  return;
51004
51662
  let stat;
51005
51663
  try {
51006
- stat = statSync21(path);
51664
+ stat = statSync25(path);
51007
51665
  } catch {
51008
51666
  return;
51009
51667
  }
51010
51668
  if (!stat.isDirectory())
51011
51669
  return;
51012
- const packageJson = join41(path, "package.json");
51013
- if (existsSync47(packageJson)) {
51670
+ const packageJson = join42(path, "package.json");
51671
+ if (existsSync49(packageJson)) {
51014
51672
  try {
51015
- const pkg = JSON.parse(readFileSync30(packageJson, "utf-8"));
51673
+ const pkg = JSON.parse(readFileSync31(packageJson, "utf-8"));
51016
51674
  const name = typeof pkg.name === "string" ? pkg.name : "";
51017
51675
  const version = typeof pkg.version === "string" ? pkg.version : undefined;
51018
51676
  if (name === PACKAGE_NAME2) {
@@ -51032,7 +51690,7 @@ function findPiMagicContextCacheDirs(cwd, expectedVersion, force = false) {
51032
51690
  return;
51033
51691
  }
51034
51692
  for (const entry of entries)
51035
- visit(join41(path, entry), depth - 1);
51693
+ visit(join42(path, entry), depth - 1);
51036
51694
  };
51037
51695
  for (const root of cacheRoots(cwd))
51038
51696
  visit(root, 5);
@@ -51093,7 +51751,7 @@ async function runHealthChecks2(options) {
51093
51751
  const settingsPath = getPiUserExtensionsPath();
51094
51752
  let packages = [];
51095
51753
  let piPluginInstalled = false;
51096
- if (!existsSync47(settingsPath)) {
51754
+ if (!existsSync49(settingsPath)) {
51097
51755
  if (pi) {
51098
51756
  add2(results, "info", `${piVersion ? `Pi ${piVersion}` : "Pi"} found; Magic Context is not installed there (run setup to add it)`);
51099
51757
  }
@@ -51135,7 +51793,7 @@ async function runHealthChecks2(options) {
51135
51793
  ["user", userConfigPath, true],
51136
51794
  ["project", projectPath, false]
51137
51795
  ]) {
51138
- if (!existsSync47(path)) {
51796
+ if (!existsSync49(path)) {
51139
51797
  if (required) {
51140
51798
  add2(results, "warn", `No ${label} magic-context.jsonc found at ${path}`);
51141
51799
  if (userConfigMigrationRefused) {
@@ -51181,9 +51839,9 @@ async function runHealthChecks2(options) {
51181
51839
  checkPiModelChains(results, pi, loadedConfig.config, options.deps);
51182
51840
  const storage = getMagicContextStorageResolution();
51183
51841
  const storageDir = storage.path;
51184
- const dbPath = join41(storageDir, "context.db");
51842
+ const dbPath = join42(storageDir, "context.db");
51185
51843
  add2(results, "info", `Shared storage: ${storageDir} (source: ${storage.source})`);
51186
- const existedBeforeOpen = existsSync47(dbPath);
51844
+ const existedBeforeOpen = existsSync49(dbPath);
51187
51845
  if (existedBeforeOpen)
51188
51846
  add2(results, "pass", `Shared context DB exists at ${dbPath}`);
51189
51847
  else
@@ -51412,7 +52070,7 @@ function writeDefaultMagicContextConfig(path) {
51412
52070
  function repair2(plan, prompts) {
51413
52071
  let fixed = 0;
51414
52072
  for (const path of plan.reasoningAgeConfigPaths) {
51415
- const content = readFileSync30(path, "utf8");
52073
+ const content = readFileSync31(path, "utf8");
51416
52074
  const parsed = readJsonc2(path);
51417
52075
  if (parsed.error)
51418
52076
  continue;
@@ -51438,7 +52096,7 @@ function repair2(plan, prompts) {
51438
52096
  }
51439
52097
  if (plan.writeUserConfig) {
51440
52098
  const configPath = getPiUserConfigPath();
51441
- if (!existsSync47(configPath)) {
52099
+ if (!existsSync49(configPath)) {
51442
52100
  try {
51443
52101
  writeDefaultMagicContextConfig(configPath);
51444
52102
  prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
@@ -51450,7 +52108,7 @@ function repair2(plan, prompts) {
51450
52108
  }
51451
52109
  for (const path of plan.clearCachePaths) {
51452
52110
  try {
51453
- rmSync9(path, { recursive: true, force: true });
52111
+ rmSync10(path, { recursive: true, force: true });
51454
52112
  prompts.log.success(`Cleared stale Pi extension cache: ${path}`);
51455
52113
  fixed += 1;
51456
52114
  } catch (error) {
@@ -51492,7 +52150,7 @@ async function runIssueFlow3(options) {
51492
52150
  if (options.reportPath) {
51493
52151
  try {
51494
52152
  const report = await options.deps.collectDiagnostics(options.cwd);
51495
- const outputPath = isAbsolute9(options.reportPath) ? options.reportPath : join41(options.cwd, options.reportPath);
52153
+ const outputPath = isAbsolute9(options.reportPath) ? options.reportPath : join42(options.cwd, options.reportPath);
51496
52154
  const bundled = await bundleIssueReport2(report, "Generated non-interactively by `doctor --issue --report`.", "Magic Context diagnostic report", { cwd: options.cwd, now: options.deps.now(), outputPath });
51497
52155
  options.prompts.log.info(`Report written to ${bundled.path}`);
51498
52156
  return 0;
@@ -51576,7 +52234,7 @@ async function runDoctor3(options = {}) {
51576
52234
  const v22Result = await runV22BackfillCommands({
51577
52235
  name: "Pi",
51578
52236
  openDatabase: (readonly = true) => {
51579
- const dbPath = join41(getMagicContextStorageDir(), "context.db");
52237
+ const dbPath = join42(getMagicContextStorageDir(), "context.db");
51580
52238
  v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
51581
52239
  return v22Db;
51582
52240
  },
@@ -51694,8 +52352,8 @@ var init_doctor_pi = __esm(async () => {
51694
52352
  });
51695
52353
 
51696
52354
  // src/commands/doctor.ts
51697
- import { existsSync as existsSync48, rmSync as rmSync10 } from "node:fs";
51698
- import { join as join42 } from "node:path";
52355
+ import { existsSync as existsSync50, rmSync as rmSync11 } from "node:fs";
52356
+ import { join as join43 } from "node:path";
51699
52357
  async function runDoctor4(options) {
51700
52358
  if (options.clear)
51701
52359
  return runClear();
@@ -51713,7 +52371,7 @@ async function runDoctor4(options) {
51713
52371
  const result = await runV22BackfillCommands({
51714
52372
  name: "Magic Context",
51715
52373
  openDatabase: (readonly = true) => {
51716
- const dbPath = join42(getMagicContextStorageDir(), "context.db");
52374
+ const dbPath = join43(getMagicContextStorageDir(), "context.db");
51717
52375
  v22Db = readonly ? openExistingContextDatabase(dbPath, { readonly: true }) : openExistingContextDatabaseForMutation(dbPath);
51718
52376
  return v22Db;
51719
52377
  },
@@ -51733,7 +52391,7 @@ async function runDoctor4(options) {
51733
52391
  log3.warn(`Identity split check unavailable: ${error instanceof Error ? error.message : String(error)}`);
51734
52392
  }
51735
52393
  await init_migrate();
51736
- const sweepDbPath = join42(getMagicContextStorageDir(), "context.db");
52394
+ const sweepDbPath = join43(getMagicContextStorageDir(), "context.db");
51737
52395
  let sweepDb = null;
51738
52396
  try {
51739
52397
  sweepDb = openExistingContextDatabaseForMutation(sweepDbPath);
@@ -51819,7 +52477,7 @@ async function runClear() {
51819
52477
  return 0;
51820
52478
  }
51821
52479
  const picks = await selectMany("Select caches to clear:", items.map((item, idx) => ({
51822
- label: `${item.adapter.displayName}${item.label ? ` (${item.label})` : ""}: ${formatSize(item.sizeBytes)} — ${item.path}`,
52480
+ label: `${item.adapter.displayName}${item.label ? ` (${item.label})` : ""}: ${formatSize2(item.sizeBytes)} — ${item.path}`,
51823
52481
  value: String(idx)
51824
52482
  })));
51825
52483
  if (picks.length === 0) {
@@ -51850,8 +52508,8 @@ async function runClear() {
51850
52508
  failed += 1;
51851
52509
  continue;
51852
52510
  }
51853
- } else if (existsSync48(item.path)) {
51854
- rmSync10(item.path, { recursive: true, force: true });
52511
+ } else if (existsSync50(item.path)) {
52512
+ rmSync11(item.path, { recursive: true, force: true });
51855
52513
  }
51856
52514
  s.stop(`Cleared ${item.path}`);
51857
52515
  } catch (err) {
@@ -51863,7 +52521,7 @@ async function runClear() {
51863
52521
  outro2(failed === 0 ? "Done." : `Done with ${failed} failure(s).`);
51864
52522
  return failed === 0 ? 0 : 1;
51865
52523
  }
51866
- function formatSize(bytes) {
52524
+ function formatSize2(bytes) {
51867
52525
  if (bytes < 1024)
51868
52526
  return `${bytes} B`;
51869
52527
  if (bytes < 1048576)
@@ -51912,13 +52570,16 @@ var HARNESS_LINES = [
51912
52570
  ];
51913
52571
  var SETUP_HELP = [
51914
52572
  "",
51915
- " Usage: magic-context setup [--harness opencode|pi|omp] [--dry-run]",
52573
+ " Usage: magic-context setup [--harness opencode|pi|omp] [--dry-run] [--dashboard|--no-dashboard]",
51916
52574
  "",
51917
52575
  " Interactive setup wizard: registers the Magic Context plugin with the",
51918
- " selected harness and writes its Magic Context config.",
52576
+ " selected harness and writes its Magic Context config. Afterwards it offers",
52577
+ " to install the Magic Context Dashboard desktop app (interactive runs only).",
51919
52578
  "",
51920
52579
  " Options:",
51921
52580
  " --dry-run Preview the wizard without writing any files",
52581
+ " --dashboard Install or update the dashboard without asking",
52582
+ " --no-dashboard Skip the dashboard offer",
51922
52583
  ...HARNESS_LINES,
51923
52584
  ""
51924
52585
  ].join(`
@@ -51971,7 +52632,7 @@ var SINGLE_STORE_HELP = [
51971
52632
  `);
51972
52633
  var MERGE_IDENTITY_HELP = [
51973
52634
  "",
51974
- " Usage: magic-context doctor merge-identities [--from <identity> --to <identity>] [--apply] [--force] [--db <path>]",
52635
+ " Usage: magic-context doctor merge-identities [--from <identity> --to <identity>] [--apply] [--force] [--verbose] [--db <path>] [--backup-root <dir>]",
51975
52636
  "",
51976
52637
  " Merge every project-scoped row from one project identity into another.",
51977
52638
  "",
@@ -51981,8 +52642,10 @@ var MERGE_IDENTITY_HELP = [
51981
52642
  " (no flags) List splits; --from/--to previews without writing",
51982
52643
  " --apply Confirm the reviewed preview; hosts must be closed",
51983
52644
  " --force Permit a target not resolving on this machine",
52645
+ " --verbose List every missing source-only folder and orphaned sidecar",
51984
52646
  " --db <path> Use this context.db instead of the shared one",
51985
52647
  " --host-db <path> Read session directories from this host database",
52648
+ " --backup-root <dir> Store the backup under this directory",
51986
52649
  " Legacy alias: doctor merge-identity; --dry-run previews, --yes applies",
51987
52650
  ""
51988
52651
  ].join(`