@cortexkit/pi-magic-context 0.30.6 → 0.30.7

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 +328 -112
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -149634,6 +149634,263 @@ function parseReportedLimit(message) {
149634
149634
  }
149635
149635
  return;
149636
149636
  }
149637
+
149638
+ // ../plugin/src/features/magic-context/session-project-backfill.ts
149639
+ init_logger();
149640
+ import { existsSync as existsSync4 } from "node:fs";
149641
+
149642
+ // ../plugin/src/features/magic-context/session-project-storage.ts
149643
+ var upsertSessionProjectStatements = new WeakMap;
149644
+ var repairSessionChunkProjectStatements = new WeakMap;
149645
+ var repairProjectChunkProjectStatements = new WeakMap;
149646
+ function getUpsertSessionProjectStatement(db) {
149647
+ let stmt = upsertSessionProjectStatements.get(db);
149648
+ if (!stmt) {
149649
+ stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
149650
+ VALUES (?, ?, ?, ?)
149651
+ ON CONFLICT(session_id, harness) DO UPDATE SET
149652
+ project_path = excluded.project_path,
149653
+ updated_at = excluded.updated_at
149654
+ WHERE session_projects.project_path <> excluded.project_path`);
149655
+ upsertSessionProjectStatements.set(db, stmt);
149656
+ }
149657
+ return stmt;
149658
+ }
149659
+ function getRepairSessionChunkProjectStatement(db) {
149660
+ let stmt = repairSessionChunkProjectStatements.get(db);
149661
+ if (!stmt) {
149662
+ stmt = db.prepare(`UPDATE compartment_chunk_embeddings
149663
+ SET project_path = ?
149664
+ WHERE session_id = ?
149665
+ AND harness = ?
149666
+ AND project_path <> ?`);
149667
+ repairSessionChunkProjectStatements.set(db, stmt);
149668
+ }
149669
+ return stmt;
149670
+ }
149671
+ function getRepairProjectChunkProjectStatement(db) {
149672
+ let stmt = repairProjectChunkProjectStatements.get(db);
149673
+ if (!stmt) {
149674
+ stmt = db.prepare(`UPDATE compartment_chunk_embeddings
149675
+ SET project_path = (
149676
+ SELECT sp.project_path
149677
+ FROM session_projects sp
149678
+ WHERE sp.session_id = compartment_chunk_embeddings.session_id
149679
+ AND sp.harness = compartment_chunk_embeddings.harness
149680
+ LIMIT 1
149681
+ )
149682
+ WHERE EXISTS (
149683
+ SELECT 1
149684
+ FROM session_projects sp
149685
+ WHERE sp.session_id = compartment_chunk_embeddings.session_id
149686
+ AND sp.harness = compartment_chunk_embeddings.harness
149687
+ AND sp.project_path <> compartment_chunk_embeddings.project_path
149688
+ AND (
149689
+ sp.project_path = ?
149690
+ OR compartment_chunk_embeddings.project_path = ?
149691
+ )
149692
+ )`);
149693
+ repairProjectChunkProjectStatements.set(db, stmt);
149694
+ }
149695
+ return stmt;
149696
+ }
149697
+ function recordSessionProjectIdentity(db, sessionId, projectPath) {
149698
+ if (!sessionId || !projectPath)
149699
+ return;
149700
+ const harness = getHarness();
149701
+ const now = Date.now();
149702
+ db.transaction(() => {
149703
+ getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
149704
+ getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath);
149705
+ })();
149706
+ }
149707
+ function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
149708
+ if (!projectPath)
149709
+ return 0;
149710
+ return getRepairProjectChunkProjectStatement(db).run(projectPath, projectPath).changes;
149711
+ }
149712
+
149713
+ // ../plugin/src/features/magic-context/session-project-backfill.ts
149714
+ var LEASE_TTL_MS = 10 * 60 * 1000;
149715
+ var SESSION_QUERY_CHUNK_SIZE = 250;
149716
+ var YIELD_EVERY_NEW_DIRECTORIES = 10;
149717
+ function ensureBackfillStateTable(db) {
149718
+ db.exec(`
149719
+ CREATE TABLE IF NOT EXISTS session_project_backfill_state (
149720
+ harness TEXT PRIMARY KEY,
149721
+ status TEXT NOT NULL CHECK (status IN ('running', 'completed')),
149722
+ started_at INTEGER,
149723
+ lease_expires_at INTEGER,
149724
+ completed_at INTEGER
149725
+ );
149726
+ `);
149727
+ }
149728
+ function withImmediateTransaction(db, fn) {
149729
+ db.exec("BEGIN IMMEDIATE");
149730
+ try {
149731
+ const result = fn();
149732
+ db.exec("COMMIT");
149733
+ return result;
149734
+ } catch (error) {
149735
+ try {
149736
+ db.exec("ROLLBACK");
149737
+ } catch {}
149738
+ throw error;
149739
+ }
149740
+ }
149741
+ function defaultYieldFn() {
149742
+ return new Promise((resolve) => setTimeout(resolve, 0));
149743
+ }
149744
+ function acquireBackfillLease(db, harness, now) {
149745
+ ensureBackfillStateTable(db);
149746
+ return withImmediateTransaction(db, () => {
149747
+ const current = db.prepare(`SELECT harness, status, started_at, lease_expires_at, completed_at
149748
+ FROM session_project_backfill_state
149749
+ WHERE harness = ?`).get(harness);
149750
+ if (current?.status === "completed") {
149751
+ return "already_completed";
149752
+ }
149753
+ if (current?.status === "running" && current.lease_expires_at !== null && current.lease_expires_at > now) {
149754
+ return "blocked_by_lease";
149755
+ }
149756
+ db.prepare(`INSERT INTO session_project_backfill_state(
149757
+ harness,
149758
+ status,
149759
+ started_at,
149760
+ lease_expires_at,
149761
+ completed_at
149762
+ )
149763
+ VALUES (?, 'running', ?, ?, NULL)
149764
+ ON CONFLICT(harness) DO UPDATE SET
149765
+ status = 'running',
149766
+ started_at = excluded.started_at,
149767
+ lease_expires_at = excluded.lease_expires_at,
149768
+ completed_at = NULL`).run(harness, now, now + LEASE_TTL_MS);
149769
+ return "completed";
149770
+ });
149771
+ }
149772
+ function renewBackfillLease(db, harness, now) {
149773
+ ensureBackfillStateTable(db);
149774
+ db.prepare(`UPDATE session_project_backfill_state
149775
+ SET lease_expires_at = ?
149776
+ WHERE harness = ? AND status = 'running'`).run(now + LEASE_TTL_MS, harness);
149777
+ }
149778
+ function markBackfillCompleted(db, harness, now) {
149779
+ ensureBackfillStateTable(db);
149780
+ db.prepare(`INSERT INTO session_project_backfill_state(
149781
+ harness,
149782
+ status,
149783
+ started_at,
149784
+ lease_expires_at,
149785
+ completed_at
149786
+ )
149787
+ VALUES (?, 'completed', ?, NULL, ?)
149788
+ ON CONFLICT(harness) DO UPDATE SET
149789
+ status = 'completed',
149790
+ lease_expires_at = NULL,
149791
+ completed_at = excluded.completed_at`).run(harness, now, now);
149792
+ }
149793
+ function dedupeSessions(sessions) {
149794
+ const sessionsById = new Map;
149795
+ for (const session of sessions) {
149796
+ if (!session.sessionId)
149797
+ continue;
149798
+ const existing = sessionsById.get(session.sessionId);
149799
+ if (!existing) {
149800
+ sessionsById.set(session.sessionId, {
149801
+ sessionId: session.sessionId,
149802
+ directory: session.directory
149803
+ });
149804
+ continue;
149805
+ }
149806
+ if (!existing.directory && session.directory) {
149807
+ sessionsById.set(session.sessionId, {
149808
+ sessionId: session.sessionId,
149809
+ directory: session.directory
149810
+ });
149811
+ }
149812
+ }
149813
+ return [...sessionsById.values()];
149814
+ }
149815
+ function getMappedSessionIds(db, harness, sessions) {
149816
+ const mapped = new Set;
149817
+ for (let index = 0;index < sessions.length; index += SESSION_QUERY_CHUNK_SIZE) {
149818
+ const chunk = sessions.slice(index, index + SESSION_QUERY_CHUNK_SIZE);
149819
+ if (chunk.length === 0)
149820
+ continue;
149821
+ const placeholders = chunk.map(() => "?").join(", ");
149822
+ const rows = db.prepare(`SELECT session_id
149823
+ FROM session_projects
149824
+ WHERE harness = ?
149825
+ AND session_id IN (${placeholders})`).all(harness, ...chunk.map((session) => session.sessionId));
149826
+ for (const row of rows) {
149827
+ mapped.add(row.session_id);
149828
+ }
149829
+ }
149830
+ return mapped;
149831
+ }
149832
+ async function runSessionProjectBackfill(db, sessions, options = {}) {
149833
+ const startedAt = performance.now();
149834
+ const harness = getHarness();
149835
+ const now = options.now ?? Date.now;
149836
+ const resolveIdentity = options.resolveIdentity ?? resolveProjectIdentity;
149837
+ const yieldFn = options.yieldFn ?? defaultYieldFn;
149838
+ const dedupedSessions = dedupeSessions(sessions);
149839
+ const result = {
149840
+ status: "completed",
149841
+ totalSessions: dedupedSessions.length,
149842
+ alreadyMappedSessions: 0,
149843
+ unmappedSessions: 0,
149844
+ backfilledSessions: 0,
149845
+ skippedDeadDirectories: 0,
149846
+ skippedEmptyDirectories: 0,
149847
+ durationMs: 0
149848
+ };
149849
+ const leaseStatus = acquireBackfillLease(db, harness, now());
149850
+ if (leaseStatus !== "completed") {
149851
+ result.status = leaseStatus;
149852
+ result.durationMs = performance.now() - startedAt;
149853
+ return result;
149854
+ }
149855
+ const mappedSessionIds = getMappedSessionIds(db, harness, dedupedSessions);
149856
+ result.alreadyMappedSessions = mappedSessionIds.size;
149857
+ const existenceCache = new Map;
149858
+ const identityCache2 = new Map;
149859
+ let newDirectoryResolutions = 0;
149860
+ for (const session of dedupedSessions) {
149861
+ if (mappedSessionIds.has(session.sessionId)) {
149862
+ continue;
149863
+ }
149864
+ result.unmappedSessions += 1;
149865
+ if (!session.directory) {
149866
+ result.skippedEmptyDirectories += 1;
149867
+ continue;
149868
+ }
149869
+ const stillExists = existenceCache.get(session.directory) ?? existsSync4(session.directory);
149870
+ existenceCache.set(session.directory, stillExists);
149871
+ if (!stillExists) {
149872
+ result.skippedDeadDirectories += 1;
149873
+ continue;
149874
+ }
149875
+ let identity = identityCache2.get(session.directory);
149876
+ if (!identity) {
149877
+ identity = resolveIdentity(session.directory);
149878
+ identityCache2.set(session.directory, identity);
149879
+ newDirectoryResolutions += 1;
149880
+ if (newDirectoryResolutions % YIELD_EVERY_NEW_DIRECTORIES === 0) {
149881
+ renewBackfillLease(db, harness, now());
149882
+ await yieldFn();
149883
+ renewBackfillLease(db, harness, now());
149884
+ }
149885
+ }
149886
+ recordSessionProjectIdentity(db, session.sessionId, identity);
149887
+ result.backfilledSessions += 1;
149888
+ }
149889
+ markBackfillCompleted(db, harness, now());
149890
+ result.durationMs = performance.now() - startedAt;
149891
+ log(`[session-projects] backfilled ${result.backfilledSessions} of ${result.unmappedSessions} unmapped sessions (skipped ${result.skippedDeadDirectories} dead dirs) in ${Math.round(result.durationMs)}ms`);
149892
+ return result;
149893
+ }
149637
149894
  // ../plugin/src/features/magic-context/compartment-lease.ts
149638
149895
  var COMPARTMENT_LEASE_TTL_MS = 5 * 60 * 1000;
149639
149896
  var COMPARTMENT_LEASE_RENEWAL_MS = 60 * 1000;
@@ -152047,7 +152304,7 @@ function readProjectDocsCanonical(projectDirectory) {
152047
152304
  return { renderedBlock, canonicalHash };
152048
152305
  }
152049
152306
  // ../plugin/src/features/magic-context/storage-db.ts
152050
- import { chmodSync, copyFileSync, cpSync, existsSync as existsSync5, mkdirSync as mkdirSync4, mkdtempSync } from "node:fs";
152307
+ import { chmodSync, copyFileSync, cpSync, existsSync as existsSync6, mkdirSync as mkdirSync4, mkdtempSync } from "node:fs";
152051
152308
  init_data_path();
152052
152309
  import { dirname as dirname3, join as join5 } from "node:path";
152053
152310
 
@@ -152186,14 +152443,14 @@ function loadToolDefinitionMeasurements(db) {
152186
152443
  // ../plugin/src/features/magic-context/tool-owner-backfill.ts
152187
152444
  init_data_path();
152188
152445
  init_logger();
152189
- import { existsSync as existsSync4 } from "node:fs";
152446
+ import { existsSync as existsSync5 } from "node:fs";
152190
152447
  import { join as join4 } from "node:path";
152191
152448
  var LEASE_DURATION_MS = 5 * 60 * 1000;
152192
152449
  var LEASE_RENEWAL_MS = 60 * 1000;
152193
152450
  function resolveOpencodeDbPath() {
152194
152451
  return join4(getDataDir(), "opencode", "opencode.db");
152195
152452
  }
152196
- function ensureBackfillStateTable(db) {
152453
+ function ensureBackfillStateTable2(db) {
152197
152454
  db.exec(`
152198
152455
  CREATE TABLE IF NOT EXISTS tool_owner_backfill_state (
152199
152456
  session_id TEXT PRIMARY KEY,
@@ -152209,7 +152466,7 @@ function ensureBackfillStateTable(db) {
152209
152466
  }
152210
152467
  function runToolOwnerBackfill(db) {
152211
152468
  const startedAt = performance.now();
152212
- ensureBackfillStateTable(db);
152469
+ ensureBackfillStateTable2(db);
152213
152470
  const result = {
152214
152471
  sessionsProcessed: 0,
152215
152472
  sessionsSkippedNoOcDb: 0,
@@ -152226,7 +152483,7 @@ function runToolOwnerBackfill(db) {
152226
152483
  return result;
152227
152484
  }
152228
152485
  const opencodeDbPath = resolveOpencodeDbPath();
152229
- if (!existsSync4(opencodeDbPath)) {
152486
+ if (!existsSync5(opencodeDbPath)) {
152230
152487
  log(`[backfill] OpenCode DB not found at ${opencodeDbPath} — marking all unbackfilled sessions as skipped. Lazy adoption (defense-in-depth) handles legacy rows at runtime.`);
152231
152488
  markAllUnbackfilledSessionsSkipped(db);
152232
152489
  result.sessionsSkippedNoOcDb = countSessionsByStatus(db, "skipped");
@@ -152249,7 +152506,7 @@ function runToolOwnerBackfill(db) {
152249
152506
  return result;
152250
152507
  }
152251
152508
  function isToolOwnerBackfillNeeded(db) {
152252
- ensureBackfillStateTable(db);
152509
+ ensureBackfillStateTable2(db);
152253
152510
  const row = db.prepare(`SELECT 1 AS hit
152254
152511
  FROM tags
152255
152512
  WHERE type = 'tool' AND tool_owner_message_id IS NULL
@@ -152465,7 +152722,7 @@ function restrictDatabaseFilePermissions(dbPath) {
152465
152722
  return;
152466
152723
  for (const suffix of ["", "-wal", "-shm"]) {
152467
152724
  const file = `${dbPath}${suffix}`;
152468
- if (!existsSync5(file))
152725
+ if (!existsSync6(file))
152469
152726
  continue;
152470
152727
  try {
152471
152728
  chmodSync(file, 384);
@@ -152491,11 +152748,11 @@ function getDatabasePath(db) {
152491
152748
  return pathByDatabase.get(db) ?? null;
152492
152749
  }
152493
152750
  function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
152494
- if (existsSync5(targetDbPath))
152751
+ if (existsSync6(targetDbPath))
152495
152752
  return;
152496
152753
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
152497
152754
  const legacyDbPath = join5(legacyDir, "context.db");
152498
- if (!existsSync5(legacyDbPath))
152755
+ if (!existsSync6(legacyDbPath))
152499
152756
  return;
152500
152757
  log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
152501
152758
  ensureSecureStorageDir(targetDbDir);
@@ -152512,7 +152769,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
152512
152769
  for (const suffix of ["", "-wal", "-shm"]) {
152513
152770
  const src = `${legacyDbPath}${suffix}`;
152514
152771
  const dst = join5(targetDbDir, `context.db${suffix}`);
152515
- if (existsSync5(src)) {
152772
+ if (existsSync6(src)) {
152516
152773
  try {
152517
152774
  copyFileSync(src, dst);
152518
152775
  } catch (error) {
@@ -152522,7 +152779,7 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
152522
152779
  }
152523
152780
  const legacyModelsDir = join5(legacyDir, "models");
152524
152781
  const targetModelsDir = join5(targetDbDir, "models");
152525
- if (existsSync5(legacyModelsDir) && !existsSync5(targetModelsDir)) {
152782
+ if (existsSync6(legacyModelsDir) && !existsSync6(targetModelsDir)) {
152526
152783
  try {
152527
152784
  cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
152528
152785
  } catch (error) {
@@ -156667,7 +156924,7 @@ init_logger();
156667
156924
 
156668
156925
  // src/subagent-runner.ts
156669
156926
  import * as childProcess from "node:child_process";
156670
- import { existsSync as existsSync7, mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
156927
+ import { existsSync as existsSync8, mkdtempSync as mkdtempSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
156671
156928
  import { createRequire as createRequire2 } from "node:module";
156672
156929
  import { tmpdir as tmpdir2 } from "node:os";
156673
156930
  import { basename as basename2, dirname as dirname4, join as join8, resolve as resolvePath } from "node:path";
@@ -156798,7 +157055,7 @@ function resolveBundledPiCli() {
156798
157055
  const require_ = createRequire2(import.meta.url);
156799
157056
  const pkgJson = require_.resolve("@earendil-works/pi-coding-agent/package.json");
156800
157057
  const cliPath = join8(dirname4(pkgJson), "dist/cli.js");
156801
- if (existsSync7(cliPath))
157058
+ if (existsSync8(cliPath))
156802
157059
  return cliPath;
156803
157060
  return null;
156804
157061
  } catch {
@@ -156809,7 +157066,7 @@ function resolvePiInvocation() {
156809
157066
  const execPath = process.execPath;
156810
157067
  const currentScript = process.argv[1];
156811
157068
  const isBunVirtualScript = currentScript?.startsWith("/$bunfs/root/") ?? false;
156812
- if (currentScript && !isBunVirtualScript && existsSync7(currentScript)) {
157069
+ if (currentScript && !isBunVirtualScript && existsSync8(currentScript)) {
156813
157070
  return { command: execPath, prefixArgs: [currentScript] };
156814
157071
  }
156815
157072
  const execName = basename2(execPath).toLowerCase();
@@ -156827,7 +157084,7 @@ function resolveSubagentEntryPath() {
156827
157084
  try {
156828
157085
  const here = dirname4(fileURLToPath(import.meta.url));
156829
157086
  const candidate = resolvePath(here, "subagent-entry.js");
156830
- if (existsSync7(candidate))
157087
+ if (existsSync8(candidate))
156831
157088
  return candidate;
156832
157089
  return;
156833
157090
  } catch {
@@ -157496,12 +157753,13 @@ ${sidekickText}
157496
157753
  init_logger();
157497
157754
 
157498
157755
  // ../plugin/src/features/magic-context/dreamer/open-opencode-db.ts
157499
- import { existsSync as existsSync8 } from "node:fs";
157756
+ import { existsSync as existsSync10 } from "node:fs";
157500
157757
  init_logger();
157501
157758
 
157502
157759
  // ../plugin/src/features/magic-context/compaction-marker.ts
157503
157760
  init_data_path();
157504
157761
  init_logger();
157762
+ import { existsSync as existsSync9 } from "node:fs";
157505
157763
  import { join as join9 } from "node:path";
157506
157764
  var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
157507
157765
  function randomBase62(length) {
@@ -157568,6 +157826,9 @@ function getWritableOpenCodeDb() {
157568
157826
  closeQuietly(cachedWriteDb.db);
157569
157827
  } catch {}
157570
157828
  }
157829
+ if (!existsSync9(dbPath)) {
157830
+ throw new Error(`OpenCode database not found at ${dbPath} (is OpenCode installed?)`);
157831
+ }
157571
157832
  const db = new Database(dbPath);
157572
157833
  db.exec("PRAGMA busy_timeout=5000");
157573
157834
  db.exec("PRAGMA journal_mode=WAL");
@@ -157686,8 +157947,8 @@ function removeCompactionMarker(state) {
157686
157947
  // ../plugin/src/features/magic-context/dreamer/open-opencode-db.ts
157687
157948
  function openOpenCodeDb() {
157688
157949
  const dbPath = getOpenCodeDbPath2();
157689
- if (!existsSync8(dbPath)) {
157690
- log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
157950
+ if (!existsSync10(dbPath)) {
157951
+ log(`[dreamer] OpenCode DB not found at ${dbPath} — skipping OpenCode history scan`);
157691
157952
  return null;
157692
157953
  }
157693
157954
  try {
@@ -157695,14 +157956,14 @@ function openOpenCodeDb() {
157695
157956
  db.exec("PRAGMA busy_timeout = 5000");
157696
157957
  return db;
157697
157958
  } catch (error) {
157698
- log(`[key-files] failed to open OpenCode DB at ${dbPath}: ${getErrorMessage(error)}`);
157959
+ log(`[dreamer] failed to open OpenCode DB at ${dbPath}: ${getErrorMessage(error)}`);
157699
157960
  return null;
157700
157961
  }
157701
157962
  }
157702
157963
 
157703
157964
  // ../plugin/src/features/magic-context/dreamer/task-executor.ts
157704
157965
  import { createHash as createHash10 } from "node:crypto";
157705
- import { existsSync as existsSync12 } from "node:fs";
157966
+ import { existsSync as existsSync14 } from "node:fs";
157706
157967
 
157707
157968
  // ../plugin/src/agents/dreamer.ts
157708
157969
  var DREAMER_AGENT = "dreamer";
@@ -174572,77 +174833,6 @@ function invalidateMemory(projectPath, memoryId) {
174572
174833
  }
174573
174834
  }
174574
174835
 
174575
- // ../plugin/src/features/magic-context/session-project-storage.ts
174576
- var upsertSessionProjectStatements = new WeakMap;
174577
- var repairSessionChunkProjectStatements = new WeakMap;
174578
- var repairProjectChunkProjectStatements = new WeakMap;
174579
- function getUpsertSessionProjectStatement(db) {
174580
- let stmt = upsertSessionProjectStatements.get(db);
174581
- if (!stmt) {
174582
- stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
174583
- VALUES (?, ?, ?, ?)
174584
- ON CONFLICT(session_id, harness) DO UPDATE SET
174585
- project_path = excluded.project_path,
174586
- updated_at = excluded.updated_at
174587
- WHERE session_projects.project_path <> excluded.project_path`);
174588
- upsertSessionProjectStatements.set(db, stmt);
174589
- }
174590
- return stmt;
174591
- }
174592
- function getRepairSessionChunkProjectStatement(db) {
174593
- let stmt = repairSessionChunkProjectStatements.get(db);
174594
- if (!stmt) {
174595
- stmt = db.prepare(`UPDATE compartment_chunk_embeddings
174596
- SET project_path = ?
174597
- WHERE session_id = ?
174598
- AND harness = ?
174599
- AND project_path <> ?`);
174600
- repairSessionChunkProjectStatements.set(db, stmt);
174601
- }
174602
- return stmt;
174603
- }
174604
- function getRepairProjectChunkProjectStatement(db) {
174605
- let stmt = repairProjectChunkProjectStatements.get(db);
174606
- if (!stmt) {
174607
- stmt = db.prepare(`UPDATE compartment_chunk_embeddings
174608
- SET project_path = (
174609
- SELECT sp.project_path
174610
- FROM session_projects sp
174611
- WHERE sp.session_id = compartment_chunk_embeddings.session_id
174612
- AND sp.harness = compartment_chunk_embeddings.harness
174613
- LIMIT 1
174614
- )
174615
- WHERE EXISTS (
174616
- SELECT 1
174617
- FROM session_projects sp
174618
- WHERE sp.session_id = compartment_chunk_embeddings.session_id
174619
- AND sp.harness = compartment_chunk_embeddings.harness
174620
- AND sp.project_path <> compartment_chunk_embeddings.project_path
174621
- AND (
174622
- sp.project_path = ?
174623
- OR compartment_chunk_embeddings.project_path = ?
174624
- )
174625
- )`);
174626
- repairProjectChunkProjectStatements.set(db, stmt);
174627
- }
174628
- return stmt;
174629
- }
174630
- function recordSessionProjectIdentity(db, sessionId, projectPath) {
174631
- if (!sessionId || !projectPath)
174632
- return;
174633
- const harness = getHarness();
174634
- const now = Date.now();
174635
- db.transaction(() => {
174636
- getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
174637
- getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath);
174638
- })();
174639
- }
174640
- function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
174641
- if (!projectPath)
174642
- return 0;
174643
- return getRepairProjectChunkProjectStatement(db).run(projectPath, projectPath).changes;
174644
- }
174645
-
174646
174836
  // ../plugin/src/features/magic-context/project-embedding-registry.ts
174647
174837
  var OFF_PROVIDER_IDENTITY = "embedding-provider:off";
174648
174838
  var SWEEP_MAX_WALL_CLOCK_MS = 10 * 60 * 1000;
@@ -176295,7 +176485,7 @@ function getMemoryVerifications(db, memoryIds) {
176295
176485
  }
176296
176486
  // ../plugin/src/features/magic-context/memory/verification-paths.ts
176297
176487
  import { execFile } from "node:child_process";
176298
- import { existsSync as existsSync9, realpathSync as realpathSync2, statSync as statSync4 } from "node:fs";
176488
+ import { existsSync as existsSync11, realpathSync as realpathSync2, statSync as statSync4 } from "node:fs";
176299
176489
  import path7 from "node:path";
176300
176490
  import { promisify } from "node:util";
176301
176491
  var execFileAsync = promisify(execFile);
@@ -176400,7 +176590,7 @@ function verificationFileExists(baseRoot, filePath) {
176400
176590
  return false;
176401
176591
  const root = path7.resolve(baseRoot);
176402
176592
  const candidate = path7.resolve(root, filePath);
176403
- return isWithin(root, candidate) && existsSync9(candidate);
176593
+ return isWithin(root, candidate) && existsSync11(candidate);
176404
176594
  }
176405
176595
  async function normalizeVerificationFiles(args) {
176406
176596
  const cwd = path7.resolve(args.cwd);
@@ -176433,7 +176623,7 @@ async function normalizeVerificationFiles(args) {
176433
176623
  warnings.push(`Skipped verification path "${value}" because it is the repo/project root.`);
176434
176624
  continue;
176435
176625
  }
176436
- if (existsSync9(candidate)) {
176626
+ if (existsSync11(candidate)) {
176437
176627
  try {
176438
176628
  if (statSync4(candidate).isDirectory()) {
176439
176629
  warnings.push(`Skipped verification path "${value}" because it is a directory.`);
@@ -176464,7 +176654,7 @@ async function normalizeVerificationFiles(args) {
176464
176654
  }
176465
176655
  normalized.push(tracked);
176466
176656
  } else {
176467
- if (!existsSync9(candidate)) {
176657
+ if (!existsSync11(candidate)) {
176468
176658
  warnings.push(`Skipped verification path "${value}" because it does not exist.`);
176469
176659
  continue;
176470
176660
  }
@@ -179107,7 +179297,7 @@ Output exactly JSON: {"met": false}`;
179107
179297
 
179108
179298
  // ../plugin/src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
179109
179299
  init_logger();
179110
- import { existsSync as existsSync10, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
179300
+ import { existsSync as existsSync12, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
179111
179301
  import { join as join11 } from "node:path";
179112
179302
 
179113
179303
  // ../plugin/src/features/magic-context/dreamer/protected-regions.ts
@@ -179211,7 +179401,7 @@ function snapshotMaintainDocsFiles(docsDir) {
179211
179401
  for (const name2 of MAINTAIN_DOCS_SNAPSHOT_FILES) {
179212
179402
  const path9 = join11(docsDir, name2);
179213
179403
  try {
179214
- if (existsSync10(path9)) {
179404
+ if (existsSync12(path9)) {
179215
179405
  snapshot.set(name2, readFileSync6(path9, "utf8"));
179216
179406
  }
179217
179407
  } catch {}
@@ -179239,7 +179429,7 @@ function enforceMaintainDocsProtectedRegions(args) {
179239
179429
  init_logger();
179240
179430
 
179241
179431
  // ../plugin/src/features/magic-context/dreamer/map-memories-prompt.ts
179242
- import { existsSync as existsSync11, statSync as statSync5 } from "node:fs";
179432
+ import { existsSync as existsSync13, statSync as statSync5 } from "node:fs";
179243
179433
  import path9 from "node:path";
179244
179434
  var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
179245
179435
 
@@ -179277,7 +179467,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
179277
179467
  if (!abs.startsWith(`${root}/`))
179278
179468
  continue;
179279
179469
  try {
179280
- if (existsSync11(abs) && statSync5(abs).isFile())
179470
+ if (existsSync13(abs) && statSync5(abs).isFile())
179281
179471
  found.add(rel);
179282
179472
  } catch {}
179283
179473
  if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
@@ -181418,8 +181608,8 @@ async function runAgenticTask(config2, ctx, helpers) {
181418
181608
  const lastRunAt = getTaskScheduleState(db, projectIdentity, config2.task)?.lastRunAt ?? null;
181419
181609
  const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
181420
181610
  const existingDocs = task === "maintain-docs" ? {
181421
- architecture: existsSync12(`${docsDir}/ARCHITECTURE.md`),
181422
- structure: existsSync12(`${docsDir}/STRUCTURE.md`)
181611
+ architecture: existsSync14(`${docsDir}/ARCHITECTURE.md`),
181612
+ structure: existsSync14(`${docsDir}/STRUCTURE.md`)
181423
181613
  } : undefined;
181424
181614
  const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
181425
181615
  let curateMemories;
@@ -182634,7 +182824,7 @@ function pruneNestedConfigLeaf(block, relativePath) {
182634
182824
  }
182635
182825
 
182636
182826
  // src/config/index.ts
182637
- import { existsSync as existsSync14, readFileSync as readFileSync8 } from "node:fs";
182827
+ import { existsSync as existsSync16, readFileSync as readFileSync8 } from "node:fs";
182638
182828
 
182639
182829
  // ../plugin/src/config/migrate-dreamer-v2.ts
182640
182830
  var OLD_VERIFY_TASK = "verify";
@@ -183016,7 +183206,7 @@ function dropInheritedEmbeddingKeyOnRedirect(projectRaw, mergedRaw, userRaw) {
183016
183206
  }
183017
183207
 
183018
183208
  // ../plugin/src/config/variable.ts
183019
- import { existsSync as existsSync13, readFileSync as readFileSync7 } from "node:fs";
183209
+ import { existsSync as existsSync15, readFileSync as readFileSync7 } from "node:fs";
183020
183210
  import { homedir as homedir4 } from "node:os";
183021
183211
  import { dirname as dirname6, isAbsolute as isAbsolute2, resolve } from "node:path";
183022
183212
 
@@ -183151,7 +183341,7 @@ function substituteConfigVariables(input) {
183151
183341
  if (sensitiveReason) {
183152
183342
  warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
183153
183343
  }
183154
- if (!existsSync13(filePath)) {
183344
+ if (!existsSync15(filePath)) {
183155
183345
  warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
183156
183346
  continue;
183157
183347
  }
@@ -183180,10 +183370,10 @@ function getUserConfigPaths() {
183180
183370
  return [`${basePath}.jsonc`, `${basePath}.json`];
183181
183371
  }
183182
183372
  function resolveFirstExisting(paths) {
183183
- return paths.find((path11) => existsSync14(path11));
183373
+ return paths.find((path11) => existsSync16(path11));
183184
183374
  }
183185
183375
  function resolvePiLegacyFallback(sources) {
183186
- return sources.find((source) => existsSync14(source.path)) ?? null;
183376
+ return sources.find((source) => existsSync16(source.path)) ?? null;
183187
183377
  }
183188
183378
  function loadConfigFile(path11, scope) {
183189
183379
  try {
@@ -183320,7 +183510,7 @@ function loadPiConfig(opts = {}) {
183320
183510
  if (loaded)
183321
183511
  loadedFiles.push(loaded);
183322
183512
  }
183323
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync14(source.path));
183513
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync16(source.path));
183324
183514
  const userPath = resolveFirstExisting(getUserConfigPaths());
183325
183515
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
183326
183516
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -183329,7 +183519,7 @@ function loadPiConfig(opts = {}) {
183329
183519
  if (loaded)
183330
183520
  loadedFiles.push(loaded);
183331
183521
  }
183332
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync14(source.path));
183522
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync16(source.path));
183333
183523
  if (userLegacyFallback) {
183334
183524
  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.`);
183335
183525
  } else if (legacyUserUnmigrated) {
@@ -183430,7 +183620,7 @@ function loadPiConfigDetailed(opts = {}) {
183430
183620
  if (loaded)
183431
183621
  loadedFiles.push(loaded);
183432
183622
  }
183433
- const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync14(source.path));
183623
+ const legacyProjectUnmigrated = !projectPath && !projectLegacyFallback && legacySources.project.some((source) => existsSync16(source.path));
183434
183624
  const userPath = resolveFirstExisting(getUserConfigPaths());
183435
183625
  const userLegacyFallback = userPath ? null : resolvePiLegacyFallback(harnessLegacy.user);
183436
183626
  const userReadPath = userPath ?? userLegacyFallback?.path;
@@ -183439,7 +183629,7 @@ function loadPiConfigDetailed(opts = {}) {
183439
183629
  if (loaded)
183440
183630
  loadedFiles.push(loaded);
183441
183631
  }
183442
- const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync14(source.path));
183632
+ const legacyUserUnmigrated = !userPath && !userLegacyFallback && legacySources.user.some((source) => existsSync16(source.path));
183443
183633
  if (userLegacyFallback) {
183444
183634
  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.`);
183445
183635
  } else if (legacyUserUnmigrated) {
@@ -197795,6 +197985,9 @@ function existingMarkerAlreadyCoversTarget(sessionId, existing, targetOrdinal, t
197795
197985
  return true;
197796
197986
  }
197797
197987
  function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
197988
+ if (getHarness() !== "opencode") {
197989
+ return true;
197990
+ }
197798
197991
  const targetEndMessageId = getCompartmentEndMessageIdForOrdinal(db, sessionId, lastCompartmentEnd);
197799
197992
  if (!targetEndMessageId) {
197800
197993
  sessionLog(sessionId, `compaction-marker: no compartment endMessageId for ordinal ${lastCompartmentEnd}; preserving existing marker`);
@@ -200126,7 +200319,7 @@ function formatThresholdPercent(value) {
200126
200319
  // package.json
200127
200320
  var package_default = {
200128
200321
  name: "@cortexkit/pi-magic-context",
200129
- version: "0.30.6",
200322
+ version: "0.30.7",
200130
200323
  type: "module",
200131
200324
  description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
200132
200325
  main: "dist/index.js",
@@ -206497,6 +206690,20 @@ async function src_default2(pi) {
206497
206690
  runDeferredV22Backfill(db).catch((err5) => {
206498
206691
  warn(`[v22-backfill] background runner failed: ${err5}`);
206499
206692
  });
206693
+ setTimeout(() => {
206694
+ (async () => {
206695
+ try {
206696
+ const api2 = await loadDefaultPiSessionApi();
206697
+ const sessions = await api2.listSessions();
206698
+ await runSessionProjectBackfill(database, sessions.map((session) => ({
206699
+ sessionId: typeof session?.id === "string" ? session.id : "",
206700
+ directory: typeof session?.cwd === "string" ? session.cwd : ""
206701
+ })));
206702
+ } catch (err5) {
206703
+ warn(`[session-projects] background runner failed: ${err5}`);
206704
+ }
206705
+ })();
206706
+ }, 0);
206500
206707
  const projectDir = process.cwd();
206501
206708
  const projectIdentity = resolveProjectIdentity(projectDir);
206502
206709
  const seenDreamerProjectIdentities = new Set([projectIdentity]);
@@ -206621,7 +206828,7 @@ async function src_default2(pi) {
206621
206828
  const bootContextOptions = buildContextOptions(config2, historianConfig, autoSearchConfig);
206622
206829
  contextOptionsByDir.set(projectDir, bootContextOptions);
206623
206830
  registerPiContextHandler(pi, bootContextOptions);
206624
- info(historianConfig ? `registered historian trigger (model=${historianConfig.model}, executeThreshold=${historianConfig.executeThresholdPercentage ?? 65}%)` : "registered historian trigger: DISABLED (set historian.model in magic-context.jsonc)");
206831
+ info(historianConfig ? `registered historian trigger (model=${historianConfig.model}, executeThreshold=${formatExecuteThresholdForLog(historianConfig.executeThresholdPercentage)})` : "registered historian trigger: DISABLED (set historian.model in magic-context.jsonc)");
206625
206832
  info(autoSearchConfig.enabled ? `registered auto-search hint (threshold=${autoSearchConfig.scoreThreshold}, minChars=${autoSearchConfig.minPromptChars})` : "registered auto-search hint: DISABLED (memory.auto_search.enabled=false)");
206626
206833
  const sidekickConfig = resolveSidekickFromConfig(config2);
206627
206834
  registerCtxAugCommand(pi, sidekickConfig);
@@ -207078,6 +207285,15 @@ ${block}` : event.systemPrompt;
207078
207285
  } catch {}
207079
207286
  });
207080
207287
  }
207288
+ function formatExecuteThresholdForLog(value) {
207289
+ if (value === undefined)
207290
+ return "65%";
207291
+ if (typeof value === "number")
207292
+ return `${value}%`;
207293
+ const overrides = Object.entries(value).filter(([key]) => key !== "default").map(([key, pct]) => `${key}=${pct}%`);
207294
+ const base = `${value.default}%`;
207295
+ return overrides.length > 0 ? `${base} (${overrides.join(", ")})` : base;
207296
+ }
207081
207297
  export {
207082
207298
  resolveSidekickFromConfig,
207083
207299
  resolveHistorianFromConfig,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.30.6",
3
+ "version": "0.30.7",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",