@cortexkit/magic-context 0.17.2 → 0.19.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 +1004 -512
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7805,26 +7805,70 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7805
7805
|
};
|
|
7806
7806
|
});
|
|
7807
7807
|
|
|
7808
|
+
// ../plugin/src/shared/harness.ts
|
|
7809
|
+
function getHarness() {
|
|
7810
|
+
return currentHarness;
|
|
7811
|
+
}
|
|
7812
|
+
var currentHarness = "opencode";
|
|
7813
|
+
|
|
7814
|
+
// ../plugin/src/shared/data-path.ts
|
|
7815
|
+
import * as os from "node:os";
|
|
7816
|
+
import * as path from "node:path";
|
|
7817
|
+
function getDataDir() {
|
|
7818
|
+
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
7819
|
+
}
|
|
7820
|
+
function getMagicContextTempDir(harness = getHarness()) {
|
|
7821
|
+
return path.join(os.tmpdir(), harness, "magic-context");
|
|
7822
|
+
}
|
|
7823
|
+
function getMagicContextLogPath(harness = getHarness()) {
|
|
7824
|
+
return path.join(getMagicContextTempDir(harness), "magic-context.log");
|
|
7825
|
+
}
|
|
7826
|
+
function getMagicContextHistorianDir(harness = getHarness()) {
|
|
7827
|
+
return path.join(getMagicContextTempDir(harness), "historian");
|
|
7828
|
+
}
|
|
7829
|
+
function getProjectMagicContextDir(directory) {
|
|
7830
|
+
return path.join(directory, ".opencode", "magic-context");
|
|
7831
|
+
}
|
|
7832
|
+
function getProjectMagicContextHistorianDir(directory) {
|
|
7833
|
+
return path.join(getProjectMagicContextDir(directory), "historian");
|
|
7834
|
+
}
|
|
7835
|
+
function getOpenCodeStorageDir() {
|
|
7836
|
+
return path.join(getDataDir(), "opencode", "storage");
|
|
7837
|
+
}
|
|
7838
|
+
function getMagicContextStorageDir() {
|
|
7839
|
+
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
7840
|
+
}
|
|
7841
|
+
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
7842
|
+
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
7843
|
+
}
|
|
7844
|
+
function getCacheDir() {
|
|
7845
|
+
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
7846
|
+
}
|
|
7847
|
+
function getOpenCodeCacheDir() {
|
|
7848
|
+
return path.join(getCacheDir(), "opencode");
|
|
7849
|
+
}
|
|
7850
|
+
var init_data_path = () => {};
|
|
7851
|
+
|
|
7808
7852
|
// src/lib/paths.ts
|
|
7809
7853
|
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
7810
|
-
import { homedir
|
|
7811
|
-
import { join } from "node:path";
|
|
7854
|
+
import { homedir as homedir2 } from "node:os";
|
|
7855
|
+
import { join as join2 } from "node:path";
|
|
7812
7856
|
function getOpenCodeConfigDir() {
|
|
7813
7857
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
7814
7858
|
if (envDir)
|
|
7815
7859
|
return envDir;
|
|
7816
7860
|
if (process.platform === "win32") {
|
|
7817
|
-
return
|
|
7861
|
+
return join2(homedir2(), ".config", "opencode");
|
|
7818
7862
|
}
|
|
7819
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
7820
|
-
return
|
|
7863
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join2(homedir2(), ".config");
|
|
7864
|
+
return join2(xdgConfig, "opencode");
|
|
7821
7865
|
}
|
|
7822
7866
|
function findOmoConfig(configDir) {
|
|
7823
7867
|
const locations = [
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7868
|
+
join2(configDir, "oh-my-openagent.jsonc"),
|
|
7869
|
+
join2(configDir, "oh-my-openagent.json"),
|
|
7870
|
+
join2(configDir, "oh-my-opencode.jsonc"),
|
|
7871
|
+
join2(configDir, "oh-my-opencode.json")
|
|
7828
7872
|
];
|
|
7829
7873
|
for (const loc of locations) {
|
|
7830
7874
|
if (existsSync(loc))
|
|
@@ -7838,8 +7882,8 @@ function detectConfigPaths() {
|
|
|
7838
7882
|
let opencodeConfigFormat;
|
|
7839
7883
|
let tuiConfig;
|
|
7840
7884
|
let tuiConfigFormat;
|
|
7841
|
-
const jsoncPath =
|
|
7842
|
-
const jsonPath =
|
|
7885
|
+
const jsoncPath = join2(configDir, "opencode.jsonc");
|
|
7886
|
+
const jsonPath = join2(configDir, "opencode.json");
|
|
7843
7887
|
if (existsSync(jsoncPath)) {
|
|
7844
7888
|
opencodeConfig = jsoncPath;
|
|
7845
7889
|
opencodeConfigFormat = "jsonc";
|
|
@@ -7850,8 +7894,8 @@ function detectConfigPaths() {
|
|
|
7850
7894
|
opencodeConfig = jsonPath;
|
|
7851
7895
|
opencodeConfigFormat = "none";
|
|
7852
7896
|
}
|
|
7853
|
-
const tuiJsoncPath =
|
|
7854
|
-
const tuiJsonPath =
|
|
7897
|
+
const tuiJsoncPath = join2(configDir, "tui.jsonc");
|
|
7898
|
+
const tuiJsonPath = join2(configDir, "tui.json");
|
|
7855
7899
|
if (existsSync(tuiJsoncPath)) {
|
|
7856
7900
|
tuiConfig = tuiJsoncPath;
|
|
7857
7901
|
tuiConfigFormat = "jsonc";
|
|
@@ -7866,7 +7910,7 @@ function detectConfigPaths() {
|
|
|
7866
7910
|
configDir,
|
|
7867
7911
|
opencodeConfig,
|
|
7868
7912
|
opencodeConfigFormat,
|
|
7869
|
-
magicContextConfig:
|
|
7913
|
+
magicContextConfig: join2(configDir, "magic-context.jsonc"),
|
|
7870
7914
|
omoConfig: findOmoConfig(configDir),
|
|
7871
7915
|
tuiConfig,
|
|
7872
7916
|
tuiConfigFormat
|
|
@@ -7876,33 +7920,36 @@ function getPiAgentConfigDir() {
|
|
|
7876
7920
|
const envDir = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
7877
7921
|
if (envDir)
|
|
7878
7922
|
return envDir;
|
|
7879
|
-
return
|
|
7923
|
+
return join2(homedir2(), ".pi", "agent");
|
|
7880
7924
|
}
|
|
7881
7925
|
function getPiUserConfigPath() {
|
|
7882
|
-
return
|
|
7926
|
+
return join2(getPiAgentConfigDir(), "magic-context.jsonc");
|
|
7883
7927
|
}
|
|
7884
7928
|
function getPiUserExtensionsPath() {
|
|
7885
|
-
return
|
|
7929
|
+
return join2(getPiAgentConfigDir(), "settings.json");
|
|
7886
7930
|
}
|
|
7887
|
-
function
|
|
7888
|
-
return
|
|
7931
|
+
function getMagicContextLogPath2(harness) {
|
|
7932
|
+
return getMagicContextLogPath(harness);
|
|
7933
|
+
}
|
|
7934
|
+
function getMagicContextHistorianDir2(harness) {
|
|
7935
|
+
return getMagicContextHistorianDir(harness);
|
|
7889
7936
|
}
|
|
7890
7937
|
function getOpenCodePluginCacheDir() {
|
|
7891
|
-
const xdg = process.env.XDG_CACHE_HOME ||
|
|
7892
|
-
return
|
|
7938
|
+
const xdg = process.env.XDG_CACHE_HOME || join2(homedir2(), ".cache");
|
|
7939
|
+
return join2(xdg, "opencode", "packages");
|
|
7893
7940
|
}
|
|
7894
|
-
function isDir(
|
|
7941
|
+
function isDir(path2) {
|
|
7895
7942
|
try {
|
|
7896
|
-
return statSync(
|
|
7943
|
+
return statSync(path2).isDirectory();
|
|
7897
7944
|
} catch {
|
|
7898
7945
|
return false;
|
|
7899
7946
|
}
|
|
7900
7947
|
}
|
|
7901
|
-
function dirSizeBytes(
|
|
7902
|
-
if (!isDir(
|
|
7948
|
+
function dirSizeBytes(path2) {
|
|
7949
|
+
if (!isDir(path2))
|
|
7903
7950
|
return 0;
|
|
7904
7951
|
let total = 0;
|
|
7905
|
-
const stack = [
|
|
7952
|
+
const stack = [path2];
|
|
7906
7953
|
while (stack.length > 0) {
|
|
7907
7954
|
const cur = stack.pop();
|
|
7908
7955
|
if (cur === undefined)
|
|
@@ -7910,7 +7957,7 @@ function dirSizeBytes(path) {
|
|
|
7910
7957
|
try {
|
|
7911
7958
|
const entries = readdirSync(cur, { withFileTypes: true });
|
|
7912
7959
|
for (const entry of entries) {
|
|
7913
|
-
const child =
|
|
7960
|
+
const child = join2(cur, entry.name);
|
|
7914
7961
|
if (entry.isDirectory()) {
|
|
7915
7962
|
stack.push(child);
|
|
7916
7963
|
} else if (entry.isFile()) {
|
|
@@ -7923,22 +7970,32 @@ function dirSizeBytes(path) {
|
|
|
7923
7970
|
}
|
|
7924
7971
|
return total;
|
|
7925
7972
|
}
|
|
7926
|
-
var init_paths = () => {
|
|
7973
|
+
var init_paths = __esm(() => {
|
|
7974
|
+
init_data_path();
|
|
7975
|
+
});
|
|
7927
7976
|
|
|
7928
7977
|
// src/adapters/opencode.ts
|
|
7929
|
-
import {
|
|
7978
|
+
import { execFileSync } from "node:child_process";
|
|
7930
7979
|
import { existsSync as existsSync2, readFileSync, writeFileSync } from "node:fs";
|
|
7931
|
-
import {
|
|
7980
|
+
import { homedir as homedir3 } from "node:os";
|
|
7981
|
+
import { dirname, join as join3 } from "node:path";
|
|
7932
7982
|
|
|
7933
7983
|
class OpenCodeAdapter {
|
|
7934
7984
|
kind = "opencode";
|
|
7935
7985
|
displayName = "OpenCode";
|
|
7936
7986
|
pluginPackageName = PLUGIN_NAME;
|
|
7937
7987
|
isInstalled() {
|
|
7938
|
-
|
|
7988
|
+
const isWindows = process.platform === "win32";
|
|
7989
|
+
const stockBin = isWindows ? join3(homedir3(), ".opencode", "bin", "opencode.exe") : join3(homedir3(), ".opencode", "bin", "opencode");
|
|
7990
|
+
if (existsSync2(stockBin))
|
|
7939
7991
|
return true;
|
|
7992
|
+
const probe = isWindows ? { cmd: "where", args: ["opencode"] } : { cmd: "command", args: ["-v", "opencode"] };
|
|
7940
7993
|
try {
|
|
7941
|
-
|
|
7994
|
+
if (!isWindows) {
|
|
7995
|
+
execFileSync("which", ["opencode"], { stdio: "ignore" });
|
|
7996
|
+
} else {
|
|
7997
|
+
execFileSync(probe.cmd, probe.args, { stdio: "ignore" });
|
|
7998
|
+
}
|
|
7942
7999
|
return true;
|
|
7943
8000
|
} catch {
|
|
7944
8001
|
return false;
|
|
@@ -8104,15 +8161,15 @@ class OpenCodeAdapter {
|
|
|
8104
8161
|
return "Install OpenCode: curl -fsSL https://opencode.ai/install | bash";
|
|
8105
8162
|
}
|
|
8106
8163
|
getPluginCacheInfo() {
|
|
8107
|
-
const
|
|
8164
|
+
const path2 = getOpenCodePluginCacheDir();
|
|
8108
8165
|
return {
|
|
8109
|
-
path,
|
|
8110
|
-
exists: existsSync2(
|
|
8111
|
-
sizeBytes: dirSizeBytes(
|
|
8166
|
+
path: path2,
|
|
8167
|
+
exists: existsSync2(path2),
|
|
8168
|
+
sizeBytes: dirSizeBytes(path2)
|
|
8112
8169
|
};
|
|
8113
8170
|
}
|
|
8114
8171
|
getLogPath() {
|
|
8115
|
-
return
|
|
8172
|
+
return getMagicContextLogPath2("opencode");
|
|
8116
8173
|
}
|
|
8117
8174
|
getInstalledPluginVersion() {
|
|
8118
8175
|
const cacheDir = getOpenCodePluginCacheDir();
|
|
@@ -8175,16 +8232,16 @@ var init_opencode = __esm(() => {
|
|
|
8175
8232
|
});
|
|
8176
8233
|
|
|
8177
8234
|
// src/lib/pi-helpers.ts
|
|
8178
|
-
import { execFileSync, spawnSync } from "node:child_process";
|
|
8235
|
+
import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
|
|
8179
8236
|
import { existsSync as existsSync3 } from "node:fs";
|
|
8180
|
-
import { homedir as
|
|
8181
|
-
import { join as
|
|
8237
|
+
import { homedir as homedir4 } from "node:os";
|
|
8238
|
+
import { join as join4 } from "node:path";
|
|
8182
8239
|
function getStaticModels() {
|
|
8183
8240
|
return [...STATIC_MODELS];
|
|
8184
8241
|
}
|
|
8185
8242
|
function commandExists(command, args) {
|
|
8186
8243
|
try {
|
|
8187
|
-
const output =
|
|
8244
|
+
const output = execFileSync2(command, args, {
|
|
8188
8245
|
encoding: "utf-8",
|
|
8189
8246
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8190
8247
|
}).trim();
|
|
@@ -8200,7 +8257,7 @@ function detectPiBinary() {
|
|
|
8200
8257
|
if (first)
|
|
8201
8258
|
return { path: first, source: "path" };
|
|
8202
8259
|
}
|
|
8203
|
-
const homeCandidate = process.platform === "win32" ?
|
|
8260
|
+
const homeCandidate = process.platform === "win32" ? join4(homedir4(), ".pi", "bin", "pi.cmd") : join4(homedir4(), ".pi", "bin", "pi");
|
|
8204
8261
|
if (existsSync3(homeCandidate))
|
|
8205
8262
|
return { path: homeCandidate, source: "home" };
|
|
8206
8263
|
return null;
|
|
@@ -8224,7 +8281,7 @@ function getPiVersion(piPath) {
|
|
|
8224
8281
|
}
|
|
8225
8282
|
function runPi(piPath, args) {
|
|
8226
8283
|
try {
|
|
8227
|
-
return
|
|
8284
|
+
return execFileSync2(piPath, args, {
|
|
8228
8285
|
encoding: "utf-8",
|
|
8229
8286
|
stdio: ["ignore", "pipe", "ignore"],
|
|
8230
8287
|
timeout: 20000
|
|
@@ -8351,7 +8408,7 @@ var init_pi_helpers = __esm(() => {
|
|
|
8351
8408
|
});
|
|
8352
8409
|
|
|
8353
8410
|
// src/adapters/pi.ts
|
|
8354
|
-
import { execFileSync as
|
|
8411
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
8355
8412
|
import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8356
8413
|
import { dirname as dirname2 } from "node:path";
|
|
8357
8414
|
|
|
@@ -8455,14 +8512,14 @@ class PiAdapter {
|
|
|
8455
8512
|
return { path: null, exists: false, sizeBytes: 0 };
|
|
8456
8513
|
}
|
|
8457
8514
|
getLogPath() {
|
|
8458
|
-
return
|
|
8515
|
+
return getMagicContextLogPath2("pi");
|
|
8459
8516
|
}
|
|
8460
8517
|
getInstalledPluginVersion() {
|
|
8461
8518
|
const piBin = detectPiBinary();
|
|
8462
8519
|
if (!piBin)
|
|
8463
8520
|
return null;
|
|
8464
8521
|
try {
|
|
8465
|
-
const output =
|
|
8522
|
+
const output = execFileSync3(piBin.path, ["list"], {
|
|
8466
8523
|
encoding: "utf-8",
|
|
8467
8524
|
stdio: ["ignore", "pipe", "ignore"],
|
|
8468
8525
|
timeout: 5000
|
|
@@ -10319,17 +10376,17 @@ function detectConfigFile(basePath) {
|
|
|
10319
10376
|
var init_jsonc_parser = () => {};
|
|
10320
10377
|
|
|
10321
10378
|
// ../plugin/src/shared/opencode-config-dir.ts
|
|
10322
|
-
import { homedir as
|
|
10323
|
-
import { join as
|
|
10379
|
+
import { homedir as homedir5 } from "node:os";
|
|
10380
|
+
import { join as join5, resolve } from "node:path";
|
|
10324
10381
|
function getCliConfigDir() {
|
|
10325
10382
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
10326
10383
|
if (envConfigDir) {
|
|
10327
10384
|
return resolve(envConfigDir);
|
|
10328
10385
|
}
|
|
10329
10386
|
if (process.platform === "win32") {
|
|
10330
|
-
return
|
|
10387
|
+
return join5(homedir5(), ".config", "opencode");
|
|
10331
10388
|
}
|
|
10332
|
-
return
|
|
10389
|
+
return join5(process.env.XDG_CONFIG_HOME || join5(homedir5(), ".config"), "opencode");
|
|
10333
10390
|
}
|
|
10334
10391
|
function getOpenCodeConfigDir2(_options) {
|
|
10335
10392
|
return getCliConfigDir();
|
|
@@ -10338,16 +10395,16 @@ function getOpenCodeConfigPaths(options) {
|
|
|
10338
10395
|
const configDir = getOpenCodeConfigDir2(options);
|
|
10339
10396
|
return {
|
|
10340
10397
|
configDir,
|
|
10341
|
-
configJson:
|
|
10342
|
-
configJsonc:
|
|
10343
|
-
packageJson:
|
|
10344
|
-
omoConfig:
|
|
10398
|
+
configJson: join5(configDir, "opencode.json"),
|
|
10399
|
+
configJsonc: join5(configDir, "opencode.jsonc"),
|
|
10400
|
+
packageJson: join5(configDir, "package.json"),
|
|
10401
|
+
omoConfig: join5(configDir, "magic-context.jsonc")
|
|
10345
10402
|
};
|
|
10346
10403
|
}
|
|
10347
10404
|
var init_opencode_config_dir = () => {};
|
|
10348
10405
|
|
|
10349
10406
|
// ../plugin/src/shared/conflict-detector.ts
|
|
10350
|
-
import { join as
|
|
10407
|
+
import { join as join6 } from "node:path";
|
|
10351
10408
|
function detectConflicts(directory) {
|
|
10352
10409
|
const conflicts = {
|
|
10353
10410
|
compactionAuto: false,
|
|
@@ -10404,8 +10461,8 @@ function checkCompaction(directory) {
|
|
|
10404
10461
|
return { auto: true, prune: false };
|
|
10405
10462
|
}
|
|
10406
10463
|
function readProjectCompaction(directory) {
|
|
10407
|
-
const dotOcJsonc =
|
|
10408
|
-
const dotOcJson =
|
|
10464
|
+
const dotOcJsonc = join6(directory, ".opencode", "opencode.jsonc");
|
|
10465
|
+
const dotOcJson = join6(directory, ".opencode", "opencode.json");
|
|
10409
10466
|
const dotOcConfig = readJsoncFile(dotOcJsonc) ?? readJsoncFile(dotOcJson);
|
|
10410
10467
|
if (dotOcConfig?.compaction) {
|
|
10411
10468
|
const c2 = dotOcConfig.compaction;
|
|
@@ -10413,8 +10470,8 @@ function readProjectCompaction(directory) {
|
|
|
10413
10470
|
return { auto: c2.auto === true, prune: c2.prune === true, resolved: true };
|
|
10414
10471
|
}
|
|
10415
10472
|
}
|
|
10416
|
-
const rootJsonc =
|
|
10417
|
-
const rootJson =
|
|
10473
|
+
const rootJsonc = join6(directory, "opencode.jsonc");
|
|
10474
|
+
const rootJson = join6(directory, "opencode.json");
|
|
10418
10475
|
const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
|
|
10419
10476
|
if (rootConfig?.compaction) {
|
|
10420
10477
|
const c2 = rootConfig.compaction;
|
|
@@ -10468,10 +10525,10 @@ function collectPluginEntries(directory) {
|
|
|
10468
10525
|
}
|
|
10469
10526
|
};
|
|
10470
10527
|
for (const configPath of [
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
|
|
10474
|
-
|
|
10528
|
+
join6(directory, ".opencode", "opencode.jsonc"),
|
|
10529
|
+
join6(directory, ".opencode", "opencode.json"),
|
|
10530
|
+
join6(directory, "opencode.jsonc"),
|
|
10531
|
+
join6(directory, "opencode.json")
|
|
10475
10532
|
]) {
|
|
10476
10533
|
const config = readJsoncFile(configPath);
|
|
10477
10534
|
pushFrom(config?.plugin);
|
|
@@ -10512,7 +10569,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
10512
10569
|
try {
|
|
10513
10570
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
10514
10571
|
for (const name of configNames) {
|
|
10515
|
-
const configPath =
|
|
10572
|
+
const configPath = join6(paths.configDir, name);
|
|
10516
10573
|
const config = readJsoncFile(configPath);
|
|
10517
10574
|
if (config?.disabled_hooks) {
|
|
10518
10575
|
for (const hook of config.disabled_hooks) {
|
|
@@ -10522,7 +10579,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
10522
10579
|
}
|
|
10523
10580
|
} catch {}
|
|
10524
10581
|
for (const name of configNames) {
|
|
10525
|
-
const config = readJsoncFile(
|
|
10582
|
+
const config = readJsoncFile(join6(directory, name));
|
|
10526
10583
|
if (config?.disabled_hooks) {
|
|
10527
10584
|
for (const hook of config.disabled_hooks) {
|
|
10528
10585
|
disabled.add(hook);
|
|
@@ -10540,11 +10597,8 @@ var init_conflict_detector = __esm(() => {
|
|
|
10540
10597
|
});
|
|
10541
10598
|
|
|
10542
10599
|
// ../plugin/src/shared/conflict-fixer.ts
|
|
10543
|
-
import { existsSync as existsSync6,
|
|
10544
|
-
import {
|
|
10545
|
-
function ensureParentDir(filePath) {
|
|
10546
|
-
mkdirSync(dirname3(filePath), { recursive: true });
|
|
10547
|
-
}
|
|
10600
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
10601
|
+
import { join as join7 } from "node:path";
|
|
10548
10602
|
function isRecord(value) {
|
|
10549
10603
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10550
10604
|
}
|
|
@@ -10553,13 +10607,17 @@ function asStringArray(value) {
|
|
|
10553
10607
|
}
|
|
10554
10608
|
function readConfig(filePath) {
|
|
10555
10609
|
if (!existsSync6(filePath)) {
|
|
10556
|
-
return
|
|
10610
|
+
return null;
|
|
10611
|
+
}
|
|
10612
|
+
try {
|
|
10613
|
+
const parsed = import_comment_json3.parse(readFileSync4(filePath, "utf-8"));
|
|
10614
|
+
return isRecord(parsed) ? parsed : null;
|
|
10615
|
+
} catch {
|
|
10616
|
+
return null;
|
|
10557
10617
|
}
|
|
10558
|
-
return readJsoncFile(filePath);
|
|
10559
10618
|
}
|
|
10560
10619
|
function writeConfig(filePath, config) {
|
|
10561
|
-
|
|
10562
|
-
writeFileSync3(filePath, `${JSON.stringify(config, null, 2)}
|
|
10620
|
+
writeFileSync3(filePath, `${import_comment_json3.stringify(config, null, 2)}
|
|
10563
10621
|
`);
|
|
10564
10622
|
}
|
|
10565
10623
|
function resolveUserOpenCodeConfigPath() {
|
|
@@ -10571,12 +10629,14 @@ function resolveUserOpenCodeConfigPath() {
|
|
|
10571
10629
|
function collectOpenCodeConfigPaths(directory) {
|
|
10572
10630
|
const paths = new Set;
|
|
10573
10631
|
const userConfig = resolveUserOpenCodeConfigPath();
|
|
10574
|
-
|
|
10632
|
+
if (existsSync6(userConfig)) {
|
|
10633
|
+
paths.add(userConfig);
|
|
10634
|
+
}
|
|
10575
10635
|
for (const filePath of [
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10636
|
+
join7(directory, ".opencode", "opencode.jsonc"),
|
|
10637
|
+
join7(directory, ".opencode", "opencode.json"),
|
|
10638
|
+
join7(directory, "opencode.jsonc"),
|
|
10639
|
+
join7(directory, "opencode.json")
|
|
10580
10640
|
]) {
|
|
10581
10641
|
if (existsSync6(filePath)) {
|
|
10582
10642
|
paths.add(filePath);
|
|
@@ -10588,8 +10648,8 @@ function collectOmoConfigPaths(directory) {
|
|
|
10588
10648
|
const paths = new Set;
|
|
10589
10649
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
10590
10650
|
for (const fileName of OMO_CONFIG_NAMES) {
|
|
10591
|
-
const userPath =
|
|
10592
|
-
const projectPath =
|
|
10651
|
+
const userPath = join7(configDir, fileName);
|
|
10652
|
+
const projectPath = join7(directory, fileName);
|
|
10593
10653
|
if (existsSync6(userPath)) {
|
|
10594
10654
|
paths.add(userPath);
|
|
10595
10655
|
}
|
|
@@ -10597,11 +10657,15 @@ function collectOmoConfigPaths(directory) {
|
|
|
10597
10657
|
paths.add(projectPath);
|
|
10598
10658
|
}
|
|
10599
10659
|
}
|
|
10600
|
-
if (paths.size === 0) {
|
|
10601
|
-
paths.add(join5(configDir, "oh-my-openagent.json"));
|
|
10602
|
-
}
|
|
10603
10660
|
return [...paths];
|
|
10604
10661
|
}
|
|
10662
|
+
function filterDcpPluginEntries(entries) {
|
|
10663
|
+
const plugins = entries.filter((entry) => {
|
|
10664
|
+
const name = extractPluginName(entry);
|
|
10665
|
+
return name ? !matchesPackageName(name, DCP_PACKAGE_NAMES) : true;
|
|
10666
|
+
});
|
|
10667
|
+
return { plugins, removed: plugins.length !== entries.length };
|
|
10668
|
+
}
|
|
10605
10669
|
function fixConflicts(directory, conflicts) {
|
|
10606
10670
|
const actions = [];
|
|
10607
10671
|
let updatedCompaction = false;
|
|
@@ -10615,7 +10679,7 @@ function fixConflicts(directory, conflicts) {
|
|
|
10615
10679
|
}
|
|
10616
10680
|
let changed = false;
|
|
10617
10681
|
if (conflicts.compactionAuto || conflicts.compactionPrune) {
|
|
10618
|
-
const compaction = isRecord(config.compaction) ?
|
|
10682
|
+
const compaction = isRecord(config.compaction) ? config.compaction : {};
|
|
10619
10683
|
if (compaction.auto !== false) {
|
|
10620
10684
|
compaction.auto = false;
|
|
10621
10685
|
changed = true;
|
|
@@ -10629,10 +10693,10 @@ function fixConflicts(directory, conflicts) {
|
|
|
10629
10693
|
config.compaction = compaction;
|
|
10630
10694
|
}
|
|
10631
10695
|
if (conflicts.dcpPlugin) {
|
|
10632
|
-
const plugins =
|
|
10633
|
-
const
|
|
10634
|
-
if (
|
|
10635
|
-
config.plugin =
|
|
10696
|
+
const plugins = Array.isArray(config.plugin) ? config.plugin : [];
|
|
10697
|
+
const filtered = filterDcpPluginEntries(plugins);
|
|
10698
|
+
if (filtered.removed) {
|
|
10699
|
+
config.plugin = filtered.plugins;
|
|
10636
10700
|
changed = true;
|
|
10637
10701
|
removedDcpPlugin = true;
|
|
10638
10702
|
}
|
|
@@ -10687,10 +10751,11 @@ function fixConflicts(directory, conflicts) {
|
|
|
10687
10751
|
}
|
|
10688
10752
|
return actions;
|
|
10689
10753
|
}
|
|
10690
|
-
var CONFLICTING_OMO_HOOKS, OMO_CONFIG_NAMES;
|
|
10754
|
+
var import_comment_json3, CONFLICTING_OMO_HOOKS, OMO_CONFIG_NAMES;
|
|
10691
10755
|
var init_conflict_fixer = __esm(() => {
|
|
10692
|
-
|
|
10756
|
+
init_conflict_detector();
|
|
10693
10757
|
init_opencode_config_dir();
|
|
10758
|
+
import_comment_json3 = __toESM(require_src2(), 1);
|
|
10694
10759
|
CONFLICTING_OMO_HOOKS = [
|
|
10695
10760
|
"context-window-monitor",
|
|
10696
10761
|
"preemptive-compaction",
|
|
@@ -10705,10 +10770,10 @@ var init_conflict_fixer = __esm(() => {
|
|
|
10705
10770
|
});
|
|
10706
10771
|
|
|
10707
10772
|
// src/lib/opencode-helpers.ts
|
|
10708
|
-
import { execSync
|
|
10773
|
+
import { execSync } from "node:child_process";
|
|
10709
10774
|
function isOpenCodeInstalled() {
|
|
10710
10775
|
try {
|
|
10711
|
-
|
|
10776
|
+
execSync("opencode --version", { stdio: "pipe" });
|
|
10712
10777
|
return true;
|
|
10713
10778
|
} catch {
|
|
10714
10779
|
return false;
|
|
@@ -10716,14 +10781,14 @@ function isOpenCodeInstalled() {
|
|
|
10716
10781
|
}
|
|
10717
10782
|
function getOpenCodeVersion() {
|
|
10718
10783
|
try {
|
|
10719
|
-
return
|
|
10784
|
+
return execSync("opencode --version", { stdio: "pipe" }).toString().trim();
|
|
10720
10785
|
} catch {
|
|
10721
10786
|
return null;
|
|
10722
10787
|
}
|
|
10723
10788
|
}
|
|
10724
10789
|
function getAvailableModels2() {
|
|
10725
10790
|
try {
|
|
10726
|
-
const output =
|
|
10791
|
+
const output = execSync("opencode models", { stdio: "pipe" }).toString().trim();
|
|
10727
10792
|
return output.split(`
|
|
10728
10793
|
`).map((l) => l.trim()).filter(Boolean);
|
|
10729
10794
|
} catch {
|
|
@@ -10782,30 +10847,30 @@ function buildModelSelection2(allModels, role) {
|
|
|
10782
10847
|
var init_opencode_helpers = () => {};
|
|
10783
10848
|
|
|
10784
10849
|
// src/commands/setup-opencode.ts
|
|
10785
|
-
import { existsSync as existsSync7, mkdirSync
|
|
10786
|
-
import { dirname as
|
|
10850
|
+
import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
10851
|
+
import { dirname as dirname3 } from "node:path";
|
|
10787
10852
|
function ensureDir3(dir) {
|
|
10788
10853
|
if (!existsSync7(dir)) {
|
|
10789
|
-
|
|
10854
|
+
mkdirSync(dir, { recursive: true });
|
|
10790
10855
|
}
|
|
10791
10856
|
}
|
|
10792
|
-
function readJsonc(
|
|
10793
|
-
const content =
|
|
10857
|
+
function readJsonc(path2) {
|
|
10858
|
+
const content = readFileSync5(path2, "utf-8");
|
|
10794
10859
|
try {
|
|
10795
|
-
return
|
|
10860
|
+
return import_comment_json4.parse(content);
|
|
10796
10861
|
} catch (err) {
|
|
10797
|
-
console.error(` ⚠ Failed to parse ${
|
|
10862
|
+
console.error(` ⚠ Failed to parse ${path2}: ${err instanceof Error ? err.message : err}`);
|
|
10798
10863
|
return null;
|
|
10799
10864
|
}
|
|
10800
10865
|
}
|
|
10801
10866
|
function addPluginToOpenCodeConfig(configPath, format) {
|
|
10802
|
-
ensureDir3(
|
|
10867
|
+
ensureDir3(dirname3(configPath));
|
|
10803
10868
|
if (format === "none") {
|
|
10804
10869
|
const config = {
|
|
10805
10870
|
plugin: [PLUGIN_ENTRY2],
|
|
10806
10871
|
compaction: { auto: false, prune: false }
|
|
10807
10872
|
};
|
|
10808
|
-
writeFileSync4(configPath, `${
|
|
10873
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(config, null, 2)}
|
|
10809
10874
|
`);
|
|
10810
10875
|
return;
|
|
10811
10876
|
}
|
|
@@ -10825,13 +10890,13 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
10825
10890
|
compaction.auto = false;
|
|
10826
10891
|
compaction.prune = false;
|
|
10827
10892
|
existing.compaction = compaction;
|
|
10828
|
-
writeFileSync4(configPath, `${
|
|
10893
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(existing, null, 2)}
|
|
10829
10894
|
`);
|
|
10830
10895
|
}
|
|
10831
10896
|
function addPluginToTuiConfig(configPath, format) {
|
|
10832
|
-
ensureDir3(
|
|
10897
|
+
ensureDir3(dirname3(configPath));
|
|
10833
10898
|
if (format === "none") {
|
|
10834
|
-
writeFileSync4(configPath, `${
|
|
10899
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify({ plugin: [PLUGIN_ENTRY2] }, null, 2)}
|
|
10835
10900
|
`);
|
|
10836
10901
|
return;
|
|
10837
10902
|
}
|
|
@@ -10847,9 +10912,42 @@ function addPluginToTuiConfig(configPath, format) {
|
|
|
10847
10912
|
rawPlugins.push(PLUGIN_ENTRY2);
|
|
10848
10913
|
}
|
|
10849
10914
|
existing.plugin = rawPlugins;
|
|
10850
|
-
writeFileSync4(configPath, `${
|
|
10915
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(existing, null, 2)}
|
|
10851
10916
|
`);
|
|
10852
10917
|
}
|
|
10918
|
+
function findDcpPluginIndexes(plugins) {
|
|
10919
|
+
return plugins.map((plugin, index) => matchesPluginEntry(plugin, DCP_PLUGIN_NAME) ? index : -1).filter((index) => index >= 0);
|
|
10920
|
+
}
|
|
10921
|
+
function pluginEntryName(entry) {
|
|
10922
|
+
if (typeof entry === "string")
|
|
10923
|
+
return entry;
|
|
10924
|
+
if (Array.isArray(entry) && typeof entry[0] === "string")
|
|
10925
|
+
return entry[0];
|
|
10926
|
+
return String(entry);
|
|
10927
|
+
}
|
|
10928
|
+
async function resolveDcpConflictBeforeSetup(configPath, format) {
|
|
10929
|
+
if (format === "none")
|
|
10930
|
+
return;
|
|
10931
|
+
const ocConfig = readJsonc(configPath);
|
|
10932
|
+
if (!ocConfig)
|
|
10933
|
+
return;
|
|
10934
|
+
const plugins = Array.isArray(ocConfig.plugin) ? ocConfig.plugin : [];
|
|
10935
|
+
const dcpIndexes = findDcpPluginIndexes(plugins);
|
|
10936
|
+
if (dcpIndexes.length === 0)
|
|
10937
|
+
return;
|
|
10938
|
+
log.warn(`Found conflicting plugin: ${pluginEntryName(plugins[dcpIndexes[0]])}`);
|
|
10939
|
+
log.message(`opencode-dcp (Dynamic Context Pruning) and Magic Context both manage context.
|
|
10940
|
+
` + "Running both simultaneously will cause unpredictable behavior.");
|
|
10941
|
+
const shouldRemove = await confirm("Remove opencode-dcp from your config?", true);
|
|
10942
|
+
if (shouldRemove) {
|
|
10943
|
+
ocConfig.plugin = plugins.filter((_plugin, index) => !dcpIndexes.includes(index));
|
|
10944
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(ocConfig, null, 2)}
|
|
10945
|
+
`);
|
|
10946
|
+
log.success("Removed opencode-dcp from plugin list");
|
|
10947
|
+
} else {
|
|
10948
|
+
log.warn("Skipped — you may experience context management conflicts");
|
|
10949
|
+
}
|
|
10950
|
+
}
|
|
10853
10951
|
function writeMagicContextConfig(configPath, options) {
|
|
10854
10952
|
const config = (existsSync7(configPath) ? readJsonc(configPath) : null) ?? {};
|
|
10855
10953
|
if (!config.$schema) {
|
|
@@ -10888,7 +10986,7 @@ function writeMagicContextConfig(configPath, options) {
|
|
|
10888
10986
|
cacheTtl["anthropic/claude-opus-4-6"] = "59m";
|
|
10889
10987
|
config.cache_ttl = cacheTtl;
|
|
10890
10988
|
}
|
|
10891
|
-
writeFileSync4(configPath, `${
|
|
10989
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(config, null, 2)}
|
|
10892
10990
|
`);
|
|
10893
10991
|
}
|
|
10894
10992
|
async function runSetup() {
|
|
@@ -10918,32 +11016,11 @@ async function runSetup() {
|
|
|
10918
11016
|
}
|
|
10919
11017
|
const paths = detectConfigPaths();
|
|
10920
11018
|
const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync7(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
|
|
11019
|
+
await resolveDcpConflictBeforeSetup(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
10921
11020
|
addPluginToOpenCodeConfig(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
10922
11021
|
log.success(`Plugin added to ${paths.opencodeConfig}`);
|
|
10923
11022
|
log.info("Disabled built-in compaction (auto=false, prune=false)");
|
|
10924
11023
|
log.message("Magic Context handles context management — built-in compaction would interfere");
|
|
10925
|
-
if (paths.opencodeConfigFormat !== "none") {
|
|
10926
|
-
const ocConfig = readJsonc(paths.opencodeConfig);
|
|
10927
|
-
if (ocConfig) {
|
|
10928
|
-
const plugins = ocConfig.plugin ?? [];
|
|
10929
|
-
const dcpIndex = plugins.findIndex((p2) => p2.startsWith("@tarquinen/opencode-dcp"));
|
|
10930
|
-
if (dcpIndex !== -1) {
|
|
10931
|
-
log.warn(`Found conflicting plugin: ${plugins[dcpIndex]}`);
|
|
10932
|
-
log.message(`opencode-dcp (Dynamic Context Pruning) and Magic Context both manage context.
|
|
10933
|
-
` + "Running both simultaneously will cause unpredictable behavior.");
|
|
10934
|
-
const shouldRemove = await confirm("Remove opencode-dcp from your config?", true);
|
|
10935
|
-
if (shouldRemove) {
|
|
10936
|
-
plugins.splice(dcpIndex, 1);
|
|
10937
|
-
ocConfig.plugin = plugins;
|
|
10938
|
-
writeFileSync4(paths.opencodeConfig, `${import_comment_json3.stringify(ocConfig, null, 2)}
|
|
10939
|
-
`);
|
|
10940
|
-
log.success("Removed opencode-dcp from plugin list");
|
|
10941
|
-
} else {
|
|
10942
|
-
log.warn("Skipped — you may experience context management conflicts");
|
|
10943
|
-
}
|
|
10944
|
-
}
|
|
10945
|
-
}
|
|
10946
|
-
}
|
|
10947
11024
|
if (hadExistingSetup) {
|
|
10948
11025
|
const conflicts = detectConflicts(process.cwd());
|
|
10949
11026
|
if (conflicts.hasConflict) {
|
|
@@ -11062,8 +11139,8 @@ async function runSetup() {
|
|
|
11062
11139
|
const shouldStar = await confirm("★ Star the repo on GitHub?", true);
|
|
11063
11140
|
if (shouldStar) {
|
|
11064
11141
|
try {
|
|
11065
|
-
const { execSync:
|
|
11066
|
-
|
|
11142
|
+
const { execSync: execSync2 } = await import("node:child_process");
|
|
11143
|
+
execSync2("gh api --silent --method PUT /user/starred/cortexkit/magic-context", {
|
|
11067
11144
|
stdio: "ignore",
|
|
11068
11145
|
timeout: 1e4
|
|
11069
11146
|
});
|
|
@@ -11076,7 +11153,7 @@ async function runSetup() {
|
|
|
11076
11153
|
outro("Run 'opencode' to start!");
|
|
11077
11154
|
return 0;
|
|
11078
11155
|
}
|
|
11079
|
-
var
|
|
11156
|
+
var import_comment_json4, PLUGIN_NAME3 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY2 = "@cortexkit/opencode-magic-context@latest", DCP_PLUGIN_NAME = "@tarquinen/opencode-dcp";
|
|
11080
11157
|
var init_setup_opencode = __esm(() => {
|
|
11081
11158
|
init_conflict_detector();
|
|
11082
11159
|
init_conflict_fixer();
|
|
@@ -11084,26 +11161,77 @@ var init_setup_opencode = __esm(() => {
|
|
|
11084
11161
|
init_opencode_helpers();
|
|
11085
11162
|
init_paths();
|
|
11086
11163
|
init_prompts();
|
|
11087
|
-
|
|
11164
|
+
import_comment_json4 = __toESM(require_src2(), 1);
|
|
11165
|
+
});
|
|
11166
|
+
|
|
11167
|
+
// src/lib/pi-package-entry.ts
|
|
11168
|
+
function stripNpmPrefix(value) {
|
|
11169
|
+
return value.startsWith("npm:") ? value.slice("npm:".length) : value;
|
|
11170
|
+
}
|
|
11171
|
+
function packageNameFromSpecifier(value) {
|
|
11172
|
+
const normalized = stripNpmPrefix(value.trim());
|
|
11173
|
+
if (!normalized)
|
|
11174
|
+
return normalized;
|
|
11175
|
+
if (normalized.startsWith("@")) {
|
|
11176
|
+
const slash = normalized.indexOf("/");
|
|
11177
|
+
if (slash < 0)
|
|
11178
|
+
return normalized;
|
|
11179
|
+
const versionAt2 = normalized.indexOf("@", slash + 1);
|
|
11180
|
+
return versionAt2 > 0 ? normalized.slice(0, versionAt2) : normalized;
|
|
11181
|
+
}
|
|
11182
|
+
const versionAt = normalized.indexOf("@");
|
|
11183
|
+
return versionAt > 0 ? normalized.slice(0, versionAt) : normalized;
|
|
11184
|
+
}
|
|
11185
|
+
function getPiPackageEntryName(entry) {
|
|
11186
|
+
if (typeof entry === "string")
|
|
11187
|
+
return packageNameFromSpecifier(entry);
|
|
11188
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
11189
|
+
const name = entry.name;
|
|
11190
|
+
if (typeof name === "string")
|
|
11191
|
+
return packageNameFromSpecifier(name);
|
|
11192
|
+
}
|
|
11193
|
+
return null;
|
|
11194
|
+
}
|
|
11195
|
+
function isPiMagicContextPackageEntry(entry) {
|
|
11196
|
+
return getPiPackageEntryName(entry) === PI_MAGIC_CONTEXT_PACKAGE_NAME;
|
|
11197
|
+
}
|
|
11198
|
+
function hasPiMagicContextPackage(entries) {
|
|
11199
|
+
return entries.some(isPiMagicContextPackageEntry);
|
|
11200
|
+
}
|
|
11201
|
+
function describePiPackageEntry(entry) {
|
|
11202
|
+
if (typeof entry === "string")
|
|
11203
|
+
return entry;
|
|
11204
|
+
const name = getPiPackageEntryName(entry);
|
|
11205
|
+
if (name)
|
|
11206
|
+
return name;
|
|
11207
|
+
try {
|
|
11208
|
+
return JSON.stringify(entry);
|
|
11209
|
+
} catch {
|
|
11210
|
+
return String(entry);
|
|
11211
|
+
}
|
|
11212
|
+
}
|
|
11213
|
+
var PI_MAGIC_CONTEXT_PACKAGE_NAME = "@cortexkit/pi-magic-context";
|
|
11214
|
+
var init_pi_package_entry = __esm(() => {
|
|
11215
|
+
init_pi_helpers();
|
|
11088
11216
|
});
|
|
11089
11217
|
|
|
11090
11218
|
// src/commands/setup-pi.ts
|
|
11091
|
-
import { existsSync as existsSync8, mkdirSync as
|
|
11092
|
-
import { dirname as
|
|
11093
|
-
function ensureDir4(
|
|
11094
|
-
if (!existsSync8(
|
|
11095
|
-
|
|
11219
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
11220
|
+
import { dirname as dirname4 } from "node:path";
|
|
11221
|
+
function ensureDir4(path2) {
|
|
11222
|
+
if (!existsSync8(path2))
|
|
11223
|
+
mkdirSync2(path2, { recursive: true });
|
|
11096
11224
|
}
|
|
11097
11225
|
async function getDefaultPrompts() {
|
|
11098
11226
|
const { promptIO: promptIO2 } = await Promise.resolve().then(() => (init_prompts(), exports_prompts));
|
|
11099
11227
|
return promptIO2;
|
|
11100
11228
|
}
|
|
11101
|
-
function readJsonc2(
|
|
11229
|
+
function readJsonc2(path2) {
|
|
11102
11230
|
try {
|
|
11103
|
-
return
|
|
11231
|
+
return import_comment_json5.parse(readFileSync6(path2, "utf-8"));
|
|
11104
11232
|
} catch (error) {
|
|
11105
11233
|
const message = error instanceof Error ? error.message : String(error);
|
|
11106
|
-
console.warn(`Could not parse ${
|
|
11234
|
+
console.warn(`Could not parse ${path2}: ${message}`);
|
|
11107
11235
|
return null;
|
|
11108
11236
|
}
|
|
11109
11237
|
}
|
|
@@ -11115,12 +11243,12 @@ function compactObject(obj) {
|
|
|
11115
11243
|
return obj;
|
|
11116
11244
|
}
|
|
11117
11245
|
function comparePiVersion(a, b2) {
|
|
11118
|
-
const
|
|
11246
|
+
const parse2 = (v2) => {
|
|
11119
11247
|
const match = v2.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
11120
11248
|
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
11121
11249
|
};
|
|
11122
|
-
const left =
|
|
11123
|
-
const right =
|
|
11250
|
+
const left = parse2(a);
|
|
11251
|
+
const right = parse2(b2);
|
|
11124
11252
|
if (!left || !right)
|
|
11125
11253
|
return 0;
|
|
11126
11254
|
for (let i = 0;i < 3; i += 1) {
|
|
@@ -11132,19 +11260,19 @@ function comparePiVersion(a, b2) {
|
|
|
11132
11260
|
return 0;
|
|
11133
11261
|
}
|
|
11134
11262
|
function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE) {
|
|
11135
|
-
ensureDir4(
|
|
11263
|
+
ensureDir4(dirname4(settingsPath));
|
|
11136
11264
|
const settings = existsSync8(settingsPath) ? readJsonc2(settingsPath) ?? {} : {};
|
|
11137
|
-
const packages = Array.isArray(settings.packages) ? settings.packages
|
|
11138
|
-
const hasPackage = packages
|
|
11265
|
+
const packages = Array.isArray(settings.packages) ? settings.packages : [];
|
|
11266
|
+
const hasPackage = hasPiMagicContextPackage(packages);
|
|
11139
11267
|
if (!hasPackage)
|
|
11140
11268
|
packages.push(packageSource);
|
|
11141
11269
|
settings.packages = packages;
|
|
11142
|
-
writeFileSync5(settingsPath, `${
|
|
11270
|
+
writeFileSync5(settingsPath, `${import_comment_json5.stringify(settings, null, 2)}
|
|
11143
11271
|
`);
|
|
11144
11272
|
return !hasPackage;
|
|
11145
11273
|
}
|
|
11146
11274
|
function writeMagicContextConfig2(configPath, options) {
|
|
11147
|
-
ensureDir4(
|
|
11275
|
+
ensureDir4(dirname4(configPath));
|
|
11148
11276
|
const config = existsSync8(configPath) ? readJsonc2(configPath) ?? {} : {};
|
|
11149
11277
|
if (!config.$schema) {
|
|
11150
11278
|
config.$schema = "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json";
|
|
@@ -11172,7 +11300,7 @@ function writeMagicContextConfig2(configPath, options) {
|
|
|
11172
11300
|
};
|
|
11173
11301
|
}
|
|
11174
11302
|
config.embedding = options.embedding;
|
|
11175
|
-
writeFileSync5(configPath, `${
|
|
11303
|
+
writeFileSync5(configPath, `${import_comment_json5.stringify(config, null, 2)}
|
|
11176
11304
|
`);
|
|
11177
11305
|
}
|
|
11178
11306
|
async function chooseModel(prompts, allModels, role, message) {
|
|
@@ -11298,11 +11426,12 @@ Run \`pi update\` (or \`npm install -g @mariozechner/pi-coding-agent@latest\`) b
|
|
|
11298
11426
|
prompts.outro("Start a Pi session and try /ctx-aug");
|
|
11299
11427
|
return 0;
|
|
11300
11428
|
}
|
|
11301
|
-
var
|
|
11429
|
+
var import_comment_json5, DEFAULT_ENV;
|
|
11302
11430
|
var init_setup_pi = __esm(() => {
|
|
11303
11431
|
init_paths();
|
|
11304
11432
|
init_pi_helpers();
|
|
11305
|
-
|
|
11433
|
+
init_pi_package_entry();
|
|
11434
|
+
import_comment_json5 = __toESM(require_src2(), 1);
|
|
11306
11435
|
DEFAULT_ENV = {
|
|
11307
11436
|
detectPiBinary,
|
|
11308
11437
|
getPiVersion,
|
|
@@ -11382,29 +11511,6 @@ var init_setup = __esm(() => {
|
|
|
11382
11511
|
init_setup_pi();
|
|
11383
11512
|
});
|
|
11384
11513
|
|
|
11385
|
-
// ../plugin/src/shared/data-path.ts
|
|
11386
|
-
import * as os from "node:os";
|
|
11387
|
-
import * as path from "node:path";
|
|
11388
|
-
function getDataDir() {
|
|
11389
|
-
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
11390
|
-
}
|
|
11391
|
-
function getOpenCodeStorageDir() {
|
|
11392
|
-
return path.join(getDataDir(), "opencode", "storage");
|
|
11393
|
-
}
|
|
11394
|
-
function getMagicContextStorageDir() {
|
|
11395
|
-
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
11396
|
-
}
|
|
11397
|
-
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
11398
|
-
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
11399
|
-
}
|
|
11400
|
-
function getCacheDir() {
|
|
11401
|
-
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
11402
|
-
}
|
|
11403
|
-
function getOpenCodeCacheDir() {
|
|
11404
|
-
return path.join(getCacheDir(), "opencode");
|
|
11405
|
-
}
|
|
11406
|
-
var init_data_path = () => {};
|
|
11407
|
-
|
|
11408
11514
|
// ../../node_modules/.bun/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
|
|
11409
11515
|
function parseTar(data, opts) {
|
|
11410
11516
|
const buffer = data.buffer || data;
|
|
@@ -11583,8 +11689,16 @@ var init_dist5 = __esm(() => {
|
|
|
11583
11689
|
|
|
11584
11690
|
// ../plugin/src/shared/logger.ts
|
|
11585
11691
|
import * as fs from "node:fs";
|
|
11586
|
-
import * as os2 from "node:os";
|
|
11587
11692
|
import * as path2 from "node:path";
|
|
11693
|
+
function ensureDir5(filePath) {
|
|
11694
|
+
const dir = path2.dirname(filePath);
|
|
11695
|
+
if (dir === lastEnsuredDir)
|
|
11696
|
+
return;
|
|
11697
|
+
try {
|
|
11698
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
11699
|
+
lastEnsuredDir = dir;
|
|
11700
|
+
} catch {}
|
|
11701
|
+
}
|
|
11588
11702
|
function flush() {
|
|
11589
11703
|
if (flushTimer) {
|
|
11590
11704
|
clearTimeout(flushTimer);
|
|
@@ -11595,6 +11709,8 @@ function flush() {
|
|
|
11595
11709
|
const data = buffer.join("");
|
|
11596
11710
|
buffer = [];
|
|
11597
11711
|
try {
|
|
11712
|
+
const logFile = getMagicContextLogPath();
|
|
11713
|
+
ensureDir5(logFile);
|
|
11598
11714
|
fs.appendFileSync(logFile, data);
|
|
11599
11715
|
} catch {}
|
|
11600
11716
|
}
|
|
@@ -11622,9 +11738,9 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
|
11622
11738
|
}
|
|
11623
11739
|
} catch {}
|
|
11624
11740
|
}
|
|
11625
|
-
var
|
|
11741
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
11626
11742
|
var init_logger = __esm(() => {
|
|
11627
|
-
|
|
11743
|
+
init_data_path();
|
|
11628
11744
|
buffer = [];
|
|
11629
11745
|
if (!isTestEnv) {
|
|
11630
11746
|
process.on("exit", flush);
|
|
@@ -11799,16 +11915,16 @@ __export(exports_migrate, {
|
|
|
11799
11915
|
});
|
|
11800
11916
|
import { randomBytes } from "node:crypto";
|
|
11801
11917
|
import { existsSync as existsSync10, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
11802
|
-
import { homedir as
|
|
11918
|
+
import { homedir as homedir6 } from "node:os";
|
|
11803
11919
|
import { join as join9 } from "node:path";
|
|
11804
11920
|
function defaultOpenCodeDbPath() {
|
|
11805
|
-
return join9(
|
|
11921
|
+
return join9(homedir6(), ".local", "share", "opencode", "opencode.db");
|
|
11806
11922
|
}
|
|
11807
11923
|
function defaultCortexkitDbPath() {
|
|
11808
11924
|
return join9(getMagicContextStorageDir(), "context.db");
|
|
11809
11925
|
}
|
|
11810
11926
|
function defaultPiSessionsRoot() {
|
|
11811
|
-
return join9(
|
|
11927
|
+
return join9(homedir6(), ".pi", "agent", "sessions");
|
|
11812
11928
|
}
|
|
11813
11929
|
function defaultFs() {
|
|
11814
11930
|
return { existsSync: existsSync10, mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 };
|
|
@@ -13318,7 +13434,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
13318
13434
|
throw e2;
|
|
13319
13435
|
}
|
|
13320
13436
|
return result.value;
|
|
13321
|
-
},
|
|
13437
|
+
}, parse2, _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
13322
13438
|
const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
|
|
13323
13439
|
let result = schema._zod.run({ value, issues: [] }, ctx);
|
|
13324
13440
|
if (result instanceof Promise)
|
|
@@ -13373,7 +13489,7 @@ var init_parse = __esm(() => {
|
|
|
13373
13489
|
init_core();
|
|
13374
13490
|
init_errors();
|
|
13375
13491
|
init_util();
|
|
13376
|
-
|
|
13492
|
+
parse2 = /* @__PURE__ */ _parse($ZodRealError);
|
|
13377
13493
|
parseAsync = /* @__PURE__ */ _parseAsync($ZodRealError);
|
|
13378
13494
|
safeParse = /* @__PURE__ */ _safeParse($ZodRealError);
|
|
13379
13495
|
safeParseAsync = /* @__PURE__ */ _safeParseAsync($ZodRealError);
|
|
@@ -16132,10 +16248,10 @@ var init_schemas = __esm(() => {
|
|
|
16132
16248
|
throw new Error("implement() must be called with a function");
|
|
16133
16249
|
}
|
|
16134
16250
|
return function(...args) {
|
|
16135
|
-
const parsedArgs = inst._def.input ?
|
|
16251
|
+
const parsedArgs = inst._def.input ? parse2(inst._def.input, args) : args;
|
|
16136
16252
|
const result = Reflect.apply(func, this, parsedArgs);
|
|
16137
16253
|
if (inst._def.output) {
|
|
16138
|
-
return
|
|
16254
|
+
return parse2(inst._def.output, result);
|
|
16139
16255
|
}
|
|
16140
16256
|
return result;
|
|
16141
16257
|
};
|
|
@@ -23620,7 +23736,7 @@ function finalize(ctx, schema) {
|
|
|
23620
23736
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
23621
23737
|
} else if (ctx.target === "draft-04") {
|
|
23622
23738
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
23623
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
23739
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
23624
23740
|
if (ctx.external?.uri) {
|
|
23625
23741
|
const id = ctx.external.registry.get(schema)?.id;
|
|
23626
23742
|
if (!id)
|
|
@@ -23881,7 +23997,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
23881
23997
|
if (val === undefined) {
|
|
23882
23998
|
if (ctx.unrepresentable === "throw") {
|
|
23883
23999
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
23884
|
-
}
|
|
24000
|
+
}
|
|
23885
24001
|
} else if (typeof val === "bigint") {
|
|
23886
24002
|
if (ctx.unrepresentable === "throw") {
|
|
23887
24003
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -24328,7 +24444,7 @@ __export(exports_core2, {
|
|
|
24328
24444
|
process: () => process2,
|
|
24329
24445
|
prettifyError: () => prettifyError,
|
|
24330
24446
|
parseAsync: () => parseAsync,
|
|
24331
|
-
parse: () =>
|
|
24447
|
+
parse: () => parse2,
|
|
24332
24448
|
meta: () => meta,
|
|
24333
24449
|
locales: () => exports_locales,
|
|
24334
24450
|
isValidJWT: () => isValidJWT,
|
|
@@ -24729,11 +24845,11 @@ var init_errors2 = __esm(() => {
|
|
|
24729
24845
|
});
|
|
24730
24846
|
|
|
24731
24847
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/parse.js
|
|
24732
|
-
var
|
|
24848
|
+
var parse4, parseAsync2, safeParse2, safeParseAsync2, encode2, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2;
|
|
24733
24849
|
var init_parse2 = __esm(() => {
|
|
24734
24850
|
init_core2();
|
|
24735
24851
|
init_errors2();
|
|
24736
|
-
|
|
24852
|
+
parse4 = /* @__PURE__ */ _parse(ZodRealError);
|
|
24737
24853
|
parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
24738
24854
|
safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
24739
24855
|
safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -25453,7 +25569,7 @@ var init_schemas2 = __esm(() => {
|
|
|
25453
25569
|
inst.def = def;
|
|
25454
25570
|
inst.type = def.type;
|
|
25455
25571
|
Object.defineProperty(inst, "_def", { value: def });
|
|
25456
|
-
inst.parse = (data, params) =>
|
|
25572
|
+
inst.parse = (data, params) => parse4(inst, data, params, { callee: inst.parse });
|
|
25457
25573
|
inst.safeParse = (data, params) => safeParse2(inst, data, params);
|
|
25458
25574
|
inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
|
|
25459
25575
|
inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params);
|
|
@@ -26805,7 +26921,7 @@ __export(exports_external, {
|
|
|
26805
26921
|
pipe: () => pipe,
|
|
26806
26922
|
partialRecord: () => partialRecord,
|
|
26807
26923
|
parseAsync: () => parseAsync2,
|
|
26808
|
-
parse: () =>
|
|
26924
|
+
parse: () => parse4,
|
|
26809
26925
|
overwrite: () => _overwrite,
|
|
26810
26926
|
optional: () => optional,
|
|
26811
26927
|
object: () => object,
|
|
@@ -27228,8 +27344,8 @@ var init_magic_context = __esm(() => {
|
|
|
27228
27344
|
});
|
|
27229
27345
|
|
|
27230
27346
|
// ../plugin/src/config/variable.ts
|
|
27231
|
-
import { existsSync as existsSync11, readFileSync as
|
|
27232
|
-
import { homedir as
|
|
27347
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
27348
|
+
import { homedir as homedir7 } from "node:os";
|
|
27233
27349
|
import { dirname as dirname7, isAbsolute, resolve as resolve2 } from "node:path";
|
|
27234
27350
|
function substituteConfigVariables(input) {
|
|
27235
27351
|
const warnings = [];
|
|
@@ -27265,7 +27381,7 @@ function substituteConfigVariables(input) {
|
|
|
27265
27381
|
}
|
|
27266
27382
|
let filePath = rawPath.trim();
|
|
27267
27383
|
if (filePath.startsWith("~/")) {
|
|
27268
|
-
filePath = resolve2(
|
|
27384
|
+
filePath = resolve2(homedir7(), filePath.slice(2));
|
|
27269
27385
|
} else if (!isAbsolute(filePath)) {
|
|
27270
27386
|
filePath = resolve2(configDir, filePath);
|
|
27271
27387
|
}
|
|
@@ -27275,7 +27391,7 @@ function substituteConfigVariables(input) {
|
|
|
27275
27391
|
}
|
|
27276
27392
|
let contents;
|
|
27277
27393
|
try {
|
|
27278
|
-
contents =
|
|
27394
|
+
contents = readFileSync7(filePath, "utf-8").trim();
|
|
27279
27395
|
} catch (error51) {
|
|
27280
27396
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
27281
27397
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -27293,11 +27409,11 @@ var init_variable = __esm(() => {
|
|
|
27293
27409
|
});
|
|
27294
27410
|
|
|
27295
27411
|
// ../plugin/src/config/index.ts
|
|
27296
|
-
import { existsSync as existsSync12, readFileSync as
|
|
27297
|
-
import { homedir as
|
|
27412
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
|
|
27413
|
+
import { homedir as homedir8 } from "node:os";
|
|
27298
27414
|
import { join as join10 } from "node:path";
|
|
27299
27415
|
function getUserConfigBasePath() {
|
|
27300
|
-
const configRoot = process.env.XDG_CONFIG_HOME ?? join10(
|
|
27416
|
+
const configRoot = process.env.XDG_CONFIG_HOME ?? join10(homedir8(), ".config");
|
|
27301
27417
|
return join10(configRoot, "opencode", CONFIG_FILE_BASENAME);
|
|
27302
27418
|
}
|
|
27303
27419
|
function getProjectConfigBasePath(directory) {
|
|
@@ -27308,7 +27424,7 @@ function loadConfigFile(configPath) {
|
|
|
27308
27424
|
if (!existsSync12(configPath)) {
|
|
27309
27425
|
return null;
|
|
27310
27426
|
}
|
|
27311
|
-
const rawText =
|
|
27427
|
+
const rawText = readFileSync8(configPath, "utf-8");
|
|
27312
27428
|
const substituted = substituteConfigVariables({ text: rawText, configPath });
|
|
27313
27429
|
return {
|
|
27314
27430
|
config: parseJsonc3(substituted.text),
|
|
@@ -27319,34 +27435,20 @@ function loadConfigFile(configPath) {
|
|
|
27319
27435
|
return null;
|
|
27320
27436
|
}
|
|
27321
27437
|
}
|
|
27322
|
-
function
|
|
27323
|
-
const
|
|
27324
|
-
|
|
27325
|
-
|
|
27326
|
-
|
|
27327
|
-
|
|
27328
|
-
|
|
27329
|
-
|
|
27330
|
-
|
|
27331
|
-
|
|
27332
|
-
|
|
27333
|
-
dreamer: override.dreamer ? {
|
|
27334
|
-
...base.dreamer ?? {},
|
|
27335
|
-
...override.dreamer
|
|
27336
|
-
} : base.dreamer,
|
|
27337
|
-
sidekick: override.sidekick ? {
|
|
27338
|
-
...base.sidekick ?? {},
|
|
27339
|
-
...override.sidekick
|
|
27340
|
-
} : base.sidekick,
|
|
27341
|
-
disabled_hooks: [
|
|
27342
|
-
...new Set([...base.disabled_hooks ?? [], ...override.disabled_hooks ?? []])
|
|
27343
|
-
],
|
|
27344
|
-
command: {
|
|
27345
|
-
...base.command ?? {},
|
|
27346
|
-
...override.command ?? {}
|
|
27438
|
+
function deepMergeRawConfig(base, override) {
|
|
27439
|
+
const result = { ...base };
|
|
27440
|
+
for (const key of Object.keys(override)) {
|
|
27441
|
+
const baseVal = base[key];
|
|
27442
|
+
const overrideVal = override[key];
|
|
27443
|
+
if (baseVal !== null && typeof baseVal === "object" && !Array.isArray(baseVal) && overrideVal !== null && typeof overrideVal === "object" && !Array.isArray(overrideVal)) {
|
|
27444
|
+
result[key] = deepMergeRawConfig(baseVal, overrideVal);
|
|
27445
|
+
} else if (key === "disabled_hooks" && Array.isArray(baseVal) && Array.isArray(overrideVal)) {
|
|
27446
|
+
result[key] = [...new Set([...baseVal, ...overrideVal])];
|
|
27447
|
+
} else {
|
|
27448
|
+
result[key] = overrideVal;
|
|
27347
27449
|
}
|
|
27348
|
-
}
|
|
27349
|
-
return
|
|
27450
|
+
}
|
|
27451
|
+
return result;
|
|
27350
27452
|
}
|
|
27351
27453
|
function getProjectUserOnlyFields(config2) {
|
|
27352
27454
|
return "auto_update" in config2 ? ["auto_update"] : [];
|
|
@@ -27487,30 +27589,38 @@ function loadPluginConfig(directory) {
|
|
|
27487
27589
|
const projectDetected = rootDetected.format !== "none" ? rootDetected : dotOpenCodeDetected;
|
|
27488
27590
|
const userLoaded = userDetected.format === "none" ? null : loadConfigFile(userDetected.path);
|
|
27489
27591
|
const projectLoaded = projectDetected.format === "none" ? null : loadConfigFile(projectDetected.path);
|
|
27490
|
-
let config2 = parsePluginConfig({});
|
|
27491
27592
|
const allWarnings = [];
|
|
27593
|
+
let mergedRaw = {};
|
|
27492
27594
|
if (userLoaded) {
|
|
27493
27595
|
allWarnings.push(...userLoaded.warnings.map((w3) => `[user config] ${w3}`));
|
|
27494
|
-
|
|
27495
|
-
if (parsed.configWarnings?.length) {
|
|
27496
|
-
allWarnings.push(...parsed.configWarnings.map((w3) => `[user config] ${w3}`));
|
|
27497
|
-
}
|
|
27498
|
-
config2 = mergeConfigs(config2, parsed, { allowUserOnlyFields: true });
|
|
27596
|
+
mergedRaw = deepMergeRawConfig(mergedRaw, userLoaded.config);
|
|
27499
27597
|
}
|
|
27500
27598
|
if (projectLoaded) {
|
|
27501
27599
|
allWarnings.push(...projectLoaded.warnings.map((w3) => `[project config] ${w3}`));
|
|
27502
|
-
const
|
|
27503
|
-
|
|
27504
|
-
allWarnings.push(...parsed.configWarnings.map((w3) => `[project config] ${w3}`));
|
|
27505
|
-
}
|
|
27506
|
-
const strippedUserOnlyFields = getProjectUserOnlyFields(projectLoaded.config);
|
|
27600
|
+
const projectRaw = { ...projectLoaded.config };
|
|
27601
|
+
const strippedUserOnlyFields = getProjectUserOnlyFields(projectRaw);
|
|
27507
27602
|
if (strippedUserOnlyFields.length > 0) {
|
|
27603
|
+
for (const key of strippedUserOnlyFields) {
|
|
27604
|
+
delete projectRaw[key];
|
|
27605
|
+
}
|
|
27508
27606
|
allWarnings.push(`[project config] Ignoring ${strippedUserOnlyFields.join(", ")} from project config (security: these settings only honor user-level config)`);
|
|
27509
27607
|
}
|
|
27510
|
-
|
|
27608
|
+
mergedRaw = deepMergeRawConfig(mergedRaw, projectRaw);
|
|
27609
|
+
}
|
|
27610
|
+
const config2 = parsePluginConfig(mergedRaw);
|
|
27611
|
+
if (config2.configWarnings?.length) {
|
|
27612
|
+
allWarnings.push(...config2.configWarnings.map((w3) => {
|
|
27613
|
+
if (userLoaded && projectLoaded)
|
|
27614
|
+
return `[config] ${w3}`;
|
|
27615
|
+
if (userLoaded)
|
|
27616
|
+
return `[user config] ${w3}`;
|
|
27617
|
+
return `[project config] ${w3}`;
|
|
27618
|
+
}));
|
|
27511
27619
|
}
|
|
27512
27620
|
if (allWarnings.length > 0) {
|
|
27513
27621
|
config2.configWarnings = allWarnings;
|
|
27622
|
+
} else if ("configWarnings" in config2) {
|
|
27623
|
+
config2.configWarnings = undefined;
|
|
27514
27624
|
}
|
|
27515
27625
|
return config2;
|
|
27516
27626
|
}
|
|
@@ -27626,7 +27736,7 @@ function truncate(text2) {
|
|
|
27626
27736
|
var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
|
|
27627
27737
|
|
|
27628
27738
|
// ../plugin/src/shared/tui-config.ts
|
|
27629
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as
|
|
27739
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "node:fs";
|
|
27630
27740
|
import { dirname as dirname8, join as join11 } from "node:path";
|
|
27631
27741
|
function isMagicContextEntry(entry) {
|
|
27632
27742
|
if (!entry)
|
|
@@ -27654,8 +27764,8 @@ function ensureTuiPluginEntry() {
|
|
|
27654
27764
|
const configPath = resolveTuiConfigPath();
|
|
27655
27765
|
let config2 = {};
|
|
27656
27766
|
if (existsSync13(configPath)) {
|
|
27657
|
-
const raw =
|
|
27658
|
-
config2 =
|
|
27767
|
+
const raw = readFileSync9(configPath, "utf-8");
|
|
27768
|
+
config2 = import_comment_json6.parse(raw) ?? {};
|
|
27659
27769
|
}
|
|
27660
27770
|
const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((p2) => typeof p2 === "string") : [];
|
|
27661
27771
|
const existingIdx = plugins.findIndex(isMagicContextEntry);
|
|
@@ -27674,7 +27784,7 @@ function ensureTuiPluginEntry() {
|
|
|
27674
27784
|
}
|
|
27675
27785
|
config2.plugin = plugins;
|
|
27676
27786
|
mkdirSync6(dirname8(configPath), { recursive: true });
|
|
27677
|
-
writeFileSync8(configPath, `${
|
|
27787
|
+
writeFileSync8(configPath, `${import_comment_json6.stringify(config2, null, 2)}
|
|
27678
27788
|
`);
|
|
27679
27789
|
log2(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
27680
27790
|
return true;
|
|
@@ -27683,11 +27793,11 @@ function ensureTuiPluginEntry() {
|
|
|
27683
27793
|
return false;
|
|
27684
27794
|
}
|
|
27685
27795
|
}
|
|
27686
|
-
var
|
|
27796
|
+
var import_comment_json6, PLUGIN_NAME4 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY3;
|
|
27687
27797
|
var init_tui_config = __esm(() => {
|
|
27688
27798
|
init_logger();
|
|
27689
27799
|
init_opencode_config_dir();
|
|
27690
|
-
|
|
27800
|
+
import_comment_json6 = __toESM(require_src2(), 1);
|
|
27691
27801
|
PLUGIN_ENTRY3 = `${PLUGIN_NAME4}@latest`;
|
|
27692
27802
|
});
|
|
27693
27803
|
|
|
@@ -27741,10 +27851,125 @@ var init_compartment_parser = __esm(() => {
|
|
|
27741
27851
|
USER_OBS_ITEM_REGEX = /^\s*\*\s*(.+)$/gm;
|
|
27742
27852
|
});
|
|
27743
27853
|
|
|
27854
|
+
// src/lib/redaction.ts
|
|
27855
|
+
import { homedir as homedir9, userInfo } from "node:os";
|
|
27856
|
+
function escapeRegex2(value) {
|
|
27857
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27858
|
+
}
|
|
27859
|
+
function redactionTypeForKey(key) {
|
|
27860
|
+
const normalized = key.trim().toLowerCase().replace(/[^a-z0-9_.-]+/g, "_");
|
|
27861
|
+
const suffix = normalized.split(".").filter(Boolean).at(-1) ?? normalized;
|
|
27862
|
+
return suffix || "secret";
|
|
27863
|
+
}
|
|
27864
|
+
function isSecretKey(key) {
|
|
27865
|
+
return SECRET_KEY_PATTERN.test(key);
|
|
27866
|
+
}
|
|
27867
|
+
function sanitizePathString(value) {
|
|
27868
|
+
const home = homedir9();
|
|
27869
|
+
const username = userInfo().username;
|
|
27870
|
+
let sanitized = value;
|
|
27871
|
+
if (home) {
|
|
27872
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex2(home), "g"), "~");
|
|
27873
|
+
}
|
|
27874
|
+
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
27875
|
+
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
27876
|
+
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
27877
|
+
if (username) {
|
|
27878
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex2(username), "g"), "<USER>");
|
|
27879
|
+
}
|
|
27880
|
+
return sanitized;
|
|
27881
|
+
}
|
|
27882
|
+
function redactSecretText(value) {
|
|
27883
|
+
let redacted = value;
|
|
27884
|
+
for (const { pattern, replacement } of SECRET_TEXT_PATTERNS) {
|
|
27885
|
+
if (typeof replacement === "string") {
|
|
27886
|
+
redacted = redacted.replace(pattern, replacement);
|
|
27887
|
+
} else {
|
|
27888
|
+
redacted = redacted.replace(pattern, replacement);
|
|
27889
|
+
}
|
|
27890
|
+
}
|
|
27891
|
+
return redacted;
|
|
27892
|
+
}
|
|
27893
|
+
function sanitizeDiagnosticText(value) {
|
|
27894
|
+
return redactSecretText(sanitizePathString(value));
|
|
27895
|
+
}
|
|
27896
|
+
function sanitizeConfigValue(value, keyPath = []) {
|
|
27897
|
+
const key = keyPath.at(-1) ?? "";
|
|
27898
|
+
if (key && isSecretKey(key)) {
|
|
27899
|
+
return `<REDACTED:${redactionTypeForKey(key)}>`;
|
|
27900
|
+
}
|
|
27901
|
+
if (typeof value === "string")
|
|
27902
|
+
return sanitizeDiagnosticText(value);
|
|
27903
|
+
if (Array.isArray(value)) {
|
|
27904
|
+
return value.map((entry, index) => sanitizeConfigValue(entry, [...keyPath, String(index)]));
|
|
27905
|
+
}
|
|
27906
|
+
if (value && typeof value === "object") {
|
|
27907
|
+
return Object.fromEntries(Object.entries(value).map(([entryKey, entry]) => [
|
|
27908
|
+
entryKey,
|
|
27909
|
+
sanitizeConfigValue(entry, [...keyPath, entryKey])
|
|
27910
|
+
]));
|
|
27911
|
+
}
|
|
27912
|
+
return value;
|
|
27913
|
+
}
|
|
27914
|
+
var SECRET_KEY_PATTERN, SECRET_TEXT_PATTERNS;
|
|
27915
|
+
var init_redaction = __esm(() => {
|
|
27916
|
+
SECRET_KEY_PATTERN = /(?:key|token|secret|password|auth|bearer|credential)/i;
|
|
27917
|
+
SECRET_TEXT_PATTERNS = [
|
|
27918
|
+
{
|
|
27919
|
+
pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
|
|
27920
|
+
replacement: "<ANTHROPIC_API_KEY_REDACTED>"
|
|
27921
|
+
},
|
|
27922
|
+
{
|
|
27923
|
+
pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g,
|
|
27924
|
+
replacement: "<OPENAI_API_KEY_REDACTED>"
|
|
27925
|
+
},
|
|
27926
|
+
{
|
|
27927
|
+
pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
|
|
27928
|
+
replacement: "<GITHUB_PAT_REDACTED>"
|
|
27929
|
+
},
|
|
27930
|
+
{
|
|
27931
|
+
pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
|
|
27932
|
+
replacement: "<GITHUB_TOKEN_REDACTED>"
|
|
27933
|
+
},
|
|
27934
|
+
{
|
|
27935
|
+
pattern: /\bhf_[A-Za-z0-9]{30,}/g,
|
|
27936
|
+
replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
|
|
27937
|
+
},
|
|
27938
|
+
{
|
|
27939
|
+
pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
27940
|
+
replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
|
|
27941
|
+
},
|
|
27942
|
+
{
|
|
27943
|
+
pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
|
|
27944
|
+
replacement: "<SLACK_TOKEN_REDACTED>"
|
|
27945
|
+
},
|
|
27946
|
+
{
|
|
27947
|
+
pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
|
|
27948
|
+
replacement: "<GOOGLE_API_KEY_REDACTED>"
|
|
27949
|
+
},
|
|
27950
|
+
{
|
|
27951
|
+
pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{8,})/gi,
|
|
27952
|
+
replacement: (_full, prefix) => `${prefix}<REDACTED:bearer>`
|
|
27953
|
+
},
|
|
27954
|
+
{
|
|
27955
|
+
pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
|
|
27956
|
+
replacement: "<JWT_REDACTED>"
|
|
27957
|
+
},
|
|
27958
|
+
{
|
|
27959
|
+
pattern: /(["'])([^"']*(?:key|token|secret|password|auth|bearer|credential)[^"']*)\1(\s*:\s*)(["'])([^"']*)\4/gi,
|
|
27960
|
+
replacement: (_full, quote, key, separator, valueQuote) => `${quote}${key}${quote}${separator}${valueQuote}<REDACTED:${redactionTypeForKey(key)}>${valueQuote}`
|
|
27961
|
+
},
|
|
27962
|
+
{
|
|
27963
|
+
pattern: /\b([A-Za-z0-9_.-]*(?:key|token|secret|password|auth|bearer|credential)[A-Za-z0-9_.-]*)\s*=\s*([^\s'"`]+)/gi,
|
|
27964
|
+
replacement: (_full, key) => `${key}=<REDACTED:${redactionTypeForKey(key)}>`
|
|
27965
|
+
}
|
|
27966
|
+
];
|
|
27967
|
+
});
|
|
27968
|
+
|
|
27744
27969
|
// src/lib/diagnostics-opencode.ts
|
|
27745
|
-
import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as
|
|
27970
|
+
import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as readFileSync10, statSync as statSync2 } from "node:fs";
|
|
27746
27971
|
import { createRequire as createRequire3 } from "node:module";
|
|
27747
|
-
import { homedir as
|
|
27972
|
+
import { homedir as homedir10 } from "node:os";
|
|
27748
27973
|
import { join as join12 } from "node:path";
|
|
27749
27974
|
function getSelfVersion() {
|
|
27750
27975
|
const require2 = createRequire3(import.meta.url);
|
|
@@ -27764,7 +27989,7 @@ function getPluginCacheInfo() {
|
|
|
27764
27989
|
try {
|
|
27765
27990
|
const installedPkgPath = join12(path4, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
27766
27991
|
if (existsSync14(installedPkgPath)) {
|
|
27767
|
-
const pkg = JSON.parse(
|
|
27992
|
+
const pkg = JSON.parse(readFileSync10(installedPkgPath, "utf-8"));
|
|
27768
27993
|
cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
27769
27994
|
}
|
|
27770
27995
|
} catch {
|
|
@@ -27773,7 +27998,7 @@ function getPluginCacheInfo() {
|
|
|
27773
27998
|
return { path: path4, cached: cached2, latest: getSelfVersion() };
|
|
27774
27999
|
}
|
|
27775
28000
|
function getStorageDir() {
|
|
27776
|
-
const dataHome = process.env.XDG_DATA_HOME || join12(
|
|
28001
|
+
const dataHome = process.env.XDG_DATA_HOME || join12(homedir10(), ".local", "share");
|
|
27777
28002
|
return join12(dataHome, "cortexkit", "magic-context");
|
|
27778
28003
|
}
|
|
27779
28004
|
function fileSize(path4) {
|
|
@@ -27783,40 +28008,18 @@ function fileSize(path4) {
|
|
|
27783
28008
|
return 0;
|
|
27784
28009
|
}
|
|
27785
28010
|
}
|
|
27786
|
-
function escapeRegex2(value) {
|
|
27787
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27788
|
-
}
|
|
27789
28011
|
function sanitizeString(value) {
|
|
27790
|
-
|
|
27791
|
-
const username = userInfo().username;
|
|
27792
|
-
let sanitized = value;
|
|
27793
|
-
if (home) {
|
|
27794
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex2(home), "g"), "~");
|
|
27795
|
-
}
|
|
27796
|
-
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
27797
|
-
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
27798
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
27799
|
-
if (username) {
|
|
27800
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex2(username), "g"), "<USER>");
|
|
27801
|
-
}
|
|
27802
|
-
return sanitized;
|
|
28012
|
+
return sanitizePathString(value);
|
|
27803
28013
|
}
|
|
27804
28014
|
function sanitizeValue(value) {
|
|
27805
|
-
|
|
27806
|
-
return sanitizeString(value);
|
|
27807
|
-
if (Array.isArray(value))
|
|
27808
|
-
return value.map(sanitizeValue);
|
|
27809
|
-
if (value && typeof value === "object") {
|
|
27810
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
|
|
27811
|
-
}
|
|
27812
|
-
return value;
|
|
28015
|
+
return sanitizeConfigValue(value);
|
|
27813
28016
|
}
|
|
27814
28017
|
function readConfig2(path4) {
|
|
27815
28018
|
if (!existsSync14(path4))
|
|
27816
28019
|
return { value: null };
|
|
27817
28020
|
try {
|
|
27818
|
-
const raw =
|
|
27819
|
-
const value =
|
|
28021
|
+
const raw = readFileSync10(path4, "utf-8");
|
|
28022
|
+
const value = import_comment_json7.parse(raw);
|
|
27820
28023
|
return { value };
|
|
27821
28024
|
} catch (error51) {
|
|
27822
28025
|
return { value: null, error: error51 instanceof Error ? error51.message : String(error51) };
|
|
@@ -27838,7 +28041,7 @@ function configHasPluginEntry(config2) {
|
|
|
27838
28041
|
}
|
|
27839
28042
|
function parseHistorianDumpMeta(path4) {
|
|
27840
28043
|
try {
|
|
27841
|
-
const xml =
|
|
28044
|
+
const xml = readFileSync10(path4, "utf-8");
|
|
27842
28045
|
const parsed = parseCompartmentOutput(xml);
|
|
27843
28046
|
const factCountByCategory = {};
|
|
27844
28047
|
for (const fact of parsed.facts) {
|
|
@@ -27870,11 +28073,9 @@ function parseHistorianDumpMeta(path4) {
|
|
|
27870
28073
|
return { error: error51 instanceof Error ? error51.message : String(error51) };
|
|
27871
28074
|
}
|
|
27872
28075
|
}
|
|
27873
|
-
function
|
|
27874
|
-
|
|
27875
|
-
|
|
27876
|
-
return { dir, count: 0, recent: [] };
|
|
27877
|
-
}
|
|
28076
|
+
function listDumpsInDir(dir, limit) {
|
|
28077
|
+
if (!existsSync14(dir))
|
|
28078
|
+
return { count: 0, recent: [] };
|
|
27878
28079
|
try {
|
|
27879
28080
|
const entries = readdirSync2(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
27880
28081
|
const stat = statSync2(join12(dir, name));
|
|
@@ -27885,7 +28086,7 @@ function collectHistorianDumps() {
|
|
|
27885
28086
|
};
|
|
27886
28087
|
}).sort((a, b2) => b2.mtime - a.mtime);
|
|
27887
28088
|
const now = Date.now();
|
|
27888
|
-
const recent = entries.slice(0,
|
|
28089
|
+
const recent = entries.slice(0, limit).map((entry) => {
|
|
27889
28090
|
const meta3 = parseHistorianDumpMeta(join12(dir, entry.name));
|
|
27890
28091
|
const summary = {
|
|
27891
28092
|
name: entry.name,
|
|
@@ -27899,9 +28100,80 @@ function collectHistorianDumps() {
|
|
|
27899
28100
|
}
|
|
27900
28101
|
return summary;
|
|
27901
28102
|
});
|
|
27902
|
-
return {
|
|
28103
|
+
return { count: entries.length, recent };
|
|
27903
28104
|
} catch {
|
|
27904
|
-
return {
|
|
28105
|
+
return { count: 0, recent: [] };
|
|
28106
|
+
}
|
|
28107
|
+
}
|
|
28108
|
+
function collectHistorianDumps(recentSessions) {
|
|
28109
|
+
const buckets = new Map;
|
|
28110
|
+
for (const session of recentSessions) {
|
|
28111
|
+
const dir = session.directory;
|
|
28112
|
+
if (!dir)
|
|
28113
|
+
continue;
|
|
28114
|
+
const projectHistorianDir = getProjectMagicContextHistorianDir(dir);
|
|
28115
|
+
const listing = listDumpsInDir(projectHistorianDir, 5);
|
|
28116
|
+
const existing = buckets.get(dir);
|
|
28117
|
+
if (existing) {
|
|
28118
|
+
if (!existing.sessionIds.includes(session.sessionId)) {
|
|
28119
|
+
existing.sessionIds.push(session.sessionId);
|
|
28120
|
+
}
|
|
28121
|
+
continue;
|
|
28122
|
+
}
|
|
28123
|
+
if (listing.count === 0)
|
|
28124
|
+
continue;
|
|
28125
|
+
buckets.set(dir, {
|
|
28126
|
+
directory: dir,
|
|
28127
|
+
primarySessionId: session.sessionId,
|
|
28128
|
+
sessionIds: [session.sessionId],
|
|
28129
|
+
count: listing.count,
|
|
28130
|
+
recent: listing.recent
|
|
28131
|
+
});
|
|
28132
|
+
}
|
|
28133
|
+
const legacyDir = getMagicContextHistorianDir2("opencode");
|
|
28134
|
+
const legacyListing = listDumpsInDir(legacyDir, 5);
|
|
28135
|
+
return {
|
|
28136
|
+
byProject: [...buckets.values()],
|
|
28137
|
+
legacyDumps: {
|
|
28138
|
+
dir: legacyDir,
|
|
28139
|
+
count: legacyListing.count,
|
|
28140
|
+
recent: legacyListing.recent
|
|
28141
|
+
}
|
|
28142
|
+
};
|
|
28143
|
+
}
|
|
28144
|
+
async function collectRecentSessions() {
|
|
28145
|
+
const opencodeDbPath = join12(homedir10(), ".local", "share", "opencode", "opencode.db");
|
|
28146
|
+
if (!existsSync14(opencodeDbPath))
|
|
28147
|
+
return [];
|
|
28148
|
+
if (typeof globalThis.Bun === "undefined") {
|
|
28149
|
+
return [];
|
|
28150
|
+
}
|
|
28151
|
+
let DatabaseClass;
|
|
28152
|
+
try {
|
|
28153
|
+
const mod = await new Function("p", "return import(p)")("bun:sqlite");
|
|
28154
|
+
DatabaseClass = mod.Database;
|
|
28155
|
+
} catch {
|
|
28156
|
+
return [];
|
|
28157
|
+
}
|
|
28158
|
+
let db = null;
|
|
28159
|
+
try {
|
|
28160
|
+
db = new DatabaseClass(opencodeDbPath, { readonly: true });
|
|
28161
|
+
const rows = db.prepare("SELECT id, directory, title, time_updated FROM session " + "WHERE time_archived IS NULL AND parent_id IS NULL " + "ORDER BY time_updated DESC LIMIT 5").all();
|
|
28162
|
+
return rows.flatMap((row) => {
|
|
28163
|
+
const sessionId = typeof row.id === "string" ? row.id : null;
|
|
28164
|
+
const directory = typeof row.directory === "string" ? row.directory : null;
|
|
28165
|
+
if (!sessionId || !directory)
|
|
28166
|
+
return [];
|
|
28167
|
+
const title = typeof row.title === "string" ? row.title : "";
|
|
28168
|
+
const lastActiveAt = typeof row.time_updated === "number" ? new Date(row.time_updated).toISOString() : "";
|
|
28169
|
+
return [{ sessionId, title, directory, lastActiveAt }];
|
|
28170
|
+
});
|
|
28171
|
+
} catch {
|
|
28172
|
+
return [];
|
|
28173
|
+
} finally {
|
|
28174
|
+
try {
|
|
28175
|
+
db?.close();
|
|
28176
|
+
} catch {}
|
|
27905
28177
|
}
|
|
27906
28178
|
}
|
|
27907
28179
|
async function collectHistorianFailures(storageDirPath) {
|
|
@@ -27927,7 +28199,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
27927
28199
|
const failureCount = typeof row.historian_failure_count === "number" ? row.historian_failure_count : 0;
|
|
27928
28200
|
const rawError = typeof row.historian_last_error === "string" ? row.historian_last_error : "";
|
|
27929
28201
|
const lastAt = typeof row.historian_last_failure_at === "number" ? new Date(row.historian_last_failure_at).toISOString() : "";
|
|
27930
|
-
const lastError =
|
|
28202
|
+
const lastError = sanitizeDiagnosticText(rawError.replace(/\s+/g, " ").trim().slice(0, 400));
|
|
27931
28203
|
return { sessionId, failureCount, lastError, lastFailureAt: lastAt };
|
|
27932
28204
|
});
|
|
27933
28205
|
} catch {
|
|
@@ -27946,9 +28218,10 @@ async function collectDiagnostics() {
|
|
|
27946
28218
|
const magicContextConfig = readConfig2(configPaths.magicContextConfig);
|
|
27947
28219
|
const storageDirPath = getStorageDir();
|
|
27948
28220
|
const contextDbPath = join12(storageDirPath, "context.db");
|
|
27949
|
-
const logPath =
|
|
28221
|
+
const logPath = getMagicContextLogPath2("opencode");
|
|
27950
28222
|
const logFileSize = existsSync14(logPath) ? statSync2(logPath).size : 0;
|
|
27951
28223
|
const conflictResult = detectConflicts(process.cwd());
|
|
28224
|
+
const recentSessions = await collectRecentSessions();
|
|
27952
28225
|
return {
|
|
27953
28226
|
timestamp: new Date().toISOString(),
|
|
27954
28227
|
platform: process.platform,
|
|
@@ -27980,7 +28253,8 @@ async function collectDiagnostics() {
|
|
|
27980
28253
|
exists: existsSync14(logPath),
|
|
27981
28254
|
sizeKb: Math.round(logFileSize / 1024)
|
|
27982
28255
|
},
|
|
27983
|
-
|
|
28256
|
+
recentSessions,
|
|
28257
|
+
historianDumps: collectHistorianDumps(recentSessions),
|
|
27984
28258
|
historianFailures: await collectHistorianFailures(storageDirPath)
|
|
27985
28259
|
};
|
|
27986
28260
|
}
|
|
@@ -28014,10 +28288,25 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28014
28288
|
context_db_size: formatBytes(report.storageDir.contextDbSizeBytes)
|
|
28015
28289
|
};
|
|
28016
28290
|
const historianDumps = {
|
|
28017
|
-
|
|
28018
|
-
|
|
28019
|
-
|
|
28291
|
+
byProject: report.historianDumps.byProject.map((bucket) => ({
|
|
28292
|
+
directory: sanitizeString(bucket.directory),
|
|
28293
|
+
primarySessionId: bucket.primarySessionId,
|
|
28294
|
+
sessionIds: bucket.sessionIds,
|
|
28295
|
+
count: bucket.count,
|
|
28296
|
+
recent: bucket.recent
|
|
28297
|
+
})),
|
|
28298
|
+
legacyDumps: {
|
|
28299
|
+
dir: sanitizeString(report.historianDumps.legacyDumps.dir),
|
|
28300
|
+
count: report.historianDumps.legacyDumps.count,
|
|
28301
|
+
recent: report.historianDumps.legacyDumps.recent
|
|
28302
|
+
}
|
|
28020
28303
|
};
|
|
28304
|
+
const recentSessions = report.recentSessions.map((session) => ({
|
|
28305
|
+
sessionId: session.sessionId,
|
|
28306
|
+
title: session.title,
|
|
28307
|
+
directory: sanitizeString(session.directory),
|
|
28308
|
+
lastActiveAt: session.lastActiveAt
|
|
28309
|
+
}));
|
|
28021
28310
|
return [
|
|
28022
28311
|
`- Timestamp: ${report.timestamp}`,
|
|
28023
28312
|
`- Plugin: v${report.pluginVersion}`,
|
|
@@ -28036,7 +28325,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28036
28325
|
"",
|
|
28037
28326
|
"### magic-context.jsonc flags",
|
|
28038
28327
|
"```jsonc",
|
|
28039
|
-
JSON.stringify(report.magicContextConfig.flags, null, 2),
|
|
28328
|
+
JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2),
|
|
28040
28329
|
"```",
|
|
28041
28330
|
"",
|
|
28042
28331
|
"### Plugin cache",
|
|
@@ -28048,15 +28337,24 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28048
28337
|
"```json",
|
|
28049
28338
|
JSON.stringify(storage, null, 2),
|
|
28050
28339
|
"```",
|
|
28340
|
+
"",
|
|
28341
|
+
"### Recent sessions",
|
|
28342
|
+
recentSessions.length === 0 ? "_No recent OpenCode sessions found (or OpenCode DB unavailable on this runtime)._" : ["```json", JSON.stringify(recentSessions, null, 2), "```"].join(`
|
|
28343
|
+
`),
|
|
28051
28344
|
"",
|
|
28052
28345
|
"### Historian dumps",
|
|
28053
28346
|
"(Metadata only — XML content is not included in this report.)",
|
|
28347
|
+
"Dumps are stored per-project under `<project>/.opencode/magic-context/historian/`.",
|
|
28054
28348
|
"```json",
|
|
28055
28349
|
JSON.stringify(historianDumps, null, 2),
|
|
28056
28350
|
"```",
|
|
28057
28351
|
"",
|
|
28058
28352
|
"### Historian failures (session_meta)",
|
|
28059
|
-
report.historianFailures.length === 0 ? "_No sessions with historian failures._" : [
|
|
28353
|
+
report.historianFailures.length === 0 ? "_No sessions with historian failures._" : [
|
|
28354
|
+
"```json",
|
|
28355
|
+
JSON.stringify(sanitizeConfigValue(report.historianFailures), null, 2),
|
|
28356
|
+
"```"
|
|
28357
|
+
].join(`
|
|
28060
28358
|
`),
|
|
28061
28359
|
"",
|
|
28062
28360
|
"### Log file",
|
|
@@ -28066,45 +28364,24 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28066
28364
|
].join(`
|
|
28067
28365
|
`);
|
|
28068
28366
|
}
|
|
28069
|
-
var
|
|
28367
|
+
var import_comment_json7, PLUGIN_NAME5 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION;
|
|
28070
28368
|
var init_diagnostics_opencode = __esm(() => {
|
|
28071
28369
|
init_compartment_parser();
|
|
28072
28370
|
init_conflict_detector();
|
|
28073
28371
|
init_data_path();
|
|
28074
28372
|
init_opencode_helpers();
|
|
28075
28373
|
init_paths();
|
|
28076
|
-
|
|
28374
|
+
init_redaction();
|
|
28375
|
+
import_comment_json7 = __toESM(require_src2(), 1);
|
|
28077
28376
|
PLUGIN_ENTRY_WITH_VERSION = `${PLUGIN_NAME5}@latest`;
|
|
28078
28377
|
});
|
|
28079
28378
|
|
|
28080
28379
|
// src/lib/logs-opencode.ts
|
|
28081
|
-
import { readFileSync as
|
|
28082
|
-
import { homedir as
|
|
28380
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28381
|
+
import { homedir as homedir11 } from "node:os";
|
|
28083
28382
|
import { join as join13 } from "node:path";
|
|
28084
|
-
function escapeRegex3(value) {
|
|
28085
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28086
|
-
}
|
|
28087
28383
|
function sanitizeLogContent(content) {
|
|
28088
|
-
|
|
28089
|
-
const username = userInfo2().username;
|
|
28090
|
-
let sanitized = content;
|
|
28091
|
-
if (home) {
|
|
28092
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex3(home), "g"), "~");
|
|
28093
|
-
}
|
|
28094
|
-
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
28095
|
-
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
28096
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
28097
|
-
if (username) {
|
|
28098
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex3(username), "g"), "<USER>");
|
|
28099
|
-
}
|
|
28100
|
-
for (const { pattern, replacement } of SECRET_PATTERNS) {
|
|
28101
|
-
if (typeof replacement === "string") {
|
|
28102
|
-
sanitized = sanitized.replace(pattern, replacement);
|
|
28103
|
-
} else {
|
|
28104
|
-
sanitized = sanitized.replace(pattern, replacement);
|
|
28105
|
-
}
|
|
28106
|
-
}
|
|
28107
|
-
return sanitized;
|
|
28384
|
+
return sanitizeDiagnosticText(content);
|
|
28108
28385
|
}
|
|
28109
28386
|
function formatTimestamp(date5) {
|
|
28110
28387
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -28131,16 +28408,28 @@ function extractHistorianFailureLines(sanitized, limit = 30) {
|
|
|
28131
28408
|
}
|
|
28132
28409
|
return matches.reverse();
|
|
28133
28410
|
}
|
|
28134
|
-
|
|
28411
|
+
function filterLogLinesBySession(lines, sessionId) {
|
|
28412
|
+
if (!sessionId)
|
|
28413
|
+
return lines;
|
|
28414
|
+
const otherSessionPattern = /\bses_[A-Za-z0-9]{8,32}\b/g;
|
|
28415
|
+
return lines.filter((line) => {
|
|
28416
|
+
const matches = line.match(otherSessionPattern);
|
|
28417
|
+
if (!matches)
|
|
28418
|
+
return true;
|
|
28419
|
+
return matches.every((id) => id === sessionId);
|
|
28420
|
+
});
|
|
28421
|
+
}
|
|
28422
|
+
async function bundleIssueReport(report, description, _title, sessionFilter = null) {
|
|
28135
28423
|
const LOG_TAIL_LINES = 400;
|
|
28136
|
-
const
|
|
28424
|
+
const allLogLines = report.logFile.exists ? readFileSync11(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
28425
|
+
const logLines = filterLogLinesBySession(allLogLines, sessionFilter);
|
|
28137
28426
|
const recentLog = sanitizeLogContent(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
28138
28427
|
`)).trim();
|
|
28139
28428
|
const historianScanWindow = sanitizeLogContent(logLines.slice(-4000).join(`
|
|
28140
28429
|
`));
|
|
28141
28430
|
const historianFailureLines = extractHistorianFailureLines(historianScanWindow, 30);
|
|
28142
|
-
const configBody = JSON.stringify(report.magicContextConfig.flags, null, 2);
|
|
28143
|
-
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(
|
|
28431
|
+
const configBody = JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2);
|
|
28432
|
+
const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(homedir11(), "~");
|
|
28144
28433
|
const bodyMarkdown = [
|
|
28145
28434
|
"## Description",
|
|
28146
28435
|
description,
|
|
@@ -28176,76 +28465,10 @@ async function bundleIssueReport(report, description, _title) {
|
|
|
28176
28465
|
`);
|
|
28177
28466
|
return { path: path4, bodyMarkdown };
|
|
28178
28467
|
}
|
|
28179
|
-
var
|
|
28468
|
+
var HISTORIAN_LOG_PATTERNS;
|
|
28180
28469
|
var init_logs_opencode = __esm(() => {
|
|
28181
28470
|
init_diagnostics_opencode();
|
|
28182
|
-
|
|
28183
|
-
{
|
|
28184
|
-
name: "anthropic_api_key",
|
|
28185
|
-
pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
|
|
28186
|
-
replacement: "<ANTHROPIC_API_KEY_REDACTED>"
|
|
28187
|
-
},
|
|
28188
|
-
{
|
|
28189
|
-
name: "openai_api_key",
|
|
28190
|
-
pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g,
|
|
28191
|
-
replacement: "<OPENAI_API_KEY_REDACTED>"
|
|
28192
|
-
},
|
|
28193
|
-
{
|
|
28194
|
-
name: "github_pat_fine_grained",
|
|
28195
|
-
pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
|
|
28196
|
-
replacement: "<GITHUB_PAT_REDACTED>"
|
|
28197
|
-
},
|
|
28198
|
-
{
|
|
28199
|
-
name: "github_token_classic",
|
|
28200
|
-
pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
|
|
28201
|
-
replacement: "<GITHUB_TOKEN_REDACTED>"
|
|
28202
|
-
},
|
|
28203
|
-
{
|
|
28204
|
-
name: "huggingface_token",
|
|
28205
|
-
pattern: /\bhf_[A-Za-z0-9]{30,}/g,
|
|
28206
|
-
replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
|
|
28207
|
-
},
|
|
28208
|
-
{
|
|
28209
|
-
name: "aws_access_key_id",
|
|
28210
|
-
pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
28211
|
-
replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
|
|
28212
|
-
},
|
|
28213
|
-
{
|
|
28214
|
-
name: "aws_secret_access_key",
|
|
28215
|
-
pattern: /\b(aws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*)([A-Za-z0-9/+=]{40})\b/gi,
|
|
28216
|
-
replacement: (_full, prefix) => `${prefix}<AWS_SECRET_REDACTED>`
|
|
28217
|
-
},
|
|
28218
|
-
{
|
|
28219
|
-
name: "slack_token",
|
|
28220
|
-
pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
|
|
28221
|
-
replacement: "<SLACK_TOKEN_REDACTED>"
|
|
28222
|
-
},
|
|
28223
|
-
{
|
|
28224
|
-
name: "google_api_key",
|
|
28225
|
-
pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
|
|
28226
|
-
replacement: "<GOOGLE_API_KEY_REDACTED>"
|
|
28227
|
-
},
|
|
28228
|
-
{
|
|
28229
|
-
name: "secret_env_assignment",
|
|
28230
|
-
pattern: /\b([A-Z][A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|PRIVATE[_-]?KEY))\s*=\s*([^\s'"]+)/g,
|
|
28231
|
-
replacement: (_full, key) => `${key}=<REDACTED>`
|
|
28232
|
-
},
|
|
28233
|
-
{
|
|
28234
|
-
name: "secret_json_assignment",
|
|
28235
|
-
pattern: /("(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer[_-]?token|client[_-]?secret|password|private[_-]?key|secret[_-]?key)"\s*:\s*)"([^"]+)"/gi,
|
|
28236
|
-
replacement: (_full, prefix) => `${prefix}"<REDACTED>"`
|
|
28237
|
-
},
|
|
28238
|
-
{
|
|
28239
|
-
name: "bearer_token",
|
|
28240
|
-
pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{16,})/gi,
|
|
28241
|
-
replacement: (_full, prefix) => `${prefix}<BEARER_TOKEN_REDACTED>`
|
|
28242
|
-
},
|
|
28243
|
-
{
|
|
28244
|
-
name: "jwt_token",
|
|
28245
|
-
pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
|
|
28246
|
-
replacement: "<JWT_REDACTED>"
|
|
28247
|
-
}
|
|
28248
|
-
];
|
|
28471
|
+
init_redaction();
|
|
28249
28472
|
HISTORIAN_LOG_PATTERNS = [
|
|
28250
28473
|
/historian failure:/,
|
|
28251
28474
|
/historian failure recorded:/,
|
|
@@ -28258,10 +28481,10 @@ var init_logs_opencode = __esm(() => {
|
|
|
28258
28481
|
});
|
|
28259
28482
|
|
|
28260
28483
|
// src/commands/doctor-opencode.ts
|
|
28261
|
-
import { execSync as
|
|
28262
|
-
import { existsSync as existsSync15,
|
|
28484
|
+
import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
28485
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, rmSync, statSync as statSync3, writeFileSync as writeFileSync10 } from "node:fs";
|
|
28263
28486
|
import { createRequire as createRequire4 } from "node:module";
|
|
28264
|
-
import { homedir as
|
|
28487
|
+
import { homedir as homedir12 } from "node:os";
|
|
28265
28488
|
import { join as join14 } from "node:path";
|
|
28266
28489
|
async function fetchNpmLatest(pkg, timeoutMs = 5000) {
|
|
28267
28490
|
try {
|
|
@@ -28320,7 +28543,7 @@ async function clearPluginCache(force = false) {
|
|
|
28320
28543
|
try {
|
|
28321
28544
|
const installedPkgPath = join14(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
28322
28545
|
if (existsSync15(installedPkgPath)) {
|
|
28323
|
-
const pkg = JSON.parse(
|
|
28546
|
+
const pkg = JSON.parse(readFileSync12(installedPkgPath, "utf-8"));
|
|
28324
28547
|
if (typeof pkg?.version === "string") {
|
|
28325
28548
|
cachedVersion = pkg.version;
|
|
28326
28549
|
}
|
|
@@ -28358,7 +28581,7 @@ async function clearPluginCache(force = false) {
|
|
|
28358
28581
|
}
|
|
28359
28582
|
function isGhInstalled() {
|
|
28360
28583
|
try {
|
|
28361
|
-
|
|
28584
|
+
execSync2("gh --version", { stdio: "pipe" });
|
|
28362
28585
|
return true;
|
|
28363
28586
|
} catch {
|
|
28364
28587
|
return false;
|
|
@@ -28395,7 +28618,27 @@ async function runIssueFlow() {
|
|
|
28395
28618
|
s.start("Collecting diagnostics");
|
|
28396
28619
|
try {
|
|
28397
28620
|
const report = await collectDiagnostics();
|
|
28398
|
-
|
|
28621
|
+
s.stop("Diagnostics collected");
|
|
28622
|
+
let sessionFilter = null;
|
|
28623
|
+
if (report.recentSessions.length > 1) {
|
|
28624
|
+
const choice = await selectOne("Which session is this issue about? (filters log lines from other sessions)", [
|
|
28625
|
+
...report.recentSessions.map((session, index) => {
|
|
28626
|
+
const displayTitle = session.title.trim() || "(no title)";
|
|
28627
|
+
const truncatedTitle = displayTitle.length > 50 ? `${displayTitle.slice(0, 47)}...` : displayTitle;
|
|
28628
|
+
return {
|
|
28629
|
+
label: `${truncatedTitle} — ${session.sessionId}${index === 0 ? " (most recent)" : ""}`,
|
|
28630
|
+
value: session.sessionId
|
|
28631
|
+
};
|
|
28632
|
+
}),
|
|
28633
|
+
{
|
|
28634
|
+
label: "All sessions (no filtering)",
|
|
28635
|
+
value: "__all__"
|
|
28636
|
+
}
|
|
28637
|
+
]);
|
|
28638
|
+
sessionFilter = choice === "__all__" ? null : choice;
|
|
28639
|
+
}
|
|
28640
|
+
s.start("Bundling issue report");
|
|
28641
|
+
const bundled = await bundleIssueReport(report, description, title, sessionFilter);
|
|
28399
28642
|
s.stop(`Report written to ${bundled.path}`);
|
|
28400
28643
|
const shouldSubmit = await confirm("Submit this issue on GitHub now?", true);
|
|
28401
28644
|
if (shouldSubmit && isGhInstalled()) {
|
|
@@ -28437,7 +28680,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
28437
28680
|
}
|
|
28438
28681
|
let rawText;
|
|
28439
28682
|
try {
|
|
28440
|
-
rawText =
|
|
28683
|
+
rawText = readFileSync12(magicContextConfigPath, "utf-8");
|
|
28441
28684
|
} catch {
|
|
28442
28685
|
log.warn("Could not read magic-context.jsonc for embedding check");
|
|
28443
28686
|
return { issues: 1 };
|
|
@@ -28448,7 +28691,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
28448
28691
|
});
|
|
28449
28692
|
let parsedConfig;
|
|
28450
28693
|
try {
|
|
28451
|
-
parsedConfig =
|
|
28694
|
+
parsedConfig = import_comment_json8.parse(substituted.text);
|
|
28452
28695
|
} catch (error51) {
|
|
28453
28696
|
log.warn(`Embedding check skipped — could not parse magic-context.jsonc: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
28454
28697
|
return { issues: 1 };
|
|
@@ -28588,12 +28831,12 @@ async function runDoctor(options = {}) {
|
|
|
28588
28831
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28589
28832
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
28590
28833
|
try {
|
|
28591
|
-
const raw =
|
|
28834
|
+
const raw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
28592
28835
|
const substituted = substituteConfigVariables({
|
|
28593
28836
|
text: raw,
|
|
28594
28837
|
configPath: paths.magicContextConfig
|
|
28595
28838
|
}).text;
|
|
28596
|
-
|
|
28839
|
+
import_comment_json8.parse(substituted);
|
|
28597
28840
|
pass("magic-context.jsonc parses as valid JSONC");
|
|
28598
28841
|
} catch (err) {
|
|
28599
28842
|
fail(`magic-context.jsonc parse failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -28615,8 +28858,8 @@ async function runDoctor(options = {}) {
|
|
|
28615
28858
|
}
|
|
28616
28859
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28617
28860
|
try {
|
|
28618
|
-
const mcRaw =
|
|
28619
|
-
const mcConfig =
|
|
28861
|
+
const mcRaw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
28862
|
+
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
28620
28863
|
let mcChanged = false;
|
|
28621
28864
|
const experimental = mcConfig.experimental;
|
|
28622
28865
|
if (experimental && "compaction_markers" in experimental) {
|
|
@@ -28691,7 +28934,7 @@ async function runDoctor(options = {}) {
|
|
|
28691
28934
|
fixed++;
|
|
28692
28935
|
}
|
|
28693
28936
|
if (mcChanged) {
|
|
28694
|
-
writeFileSync10(paths.magicContextConfig, `${
|
|
28937
|
+
writeFileSync10(paths.magicContextConfig, `${import_comment_json8.stringify(mcConfig, null, 2)}
|
|
28695
28938
|
`);
|
|
28696
28939
|
}
|
|
28697
28940
|
} catch {
|
|
@@ -28700,8 +28943,8 @@ async function runDoctor(options = {}) {
|
|
|
28700
28943
|
}
|
|
28701
28944
|
if (paths.opencodeConfigFormat !== "none") {
|
|
28702
28945
|
try {
|
|
28703
|
-
const raw =
|
|
28704
|
-
const config2 =
|
|
28946
|
+
const raw = readFileSync12(paths.opencodeConfig, "utf-8");
|
|
28947
|
+
const config2 = import_comment_json8.parse(raw);
|
|
28705
28948
|
const rawPlugins = Array.isArray(config2?.plugin) ? config2.plugin : [];
|
|
28706
28949
|
const existingIdx = rawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
28707
28950
|
const configName = paths.opencodeConfigFormat === "jsonc" ? "opencode.jsonc" : "opencode.json";
|
|
@@ -28732,7 +28975,7 @@ async function runDoctor(options = {}) {
|
|
|
28732
28975
|
rawPlugins[existingIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
28733
28976
|
}
|
|
28734
28977
|
config2.plugin = rawPlugins;
|
|
28735
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
28978
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json8.stringify(config2, null, 2)}
|
|
28736
28979
|
`);
|
|
28737
28980
|
pass(`Upgraded plugin entry in ${configName}: ${oldEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
28738
28981
|
fixed++;
|
|
@@ -28741,7 +28984,7 @@ async function runDoctor(options = {}) {
|
|
|
28741
28984
|
} else {
|
|
28742
28985
|
rawPlugins.push(PLUGIN_ENTRY_WITH_VERSION2);
|
|
28743
28986
|
config2.plugin = rawPlugins;
|
|
28744
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
28987
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json8.stringify(config2, null, 2)}
|
|
28745
28988
|
`);
|
|
28746
28989
|
pass(`Added plugin to ${configName}`);
|
|
28747
28990
|
fixed++;
|
|
@@ -28774,8 +29017,8 @@ async function runDoctor(options = {}) {
|
|
|
28774
29017
|
fixed++;
|
|
28775
29018
|
} else if (existsSync15(paths.tuiConfig)) {
|
|
28776
29019
|
try {
|
|
28777
|
-
const tuiRaw =
|
|
28778
|
-
const tuiConfig =
|
|
29020
|
+
const tuiRaw = readFileSync12(paths.tuiConfig, "utf-8");
|
|
29021
|
+
const tuiConfig = import_comment_json8.parse(tuiRaw);
|
|
28779
29022
|
const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
|
|
28780
29023
|
const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
28781
29024
|
const tuiEntryAsString = (entry) => {
|
|
@@ -28803,7 +29046,7 @@ async function runDoctor(options = {}) {
|
|
|
28803
29046
|
tuiRawPlugins[tuiIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
28804
29047
|
}
|
|
28805
29048
|
tuiConfig.plugin = tuiRawPlugins;
|
|
28806
|
-
writeFileSync10(paths.tuiConfig, `${
|
|
29049
|
+
writeFileSync10(paths.tuiConfig, `${import_comment_json8.stringify(tuiConfig, null, 2)}
|
|
28807
29050
|
`);
|
|
28808
29051
|
pass(`Upgraded TUI plugin: ${tuiEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
28809
29052
|
fixed++;
|
|
@@ -28822,8 +29065,8 @@ async function runDoctor(options = {}) {
|
|
|
28822
29065
|
}
|
|
28823
29066
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28824
29067
|
try {
|
|
28825
|
-
const mcRaw =
|
|
28826
|
-
const mcConfig =
|
|
29068
|
+
const mcRaw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
29069
|
+
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
28827
29070
|
const dreamerObj = mcConfig?.dreamer;
|
|
28828
29071
|
const dreamerEnabled = dreamerObj?.enabled === true;
|
|
28829
29072
|
const userMemObj = dreamerObj?.user_memories;
|
|
@@ -28902,10 +29145,10 @@ async function runDoctor(options = {}) {
|
|
|
28902
29145
|
}
|
|
28903
29146
|
{
|
|
28904
29147
|
const ageWarnings = [];
|
|
28905
|
-
const npmrcPath = join14(
|
|
29148
|
+
const npmrcPath = join14(homedir12(), ".npmrc");
|
|
28906
29149
|
if (existsSync15(npmrcPath)) {
|
|
28907
29150
|
try {
|
|
28908
|
-
const npmrc =
|
|
29151
|
+
const npmrc = readFileSync12(npmrcPath, "utf-8");
|
|
28909
29152
|
for (const line of npmrc.split(`
|
|
28910
29153
|
`)) {
|
|
28911
29154
|
const trimmed = line.trim();
|
|
@@ -28928,7 +29171,7 @@ async function runDoctor(options = {}) {
|
|
|
28928
29171
|
issues++;
|
|
28929
29172
|
}
|
|
28930
29173
|
}
|
|
28931
|
-
const logPath =
|
|
29174
|
+
const logPath = getMagicContextLogPath2("opencode");
|
|
28932
29175
|
if (existsSync15(logPath)) {
|
|
28933
29176
|
const logStat = statSync3(logPath);
|
|
28934
29177
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
@@ -28936,25 +29179,27 @@ async function runDoctor(options = {}) {
|
|
|
28936
29179
|
} else {
|
|
28937
29180
|
log.info(`Log file: ${logPath} (not yet created)`);
|
|
28938
29181
|
}
|
|
28939
|
-
const
|
|
28940
|
-
|
|
28941
|
-
|
|
28942
|
-
|
|
28943
|
-
|
|
28944
|
-
|
|
28945
|
-
|
|
28946
|
-
|
|
28947
|
-
|
|
28948
|
-
|
|
28949
|
-
|
|
28950
|
-
|
|
28951
|
-
log.info(` ${dump.name} (${ageStr})`);
|
|
28952
|
-
}
|
|
28953
|
-
if (dumps.length > 3) {
|
|
28954
|
-
log.info(` ... and ${dumps.length - 3} more`);
|
|
28955
|
-
}
|
|
29182
|
+
const diagnostics = await collectDiagnostics();
|
|
29183
|
+
const dumpBuckets = diagnostics.historianDumps.byProject;
|
|
29184
|
+
if (dumpBuckets.length > 0) {
|
|
29185
|
+
const totalCount = dumpBuckets.reduce((sum, b2) => sum + b2.count, 0);
|
|
29186
|
+
const sessionCount = dumpBuckets.length;
|
|
29187
|
+
warn(`Historian debug dumps: ${totalCount} file(s) across ${sessionCount} project(s)`);
|
|
29188
|
+
for (const bucket of dumpBuckets) {
|
|
29189
|
+
log.info(` [${bucket.directory}] ${bucket.count} file(s)`);
|
|
29190
|
+
for (const dump of bucket.recent.slice(0, 3)) {
|
|
29191
|
+
const age = dump.ageMinutes;
|
|
29192
|
+
const ageStr = age < 60 ? `${age}m ago` : `${Math.round(age / 60)}h ago`;
|
|
29193
|
+
log.info(` ${dump.name} (${ageStr})`);
|
|
28956
29194
|
}
|
|
28957
|
-
|
|
29195
|
+
if (bucket.count > 3) {
|
|
29196
|
+
log.info(` ... and ${bucket.count - 3} more`);
|
|
29197
|
+
}
|
|
29198
|
+
}
|
|
29199
|
+
}
|
|
29200
|
+
const legacy = diagnostics.historianDumps.legacyDumps;
|
|
29201
|
+
if (legacy.count > 0) {
|
|
29202
|
+
log.info(`Legacy historian dumps (pre-v0.18.x): ${legacy.count} file(s) in ${legacy.dir}`);
|
|
28958
29203
|
}
|
|
28959
29204
|
if (paths.omoConfig) {
|
|
28960
29205
|
log.info(`OMO config found: ${paths.omoConfig}`);
|
|
@@ -28973,7 +29218,7 @@ async function runDoctor(options = {}) {
|
|
|
28973
29218
|
}
|
|
28974
29219
|
return 0;
|
|
28975
29220
|
}
|
|
28976
|
-
var
|
|
29221
|
+
var import_comment_json8, PLUGIN_NAME6 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION2, CLI_PACKAGE_NAME = "@cortexkit/magic-context";
|
|
28977
29222
|
var init_doctor_opencode = __esm(async () => {
|
|
28978
29223
|
init_config();
|
|
28979
29224
|
init_variable();
|
|
@@ -28988,9 +29233,10 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
28988
29233
|
init_paths();
|
|
28989
29234
|
init_prompts();
|
|
28990
29235
|
await init_sqlite();
|
|
28991
|
-
|
|
29236
|
+
import_comment_json8 = __toESM(require_src2(), 1);
|
|
28992
29237
|
PLUGIN_ENTRY_WITH_VERSION2 = `${PLUGIN_NAME6}@latest`;
|
|
28993
29238
|
});
|
|
29239
|
+
|
|
28994
29240
|
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
28995
29241
|
var insertCompartmentStatements, insertFactStatements;
|
|
28996
29242
|
var init_compartment_storage = __esm(() => {
|
|
@@ -29130,7 +29376,7 @@ function binarySearchBytes(sortedArray, key) {
|
|
|
29130
29376
|
}
|
|
29131
29377
|
return -1;
|
|
29132
29378
|
}
|
|
29133
|
-
function
|
|
29379
|
+
function escapeRegex3(str) {
|
|
29134
29380
|
return str.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
29135
29381
|
}
|
|
29136
29382
|
function bytePairMerge(piece, stringRanks, binaryFirstByteIndex) {
|
|
@@ -29240,7 +29486,7 @@ var Tokenizer = class {
|
|
|
29240
29486
|
};
|
|
29241
29487
|
this.specialTokenKeys = Object.keys(this.specialTokens);
|
|
29242
29488
|
this.hasSpecialTokens = this.specialTokenKeys.length > 0;
|
|
29243
|
-
this.specialTokensRegex = this.hasSpecialTokens ? new RegExp(this.specialTokenKeys.map(
|
|
29489
|
+
this.specialTokensRegex = this.hasSpecialTokens ? new RegExp(this.specialTokenKeys.map(escapeRegex3).join("|"), "g") : null;
|
|
29244
29490
|
this.inverseSpecialTokens = {};
|
|
29245
29491
|
for (const [text2, rank] of Object.entries(this.specialTokens))
|
|
29246
29492
|
this.inverseSpecialTokens[rank] = textEncoder.encode(text2);
|
|
@@ -29270,7 +29516,7 @@ var Tokenizer = class {
|
|
|
29270
29516
|
const allowedSet = new Set(allowedSpecial === "all" ? this.specialTokenKeys : allowedSpecial);
|
|
29271
29517
|
const disallowedSet = new Set(disallowedSpecial === "all" ? this.specialTokenKeys.filter((x2) => !allowedSet.has(x2)) : disallowedSpecial);
|
|
29272
29518
|
if (disallowedSet.size > 0) {
|
|
29273
|
-
const disallowedRegex = new RegExp([...disallowedSet].map(
|
|
29519
|
+
const disallowedRegex = new RegExp([...disallowedSet].map(escapeRegex3).join("|"), "g");
|
|
29274
29520
|
const match = text2.match(disallowedRegex);
|
|
29275
29521
|
if (match)
|
|
29276
29522
|
throw new Error(`Text contains disallowed special token: ${match[0]}`);
|
|
@@ -161776,6 +162022,9 @@ var init_migrations = __esm(async () => {
|
|
|
161776
162022
|
embedding BLOB NOT NULL,
|
|
161777
162023
|
model_id TEXT NOT NULL,
|
|
161778
162024
|
created_at INTEGER NOT NULL,
|
|
162025
|
+
-- FK-cascade audit (v12): git_commit_embeddings.sha -> git_commits.sha
|
|
162026
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
162027
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
161779
162028
|
FOREIGN KEY(sha) REFERENCES git_commits(sha) ON DELETE CASCADE
|
|
161780
162029
|
);
|
|
161781
162030
|
|
|
@@ -161896,10 +162145,51 @@ var init_migrations = __esm(async () => {
|
|
|
161896
162145
|
WHERE type = 'tool' AND tool_owner_message_id IS NULL;
|
|
161897
162146
|
`);
|
|
161898
162147
|
}
|
|
162148
|
+
},
|
|
162149
|
+
{
|
|
162150
|
+
version: 11,
|
|
162151
|
+
description: "Add todo state synthesis columns to session_meta",
|
|
162152
|
+
up: (db) => {
|
|
162153
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
162154
|
+
if (!cols.some((c2) => c2.name === "last_todo_state")) {
|
|
162155
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN last_todo_state TEXT DEFAULT ''");
|
|
162156
|
+
}
|
|
162157
|
+
if (!cols.some((c2) => c2.name === "todo_synthetic_call_id")) {
|
|
162158
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_call_id TEXT DEFAULT ''");
|
|
162159
|
+
}
|
|
162160
|
+
if (!cols.some((c2) => c2.name === "todo_synthetic_anchor_message_id")) {
|
|
162161
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_anchor_message_id TEXT DEFAULT ''");
|
|
162162
|
+
}
|
|
162163
|
+
if (!cols.some((c2) => c2.name === "todo_synthetic_state_json")) {
|
|
162164
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
162165
|
+
}
|
|
162166
|
+
}
|
|
162167
|
+
},
|
|
162168
|
+
{
|
|
162169
|
+
version: 12,
|
|
162170
|
+
description: "Clean orphan rows from FK-cascade embedding tables",
|
|
162171
|
+
up: (db) => {
|
|
162172
|
+
const hasTable = (name2) => Boolean(db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name = ?").get(name2));
|
|
162173
|
+
const memoryEmbeddings = hasTable("memory_embeddings") ? db.prepare(`DELETE FROM memory_embeddings
|
|
162174
|
+
WHERE memory_id NOT IN (SELECT id FROM memories)`).run().changes : 0;
|
|
162175
|
+
log2(`[migrations] v12 cleaned ${memoryEmbeddings} orphan memory_embeddings row(s)`);
|
|
162176
|
+
const gitCommitEmbeddings = hasTable("git_commit_embeddings") ? db.prepare(`DELETE FROM git_commit_embeddings
|
|
162177
|
+
WHERE sha NOT IN (SELECT sha FROM git_commits)`).run().changes : 0;
|
|
162178
|
+
log2(`[migrations] v12 cleaned ${gitCommitEmbeddings} orphan git_commit_embeddings row(s)`);
|
|
162179
|
+
}
|
|
162180
|
+
},
|
|
162181
|
+
{
|
|
162182
|
+
version: 13,
|
|
162183
|
+
description: "Add pending_compaction_marker_state column for deferred marker drain",
|
|
162184
|
+
up: (db) => {
|
|
162185
|
+
const cols = db.prepare("PRAGMA table_info(session_meta)").all();
|
|
162186
|
+
if (!cols.some((c2) => c2.name === "pending_compaction_marker_state")) {
|
|
162187
|
+
db.exec("ALTER TABLE session_meta ADD COLUMN pending_compaction_marker_state TEXT");
|
|
162188
|
+
}
|
|
162189
|
+
}
|
|
161899
162190
|
}
|
|
161900
162191
|
];
|
|
161901
162192
|
});
|
|
161902
|
-
|
|
161903
162193
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
161904
162194
|
function keyFor(providerID, modelID, agentName) {
|
|
161905
162195
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
@@ -162219,9 +162509,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
162219
162509
|
}
|
|
162220
162510
|
}
|
|
162221
162511
|
function initializeDatabase(db) {
|
|
162512
|
+
db.exec("PRAGMA foreign_keys=ON");
|
|
162222
162513
|
db.exec("PRAGMA journal_mode=WAL");
|
|
162223
162514
|
db.exec("PRAGMA busy_timeout=5000");
|
|
162224
|
-
db.exec("PRAGMA foreign_keys=ON");
|
|
162225
162515
|
db.exec(`
|
|
162226
162516
|
CREATE TABLE IF NOT EXISTS tags (
|
|
162227
162517
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -162319,6 +162609,9 @@ function initializeDatabase(db) {
|
|
|
162319
162609
|
);
|
|
162320
162610
|
|
|
162321
162611
|
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
162612
|
+
-- FK-cascade audit (v12): memory_embeddings.memory_id -> memories.id
|
|
162613
|
+
-- uses ON DELETE CASCADE, so SQLite PRAGMA foreign_keys must be ON on
|
|
162614
|
+
-- every connection and v12 cleans historical orphan rows.
|
|
162322
162615
|
memory_id INTEGER PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
162323
162616
|
embedding BLOB NOT NULL,
|
|
162324
162617
|
model_id TEXT
|
|
@@ -162411,6 +162704,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162411
162704
|
note_nudge_trigger_message_id TEXT DEFAULT '',
|
|
162412
162705
|
note_nudge_sticky_text TEXT DEFAULT '',
|
|
162413
162706
|
note_nudge_sticky_message_id TEXT DEFAULT '',
|
|
162707
|
+
last_todo_state TEXT DEFAULT '',
|
|
162708
|
+
todo_synthetic_call_id TEXT DEFAULT '',
|
|
162709
|
+
todo_synthetic_anchor_message_id TEXT DEFAULT '',
|
|
162710
|
+
todo_synthetic_state_json TEXT DEFAULT '',
|
|
162414
162711
|
is_subagent INTEGER DEFAULT 0,
|
|
162415
162712
|
last_context_percentage REAL DEFAULT 0,
|
|
162416
162713
|
last_input_tokens INTEGER DEFAULT 0,
|
|
@@ -162422,7 +162719,13 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162422
162719
|
system_prompt_hash TEXT DEFAULT '',
|
|
162423
162720
|
memory_block_cache TEXT DEFAULT '',
|
|
162424
162721
|
memory_block_count INTEGER DEFAULT 0,
|
|
162425
|
-
memory_block_ids TEXT DEFAULT ''
|
|
162722
|
+
memory_block_ids TEXT DEFAULT '',
|
|
162723
|
+
-- pending_compaction_marker_state: intentionally NULLABLE without a
|
|
162724
|
+
-- default. Absence of a deferred marker is SQL NULL; presence is a
|
|
162725
|
+
-- valid JSON blob written via setPendingCompactionMarkerState.
|
|
162726
|
+
-- Excluded from healNullTextColumns. Readers filter IS NOT NULL AND
|
|
162727
|
+
-- != empty-string defensively. Plan v6 section 3.
|
|
162728
|
+
pending_compaction_marker_state TEXT
|
|
162426
162729
|
);
|
|
162427
162730
|
|
|
162428
162731
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
@@ -162475,6 +162778,10 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162475
162778
|
ensureColumn(db, "session_meta", "note_nudge_trigger_message_id", "TEXT DEFAULT ''");
|
|
162476
162779
|
ensureColumn(db, "session_meta", "note_nudge_sticky_text", "TEXT DEFAULT ''");
|
|
162477
162780
|
ensureColumn(db, "session_meta", "note_nudge_sticky_message_id", "TEXT DEFAULT ''");
|
|
162781
|
+
ensureColumn(db, "session_meta", "last_todo_state", "TEXT DEFAULT ''");
|
|
162782
|
+
ensureColumn(db, "session_meta", "todo_synthetic_call_id", "TEXT DEFAULT ''");
|
|
162783
|
+
ensureColumn(db, "session_meta", "todo_synthetic_anchor_message_id", "TEXT DEFAULT ''");
|
|
162784
|
+
ensureColumn(db, "session_meta", "todo_synthetic_state_json", "TEXT DEFAULT ''");
|
|
162478
162785
|
ensureColumn(db, "session_meta", "note_last_read_at", "INTEGER DEFAULT 0");
|
|
162479
162786
|
ensureColumn(db, "session_meta", "times_execute_threshold_reached", "INTEGER DEFAULT 0");
|
|
162480
162787
|
ensureColumn(db, "session_meta", "compartment_in_progress", "INTEGER DEFAULT 0");
|
|
@@ -162506,6 +162813,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162506
162813
|
ensureColumn(db, "session_meta", "recomp_partial_range_end", "INTEGER DEFAULT 0");
|
|
162507
162814
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
162508
162815
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
162816
|
+
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
162509
162817
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162510
162818
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162511
162819
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -162539,6 +162847,10 @@ function healNullTextColumns(db) {
|
|
|
162539
162847
|
["note_nudge_trigger_message_id", ""],
|
|
162540
162848
|
["note_nudge_sticky_text", ""],
|
|
162541
162849
|
["note_nudge_sticky_message_id", ""],
|
|
162850
|
+
["last_todo_state", ""],
|
|
162851
|
+
["todo_synthetic_call_id", ""],
|
|
162852
|
+
["todo_synthetic_anchor_message_id", ""],
|
|
162853
|
+
["todo_synthetic_state_json", ""],
|
|
162542
162854
|
["system_prompt_hash", ""],
|
|
162543
162855
|
["stripped_placeholder_ids", ""],
|
|
162544
162856
|
["memory_block_cache", ""],
|
|
@@ -162733,15 +163045,15 @@ var init_storage = __esm(async () => {
|
|
|
162733
163045
|
});
|
|
162734
163046
|
|
|
162735
163047
|
// ../pi-plugin/src/config/index.ts
|
|
162736
|
-
import { existsSync as existsSync18, readFileSync as
|
|
162737
|
-
import { homedir as
|
|
163048
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
|
|
163049
|
+
import { homedir as homedir13 } from "node:os";
|
|
162738
163050
|
import { join as join17 } from "node:path";
|
|
162739
163051
|
function getProjectConfigPaths(cwd) {
|
|
162740
163052
|
const basePath = join17(cwd, ".pi", CONFIG_FILE_NAME);
|
|
162741
163053
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
162742
163054
|
}
|
|
162743
163055
|
function getUserConfigPaths() {
|
|
162744
|
-
const home = process.env.HOME ??
|
|
163056
|
+
const home = process.env.HOME ?? homedir13();
|
|
162745
163057
|
const basePath = join17(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
162746
163058
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
162747
163059
|
}
|
|
@@ -162750,7 +163062,7 @@ function resolveFirstExisting(paths) {
|
|
|
162750
163062
|
}
|
|
162751
163063
|
function loadConfigFile2(path4, scope) {
|
|
162752
163064
|
try {
|
|
162753
|
-
const rawText =
|
|
163065
|
+
const rawText = readFileSync13(path4, "utf-8");
|
|
162754
163066
|
const substituted = substituteConfigVariables({
|
|
162755
163067
|
text: rawText,
|
|
162756
163068
|
configPath: path4
|
|
@@ -162758,7 +163070,7 @@ function loadConfigFile2(path4, scope) {
|
|
|
162758
163070
|
return {
|
|
162759
163071
|
path: path4,
|
|
162760
163072
|
scope,
|
|
162761
|
-
config:
|
|
163073
|
+
config: import_comment_json9.parse(substituted.text),
|
|
162762
163074
|
warnings: substituted.warnings.map((warning) => `${path4}: ${warning}`)
|
|
162763
163075
|
};
|
|
162764
163076
|
} catch (error51) {
|
|
@@ -162871,18 +163183,18 @@ function loadPiConfig(opts = {}) {
|
|
|
162871
163183
|
loadedFromPaths: loadedFiles.map((loaded) => loaded.path)
|
|
162872
163184
|
};
|
|
162873
163185
|
}
|
|
162874
|
-
var
|
|
163186
|
+
var import_comment_json9, CONFIG_FILE_NAME = "magic-context";
|
|
162875
163187
|
var init_config2 = __esm(() => {
|
|
162876
163188
|
init_magic_context();
|
|
162877
163189
|
init_variable();
|
|
162878
|
-
|
|
163190
|
+
import_comment_json9 = __toESM(require_src2(), 1);
|
|
162879
163191
|
});
|
|
162880
163192
|
|
|
162881
163193
|
// src/lib/diagnostics-pi.ts
|
|
162882
163194
|
import { createHash } from "node:crypto";
|
|
162883
|
-
import { existsSync as existsSync19, readFileSync as
|
|
163195
|
+
import { existsSync as existsSync19, readdirSync as readdirSync3, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
162884
163196
|
import { createRequire as createRequire5 } from "node:module";
|
|
162885
|
-
import { homedir as
|
|
163197
|
+
import { homedir as homedir14, userInfo as userInfo2 } from "node:os";
|
|
162886
163198
|
import { join as join18 } from "node:path";
|
|
162887
163199
|
function getSelfVersion3() {
|
|
162888
163200
|
const req = createRequire5(import.meta.url);
|
|
@@ -162903,29 +163215,29 @@ function fileSize2(path4) {
|
|
|
162903
163215
|
return 0;
|
|
162904
163216
|
}
|
|
162905
163217
|
}
|
|
162906
|
-
function
|
|
163218
|
+
function escapeRegex4(value) {
|
|
162907
163219
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
162908
163220
|
}
|
|
162909
163221
|
function currentUserHash() {
|
|
162910
|
-
const username =
|
|
163222
|
+
const username = userInfo2().username || "unknown";
|
|
162911
163223
|
return createHash("sha256").update(username).digest("hex").slice(0, 12);
|
|
162912
163224
|
}
|
|
162913
163225
|
function redactSecretString(value) {
|
|
162914
163226
|
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>");
|
|
162915
163227
|
}
|
|
162916
163228
|
function sanitizeString2(value) {
|
|
162917
|
-
const home = process.env.HOME ||
|
|
162918
|
-
const username =
|
|
163229
|
+
const home = process.env.HOME || homedir14();
|
|
163230
|
+
const username = userInfo2().username;
|
|
162919
163231
|
const userHash = `<USER:${currentUserHash()}>`;
|
|
162920
163232
|
let sanitized = redactSecretString(value);
|
|
162921
163233
|
if (home) {
|
|
162922
|
-
sanitized = sanitized.replace(new RegExp(
|
|
163234
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex4(home), "g"), "<HOME>");
|
|
162923
163235
|
}
|
|
162924
163236
|
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, `/Users/${userHash}/`);
|
|
162925
163237
|
sanitized = sanitized.replace(/\/home\/[^/]+\//g, `/home/${userHash}/`);
|
|
162926
163238
|
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, `C:\\Users\\${userHash}\\`);
|
|
162927
163239
|
if (username) {
|
|
162928
|
-
sanitized = sanitized.replace(new RegExp(
|
|
163240
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex4(username), "g"), userHash);
|
|
162929
163241
|
}
|
|
162930
163242
|
return sanitized;
|
|
162931
163243
|
}
|
|
@@ -162952,7 +163264,7 @@ function readJsonc3(path4) {
|
|
|
162952
163264
|
return { value: {} };
|
|
162953
163265
|
try {
|
|
162954
163266
|
return {
|
|
162955
|
-
value:
|
|
163267
|
+
value: import_comment_json10.parse(readFileSync14(path4, "utf-8"))
|
|
162956
163268
|
};
|
|
162957
163269
|
} catch (error51) {
|
|
162958
163270
|
return {
|
|
@@ -162974,10 +163286,153 @@ function readConfigDiagnostic(path4) {
|
|
|
162974
163286
|
};
|
|
162975
163287
|
}
|
|
162976
163288
|
function packageEntries(settings) {
|
|
162977
|
-
return Array.isArray(settings.packages) ? settings.packages
|
|
163289
|
+
return Array.isArray(settings.packages) ? settings.packages : [];
|
|
163290
|
+
}
|
|
163291
|
+
function reverseSlugToDirectory(slug) {
|
|
163292
|
+
if (!slug.startsWith("--") || !slug.endsWith("--"))
|
|
163293
|
+
return null;
|
|
163294
|
+
const inner = slug.slice(2, -2);
|
|
163295
|
+
if (!inner)
|
|
163296
|
+
return null;
|
|
163297
|
+
return `/${inner.replace(/-/g, "/")}`;
|
|
163298
|
+
}
|
|
163299
|
+
function collectPiRecentSessions() {
|
|
163300
|
+
const sessionsRoot = join18(homedir14(), ".pi", "agent", "sessions");
|
|
163301
|
+
if (!existsSync19(sessionsRoot))
|
|
163302
|
+
return [];
|
|
163303
|
+
try {
|
|
163304
|
+
const slugs = readdirSync3(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
163305
|
+
const candidates = [];
|
|
163306
|
+
for (const slug of slugs) {
|
|
163307
|
+
const directory = reverseSlugToDirectory(slug);
|
|
163308
|
+
if (!directory)
|
|
163309
|
+
continue;
|
|
163310
|
+
const slugDir = join18(sessionsRoot, slug);
|
|
163311
|
+
let files;
|
|
163312
|
+
try {
|
|
163313
|
+
files = readdirSync3(slugDir).filter((name2) => name2.endsWith(".jsonl"));
|
|
163314
|
+
} catch {
|
|
163315
|
+
continue;
|
|
163316
|
+
}
|
|
163317
|
+
for (const file2 of files) {
|
|
163318
|
+
try {
|
|
163319
|
+
const mtime = statSync4(join18(slugDir, file2)).mtimeMs;
|
|
163320
|
+
const sessionId = file2.replace(/\.jsonl$/, "");
|
|
163321
|
+
candidates.push({ sessionId, directory, mtime });
|
|
163322
|
+
} catch {}
|
|
163323
|
+
}
|
|
163324
|
+
}
|
|
163325
|
+
candidates.sort((a, b2) => b2.mtime - a.mtime);
|
|
163326
|
+
return candidates.slice(0, 5).map((entry) => ({
|
|
163327
|
+
sessionId: entry.sessionId,
|
|
163328
|
+
directory: entry.directory,
|
|
163329
|
+
lastActiveAt: new Date(entry.mtime).toISOString()
|
|
163330
|
+
}));
|
|
163331
|
+
} catch {
|
|
163332
|
+
return [];
|
|
163333
|
+
}
|
|
163334
|
+
}
|
|
163335
|
+
function parseHistorianDumpMeta2(path4) {
|
|
163336
|
+
try {
|
|
163337
|
+
const xml = readFileSync14(path4, "utf-8");
|
|
163338
|
+
const parsed = parseCompartmentOutput(xml);
|
|
163339
|
+
const factCountByCategory = {};
|
|
163340
|
+
for (const fact of parsed.facts) {
|
|
163341
|
+
factCountByCategory[fact.category] = (factCountByCategory[fact.category] ?? 0) + 1;
|
|
163342
|
+
}
|
|
163343
|
+
const starts = parsed.compartments.map((c2) => c2.startMessage);
|
|
163344
|
+
const ends = parsed.compartments.map((c2) => c2.endMessage);
|
|
163345
|
+
let gaps = 0;
|
|
163346
|
+
let overlaps = 0;
|
|
163347
|
+
for (let i = 1;i < parsed.compartments.length; i++) {
|
|
163348
|
+
const prev = parsed.compartments[i - 1];
|
|
163349
|
+
const curr = parsed.compartments[i];
|
|
163350
|
+
if (curr.startMessage > prev.endMessage + 1)
|
|
163351
|
+
gaps += 1;
|
|
163352
|
+
else if (curr.startMessage <= prev.endMessage)
|
|
163353
|
+
overlaps += 1;
|
|
163354
|
+
}
|
|
163355
|
+
return {
|
|
163356
|
+
compartmentCount: parsed.compartments.length,
|
|
163357
|
+
minStart: starts.length > 0 ? Math.min(...starts) : null,
|
|
163358
|
+
maxEnd: ends.length > 0 ? Math.max(...ends) : null,
|
|
163359
|
+
unprocessedFrom: parsed.unprocessedFrom,
|
|
163360
|
+
factCountByCategory,
|
|
163361
|
+
userObservationCount: parsed.userObservations.length,
|
|
163362
|
+
ordinalGapCount: gaps,
|
|
163363
|
+
ordinalOverlapCount: overlaps
|
|
163364
|
+
};
|
|
163365
|
+
} catch (error51) {
|
|
163366
|
+
return { error: error51 instanceof Error ? error51.message : String(error51) };
|
|
163367
|
+
}
|
|
163368
|
+
}
|
|
163369
|
+
function listDumpsInDir2(dir, limit) {
|
|
163370
|
+
if (!existsSync19(dir))
|
|
163371
|
+
return { count: 0, recent: [] };
|
|
163372
|
+
try {
|
|
163373
|
+
const entries = readdirSync3(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
|
|
163374
|
+
const stat = statSync4(join18(dir, name2));
|
|
163375
|
+
return {
|
|
163376
|
+
name: name2,
|
|
163377
|
+
mtime: stat.mtimeMs,
|
|
163378
|
+
sizeKb: Math.round(stat.size / 1024)
|
|
163379
|
+
};
|
|
163380
|
+
}).sort((a, b2) => b2.mtime - a.mtime);
|
|
163381
|
+
const now = Date.now();
|
|
163382
|
+
const recent = entries.slice(0, limit).map((entry) => {
|
|
163383
|
+
const meta3 = parseHistorianDumpMeta2(join18(dir, entry.name));
|
|
163384
|
+
const summary = {
|
|
163385
|
+
name: entry.name,
|
|
163386
|
+
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
163387
|
+
sizeKb: entry.sizeKb
|
|
163388
|
+
};
|
|
163389
|
+
if ("error" in meta3) {
|
|
163390
|
+
summary.parseError = meta3.error;
|
|
163391
|
+
} else {
|
|
163392
|
+
summary.meta = meta3;
|
|
163393
|
+
}
|
|
163394
|
+
return summary;
|
|
163395
|
+
});
|
|
163396
|
+
return { count: entries.length, recent };
|
|
163397
|
+
} catch {
|
|
163398
|
+
return { count: 0, recent: [] };
|
|
163399
|
+
}
|
|
162978
163400
|
}
|
|
162979
|
-
function
|
|
162980
|
-
|
|
163401
|
+
function collectPiHistorianDumps(recentSessions) {
|
|
163402
|
+
const buckets = new Map;
|
|
163403
|
+
for (const session of recentSessions) {
|
|
163404
|
+
const dir = session.directory;
|
|
163405
|
+
if (!dir)
|
|
163406
|
+
continue;
|
|
163407
|
+
const projectHistorianDir = getProjectMagicContextHistorianDir(dir);
|
|
163408
|
+
const listing = listDumpsInDir2(projectHistorianDir, 5);
|
|
163409
|
+
const existing = buckets.get(dir);
|
|
163410
|
+
if (existing) {
|
|
163411
|
+
if (!existing.sessionIds.includes(session.sessionId)) {
|
|
163412
|
+
existing.sessionIds.push(session.sessionId);
|
|
163413
|
+
}
|
|
163414
|
+
continue;
|
|
163415
|
+
}
|
|
163416
|
+
if (listing.count === 0)
|
|
163417
|
+
continue;
|
|
163418
|
+
buckets.set(dir, {
|
|
163419
|
+
directory: dir,
|
|
163420
|
+
primarySessionId: session.sessionId,
|
|
163421
|
+
sessionIds: [session.sessionId],
|
|
163422
|
+
count: listing.count,
|
|
163423
|
+
recent: listing.recent
|
|
163424
|
+
});
|
|
163425
|
+
}
|
|
163426
|
+
const legacyDir = getMagicContextHistorianDir2("pi");
|
|
163427
|
+
const legacyListing = listDumpsInDir2(legacyDir, 5);
|
|
163428
|
+
return {
|
|
163429
|
+
byProject: [...buckets.values()],
|
|
163430
|
+
legacyDumps: {
|
|
163431
|
+
dir: legacyDir,
|
|
163432
|
+
count: legacyListing.count,
|
|
163433
|
+
recent: legacyListing.recent
|
|
163434
|
+
}
|
|
163435
|
+
};
|
|
162981
163436
|
}
|
|
162982
163437
|
async function collectDiagnostics2(cwd = process.cwd()) {
|
|
162983
163438
|
const pi = detectPiBinary();
|
|
@@ -162989,9 +163444,11 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
162989
163444
|
const loaded = loadPiConfig({ cwd });
|
|
162990
163445
|
const storageDirPath = getMagicContextStorageDir();
|
|
162991
163446
|
const dbPath = join18(storageDirPath, "context.db");
|
|
162992
|
-
const logPath =
|
|
163447
|
+
const logPath = getMagicContextLogPath2("pi");
|
|
162993
163448
|
const logFileSize = existsSync19(logPath) ? statSync4(logPath).size : 0;
|
|
162994
|
-
const otherPiExtensions = packages.filter((entry) => !
|
|
163449
|
+
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
163450
|
+
const recentSessions = collectPiRecentSessions();
|
|
163451
|
+
const historianDumps = collectPiHistorianDumps(recentSessions);
|
|
162995
163452
|
return {
|
|
162996
163453
|
timestamp: new Date().toISOString(),
|
|
162997
163454
|
platform: process.platform,
|
|
@@ -163005,8 +163462,8 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163005
163462
|
path: settingsPath,
|
|
163006
163463
|
exists: existsSync19(settingsPath),
|
|
163007
163464
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
163008
|
-
hasMagicContextPackage:
|
|
163009
|
-
packages: packages
|
|
163465
|
+
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
163466
|
+
packages: sanitizeValue2(packages)
|
|
163010
163467
|
},
|
|
163011
163468
|
configPaths: {
|
|
163012
163469
|
agentDir: getPiAgentConfigDir(),
|
|
@@ -163030,7 +163487,9 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163030
163487
|
path: logPath,
|
|
163031
163488
|
exists: existsSync19(logPath),
|
|
163032
163489
|
sizeKb: Math.round(logFileSize / 1024)
|
|
163033
|
-
}
|
|
163490
|
+
},
|
|
163491
|
+
recentSessions,
|
|
163492
|
+
historianDumps
|
|
163034
163493
|
};
|
|
163035
163494
|
}
|
|
163036
163495
|
function formatBytes2(bytes) {
|
|
@@ -163107,17 +163566,19 @@ function renderDiagnosticsMarkdown2(report) {
|
|
|
163107
163566
|
].join(`
|
|
163108
163567
|
`);
|
|
163109
163568
|
}
|
|
163110
|
-
var
|
|
163569
|
+
var import_comment_json10;
|
|
163111
163570
|
var init_diagnostics_pi = __esm(() => {
|
|
163571
|
+
init_compartment_parser();
|
|
163112
163572
|
init_data_path();
|
|
163113
163573
|
init_config2();
|
|
163114
163574
|
init_paths();
|
|
163115
163575
|
init_pi_helpers();
|
|
163116
|
-
|
|
163576
|
+
init_pi_package_entry();
|
|
163577
|
+
import_comment_json10 = __toESM(require_src2(), 1);
|
|
163117
163578
|
});
|
|
163118
163579
|
|
|
163119
163580
|
// src/lib/logs-pi.ts
|
|
163120
|
-
import { readFileSync as
|
|
163581
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
|
|
163121
163582
|
import { join as join19 } from "node:path";
|
|
163122
163583
|
function sanitizeLogContent2(content) {
|
|
163123
163584
|
return sanitizeString2(content);
|
|
@@ -163134,9 +163595,21 @@ function formatTimestamp2(date5) {
|
|
|
163134
163595
|
pad(date5.getSeconds())
|
|
163135
163596
|
].join("");
|
|
163136
163597
|
}
|
|
163598
|
+
function filterLogLinesBySession2(lines, sessionId) {
|
|
163599
|
+
if (!sessionId)
|
|
163600
|
+
return lines;
|
|
163601
|
+
const otherSessionPattern = /\bses_[A-Za-z0-9]{8,32}\b/g;
|
|
163602
|
+
return lines.filter((line) => {
|
|
163603
|
+
const matches = line.match(otherSessionPattern);
|
|
163604
|
+
if (!matches)
|
|
163605
|
+
return true;
|
|
163606
|
+
return matches.every((id) => id === sessionId);
|
|
163607
|
+
});
|
|
163608
|
+
}
|
|
163137
163609
|
async function bundleIssueReport2(report, description, title, options = {}) {
|
|
163138
163610
|
const LOG_TAIL_LINES = 400;
|
|
163139
|
-
const
|
|
163611
|
+
const allLogLines = report.logFile.exists ? readFileSync15(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
163612
|
+
const logLines = filterLogLinesBySession2(allLogLines, options.sessionFilter ?? null);
|
|
163140
163613
|
const recentLog = sanitizeLogContent2(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
163141
163614
|
`)).trim();
|
|
163142
163615
|
const bodyMarkdown = [
|
|
@@ -163172,18 +163645,18 @@ var init_logs_pi = __esm(() => {
|
|
|
163172
163645
|
});
|
|
163173
163646
|
|
|
163174
163647
|
// src/commands/doctor-pi.ts
|
|
163175
|
-
import { execFileSync as
|
|
163648
|
+
import { execFileSync as execFileSync4, spawnSync as spawnSync3 } from "node:child_process";
|
|
163176
163649
|
import {
|
|
163177
163650
|
existsSync as existsSync20,
|
|
163178
163651
|
mkdirSync as mkdirSync8,
|
|
163179
163652
|
readdirSync as readdirSync4,
|
|
163180
|
-
readFileSync as
|
|
163653
|
+
readFileSync as readFileSync16,
|
|
163181
163654
|
rmSync as rmSync2,
|
|
163182
163655
|
statSync as statSync5,
|
|
163183
163656
|
writeFileSync as writeFileSync12
|
|
163184
163657
|
} from "node:fs";
|
|
163185
163658
|
import { createRequire as createRequire6 } from "node:module";
|
|
163186
|
-
import { homedir as
|
|
163659
|
+
import { homedir as homedir15 } from "node:os";
|
|
163187
163660
|
import { dirname as dirname9, join as join20 } from "node:path";
|
|
163188
163661
|
function depsFrom(options) {
|
|
163189
163662
|
return {
|
|
@@ -163217,7 +163690,7 @@ function selfVersion() {
|
|
|
163217
163690
|
}
|
|
163218
163691
|
function getLatestNpmVersion(packageName) {
|
|
163219
163692
|
try {
|
|
163220
|
-
return
|
|
163693
|
+
return execFileSync4("npm", ["view", packageName, "version"], {
|
|
163221
163694
|
encoding: "utf-8",
|
|
163222
163695
|
stdio: ["ignore", "pipe", "ignore"],
|
|
163223
163696
|
timeout: 1e4
|
|
@@ -163271,7 +163744,7 @@ function summarize(results) {
|
|
|
163271
163744
|
function readJsonc4(path4) {
|
|
163272
163745
|
try {
|
|
163273
163746
|
return {
|
|
163274
|
-
value:
|
|
163747
|
+
value: import_comment_json11.parse(readFileSync16(path4, "utf-8"))
|
|
163275
163748
|
};
|
|
163276
163749
|
} catch (error51) {
|
|
163277
163750
|
return {
|
|
@@ -163281,10 +163754,7 @@ function readJsonc4(path4) {
|
|
|
163281
163754
|
}
|
|
163282
163755
|
}
|
|
163283
163756
|
function packagesFrom(settings) {
|
|
163284
|
-
return Array.isArray(settings.packages) ? settings.packages
|
|
163285
|
-
}
|
|
163286
|
-
function hasPiPackage(packages) {
|
|
163287
|
-
return packages.some((entry) => entry === PI_PACKAGE_SOURCE || entry === PACKAGE_NAME2 || entry.includes("pi-magic-context"));
|
|
163757
|
+
return Array.isArray(settings.packages) ? settings.packages : [];
|
|
163288
163758
|
}
|
|
163289
163759
|
function projectConfigPath(cwd) {
|
|
163290
163760
|
return join20(cwd, ".pi", "magic-context.jsonc");
|
|
@@ -163293,12 +163763,12 @@ function readConfigForEmbedding(path4) {
|
|
|
163293
163763
|
if (!existsSync20(path4))
|
|
163294
163764
|
return null;
|
|
163295
163765
|
try {
|
|
163296
|
-
const rawText =
|
|
163766
|
+
const rawText = readFileSync16(path4, "utf-8");
|
|
163297
163767
|
const substituted = substituteConfigVariables({
|
|
163298
163768
|
text: rawText,
|
|
163299
163769
|
configPath: path4
|
|
163300
163770
|
});
|
|
163301
|
-
return
|
|
163771
|
+
return import_comment_json11.parse(substituted.text);
|
|
163302
163772
|
} catch {
|
|
163303
163773
|
return null;
|
|
163304
163774
|
}
|
|
@@ -163351,7 +163821,7 @@ function countTable(db, table) {
|
|
|
163351
163821
|
}
|
|
163352
163822
|
}
|
|
163353
163823
|
function cacheRoots() {
|
|
163354
|
-
const home =
|
|
163824
|
+
const home = homedir15();
|
|
163355
163825
|
const cacheHome = process.env.XDG_CACHE_HOME || join20(home, ".cache");
|
|
163356
163826
|
return [
|
|
163357
163827
|
join20(home, ".pi", "cache", "extensions"),
|
|
@@ -163377,10 +163847,10 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
163377
163847
|
const packageJson = join20(path4, "package.json");
|
|
163378
163848
|
if (existsSync20(packageJson)) {
|
|
163379
163849
|
try {
|
|
163380
|
-
const pkg = JSON.parse(
|
|
163850
|
+
const pkg = JSON.parse(readFileSync16(packageJson, "utf-8"));
|
|
163381
163851
|
const name2 = typeof pkg.name === "string" ? pkg.name : "";
|
|
163382
163852
|
const version2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
163383
|
-
if (name2 ===
|
|
163853
|
+
if (name2 === PACKAGE_NAME || path4.includes("pi-magic-context")) {
|
|
163384
163854
|
if (force || !version2 || version2 !== self)
|
|
163385
163855
|
found.set(path4, { path: path4, version: version2 });
|
|
163386
163856
|
}
|
|
@@ -163443,7 +163913,7 @@ async function runHealthChecks(options) {
|
|
|
163443
163913
|
} else {
|
|
163444
163914
|
packages = packagesFrom(parsed.value);
|
|
163445
163915
|
add(results, "pass", `Pi settings found at ${settingsPath}`);
|
|
163446
|
-
if (
|
|
163916
|
+
if (hasPiMagicContextPackage(packages)) {
|
|
163447
163917
|
add(results, "pass", `${PI_PACKAGE_SOURCE} is registered in packages[]`);
|
|
163448
163918
|
} else {
|
|
163449
163919
|
add(results, "warn", `${PI_PACKAGE_SOURCE} is missing from packages[]`);
|
|
@@ -163548,13 +164018,13 @@ async function runHealthChecks(options) {
|
|
|
163548
164018
|
} else {
|
|
163549
164019
|
add(results, "pass", `Embedding provider: ${loadedConfig.config.embedding.provider}`);
|
|
163550
164020
|
}
|
|
163551
|
-
const piEntries = packages.filter(
|
|
164021
|
+
const piEntries = packages.filter(isPiMagicContextPackageEntry).map(describePiPackageEntry);
|
|
163552
164022
|
if (piEntries.length > 1) {
|
|
163553
164023
|
add(results, "fail", `Multiple magic-context entries in Pi packages[] — this loads the plugin twice: ${piEntries.join(", ")}`);
|
|
163554
164024
|
} else {
|
|
163555
164025
|
add(results, "pass", "No conflicting magic-context entries in Pi packages[]");
|
|
163556
164026
|
}
|
|
163557
|
-
const otherExtensions = packages.filter((entry) => !
|
|
164027
|
+
const otherExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
163558
164028
|
if (otherExtensions.length > 0) {
|
|
163559
164029
|
add(results, "info", `Other Pi extensions registered: ${otherExtensions.join(", ")}`);
|
|
163560
164030
|
} else {
|
|
@@ -163567,32 +164037,36 @@ async function runHealthChecks(options) {
|
|
|
163567
164037
|
} else {
|
|
163568
164038
|
add(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
163569
164039
|
}
|
|
163570
|
-
const logPath =
|
|
164040
|
+
const logPath = getMagicContextLogPath2("pi");
|
|
163571
164041
|
if (existsSync20(logPath)) {
|
|
163572
164042
|
const stat = statSync5(logPath);
|
|
163573
164043
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
163574
|
-
const lines =
|
|
164044
|
+
const lines = readFileSync16(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
163575
164045
|
add(results, "info", `Log file: ${logPath} (${sizeKb} KB)`);
|
|
163576
164046
|
add(results, "info", `Last plugin log line: ${lines.at(-1) ?? "<empty log>"}`);
|
|
163577
164047
|
} else {
|
|
163578
164048
|
add(results, "info", `No plugin log file yet at ${logPath}`);
|
|
163579
164049
|
}
|
|
163580
|
-
const
|
|
163581
|
-
|
|
163582
|
-
|
|
163583
|
-
|
|
163584
|
-
|
|
163585
|
-
|
|
163586
|
-
|
|
163587
|
-
|
|
163588
|
-
|
|
163589
|
-
|
|
163590
|
-
}
|
|
163591
|
-
if (dumps.length > 3) {
|
|
163592
|
-
add(results, "info", ` ... and ${dumps.length - 3} more`);
|
|
163593
|
-
}
|
|
164050
|
+
const diagnosticsForDumps = await collectDiagnostics2(options.cwd);
|
|
164051
|
+
const dumpBuckets = diagnosticsForDumps.historianDumps.byProject;
|
|
164052
|
+
if (dumpBuckets.length > 0) {
|
|
164053
|
+
const totalCount = dumpBuckets.reduce((sum, b2) => sum + b2.count, 0);
|
|
164054
|
+
add(results, "warn", `Historian debug dumps: ${totalCount} file(s) across ${dumpBuckets.length} project(s)`);
|
|
164055
|
+
for (const bucket of dumpBuckets) {
|
|
164056
|
+
add(results, "info", ` [${bucket.directory}] ${bucket.count} file(s)`);
|
|
164057
|
+
for (const dump of bucket.recent.slice(0, 3)) {
|
|
164058
|
+
const age = dump.ageMinutes;
|
|
164059
|
+
const ageStr = age < 60 ? `${age}m ago` : `${Math.round(age / 60)}h ago`;
|
|
164060
|
+
add(results, "info", ` ${dump.name} (${ageStr})`);
|
|
163594
164061
|
}
|
|
163595
|
-
|
|
164062
|
+
if (bucket.count > 3) {
|
|
164063
|
+
add(results, "info", ` ... and ${bucket.count - 3} more`);
|
|
164064
|
+
}
|
|
164065
|
+
}
|
|
164066
|
+
}
|
|
164067
|
+
const legacyDumps = diagnosticsForDumps.historianDumps.legacyDumps;
|
|
164068
|
+
if (legacyDumps.count > 0) {
|
|
164069
|
+
add(results, "info", `Legacy historian dumps (pre-v0.18.x): ${legacyDumps.count} file(s) in ${legacyDumps.dir}`);
|
|
163596
164070
|
}
|
|
163597
164071
|
if (!options.quiet) {
|
|
163598
164072
|
for (const result of results)
|
|
@@ -163606,7 +164080,7 @@ function writeDefaultMagicContextConfig(path4) {
|
|
|
163606
164080
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
163607
164081
|
...MagicContextConfigSchema.parse({})
|
|
163608
164082
|
};
|
|
163609
|
-
writeFileSync12(path4, `${
|
|
164083
|
+
writeFileSync12(path4, `${import_comment_json11.stringify(config2, null, 2)}
|
|
163610
164084
|
`);
|
|
163611
164085
|
}
|
|
163612
164086
|
function repair(plan, prompts) {
|
|
@@ -163671,9 +164145,26 @@ async function runIssueFlow2(options) {
|
|
|
163671
164145
|
spinner2.start("Collecting sanitized Pi diagnostics");
|
|
163672
164146
|
try {
|
|
163673
164147
|
const report = await options.deps.collectDiagnostics(options.cwd);
|
|
164148
|
+
spinner2.stop("Diagnostics collected");
|
|
164149
|
+
let sessionFilter = null;
|
|
164150
|
+
if (report.recentSessions.length > 1) {
|
|
164151
|
+
const choice = await options.prompts.selectOne("Which Pi session is this issue about? (filters log lines from other sessions)", [
|
|
164152
|
+
...report.recentSessions.map((session, index) => ({
|
|
164153
|
+
label: `${session.directory} — ${session.sessionId}${index === 0 ? " (most recent)" : ""}`,
|
|
164154
|
+
value: session.sessionId
|
|
164155
|
+
})),
|
|
164156
|
+
{
|
|
164157
|
+
label: "All sessions (no filtering)",
|
|
164158
|
+
value: "__all__"
|
|
164159
|
+
}
|
|
164160
|
+
]);
|
|
164161
|
+
sessionFilter = choice === "__all__" ? null : choice;
|
|
164162
|
+
}
|
|
164163
|
+
spinner2.start("Bundling Pi issue report");
|
|
163674
164164
|
const bundled = await bundleIssueReport2(report, description, title, {
|
|
163675
164165
|
cwd: options.cwd,
|
|
163676
|
-
now: options.deps.now()
|
|
164166
|
+
now: options.deps.now(),
|
|
164167
|
+
sessionFilter
|
|
163677
164168
|
});
|
|
163678
164169
|
spinner2.stop(`Report written to ${bundled.path}`);
|
|
163679
164170
|
if (ghAvailableAndAuthed(options.deps)) {
|
|
@@ -163748,7 +164239,7 @@ function parseDoctorArgs(args) {
|
|
|
163748
164239
|
function doctor(args = []) {
|
|
163749
164240
|
return runDoctor2(parseDoctorArgs(args));
|
|
163750
164241
|
}
|
|
163751
|
-
var
|
|
164242
|
+
var import_comment_json11, PACKAGE_NAME = "@cortexkit/pi-magic-context", MIN_PI_VERSION = "0.71.0", ROW_COUNT_TABLES, DEFAULT_DEPS;
|
|
163752
164243
|
var init_doctor_pi = __esm(async () => {
|
|
163753
164244
|
init_magic_context();
|
|
163754
164245
|
init_variable();
|
|
@@ -163758,23 +164249,24 @@ var init_doctor_pi = __esm(async () => {
|
|
|
163758
164249
|
init_logs_pi();
|
|
163759
164250
|
init_paths();
|
|
163760
164251
|
init_pi_helpers();
|
|
164252
|
+
init_pi_package_entry();
|
|
163761
164253
|
init_prompts();
|
|
163762
164254
|
init_setup_pi();
|
|
163763
164255
|
await init_storage();
|
|
163764
|
-
|
|
164256
|
+
import_comment_json11 = __toESM(require_src2(), 1);
|
|
163765
164257
|
ROW_COUNT_TABLES = ["tags", "compartments", "memories", "notes", "dream_runs"];
|
|
163766
164258
|
DEFAULT_DEPS = {
|
|
163767
164259
|
prompts: promptIO,
|
|
163768
164260
|
collectDiagnostics: collectDiagnostics2,
|
|
163769
164261
|
detectPiBinary,
|
|
163770
164262
|
getPiVersion,
|
|
163771
|
-
getLatestNpmVersion: () => getLatestNpmVersion(
|
|
164263
|
+
getLatestNpmVersion: () => getLatestNpmVersion(PACKAGE_NAME),
|
|
163772
164264
|
probeEmbeddingEndpoint,
|
|
163773
164265
|
openDatabase,
|
|
163774
164266
|
isDatabasePersisted,
|
|
163775
164267
|
closeDatabase,
|
|
163776
164268
|
now: () => new Date,
|
|
163777
|
-
execFileSync:
|
|
164269
|
+
execFileSync: execFileSync4,
|
|
163778
164270
|
spawnSync: spawnSync3
|
|
163779
164271
|
};
|
|
163780
164272
|
});
|