@cortexkit/opencode-magic-context 0.49.30 → 0.49.32

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 (79) hide show
  1. package/dist/auto-search-worker.js +4 -4
  2. package/dist/chunk-embedding-write-worker.js +1 -1
  3. package/dist/{compartment-chunk-embedding-qgp0tbf7.js → compartment-chunk-embedding-5q5gj67r.js} +1 -1
  4. package/dist/{context-vnfr6d7t.js → context-n27jdyyh.js} +150 -19
  5. package/dist/{embedding-backfill-mms9nb0h.js → embedding-backfill-0jgtqxen.js} +3 -3
  6. package/dist/features/magic-context/chunk-scope-repair-revision.d.ts +4 -0
  7. package/dist/features/magic-context/chunk-scope-repair-revision.d.ts.map +1 -0
  8. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  9. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +3 -3
  10. package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
  11. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  12. package/dist/features/magic-context/dreamer/task-gates.d.ts +2 -0
  13. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  14. package/dist/features/magic-context/dreamer/verify.d.ts +13 -17
  15. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  16. package/dist/features/magic-context/message-index-async.d.ts +3 -0
  17. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  18. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  19. package/dist/features/magic-context/search.d.ts.map +1 -1
  20. package/dist/features/magic-context/storage-native-replay.d.ts +2 -0
  21. package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/apply-operations.d.ts +11 -1
  23. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/auto-search-branch-index.fixture.d.ts +2 -0
  25. package/dist/hooks/magic-context/auto-search-branch-index.fixture.d.ts.map +1 -0
  26. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  29. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +2 -0
  31. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/transform.d.ts +11 -0
  33. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  34. package/dist/{index-gxkhzmjq.js → index-2743x98y.js} +65 -2
  35. package/dist/{index-adr4vfys.js → index-2agkcr3y.js} +2 -2
  36. package/dist/{index-ekzzw66a.js → index-3drcgsnf.js} +74 -385
  37. package/dist/index-94ef0qe2.js +429 -0
  38. package/dist/{index-pe6b4bhs.js → index-as2amvn3.js} +1 -1
  39. package/dist/{index-k0dpkyn7.js → index-bzwh06cp.js} +4 -3
  40. package/dist/{index-vzz570j8.js → index-g0kqnc6y.js} +13 -4
  41. package/dist/{index-vtz789ex.js → index-qr2mb02j.js} +16 -5
  42. package/dist/{index-vnn5405n.js → index-rfxzazzy.js} +1 -1
  43. package/dist/{index-69gd2scx.js → index-t6b3px80.js} +2 -2
  44. package/dist/{index-mm93m7y6.js → index-v7287tzq.js} +47 -7
  45. package/dist/index.js +16 -14
  46. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  47. package/dist/{project-embedding-registry-cg281d9j.js → project-embedding-registry-6yex0r9f.js} +2 -2
  48. package/dist/{recomp-orchestrator-w3pjp33d.js → recomp-orchestrator-6ncc6wrw.js} +6 -6
  49. package/dist/{search-fbaz1m8r.js → search-040pac3a.js} +6 -5
  50. package/dist/shared/tag-transcript.d.ts +4 -1
  51. package/dist/shared/tag-transcript.d.ts.map +1 -1
  52. package/dist/shared/transcript.d.ts +3 -1
  53. package/dist/shared/transcript.d.ts.map +1 -1
  54. package/dist/{transform-postprocess-phase-6ccazq85.js → transform-postprocess-phase-wvt1k03d.js} +7 -6
  55. package/dist/v2/auto-search-worker.js +4 -4
  56. package/dist/v2/chunk-embedding-write-worker.js +1 -1
  57. package/dist/v2/{compartment-chunk-embedding-63dzs31c.js → compartment-chunk-embedding-rc31e6md.js} +1 -1
  58. package/dist/v2/{context-wx4sfhgr.js → context-ehews84p.js} +229 -286
  59. package/dist/v2/{embedding-backfill-35k6czrr.js → embedding-backfill-f43hd8y6.js} +3 -3
  60. package/dist/v2/fold/owner.d.ts +4 -0
  61. package/dist/v2/fold/owner.d.ts.map +1 -1
  62. package/dist/v2/hooks/context.d.ts.map +1 -1
  63. package/dist/v2/hooks/types.d.ts +3 -0
  64. package/dist/v2/hooks/types.d.ts.map +1 -1
  65. package/dist/v2/{project-embedding-registry-p1p10ks7.js → project-embedding-registry-1x5qe2fy.js} +2 -2
  66. package/dist/v2/{recomp-orchestrator-wb28kr9k.js → recomp-orchestrator-3r9kcs61.js} +5 -5
  67. package/dist/v2/{search-q3jjw6zp.js → search-q3wkpe8t.js} +5 -5
  68. package/dist/v2/{server-p0snacz3.js → server-2aasmpsp.js} +1 -1
  69. package/dist/v2/{server-k33t88h3.js → server-4n176b5m.js} +4 -3
  70. package/dist/v2/{server-zh3esb0z.js → server-ab8017gw.js} +65 -2
  71. package/dist/v2/{server-4sn3at8p.js → server-h1byrhwx.js} +47 -7
  72. package/dist/v2/{server-42nebt63.js → server-n14edf07.js} +336 -25
  73. package/dist/v2/{server-ph300d6m.js → server-tkdabx8q.js} +1 -1
  74. package/dist/v2/server.js +2 -2
  75. package/dist/v2/{wrapup-orchestrator-2t0pdqzm.js → wrapup-orchestrator-ddmvbkra.js} +5 -5
  76. package/dist/{wrapup-orchestrator-kjmkms5g.js → wrapup-orchestrator-fyvyzcbm.js} +7 -7
  77. package/package.json +1 -1
  78. package/src/shared/tag-transcript.ts +34 -5
  79. package/src/shared/transcript.ts +1 -1
