@cortexkit/magic-context 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +372 -180
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -8300,7 +8300,7 @@ function parseModelListOutput(output) {
|
|
|
8300
8300
|
if (!line || line.toLowerCase().includes("usage:"))
|
|
8301
8301
|
continue;
|
|
8302
8302
|
const token = line.split(/\s+/)[0]?.trim().replace(/,$/, "");
|
|
8303
|
-
if (!token
|
|
8303
|
+
if (!token?.includes("/"))
|
|
8304
8304
|
continue;
|
|
8305
8305
|
if (/^https?:\/\//.test(token))
|
|
8306
8306
|
continue;
|
|
@@ -8506,7 +8506,7 @@ class PiAdapter {
|
|
|
8506
8506
|
}
|
|
8507
8507
|
}
|
|
8508
8508
|
getInstallHint() {
|
|
8509
|
-
return "Install Pi: https://pi.coding/install (npm: @
|
|
8509
|
+
return "Install Pi: https://pi.coding/install (npm: @earendil-works/pi-coding-agent)";
|
|
8510
8510
|
}
|
|
8511
8511
|
getPluginCacheInfo() {
|
|
8512
8512
|
return { path: null, exists: false, sizeBytes: 0 };
|
|
@@ -11353,11 +11353,11 @@ async function runSetup2(options = {}) {
|
|
|
11353
11353
|
}
|
|
11354
11354
|
const version = env.getPiVersion(pi.path);
|
|
11355
11355
|
spinner2.stop(version ? `Pi ${version} detected at ${pi.path}` : `Pi detected at ${pi.path}`);
|
|
11356
|
-
const MIN_PI_VERSION = "0.
|
|
11356
|
+
const MIN_PI_VERSION = "0.74.0";
|
|
11357
11357
|
if (version && comparePiVersion(version, MIN_PI_VERSION) < 0) {
|
|
11358
11358
|
prompts.log.warn(`Pi ${version} is older than the required ${MIN_PI_VERSION}.
|
|
11359
|
-
|
|
11360
|
-
Run \`pi update\` (or \`npm install -g @
|
|
11359
|
+
Pi 0.74.0 renamed the npm package from \`@mariozechner/pi-coding-agent\` to \`@earendil-works/pi-coding-agent\`. Magic Context's peer dependency targets the new scope, so older Pi installs cannot load this extension.
|
|
11360
|
+
Run \`pi update --self\` (or \`npm install -g @earendil-works/pi-coding-agent@latest\`) before continuing.`);
|
|
11361
11361
|
const proceed = await prompts.confirm("Continue with setup anyway? (subagents will fail at runtime)", false);
|
|
11362
11362
|
if (!proceed) {
|
|
11363
11363
|
prompts.outro("Setup cancelled — upgrade Pi and try again.");
|
|
@@ -27631,6 +27631,78 @@ var init_config = __esm(() => {
|
|
|
27631
27631
|
init_variable();
|
|
27632
27632
|
});
|
|
27633
27633
|
|
|
27634
|
+
// ../plugin/src/features/magic-context/key-files/aft-availability.ts
|
|
27635
|
+
import { existsSync as existsSync13, readFileSync as readFileSync9 } from "node:fs";
|
|
27636
|
+
import { homedir as homedir9 } from "node:os";
|
|
27637
|
+
import { join as join11 } from "node:path";
|
|
27638
|
+
function parseConfig(path4) {
|
|
27639
|
+
if (!existsSync13(path4))
|
|
27640
|
+
return null;
|
|
27641
|
+
return import_comment_json6.parse(readFileSync9(path4, "utf-8"));
|
|
27642
|
+
}
|
|
27643
|
+
function entryMatchesAft(entry) {
|
|
27644
|
+
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
27645
|
+
return typeof value === "string" && (value.includes("@cortexkit/aft") || value.includes("aft-opencode") || value.includes("aft-pi"));
|
|
27646
|
+
}
|
|
27647
|
+
function hasAftInArray(value) {
|
|
27648
|
+
return Array.isArray(value) && value.some(entryMatchesAft);
|
|
27649
|
+
}
|
|
27650
|
+
function hasAftAtKeys(value, keys) {
|
|
27651
|
+
if (!value || typeof value !== "object")
|
|
27652
|
+
return false;
|
|
27653
|
+
const record2 = value;
|
|
27654
|
+
for (const key of keys) {
|
|
27655
|
+
if (hasAftInArray(record2[key]))
|
|
27656
|
+
return true;
|
|
27657
|
+
}
|
|
27658
|
+
return false;
|
|
27659
|
+
}
|
|
27660
|
+
function getAftAvailability() {
|
|
27661
|
+
const home = process.env.HOME || homedir9();
|
|
27662
|
+
const opencodePaths = [
|
|
27663
|
+
join11(home, ".config", "opencode", "opencode.jsonc"),
|
|
27664
|
+
join11(home, ".config", "opencode", "opencode.json")
|
|
27665
|
+
];
|
|
27666
|
+
const piPaths = [join11(home, ".pi", "agent", "settings.json")];
|
|
27667
|
+
const checkedPaths = [...opencodePaths, ...piPaths];
|
|
27668
|
+
let opencode = false;
|
|
27669
|
+
for (const path4 of opencodePaths) {
|
|
27670
|
+
try {
|
|
27671
|
+
const config2 = parseConfig(path4);
|
|
27672
|
+
if (hasAftAtKeys(config2, ["plugin", "plugins", "mcp", "mcp_servers"])) {
|
|
27673
|
+
opencode = true;
|
|
27674
|
+
break;
|
|
27675
|
+
}
|
|
27676
|
+
} catch {}
|
|
27677
|
+
}
|
|
27678
|
+
let pi = false;
|
|
27679
|
+
for (const path4 of piPaths) {
|
|
27680
|
+
try {
|
|
27681
|
+
const config2 = parseConfig(path4);
|
|
27682
|
+
if (hasAftAtKeys(config2, ["packages", "extensions"])) {
|
|
27683
|
+
pi = true;
|
|
27684
|
+
break;
|
|
27685
|
+
}
|
|
27686
|
+
const agent = config2?.agent;
|
|
27687
|
+
if (hasAftAtKeys(agent, ["packages", "extensions"])) {
|
|
27688
|
+
pi = true;
|
|
27689
|
+
break;
|
|
27690
|
+
}
|
|
27691
|
+
} catch {}
|
|
27692
|
+
}
|
|
27693
|
+
const detected = opencode || pi;
|
|
27694
|
+
return {
|
|
27695
|
+
available: overrideAvailability ?? detected,
|
|
27696
|
+
opencode,
|
|
27697
|
+
pi,
|
|
27698
|
+
checkedPaths
|
|
27699
|
+
};
|
|
27700
|
+
}
|
|
27701
|
+
var import_comment_json6, overrideAvailability = null;
|
|
27702
|
+
var init_aft_availability = __esm(() => {
|
|
27703
|
+
import_comment_json6 = __toESM(require_src2(), 1);
|
|
27704
|
+
});
|
|
27705
|
+
|
|
27634
27706
|
// ../plugin/src/features/magic-context/memory/embedding-probe.ts
|
|
27635
27707
|
async function probeEmbeddingEndpoint(options) {
|
|
27636
27708
|
const endpoint = options.endpoint.trim().replace(/\/+$/, "");
|
|
@@ -27736,8 +27808,8 @@ function truncate(text2) {
|
|
|
27736
27808
|
var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
|
|
27737
27809
|
|
|
27738
27810
|
// ../plugin/src/shared/tui-config.ts
|
|
27739
|
-
import { existsSync as
|
|
27740
|
-
import { dirname as dirname8, join as
|
|
27811
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "node:fs";
|
|
27812
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
27741
27813
|
function isMagicContextEntry(entry) {
|
|
27742
27814
|
if (!entry)
|
|
27743
27815
|
return false;
|
|
@@ -27751,11 +27823,11 @@ function isMagicContextEntry(entry) {
|
|
|
27751
27823
|
}
|
|
27752
27824
|
function resolveTuiConfigPath() {
|
|
27753
27825
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
27754
|
-
const jsoncPath =
|
|
27755
|
-
const jsonPath =
|
|
27756
|
-
if (
|
|
27826
|
+
const jsoncPath = join12(configDir, "tui.jsonc");
|
|
27827
|
+
const jsonPath = join12(configDir, "tui.json");
|
|
27828
|
+
if (existsSync14(jsoncPath))
|
|
27757
27829
|
return jsoncPath;
|
|
27758
|
-
if (
|
|
27830
|
+
if (existsSync14(jsonPath))
|
|
27759
27831
|
return jsonPath;
|
|
27760
27832
|
return jsonPath;
|
|
27761
27833
|
}
|
|
@@ -27763,9 +27835,9 @@ function ensureTuiPluginEntry() {
|
|
|
27763
27835
|
try {
|
|
27764
27836
|
const configPath = resolveTuiConfigPath();
|
|
27765
27837
|
let config2 = {};
|
|
27766
|
-
if (
|
|
27767
|
-
const raw =
|
|
27768
|
-
config2 =
|
|
27838
|
+
if (existsSync14(configPath)) {
|
|
27839
|
+
const raw = readFileSync10(configPath, "utf-8");
|
|
27840
|
+
config2 = import_comment_json7.parse(raw) ?? {};
|
|
27769
27841
|
}
|
|
27770
27842
|
const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((p2) => typeof p2 === "string") : [];
|
|
27771
27843
|
const existingIdx = plugins.findIndex(isMagicContextEntry);
|
|
@@ -27784,7 +27856,7 @@ function ensureTuiPluginEntry() {
|
|
|
27784
27856
|
}
|
|
27785
27857
|
config2.plugin = plugins;
|
|
27786
27858
|
mkdirSync6(dirname8(configPath), { recursive: true });
|
|
27787
|
-
writeFileSync8(configPath, `${
|
|
27859
|
+
writeFileSync8(configPath, `${import_comment_json7.stringify(config2, null, 2)}
|
|
27788
27860
|
`);
|
|
27789
27861
|
log2(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
27790
27862
|
return true;
|
|
@@ -27793,11 +27865,11 @@ function ensureTuiPluginEntry() {
|
|
|
27793
27865
|
return false;
|
|
27794
27866
|
}
|
|
27795
27867
|
}
|
|
27796
|
-
var
|
|
27868
|
+
var import_comment_json7, PLUGIN_NAME4 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY3;
|
|
27797
27869
|
var init_tui_config = __esm(() => {
|
|
27798
27870
|
init_logger();
|
|
27799
27871
|
init_opencode_config_dir();
|
|
27800
|
-
|
|
27872
|
+
import_comment_json7 = __toESM(require_src2(), 1);
|
|
27801
27873
|
PLUGIN_ENTRY3 = `${PLUGIN_NAME4}@latest`;
|
|
27802
27874
|
});
|
|
27803
27875
|
|
|
@@ -27852,7 +27924,7 @@ var init_compartment_parser = __esm(() => {
|
|
|
27852
27924
|
});
|
|
27853
27925
|
|
|
27854
27926
|
// src/lib/redaction.ts
|
|
27855
|
-
import { homedir as
|
|
27927
|
+
import { homedir as homedir10, userInfo } from "node:os";
|
|
27856
27928
|
function escapeRegex2(value) {
|
|
27857
27929
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27858
27930
|
}
|
|
@@ -27865,7 +27937,7 @@ function isSecretKey(key) {
|
|
|
27865
27937
|
return SECRET_KEY_PATTERN.test(key);
|
|
27866
27938
|
}
|
|
27867
27939
|
function sanitizePathString(value) {
|
|
27868
|
-
const home =
|
|
27940
|
+
const home = homedir10();
|
|
27869
27941
|
const username = userInfo().username;
|
|
27870
27942
|
let sanitized = value;
|
|
27871
27943
|
if (home) {
|
|
@@ -27967,10 +28039,10 @@ var init_redaction = __esm(() => {
|
|
|
27967
28039
|
});
|
|
27968
28040
|
|
|
27969
28041
|
// src/lib/diagnostics-opencode.ts
|
|
27970
|
-
import { existsSync as
|
|
28042
|
+
import { existsSync as existsSync15, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync2 } from "node:fs";
|
|
27971
28043
|
import { createRequire as createRequire3 } from "node:module";
|
|
27972
|
-
import { homedir as
|
|
27973
|
-
import { join as
|
|
28044
|
+
import { homedir as homedir11 } from "node:os";
|
|
28045
|
+
import { join as join13 } from "node:path";
|
|
27974
28046
|
function getSelfVersion() {
|
|
27975
28047
|
const require2 = createRequire3(import.meta.url);
|
|
27976
28048
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -27984,12 +28056,12 @@ function getSelfVersion() {
|
|
|
27984
28056
|
return "unknown";
|
|
27985
28057
|
}
|
|
27986
28058
|
function getPluginCacheInfo() {
|
|
27987
|
-
const path4 =
|
|
28059
|
+
const path4 = join13(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
|
|
27988
28060
|
let cached2;
|
|
27989
28061
|
try {
|
|
27990
|
-
const installedPkgPath =
|
|
27991
|
-
if (
|
|
27992
|
-
const pkg = JSON.parse(
|
|
28062
|
+
const installedPkgPath = join13(path4, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
28063
|
+
if (existsSync15(installedPkgPath)) {
|
|
28064
|
+
const pkg = JSON.parse(readFileSync11(installedPkgPath, "utf-8"));
|
|
27993
28065
|
cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
27994
28066
|
}
|
|
27995
28067
|
} catch {
|
|
@@ -27998,12 +28070,12 @@ function getPluginCacheInfo() {
|
|
|
27998
28070
|
return { path: path4, cached: cached2, latest: getSelfVersion() };
|
|
27999
28071
|
}
|
|
28000
28072
|
function getStorageDir() {
|
|
28001
|
-
const dataHome = process.env.XDG_DATA_HOME ||
|
|
28002
|
-
return
|
|
28073
|
+
const dataHome = process.env.XDG_DATA_HOME || join13(homedir11(), ".local", "share");
|
|
28074
|
+
return join13(dataHome, "cortexkit", "magic-context");
|
|
28003
28075
|
}
|
|
28004
28076
|
function fileSize(path4) {
|
|
28005
28077
|
try {
|
|
28006
|
-
return
|
|
28078
|
+
return existsSync15(path4) ? statSync2(path4).size : 0;
|
|
28007
28079
|
} catch {
|
|
28008
28080
|
return 0;
|
|
28009
28081
|
}
|
|
@@ -28015,11 +28087,11 @@ function sanitizeValue(value) {
|
|
|
28015
28087
|
return sanitizeConfigValue(value);
|
|
28016
28088
|
}
|
|
28017
28089
|
function readConfig2(path4) {
|
|
28018
|
-
if (!
|
|
28090
|
+
if (!existsSync15(path4))
|
|
28019
28091
|
return { value: null };
|
|
28020
28092
|
try {
|
|
28021
|
-
const raw =
|
|
28022
|
-
const value =
|
|
28093
|
+
const raw = readFileSync11(path4, "utf-8");
|
|
28094
|
+
const value = import_comment_json8.parse(raw);
|
|
28023
28095
|
return { value };
|
|
28024
28096
|
} catch (error51) {
|
|
28025
28097
|
return { value: null, error: error51 instanceof Error ? error51.message : String(error51) };
|
|
@@ -28041,7 +28113,7 @@ function configHasPluginEntry(config2) {
|
|
|
28041
28113
|
}
|
|
28042
28114
|
function parseHistorianDumpMeta(path4) {
|
|
28043
28115
|
try {
|
|
28044
|
-
const xml =
|
|
28116
|
+
const xml = readFileSync11(path4, "utf-8");
|
|
28045
28117
|
const parsed = parseCompartmentOutput(xml);
|
|
28046
28118
|
const factCountByCategory = {};
|
|
28047
28119
|
for (const fact of parsed.facts) {
|
|
@@ -28074,11 +28146,11 @@ function parseHistorianDumpMeta(path4) {
|
|
|
28074
28146
|
}
|
|
28075
28147
|
}
|
|
28076
28148
|
function listDumpsInDir(dir, limit) {
|
|
28077
|
-
if (!
|
|
28149
|
+
if (!existsSync15(dir))
|
|
28078
28150
|
return { count: 0, recent: [] };
|
|
28079
28151
|
try {
|
|
28080
28152
|
const entries = readdirSync2(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
28081
|
-
const stat = statSync2(
|
|
28153
|
+
const stat = statSync2(join13(dir, name));
|
|
28082
28154
|
return {
|
|
28083
28155
|
name,
|
|
28084
28156
|
mtime: stat.mtimeMs,
|
|
@@ -28087,7 +28159,7 @@ function listDumpsInDir(dir, limit) {
|
|
|
28087
28159
|
}).sort((a, b2) => b2.mtime - a.mtime);
|
|
28088
28160
|
const now = Date.now();
|
|
28089
28161
|
const recent = entries.slice(0, limit).map((entry) => {
|
|
28090
|
-
const meta3 = parseHistorianDumpMeta(
|
|
28162
|
+
const meta3 = parseHistorianDumpMeta(join13(dir, entry.name));
|
|
28091
28163
|
const summary = {
|
|
28092
28164
|
name: entry.name,
|
|
28093
28165
|
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
@@ -28142,8 +28214,8 @@ function collectHistorianDumps(recentSessions) {
|
|
|
28142
28214
|
};
|
|
28143
28215
|
}
|
|
28144
28216
|
async function collectRecentSessions() {
|
|
28145
|
-
const opencodeDbPath =
|
|
28146
|
-
if (!
|
|
28217
|
+
const opencodeDbPath = join13(homedir11(), ".local", "share", "opencode", "opencode.db");
|
|
28218
|
+
if (!existsSync15(opencodeDbPath))
|
|
28147
28219
|
return [];
|
|
28148
28220
|
if (typeof globalThis.Bun === "undefined") {
|
|
28149
28221
|
return [];
|
|
@@ -28177,8 +28249,8 @@ async function collectRecentSessions() {
|
|
|
28177
28249
|
}
|
|
28178
28250
|
}
|
|
28179
28251
|
async function collectHistorianFailures(storageDirPath) {
|
|
28180
|
-
const contextDbPath =
|
|
28181
|
-
if (!
|
|
28252
|
+
const contextDbPath = join13(storageDirPath, "context.db");
|
|
28253
|
+
if (!existsSync15(contextDbPath))
|
|
28182
28254
|
return [];
|
|
28183
28255
|
if (typeof globalThis.Bun === "undefined") {
|
|
28184
28256
|
return [];
|
|
@@ -28217,9 +28289,9 @@ async function collectDiagnostics() {
|
|
|
28217
28289
|
const tuiConfig = readConfig2(configPaths.tuiConfig);
|
|
28218
28290
|
const magicContextConfig = readConfig2(configPaths.magicContextConfig);
|
|
28219
28291
|
const storageDirPath = getStorageDir();
|
|
28220
|
-
const contextDbPath =
|
|
28292
|
+
const contextDbPath = join13(storageDirPath, "context.db");
|
|
28221
28293
|
const logPath = getMagicContextLogPath2("opencode");
|
|
28222
|
-
const logFileSize =
|
|
28294
|
+
const logFileSize = existsSync15(logPath) ? statSync2(logPath).size : 0;
|
|
28223
28295
|
const conflictResult = detectConflicts(process.cwd());
|
|
28224
28296
|
const recentSessions = await collectRecentSessions();
|
|
28225
28297
|
return {
|
|
@@ -28234,14 +28306,15 @@ async function collectDiagnostics() {
|
|
|
28234
28306
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
28235
28307
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
28236
28308
|
magicContextConfig: {
|
|
28237
|
-
exists:
|
|
28309
|
+
exists: existsSync15(configPaths.magicContextConfig),
|
|
28238
28310
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
28239
28311
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
28240
28312
|
},
|
|
28313
|
+
aft: getAftAvailability(),
|
|
28241
28314
|
pluginCache: getPluginCacheInfo(),
|
|
28242
28315
|
storageDir: {
|
|
28243
28316
|
path: storageDirPath,
|
|
28244
|
-
exists:
|
|
28317
|
+
exists: existsSync15(storageDirPath),
|
|
28245
28318
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
28246
28319
|
},
|
|
28247
28320
|
conflicts: {
|
|
@@ -28250,7 +28323,7 @@ async function collectDiagnostics() {
|
|
|
28250
28323
|
},
|
|
28251
28324
|
logFile: {
|
|
28252
28325
|
path: logPath,
|
|
28253
|
-
exists:
|
|
28326
|
+
exists: existsSync15(logPath),
|
|
28254
28327
|
sizeKb: Math.round(logFileSize / 1024)
|
|
28255
28328
|
},
|
|
28256
28329
|
recentSessions,
|
|
@@ -28316,6 +28389,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28316
28389
|
`- Plugin registered in opencode config: ${report.opencodeConfigHasPlugin}`,
|
|
28317
28390
|
`- Plugin registered in tui config: ${report.tuiConfigHasPlugin}`,
|
|
28318
28391
|
`- magic-context.jsonc parse error: ${report.magicContextConfig.parseError ?? "none"}`,
|
|
28392
|
+
`- AFT available: ${report.aft?.available ?? false} (opencode=${report.aft?.opencode ?? false}, pi=${report.aft?.pi ?? false})`,
|
|
28319
28393
|
`- Conflicts detected: ${report.conflicts.hasConflict ? report.conflicts.reasons.join("; ") : "none"}`,
|
|
28320
28394
|
"",
|
|
28321
28395
|
"### Config paths",
|
|
@@ -28364,22 +28438,23 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28364
28438
|
].join(`
|
|
28365
28439
|
`);
|
|
28366
28440
|
}
|
|
28367
|
-
var
|
|
28441
|
+
var import_comment_json8, PLUGIN_NAME5 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION;
|
|
28368
28442
|
var init_diagnostics_opencode = __esm(() => {
|
|
28443
|
+
init_aft_availability();
|
|
28369
28444
|
init_compartment_parser();
|
|
28370
28445
|
init_conflict_detector();
|
|
28371
28446
|
init_data_path();
|
|
28372
28447
|
init_opencode_helpers();
|
|
28373
28448
|
init_paths();
|
|
28374
28449
|
init_redaction();
|
|
28375
|
-
|
|
28450
|
+
import_comment_json8 = __toESM(require_src2(), 1);
|
|
28376
28451
|
PLUGIN_ENTRY_WITH_VERSION = `${PLUGIN_NAME5}@latest`;
|
|
28377
28452
|
});
|
|
28378
28453
|
|
|
28379
28454
|
// src/lib/logs-opencode.ts
|
|
28380
|
-
import { readFileSync as
|
|
28381
|
-
import { homedir as
|
|
28382
|
-
import { join as
|
|
28455
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28456
|
+
import { homedir as homedir12 } from "node:os";
|
|
28457
|
+
import { join as join14 } from "node:path";
|
|
28383
28458
|
function sanitizeLogContent(content) {
|
|
28384
28459
|
return sanitizeDiagnosticText(content);
|
|
28385
28460
|
}
|
|
@@ -28421,7 +28496,7 @@ function filterLogLinesBySession(lines, sessionId) {
|
|
|
28421
28496
|
}
|
|
28422
28497
|
async function bundleIssueReport(report, description, _title, sessionFilter = null) {
|
|
28423
28498
|
const LOG_TAIL_LINES = 400;
|
|
28424
|
-
const allLogLines = report.logFile.exists ?
|
|
28499
|
+
const allLogLines = report.logFile.exists ? readFileSync12(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
28425
28500
|
const logLines = filterLogLinesBySession(allLogLines, sessionFilter);
|
|
28426
28501
|
const recentLog = sanitizeLogContent(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
28427
28502
|
`)).trim();
|
|
@@ -28429,7 +28504,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28429
28504
|
`));
|
|
28430
28505
|
const historianFailureLines = extractHistorianFailureLines(historianScanWindow, 30);
|
|
28431
28506
|
const configBody = JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2);
|
|
28432
|
-
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(
|
|
28507
|
+
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(homedir12(), "~");
|
|
28433
28508
|
const bodyMarkdown = [
|
|
28434
28509
|
"## Description",
|
|
28435
28510
|
description,
|
|
@@ -28460,7 +28535,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
28460
28535
|
"```"
|
|
28461
28536
|
].join(`
|
|
28462
28537
|
`);
|
|
28463
|
-
const path4 =
|
|
28538
|
+
const path4 = join14(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
|
|
28464
28539
|
writeFileSync9(path4, `${bodyMarkdown}
|
|
28465
28540
|
`);
|
|
28466
28541
|
return { path: path4, bodyMarkdown };
|
|
@@ -28482,10 +28557,10 @@ var init_logs_opencode = __esm(() => {
|
|
|
28482
28557
|
|
|
28483
28558
|
// src/commands/doctor-opencode.ts
|
|
28484
28559
|
import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
28485
|
-
import { existsSync as
|
|
28560
|
+
import { existsSync as existsSync16, readFileSync as readFileSync13, rmSync, statSync as statSync3, writeFileSync as writeFileSync10 } from "node:fs";
|
|
28486
28561
|
import { createRequire as createRequire4 } from "node:module";
|
|
28487
|
-
import { homedir as
|
|
28488
|
-
import { join as
|
|
28562
|
+
import { homedir as homedir13 } from "node:os";
|
|
28563
|
+
import { join as join15 } from "node:path";
|
|
28489
28564
|
async function fetchNpmLatest(pkg, timeoutMs = 5000) {
|
|
28490
28565
|
try {
|
|
28491
28566
|
const controller = new AbortController;
|
|
@@ -28535,15 +28610,15 @@ function compareVersions(a, b2) {
|
|
|
28535
28610
|
}
|
|
28536
28611
|
async function clearPluginCache(force = false) {
|
|
28537
28612
|
const cacheDir = getOpenCodeCacheDir();
|
|
28538
|
-
const pluginCacheDir =
|
|
28539
|
-
if (!
|
|
28613
|
+
const pluginCacheDir = join15(cacheDir, "packages", PLUGIN_ENTRY_WITH_VERSION2);
|
|
28614
|
+
if (!existsSync16(pluginCacheDir)) {
|
|
28540
28615
|
return { action: "not_found", path: pluginCacheDir };
|
|
28541
28616
|
}
|
|
28542
28617
|
let cachedVersion;
|
|
28543
28618
|
try {
|
|
28544
|
-
const installedPkgPath =
|
|
28545
|
-
if (
|
|
28546
|
-
const pkg = JSON.parse(
|
|
28619
|
+
const installedPkgPath = join15(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
28620
|
+
if (existsSync16(installedPkgPath)) {
|
|
28621
|
+
const pkg = JSON.parse(readFileSync13(installedPkgPath, "utf-8"));
|
|
28547
28622
|
if (typeof pkg?.version === "string") {
|
|
28548
28623
|
cachedVersion = pkg.version;
|
|
28549
28624
|
}
|
|
@@ -28675,12 +28750,12 @@ async function runIssueFlow() {
|
|
|
28675
28750
|
}
|
|
28676
28751
|
}
|
|
28677
28752
|
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
28678
|
-
if (!
|
|
28753
|
+
if (!existsSync16(magicContextConfigPath)) {
|
|
28679
28754
|
return { issues: 0 };
|
|
28680
28755
|
}
|
|
28681
28756
|
let rawText;
|
|
28682
28757
|
try {
|
|
28683
|
-
rawText =
|
|
28758
|
+
rawText = readFileSync13(magicContextConfigPath, "utf-8");
|
|
28684
28759
|
} catch {
|
|
28685
28760
|
log.warn("Could not read magic-context.jsonc for embedding check");
|
|
28686
28761
|
return { issues: 1 };
|
|
@@ -28691,7 +28766,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
28691
28766
|
});
|
|
28692
28767
|
let parsedConfig;
|
|
28693
28768
|
try {
|
|
28694
|
-
parsedConfig =
|
|
28769
|
+
parsedConfig = import_comment_json9.parse(substituted.text);
|
|
28695
28770
|
} catch (error51) {
|
|
28696
28771
|
log.warn(`Embedding check skipped — could not parse magic-context.jsonc: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
28697
28772
|
return { issues: 1 };
|
|
@@ -28828,15 +28903,15 @@ async function runDoctor(options = {}) {
|
|
|
28828
28903
|
} else {
|
|
28829
28904
|
pass(`OpenCode config: ${paths.opencodeConfig}`);
|
|
28830
28905
|
}
|
|
28831
|
-
if (
|
|
28906
|
+
if (existsSync16(paths.magicContextConfig)) {
|
|
28832
28907
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
28833
28908
|
try {
|
|
28834
|
-
const raw =
|
|
28909
|
+
const raw = readFileSync13(paths.magicContextConfig, "utf-8");
|
|
28835
28910
|
const substituted = substituteConfigVariables({
|
|
28836
28911
|
text: raw,
|
|
28837
28912
|
configPath: paths.magicContextConfig
|
|
28838
28913
|
}).text;
|
|
28839
|
-
|
|
28914
|
+
import_comment_json9.parse(substituted);
|
|
28840
28915
|
pass("magic-context.jsonc parses as valid JSONC");
|
|
28841
28916
|
} catch (err) {
|
|
28842
28917
|
fail(`magic-context.jsonc parse failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -28856,10 +28931,10 @@ async function runDoctor(options = {}) {
|
|
|
28856
28931
|
warn(`No magic-context.jsonc found — using defaults`);
|
|
28857
28932
|
log.info(" Run 'setup' to create one with model recommendations");
|
|
28858
28933
|
}
|
|
28859
|
-
if (
|
|
28934
|
+
if (existsSync16(paths.magicContextConfig)) {
|
|
28860
28935
|
try {
|
|
28861
|
-
const mcRaw =
|
|
28862
|
-
const mcConfig =
|
|
28936
|
+
const mcRaw = readFileSync13(paths.magicContextConfig, "utf-8");
|
|
28937
|
+
const mcConfig = import_comment_json9.parse(mcRaw);
|
|
28863
28938
|
let mcChanged = false;
|
|
28864
28939
|
const experimental = mcConfig.experimental;
|
|
28865
28940
|
if (experimental && "compaction_markers" in experimental) {
|
|
@@ -28934,7 +29009,7 @@ async function runDoctor(options = {}) {
|
|
|
28934
29009
|
fixed++;
|
|
28935
29010
|
}
|
|
28936
29011
|
if (mcChanged) {
|
|
28937
|
-
writeFileSync10(paths.magicContextConfig, `${
|
|
29012
|
+
writeFileSync10(paths.magicContextConfig, `${import_comment_json9.stringify(mcConfig, null, 2)}
|
|
28938
29013
|
`);
|
|
28939
29014
|
}
|
|
28940
29015
|
} catch {
|
|
@@ -28943,8 +29018,8 @@ async function runDoctor(options = {}) {
|
|
|
28943
29018
|
}
|
|
28944
29019
|
if (paths.opencodeConfigFormat !== "none") {
|
|
28945
29020
|
try {
|
|
28946
|
-
const raw =
|
|
28947
|
-
const config2 =
|
|
29021
|
+
const raw = readFileSync13(paths.opencodeConfig, "utf-8");
|
|
29022
|
+
const config2 = import_comment_json9.parse(raw);
|
|
28948
29023
|
const rawPlugins = Array.isArray(config2?.plugin) ? config2.plugin : [];
|
|
28949
29024
|
const existingIdx = rawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
28950
29025
|
const configName = paths.opencodeConfigFormat === "jsonc" ? "opencode.jsonc" : "opencode.json";
|
|
@@ -28975,7 +29050,7 @@ async function runDoctor(options = {}) {
|
|
|
28975
29050
|
rawPlugins[existingIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
28976
29051
|
}
|
|
28977
29052
|
config2.plugin = rawPlugins;
|
|
28978
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
29053
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json9.stringify(config2, null, 2)}
|
|
28979
29054
|
`);
|
|
28980
29055
|
pass(`Upgraded plugin entry in ${configName}: ${oldEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
28981
29056
|
fixed++;
|
|
@@ -28984,7 +29059,7 @@ async function runDoctor(options = {}) {
|
|
|
28984
29059
|
} else {
|
|
28985
29060
|
rawPlugins.push(PLUGIN_ENTRY_WITH_VERSION2);
|
|
28986
29061
|
config2.plugin = rawPlugins;
|
|
28987
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
29062
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json9.stringify(config2, null, 2)}
|
|
28988
29063
|
`);
|
|
28989
29064
|
pass(`Added plugin to ${configName}`);
|
|
28990
29065
|
fixed++;
|
|
@@ -29015,10 +29090,10 @@ async function runDoctor(options = {}) {
|
|
|
29015
29090
|
pass("Added TUI sidebar plugin to tui.json");
|
|
29016
29091
|
warn("Restart OpenCode to see the sidebar");
|
|
29017
29092
|
fixed++;
|
|
29018
|
-
} else if (
|
|
29093
|
+
} else if (existsSync16(paths.tuiConfig)) {
|
|
29019
29094
|
try {
|
|
29020
|
-
const tuiRaw =
|
|
29021
|
-
const tuiConfig =
|
|
29095
|
+
const tuiRaw = readFileSync13(paths.tuiConfig, "utf-8");
|
|
29096
|
+
const tuiConfig = import_comment_json9.parse(tuiRaw);
|
|
29022
29097
|
const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
|
|
29023
29098
|
const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
29024
29099
|
const tuiEntryAsString = (entry) => {
|
|
@@ -29046,7 +29121,7 @@ async function runDoctor(options = {}) {
|
|
|
29046
29121
|
tuiRawPlugins[tuiIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
29047
29122
|
}
|
|
29048
29123
|
tuiConfig.plugin = tuiRawPlugins;
|
|
29049
|
-
writeFileSync10(paths.tuiConfig, `${
|
|
29124
|
+
writeFileSync10(paths.tuiConfig, `${import_comment_json9.stringify(tuiConfig, null, 2)}
|
|
29050
29125
|
`);
|
|
29051
29126
|
pass(`Upgraded TUI plugin: ${tuiEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
29052
29127
|
fixed++;
|
|
@@ -29063,10 +29138,10 @@ async function runDoctor(options = {}) {
|
|
|
29063
29138
|
} else {
|
|
29064
29139
|
pass("TUI sidebar plugin configured (tui.json created)");
|
|
29065
29140
|
}
|
|
29066
|
-
if (
|
|
29141
|
+
if (existsSync16(paths.magicContextConfig)) {
|
|
29067
29142
|
try {
|
|
29068
|
-
const mcRaw =
|
|
29069
|
-
const mcConfig =
|
|
29143
|
+
const mcRaw = readFileSync13(paths.magicContextConfig, "utf-8");
|
|
29144
|
+
const mcConfig = import_comment_json9.parse(mcRaw);
|
|
29070
29145
|
const dreamerObj = mcConfig?.dreamer;
|
|
29071
29146
|
const dreamerEnabled = dreamerObj?.enabled === true;
|
|
29072
29147
|
const userMemObj = dreamerObj?.user_memories;
|
|
@@ -29075,6 +29150,15 @@ async function runDoctor(options = {}) {
|
|
|
29075
29150
|
log.warn("dreamer.user_memories is enabled (default) but dreamer itself is disabled — user memory candidates will be collected but never promoted to stable memories. Enable `dreamer.enabled: true` or set `dreamer.user_memories.enabled: false` to silence this.");
|
|
29076
29151
|
issues++;
|
|
29077
29152
|
}
|
|
29153
|
+
const pinKeyFilesObj = dreamerObj?.pin_key_files;
|
|
29154
|
+
if (pinKeyFilesObj?.enabled === true) {
|
|
29155
|
+
const aft = getAftAvailability();
|
|
29156
|
+
if (aft.available) {
|
|
29157
|
+
pass("AFT detected for dreamer.pin_key_files");
|
|
29158
|
+
} else {
|
|
29159
|
+
fail(`dreamer.pin_key_files is enabled but AFT is not configured. Install/register AFT (checked: ${aft.checkedPaths.join(", ")})`);
|
|
29160
|
+
}
|
|
29161
|
+
}
|
|
29078
29162
|
} catch {}
|
|
29079
29163
|
}
|
|
29080
29164
|
const embeddingCheck = await checkEmbeddingConfig(paths.magicContextConfig);
|
|
@@ -29083,8 +29167,8 @@ async function runDoctor(options = {}) {
|
|
|
29083
29167
|
failCount += embeddingCheck.issues;
|
|
29084
29168
|
else
|
|
29085
29169
|
passCount++;
|
|
29086
|
-
const dbPath =
|
|
29087
|
-
if (!
|
|
29170
|
+
const dbPath = join15(getMagicContextStorageDir(), "context.db");
|
|
29171
|
+
if (!existsSync16(dbPath)) {
|
|
29088
29172
|
log.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
29089
29173
|
} else {
|
|
29090
29174
|
pass(`Shared context DB exists at ${dbPath}`);
|
|
@@ -29145,10 +29229,10 @@ async function runDoctor(options = {}) {
|
|
|
29145
29229
|
}
|
|
29146
29230
|
{
|
|
29147
29231
|
const ageWarnings = [];
|
|
29148
|
-
const npmrcPath =
|
|
29149
|
-
if (
|
|
29232
|
+
const npmrcPath = join15(homedir13(), ".npmrc");
|
|
29233
|
+
if (existsSync16(npmrcPath)) {
|
|
29150
29234
|
try {
|
|
29151
|
-
const npmrc =
|
|
29235
|
+
const npmrc = readFileSync13(npmrcPath, "utf-8");
|
|
29152
29236
|
for (const line of npmrc.split(`
|
|
29153
29237
|
`)) {
|
|
29154
29238
|
const trimmed = line.trim();
|
|
@@ -29172,7 +29256,7 @@ async function runDoctor(options = {}) {
|
|
|
29172
29256
|
}
|
|
29173
29257
|
}
|
|
29174
29258
|
const logPath = getMagicContextLogPath2("opencode");
|
|
29175
|
-
if (
|
|
29259
|
+
if (existsSync16(logPath)) {
|
|
29176
29260
|
const logStat = statSync3(logPath);
|
|
29177
29261
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
29178
29262
|
log.info(`Log file: ${logPath} (${sizeKb} KB)`);
|
|
@@ -29218,10 +29302,11 @@ async function runDoctor(options = {}) {
|
|
|
29218
29302
|
}
|
|
29219
29303
|
return 0;
|
|
29220
29304
|
}
|
|
29221
|
-
var
|
|
29305
|
+
var import_comment_json9, PLUGIN_NAME6 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION2, CLI_PACKAGE_NAME = "@cortexkit/magic-context";
|
|
29222
29306
|
var init_doctor_opencode = __esm(async () => {
|
|
29223
29307
|
init_config();
|
|
29224
29308
|
init_variable();
|
|
29309
|
+
init_aft_availability();
|
|
29225
29310
|
init_conflict_detector();
|
|
29226
29311
|
init_conflict_fixer();
|
|
29227
29312
|
init_data_path();
|
|
@@ -29233,7 +29318,7 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
29233
29318
|
init_paths();
|
|
29234
29319
|
init_prompts();
|
|
29235
29320
|
await init_sqlite();
|
|
29236
|
-
|
|
29321
|
+
import_comment_json9 = __toESM(require_src2(), 1);
|
|
29237
29322
|
PLUGIN_ENTRY_WITH_VERSION2 = `${PLUGIN_NAME6}@latest`;
|
|
29238
29323
|
});
|
|
29239
29324
|
|
|
@@ -161820,6 +161905,34 @@ function getErrorMessage(error51) {
|
|
|
161820
161905
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
161821
161906
|
}
|
|
161822
161907
|
|
|
161908
|
+
// ../plugin/src/features/magic-context/key-files/project-key-files.ts
|
|
161909
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14, realpathSync } from "node:fs";
|
|
161910
|
+
function deleteOrphanProjectKeyFiles(db, now = Date.now()) {
|
|
161911
|
+
const cutoff = now - ORPHAN_GRACE_MS;
|
|
161912
|
+
const rows = db.prepare(`SELECT project_path AS projectPath, MAX(generated_at) AS lastGen
|
|
161913
|
+
FROM project_key_files
|
|
161914
|
+
GROUP BY project_path
|
|
161915
|
+
HAVING lastGen < ?`).all(cutoff);
|
|
161916
|
+
let deletedProjects = 0;
|
|
161917
|
+
for (const row of rows) {
|
|
161918
|
+
if (existsSync17(row.projectPath))
|
|
161919
|
+
continue;
|
|
161920
|
+
try {
|
|
161921
|
+
db.prepare("DELETE FROM project_key_files WHERE project_path = ?").run(row.projectPath);
|
|
161922
|
+
db.prepare("DELETE FROM project_key_files_version WHERE project_path = ?").run(row.projectPath);
|
|
161923
|
+
deletedProjects++;
|
|
161924
|
+
} catch (error51) {
|
|
161925
|
+
log2(`[key-files] orphan GC failed for ${row.projectPath}:`, error51);
|
|
161926
|
+
}
|
|
161927
|
+
}
|
|
161928
|
+
return deletedProjects;
|
|
161929
|
+
}
|
|
161930
|
+
var ORPHAN_GRACE_MS;
|
|
161931
|
+
var init_project_key_files = __esm(() => {
|
|
161932
|
+
init_logger();
|
|
161933
|
+
ORPHAN_GRACE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
161934
|
+
});
|
|
161935
|
+
|
|
161823
161936
|
// ../plugin/src/features/magic-context/migrations.ts
|
|
161824
161937
|
function ensureMigrationsTable(db) {
|
|
161825
161938
|
db.exec(`
|
|
@@ -162187,6 +162300,46 @@ var init_migrations = __esm(async () => {
|
|
|
162187
162300
|
db.exec("ALTER TABLE session_meta ADD COLUMN pending_compaction_marker_state TEXT");
|
|
162188
162301
|
}
|
|
162189
162302
|
}
|
|
162303
|
+
},
|
|
162304
|
+
{
|
|
162305
|
+
version: 14,
|
|
162306
|
+
description: "Add project-scoped key files and version counter",
|
|
162307
|
+
up: (db) => {
|
|
162308
|
+
db.exec(`
|
|
162309
|
+
CREATE TABLE IF NOT EXISTS project_key_files (
|
|
162310
|
+
project_path TEXT NOT NULL,
|
|
162311
|
+
path TEXT NOT NULL,
|
|
162312
|
+
content TEXT NOT NULL,
|
|
162313
|
+
content_hash TEXT NOT NULL,
|
|
162314
|
+
local_token_estimate INTEGER NOT NULL,
|
|
162315
|
+
generated_at INTEGER NOT NULL,
|
|
162316
|
+
generated_by_model TEXT,
|
|
162317
|
+
generation_config_hash TEXT NOT NULL,
|
|
162318
|
+
stale_reason TEXT,
|
|
162319
|
+
PRIMARY KEY (project_path, path)
|
|
162320
|
+
);
|
|
162321
|
+
|
|
162322
|
+
CREATE INDEX IF NOT EXISTS idx_project_key_files_project
|
|
162323
|
+
ON project_key_files(project_path);
|
|
162324
|
+
CREATE INDEX IF NOT EXISTS idx_project_key_files_generated_at
|
|
162325
|
+
ON project_key_files(project_path, generated_at);
|
|
162326
|
+
|
|
162327
|
+
CREATE TABLE IF NOT EXISTS project_key_files_version (
|
|
162328
|
+
project_path TEXT PRIMARY KEY,
|
|
162329
|
+
version INTEGER NOT NULL DEFAULT 0
|
|
162330
|
+
);
|
|
162331
|
+
`);
|
|
162332
|
+
}
|
|
162333
|
+
},
|
|
162334
|
+
{
|
|
162335
|
+
version: 15,
|
|
162336
|
+
description: "Add deferred_execute_state column for boundary execution drain",
|
|
162337
|
+
up: (db) => {
|
|
162338
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
162339
|
+
if (!cols.some((c2) => c2.name === "deferred_execute_state")) {
|
|
162340
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN deferred_execute_state TEXT");
|
|
162341
|
+
}
|
|
162342
|
+
}
|
|
162190
162343
|
}
|
|
162191
162344
|
];
|
|
162192
162345
|
});
|
|
@@ -162224,10 +162377,10 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
162224
162377
|
});
|
|
162225
162378
|
|
|
162226
162379
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
162227
|
-
import { existsSync as
|
|
162228
|
-
import { join as
|
|
162380
|
+
import { existsSync as existsSync18 } from "node:fs";
|
|
162381
|
+
import { join as join16 } from "node:path";
|
|
162229
162382
|
function resolveOpencodeDbPath() {
|
|
162230
|
-
return
|
|
162383
|
+
return join16(getDataDir(), "opencode", "opencode.db");
|
|
162231
162384
|
}
|
|
162232
162385
|
function ensureBackfillStateTable(db) {
|
|
162233
162386
|
db.exec(`
|
|
@@ -162262,7 +162415,7 @@ function runToolOwnerBackfill(db) {
|
|
|
162262
162415
|
return result;
|
|
162263
162416
|
}
|
|
162264
162417
|
const opencodeDbPath = resolveOpencodeDbPath();
|
|
162265
|
-
if (!
|
|
162418
|
+
if (!existsSync18(opencodeDbPath)) {
|
|
162266
162419
|
log2(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
162267
162420
|
markAllUnbackfilledSessionsSkipped(db);
|
|
162268
162421
|
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
@@ -162472,25 +162625,25 @@ var init_tool_owner_backfill = __esm(() => {
|
|
|
162472
162625
|
});
|
|
162473
162626
|
|
|
162474
162627
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
162475
|
-
import { copyFileSync, cpSync, existsSync as
|
|
162476
|
-
import { join as
|
|
162628
|
+
import { copyFileSync, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync7 } from "node:fs";
|
|
162629
|
+
import { join as join17 } from "node:path";
|
|
162477
162630
|
function resolveDatabasePath() {
|
|
162478
162631
|
const dbDir = getMagicContextStorageDir();
|
|
162479
|
-
return { dbDir, dbPath:
|
|
162632
|
+
return { dbDir, dbPath: join17(dbDir, "context.db") };
|
|
162480
162633
|
}
|
|
162481
162634
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
162482
|
-
if (
|
|
162635
|
+
if (existsSync19(targetDbPath))
|
|
162483
162636
|
return;
|
|
162484
162637
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
162485
|
-
const legacyDbPath =
|
|
162486
|
-
if (!
|
|
162638
|
+
const legacyDbPath = join17(legacyDir, "context.db");
|
|
162639
|
+
if (!existsSync19(legacyDbPath))
|
|
162487
162640
|
return;
|
|
162488
162641
|
log2(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
162489
162642
|
mkdirSync7(targetDbDir, { recursive: true });
|
|
162490
162643
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
162491
162644
|
const src = `${legacyDbPath}${suffix}`;
|
|
162492
|
-
const dst =
|
|
162493
|
-
if (
|
|
162645
|
+
const dst = join17(targetDbDir, `context.db${suffix}`);
|
|
162646
|
+
if (existsSync19(src)) {
|
|
162494
162647
|
try {
|
|
162495
162648
|
copyFileSync(src, dst);
|
|
162496
162649
|
} catch (error51) {
|
|
@@ -162498,9 +162651,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
162498
162651
|
}
|
|
162499
162652
|
}
|
|
162500
162653
|
}
|
|
162501
|
-
const legacyModelsDir =
|
|
162502
|
-
const targetModelsDir =
|
|
162503
|
-
if (
|
|
162654
|
+
const legacyModelsDir = join17(legacyDir, "models");
|
|
162655
|
+
const targetModelsDir = join17(targetDbDir, "models");
|
|
162656
|
+
if (existsSync19(legacyModelsDir) && !existsSync19(targetModelsDir)) {
|
|
162504
162657
|
try {
|
|
162505
162658
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
162506
162659
|
} catch (error51) {
|
|
@@ -162648,6 +162801,26 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162648
162801
|
);
|
|
162649
162802
|
CREATE INDEX IF NOT EXISTS idx_dream_runs_project ON dream_runs(project_path, finished_at DESC);
|
|
162650
162803
|
|
|
162804
|
+
CREATE TABLE IF NOT EXISTS project_key_files (
|
|
162805
|
+
project_path TEXT NOT NULL,
|
|
162806
|
+
path TEXT NOT NULL,
|
|
162807
|
+
content TEXT NOT NULL,
|
|
162808
|
+
content_hash TEXT NOT NULL,
|
|
162809
|
+
local_token_estimate INTEGER NOT NULL,
|
|
162810
|
+
generated_at INTEGER NOT NULL,
|
|
162811
|
+
generated_by_model TEXT,
|
|
162812
|
+
generation_config_hash TEXT NOT NULL,
|
|
162813
|
+
stale_reason TEXT,
|
|
162814
|
+
PRIMARY KEY (project_path, path)
|
|
162815
|
+
);
|
|
162816
|
+
CREATE INDEX IF NOT EXISTS idx_project_key_files_project ON project_key_files(project_path);
|
|
162817
|
+
CREATE INDEX IF NOT EXISTS idx_project_key_files_generated_at ON project_key_files(project_path, generated_at);
|
|
162818
|
+
|
|
162819
|
+
CREATE TABLE IF NOT EXISTS project_key_files_version (
|
|
162820
|
+
project_path TEXT PRIMARY KEY,
|
|
162821
|
+
version INTEGER NOT NULL DEFAULT 0
|
|
162822
|
+
);
|
|
162823
|
+
|
|
162651
162824
|
-- (smart_notes: see note above; merged into unified notes table by migration v1)
|
|
162652
162825
|
|
|
162653
162826
|
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
@@ -162725,7 +162898,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162725
162898
|
-- valid JSON blob written via setPendingCompactionMarkerState.
|
|
162726
162899
|
-- Excluded from healNullTextColumns. Readers filter IS NOT NULL AND
|
|
162727
162900
|
-- != empty-string defensively. Plan v6 section 3.
|
|
162728
|
-
pending_compaction_marker_state TEXT
|
|
162901
|
+
pending_compaction_marker_state TEXT,
|
|
162902
|
+
-- deferred_execute_state: intentionally NULLABLE without a default.
|
|
162903
|
+
-- Absence is SQL NULL; presence is a JSON blob written via
|
|
162904
|
+
-- setDeferredExecutePendingIfAbsent. Excluded from healNullTextColumns.
|
|
162905
|
+
deferred_execute_state TEXT
|
|
162729
162906
|
);
|
|
162730
162907
|
|
|
162731
162908
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
@@ -162814,6 +162991,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162814
162991
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
162815
162992
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
162816
162993
|
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
162994
|
+
ensureColumn(db, "session_meta", "deferred_execute_state", "TEXT");
|
|
162817
162995
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162818
162996
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162819
162997
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -162890,7 +163068,15 @@ function ensureColumn(db, table, column, definition) {
|
|
|
162890
163068
|
if (rows.some((row) => row.name === column)) {
|
|
162891
163069
|
return;
|
|
162892
163070
|
}
|
|
162893
|
-
|
|
163071
|
+
try {
|
|
163072
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
163073
|
+
} catch (err) {
|
|
163074
|
+
const recheck = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
163075
|
+
if (recheck.some((row) => row.name === column)) {
|
|
163076
|
+
return;
|
|
163077
|
+
}
|
|
163078
|
+
throw err;
|
|
163079
|
+
}
|
|
162894
163080
|
}
|
|
162895
163081
|
function openDatabase() {
|
|
162896
163082
|
const { dbDir, dbPath } = resolveDatabasePath();
|
|
@@ -162907,6 +163093,11 @@ function openDatabase() {
|
|
|
162907
163093
|
const db = new Database(dbPath);
|
|
162908
163094
|
initializeDatabase(db);
|
|
162909
163095
|
runMigrations(db);
|
|
163096
|
+
try {
|
|
163097
|
+
deleteOrphanProjectKeyFiles(db);
|
|
163098
|
+
} catch (error51) {
|
|
163099
|
+
log2(`[magic-context] key-files orphan GC failed: ${getErrorMessage(error51)}`);
|
|
163100
|
+
}
|
|
162910
163101
|
try {
|
|
162911
163102
|
runToolOwnerBackfill(db);
|
|
162912
163103
|
} catch (error51) {
|
|
@@ -162942,6 +163133,7 @@ var databases, persistenceByDatabase, persistenceErrorByDatabase;
|
|
|
162942
163133
|
var init_storage_db = __esm(async () => {
|
|
162943
163134
|
init_data_path();
|
|
162944
163135
|
init_logger();
|
|
163136
|
+
init_project_key_files();
|
|
162945
163137
|
init_tool_definition_tokens();
|
|
162946
163138
|
init_tool_owner_backfill();
|
|
162947
163139
|
await __promiseAll([
|
|
@@ -163045,24 +163237,24 @@ var init_storage = __esm(async () => {
|
|
|
163045
163237
|
});
|
|
163046
163238
|
|
|
163047
163239
|
// ../pi-plugin/src/config/index.ts
|
|
163048
|
-
import { existsSync as
|
|
163049
|
-
import { homedir as
|
|
163050
|
-
import { join as
|
|
163240
|
+
import { existsSync as existsSync20, readFileSync as readFileSync15 } from "node:fs";
|
|
163241
|
+
import { homedir as homedir14 } from "node:os";
|
|
163242
|
+
import { join as join18 } from "node:path";
|
|
163051
163243
|
function getProjectConfigPaths(cwd) {
|
|
163052
|
-
const basePath =
|
|
163244
|
+
const basePath = join18(cwd, ".pi", CONFIG_FILE_NAME);
|
|
163053
163245
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
163054
163246
|
}
|
|
163055
163247
|
function getUserConfigPaths() {
|
|
163056
|
-
const home = process.env.HOME ??
|
|
163057
|
-
const basePath =
|
|
163248
|
+
const home = process.env.HOME ?? homedir14();
|
|
163249
|
+
const basePath = join18(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
163058
163250
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
163059
163251
|
}
|
|
163060
163252
|
function resolveFirstExisting(paths) {
|
|
163061
|
-
return paths.find((path4) =>
|
|
163253
|
+
return paths.find((path4) => existsSync20(path4));
|
|
163062
163254
|
}
|
|
163063
163255
|
function loadConfigFile2(path4, scope) {
|
|
163064
163256
|
try {
|
|
163065
|
-
const rawText =
|
|
163257
|
+
const rawText = readFileSync15(path4, "utf-8");
|
|
163066
163258
|
const substituted = substituteConfigVariables({
|
|
163067
163259
|
text: rawText,
|
|
163068
163260
|
configPath: path4
|
|
@@ -163070,7 +163262,7 @@ function loadConfigFile2(path4, scope) {
|
|
|
163070
163262
|
return {
|
|
163071
163263
|
path: path4,
|
|
163072
163264
|
scope,
|
|
163073
|
-
config:
|
|
163265
|
+
config: import_comment_json10.parse(substituted.text),
|
|
163074
163266
|
warnings: substituted.warnings.map((warning) => `${path4}: ${warning}`)
|
|
163075
163267
|
};
|
|
163076
163268
|
} catch (error51) {
|
|
@@ -163183,19 +163375,19 @@ function loadPiConfig(opts = {}) {
|
|
|
163183
163375
|
loadedFromPaths: loadedFiles.map((loaded) => loaded.path)
|
|
163184
163376
|
};
|
|
163185
163377
|
}
|
|
163186
|
-
var
|
|
163378
|
+
var import_comment_json10, CONFIG_FILE_NAME = "magic-context";
|
|
163187
163379
|
var init_config2 = __esm(() => {
|
|
163188
163380
|
init_magic_context();
|
|
163189
163381
|
init_variable();
|
|
163190
|
-
|
|
163382
|
+
import_comment_json10 = __toESM(require_src2(), 1);
|
|
163191
163383
|
});
|
|
163192
163384
|
|
|
163193
163385
|
// src/lib/diagnostics-pi.ts
|
|
163194
163386
|
import { createHash } from "node:crypto";
|
|
163195
|
-
import { existsSync as
|
|
163387
|
+
import { existsSync as existsSync21, readdirSync as readdirSync3, readFileSync as readFileSync16, statSync as statSync4 } from "node:fs";
|
|
163196
163388
|
import { createRequire as createRequire5 } from "node:module";
|
|
163197
|
-
import { homedir as
|
|
163198
|
-
import { join as
|
|
163389
|
+
import { homedir as homedir15, userInfo as userInfo2 } from "node:os";
|
|
163390
|
+
import { join as join19 } from "node:path";
|
|
163199
163391
|
function getSelfVersion3() {
|
|
163200
163392
|
const req = createRequire5(import.meta.url);
|
|
163201
163393
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -163210,7 +163402,7 @@ function getSelfVersion3() {
|
|
|
163210
163402
|
}
|
|
163211
163403
|
function fileSize2(path4) {
|
|
163212
163404
|
try {
|
|
163213
|
-
return
|
|
163405
|
+
return existsSync21(path4) ? statSync4(path4).size : 0;
|
|
163214
163406
|
} catch {
|
|
163215
163407
|
return 0;
|
|
163216
163408
|
}
|
|
@@ -163226,7 +163418,7 @@ function redactSecretString(value) {
|
|
|
163226
163418
|
return value.replace(/Bearer\s+[A-Za-z0-9._~+\-/=]+/g, "Bearer <REDACTED>").replace(/sk-[A-Za-z0-9_-]{12,}/g, "sk-<REDACTED>").replace(/api[_-]?key=([^\s&]+)/gi, "api_key=<REDACTED>").replace(/token=([^\s&]+)/gi, "token=<REDACTED>");
|
|
163227
163419
|
}
|
|
163228
163420
|
function sanitizeString2(value) {
|
|
163229
|
-
const home = process.env.HOME ||
|
|
163421
|
+
const home = process.env.HOME || homedir15();
|
|
163230
163422
|
const username = userInfo2().username;
|
|
163231
163423
|
const userHash = `<USER:${currentUserHash()}>`;
|
|
163232
163424
|
let sanitized = redactSecretString(value);
|
|
@@ -163260,11 +163452,11 @@ function sanitizeValue2(value, key = "") {
|
|
|
163260
163452
|
return value;
|
|
163261
163453
|
}
|
|
163262
163454
|
function readJsonc3(path4) {
|
|
163263
|
-
if (!
|
|
163455
|
+
if (!existsSync21(path4))
|
|
163264
163456
|
return { value: {} };
|
|
163265
163457
|
try {
|
|
163266
163458
|
return {
|
|
163267
|
-
value:
|
|
163459
|
+
value: import_comment_json11.parse(readFileSync16(path4, "utf-8"))
|
|
163268
163460
|
};
|
|
163269
163461
|
} catch (error51) {
|
|
163270
163462
|
return {
|
|
@@ -163274,13 +163466,13 @@ function readJsonc3(path4) {
|
|
|
163274
163466
|
}
|
|
163275
163467
|
}
|
|
163276
163468
|
function getProjectConfigPath(cwd) {
|
|
163277
|
-
return
|
|
163469
|
+
return join19(cwd, ".pi", "magic-context.jsonc");
|
|
163278
163470
|
}
|
|
163279
163471
|
function readConfigDiagnostic(path4) {
|
|
163280
163472
|
const parsed = readJsonc3(path4);
|
|
163281
163473
|
return {
|
|
163282
163474
|
path: path4,
|
|
163283
|
-
exists:
|
|
163475
|
+
exists: existsSync21(path4),
|
|
163284
163476
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
163285
163477
|
flags: sanitizeValue2(parsed.value)
|
|
163286
163478
|
};
|
|
@@ -163297,8 +163489,8 @@ function reverseSlugToDirectory(slug) {
|
|
|
163297
163489
|
return `/${inner.replace(/-/g, "/")}`;
|
|
163298
163490
|
}
|
|
163299
163491
|
function collectPiRecentSessions() {
|
|
163300
|
-
const sessionsRoot =
|
|
163301
|
-
if (!
|
|
163492
|
+
const sessionsRoot = join19(homedir15(), ".pi", "agent", "sessions");
|
|
163493
|
+
if (!existsSync21(sessionsRoot))
|
|
163302
163494
|
return [];
|
|
163303
163495
|
try {
|
|
163304
163496
|
const slugs = readdirSync3(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -163307,7 +163499,7 @@ function collectPiRecentSessions() {
|
|
|
163307
163499
|
const directory = reverseSlugToDirectory(slug);
|
|
163308
163500
|
if (!directory)
|
|
163309
163501
|
continue;
|
|
163310
|
-
const slugDir =
|
|
163502
|
+
const slugDir = join19(sessionsRoot, slug);
|
|
163311
163503
|
let files;
|
|
163312
163504
|
try {
|
|
163313
163505
|
files = readdirSync3(slugDir).filter((name2) => name2.endsWith(".jsonl"));
|
|
@@ -163316,7 +163508,7 @@ function collectPiRecentSessions() {
|
|
|
163316
163508
|
}
|
|
163317
163509
|
for (const file2 of files) {
|
|
163318
163510
|
try {
|
|
163319
|
-
const mtime = statSync4(
|
|
163511
|
+
const mtime = statSync4(join19(slugDir, file2)).mtimeMs;
|
|
163320
163512
|
const sessionId = file2.replace(/\.jsonl$/, "");
|
|
163321
163513
|
candidates.push({ sessionId, directory, mtime });
|
|
163322
163514
|
} catch {}
|
|
@@ -163334,7 +163526,7 @@ function collectPiRecentSessions() {
|
|
|
163334
163526
|
}
|
|
163335
163527
|
function parseHistorianDumpMeta2(path4) {
|
|
163336
163528
|
try {
|
|
163337
|
-
const xml =
|
|
163529
|
+
const xml = readFileSync16(path4, "utf-8");
|
|
163338
163530
|
const parsed = parseCompartmentOutput(xml);
|
|
163339
163531
|
const factCountByCategory = {};
|
|
163340
163532
|
for (const fact of parsed.facts) {
|
|
@@ -163367,11 +163559,11 @@ function parseHistorianDumpMeta2(path4) {
|
|
|
163367
163559
|
}
|
|
163368
163560
|
}
|
|
163369
163561
|
function listDumpsInDir2(dir, limit) {
|
|
163370
|
-
if (!
|
|
163562
|
+
if (!existsSync21(dir))
|
|
163371
163563
|
return { count: 0, recent: [] };
|
|
163372
163564
|
try {
|
|
163373
163565
|
const entries = readdirSync3(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
|
|
163374
|
-
const stat = statSync4(
|
|
163566
|
+
const stat = statSync4(join19(dir, name2));
|
|
163375
163567
|
return {
|
|
163376
163568
|
name: name2,
|
|
163377
163569
|
mtime: stat.mtimeMs,
|
|
@@ -163380,7 +163572,7 @@ function listDumpsInDir2(dir, limit) {
|
|
|
163380
163572
|
}).sort((a, b2) => b2.mtime - a.mtime);
|
|
163381
163573
|
const now = Date.now();
|
|
163382
163574
|
const recent = entries.slice(0, limit).map((entry) => {
|
|
163383
|
-
const meta3 = parseHistorianDumpMeta2(
|
|
163575
|
+
const meta3 = parseHistorianDumpMeta2(join19(dir, entry.name));
|
|
163384
163576
|
const summary = {
|
|
163385
163577
|
name: entry.name,
|
|
163386
163578
|
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
@@ -163443,9 +163635,9 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163443
163635
|
const projectConfigPath = getProjectConfigPath(cwd);
|
|
163444
163636
|
const loaded = loadPiConfig({ cwd });
|
|
163445
163637
|
const storageDirPath = getMagicContextStorageDir();
|
|
163446
|
-
const dbPath =
|
|
163638
|
+
const dbPath = join19(storageDirPath, "context.db");
|
|
163447
163639
|
const logPath = getMagicContextLogPath2("pi");
|
|
163448
|
-
const logFileSize =
|
|
163640
|
+
const logFileSize = existsSync21(logPath) ? statSync4(logPath).size : 0;
|
|
163449
163641
|
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
163450
163642
|
const recentSessions = collectPiRecentSessions();
|
|
163451
163643
|
const historianDumps = collectPiHistorianDumps(recentSessions);
|
|
@@ -163460,7 +163652,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163460
163652
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
163461
163653
|
settings: {
|
|
163462
163654
|
path: settingsPath,
|
|
163463
|
-
exists:
|
|
163655
|
+
exists: existsSync21(settingsPath),
|
|
163464
163656
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
163465
163657
|
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
163466
163658
|
packages: sanitizeValue2(packages)
|
|
@@ -163476,7 +163668,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163476
163668
|
loadWarnings: loaded.warnings.map(sanitizeString2),
|
|
163477
163669
|
storageDir: {
|
|
163478
163670
|
path: storageDirPath,
|
|
163479
|
-
exists:
|
|
163671
|
+
exists: existsSync21(storageDirPath),
|
|
163480
163672
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
163481
163673
|
},
|
|
163482
163674
|
conflicts: {
|
|
@@ -163485,7 +163677,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163485
163677
|
},
|
|
163486
163678
|
logFile: {
|
|
163487
163679
|
path: logPath,
|
|
163488
|
-
exists:
|
|
163680
|
+
exists: existsSync21(logPath),
|
|
163489
163681
|
sizeKb: Math.round(logFileSize / 1024)
|
|
163490
163682
|
},
|
|
163491
163683
|
recentSessions,
|
|
@@ -163566,7 +163758,7 @@ function renderDiagnosticsMarkdown2(report) {
|
|
|
163566
163758
|
].join(`
|
|
163567
163759
|
`);
|
|
163568
163760
|
}
|
|
163569
|
-
var
|
|
163761
|
+
var import_comment_json11;
|
|
163570
163762
|
var init_diagnostics_pi = __esm(() => {
|
|
163571
163763
|
init_compartment_parser();
|
|
163572
163764
|
init_data_path();
|
|
@@ -163574,12 +163766,12 @@ var init_diagnostics_pi = __esm(() => {
|
|
|
163574
163766
|
init_paths();
|
|
163575
163767
|
init_pi_helpers();
|
|
163576
163768
|
init_pi_package_entry();
|
|
163577
|
-
|
|
163769
|
+
import_comment_json11 = __toESM(require_src2(), 1);
|
|
163578
163770
|
});
|
|
163579
163771
|
|
|
163580
163772
|
// src/lib/logs-pi.ts
|
|
163581
|
-
import { readFileSync as
|
|
163582
|
-
import { join as
|
|
163773
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync11 } from "node:fs";
|
|
163774
|
+
import { join as join20 } from "node:path";
|
|
163583
163775
|
function sanitizeLogContent2(content) {
|
|
163584
163776
|
return sanitizeString2(content);
|
|
163585
163777
|
}
|
|
@@ -163608,7 +163800,7 @@ function filterLogLinesBySession2(lines, sessionId) {
|
|
|
163608
163800
|
}
|
|
163609
163801
|
async function bundleIssueReport2(report, description, title, options = {}) {
|
|
163610
163802
|
const LOG_TAIL_LINES = 400;
|
|
163611
|
-
const allLogLines = report.logFile.exists ?
|
|
163803
|
+
const allLogLines = report.logFile.exists ? readFileSync17(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
163612
163804
|
const logLines = filterLogLinesBySession2(allLogLines, options.sessionFilter ?? null);
|
|
163613
163805
|
const recentLog = sanitizeLogContent2(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
163614
163806
|
`)).trim();
|
|
@@ -163635,7 +163827,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163635
163827
|
].join(`
|
|
163636
163828
|
`);
|
|
163637
163829
|
const cwd = options.cwd ?? process.cwd();
|
|
163638
|
-
const path4 =
|
|
163830
|
+
const path4 = join20(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
163639
163831
|
writeFileSync11(path4, `${bodyMarkdown}
|
|
163640
163832
|
`);
|
|
163641
163833
|
return { path: path4, bodyMarkdown };
|
|
@@ -163647,17 +163839,17 @@ var init_logs_pi = __esm(() => {
|
|
|
163647
163839
|
// src/commands/doctor-pi.ts
|
|
163648
163840
|
import { execFileSync as execFileSync4, spawnSync as spawnSync3 } from "node:child_process";
|
|
163649
163841
|
import {
|
|
163650
|
-
existsSync as
|
|
163842
|
+
existsSync as existsSync22,
|
|
163651
163843
|
mkdirSync as mkdirSync8,
|
|
163652
163844
|
readdirSync as readdirSync4,
|
|
163653
|
-
readFileSync as
|
|
163845
|
+
readFileSync as readFileSync18,
|
|
163654
163846
|
rmSync as rmSync2,
|
|
163655
163847
|
statSync as statSync5,
|
|
163656
163848
|
writeFileSync as writeFileSync12
|
|
163657
163849
|
} from "node:fs";
|
|
163658
163850
|
import { createRequire as createRequire6 } from "node:module";
|
|
163659
|
-
import { homedir as
|
|
163660
|
-
import { dirname as dirname9, join as
|
|
163851
|
+
import { homedir as homedir16 } from "node:os";
|
|
163852
|
+
import { dirname as dirname9, join as join21 } from "node:path";
|
|
163661
163853
|
function depsFrom(options) {
|
|
163662
163854
|
return {
|
|
163663
163855
|
...DEFAULT_DEPS,
|
|
@@ -163744,7 +163936,7 @@ function summarize(results) {
|
|
|
163744
163936
|
function readJsonc4(path4) {
|
|
163745
163937
|
try {
|
|
163746
163938
|
return {
|
|
163747
|
-
value:
|
|
163939
|
+
value: import_comment_json12.parse(readFileSync18(path4, "utf-8"))
|
|
163748
163940
|
};
|
|
163749
163941
|
} catch (error51) {
|
|
163750
163942
|
return {
|
|
@@ -163757,18 +163949,18 @@ function packagesFrom(settings) {
|
|
|
163757
163949
|
return Array.isArray(settings.packages) ? settings.packages : [];
|
|
163758
163950
|
}
|
|
163759
163951
|
function projectConfigPath(cwd) {
|
|
163760
|
-
return
|
|
163952
|
+
return join21(cwd, ".pi", "magic-context.jsonc");
|
|
163761
163953
|
}
|
|
163762
163954
|
function readConfigForEmbedding(path4) {
|
|
163763
|
-
if (!
|
|
163955
|
+
if (!existsSync22(path4))
|
|
163764
163956
|
return null;
|
|
163765
163957
|
try {
|
|
163766
|
-
const rawText =
|
|
163958
|
+
const rawText = readFileSync18(path4, "utf-8");
|
|
163767
163959
|
const substituted = substituteConfigVariables({
|
|
163768
163960
|
text: rawText,
|
|
163769
163961
|
configPath: path4
|
|
163770
163962
|
});
|
|
163771
|
-
return
|
|
163963
|
+
return import_comment_json12.parse(substituted.text);
|
|
163772
163964
|
} catch {
|
|
163773
163965
|
return null;
|
|
163774
163966
|
}
|
|
@@ -163821,20 +164013,20 @@ function countTable(db, table) {
|
|
|
163821
164013
|
}
|
|
163822
164014
|
}
|
|
163823
164015
|
function cacheRoots() {
|
|
163824
|
-
const home =
|
|
163825
|
-
const cacheHome = process.env.XDG_CACHE_HOME ||
|
|
164016
|
+
const home = homedir16();
|
|
164017
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join21(home, ".cache");
|
|
163826
164018
|
return [
|
|
163827
|
-
|
|
163828
|
-
|
|
163829
|
-
|
|
163830
|
-
|
|
163831
|
-
|
|
164019
|
+
join21(home, ".pi", "cache", "extensions"),
|
|
164020
|
+
join21(home, ".pi", "cache", "packages"),
|
|
164021
|
+
join21(cacheHome, "pi", "extensions"),
|
|
164022
|
+
join21(cacheHome, "pi", "packages"),
|
|
164023
|
+
join21(getPiAgentConfigDir(), "cache", "extensions")
|
|
163832
164024
|
];
|
|
163833
164025
|
}
|
|
163834
164026
|
function findPiMagicContextCacheDirs(self, force = false) {
|
|
163835
164027
|
const found = new Map;
|
|
163836
164028
|
const visit = (path4, depth) => {
|
|
163837
|
-
if (depth < 0 || !
|
|
164029
|
+
if (depth < 0 || !existsSync22(path4))
|
|
163838
164030
|
return;
|
|
163839
164031
|
let stat;
|
|
163840
164032
|
try {
|
|
@@ -163844,10 +164036,10 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
163844
164036
|
}
|
|
163845
164037
|
if (!stat.isDirectory())
|
|
163846
164038
|
return;
|
|
163847
|
-
const packageJson =
|
|
163848
|
-
if (
|
|
164039
|
+
const packageJson = join21(path4, "package.json");
|
|
164040
|
+
if (existsSync22(packageJson)) {
|
|
163849
164041
|
try {
|
|
163850
|
-
const pkg = JSON.parse(
|
|
164042
|
+
const pkg = JSON.parse(readFileSync18(packageJson, "utf-8"));
|
|
163851
164043
|
const name2 = typeof pkg.name === "string" ? pkg.name : "";
|
|
163852
164044
|
const version2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
163853
164045
|
if (name2 === PACKAGE_NAME || path4.includes("pi-magic-context")) {
|
|
@@ -163866,7 +164058,7 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
163866
164058
|
return;
|
|
163867
164059
|
}
|
|
163868
164060
|
for (const entry of entries)
|
|
163869
|
-
visit(
|
|
164061
|
+
visit(join21(path4, entry), depth - 1);
|
|
163870
164062
|
};
|
|
163871
164063
|
for (const root of cacheRoots())
|
|
163872
164064
|
visit(root, 5);
|
|
@@ -163888,7 +164080,7 @@ async function runHealthChecks(options) {
|
|
|
163888
164080
|
add(results, "pass", version2 ? `Pi ${version2} detected at ${pi.path}` : `Pi detected at ${pi.path}`);
|
|
163889
164081
|
const compare = compareSemver(version2, MIN_PI_VERSION);
|
|
163890
164082
|
if (compare !== null && compare < 0) {
|
|
163891
|
-
add(results, "fail", `Pi ${version2} is older than required ${MIN_PI_VERSION}. Subagents (historian/dreamer/sidekick) use the long-form \`--extension\` flag introduced in Pi 0.71.0; older versions hard-fail with "Unknown option". Run \`pi update\` (or \`npm install -g @
|
|
164083
|
+
add(results, "fail", `Pi ${version2} is older than required ${MIN_PI_VERSION}. Subagents (historian/dreamer/sidekick) use the long-form \`--extension\` flag introduced in Pi 0.71.0; older versions hard-fail with "Unknown option". Run \`pi update\` (or \`npm install -g @earendil-works/pi-coding-agent@latest\`).`);
|
|
163892
164084
|
} else if (version2) {
|
|
163893
164085
|
add(results, "pass", `Pi version meets minimum ${MIN_PI_VERSION} requirement`);
|
|
163894
164086
|
}
|
|
@@ -163903,7 +164095,7 @@ async function runHealthChecks(options) {
|
|
|
163903
164095
|
}
|
|
163904
164096
|
const settingsPath = getPiUserExtensionsPath();
|
|
163905
164097
|
let packages = [];
|
|
163906
|
-
if (!
|
|
164098
|
+
if (!existsSync22(settingsPath)) {
|
|
163907
164099
|
add(results, "warn", `Pi settings not found at ${settingsPath}`);
|
|
163908
164100
|
repairPlan.addPackageEntry = true;
|
|
163909
164101
|
} else {
|
|
@@ -163927,7 +164119,7 @@ async function runHealthChecks(options) {
|
|
|
163927
164119
|
["user", userConfigPath, true],
|
|
163928
164120
|
["project", projectPath, false]
|
|
163929
164121
|
]) {
|
|
163930
|
-
if (!
|
|
164122
|
+
if (!existsSync22(path4)) {
|
|
163931
164123
|
if (required2) {
|
|
163932
164124
|
add(results, "warn", `No ${label} magic-context.jsonc found at ${path4}`);
|
|
163933
164125
|
repairPlan.writeUserConfig = true;
|
|
@@ -163960,8 +164152,8 @@ async function runHealthChecks(options) {
|
|
|
163960
164152
|
add(results, "pass", `historian.model "${historianModel}" has thinking_level "${historianThinkingLevel}" configured`);
|
|
163961
164153
|
}
|
|
163962
164154
|
const storageDir = getMagicContextStorageDir();
|
|
163963
|
-
const dbPath =
|
|
163964
|
-
const existedBeforeOpen =
|
|
164155
|
+
const dbPath = join21(storageDir, "context.db");
|
|
164156
|
+
const existedBeforeOpen = existsSync22(dbPath);
|
|
163965
164157
|
if (existedBeforeOpen)
|
|
163966
164158
|
add(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
163967
164159
|
else
|
|
@@ -164038,10 +164230,10 @@ async function runHealthChecks(options) {
|
|
|
164038
164230
|
add(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
164039
164231
|
}
|
|
164040
164232
|
const logPath = getMagicContextLogPath2("pi");
|
|
164041
|
-
if (
|
|
164233
|
+
if (existsSync22(logPath)) {
|
|
164042
164234
|
const stat = statSync5(logPath);
|
|
164043
164235
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
164044
|
-
const lines =
|
|
164236
|
+
const lines = readFileSync18(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
164045
164237
|
add(results, "info", `Log file: ${logPath} (${sizeKb} KB)`);
|
|
164046
164238
|
add(results, "info", `Last plugin log line: ${lines.at(-1) ?? "<empty log>"}`);
|
|
164047
164239
|
} else {
|
|
@@ -164080,7 +164272,7 @@ function writeDefaultMagicContextConfig(path4) {
|
|
|
164080
164272
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
164081
164273
|
...MagicContextConfigSchema.parse({})
|
|
164082
164274
|
};
|
|
164083
|
-
writeFileSync12(path4, `${
|
|
164275
|
+
writeFileSync12(path4, `${import_comment_json12.stringify(config2, null, 2)}
|
|
164084
164276
|
`);
|
|
164085
164277
|
}
|
|
164086
164278
|
function repair(plan, prompts) {
|
|
@@ -164097,7 +164289,7 @@ function repair(plan, prompts) {
|
|
|
164097
164289
|
}
|
|
164098
164290
|
if (plan.writeUserConfig) {
|
|
164099
164291
|
const configPath = getPiUserConfigPath();
|
|
164100
|
-
if (!
|
|
164292
|
+
if (!existsSync22(configPath)) {
|
|
164101
164293
|
try {
|
|
164102
164294
|
writeDefaultMagicContextConfig(configPath);
|
|
164103
164295
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -164239,7 +164431,7 @@ function parseDoctorArgs(args) {
|
|
|
164239
164431
|
function doctor(args = []) {
|
|
164240
164432
|
return runDoctor2(parseDoctorArgs(args));
|
|
164241
164433
|
}
|
|
164242
|
-
var
|
|
164434
|
+
var import_comment_json12, PACKAGE_NAME = "@cortexkit/pi-magic-context", MIN_PI_VERSION = "0.74.0", ROW_COUNT_TABLES, DEFAULT_DEPS;
|
|
164243
164435
|
var init_doctor_pi = __esm(async () => {
|
|
164244
164436
|
init_magic_context();
|
|
164245
164437
|
init_variable();
|
|
@@ -164253,7 +164445,7 @@ var init_doctor_pi = __esm(async () => {
|
|
|
164253
164445
|
init_prompts();
|
|
164254
164446
|
init_setup_pi();
|
|
164255
164447
|
await init_storage();
|
|
164256
|
-
|
|
164448
|
+
import_comment_json12 = __toESM(require_src2(), 1);
|
|
164257
164449
|
ROW_COUNT_TABLES = ["tags", "compartments", "memories", "notes", "dream_runs"];
|
|
164258
164450
|
DEFAULT_DEPS = {
|
|
164259
164451
|
prompts: promptIO,
|
|
@@ -164276,7 +164468,7 @@ var exports_doctor = {};
|
|
|
164276
164468
|
__export(exports_doctor, {
|
|
164277
164469
|
runDoctor: () => runDoctor3
|
|
164278
164470
|
});
|
|
164279
|
-
import { existsSync as
|
|
164471
|
+
import { existsSync as existsSync23, rmSync as rmSync3 } from "node:fs";
|
|
164280
164472
|
async function runDoctor3(options) {
|
|
164281
164473
|
if (options.clear)
|
|
164282
164474
|
return runClear();
|
|
@@ -164360,7 +164552,7 @@ async function runClear() {
|
|
|
164360
164552
|
const s = spinner();
|
|
164361
164553
|
s.start(`Clearing ${item.path}`);
|
|
164362
164554
|
try {
|
|
164363
|
-
if (
|
|
164555
|
+
if (existsSync23(item.path)) {
|
|
164364
164556
|
rmSync3(item.path, { recursive: true, force: true });
|
|
164365
164557
|
}
|
|
164366
164558
|
s.stop(`Cleared ${item.path}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortexkit/magic-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode and Pi",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"opencode",
|
|
@@ -51,6 +51,6 @@
|
|
|
51
51
|
"typescript": "^5.8.0"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
|
-
"node": ">=
|
|
54
|
+
"node": ">=24.0.0"
|
|
55
55
|
}
|
|
56
56
|
}
|