@cortexkit/opencode-magic-context 0.16.1 → 0.16.3

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 (35) hide show
  1. package/README.md +20 -13
  2. package/dist/config/schema/magic-context.d.ts +29 -0
  3. package/dist/config/schema/magic-context.d.ts.map +1 -1
  4. package/dist/features/magic-context/dreamer/queue.d.ts +18 -4
  5. package/dist/features/magic-context/dreamer/queue.d.ts.map +1 -1
  6. package/dist/features/magic-context/dreamer/runner.d.ts +14 -0
  7. package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
  8. package/dist/features/magic-context/dreamer/scheduler.d.ts +13 -1
  9. package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
  10. package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
  11. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  12. package/dist/hooks/auto-update-checker/cache.d.ts +12 -1
  13. package/dist/hooks/auto-update-checker/cache.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/hook-handlers.d.ts +6 -0
  16. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/hook.d.ts +7 -0
  18. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  19. package/dist/hooks/magic-context/live-session-state.d.ts +13 -0
  20. package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
  21. package/dist/hooks/magic-context/system-prompt-hash.d.ts +15 -0
  22. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  23. package/dist/hooks/magic-context/transform.d.ts +7 -0
  24. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  25. package/dist/index.js +483 -116
  26. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  27. package/dist/shared/native-binding.d.ts +87 -0
  28. package/dist/shared/native-binding.d.ts.map +1 -0
  29. package/dist/shared/sqlite.d.ts +0 -12
  30. package/dist/shared/sqlite.d.ts.map +1 -1
  31. package/package.json +2 -1
  32. package/src/shared/conflict-detector.ts +1 -1
  33. package/src/shared/native-binding.ts +311 -0
  34. package/src/shared/sqlite.ts +57 -14
  35. package/src/tui/index.tsx +2 -2
package/dist/index.js CHANGED
@@ -14190,6 +14190,13 @@ var init_magic_context = __esm(() => {
14190
14190
  min_clusters: exports_external.number().min(1).default(3)
14191
14191
  }).default({ enabled: true, min_clusters: 3 }),
14192
14192
  compaction_markers: exports_external.boolean().default(true),
