@cortexkit/pi-magic-context 0.49.16 → 0.49.17

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 (51) hide show
  1. package/dist/auto-search-worker.js +76 -63
  2. package/dist/chunk-embedding-write-worker.js +10 -10
  3. package/dist/{compaction-marker-candidates-k4tqg4jb.js → compaction-marker-candidates-wjzqbspm.js} +2 -2
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/embedding-backfill-vwag34t0.js +23 -0
  6. package/dist/embedding-worker-process.js +1 -1
  7. package/dist/embedding-worker.js +4 -4
  8. package/dist/historian-calibration-extension.js +4 -1
  9. package/dist/{index-g4jf772p.js → index-1kcfwk9c.js} +22 -2
  10. package/dist/{index-657xh9w4.js → index-2mmy81qt.js} +2 -2
  11. package/dist/{index-v8d4vgam.js → index-469ttgzv.js} +6 -6
  12. package/dist/index-4knyh1kt.js +1387 -0
  13. package/dist/{index-44h64qza.js → index-5k2mshvq.js} +9 -9
  14. package/dist/{index-fhyy4ave.js → index-8r2t8fv2.js} +842 -73
  15. package/dist/{index-xmzhrht0.js → index-9j809q6f.js} +29 -18
  16. package/dist/{index-6dz2ed1v.js → index-d8gc0112.js} +2 -2
  17. package/dist/{index-x3k1530z.js → index-dvbjsh98.js} +3 -3
  18. package/dist/{index-hy44m6jc.js → index-e1rza8gp.js} +1 -1
  19. package/dist/{index-dne4ja7a.js → index-ej4eak9d.js} +2 -2
  20. package/dist/{index-4178cbfw.js → index-es03azap.js} +121 -2038
  21. package/dist/{index-ajfpyk0x.js → index-fa485mqs.js} +59 -1
  22. package/dist/{index-y5c73caa.js → index-g7p75667.js} +32 -3
  23. package/dist/{index-tympym62.js → index-gdjv1nnd.js} +2 -2
  24. package/dist/{index-46q4e104.js → index-qpq6w67c.js} +1 -1
  25. package/dist/{index-asrxgdt4.js → index-rrwv9y2k.js} +8 -0
  26. package/dist/{index-mx59cve4.js → index-svgkv4g2.js} +1 -1
  27. package/dist/{index-qqxqwqhp.js → index-vktahpdj.js} +1 -1
  28. package/dist/{index-n3r2d2pr.js → index-vmcgew7x.js} +10 -7
  29. package/dist/{index-afy3dzf9.js → index-xnch62s6.js} +12 -6
  30. package/dist/{index-s1xn8qfw.js → index-yygsh681.js} +6 -3
  31. package/dist/{index-p3evwech.js → index-z2rkv0mb.js} +3 -3
  32. package/dist/{index-ja1c33qa.js → index-z7kbck29.js} +2 -2
  33. package/dist/index.js +523 -227
  34. package/dist/{message-fts-rowid-map-mbanfkt1.js → message-fts-rowid-map-cvpy2dmb.js} +5 -3
  35. package/dist/{message-index-easvmz22.js → message-index-2g23b7fe.js} +11 -11
  36. package/dist/{message-index-bounded-xzerjxmp.js → message-index-bounded-d6zj2tn5.js} +15 -15
  37. package/dist/{message-time-backfill-3q4kemfc.js → message-time-backfill-ssshbdy8.js} +1 -1
  38. package/dist/migration-worker.js +7 -7
  39. package/dist/{project-embedding-registry-xwnmqmx8.js → project-embedding-registry-vf1ncptn.js} +10 -10
  40. package/dist/raw-ordinal-warmup-worker.js +10 -10
  41. package/dist/{read-session-chunk-1sb5n7zs.js → read-session-chunk-2ky7mbqp.js} +5 -5
  42. package/dist/{read-session-raw-jz5e9jz0.js → read-session-raw-9s3xn7fc.js} +2 -2
  43. package/dist/{search-archive-3ma5n0wr.js → search-archive-9akqcr90.js} +6 -6
  44. package/dist/{search-x3fa0561.js → search-zjyc65g1.js} +17 -17
  45. package/dist/{sqlite-adjpy399.js → sqlite-fsp0sf3r.js} +1 -1
  46. package/dist/{storage-memory-axnsk5t1.js → storage-memory-yxxc5v4n.js} +2 -2
  47. package/dist/{storage-tags-jtessrec.js → storage-tags-cx6ccsv1.js} +3 -3
  48. package/dist/subagent-entry.js +22 -21
  49. package/dist/tag-snapshot-worker-pi.js +9 -9
  50. package/package.json +1 -1
  51. package/dist/embedding-backfill-c4bdw8pp.js +0 -23
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  harnessOwnsOpenCodeStore2
5
5
  } from "./index-0h2mkab2.js";
