@cortexkit/magic-context 0.31.3 → 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.
Files changed (2) hide show
  1. package/dist/index.js +615 -308
  2. 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 getPiAgentConfigDir() {
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(homedir4(), ".pi", "agent");
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 dirname3 } from "node:path";
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 = dirname3(filePath);
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 dirname4 } from "node:path";
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 = dirname4(filePath);
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 dirname5 } from "node:path";
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(dirname5(configPath));
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(dirname5(configPath));
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 dirname6 } from "node:path";
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(dirname6(settingsPath));
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(dirname6(configPath));
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 { existsSync as existsSync12, mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
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 join11(homedir7(), ".pi", "agent", "sessions");
12801
+ return getPiSessionsRoot();
12789
12802
  }
12790
12803
  function defaultFs() {
12791
- return { existsSync: existsSync12, mkdirSync: mkdirSync5, writeFileSync: writeFileSync4, unlinkSync: unlinkSync2 };
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
- if (!fs.existsSync(outputDir))
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 existsSync13, realpathSync, statSync as statSync5 } from "node:fs";
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 (existsSync13(path3.join(current, ".git"))) {
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 existsSync14, realpathSync as realpathSync2 } from "node:fs";
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) => existsSync14(join12(dir, ".git")),
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 (!existsSync14(expandedTo)) {
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 existsSync15 } from "node:fs";
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 (!existsSync15(opencodeDbPath)) {
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 existsSync16, mkdirSync as mkdirSync7, mkdtempSync } from "node:fs";
148735
- import { dirname as dirname8, join as join14 } from "node:path";
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
- mkdirSync7(dir, { recursive: true, mode: 448 });
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 (!existsSync16(file))
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: dirname8(dbPathOverride), dbPath: dbPathOverride };
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 (existsSync16(targetDbPath))
148792
+ if (existsSync15(targetDbPath))
148775
148793
  return;
148776
148794
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
148777
148795
  const legacyDbPath = join14(legacyDir, "context.db");