14193
+ system_prompt_injection: exports_external.object({
14194
+ enabled: exports_external.boolean().default(true),
14195
+ skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
14196
+ }).default({
14197
+ enabled: true,
14198
+ skip_signatures: ["<!-- magic-context: skip -->"]
14199
+ }),
14193
14200
  compressor: exports_external.object({
14194
14201
  enabled: exports_external.boolean().default(true),
14195
14202
  min_compartment_ratio: exports_external.number().min(100).max(1e4).default(DEFAULT_COMPRESSOR_MIN_COMPARTMENT_RATIO),
@@ -155701,7 +155708,7 @@ function formatConflictShort(result) {
155701
155708
  "",
155702
155709
  ...result.reasons.map((r) => `• ${r}`),
155703
155710
  "",
155704
- "Fix: run `bunx --bun @cortexkit/opencode-magic-context@latest doctor`"
155711
+ "Fix: run `npx @cortexkit/opencode-magic-context@latest doctor`"
155705
155712
  ];
155706
155713
  return lines.join(`
155707
155714
  `);
@@ -156101,14 +156108,334 @@ function safeString(value) {
156101
156108
  }
156102
156109
  }
156103
156110
 
156111
+ // ../../node_modules/.bun/nanotar@0.3.0/node_modules/nanotar/dist/index.mjs
156112
+ function parseTar(data, opts) {
156113
+ const buffer2 = data.buffer || data;
156114
+ const files = [];
156115
+ let offset = 0;
156116
+ let nextExtendedHeader;
156117
+ let globalExtendedHeader;
156118
+ while (offset < buffer2.byteLength - 512) {
156119
+ let name2 = _readString(buffer2, offset, 100);
156120
+ if (name2.length === 0) {
156121
+ break;
156122
+ }
156123
+ if (nextExtendedHeader) {
156124
+ const longName = nextExtendedHeader.path || nextExtendedHeader.linkpath;
156125
+ if (longName) {
156126
+ name2 = longName;
156127
+ }
156128
+ }
156129
+ const mode = _readString(buffer2, offset + 100, 8).trim();
156130
+ const uid = Number.parseInt(_readString(buffer2, offset + 108, 8));
156131
+ const gid = Number.parseInt(_readString(buffer2, offset + 116, 8));
156132
+ const size = _readNumber(buffer2, offset + 124, 12);
156133
+ const seek = 512 + 512 * Math.trunc(size / 512) + (size % 512 ? 512 : 0);
156134
+ const mtime = _readNumber(buffer2, offset + 136, 12);
156135
+ const _type = _readString(buffer2, offset + 156, 1) || "0";
156136
+ const type = tarItemTypeMap[_type] || _type;
156137
+ switch (type) {
156138
+ case "extendedHeader":
156139
+ case "globalExtendedHeader": {
156140
+ const headers = _parseExtendedHeaders(new Uint8Array(buffer2, offset + 512, size));
156141
+ if (type === "extendedHeader") {
156142
+ nextExtendedHeader = headers;
156143
+ } else {
156144
+ nextExtendedHeader = undefined;
156145
+ globalExtendedHeader = {
156146
+ ...globalExtendedHeader,
156147
+ ...headers
156148
+ };
156149
+ }
156150
+ offset += seek;
156151
+ continue;
156152
+ }
156153
+ case "gnuLongFileName":
156154
+ case "gnuOldLongFileName":
156155
+ case "gnuLongLinkName": {
156156
+ nextExtendedHeader = { path: _readString(buffer2, offset + 512, size) };
156157
+ offset += seek;
156158
+ continue;
156159
+ }
156160
+ }
156161
+ const user = _readString(buffer2, offset + 265, 32);
156162
+ const group = _readString(buffer2, offset + 297, 32);
156163
+ name2 = _sanitizePath(name2);
156164
+ const meta3 = {
156165
+ name: name2,
156166
+ type,
156167
+ size,
156168
+ attrs: {
156169
+ ...globalExtendedHeader,
156170
+ ...nextExtendedHeader,
156171
+ mode,
156172
+ uid,
156173
+ gid,
156174
+ mtime,
156175
+ user,
156176
+ group
156177
+ }
156178
+ };
156179
+ nextExtendedHeader = undefined;
156180
+ if (opts?.filter && !opts.filter(meta3)) {
156181
+ offset += seek;
156182
+ continue;
156183
+ }
156184
+ if (opts?.metaOnly) {
156185
+ files.push(meta3);
156186
+ offset += seek;
156187
+ continue;
156188
+ }
156189
+ const data2 = size === 0 ? undefined : new Uint8Array(buffer2, offset + 512, size);
156190
+ files.push({
156191
+ ...meta3,
156192
+ data: data2,
156193
+ get text() {
156194
+ return new TextDecoder().decode(this.data);
156195
+ }
156196
+ });
156197
+ offset += seek;
156198
+ }
156199
+ return files;
156200
+ }
156201
+ async function parseTarGzip(data, opts = {}) {
156202
+ const stream = new ReadableStream({
156203
+ start(controller) {
156204
+ controller.enqueue(new Uint8Array(data));
156205
+ controller.close();
156206
+ }
156207
+ }).pipeThrough(new DecompressionStream(opts.compression ?? "gzip"));
156208
+ const decompressedData = await new Response(stream).arrayBuffer();
156209
+ return parseTar(decompressedData, opts);
156210
+ }
156211
+ function _sanitizePath(path3) {
156212
+ let normalized = path3.replace(/\\/g, "/");
156213
+ normalized = normalized.replace(/^[a-zA-Z]:\//, "");
156214
+ normalized = normalized.replace(/^\/+/, "");
156215
+ const hasLeadingDotSlash = normalized.startsWith("./");
156216
+ const parts = normalized.split("/");
156217
+ const resolved = [];
156218
+ for (const part of parts) {
156219
+ if (part === "..") {
156220
+ resolved.pop();
156221
+ } else if (part !== "." && part !== "") {
156222
+ resolved.push(part);
156223
+ }
156224
+ }
156225
+ let result = resolved.join("/");
156226
+ if (hasLeadingDotSlash && !result.startsWith("./")) {
156227
+ result = "./" + result;
156228
+ }
156229
+ if (path3.endsWith("/") && !result.endsWith("/")) {
156230
+ result += "/";
156231
+ }
156232
+ return result;
156233
+ }
156234
+ function _readString(buffer2, offset, size) {
156235
+ const view = new Uint8Array(buffer2, offset, size);
156236
+ const i = view.indexOf(0);
156237
+ const td = new TextDecoder;
156238
+ return td.decode(i === -1 ? view : view.slice(0, i));
156239
+ }
156240
+ function _readNumber(buffer2, offset, size) {
156241
+ const view = new Uint8Array(buffer2, offset, size);
156242
+ let str = "";
156243
+ for (let i = 0;i < size; i++) {
156244
+ str += String.fromCodePoint(view[i]);
156245
+ }
156246
+ return Number.parseInt(str, 8);
156247
+ }
156248
+ function _parseExtendedHeaders(data) {
156249
+ const dataStr = new TextDecoder().decode(data);
156250
+ const headers = {};
156251
+ for (const line of dataStr.split(`
156252
+ `)) {
156253
+ const s = line.split(" ")[1]?.split("=");
156254
+ if (s) {
156255
+ headers[s[0]] = s[1];
156256
+ }
156257
+ }
156258
+ return headers;
156259
+ }
156260
+ var tarItemTypeMap;
156261
+ var init_dist2 = __esm(() => {
156262
+ tarItemTypeMap = {
156263
+ "0": "file",
156264
+ "1": "hardLink",
156265
+ "2": "symbolicLink",
156266
+ "3": "characterDevice",
156267
+ "4": "blockDevice",
156268
+ "5": "directory",
156269
+ "6": "fifo",
156270
+ "7": "contiguousFile",
156271
+ g: "globalExtendedHeader",
156272
+ x: "extendedHeader",
156273
+ D: "gnuDirectory",
156274
+ I: "gnuInodeMetadata",
156275
+ K: "gnuLongLinkName",
156276
+ L: "gnuLongFileName",
156277
+ N: "gnuOldLongFileName",
156278
+ M: "gnuMultiVolume",
156279
+ S: "gnuSparseFile",
156280
+ E: "gnuExtendedSparse",
156281
+ A: "solarisAcl",
156282
+ V: "solarisVolumeLabel",
156283
+ X: "solarisOldExtendedHeader"
156284
+ };
156285
+ });
156286
+
156287
+ // src/shared/native-binding.ts
156288
+ var exports_native_binding = {};
156289
+ __export(exports_native_binding, {
156290
+ resolveBetterSqliteNativeBinding: () => resolveBetterSqliteNativeBinding
156291
+ });
156292
+ import { existsSync as existsSync7, mkdirSync, writeFileSync as writeFileSync3 } from "node:fs";
156293
+ import { createRequire } from "node:module";
156294
+ import * as path3 from "node:path";
156295
+ function logInfo(message) {
156296
+ log(`${PREFIX} ${message}`);
156297
+ }
156298
+ function logWarn(message) {
156299
+ log(`${PREFIX} WARN ${message}`);
156300
+ }
156301
+ function probeAbi(binaryPath) {
156302
+ const expected = process.versions.modules;
156303
+ try {
156304
+ const sandbox = { exports: {} };
156305
+ process.dlopen(sandbox, binaryPath);
156306
+ return { ok: true };
156307
+ } catch (err) {
156308
+ const message = err instanceof Error ? err.message : String(err);
156309
+ const pair = message.match(/NODE_MODULE_VERSION (\d+).*NODE_MODULE_VERSION (\d+)/s);
156310
+ if (pair?.[1] && pair[2]) {
156311
+ return { ok: false, expected: pair[2], actual: pair[1] };
156312
+ }
156313
+ const single = message.match(/NODE_MODULE_VERSION[ =:]+(\d+)/);
156314
+ if (single?.[1]) {
156315
+ return { ok: false, expected, actual: single[1] };
156316
+ }
156317
+ logWarn(`could not parse ABI from dlopen error: ${message}`);
156318
+ return { ok: false, expected, actual: null };
156319
+ }
156320
+ }
156321
+ function resolveBetterSqlite3OnDisk(requireFn) {
156322
+ try {
156323
+ const pkgJsonPath = requireFn.resolve("better-sqlite3/package.json");
156324
+ const pkgDir = path3.dirname(pkgJsonPath);
156325
+ const pkgJson = requireFn(pkgJsonPath);
156326
+ const binaryPath = path3.join(pkgDir, "build", "Release", "better_sqlite3.node");
156327
+ return { binaryPath, pkgVersion: pkgJson.version };
156328
+ } catch (err) {
156329
+ logWarn(`could not resolve better-sqlite3 in node_modules: ${err instanceof Error ? err.message : String(err)}`);
156330
+ return null;
156331
+ }
156332
+ }
156333
+ function getCachedBinaryPath(pkgVersion, abi) {
156334
+ return path3.join(getCacheDir(), "cortexkit", "native-bindings", "better-sqlite3", `v${pkgVersion}`, `electron-v${abi}-${process.platform}-${process.arch}`, "better_sqlite3.node");
156335
+ }
156336
+ async function downloadElectronPrebuild(pkgVersion, abi) {
156337
+ const filename = `better-sqlite3-v${pkgVersion}-electron-v${abi}-${process.platform}-${process.arch}.tar.gz`;
156338
+ const url2 = `https://github.com/WiseLibs/better-sqlite3/releases/download/v${pkgVersion}/${filename}`;
156339
+ logInfo(`downloading ${url2}`);
156340
+ const response = await fetch(url2, {
156341
+ redirect: "follow",
156342
+ headers: { "User-Agent": "magic-context-plugin/native-binding" }
156343
+ });
156344
+ if (!response.ok) {
156345
+ throw new Error(`failed to download Electron prebuild (HTTP ${response.status} ${response.statusText}) from ${url2}`);
156346
+ }
156347
+ const tarballBytes = new Uint8Array(await response.arrayBuffer());
156348
+ logInfo(`downloaded ${(tarballBytes.length / 1024).toFixed(1)} KB; extracting`);
156349
+ const files = await parseTarGzip(tarballBytes);
156350
+ const nodeFile = files.find((f) => f.name.endsWith("better_sqlite3.node"));
156351
+ if (!nodeFile?.data) {
156352
+ const names = files.map((f) => f.name).join(", ");
156353
+ throw new Error(`Electron prebuild tarball did not contain better_sqlite3.node; got: [${names}]`);
156354
+ }
156355
+ return nodeFile.data instanceof Uint8Array ? nodeFile.data : new Uint8Array(nodeFile.data);
156356
+ }
156357
+ async function resolveBetterSqliteNativeBinding() {
156358
+ if (!process.versions.electron) {
156359
+ return null;
156360
+ }
156361
+ if (inFlight) {
156362
+ return inFlight;
156363
+ }
156364
+ const promise2 = (async () => {
156365
+ const expected = process.versions.modules;
156366
+ logInfo(`Electron detected (v${process.versions.electron}, NODE_MODULE_VERSION ${expected}); verifying better-sqlite3 binding`);
156367
+ const requireFn = createRequire(import.meta.url);
156368
+ const resolved = resolveBetterSqlite3OnDisk(requireFn);
156369
+ if (!resolved) {
156370
+ return null;
156371
+ }
156372
+ const { binaryPath: diskPath, pkgVersion } = resolved;
156373
+ if (existsSync7(diskPath)) {
156374
+ const diskProbe = probeAbi(diskPath);
156375
+ if (diskProbe.ok) {
156376
+ logInfo(`on-disk binary already matches Electron ABI v${expected}; using default bindings() lookup`);
156377
+ return null;
156378
+ }
156379
+ logInfo(`on-disk binary ABI ${diskProbe.actual ?? "unknown"} != required ${expected}; will use Electron prebuild`);
156380
+ } else {
156381
+ logWarn(`expected better-sqlite3 binary not found at ${diskPath}; will fetch Electron prebuild anyway`);
156382
+ }
156383
+ const cachedPath = getCachedBinaryPath(pkgVersion, expected);
156384
+ if (existsSync7(cachedPath)) {
156385
+ const cachedProbe = probeAbi(cachedPath);
156386
+ if (cachedProbe.ok) {
156387
+ logInfo(`using cached Electron prebuild at ${cachedPath}`);
156388
+ return cachedPath;
156389
+ }
156390
+ logWarn(`cached binary at ${cachedPath} has wrong ABI (${cachedProbe.actual ?? "unknown"} != ${expected}); refetching`);
156391
+ }
156392
+ mkdirSync(path3.dirname(cachedPath), { recursive: true });
156393
+ const nodeFileBytes = await downloadElectronPrebuild(pkgVersion, expected);
156394
+ writeFileSync3(cachedPath, nodeFileBytes);
156395
+ logInfo(`cached Electron prebuild at ${cachedPath} (${(nodeFileBytes.length / 1024).toFixed(1)} KB)`);
156396
+ const finalProbe = probeAbi(cachedPath);
156397
+ if (!finalProbe.ok) {
156398
+ throw new Error(`downloaded Electron prebuild has wrong ABI (${finalProbe.actual ?? "unknown"} != ${expected}); refusing to use`);
156399
+ }
156400
+ return cachedPath;
156401
+ })();
156402
+ inFlight = promise2;
156403
+ try {
156404
+ return await promise2;
156405
+ } finally {
156406
+ if (inFlight === promise2) {
156407
+ inFlight = null;
156408
+ }
156409
+ }
156410
+ }
156411
+ var PREFIX = "[native-binding]", inFlight = null;
156412
+ var init_native_binding = __esm(() => {
156413
+ init_dist2();
156414
+ init_data_path();
156415
+ init_logger();
156416
+ });
156417
+
156104
156418
  // src/shared/sqlite.ts
156105
- var isBun, bunSpec, betterSpec, sqliteModule, DatabaseImpl, Database;
156419
+ var isBun, bunSpec, betterSpec, electronNativeBinding, sqliteModule, RawDatabaseImpl, DatabaseImpl, Database;
156106
156420
  var init_sqlite = __esm(async () => {
156107
156421
  isBun = typeof process !== "undefined" && typeof process.versions?.bun === "string";
156108
156422
  bunSpec = "bun:" + "sqlite";
156109
156423
  betterSpec = "better-" + "sqlite3";
156424
+ electronNativeBinding = isBun ? null : await (async () => {
156425
+ const mod = await Promise.resolve().then(() => (init_native_binding(), exports_native_binding));
156426
+ return mod.resolveBetterSqliteNativeBinding();
156427
+ })();
156110
156428
  sqliteModule = isBun ? await import(bunSpec) : await import(betterSpec);
156111
- DatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
156429
+ RawDatabaseImpl = isBun ? sqliteModule.Database : sqliteModule.default;
156430
+ DatabaseImpl = electronNativeBinding == null ? RawDatabaseImpl : class DatabaseWithElectronBinding extends RawDatabaseImpl {
156431
+ constructor(filename, options) {
156432
+ const fallback = electronNativeBinding;
156433
+ super(filename, {
156434
+ ...options,
156435
+ nativeBinding: options?.nativeBinding ?? fallback
156436
+ });
156437
+ }
156438
+ };
156112
156439
  Database = DatabaseImpl;
156113
156440
  });
156114
156441
 
@@ -156840,9 +157167,9 @@ __export(exports_read_session_db, {
156840
157167
  findLastAssistantModelFromOpenCodeDb: () => findLastAssistantModelFromOpenCodeDb,
156841
157168
  closeReadOnlySessionDb: () => closeReadOnlySessionDb
156842
157169
  });
156843
- import { join as join10 } from "node:path";
157170
+ import { join as join11 } from "node:path";
156844
157171
  function getOpenCodeDbPath() {
156845
- return join10(getDataDir(), "opencode", "opencode.db");
157172
+ return join11(getDataDir(), "opencode", "opencode.db");
156846
157173
  }
156847
157174
  function closeCachedReadOnlyDb() {
156848
157175
  if (!cachedReadOnlyDb) {
@@ -156944,9 +157271,9 @@ function cosineSimilarity(a, b) {
156944
157271
  }
156945
157272
 
156946
157273
  // src/features/magic-context/memory/embedding-local.ts
156947
- import { mkdirSync } from "node:fs";
157274
+ import { mkdirSync as mkdirSync2 } from "node:fs";
156948
157275
  import { open, stat, unlink, writeFile } from "node:fs/promises";
156949
- import { join as join12 } from "node:path";
157276
+ import { join as join13 } from "node:path";
156950
157277
  async function acquireModelLoadLock(lockPath) {
156951
157278
  const waitStart = Date.now();
156952
157279
  while (true) {
@@ -157080,15 +157407,15 @@ class LocalEmbeddingProvider {
157080
157407
  if (LogLevel && "ERROR" in LogLevel) {
157081
157408
  env.logLevel = LogLevel.ERROR;
157082
157409
  }
157083
- const modelCacheDir = join12(getMagicContextStorageDir(), "models");
157410
+ const modelCacheDir = join13(getMagicContextStorageDir(), "models");
157084
157411
  try {
157085
- mkdirSync(modelCacheDir, { recursive: true });
157412
+ mkdirSync2(modelCacheDir, { recursive: true });
157086
157413
  env.cacheDir = modelCacheDir;
157087
157414
  } catch {
157088
157415
  log("[magic-context] could not create model cache dir, using library default");
157089
157416
  }
157090
157417
  const createPipeline = transformersModule.pipeline;
157091
- const lockPath = join12(modelCacheDir, ".load.lock");
157418
+ const lockPath = join13(modelCacheDir, ".load.lock");
157092
157419
  const releaseLock = await acquireModelLoadLock(lockPath);
157093
157420
  const stopHeartbeat = startLockHeartbeat(lockPath);
157094
157421
  try {
@@ -157659,7 +157986,7 @@ var init_storage_memory_fts = __esm(() => {
157659
157986
  // src/features/magic-context/memory/project-identity.ts
157660
157987
  import { execSync } from "node:child_process";
157661
157988
  import { createHash as createHash2 } from "node:crypto";
157662
- import path3 from "node:path";
157989
+ import path4 from "node:path";
157663
157990
  function getRootCommitHash(directory) {
157664
157991
  try {
157665
157992
  const hash2 = execSync("git rev-list --max-parents=0 HEAD", {
@@ -157676,12 +158003,12 @@ function getRootCommitHash(directory) {
157676
158003
  }
157677
158004
  }
157678
158005
  function directoryFallback(directory) {
157679
- const canonical = path3.resolve(directory);
158006
+ const canonical = path4.resolve(directory);
157680
158007
  const hash2 = createHash2("md5").update(canonical).digest("hex").slice(0, 12);
157681
158008
  return `dir:${hash2}`;
157682
158009
  }
157683
158010
  function resolveProjectIdentity(directory) {
157684
- const resolved = path3.resolve(directory);
158011
+ const resolved = path4.resolve(directory);
157685
158012
  const cached2 = resolvedCache.get(resolved);
157686
158013
  if (cached2 !== undefined) {
157687
158014
  return cached2;
@@ -158460,25 +158787,25 @@ var init_migrations = __esm(async () => {
158460
158787
  });
158461
158788
 
158462
158789
  // src/features/magic-context/storage-db.ts
158463
- import { copyFileSync, cpSync, existsSync as existsSync8, mkdirSync as mkdirSync2 } from "node:fs";
158464
- import { join as join13 } from "node:path";
158790
+ import { copyFileSync, cpSync, existsSync as existsSync9, mkdirSync as mkdirSync3 } from "node:fs";
158791
+ import { join as join14 } from "node:path";
158465
158792
  function resolveDatabasePath() {
158466
158793
  const dbDir = getMagicContextStorageDir();
158467
- return { dbDir, dbPath: join13(dbDir, "context.db") };
158794
+ return { dbDir, dbPath: join14(dbDir, "context.db") };
158468
158795
  }
158469
158796
  function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
158470
- if (existsSync8(targetDbPath))
158797
+ if (existsSync9(targetDbPath))
158471
158798
  return;
158472
158799
  const legacyDir = getLegacyOpenCodeMagicContextStorageDir();
158473
- const legacyDbPath = join13(legacyDir, "context.db");
158474
- if (!existsSync8(legacyDbPath))
158800
+ const legacyDbPath = join14(legacyDir, "context.db");
158801
+ if (!existsSync9(legacyDbPath))
158475
158802
  return;
158476
158803
  log(`[magic-context] migrating legacy plugin storage: ${legacyDir} -> ${targetDbDir} (legacy left in place as backup)`);
158477
- mkdirSync2(targetDbDir, { recursive: true });
158804
+ mkdirSync3(targetDbDir, { recursive: true });
158478
158805
  for (const suffix of ["", "-wal", "-shm"]) {
158479
158806
  const src = `${legacyDbPath}${suffix}`;
158480
- const dst = join13(targetDbDir, `context.db${suffix}`);
158481
- if (existsSync8(src)) {
158807
+ const dst = join14(targetDbDir, `context.db${suffix}`);
158808
+ if (existsSync9(src)) {
158482
158809
  try {
158483
158810
  copyFileSync(src, dst);
158484
158811
  } catch (error48) {
@@ -158486,9 +158813,9 @@ function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
158486
158813
  }
158487
158814
  }
158488
158815
  }
158489
- const legacyModelsDir = join13(legacyDir, "models");
158490
- const targetModelsDir = join13(targetDbDir, "models");
158491
- if (existsSync8(legacyModelsDir) && !existsSync8(targetModelsDir)) {
158816
+ const legacyModelsDir = join14(legacyDir, "models");
158817
+ const targetModelsDir = join14(targetDbDir, "models");
158818
+ if (existsSync9(legacyModelsDir) && !existsSync9(targetModelsDir)) {
158492
158819
  try {
158493
158820
  cpSync(legacyModelsDir, targetModelsDir, { recursive: true });
158494
158821
  } catch (error48) {
@@ -158868,7 +159195,7 @@ function openDatabase() {
158868
159195
  }
158869
159196
  try {
158870
159197
  migrateLegacyStorageIfNeeded(dbPath, dbDir);
158871
- mkdirSync2(dbDir, { recursive: true });
159198
+ mkdirSync3(dbDir, { recursive: true });
158872
159199
  const db = new Database(dbPath);
158873
159200
  initializeDatabase(db);
158874
159201
  runMigrations(db);
@@ -159638,9 +159965,9 @@ var init_storage = __esm(async () => {
159638
159965
 
159639
159966
  // src/shared/models-dev-cache.ts
159640
159967
  import { createHash as createHash3 } from "node:crypto";
159641
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
159968
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "node:fs";
159642
159969
  import { homedir as homedir8, platform as platform3 } from "node:os";
159643
- import { join as join14 } from "node:path";
159970
+ import { join as join15 } from "node:path";
159644
159971
  function hashFast(input) {
159645
159972
  return createHash3("sha1").update(input).digest("hex");
159646
159973
  }
@@ -159651,16 +159978,16 @@ function getModelsJsonPath() {
159651
159978
  const cacheBase = getCacheDir();
159652
159979
  const source = process.env.OPENCODE_MODELS_URL?.trim();
159653
159980
  const filename = source && source !== "https://models.dev" ? `models-${hashFast(source)}.json` : "models.json";
159654
- return join14(cacheBase, "opencode", filename);
159981
+ return join15(cacheBase, "opencode", filename);
159655
159982
  }
159656
159983
  function getOpencodeConfigPath() {
159657
159984
  const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
159658
- const configDir = envDir ? envDir : platform3() === "win32" ? join14(homedir8(), ".config", "opencode") : join14(process.env.XDG_CONFIG_HOME || join14(homedir8(), ".config"), "opencode");
159659
- const jsonc = join14(configDir, "opencode.jsonc");
159660
- if (existsSync9(jsonc))
159985
+ const configDir = envDir ? envDir : platform3() === "win32" ? join15(homedir8(), ".config", "opencode") : join15(process.env.XDG_CONFIG_HOME || join15(homedir8(), ".config"), "opencode");
159986
+ const jsonc = join15(configDir, "opencode.jsonc");
159987
+ if (existsSync10(jsonc))
159661
159988
  return jsonc;
159662
- const json2 = join14(configDir, "opencode.json");
159663
- if (existsSync9(json2))
159989
+ const json2 = join15(configDir, "opencode.json");
159990
+ if (existsSync10(json2))
159664
159991
  return json2;
159665
159992
  return null;
159666
159993
  }
@@ -159703,7 +160030,7 @@ function loadModelsDevMetadataFromFile() {
159703
160030
  const modelsJsonPath = getModelsJsonPath();
159704
160031
  let fileFound = false;
159705
160032
  try {
159706
- if (existsSync9(modelsJsonPath)) {
160033
+ if (existsSync10(modelsJsonPath)) {
159707
160034
  fileFound = true;
159708
160035
  const raw = readFileSync7(modelsJsonPath, "utf-8");
159709
160036
  const data = JSON.parse(raw);
@@ -159720,7 +160047,7 @@ function loadModelsDevMetadataFromFile() {
159720
160047
  }
159721
160048
  try {
159722
160049
  const configPath = getOpencodeConfigPath();
159723
- if (configPath && existsSync9(configPath)) {
160050
+ if (configPath && existsSync10(configPath)) {
159724
160051
  let raw = readFileSync7(configPath, "utf-8");
159725
160052
  raw = raw.replace(/"(?:[^"\\]|\\.)*"|\/\/.*$/gm, (match) => match.startsWith('"') ? match : "");
159726
160053
  const config2 = JSON.parse(raw);
@@ -160052,9 +160379,9 @@ var init_compartment_runner_validation = __esm(async () => {
160052
160379
  });
160053
160380
 
160054
160381
  // src/hooks/magic-context/compartment-runner-historian.ts
160055
- import { mkdirSync as mkdirSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
160382
+ import { mkdirSync as mkdirSync4, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
160056
160383
  import { tmpdir as tmpdir2 } from "node:os";
160057
- import { join as join15 } from "node:path";
160384
+ import { join as join16 } from "node:path";
160058
160385
  async function runValidatedHistorianPass(args) {
160059
160386
  const firstRun = await runHistorianPrompt({
160060
160387
  ...args,
@@ -160172,7 +160499,7 @@ async function runHistorianPrompt(args) {
160172
160499
  body: {
160173
160500
  agent: agentId,
160174
160501
  ...modelOverride ? { model: modelOverride } : {},
160175
- parts: [{ type: "text", text: prompt }]
160502
+ parts: [{ type: "text", text: prompt, synthetic: true }]
160176
160503
  }
160177
160504
  }, { timeoutMs: timeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS });
160178
160505
  sessionLog(parentSessionId, `historian: prompt completed (attempt ${retryIndex + 1}/${MAX_HISTORIAN_RETRIES + 1})`);
@@ -160294,11 +160621,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
160294
160621
  }
160295
160622
  function dumpHistorianResponse(sessionId, label, text) {
160296
160623
  try {
160297
- mkdirSync3(HISTORIAN_RESPONSE_DUMP_DIR, { recursive: true });
160624
+ mkdirSync4(HISTORIAN_RESPONSE_DUMP_DIR, { recursive: true });
160298
160625
  const safeSessionId = sanitizeDumpName(sessionId);
160299
160626
  const safeLabel = sanitizeDumpName(label);
160300
- const dumpPath = join15(HISTORIAN_RESPONSE_DUMP_DIR, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
160301
- writeFileSync3(dumpPath, text, "utf8");
160627
+ const dumpPath = join16(HISTORIAN_RESPONSE_DUMP_DIR, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
160628
+ writeFileSync4(dumpPath, text, "utf8");
160302
160629
  sessionLog(sessionId, "compartment agent: historian response dumped", {
160303
160630
  label,
160304
160631
  dumpPath
@@ -160322,7 +160649,7 @@ var init_compartment_runner_historian = __esm(async () => {
160322
160649
  init_assistant_message_extractor();
160323
160650
  init_compartment_prompt();
160324
160651
  await init_compartment_runner_validation();
160325
- HISTORIAN_RESPONSE_DUMP_DIR = join15(tmpdir2(), "magic-context-historian");
160652
+ HISTORIAN_RESPONSE_DUMP_DIR = join16(tmpdir2(), "magic-context-historian");
160326
160653
  });
160327
160654
 
160328
160655
  // src/hooks/magic-context/compartment-runner-state-xml.ts
@@ -161301,7 +161628,7 @@ var init_derive_budgets = __esm(() => {
161301
161628
  });
161302
161629
 
161303
161630
  // src/features/magic-context/compaction-marker.ts
161304
- import { join as join16 } from "node:path";
161631
+ import { join as join17 } from "node:path";
161305
161632
  function randomBase62(length) {
161306
161633
  const chars = [];
161307
161634
  for (let i = 0;i < length; i++) {
@@ -161321,7 +161648,7 @@ function generatePartId(timestampMs, counter = 0n) {
161321
161648
  return generateId("prt", timestampMs, counter);
161322
161649
  }
161323
161650
  function getOpenCodeDbPath3() {
161324
- return join16(getDataDir(), "opencode", "opencode.db");
161651
+ return join17(getDataDir(), "opencode", "opencode.db");
161325
161652
  }
161326
161653
  function isOpenCodeSchemaCompatible(db, dbPath) {
161327
161654
  if (cachedSchemaCompatible?.path === dbPath) {
@@ -161458,7 +161785,7 @@ var init_compaction_marker = __esm(async () => {
161458
161785
  });
161459
161786
 
161460
161787
  // src/hooks/magic-context/compaction-marker-manager.ts
161461
- import { join as join17 } from "node:path";
161788
+ import { join as join18 } from "node:path";
161462
161789
  function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEnd, directory) {
161463
161790
  const existing = getPersistedCompactionMarkerState(db, sessionId);
161464
161791
  if (existing) {
@@ -161501,7 +161828,7 @@ function removeCompactionMarkerForSession(db, sessionId) {
161501
161828
  }
161502
161829
  }
161503
161830
  function checkCompactionMarkerConsistency(db) {
161504
- const opencodeDbPath = join17(getDataDir(), "opencode", "opencode.db");
161831
+ const opencodeDbPath = join18(getDataDir(), "opencode", "opencode.db");
161505
161832
  let opencodeDb;
161506
161833
  try {
161507
161834
  opencodeDb = new Database(opencodeDbPath, { readonly: true });
@@ -161888,31 +162215,31 @@ var init_caveman = __esm(() => {
161888
162215
  });
161889
162216
 
161890
162217
  // src/hooks/magic-context/historian-state-file.ts
161891
- import { mkdirSync as mkdirSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
162218
+ import { mkdirSync as mkdirSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
161892
162219
  import { tmpdir as tmpdir3 } from "node:os";
161893
- import { join as join18 } from "node:path";
162220
+ import { join as join19 } from "node:path";
161894
162221
  function maybeWriteHistorianStateFile(sessionId, existingState) {
161895
162222
  if (existingState.length <= HISTORIAN_STATE_INLINE_THRESHOLD)
161896
162223
  return;
161897
162224
  try {
161898
- mkdirSync4(HISTORIAN_STATE_DIR, { recursive: true });
161899
- const path4 = join18(HISTORIAN_STATE_DIR, `state-${sessionId}-${Date.now()}.xml`);
161900
- writeFileSync4(path4, existingState, "utf8");
161901
- return path4;
162225
+ mkdirSync5(HISTORIAN_STATE_DIR, { recursive: true });
162226
+ const path5 = join19(HISTORIAN_STATE_DIR, `state-${sessionId}-${Date.now()}.xml`);
162227
+ writeFileSync5(path5, existingState, "utf8");
162228
+ return path5;
161902
162229
  } catch {
161903
162230
  return;
161904
162231
  }
161905
162232
  }
161906
- function cleanupHistorianStateFile(path4) {
161907
- if (!path4)
162233
+ function cleanupHistorianStateFile(path5) {
162234
+ if (!path5)
161908
162235
  return;
161909
162236
  try {
161910
- unlinkSync2(path4);
162237
+ unlinkSync2(path5);
161911
162238
  } catch {}
161912
162239
  }
161913
162240
  var HISTORIAN_STATE_INLINE_THRESHOLD = 30000, HISTORIAN_STATE_DIR;
161914
162241
  var init_historian_state_file = __esm(() => {
161915
- HISTORIAN_STATE_DIR = join18(tmpdir3(), "magic-context-historian");
162242
+ HISTORIAN_STATE_DIR = join19(tmpdir3(), "magic-context-historian");
161916
162243
  });
161917
162244
 
161918
162245
  // src/features/magic-context/memory/embedding-backfill.ts
@@ -162360,7 +162687,7 @@ async function runCompressorPass(args) {
162360
162687
  query: { directory },
162361
162688
  body: {
162362
162689
  agent: HISTORIAN_AGENT2,
162363
- parts: [{ type: "text", text: prompt }]
162690
+ parts: [{ type: "text", text: prompt, synthetic: true }]
162364
162691
  }
162365
162692
  }, { timeoutMs: historianTimeoutMs ?? DEFAULT_HISTORIAN_TIMEOUT_MS });
162366
162693
  const messagesResponse = await client.session.messages({
@@ -162982,8 +163309,8 @@ var exports_tui_config = {};
162982
163309
  __export(exports_tui_config, {
162983
163310
  ensureTuiPluginEntry: () => ensureTuiPluginEntry
162984
163311
  });
162985
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
162986
- import { dirname as dirname5, join as join21 } from "node:path";
163312
+ import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
163313
+ import { dirname as dirname6, join as join22 } from "node:path";
162987
163314
  function isMagicContextEntry(entry) {
162988
163315
  if (!entry)
162989
163316
  return false;
@@ -162997,11 +163324,11 @@ function isMagicContextEntry(entry) {
162997
163324
  }
162998
163325
  function resolveTuiConfigPath() {
162999
163326
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
163000
- const jsoncPath = join21(configDir, "tui.jsonc");
163001
- const jsonPath = join21(configDir, "tui.json");
163002
- if (existsSync11(jsoncPath))
163327
+ const jsoncPath = join22(configDir, "tui.jsonc");
163328
+ const jsonPath = join22(configDir, "tui.json");
163329
+ if (existsSync12(jsoncPath))
163003
163330
  return jsoncPath;
163004
- if (existsSync11(jsonPath))
163331
+ if (existsSync12(jsonPath))
163005
163332
  return jsonPath;
163006
163333
  return jsonPath;
163007
163334
  }
@@ -163009,7 +163336,7 @@ function ensureTuiPluginEntry() {
163009
163336
  try {
163010
163337
  const configPath = resolveTuiConfigPath();
163011
163338
  let config2 = {};
163012
- if (existsSync11(configPath)) {
163339
+ if (existsSync12(configPath)) {
163013
163340
  const raw = readFileSync9(configPath, "utf-8");
163014
163341
  config2 = import_comment_json3.parse(raw) ?? {};
163015
163342
  }
@@ -163029,8 +163356,8 @@ function ensureTuiPluginEntry() {
163029
163356
  plugins.push(PLUGIN_ENTRY);
163030
163357
  }
163031
163358
  config2.plugin = plugins;
163032
- mkdirSync6(dirname5(configPath), { recursive: true });
163033
- writeFileSync6(configPath, `${import_comment_json3.stringify(config2, null, 2)}
163359
+ mkdirSync7(dirname6(configPath), { recursive: true });
163360
+ writeFileSync7(configPath, `${import_comment_json3.stringify(config2, null, 2)}
163034
163361
  `);
163035
163362
  log(`[magic-context] updated TUI plugin entry in ${configPath}`);
163036
163363
  return true;
@@ -163771,7 +164098,7 @@ async function runSidekick(deps) {
163771
164098
  body: {
163772
164099
  agent: SIDEKICK_AGENT,
163773
164100
  system: deps.config.system_prompt?.trim() || deps.config.prompt?.trim() || SIDEKICK_SYSTEM_PROMPT,
163774
- parts: [{ type: "text", text: deps.userMessage }]
164101
+ parts: [{ type: "text", text: deps.userMessage, synthetic: true }]
163775
164102
  }
163776
164103
  }, { timeoutMs: deps.config.timeout_ms });
163777
164104
  const messagesResponse = await deps.client.session.messages({
@@ -164123,24 +164450,27 @@ function stripPackageNameFromPath(pathValue, packageName) {
164123
164450
  }
164124
164451
  return current;
164125
164452
  }
164126
- function removeFromBunLock(installDir, packageName) {
164127
- const lockPath = join5(installDir, "bun.lock");
164453
+ function removeFromPackageLock(installDir, packageName) {
164454
+ const lockPath = join5(installDir, "package-lock.json");
164128
164455
  if (!existsSync5(lockPath))
164129
164456
  return false;
164130
164457
  try {
164131
164458
  const lock = import_comment_json2.parse(readFileSync5(lockPath, "utf-8"));
164132
164459
  let modified = false;
164133
- if (lock.workspaces?.[""]?.dependencies?.[packageName]) {
164134
- delete lock.workspaces[""].dependencies[packageName];
164135
- modified = true;
164460
+ if (lock.packages) {
164461
+ const key = `node_modules/${packageName}`;
164462
+ if (lock.packages[key] !== undefined) {
164463
+ delete lock.packages[key];
164464
+ modified = true;
164465
+ }
164136
164466
  }
164137
- if (lock.packages?.[packageName]) {
164138
- delete lock.packages[packageName];
164467
+ if (lock.dependencies?.[packageName]) {
164468
+ delete lock.dependencies[packageName];
164139
164469
  modified = true;
164140
164470
  }
164141
164471
  if (modified) {
164142
164472
  writeFileSync2(lockPath, JSON.stringify(lock, null, 2));
164143
- log(`[auto-update-checker] Removed from bun.lock: ${packageName}`);
164473
+ log(`[auto-update-checker] Removed from package-lock.json: ${packageName}`);
164144
164474
  }
164145
164475
  return modified;
164146
164476
  } catch {
@@ -164205,7 +164535,7 @@ function preparePackageUpdate(version2, packageName = PACKAGE_NAME, runtimePacka
164205
164535
  if (!ensureDependencyVersion(installContext.packageJsonPath, packageName, version2))
164206
164536
  return null;
164207
164537
  const packageRemoved = removeInstalledPackage(installContext.installDir, packageName);
164208
- const lockRemoved = removeFromBunLock(installContext.installDir, packageName);
164538
+ const lockRemoved = removeFromPackageLock(installContext.installDir, packageName);
164209
164539
  if (!packageRemoved && !lockRemoved) {
164210
164540
  log(`[auto-update-checker] No cached package artifacts removed for ${packageName}; continuing with updated dependency spec`);
164211
164541
  }
@@ -164215,12 +164545,12 @@ function preparePackageUpdate(version2, packageName = PACKAGE_NAME, runtimePacka
164215
164545
  return null;
164216
164546
  }
164217
164547
  }
164218
- async function runBunInstallSafe(installDir, options = {}) {
164548
+ async function runNpmInstallSafe(installDir, options = {}) {
164219
164549
  let timeout = null;
164220
164550
  try {
164221
164551
  if (options.signal?.aborted)
164222
164552
  return false;
164223
- const proc = spawn("bun", ["install"], {
164553
+ const proc = spawn("npm", ["install", "--no-audit", "--no-fund", "--no-progress"], {
164224
164554
  cwd: installDir,
164225
164555
  stdio: "pipe"
164226
164556
  });
@@ -164245,7 +164575,7 @@ async function runBunInstallSafe(installDir, options = {}) {
164245
164575
  }
164246
164576
  return result;
164247
164577
  } catch (err) {
164248
- warn2(`[auto-update-checker] bun install error: ${String(err)}`);
164578
+ warn2(`[auto-update-checker] npm install error: ${String(err)}`);
164249
164579
  return false;
164250
164580
  } finally {
164251
164581
  if (timeout)
@@ -164363,7 +164693,7 @@ async function runBackgroundUpdateCheck(ctx, options) {
164363
164693
  warn3("[auto-update-checker] Failed to prepare install root for auto-update");
164364
164694
  return;
164365
164695
  }
164366
- const installSuccess = await runBunInstallSafe(installDir, { signal: options.signal });
164696
+ const installSuccess = await runNpmInstallSafe(installDir, { signal: options.signal });
164367
164697
  if (installSuccess) {
164368
164698
  showToast(ctx, "Magic Context Updated!", `v${currentVersion} → v${latestVersion}
164369
164699
  Restart OpenCode to apply.`, "success", 8000);
@@ -164371,7 +164701,7 @@ Restart OpenCode to apply.`, "success", 8000);
164371
164701
  return;
164372
164702
  }
164373
164703
  showToast(ctx, `Magic Context ${latestVersion}`, `v${latestVersion} available, but auto-update failed to install it. Check logs or retry manually.`, "error", 8000);
164374
- warn3("[auto-update-checker] bun install failed; update not installed");
164704
+ warn3("[auto-update-checker] npm install failed; update not installed");
164375
164705
  }
164376
164706
  function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
164377
164707
  ctx.client.tui.showToast({ body: { title, message, variant, duration: duration3 } }).catch(() => {});
@@ -164388,7 +164718,8 @@ function createLiveSessionState() {
164388
164718
  agentBySession: new Map,
164389
164719
  historyRefreshSessions: new Set,
164390
164720
  systemPromptRefreshSessions: new Set,
164391
- pendingMaterializationSessions: new Set
164721
+ pendingMaterializationSessions: new Set,
164722
+ sessionDirectoryBySession: new Map
164392
164723
  };
164393
164724
  }
164394
164725
 
@@ -164510,8 +164841,8 @@ function enqueueDream(db, projectIdentity, reason, force = false) {
164510
164841
  };
164511
164842
  })();
164512
164843
  }
164513
- function peekQueue(db) {
164514
- const row = db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
164844
+ function peekQueue(db, projectIdentity) {
164845
+ const row = projectIdentity ? db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL AND project_path = ? ORDER BY enqueued_at ASC LIMIT 1").get(projectIdentity) : db.prepare("SELECT id, project_path, reason, enqueued_at FROM dream_queue WHERE started_at IS NULL ORDER BY enqueued_at ASC LIMIT 1").get();
164515
164846
  if (!row)
164516
164847
  return null;
164517
164848
  return {
@@ -164522,10 +164853,10 @@ function peekQueue(db) {
164522
164853
  startedAt: null
164523
164854
  };
164524
164855
  }
164525
- function dequeueNext(db) {
164856
+ function dequeueNext(db, projectIdentity) {
164526
164857
  const now = Date.now();
164527
164858
  return db.transaction(() => {
164528
- const entry = peekQueue(db);
164859
+ const entry = peekQueue(db, projectIdentity);
164529
164860
  if (!entry)
164530
164861
  return null;
164531
164862
  const result = db.prepare("UPDATE dream_queue SET started_at = ? WHERE id = ? AND started_at IS NULL").run(now, entry.id);
@@ -164555,8 +164886,8 @@ init_assistant_message_extractor();
164555
164886
  init_data_path();
164556
164887
  init_logger();
164557
164888
  await init_sqlite();
164558
- import { existsSync as existsSync7 } from "node:fs";
164559
- import { join as join11 } from "node:path";
164889
+ import { existsSync as existsSync8 } from "node:fs";
164890
+ import { join as join12 } from "node:path";
164560
164891
 
164561
164892
  // src/features/magic-context/key-files/identify-key-files.ts
164562
164893
  init_logger();
@@ -164838,7 +165169,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
164838
165169
  body: {
164839
165170
  agent: DREAMER_AGENT,
164840
165171
  system: DREAMER_SYSTEM_PROMPT,
164841
- parts: [{ type: "text", text: prompt }]
165172
+ parts: [{ type: "text", text: prompt, synthetic: true }]
164842
165173
  }
164843
165174
  }, { timeoutMs: Math.min(remainingMs, 5 * 60 * 1000), signal: abortController.signal });
164844
165175
  const messagesResponse = await args.client.session.messages({
@@ -164947,11 +165278,11 @@ function countNewIds(beforeIds, afterIds) {
164947
165278
  return count;
164948
165279
  }
164949
165280
  function getOpenCodeDbPath2() {
164950
- return join11(getDataDir(), "opencode", "opencode.db");
165281
+ return join12(getDataDir(), "opencode", "opencode.db");
164951
165282
  }
164952
165283
  function openOpenCodeDb() {
164953
165284
  const dbPath = getOpenCodeDbPath2();
164954
- if (!existsSync7(dbPath)) {
165285
+ if (!existsSync8(dbPath)) {
164955
165286
  log(`[key-files] OpenCode DB not found at ${dbPath} — skipping`);
164956
165287
  return null;
164957
165288
  }
@@ -165049,7 +165380,7 @@ async function identifyKeyFilesForSession(args) {
165049
165380
  body: {
165050
165381
  agent: DREAMER_AGENT,
165051
165382
  system: KEY_FILES_SYSTEM_PROMPT,
165052
- parts: [{ type: "text", text: prompt }]
165383
+ parts: [{ type: "text", text: prompt, synthetic: true }]
165053
165384
  }
165054
165385
  }, { timeoutMs: Math.min(remainingMs, 300000), signal: abortController.signal });
165055
165386
  const messagesResponse = await args.client.session.messages({
@@ -165201,8 +165532,8 @@ async function runDream(args) {
165201
165532
  try {
165202
165533
  const docsDir = args.sessionDirectory ?? args.projectIdentity;
165203
165534
  const existingDocs = taskName === "maintain-docs" ? {
165204
- architecture: existsSync7(join11(docsDir, "ARCHITECTURE.md")),
165205
- structure: existsSync7(join11(docsDir, "STRUCTURE.md"))
165535
+ architecture: existsSync8(join12(docsDir, "ARCHITECTURE.md")),
165536
+ structure: existsSync8(join12(docsDir, "STRUCTURE.md"))
165206
165537
  } : undefined;
165207
165538
  const userMemories = taskName === "archive-stale" ? getActiveUserMemories(args.db).map((um) => ({
165208
165539
  id: um.id,
@@ -165233,7 +165564,7 @@ async function runDream(args) {
165233
165564
  body: {
165234
165565
  agent: DREAMER_AGENT,
165235
165566
  system: DREAMER_SYSTEM_PROMPT,
165236
- parts: [{ type: "text", text: taskPrompt }]
165567
+ parts: [{ type: "text", text: taskPrompt, synthetic: true }]
165237
165568
  }
165238
165569
  }, {
165239
165570
  timeoutMs: args.taskTimeoutMinutes * 60 * 1000,
@@ -165462,7 +165793,7 @@ Only include notes whose conditions you could definitively evaluate. Skip notes
165462
165793
  body: {
165463
165794
  agent: DREAMER_AGENT,
165464
165795
  system: DREAMER_SYSTEM_PROMPT,
165465
- parts: [{ type: "text", text: evaluationPrompt }]
165796
+ parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
165466
165797
  }
165467
165798
  }, { timeoutMs: Math.min(remainingMs, 300000), signal: abortController.signal });
165468
165799
  const messagesResponse = await args.client.session.messages({
@@ -165547,7 +165878,7 @@ var MAX_LEASE_RETRIES = 3;
165547
165878
  async function processDreamQueue(args) {
165548
165879
  const maxRuntimeMs = args.maxRuntimeMinutes * 60 * 1000;
165549
165880
  clearStaleEntries(args.db, maxRuntimeMs + 1800000);
165550
- const entry = dequeueNext(args.db);
165881
+ const entry = dequeueNext(args.db, args.projectIdentity);
165551
165882
  if (!entry) {
165552
165883
  return null;
165553
165884
  }
@@ -165642,7 +165973,7 @@ function findProjectsNeedingDream(db) {
165642
165973
  }
165643
165974
  return projects;
165644
165975
  }
165645
- function checkScheduleAndEnqueue(db, schedule) {
165976
+ function checkScheduleAndEnqueue(db, schedule, ownProjectIdentity) {
165646
165977
  if (!isInScheduleWindow(schedule)) {
165647
165978
  return 0;
165648
165979
  }
@@ -165650,8 +165981,9 @@ function checkScheduleAndEnqueue(db, schedule) {
165650
165981
  if (projects.length === 0) {
165651
165982
  return 0;
165652
165983
  }
165984
+ const eligible = ownProjectIdentity ? projects.filter((id) => id === ownProjectIdentity) : projects;
165653
165985
  let enqueued = 0;
165654
- for (const projectIdentity of projects) {
165986
+ for (const projectIdentity of eligible) {
165655
165987
  const entry = enqueueDream(db, projectIdentity, "scheduled");
165656
165988
  if (entry) {
165657
165989
  log(`[dreamer] enqueued project for scheduled dream: ${projectIdentity}`);
@@ -166247,7 +166579,8 @@ async function sweepProject(reg, origin) {
166247
166579
  try {
166248
166580
  const db = openDatabase();
166249
166581
  log(`[dreamer] timer tick (${origin}) ${reg.directory} — checking schedule window "${reg.dreamerConfig.schedule}"`);
166250
- checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule);
166582
+ const registrationIdentity = resolveProjectIdentity(reg.directory);
166583
+ checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule, registrationIdentity);
166251
166584
  await processDreamQueue({
166252
166585
  db,
166253
166586
  client: reg.client,
@@ -166255,7 +166588,8 @@ async function sweepProject(reg, origin) {
166255
166588
  taskTimeoutMinutes: reg.dreamerConfig.task_timeout_minutes,
166256
166589
  maxRuntimeMinutes: reg.dreamerConfig.max_runtime_minutes,
166257
166590
  experimentalUserMemories: reg.experimentalUserMemories,
166258
- experimentalPinKeyFiles: reg.experimentalPinKeyFiles
166591
+ experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
166592
+ projectIdentity: registrationIdentity
166259
166593
  });
166260
166594
  } catch (error48) {
166261
166595
  log(`[dreamer] timer-triggered queue processing failed for ${reg.directory}:`, error48);
@@ -167156,7 +167490,8 @@ Dreaming is not configured for this project.`, {});
167156
167490
  taskTimeoutMinutes: deps.dreamer.config.task_timeout_minutes,
167157
167491
  maxRuntimeMinutes: deps.dreamer.config.max_runtime_minutes,
167158
167492
  experimentalUserMemories: deps.dreamer.experimentalUserMemories,
167159
- experimentalPinKeyFiles: deps.dreamer.experimentalPinKeyFiles
167493
+ experimentalPinKeyFiles: deps.dreamer.experimentalPinKeyFiles,
167494
+ projectIdentity: deps.dreamer.projectPath
167160
167495
  });
167161
167496
  await deps.sendNotification(sessionId, result ? summarizeDreamResult(result) : "Dream queued, but another worker is already processing the queue.", {});
167162
167497
  throwSentinel("CTX-DREAM");
@@ -170497,12 +170832,16 @@ function createTransform(deps) {
170497
170832
  const reducedMode = sessionMeta.isSubagent;
170498
170833
  const fullFeatureMode = !reducedMode;
170499
170834
  let sessionDirectory = deps.directory ?? "";
170500
- if (deps.client !== undefined) {
170835
+ const cachedDirectory = deps.sessionDirectoryBySession?.get(sessionId);
170836
+ if (cachedDirectory && cachedDirectory.length > 0) {
170837
+ sessionDirectory = cachedDirectory;
170838
+ } else if (deps.client !== undefined) {
170501
170839
  try {
170502
170840
  const sessionResponse = await deps.client.session.get({ path: { id: sessionId } }).catch(() => null);
170503
170841
  const sessionInfo = sessionResponse?.data;
170504
170842
  if (sessionInfo && typeof sessionInfo.directory === "string" && sessionInfo.directory.length > 0) {
170505
170843
  sessionDirectory = sessionInfo.directory;
170844
+ deps.sessionDirectoryBySession?.set(sessionId, sessionDirectory);
170506
170845
  }
170507
170846
  } catch {}
170508
170847
  }
@@ -171559,6 +171898,7 @@ function createEventHook(args) {
171559
171898
  args.liveModelBySession.delete(sessionId);
171560
171899
  args.variantBySession.delete(sessionId);
171561
171900
  args.agentBySession.delete(sessionId);
171901
+ args.sessionDirectoryBySession.delete(sessionId);
171562
171902
  args.recentReduceBySession.delete(sessionId);
171563
171903
  args.toolUsageSinceUserTurn.delete(sessionId);
171564
171904
  args.historyRefreshSessions.delete(sessionId);
@@ -171616,8 +171956,8 @@ init_send_session_notification();
171616
171956
 
171617
171957
  // src/hooks/magic-context/system-prompt-hash.ts
171618
171958
  import { createHash as createHash4 } from "node:crypto";
171619
- import { existsSync as existsSync10, readFileSync as readFileSync8, realpathSync } from "node:fs";
171620
- import { join as join19, resolve as resolve4, sep } from "node:path";
171959
+ import { existsSync as existsSync11, readFileSync as readFileSync8, realpathSync } from "node:fs";
171960
+ import { join as join20, resolve as resolve4, sep } from "node:path";
171621
171961
 
171622
171962
  // src/agents/magic-context-prompt.ts
171623
171963
  function getToolHistoryGuidance(dropToolStructure) {
@@ -171723,13 +172063,16 @@ function clearSystemPromptHashSession(sessionId, handleMaps) {
171723
172063
  handleMaps.stickyDateBySession.delete(sessionId);
171724
172064
  handleMaps.cachedDocsBySession.delete(sessionId);
171725
172065
  }
172066
+ function isInternalOpenCodeAgent(systemPromptContent) {
172067
+ return systemPromptContent.includes("You are a title generator. You output ONLY a thread title.") || systemPromptContent.includes("Summarize what was done in this conversation. Write like a pull request description.") || systemPromptContent.includes("You are an anchored context summarization assistant for coding sessions.");
172068
+ }
171726
172069
  var DOC_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
171727
172070
  function readProjectDocs(directory) {
171728
172071
  const sections = [];
171729
172072
  for (const filename of DOC_FILES) {
171730
- const filePath = join19(directory, filename);
172073
+ const filePath = join20(directory, filename);
171731
172074
  try {
171732
- if (existsSync10(filePath)) {
172075
+ if (existsSync11(filePath)) {
171733
172076
  const content = readFileSync8(filePath, "utf-8").trim();
171734
172077
  if (content.length > 0) {
171735
172078
  sections.push(`<${filename}>
@@ -171757,6 +172100,22 @@ function createSystemPromptHashHandler(deps) {
171757
172100
  const sessionId = input.sessionID;
171758
172101
  if (!sessionId)
171759
172102
  return;
172103
+ const fullPromptForDetection = output.system.join(`
172104
+ `);
172105
+ if (isInternalOpenCodeAgent(fullPromptForDetection)) {
172106
+ sessionLog(sessionId, "system-prompt-hash skipped (OpenCode internal agent: title/summary/compaction)");
172107
+ return;
172108
+ }
172109
+ const injectionEnabled = deps.injectionEnabled !== false;
172110
+ const skipSignatures = deps.injectionSkipSignatures ?? [];
172111
+ if (!injectionEnabled) {
172112
+ sessionLog(sessionId, "system-prompt-hash skipped (injection globally disabled)");
172113
+ return;
172114
+ }
172115
+ if (skipSignatures.some((sig) => sig.length > 0 && fullPromptForDetection.includes(sig))) {
172116
+ sessionLog(sessionId, "system-prompt-hash skipped (matched system_prompt_injection.skip_signatures)");
172117
+ return;
172118
+ }
171760
172119
  let sessionMetaEarly;
171761
172120
  try {
171762
172121
  sessionMetaEarly = getOrCreateSessionMeta(deps.db, sessionId);
@@ -171826,7 +172185,7 @@ ${items}
171826
172185
  log(`[magic-context] key file path escapes project root, skipping: ${entry.filePath}`);
171827
172186
  continue;
171828
172187
  }
171829
- if (!existsSync10(absPath))
172188
+ if (!existsSync11(absPath))
171830
172189
  continue;
171831
172190
  let realPath;
171832
172191
  try {
@@ -171994,6 +172353,7 @@ function createMagicContextHook(deps) {
171994
172353
  const variantBySession = deps.liveSessionState?.variantBySession ?? new Map;
171995
172354
  const liveModelBySession = deps.liveSessionState?.liveModelBySession ?? new Map;
171996
172355
  const agentBySession = deps.liveSessionState?.agentBySession ?? new Map;
172356
+ const sessionDirectoryBySession = deps.liveSessionState?.sessionDirectoryBySession ?? new Map;
171997
172357
  const recentReduceBySession = new Map;
171998
172358
  const toolUsageSinceUserTurn = new Map;
171999
172359
  const resolveLiveModel = (sessionId) => {
@@ -172061,6 +172421,7 @@ function createMagicContextHook(deps) {
172061
172421
  compressorMaxMergeDepth: deps.config.compressor?.enabled === false ? undefined : deps.config.compressor?.max_merge_depth,
172062
172422
  compressorCooldownMs: deps.config.compressor?.enabled === false ? undefined : deps.config.compressor?.cooldown_ms,
172063
172423
  liveModelBySession,
172424
+ sessionDirectoryBySession,
172064
172425
  autoSearch: deps.config.experimental?.auto_search?.enabled ? {
172065
172426
  enabled: true,
172066
172427
  scoreThreshold: deps.config.experimental.auto_search.score_threshold,
@@ -172207,6 +172568,10 @@ function createMagicContextHook(deps) {
172207
172568
  systemPromptRefreshSessions,
172208
172569
  pendingMaterializationSessions,
172209
172570
  lastHeuristicsTurnId,
172571
+ injectionEnabled: deps.config.system_prompt_injection?.enabled ?? true,
172572
+ injectionSkipSignatures: deps.config.system_prompt_injection?.skip_signatures ?? [
172573
+ "<!-- magic-context: skip -->"
172574
+ ],
172210
172575
  experimentalUserMemories: deps.config.dreamer?.user_memories?.enabled,
172211
172576
  experimentalPinKeyFiles: deps.config.dreamer?.pin_key_files?.enabled ?? false,
172212
172577
  experimentalPinKeyFilesTokenBudget: deps.config.dreamer?.pin_key_files?.token_budget,
@@ -172221,6 +172586,7 @@ function createMagicContextHook(deps) {
172221
172586
  liveModelBySession,
172222
172587
  variantBySession,
172223
172588
  agentBySession,
172589
+ sessionDirectoryBySession,
172224
172590
  recentReduceBySession,
172225
172591
  toolUsageSinceUserTurn,
172226
172592
  historyRefreshSessions,
@@ -172302,6 +172668,7 @@ function createSessionHooks(args) {
172302
172668
  dreamer: pluginConfig.dreamer,
172303
172669
  commit_cluster_trigger: pluginConfig.commit_cluster_trigger,
172304
172670
  compaction_markers: pluginConfig.compaction_markers,
172671
+ system_prompt_injection: pluginConfig.system_prompt_injection,
172305
172672
  compressor: pluginConfig.compressor,
172306
172673
  experimental: pluginConfig.experimental
172307
172674
  }
@@ -173863,19 +174230,19 @@ init_models_dev_cache();
173863
174230
 
173864
174231
  // src/shared/rpc-server.ts
173865
174232
  init_logger();
173866
- import { mkdirSync as mkdirSync5, renameSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
174233
+ import { mkdirSync as mkdirSync6, renameSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
173867
174234
  import { createServer } from "node:http";
173868
- import { dirname as dirname4 } from "node:path";
174235
+ import { dirname as dirname5 } from "node:path";
173869
174236
 
173870
174237
  // src/shared/rpc-utils.ts
173871
174238
  import { createHash as createHash5 } from "node:crypto";
173872
- import { join as join20 } from "node:path";
174239
+ import { join as join21 } from "node:path";
173873
174240
  function projectHash(directory) {
173874
174241
  const normalized = directory.replace(/\/+$/, "");
173875
174242
  return createHash5("sha256").update(normalized).digest("hex").slice(0, 16);
173876
174243
  }
173877
174244
  function rpcPortFilePath(storageDir, directory) {
173878
- return join20(storageDir, "rpc", projectHash(directory), "port");
174245
+ return join21(storageDir, "rpc", projectHash(directory), "port");
173879
174246
  }
173880
174247
 
173881
174248
  // src/shared/rpc-server.ts
@@ -173906,10 +174273,10 @@ class MagicContextRpcServer {
173906
174273
  this.port = addr.port;
173907
174274
  this.server = server;
173908
174275
  try {
173909
- const dir = dirname4(this.portFilePath);
173910
- mkdirSync5(dir, { recursive: true });
174276
+ const dir = dirname5(this.portFilePath);
174277
+ mkdirSync6(dir, { recursive: true });
173911
174278
  const tmpPath = `${this.portFilePath}.tmp`;
173912
- writeFileSync5(tmpPath, String(this.port), "utf-8");
174279
+ writeFileSync6(tmpPath, String(this.port), "utf-8");
173913
174280
  renameSync(tmpPath, this.portFilePath);
173914
174281
  log(`[rpc] server listening on 127.0.0.1:${this.port}`);
173915
174282
  } catch (err) {