6
6
  import {
7
+ getDataDir,
7
8
  ensureCortexKitArtifactGitignore,
8
9
  getProjectMagicContextHistorianDir,
9
10
  getMagicContextStorageDir,
@@ -248,7 +249,8 @@ import {
248
249
  registerTodoStateLifecycle,
249
250
  syncCtxMemoryToolEnabled,
250
251
  registerMagicContextTools
251
- } from "./index-4178cbfw.js";
252
+ } from "./index-es03azap.js";
253
+ import"./index-4knyh1kt.js";
252
254
  import {
253
255
  canonicalModelIdentity,
254
256
  piModelRefToCanonical,
@@ -288,8 +290,9 @@ import {
288
290
  openCurrentDatabase,
289
291
  openDatabaseAsync,
290
292
  closeDatabase
291
- } from "./index-v8d4vgam.js";
293
+ } from "./index-469ttgzv.js";
292
294
  import {
295
+ pruneMissingProjectIdentities,
293
296
  setHomeProjectPermission,
294
297
  ProjectIdentityError,
295
298
  resolveProjectIdentityStrict,
@@ -299,7 +302,7 @@ import {
299
302
  resolveProjectIdentityForSession,
300
303
  beginBootQuietPeriod,
301
304
  scheduleAfterBootQuiet
302
- } from "./index-y5c73caa.js";
305
+ } from "./index-g7p75667.js";
303
306
  import {
304
307
  detectThinkingBindingMismatch,
305
308
  detectLatestTurnThinkingMismatch,
@@ -458,7 +461,7 @@ import {
458
461
  getRawSessionTagKeysThrough2,
459
462
  getLegacyProtectedTailStartOrdinal2,
460
463
  readSessionChunk2
461
- } from "./index-44h64qza.js";
464
+ } from "./index-5k2mshvq.js";
462
465
  import {
463
466
  UNKNOWN_FIT_RATIO,
464
467
  hasMeasuredDecisionCalibration,
@@ -545,7 +548,7 @@ import {
545
548
  getToolTagNumberByOwner2,
546
549
  getNullOwnerToolTag2,
547
550
  adoptNullOwnerToolTag2
548
- } from "./index-dne4ja7a.js";
551
+ } from "./index-ej4eak9d.js";
549
552
  import {
550
553
  textMentionsRecentCommit,
551
554
  hasMeaningfulUserText2,
@@ -557,7 +560,7 @@ import {
557
560
  estimateTokens,
558
561
  estimateFixedPromptTokens,
559
562
  normalizeText
560
- } from "./index-g4jf772p.js";
563
+ } from "./index-1kcfwk9c.js";
561
564
  import {
562
565
  inRootAsyncContext2,
563
566
  Database2,
@@ -570,7 +573,7 @@ import {
570
573
  isTransientSqliteError2,
571
574
  withAsyncPrivilegedWriter2,
572
575
  indexCoordinationInput2
573
- } from "./index-asrxgdt4.js";
576
+ } from "./index-rrwv9y2k.js";
574
577
  import {
575
578
  stableStringify,
576
579
  closeQuietly,
@@ -579,19 +582,6 @@ import {
579
582
  freezeTemporalDecisions,
580
583
  tagIdentityRevisionKey
581
584
  } from "./index-jrap43gc.js";
582
- import {
583
- resolveOpenCodeDbPath,
584
- assertOpenCodeStoreGeneration,
585
- openCodeDbPathExists,
586
- recordOpenCodeDbReadFailure,
587
- clearOpenCodeDbReadFailure,
588
- claimOpenCodeDbDiagnosticOnce
589
- } from "./index-8976mezv.js";
590
- import"./index-399p688g.js";
591
- import {
592
- runSessionWarmupWorker,
593
- RAW_SUMMARY_TEXT_MAX_CHARS2
594
- } from "./index-qqxqwqhp.js";
595
585
  import {
596
586
  piHarnessKindFromExecutable
597
587
  } from "./index-apgwdby5.js";
@@ -604,11 +594,14 @@ import {
604
594
  ownsLkgDirtyFence,
605
595
  invalidateCleanLkgRecoveryFence,
606
596
  markLkgRecoveryDirty,
597
+ gaDatabasePath,
607
598
  readSessionActivity,
608
599
  observeSessionActivity,
609
600
  backfillSessionActivity,
610
601
  clearCompressionDepth,
611
602
  clearCompressionDepthRange,
603
+ cleanSearchText,
604
+ matchedSearchSnippet,
612
605
  getMessageIndexSourceIdentity2,
613
606
  isMessageIndexSourceCurrent2,
614
607
  getLastIndexedOrdinal2,
@@ -616,12 +609,25 @@ import {
616
609
  isMessageIndexReconciledThrough2,
617
610
  indexSingleMessage2,
618
611
  indexMessagesAfterOrdinal2,
619
- sweepOrphanedOpenCodeMessageIndexes2
620
- } from "./index-fhyy4ave.js";
612
+ sweepOrphanedOpenCodeMessageIndexesCooperatively2
613
+ } from "./index-8r2t8fv2.js";
614
+ import {
615
+ resolveOpenCodeDbPath,
616
+ assertOpenCodeStoreGeneration,
617
+ openCodeDbPathExists,
618
+ recordOpenCodeDbReadFailure,
619
+ clearOpenCodeDbReadFailure,
620
+ claimOpenCodeDbDiagnosticOnce
621
+ } from "./index-8976mezv.js";
622
+ import"./index-399p688g.js";
623
+ import {
624
+ runSessionWarmupWorker,
625
+ RAW_SUMMARY_TEXT_MAX_CHARS2
626
+ } from "./index-vktahpdj.js";
621
627
  import {
622
628
  formatSynapseLaneDescriptor
623
- } from "./index-6dz2ed1v.js";
624
- import"./index-s1xn8qfw.js";
629
+ } from "./index-d8gc0112.js";
630
+ import"./index-yygsh681.js";
625
631
  import {
626
632
  buildCanonicalChunkTextFromFts,
627
633
  buildCompartmentSummaryFallbackText,
@@ -631,7 +637,7 @@ import {
631
637
  replaceCompartmentChunkEmbeddings,
632
638
  deleteChunkEmbedBackoffForSession,
633
639
  chunkWindowSourceKey
634
- } from "./index-afy3dzf9.js";
640
+ } from "./index-xnch62s6.js";
635
641
  import {
636
642
  recordSessionProjectIdentity,
637
643
  GIT_SWEEP_LEASE_RENEWAL_MS,
@@ -640,7 +646,7 @@ import {
640
646
  markGitSweepSuccessAndRelease,
641
647
  parkGitSweepNonIndexable,
642
648
  releaseGitSweepLease
643
- } from "./index-mx59cve4.js";
649
+ } from "./index-svgkv4g2.js";
644
650
  import {
645
651
  embedPauseBySession,
646
652
  embedRunStateBySession,
@@ -666,7 +672,7 @@ import {
666
672
  embedSessionCompartmentChunks2,
667
673
  getEmbeddingCoverageStatus2,
668
674
  getAutoEmbeddingSessionCoverage2
669
- } from "./index-n3r2d2pr.js";
675
+ } from "./index-vmcgew7x.js";
670
676
  import {
671
677
  rememberV1HiddenRun
672
678
  } from "./index-6x556c2q.js";
@@ -681,7 +687,7 @@ import {
681
687
  expandWorkspaceIdentitySetWithAliases,
682
688
  sourceNameForMemory,
683
689
  computeWorkspaceEpochFingerprint
684
- } from "./index-tympym62.js";
690
+ } from "./index-gdjv1nnd.js";
685
691
  import {
686
692
  configureContextDatabasePragmas2
687
693
  } from "./index-fapenpch.js";
@@ -731,7 +737,7 @@ import {
731
737
  normalizeVerificationFiles,
732
738
  indexCommitsForProject,
733
739
  embedUnembeddedCommits
734
- } from "./index-xmzhrht0.js";
740
+ } from "./index-9j809q6f.js";
735
741
  import {
736
742
  setEmbeddingSessionBusy2,
737
743
  isEmbeddingHostBusy2
@@ -755,18 +761,18 @@ import {
755
761
  setMemoryClassification2,
756
762
  archiveMemory2,
757
763
  getMemoryCountsByStatus2
758
- } from "./index-hy44m6jc.js";
764
+ } from "./index-e1rza8gp.js";
759
765
  import {
760
766
  invalidateMemory2
761
767
  } from "./index-yhzhdp3m.js";
762
768
  import {
763
769
  pushNotification2
764
770
  } from "./index-q1yc6bs0.js";
765
- import"./index-657xh9w4.js";
771
+ import"./index-2mmy81qt.js";
766
772
  import {
767
773
  cosineSimilarity
768
- } from "./index-p3evwech.js";
769
- import"./index-46q4e104.js";
774
+ } from "./index-z2rkv0mb.js";
775
+ import"./index-qpq6w67c.js";
770
776
  import {
771
777
  DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
772
778
  buildHiddenAgentRegistrations,
@@ -774,9 +780,10 @@ import {
774
780
  readHostSystemPrompt,
775
781
  subagentStepCap,
776
782
  SubagentTelemetry,
783
+ HISTORIAN_CACHE_TAIL_ENV2,
777
784
  HISTORIAN_MAX_OUTPUT_TOKENS_ENV2,
778
785
  SUBAGENT_OUTPUT_CEILING_ENV2
779
- } from "./index-ajfpyk0x.js";
786
+ } from "./index-fa485mqs.js";
780
787
  import {
781
788
  PiTagHydrationError,
782
789
  getPiTagSnapshotView,
@@ -787,10 +794,10 @@ import {
787
794
  drainPiTagSnapshotSession,
788
795
  assertPiTagSnapshotReady,
789
796
  ensurePiTagSnapshotReady
790
- } from "./index-x3k1530z.js";
797
+ } from "./index-dvbjsh98.js";
791
798
  import"./index-f18ec69t.js";
792
799
  import"./index-1cvyaw9a.js";
793
- import"./index-ja1c33qa.js";
800
+ import"./index-z7kbck29.js";
794
801
  import {
795
802
  __toESM
796
803
  } from "./index-22jkk6wg.js";
@@ -815,7 +822,7 @@ import {
815
822
  } from "./index-81nthk8j.js";
816
823
 
817
824
  // src/index.ts
818
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
825
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
819
826
  import { createRequire as createRequire2 } from "node:module";
820
827
  import { join as join16, resolve as resolve3 } from "node:path";
821
828
 