@@ -0,0 +1,429 @@
1
+ import {
2
+ getHarness2
3
+ } from "./index-pavzsdc6.js";
4
+ import {
5
+ log2,
6
+ sessionLog2
7
+ } from "./index-h7tgn49j.js";
8
+ import {
9
+ inRootAsyncContext2,
10
+ getSqliteDatabasePath2,
11
+ withSqliteBackgroundWriter2,
12
+ indexCoordinationInput2
13
+ } from "./index-gzy5w8ya.js";
14
+ import {
15
+ runSessionWarmupWorker
16
+ } from "./index-rverk2vz.js";
17
+ import {
18
+ scheduleAfterBootQuiet
19
+ } from "./index-kq5w68dp.js";
20
+ import {
21
+ getMessageIndexSourceIdentity,
22
+ isMessageIndexSourceCurrent,
23
+ getLastIndexedOrdinal,
24
+ getMessageIndexReconciliationStartOrdinal,
25
+ isMessageIndexReconciledThrough,
26
+ clearIndexedMessages,
27
+ indexSingleMessage,
28
+ indexMessagesAfterOrdinal
29
+ } from "./index-4s4zq97n.js";
30
+
31
+ // src/features/magic-context/message-index-async.ts
32
+ var indexCancellations = new Map;
33
+ var sessionEpochs = new Map;
34
+ var rebuildingSessions = new Set;
35
+ function getMessageIndexEpoch(sessionId) {
36
+ return sessionEpochs.get(sessionId) ?? 0;
37
+ }
38
+ function isMessageIndexSearchable(sessionId) {
39
+ return !rebuildingSessions.has(sessionId);
40
+ }
41
+ var workerMeasurements = new WeakMap;
42
+ function isDatabaseLockedError(error) {
43
+ if (!error || typeof error !== "object")
44
+ return false;
45
+ const e = error;
46
+ if (typeof e.code === "string") {
47
+ if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
48
+ return true;
49
+ }
50
+ if (typeof e.message === "string") {
51
+ if (/database is locked/i.test(e.message))
52
+ return true;
53
+ if (/sqlite_(busy|locked)/i.test(e.message))
54
+ return true;
55
+ }
56
+ return false;
57
+ }
58
+ var INCREMENTAL_DEBOUNCE_MS = 100;
59
+ var RECONCILIATION_BATCH_SIZE = 100;
60
+
61
+ class MagicContextMessageIndexHeapHolder {
62
+ reconciledSessions = new Set;
63
+ reconciledSnapshots = new Map;
64
+ stalledSessions = new Set;
65
+ reconciliationScheduledSessions = new Set;
66
+ clearAndReindexScheduledSessions = new Map;
67
+ sessionLocks = new Map;
68
+ incrementalTimers = new Map;
69
+ pendingIncrementalKeys = new Set;
70
+ completedIncrementalKeys = new Set;
71
+ activeReconcilerBuffers = new Map;
72
+ }
73
+ var heapHolder = new MagicContextMessageIndexHeapHolder;
74
+ function clearCompletedIncrementalKeys(sessionId) {
75
+ const prefix = `${sessionId}\x00`;
76
+ for (const key of heapHolder.completedIncrementalKeys) {
77
+ if (key.startsWith(prefix))
78
+ heapHolder.completedIncrementalKeys.delete(key);
79
+ }
80
+ }
81
+ var PREPARE_RETRY_MS = 60000;
82
+ async function sourceReady(source, sessionId) {
83
+ const prepare = source?.prepare;
84
+ return typeof prepare === "function" ? prepare(sessionId) : true;
85
+ }
86
+ function defer(fn) {
87
+ const immediate = globalThis.setImmediate;
88
+ if (typeof immediate === "function") {
89
+ inRootAsyncContext2(() => immediate(fn));
90
+ return;
91
+ }
92
+ inRootAsyncContext2(() => setTimeout(fn, 0));
93
+ }
94
+ function yieldToEventLoop() {
95
+ return new Promise((resolve) => defer(resolve));
96
+ }
97
+ function runWithSessionLock(sessionId, operation) {
98
+ const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
99
+ const run = previous.catch(() => {
100
+ return;
101
+ }).then(async () => {
102
+ await operation();
103
+ });
104
+ heapHolder.sessionLocks.set(sessionId, run);
105
+ run.finally(() => {
106
+ if (heapHolder.sessionLocks.get(sessionId) === run) {
107
+ heapHolder.sessionLocks.delete(sessionId);
108
+ }
109
+ }).catch(() => {
110
+ return;
111
+ });
112
+ return run;
113
+ }
114
+ function logIndexingError(sessionId, action, error) {
115
+ if (isDatabaseLockedError(error)) {
116
+ sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
117
+ return;
118
+ }
119
+ sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
120
+ log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
121
+ }
122
+ function serializedMessageBytes(messages) {
123
+ try {
124
+ return Buffer.byteLength(JSON.stringify(messages));
125
+ } catch {
126
+ return 0;
127
+ }
128
+ }
129
+ function logReconciliationStall(sessionId, reason) {
130
+ if (heapHolder.stalledSessions.has(sessionId))
131
+ return;
132
+ heapHolder.stalledSessions.add(sessionId);
133
+ sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
134
+ }
135
+ async function reconcileSessionIndex(db, sessionId, readMessages, epoch = getMessageIndexEpoch(sessionId)) {
136
+ if (!await sourceReady(readMessages, sessionId)) {
137
+ logReconciliationStall(sessionId, "raw message reader is not ready");
138
+ return false;
139
+ }
140
+ await runWithSessionLock(sessionId, async () => {
141
+ if (getMessageIndexEpoch(sessionId) !== epoch)
142
+ return;
143
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
144
+ return;
145
+ let fallbackSnapshot = null;
146
+ try {
147
+ const fullReader = typeof readMessages === "function" ? readMessages : null;
148
+ const revision = readMessages.getRevision?.(sessionId);
149
+ const previous = heapHolder.reconciledSnapshots.get(sessionId);
150
+ const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
151
+ let cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
152
+ let after = cursor === previous?.count ? previous.after : undefined;
153
+ while (cursor < finalWatermark) {
154
+ if (getMessageIndexEpoch(sessionId) !== epoch)
155
+ return;
156
+ const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
157
+ const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
158
+ const retainedMessages = fallbackSnapshot ?? messages;
159
+ heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
160
+ if (getMessageIndexEpoch(sessionId) !== epoch)
161
+ return;
162
+ withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
163
+ const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
164
+ if (nextCursor <= cursor)
165
+ break;
166
+ cursor = nextCursor;
167
+ const last = messages.at(-1);
168
+ after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
169
+ if (cursor < finalWatermark) {
170
+ await yieldToEventLoop();
171
+ }
172
+ }
173
+ if (getMessageIndexEpoch(sessionId) !== epoch)
174
+ return;
175
+ if (isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
176
+ heapHolder.reconciledSessions.add(sessionId);
177
+ rebuildingSessions.delete(sessionId);
178
+ if (revision !== undefined) {
179
+ if (!after && finalWatermark > 0 && readMessages.readPage) {
180
+ const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
181
+ if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
182
+ after = { timeCreated: last.createdAt, id: last.id };
183
+ }
184
+ heapHolder.reconciledSnapshots.set(sessionId, {
185
+ revision,
186
+ count: finalWatermark,
187
+ after
188
+ });
189
+ }
190
+ } else {
191
+ logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
192
+ }
193
+ } finally {
194
+ heapHolder.activeReconcilerBuffers.delete(sessionId);
195
+ }
196
+ });
197
+ return true;
198
+ }
199
+ function scheduleReconciliation(db, sessionId, readMessages) {
200
+ if (rebuildingSessions.has(sessionId)) {
201
+ if (!heapHolder.clearAndReindexScheduledSessions.has(sessionId))
202
+ scheduleClearAndReindex(db, sessionId, readMessages);
203
+ return;
204
+ }
205
+ const epoch = getMessageIndexEpoch(sessionId);
206
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
207
+ return;
208
+ }
209
+ heapHolder.reconciliationScheduledSessions.add(sessionId);
210
+ scheduleAfterBootQuiet(() => {
211
+ defer(() => {
212
+ let appendedDuringReconciliation = false;
213
+ const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
214
+ if (getMessageIndexEpoch(sessionId) !== epoch)
215
+ return;
216
+ reconcileSessionIndex(db, sessionId, readMessages, epoch).then((ran) => {
217
+ if (getMessageIndexEpoch(sessionId) !== epoch)
218
+ return;
219
+ if (ran) {
220
+ const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
221
+ appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
222
+ return;
223
+ }
224
+ inRootAsyncContext2(() => setTimeout(() => {
225
+ if (getMessageIndexEpoch(sessionId) !== epoch)
226
+ return;
227
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
228
+ scheduleReconciliation(db, sessionId, readMessages);
229
+ }, PREPARE_RETRY_MS)).unref?.();
230
+ }).catch((error) => {
231
+ if (getMessageIndexEpoch(sessionId) !== epoch)
232
+ return;
233
+ logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
234
+ if (isDatabaseLockedError(error))
235
+ inRootAsyncContext2(() => setTimeout(() => {
236
+ if (getMessageIndexEpoch(sessionId) === epoch)
237
+ scheduleReconciliation(db, sessionId, readMessages);
238
+ }, 1000)).unref();
239
+ }).finally(() => {
240
+ if (getMessageIndexEpoch(sessionId) !== epoch)
241
+ return;
242
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
243
+ if (appendedDuringReconciliation)
244
+ scheduleReconciliation(db, sessionId, readMessages);
245
+ });
246
+ });
247
+ });
248
+ }
249
+ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
250
+ const schedulingKey = `${sessionId}\x00${messageId}`;
251
+ const epoch = sessionEpochs.get(sessionId) ?? 0;
252
+ if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
253
+ return;
254
+ const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
255
+ if (activeTimer)
256
+ clearTimeout(activeTimer);
257
+ const timer = inRootAsyncContext2(() => setTimeout(() => {
258
+ heapHolder.incrementalTimers.delete(schedulingKey);
259
+ heapHolder.pendingIncrementalKeys.add(schedulingKey);
260
+ const indexMessage = async () => {
261
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
262
+ return;
263
+ const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
264
+ if (!message)
265
+ return;
266
+ const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity(message)}`;
267
+ if (heapHolder.completedIncrementalKeys.has(revisionKey))
268
+ return;
269
+ const currentWatermark = getLastIndexedOrdinal(db, sessionId);
270
+ if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent(db, sessionId, message)) {
271
+ heapHolder.completedIncrementalKeys.add(revisionKey);
272
+ return;
273
+ }
274
+ const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
275
+ await indexSingleMessageOffThread(db, sessionId, message);
276
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
277
+ return;
278
+ const finalWatermark = getLastIndexedOrdinal(db, sessionId);
279
+ if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
280
+ heapHolder.reconciledSessions.add(sessionId);
281
+ }
282
+ heapHolder.completedIncrementalKeys.add(revisionKey);
283
+ };
284
+ sourceReady(messageSource, sessionId).then((ready) => {
285
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
286
+ return;
287
+ if (ready)
288
+ return runWithSessionLock(sessionId, indexMessage);
289
+ setTimeout(() => {
290
+ if (getMessageIndexEpoch(sessionId) === epoch)
291
+ scheduleIncrementalIndex(db, sessionId, messageId, messageSource);
292
+ }, PREPARE_RETRY_MS).unref?.();
293
+ }).catch((error) => {
294
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
295
+ return;
296
+ heapHolder.reconciledSessions.delete(sessionId);
297
+ logIndexingError(sessionId, `incremental index for ${messageId}`, error);
298
+ if (isDatabaseLockedError(error))
299
+ setTimeout(() => {
300
+ if (getMessageIndexEpoch(sessionId) === epoch)
301
+ scheduleIncrementalIndex(db, sessionId, messageId, messageSource);
302
+ }, 1000).unref();
303
+ }).finally(() => {
304
+ if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
305
+ heapHolder.pendingIncrementalKeys.delete(schedulingKey);
306
+ });
307
+ }, INCREMENTAL_DEBOUNCE_MS));
308
+ heapHolder.incrementalTimers.set(schedulingKey, timer);
309
+ }
310
+ async function indexSingleMessageOffThread(db, sessionId, message) {
311
+ const path = getSqliteDatabasePath2(db);
312
+ if (!path)
313
+ return withSqliteBackgroundWriter2(() => indexSingleMessage(db, sessionId, message));
314
+ const cancellation = new Int32Array(new SharedArrayBuffer(4));
315
+ const active = indexCancellations.get(sessionId) ?? new Set;
316
+ active.add(cancellation);
317
+ indexCancellations.set(sessionId, active);
318
+ const result = await runSessionWarmupWorker({
319
+ path,
320
+ sessionId,
321
+ indexMessage: message,
322
+ harness: getHarness2(),
323
+ indexCancellation: cancellation.buffer,
324
+ ...indexCoordinationInput2()
325
+ }, {}).finally(() => {
326
+ active.delete(cancellation);
327
+ if (active.size === 0)
328
+ indexCancellations.delete(sessionId);
329
+ });
330
+ if (!("inserted" in result))
331
+ throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
332
+ if (result.measurements) {
333
+ const sessions = workerMeasurements.get(db) ?? new Map;
334
+ sessions.set(sessionId, result.measurements);
335
+ workerMeasurements.set(db, sessions);
336
+ if (result.measurements.skipped)
337
+ log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
338
+ }
339
+ return result.inserted;
340
+ }
341
+ function scheduleClearAndReindex(db, sessionId, readMessages) {
342
+ rebuildingSessions.add(sessionId);
343
+ invalidateIncrementalWork(sessionId);
344
+ heapHolder.reconciledSessions.delete(sessionId);
345
+ heapHolder.reconciledSnapshots.delete(sessionId);
346
+ heapHolder.reconciliationScheduledSessions.add(sessionId);
347
+ clearCompletedIncrementalKeys(sessionId);
348
+ const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
349
+ if (existing) {
350
+ existing.source = readMessages;
351
+ return;
352
+ }
353
+ const pending = { source: readMessages };
354
+ heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
355
+ scheduleAfterBootQuiet(() => {
356
+ defer(() => {
357
+ let cleared = false;
358
+ let ownsSchedule = false;
359
+ let epoch = getMessageIndexEpoch(sessionId);
360
+ runWithSessionLock(sessionId, () => {
361
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
362
+ return;
363
+ ownsSchedule = true;
364
+ epoch = getMessageIndexEpoch(sessionId);
365
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
366
+ heapHolder.reconciledSessions.delete(sessionId);
367
+ heapHolder.reconciledSnapshots.delete(sessionId);
368
+ clearCompletedIncrementalKeys(sessionId);
369
+ clearIndexedMessages(db, sessionId);
370
+ cleared = true;
371
+ }).then(() => cleared && getMessageIndexEpoch(sessionId) === epoch ? reconcileSessionIndex(db, sessionId, pending.source, epoch) : undefined).catch((error) => {
372
+ if (getMessageIndexEpoch(sessionId) !== epoch)
373
+ return;
374
+ heapHolder.reconciledSessions.delete(sessionId);
375
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
376
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
377
+ logIndexingError(sessionId, "clear and reindex", error);
378
+ }).finally(() => {
379
+ if (ownsSchedule && getMessageIndexEpoch(sessionId) === epoch)
380
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
381
+ });
382
+ });
383
+ });
384
+ }
385
+ function getMessageIndexQueueHeapStats() {
386
+ return {
387
+ queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
388
+ reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
389
+ incrementalTimers: heapHolder.incrementalTimers.size,
390
+ pendingIncremental: heapHolder.pendingIncrementalKeys.size,
391
+ activeSessionLocks: heapHolder.sessionLocks.size,
392
+ completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
393
+ activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
394
+ activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
395
+ };
396
+ }
397
+ function clearSessionTracking(sessionId) {
398
+ invalidateIncrementalWork(sessionId);
399
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
400
+ heapHolder.reconciledSessions.delete(sessionId);
401
+ heapHolder.reconciledSnapshots.delete(sessionId);
402
+ heapHolder.stalledSessions.delete(sessionId);
403
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
404
+ heapHolder.sessionLocks.delete(sessionId);
405
+ heapHolder.activeReconcilerBuffers.delete(sessionId);
406
+ }
407
+ function invalidateIncrementalWork(sessionId) {
408
+ sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
409
+ for (const cancellation of indexCancellations.get(sessionId) ?? [])
410
+ Atomics.store(cancellation, 0, 1);
411
+ const prefix = `${sessionId}\x00`;
412
+ for (const [key, timer] of heapHolder.incrementalTimers) {
413
+ if (key.startsWith(prefix)) {
414
+ clearTimeout(timer);
415
+ heapHolder.incrementalTimers.delete(key);
416
+ }
417
+ }
418
+ for (const key of heapHolder.pendingIncrementalKeys) {
419
+ if (key.startsWith(prefix)) {
420
+ heapHolder.pendingIncrementalKeys.delete(key);
421
+ }
422
+ }
423
+ for (const key of heapHolder.completedIncrementalKeys) {
424
+ if (key.startsWith(prefix))
425
+ heapHolder.completedIncrementalKeys.delete(key);
426
+ }
427
+ }
428
+
429
+ export { getMessageIndexEpoch, isMessageIndexSearchable, scheduleReconciliation, scheduleIncrementalIndex, scheduleClearAndReindex, getMessageIndexQueueHeapStats, clearSessionTracking };
@@ -17,7 +17,7 @@ import {
17
17
  } from "./index-7kkphb6c.js";
18
18
  import {
19
19
  embedTextForProject2
20
- } from "./index-gxkhzmjq.js";
20
+ } from "./index-2743x98y.js";
21
21
  import {
22
22
  saveEmbeddingIfHashMatches
23
23
  } from "./index-4dhv7mqz.js";
@@ -237,7 +237,7 @@ import {
237
237
  getProjectChunkEmbeddingModelId2,
238
238
  getProjectEmbeddingMaxInputTokens2,
239
239
  embedItemsForProject2
240
- } from "./index-gxkhzmjq.js";
240
+ } from "./index-2743x98y.js";
241
241
  import {
242
242
  buildCanonicalChunkTextFromFts2,
243
243
  buildCompartmentSummaryFallbackText2,
@@ -247,7 +247,7 @@ import {
247
247
  replaceCompartmentChunkEmbeddings2,
248
248
  deleteChunkEmbedBackoffForSession2,
249
249
  chunkWindowSourceKey2
250
- } from "./index-mm93m7y6.js";
250
+ } from "./index-v7287tzq.js";
251
251
  import {
252
252
  clearCompressionDepth,
253
253
  clearCompressionDepthRange,
@@ -281,7 +281,7 @@ import {
281
281
  insertPrimerCandidates,
282
282
  promoteSessionFactsDurable,
283
283
  embedPromotedFacts
284
- } from "./index-pe6b4bhs.js";
284
+ } from "./index-as2amvn3.js";
285
285
  import {
286
286
  pushNotification2
287
287
  } from "./index-x8a7jmkh.js";
@@ -8872,6 +8872,7 @@ function decodePiContentDecision(value) {
8872
8872
  // src/features/magic-context/storage-native-replay.ts
8873
8873
  var NATIVE_TOOL_INPUTS = "native tool inputs";
8874
8874
  var NATIVE_REASONING_IDS = "native reasoning ids";
8875
+ var nativeWriteBarriers = new WeakMap;
8875
8876
  function invalidPersistedReplayState(lane, sessionId) {
8876
8877
  return new Error(`invalid persisted ${lane} state for session ${sessionId}`);
8877
8878
  }
@@ -98,7 +98,7 @@ import {
98
98
  getProjectEmbeddingSnapshot2,
99
99
  embedTextForProject2,
100
100
  embedBatchForProject2
101
- } from "./index-gxkhzmjq.js";
101
+ } from "./index-2743x98y.js";
102
102
  import {
103
103
  createWorkerShutdown
104
104
  } from "./index-cpjk5jd2.js";
@@ -140,7 +140,7 @@ import {
140
140
  peekNoteNudgeText,
141
141
  markNoteNudgeDelivered,
142
142
  getActiveCompartmentRun
143
- } from "./index-k0dpkyn7.js";
143
+ } from "./index-bzwh06cp.js";
144
144
  import {
145
145
  cleanSearchText,
146
146
  matchedSearchSnippet
@@ -257,9 +257,13 @@ import {
257
257
  import {
258
258
  BoundedSessionMap
259
259
  } from "./index-s1n8dd2n.js";
260
+ import {
261
+ getMessageIndexEpoch,
262
+ isMessageIndexSearchable
263
+ } from "./index-94ef0qe2.js";
260
264
  import {
261
265
  userFacingFailureCode
262
- } from "./index-pe6b4bhs.js";
266
+ } from "./index-as2amvn3.js";
263
267
  import {
264
268
  normalizeProtectedToolName,
265
269
  mergeProtectedTools
@@ -1356,6 +1360,8 @@ class AutoSearchBusyError extends Error {
1356
1360
  }
1357
1361
  }
1358
1362
  async function searchAutoHint(db, sessionId, projectPath, query, options, entry = new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./auto-search-worker.ts" : "./auto-search-worker.js", import.meta.url)) {
1363
+ const messageIndexEpoch = getMessageIndexEpoch(sessionId);
1364
+ const messageIndexWasSearchable = isMessageIndexSearchable(sessionId);
1359
1365
  const {
1360
1366
  rerankConfig: _rerankConfig,
1361
1367
  rerankClient: _rerankClient,
@@ -1364,7 +1370,8 @@ async function searchAutoHint(db, sessionId, projectPath, query, options, entry
1364
1370
  captureRerankLanes: _captureRerankLanes,
1365
1371
  ...hintOptions
1366
1372
  } = options;
1367
- return executeAutoSearchWorker(db, sessionId, projectPath, query, { ...hintOptions, explicitSearch: false, rerank: false }, entry, "search");
1373
+ const results = await executeAutoSearchWorker(db, sessionId, projectPath, query, { ...hintOptions, explicitSearch: false, rerank: false }, entry, "search");
1374
+ return messageIndexWasSearchable && isMessageIndexSearchable(sessionId) && getMessageIndexEpoch(sessionId) === messageIndexEpoch ? results : results.filter((result) => result.source !== "message");
1368
1375
  }
1369
1376
  var pendingBackfills = new WeakMap;
1370
1377
  var searchWorkers = new WeakMap;
@@ -3424,6 +3431,7 @@ function prepareLegacyToolSkeletonConversions(db, sessionId, targets, options =
3424
3431
  });
3425
3432
  };
3426
3433
  const rows = readRows(db);
3434
+ options.prepareRemovals?.(rows);
3427
3435
  const converted = new Map;
3428
3436
  for (const row of rows) {
3429
3437
  const target = targets.get(row.tagNumber);
@@ -7568,6 +7576,7 @@ async function runPostTransformPhase2(args) {
7568
7576
  emergencyReclaimedTokens,
7569
7577
  droppedCount,
7570
7578
  emergency,
7579
+ prefixMutationPermitted: isCacheBustingPass,
7571
7580
  bustedThisPass,
7572
7581
  prefixTrimStatus: deliveredPrefix?.prefixTrimStatus ?? null,
7573
7582
  thinkingBindingRecovery,
@@ -24,7 +24,7 @@ import {
24
24
  loadCompartmentChunkEmbeddingsForSearch2,
25
25
  peekCompartmentChunkSearchPool2,
26
26
  warmCompartmentChunkSearchPool2
27
- } from "./index-mm93m7y6.js";
27
+ } from "./index-v7287tzq.js";
28
28
  import {
29
29
  recordEmbeddingMeasurement,
30
30
  saveCommitEmbedding,
@@ -41,7 +41,7 @@ import {
41
41
  enqueueShadowEmbeddingItems2,
42
42
  getProjectEmbeddingSnapshot2,
43
43
  embedItemsForProject2
44
- } from "./index-gxkhzmjq.js";
44
+ } from "./index-2743x98y.js";
45
45
  import {
46
46
  getProjectEmbeddings2
47
47
  } from "./index-4dhv7mqz.js";
@@ -50,7 +50,7 @@ import {
50
50
  isEmbeddingEnabled,
51
51
  embedText,
52
52
  ensureMemoryEmbeddings2
53
- } from "./index-vnn5405n.js";
53
+ } from "./index-rfxzazzy.js";
54
54
  import {
55
55
  ModuleMemoryAuthorityError2,
56
56
  getMemoriesByProject2,
@@ -65,7 +65,7 @@ import {
65
65
  sanitizeFtsQuery,
66
66
  searchMemoriesFTS,
67
67
  searchMemoriesFTSUnion
68
- } from "./index-pe6b4bhs.js";
68
+ } from "./index-as2amvn3.js";
69
69
  import {
70
70
  cleanSearchText,
71
71
  keywordRelevance,
@@ -79,6 +79,10 @@ import {
79
79
  import {
80
80
  isRecord
81
81
  } from "./index-np3rgfw4.js";
82
+ import {
83
+ getMessageIndexEpoch,
84
+ isMessageIndexSearchable
85
+ } from "./index-94ef0qe2.js";
82
86
  import {
83
87
  resolveWorkspaceShareCategories,
84
88
  resolveWorkspaceIdentitySet,
@@ -1801,6 +1805,8 @@ function createUnifiedSearchDiagnostics2() {
1801
1805
  };
1802
1806
  }
1803
1807
  function searchMessageHistory2(db, request) {
1808
+ if (!isMessageIndexSearchable(request.sessionId))
1809
+ return { results: [], suppressedLiveMessageMatches: 0 };
1804
1810
  const diagnostics = request.collectDiagnostics ? createUnifiedSearchDiagnostics2() : undefined;
1805
1811
  const capture = request.captureLimit ? { limit: request.captureLimit, results: [] } : undefined;
1806
1812
  const results = searchMessages({
@@ -3023,6 +3029,9 @@ function resolveMemoriesByIdsForSearch2(args) {
3023
3029
  });
3024
3030
  }
3025
3031
  async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3032
+ const messageIndexEpoch = getMessageIndexEpoch(sessionId);
3033
+ const messageIndexWasSearchable = isMessageIndexSearchable(sessionId);
3034
+ const messageIndexStillCurrent = () => messageIndexWasSearchable && isMessageIndexSearchable(sessionId) && getMessageIndexEpoch(sessionId) === messageIndexEpoch;
3026
3035
  const trimmedQuery = query.trim();
3027
3036
  const measurementStartedAt = Date.now();
3028
3037
  if (trimmedQuery.length === 0 || options.signal?.aborted) {
@@ -3065,7 +3074,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3065
3074
  const timings = options.stepTimings;
3066
3075
  let stepStartedAt = performance.now();
3067
3076
  let messageResults = [];
3068
- if (runMessages) {
3077
+ if (runMessages && messageIndexStillCurrent()) {
3069
3078
  const messageRequest = {
3070
3079
  sessionId,
3071
3080
  query: trimmedQuery,
@@ -3239,6 +3248,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3239
3248
  }).immediate();
3240
3249
  }
3241
3250
  }
3251
+ if (!messageIndexStillCurrent())
3252
+ results = results.filter((result) => result.source !== "message");
3242
3253
  if (options.autoHint) {
3243
3254
  return results.map((result) => ({
3244
3255
  ...result,
@@ -15,7 +15,7 @@ import {
15
15
  OpenAICompatibleEmbeddingProvider,
16
16
  getProjectEmbeddingSnapshot2,
17
17
  embedBatchForProject2
18
- } from "./index-gxkhzmjq.js";
18
+ } from "./index-2743x98y.js";
19
19
  import {
20
20
  isEmbeddingHostBusy2
21
21
  } from "./index-qt1qqasc.js";
@@ -15,7 +15,7 @@ import {
15
15
  getActiveCompartmentRun,
16
16
  markActiveCompartmentRunPublished,
17
17
  registerActiveCompartmentRun
18
- } from "./index-k0dpkyn7.js";
18
+ } from "./index-bzwh06cp.js";
19
19
  import {
20
20
  inRootAsyncContext2
21
21
  } from "./index-gzy5w8ya.js";
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  setRecompStarting2,
39
39
  setRecompTerminal2
40
- } from "./index-adr4vfys.js";
40
+ } from "./index-2agkcr3y.js";
41
41
 
42
42
  // src/hooks/magic-context/wrapup-orchestrator.ts
43
43
  import * as crypto from "node:crypto";