148778
- if (!existsSync16(legacyDbPath))
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 (existsSync16(src)) {
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 (existsSync16(legacyModelsDir) && !existsSync16(targetModelsDir)) {
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: () => isPlainObject3,
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 isPlainObject3(o2) {
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 (isPlainObject3(o2))
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 (!isPlainObject3(shape)) {
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 (!isPlainObject3(shape)) {
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 (isPlainObject3(a3) && isPlainObject3(b2)) {
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 (!isPlainObject3(input)) {
153825
+ if (!isPlainObject(input)) {
153925
153826
  payload.issues.push({
153926
153827
  expected: "record",
153927
153828
  code: "invalid_type",
@@ -165628,10 +165529,332 @@ var init_magic_context = __esm(() => {
165628
165529
  });
165629
165530
  });
165630
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
+
165631
165854
  // ../plugin/src/config/variable.ts
165632
- import { existsSync as existsSync17, readFileSync as readFileSync8 } from "node:fs";
165855
+ import { existsSync as existsSync16, readFileSync as readFileSync8 } from "node:fs";
165633
165856
  import { homedir as homedir9 } from "node:os";
165634
- import { dirname as dirname9, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
165857
+ import { dirname as dirname10, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
165635
165858
  function sensitiveFilePathReason(resolvedPath) {
165636
165859
  const home = homedir9();
165637
165860
  const sensitiveDirs = [
@@ -165678,7 +165901,7 @@ function substituteConfigVariables(input) {
165678
165901
  if (fileMatches.length === 0) {
165679
165902
  return { text: text3, warnings };
165680
165903
  }
165681
- const configDir = input.configPath ? dirname9(input.configPath) : process.cwd();
165904
+ const configDir = input.configPath ? dirname10(input.configPath) : process.cwd();
165682
165905
  let output = "";
165683
165906
  let cursor3 = 0;
165684
165907
  for (const match of fileMatches) {
@@ -165704,7 +165927,7 @@ function substituteConfigVariables(input) {
165704
165927
  if (sensitiveReason) {
165705
165928
  warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
165706
165929
  }
165707
- if (!existsSync17(filePath)) {
165930
+ if (!existsSync16(filePath)) {
165708
165931
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
165709
165932
  continue;
165710
165933
  }
@@ -165729,7 +165952,7 @@ var init_variable = __esm(() => {
165729
165952
  });
165730
165953
 
165731
165954
  // ../plugin/src/config/index.ts
165732
- import { existsSync as existsSync18, readFileSync as readFileSync9 } from "node:fs";
165955
+ import { existsSync as existsSync17, readFileSync as readFileSync9 } from "node:fs";
165733
165956
  function getUserConfigBasePath() {
165734
165957
  return cortexKitUserConfigBasePath();
165735
165958
  }
@@ -165737,10 +165960,10 @@ function getProjectConfigBasePath(directory) {
165737
165960
  return cortexKitProjectConfigBasePath(directory);
165738
165961
  }
165739
165962
  function resolveLegacyReadFallback(sources) {
165740
- return { source: sources.find((s) => existsSync18(s.path)) ?? null };
165963
+ return { source: sources.find((s) => existsSync17(s.path)) ?? null };
165741
165964
  }
165742
165965
  function loadConfigFileDetailed(configPath, source) {
165743
- if (!existsSync18(configPath)) {
165966
+ if (!existsSync17(configPath)) {
165744
165967
  return null;
165745
165968
  }
165746
165969
  let rawText;
@@ -165955,12 +166178,13 @@ function loadPluginConfigDetailed(directory) {
165955
166178
  const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
165956
166179
  const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
165957
166180
  const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
165958
- const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync18(source.path));
165959
- const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync18(source.path));
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));
165960
166183
  const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
165961
166184
  const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
165962
166185
  const allWarnings = [];
165963
166186
  let mergedRaw = {};
166187
+ const trustedBaseConfig = parsePluginConfig(userLoaded?.config ?? {});
165964
166188
  if (userLegacyFallback.source) {
165965
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.`);
165966
166190
  } else if (legacyUserUnmigrated) {
@@ -165985,6 +166209,13 @@ function loadPluginConfigDetailed(directory) {
165985
166209
  for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userLoaded?.config)) {
165986
166210
  allWarnings.push(`[project config] ${warning}`);
165987
166211
  }
166212
+ for (const warning of constrainProjectThresholdOverrides({
166213
+ mergedRaw,
166214
+ projectRaw,
166215
+ trustedBaseConfig
166216
+ })) {
166217
+ allWarnings.push(`[project config] ${warning}`);
166218
+ }
165988
166219
  }
165989
166220
  const recoveredTopLevelKeys = [];
165990
166221
  const config2 = parsePluginConfig(mergedRaw, recoveredTopLevelKeys);
@@ -166141,14 +166372,14 @@ var DEFAULT_TIMEOUT_MS = 1e4, MAX_PREVIEW_CHARS = 240;
166141
166372
  // ../plugin/src/shared/tui-config.ts
166142
166373
  import {
166143
166374
  chmodSync as chmodSync3,
166144
- existsSync as existsSync19,
166145
- mkdirSync as mkdirSync8,
166375
+ existsSync as existsSync18,
166376
+ mkdirSync as mkdirSync7,
166146
166377
  readFileSync as readFileSync10,
166147
166378
  renameSync as renameSync3,
166148
166379
  statSync as statSync6,
166149
- writeFileSync as writeFileSync5
166380
+ writeFileSync as writeFileSync4
166150
166381
  } from "node:fs";
166151
- import { dirname as dirname10, join as join15 } from "node:path";
166382
+ import { dirname as dirname11, join as join15 } from "node:path";
166152
166383
  function pluginEntryId(entry) {
166153
166384
  if (typeof entry === "string")
166154
166385
  return entry;
@@ -166179,7 +166410,7 @@ function writeTuiConfigAtomic(configPath, config2) {
166179
166410
  const body = `${import_comment_json6.stringify(config2, null, 2)}
166180
166411
  `;
166181
166412
  const tmpPath = `${configPath}.tmp`;
166182
- writeFileSync5(tmpPath, body);
166413
+ writeFileSync4(tmpPath, body);
166183
166414
  try {
166184
166415
  if (statSync6(configPath, { throwIfNoEntry: false })?.isFile()) {
166185
166416
  chmodSync3(tmpPath, statSync6(configPath).mode & 511);
@@ -166191,9 +166422,9 @@ function resolveTuiConfigPath() {
166191
166422
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
166192
166423
  const jsoncPath = join15(configDir, "tui.jsonc");
166193
166424
  const jsonPath = join15(configDir, "tui.json");
166194
- if (existsSync19(jsoncPath))
166425
+ if (existsSync18(jsoncPath))
166195
166426
  return jsoncPath;
166196
- if (existsSync19(jsonPath))
166427
+ if (existsSync18(jsonPath))
166197
166428
  return jsonPath;
166198
166429
  return jsoncPath;
166199
166430
  }
@@ -166201,7 +166432,7 @@ function ensureTuiPluginEntry() {
166201
166432
  try {
166202
166433
  const configPath = resolveTuiConfigPath();
166203
166434
  let config2 = {};
166204
- if (existsSync19(configPath)) {
166435
+ if (existsSync18(configPath)) {
166205
166436
  const raw = readFileSync10(configPath, "utf-8");
166206
166437
  config2 = import_comment_json6.parse(raw) ?? {};
166207
166438
  }
@@ -166236,7 +166467,7 @@ function ensureTuiPluginEntry() {
166236
166467
  }
166237
166468
  }
166238
166469
  config2.plugin = plugins;
166239
- mkdirSync8(dirname10(configPath), { recursive: true });
166470
+ mkdirSync7(dirname11(configPath), { recursive: true });
166240
166471
  writeTuiConfigAtomic(configPath, config2);
166241
166472
  log3(`[magic-context] updated TUI plugin entry in ${configPath}`);
166242
166473
  return true;
@@ -166491,6 +166722,8 @@ function sanitizeDiagnosticText(value) {
166491
166722
  return redactSecretText(sanitizePathString(value));
166492
166723
  }
166493
166724
  function sanitizeConfigValue(value, keyPath = []) {
166725
+ if (value === null || typeof value === "number" || typeof value === "boolean")
166726
+ return value;
166494
166727
  const key = keyPath.at(-1) ?? "";
166495
166728
  if (key && isSecretKey(key)) {
166496
166729
  return `<REDACTED:${redactionTypeForKey(key)}>`;
@@ -166596,12 +166829,29 @@ var init_redaction = __esm(() => {
166596
166829
  });
166597
166830
 
166598
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
+ }
166599
166849
  var init_redaction2 = __esm(() => {
166600
166850
  init_redaction();
166601
166851
  });
166602
166852
 
166603
166853
  // src/lib/diagnostics-opencode.ts
166604
- import { existsSync as existsSync20, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync7 } from "node:fs";
166854
+ import { existsSync as existsSync19, readdirSync as readdirSync2, readFileSync as readFileSync11, statSync as statSync7 } from "node:fs";
166605
166855
  import { createRequire as createRequire2 } from "node:module";
166606
166856
  import { homedir as homedir11 } from "node:os";
166607
166857
  import { join as join16 } from "node:path";
@@ -166622,7 +166872,7 @@ function getPluginCacheInfo() {
166622
166872
  let cached2;
166623
166873
  for (const installedPkgPath of getOpenCodePluginPackageJsonPaths()) {
166624
166874
  try {
166625
- if (existsSync20(installedPkgPath)) {
166875
+ if (existsSync19(installedPkgPath)) {
166626
166876
  const pkg = JSON.parse(readFileSync11(installedPkgPath, "utf-8"));
166627
166877
  cached2 = typeof pkg.version === "string" ? pkg.version : undefined;
166628
166878
  if (cached2)
@@ -166640,7 +166890,7 @@ function getStorageDir() {
166640
166890
  }
166641
166891
  function fileSize(path6) {
166642
166892
  try {
166643
- return existsSync20(path6) ? statSync7(path6).size : 0;
166893
+ return existsSync19(path6) ? statSync7(path6).size : 0;
166644
166894
  } catch {
166645
166895
  return 0;
166646
166896
  }
@@ -166652,7 +166902,7 @@ function sanitizeValue(value) {
166652
166902
  return sanitizeConfigValue(value);
166653
166903
  }
166654
166904
  function readConfig2(path6) {
166655
- if (!existsSync20(path6))
166905
+ if (!existsSync19(path6))
166656
166906
  return { value: null };
166657
166907
  try {
166658
166908
  const raw = readFileSync11(path6, "utf-8");
@@ -166713,7 +166963,7 @@ function parseHistorianDumpMeta(path6) {
166713
166963
  }
166714
166964
  }
166715
166965
  function listDumpsInDir(dir, limit) {
166716
- if (!existsSync20(dir))
166966
+ if (!existsSync19(dir))
166717
166967
  return { count: 0, recent: [] };
166718
166968
  try {
166719
166969
  const entries = readdirSync2(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
@@ -166783,7 +167033,7 @@ function collectHistorianDumps(recentSessions) {
166783
167033
  async function collectRecentSessions() {
166784
167034
  const dataHome = process.env.XDG_DATA_HOME || join16(process.env.HOME || homedir11(), ".local", "share");
166785
167035
  const opencodeDbPath = join16(dataHome, "opencode", "opencode.db");
166786
- if (!existsSync20(opencodeDbPath))
167036
+ if (!existsSync19(opencodeDbPath))
166787
167037
  return [];
166788
167038
  if (typeof globalThis.Bun === "undefined") {
166789
167039
  return [];
@@ -166818,7 +167068,7 @@ async function collectRecentSessions() {
166818
167068
  }
166819
167069
  async function collectHistorianFailures(storageDirPath) {
166820
167070
  const contextDbPath = join16(storageDirPath, "context.db");
166821
- if (!existsSync20(contextDbPath))
167071
+ if (!existsSync19(contextDbPath))
166822
167072
  return [];
166823
167073
  if (typeof globalThis.Bun === "undefined") {
166824
167074
  return [];
@@ -166852,7 +167102,7 @@ async function collectHistorianFailures(storageDirPath) {
166852
167102
  }
166853
167103
  async function collectHistorianRuns(storageDirPath) {
166854
167104
  const contextDbPath = join16(storageDirPath, "context.db");
166855
- if (!existsSync20(contextDbPath))
167105
+ if (!existsSync19(contextDbPath))
166856
167106
  return [];
166857
167107
  if (typeof globalThis.Bun === "undefined")
166858
167108
  return [];
@@ -166923,7 +167173,7 @@ async function collectDiagnostics() {
166923
167173
  const storageDirPath = getStorageDir();
166924
167174
  const contextDbPath = join16(storageDirPath, "context.db");
166925
167175
  const logPath = getMagicContextLogPath2("opencode");
166926
- const logFileSize = existsSync20(logPath) ? statSync7(logPath).size : 0;
167176
+ const logFileSize = existsSync19(logPath) ? statSync7(logPath).size : 0;
166927
167177
  const conflictResult = detectConflicts(process.cwd());
166928
167178
  const recentSessions = await collectRecentSessions();
166929
167179
  const openCodeDetection = detectOpenCode();
@@ -166942,14 +167192,14 @@ async function collectDiagnostics() {
166942
167192
  opencodeConfigHasPlugin: configHasPluginEntry(opencodeConfig.value),
166943
167193
  tuiConfigHasPlugin: configHasPluginEntry(tuiConfig.value),
166944
167194
  magicContextConfig: {
166945
- exists: existsSync20(configPaths.magicContextConfig),
167195
+ exists: existsSync19(configPaths.magicContextConfig),
166946
167196
  ...magicContextConfig.error ? { parseError: magicContextConfig.error } : {},
166947
167197
  flags: sanitizeValue(magicContextConfig.value ?? {}) ?? {}
166948
167198
  },
166949
167199
  pluginCache: getPluginCacheInfo(),
166950
167200
  storageDir: {
166951
167201
  path: storageDirPath,
166952
- exists: existsSync20(storageDirPath),
167202
+ exists: existsSync19(storageDirPath),
166953
167203
  contextDbSizeBytes: fileSize(contextDbPath)
166954
167204
  },
166955
167205
  conflicts: {
@@ -166958,7 +167208,7 @@ async function collectDiagnostics() {
166958
167208
  },
166959
167209
  logFile: {
166960
167210
  path: logPath,
166961
- exists: existsSync20(logPath),
167211
+ exists: existsSync19(logPath),
166962
167212
  sizeKb: Math.round(logFileSize / 1024)
166963
167213
  },
166964
167214
  recentSessions,
@@ -167012,7 +167262,7 @@ function renderDiagnosticsMarkdown(report) {
167012
167262
  };
167013
167263
  const recentSessions = report.recentSessions.map((session) => ({
167014
167264
  sessionId: session.sessionId,
167015
- title: session.title,
167265
+ title: sanitizeDiagnosticText(session.title),
167016
167266
  directory: sanitizeString(session.directory),
167017
167267
  lastActiveAt: session.lastActiveAt
167018
167268
  }));
@@ -167098,9 +167348,9 @@ var init_diagnostics_opencode = __esm(() => {
167098
167348
 
167099
167349
  // src/lib/embedding-runtime.ts
167100
167350
  import { spawnSync as spawnSync2 } from "node:child_process";
167101
- import { existsSync as existsSync21 } from "node:fs";
167351
+ import { existsSync as existsSync20 } from "node:fs";
167102
167352
  import { createRequire as createRequire3 } from "node:module";
167103
- import { dirname as dirname11, join as join17, sep } from "node:path";
167353
+ import { dirname as dirname12, join as join17, sep } from "node:path";
167104
167354
  function describeError(error51) {
167105
167355
  const message = error51 instanceof Error ? error51.message : String(error51 ?? "unknown error");
167106
167356
  const code = error51?.code;
@@ -167213,7 +167463,7 @@ function expectedBinaryRelPath(platform, arch) {
167213
167463
  }
167214
167464
  function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform, arch = process.arch) {
167215
167465
  const packageDir = join17(installRoot, "node_modules", "onnxruntime-node");
167216
- if (!existsSync21(join17(packageDir, "package.json"))) {
167466
+ if (!existsSync20(join17(packageDir, "package.json"))) {
167217
167467
  return { state: "package-missing", packageDir };
167218
167468
  }
167219
167469
  const rel = expectedBinaryRelPath(platform, arch);
@@ -167221,13 +167471,13 @@ function checkLocalEmbeddingRuntimeAt(installRoot, platform = process.platform,
167221
167471
  return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath: packageDir };
167222
167472
  }
167223
167473
  const binaryPath = join17(packageDir, rel);
167224
- if (!existsSync21(binaryPath)) {
167474
+ if (!existsSync20(binaryPath)) {
167225
167475
  return { state: "binary-missing", packageDir, expectedBinary: binaryPath };
167226
167476
  }
167227
167477
  return probeOnnxRuntimeNodeLoad(packageDir) ?? { state: "ok", binaryPath };
167228
167478
  }
167229
167479
  function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, arch = process.arch) {
167230
- const existing = installRoots.filter((root) => existsSync21(root));
167480
+ const existing = installRoots.filter((root) => existsSync20(root));
167231
167481
  if (existing.length === 0) {
167232
167482
  return {
167233
167483
  state: "unknown",
@@ -167247,10 +167497,10 @@ function checkLocalEmbeddingRuntime(installRoots, platform = process.platform, a
167247
167497
  function packageDirFromResolved(resolvedPath, packageName) {
167248
167498
  const marker = `node_modules${sep}${packageName.split("/").join(sep)}`;
167249
167499
  const idx = resolvedPath.indexOf(marker);
167250
- return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname11(resolvedPath);
167500
+ return idx >= 0 ? resolvedPath.slice(0, idx + marker.length) : dirname12(resolvedPath);
167251
167501
  }
167252
167502
  function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.platform, arch = process.arch) {
167253
- if (!existsSync21(join17(pluginDir, "package.json"))) {
167503
+ if (!existsSync20(join17(pluginDir, "package.json"))) {
167254
167504
  return { state: "unknown", reason: "plugin package dir not found" };
167255
167505
  }
167256
167506
  let onnxDir = null;
@@ -167286,7 +167536,7 @@ function checkLocalEmbeddingRuntimeByResolution(pluginDir, platform = process.pl
167286
167536
  return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath: onnxDir };
167287
167537
  }
167288
167538
  const binaryPath = join17(onnxDir, rel);
167289
- if (!existsSync21(binaryPath)) {
167539
+ if (!existsSync20(binaryPath)) {
167290
167540
  return { state: "binary-missing", packageDir: onnxDir, expectedBinary: binaryPath };
167291
167541
  }
167292
167542
  return probeOnnxRuntimeNodeLoad(onnxDir) ?? { state: "ok", binaryPath };
@@ -167332,33 +167582,30 @@ function extractRecentErrors(sanitized, limit = 20) {
167332
167582
  function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
167333
167583
  if (Buffer.byteLength(body, "utf8") <= maxBytes)
167334
167584
  return body;
167585
+ let capped = body;
167335
167586
  const heading = "## Log (last";
167336
167587
  const headingIdx = body.indexOf(heading);
167337
167588
  if (headingIdx === -1) {
167338
- const marker = `
167339
-
167340
- [truncated for GitHub 64KB limit]
167341
- `;
167342
- const markerBytes2 = Buffer.byteLength(marker, "utf8");
167343
- 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);
167344
167592
  }
167345
167593
  const fenceOpenIdx = body.indexOf("\n```", headingIdx);
167346
167594
  if (fenceOpenIdx === -1)
167347
- return body;
167595
+ return enforceFinalBodyLimit(body, maxBytes);
167348
167596
  const logStart = fenceOpenIdx + "\n```\n".length;
167349
167597
  const fenceCloseIdx = body.indexOf("\n```", logStart);
167350
167598
  if (fenceCloseIdx === -1)
167351
- return body;
167599
+ return enforceFinalBodyLimit(body, maxBytes);
167352
167600
  const head = body.slice(0, logStart);
167353
167601
  const log4 = body.slice(logStart, fenceCloseIdx);
167354
167602
  const tail = body.slice(fenceCloseIdx);
167355
167603
  const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
167356
- const truncationMarker = `[truncated for GitHub 64KB limit — older log lines dropped]
167357
- `;
167358
- const markerBytes = Buffer.byteLength(truncationMarker, "utf8");
167604
+ const markerBytes = Buffer.byteLength(LOG_TRUNCATION_MARKER, "utf8");
167359
167605
  const logBudget = maxBytes - overheadBytes - markerBytes;
167360
167606
  if (logBudget <= 0) {
167361
- return `${head}${truncationMarker}${tail}`;
167607
+ capped = `${head}${LOG_TRUNCATION_MARKER}${tail}`;
167608
+ return enforceFinalBodyLimit(capped, maxBytes);
167362
167609
  }
167363
167610
  const lines = log4.split(`
167364
167611
  `);
@@ -167374,7 +167621,17 @@ function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
167374
167621
  if (Buffer.byteLength(kept, "utf8") > logBudget) {
167375
167622
  kept = truncateToByteBudget(kept, logBudget);
167376
167623
  }
167377
- return `${head}${truncationMarker}${kept}${tail}`;
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;
167378
167635
  }
167379
167636
  function truncateToByteBudget(input, maxBytes) {
167380
167637
  if (maxBytes <= 0)
@@ -167388,7 +167645,14 @@ function truncateToByteBudget(input, maxBytes) {
167388
167645
  }
167389
167646
  return buf.subarray(0, end).toString("utf8");
167390
167647
  }
167391
- var MAX_GITHUB_BODY_BYTES = 60000, ERROR_LOG_PATTERNS;
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;
167392
167656
  var init_issue_body = __esm(() => {
167393
167657
  ERROR_LOG_PATTERNS = [
167394
167658
  /\bfailed:/i,
@@ -167401,8 +167665,7 @@ var init_issue_body = __esm(() => {
167401
167665
  });
167402
167666
 
167403
167667
  // src/lib/logs-opencode.ts
167404
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
167405
- import { homedir as homedir12 } from "node:os";
167668
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync5 } from "node:fs";
167406
167669
  import { join as join18 } from "node:path";
167407
167670
  function sanitizeLogContent(content) {
167408
167671
  return sanitizeDiagnosticText(content);
@@ -167443,7 +167706,7 @@ function filterLogLinesBySession(lines, sessionId) {
167443
167706
  return matches.every((id) => id === sessionId);
167444
167707
  });
167445
167708
  }
167446
- async function bundleIssueReport(report, description, _title, sessionFilter = null) {
167709
+ async function bundleIssueReport(report, description, title, sessionFilter = null) {
167447
167710
  const LOG_TAIL_LINES = 400;
167448
167711
  const allLogLines = report.logFile.exists ? readFileSync12(report.logFile.path, "utf-8").split(/\r?\n/) : [];
167449
167712
  const logLines = filterLogLinesBySession(allLogLines, sessionFilter);
@@ -167456,10 +167719,13 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
167456
167719
  `));
167457
167720
  const recentErrorLines = extractRecentErrors(errorScanWindow, 20);
167458
167721
  const configBody = JSON.stringify(sanitizeConfigValue(report.magicContextConfig.flags), null, 2);
167459
- const sanitizedConfigPath = report.configPaths.magicContextConfig.replace(homedir12(), "~");
167722
+ const sanitizedConfigPath = sanitizeDiagnosticText(report.configPaths.magicContextConfig);
167723
+ const sanitizedDescription = sanitizeDiagnosticText(description);
167724
+ const sanitizedTitle = sanitizeDiagnosticText(title).trim();
167460
167725
  const rawBodyMarkdown = [
167726
+ ...sanitizedTitle ? ["## Title", sanitizedTitle, ""] : [],
167461
167727
  "## Description",
167462
- description,
167728
+ sanitizedDescription,
167463
167729
  "",
167464
167730
  "## Environment",
167465
167731
  `- Plugin: v${report.pluginVersion}`,
@@ -167494,7 +167760,7 @@ async function bundleIssueReport(report, description, _title, sessionFilter = nu
167494
167760
  `);
167495
167761
  const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
167496
167762
  const path6 = join18(process.cwd(), `magic-context-issue-${formatTimestamp(new Date)}.md`);
167497
- writeFileSync6(path6, `${bodyMarkdown}
167763
+ writeFileSync5(path6, `${bodyMarkdown}
167498
167764
  `);
167499
167765
  return { path: path6, bodyMarkdown };
167500
167766
  }
@@ -167757,11 +168023,11 @@ function migrateExperimentalPinKeyFilesForDoctor(mcConfig) {
167757
168023
  }
167758
168024
 
167759
168025
  // src/commands/doctor-opencode-cache.ts
167760
- import { existsSync as existsSync22, readFileSync as readFileSync13, rmSync as rmSync2 } from "node:fs";
168026
+ import { existsSync as existsSync21, readFileSync as readFileSync13, rmSync as rmSync2 } from "node:fs";
167761
168027
  function readCachedPluginVersion(pluginCacheDir) {
167762
168028
  try {
167763
168029
  const installedPkgPath = getOpenCodePluginPackageJsonPath(pluginCacheDir);
167764
- if (!existsSync22(installedPkgPath))
168030
+ if (!existsSync21(installedPkgPath))
167765
168031
  return;
167766
168032
  const pkg = JSON.parse(readFileSync13(installedPkgPath, "utf-8"));
167767
168033
  return typeof pkg.version === "string" ? pkg.version : undefined;
@@ -167772,7 +168038,7 @@ function readCachedPluginVersion(pluginCacheDir) {
167772
168038
  async function clearPluginCache(options = {}, deps = {}) {
167773
168039
  const remove = deps.remove ?? ((path6) => rmSync2(path6, { recursive: true, force: true }));
167774
168040
  const pluginCacheRoots = getOpenCodePluginCacheRoots();
167775
- const existingRoots = pluginCacheRoots.filter((root) => existsSync22(root));
168041
+ const existingRoots = pluginCacheRoots.filter((root) => existsSync21(root));
167776
168042
  if (existingRoots.length === 0) {
167777
168043
  return { action: "not_found", path: pluginCacheRoots[0] ?? "" };
167778
168044
  }
@@ -167820,6 +168086,8 @@ async function clearPluginCache(options = {}, deps = {}) {
167820
168086
  action: "error",
167821
168087
  path: firstFailure?.path ?? clearTargets[0]?.path ?? existingRoots[0] ?? "",
167822
168088
  paths: failed.map((entry) => entry.path),
168089
+ clearedPaths: cleared.map((entry) => entry.path),
168090
+ failedPaths: failed.map((entry) => entry.path),
167823
168091
  error: firstFailure?.error
167824
168092
  };
167825
168093
  }
@@ -167838,9 +168106,9 @@ var init_doctor_opencode_cache = __esm(() => {
167838
168106
 
167839
168107
  // src/commands/doctor-opencode.ts
167840
168108
  import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
167841
- import { existsSync as existsSync23, readFileSync as readFileSync14, statSync as statSync8 } from "node:fs";
168109
+ import { existsSync as existsSync22, readFileSync as readFileSync14, statSync as statSync8 } from "node:fs";
167842
168110
  import { createRequire as createRequire4 } from "node:module";
167843
- import { homedir as homedir13 } from "node:os";
168111
+ import { homedir as homedir12 } from "node:os";
167844
168112
  import { join as join19 } from "node:path";
167845
168113
  function migrateLegacyAgentEnabledConfigForDoctor(mcConfig, logs) {
167846
168114
  let changed = false;
@@ -167910,6 +168178,38 @@ function getSelfVersion2() {
167910
168178
  }
167911
168179
  return "0.0.0";
167912
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
+ }
167913
168213
  function compareVersions(a3, b2) {
167914
168214
  const pa = a3.split(/[.-]/).map((s) => Number.parseInt(s, 10));
167915
168215
  const pb = b2.split(/[.-]/).map((s) => Number.parseInt(s, 10));
@@ -168031,7 +168331,7 @@ function checkLocalEmbeddingRuntimeForDoctor() {
168031
168331
  return { issues: 0 };
168032
168332
  }
168033
168333
  async function checkEmbeddingConfig(magicContextConfigPath) {
168034
- if (!existsSync23(magicContextConfigPath)) {
168334
+ if (!existsSync22(magicContextConfigPath)) {
168035
168335
  return checkLocalEmbeddingRuntimeForDoctor();
168036
168336
  }
168037
168337
  let rawText;
@@ -168094,7 +168394,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
168094
168394
  }
168095
168395
  }
168096
168396
  const probeSpinner = spinner2();
168097
- probeSpinner.start(`Testing embedding endpoint ${endpoint} (model: ${model})`);
168397
+ probeSpinner.start(`Testing embedding endpoint ${sanitizeDiagnosticEndpoint(endpoint)} (model: ${sanitizeDiagnosticText(model)})`);
168098
168398
  let outcome;
168099
168399
  try {
168100
168400
  outcome = await probeEmbeddingEndpoint({
@@ -168107,7 +168407,7 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
168107
168407
  });
168108
168408
  } catch (error51) {
168109
168409
  probeSpinner.stop("Embedding probe failed unexpectedly");
168110
- log2.error(`Probe threw: ${error51 instanceof Error ? error51.message : String(error51)}`);
168410
+ log2.error(`Probe threw: ${sanitizeDiagnosticText(error51 instanceof Error ? error51.message : String(error51))}`);
168111
168411
  return { issues: localIssues + 1 };
168112
168412
  }
168113
168413
  probeSpinner.stop("Embedding endpoint probed");
@@ -168118,28 +168418,28 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
168118
168418
  case "auth_failed":
168119
168419
  log2.error(`Embedding endpoint rejected credentials (${outcome.status}) — check api_key / env var`);
168120
168420
  if (outcome.preview)
168121
- log2.info(` ${outcome.preview}`);
168421
+ log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
168122
168422
  return { issues: localIssues + 1 };
168123
168423
  case "endpoint_unsupported":
168124
168424
  log2.error(`Embedding endpoint does not support embeddings (${outcome.status})`);
168125
168425
  if (outcome.preview)
168126
- log2.info(` ${outcome.preview}`);
168426
+ log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
168127
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");
168128
168428
  log2.info(" Known non-embedding providers: OpenRouter (chat proxy), Anthropic (no embeddings endpoint). Use OpenAI, Voyage, Together, or a local provider instead.");
168129
168429
  return { issues: localIssues + 1 };
168130
168430
  case "http_error":
168131
168431
  log2.error(`Embedding endpoint returned ${outcome.status}`);
168132
168432
  if (outcome.preview)
168133
- log2.info(` ${outcome.preview}`);
168433
+ log2.info(` ${sanitizeDiagnosticText(outcome.preview)}`);
168134
168434
  return { issues: localIssues + 1 };
168135
168435
  case "timeout":
168136
168436
  log2.warn(`Embedding endpoint did not respond within ${outcome.timeoutMs}ms — check endpoint URL and network`);
168137
168437
  return { issues: localIssues + 1 };
168138
168438
  case "network_error":
168139
- log2.error(`Could not reach embedding endpoint: ${outcome.message}`);
168439
+ log2.error(`Could not reach embedding endpoint: ${sanitizeDiagnosticText(outcome.message)}`);
168140
168440
  return { issues: localIssues + 1 };
168141
168441
  case "invalid_scheme":
168142
- 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)}`);
168143
168443
  return { issues: localIssues + 1 };
168144
168444
  }
168145
168445
  }
@@ -168207,7 +168507,7 @@ async function runDoctor(options = {}) {
168207
168507
  } else {
168208
168508
  pass(`OpenCode config: ${paths.opencodeConfig}`);
168209
168509
  }
168210
- if (existsSync23(paths.magicContextConfig)) {
168510
+ if (existsSync22(paths.magicContextConfig)) {
168211
168511
  pass(`Magic Context config: ${paths.magicContextConfig}`);
168212
168512
  try {
168213
168513
  const raw = readFileSync14(paths.magicContextConfig, "utf-8");
@@ -168235,7 +168535,7 @@ async function runDoctor(options = {}) {
168235
168535
  warn(`No magic-context.jsonc found — using defaults`);
168236
168536
  log2.info(" Run 'setup' to create one with model recommendations");
168237
168537
  }
168238
- if (existsSync23(paths.magicContextConfig)) {
168538
+ if (existsSync22(paths.magicContextConfig)) {
168239
168539
  try {
168240
168540
  const mcRaw = readFileSync14(paths.magicContextConfig, "utf-8");
168241
168541
  const mcConfig = import_comment_json8.parse(mcRaw);
@@ -168374,7 +168674,7 @@ async function runDoctor(options = {}) {
168374
168674
  if (isDevPathPluginEntry(oldEntry)) {
168375
168675
  pass(`Plugin registered in ${configName} (dev path: ${oldEntryStr})`);
168376
168676
  } else {
168377
- const isPinned = oldEntryStr !== OPENCODE_PLUGIN_NAME && oldEntryStr !== OPENCODE_PLUGIN_ENTRY_WITH_VERSION && /^@cortexkit\/opencode-magic-context@\d/.test(oldEntryStr);
168677
+ const isPinned = isPinnedOpenCodePluginSpecifier(oldEntryStr);
168378
168678
  if (isPinned && !options.force) {
168379
168679
  warn(`Plugin pinned to ${oldEntryStr} in ${configName} — use 'doctor --force' to upgrade`);
168380
168680
  } else {
@@ -168426,7 +168726,7 @@ async function runDoctor(options = {}) {
168426
168726
  pass("Added TUI sidebar plugin to tui.json");
168427
168727
  warn("Restart OpenCode to see the sidebar");
168428
168728
  fixed++;
168429
- } else if (existsSync23(paths.tuiConfig)) {
168729
+ } else if (existsSync22(paths.tuiConfig)) {
168430
168730
  try {
168431
168731
  const tuiRaw = readFileSync14(paths.tuiConfig, "utf-8");
168432
168732
  const tuiConfig = import_comment_json8.parse(tuiRaw);
@@ -168445,7 +168745,7 @@ async function runDoctor(options = {}) {
168445
168745
  if (isDevPathPluginEntry(tuiEntry)) {
168446
168746
  pass(`TUI sidebar plugin configured (dev path: ${tuiEntryStr})`);
168447
168747
  } else {
168448
- const tuiPinned = tuiEntryStr !== OPENCODE_PLUGIN_NAME && tuiEntryStr !== OPENCODE_PLUGIN_ENTRY_WITH_VERSION && /^@cortexkit\/opencode-magic-context@\d/.test(tuiEntryStr);
168748
+ const tuiPinned = isPinnedOpenCodePluginSpecifier(tuiEntryStr);
168449
168749
  if (tuiPinned && !options.force) {
168450
168750
  warn(`TUI plugin pinned to ${tuiEntryStr} — use 'doctor --force' to upgrade`);
168451
168751
  } else if (tuiPinned && options.force) {
@@ -168474,7 +168774,7 @@ async function runDoctor(options = {}) {
168474
168774
  } else {
168475
168775
  pass("TUI sidebar plugin configured (tui.json created)");
168476
168776
  }
168477
- if (existsSync23(paths.magicContextConfig)) {
168777
+ if (existsSync22(paths.magicContextConfig)) {
168478
168778
  try {
168479
168779
  const mcRaw = readFileSync14(paths.magicContextConfig, "utf-8");
168480
168780
  const mcConfig = import_comment_json8.parse(mcRaw);
@@ -168495,7 +168795,7 @@ async function runDoctor(options = {}) {
168495
168795
  else
168496
168796
  passCount++;
168497
168797
  const dbPath = join19(getMagicContextStorageDir(), "context.db");
168498
- if (!existsSync23(dbPath)) {
168798
+ if (!existsSync22(dbPath)) {
168499
168799
  log2.info(`Shared context DB not yet created at ${dbPath} (will be created on first run)`);
168500
168800
  } else {
168501
168801
  pass(`Shared context DB exists at ${dbPath}`);
@@ -168555,29 +168855,20 @@ async function runDoctor(options = {}) {
168555
168855
  warn(`Plugin cache version check unavailable; preserving cached plugin${cacheResult.cached ? ` (cached: ${cacheResult.cached})` : ""}. Use doctor --force to reinstall it.`);
168556
168856
  } else if (cacheResult.action === "error") {
168557
168857
  warn(`Could not clear plugin cache: ${cacheResult.error}`);
168558
- log2.info(` Manually delete: ${cacheResult.path}`);
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
+ }
168559
168866
  issues++;
168560
168867
  } else {
168561
168868
  pass("Plugin cache clean (no cached version found)");
168562
168869
  }
168563
168870
  {
168564
- const ageWarnings = [];
168565
- const npmrcPath = join19(homedir13(), ".npmrc");
168566
- if (existsSync23(npmrcPath)) {
168567
- try {
168568
- const npmrc = readFileSync14(npmrcPath, "utf-8");
168569
- for (const line of npmrc.split(`
168570
- `)) {
168571
- const trimmed = line.trim();
168572
- if (trimmed.startsWith("#") || trimmed.startsWith(";"))
168573
- continue;
168574
- const [key] = trimmed.split("=").map((s) => s.trim());
168575
- if (key === "min-release-age" || key === "before") {
168576
- ageWarnings.push(`~/.npmrc has '${trimmed}'`);
168577
- }
168578
- }
168579
- } catch {}
168580
- }
168871
+ const ageWarnings = collectNpmReleaseAgeWarnings();
168581
168872
  if (ageWarnings.length > 0) {
168582
168873
  log2.warn("npm min-release-age restriction detected — this can prevent OpenCode from installing the latest plugin version");
168583
168874
  for (const w of ageWarnings) {
@@ -168589,7 +168880,7 @@ async function runDoctor(options = {}) {
168589
168880
  }
168590
168881
  }
168591
168882
  const logPath = getMagicContextLogPath2("opencode");
168592
- if (existsSync23(logPath)) {
168883
+ if (existsSync22(logPath)) {
168593
168884
  const logStat = statSync8(logPath);
168594
168885
  const sizeKb = (logStat.size / 1024).toFixed(0);
168595
168886
  log2.info(`Log file: ${logPath} (${sizeKb} KB)`);
@@ -168654,6 +168945,7 @@ var init_doctor_opencode = __esm(async () => {
168654
168945
  init_opencode_plugin_cache();
168655
168946
  init_paths();
168656
168947
  init_prompts();
168948
+ init_redaction2();
168657
168949
  init_v22_backfill_commands();
168658
168950
  init_doctor_opencode_cache();
168659
168951
  await __promiseAll([
@@ -168664,7 +168956,7 @@ var init_doctor_opencode = __esm(async () => {
168664
168956
  });
168665
168957
 
168666
168958
  // ../pi-plugin/src/config/index.ts
168667
- import { existsSync as existsSync24, readFileSync as readFileSync15 } from "node:fs";
168959
+ import { existsSync as existsSync23, readFileSync as readFileSync15 } from "node:fs";
168668
168960
  function getProjectConfigPaths(cwd) {
168669
168961
  const basePath = cortexKitProjectConfigBasePath(cwd);
168670
168962
  return [`${basePath}.jsonc`, `${basePath}.json`];
@@ -168674,10 +168966,10 @@ function getUserConfigPaths() {
168674
168966
  return [`${basePath}.jsonc`, `${basePath}.json`];
168675
168967
  }
168676
168968
  function resolveFirstExisting(paths) {
168677
- return paths.find((path6) => existsSync24(path6));
168969
+ return paths.find((path6) => existsSync23(path6));
168678
168970
  }
168679
168971
  function resolvePiLegacyFallback(sources) {
168680
- return sources.find((source) => existsSync24(source.path)) ?? null;
168972
+ return sources.find((source) => existsSync23(source.path)) ?? null;
168681
168973
  }
168682
168974
  function loadConfigFile(path6, scope) {
168683
168975
  try {
@@ -168814,7 +169106,7 @@ function loadPiConfig(opts = {}) {
168814
169106
  if (loaded)
168815
169107
  loadedFiles.push(loaded);
168816
169108
  }
168817
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync24(source.path));
169109
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync23(source.path));
168818
169110
  const userPath = resolveFirstExisting(getUserConfigPaths());
168819
169111
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
168820
169112
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -168823,7 +169115,7 @@ function loadPiConfig(opts = {}) {
168823
169115
  if (loaded)
168824
169116
  loadedFiles.push(loaded);
168825
169117
  }
168826
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync24(source.path));
169118
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync23(source.path));
168827
169119
  if (userLegacyFallback) {
168828
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.`);
168829
169121
  } else if (legacyUserUnmigrated) {
@@ -168841,6 +169133,7 @@ function loadPiConfig(opts = {}) {
168841
169133
  return a3.scope === "user" ? -1 : 1;
168842
169134
  });
168843
169135
  const userRaw = mergeFiles.find((f2) => f2.scope === "user")?.config;
169136
+ const trustedBaseConfig = parsePiConfig(userRaw ?? {}).config;
168844
169137
  for (const loaded of mergeFiles) {
168845
169138
  const prefix = loaded.scope === "user" ? "[user config]" : "[project config]";
168846
169139
  warnings.push(...loaded.warnings.map((warning) => `${prefix} ${warning}`));
@@ -168853,6 +169146,13 @@ function loadPiConfig(opts = {}) {
168853
169146
  for (const warning of dropInheritedEmbeddingKeyOnRedirect(projectRaw, rawConfig, userRaw)) {
168854
169147
  warnings.push(`${prefix} ${warning}`);
168855
169148
  }
169149
+ for (const warning of constrainProjectThresholdOverrides({
169150
+ mergedRaw: rawConfig,
169151
+ projectRaw,
169152
+ trustedBaseConfig
169153
+ })) {
169154
+ warnings.push(`${prefix} ${warning}`);
169155
+ }
168856
169156
  } else {
168857
169157
  rawConfig = mergeRawConfigs(rawConfig, loaded.config);
168858
169158
  }
@@ -168877,9 +169177,9 @@ var init_config2 = __esm(() => {
168877
169177
 
168878
169178
  // src/lib/diagnostics-pi.ts
168879
169179
  import { createHash as createHash3 } from "node:crypto";
168880
- import { existsSync as existsSync25, readdirSync as readdirSync3, readFileSync as readFileSync16, statSync as statSync9 } from "node:fs";
169180
+ import { existsSync as existsSync24, readdirSync as readdirSync3, readFileSync as readFileSync16, statSync as statSync9 } from "node:fs";
168881
169181
  import { createRequire as createRequire5 } from "node:module";
168882
- import { homedir as homedir14, userInfo as userInfo2 } from "node:os";
169182
+ import { homedir as homedir13, userInfo as userInfo2 } from "node:os";
168883
169183
  import { join as join20 } from "node:path";
168884
169184
  function getSelfVersion3() {
168885
169185
  const req = createRequire5(import.meta.url);
@@ -168895,7 +169195,7 @@ function getSelfVersion3() {
168895
169195
  }
168896
169196
  function fileSize2(path6) {
168897
169197
  try {
168898
- return existsSync25(path6) ? statSync9(path6).size : 0;
169198
+ return existsSync24(path6) ? statSync9(path6).size : 0;
168899
169199
  } catch {
168900
169200
  return 0;
168901
169201
  }
@@ -168911,7 +169211,7 @@ function redactSecretString(value) {
168911
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>");
168912
169212
  }
168913
169213
  function sanitizeString2(value) {
168914
- const home = process.env.HOME || homedir14();
169214
+ const home = process.env.HOME || homedir13();
168915
169215
  const username = userInfo2().username;
168916
169216
  const userHash = `<USER:${currentUserHash()}>`;
168917
169217
  let sanitized = redactSecretString(value);
@@ -168930,6 +169230,8 @@ function shouldRedactKey(key) {
168930
169230
  return /api[_-]?key|token|secret|password|authorization|cookie/i.test(key);
168931
169231
  }
168932
169232
  function sanitizeValue2(value, key = "") {
169233
+ if (value === null || typeof value === "number" || typeof value === "boolean")
169234
+ return value;
168933
169235
  if (shouldRedactKey(key))
168934
169236
  return "<REDACTED>";
168935
169237
  if (typeof value === "string")
@@ -168945,7 +169247,7 @@ function sanitizeValue2(value, key = "") {
168945
169247
  return value;
168946
169248
  }
168947
169249
  function readJsonc3(path6) {
168948
- if (!existsSync25(path6))
169250
+ if (!existsSync24(path6))
168949
169251
  return { value: {} };
168950
169252
  try {
168951
169253
  return {
@@ -168965,7 +169267,7 @@ function readConfigDiagnostic(path6) {
168965
169267
  const parsed = readJsonc3(path6);
168966
169268
  return {
168967
169269
  path: path6,
168968
- exists: existsSync25(path6),
169270
+ exists: existsSync24(path6),
168969
169271
  ...parsed.parseError ? { parseError: parsed.parseError } : {},
168970
169272
  flags: sanitizeValue2(parsed.value)
168971
169273
  };
@@ -168982,8 +169284,8 @@ function reverseSlugToDirectory(slug) {
168982
169284
  return `/${inner.replace(/-/g, "/")}`;
168983
169285
  }
168984
169286
  function collectPiRecentSessions() {
168985
- const sessionsRoot = join20(process.env.HOME || homedir14(), ".pi", "agent", "sessions");
168986
- if (!existsSync25(sessionsRoot))
169287
+ const sessionsRoot = getPiSessionsRoot();
169288
+ if (!existsSync24(sessionsRoot))
168987
169289
  return [];
168988
169290
  try {
168989
169291
  const slugs = readdirSync3(sessionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -169052,7 +169354,7 @@ function parseHistorianDumpMeta2(path6) {
169052
169354
  }
169053
169355
  }
169054
169356
  function listDumpsInDir2(dir, limit) {
169055
- if (!existsSync25(dir))
169357
+ if (!existsSync24(dir))
169056
169358
  return { count: 0, recent: [] };
169057
169359
  try {
169058
169360
  const entries = readdirSync3(dir).filter((name2) => name2.endsWith(".xml")).map((name2) => {
@@ -169130,7 +169432,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
169130
169432
  const storageDirPath = getMagicContextStorageDir();
169131
169433
  const dbPath = join20(storageDirPath, "context.db");
169132
169434
  const logPath = getMagicContextLogPath2("pi");
169133
- const logFileSize = existsSync25(logPath) ? statSync9(logPath).size : 0;
169435
+ const logFileSize = existsSync24(logPath) ? statSync9(logPath).size : 0;
169134
169436
  const otherPiExtensions = packages.filter((entry) => !isPiMagicContextPackageEntry(entry)).map(describePiPackageEntry);
169135
169437
  const recentSessions = collectPiRecentSessions();
169136
169438
  const historianDumps = collectPiHistorianDumps(recentSessions);
@@ -169145,7 +169447,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
169145
169447
  piVersion: pi ? getPiVersion(pi.path) : null,
169146
169448
  settings: {
169147
169449
  path: settingsPath,
169148
- exists: existsSync25(settingsPath),
169450
+ exists: existsSync24(settingsPath),
169149
169451
  ...settingsParsed.parseError ? { parseError: settingsParsed.parseError } : {},
169150
169452
  hasMagicContextPackage: hasPiMagicContextPackage(packages),
169151
169453
  packages: sanitizeValue2(packages)
@@ -169161,7 +169463,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
169161
169463
  loadWarnings: loaded.warnings.map(sanitizeString2),
169162
169464
  storageDir: {
169163
169465
  path: storageDirPath,
169164
- exists: existsSync25(storageDirPath),
169466
+ exists: existsSync24(storageDirPath),
169165
169467
  contextDbSizeBytes: fileSize2(dbPath)
169166
169468
  },
169167
169469
  conflicts: {
@@ -169170,7 +169472,7 @@ async function collectDiagnostics2(cwd = process.cwd()) {
169170
169472
  },
169171
169473
  logFile: {
169172
169474
  path: logPath,
169173
- exists: existsSync25(logPath),
169475
+ exists: existsSync24(logPath),
169174
169476
  sizeKb: Math.round(logFileSize / 1024)
169175
169477
  },
169176
169478
  recentSessions,
@@ -169264,7 +169566,7 @@ var init_diagnostics_pi = __esm(() => {
169264
169566
  });
169265
169567
 
169266
169568
  // src/lib/logs-pi.ts
169267
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "node:fs";
169569
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "node:fs";
169268
169570
  import { join as join21 } from "node:path";
169269
169571
  function sanitizeLogContent2(content) {
169270
169572
  return sanitizeString2(content);
@@ -169331,7 +169633,7 @@ async function bundleIssueReport2(report, description, title, options = {}) {
169331
169633
  const bodyMarkdown = capBodyToGithubLimit(rawBodyMarkdown);
169332
169634
  const cwd = options.cwd ?? process.cwd();
169333
169635
  const path6 = join21(cwd, `magic-context-pi-issue-${formatTimestamp2(options.now ?? new Date)}.md`);
169334
- writeFileSync7(path6, `${bodyMarkdown}
169636
+ writeFileSync6(path6, `${bodyMarkdown}
169335
169637
  `);
169336
169638
  return { path: path6, bodyMarkdown };
169337
169639
  }
@@ -169342,10 +169644,10 @@ var init_logs_pi = __esm(() => {
169342
169644
 
169343
169645
  // src/commands/doctor-pi.ts
169344
169646
  import { execFileSync as execFileSync5, spawnSync as spawnSync4 } from "node:child_process";
169345
- import { existsSync as existsSync26, mkdirSync as mkdirSync9, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as rmSync3, statSync as statSync10 } from "node:fs";
169647
+ import { existsSync as existsSync25, mkdirSync as mkdirSync8, readdirSync as readdirSync4, readFileSync as readFileSync18, rmSync as rmSync3, statSync as statSync10 } from "node:fs";
169346
169648
  import { createRequire as createRequire6 } from "node:module";
169347
- import { homedir as homedir15 } from "node:os";
169348
- import { dirname as dirname12, isAbsolute as isAbsolute3, join as join22 } from "node:path";
169649
+ import { homedir as homedir14 } from "node:os";
169650
+ import { dirname as dirname13, isAbsolute as isAbsolute3, join as join22 } from "node:path";
169349
169651
  function depsFrom(options) {
169350
169652
  return {
169351
169653
  ...DEFAULT_DEPS,
@@ -169459,13 +169761,13 @@ function piPluginDirCandidates(packages, cwd) {
169459
169761
  }
169460
169762
  dirs.push(join22(agentDir, "npm", "node_modules", PACKAGE_NAME));
169461
169763
  dirs.push(join22(cwd, ".pi", "npm", "node_modules", PACKAGE_NAME));
169462
- return dirs.filter((dir) => existsSync26(join22(dir, "package.json")));
169764
+ return dirs.filter((dir) => existsSync25(join22(dir, "package.json")));
169463
169765
  }
169464
169766
  function projectConfigPath(cwd) {
169465
169767
  return resolveCortexKitProjectConfigPath(cwd);
169466
169768
  }
169467
169769
  function readConfigForEmbedding(path6, isProjectConfig) {
169468
- if (!existsSync26(path6))
169770
+ if (!existsSync25(path6))
169469
169771
  return null;
169470
169772
  try {
169471
169773
  const rawText = readFileSync18(path6, "utf-8");
@@ -169499,7 +169801,7 @@ function classifyEmbeddingOutcome(outcome) {
169499
169801
  case "network_error":
169500
169802
  return {
169501
169803
  status: "fail",
169502
- message: `Embedding endpoint network error: ${outcome.message}`
169804
+ message: `Embedding endpoint network error: ${sanitizeDiagnosticText(outcome.message)}`
169503
169805
  };
169504
169806
  case "endpoint_unsupported":
169505
169807
  return {
@@ -169514,7 +169816,7 @@ function classifyEmbeddingOutcome(outcome) {
169514
169816
  case "invalid_scheme":
169515
169817
  return {
169516
169818
  status: "fail",
169517
- message: `Embedding endpoint must start with http:// or https://: ${outcome.endpoint}`
169819
+ message: `Embedding endpoint must start with http:// or https://: ${sanitizeDiagnosticEndpoint(outcome.endpoint)}`
169518
169820
  };
169519
169821
  }
169520
169822
  }
@@ -169527,11 +169829,12 @@ function countTable(db, table) {
169527
169829
  }
169528
169830
  }
169529
169831
  function cacheRoots() {
169530
- const home = homedir15();
169531
- 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();
169532
169835
  return [
169533
- join22(home, ".pi", "cache", "extensions"),
169534
- join22(home, ".pi", "cache", "packages"),
169836
+ join22(piCacheRoot, "extensions"),
169837
+ join22(piCacheRoot, "packages"),
169535
169838
  join22(cacheHome, "pi", "extensions"),
169536
169839
  join22(cacheHome, "pi", "packages"),
169537
169840
  join22(getPiAgentConfigDir(), "cache", "extensions")
@@ -169540,7 +169843,7 @@ function cacheRoots() {
169540
169843
  function findPiMagicContextCacheDirs(self, force = false) {
169541
169844
  const found = new Map;
169542
169845
  const visit = (path6, depth) => {
169543
- if (depth < 0 || !existsSync26(path6))
169846
+ if (depth < 0 || !existsSync25(path6))
169544
169847
  return;
169545
169848
  let stat;
169546
169849
  try {
@@ -169551,7 +169854,7 @@ function findPiMagicContextCacheDirs(self, force = false) {
169551
169854
  if (!stat.isDirectory())
169552
169855
  return;
169553
169856
  const packageJson = join22(path6, "package.json");
169554
- if (existsSync26(packageJson)) {
169857
+ if (existsSync25(packageJson)) {
169555
169858
  try {
169556
169859
  const pkg = JSON.parse(readFileSync18(packageJson, "utf-8"));
169557
169860
  const name2 = typeof pkg.name === "string" ? pkg.name : "";
@@ -169586,7 +169889,7 @@ async function runHealthChecks(options) {
169586
169889
  writeUserConfig: false,
169587
169890
  clearCachePaths: []
169588
169891
  };
169589
- const self = selfVersion();
169892
+ const self = options.deps.selfVersion();
169590
169893
  const pi = options.deps.detectPiBinary();
169591
169894
  if (!pi) {
169592
169895
  add(results, "fail", "Pi binary not found on PATH or at ~/.pi/bin/pi");
@@ -169601,16 +169904,19 @@ async function runHealthChecks(options) {
169601
169904
  }
169602
169905
  }
169603
169906
  const latest = options.deps.getLatestNpmVersion();
169604
- if (latest && compareSemver(self, latest) === -1) {
169907
+ const latestCompare = latest ? compareSemver(self, latest) : null;
169908
+ if (latest && latestCompare === -1) {
169605
169909
  add(results, "warn", `Magic Context for Pi CLI v${self} is older than npm latest v${latest}`);
169606
- } else if (latest) {
169910
+ } else if (latest && latestCompare !== null) {
169607
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}`);
169608
169914
  } else {
169609
169915
  add(results, "info", `Magic Context for Pi CLI v${self}; npm latest check unavailable`);
169610
169916
  }
169611
169917
  const settingsPath = getPiUserExtensionsPath();
169612
169918
  let packages = [];
169613
- if (!existsSync26(settingsPath)) {
169919
+ if (!existsSync25(settingsPath)) {
169614
169920
  add(results, "warn", `Pi settings not found at ${settingsPath}`);
169615
169921
  repairPlan.addPackageEntry = true;
169616
169922
  } else {
@@ -169634,7 +169940,7 @@ async function runHealthChecks(options) {
169634
169940
  ["user", userConfigPath, true],
169635
169941
  ["project", projectPath, false]
169636
169942
  ]) {
169637
- if (!existsSync26(path6)) {
169943
+ if (!existsSync25(path6)) {
169638
169944
  if (required2) {
169639
169945
  add(results, "warn", `No ${label} magic-context.jsonc found at ${path6}`);
169640
169946
  if (userConfigMigrationRefused) {
@@ -169672,7 +169978,7 @@ async function runHealthChecks(options) {
169672
169978
  }
169673
169979
  const storageDir = getMagicContextStorageDir();
169674
169980
  const dbPath = join22(storageDir, "context.db");
169675
- const existedBeforeOpen = existsSync26(dbPath);
169981
+ const existedBeforeOpen = existsSync25(dbPath);
169676
169982
  if (existedBeforeOpen)
169677
169983
  add(results, "pass", `Shared context DB exists at ${dbPath}`);
169678
169984
  else
@@ -169736,7 +170042,7 @@ async function runHealthChecks(options) {
169736
170042
  const classified = classifyEmbeddingOutcome(outcome);
169737
170043
  add(results, classified.status, classified.message);
169738
170044
  } catch (error51) {
169739
- 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))}`);
169740
170046
  }
169741
170047
  }
169742
170048
  } else if (loadedConfig.config.embedding.provider === "off") {
@@ -169780,7 +170086,7 @@ async function runHealthChecks(options) {
169780
170086
  add(results, "pass", "Pi extension cache clean (no stale cached package found)");
169781
170087
  }
169782
170088
  const logPath = getMagicContextLogPath2("pi");
169783
- if (existsSync26(logPath)) {
170089
+ if (existsSync25(logPath)) {
169784
170090
  const stat = statSync10(logPath);
169785
170091
  const sizeKb = (stat.size / 1024).toFixed(0);
169786
170092
  const lines = readFileSync18(logPath, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -169818,7 +170124,7 @@ async function runHealthChecks(options) {
169818
170124
  return { results, repairPlan, ...summarize(results) };
169819
170125
  }
169820
170126
  function writeDefaultMagicContextConfig(path6) {
169821
- mkdirSync9(dirname12(path6), { recursive: true });
170127
+ mkdirSync8(dirname13(path6), { recursive: true });
169822
170128
  const config2 = {
169823
170129
  $schema: "https://raw.githubusercontent.com/cortexkit/magic-context/master/assets/magic-context.schema.json",
169824
170130
  ...MagicContextConfigSchema.parse({})
@@ -169840,7 +170146,7 @@ function repair(plan, prompts) {
169840
170146
  }
169841
170147
  if (plan.writeUserConfig) {
169842
170148
  const configPath = getPiUserConfigPath();
169843
- if (!existsSync26(configPath)) {
170149
+ if (!existsSync25(configPath)) {
169844
170150
  try {
169845
170151
  writeDefaultMagicContextConfig(configPath);
169846
170152
  prompts.log.success(`Wrote default Magic Context config to ${configPath}`);
@@ -170043,6 +170349,7 @@ var init_doctor_pi = __esm(async () => {
170043
170349
  detectPiBinary,
170044
170350
  getPiVersion,
170045
170351
  getLatestNpmVersion: () => getLatestNpmVersion(PACKAGE_NAME),
170352
+ selfVersion,
170046
170353
  probeEmbeddingEndpoint,
170047
170354
  openDatabase,
170048
170355
  isDatabasePersisted,
@@ -170058,7 +170365,7 @@ var exports_doctor = {};
170058
170365
  __export(exports_doctor, {
170059
170366
  runDoctor: () => runDoctor3
170060
170367
  });
170061
- import { existsSync as existsSync27, rmSync as rmSync4 } from "node:fs";
170368
+ import { existsSync as existsSync26, rmSync as rmSync4 } from "node:fs";
170062
170369
  async function runDoctor3(options) {
170063
170370
  if (options.clear)
170064
170371
  return runClear();
@@ -170147,7 +170454,7 @@ async function runClear() {
170147
170454
  const s = spinner2();
170148
170455
  s.start(`Clearing ${item.path}`);
170149
170456
  try {
170150
- if (existsSync27(item.path)) {
170457
+ if (existsSync26(item.path)) {
170151
170458
  rmSync4(item.path, { recursive: true, force: true });
170152
170459
  }
170153
170460
  s.stop(`Cleared ${item.path}`);