@@ -3512,7 +3519,7 @@ function startHostStallProfilerSwitch() {
3512
3519
  // package.json
3513
3520
  var package_default = {
3514
3521
  name: "@cortexkit/pi-magic-context",
3515
- version: "0.49.16",
3522
+ version: "0.49.17",
3516
3523
  type: "module",
3517
3524
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3518
3525
  main: "dist/index.js",
@@ -9340,6 +9347,7 @@ async function runHistorianPrompt(args) {
9340
9347
  let handle = null;
9341
9348
  let completion;
9342
9349
  const executor = resolveHiddenCompletionExecutor(args.hiddenCompletionExecutor, client, db, sessionDirectory, "historian");
9350
+ const cacheTail = args.cacheTail ?? (executor.capabilities.harness === "opencode2" ? "skip" : undefined);
9343
9351
  let promptSettled = false;
9344
9352
  let hadUnsettledPrompt = false;
9345
9353
  const startedAt = Date.now();
@@ -9421,6 +9429,7 @@ async function runHistorianPrompt(args) {
9421
9429
  try {
9422
9430
  await promptSyncWithModelSuggestionRetry(client, {
9423
9431
  path: { id: agentSessionId },
9432
+ ...cacheTail !== undefined ? { cacheTail: retryIndex > 0 ? "write" : cacheTail } : {},
9424
9433
  query: { directory: sessionDirectory },
9425
9434
  body: {
9426
9435
  agent: agentId,
@@ -19233,9 +19242,14 @@ async function indexSingleMessageOffThread(db, sessionId, message) {
19233
19242
  return result.inserted;
19234
19243
  }
19235
19244
  async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
19245
+ if (getHarness2() === "opencode2")
19246
+ openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
19247
+ readonly: true,
19248
+ fileMustExist: true
19249
+ });
19236
19250
  const path = getSqliteDatabasePath2(db);
19237
- if (!path || getHarness2() !== "opencode")
19238
- return sweepOrphanedOpenCodeMessageIndexes2(db, openSource, options);
19251
+ if (!path || getHarness2() !== "opencode" && getHarness2() !== "opencode2")
19252
+ return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, openSource, options);
19239
19253
  let source = null;
19240
19254
  let sourcePath = null;
19241
19255
  try {
@@ -19247,7 +19261,7 @@ async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, opti
19247
19261
  source?.close();
19248
19262
  }
19249
19263
  if (!sourcePath)
19250
- return sweepOrphanedOpenCodeMessageIndexes2(db, () => source, options);
19264
+ return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, () => source, options);
19251
19265
  const reply = await runSessionWarmupWorker({
19252
19266
  path,
19253
19267
  sessionId: "",
@@ -19403,7 +19417,7 @@ function runTick(origin) {
19403
19417
  if (tickInFlight)
19404
19418
  return;
19405
19419
  tickInFlight = true;
19406
- log2(`[dreamer] timer tick (${origin}) — projects=${registeredProjects.size}`);
19420
+ log2(`[magic-context] maintenance tick (${origin}) — projects=${registeredProjects.size}`);
19407
19421
  (async () => {
19408
19422
  try {
19409
19423
  const db = openTimerDatabaseOrNull("maintenance tick");
@@ -19453,6 +19467,9 @@ function persistTickOutcome(db, failure) {
19453
19467
  }
19454
19468
  }
19455
19469
  async function runMessageHistoryMaintenance(db) {
19470
+ const prunedIdentities = await pruneMissingProjectIdentities();
19471
+ if (prunedIdentities > 0)
19472
+ log2(`[magic-context] pruned ${prunedIdentities} missing project identities`);
19456
19473
  try {
19457
19474
  await drainStaleLkgSlots(db);
19458
19475
  } catch (error) {
@@ -19686,10 +19703,20 @@ async function sweepGitCommits(args) {
19686
19703
  const holderId = crypto.randomUUID();
19687
19704
  const lease = acquireGitSweepLease(db, projectIdentity, holderId);
19688
19705
  if (!lease.acquired) {
19689
- const reason = lease.reason === "cooldown_active" ? `cooldown active until ${lease.nextAllowedAt}` : `lease held by ${lease.leaseHolder ?? "another holder"} until ${lease.leaseExpiresAt ?? "unknown"}`;
19706
+ if (lease.reason === "cooldown_active")
19707
+ return;
19708
+ const reason = `lease held by ${lease.leaseHolder ?? "another holder"} until ${lease.leaseExpiresAt ?? "unknown"}`;
19690
19709
  log2(`[git-commits] sweep skipped for ${projectIdentity}: ${reason}`);
19691
19710
  return;
19692
19711
  }
19712
+ if (projectIdentity.startsWith("dir:")) {
19713
+ if (parkGitSweepNonIndexable(db, projectIdentity, holderId)) {
19714
+ log2(`[git-commits] sweep parked for ${projectIdentity}: directory identity has no commits`);
19715
+ } else {
19716
+ releaseGitSweepLease(db, projectIdentity, holderId);
19717
+ }
19718
+ return;
19719
+ }
19693
19720
  const startedAt = Date.now();
19694
19721
  const stopRenewal = startGitSweepLeaseRenewal(db, projectIdentity, holderId);
19695
19722
  log2(`[git-commits] sweep starting for ${projectIdentity} (sinceDays=${gitCommitIndexing.since_days} maxCommits=${gitCommitIndexing.max_commits})`);
@@ -20658,6 +20685,7 @@ class PiSubagentRunner {
20658
20685
  delete parentEnv.MAGIC_CONTEXT_HISTORIAN_TEMPERATURE;
20659
20686
  delete parentEnv[HISTORIAN_MAX_OUTPUT_TOKENS_ENV2];
20660
20687
  delete parentEnv[SUBAGENT_OUTPUT_CEILING_ENV2];
20688
+ delete parentEnv[HISTORIAN_CACHE_TAIL_ENV2];
20661
20689
  try {
20662
20690
  child = inRootAsyncContext2(() => this.spawnImpl(this.invocation.command, [...this.invocation.prefixArgs, ...this.extraArgs, ...args], {
20663
20691
  windowsHide: true,
@@ -20666,6 +20694,7 @@ class PiSubagentRunner {
20666
20694
  ...parentEnv,
20667
20695
  [MAGIC_CONTEXT_PI_SUBAGENT_ENV]: "1",
20668
20696
  MAGIC_CONTEXT_SUBAGENT_PROMPT_FILE: systemPromptPath,
20697
+ [HISTORIAN_CACHE_TAIL_ENV2]: /^(magic-context-)?historian(?:-recomp)?$/.test(options.agent) && options.accountingSubagent !== "historian_editor" ? options.cacheTail : undefined,
20669
20698
  MAGIC_CONTEXT_SUBAGENT_BUDGET_GUARD_FILE: budgetGuardFile,
20670
20699
  MAGIC_CONTEXT_SUBAGENT_PROVENANCE_ONLY: /^(magic-context-)?historian(?:-recomp|-editor)?$/.test(options.agent) ? undefined : "1",
20671
20700
  ...options.temperature !== undefined ? {
@@ -24219,27 +24248,43 @@ function buildReplacementContent(tagId) {
24219
24248
  return `[dropped §${tagId}§]`;
24220
24249
  }
24221
24250
  function applyNewToolDrop(target, options) {
24222
- if (options.persist && (target?.prepareDrop?.() ?? target?.canDrop?.()) === false) {
24251
+ const plan = planNewToolDrop(target, options, !!options.persist);
24252
+ if (!plan)
24223
24253
  return { result: "incomplete", mode: "full" };
24254
+ options.persist?.(plan.mode);
24255
+ return plan.apply();
24256
+ }
24257
+ function planNewToolDrop(target, options, prepare, plannedRemovals) {
24258
+ if (prepare && (target?.prepareDrop?.() ?? target?.canDrop?.()) === false) {
24259
+ return;
24224
24260
  }
24225
24261
  if (!target) {
24226
- options.persist?.("full");
24227
- return { result: "absent", mode: "full" };
24262
+ return { mode: "full", apply: () => ({ result: "absent", mode: "full" }) };
24228
24263
  }
24229
- if (options.inWindow && hasSmallToolInput(target) || options.keepSkeleton === true || target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.() === true) {
24264
+ if (options.inWindow && hasSmallToolInput(target) || options.keepSkeleton === true || target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.(plannedRemovals) === true) {
24230
24265
  const strip = target.hasAttachments?.() === true;
24231
- options.persist?.(strip ? "skeleton_stripped" : "skeleton_real");
24266
+ const mode = strip ? "skeleton_stripped" : "skeleton_real";
24232
24267
  return {
24233
- result: (strip ? target.skeletonStripped?.() : target.skeletonReal?.()) ?? "absent",
24234
- mode: strip ? "skeleton_stripped" : "skeleton_real"
24268
+ mode,
24269
+ apply: () => ({
24270
+ result: (strip ? target.skeletonStripped?.() : target.skeletonReal?.()) ?? "absent",
24271
+ mode
24272
+ })
24235
24273
  };
24236
24274
  }
24237
- options.persist?.("full");
24238
- const result = target.drop?.() ?? "absent";
24239
- if (result === "truncated" && target.hasAttachments?.() === true) {
24240
- return { result: target.skeletonStripped?.() ?? "absent", mode: "skeleton_stripped" };
24241
- }
24242
- return { result, mode: result === "truncated" ? "skeleton_real" : "full" };
24275
+ return {
24276
+ mode: "full",
24277
+ apply: () => {
24278
+ const result = target.drop?.() ?? "absent";
24279
+ if (result === "truncated" && target.hasAttachments?.() === true) {
24280
+ return {
24281
+ result: target.skeletonStripped?.() ?? "absent",
24282
+ mode: "skeleton_stripped"
24283
+ };
24284
+ }
24285
+ return { result, mode: result === "truncated" ? "skeleton_real" : "full" };
24286
+ }
24287
+ };
24243
24288
  }
24244
24289
  function applyPersistedToolDrop(db, sessionId, tagNumber, target, options, afterWrite) {
24245
24290
  return applyNewToolDrop(target, {
@@ -24328,6 +24373,7 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
24328
24373
  }
24329
24374
  };
24330
24375
  }
24376
+ var PENDING_OPERATION_CHUNK_SIZE = 64;
24331
24377
  function applyPendingOperations(sessionId, db, targets, protectedTagIds, preloadedTags, preloadedPendingOps, syntheticPendingOps = [], editMarkerTagIds = new Set, onTagReduced, onBatchComplete, onEligibilitySnapshot) {
24332
24378
  let didMutateMessage = false;
24333
24379
  let diagnostics;
@@ -24337,153 +24383,184 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
24337
24383
  diagnostics.reasons[reason] = (diagnostics.reasons[reason] ?? 0) + 1;
24338
24384
  };
24339
24385
  let admitted = false;
24340
- try {
24341
- db.transaction(() => {
24342
- admitted = true;
24343
- }).immediate();
24344
- {
24345
- const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
24346
- onEligibilitySnapshot?.(capturePendingDropEligibility(targets, protectedTagIds));
24347
- const tags = preloadedTags ?? getTagsByNumbers2(db, sessionId, [
24348
- ...new Set([
24349
- ...pendingOps.map((op) => op.tagId),
24350
- ...syntheticPendingOps.map((op) => op.tagId)
24351
- ])
24352
- ]);
24353
- const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
24354
- const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
24355
- const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
24356
- const opsToApply = [
24357
- ...pendingOps.map((op) => ({ op, synthetic: false })),
24358
- ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
24359
- ];
24360
- diagnostics = {
24361
- source: pendingOps.length > 0 && syntheticPendingOps.length > 0 ? "mixed" : syntheticPendingOps.length > 0 ? "synthetic" : "pending",
24362
- total: opsToApply.length,
24363
- mutated: 0,
24364
- persistedWithoutMutation: 0,
24365
- reasons: {}
24366
- };
24367
- const skeletonWindow = new Set(preloadedTags ? tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW) : getNewestToolTagNumbers2(db, sessionId, RECENT_TOOL_SKELETON_WINDOW));
24368
- for (const { op: pendingOp, synthetic } of opsToApply) {
24369
- let operationMutated = false;
24370
- const tagStatus = tagStatusById.get(pendingOp.tagId);
24371
- if (tagStatus === "compacted" || tagStatus === "dropped") {
24372
- reject("already_reduced");
24373
- if (!synthetic)
24374
- removePendingOp(db, sessionId, pendingOp.tagId);
24375
- continue;
24376
- }
24377
- const target = targets.get(pendingOp.tagId);
24378
- const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
24379
- if (veto) {
24380
- reject(veto);
24381
- continue;
24382
- }
24383
- const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
24384
- if (synthetic) {
24385
- if (!isToolTag) {
24386
- reject("synthetic_non_tool");
24387
- continue;
24388
- }
24389
- if (target?.canDrop?.() !== true) {
24390
- reject("synthetic_target_not_droppable");
24391
- continue;
24392
- }
24386
+ let startedAt = 0;
24387
+ const mutations = [];
24388
+ let drainChunk;
24389
+ let hasMore = false;
24390
+ do {
24391
+ admitted = false;
24392
+ startedAt = 0;
24393
+ try {
24394
+ db.transaction(() => {
24395
+ admitted = true;
24396
+ startedAt = performance.now();
24397
+ if (drainChunk) {
24398
+ drainChunk();
24399
+ return;
24393
24400
  }
24394
- const persistDrop = (mode) => {
24395
- let startedAt = 0;
24396
- try {
24397
- db.transaction(() => {
24398
- startedAt = performance.now();
24399
- markTagDropped2(db, sessionId, pendingOp.tagId, mode);
24401
+ const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
24402
+ onEligibilitySnapshot?.(capturePendingDropEligibility(targets, protectedTagIds));
24403
+ const tags = preloadedTags ?? getTagsByNumbers2(db, sessionId, [
24404
+ ...new Set([
24405
+ ...pendingOps.map((op) => op.tagId),
24406
+ ...syntheticPendingOps.map((op) => op.tagId)
24407
+ ])
24408
+ ]);
24409
+ const tagById = new Map(tags.map((tag) => [tag.tagNumber, tag]));
24410
+ const tagStatusById = new Map(tags.map((tag) => [tag.tagNumber, tag.status]));
24411
+ const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
24412
+ const opsToApply = [
24413
+ ...pendingOps.map((op) => ({ op, synthetic: false })),
24414
+ ...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
24415
+ ];
24416
+ diagnostics = {
24417
+ source: pendingOps.length > 0 && syntheticPendingOps.length > 0 ? "mixed" : syntheticPendingOps.length > 0 ? "synthetic" : "pending",
24418
+ total: opsToApply.length,
24419
+ mutated: 0,
24420
+ persistedWithoutMutation: 0,
24421
+ reasons: {}
24422
+ };
24423
+ const skeletonWindow = new Set(preloadedTags ? tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW) : getNewestToolTagNumbers2(db, sessionId, RECENT_TOOL_SKELETON_WINDOW));
24424
+ const plannedRemovals = new Set;
24425
+ const removedTagIds = new Set;
24426
+ const record = (mutated) => {
24427
+ if (!diagnostics)
24428
+ return;
24429
+ if (mutated) {
24430
+ didMutateMessage = true;
24431
+ diagnostics.mutated += 1;
24432
+ } else
24433
+ diagnostics.persistedWithoutMutation += 1;
24434
+ };
24435
+ let cursor = 0;
24436
+ drainChunk = () => {
24437
+ const chunk = opsToApply.slice(cursor, cursor + PENDING_OPERATION_CHUNK_SIZE);
24438
+ cursor += chunk.length;
24439
+ hasMore = cursor < opsToApply.length;
24440
+ for (const { op: pendingOp, synthetic } of chunk) {
24441
+ const tagStatus = tagStatusById.get(pendingOp.tagId);
24442
+ if (tagStatus === "compacted" || tagStatus === "dropped") {
24443
+ reject("already_reduced");
24400
24444
  if (!synthetic)
24401
24445
  removePendingOp(db, sessionId, pendingOp.tagId);
24402
- }).immediate();
24403
- } finally {
24404
- if (startedAt)
24405
- logSlowWriteTransaction("apply_pending_operation", startedAt);
24406
- }
24407
- };
24408
- let shouldPersistDrop = false;
24409
- if (isToolTag) {
24410
- if (editMarkerTagIds.has(pendingOp.tagId)) {
24411
- const strip = target?.hasAttachments?.() === true;
24412
- if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
24413
- reject("edit_marker_incomplete");
24414
24446
  continue;
24415
24447
  }
24416
- persistDrop(strip ? "edit_marker_stripped" : "edit_marker");
24417
- const markResult = (strip ? target?.editMarkerStripped?.() : target?.editMarker?.()) ?? "absent";
24418
- if (markResult === "incomplete" || markResult === "absent") {
24419
- reject(`edit_marker_${markResult}`);
24448
+ if (removedTagIds.has(pendingOp.tagId)) {
24449
+ reject("drop_incomplete");
24420
24450
  continue;
24421
24451
  }
24422
- didMutateMessage = true;
24423
- operationMutated = true;
24424
- onTagReduced?.({ tagNumber: pendingOp.tagId, mode: "edit_marker" });
24425
- shouldPersistDrop = true;
24426
- } else {
24427
- const { result: dropResult, mode: appliedMode } = applyNewToolDrop(target, {
24428
- inWindow: skeletonWindow.has(pendingOp.tagId),
24429
- persist: persistDrop
24430
- });
24431
- if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
24432
- reject(`drop_${dropResult}`);
24452
+ const target = targets.get(pendingOp.tagId);
24453
+ const veto = pendingDropVeto(pendingOp.tagId, target, protectedTagIds);
24454
+ if (veto) {
24455
+ reject(veto);
24433
24456
  continue;
24434
24457
  }
24435
- if (dropResult === "removed" || dropResult === "truncated") {
24436
- didMutateMessage = true;
24437
- operationMutated = true;
24438
- onTagReduced?.({
24439
- tagNumber: pendingOp.tagId,
24440
- mode: appliedMode === "full" ? "full" : "truncated"
24458
+ const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
24459
+ if (synthetic) {
24460
+ if (!isToolTag) {
24461
+ reject("synthetic_non_tool");
24462
+ continue;
24463
+ }
24464
+ if (target?.canDrop?.() !== true) {
24465
+ reject("synthetic_target_not_droppable");
24466
+ continue;
24467
+ }
24468
+ }
24469
+ const persistDrop = (mode) => {
24470
+ markTagDropped2(db, sessionId, pendingOp.tagId, mode);
24471
+ if (!synthetic)
24472
+ removePendingOp(db, sessionId, pendingOp.tagId);
24473
+ };
24474
+ if (isToolTag) {
24475
+ if (editMarkerTagIds.has(pendingOp.tagId)) {
24476
+ const strip = target?.hasAttachments?.() === true;
24477
+ if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
24478
+ reject("edit_marker_incomplete");
24479
+ continue;
24480
+ }
24481
+ persistDrop(strip ? "edit_marker_stripped" : "edit_marker");
24482
+ mutations.push(() => {
24483
+ const markResult = (strip ? target?.editMarkerStripped?.() : target?.editMarker?.()) ?? "absent";
24484
+ if (markResult === "incomplete" || markResult === "absent") {
24485
+ reject(`edit_marker_${markResult}`);
24486
+ return;
24487
+ }
24488
+ record(true);
24489
+ onTagReduced?.({
24490
+ tagNumber: pendingOp.tagId,
24491
+ mode: "edit_marker"
24492
+ });
24493
+ });
24494
+ } else {
24495
+ const plan = planNewToolDrop(target, { inWindow: skeletonWindow.has(pendingOp.tagId) }, true, plannedRemovals);
24496
+ if (!plan) {
24497
+ reject("drop_incomplete");
24498
+ continue;
24499
+ }
24500
+ persistDrop(plan.mode);
24501
+ if (plan.mode === "full" && target?.drop) {
24502
+ target.notePlannedRemoval?.(plannedRemovals);
24503
+ removedTagIds.add(pendingOp.tagId);
24504
+ }
24505
+ mutations.push(() => {
24506
+ const { result: dropResult, mode: appliedMode } = plan.apply();
24507
+ if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
24508
+ reject(`drop_${dropResult}`);
24509
+ return;
24510
+ }
24511
+ if (dropResult === "removed" || dropResult === "truncated") {
24512
+ record(true);
24513
+ onTagReduced?.({
24514
+ tagNumber: pendingOp.tagId,
24515
+ mode: appliedMode === "full" ? "full" : "truncated"
24516
+ });
24517
+ } else {
24518
+ reject(`drop_${dropResult}`);
24519
+ record(false);
24520
+ }
24521
+ });
24522
+ }
24523
+ } else if (target) {
24524
+ const replacement = buildReplacementContent(pendingOp.tagId);
24525
+ persistDrop();
24526
+ mutations.push(() => {
24527
+ const priorContent = target.getContent?.();
24528
+ const changed = target.setContent(replacement);
24529
+ record(changed);
24530
+ if (changed) {
24531
+ const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
24532
+ onTagReduced?.({
24533
+ tagNumber: pendingOp.tagId,
24534
+ mode: "partial",
24535
+ removedCharacters: Math.max(0, originalCharacters - replacement.length)
24536
+ });
24537
+ } else {
24538
+ reject("content_unchanged");
24539
+ }
24441
24540
  });
24442
- } else {
24443
- reject(`drop_${dropResult}`);
24541
+ } else if (!synthetic) {
24542
+ reject("target_absent");
24543
+ persistDrop();
24544
+ mutations.push(() => record(false));
24444
24545
  }
24445
- shouldPersistDrop = true;
24446
24546
  }
24447
- } else if (target) {
24448
- const replacement = buildReplacementContent(pendingOp.tagId);
24449
- const priorContent = target.getContent?.();
24450
- persistDrop();
24451
- const changed = target.setContent(replacement);
24452
- if (changed) {
24453
- didMutateMessage = true;
24454
- operationMutated = true;
24455
- const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
24456
- onTagReduced?.({
24457
- tagNumber: pendingOp.tagId,
24458
- mode: "partial",
24459
- removedCharacters: Math.max(0, originalCharacters - replacement.length)
24460
- });
24461
- } else {
24462
- reject("content_unchanged");
24463
- }
24464
- shouldPersistDrop = true;
24465
- } else if (!synthetic) {
24466
- reject("target_absent");
24467
- persistDrop();
24468
- shouldPersistDrop = true;
24469
- }
24470
- if (!shouldPersistDrop) {
24471
- reject("not_persisted");
24472
- continue;
24473
- }
24474
- if (operationMutated)
24475
- diagnostics.mutated += 1;
24476
- else
24477
- diagnostics.persistedWithoutMutation += 1;
24547
+ };
24548
+ drainChunk();
24549
+ }).immediate();
24550
+ } catch (error) {
24551
+ if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
24552
+ sessionLog2(sessionId, "pending operations write admission busy; retaining remaining operations for retry");
24553
+ hasMore = false;
24554
+ } else {
24555
+ throw error;
24478
24556
  }
24557
+ } finally {
24558
+ if (startedAt)
24559
+ logSlowWriteTransaction("apply_pending_operations", startedAt);
24479
24560
  }
24480
- } catch (error) {
24481
- if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
24482
- sessionLog2(sessionId, "pending operations write admission busy; retaining prior bytes for retry");
24483
- return false;
24484
- }
24485
- throw error;
24486
- }
24561
+ for (const mutate of mutations.splice(0))
24562
+ mutate();
24563
+ } while (hasMore);
24487
24564
  if (diagnostics) {
24488
24565
  onBatchComplete?.(diagnostics);
24489
24566
  if (diagnostics.total > 0 && diagnostics.mutated === 0) {
@@ -26625,6 +26702,41 @@ ${typeof state?.output === "string" ? state.output : JSON.stringify(state?.outpu
26625
26702
  };
26626
26703
  }
26627
26704
 
26705
+ // ../plugin/src/hooks/magic-context/transform-stage-logger.ts
26706
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
26707
+ var SLOW_STAGE_MS = 100;
26708
+ var passes = new AsyncLocalStorage2;
26709
+ async function withTransformTimingSummary(run) {
26710
+ const pass = {
26711
+ stages: [],
26712
+ slow: [],
26713
+ closed: false,
26714
+ sessionId: undefined
26715
+ };
26716
+ return passes.run(pass, async () => {
26717
+ try {
26718
+ return await run();
26719
+ } finally {
26720
+ pass.closed = true;
26721
+ if (pass.sessionId)
26722
+ sessionLog2(pass.sessionId, `transform stages: ${pass.stages.join(" ")} slow>=${SLOW_STAGE_MS}ms=[${pass.slow.join(",")}]`);
26723
+ }
26724
+ });
26725
+ }
26726
+ function logTransformElapsed(sessionId, stage, elapsedMs, extra) {
26727
+ const elapsed = elapsedMs.toFixed(1);
26728
+ const suffix = extra ? ` ${extra}` : "";
26729
+ const pass = passes.getStore();
26730
+ if (pass && !pass.closed) {
26731
+ pass.sessionId = sessionId;
26732
+ pass.stages.push(`${stage}=${elapsed}ms${extra ? `(${extra})` : ""}`);
26733
+ if (elapsedMs >= SLOW_STAGE_MS)
26734
+ pass.slow.push(stage);
26735
+ }
26736
+ if (elapsedMs >= SLOW_STAGE_MS)
26737
+ sessionLog2(sessionId, `transform stage: stage=${stage} elapsed=${elapsed}ms${suffix}`);
26738
+ }
26739
+
26628
26740
  // ../plugin/src/shared/recovery-reasoning-prefix.ts
26629
26741
  function recoveryReasoningPrefixes(messages, partsKey) {
26630
26742
  const prefixes = [];
@@ -27070,12 +27182,12 @@ class ConversationEndGuard {
27070
27182
  this.end = message;
27071
27183
  }
27072
27184
  }
27073
- wouldStrand(occurrences) {
27185
+ wouldStrand(occurrences, plannedRemovals) {
27074
27186
  const end = this.end;
27075
27187
  if (!end || !occurrences.some((occ) => occ.message === end))
27076
27188
  return false;
27077
27189
  const leaving = new Set(occurrences.map((occ) => partKey(occ.part)));
27078
- const survives = (part) => !leaving.has(partKey(part)) && !this.removed.has(partKey(part));
27190
+ const survives = (part) => !leaving.has(partKey(part)) && !this.removed.has(partKey(part)) && !plannedRemovals?.has(partKey(part));
27079
27191
  return end.info.role === "assistant" ? !end.parts.some((part) => part.kind === "tool_result" && survives(part)) : !end.parts.some((part) => partHasContent(part) && survives(part));
27080
27192
  }
27081
27193
  noteRemoved(occurrences) {
@@ -27402,8 +27514,12 @@ function buildAggregateTarget(tagId, occurrences, requiresToolArcSkeleton, conve
27402
27514
  }
27403
27515
  return null;
27404
27516
  },
27405
- wouldStrandConversationEnd() {
27406
- return conversationEnd?.wouldStrand(occurrences) ?? false;
27517
+ wouldStrandConversationEnd(plannedRemovals) {
27518
+ return conversationEnd?.wouldStrand(occurrences, plannedRemovals) ?? false;
27519
+ },
27520
+ notePlannedRemoval(plannedRemovals) {
27521
+ for (const occ of occurrences)
27522
+ plannedRemovals.add(partKey(occ.part));
27407
27523
  },
27408
27524
  editMarker() {
27409
27525
  const sentinel = `[dropped §${tagId}§]`;
@@ -27491,7 +27607,8 @@ function buildToolTarget(part, message, tagId) {
27491
27607
  }
27492
27608
 
27493
27609
  // ../plugin/src/hooks/magic-context/auto-search-deadline.ts
27494
- var AUTO_SEARCH_TIMEOUT_MS = 3000;
27610
+ var AUTO_SEARCH_TIMEOUT_MS = 1000;
27611
+ var AUTO_SEARCH_VECTOR_TIMEOUT_MS = 200;
27495
27612
  var operationDeadlines = new WeakMap;
27496
27613
  function autoSearchDeadlineUnixMs(signal) {
27497
27614
  const deadline = signal && operationDeadlines.get(signal);
@@ -27604,32 +27721,32 @@ function formatAge(committedAtMs) {
27604
27721
  const years = Math.floor(days / 365);
27605
27722
  return years === 1 ? "1y ago" : `${years}y ago`;
27606
27723
  }
27607
- function renderFragment(result, charCap, wordRules) {
27724
+ function renderFragment(result, charCap, wordRules, query) {
27608
27725
  switch (result.source) {
27609
27726
  case "memory": {
27610
- const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27727
+ const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27611
27728
  return truncate2(compressed, charCap);
27612
27729
  }
27613
27730
  case "git_commit": {
27614
- const subject = result.content.split(/\r?\n/)[0] ?? result.content;
27731
+ const subject = cleanSearchText(result.content.split(/\r?\n/)[0] ?? result.content);
27615
27732
  const body = truncate2(subject, Math.max(10, charCap - 20));
27616
27733
  return `commit ${result.shortSha} ${formatAge(result.committedAtMs)}: ${body}`;
27617
27734
  }
27618
27735
  case "message": {
27619
- const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27736
+ const compressed = cavemanCompress(query ? matchedSearchSnippet(result.content, query, charCap) : cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27620
27737
  return truncate2(compressed, charCap);
27621
27738
  }
27622
27739
  case "compartment": {
27623
- const source = result.snippet ?? result.title;
27740
+ const source = cleanSearchText(result.title);
27624
27741
  const compressed = cavemanCompress(source, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27625
27742
  return truncate2(compressed, charCap);
27626
27743
  }
27627
27744
  case "primer": {
27628
- const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27745
+ const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27629
27746
  return truncate2(compressed, charCap);
27630
27747
  }
27631
27748
  case "note": {
27632
- const compressed = cavemanCompress(result.content, "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27749
+ const compressed = cavemanCompress(cleanSearchText(result.content), "ultra", CURRENT_CAVEMAN_RULES, wordRules);
27633
27750
  return truncate2(compressed, charCap);
27634
27751
  }
27635
27752
  }
@@ -27640,7 +27757,7 @@ function buildAutoSearchHint(results, options = {}) {
27640
27757
  const picks = results.slice(0, maxFragments);
27641
27758
  const lines = [];
27642
27759
  for (const result of picks) {
27643
- const fragment = renderFragment(result, fragmentCharCap, options.wordRules ?? "english");
27760
+ const fragment = renderFragment(result, fragmentCharCap, options.wordRules ?? "english", options.query ?? "");
27644
27761
  if (fragment.length === 0)
27645
27762
  continue;
27646
27763
  lines.push(`- ${fragment}`);
@@ -27663,6 +27780,9 @@ ${trimmedBody}…
27663
27780
  }
27664
27781
  return wrapped;
27665
27782
  }
27783
+ function selectAutoSearchResults(results, threshold) {
27784
+ return results.filter((result) => (result.relevanceScore ?? result.score) >= threshold);
27785
+ }
27666
27786
 
27667
27787
  // ../plugin/src/hooks/magic-context/auto-search-worker-client.ts
27668
27788
  import { Worker } from "node:worker_threads";
@@ -27758,6 +27878,63 @@ async function searchAutoHint(db, sessionId, projectPath, query, options, entry
27758
27878
  return executeAutoSearchWorker(db, sessionId, projectPath, query, options, entry, "search");
27759
27879
  }
27760
27880
  var pendingBackfills = new WeakMap;
27881
+ var searchWorkers = new WeakMap;
27882
+ var liveSearchWorkers = new Set;
27883
+ var MAX_IDLE_SEARCH_WORKERS = 4;
27884
+ var SEARCH_WORKER_IDLE_MS = 5 * 60000;
27885
+ var workersCreated = 0;
27886
+ var workersReused = 0;
27887
+ async function acquireSearchWorker(db, key, entry, input, signal) {
27888
+ const pool = searchWorkers.get(db) ?? new Map;
27889
+ searchWorkers.set(db, pool);
27890
+ while (!signal.aborted) {
27891
+ let slot = pool.get(key);
27892
+ if (slot?.busy) {
27893
+ const current = slot;
27894
+ await new Promise((resolve) => {
27895
+ const done = () => {
27896
+ signal.removeEventListener("abort", done);
27897
+ resolve();
27898
+ };
27899
+ signal.addEventListener("abort", done, { once: true });
27900
+ current.busy?.then(done);
27901
+ if (signal.aborted)
27902
+ done();
27903
+ });
27904
+ continue;
27905
+ }
27906
+ const fresh = !slot;
27907
+ if (!slot) {
27908
+ const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { ...input, persistent: true } }));
27909
+ slot = {
27910
+ worker,
27911
+ dispose() {
27912
+ clearTimeout(this.idleTimer);
27913
+ if (pool.get(key) === this)
27914
+ pool.delete(key);
27915
+ liveSearchWorkers.delete(this);
27916
+ worker.terminate();
27917
+ worker.unref();
27918
+ }
27919
+ };
27920
+ workersCreated++;
27921
+ pool.set(key, slot);
27922
+ liveSearchWorkers.add(slot);
27923
+ const current = slot;
27924
+ worker.on("error", () => current.dispose());
27925
+ worker.on("exit", () => current.dispose());
27926
+ } else
27927
+ workersReused++;
27928
+ clearTimeout(slot.idleTimer);
27929
+ const current = slot;
27930
+ current.busy = new Promise((resolve) => {
27931
+ current.release = resolve;
27932
+ });
27933
+ current.worker.ref();
27934
+ return { slot: current, fresh };
27935
+ }
27936
+ return null;
27937
+ }
27761
27938
  function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
27762
27939
  if (isEmbeddingHostBusy2())
27763
27940
  return Promise.resolve();
@@ -27822,6 +27999,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27822
27999
  query,
27823
28000
  options: {
27824
28001
  ...serializable,
28002
+ autoHint: true,
27825
28003
  backfillMemoryEmbeddings: false,
27826
28004
  countRetrievals: false,
27827
28005
  measurementDisabled: true
@@ -27831,8 +28009,20 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27831
28009
  snapshot,
27832
28010
  deadlineUnixMs: autoSearchDeadlineUnixMs(deadlineSignal)
27833
28011
  };
28012
+ let lease;
28013
+ try {
28014
+ lease = await acquireSearchWorker(db, `${input.harness}\x00${projectPath}\x00${job}\x00${entry.href}`, entry, input, signal);
28015
+ } catch (error) {
28016
+ lifecycle.done();
28017
+ throw error;
28018
+ }
28019
+ if (!lease) {
28020
+ lifecycle.done();
28021
+ return [];
28022
+ }
28023
+ const { slot, fresh } = lease;
28024
+ const worker = slot.worker;
27834
28025
  return new Promise((resolve, reject) => {
27835
- const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: input }));
27836
28026
  let settled = false;
27837
28027
  const finish = (results, error) => {
27838
28028
  if (settled)
@@ -27841,7 +28031,25 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27841
28031
  signal?.removeEventListener("abort", abort);
27842
28032
  lifecycle.signal.removeEventListener("abort", abort);
27843
28033
  lifecycle.done();
27844
- worker.terminate();
28034
+ worker.off("message", onMessage);
28035
+ worker.off("error", onError);
28036
+ worker.off("exit", onExit);
28037
+ if (error || signal.aborted || entry.href !== defaultAutoSearchWorkerEntry().href)
28038
+ slot.dispose();
28039
+ else {
28040
+ slot.idleTimer = setTimeout(() => slot.dispose(), SEARCH_WORKER_IDLE_MS);
28041
+ slot.idleTimer.unref?.();
28042
+ }
28043
+ const release = slot.release;
28044
+ slot.busy = undefined;
28045
+ slot.release = undefined;
28046
+ release?.();
28047
+ const reusable = liveSearchWorkers.delete(slot);
28048
+ if (reusable)
28049
+ liveSearchWorkers.add(slot);
28050
+ const idle = [...liveSearchWorkers].filter((candidate) => !candidate.busy);
28051
+ for (const prior of idle.slice(0, Math.max(0, idle.length - MAX_IDLE_SEARCH_WORKERS)))
28052
+ prior.dispose();
27845
28053
  worker.unref();
27846
28054
  if (error)
27847
28055
  reject(error);
@@ -27851,9 +28059,9 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27851
28059
  const abort = () => finish([]);
27852
28060
  signal?.addEventListener("abort", abort, { once: true });
27853
28061
  lifecycle.signal.addEventListener("abort", abort, { once: true });
27854
- worker.on("error", (error) => finish([], error));
27855
- worker.on("exit", (code) => finish([], new Error(`auto-search worker exited (${code})`)));
27856
- worker.on("message", async (reply) => {
28062
+ const onError = (error) => finish([], error);
28063
+ const onExit = (code) => finish([], new Error(`auto-search worker exited (${code})`));
28064
+ const onMessage = async (reply) => {
27857
28065
  if (settled)
27858
28066
  return;
27859
28067
  if (reply.kind === "result") {
@@ -27872,7 +28080,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27872
28080
  const response = { id: reply.id };
27873
28081
  try {
27874
28082
  if (reply.kind === "query")
27875
- response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : embedQuery?.(reply.text, signal)) ?? null;
28083
+ response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
27876
28084
  else {
27877
28085
  const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
27878
28086
  const current = getProjectEmbeddingSnapshot2(projectPath);
@@ -27887,13 +28095,49 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
27887
28095
  response.error = error instanceof Error ? error.message : String(error);
27888
28096
  }
27889
28097
  response.embeddingHostBusy = isEmbeddingHostBusy2();
27890
- if (!settled && !signal?.aborted)
27891
- worker.postMessage(response);
27892
- });
28098
+ if (!settled && !signal?.aborted) {
28099
+ try {
28100
+ worker.postMessage(response);
28101
+ } catch (error) {
28102
+ finish([], error instanceof Error ? error : new Error(String(error)));
28103
+ }
28104
+ }
28105
+ };
28106
+ worker.on("error", onError);
28107
+ worker.on("exit", onExit);
28108
+ worker.on("message", onMessage);
27893
28109
  if (signal?.aborted)
27894
28110
  abort();
28111
+ else if (!fresh) {
28112
+ try {
28113
+ worker.postMessage({ kind: "run", input });
28114
+ } catch (error) {
28115
+ finish([], error instanceof Error ? error : new Error(String(error)));
28116
+ }
28117
+ }
27895
28118
  });
27896
28119
  }
28120
+ async function boundedHintEmbedding(embed, text, signal) {
28121
+ const controller = new AbortController;
28122
+ const combined = AbortSignal.any([signal, controller.signal]);
28123
+ let timer;
28124
+ try {
28125
+ return await Promise.race([
28126
+ Promise.resolve().then(() => embed?.(text, combined) ?? null),
28127
+ new Promise((resolve) => {
28128
+ timer = setTimeout(() => {
28129
+ resolve(null);
28130
+ controller.abort();
28131
+ }, AUTO_SEARCH_VECTOR_TIMEOUT_MS);
28132
+ })
28133
+ ]);
28134
+ } finally {
28135
+ clearTimeout(timer);
28136
+ }
28137
+ }
28138
+ function defaultAutoSearchWorkerEntry() {
28139
+ return new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./auto-search-worker.ts" : "./auto-search-worker.js", import.meta.url);
28140
+ }
27897
28141
  var messageSearchWorkerFallbacks = new Map;
27898
28142
 
27899
28143
  // src/auto-search-pi.ts
@@ -28083,6 +28327,8 @@ async function runAutoSearchHintForPi(args) {
28083
28327
  const gitCommitsEnabled = snapshot?.gitCommitEnabled ?? false;
28084
28328
  const searchOptions = {
28085
28329
  limit: 10,
28330
+ maxMessageOrdinal: Math.max(0, getLastCompartmentEndMessage(db, sessionId)),
28331
+ excludeMessageId: userMsgId,
28086
28332
  memoryEnabled,
28087
28333
  embeddingEnabled,
28088
28334
  gitCommitsEnabled,
@@ -28124,13 +28370,15 @@ async function runAutoSearchHintForPi(args) {
28124
28370
  return messages;
28125
28371
  }
28126
28372
  const scoreThreshold = options.scoreThreshold ?? DEFAULT_SCORE_THRESHOLD;
28127
- if (results[0].score < scoreThreshold) {
28128
- sessionLog2(sessionId, `auto-search: top score ${results[0].score.toFixed(3)} below threshold ${scoreThreshold}`);
28373
+ results = selectAutoSearchResults(results, scoreThreshold);
28374
+ if (results.length === 0) {
28375
+ sessionLog2(sessionId, `auto-search: no fragment meets relevance threshold ${scoreThreshold}`);
28129
28376
  await writeNoHintAndReconcile("below-threshold");
28130
28377
  return messages;
28131
28378
  }
28132
28379
  const hintText = buildAutoSearchHint(results, {
28133
- wordRules: options.wordRules
28380
+ wordRules: options.wordRules,
28381
+ query: rawPrompt
28134
28382
  });
28135
28383
  if (!hintText) {
28136
28384
  await writeNoHintAndReconcile("empty");
@@ -28563,6 +28811,7 @@ async function runHistorianSubagentWithTransientRetriesGuarded(args) {
28563
28811
  args.onDispatch?.();
28564
28812
  result = await args.runner.run({
28565
28813
  ...args.options,
28814
+ cacheTail: retryIndex > 0 ? "write" : args.options.cacheTail ?? "skip",
28566
28815
  fallbackModels: undefined
28567
28816
  });
28568
28817
  } catch (error) {
@@ -34029,6 +34278,54 @@ function isSentinelPart(part) {
34029
34278
  return p.type === "text" && typeof p.text === "string" && (p.text === "" || p.text === WHOLE_MESSAGE_PLACEHOLDER_TEXT);
34030
34279
  }
34031
34280
 
34281
+ // src/pi-append-compaction.ts
34282
+ var loggedIncompatibleHost = false;
34283
+ var failedWrites = new WeakMap;
34284
+ function adaptPiAppendCompaction(sessionManager) {
34285
+ if (!sessionManager || typeof sessionManager !== "object")
34286
+ return;
34287
+ const host = sessionManager;
34288
+ const append = host.appendCompaction;
34289
+ if (typeof append !== "function")
34290
+ return;
34291
+ if (failedWrites.has(host))
34292
+ return;
34293
+ const harness = resolvePiHarnessKind();
34294
+ if ((harness === "omp" ? append.length !== 4 && append.length !== 7 : append.length !== 5 && append.length !== 6) || typeof host.getEntry !== "function") {
34295
+ if (!loggedIncompatibleHost) {
34296
+ loggedIncompatibleHost = true;
34297
+ log2(`ERROR: compaction marker disabled: incompatible host binding harness=${harness} arity=${append.length} getEntry=${typeof host.getEntry}; leaving marker pending`);
34298
+ }
34299
+ return;
34300
+ }
34301
+ const getEntry = host.getEntry.bind(host);
34302
+ return (summary, firstKeptEntryId, tokensBefore, details, fromHook) => {
34303
+ const previousFailure = failedWrites.get(host);
34304
+ if (previousFailure)
34305
+ throw previousFailure;
34306
+ let id;
34307
+ if (harness === "pi") {
34308
+ id = append.call(host, summary, firstKeptEntryId, tokensBefore, details, fromHook);
34309
+ } else if (append.length === 7) {
34310
+ id = append.call(host, summary, undefined, firstKeptEntryId, tokensBefore, details, fromHook);
34311
+ } else {
34312
+ id = append.call(host, summary, undefined, firstKeptEntryId, tokensBefore, { details, fromExtension: fromHook });
34313
+ }
34314
+ try {
34315
+ const entry = typeof id === "string" && id.length > 0 ? getEntry(id) : undefined;
34316
+ if (entry?.type !== "compaction" || entry.firstKeptEntryId !== firstKeptEntryId || entry.details?.source !== "magic-context") {
34317
+ throw new Error("Compaction marker read-back mismatch");
34318
+ }
34319
+ } catch {
34320
+ const error = new Error("Compaction marker read-back failed; writes disabled for this session manager until restart");
34321
+ failedWrites.set(host, error);
34322
+ log2(`ERROR: compaction marker read-back failed harness=${harness} compactionId=${typeof id === "string" ? id : "<missing>"} expectedFirstKept=${firstKeptEntryId}; further writes disabled for this session manager until restart; leaving marker pending`);
34323
+ throw error;
34324
+ }
34325
+ return id;
34326
+ };
34327
+ }
34328
+
34032
34329
  // src/pi-context-budget.ts
34033
34330
  var PI_CONTEXT_BUDGET = {
34034
34331
  hostDeadlineMs: 30000,
@@ -41294,13 +41591,12 @@ function buildPiTextIdentityPlan(db, sessionId, tagger, transcript, reuseCandida
41294
41591
  }
41295
41592
  var piBranchProjectionBySession = new Map;
41296
41593
  var piBranchLookupByProjection = new WeakMap;
41297
- function logTransformElapsed(sessionId, stage, elapsedMs, extra) {
41298
- const suffix = extra ? ` ${extra}` : "";
41594
+ function logTransformElapsed2(sessionId, stage, elapsedMs, extra) {
41299
41595
  recordPiTransformTiming({ sessionId, stage, elapsedMs, extra });
41300
- sessionLog2(sessionId, `transform stage: stage=${stage} elapsed=${elapsedMs.toFixed(1)}ms${suffix}`);
41596
+ logTransformElapsed(sessionId, stage, elapsedMs, extra);
41301
41597
  }
41302
41598
  function logTransformTiming(sessionId, stage, start, extra) {
41303
- logTransformElapsed(sessionId, stage, performance.now() - start, extra);
41599
+ logTransformElapsed2(sessionId, stage, performance.now() - start, extra);
41304
41600
  }
41305
41601
  function piVariantChangeBustsProviderCache(providerID, modelID) {
41306
41602
  return variantChangeBustsProviderCache(providerID, modelID);
@@ -41939,7 +42235,7 @@ function stripMcOwnedPiCompactionSummary(messages, entryIds, branchEntries) {
41939
42235
  break;
41940
42236
  }
41941
42237
  }
41942
- if (compaction?.fromHook !== true)
42238
+ if (compaction?.fromHook !== true && compaction?.fromExtension !== true)
41943
42239
  return false;
41944
42240
  const details = compaction.details;
41945
42241
  if (details?.source !== "magic-context")
@@ -42727,7 +43023,7 @@ function loadPiHistorianStateSnapshot(db, sessionId) {
42727
43023
  }
42728
43024
  function registerPiContextHandler(pi, baseOptions) {
42729
43025
  const tagger = createTagger();
42730
- const lkgCoordinator = createPiLkgCoordinator(baseOptions.db, undefined, ({ sessionId, elapsedMs, reusedPrefix }) => logTransformElapsed(sessionId, "lkgCapture", elapsedMs, `reusedPrefix=${reusedPrefix}`));
43026
+ const lkgCoordinator = createPiLkgCoordinator(baseOptions.db, undefined, ({ sessionId, elapsedMs, reusedPrefix }) => logTransformElapsed2(sessionId, "lkgCapture", elapsedMs, `reusedPrefix=${reusedPrefix}`));
42731
43027
  const schedulerCache = new WeakMap;
42732
43028
  const DEFAULT_SCHEDULER_CONFIG = {
42733
43029
  executeThresholdPercentage: 65
@@ -42764,7 +43060,7 @@ function registerPiContextHandler(pi, baseOptions) {
42764
43060
  variantChangeLogObserverForTests?.(message);
42765
43061
  sessionLog2(sessionId, message);
42766
43062
  });
42767
- const contextHandler = async (event, ctx, budget) => {
43063
+ const runHandler = async (event, ctx, budget) => {
42768
43064
  budget.assertOutcome();
42769
43065
  const passSessionId = ctx.sessionManager ? resolveSessionId2(ctx) : undefined;
42770
43066
  const generation = Symbol();
@@ -44148,6 +44444,7 @@ function registerPiContextHandler(pi, baseOptions) {
44148
44444
  return;
44149
44445
  }
44150
44446
  };
44447
+ const contextHandler = (...args) => withTransformTimingSummary(async () => await runHandler(...args) ?? undefined);
44151
44448
  registerPiGuardedContext(pi, contextHandler, {
44152
44449
  compactionOff: (ctx) => (baseOptions.resolveForProject?.(ctx.cwd) ?? baseOptions).compactionOff === true,
44153
44450
  onRefusal: (ctx, budget, message, isCurrent) => {
@@ -44400,10 +44697,7 @@ function spawnPiHistorianRun(args) {
44400
44697
  historian.onStatusChange?.(ctx, sessionId);
44401
44698
  }
44402
44699
  function resolvePiAppendCompaction(ctx) {
44403
- const sm = ctx.sessionManager;
44404
- if (typeof sm?.appendCompaction !== "function")
44405
- return;
44406
- return sm.appendCompaction.bind(sm);
44700
+ return adaptPiAppendCompaction(ctx.sessionManager);
44407
44701
  }
44408
44702
  function guardedPiAppendCompaction(ctx, assertCurrentPass) {
44409
44703
  const append = resolvePiAppendCompaction(ctx);
@@ -46452,10 +46746,12 @@ function createPiHistorianClient(args) {
46452
46746
  }
46453
46747
  const promptText = extractPromptText(body.parts);
46454
46748
  const modelOverride = readBodyModel(body);
46749
+ const cacheTail = input && typeof input === "object" && "cacheTail" in input ? input.cacheTail : undefined;
46455
46750
  const result = await args.runner.run({
46456
46751
  agent: "magic-context-historian",
46457
46752
  systemPrompt: args.systemPrompt,
46458
46753
  userMessage: promptText,
46754
+ ...cacheTail === "write" || cacheTail === "skip" ? { cacheTail } : {},
46459
46755
  model: modelOverride?.model ?? args.model,
46460
46756
  fallbackModels: modelOverride ? undefined : args.fallbackModels,
46461
46757
  timeoutMs: args.timeoutMs,
@@ -49804,9 +50100,9 @@ var PI_STARTUP_MAINTENANCE_SCHEDULED = Symbol.for("magic-context.pi.startup-main
49804
50100
  function getPiChildInitContext() {
49805
50101
  const globals = globalThis;
49806
50102
  const existing = globals[PI_CHILD_INIT_CONTEXT];
49807
- if (existing instanceof AsyncLocalStorage2)
50103
+ if (existing instanceof AsyncLocalStorage3)
49808
50104
  return existing;
49809
- const context = new AsyncLocalStorage2;
50105
+ const context = new AsyncLocalStorage3;
49810
50106
  globals[PI_CHILD_INIT_CONTEXT] = context;
49811
50107
  return context;
49812
50108
  }