@cortexkit/magic-context 0.18.0 → 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 +996 -543
- 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");
|
|
7930
|
+
}
|
|
7931
|
+
function getMagicContextLogPath2(harness) {
|
|
7932
|
+
return getMagicContextLogPath(harness);
|
|
7886
7933
|
}
|
|
7887
|
-
function
|
|
7888
|
-
return
|
|
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,13 +7970,15 @@ 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
7978
|
import { execFileSync } from "node:child_process";
|
|
7930
7979
|
import { existsSync as existsSync2, readFileSync, writeFileSync } from "node:fs";
|
|
7931
|
-
import { homedir as
|
|
7932
|
-
import { dirname, join as
|
|
7980
|
+
import { homedir as homedir3 } from "node:os";
|
|
7981
|
+
import { dirname, join as join3 } from "node:path";
|
|
7933
7982
|
|
|
7934
7983
|
class OpenCodeAdapter {
|
|
7935
7984
|
kind = "opencode";
|
|
@@ -7937,7 +7986,7 @@ class OpenCodeAdapter {
|
|
|
7937
7986
|
pluginPackageName = PLUGIN_NAME;
|
|
7938
7987
|
isInstalled() {
|
|
7939
7988
|
const isWindows = process.platform === "win32";
|
|
7940
|
-
const stockBin = isWindows ?
|
|
7989
|
+
const stockBin = isWindows ? join3(homedir3(), ".opencode", "bin", "opencode.exe") : join3(homedir3(), ".opencode", "bin", "opencode");
|
|
7941
7990
|
if (existsSync2(stockBin))
|
|
7942
7991
|
return true;
|
|
7943
7992
|
const probe = isWindows ? { cmd: "where", args: ["opencode"] } : { cmd: "command", args: ["-v", "opencode"] };
|
|
@@ -8112,15 +8161,15 @@ class OpenCodeAdapter {
|
|
|
8112
8161
|
return "Install OpenCode: curl -fsSL https://opencode.ai/install | bash";
|
|
8113
8162
|
}
|
|
8114
8163
|
getPluginCacheInfo() {
|
|
8115
|
-
const
|
|
8164
|
+
const path2 = getOpenCodePluginCacheDir();
|
|
8116
8165
|
return {
|
|
8117
|
-
path,
|
|
8118
|
-
exists: existsSync2(
|
|
8119
|
-
sizeBytes: dirSizeBytes(
|
|
8166
|
+
path: path2,
|
|
8167
|
+
exists: existsSync2(path2),
|
|
8168
|
+
sizeBytes: dirSizeBytes(path2)
|
|
8120
8169
|
};
|
|
8121
8170
|
}
|
|
8122
8171
|
getLogPath() {
|
|
8123
|
-
return
|
|
8172
|
+
return getMagicContextLogPath2("opencode");
|
|
8124
8173
|
}
|
|
8125
8174
|
getInstalledPluginVersion() {
|
|
8126
8175
|
const cacheDir = getOpenCodePluginCacheDir();
|
|
@@ -8185,8 +8234,8 @@ var init_opencode = __esm(() => {
|
|
|
8185
8234
|
// src/lib/pi-helpers.ts
|
|
8186
8235
|
import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
|
|
8187
8236
|
import { existsSync as existsSync3 } from "node:fs";
|
|
8188
|
-
import { homedir as
|
|
8189
|
-
import { join as
|
|
8237
|
+
import { homedir as homedir4 } from "node:os";
|
|
8238
|
+
import { join as join4 } from "node:path";
|
|
8190
8239
|
function getStaticModels() {
|
|
8191
8240
|
return [...STATIC_MODELS];
|
|
8192
8241
|
}
|
|
@@ -8208,7 +8257,7 @@ function detectPiBinary() {
|
|
|
8208
8257
|
if (first)
|
|
8209
8258
|
return { path: first, source: "path" };
|
|
8210
8259
|
}
|
|
8211
|
-
const homeCandidate = process.platform === "win32" ?
|
|
8260
|
+
const homeCandidate = process.platform === "win32" ? join4(homedir4(), ".pi", "bin", "pi.cmd") : join4(homedir4(), ".pi", "bin", "pi");
|
|
8212
8261
|
if (existsSync3(homeCandidate))
|
|
8213
8262
|
return { path: homeCandidate, source: "home" };
|
|
8214
8263
|
return null;
|
|
@@ -8463,7 +8512,7 @@ class PiAdapter {
|
|
|
8463
8512
|
return { path: null, exists: false, sizeBytes: 0 };
|
|
8464
8513
|
}
|
|
8465
8514
|
getLogPath() {
|
|
8466
|
-
return
|
|
8515
|
+
return getMagicContextLogPath2("pi");
|
|
8467
8516
|
}
|
|
8468
8517
|
getInstalledPluginVersion() {
|
|
8469
8518
|
const piBin = detectPiBinary();
|
|
@@ -10327,17 +10376,17 @@ function detectConfigFile(basePath) {
|
|
|
10327
10376
|
var init_jsonc_parser = () => {};
|
|
10328
10377
|
|
|
10329
10378
|
// ../plugin/src/shared/opencode-config-dir.ts
|
|
10330
|
-
import { homedir as
|
|
10331
|
-
import { join as
|
|
10379
|
+
import { homedir as homedir5 } from "node:os";
|
|
10380
|
+
import { join as join5, resolve } from "node:path";
|
|
10332
10381
|
function getCliConfigDir() {
|
|
10333
10382
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
10334
10383
|
if (envConfigDir) {
|
|
10335
10384
|
return resolve(envConfigDir);
|
|
10336
10385
|
}
|
|
10337
10386
|
if (process.platform === "win32") {
|
|
10338
|
-
return
|
|
10387
|
+
return join5(homedir5(), ".config", "opencode");
|
|
10339
10388
|
}
|
|
10340
|
-
return
|
|
10389
|
+
return join5(process.env.XDG_CONFIG_HOME || join5(homedir5(), ".config"), "opencode");
|
|
10341
10390
|
}
|
|
10342
10391
|
function getOpenCodeConfigDir2(_options) {
|
|
10343
10392
|
return getCliConfigDir();
|
|
@@ -10346,16 +10395,16 @@ function getOpenCodeConfigPaths(options) {
|
|
|
10346
10395
|
const configDir = getOpenCodeConfigDir2(options);
|
|
10347
10396
|
return {
|
|
10348
10397
|
configDir,
|
|
10349
|
-
configJson:
|
|
10350
|
-
configJsonc:
|
|
10351
|
-
packageJson:
|
|
10352
|
-
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")
|
|
10353
10402
|
};
|
|
10354
10403
|
}
|
|
10355
10404
|
var init_opencode_config_dir = () => {};
|
|
10356
10405
|
|
|
10357
10406
|
// ../plugin/src/shared/conflict-detector.ts
|
|
10358
|
-
import { join as
|
|
10407
|
+
import { join as join6 } from "node:path";
|
|
10359
10408
|
function detectConflicts(directory) {
|
|
10360
10409
|
const conflicts = {
|
|
10361
10410
|
compactionAuto: false,
|
|
@@ -10412,8 +10461,8 @@ function checkCompaction(directory) {
|
|
|
10412
10461
|
return { auto: true, prune: false };
|
|
10413
10462
|
}
|
|
10414
10463
|
function readProjectCompaction(directory) {
|
|
10415
|
-
const dotOcJsonc =
|
|
10416
|
-
const dotOcJson =
|
|
10464
|
+
const dotOcJsonc = join6(directory, ".opencode", "opencode.jsonc");
|
|
10465
|
+
const dotOcJson = join6(directory, ".opencode", "opencode.json");
|
|
10417
10466
|
const dotOcConfig = readJsoncFile(dotOcJsonc) ?? readJsoncFile(dotOcJson);
|
|
10418
10467
|
if (dotOcConfig?.compaction) {
|
|
10419
10468
|
const c2 = dotOcConfig.compaction;
|
|
@@ -10421,8 +10470,8 @@ function readProjectCompaction(directory) {
|
|
|
10421
10470
|
return { auto: c2.auto === true, prune: c2.prune === true, resolved: true };
|
|
10422
10471
|
}
|
|
10423
10472
|
}
|
|
10424
|
-
const rootJsonc =
|
|
10425
|
-
const rootJson =
|
|
10473
|
+
const rootJsonc = join6(directory, "opencode.jsonc");
|
|
10474
|
+
const rootJson = join6(directory, "opencode.json");
|
|
10426
10475
|
const rootConfig = readJsoncFile(rootJsonc) ?? readJsoncFile(rootJson);
|
|
10427
10476
|
if (rootConfig?.compaction) {
|
|
10428
10477
|
const c2 = rootConfig.compaction;
|
|
@@ -10476,10 +10525,10 @@ function collectPluginEntries(directory) {
|
|
|
10476
10525
|
}
|
|
10477
10526
|
};
|
|
10478
10527
|
for (const configPath of [
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10528
|
+
join6(directory, ".opencode", "opencode.jsonc"),
|
|
10529
|
+
join6(directory, ".opencode", "opencode.json"),
|
|
10530
|
+
join6(directory, "opencode.jsonc"),
|
|
10531
|
+
join6(directory, "opencode.json")
|
|
10483
10532
|
]) {
|
|
10484
10533
|
const config = readJsoncFile(configPath);
|
|
10485
10534
|
pushFrom(config?.plugin);
|
|
@@ -10520,7 +10569,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
10520
10569
|
try {
|
|
10521
10570
|
const paths = getOpenCodeConfigPaths({ binary: "opencode" });
|
|
10522
10571
|
for (const name of configNames) {
|
|
10523
|
-
const configPath =
|
|
10572
|
+
const configPath = join6(paths.configDir, name);
|
|
10524
10573
|
const config = readJsoncFile(configPath);
|
|
10525
10574
|
if (config?.disabled_hooks) {
|
|
10526
10575
|
for (const hook of config.disabled_hooks) {
|
|
@@ -10530,7 +10579,7 @@ function readOmoDisabledHooks(directory) {
|
|
|
10530
10579
|
}
|
|
10531
10580
|
} catch {}
|
|
10532
10581
|
for (const name of configNames) {
|
|
10533
|
-
const config = readJsoncFile(
|
|
10582
|
+
const config = readJsoncFile(join6(directory, name));
|
|
10534
10583
|
if (config?.disabled_hooks) {
|
|
10535
10584
|
for (const hook of config.disabled_hooks) {
|
|
10536
10585
|
disabled.add(hook);
|
|
@@ -10548,11 +10597,8 @@ var init_conflict_detector = __esm(() => {
|
|
|
10548
10597
|
});
|
|
10549
10598
|
|
|
10550
10599
|
// ../plugin/src/shared/conflict-fixer.ts
|
|
10551
|
-
import { existsSync as existsSync6,
|
|
10552
|
-
import {
|
|
10553
|
-
function ensureParentDir(filePath) {
|
|
10554
|
-
mkdirSync(dirname3(filePath), { recursive: true });
|
|
10555
|
-
}
|
|
10600
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
10601
|
+
import { join as join7 } from "node:path";
|
|
10556
10602
|
function isRecord(value) {
|
|
10557
10603
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10558
10604
|
}
|
|
@@ -10561,13 +10607,17 @@ function asStringArray(value) {
|
|
|
10561
10607
|
}
|
|
10562
10608
|
function readConfig(filePath) {
|
|
10563
10609
|
if (!existsSync6(filePath)) {
|
|
10564
|
-
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;
|
|
10565
10617
|
}
|
|
10566
|
-
return readJsoncFile(filePath);
|
|
10567
10618
|
}
|
|
10568
10619
|
function writeConfig(filePath, config) {
|
|
10569
|
-
|
|
10570
|
-
writeFileSync3(filePath, `${JSON.stringify(config, null, 2)}
|
|
10620
|
+
writeFileSync3(filePath, `${import_comment_json3.stringify(config, null, 2)}
|
|
10571
10621
|
`);
|
|
10572
10622
|
}
|
|
10573
10623
|
function resolveUserOpenCodeConfigPath() {
|
|
@@ -10579,12 +10629,14 @@ function resolveUserOpenCodeConfigPath() {
|
|
|
10579
10629
|
function collectOpenCodeConfigPaths(directory) {
|
|
10580
10630
|
const paths = new Set;
|
|
10581
10631
|
const userConfig = resolveUserOpenCodeConfigPath();
|
|
10582
|
-
|
|
10632
|
+
if (existsSync6(userConfig)) {
|
|
10633
|
+
paths.add(userConfig);
|
|
10634
|
+
}
|
|
10583
10635
|
for (const filePath of [
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10636
|
+
join7(directory, ".opencode", "opencode.jsonc"),
|
|
10637
|
+
join7(directory, ".opencode", "opencode.json"),
|
|
10638
|
+
join7(directory, "opencode.jsonc"),
|
|
10639
|
+
join7(directory, "opencode.json")
|
|
10588
10640
|
]) {
|
|
10589
10641
|
if (existsSync6(filePath)) {
|
|
10590
10642
|
paths.add(filePath);
|
|
@@ -10596,8 +10648,8 @@ function collectOmoConfigPaths(directory) {
|
|
|
10596
10648
|
const paths = new Set;
|
|
10597
10649
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
10598
10650
|
for (const fileName of OMO_CONFIG_NAMES) {
|
|
10599
|
-
const userPath =
|
|
10600
|
-
const projectPath =
|
|
10651
|
+
const userPath = join7(configDir, fileName);
|
|
10652
|
+
const projectPath = join7(directory, fileName);
|
|
10601
10653
|
if (existsSync6(userPath)) {
|
|
10602
10654
|
paths.add(userPath);
|
|
10603
10655
|
}
|
|
@@ -10605,11 +10657,15 @@ function collectOmoConfigPaths(directory) {
|
|
|
10605
10657
|
paths.add(projectPath);
|
|
10606
10658
|
}
|
|
10607
10659
|
}
|
|
10608
|
-
if (paths.size === 0) {
|
|
10609
|
-
paths.add(join6(configDir, "oh-my-openagent.json"));
|
|
10610
|
-
}
|
|
10611
10660
|
return [...paths];
|
|
10612
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
|
+
}
|
|
10613
10669
|
function fixConflicts(directory, conflicts) {
|
|
10614
10670
|
const actions = [];
|
|
10615
10671
|
let updatedCompaction = false;
|
|
@@ -10623,7 +10679,7 @@ function fixConflicts(directory, conflicts) {
|
|
|
10623
10679
|
}
|
|
10624
10680
|
let changed = false;
|
|
10625
10681
|
if (conflicts.compactionAuto || conflicts.compactionPrune) {
|
|
10626
|
-
const compaction = isRecord(config.compaction) ?
|
|
10682
|
+
const compaction = isRecord(config.compaction) ? config.compaction : {};
|
|
10627
10683
|
if (compaction.auto !== false) {
|
|
10628
10684
|
compaction.auto = false;
|
|
10629
10685
|
changed = true;
|
|
@@ -10637,10 +10693,10 @@ function fixConflicts(directory, conflicts) {
|
|
|
10637
10693
|
config.compaction = compaction;
|
|
10638
10694
|
}
|
|
10639
10695
|
if (conflicts.dcpPlugin) {
|
|
10640
|
-
const plugins =
|
|
10641
|
-
const
|
|
10642
|
-
if (
|
|
10643
|
-
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;
|
|
10644
10700
|
changed = true;
|
|
10645
10701
|
removedDcpPlugin = true;
|
|
10646
10702
|
}
|
|
@@ -10695,10 +10751,11 @@ function fixConflicts(directory, conflicts) {
|
|
|
10695
10751
|
}
|
|
10696
10752
|
return actions;
|
|
10697
10753
|
}
|
|
10698
|
-
var CONFLICTING_OMO_HOOKS, OMO_CONFIG_NAMES;
|
|
10754
|
+
var import_comment_json3, CONFLICTING_OMO_HOOKS, OMO_CONFIG_NAMES;
|
|
10699
10755
|
var init_conflict_fixer = __esm(() => {
|
|
10700
|
-
|
|
10756
|
+
init_conflict_detector();
|
|
10701
10757
|
init_opencode_config_dir();
|
|
10758
|
+
import_comment_json3 = __toESM(require_src2(), 1);
|
|
10702
10759
|
CONFLICTING_OMO_HOOKS = [
|
|
10703
10760
|
"context-window-monitor",
|
|
10704
10761
|
"preemptive-compaction",
|
|
@@ -10790,30 +10847,30 @@ function buildModelSelection2(allModels, role) {
|
|
|
10790
10847
|
var init_opencode_helpers = () => {};
|
|
10791
10848
|
|
|
10792
10849
|
// src/commands/setup-opencode.ts
|
|
10793
|
-
import { existsSync as existsSync7, mkdirSync
|
|
10794
|
-
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";
|
|
10795
10852
|
function ensureDir3(dir) {
|
|
10796
10853
|
if (!existsSync7(dir)) {
|
|
10797
|
-
|
|
10854
|
+
mkdirSync(dir, { recursive: true });
|
|
10798
10855
|
}
|
|
10799
10856
|
}
|
|
10800
|
-
function readJsonc(
|
|
10801
|
-
const content =
|
|
10857
|
+
function readJsonc(path2) {
|
|
10858
|
+
const content = readFileSync5(path2, "utf-8");
|
|
10802
10859
|
try {
|
|
10803
|
-
return
|
|
10860
|
+
return import_comment_json4.parse(content);
|
|
10804
10861
|
} catch (err) {
|
|
10805
|
-
console.error(` ⚠ Failed to parse ${
|
|
10862
|
+
console.error(` ⚠ Failed to parse ${path2}: ${err instanceof Error ? err.message : err}`);
|
|
10806
10863
|
return null;
|
|
10807
10864
|
}
|
|
10808
10865
|
}
|
|
10809
10866
|
function addPluginToOpenCodeConfig(configPath, format) {
|
|
10810
|
-
ensureDir3(
|
|
10867
|
+
ensureDir3(dirname3(configPath));
|
|
10811
10868
|
if (format === "none") {
|
|
10812
10869
|
const config = {
|
|
10813
10870
|
plugin: [PLUGIN_ENTRY2],
|
|
10814
10871
|
compaction: { auto: false, prune: false }
|
|
10815
10872
|
};
|
|
10816
|
-
writeFileSync4(configPath, `${
|
|
10873
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(config, null, 2)}
|
|
10817
10874
|
`);
|
|
10818
10875
|
return;
|
|
10819
10876
|
}
|
|
@@ -10833,13 +10890,13 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
10833
10890
|
compaction.auto = false;
|
|
10834
10891
|
compaction.prune = false;
|
|
10835
10892
|
existing.compaction = compaction;
|
|
10836
|
-
writeFileSync4(configPath, `${
|
|
10893
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(existing, null, 2)}
|
|
10837
10894
|
`);
|
|
10838
10895
|
}
|
|
10839
10896
|
function addPluginToTuiConfig(configPath, format) {
|
|
10840
|
-
ensureDir3(
|
|
10897
|
+
ensureDir3(dirname3(configPath));
|
|
10841
10898
|
if (format === "none") {
|
|
10842
|
-
writeFileSync4(configPath, `${
|
|
10899
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify({ plugin: [PLUGIN_ENTRY2] }, null, 2)}
|
|
10843
10900
|
`);
|
|
10844
10901
|
return;
|
|
10845
10902
|
}
|
|
@@ -10855,9 +10912,42 @@ function addPluginToTuiConfig(configPath, format) {
|
|
|
10855
10912
|
rawPlugins.push(PLUGIN_ENTRY2);
|
|
10856
10913
|
}
|
|
10857
10914
|
existing.plugin = rawPlugins;
|
|
10858
|
-
writeFileSync4(configPath, `${
|
|
10915
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(existing, null, 2)}
|
|
10859
10916
|
`);
|
|
10860
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
|
+
}
|
|
10861
10951
|
function writeMagicContextConfig(configPath, options) {
|
|
10862
10952
|
const config = (existsSync7(configPath) ? readJsonc(configPath) : null) ?? {};
|
|
10863
10953
|
if (!config.$schema) {
|
|
@@ -10896,7 +10986,7 @@ function writeMagicContextConfig(configPath, options) {
|
|
|
10896
10986
|
cacheTtl["anthropic/claude-opus-4-6"] = "59m";
|
|
10897
10987
|
config.cache_ttl = cacheTtl;
|
|
10898
10988
|
}
|
|
10899
|
-
writeFileSync4(configPath, `${
|
|
10989
|
+
writeFileSync4(configPath, `${import_comment_json4.stringify(config, null, 2)}
|
|
10900
10990
|
`);
|
|
10901
10991
|
}
|
|
10902
10992
|
async function runSetup() {
|
|
@@ -10926,32 +11016,11 @@ async function runSetup() {
|
|
|
10926
11016
|
}
|
|
10927
11017
|
const paths = detectConfigPaths();
|
|
10928
11018
|
const hadExistingSetup = paths.opencodeConfigFormat !== "none" || existsSync7(paths.magicContextConfig) || paths.tuiConfigFormat !== "none";
|
|
11019
|
+
await resolveDcpConflictBeforeSetup(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
10929
11020
|
addPluginToOpenCodeConfig(paths.opencodeConfig, paths.opencodeConfigFormat);
|
|
10930
11021
|
log.success(`Plugin added to ${paths.opencodeConfig}`);
|
|
10931
11022
|
log.info("Disabled built-in compaction (auto=false, prune=false)");
|
|
10932
11023
|
log.message("Magic Context handles context management — built-in compaction would interfere");
|
|
10933
|
-
if (paths.opencodeConfigFormat !== "none") {
|
|
10934
|
-
const ocConfig = readJsonc(paths.opencodeConfig);
|
|
10935
|
-
if (ocConfig) {
|
|
10936
|
-
const plugins = ocConfig.plugin ?? [];
|
|
10937
|
-
const dcpIndex = plugins.findIndex((p2) => p2.startsWith("@tarquinen/opencode-dcp"));
|
|
10938
|
-
if (dcpIndex !== -1) {
|
|
10939
|
-
log.warn(`Found conflicting plugin: ${plugins[dcpIndex]}`);
|
|
10940
|
-
log.message(`opencode-dcp (Dynamic Context Pruning) and Magic Context both manage context.
|
|
10941
|
-
` + "Running both simultaneously will cause unpredictable behavior.");
|
|
10942
|
-
const shouldRemove = await confirm("Remove opencode-dcp from your config?", true);
|
|
10943
|
-
if (shouldRemove) {
|
|
10944
|
-
plugins.splice(dcpIndex, 1);
|
|
10945
|
-
ocConfig.plugin = plugins;
|
|
10946
|
-
writeFileSync4(paths.opencodeConfig, `${import_comment_json3.stringify(ocConfig, null, 2)}
|
|
10947
|
-
`);
|
|
10948
|
-
log.success("Removed opencode-dcp from plugin list");
|
|
10949
|
-
} else {
|
|
10950
|
-
log.warn("Skipped — you may experience context management conflicts");
|
|
10951
|
-
}
|
|
10952
|
-
}
|
|
10953
|
-
}
|
|
10954
|
-
}
|
|
10955
11024
|
if (hadExistingSetup) {
|
|
10956
11025
|
const conflicts = detectConflicts(process.cwd());
|
|
10957
11026
|
if (conflicts.hasConflict) {
|
|
@@ -11084,7 +11153,7 @@ async function runSetup() {
|
|
|
11084
11153
|
outro("Run 'opencode' to start!");
|
|
11085
11154
|
return 0;
|
|
11086
11155
|
}
|
|
11087
|
-
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";
|
|
11088
11157
|
var init_setup_opencode = __esm(() => {
|
|
11089
11158
|
init_conflict_detector();
|
|
11090
11159
|
init_conflict_fixer();
|
|
@@ -11092,26 +11161,77 @@ var init_setup_opencode = __esm(() => {
|
|
|
11092
11161
|
init_opencode_helpers();
|
|
11093
11162
|
init_paths();
|
|
11094
11163
|
init_prompts();
|
|
11095
|
-
|
|
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();
|
|
11096
11216
|
});
|
|
11097
11217
|
|
|
11098
11218
|
// src/commands/setup-pi.ts
|
|
11099
|
-
import { existsSync as existsSync8, mkdirSync as
|
|
11100
|
-
import { dirname as
|
|
11101
|
-
function ensureDir4(
|
|
11102
|
-
if (!existsSync8(
|
|
11103
|
-
|
|
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 });
|
|
11104
11224
|
}
|
|
11105
11225
|
async function getDefaultPrompts() {
|
|
11106
11226
|
const { promptIO: promptIO2 } = await Promise.resolve().then(() => (init_prompts(), exports_prompts));
|
|
11107
11227
|
return promptIO2;
|
|
11108
11228
|
}
|
|
11109
|
-
function readJsonc2(
|
|
11229
|
+
function readJsonc2(path2) {
|
|
11110
11230
|
try {
|
|
11111
|
-
return
|
|
11231
|
+
return import_comment_json5.parse(readFileSync6(path2, "utf-8"));
|
|
11112
11232
|
} catch (error) {
|
|
11113
11233
|
const message = error instanceof Error ? error.message : String(error);
|
|
11114
|
-
console.warn(`Could not parse ${
|
|
11234
|
+
console.warn(`Could not parse ${path2}: ${message}`);
|
|
11115
11235
|
return null;
|
|
11116
11236
|
}
|
|
11117
11237
|
}
|
|
@@ -11123,12 +11243,12 @@ function compactObject(obj) {
|
|
|
11123
11243
|
return obj;
|
|
11124
11244
|
}
|
|
11125
11245
|
function comparePiVersion(a, b2) {
|
|
11126
|
-
const
|
|
11246
|
+
const parse2 = (v2) => {
|
|
11127
11247
|
const match = v2.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
11128
11248
|
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
11129
11249
|
};
|
|
11130
|
-
const left =
|
|
11131
|
-
const right =
|
|
11250
|
+
const left = parse2(a);
|
|
11251
|
+
const right = parse2(b2);
|
|
11132
11252
|
if (!left || !right)
|
|
11133
11253
|
return 0;
|
|
11134
11254
|
for (let i = 0;i < 3; i += 1) {
|
|
@@ -11140,19 +11260,19 @@ function comparePiVersion(a, b2) {
|
|
|
11140
11260
|
return 0;
|
|
11141
11261
|
}
|
|
11142
11262
|
function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE) {
|
|
11143
|
-
ensureDir4(
|
|
11263
|
+
ensureDir4(dirname4(settingsPath));
|
|
11144
11264
|
const settings = existsSync8(settingsPath) ? readJsonc2(settingsPath) ?? {} : {};
|
|
11145
|
-
const packages = Array.isArray(settings.packages) ? settings.packages
|
|
11146
|
-
const hasPackage = packages
|
|
11265
|
+
const packages = Array.isArray(settings.packages) ? settings.packages : [];
|
|
11266
|
+
const hasPackage = hasPiMagicContextPackage(packages);
|
|
11147
11267
|
if (!hasPackage)
|
|
11148
11268
|
packages.push(packageSource);
|
|
11149
11269
|
settings.packages = packages;
|
|
11150
|
-
writeFileSync5(settingsPath, `${
|
|
11270
|
+
writeFileSync5(settingsPath, `${import_comment_json5.stringify(settings, null, 2)}
|
|
11151
11271
|
`);
|
|
11152
11272
|
return !hasPackage;
|
|
11153
11273
|
}
|
|
11154
11274
|
function writeMagicContextConfig2(configPath, options) {
|
|
11155
|
-
ensureDir4(
|
|
11275
|
+
ensureDir4(dirname4(configPath));
|
|
11156
11276
|
const config = existsSync8(configPath) ? readJsonc2(configPath) ?? {} : {};
|
|
11157
11277
|
if (!config.$schema) {
|
|
11158
11278
|
config.$schema = "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json";
|
|
@@ -11180,7 +11300,7 @@ function writeMagicContextConfig2(configPath, options) {
|
|
|
11180
11300
|
};
|
|
11181
11301
|
}
|
|
11182
11302
|
config.embedding = options.embedding;
|
|
11183
|
-
writeFileSync5(configPath, `${
|
|
11303
|
+
writeFileSync5(configPath, `${import_comment_json5.stringify(config, null, 2)}
|
|
11184
11304
|
`);
|
|
11185
11305
|
}
|
|
11186
11306
|
async function chooseModel(prompts, allModels, role, message) {
|
|
@@ -11306,11 +11426,12 @@ Run \`pi update\` (or \`npm install -g @mariozechner/pi-coding-agent@latest\`) b
|
|
|
11306
11426
|
prompts.outro("Start a Pi session and try /ctx-aug");
|
|
11307
11427
|
return 0;
|
|
11308
11428
|
}
|
|
11309
|
-
var
|
|
11429
|
+
var import_comment_json5, DEFAULT_ENV;
|
|
11310
11430
|
var init_setup_pi = __esm(() => {
|
|
11311
11431
|
init_paths();
|
|
11312
11432
|
init_pi_helpers();
|
|
11313
|
-
|
|
11433
|
+
init_pi_package_entry();
|
|
11434
|
+
import_comment_json5 = __toESM(require_src2(), 1);
|
|
11314
11435
|
DEFAULT_ENV = {
|
|
11315
11436
|
detectPiBinary,
|
|
11316
11437
|
getPiVersion,
|
|
@@ -11390,29 +11511,6 @@ var init_setup = __esm(() => {
|
|
|
11390
11511
|
init_setup_pi();
|
|
11391
11512
|
});
|
|
11392
11513
|
|
|
11393
|
-
// ../plugin/src/shared/data-path.ts
|
|
11394
|
-
import * as os from "node:os";
|
|
11395
|
-
import * as path from "node:path";
|
|
11396
|
-
function getDataDir() {
|
|
11397
|
-
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
11398
|
-
}
|
|
11399
|
-
function getOpenCodeStorageDir() {
|
|
11400
|
-
return path.join(getDataDir(), "opencode", "storage");
|
|
11401
|
-
}
|
|
11402
|
-
function getMagicContextStorageDir() {
|
|
11403
|
-
return path.join(getDataDir(), "cortexkit", "magic-context");
|
|
11404
|
-
}
|
|
11405
|
-
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
11406
|
-
return path.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
11407
|
-
}
|
|
11408
|
-
function getCacheDir() {
|
|
11409
|
-
return process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), ".cache");
|
|
11410
|
-
}
|
|
11411
|
-
function getOpenCodeCacheDir() {
|
|
11412
|
-
return path.join(getCacheDir(), "opencode");
|
|
11413
|
-
}
|
|
11414
|
-
var init_data_path = () => {};
|
|
11415
|
-
|
|
11416
11514
|
// ../../node_modules/.bun/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
|
|
11417
11515
|
function parseTar(data, opts) {
|
|
11418
11516
|
const buffer = data.buffer || data;
|
|
@@ -11591,8 +11689,16 @@ var init_dist5 = __esm(() => {
|
|
|
11591
11689
|
|
|
11592
11690
|
// ../plugin/src/shared/logger.ts
|
|
11593
11691
|
import * as fs from "node:fs";
|
|
11594
|
-
import * as os2 from "node:os";
|
|
11595
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
|
+
}
|
|
11596
11702
|
function flush() {
|
|
11597
11703
|
if (flushTimer) {
|
|
11598
11704
|
clearTimeout(flushTimer);
|
|
@@ -11603,6 +11709,8 @@ function flush() {
|
|
|
11603
11709
|
const data = buffer.join("");
|
|
11604
11710
|
buffer = [];
|
|
11605
11711
|
try {
|
|
11712
|
+
const logFile = getMagicContextLogPath();
|
|
11713
|
+
ensureDir5(logFile);
|
|
11606
11714
|
fs.appendFileSync(logFile, data);
|
|
11607
11715
|
} catch {}
|
|
11608
11716
|
}
|
|
@@ -11630,9 +11738,9 @@ ${data.stack}` : ""}` : ` ${JSON.stringify(data)}`;
|
|
|
11630
11738
|
}
|
|
11631
11739
|
} catch {}
|
|
11632
11740
|
}
|
|
11633
|
-
var
|
|
11741
|
+
var isTestEnv = false, buffer, flushTimer = null, FLUSH_INTERVAL_MS = 500, BUFFER_SIZE_LIMIT = 50, lastEnsuredDir = null;
|
|
11634
11742
|
var init_logger = __esm(() => {
|
|
11635
|
-
|
|
11743
|
+
init_data_path();
|
|
11636
11744
|
buffer = [];
|
|
11637
11745
|
if (!isTestEnv) {
|
|
11638
11746
|
process.on("exit", flush);
|
|
@@ -11808,15 +11916,15 @@ __export(exports_migrate, {
|
|
|
11808
11916
|
import { randomBytes } from "node:crypto";
|
|
11809
11917
|
import { existsSync as existsSync10, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
11810
11918
|
import { homedir as homedir6 } from "node:os";
|
|
11811
|
-
import { join as
|
|
11919
|
+
import { join as join9 } from "node:path";
|
|
11812
11920
|
function defaultOpenCodeDbPath() {
|
|
11813
|
-
return
|
|
11921
|
+
return join9(homedir6(), ".local", "share", "opencode", "opencode.db");
|
|
11814
11922
|
}
|
|
11815
11923
|
function defaultCortexkitDbPath() {
|
|
11816
|
-
return
|
|
11924
|
+
return join9(getMagicContextStorageDir(), "context.db");
|
|
11817
11925
|
}
|
|
11818
11926
|
function defaultPiSessionsRoot() {
|
|
11819
|
-
return
|
|
11927
|
+
return join9(homedir6(), ".pi", "agent", "sessions");
|
|
11820
11928
|
}
|
|
11821
11929
|
function defaultFs() {
|
|
11822
11930
|
return { existsSync: existsSync10, mkdirSync: mkdirSync5, writeFileSync: writeFileSync7 };
|
|
@@ -12242,7 +12350,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
12242
12350
|
const provider = opts.provider ?? model.provider;
|
|
12243
12351
|
const modelId = opts.modelId ?? model.modelId;
|
|
12244
12352
|
const cwd = session.directory ?? session.path ?? process.cwd();
|
|
12245
|
-
const outputDir =
|
|
12353
|
+
const outputDir = join9(piSessionsRoot, projectPathToPiDirSlug(cwd));
|
|
12246
12354
|
const buildResult = buildPiEntries({
|
|
12247
12355
|
session,
|
|
12248
12356
|
messages,
|
|
@@ -12268,7 +12376,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
12268
12376
|
});
|
|
12269
12377
|
}
|
|
12270
12378
|
const compactionMarker = insertCompactionMarker(buildResult.entries, copyResult.lastCompartmentEndPiEntryId);
|
|
12271
|
-
const outputPath =
|
|
12379
|
+
const outputPath = join9(outputDir, `${formatPiFilenameTimestamp(now)}_${buildResult.piSessionId}.jsonl`);
|
|
12272
12380
|
const jsonl = `${buildResult.entries.map((entry) => JSON.stringify(entry)).join(`
|
|
12273
12381
|
`)}
|
|
12274
12382
|
`;
|
|
@@ -13326,7 +13434,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
13326
13434
|
throw e2;
|
|
13327
13435
|
}
|
|
13328
13436
|
return result.value;
|
|
13329
|
-
},
|
|
13437
|
+
}, parse2, _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
13330
13438
|
const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
|
|
13331
13439
|
let result = schema._zod.run({ value, issues: [] }, ctx);
|
|
13332
13440
|
if (result instanceof Promise)
|
|
@@ -13381,7 +13489,7 @@ var init_parse = __esm(() => {
|
|
|
13381
13489
|
init_core();
|
|
13382
13490
|
init_errors();
|
|
13383
13491
|
init_util();
|
|
13384
|
-
|
|
13492
|
+
parse2 = /* @__PURE__ */ _parse($ZodRealError);
|
|
13385
13493
|
parseAsync = /* @__PURE__ */ _parseAsync($ZodRealError);
|
|
13386
13494
|
safeParse = /* @__PURE__ */ _safeParse($ZodRealError);
|
|
13387
13495
|
safeParseAsync = /* @__PURE__ */ _safeParseAsync($ZodRealError);
|
|
@@ -16140,10 +16248,10 @@ var init_schemas = __esm(() => {
|
|
|
16140
16248
|
throw new Error("implement() must be called with a function");
|
|
16141
16249
|
}
|
|
16142
16250
|
return function(...args) {
|
|
16143
|
-
const parsedArgs = inst._def.input ?
|
|
16251
|
+
const parsedArgs = inst._def.input ? parse2(inst._def.input, args) : args;
|
|
16144
16252
|
const result = Reflect.apply(func, this, parsedArgs);
|
|
16145
16253
|
if (inst._def.output) {
|
|
16146
|
-
return
|
|
16254
|
+
return parse2(inst._def.output, result);
|
|
16147
16255
|
}
|
|
16148
16256
|
return result;
|
|
16149
16257
|
};
|
|
@@ -23628,7 +23736,7 @@ function finalize(ctx, schema) {
|
|
|
23628
23736
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
23629
23737
|
} else if (ctx.target === "draft-04") {
|
|
23630
23738
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
23631
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
23739
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
23632
23740
|
if (ctx.external?.uri) {
|
|
23633
23741
|
const id = ctx.external.registry.get(schema)?.id;
|
|
23634
23742
|
if (!id)
|
|
@@ -23889,7 +23997,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
23889
23997
|
if (val === undefined) {
|
|
23890
23998
|
if (ctx.unrepresentable === "throw") {
|
|
23891
23999
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
23892
|
-
}
|
|
24000
|
+
}
|
|
23893
24001
|
} else if (typeof val === "bigint") {
|
|
23894
24002
|
if (ctx.unrepresentable === "throw") {
|
|
23895
24003
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -24336,7 +24444,7 @@ __export(exports_core2, {
|
|
|
24336
24444
|
process: () => process2,
|
|
24337
24445
|
prettifyError: () => prettifyError,
|
|
24338
24446
|
parseAsync: () => parseAsync,
|
|
24339
|
-
parse: () =>
|
|
24447
|
+
parse: () => parse2,
|
|
24340
24448
|
meta: () => meta,
|
|
24341
24449
|
locales: () => exports_locales,
|
|
24342
24450
|
isValidJWT: () => isValidJWT,
|
|
@@ -24737,11 +24845,11 @@ var init_errors2 = __esm(() => {
|
|
|
24737
24845
|
});
|
|
24738
24846
|
|
|
24739
24847
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/parse.js
|
|
24740
|
-
var
|
|
24848
|
+
var parse4, parseAsync2, safeParse2, safeParseAsync2, encode2, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2;
|
|
24741
24849
|
var init_parse2 = __esm(() => {
|
|
24742
24850
|
init_core2();
|
|
24743
24851
|
init_errors2();
|
|
24744
|
-
|
|
24852
|
+
parse4 = /* @__PURE__ */ _parse(ZodRealError);
|
|
24745
24853
|
parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
24746
24854
|
safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
24747
24855
|
safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -25461,7 +25569,7 @@ var init_schemas2 = __esm(() => {
|
|
|
25461
25569
|
inst.def = def;
|
|
25462
25570
|
inst.type = def.type;
|
|
25463
25571
|
Object.defineProperty(inst, "_def", { value: def });
|
|
25464
|
-
inst.parse = (data, params) =>
|
|
25572
|
+
inst.parse = (data, params) => parse4(inst, data, params, { callee: inst.parse });
|
|
25465
25573
|
inst.safeParse = (data, params) => safeParse2(inst, data, params);
|
|
25466
25574
|
inst.parseAsync = async (data, params) => parseAsync2(inst, data, params, { callee: inst.parseAsync });
|
|
25467
25575
|
inst.safeParseAsync = async (data, params) => safeParseAsync2(inst, data, params);
|
|
@@ -26813,7 +26921,7 @@ __export(exports_external, {
|
|
|
26813
26921
|
pipe: () => pipe,
|
|
26814
26922
|
partialRecord: () => partialRecord,
|
|
26815
26923
|
parseAsync: () => parseAsync2,
|
|
26816
|
-
parse: () =>
|
|
26924
|
+
parse: () => parse4,
|
|
26817
26925
|
overwrite: () => _overwrite,
|
|
26818
26926
|
optional: () => optional,
|
|
26819
26927
|
object: () => object,
|
|
@@ -27236,7 +27344,7 @@ var init_magic_context = __esm(() => {
|
|
|
27236
27344
|
});
|
|
27237
27345
|
|
|
27238
27346
|
// ../plugin/src/config/variable.ts
|
|
27239
|
-
import { existsSync as existsSync11, readFileSync as
|
|
27347
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7 } from "node:fs";
|
|
27240
27348
|
import { homedir as homedir7 } from "node:os";
|
|
27241
27349
|
import { dirname as dirname7, isAbsolute, resolve as resolve2 } from "node:path";
|
|
27242
27350
|
function substituteConfigVariables(input) {
|
|
@@ -27283,7 +27391,7 @@ function substituteConfigVariables(input) {
|
|
|
27283
27391
|
}
|
|
27284
27392
|
let contents;
|
|
27285
27393
|
try {
|
|
27286
|
-
contents =
|
|
27394
|
+
contents = readFileSync7(filePath, "utf-8").trim();
|
|
27287
27395
|
} catch (error51) {
|
|
27288
27396
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
27289
27397
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -27301,22 +27409,22 @@ var init_variable = __esm(() => {
|
|
|
27301
27409
|
});
|
|
27302
27410
|
|
|
27303
27411
|
// ../plugin/src/config/index.ts
|
|
27304
|
-
import { existsSync as existsSync12, readFileSync as
|
|
27412
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8 } from "node:fs";
|
|
27305
27413
|
import { homedir as homedir8 } from "node:os";
|
|
27306
|
-
import { join as
|
|
27414
|
+
import { join as join10 } from "node:path";
|
|
27307
27415
|
function getUserConfigBasePath() {
|
|
27308
|
-
const configRoot = process.env.XDG_CONFIG_HOME ??
|
|
27309
|
-
return
|
|
27416
|
+
const configRoot = process.env.XDG_CONFIG_HOME ?? join10(homedir8(), ".config");
|
|
27417
|
+
return join10(configRoot, "opencode", CONFIG_FILE_BASENAME);
|
|
27310
27418
|
}
|
|
27311
27419
|
function getProjectConfigBasePath(directory) {
|
|
27312
|
-
return
|
|
27420
|
+
return join10(directory, ".opencode", CONFIG_FILE_BASENAME);
|
|
27313
27421
|
}
|
|
27314
27422
|
function loadConfigFile(configPath) {
|
|
27315
27423
|
try {
|
|
27316
27424
|
if (!existsSync12(configPath)) {
|
|
27317
27425
|
return null;
|
|
27318
27426
|
}
|
|
27319
|
-
const rawText =
|
|
27427
|
+
const rawText = readFileSync8(configPath, "utf-8");
|
|
27320
27428
|
const substituted = substituteConfigVariables({ text: rawText, configPath });
|
|
27321
27429
|
return {
|
|
27322
27430
|
config: parseJsonc3(substituted.text),
|
|
@@ -27327,34 +27435,20 @@ function loadConfigFile(configPath) {
|
|
|
27327
27435
|
return null;
|
|
27328
27436
|
}
|
|
27329
27437
|
}
|
|
27330
|
-
function
|
|
27331
|
-
const
|
|
27332
|
-
|
|
27333
|
-
|
|
27334
|
-
|
|
27335
|
-
|
|
27336
|
-
|
|
27337
|
-
|
|
27338
|
-
|
|
27339
|
-
|
|
27340
|
-
|
|
27341
|
-
dreamer: override.dreamer ? {
|
|
27342
|
-
...base.dreamer ?? {},
|
|
27343
|
-
...override.dreamer
|
|
27344
|
-
} : base.dreamer,
|
|
27345
|
-
sidekick: override.sidekick ? {
|
|
27346
|
-
...base.sidekick ?? {},
|
|
27347
|
-
...override.sidekick
|
|
27348
|
-
} : base.sidekick,
|
|
27349
|
-
disabled_hooks: [
|
|
27350
|
-
...new Set([...base.disabled_hooks ?? [], ...override.disabled_hooks ?? []])
|
|
27351
|
-
],
|
|
27352
|
-
command: {
|
|
27353
|
-
...base.command ?? {},
|
|
27354
|
-
...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;
|
|
27355
27449
|
}
|
|
27356
|
-
}
|
|
27357
|
-
return
|
|
27450
|
+
}
|
|
27451
|
+
return result;
|
|
27358
27452
|
}
|
|
27359
27453
|
function getProjectUserOnlyFields(config2) {
|
|
27360
27454
|
return "auto_update" in config2 ? ["auto_update"] : [];
|
|
@@ -27490,35 +27584,43 @@ function parsePluginConfig(rawConfig) {
|
|
|
27490
27584
|
}
|
|
27491
27585
|
function loadPluginConfig(directory) {
|
|
27492
27586
|
const userDetected = detectConfigFile(getUserConfigBasePath());
|
|
27493
|
-
const rootDetected = detectConfigFile(
|
|
27587
|
+
const rootDetected = detectConfigFile(join10(directory, CONFIG_FILE_BASENAME));
|
|
27494
27588
|
const dotOpenCodeDetected = detectConfigFile(getProjectConfigBasePath(directory));
|
|
27495
27589
|
const projectDetected = rootDetected.format !== "none" ? rootDetected : dotOpenCodeDetected;
|
|
27496
27590
|
const userLoaded = userDetected.format === "none" ? null : loadConfigFile(userDetected.path);
|
|
27497
27591
|
const projectLoaded = projectDetected.format === "none" ? null : loadConfigFile(projectDetected.path);
|
|
27498
|
-
let config2 = parsePluginConfig({});
|
|
27499
27592
|
const allWarnings = [];
|
|
27593
|
+
let mergedRaw = {};
|
|
27500
27594
|
if (userLoaded) {
|
|
27501
27595
|
allWarnings.push(...userLoaded.warnings.map((w3) => `[user config] ${w3}`));
|
|
27502
|
-
|
|
27503
|
-
if (parsed.configWarnings?.length) {
|
|
27504
|
-
allWarnings.push(...parsed.configWarnings.map((w3) => `[user config] ${w3}`));
|
|
27505
|
-
}
|
|
27506
|
-
config2 = mergeConfigs(config2, parsed, { allowUserOnlyFields: true });
|
|
27596
|
+
mergedRaw = deepMergeRawConfig(mergedRaw, userLoaded.config);
|
|
27507
27597
|
}
|
|
27508
27598
|
if (projectLoaded) {
|
|
27509
27599
|
allWarnings.push(...projectLoaded.warnings.map((w3) => `[project config] ${w3}`));
|
|
27510
|
-
const
|
|
27511
|
-
|
|
27512
|
-
allWarnings.push(...parsed.configWarnings.map((w3) => `[project config] ${w3}`));
|
|
27513
|
-
}
|
|
27514
|
-
const strippedUserOnlyFields = getProjectUserOnlyFields(projectLoaded.config);
|
|
27600
|
+
const projectRaw = { ...projectLoaded.config };
|
|
27601
|
+
const strippedUserOnlyFields = getProjectUserOnlyFields(projectRaw);
|
|
27515
27602
|
if (strippedUserOnlyFields.length > 0) {
|
|
27603
|
+
for (const key of strippedUserOnlyFields) {
|
|
27604
|
+
delete projectRaw[key];
|
|
27605
|
+
}
|
|
27516
27606
|
allWarnings.push(`[project config] Ignoring ${strippedUserOnlyFields.join(", ")} from project config (security: these settings only honor user-level config)`);
|
|
27517
27607
|
}
|
|
27518
|
-
|
|
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
|
+
}));
|
|
27519
27619
|
}
|
|
27520
27620
|
if (allWarnings.length > 0) {
|
|
27521
27621
|
config2.configWarnings = allWarnings;
|
|
27622
|
+
} else if ("configWarnings" in config2) {
|
|
27623
|
+
config2.configWarnings = undefined;
|
|
27522
27624
|
}
|
|
27523
27625
|
return config2;
|
|
27524
27626
|
}
|
|
@@ -27634,8 +27736,8 @@ function truncate(text2) {
|
|
|
27634
27736
|
var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
|
|
27635
27737
|
|
|
27636
27738
|
// ../plugin/src/shared/tui-config.ts
|
|
27637
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as
|
|
27638
|
-
import { dirname as dirname8, join as
|
|
27739
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "node:fs";
|
|
27740
|
+
import { dirname as dirname8, join as join11 } from "node:path";
|
|
27639
27741
|
function isMagicContextEntry(entry) {
|
|
27640
27742
|
if (!entry)
|
|
27641
27743
|
return false;
|
|
@@ -27649,8 +27751,8 @@ function isMagicContextEntry(entry) {
|
|
|
27649
27751
|
}
|
|
27650
27752
|
function resolveTuiConfigPath() {
|
|
27651
27753
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
27652
|
-
const jsoncPath =
|
|
27653
|
-
const jsonPath =
|
|
27754
|
+
const jsoncPath = join11(configDir, "tui.jsonc");
|
|
27755
|
+
const jsonPath = join11(configDir, "tui.json");
|
|
27654
27756
|
if (existsSync13(jsoncPath))
|
|
27655
27757
|
return jsoncPath;
|
|
27656
27758
|
if (existsSync13(jsonPath))
|
|
@@ -27662,8 +27764,8 @@ function ensureTuiPluginEntry() {
|
|
|
27662
27764
|
const configPath = resolveTuiConfigPath();
|
|
27663
27765
|
let config2 = {};
|
|
27664
27766
|
if (existsSync13(configPath)) {
|
|
27665
|
-
const raw =
|
|
27666
|
-
config2 =
|
|
27767
|
+
const raw = readFileSync9(configPath, "utf-8");
|
|
27768
|
+
config2 = import_comment_json6.parse(raw) ?? {};
|
|
27667
27769
|
}
|
|
27668
27770
|
const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((p2) => typeof p2 === "string") : [];
|
|
27669
27771
|
const existingIdx = plugins.findIndex(isMagicContextEntry);
|
|
@@ -27682,7 +27784,7 @@ function ensureTuiPluginEntry() {
|
|
|
27682
27784
|
}
|
|
27683
27785
|
config2.plugin = plugins;
|
|
27684
27786
|
mkdirSync6(dirname8(configPath), { recursive: true });
|
|
27685
|
-
writeFileSync8(configPath, `${
|
|
27787
|
+
writeFileSync8(configPath, `${import_comment_json6.stringify(config2, null, 2)}
|
|
27686
27788
|
`);
|
|
27687
27789
|
log2(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
27688
27790
|
return true;
|
|
@@ -27691,11 +27793,11 @@ function ensureTuiPluginEntry() {
|
|
|
27691
27793
|
return false;
|
|
27692
27794
|
}
|
|
27693
27795
|
}
|
|
27694
|
-
var
|
|
27796
|
+
var import_comment_json6, PLUGIN_NAME4 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY3;
|
|
27695
27797
|
var init_tui_config = __esm(() => {
|
|
27696
27798
|
init_logger();
|
|
27697
27799
|
init_opencode_config_dir();
|
|
27698
|
-
|
|
27800
|
+
import_comment_json6 = __toESM(require_src2(), 1);
|
|
27699
27801
|
PLUGIN_ENTRY3 = `${PLUGIN_NAME4}@latest`;
|
|
27700
27802
|
});
|
|
27701
27803
|
|
|
@@ -27749,11 +27851,126 @@ var init_compartment_parser = __esm(() => {
|
|
|
27749
27851
|
USER_OBS_ITEM_REGEX = /^\s*\*\s*(.+)$/gm;
|
|
27750
27852
|
});
|
|
27751
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
|
+
|
|
27752
27969
|
// src/lib/diagnostics-opencode.ts
|
|
27753
|
-
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";
|
|
27754
27971
|
import { createRequire as createRequire3 } from "node:module";
|
|
27755
|
-
import { homedir as
|
|
27756
|
-
import { join as
|
|
27972
|
+
import { homedir as homedir10 } from "node:os";
|
|
27973
|
+
import { join as join12 } from "node:path";
|
|
27757
27974
|
function getSelfVersion() {
|
|
27758
27975
|
const require2 = createRequire3(import.meta.url);
|
|
27759
27976
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -27767,12 +27984,12 @@ function getSelfVersion() {
|
|
|
27767
27984
|
return "unknown";
|
|
27768
27985
|
}
|
|
27769
27986
|
function getPluginCacheInfo() {
|
|
27770
|
-
const path4 =
|
|
27987
|
+
const path4 = join12(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY_WITH_VERSION);
|
|
27771
27988
|
let cached2;
|
|
27772
27989
|
try {
|
|
27773
|
-
const installedPkgPath =
|
|
27990
|
+
const installedPkgPath = join12(path4, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
27774
27991
|
if (existsSync14(installedPkgPath)) {
|
|
27775
|
-
const pkg = JSON.parse(
|
|
27992
|
+
const pkg = JSON.parse(readFileSync10(installedPkgPath, "utf-8"));
|
|
27776
27993
|
cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
27777
27994
|
}
|
|
27778
27995
|
} catch {
|
|
@@ -27781,8 +27998,8 @@ function getPluginCacheInfo() {
|
|
|
27781
27998
|
return { path: path4, cached: cached2, latest: getSelfVersion() };
|
|
27782
27999
|
}
|
|
27783
28000
|
function getStorageDir() {
|
|
27784
|
-
const dataHome = process.env.XDG_DATA_HOME ||
|
|
27785
|
-
return
|
|
28001
|
+
const dataHome = process.env.XDG_DATA_HOME || join12(homedir10(), ".local", "share");
|
|
28002
|
+
return join12(dataHome, "cortexkit", "magic-context");
|
|
27786
28003
|
}
|
|
27787
28004
|
function fileSize(path4) {
|
|
27788
28005
|
try {
|
|
@@ -27791,40 +28008,18 @@ function fileSize(path4) {
|
|
|
27791
28008
|
return 0;
|
|
27792
28009
|
}
|
|
27793
28010
|
}
|
|
27794
|
-
function escapeRegex2(value) {
|
|
27795
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27796
|
-
}
|
|
27797
28011
|
function sanitizeString(value) {
|
|
27798
|
-
|
|
27799
|
-
const username = userInfo().username;
|
|
27800
|
-
let sanitized = value;
|
|
27801
|
-
if (home) {
|
|
27802
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex2(home), "g"), "~");
|
|
27803
|
-
}
|
|
27804
|
-
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
27805
|
-
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
27806
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
27807
|
-
if (username) {
|
|
27808
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex2(username), "g"), "<USER>");
|
|
27809
|
-
}
|
|
27810
|
-
return sanitized;
|
|
28012
|
+
return sanitizePathString(value);
|
|
27811
28013
|
}
|
|
27812
28014
|
function sanitizeValue(value) {
|
|
27813
|
-
|
|
27814
|
-
return sanitizeString(value);
|
|
27815
|
-
if (Array.isArray(value))
|
|
27816
|
-
return value.map(sanitizeValue);
|
|
27817
|
-
if (value && typeof value === "object") {
|
|
27818
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
|
|
27819
|
-
}
|
|
27820
|
-
return value;
|
|
28015
|
+
return sanitizeConfigValue(value);
|
|
27821
28016
|
}
|
|
27822
28017
|
function readConfig2(path4) {
|
|
27823
28018
|
if (!existsSync14(path4))
|
|
27824
28019
|
return { value: null };
|
|
27825
28020
|
try {
|
|
27826
|
-
const raw =
|
|
27827
|
-
const value =
|
|
28021
|
+
const raw = readFileSync10(path4, "utf-8");
|
|
28022
|
+
const value = import_comment_json7.parse(raw);
|
|
27828
28023
|
return { value };
|
|
27829
28024
|
} catch (error51) {
|
|
27830
28025
|
return { value: null, error: error51 instanceof Error ? error51.message : String(error51) };
|
|
@@ -27846,7 +28041,7 @@ function configHasPluginEntry(config2) {
|
|
|
27846
28041
|
}
|
|
27847
28042
|
function parseHistorianDumpMeta(path4) {
|
|
27848
28043
|
try {
|
|
27849
|
-
const xml =
|
|
28044
|
+
const xml = readFileSync10(path4, "utf-8");
|
|
27850
28045
|
const parsed = parseCompartmentOutput(xml);
|
|
27851
28046
|
const factCountByCategory = {};
|
|
27852
28047
|
for (const fact of parsed.facts) {
|
|
@@ -27878,14 +28073,12 @@ function parseHistorianDumpMeta(path4) {
|
|
|
27878
28073
|
return { error: error51 instanceof Error ? error51.message : String(error51) };
|
|
27879
28074
|
}
|
|
27880
28075
|
}
|
|
27881
|
-
function
|
|
27882
|
-
|
|
27883
|
-
|
|
27884
|
-
return { dir, count: 0, recent: [] };
|
|
27885
|
-
}
|
|
28076
|
+
function listDumpsInDir(dir, limit) {
|
|
28077
|
+
if (!existsSync14(dir))
|
|
28078
|
+
return { count: 0, recent: [] };
|
|
27886
28079
|
try {
|
|
27887
28080
|
const entries = readdirSync2(dir).filter((name) => name.endsWith(".xml")).map((name) => {
|
|
27888
|
-
const stat = statSync2(
|
|
28081
|
+
const stat = statSync2(join12(dir, name));
|
|
27889
28082
|
return {
|
|
27890
28083
|
name,
|
|
27891
28084
|
mtime: stat.mtimeMs,
|
|
@@ -27893,8 +28086,8 @@ function collectHistorianDumps() {
|
|
|
27893
28086
|
};
|
|
27894
28087
|
}).sort((a, b2) => b2.mtime - a.mtime);
|
|
27895
28088
|
const now = Date.now();
|
|
27896
|
-
const recent = entries.slice(0,
|
|
27897
|
-
const meta3 = parseHistorianDumpMeta(
|
|
28089
|
+
const recent = entries.slice(0, limit).map((entry) => {
|
|
28090
|
+
const meta3 = parseHistorianDumpMeta(join12(dir, entry.name));
|
|
27898
28091
|
const summary = {
|
|
27899
28092
|
name: entry.name,
|
|
27900
28093
|
ageMinutes: Math.round((now - entry.mtime) / 60000),
|
|
@@ -27907,13 +28100,84 @@ function collectHistorianDumps() {
|
|
|
27907
28100
|
}
|
|
27908
28101
|
return summary;
|
|
27909
28102
|
});
|
|
27910
|
-
return {
|
|
28103
|
+
return { count: entries.length, recent };
|
|
27911
28104
|
} catch {
|
|
27912
|
-
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 {}
|
|
27913
28177
|
}
|
|
27914
28178
|
}
|
|
27915
28179
|
async function collectHistorianFailures(storageDirPath) {
|
|
27916
|
-
const contextDbPath =
|
|
28180
|
+
const contextDbPath = join12(storageDirPath, "context.db");
|
|
27917
28181
|
if (!existsSync14(contextDbPath))
|
|
27918
28182
|
return [];
|
|
27919
28183
|
if (typeof globalThis.Bun === "undefined") {
|
|
@@ -27935,7 +28199,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
27935
28199
|
const failureCount = typeof row.historian_failure_count === "number" ? row.historian_failure_count : 0;
|
|
27936
28200
|
const rawError = typeof row.historian_last_error === "string" ? row.historian_last_error : "";
|
|
27937
28201
|
const lastAt = typeof row.historian_last_failure_at === "number" ? new Date(row.historian_last_failure_at).toISOString() : "";
|
|
27938
|
-
const lastError =
|
|
28202
|
+
const lastError = sanitizeDiagnosticText(rawError.replace(/\s+/g, " ").trim().slice(0, 400));
|
|
27939
28203
|
return { sessionId, failureCount, lastError, lastFailureAt: lastAt };
|
|
27940
28204
|
});
|
|
27941
28205
|
} catch {
|
|
@@ -27953,10 +28217,11 @@ async function collectDiagnostics() {
|
|
|
27953
28217
|
const tuiConfig = readConfig2(configPaths.tuiConfig);
|
|
27954
28218
|
const magicContextConfig = readConfig2(configPaths.magicContextConfig);
|
|
27955
28219
|
const storageDirPath = getStorageDir();
|
|
27956
|
-
const contextDbPath =
|
|
27957
|
-
const logPath =
|
|
28220
|
+
const contextDbPath = join12(storageDirPath, "context.db");
|
|
28221
|
+
const logPath = getMagicContextLogPath2("opencode");
|
|
27958
28222
|
const logFileSize = existsSync14(logPath) ? statSync2(logPath).size : 0;
|
|
27959
28223
|
const conflictResult = detectConflicts(process.cwd());
|
|
28224
|
+
const recentSessions = await collectRecentSessions();
|
|
27960
28225
|
return {
|
|
27961
28226
|
timestamp: new Date().toISOString(),
|
|
27962
28227
|
platform: process.platform,
|
|
@@ -27988,7 +28253,8 @@ async function collectDiagnostics() {
|
|
|
27988
28253
|
exists: existsSync14(logPath),
|
|
27989
28254
|
sizeKb: Math.round(logFileSize / 1024)
|
|
27990
28255
|
},
|
|
27991
|
-
|
|
28256
|
+
recentSessions,
|
|
28257
|
+
historianDumps: collectHistorianDumps(recentSessions),
|
|
27992
28258
|
historianFailures: await collectHistorianFailures(storageDirPath)
|
|
27993
28259
|
};
|
|
27994
28260
|
}
|
|
@@ -28022,10 +28288,25 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28022
28288
|
context_db_size: formatBytes(report.storageDir.contextDbSizeBytes)
|
|
28023
28289
|
};
|
|
28024
28290
|
const historianDumps = {
|
|
28025
|
-
|
|
28026
|
-
|
|
28027
|
-
|
|
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
|
+
}
|
|
28028
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
|
+
}));
|
|
28029
28310
|
return [
|
|
28030
28311
|
`- Timestamp: ${report.timestamp}`,
|
|
28031
28312
|
`- Plugin: v${report.pluginVersion}`,
|
|
@@ -28044,7 +28325,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28044
28325
|
"",
|
|
28045
28326
|
"### magic-context.jsonc flags",
|
|
28046
28327
|
"```jsonc",
|
|
28047
|
-
JSON.stringify(report.magicContextConfig.flags, null, 2),
|
|
28328
|
+
JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2),
|
|
28048
28329
|
"```",
|
|
28049
28330
|
"",
|
|
28050
28331
|
"### Plugin cache",
|
|
@@ -28056,15 +28337,24 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28056
28337
|
"```json",
|
|
28057
28338
|
JSON.stringify(storage, null, 2),
|
|
28058
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
|
+
`),
|
|
28059
28344
|
"",
|
|
28060
28345
|
"### Historian dumps",
|
|
28061
28346
|
"(Metadata only — XML content is not included in this report.)",
|
|
28347
|
+
"Dumps are stored per-project under `<project>/.opencode/magic-context/historian/`.",
|
|
28062
28348
|
"```json",
|
|
28063
28349
|
JSON.stringify(historianDumps, null, 2),
|
|
28064
28350
|
"```",
|
|
28065
28351
|
"",
|
|
28066
28352
|
"### Historian failures (session_meta)",
|
|
28067
|
-
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(`
|
|
28068
28358
|
`),
|
|
28069
28359
|
"",
|
|
28070
28360
|
"### Log file",
|
|
@@ -28074,45 +28364,24 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
28074
28364
|
].join(`
|
|
28075
28365
|
`);
|
|
28076
28366
|
}
|
|
28077
|
-
var
|
|
28367
|
+
var import_comment_json7, PLUGIN_NAME5 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION;
|
|
28078
28368
|
var init_diagnostics_opencode = __esm(() => {
|
|
28079
28369
|
init_compartment_parser();
|
|
28080
28370
|
init_conflict_detector();
|
|
28081
28371
|
init_data_path();
|
|
28082
28372
|
init_opencode_helpers();
|
|
28083
28373
|
init_paths();
|
|
28084
|
-
|
|
28374
|
+
init_redaction();
|
|
28375
|
+
import_comment_json7 = __toESM(require_src2(), 1);
|
|
28085
28376
|
PLUGIN_ENTRY_WITH_VERSION = `${PLUGIN_NAME5}@latest`;
|
|
28086
28377
|
});
|
|
28087
28378
|
|
|
28088
28379
|
// src/lib/logs-opencode.ts
|
|
28089
|
-
import { readFileSync as
|
|
28090
|
-
import { homedir as
|
|
28091
|
-
import { join as
|
|
28092
|
-
function escapeRegex3(value) {
|
|
28093
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28094
|
-
}
|
|
28380
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
28381
|
+
import { homedir as homedir11 } from "node:os";
|
|
28382
|
+
import { join as join13 } from "node:path";
|
|
28095
28383
|
function sanitizeLogContent(content) {
|
|
28096
|
-
|
|
28097
|
-
const username = userInfo2().username;
|
|
28098
|
-
let sanitized = content;
|
|
28099
|
-
if (home) {
|
|
28100
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex3(home), "g"), "~");
|
|
28101
|
-
}
|
|
28102
|
-
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, "/Users/<USER>/");
|
|
28103
|
-
sanitized = sanitized.replace(/\/home\/[^/]+\//g, "/home/<USER>/");
|
|
28104
|
-
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, "C:\\Users\\<USER>\\");
|
|
28105
|
-
if (username) {
|
|
28106
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex3(username), "g"), "<USER>");
|
|
28107
|
-
}
|
|
28108
|
-
for (const { pattern, replacement } of SECRET_PATTERNS) {
|
|
28109
|
-
if (typeof replacement === "string") {
|
|
28110
|
-
sanitized = sanitized.replace(pattern, replacement);
|
|
28111
|
-
} else {
|
|
28112
|
-
sanitized = sanitized.replace(pattern, replacement);
|
|
28113
|
-
}
|
|
28114
|
-
}
|
|
28115
|
-
return sanitized;
|
|
28384
|
+
return sanitizeDiagnosticText(content);
|
|
28116
28385
|
}
|
|
28117
28386
|
function formatTimestamp(date5) {
|
|
28118
28387
|
const pad = (value) => String(value).padStart(2, "0");
|
|
@@ -28139,16 +28408,28 @@ function extractHistorianFailureLines(sanitized, limit = 30) {
|
|
|
28139
28408
|
}
|
|
28140
28409
|
return matches.reverse();
|
|
28141
28410
|
}
|
|
28142
|
-
|
|
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) {
|
|
28143
28423
|
const LOG_TAIL_LINES = 400;
|
|
28144
|
-
const
|
|
28424
|
+
const allLogLines = report.logFile.exists ? readFileSync11(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
28425
|
+
const logLines = filterLogLinesBySession(allLogLines, sessionFilter);
|
|
28145
28426
|
const recentLog = sanitizeLogContent(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
28146
28427
|
`)).trim();
|
|
28147
28428
|
const historianScanWindow = sanitizeLogContent(logLines.slice(-4000).join(`
|
|
28148
28429
|
`));
|
|
28149
28430
|
const historianFailureLines = extractHistorianFailureLines(historianScanWindow, 30);
|
|
28150
|
-
const configBody = JSON.stringify(report.magicContextConfig.flags, null, 2);
|
|
28151
|
-
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(), "~");
|
|
28152
28433
|
const bodyMarkdown = [
|
|
28153
28434
|
"## Description",
|
|
28154
28435
|
description,
|
|
@@ -28179,81 +28460,15 @@ async function bundleIssueReport(report, description, _title) {
|
|
|
28179
28460
|
"```"
|
|
28180
28461
|
].join(`
|
|
28181
28462
|
`);
|
|
28182
|
-
const path4 =
|
|
28463
|
+
const path4 = join13(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
|
|
28183
28464
|
writeFileSync9(path4, `${bodyMarkdown}
|
|
28184
28465
|
`);
|
|
28185
28466
|
return { path: path4, bodyMarkdown };
|
|
28186
28467
|
}
|
|
28187
|
-
var
|
|
28468
|
+
var HISTORIAN_LOG_PATTERNS;
|
|
28188
28469
|
var init_logs_opencode = __esm(() => {
|
|
28189
28470
|
init_diagnostics_opencode();
|
|
28190
|
-
|
|
28191
|
-
{
|
|
28192
|
-
name: "anthropic_api_key",
|
|
28193
|
-
pattern: /\bsk-ant-(?:api03-)?[A-Za-z0-9_-]{32,}/g,
|
|
28194
|
-
replacement: "<ANTHROPIC_API_KEY_REDACTED>"
|
|
28195
|
-
},
|
|
28196
|
-
{
|
|
28197
|
-
name: "openai_api_key",
|
|
28198
|
-
pattern: /\bsk-(?:proj-)?[A-Za-z0-9_-]{32,}/g,
|
|
28199
|
-
replacement: "<OPENAI_API_KEY_REDACTED>"
|
|
28200
|
-
},
|
|
28201
|
-
{
|
|
28202
|
-
name: "github_pat_fine_grained",
|
|
28203
|
-
pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g,
|
|
28204
|
-
replacement: "<GITHUB_PAT_REDACTED>"
|
|
28205
|
-
},
|
|
28206
|
-
{
|
|
28207
|
-
name: "github_token_classic",
|
|
28208
|
-
pattern: /\b(?:gh[opsu]|ghr)_[A-Za-z0-9]{30,}/g,
|
|
28209
|
-
replacement: "<GITHUB_TOKEN_REDACTED>"
|
|
28210
|
-
},
|
|
28211
|
-
{
|
|
28212
|
-
name: "huggingface_token",
|
|
28213
|
-
pattern: /\bhf_[A-Za-z0-9]{30,}/g,
|
|
28214
|
-
replacement: "<HUGGINGFACE_TOKEN_REDACTED>"
|
|
28215
|
-
},
|
|
28216
|
-
{
|
|
28217
|
-
name: "aws_access_key_id",
|
|
28218
|
-
pattern: /\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,
|
|
28219
|
-
replacement: "<AWS_ACCESS_KEY_ID_REDACTED>"
|
|
28220
|
-
},
|
|
28221
|
-
{
|
|
28222
|
-
name: "aws_secret_access_key",
|
|
28223
|
-
pattern: /\b(aws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*)([A-Za-z0-9/+=]{40})\b/gi,
|
|
28224
|
-
replacement: (_full, prefix) => `${prefix}<AWS_SECRET_REDACTED>`
|
|
28225
|
-
},
|
|
28226
|
-
{
|
|
28227
|
-
name: "slack_token",
|
|
28228
|
-
pattern: /\bxox[abprsuvc]-[A-Za-z0-9-]{10,}/g,
|
|
28229
|
-
replacement: "<SLACK_TOKEN_REDACTED>"
|
|
28230
|
-
},
|
|
28231
|
-
{
|
|
28232
|
-
name: "google_api_key",
|
|
28233
|
-
pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g,
|
|
28234
|
-
replacement: "<GOOGLE_API_KEY_REDACTED>"
|
|
28235
|
-
},
|
|
28236
|
-
{
|
|
28237
|
-
name: "secret_env_assignment",
|
|
28238
|
-
pattern: /\b([A-Z][A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|PRIVATE[_-]?KEY))\s*=\s*([^\s'"]+)/g,
|
|
28239
|
-
replacement: (_full, key) => `${key}=<REDACTED>`
|
|
28240
|
-
},
|
|
28241
|
-
{
|
|
28242
|
-
name: "secret_json_assignment",
|
|
28243
|
-
pattern: /("(?:api[_-]?key|access[_-]?token|auth[_-]?token|bearer[_-]?token|client[_-]?secret|password|private[_-]?key|secret[_-]?key)"\s*:\s*)"([^"]+)"/gi,
|
|
28244
|
-
replacement: (_full, prefix) => `${prefix}"<REDACTED>"`
|
|
28245
|
-
},
|
|
28246
|
-
{
|
|
28247
|
-
name: "bearer_token",
|
|
28248
|
-
pattern: /\b(Authorization\s*:\s*Bearer\s+)([A-Za-z0-9._~+/=-]{16,})/gi,
|
|
28249
|
-
replacement: (_full, prefix) => `${prefix}<BEARER_TOKEN_REDACTED>`
|
|
28250
|
-
},
|
|
28251
|
-
{
|
|
28252
|
-
name: "jwt_token",
|
|
28253
|
-
pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
|
|
28254
|
-
replacement: "<JWT_REDACTED>"
|
|
28255
|
-
}
|
|
28256
|
-
];
|
|
28471
|
+
init_redaction();
|
|
28257
28472
|
HISTORIAN_LOG_PATTERNS = [
|
|
28258
28473
|
/historian failure:/,
|
|
28259
28474
|
/historian failure recorded:/,
|
|
@@ -28267,10 +28482,10 @@ var init_logs_opencode = __esm(() => {
|
|
|
28267
28482
|
|
|
28268
28483
|
// src/commands/doctor-opencode.ts
|
|
28269
28484
|
import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
28270
|
-
import { existsSync as existsSync15,
|
|
28485
|
+
import { existsSync as existsSync15, readFileSync as readFileSync12, rmSync, statSync as statSync3, writeFileSync as writeFileSync10 } from "node:fs";
|
|
28271
28486
|
import { createRequire as createRequire4 } from "node:module";
|
|
28272
|
-
import { homedir as
|
|
28273
|
-
import { join as
|
|
28487
|
+
import { homedir as homedir12 } from "node:os";
|
|
28488
|
+
import { join as join14 } from "node:path";
|
|
28274
28489
|
async function fetchNpmLatest(pkg, timeoutMs = 5000) {
|
|
28275
28490
|
try {
|
|
28276
28491
|
const controller = new AbortController;
|
|
@@ -28320,15 +28535,15 @@ function compareVersions(a, b2) {
|
|
|
28320
28535
|
}
|
|
28321
28536
|
async function clearPluginCache(force = false) {
|
|
28322
28537
|
const cacheDir = getOpenCodeCacheDir();
|
|
28323
|
-
const pluginCacheDir =
|
|
28538
|
+
const pluginCacheDir = join14(cacheDir, "packages", PLUGIN_ENTRY_WITH_VERSION2);
|
|
28324
28539
|
if (!existsSync15(pluginCacheDir)) {
|
|
28325
28540
|
return { action: "not_found", path: pluginCacheDir };
|
|
28326
28541
|
}
|
|
28327
28542
|
let cachedVersion;
|
|
28328
28543
|
try {
|
|
28329
|
-
const installedPkgPath =
|
|
28544
|
+
const installedPkgPath = join14(pluginCacheDir, "node_modules", "@cortexkit", "opencode-magic-context", "package.json");
|
|
28330
28545
|
if (existsSync15(installedPkgPath)) {
|
|
28331
|
-
const pkg = JSON.parse(
|
|
28546
|
+
const pkg = JSON.parse(readFileSync12(installedPkgPath, "utf-8"));
|
|
28332
28547
|
if (typeof pkg?.version === "string") {
|
|
28333
28548
|
cachedVersion = pkg.version;
|
|
28334
28549
|
}
|
|
@@ -28403,7 +28618,27 @@ async function runIssueFlow() {
|
|
|
28403
28618
|
s.start("Collecting diagnostics");
|
|
28404
28619
|
try {
|
|
28405
28620
|
const report = await collectDiagnostics();
|
|
28406
|
-
|
|
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);
|
|
28407
28642
|
s.stop(`Report written to ${bundled.path}`);
|
|
28408
28643
|
const shouldSubmit = await confirm("Submit this issue on GitHub now?", true);
|
|
28409
28644
|
if (shouldSubmit && isGhInstalled()) {
|
|
@@ -28445,7 +28680,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
28445
28680
|
}
|
|
28446
28681
|
let rawText;
|
|
28447
28682
|
try {
|
|
28448
|
-
rawText =
|
|
28683
|
+
rawText = readFileSync12(magicContextConfigPath, "utf-8");
|
|
28449
28684
|
} catch {
|
|
28450
28685
|
log.warn("Could not read magic-context.jsonc for embedding check");
|
|
28451
28686
|
return { issues: 1 };
|
|
@@ -28456,7 +28691,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
28456
28691
|
});
|
|
28457
28692
|
let parsedConfig;
|
|
28458
28693
|
try {
|
|
28459
|
-
parsedConfig =
|
|
28694
|
+
parsedConfig = import_comment_json8.parse(substituted.text);
|
|
28460
28695
|
} catch (error51) {
|
|
28461
28696
|
log.warn(`Embedding check skipped — could not parse magic-context.jsonc: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
28462
28697
|
return { issues: 1 };
|
|
@@ -28596,12 +28831,12 @@ async function runDoctor(options = {}) {
|
|
|
28596
28831
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28597
28832
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
28598
28833
|
try {
|
|
28599
|
-
const raw =
|
|
28834
|
+
const raw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
28600
28835
|
const substituted = substituteConfigVariables({
|
|
28601
28836
|
text: raw,
|
|
28602
28837
|
configPath: paths.magicContextConfig
|
|
28603
28838
|
}).text;
|
|
28604
|
-
|
|
28839
|
+
import_comment_json8.parse(substituted);
|
|
28605
28840
|
pass("magic-context.jsonc parses as valid JSONC");
|
|
28606
28841
|
} catch (err) {
|
|
28607
28842
|
fail(`magic-context.jsonc parse failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -28623,8 +28858,8 @@ async function runDoctor(options = {}) {
|
|
|
28623
28858
|
}
|
|
28624
28859
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28625
28860
|
try {
|
|
28626
|
-
const mcRaw =
|
|
28627
|
-
const mcConfig =
|
|
28861
|
+
const mcRaw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
28862
|
+
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
28628
28863
|
let mcChanged = false;
|
|
28629
28864
|
const experimental = mcConfig.experimental;
|
|
28630
28865
|
if (experimental && "compaction_markers" in experimental) {
|
|
@@ -28699,7 +28934,7 @@ async function runDoctor(options = {}) {
|
|
|
28699
28934
|
fixed++;
|
|
28700
28935
|
}
|
|
28701
28936
|
if (mcChanged) {
|
|
28702
|
-
writeFileSync10(paths.magicContextConfig, `${
|
|
28937
|
+
writeFileSync10(paths.magicContextConfig, `${import_comment_json8.stringify(mcConfig, null, 2)}
|
|
28703
28938
|
`);
|
|
28704
28939
|
}
|
|
28705
28940
|
} catch {
|
|
@@ -28708,8 +28943,8 @@ async function runDoctor(options = {}) {
|
|
|
28708
28943
|
}
|
|
28709
28944
|
if (paths.opencodeConfigFormat !== "none") {
|
|
28710
28945
|
try {
|
|
28711
|
-
const raw =
|
|
28712
|
-
const config2 =
|
|
28946
|
+
const raw = readFileSync12(paths.opencodeConfig, "utf-8");
|
|
28947
|
+
const config2 = import_comment_json8.parse(raw);
|
|
28713
28948
|
const rawPlugins = Array.isArray(config2?.plugin) ? config2.plugin : [];
|
|
28714
28949
|
const existingIdx = rawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
28715
28950
|
const configName = paths.opencodeConfigFormat === "jsonc" ? "opencode.jsonc" : "opencode.json";
|
|
@@ -28740,7 +28975,7 @@ async function runDoctor(options = {}) {
|
|
|
28740
28975
|
rawPlugins[existingIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
28741
28976
|
}
|
|
28742
28977
|
config2.plugin = rawPlugins;
|
|
28743
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
28978
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json8.stringify(config2, null, 2)}
|
|
28744
28979
|
`);
|
|
28745
28980
|
pass(`Upgraded plugin entry in ${configName}: ${oldEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
28746
28981
|
fixed++;
|
|
@@ -28749,7 +28984,7 @@ async function runDoctor(options = {}) {
|
|
|
28749
28984
|
} else {
|
|
28750
28985
|
rawPlugins.push(PLUGIN_ENTRY_WITH_VERSION2);
|
|
28751
28986
|
config2.plugin = rawPlugins;
|
|
28752
|
-
writeFileSync10(paths.opencodeConfig, `${
|
|
28987
|
+
writeFileSync10(paths.opencodeConfig, `${import_comment_json8.stringify(config2, null, 2)}
|
|
28753
28988
|
`);
|
|
28754
28989
|
pass(`Added plugin to ${configName}`);
|
|
28755
28990
|
fixed++;
|
|
@@ -28782,8 +29017,8 @@ async function runDoctor(options = {}) {
|
|
|
28782
29017
|
fixed++;
|
|
28783
29018
|
} else if (existsSync15(paths.tuiConfig)) {
|
|
28784
29019
|
try {
|
|
28785
|
-
const tuiRaw =
|
|
28786
|
-
const tuiConfig =
|
|
29020
|
+
const tuiRaw = readFileSync12(paths.tuiConfig, "utf-8");
|
|
29021
|
+
const tuiConfig = import_comment_json8.parse(tuiRaw);
|
|
28787
29022
|
const tuiRawPlugins = Array.isArray(tuiConfig?.plugin) ? tuiConfig.plugin : [];
|
|
28788
29023
|
const tuiIdx = tuiRawPlugins.findIndex((entry) => matchesPluginEntry(entry, PLUGIN_NAME6) || isDevPathPluginEntry(entry));
|
|
28789
29024
|
const tuiEntryAsString = (entry) => {
|
|
@@ -28811,7 +29046,7 @@ async function runDoctor(options = {}) {
|
|
|
28811
29046
|
tuiRawPlugins[tuiIdx] = PLUGIN_ENTRY_WITH_VERSION2;
|
|
28812
29047
|
}
|
|
28813
29048
|
tuiConfig.plugin = tuiRawPlugins;
|
|
28814
|
-
writeFileSync10(paths.tuiConfig, `${
|
|
29049
|
+
writeFileSync10(paths.tuiConfig, `${import_comment_json8.stringify(tuiConfig, null, 2)}
|
|
28815
29050
|
`);
|
|
28816
29051
|
pass(`Upgraded TUI plugin: ${tuiEntryStr} → ${PLUGIN_ENTRY_WITH_VERSION2}`);
|
|
28817
29052
|
fixed++;
|
|
@@ -28830,8 +29065,8 @@ async function runDoctor(options = {}) {
|
|
|
28830
29065
|
}
|
|
28831
29066
|
if (existsSync15(paths.magicContextConfig)) {
|
|
28832
29067
|
try {
|
|
28833
|
-
const mcRaw =
|
|
28834
|
-
const mcConfig =
|
|
29068
|
+
const mcRaw = readFileSync12(paths.magicContextConfig, "utf-8");
|
|
29069
|
+
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
28835
29070
|
const dreamerObj = mcConfig?.dreamer;
|
|
28836
29071
|
const dreamerEnabled = dreamerObj?.enabled === true;
|
|
28837
29072
|
const userMemObj = dreamerObj?.user_memories;
|
|
@@ -28848,7 +29083,7 @@ async function runDoctor(options = {}) {
|
|
|
28848
29083
|
failCount += embeddingCheck.issues;
|
|
28849
29084
|
else
|
|
28850
29085
|
passCount++;
|
|
28851
|
-
const dbPath =
|
|
29086
|
+
const dbPath = join14(getMagicContextStorageDir(), "context.db");
|
|
28852
29087
|
if (!existsSync15(dbPath)) {
|
|
28853
29088
|
log.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
28854
29089
|
} else {
|
|
@@ -28910,10 +29145,10 @@ async function runDoctor(options = {}) {
|
|
|
28910
29145
|
}
|
|
28911
29146
|
{
|
|
28912
29147
|
const ageWarnings = [];
|
|
28913
|
-
const npmrcPath =
|
|
29148
|
+
const npmrcPath = join14(homedir12(), ".npmrc");
|
|
28914
29149
|
if (existsSync15(npmrcPath)) {
|
|
28915
29150
|
try {
|
|
28916
|
-
const npmrc =
|
|
29151
|
+
const npmrc = readFileSync12(npmrcPath, "utf-8");
|
|
28917
29152
|
for (const line of npmrc.split(`
|
|
28918
29153
|
`)) {
|
|
28919
29154
|
const trimmed = line.trim();
|
|
@@ -28936,7 +29171,7 @@ async function runDoctor(options = {}) {
|
|
|
28936
29171
|
issues++;
|
|
28937
29172
|
}
|
|
28938
29173
|
}
|
|
28939
|
-
const logPath =
|
|
29174
|
+
const logPath = getMagicContextLogPath2("opencode");
|
|
28940
29175
|
if (existsSync15(logPath)) {
|
|
28941
29176
|
const logStat = statSync3(logPath);
|
|
28942
29177
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
@@ -28944,25 +29179,27 @@ async function runDoctor(options = {}) {
|
|
|
28944
29179
|
} else {
|
|
28945
29180
|
log.info(`Log file: ${logPath} (not yet created)`);
|
|
28946
29181
|
}
|
|
28947
|
-
const
|
|
28948
|
-
|
|
28949
|
-
|
|
28950
|
-
|
|
28951
|
-
|
|
28952
|
-
|
|
28953
|
-
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
log.info(` ${dump.name} (${ageStr})`);
|
|
28960
|
-
}
|
|
28961
|
-
if (dumps.length > 3) {
|
|
28962
|
-
log.info(` ... and ${dumps.length - 3} more`);
|
|
28963
|
-
}
|
|
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})`);
|
|
28964
29194
|
}
|
|
28965
|
-
|
|
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}`);
|
|
28966
29203
|
}
|
|
28967
29204
|
if (paths.omoConfig) {
|
|
28968
29205
|
log.info(`OMO config found: ${paths.omoConfig}`);
|
|
@@ -28981,7 +29218,7 @@ async function runDoctor(options = {}) {
|
|
|
28981
29218
|
}
|
|
28982
29219
|
return 0;
|
|
28983
29220
|
}
|
|
28984
|
-
var
|
|
29221
|
+
var import_comment_json8, PLUGIN_NAME6 = "@cortexkit/opencode-magic-context", PLUGIN_ENTRY_WITH_VERSION2, CLI_PACKAGE_NAME = "@cortexkit/magic-context";
|
|
28985
29222
|
var init_doctor_opencode = __esm(async () => {
|
|
28986
29223
|
init_config();
|
|
28987
29224
|
init_variable();
|
|
@@ -28996,9 +29233,10 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
28996
29233
|
init_paths();
|
|
28997
29234
|
init_prompts();
|
|
28998
29235
|
await init_sqlite();
|
|
28999
|
-
|
|
29236
|
+
import_comment_json8 = __toESM(require_src2(), 1);
|
|
29000
29237
|
PLUGIN_ENTRY_WITH_VERSION2 = `${PLUGIN_NAME6}@latest`;
|
|
29001
29238
|
});
|
|
29239
|
+
|
|
29002
29240
|
// ../plugin/src/features/magic-context/compartment-storage.ts
|
|
29003
29241
|
var insertCompartmentStatements, insertFactStatements;
|
|
29004
29242
|
var init_compartment_storage = __esm(() => {
|
|
@@ -29138,7 +29376,7 @@ function binarySearchBytes(sortedArray, key) {
|
|
|
29138
29376
|
}
|
|
29139
29377
|
return -1;
|
|
29140
29378
|
}
|
|
29141
|
-
function
|
|
29379
|
+
function escapeRegex3(str) {
|
|
29142
29380
|
return str.replace(/[\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
29143
29381
|
}
|
|
29144
29382
|
function bytePairMerge(piece, stringRanks, binaryFirstByteIndex) {
|
|
@@ -29248,7 +29486,7 @@ var Tokenizer = class {
|
|
|
29248
29486
|
};
|
|
29249
29487
|
this.specialTokenKeys = Object.keys(this.specialTokens);
|
|
29250
29488
|
this.hasSpecialTokens = this.specialTokenKeys.length > 0;
|
|
29251
|
-
this.specialTokensRegex = this.hasSpecialTokens ? new RegExp(this.specialTokenKeys.map(
|
|
29489
|
+
this.specialTokensRegex = this.hasSpecialTokens ? new RegExp(this.specialTokenKeys.map(escapeRegex3).join("|"), "g") : null;
|
|
29252
29490
|
this.inverseSpecialTokens = {};
|
|
29253
29491
|
for (const [text2, rank] of Object.entries(this.specialTokens))
|
|
29254
29492
|
this.inverseSpecialTokens[rank] = textEncoder.encode(text2);
|
|
@@ -29278,7 +29516,7 @@ var Tokenizer = class {
|
|
|
29278
29516
|
const allowedSet = new Set(allowedSpecial === "all" ? this.specialTokenKeys : allowedSpecial);
|
|
29279
29517
|
const disallowedSet = new Set(disallowedSpecial === "all" ? this.specialTokenKeys.filter((x2) => !allowedSet.has(x2)) : disallowedSpecial);
|
|
29280
29518
|
if (disallowedSet.size > 0) {
|
|
29281
|
-
const disallowedRegex = new RegExp([...disallowedSet].map(
|
|
29519
|
+
const disallowedRegex = new RegExp([...disallowedSet].map(escapeRegex3).join("|"), "g");
|
|
29282
29520
|
const match = text2.match(disallowedRegex);
|
|
29283
29521
|
if (match)
|
|
29284
29522
|
throw new Error(`Text contains disallowed special token: ${match[0]}`);
|
|
@@ -161784,6 +162022,9 @@ var init_migrations = __esm(async () => {
|
|
|
161784
162022
|
embedding BLOB NOT NULL,
|
|
161785
162023
|
model_id TEXT NOT NULL,
|
|
161786
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.
|
|
161787
162028
|
FOREIGN KEY(sha) REFERENCES git_commits(sha) ON DELETE CASCADE
|
|
161788
162029
|
);
|
|
161789
162030
|
|
|
@@ -161923,10 +162164,32 @@ var init_migrations = __esm(async () => {
|
|
|
161923
162164
|
db.exec("ALTER TABLE session_meta ADD COLUMN todo_synthetic_state_json TEXT DEFAULT ''");
|
|
161924
162165
|
}
|
|
161925
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
|
+
}
|
|
161926
162190
|
}
|
|
161927
162191
|
];
|
|
161928
162192
|
});
|
|
161929
|
-
|
|
161930
162193
|
// ../plugin/src/features/magic-context/tool-definition-tokens.ts
|
|
161931
162194
|
function keyFor(providerID, modelID, agentName) {
|
|
161932
162195
|
const agent = agentName && agentName.length > 0 ? agentName : "default";
|
|
@@ -161962,9 +162225,9 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
161962
162225
|
|
|
161963
162226
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
161964
162227
|
import { existsSync as existsSync16 } from "node:fs";
|
|
161965
|
-
import { join as
|
|
162228
|
+
import { join as join15 } from "node:path";
|
|
161966
162229
|
function resolveOpencodeDbPath() {
|
|
161967
|
-
return
|
|
162230
|
+
return join15(getDataDir(), "opencode", "opencode.db");
|
|
161968
162231
|
}
|
|
161969
162232
|
function ensureBackfillStateTable(db) {
|
|
161970
162233
|
db.exec(`
|
|
@@ -162210,23 +162473,23 @@ var init_tool_owner_backfill = __esm(() => {
|
|
|
162210
162473
|
|
|
162211
162474
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
162212
162475
|
import { copyFileSync, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync7 } from "node:fs";
|
|
162213
|
-
import { join as
|
|
162476
|
+
import { join as join16 } from "node:path";
|
|
162214
162477
|
function resolveDatabasePath() {
|
|
162215
162478
|
const dbDir = getMagicContextStorageDir();
|
|
162216
|
-
return { dbDir, dbPath:
|
|
162479
|
+
return { dbDir, dbPath: join16(dbDir, "context.db") };
|
|
162217
162480
|
}
|
|
162218
162481
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
162219
162482
|
if (existsSync17(targetDbPath))
|
|
162220
162483
|
return;
|
|
162221
162484
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
162222
|
-
const legacyDbPath =
|
|
162485
|
+
const legacyDbPath = join16(legacyDir, "context.db");
|
|
162223
162486
|
if (!existsSync17(legacyDbPath))
|
|
162224
162487
|
return;
|
|
162225
162488
|
log2(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
162226
162489
|
mkdirSync7(targetDbDir, { recursive: true });
|
|
162227
162490
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
162228
162491
|
const src = `${legacyDbPath}${suffix}`;
|
|
162229
|
-
const dst =
|
|
162492
|
+
const dst = join16(targetDbDir, `context.db${suffix}`);
|
|
162230
162493
|
if (existsSync17(src)) {
|
|
162231
162494
|
try {
|
|
162232
162495
|
copyFileSync(src, dst);
|
|
@@ -162235,8 +162498,8 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
162235
162498
|
}
|
|
162236
162499
|
}
|
|
162237
162500
|
}
|
|
162238
|
-
const legacyModelsDir =
|
|
162239
|
-
const targetModelsDir =
|
|
162501
|
+
const legacyModelsDir = join16(legacyDir, "models");
|
|
162502
|
+
const targetModelsDir = join16(targetDbDir, "models");
|
|
162240
162503
|
if (existsSync17(legacyModelsDir) && !existsSync17(targetModelsDir)) {
|
|
162241
162504
|
try {
|
|
162242
162505
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
@@ -162246,9 +162509,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
162246
162509
|
}
|
|
162247
162510
|
}
|
|
162248
162511
|
function initializeDatabase(db) {
|
|
162512
|
+
db.exec("PRAGMA foreign_keys=ON");
|
|
162249
162513
|
db.exec("PRAGMA journal_mode=WAL");
|
|
162250
162514
|
db.exec("PRAGMA busy_timeout=5000");
|
|
162251
|
-
db.exec("PRAGMA foreign_keys=ON");
|
|
162252
162515
|
db.exec(`
|
|
162253
162516
|
CREATE TABLE IF NOT EXISTS tags (
|
|
162254
162517
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -162346,6 +162609,9 @@ function initializeDatabase(db) {
|
|
|
162346
162609
|
);
|
|
162347
162610
|
|
|
162348
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.
|
|
162349
162615
|
memory_id INTEGER PRIMARY KEY REFERENCES memories(id) ON DELETE CASCADE,
|
|
162350
162616
|
embedding BLOB NOT NULL,
|
|
162351
162617
|
model_id TEXT
|
|
@@ -162453,7 +162719,13 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162453
162719
|
system_prompt_hash TEXT DEFAULT '',
|
|
162454
162720
|
memory_block_cache TEXT DEFAULT '',
|
|
162455
162721
|
memory_block_count INTEGER DEFAULT 0,
|
|
162456
|
-
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
|
|
162457
162729
|
);
|
|
162458
162730
|
|
|
162459
162731
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
@@ -162541,6 +162813,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
162541
162813
|
ensureColumn(db, "session_meta", "recomp_partial_range_end", "INTEGER DEFAULT 0");
|
|
162542
162814
|
ensureColumn(db, "session_meta", "detected_context_limit", "INTEGER DEFAULT 0");
|
|
162543
162815
|
ensureColumn(db, "session_meta", "needs_emergency_recovery", "INTEGER DEFAULT 0");
|
|
162816
|
+
ensureColumn(db, "session_meta", "pending_compaction_marker_state", "TEXT");
|
|
162544
162817
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162545
162818
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
162546
162819
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -162772,16 +163045,16 @@ var init_storage = __esm(async () => {
|
|
|
162772
163045
|
});
|
|
162773
163046
|
|
|
162774
163047
|
// ../pi-plugin/src/config/index.ts
|
|
162775
|
-
import { existsSync as existsSync18, readFileSync as
|
|
162776
|
-
import { homedir as
|
|
162777
|
-
import { join as
|
|
163048
|
+
import { existsSync as existsSync18, readFileSync as readFileSync13 } from "node:fs";
|
|
163049
|
+
import { homedir as homedir13 } from "node:os";
|
|
163050
|
+
import { join as join17 } from "node:path";
|
|
162778
163051
|
function getProjectConfigPaths(cwd) {
|
|
162779
|
-
const basePath =
|
|
163052
|
+
const basePath = join17(cwd, ".pi", CONFIG_FILE_NAME);
|
|
162780
163053
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
162781
163054
|
}
|
|
162782
163055
|
function getUserConfigPaths() {
|
|
162783
|
-
const home = process.env.HOME ??
|
|
162784
|
-
const basePath =
|
|
163056
|
+
const home = process.env.HOME ?? homedir13();
|
|
163057
|
+
const basePath = join17(home, ".pi", "agent", CONFIG_FILE_NAME);
|
|
162785
163058
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
162786
163059
|
}
|
|
162787
163060
|
function resolveFirstExisting(paths) {
|
|
@@ -162789,7 +163062,7 @@ function resolveFirstExisting(paths) {
|
|
|
162789
163062
|
}
|
|
162790
163063
|
function loadConfigFile2(path4, scope) {
|
|
162791
163064
|
try {
|
|
162792
|
-
const rawText =
|
|
163065
|
+
const rawText = readFileSync13(path4, "utf-8");
|
|
162793
163066
|
const substituted = substituteConfigVariables({
|
|
162794
163067
|
text: rawText,
|
|
162795
163068
|
configPath: path4
|
|
@@ -162797,7 +163070,7 @@ function loadConfigFile2(path4, scope) {
|
|
|
162797
163070
|
return {
|
|
162798
163071
|
path: path4,
|
|
162799
163072
|
scope,
|
|
162800
|
-
config:
|
|
163073
|
+
config: import_comment_json9.parse(substituted.text),
|
|
162801
163074
|
warnings: substituted.warnings.map((warning) => `${path4}: ${warning}`)
|
|
162802
163075
|
};
|
|
162803
163076
|
} catch (error51) {
|
|
@@ -162910,19 +163183,19 @@ function loadPiConfig(opts = {}) {
|
|
|
162910
163183
|
loadedFromPaths: loadedFiles.map((loaded) => loaded.path)
|
|
162911
163184
|
};
|
|
162912
163185
|
}
|
|
162913
|
-
var
|
|
163186
|
+
var import_comment_json9, CONFIG_FILE_NAME = "magic-context";
|
|
162914
163187
|
var init_config2 = __esm(() => {
|
|
162915
163188
|
init_magic_context();
|
|
162916
163189
|
init_variable();
|
|
162917
|
-
|
|
163190
|
+
import_comment_json9 = __toESM(require_src2(), 1);
|
|
162918
163191
|
});
|
|
162919
163192
|
|
|
162920
163193
|
// src/lib/diagnostics-pi.ts
|
|
162921
163194
|
import { createHash } from "node:crypto";
|
|
162922
|
-
import { existsSync as existsSync19, readFileSync as
|
|
163195
|
+
import { existsSync as existsSync19, readdirSync as readdirSync3, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
162923
163196
|
import { createRequire as createRequire5 } from "node:module";
|
|
162924
|
-
import { homedir as
|
|
162925
|
-
import { join as
|
|
163197
|
+
import { homedir as homedir14, userInfo as userInfo2 } from "node:os";
|
|
163198
|
+
import { join as join18 } from "node:path";
|
|
162926
163199
|
function getSelfVersion3() {
|
|
162927
163200
|
const req = createRequire5(import.meta.url);
|
|
162928
163201
|
for (const relPath of ["../../package.json", "../package.json"]) {
|
|
@@ -162942,29 +163215,29 @@ function fileSize2(path4) {
|
|
|
162942
163215
|
return 0;
|
|
162943
163216
|
}
|
|
162944
163217
|
}
|
|
162945
|
-
function
|
|
163218
|
+
function escapeRegex4(value) {
|
|
162946
163219
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
162947
163220
|
}
|
|
162948
163221
|
function currentUserHash() {
|
|
162949
|
-
const username =
|
|
163222
|
+
const username = userInfo2().username || "unknown";
|
|
162950
163223
|
return createHash("sha256").update(username).digest("hex").slice(0, 12);
|
|
162951
163224
|
}
|
|
162952
163225
|
function redactSecretString(value) {
|
|
162953
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>");
|
|
162954
163227
|
}
|
|
162955
163228
|
function sanitizeString2(value) {
|
|
162956
|
-
const home = process.env.HOME ||
|
|
162957
|
-
const username =
|
|
163229
|
+
const home = process.env.HOME || homedir14();
|
|
163230
|
+
const username = userInfo2().username;
|
|
162958
163231
|
const userHash = `<USER:${currentUserHash()}>`;
|
|
162959
163232
|
let sanitized = redactSecretString(value);
|
|
162960
163233
|
if (home) {
|
|
162961
|
-
sanitized = sanitized.replace(new RegExp(
|
|
163234
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex4(home), "g"), "<HOME>");
|
|
162962
163235
|
}
|
|
162963
163236
|
sanitized = sanitized.replace(/\/Users\/[^/]+\//g, `/Users/${userHash}/`);
|
|
162964
163237
|
sanitized = sanitized.replace(/\/home\/[^/]+\//g, `/home/${userHash}/`);
|
|
162965
163238
|
sanitized = sanitized.replace(/C:\\Users\\[^\\]+\\/g, `C:\\Users\\${userHash}\\`);
|
|
162966
163239
|
if (username) {
|
|
162967
|
-
sanitized = sanitized.replace(new RegExp(
|
|
163240
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex4(username), "g"), userHash);
|
|
162968
163241
|
}
|
|
162969
163242
|
return sanitized;
|
|
162970
163243
|
}
|
|
@@ -162991,7 +163264,7 @@ function readJsonc3(path4) {
|
|
|
162991
163264
|
return { value: {} };
|
|
162992
163265
|
try {
|
|
162993
163266
|
return {
|
|
162994
|
-
value:
|
|
163267
|
+
value: import_comment_json10.parse(readFileSync14(path4, "utf-8"))
|
|
162995
163268
|
};
|
|
162996
163269
|
} catch (error51) {
|
|
162997
163270
|
return {
|
|
@@ -163001,7 +163274,7 @@ function readJsonc3(path4) {
|
|
|
163001
163274
|
}
|
|
163002
163275
|
}
|
|
163003
163276
|
function getProjectConfigPath(cwd) {
|
|
163004
|
-
return
|
|
163277
|
+
return join18(cwd, ".pi", "magic-context.jsonc");
|
|
163005
163278
|
}
|
|
163006
163279
|
function readConfigDiagnostic(path4) {
|
|
163007
163280
|
const parsed = readJsonc3(path4);
|
|
@@ -163013,10 +163286,153 @@ function readConfigDiagnostic(path4) {
|
|
|
163013
163286
|
};
|
|
163014
163287
|
}
|
|
163015
163288
|
function packageEntries(settings) {
|
|
163016
|
-
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
|
+
}
|
|
163017
163368
|
}
|
|
163018
|
-
function
|
|
163019
|
-
|
|
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
|
+
}
|
|
163400
|
+
}
|
|
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
|
+
};
|
|
163020
163436
|
}
|
|
163021
163437
|
async function collectDiagnostics2(cwd = process.cwd()) {
|
|
163022
163438
|
const pi = detectPiBinary();
|
|
@@ -163027,10 +163443,12 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163027
163443
|
const projectConfigPath = getProjectConfigPath(cwd);
|
|
163028
163444
|
const loaded = loadPiConfig({ cwd });
|
|
163029
163445
|
const storageDirPath = getMagicContextStorageDir();
|
|
163030
|
-
const dbPath =
|
|
163031
|
-
const logPath =
|
|
163446
|
+
const dbPath = join18(storageDirPath, "context.db");
|
|
163447
|
+
const logPath = getMagicContextLogPath2("pi");
|
|
163032
163448
|
const logFileSize = existsSync19(logPath) ? statSync4(logPath).size : 0;
|
|
163033
|
-
const otherPiExtensions = packages.filter((entry) => !
|
|
163449
|
+
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
163450
|
+
const recentSessions = collectPiRecentSessions();
|
|
163451
|
+
const historianDumps = collectPiHistorianDumps(recentSessions);
|
|
163034
163452
|
return {
|
|
163035
163453
|
timestamp: new Date().toISOString(),
|
|
163036
163454
|
platform: process.platform,
|
|
@@ -163044,8 +163462,8 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163044
163462
|
path: settingsPath,
|
|
163045
163463
|
exists: existsSync19(settingsPath),
|
|
163046
163464
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
163047
|
-
hasMagicContextPackage:
|
|
163048
|
-
packages: packages
|
|
163465
|
+
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
163466
|
+
packages: sanitizeValue2(packages)
|
|
163049
163467
|
},
|
|
163050
163468
|
configPaths: {
|
|
163051
163469
|
agentDir: getPiAgentConfigDir(),
|
|
@@ -163069,7 +163487,9 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
163069
163487
|
path: logPath,
|
|
163070
163488
|
exists: existsSync19(logPath),
|
|
163071
163489
|
sizeKb: Math.round(logFileSize / 1024)
|
|
163072
|
-
}
|
|
163490
|
+
},
|
|
163491
|
+
recentSessions,
|
|
163492
|
+
historianDumps
|
|
163073
163493
|
};
|
|
163074
163494
|
}
|
|
163075
163495
|
function formatBytes2(bytes) {
|
|
@@ -163146,18 +163566,20 @@ function renderDiagnosticsMarkdown2(report) {
|
|
|
163146
163566
|
].join(`
|
|
163147
163567
|
`);
|
|
163148
163568
|
}
|
|
163149
|
-
var
|
|
163569
|
+
var import_comment_json10;
|
|
163150
163570
|
var init_diagnostics_pi = __esm(() => {
|
|
163571
|
+
init_compartment_parser();
|
|
163151
163572
|
init_data_path();
|
|
163152
163573
|
init_config2();
|
|
163153
163574
|
init_paths();
|
|
163154
163575
|
init_pi_helpers();
|
|
163155
|
-
|
|
163576
|
+
init_pi_package_entry();
|
|
163577
|
+
import_comment_json10 = __toESM(require_src2(), 1);
|
|
163156
163578
|
});
|
|
163157
163579
|
|
|
163158
163580
|
// src/lib/logs-pi.ts
|
|
163159
|
-
import { readFileSync as
|
|
163160
|
-
import { join as
|
|
163581
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "node:fs";
|
|
163582
|
+
import { join as join19 } from "node:path";
|
|
163161
163583
|
function sanitizeLogContent2(content) {
|
|
163162
163584
|
return sanitizeString2(content);
|
|
163163
163585
|
}
|
|
@@ -163173,9 +163595,21 @@ function formatTimestamp2(date5) {
|
|
|
163173
163595
|
pad(date5.getSeconds())
|
|
163174
163596
|
].join("");
|
|
163175
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
|
+
}
|
|
163176
163609
|
async function bundleIssueReport2(report, description, title, options = {}) {
|
|
163177
163610
|
const LOG_TAIL_LINES = 400;
|
|
163178
|
-
const
|
|
163611
|
+
const allLogLines = report.logFile.exists ? readFileSync15(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
163612
|
+
const logLines = filterLogLinesBySession2(allLogLines, options.sessionFilter ?? null);
|
|
163179
163613
|
const recentLog = sanitizeLogContent2(logLines.slice(-LOG_TAIL_LINES).join(`
|
|
163180
163614
|
`)).trim();
|
|
163181
163615
|
const bodyMarkdown = [
|
|
@@ -163201,7 +163635,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
163201
163635
|
].join(`
|
|
163202
163636
|
`);
|
|
163203
163637
|
const cwd = options.cwd ?? process.cwd();
|
|
163204
|
-
const path4 =
|
|
163638
|
+
const path4 = join19(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
163205
163639
|
writeFileSync11(path4, `${bodyMarkdown}
|
|
163206
163640
|
`);
|
|
163207
163641
|
return { path: path4, bodyMarkdown };
|
|
@@ -163216,14 +163650,14 @@ import {
|
|
|
163216
163650
|
existsSync as existsSync20,
|
|
163217
163651
|
mkdirSync as mkdirSync8,
|
|
163218
163652
|
readdirSync as readdirSync4,
|
|
163219
|
-
readFileSync as
|
|
163653
|
+
readFileSync as readFileSync16,
|
|
163220
163654
|
rmSync as rmSync2,
|
|
163221
163655
|
statSync as statSync5,
|
|
163222
163656
|
writeFileSync as writeFileSync12
|
|
163223
163657
|
} from "node:fs";
|
|
163224
163658
|
import { createRequire as createRequire6 } from "node:module";
|
|
163225
|
-
import { homedir as
|
|
163226
|
-
import { dirname as dirname9, join as
|
|
163659
|
+
import { homedir as homedir15 } from "node:os";
|
|
163660
|
+
import { dirname as dirname9, join as join20 } from "node:path";
|
|
163227
163661
|
function depsFrom(options) {
|
|
163228
163662
|
return {
|
|
163229
163663
|
...DEFAULT_DEPS,
|
|
@@ -163310,7 +163744,7 @@ function summarize(results) {
|
|
|
163310
163744
|
function readJsonc4(path4) {
|
|
163311
163745
|
try {
|
|
163312
163746
|
return {
|
|
163313
|
-
value:
|
|
163747
|
+
value: import_comment_json11.parse(readFileSync16(path4, "utf-8"))
|
|
163314
163748
|
};
|
|
163315
163749
|
} catch (error51) {
|
|
163316
163750
|
return {
|
|
@@ -163320,24 +163754,21 @@ function readJsonc4(path4) {
|
|
|
163320
163754
|
}
|
|
163321
163755
|
}
|
|
163322
163756
|
function packagesFrom(settings) {
|
|
163323
|
-
return Array.isArray(settings.packages) ? settings.packages
|
|
163324
|
-
}
|
|
163325
|
-
function hasPiPackage(packages) {
|
|
163326
|
-
return packages.some((entry) => entry === PI_PACKAGE_SOURCE || entry === PACKAGE_NAME2 || entry.includes("pi-magic-context"));
|
|
163757
|
+
return Array.isArray(settings.packages) ? settings.packages : [];
|
|
163327
163758
|
}
|
|
163328
163759
|
function projectConfigPath(cwd) {
|
|
163329
|
-
return
|
|
163760
|
+
return join20(cwd, ".pi", "magic-context.jsonc");
|
|
163330
163761
|
}
|
|
163331
163762
|
function readConfigForEmbedding(path4) {
|
|
163332
163763
|
if (!existsSync20(path4))
|
|
163333
163764
|
return null;
|
|
163334
163765
|
try {
|
|
163335
|
-
const rawText =
|
|
163766
|
+
const rawText = readFileSync16(path4, "utf-8");
|
|
163336
163767
|
const substituted = substituteConfigVariables({
|
|
163337
163768
|
text: rawText,
|
|
163338
163769
|
configPath: path4
|
|
163339
163770
|
});
|
|
163340
|
-
return
|
|
163771
|
+
return import_comment_json11.parse(substituted.text);
|
|
163341
163772
|
} catch {
|
|
163342
163773
|
return null;
|
|
163343
163774
|
}
|
|
@@ -163390,14 +163821,14 @@ function countTable(db, table) {
|
|
|
163390
163821
|
}
|
|
163391
163822
|
}
|
|
163392
163823
|
function cacheRoots() {
|
|
163393
|
-
const home =
|
|
163394
|
-
const cacheHome = process.env.XDG_CACHE_HOME ||
|
|
163824
|
+
const home = homedir15();
|
|
163825
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join20(home, ".cache");
|
|
163395
163826
|
return [
|
|
163396
|
-
|
|
163397
|
-
|
|
163398
|
-
|
|
163399
|
-
|
|
163400
|
-
|
|
163827
|
+
join20(home, ".pi", "cache", "extensions"),
|
|
163828
|
+
join20(home, ".pi", "cache", "packages"),
|
|
163829
|
+
join20(cacheHome, "pi", "extensions"),
|
|
163830
|
+
join20(cacheHome, "pi", "packages"),
|
|
163831
|
+
join20(getPiAgentConfigDir(), "cache", "extensions")
|
|
163401
163832
|
];
|
|
163402
163833
|
}
|
|
163403
163834
|
function findPiMagicContextCacheDirs(self, force = false) {
|
|
@@ -163413,13 +163844,13 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
163413
163844
|
}
|
|
163414
163845
|
if (!stat.isDirectory())
|
|
163415
163846
|
return;
|
|
163416
|
-
const packageJson =
|
|
163847
|
+
const packageJson = join20(path4, "package.json");
|
|
163417
163848
|
if (existsSync20(packageJson)) {
|
|
163418
163849
|
try {
|
|
163419
|
-
const pkg = JSON.parse(
|
|
163850
|
+
const pkg = JSON.parse(readFileSync16(packageJson, "utf-8"));
|
|
163420
163851
|
const name2 = typeof pkg.name === "string" ? pkg.name : "";
|
|
163421
163852
|
const version2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
163422
|
-
if (name2 ===
|
|
163853
|
+
if (name2 === PACKAGE_NAME || path4.includes("pi-magic-context")) {
|
|
163423
163854
|
if (force || !version2 || version2 !== self)
|
|
163424
163855
|
found.set(path4, { path: path4, version: version2 });
|
|
163425
163856
|
}
|
|
@@ -163435,7 +163866,7 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
163435
163866
|
return;
|
|
163436
163867
|
}
|
|
163437
163868
|
for (const entry of entries)
|
|
163438
|
-
visit(
|
|
163869
|
+
visit(join20(path4, entry), depth - 1);
|
|
163439
163870
|
};
|
|
163440
163871
|
for (const root of cacheRoots())
|
|
163441
163872
|
visit(root, 5);
|
|
@@ -163482,7 +163913,7 @@ async function runHealthChecks(options) {
|
|
|
163482
163913
|
} else {
|
|
163483
163914
|
packages = packagesFrom(parsed.value);
|
|
163484
163915
|
add(results, "pass", `Pi settings found at ${settingsPath}`);
|
|
163485
|
-
if (
|
|
163916
|
+
if (hasPiMagicContextPackage(packages)) {
|
|
163486
163917
|
add(results, "pass", `${PI_PACKAGE_SOURCE} is registered in packages[]`);
|
|
163487
163918
|
} else {
|
|
163488
163919
|
add(results, "warn", `${PI_PACKAGE_SOURCE} is missing from packages[]`);
|
|
@@ -163529,7 +163960,7 @@ async function runHealthChecks(options) {
|
|
|
163529
163960
|
add(results, "pass", `historian.model "${historianModel}" has thinking_level "${historianThinkingLevel}" configured`);
|
|
163530
163961
|
}
|
|
163531
163962
|
const storageDir = getMagicContextStorageDir();
|
|
163532
|
-
const dbPath =
|
|
163963
|
+
const dbPath = join20(storageDir, "context.db");
|
|
163533
163964
|
const existedBeforeOpen = existsSync20(dbPath);
|
|
163534
163965
|
if (existedBeforeOpen)
|
|
163535
163966
|
add(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
@@ -163587,13 +164018,13 @@ async function runHealthChecks(options) {
|
|
|
163587
164018
|
} else {
|
|
163588
164019
|
add(results, "pass", `Embedding provider: ${loadedConfig.config.embedding.provider}`);
|
|
163589
164020
|
}
|
|
163590
|
-
const piEntries = packages.filter(
|
|
164021
|
+
const piEntries = packages.filter(isPiMagicContextPackageEntry).map(describePiPackageEntry);
|
|
163591
164022
|
if (piEntries.length > 1) {
|
|
163592
164023
|
add(results, "fail", `Multiple magic-context entries in Pi packages[] — this loads the plugin twice: ${piEntries.join(", ")}`);
|
|
163593
164024
|
} else {
|
|
163594
164025
|
add(results, "pass", "No conflicting magic-context entries in Pi packages[]");
|
|
163595
164026
|
}
|
|
163596
|
-
const otherExtensions = packages.filter((entry) => !
|
|
164027
|
+
const otherExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
163597
164028
|
if (otherExtensions.length > 0) {
|
|
163598
164029
|
add(results, "info", `Other Pi extensions registered: ${otherExtensions.join(", ")}`);
|
|
163599
164030
|
} else {
|
|
@@ -163606,32 +164037,36 @@ async function runHealthChecks(options) {
|
|
|
163606
164037
|
} else {
|
|
163607
164038
|
add(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
163608
164039
|
}
|
|
163609
|
-
const logPath =
|
|
164040
|
+
const logPath = getMagicContextLogPath2("pi");
|
|
163610
164041
|
if (existsSync20(logPath)) {
|
|
163611
164042
|
const stat = statSync5(logPath);
|
|
163612
164043
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
163613
|
-
const lines =
|
|
164044
|
+
const lines = readFileSync16(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
163614
164045
|
add(results, "info", `Log file: ${logPath} (${sizeKb} KB)`);
|
|
163615
164046
|
add(results, "info", `Last plugin log line: ${lines.at(-1) ?? "<empty log>"}`);
|
|
163616
164047
|
} else {
|
|
163617
164048
|
add(results, "info", `No plugin log file yet at ${logPath}`);
|
|
163618
164049
|
}
|
|
163619
|
-
const
|
|
163620
|
-
|
|
163621
|
-
|
|
163622
|
-
|
|
163623
|
-
|
|
163624
|
-
|
|
163625
|
-
|
|
163626
|
-
|
|
163627
|
-
|
|
163628
|
-
|
|
163629
|
-
}
|
|
163630
|
-
if (dumps.length > 3) {
|
|
163631
|
-
add(results, "info", ` ... and ${dumps.length - 3} more`);
|
|
163632
|
-
}
|
|
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})`);
|
|
163633
164061
|
}
|
|
163634
|
-
|
|
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}`);
|
|
163635
164070
|
}
|
|
163636
164071
|
if (!options.quiet) {
|
|
163637
164072
|
for (const result of results)
|
|
@@ -163645,7 +164080,7 @@ function writeDefaultMagicContextConfig(path4) {
|
|
|
163645
164080
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
163646
164081
|
...MagicContextConfigSchema.parse({})
|
|
163647
164082
|
};
|
|
163648
|
-
writeFileSync12(path4, `${
|
|
164083
|
+
writeFileSync12(path4, `${import_comment_json11.stringify(config2, null, 2)}
|
|
163649
164084
|
`);
|
|
163650
164085
|
}
|
|
163651
164086
|
function repair(plan, prompts) {
|
|
@@ -163710,9 +164145,26 @@ async function runIssueFlow2(options) {
|
|
|
163710
164145
|
spinner2.start("Collecting sanitized Pi diagnostics");
|
|
163711
164146
|
try {
|
|
163712
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");
|
|
163713
164164
|
const bundled = await bundleIssueReport2(report, description, title, {
|
|
163714
164165
|
cwd: options.cwd,
|
|
163715
|
-
now: options.deps.now()
|
|
164166
|
+
now: options.deps.now(),
|
|
164167
|
+
sessionFilter
|
|
163716
164168
|
});
|
|
163717
164169
|
spinner2.stop(`Report written to ${bundled.path}`);
|
|
163718
164170
|
if (ghAvailableAndAuthed(options.deps)) {
|
|
@@ -163787,7 +164239,7 @@ function parseDoctorArgs(args) {
|
|
|
163787
164239
|
function doctor(args = []) {
|
|
163788
164240
|
return runDoctor2(parseDoctorArgs(args));
|
|
163789
164241
|
}
|
|
163790
|
-
var
|
|
164242
|
+
var import_comment_json11, PACKAGE_NAME = "@cortexkit/pi-magic-context", MIN_PI_VERSION = "0.71.0", ROW_COUNT_TABLES, DEFAULT_DEPS;
|
|
163791
164243
|
var init_doctor_pi = __esm(async () => {
|
|
163792
164244
|
init_magic_context();
|
|
163793
164245
|
init_variable();
|
|
@@ -163797,17 +164249,18 @@ var init_doctor_pi = __esm(async () => {
|
|
|
163797
164249
|
init_logs_pi();
|
|
163798
164250
|
init_paths();
|
|
163799
164251
|
init_pi_helpers();
|
|
164252
|
+
init_pi_package_entry();
|
|
163800
164253
|
init_prompts();
|
|
163801
164254
|
init_setup_pi();
|
|
163802
164255
|
await init_storage();
|
|
163803
|
-
|
|
164256
|
+
import_comment_json11 = __toESM(require_src2(), 1);
|
|
163804
164257
|
ROW_COUNT_TABLES = ["tags", "compartments", "memories", "notes", "dream_runs"];
|
|
163805
164258
|
DEFAULT_DEPS = {
|
|
163806
164259
|
prompts: promptIO,
|
|
163807
164260
|
collectDiagnostics: collectDiagnostics2,
|
|
163808
164261
|
detectPiBinary,
|
|
163809
164262
|
getPiVersion,
|
|
163810
|
-
getLatestNpmVersion: () => getLatestNpmVersion(
|
|
164263
|
+
getLatestNpmVersion: () => getLatestNpmVersion(PACKAGE_NAME),
|
|
163811
164264
|
probeEmbeddingEndpoint,
|
|
163812
164265
|
openDatabase,
|
|
163813
164266
|
isDatabasePersisted,
|