@cortexkit/magic-context 0.31.2 → 0.31.4
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 +621 -309
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8476,7 +8476,7 @@ var init_data_path = () => {};
|
|
|
8476
8476
|
// src/lib/paths.ts
|
|
8477
8477
|
import { existsSync as existsSync4, readdirSync, statSync as statSync4 } from "node:fs";
|
|
8478
8478
|
import { homedir as homedir4 } from "node:os";
|
|
8479
|
-
import { join as join5 } from "node:path";
|
|
8479
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
8480
8480
|
function getOpenCodeConfigDir() {
|
|
8481
8481
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
8482
8482
|
if (envDir)
|
|
@@ -8540,11 +8540,24 @@ function detectConfigPaths() {
|
|
|
8540
8540
|
tuiConfigFormat
|
|
8541
8541
|
};
|
|
8542
8542
|
}
|
|
8543
|
-
function
|
|
8543
|
+
function envFirstHomeDir() {
|
|
8544
|
+
const home = process.env.HOME?.trim();
|
|
8545
|
+
return home || homedir4();
|
|
8546
|
+
}
|
|
8547
|
+
function getPiAgentDir() {
|
|
8544
8548
|
const envDir = process.env.PI_CODING_AGENT_DIR?.trim();
|
|
8545
8549
|
if (envDir)
|
|
8546
8550
|
return envDir;
|
|
8547
|
-
return join5(
|
|
8551
|
+
return join5(envFirstHomeDir(), ".pi", "agent");
|
|
8552
|
+
}
|
|
8553
|
+
function getPiAgentConfigDir() {
|
|
8554
|
+
return getPiAgentDir();
|
|
8555
|
+
}
|
|
8556
|
+
function getPiSessionsRoot() {
|
|
8557
|
+
return join5(getPiAgentDir(), "sessions");
|
|
8558
|
+
}
|
|
8559
|
+
function getPiCacheRoot() {
|
|
8560
|
+
return join5(dirname3(getPiAgentDir()), "cache");
|
|
8548
8561
|
}
|
|
8549
8562
|
function getPiUserConfigPath() {
|
|
8550
8563
|
return resolveCortexKitUserConfigPath();
|
|
@@ -8622,7 +8635,7 @@ var init_opencode_plugin_cache = __esm(() => {
|
|
|
8622
8635
|
|
|
8623
8636
|
// src/adapters/opencode.ts
|
|
8624
8637
|
import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
|
|
8625
|
-
import { dirname as
|
|
8638
|
+
import { dirname as dirname4 } from "node:path";
|
|
8626
8639
|
|
|
8627
8640
|
class OpenCodeAdapter {
|
|
8628
8641
|
kind = "opencode";
|
|
@@ -8843,7 +8856,7 @@ function matchesPluginEntry(entry, pkgName) {
|
|
|
8843
8856
|
return head === pkgName;
|
|
8844
8857
|
}
|
|
8845
8858
|
function ensureDir(filePath) {
|
|
8846
|
-
const dir =
|
|
8859
|
+
const dir = dirname4(filePath);
|
|
8847
8860
|
if (!existsSync5(dir)) {
|
|
8848
8861
|
const { mkdirSync: mkdirSync3 } = __require("node:fs");
|
|
8849
8862
|
mkdirSync3(dir, { recursive: true });
|
|
@@ -8948,7 +8961,7 @@ var init_pi_helpers = __esm(() => {
|
|
|
8948
8961
|
// src/adapters/pi.ts
|
|
8949
8962
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
8950
8963
|
import { existsSync as existsSync7, readFileSync as readFileSync3 } from "node:fs";
|
|
8951
|
-
import { dirname as
|
|
8964
|
+
import { dirname as dirname5 } from "node:path";
|
|
8952
8965
|
|
|
8953
8966
|
class PiAdapter {
|
|
8954
8967
|
kind = "pi";
|
|
@@ -9105,7 +9118,7 @@ function matchesPiPackage(entry) {
|
|
|
9105
9118
|
return false;
|
|
9106
9119
|
}
|
|
9107
9120
|
function ensureDir2(filePath) {
|
|
9108
|
-
const dir =
|
|
9121
|
+
const dir = dirname5(filePath);
|
|
9109
9122
|
if (!existsSync7(dir)) {
|
|
9110
9123
|
const { mkdirSync: mkdirSync3 } = __require("node:fs");
|
|
9111
9124
|
mkdirSync3(dir, { recursive: true });
|
|
@@ -11974,7 +11987,7 @@ var init_opencode_helpers = () => {};
|
|
|
11974
11987
|
|
|
11975
11988
|
// src/commands/setup-opencode.ts
|
|
11976
11989
|
import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync6 } from "node:fs";
|
|
11977
|
-
import { basename as basename2, dirname as
|
|
11990
|
+
import { basename as basename2, dirname as dirname6 } from "node:path";
|
|
11978
11991
|
function ensureDir3(dir) {
|
|
11979
11992
|
if (!existsSync10(dir)) {
|
|
11980
11993
|
mkdirSync3(dir, { recursive: true });
|
|
@@ -11990,7 +12003,7 @@ function readJsonc(path2) {
|
|
|
11990
12003
|
}
|
|
11991
12004
|
}
|
|
11992
12005
|
function addPluginToOpenCodeConfig(configPath, format) {
|
|
11993
|
-
ensureDir3(
|
|
12006
|
+
ensureDir3(dirname6(configPath));
|
|
11994
12007
|
if (format === "none") {
|
|
11995
12008
|
const config = {
|
|
11996
12009
|
plugin: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION],
|
|
@@ -12020,7 +12033,7 @@ function addPluginToOpenCodeConfig(configPath, format) {
|
|
|
12020
12033
|
`);
|
|
12021
12034
|
}
|
|
12022
12035
|
function addPluginToTuiConfig(configPath, format) {
|
|
12023
|
-
ensureDir3(
|
|
12036
|
+
ensureDir3(dirname6(configPath));
|
|
12024
12037
|
if (format === "none") {
|
|
12025
12038
|
writeFileAtomic(configPath, `${import_comment_json4.stringify({ plugin: [OPENCODE_PLUGIN_ENTRY_WITH_VERSION] }, null, 2)}
|
|
12026
12039
|
`);
|
|
@@ -12386,7 +12399,7 @@ var PI_MAGIC_CONTEXT_PACKAGE_NAME = "@cortexkit/pi-magic-context";
|
|
|
12386
12399
|
|
|
12387
12400
|
// src/commands/setup-pi.ts
|
|
12388
12401
|
import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync7 } from "node:fs";
|
|
12389
|
-
import { dirname as
|
|
12402
|
+
import { dirname as dirname7 } from "node:path";
|
|
12390
12403
|
function ensureDir4(path2) {
|
|
12391
12404
|
if (!existsSync11(path2))
|
|
12392
12405
|
mkdirSync4(path2, { recursive: true });
|
|
@@ -12429,7 +12442,7 @@ function comparePiVersion(a3, b2) {
|
|
|
12429
12442
|
return 0;
|
|
12430
12443
|
}
|
|
12431
12444
|
function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE) {
|
|
12432
|
-
ensureDir4(
|
|
12445
|
+
ensureDir4(dirname7(settingsPath));
|
|
12433
12446
|
const settings2 = existsSync11(settingsPath) ? readJsonc2(settingsPath) ?? {} : {};
|
|
12434
12447
|
const packages = Array.isArray(settings2.packages) ? settings2.packages : [];
|
|
12435
12448
|
const hasPackage = hasPiMagicContextPackage(packages);
|
|
@@ -12441,7 +12454,7 @@ function writePiSettingsPackage(settingsPath, packageSource = PI_PACKAGE_SOURCE)
|
|
|
12441
12454
|
return !hasPackage;
|
|
12442
12455
|
}
|
|
12443
12456
|
function writeMagicContextConfig2(configPath, options) {
|
|
12444
|
-
ensureDir4(
|
|
12457
|
+
ensureDir4(dirname7(configPath));
|
|
12445
12458
|
const config = existsSync11(configPath) ? readJsonc2(configPath) ?? {} : {};
|
|
12446
12459
|
if (!config.$schema) {
|
|
12447
12460
|
config.$schema = "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json";
|
|
@@ -12775,7 +12788,7 @@ __export(exports_migrate, {
|
|
|
12775
12788
|
formatPiFilenameTimestamp: () => formatPiFilenameTimestamp
|
|
12776
12789
|
});
|
|
12777
12790
|
import { randomBytes } from "node:crypto";
|
|
12778
|
-
import {
|
|
12791
|
+
import { unlinkSync as unlinkSync2 } from "node:fs";
|
|
12779
12792
|
import { homedir as homedir7 } from "node:os";
|
|
12780
12793
|
import { join as join11 } from "node:path";
|
|
12781
12794
|
function defaultOpenCodeDbPath() {
|
|
@@ -12785,10 +12798,10 @@ function defaultCortexkitDbPath() {
|
|
|
12785
12798
|
return join11(getMagicContextStorageDir(), "context.db");
|
|
12786
12799
|
}
|
|
12787
12800
|
function defaultPiSessionsRoot() {
|
|
12788
|
-
return
|
|
12801
|
+
return getPiSessionsRoot();
|
|
12789
12802
|
}
|
|
12790
12803
|
function defaultFs() {
|
|
12791
|
-
return {
|
|
12804
|
+
return { writeFileAtomic, unlinkSync: unlinkSync2 };
|
|
12792
12805
|
}
|
|
12793
12806
|
function stmt(db, sql) {
|
|
12794
12807
|
return db.prepare(sql);
|
|
@@ -13259,9 +13272,7 @@ function migrateOpenCodeSessionToPi(opts) {
|
|
|
13259
13272
|
`)}
|
|
13260
13273
|
`;
|
|
13261
13274
|
if (!opts.dryRun) {
|
|
13262
|
-
|
|
13263
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
13264
|
-
fs.writeFileSync(outputPath, jsonl);
|
|
13275
|
+
fs.writeFileAtomic(outputPath, jsonl);
|
|
13265
13276
|
try {
|
|
13266
13277
|
commitMagicContextState?.();
|
|
13267
13278
|
} catch (commitError) {
|
|
@@ -13386,6 +13397,8 @@ async function runMigrateCli(args) {
|
|
|
13386
13397
|
var DEFAULT_PROVIDER = "openai-codex", DEFAULT_MODEL = "gpt-5.5", MIGRATION_COMPACTION_SUMMARY = "Magic Context compacted prior conversation. See <session-history> block for the structured summary.";
|
|
13387
13398
|
var init_migrate = __esm(async () => {
|
|
13388
13399
|
init_data_path();
|
|
13400
|
+
init_atomic_write();
|
|
13401
|
+
init_paths();
|
|
13389
13402
|
await init_sqlite();
|
|
13390
13403
|
});
|
|
13391
13404
|
|
|
@@ -13452,7 +13465,7 @@ var init_logger = __esm(() => {
|
|
|
13452
13465
|
// ../plugin/src/features/magic-context/memory/project-identity.ts
|
|
13453
13466
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
13454
13467
|
import { createHash } from "node:crypto";
|
|
13455
|
-
import { existsSync as
|
|
13468
|
+
import { existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
|
|
13456
13469
|
import path3 from "node:path";
|
|
13457
13470
|
function asError(error) {
|
|
13458
13471
|
return error instanceof Error ? error : undefined;
|
|
@@ -13691,7 +13704,7 @@ function hasGitDir(canonical) {
|
|
|
13691
13704
|
function hasGitDirInAncestorChain(startDirectory) {
|
|
13692
13705
|
let current = startDirectory;
|
|
13693
13706
|
while (true) {
|
|
13694
|
-
if (
|
|
13707
|
+
if (existsSync12(path3.join(current, ".git"))) {
|
|
13695
13708
|
return true;
|
|
13696
13709
|
}
|
|
13697
13710
|
const parent = path3.dirname(current);
|
|
@@ -13855,7 +13868,7 @@ __export(exports_migrate_session, {
|
|
|
13855
13868
|
planMigrateSession: () => planMigrateSession,
|
|
13856
13869
|
applyMigrateSession: () => applyMigrateSession
|
|
13857
13870
|
});
|
|
13858
|
-
import { copyFileSync, existsSync as
|
|
13871
|
+
import { copyFileSync, existsSync as existsSync13, realpathSync as realpathSync2 } from "node:fs";
|
|
13859
13872
|
import { homedir as homedir8 } from "node:os";
|
|
13860
13873
|
import path4, { join as join12 } from "node:path";
|
|
13861
13874
|
function existingSessionColumns(db) {
|
|
@@ -14018,7 +14031,7 @@ function realDeps(opencodeDb, contextDb) {
|
|
|
14018
14031
|
opencodeDb,
|
|
14019
14032
|
contextDb,
|
|
14020
14033
|
resolveIdentity: resolveProjectIdentity,
|
|
14021
|
-
hasGitDir: (dir) =>
|
|
14034
|
+
hasGitDir: (dir) => existsSync13(join12(dir, ".git")),
|
|
14022
14035
|
realpath: (p2) => realpathSync2(p2)
|
|
14023
14036
|
};
|
|
14024
14037
|
}
|
|
@@ -14097,7 +14110,7 @@ async function runMigrateSessionCli(args) {
|
|
|
14097
14110
|
return 1;
|
|
14098
14111
|
}
|
|
14099
14112
|
const expandedTo = toDir.startsWith("~") ? join12(homedir8(), toDir.slice(1).replace(/^[/\\]/, "")) : toDir;
|
|
14100
|
-
if (!
|
|
14113
|
+
if (!existsSync13(expandedTo)) {
|
|
14101
14114
|
console.error(`Target directory does not exist: ${expandedTo}`);
|
|
14102
14115
|
return 1;
|
|
14103
14116
|
}
|
|
@@ -146830,14 +146843,17 @@ var init_read_session_chunk = __esm(async () => {
|
|
|
146830
146843
|
});
|
|
146831
146844
|
|
|
146832
146845
|
// ../plugin/src/features/magic-context/message-index.ts
|
|
146833
|
-
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, deleteFtsStatements, deleteIndexStatements, countIndexedMessageStatements;
|
|
146846
|
+
var lastIndexedStatements, insertMessageStatements, upsertIndexStatements, upsertCleanIndexStatements, upsertDirtyFloorStatements, deleteFtsStatements, deleteFtsFromOrdinalStatements, deleteIndexStatements, countIndexedMessageStatements;
|
|
146834
146847
|
var init_message_index = __esm(async () => {
|
|
146835
146848
|
init_compression_depth_storage();
|
|
146836
146849
|
await init_read_session_chunk();
|
|
146837
146850
|
lastIndexedStatements = new WeakMap;
|
|
146838
146851
|
insertMessageStatements = new WeakMap;
|
|
146839
146852
|
upsertIndexStatements = new WeakMap;
|
|
146853
|
+
upsertCleanIndexStatements = new WeakMap;
|
|
146854
|
+
upsertDirtyFloorStatements = new WeakMap;
|
|
146840
146855
|
deleteFtsStatements = new WeakMap;
|
|
146856
|
+
deleteFtsFromOrdinalStatements = new WeakMap;
|
|
146841
146857
|
deleteIndexStatements = new WeakMap;
|
|
146842
146858
|
countIndexedMessageStatements = new WeakMap;
|
|
146843
146859
|
});
|
|
@@ -146876,6 +146892,7 @@ function healNullTextColumns(db) {
|
|
|
146876
146892
|
["cache_ttl", ""],
|
|
146877
146893
|
["last_nudge_band", ""],
|
|
146878
146894
|
["last_nudge_level", ""],
|
|
146895
|
+
["channel2_nudge_claim_token", ""],
|
|
146879
146896
|
["last_transform_error", ""],
|
|
146880
146897
|
["nudge_anchor_message_id", ""],
|
|
146881
146898
|
["nudge_anchor_text", ""],
|
|
@@ -147016,6 +147033,7 @@ function bumpEpochsForWorkspaceMemberSet(db, identities, now = Date.now()) {
|
|
|
147016
147033
|
}
|
|
147017
147034
|
var VALID_SHARE_CATEGORIES;
|
|
147018
147035
|
var init_workspaces = __esm(() => {
|
|
147036
|
+
init_logger();
|
|
147019
147037
|
init_constants();
|
|
147020
147038
|
init_project_identity2();
|
|
147021
147039
|
VALID_SHARE_CATEGORIES = new Set(V2_MEMORY_CATEGORIES);
|
|
@@ -148469,7 +148487,7 @@ var init_tool_definition_tokens = __esm(() => {
|
|
|
148469
148487
|
});
|
|
148470
148488
|
|
|
148471
148489
|
// ../plugin/src/features/magic-context/tool-owner-backfill.ts
|
|
148472
|
-
import { existsSync as
|
|
148490
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
148473
148491
|
import { join as join13 } from "node:path";
|
|
148474
148492
|
function resolveOpencodeDbPath() {
|
|
148475
148493
|
return join13(getDataDir(), "opencode", "opencode.db");
|
|
@@ -148507,7 +148525,7 @@ function runToolOwnerBackfill(db) {
|
|
|
148507
148525
|
return result;
|
|
148508
148526
|
}
|
|
148509
148527
|
const opencodeDbPath = resolveOpencodeDbPath();
|
|
148510
|
-
if (!
|
|
148528
|
+
if (!existsSync14(opencodeDbPath)) {
|
|
148511
148529
|
log3(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
|
|
148512
148530
|
markAllUnbackfilledSessionsSkipped(db);
|
|
148513
148531
|
result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
|
|
@@ -148731,10 +148749,10 @@ var init_tool_owner_backfill = __esm(() => {
|
|
|
148731
148749
|
});
|
|
148732
148750
|
|
|
148733
148751
|
// ../plugin/src/features/magic-context/storage-db.ts
|
|
148734
|
-
import { chmodSync as chmodSync2, copyFileSync as copyFileSync2, cpSync, existsSync as
|
|
148735
|
-
import { dirname as
|
|
148752
|
+
import { chmodSync as chmodSync2, copyFileSync as copyFileSync2, cpSync, existsSync as existsSync15, mkdirSync as mkdirSync6, mkdtempSync } from "node:fs";
|
|
148753
|
+
import { dirname as dirname9, join as join14 } from "node:path";
|
|
148736
148754
|
function ensureSecureStorageDir(dir) {
|
|
148737
|
-
|
|
148755
|
+
mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
148738
148756
|
if (!PERMISSIONS_ENFORCEABLE)
|
|
148739
148757
|
return;
|
|
148740
148758
|
try {
|
|
@@ -148748,7 +148766,7 @@ function restrictDatabaseFilePermissions(dbPath) {
|
|
|
148748
148766
|
return;
|
|
148749
148767
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
148750
148768
|
const file = `${dbPath}${suffix}`;
|
|
148751
|
-
if (!
|
|
148769
|
+
if (!existsSync15(file))
|
|
148752
148770
|
continue;
|
|
148753
148771
|
try {
|
|
148754
148772
|
chmodSync2(file, 384);
|
|
@@ -148759,7 +148777,7 @@ function restrictDatabaseFilePermissions(dbPath) {
|
|
|
148759
148777
|
}
|
|
148760
148778
|
function resolveDatabasePath(dbPathOverride) {
|
|
148761
148779
|
if (dbPathOverride) {
|
|
148762
|
-
return { dbDir:
|
|
148780
|
+
return { dbDir: dirname9(dbPathOverride), dbPath: dbPathOverride };
|
|
148763
148781
|
}
|
|
148764
148782
|
const testDataDir = process.env.MAGIC_CONTEXT_TEST_DATA_DIR;
|
|
148765
148783
|
if (testDataDir && !process.env.XDG_DATA_HOME) {
|
|
@@ -148771,11 +148789,11 @@ function resolveDatabasePath(dbPathOverride) {
|
|
|
148771
148789
|
return { dbDir, dbPath: join14(dbDir, "context.db") };
|
|
148772
148790
|
}
|
|
148773
148791
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
148774
|
-
if (
|
|
148792
|
+
if (existsSync15(targetDbPath))
|
|
148775
148793
|
return;
|
|
148776
148794
|
const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
|
|
148777
148795
|
const legacyDbPath = join14(legacyDir, "context.db");
|
|
148778
|
-
if (!
|
|
148796
|
+
if (!existsSync15(legacyDbPath))
|
|
148779
148797
|
return;
|
|
148780
148798
|
log3(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
|
|
148781
148799
|
ensureSecureStorageDir(targetDbDir);
|
|
@@ -148792,7 +148810,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
148792
148810
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
148793
148811
|
const src = `${legacyDbPath}${suffix}`;
|
|
148794
148812
|
const dst = join14(targetDbDir, `context.db${suffix}`);
|
|
148795
|
-
if (
|
|
148813
|
+
if (existsSync15(src)) {
|
|
148796
148814
|
try {
|
|
148797
148815
|
copyFileSync2(src, dst);
|
|
148798
148816
|
} catch (error) {
|
|
@@ -148802,7 +148820,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
|
148802
148820
|
}
|
|
148803
148821
|
const legacyModelsDir = join14(legacyDir, "models");
|
|
148804
148822
|
const targetModelsDir = join14(targetDbDir, "models");
|
|
148805
|
-
if (
|
|
148823
|
+
if (existsSync15(legacyModelsDir) && !existsSync15(targetModelsDir)) {
|
|
148806
148824
|
try {
|
|
148807
148825
|
cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
|
|
148808
148826
|
} catch (error) {
|
|
@@ -149293,6 +149311,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
149293
149311
|
CREATE TABLE IF NOT EXISTS message_history_index (
|
|
149294
149312
|
session_id TEXT PRIMARY KEY,
|
|
149295
149313
|
last_indexed_ordinal INTEGER NOT NULL DEFAULT 0,
|
|
149314
|
+
dirty_floor_ordinal INTEGER NOT NULL DEFAULT 0,
|
|
149296
149315
|
updated_at INTEGER NOT NULL,
|
|
149297
149316
|
harness TEXT NOT NULL DEFAULT 'opencode'
|
|
149298
149317
|
);
|
|
@@ -149322,6 +149341,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
149322
149341
|
last_nudge_level TEXT DEFAULT '',
|
|
149323
149342
|
channel2_nudge_state TEXT DEFAULT '',
|
|
149324
149343
|
channel2_nudge_claimed_at INTEGER DEFAULT 0,
|
|
149344
|
+
channel2_nudge_claim_token TEXT DEFAULT '',
|
|
149325
149345
|
last_emergency_input_sample INTEGER DEFAULT 0,
|
|
149326
149346
|
last_transform_error TEXT DEFAULT '',
|
|
149327
149347
|
nudge_anchor_message_id TEXT DEFAULT '',
|
|
@@ -149568,6 +149588,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
149568
149588
|
ensureColumn(db, "session_meta", "last_nudge_level", "TEXT DEFAULT ''");
|
|
149569
149589
|
ensureColumn(db, "session_meta", "channel2_nudge_state", "TEXT DEFAULT ''");
|
|
149570
149590
|
ensureColumn(db, "session_meta", "channel2_nudge_claimed_at", "INTEGER DEFAULT 0");
|
|
149591
|
+
ensureColumn(db, "session_meta", "channel2_nudge_claim_token", "TEXT DEFAULT ''");
|
|
149571
149592
|
ensureColumn(db, "session_meta", "last_emergency_input_sample", "INTEGER DEFAULT 0");
|
|
149572
149593
|
ensureColumn(db, "session_meta", "last_transform_error", "TEXT DEFAULT ''");
|
|
149573
149594
|
ensureColumn(db, "session_meta", "nudge_anchor_message_id", "TEXT DEFAULT ''");
|
|
@@ -149780,6 +149801,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
149780
149801
|
ON transform_decisions(session_id, harness);
|
|
149781
149802
|
`);
|
|
149782
149803
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
149804
|
+
ensureColumn(db, "message_history_index", "dirty_floor_ordinal", "INTEGER NOT NULL DEFAULT 0");
|
|
149783
149805
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
149784
149806
|
ensureColumn(db, "source_contents", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
149785
149807
|
ensureColumn(db, "compartments", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -149794,7 +149816,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
149794
149816
|
function healWedgedChannel2Claims(db) {
|
|
149795
149817
|
try {
|
|
149796
149818
|
const staleBefore = Date.now() - CHANNEL2_CLAIM_TTL_MS;
|
|
149797
|
-
db.prepare("UPDATE session_meta SET channel2_nudge_state = 'pending', channel2_nudge_claimed_at = 0 WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
|
|
149819
|
+
db.prepare("UPDATE session_meta SET channel2_nudge_state = 'pending', channel2_nudge_claimed_at = 0, channel2_nudge_claim_token = '' WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
|
|
149798
149820
|
} catch {}
|
|
149799
149821
|
}
|
|
149800
149822
|
function openDatabase(dbPathOrOptions) {
|
|
@@ -150605,127 +150627,6 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
150605
150627
|
return patched;
|
|
150606
150628
|
}
|
|
150607
150629
|
|
|
150608
|
-
// ../plugin/src/config/project-security.ts
|
|
150609
|
-
function isPlainObject(value) {
|
|
150610
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
150611
|
-
}
|
|
150612
|
-
function stripUnsafeProjectConfigFields(projectRaw) {
|
|
150613
|
-
const warnings = [];
|
|
150614
|
-
if ("auto_update" in projectRaw) {
|
|
150615
|
-
delete projectRaw.auto_update;
|
|
150616
|
-
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
150617
|
-
}
|
|
150618
|
-
if ("language" in projectRaw) {
|
|
150619
|
-
delete projectRaw.language;
|
|
150620
|
-
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
150621
|
-
}
|
|
150622
|
-
if ("sqlite" in projectRaw) {
|
|
150623
|
-
delete projectRaw.sqlite;
|
|
150624
|
-
warnings.push("Ignoring sqlite.* from project config (security: SQLite cache/mmap PRAGMAs apply to the " + "process-global shared database handle; only user-level config may set them).");
|
|
150625
|
-
}
|
|
150626
|
-
const embedding = projectRaw.embedding;
|
|
150627
|
-
if (isPlainObject(embedding)) {
|
|
150628
|
-
const removed = [];
|
|
150629
|
-
for (const field of EMBEDDING_DESTINATION_FIELDS) {
|
|
150630
|
-
if (field in embedding) {
|
|
150631
|
-
delete embedding[field];
|
|
150632
|
-
removed.push(field);
|
|
150633
|
-
}
|
|
150634
|
-
}
|
|
150635
|
-
if (removed.length > 0) {
|
|
150636
|
-
warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where private text is embedded).");
|
|
150637
|
-
}
|
|
150638
|
-
}
|
|
150639
|
-
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
150640
|
-
const block2 = projectRaw[agentKey];
|
|
150641
|
-
if (!isPlainObject(block2))
|
|
150642
|
-
continue;
|
|
150643
|
-
const removed = [];
|
|
150644
|
-
for (const field of AGENT_ESCALATION_FIELDS) {
|
|
150645
|
-
if (field in block2) {
|
|
150646
|
-
delete block2[field];
|
|
150647
|
-
removed.push(field);
|
|
150648
|
-
}
|
|
150649
|
-
}
|
|
150650
|
-
if (removed.length > 0) {
|
|
150651
|
-
warnings.push(`Ignoring ${agentKey}.${removed.join("/")} from project config ` + "(security: a repository cannot reprogram or re-permission hidden agents).");
|
|
150652
|
-
}
|
|
150653
|
-
}
|
|
150654
|
-
return warnings;
|
|
150655
|
-
}
|
|
150656
|
-
function normalizeEndpoint(value) {
|
|
150657
|
-
if (typeof value !== "string")
|
|
150658
|
-
return;
|
|
150659
|
-
const trimmed = value.trim().replace(/\/+$/, "");
|
|
150660
|
-
return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;
|
|
150661
|
-
}
|
|
150662
|
-
function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
150663
|
-
const projectEmbedding = projectRaw.embedding;
|
|
150664
|
-
if (!isPlainObject(projectEmbedding))
|
|
150665
|
-
return [];
|
|
150666
|
-
const redirectsEndpoint = "endpoint" in projectEmbedding;
|
|
150667
|
-
if (!redirectsEndpoint)
|
|
150668
|
-
return [];
|
|
150669
|
-
const userEmbedding = userRaw?.embedding;
|
|
150670
|
-
if (isPlainObject(userEmbedding)) {
|
|
150671
|
-
const projectEndpoint = normalizeEndpoint(projectEmbedding.endpoint);
|
|
150672
|
-
const userEndpoint = normalizeEndpoint(userEmbedding.endpoint);
|
|
150673
|
-
if (projectEndpoint !== undefined && projectEndpoint === userEndpoint) {
|
|
150674
|
-
return [];
|
|
150675
|
-
}
|
|
150676
|
-
}
|
|
150677
|
-
const providesOwnKey = typeof projectEmbedding.api_key === "string" && projectEmbedding.api_key.length > 0;
|
|
150678
|
-
if (providesOwnKey)
|
|
150679
|
-
return [];
|
|
150680
|
-
const mergedEmbedding = mergedRaw.embedding;
|
|
150681
|
-
if (!isPlainObject(mergedEmbedding))
|
|
150682
|
-
return [];
|
|
150683
|
-
if (!("api_key" in mergedEmbedding))
|
|
150684
|
-
return [];
|
|
150685
|
-
delete mergedEmbedding.api_key;
|
|
150686
|
-
return [
|
|
150687
|
-
"Dropped inherited user embedding api_key because project config redirected " + "embedding.endpoint without supplying its own key (security: prevents key " + "exfiltration to a repository-chosen endpoint)."
|
|
150688
|
-
];
|
|
150689
|
-
}
|
|
150690
|
-
var HIDDEN_AGENT_KEYS, AGENT_ESCALATION_FIELDS, EMBEDDING_DESTINATION_FIELDS;
|
|
150691
|
-
var init_project_security = __esm(() => {
|
|
150692
|
-
HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
150693
|
-
AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
150694
|
-
EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider"];
|
|
150695
|
-
});
|
|
150696
|
-
|
|
150697
|
-
// ../plugin/src/config/prune-config-leaf.ts
|
|
150698
|
-
function isPlainObject2(value) {
|
|
150699
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
150700
|
-
}
|
|
150701
|
-
function pruneNestedConfigLeaf(block2, relativePath) {
|
|
150702
|
-
if (relativePath.length === 0)
|
|
150703
|
-
return null;
|
|
150704
|
-
const result = { ...block2 };
|
|
150705
|
-
let cursor3 = result;
|
|
150706
|
-
for (let i2 = 0;i2 < relativePath.length - 1; i2++) {
|
|
150707
|
-
const seg = String(relativePath[i2]);
|
|
150708
|
-
const child = cursor3[seg];
|
|
150709
|
-
if (!isPlainObject2(child)) {
|
|
150710
|
-
if (!(seg in cursor3))
|
|
150711
|
-
return null;
|
|
150712
|
-
delete cursor3[seg];
|
|
150713
|
-
return {
|
|
150714
|
-
block: result,
|
|
150715
|
-
removed: relativePath.slice(0, i2 + 1).map(String).join(".")
|
|
150716
|
-
};
|
|
150717
|
-
}
|
|
150718
|
-
const clonedChild = { ...child };
|
|
150719
|
-
cursor3[seg] = clonedChild;
|
|
150720
|
-
cursor3 = clonedChild;
|
|
150721
|
-
}
|
|
150722
|
-
const leaf = String(relativePath[relativePath.length - 1]);
|
|
150723
|
-
if (!(leaf in cursor3))
|
|
150724
|
-
return null;
|
|
150725
|
-
delete cursor3[leaf];
|
|
150726
|
-
return { block: result, removed: relativePath.map(String).join(".") };
|
|
150727
|
-
}
|
|
150728
|
-
|
|
150729
150630
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/core/core.js
|
|
150730
150631
|
function $constructor(name2, initializer, params) {
|
|
150731
150632
|
function init(inst, def) {
|
|
@@ -150836,7 +150737,7 @@ __export(exports_util, {
|
|
|
150836
150737
|
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
150837
150738
|
joinValues: () => joinValues,
|
|
150838
150739
|
issue: () => issue,
|
|
150839
|
-
isPlainObject: () =>
|
|
150740
|
+
isPlainObject: () => isPlainObject,
|
|
150840
150741
|
isObject: () => isObject,
|
|
150841
150742
|
hexToUint8Array: () => hexToUint8Array,
|
|
150842
150743
|
getSizableOrigin: () => getSizableOrigin,
|
|
@@ -151001,7 +150902,7 @@ function slugify(input) {
|
|
|
151001
150902
|
function isObject(data) {
|
|
151002
150903
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
151003
150904
|
}
|
|
151004
|
-
function
|
|
150905
|
+
function isPlainObject(o2) {
|
|
151005
150906
|
if (isObject(o2) === false)
|
|
151006
150907
|
return false;
|
|
151007
150908
|
const ctor = o2.constructor;
|
|
@@ -151018,7 +150919,7 @@ function isPlainObject3(o2) {
|
|
|
151018
150919
|
return true;
|
|
151019
150920
|
}
|
|
151020
150921
|
function shallowClone(o2) {
|
|
151021
|
-
if (
|
|
150922
|
+
if (isPlainObject(o2))
|
|
151022
150923
|
return { ...o2 };
|
|
151023
150924
|
if (Array.isArray(o2))
|
|
151024
150925
|
return [...o2];
|
|
@@ -151158,7 +151059,7 @@ function omit(schema, mask) {
|
|
|
151158
151059
|
return clone(schema, def);
|
|
151159
151060
|
}
|
|
151160
151061
|
function extend(schema, shape) {
|
|
151161
|
-
if (!
|
|
151062
|
+
if (!isPlainObject(shape)) {
|
|
151162
151063
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
151163
151064
|
}
|
|
151164
151065
|
const checks = schema._zod.def.checks;
|
|
@@ -151181,7 +151082,7 @@ function extend(schema, shape) {
|
|
|
151181
151082
|
return clone(schema, def);
|
|
151182
151083
|
}
|
|
151183
151084
|
function safeExtend(schema, shape) {
|
|
151184
|
-
if (!
|
|
151085
|
+
if (!isPlainObject(shape)) {
|
|
151185
151086
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
151186
151087
|
}
|
|
151187
151088
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -152664,7 +152565,7 @@ function mergeValues(a3, b2) {
|
|
|
152664
152565
|
if (a3 instanceof Date && b2 instanceof Date && +a3 === +b2) {
|
|
152665
152566
|
return { valid: true, data: a3 };
|
|
152666
152567
|
}
|
|
152667
|
-
if (
|
|
152568
|
+
if (isPlainObject(a3) && isPlainObject(b2)) {
|
|
152668
152569
|
const bKeys = Object.keys(b2);
|
|
152669
152570
|
const sharedKeys = Object.keys(a3).filter((key) => bKeys.indexOf(key) !== -1);
|
|
152670
152571
|
const newObj = { ...a3, ...b2 };
|
|
@@ -153921,7 +153822,7 @@ var init_schemas = __esm(() => {
|
|
|
153921
153822
|
$ZodType.init(inst, def);
|
|
153922
153823
|
inst._zod.parse = (payload, ctx) => {
|
|
153923
153824
|
const input = payload.value;
|
|
153924
|
-
if (!
|
|
153825
|
+
if (!isPlainObject(input)) {
|
|
153925
153826
|
payload.issues.push({
|
|
153926
153827
|
expected: "record",
|
|
153927
153828
|
code: "invalid_type",
|
|
@@ -165587,6 +165488,10 @@ var init_magic_context = __esm(() => {
|
|
|
165587
165488
|
}).describe("Embedding provider configuration"),
|
|
165588
165489
|
temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add start/end date attributes on compartments. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
|
|
165589
165490
|
keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
|
|
165491
|
+
todowrite: exports_external.object({
|
|
165492
|
+
enabled: exports_external.boolean().default(true).describe("Pi only: register Magic Context's todowrite task-list tool. Disable if you use your own todo extension. OpenCode ships its own built-in todowrite; this setting has no effect there."),
|
|
165493
|
+
overlay: exports_external.boolean().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
|
|
165494
|
+
}).default({ enabled: true, overlay: true }).describe("Pi-only todowrite tool and overlay controls. Pi registers tools and widgets at extension boot, so changing this after /cd requires /reload or restart."),
|
|
165590
165495
|
smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest 5), and zero-value meta (bash_status, bash_kill, ctx_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
|
|
165591
165496
|
caveman_text_compression: exports_external.object({
|
|
165592
165497
|
enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Active for primary sessions when enabled; never for subagents. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
|
|
@@ -165624,10 +165529,332 @@ var init_magic_context = __esm(() => {
|
|
|
165624
165529
|
});
|
|
165625
165530
|
});
|
|
165626
165531
|
|
|
165532
|
+
// ../plugin/src/config/project-security.ts
|
|
165533
|
+
function isPlainObject2(value) {
|
|
165534
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
165535
|
+
}
|
|
165536
|
+
function isValidPercentageThreshold(value) {
|
|
165537
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 20 && value <= 80;
|
|
165538
|
+
}
|
|
165539
|
+
function isValidTokenThreshold(value) {
|
|
165540
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 5000 && value <= 2000000;
|
|
165541
|
+
}
|
|
165542
|
+
function normalizeTrustedPercentageThresholds(value) {
|
|
165543
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
165544
|
+
return { defaultValue: value, overrides: new Map };
|
|
165545
|
+
}
|
|
165546
|
+
if (isPlainObject2(value) && typeof value.default === "number" && Number.isFinite(value.default)) {
|
|
165547
|
+
const overrides = new Map;
|
|
165548
|
+
for (const [key, child] of Object.entries(value)) {
|
|
165549
|
+
if (key === "default")
|
|
165550
|
+
continue;
|
|
165551
|
+
if (typeof child === "number" && Number.isFinite(child)) {
|
|
165552
|
+
overrides.set(key, child);
|
|
165553
|
+
}
|
|
165554
|
+
}
|
|
165555
|
+
return { defaultValue: value.default, overrides };
|
|
165556
|
+
}
|
|
165557
|
+
return { defaultValue: DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, overrides: new Map };
|
|
165558
|
+
}
|
|
165559
|
+
function normalizeTrustedTokenThresholds(value) {
|
|
165560
|
+
if (!isPlainObject2(value)) {
|
|
165561
|
+
return { defaultValue: undefined, overrides: new Map };
|
|
165562
|
+
}
|
|
165563
|
+
const overrides = new Map;
|
|
165564
|
+
for (const [key, child] of Object.entries(value)) {
|
|
165565
|
+
if (key === "default")
|
|
165566
|
+
continue;
|
|
165567
|
+
if (typeof child === "number" && Number.isFinite(child)) {
|
|
165568
|
+
overrides.set(key, child);
|
|
165569
|
+
}
|
|
165570
|
+
}
|
|
165571
|
+
return {
|
|
165572
|
+
defaultValue: typeof value.default === "number" && Number.isFinite(value.default) ? value.default : undefined,
|
|
165573
|
+
overrides
|
|
165574
|
+
};
|
|
165575
|
+
}
|
|
165576
|
+
function clonePercentageThresholds(value) {
|
|
165577
|
+
return {
|
|
165578
|
+
defaultValue: value.defaultValue,
|
|
165579
|
+
overrides: new Map(value.overrides)
|
|
165580
|
+
};
|
|
165581
|
+
}
|
|
165582
|
+
function cloneTokenThresholds(value) {
|
|
165583
|
+
return {
|
|
165584
|
+
defaultValue: value.defaultValue,
|
|
165585
|
+
overrides: new Map(value.overrides)
|
|
165586
|
+
};
|
|
165587
|
+
}
|
|
165588
|
+
function percentageThresholdsEqual(left, right) {
|
|
165589
|
+
if (left.defaultValue !== right.defaultValue)
|
|
165590
|
+
return false;
|
|
165591
|
+
if (left.overrides.size !== right.overrides.size)
|
|
165592
|
+
return false;
|
|
165593
|
+
for (const [key, value] of left.overrides) {
|
|
165594
|
+
if (right.overrides.get(key) !== value)
|
|
165595
|
+
return false;
|
|
165596
|
+
}
|
|
165597
|
+
return true;
|
|
165598
|
+
}
|
|
165599
|
+
function setMergedPercentageThreshold(mergedRaw, value) {
|
|
165600
|
+
if (value.overrides.size === 0) {
|
|
165601
|
+
mergedRaw.execute_threshold_percentage = value.defaultValue;
|
|
165602
|
+
return;
|
|
165603
|
+
}
|
|
165604
|
+
const serialized = { default: value.defaultValue };
|
|
165605
|
+
for (const [key, threshold] of value.overrides) {
|
|
165606
|
+
serialized[key] = threshold;
|
|
165607
|
+
}
|
|
165608
|
+
mergedRaw.execute_threshold_percentage = serialized;
|
|
165609
|
+
}
|
|
165610
|
+
function setMergedTokenThreshold(mergedRaw, value) {
|
|
165611
|
+
if (value.defaultValue === undefined && value.overrides.size === 0) {
|
|
165612
|
+
delete mergedRaw.execute_threshold_tokens;
|
|
165613
|
+
return;
|
|
165614
|
+
}
|
|
165615
|
+
const serialized = {};
|
|
165616
|
+
if (value.defaultValue !== undefined) {
|
|
165617
|
+
serialized.default = value.defaultValue;
|
|
165618
|
+
}
|
|
165619
|
+
for (const [key, threshold] of value.overrides) {
|
|
165620
|
+
serialized[key] = threshold;
|
|
165621
|
+
}
|
|
165622
|
+
mergedRaw.execute_threshold_tokens = serialized;
|
|
165623
|
+
}
|
|
165624
|
+
function makeProjectThresholdWarning(field, reason) {
|
|
165625
|
+
return `Ignoring ${field} from project config (${reason})`;
|
|
165626
|
+
}
|
|
165627
|
+
function stripUnsafeProjectConfigFields(projectRaw) {
|
|
165628
|
+
const warnings = [];
|
|
165629
|
+
if ("auto_update" in projectRaw) {
|
|
165630
|
+
delete projectRaw.auto_update;
|
|
165631
|
+
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
165632
|
+
}
|
|
165633
|
+
if ("language" in projectRaw) {
|
|
165634
|
+
delete projectRaw.language;
|
|
165635
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
165636
|
+
}
|
|
165637
|
+
if ("sqlite" in projectRaw) {
|
|
165638
|
+
delete projectRaw.sqlite;
|
|
165639
|
+
warnings.push("Ignoring sqlite.* from project config (security: SQLite cache/mmap PRAGMAs apply to the " + "process-global shared database handle; only user-level config may set them).");
|
|
165640
|
+
}
|
|
165641
|
+
const embedding = projectRaw.embedding;
|
|
165642
|
+
if (isPlainObject2(embedding)) {
|
|
165643
|
+
const removed = [];
|
|
165644
|
+
for (const field of EMBEDDING_DESTINATION_FIELDS) {
|
|
165645
|
+
if (field in embedding) {
|
|
165646
|
+
delete embedding[field];
|
|
165647
|
+
removed.push(field);
|
|
165648
|
+
}
|
|
165649
|
+
}
|
|
165650
|
+
if (removed.length > 0) {
|
|
165651
|
+
warnings.push(`Ignoring embedding.${removed.join("/")} from project config ` + "(security: a repository cannot choose where private text is embedded).");
|
|
165652
|
+
}
|
|
165653
|
+
}
|
|
165654
|
+
const historian = projectRaw.historian;
|
|
165655
|
+
if (isPlainObject2(historian)) {
|
|
165656
|
+
const removed = [];
|
|
165657
|
+
for (const field of HISTORIAN_USER_ONLY_FIELDS) {
|
|
165658
|
+
if (field in historian) {
|
|
165659
|
+
delete historian[field];
|
|
165660
|
+
removed.push(field);
|
|
165661
|
+
}
|
|
165662
|
+
}
|
|
165663
|
+
if (removed.length > 0) {
|
|
165664
|
+
warnings.push(`Ignoring historian.${removed.join("/")} from project config ` + "(security: historian model selection is user-level only; a repository cannot force extra compaction cost).");
|
|
165665
|
+
}
|
|
165666
|
+
}
|
|
165667
|
+
for (const agentKey of HIDDEN_AGENT_KEYS) {
|
|
165668
|
+
const block2 = projectRaw[agentKey];
|
|
165669
|
+
if (!isPlainObject2(block2))
|
|
165670
|
+
continue;
|
|
165671
|
+
const removed = [];
|
|
165672
|
+
for (const field of AGENT_ESCALATION_FIELDS) {
|
|
165673
|
+
if (field in block2) {
|
|
165674
|
+
delete block2[field];
|
|
165675
|
+
removed.push(field);
|
|
165676
|
+
}
|
|
165677
|
+
}
|
|
165678
|
+
if (removed.length > 0) {
|
|
165679
|
+
warnings.push(`Ignoring ${agentKey}.${removed.join("/")} from project config ` + "(security: a repository cannot reprogram or re-permission hidden agents).");
|
|
165680
|
+
}
|
|
165681
|
+
}
|
|
165682
|
+
return warnings;
|
|
165683
|
+
}
|
|
165684
|
+
function constrainProjectThresholdOverrides(args) {
|
|
165685
|
+
const warnings = [];
|
|
165686
|
+
const basePercentage = normalizeTrustedPercentageThresholds(args.trustedBaseConfig.execute_threshold_percentage);
|
|
165687
|
+
const baseTokens = normalizeTrustedTokenThresholds(args.trustedBaseConfig.execute_threshold_tokens);
|
|
165688
|
+
if ("execute_threshold_percentage" in args.projectRaw) {
|
|
165689
|
+
const projectValue = args.projectRaw.execute_threshold_percentage;
|
|
165690
|
+
if (isValidPercentageThreshold(projectValue)) {
|
|
165691
|
+
const constrained = clonePercentageThresholds(basePercentage);
|
|
165692
|
+
constrained.defaultValue = Math.max(basePercentage.defaultValue, projectValue);
|
|
165693
|
+
for (const [modelKey, threshold] of basePercentage.overrides) {
|
|
165694
|
+
const raisedThreshold = Math.max(threshold, projectValue);
|
|
165695
|
+
if (raisedThreshold === constrained.defaultValue) {
|
|
165696
|
+
constrained.overrides.delete(modelKey);
|
|
165697
|
+
} else {
|
|
165698
|
+
constrained.overrides.set(modelKey, raisedThreshold);
|
|
165699
|
+
}
|
|
165700
|
+
}
|
|
165701
|
+
setMergedPercentageThreshold(args.mergedRaw, constrained);
|
|
165702
|
+
if (percentageThresholdsEqual(constrained, basePercentage)) {
|
|
165703
|
+
warnings.push(makeProjectThresholdWarning("execute_threshold_percentage", PERCENTAGE_THRESHOLD_REASON));
|
|
165704
|
+
}
|
|
165705
|
+
} else if (isPlainObject2(projectValue)) {
|
|
165706
|
+
const constrained = clonePercentageThresholds(basePercentage);
|
|
165707
|
+
let touchedValidEntry = false;
|
|
165708
|
+
if (isValidPercentageThreshold(projectValue.default)) {
|
|
165709
|
+
touchedValidEntry = true;
|
|
165710
|
+
if (projectValue.default > basePercentage.defaultValue) {
|
|
165711
|
+
constrained.defaultValue = projectValue.default;
|
|
165712
|
+
} else {
|
|
165713
|
+
warnings.push(makeProjectThresholdWarning("execute_threshold_percentage.default", PERCENTAGE_THRESHOLD_REASON));
|
|
165714
|
+
}
|
|
165715
|
+
}
|
|
165716
|
+
for (const [modelKey, rawValue] of Object.entries(projectValue)) {
|
|
165717
|
+
if (modelKey === "default")
|
|
165718
|
+
continue;
|
|
165719
|
+
if (!isValidPercentageThreshold(rawValue))
|
|
165720
|
+
continue;
|
|
165721
|
+
touchedValidEntry = true;
|
|
165722
|
+
const baseValue = basePercentage.overrides.get(modelKey) ?? basePercentage.defaultValue;
|
|
165723
|
+
if (rawValue > baseValue) {
|
|
165724
|
+
if (rawValue === constrained.defaultValue) {
|
|
165725
|
+
constrained.overrides.delete(modelKey);
|
|
165726
|
+
} else {
|
|
165727
|
+
constrained.overrides.set(modelKey, rawValue);
|
|
165728
|
+
}
|
|
165729
|
+
} else {
|
|
165730
|
+
warnings.push(makeProjectThresholdWarning(`execute_threshold_percentage.${modelKey}`, PERCENTAGE_THRESHOLD_REASON));
|
|
165731
|
+
}
|
|
165732
|
+
}
|
|
165733
|
+
if (touchedValidEntry) {
|
|
165734
|
+
setMergedPercentageThreshold(args.mergedRaw, constrained);
|
|
165735
|
+
}
|
|
165736
|
+
}
|
|
165737
|
+
}
|
|
165738
|
+
if ("execute_threshold_tokens" in args.projectRaw && isPlainObject2(args.projectRaw.execute_threshold_tokens)) {
|
|
165739
|
+
const projectValue = args.projectRaw.execute_threshold_tokens;
|
|
165740
|
+
const constrained = cloneTokenThresholds(baseTokens);
|
|
165741
|
+
let touchedValidEntry = false;
|
|
165742
|
+
if (isValidTokenThreshold(projectValue.default)) {
|
|
165743
|
+
touchedValidEntry = true;
|
|
165744
|
+
if (baseTokens.defaultValue === undefined) {
|
|
165745
|
+
warnings.push(makeProjectThresholdWarning("execute_threshold_tokens.default", TOKEN_THRESHOLD_INTRODUCTION_REASON));
|
|
165746
|
+
} else if (projectValue.default > baseTokens.defaultValue) {
|
|
165747
|
+
constrained.defaultValue = projectValue.default;
|
|
165748
|
+
} else {
|
|
165749
|
+
warnings.push(makeProjectThresholdWarning("execute_threshold_tokens.default", TOKEN_THRESHOLD_REASON));
|
|
165750
|
+
}
|
|
165751
|
+
}
|
|
165752
|
+
for (const [modelKey, rawValue] of Object.entries(projectValue)) {
|
|
165753
|
+
if (modelKey === "default")
|
|
165754
|
+
continue;
|
|
165755
|
+
if (!isValidTokenThreshold(rawValue))
|
|
165756
|
+
continue;
|
|
165757
|
+
touchedValidEntry = true;
|
|
165758
|
+
const baseValue = baseTokens.overrides.get(modelKey) ?? baseTokens.defaultValue;
|
|
165759
|
+
if (baseValue === undefined) {
|
|
165760
|
+
warnings.push(makeProjectThresholdWarning(`execute_threshold_tokens.${modelKey}`, TOKEN_THRESHOLD_INTRODUCTION_REASON));
|
|
165761
|
+
continue;
|
|
165762
|
+
}
|
|
165763
|
+
if (rawValue > baseValue) {
|
|
165764
|
+
if (rawValue === constrained.defaultValue) {
|
|
165765
|
+
constrained.overrides.delete(modelKey);
|
|
165766
|
+
} else {
|
|
165767
|
+
constrained.overrides.set(modelKey, rawValue);
|
|
165768
|
+
}
|
|
165769
|
+
} else {
|
|
165770
|
+
warnings.push(makeProjectThresholdWarning(`execute_threshold_tokens.${modelKey}`, TOKEN_THRESHOLD_REASON));
|
|
165771
|
+
}
|
|
165772
|
+
}
|
|
165773
|
+
if (touchedValidEntry) {
|
|
165774
|
+
setMergedTokenThreshold(args.mergedRaw, constrained);
|
|
165775
|
+
}
|
|
165776
|
+
}
|
|
165777
|
+
return warnings;
|
|
165778
|
+
}
|
|
165779
|
+
function normalizeEndpoint(value) {
|
|
165780
|
+
if (typeof value !== "string")
|
|
165781
|
+
return;
|
|
165782
|
+
const trimmed = value.trim().replace(/\/+$/, "");
|
|
165783
|
+
return trimmed.length > 0 ? trimmed.toLowerCase() : undefined;
|
|
165784
|
+
}
|
|
165785
|
+
function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
|
|
165786
|
+
const projectEmbedding = projectRaw.embedding;
|
|
165787
|
+
if (!isPlainObject2(projectEmbedding))
|
|
165788
|
+
return [];
|
|
165789
|
+
const redirectsEndpoint = "endpoint" in projectEmbedding;
|
|
165790
|
+
if (!redirectsEndpoint)
|
|
165791
|
+
return [];
|
|
165792
|
+
const userEmbedding = userRaw?.embedding;
|
|
165793
|
+
if (isPlainObject2(userEmbedding)) {
|
|
165794
|
+
const projectEndpoint = normalizeEndpoint(projectEmbedding.endpoint);
|
|
165795
|
+
const userEndpoint = normalizeEndpoint(userEmbedding.endpoint);
|
|
165796
|
+
if (projectEndpoint !== undefined && projectEndpoint === userEndpoint) {
|
|
165797
|
+
return [];
|
|
165798
|
+
}
|
|
165799
|
+
}
|
|
165800
|
+
const providesOwnKey = typeof projectEmbedding.api_key === "string" && projectEmbedding.api_key.length > 0;
|
|
165801
|
+
if (providesOwnKey)
|
|
165802
|
+
return [];
|
|
165803
|
+
const mergedEmbedding = mergedRaw.embedding;
|
|
165804
|
+
if (!isPlainObject2(mergedEmbedding))
|
|
165805
|
+
return [];
|
|
165806
|
+
if (!("api_key" in mergedEmbedding))
|
|
165807
|
+
return [];
|
|
165808
|
+
delete mergedEmbedding.api_key;
|
|
165809
|
+
return [
|
|
165810
|
+
"Dropped inherited user embedding api_key because project config redirected " + "embedding.endpoint without supplying its own key (security: prevents key " + "exfiltration to a repository-chosen endpoint)."
|
|
165811
|
+
];
|
|
165812
|
+
}
|
|
165813
|
+
var HIDDEN_AGENT_KEYS, HISTORIAN_USER_ONLY_FIELDS, AGENT_ESCALATION_FIELDS, EMBEDDING_DESTINATION_FIELDS, PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.", TOKEN_THRESHOLD_REASON = "security: a repository may only raise execute_threshold_tokens above the user's trusted token threshold; it cannot force earlier historian work or cloned-repo cost escalation.", TOKEN_THRESHOLD_INTRODUCTION_REASON = "security: a repository cannot introduce a new execute_threshold_tokens override when the user has no trusted token threshold for that key; that could force earlier historian work or cloned-repo cost escalation.";
|
|
165814
|
+
var init_project_security = __esm(() => {
|
|
165815
|
+
init_magic_context();
|
|
165816
|
+
HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
165817
|
+
HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
|
|
165818
|
+
AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
165819
|
+
EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider"];
|
|
165820
|
+
});
|
|
165821
|
+
|
|
165822
|
+
// ../plugin/src/config/prune-config-leaf.ts
|
|
165823
|
+
function isPlainObject3(value) {
|
|
165824
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
165825
|
+
}
|
|
165826
|
+
function pruneNestedConfigLeaf(block2, relativePath) {
|
|
165827
|
+
if (relativePath.length === 0)
|
|
165828
|
+
return null;
|
|
165829
|
+
const result = { ...block2 };
|
|
165830
|
+
let cursor3 = result;
|
|
165831
|
+
for (let i2 = 0;i2 < relativePath.length - 1; i2++) {
|
|
165832
|
+
const seg = String(relativePath[i2]);
|
|
165833
|
+
const child = cursor3[seg];
|
|
165834
|
+
if (!isPlainObject3(child)) {
|
|
165835
|
+
if (!(seg in cursor3))
|
|
165836
|
+
return null;
|
|
165837
|
+
delete cursor3[seg];
|
|
165838
|
+
return {
|
|
165839
|
+
block: result,
|
|
165840
|
+
removed: relativePath.slice(0, i2 + 1).map(String).join(".")
|
|
165841
|
+
};
|
|
165842
|
+
}
|
|
165843
|
+
const clonedChild = { ...child };
|
|
165844
|
+
cursor3[seg] = clonedChild;
|
|
165845
|
+
cursor3 = clonedChild;
|
|
165846
|
+
}
|
|
165847
|
+
const leaf = String(relativePath[relativePath.length - 1]);
|
|
165848
|
+
if (!(leaf in cursor3))
|
|
165849
|
+
return null;
|
|
165850
|
+
delete cursor3[leaf];
|
|
165851
|
+
return { block: result, removed: relativePath.map(String).join(".") };
|
|
165852
|
+
}
|
|
165853
|
+
|
|
165627
165854
|
// ../plugin/src/config/variable.ts
|
|
165628
|
-
import { existsSync as
|
|
165855
|
+
import { existsSync as existsSync16, readFileSync as readFileSync8 } from "node:fs";
|
|
165629
165856
|
import { homedir as homedir9 } from "node:os";
|
|
165630
|
-
import { dirname as
|
|
165857
|
+
import { dirname as dirname10, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
|
|
165631
165858
|
function sensitiveFilePathReason(resolvedPath) {
|
|
165632
165859
|
const home = homedir9();
|
|
165633
165860
|
const sensitiveDirs = [
|
|
@@ -165674,7 +165901,7 @@ function substituteConfigVariables(input) {
|
|
|
165674
165901
|
if (fileMatches.length === 0) {
|
|
165675
165902
|
return { text: text3, warnings };
|
|
165676
165903
|
}
|
|
165677
|
-
const configDir = input.configPath ?
|
|
165904
|
+
const configDir = input.configPath ? dirname10(input.configPath) : process.cwd();
|
|
165678
165905
|
let output = "";
|
|
165679
165906
|
let cursor3 = 0;
|
|
165680
165907
|
for (const match of fileMatches) {
|
|
@@ -165700,7 +165927,7 @@ function substituteConfigVariables(input) {
|
|
|
165700
165927
|
if (sensitiveReason) {
|
|
165701
165928
|
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
165702
165929
|
}
|
|
165703
|
-
if (!
|
|
165930
|
+
if (!existsSync16(filePath)) {
|
|
165704
165931
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
165705
165932
|
continue;
|
|
165706
165933
|
}
|
|
@@ -165725,7 +165952,7 @@ var init_variable = __esm(() => {
|
|
|
165725
165952
|
});
|
|
165726
165953
|
|
|
165727
165954
|
// ../plugin/src/config/index.ts
|
|
165728
|
-
import { existsSync as
|
|
165955
|
+
import { existsSync as existsSync17, readFileSync as readFileSync9 } from "node:fs";
|
|
165729
165956
|
function getUserConfigBasePath() {
|
|
165730
165957
|
return cortexKitUserConfigBasePath();
|
|
165731
165958
|
}
|
|
@@ -165733,10 +165960,10 @@ function getProjectConfigBasePath(directory) {
|
|
|
165733
165960
|
return cortexKitProjectConfigBasePath(directory);
|
|
165734
165961
|
}
|
|
165735
165962
|
function resolveLegacyReadFallback(sources) {
|
|
165736
|
-
return { source: sources.find((s) =>
|
|
165963
|
+
return { source: sources.find((s) => existsSync17(s.path)) ?? null };
|
|
165737
165964
|
}
|
|
165738
165965
|
function loadConfigFileDetailed(configPath, source) {
|
|
165739
|
-
if (!
|
|
165966
|
+
if (!existsSync17(configPath)) {
|
|
165740
165967
|
return null;
|
|
165741
165968
|
}
|
|
165742
165969
|
let rawText;
|
|
@@ -165951,12 +166178,13 @@ function loadPluginConfigDetailed(directory) {
|
|
|
165951
166178
|
const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
|
|
165952
166179
|
const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
|
|
165953
166180
|
const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
|
|
165954
|
-
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) =>
|
|
165955
|
-
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) =>
|
|
166181
|
+
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync17(source.path));
|
|
166182
|
+
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync17(source.path));
|
|
165956
166183
|
const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
|
|
165957
166184
|
const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
|
|
165958
166185
|
const allWarnings = [];
|
|
165959
166186
|
let mergedRaw = {};
|
|
166187
|
+
const trustedBaseConfig = parsePluginConfig(userLoaded?.config ?? {});
|
|
165960
166188
|
if (userLegacyFallback.source) {
|
|
165961
166189
|
allWarnings.push(`[user config] reading legacy config from ${userLegacyFallback.source.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
|
|
165962
166190
|
} else if (legacyUserUnmigrated) {
|
|
@@ -165981,6 +166209,13 @@ function loadPluginConfigDetailed(directory) {
|
|
|
165981
166209
|
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userLoaded?.config)) {
|
|
165982
166210
|
allWarnings.push(`[project config] ${warning}`);
|
|
165983
166211
|
}
|
|
166212
|
+
for (const warning of constrainProjectThresholdOverrides({
|
|
166213
|
+
mergedRaw,
|
|
166214
|
+
projectRaw,
|
|
166215
|
+
trustedBaseConfig
|
|
166216
|
+
})) {
|
|
166217
|
+
allWarnings.push(`[project config] ${warning}`);
|
|
166218
|
+
}
|
|
165984
166219
|
}
|
|
165985
166220
|
const recoveredTopLevelKeys = [];
|
|
165986
166221
|
const config2 = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
|
|
@@ -166137,14 +166372,14 @@ var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
|
|
|
166137
166372
|
// ../plugin/src/shared/tui-config.ts
|
|
166138
166373
|
import {
|
|
166139
166374
|
chmodSync as chmodSync3,
|
|
166140
|
-
existsSync as
|
|
166141
|
-
mkdirSync as
|
|
166375
|
+
existsSync as existsSync18,
|
|
166376
|
+
mkdirSync as mkdirSync7,
|
|
166142
166377
|
readFileSync as readFileSync10,
|
|
166143
166378
|
renameSync as renameSync3,
|
|
166144
166379
|
statSync as statSync6,
|
|
166145
|
-
writeFileSync as
|
|
166380
|
+
writeFileSync as writeFileSync4
|
|
166146
166381
|
} from "node:fs";
|
|
166147
|
-
import { dirname as
|
|
166382
|
+
import { dirname as dirname11, join as join15 } from "node:path";
|
|
166148
166383
|
function pluginEntryId(entry) {
|
|
166149
166384
|
if (typeof entry === "string")
|
|
166150
166385
|
return entry;
|
|
@@ -166175,7 +166410,7 @@ function writeTuiConfigAtomic(configPath, config2) {
|
|
|
166175
166410
|
const body = `${import_comment_json6.stringify(config2, null, 2)}
|
|
166176
166411
|
`;
|
|
166177
166412
|
const tmpPath = `${configPath}.tmp`;
|
|
166178
|
-
|
|
166413
|
+
writeFileSync4(tmpPath, body);
|
|
166179
166414
|
try {
|
|
166180
166415
|
if (statSync6(configPath, { throwIfNoEntry: false })?.isFile()) {
|
|
166181
166416
|
chmodSync3(tmpPath, statSync6(configPath).mode & 511);
|
|
@@ -166187,9 +166422,9 @@ function resolveTuiConfigPath() {
|
|
|
166187
166422
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
166188
166423
|
const jsoncPath = join15(configDir, "tui.jsonc");
|
|
166189
166424
|
const jsonPath = join15(configDir, "tui.json");
|
|
166190
|
-
if (
|
|
166425
|
+
if (existsSync18(jsoncPath))
|
|
166191
166426
|
return jsoncPath;
|
|
166192
|
-
if (
|
|
166427
|
+
if (existsSync18(jsonPath))
|
|
166193
166428
|
return jsonPath;
|
|
166194
166429
|
return jsoncPath;
|
|
166195
166430
|
}
|
|
@@ -166197,7 +166432,7 @@ function ensureTuiPluginEntry() {
|
|
|
166197
166432
|
try {
|
|
166198
166433
|
const configPath = resolveTuiConfigPath();
|
|
166199
166434
|
let config2 = {};
|
|
166200
|
-
if (
|
|
166435
|
+
if (existsSync18(configPath)) {
|
|
166201
166436
|
const raw = readFileSync10(configPath, "utf-8");
|
|
166202
166437
|
config2 = import_comment_json6.parse(raw) ?? {};
|
|
166203
166438
|
}
|
|
@@ -166232,7 +166467,7 @@ function ensureTuiPluginEntry() {
|
|
|
166232
166467
|
}
|
|
166233
166468
|
}
|
|
166234
166469
|
config2.plugin = plugins;
|
|
166235
|
-
|
|
166470
|
+
mkdirSync7(dirname11(configPath), { recursive: true });
|
|
166236
166471
|
writeTuiConfigAtomic(configPath, config2);
|
|
166237
166472
|
log3(`[magic-context] updated TUI plugin entry in ${configPath}`);
|
|
166238
166473
|
return true;
|
|
@@ -166487,6 +166722,8 @@ function sanitizeDiagnosticText(value) {
|
|
|
166487
166722
|
return redactSecretText(sanitizePathString(value));
|
|
166488
166723
|
}
|
|
166489
166724
|
function sanitizeConfigValue(value, keyPath = []) {
|
|
166725
|
+
if (value === null || typeof value === "number" || typeof value === "boolean")
|
|
166726
|
+
return value;
|
|
166490
166727
|
const key = keyPath.at(-1) ?? "";
|
|
166491
166728
|
if (key && isSecretKey(key)) {
|
|
166492
166729
|
return `<REDACTED:${redactionTypeForKey(key)}>`;
|
|
@@ -166592,12 +166829,29 @@ var init_redaction = __esm(() => {
|
|
|
166592
166829
|
});
|
|
166593
166830
|
|
|
166594
166831
|
// src/lib/redaction.ts
|
|
166832
|
+
function sanitizeDiagnosticEndpoint(value) {
|
|
166833
|
+
const trimmed = value.trim();
|
|
166834
|
+
if (!trimmed)
|
|
166835
|
+
return sanitizeDiagnosticText(value);
|
|
166836
|
+
try {
|
|
166837
|
+
const url2 = new URL(trimmed);
|
|
166838
|
+
url2.username = "";
|
|
166839
|
+
url2.password = "";
|
|
166840
|
+
url2.search = "";
|
|
166841
|
+
url2.hash = "";
|
|
166842
|
+
return sanitizeDiagnosticText(url2.toString());
|
|
166843
|
+
} catch {
|
|
166844
|
+
const withoutQuery = trimmed.replace(/[?#].*$/, "");
|
|
166845
|
+
const withoutUserInfo = withoutQuery.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/@\s]+@/i, "$1");
|
|
166846
|
+
return sanitizeDiagnosticText(withoutUserInfo);
|
|
166847
|
+
}
|
|
166848
|
+
}
|
|
166595
166849
|
var init_redaction2 = __esm(() => {
|
|
166596
166850
|
init_redaction();
|
|
166597
166851
|
});
|
|
166598
166852
|
|
|
166599
166853
|
// src/lib/diagnostics-opencode.ts
|
|
166600
|
-
import { existsSync as
|
|
166854
|
+
import { existsSync as existsSync19, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync7 } from "node:fs";
|
|
166601
166855
|
import { createRequire as createRequire2 } from "node:module";
|
|
166602
166856
|
import { homedir as homedir11 } from "node:os";
|
|
166603
166857
|
import { join as join16 } from "node:path";
|
|
@@ -166618,7 +166872,7 @@ function getPluginCacheInfo() {
|
|
|
166618
166872
|
let cached2;
|
|
166619
166873
|
for (const installedPkgPath of getOpenCodePluginPackageJsonPaths()) {
|
|
166620
166874
|
try {
|
|
166621
|
-
if (
|
|
166875
|
+
if (existsSync19(installedPkgPath)) {
|
|
166622
166876
|
const pkg = JSON.parse(readFileSync11(installedPkgPath, "utf-8"));
|
|
166623
166877
|
cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
166624
166878
|
if (cached2)
|
|
@@ -166636,7 +166890,7 @@ function getStorageDir() {
|
|
|
166636
166890
|
}
|
|
166637
166891
|
function fileSize(path6) {
|
|
166638
166892
|
try {
|
|
166639
|
-
return
|
|
166893
|
+
return existsSync19(path6) ? statSync7(path6).size : 0;
|
|
166640
166894
|
} catch {
|
|
166641
166895
|
return 0;
|
|
166642
166896
|
}
|
|
@@ -166648,7 +166902,7 @@ function sanitizeValue(value) {
|
|
|
166648
166902
|
return sanitizeConfigValue(value);
|
|
166649
166903
|
}
|
|
166650
166904
|
function readConfig2(path6) {
|
|
166651
|
-
if (!
|
|
166905
|
+
if (!existsSync19(path6))
|
|
166652
166906
|
return { value: null };
|
|
166653
166907
|
try {
|
|
166654
166908
|
const raw = readFileSync11(path6, "utf-8");
|
|
@@ -166709,7 +166963,7 @@ function parseHistorianDumpMeta(path6) {
|
|
|
166709
166963
|
}
|
|
166710
166964
|
}
|
|
166711
166965
|
function listDumpsInDir(dir, limit) {
|
|
166712
|
-
if (!
|
|
166966
|
+
if (!existsSync19(dir))
|
|
166713
166967
|
return { count: 0, recent: [] };
|
|
166714
166968
|
try {
|
|
166715
166969
|
const entries = readdirSync2(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
|
|
@@ -166777,8 +167031,9 @@ function collectHistorianDumps(recentSessions) {
|
|
|
166777
167031
|
};
|
|
166778
167032
|
}
|
|
166779
167033
|
async function collectRecentSessions() {
|
|
166780
|
-
const
|
|
166781
|
-
|
|
167034
|
+
const dataHome = process.env.XDG_DATA_HOME || join16(process.env.HOME || homedir11(), ".local", "share");
|
|
167035
|
+
const opencodeDbPath = join16(dataHome, "opencode", "opencode.db");
|
|
167036
|
+
if (!existsSync19(opencodeDbPath))
|
|
166782
167037
|
return [];
|
|
166783
167038
|
if (typeof globalThis.Bun === "undefined") {
|
|
166784
167039
|
return [];
|
|
@@ -166813,7 +167068,7 @@ async function collectRecentSessions() {
|
|
|
166813
167068
|
}
|
|
166814
167069
|
async function collectHistorianFailures(storageDirPath) {
|
|
166815
167070
|
const contextDbPath = join16(storageDirPath, "context.db");
|
|
166816
|
-
if (!
|
|
167071
|
+
if (!existsSync19(contextDbPath))
|
|
166817
167072
|
return [];
|
|
166818
167073
|
if (typeof globalThis.Bun === "undefined") {
|
|
166819
167074
|
return [];
|
|
@@ -166847,7 +167102,7 @@ async function collectHistorianFailures(storageDirPath) {
|
|
|
166847
167102
|
}
|
|
166848
167103
|
async function collectHistorianRuns(storageDirPath) {
|
|
166849
167104
|
const contextDbPath = join16(storageDirPath, "context.db");
|
|
166850
|
-
if (!
|
|
167105
|
+
if (!existsSync19(contextDbPath))
|
|
166851
167106
|
return [];
|
|
166852
167107
|
if (typeof globalThis.Bun === "undefined")
|
|
166853
167108
|
return [];
|
|
@@ -166918,7 +167173,7 @@ async function collectDiagnostics() {
|
|
|
166918
167173
|
const storageDirPath = getStorageDir();
|
|
166919
167174
|
const contextDbPath = join16(storageDirPath, "context.db");
|
|
166920
167175
|
const logPath = getMagicContextLogPath2("opencode");
|
|
166921
|
-
const logFileSize =
|
|
167176
|
+
const logFileSize = existsSync19(logPath) ? statSync7(logPath).size : 0;
|
|
166922
167177
|
const conflictResult = detectConflicts(process.cwd());
|
|
166923
167178
|
const recentSessions = await collectRecentSessions();
|
|
166924
167179
|
const openCodeDetection = detectOpenCode();
|
|
@@ -166937,14 +167192,14 @@ async function collectDiagnostics() {
|
|
|
166937
167192
|
opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
|
|
166938
167193
|
tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
|
|
166939
167194
|
magicContextConfig: {
|
|
166940
|
-
exists:
|
|
167195
|
+
exists: existsSync19(configPaths.magicContextConfig),
|
|
166941
167196
|
...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
|
|
166942
167197
|
flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
|
|
166943
167198
|
},
|
|
166944
167199
|
pluginCache: getPluginCacheInfo(),
|
|
166945
167200
|
storageDir: {
|
|
166946
167201
|
path: storageDirPath,
|
|
166947
|
-
exists:
|
|
167202
|
+
exists: existsSync19(storageDirPath),
|
|
166948
167203
|
contextDbSizeBytes: fileSize(contextDbPath)
|
|
166949
167204
|
},
|
|
166950
167205
|
conflicts: {
|
|
@@ -166953,7 +167208,7 @@ async function collectDiagnostics() {
|
|
|
166953
167208
|
},
|
|
166954
167209
|
logFile: {
|
|
166955
167210
|
path: logPath,
|
|
166956
|
-
exists:
|
|
167211
|
+
exists: existsSync19(logPath),
|
|
166957
167212
|
sizeKb: Math.round(logFileSize / 1024)
|
|
166958
167213
|
},
|
|
166959
167214
|
recentSessions,
|
|
@@ -167007,7 +167262,7 @@ function renderDiagnosticsMarkdown(report) {
|
|
|
167007
167262
|
};
|
|
167008
167263
|
const recentSessions = report.recentSessions.map((session) => ({
|
|
167009
167264
|
sessionId: session.sessionId,
|
|
167010
|
-
title: session.title,
|
|
167265
|
+
title: sanitizeDiagnosticText(session.title),
|
|
167011
167266
|
directory: sanitizeString(session.directory),
|
|
167012
167267
|
lastActiveAt: session.lastActiveAt
|
|
167013
167268
|
}));
|
|
@@ -167093,9 +167348,9 @@ var init_diagnostics_opencode = __esm(() => {
|
|
|
167093
167348
|
|
|
167094
167349
|
// src/lib/embedding-runtime.ts
|
|
167095
167350
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
167096
|
-
import { existsSync as
|
|
167351
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
167097
167352
|
import { createRequire as createRequire3 } from "node:module";
|
|
167098
|
-
import { dirname as
|
|
167353
|
+
import { dirname as dirname12, join as join17, sep } from "node:path";
|
|
167099
167354
|
function describeError(error51) {
|
|
167100
167355
|
const message = error51 instanceof Error ? error51.message : String(error51 ?? "unknown error");
|
|
167101
167356
|
const code = error51?.code;
|
|
@@ -167208,7 +167463,7 @@ function expectedBinaryRelPath(platform, arch) {
|
|
|
167208
167463
|
}
|
|
167209
167464
|
function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch) {
|
|
167210
167465
|
const packageDir = join17(installRoot, "node_modules", "onnxruntime-node");
|
|
167211
|
-
if (!
|
|
167466
|
+
if (!existsSync20(join17(packageDir, "package.json"))) {
|
|
167212
167467
|
return { state: "package-missing", packageDir };
|
|
167213
167468
|
}
|
|
167214
167469
|
const rel = expectedBinaryRelPath(platform, arch);
|
|
@@ -167216,13 +167471,13 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
|
|
|
167216
167471
|
return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath: packageDir };
|
|
167217
167472
|
}
|
|
167218
167473
|
const binaryPath = join17(packageDir, rel);
|
|
167219
|
-
if (!
|
|
167474
|
+
if (!existsSync20(binaryPath)) {
|
|
167220
167475
|
return { state: "binary-missing", packageDir, expectedBinary: binaryPath };
|
|
167221
167476
|
}
|
|
167222
167477
|
return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath };
|
|
167223
167478
|
}
|
|
167224
167479
|
function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch) {
|
|
167225
|
-
const existing = installRoots.filter((root) =>
|
|
167480
|
+
const existing = installRoots.filter((root) => existsSync20(root));
|
|
167226
167481
|
if (existing.length === 0) {
|
|
167227
167482
|
return {
|
|
167228
167483
|
state: "unknown",
|
|
@@ -167242,10 +167497,10 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
|
|
|
167242
167497
|
function packageDirFromResolved(resolvedPath, packageName) {
|
|
167243
167498
|
const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
|
|
167244
167499
|
const idx = resolvedPath.indexOf(marker);
|
|
167245
|
-
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) :
|
|
167500
|
+
return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname12(resolvedPath);
|
|
167246
167501
|
}
|
|
167247
167502
|
function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch) {
|
|
167248
|
-
if (!
|
|
167503
|
+
if (!existsSync20(join17(pluginDir, "package.json"))) {
|
|
167249
167504
|
return { state: "unknown", reason: "plugin package dir not found" };
|
|
167250
167505
|
}
|
|
167251
167506
|
let onnxDir = null;
|
|
@@ -167281,7 +167536,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
|
|
|
167281
167536
|
return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
|
|
167282
167537
|
}
|
|
167283
167538
|
const binaryPath = join17(onnxDir, rel);
|
|
167284
|
-
if (!
|
|
167539
|
+
if (!existsSync20(binaryPath)) {
|
|
167285
167540
|
return { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
|
|
167286
167541
|
}
|
|
167287
167542
|
return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath };
|
|
@@ -167327,33 +167582,30 @@ function extractRecentErrors(sanitized, limit = 20) {
|
|
|
167327
167582
|
function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
167328
167583
|
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
167329
167584
|
return body;
|
|
167585
|
+
let capped = body;
|
|
167330
167586
|
const heading = "## Log (last";
|
|
167331
167587
|
const headingIdx = body.indexOf(heading);
|
|
167332
167588
|
if (headingIdx === -1) {
|
|
167333
|
-
const
|
|
167334
|
-
|
|
167335
|
-
|
|
167336
|
-
`;
|
|
167337
|
-
const markerBytes2 = Buffer.byteLength(marker, "utf8");
|
|
167338
|
-
return truncateToByteBudget(body, maxBytes - markerBytes2) + marker;
|
|
167589
|
+
const markerBytes2 = Buffer.byteLength(FALLBACK_TRUNCATION_MARKER, "utf8");
|
|
167590
|
+
capped = truncateToByteBudget(body, maxBytes - markerBytes2) + FALLBACK_TRUNCATION_MARKER;
|
|
167591
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
167339
167592
|
}
|
|
167340
167593
|
const fenceOpenIdx = body.indexOf("\n```", headingIdx);
|
|
167341
167594
|
if (fenceOpenIdx === -1)
|
|
167342
|
-
return body;
|
|
167595
|
+
return enforceFinalBodyLimit(body, maxBytes);
|
|
167343
167596
|
const logStart = fenceOpenIdx + "\n```\n".length;
|
|
167344
167597
|
const fenceCloseIdx = body.indexOf("\n```", logStart);
|
|
167345
167598
|
if (fenceCloseIdx === -1)
|
|
167346
|
-
return body;
|
|
167599
|
+
return enforceFinalBodyLimit(body, maxBytes);
|
|
167347
167600
|
const head = body.slice(0, logStart);
|
|
167348
167601
|
const log4 = body.slice(logStart, fenceCloseIdx);
|
|
167349
167602
|
const tail = body.slice(fenceCloseIdx);
|
|
167350
167603
|
const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
167351
|
-
const
|
|
167352
|
-
`;
|
|
167353
|
-
const markerBytes = Buffer.byteLength(truncationMarker, "utf8");
|
|
167604
|
+
const markerBytes = Buffer.byteLength(LOG_TRUNCATION_MARKER, "utf8");
|
|
167354
167605
|
const logBudget = maxBytes - overheadBytes - markerBytes;
|
|
167355
167606
|
if (logBudget <= 0) {
|
|
167356
|
-
|
|
167607
|
+
capped = `${head}${LOG_TRUNCATION_MARKER}${tail}`;
|
|
167608
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
167357
167609
|
}
|
|
167358
167610
|
const lines = log4.split(`
|
|
167359
167611
|
`);
|
|
@@ -167369,7 +167621,17 @@ function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
|
167369
167621
|
if (Buffer.byteLength(kept, "utf8") > logBudget) {
|
|
167370
167622
|
kept = truncateToByteBudget(kept, logBudget);
|
|
167371
167623
|
}
|
|
167372
|
-
|
|
167624
|
+
capped = `${head}${LOG_TRUNCATION_MARKER}${kept}${tail}`;
|
|
167625
|
+
return enforceFinalBodyLimit(capped, maxBytes);
|
|
167626
|
+
}
|
|
167627
|
+
function enforceFinalBodyLimit(body, maxBytes) {
|
|
167628
|
+
if (Buffer.byteLength(body, "utf8") <= maxBytes)
|
|
167629
|
+
return body;
|
|
167630
|
+
const markerBytes = Buffer.byteLength(FINAL_TRUNCATION_MARKER, "utf8");
|
|
167631
|
+
if (markerBytes >= maxBytes) {
|
|
167632
|
+
return truncateToByteBudget(FINAL_TRUNCATION_MARKER, maxBytes);
|
|
167633
|
+
}
|
|
167634
|
+
return truncateToByteBudget(body, maxBytes - markerBytes) + FINAL_TRUNCATION_MARKER;
|
|
167373
167635
|
}
|
|
167374
167636
|
function truncateToByteBudget(input, maxBytes) {
|
|
167375
167637
|
if (maxBytes <= 0)
|
|
@@ -167383,7 +167645,14 @@ function truncateToByteBudget(input, maxBytes) {
|
|
|
167383
167645
|
}
|
|
167384
167646
|
return buf.subarray(0, end).toString("utf8");
|
|
167385
167647
|
}
|
|
167386
|
-
var MAX_GITHUB_BODY_BYTES = 60000,
|
|
167648
|
+
var MAX_GITHUB_BODY_BYTES = 60000, LOG_TRUNCATION_MARKER = `[truncated for GitHub 64KB limit — older log lines dropped]
|
|
167649
|
+
`, FINAL_TRUNCATION_MARKER = `
|
|
167650
|
+
|
|
167651
|
+
[truncated further to fit GitHub body limit]
|
|
167652
|
+
`, FALLBACK_TRUNCATION_MARKER = `
|
|
167653
|
+
|
|
167654
|
+
[truncated for GitHub 64KB limit]
|
|
167655
|
+
`, ERROR_LOG_PATTERNS;
|
|
167387
167656
|
var init_issue_body = __esm(() => {
|
|
167388
167657
|
ERROR_LOG_PATTERNS = [
|
|
167389
167658
|
/\bfailed:/i,
|
|
@@ -167396,8 +167665,7 @@ var init_issue_body = __esm(() => {
|
|
|
167396
167665
|
});
|
|
167397
167666
|
|
|
167398
167667
|
// src/lib/logs-opencode.ts
|
|
167399
|
-
import { readFileSync as readFileSync12, writeFileSync as
|
|
167400
|
-
import { homedir as homedir12 } from "node:os";
|
|
167668
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "node:fs";
|
|
167401
167669
|
import { join as join18 } from "node:path";
|
|
167402
167670
|
function sanitizeLogContent(content) {
|
|
167403
167671
|
return sanitizeDiagnosticText(content);
|
|
@@ -167438,7 +167706,7 @@ function filterLogLinesBySession(lines, sessionId) {
|
|
|
167438
167706
|
return matches.every((id) => id === sessionId);
|
|
167439
167707
|
});
|
|
167440
167708
|
}
|
|
167441
|
-
async function bundleIssueReport(report, description,
|
|
167709
|
+
async function bundleIssueReport(report, description, title, sessionFilter = null) {
|
|
167442
167710
|
const LOG_TAIL_LINES = 400;
|
|
167443
167711
|
const allLogLines = report.logFile.exists ? readFileSync12(report.logFile.path, "utf-8").split(/\r?\n/) : [];
|
|
167444
167712
|
const logLines = filterLogLinesBySession(allLogLines, sessionFilter);
|
|
@@ -167451,10 +167719,13 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
167451
167719
|
`));
|
|
167452
167720
|
const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
|
|
167453
167721
|
const configBody = JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2);
|
|
167454
|
-
const sanitizedConfigPath = report.configPaths.magicContextConfig
|
|
167722
|
+
const sanitizedConfigPath = sanitizeDiagnosticText(report.configPaths.magicContextConfig);
|
|
167723
|
+
const sanitizedDescription = sanitizeDiagnosticText(description);
|
|
167724
|
+
const sanitizedTitle = sanitizeDiagnosticText(title).trim();
|
|
167455
167725
|
const rawBodyMarkdown = [
|
|
167726
|
+
...sanitizedTitle ? ["## Title", sanitizedTitle, ""] : [],
|
|
167456
167727
|
"## Description",
|
|
167457
|
-
|
|
167728
|
+
sanitizedDescription,
|
|
167458
167729
|
"",
|
|
167459
167730
|
"## Environment",
|
|
167460
167731
|
`- Plugin: v${report.pluginVersion}`,
|
|
@@ -167489,7 +167760,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
|
|
|
167489
167760
|
`);
|
|
167490
167761
|
const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
|
|
167491
167762
|
const path6 = join18(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
|
|
167492
|
-
|
|
167763
|
+
writeFileSync5(path6, `${bodyMarkdown}
|
|
167493
167764
|
`);
|
|
167494
167765
|
return { path: path6, bodyMarkdown };
|
|
167495
167766
|
}
|
|
@@ -167752,11 +168023,11 @@ function migrateExperimentalPinKeyFilesForDoctor(mcConfig) {
|
|
|
167752
168023
|
}
|
|
167753
168024
|
|
|
167754
168025
|
// src/commands/doctor-opencode-cache.ts
|
|
167755
|
-
import { existsSync as
|
|
168026
|
+
import { existsSync as existsSync21, readFileSync as readFileSync13, rmSync as rmSync2 } from "node:fs";
|
|
167756
168027
|
function readCachedPluginVersion(pluginCacheDir) {
|
|
167757
168028
|
try {
|
|
167758
168029
|
const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
|
|
167759
|
-
if (!
|
|
168030
|
+
if (!existsSync21(installedPkgPath))
|
|
167760
168031
|
return;
|
|
167761
168032
|
const pkg = JSON.parse(readFileSync13(installedPkgPath, "utf-8"));
|
|
167762
168033
|
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
@@ -167767,7 +168038,7 @@ function readCachedPluginVersion(pluginCacheDir) {
|
|
|
167767
168038
|
async function clearPluginCache(options = {}, deps = {}) {
|
|
167768
168039
|
const remove = deps.remove ?? ((path6) => rmSync2(path6, { recursive: true, force: true }));
|
|
167769
168040
|
const pluginCacheRoots = getOpenCodePluginCacheRoots();
|
|
167770
|
-
const existingRoots = pluginCacheRoots.filter((root) =>
|
|
168041
|
+
const existingRoots = pluginCacheRoots.filter((root) => existsSync21(root));
|
|
167771
168042
|
if (existingRoots.length === 0) {
|
|
167772
168043
|
return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
|
|
167773
168044
|
}
|
|
@@ -167815,6 +168086,8 @@ async function clearPluginCache(options = {}, deps = {}) {
|
|
|
167815
168086
|
action: "error",
|
|
167816
168087
|
path: firstFailure?.path ?? clearTargets[0]?.path ?? existingRoots[0] ?? "",
|
|
167817
168088
|
paths: failed.map((entry) => entry.path),
|
|
168089
|
+
clearedPaths: cleared.map((entry) => entry.path),
|
|
168090
|
+
failedPaths: failed.map((entry) => entry.path),
|
|
167818
168091
|
error: firstFailure?.error
|
|
167819
168092
|
};
|
|
167820
168093
|
}
|
|
@@ -167833,9 +168106,9 @@ var init_doctor_opencode_cache = __esm(() => {
|
|
|
167833
168106
|
|
|
167834
168107
|
// src/commands/doctor-opencode.ts
|
|
167835
168108
|
import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
|
|
167836
|
-
import { existsSync as
|
|
168109
|
+
import { existsSync as existsSync22, readFileSync as readFileSync14, statSync as statSync8 } from "node:fs";
|
|
167837
168110
|
import { createRequire as createRequire4 } from "node:module";
|
|
167838
|
-
import { homedir as
|
|
168111
|
+
import { homedir as homedir12 } from "node:os";
|
|
167839
168112
|
import { join as join19 } from "node:path";
|
|
167840
168113
|
function migrateLegacyAgentEnabledConfigForDoctor(mcConfig, logs) {
|
|
167841
168114
|
let changed = false;
|
|
@@ -167905,6 +168178,38 @@ function getSelfVersion2() {
|
|
|
167905
168178
|
}
|
|
167906
168179
|
return "0.0.0";
|
|
167907
168180
|
}
|
|
168181
|
+
function isPinnedOpenCodePluginSpecifier(specifier) {
|
|
168182
|
+
if (specifier === OPENCODE_PLUGIN_NAME || specifier === OPENCODE_PLUGIN_ENTRY_WITH_VERSION)
|
|
168183
|
+
return false;
|
|
168184
|
+
return specifier.startsWith(`${OPENCODE_PLUGIN_NAME}@`);
|
|
168185
|
+
}
|
|
168186
|
+
function getUserNpmrcPath() {
|
|
168187
|
+
const custom2 = process.env.NPM_CONFIG_USERCONFIG?.trim();
|
|
168188
|
+
if (custom2)
|
|
168189
|
+
return custom2;
|
|
168190
|
+
const home = process.env.HOME?.trim();
|
|
168191
|
+
return join19(home || homedir12(), ".npmrc");
|
|
168192
|
+
}
|
|
168193
|
+
function collectNpmReleaseAgeWarnings() {
|
|
168194
|
+
const ageWarnings = [];
|
|
168195
|
+
const npmrcPath = getUserNpmrcPath();
|
|
168196
|
+
if (!existsSync22(npmrcPath))
|
|
168197
|
+
return ageWarnings;
|
|
168198
|
+
try {
|
|
168199
|
+
const npmrc = readFileSync14(npmrcPath, "utf-8");
|
|
168200
|
+
for (const line of npmrc.split(`
|
|
168201
|
+
`)) {
|
|
168202
|
+
const trimmed = line.trim();
|
|
168203
|
+
if (trimmed.startsWith("#") || trimmed.startsWith(";"))
|
|
168204
|
+
continue;
|
|
168205
|
+
const [key] = trimmed.split("=").map((s) => s.trim());
|
|
168206
|
+
if (key === "min-release-age" || key === "before") {
|
|
168207
|
+
ageWarnings.push(`${sanitizePathString(npmrcPath)} has '${sanitizeDiagnosticText(trimmed)}'`);
|
|
168208
|
+
}
|
|
168209
|
+
}
|
|
168210
|
+
} catch {}
|
|
168211
|
+
return ageWarnings;
|
|
168212
|
+
}
|
|
167908
168213
|
function compareVersions(a3, b2) {
|
|
167909
168214
|
const pa = a3.split(/[.-]/).map((s) => Number.parseInt(s, 10));
|
|
167910
168215
|
const pb = b2.split(/[.-]/).map((s) => Number.parseInt(s, 10));
|
|
@@ -168026,7 +168331,7 @@ function checkLocalEmbeddingRuntimeForDoctor() {
|
|
|
168026
168331
|
return { issues: 0 };
|
|
168027
168332
|
}
|
|
168028
168333
|
async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
168029
|
-
if (!
|
|
168334
|
+
if (!existsSync22(magicContextConfigPath)) {
|
|
168030
168335
|
return checkLocalEmbeddingRuntimeForDoctor();
|
|
168031
168336
|
}
|
|
168032
168337
|
let rawText;
|
|
@@ -168089,7 +168394,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
168089
168394
|
}
|
|
168090
168395
|
}
|
|
168091
168396
|
const probeSpinner = spinner2();
|
|
168092
|
-
probeSpinner.start(`Testing embedding endpoint ${endpoint} (model: ${model})`);
|
|
168397
|
+
probeSpinner.start(`Testing embedding endpoint ${sanitizeDiagnosticEndpoint(endpoint)} (model: ${sanitizeDiagnosticText(model)})`);
|
|
168093
168398
|
let outcome;
|
|
168094
168399
|
try {
|
|
168095
168400
|
outcome = await probeEmbeddingEndpoint({
|
|
@@ -168102,7 +168407,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
168102
168407
|
});
|
|
168103
168408
|
} catch (error51) {
|
|
168104
168409
|
probeSpinner.stop("Embedding probe failed unexpectedly");
|
|
168105
|
-
log2.error(`Probe threw: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
168410
|
+
log2.error(`Probe threw: ${sanitizeDiagnosticText(error51 instanceof Error ? error51.message : String(error51))}`);
|
|
168106
168411
|
return { issues: localIssues + 1 };
|
|
168107
168412
|
}
|
|
168108
168413
|
probeSpinner.stop("Embedding endpoint probed");
|
|
@@ -168113,28 +168418,28 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
168113
168418
|
case "auth_failed":
|
|
168114
168419
|
log2.error(`Embedding endpoint rejected credentials (${outcome.status}) — check api_key / env var`);
|
|
168115
168420
|
if (outcome.preview)
|
|
168116
|
-
log2.info(` ${outcome.preview}`);
|
|
168421
|
+
log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
|
|
168117
168422
|
return { issues: localIssues + 1 };
|
|
168118
168423
|
case "endpoint_unsupported":
|
|
168119
168424
|
log2.error(`Embedding endpoint does not support embeddings (${outcome.status})`);
|
|
168120
168425
|
if (outcome.preview)
|
|
168121
|
-
log2.info(` ${outcome.preview}`);
|
|
168426
|
+
log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
|
|
168122
168427
|
log2.info(" Common causes: endpoint points at a chat-completion route (should be the provider base, e.g. '.../v1'), or the provider doesn't offer an embeddings API");
|
|
168123
168428
|
log2.info(" Known non-embedding providers: OpenRouter (chat proxy), Anthropic (no embeddings endpoint). Use OpenAI, Voyage, Together, or a local provider instead.");
|
|
168124
168429
|
return { issues: localIssues + 1 };
|
|
168125
168430
|
case "http_error":
|
|
168126
168431
|
log2.error(`Embedding endpoint returned ${outcome.status}`);
|
|
168127
168432
|
if (outcome.preview)
|
|
168128
|
-
log2.info(` ${outcome.preview}`);
|
|
168433
|
+
log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
|
|
168129
168434
|
return { issues: localIssues + 1 };
|
|
168130
168435
|
case "timeout":
|
|
168131
168436
|
log2.warn(`Embedding endpoint did not respond within ${outcome.timeoutMs}ms — check endpoint URL and network`);
|
|
168132
168437
|
return { issues: localIssues + 1 };
|
|
168133
168438
|
case "network_error":
|
|
168134
|
-
log2.error(`Could not reach embedding endpoint: ${outcome.message}`);
|
|
168439
|
+
log2.error(`Could not reach embedding endpoint: ${sanitizeDiagnosticText(outcome.message)}`);
|
|
168135
168440
|
return { issues: localIssues + 1 };
|
|
168136
168441
|
case "invalid_scheme":
|
|
168137
|
-
log2.error(`Embedding endpoint must start with http:// or https://: ${outcome.endpoint}`);
|
|
168442
|
+
log2.error(`Embedding endpoint must start with http:// or https://: ${sanitizeDiagnosticEndpoint(outcome.endpoint)}`);
|
|
168138
168443
|
return { issues: localIssues + 1 };
|
|
168139
168444
|
}
|
|
168140
168445
|
}
|
|
@@ -168202,7 +168507,7 @@ async function runDoctor(options = {}) {
|
|
|
168202
168507
|
} else {
|
|
168203
168508
|
pass(`OpenCode config: ${paths.opencodeConfig}`);
|
|
168204
168509
|
}
|
|
168205
|
-
if (
|
|
168510
|
+
if (existsSync22(paths.magicContextConfig)) {
|
|
168206
168511
|
pass(`Magic Context config: ${paths.magicContextConfig}`);
|
|
168207
168512
|
try {
|
|
168208
168513
|
const raw = readFileSync14(paths.magicContextConfig, "utf-8");
|
|
@@ -168230,7 +168535,7 @@ async function runDoctor(options = {}) {
|
|
|
168230
168535
|
warn(`No magic-context.jsonc found — using defaults`);
|
|
168231
168536
|
log2.info(" Run 'setup' to create one with model recommendations");
|
|
168232
168537
|
}
|
|
168233
|
-
if (
|
|
168538
|
+
if (existsSync22(paths.magicContextConfig)) {
|
|
168234
168539
|
try {
|
|
168235
168540
|
const mcRaw = readFileSync14(paths.magicContextConfig, "utf-8");
|
|
168236
168541
|
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
@@ -168369,7 +168674,7 @@ async function runDoctor(options = {}) {
|
|
|
168369
168674
|
if (isDevPathPluginEntry(oldEntry)) {
|
|
168370
168675
|
pass(`Plugin registered in ${configName} (dev path: ${oldEntryStr})`);
|
|
168371
168676
|
} else {
|
|
168372
|
-
const isPinned =
|
|
168677
|
+
const isPinned = isPinnedOpenCodePluginSpecifier(oldEntryStr);
|
|
168373
168678
|
if (isPinned && !options.force) {
|
|
168374
168679
|
warn(`Plugin pinned to ${oldEntryStr} in ${configName} — use 'doctor --force' to upgrade`);
|
|
168375
168680
|
} else {
|
|
@@ -168421,7 +168726,7 @@ async function runDoctor(options = {}) {
|
|
|
168421
168726
|
pass("Added TUI sidebar plugin to tui.json");
|
|
168422
168727
|
warn("Restart OpenCode to see the sidebar");
|
|
168423
168728
|
fixed++;
|
|
168424
|
-
} else if (
|
|
168729
|
+
} else if (existsSync22(paths.tuiConfig)) {
|
|
168425
168730
|
try {
|
|
168426
168731
|
const tuiRaw = readFileSync14(paths.tuiConfig, "utf-8");
|
|
168427
168732
|
const tuiConfig = import_comment_json8.parse(tuiRaw);
|
|
@@ -168440,7 +168745,7 @@ async function runDoctor(options = {}) {
|
|
|
168440
168745
|
if (isDevPathPluginEntry(tuiEntry)) {
|
|
168441
168746
|
pass(`TUI sidebar plugin configured (dev path: ${tuiEntryStr})`);
|
|
168442
168747
|
} else {
|
|
168443
|
-
const tuiPinned =
|
|
168748
|
+
const tuiPinned = isPinnedOpenCodePluginSpecifier(tuiEntryStr);
|
|
168444
168749
|
if (tuiPinned && !options.force) {
|
|
168445
168750
|
warn(`TUI plugin pinned to ${tuiEntryStr} — use 'doctor --force' to upgrade`);
|
|
168446
168751
|
} else if (tuiPinned && options.force) {
|
|
@@ -168469,7 +168774,7 @@ async function runDoctor(options = {}) {
|
|
|
168469
168774
|
} else {
|
|
168470
168775
|
pass("TUI sidebar plugin configured (tui.json created)");
|
|
168471
168776
|
}
|
|
168472
|
-
if (
|
|
168777
|
+
if (existsSync22(paths.magicContextConfig)) {
|
|
168473
168778
|
try {
|
|
168474
168779
|
const mcRaw = readFileSync14(paths.magicContextConfig, "utf-8");
|
|
168475
168780
|
const mcConfig = import_comment_json8.parse(mcRaw);
|
|
@@ -168490,7 +168795,7 @@ async function runDoctor(options = {}) {
|
|
|
168490
168795
|
else
|
|
168491
168796
|
passCount++;
|
|
168492
168797
|
const dbPath = join19(getMagicContextStorageDir(), "context.db");
|
|
168493
|
-
if (!
|
|
168798
|
+
if (!existsSync22(dbPath)) {
|
|
168494
168799
|
log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
|
|
168495
168800
|
} else {
|
|
168496
168801
|
pass(`Shared context DB exists at ${dbPath}`);
|
|
@@ -168550,29 +168855,20 @@ async function runDoctor(options = {}) {
|
|
|
168550
168855
|
warn(`Plugin cache version check unavailable; preserving cached plugin${cacheResult.cached ? ` (cached: ${cacheResult.cached})` : ""}. Use doctor --force to reinstall it.`);
|
|
168551
168856
|
} else if (cacheResult.action === "error") {
|
|
168552
168857
|
warn(`Could not clear plugin cache: ${cacheResult.error}`);
|
|
168553
|
-
|
|
168858
|
+
if (cacheResult.clearedPaths && cacheResult.clearedPaths.length > 0) {
|
|
168859
|
+
log2.info(` Cleared roots: ${cacheResult.clearedPaths.join(", ")}`);
|
|
168860
|
+
}
|
|
168861
|
+
if (cacheResult.failedPaths && cacheResult.failedPaths.length > 0) {
|
|
168862
|
+
log2.info(` Failed roots: ${cacheResult.failedPaths.join(", ")}`);
|
|
168863
|
+
} else {
|
|
168864
|
+
log2.info(` Manually delete: ${cacheResult.path}`);
|
|
168865
|
+
}
|
|
168554
168866
|
issues++;
|
|
168555
168867
|
} else {
|
|
168556
168868
|
pass("Plugin cache clean (no cached version found)");
|
|
168557
168869
|
}
|
|
168558
168870
|
{
|
|
168559
|
-
const ageWarnings =
|
|
168560
|
-
const npmrcPath = join19(homedir13(), ".npmrc");
|
|
168561
|
-
if (existsSync23(npmrcPath)) {
|
|
168562
|
-
try {
|
|
168563
|
-
const npmrc = readFileSync14(npmrcPath, "utf-8");
|
|
168564
|
-
for (const line of npmrc.split(`
|
|
168565
|
-
`)) {
|
|
168566
|
-
const trimmed = line.trim();
|
|
168567
|
-
if (trimmed.startsWith("#") || trimmed.startsWith(";"))
|
|
168568
|
-
continue;
|
|
168569
|
-
const [key] = trimmed.split("=").map((s) => s.trim());
|
|
168570
|
-
if (key === "min-release-age" || key === "before") {
|
|
168571
|
-
ageWarnings.push(`~/.npmrc has '${trimmed}'`);
|
|
168572
|
-
}
|
|
168573
|
-
}
|
|
168574
|
-
} catch {}
|
|
168575
|
-
}
|
|
168871
|
+
const ageWarnings = collectNpmReleaseAgeWarnings();
|
|
168576
168872
|
if (ageWarnings.length > 0) {
|
|
168577
168873
|
log2.warn("npm min-release-age restriction detected — this can prevent OpenCode from installing the latest plugin version");
|
|
168578
168874
|
for (const w of ageWarnings) {
|
|
@@ -168584,7 +168880,7 @@ async function runDoctor(options = {}) {
|
|
|
168584
168880
|
}
|
|
168585
168881
|
}
|
|
168586
168882
|
const logPath = getMagicContextLogPath2("opencode");
|
|
168587
|
-
if (
|
|
168883
|
+
if (existsSync22(logPath)) {
|
|
168588
168884
|
const logStat = statSync8(logPath);
|
|
168589
168885
|
const sizeKb = (logStat.size / 1024).toFixed(0);
|
|
168590
168886
|
log2.info(`Log file: ${logPath} (${sizeKb} KB)`);
|
|
@@ -168649,6 +168945,7 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
168649
168945
|
init_opencode_plugin_cache();
|
|
168650
168946
|
init_paths();
|
|
168651
168947
|
init_prompts();
|
|
168948
|
+
init_redaction2();
|
|
168652
168949
|
init_v22_backfill_commands();
|
|
168653
168950
|
init_doctor_opencode_cache();
|
|
168654
168951
|
await __promiseAll([
|
|
@@ -168659,7 +168956,7 @@ var init_doctor_opencode = __esm(async () => {
|
|
|
168659
168956
|
});
|
|
168660
168957
|
|
|
168661
168958
|
// ../pi-plugin/src/config/index.ts
|
|
168662
|
-
import { existsSync as
|
|
168959
|
+
import { existsSync as existsSync23, readFileSync as readFileSync15 } from "node:fs";
|
|
168663
168960
|
function getProjectConfigPaths(cwd) {
|
|
168664
168961
|
const basePath = cortexKitProjectConfigBasePath(cwd);
|
|
168665
168962
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
@@ -168669,10 +168966,10 @@ function getUserConfigPaths() {
|
|
|
168669
168966
|
return [`${basePath}.jsonc`, `${basePath}.json`];
|
|
168670
168967
|
}
|
|
168671
168968
|
function resolveFirstExisting(paths) {
|
|
168672
|
-
return paths.find((path6) =>
|
|
168969
|
+
return paths.find((path6) => existsSync23(path6));
|
|
168673
168970
|
}
|
|
168674
168971
|
function resolvePiLegacyFallback(sources) {
|
|
168675
|
-
return sources.find((source) =>
|
|
168972
|
+
return sources.find((source) => existsSync23(source.path)) ?? null;
|
|
168676
168973
|
}
|
|
168677
168974
|
function loadConfigFile(path6, scope) {
|
|
168678
168975
|
try {
|
|
@@ -168809,7 +169106,7 @@ function loadPiConfig(opts = {}) {
|
|
|
168809
169106
|
if (loaded)
|
|
168810
169107
|
loadedFiles.push(loaded);
|
|
168811
169108
|
}
|
|
168812
|
-
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) =>
|
|
169109
|
+
const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync23(source.path));
|
|
168813
169110
|
const userPath = resolveFirstExisting(getUserConfigPaths());
|
|
168814
169111
|
const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
|
|
168815
169112
|
const userReadPath = userPath ?? userLegacyFallback?.path;
|
|
@@ -168818,7 +169115,7 @@ function loadPiConfig(opts = {}) {
|
|
|
168818
169115
|
if (loaded)
|
|
168819
169116
|
loadedFiles.push(loaded);
|
|
168820
169117
|
}
|
|
168821
|
-
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) =>
|
|
169118
|
+
const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync23(source.path));
|
|
168822
169119
|
if (userLegacyFallback) {
|
|
168823
169120
|
warnings.push(`[user config] reading legacy config from ${userLegacyFallback.path} until migration completes; run \`npx @cortexkit/magic-context doctor\` to consolidate into the shared CortexKit location.`);
|
|
168824
169121
|
} else if (legacyUserUnmigrated) {
|
|
@@ -168836,6 +169133,7 @@ function loadPiConfig(opts = {}) {
|
|
|
168836
169133
|
return a3.scope === "user" ? -1 : 1;
|
|
168837
169134
|
});
|
|
168838
169135
|
const userRaw = mergeFiles.find((f2) => f2.scope === "user")?.config;
|
|
169136
|
+
const trustedBaseConfig = parsePiConfig(userRaw ?? {}).config;
|
|
168839
169137
|
for (const loaded of mergeFiles) {
|
|
168840
169138
|
const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
|
|
168841
169139
|
warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
|
|
@@ -168848,6 +169146,13 @@ function loadPiConfig(opts = {}) {
|
|
|
168848
169146
|
for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
|
|
168849
169147
|
warnings.push(`${prefix} ${warning}`);
|
|
168850
169148
|
}
|
|
169149
|
+
for (const warning of constrainProjectThresholdOverrides({
|
|
169150
|
+
mergedRaw: rawConfig,
|
|
169151
|
+
projectRaw,
|
|
169152
|
+
trustedBaseConfig
|
|
169153
|
+
})) {
|
|
169154
|
+
warnings.push(`${prefix} ${warning}`);
|
|
169155
|
+
}
|
|
168851
169156
|
} else {
|
|
168852
169157
|
rawConfig = mergeRawConfigs(rawConfig, loaded.config);
|
|
168853
169158
|
}
|
|
@@ -168872,9 +169177,9 @@ var init_config2 = __esm(() => {
|
|
|
168872
169177
|
|
|
168873
169178
|
// src/lib/diagnostics-pi.ts
|
|
168874
169179
|
import { createHash as createHash3 } from "node:crypto";
|
|
168875
|
-
import { existsSync as
|
|
169180
|
+
import { existsSync as existsSync24, readdirSync as readdirSync3, readFileSync as readFileSync16, statSync as statSync9 } from "node:fs";
|
|
168876
169181
|
import { createRequire as createRequire5 } from "node:module";
|
|
168877
|
-
import { homedir as
|
|
169182
|
+
import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
|
|
168878
169183
|
import { join as join20 } from "node:path";
|
|
168879
169184
|
function getSelfVersion3() {
|
|
168880
169185
|
const req = createRequire5(import.meta.url);
|
|
@@ -168890,7 +169195,7 @@ function getSelfVersion3() {
|
|
|
168890
169195
|
}
|
|
168891
169196
|
function fileSize2(path6) {
|
|
168892
169197
|
try {
|
|
168893
|
-
return
|
|
169198
|
+
return existsSync24(path6) ? statSync9(path6).size : 0;
|
|
168894
169199
|
} catch {
|
|
168895
169200
|
return 0;
|
|
168896
169201
|
}
|
|
@@ -168906,7 +169211,7 @@ function redactSecretString(value) {
|
|
|
168906
169211
|
return redactSecretText(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>");
|
|
168907
169212
|
}
|
|
168908
169213
|
function sanitizeString2(value) {
|
|
168909
|
-
const home = process.env.HOME ||
|
|
169214
|
+
const home = process.env.HOME || homedir13();
|
|
168910
169215
|
const username = userInfo2().username;
|
|
168911
169216
|
const userHash = `<USER:${currentUserHash()}>`;
|
|
168912
169217
|
let sanitized = redactSecretString(value);
|
|
@@ -168925,6 +169230,8 @@ function shouldRedactKey(key) {
|
|
|
168925
169230
|
return /api[_-]?key|token|secret|password|authorization|cookie/i.test(key);
|
|
168926
169231
|
}
|
|
168927
169232
|
function sanitizeValue2(value, key = "") {
|
|
169233
|
+
if (value === null || typeof value === "number" || typeof value === "boolean")
|
|
169234
|
+
return value;
|
|
168928
169235
|
if (shouldRedactKey(key))
|
|
168929
169236
|
return "<REDACTED>";
|
|
168930
169237
|
if (typeof value === "string")
|
|
@@ -168940,7 +169247,7 @@ function sanitizeValue2(value, key = "") {
|
|
|
168940
169247
|
return value;
|
|
168941
169248
|
}
|
|
168942
169249
|
function readJsonc3(path6) {
|
|
168943
|
-
if (!
|
|
169250
|
+
if (!existsSync24(path6))
|
|
168944
169251
|
return { value: {} };
|
|
168945
169252
|
try {
|
|
168946
169253
|
return {
|
|
@@ -168960,7 +169267,7 @@ function readConfigDiagnostic(path6) {
|
|
|
168960
169267
|
const parsed = readJsonc3(path6);
|
|
168961
169268
|
return {
|
|
168962
169269
|
path: path6,
|
|
168963
|
-
exists:
|
|
169270
|
+
exists: existsSync24(path6),
|
|
168964
169271
|
...parsed.parseError ? { parseError: parsed.parseError } : {},
|
|
168965
169272
|
flags: sanitizeValue2(parsed.value)
|
|
168966
169273
|
};
|
|
@@ -168977,8 +169284,8 @@ function reverseSlugToDirectory(slug) {
|
|
|
168977
169284
|
return `/${inner.replace(/-/g, "/")}`;
|
|
168978
169285
|
}
|
|
168979
169286
|
function collectPiRecentSessions() {
|
|
168980
|
-
const sessionsRoot =
|
|
168981
|
-
if (!
|
|
169287
|
+
const sessionsRoot = getPiSessionsRoot();
|
|
169288
|
+
if (!existsSync24(sessionsRoot))
|
|
168982
169289
|
return [];
|
|
168983
169290
|
try {
|
|
168984
169291
|
const slugs = readdirSync3(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -169047,7 +169354,7 @@ function parseHistorianDumpMeta2(path6) {
|
|
|
169047
169354
|
}
|
|
169048
169355
|
}
|
|
169049
169356
|
function listDumpsInDir2(dir, limit) {
|
|
169050
|
-
if (!
|
|
169357
|
+
if (!existsSync24(dir))
|
|
169051
169358
|
return { count: 0, recent: [] };
|
|
169052
169359
|
try {
|
|
169053
169360
|
const entries = readdirSync3(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
|
|
@@ -169125,7 +169432,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
169125
169432
|
const storageDirPath = getMagicContextStorageDir();
|
|
169126
169433
|
const dbPath = join20(storageDirPath, "context.db");
|
|
169127
169434
|
const logPath = getMagicContextLogPath2("pi");
|
|
169128
|
-
const logFileSize =
|
|
169435
|
+
const logFileSize = existsSync24(logPath) ? statSync9(logPath).size : 0;
|
|
169129
169436
|
const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
|
|
169130
169437
|
const recentSessions = collectPiRecentSessions();
|
|
169131
169438
|
const historianDumps = collectPiHistorianDumps(recentSessions);
|
|
@@ -169140,7 +169447,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
169140
169447
|
piVersion: pi ? getPiVersion(pi.path) : null,
|
|
169141
169448
|
settings: {
|
|
169142
169449
|
path: settingsPath,
|
|
169143
|
-
exists:
|
|
169450
|
+
exists: existsSync24(settingsPath),
|
|
169144
169451
|
...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
|
|
169145
169452
|
hasMagicContextPackage: hasPiMagicContextPackage(packages),
|
|
169146
169453
|
packages: sanitizeValue2(packages)
|
|
@@ -169156,7 +169463,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
169156
169463
|
loadWarnings: loaded.warnings.map(sanitizeString2),
|
|
169157
169464
|
storageDir: {
|
|
169158
169465
|
path: storageDirPath,
|
|
169159
|
-
exists:
|
|
169466
|
+
exists: existsSync24(storageDirPath),
|
|
169160
169467
|
contextDbSizeBytes: fileSize2(dbPath)
|
|
169161
169468
|
},
|
|
169162
169469
|
conflicts: {
|
|
@@ -169165,7 +169472,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
|
|
|
169165
169472
|
},
|
|
169166
169473
|
logFile: {
|
|
169167
169474
|
path: logPath,
|
|
169168
|
-
exists:
|
|
169475
|
+
exists: existsSync24(logPath),
|
|
169169
169476
|
sizeKb: Math.round(logFileSize / 1024)
|
|
169170
169477
|
},
|
|
169171
169478
|
recentSessions,
|
|
@@ -169259,7 +169566,7 @@ var init_diagnostics_pi = __esm(() => {
|
|
|
169259
169566
|
});
|
|
169260
169567
|
|
|
169261
169568
|
// src/lib/logs-pi.ts
|
|
169262
|
-
import { readFileSync as readFileSync17, writeFileSync as
|
|
169569
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "node:fs";
|
|
169263
169570
|
import { join as join21 } from "node:path";
|
|
169264
169571
|
function sanitizeLogContent2(content) {
|
|
169265
169572
|
return sanitizeString2(content);
|
|
@@ -169326,7 +169633,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
|
|
|
169326
169633
|
const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
|
|
169327
169634
|
const cwd = options.cwd ?? process.cwd();
|
|
169328
169635
|
const path6 = join21(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
|
|
169329
|
-
|
|
169636
|
+
writeFileSync6(path6, `${bodyMarkdown}
|
|
169330
169637
|
`);
|
|
169331
169638
|
return { path: path6, bodyMarkdown };
|
|
169332
169639
|
}
|
|
@@ -169337,10 +169644,10 @@ var init_logs_pi = __esm(() => {
|
|
|
169337
169644
|
|
|
169338
169645
|
// src/commands/doctor-pi.ts
|
|
169339
169646
|
import { execFileSync as execFileSync5, spawnSync as spawnSync4 } from "node:child_process";
|
|
169340
|
-
import { existsSync as
|
|
169647
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as rmSync3, statSync as statSync10 } from "node:fs";
|
|
169341
169648
|
import { createRequire as createRequire6 } from "node:module";
|
|
169342
|
-
import { homedir as
|
|
169343
|
-
import { dirname as
|
|
169649
|
+
import { homedir as homedir14 } from "node:os";
|
|
169650
|
+
import { dirname as dirname13, isAbsolute as isAbsolute3, join as join22 } from "node:path";
|
|
169344
169651
|
function depsFrom(options) {
|
|
169345
169652
|
return {
|
|
169346
169653
|
...DEFAULT_DEPS,
|
|
@@ -169454,13 +169761,13 @@ function piPluginDirCandidates(packages, cwd) {
|
|
|
169454
169761
|
}
|
|
169455
169762
|
dirs.push(join22(agentDir, "npm", "node_modules", PACKAGE_NAME));
|
|
169456
169763
|
dirs.push(join22(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME));
|
|
169457
|
-
return dirs.filter((dir) =>
|
|
169764
|
+
return dirs.filter((dir) => existsSync25(join22(dir, "package.json")));
|
|
169458
169765
|
}
|
|
169459
169766
|
function projectConfigPath(cwd) {
|
|
169460
169767
|
return resolveCortexKitProjectConfigPath(cwd);
|
|
169461
169768
|
}
|
|
169462
169769
|
function readConfigForEmbedding(path6, isProjectConfig) {
|
|
169463
|
-
if (!
|
|
169770
|
+
if (!existsSync25(path6))
|
|
169464
169771
|
return null;
|
|
169465
169772
|
try {
|
|
169466
169773
|
const rawText = readFileSync18(path6, "utf-8");
|
|
@@ -169494,7 +169801,7 @@ function classifyEmbeddingOutcome(outcome) {
|
|
|
169494
169801
|
case "network_error":
|
|
169495
169802
|
return {
|
|
169496
169803
|
status: "fail",
|
|
169497
|
-
message: `Embedding endpoint network error: ${outcome.message}`
|
|
169804
|
+
message: `Embedding endpoint network error: ${sanitizeDiagnosticText(outcome.message)}`
|
|
169498
169805
|
};
|
|
169499
169806
|
case "endpoint_unsupported":
|
|
169500
169807
|
return {
|
|
@@ -169509,7 +169816,7 @@ function classifyEmbeddingOutcome(outcome) {
|
|
|
169509
169816
|
case "invalid_scheme":
|
|
169510
169817
|
return {
|
|
169511
169818
|
status: "fail",
|
|
169512
|
-
message: `Embedding endpoint must start with http:// or https://: ${outcome.endpoint}`
|
|
169819
|
+
message: `Embedding endpoint must start with http:// or https://: ${sanitizeDiagnosticEndpoint(outcome.endpoint)}`
|
|
169513
169820
|
};
|
|
169514
169821
|
}
|
|
169515
169822
|
}
|
|
@@ -169522,11 +169829,12 @@ function countTable(db, table) {
|
|
|
169522
169829
|
}
|
|
169523
169830
|
}
|
|
169524
169831
|
function cacheRoots() {
|
|
169525
|
-
const home =
|
|
169526
|
-
const cacheHome = process.env.XDG_CACHE_HOME || join22(home, ".cache");
|
|
169832
|
+
const home = process.env.HOME?.trim();
|
|
169833
|
+
const cacheHome = process.env.XDG_CACHE_HOME || join22(home || homedir14(), ".cache");
|
|
169834
|
+
const piCacheRoot = getPiCacheRoot();
|
|
169527
169835
|
return [
|
|
169528
|
-
join22(
|
|
169529
|
-
join22(
|
|
169836
|
+
join22(piCacheRoot, "extensions"),
|
|
169837
|
+
join22(piCacheRoot, "packages"),
|
|
169530
169838
|
join22(cacheHome, "pi", "extensions"),
|
|
169531
169839
|
join22(cacheHome, "pi", "packages"),
|
|
169532
169840
|
join22(getPiAgentConfigDir(), "cache", "extensions")
|
|
@@ -169535,7 +169843,7 @@ function cacheRoots() {
|
|
|
169535
169843
|
function findPiMagicContextCacheDirs(self, force = false) {
|
|
169536
169844
|
const found = new Map;
|
|
169537
169845
|
const visit = (path6, depth) => {
|
|
169538
|
-
if (depth < 0 || !
|
|
169846
|
+
if (depth < 0 || !existsSync25(path6))
|
|
169539
169847
|
return;
|
|
169540
169848
|
let stat;
|
|
169541
169849
|
try {
|
|
@@ -169546,7 +169854,7 @@ function findPiMagicContextCacheDirs(self, force = false) {
|
|
|
169546
169854
|
if (!stat.isDirectory())
|
|
169547
169855
|
return;
|
|
169548
169856
|
const packageJson = join22(path6, "package.json");
|
|
169549
|
-
if (
|
|
169857
|
+
if (existsSync25(packageJson)) {
|
|
169550
169858
|
try {
|
|
169551
169859
|
const pkg = JSON.parse(readFileSync18(packageJson, "utf-8"));
|
|
169552
169860
|
const name2 = typeof pkg.name === "string" ? pkg.name : "";
|
|
@@ -169581,7 +169889,7 @@ async function runHealthChecks(options) {
|
|
|
169581
169889
|
writeUserConfig: false,
|
|
169582
169890
|
clearCachePaths: []
|
|
169583
169891
|
};
|
|
169584
|
-
const self = selfVersion();
|
|
169892
|
+
const self = options.deps.selfVersion();
|
|
169585
169893
|
const pi = options.deps.detectPiBinary();
|
|
169586
169894
|
if (!pi) {
|
|
169587
169895
|
add(results, "fail", "Pi binary not found on PATH or at ~/.pi/bin/pi");
|
|
@@ -169596,16 +169904,19 @@ async function runHealthChecks(options) {
|
|
|
169596
169904
|
}
|
|
169597
169905
|
}
|
|
169598
169906
|
const latest = options.deps.getLatestNpmVersion();
|
|
169599
|
-
|
|
169907
|
+
const latestCompare = latest ? compareSemver(self, latest) : null;
|
|
169908
|
+
if (latest && latestCompare === -1) {
|
|
169600
169909
|
add(results, "warn", `Magic Context for Pi CLI v${self} is older than npm latest v${latest}`);
|
|
169601
|
-
} else if (latest) {
|
|
169910
|
+
} else if (latest && latestCompare !== null) {
|
|
169602
169911
|
add(results, "pass", `Magic Context for Pi CLI v${self} is current (npm latest v${latest})`);
|
|
169912
|
+
} else if (latest) {
|
|
169913
|
+
add(results, "info", `Magic Context for Pi CLI version unknown; npm latest is v${latest}`);
|
|
169603
169914
|
} else {
|
|
169604
169915
|
add(results, "info", `Magic Context for Pi CLI v${self}; npm latest check unavailable`);
|
|
169605
169916
|
}
|
|
169606
169917
|
const settingsPath = getPiUserExtensionsPath();
|
|
169607
169918
|
let packages = [];
|
|
169608
|
-
if (!
|
|
169919
|
+
if (!existsSync25(settingsPath)) {
|
|
169609
169920
|
add(results, "warn", `Pi settings not found at ${settingsPath}`);
|
|
169610
169921
|
repairPlan.addPackageEntry = true;
|
|
169611
169922
|
} else {
|
|
@@ -169629,7 +169940,7 @@ async function runHealthChecks(options) {
|
|
|
169629
169940
|
["user", userConfigPath, true],
|
|
169630
169941
|
["project", projectPath, false]
|
|
169631
169942
|
]) {
|
|
169632
|
-
if (!
|
|
169943
|
+
if (!existsSync25(path6)) {
|
|
169633
169944
|
if (required2) {
|
|
169634
169945
|
add(results, "warn", `No ${label} magic-context.jsonc found at ${path6}`);
|
|
169635
169946
|
if (userConfigMigrationRefused) {
|
|
@@ -169667,7 +169978,7 @@ async function runHealthChecks(options) {
|
|
|
169667
169978
|
}
|
|
169668
169979
|
const storageDir = getMagicContextStorageDir();
|
|
169669
169980
|
const dbPath = join22(storageDir, "context.db");
|
|
169670
|
-
const existedBeforeOpen =
|
|
169981
|
+
const existedBeforeOpen = existsSync25(dbPath);
|
|
169671
169982
|
if (existedBeforeOpen)
|
|
169672
169983
|
add(results, "pass", `Shared context DB exists at ${dbPath}`);
|
|
169673
169984
|
else
|
|
@@ -169731,7 +170042,7 @@ async function runHealthChecks(options) {
|
|
|
169731
170042
|
const classified = classifyEmbeddingOutcome(outcome);
|
|
169732
170043
|
add(results, classified.status, classified.message);
|
|
169733
170044
|
} catch (error51) {
|
|
169734
|
-
add(results, "fail", `Embedding probe threw: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
170045
|
+
add(results, "fail", `Embedding probe threw: ${sanitizeDiagnosticText(error51 instanceof Error ? error51.message : String(error51))}`);
|
|
169735
170046
|
}
|
|
169736
170047
|
}
|
|
169737
170048
|
} else if (loadedConfig.config.embedding.provider === "off") {
|
|
@@ -169775,7 +170086,7 @@ async function runHealthChecks(options) {
|
|
|
169775
170086
|
add(results, "pass", "Pi extension cache clean (no stale cached package found)");
|
|
169776
170087
|
}
|
|
169777
170088
|
const logPath = getMagicContextLogPath2("pi");
|
|
169778
|
-
if (
|
|
170089
|
+
if (existsSync25(logPath)) {
|
|
169779
170090
|
const stat = statSync10(logPath);
|
|
169780
170091
|
const sizeKb = (stat.size / 1024).toFixed(0);
|
|
169781
170092
|
const lines = readFileSync18(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
@@ -169813,7 +170124,7 @@ async function runHealthChecks(options) {
|
|
|
169813
170124
|
return { results, repairPlan, ...summarize(results) };
|
|
169814
170125
|
}
|
|
169815
170126
|
function writeDefaultMagicContextConfig(path6) {
|
|
169816
|
-
|
|
170127
|
+
mkdirSync8(dirname13(path6), { recursive: true });
|
|
169817
170128
|
const config2 = {
|
|
169818
170129
|
$schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
|
|
169819
170130
|
...MagicContextConfigSchema.parse({})
|
|
@@ -169835,7 +170146,7 @@ function repair(plan, prompts) {
|
|
|
169835
170146
|
}
|
|
169836
170147
|
if (plan.writeUserConfig) {
|
|
169837
170148
|
const configPath = getPiUserConfigPath();
|
|
169838
|
-
if (!
|
|
170149
|
+
if (!existsSync25(configPath)) {
|
|
169839
170150
|
try {
|
|
169840
170151
|
writeDefaultMagicContextConfig(configPath);
|
|
169841
170152
|
prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
|
|
@@ -170038,6 +170349,7 @@ var init_doctor_pi = __esm(async () => {
|
|
|
170038
170349
|
detectPiBinary,
|
|
170039
170350
|
getPiVersion,
|
|
170040
170351
|
getLatestNpmVersion: () => getLatestNpmVersion(PACKAGE_NAME),
|
|
170352
|
+
selfVersion,
|
|
170041
170353
|
probeEmbeddingEndpoint,
|
|
170042
170354
|
openDatabase,
|
|
170043
170355
|
isDatabasePersisted,
|
|
@@ -170053,7 +170365,7 @@ var exports_doctor = {};
|
|
|
170053
170365
|
__export(exports_doctor, {
|
|
170054
170366
|
runDoctor: () => runDoctor3
|
|
170055
170367
|
});
|
|
170056
|
-
import { existsSync as
|
|
170368
|
+
import { existsSync as existsSync26, rmSync as rmSync4 } from "node:fs";
|
|
170057
170369
|
async function runDoctor3(options) {
|
|
170058
170370
|
if (options.clear)
|
|
170059
170371
|
return runClear();
|
|
@@ -170142,7 +170454,7 @@ async function runClear() {
|
|
|
170142
170454
|
const s = spinner2();
|
|
170143
170455
|
s.start(`Clearing ${item.path}`);
|
|
170144
170456
|
try {
|
|
170145
|
-
if (
|
|
170457
|
+
if (existsSync26(item.path)) {
|
|
170146
170458
|
rmSync4(item.path, { recursive: true, force: true });
|
|
170147
170459
|
}
|
|
170148
170460
|
s.stop(`Cleared ${item.path}`);
|