@cortexkit/pi-magic-context 0.49.31 → 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 (30) hide show
  1. package/dist/auto-search-worker.js +4 -4
  2. package/dist/chunk-embedding-write-worker.js +4 -4
  3. package/dist/{compartment-chunk-embedding-pkk5beqp.js → compartment-chunk-embedding-8c85ebce.js} +1 -1
  4. package/dist/{embedding-backfill-v83xh6e8.js → embedding-backfill-rwfmyvze.js} +3 -3
  5. package/dist/{index-kmk3xpf9.js → index-0gymvr5j.js} +47 -7
  6. package/dist/{index-34e3mm36.js → index-87xkw8xm.js} +6 -4
  7. package/dist/{index-4nny4r40.js → index-9xd7qveg.js} +1 -1
  8. package/dist/{index-g026ztby.js → index-c474g0gj.js} +4 -18
  9. package/dist/{index-2nryd8ye.js → index-d0n9yjnc.js} +13 -11
  10. package/dist/{index-sr1ss4f8.js → index-d5q1q700.js} +1 -1
  11. package/dist/{index-v40sm8q6.js → index-drmr22ac.js} +3 -3
  12. package/dist/{index-bpd654bz.js → index-e59j3yq5.js} +414 -11
  13. package/dist/{index-0x1c054v.js → index-eqw9t2ty.js} +1 -1
  14. package/dist/index-nrzkqte4.js +18 -0
  15. package/dist/{index-0s14xaca.js → index-pb3ea2tq.js} +1 -1
  16. package/dist/{index-xvqcqg0r.js → index-r9y6tbbm.js} +6 -4
  17. package/dist/{index-yddeb86g.js → index-wpazxe9x.js} +64 -3
  18. package/dist/{index-0jykn0dw.js → index-xn5yh0pn.js} +65 -2
  19. package/dist/index.js +84 -314
  20. package/dist/{message-index-bounded-7aw556kv.js → message-index-bounded-n30vk21s.js} +4 -4
  21. package/dist/migration-worker.js +6 -5
  22. package/dist/{project-embedding-registry-wwbhm9rf.js → project-embedding-registry-acqb6be4.js} +2 -2
  23. package/dist/raw-ordinal-warmup-worker.js +3 -3
  24. package/dist/{read-session-chunk-xrymr0pp.js → read-session-chunk-ka6dhc77.js} +3 -3
  25. package/dist/{search-archive-5tmg1jyb.js → search-archive-msy2bczx.js} +4 -4
  26. package/dist/{search-dcdmpc62.js → search-qbxrnnjb.js} +9 -9
  27. package/dist/{storage-tags-9qaasrky.js → storage-tags-6409qq18.js} +2 -2
  28. package/dist/subagent-entry.js +12 -12
  29. package/dist/tag-snapshot-worker-pi.js +5 -5
  30. package/package.json +1 -1
@@ -3,7 +3,10 @@ import {
3
3
  } from "./index-0h2mkab2.js";
4
4
  import {
5
5
  inRootAsyncContext2,
6
- isTransientSqliteError2
6
+ getSqliteDatabasePath2,
7
+ withSqliteBackgroundWriter2,
8
+ isTransientSqliteError2,
9
+ indexCoordinationInput2
7
10
  } from "./index-2qtx0q6h.js";
8
11
  import {
9
12
  PROMOTABLE_CATEGORIES,
@@ -22,19 +25,22 @@ import {
22
25
  resolveStoredPathWorkspaceIdentity,
23
26
  sourceNameForMemory,
24
27
  managedAuthorityNoteRow
25
- } from "./index-0s14xaca.js";
28
+ } from "./index-pb3ea2tq.js";
26
29
  import {
27
- isKnownAutocommit
28
- } from "./index-g026ztby.js";
30
+ scheduleAfterBootQuiet
31
+ } from "./index-48twbev2.js";
29
32
  import {
30
33
  SubcClient
31
34
  } from "./index-gwxaz0z5.js";
35
+ import {
36
+ runSessionWarmupWorker
37
+ } from "./index-6981g1xv.js";
32
38
  import {
33
39
  buildCanonicalChunkTextFromFts2,
34
40
  loadCompartmentChunkEmbeddingsForSearch2,
35
41
  peekCompartmentChunkSearchPool2,
36
42
  warmCompartmentChunkSearchPool2
37
- } from "./index-kmk3xpf9.js";
43
+ } from "./index-0gymvr5j.js";
38
44
  import {
39
45
  recordEmbeddingMeasurement,
40
46
  saveCommitEmbedding,
@@ -52,7 +58,7 @@ import {
52
58
  getProjectEmbeddingSnapshot2,
53
59
  embedTextForProject2,
54
60
  embedItemsForProject2
55
- } from "./index-0jykn0dw.js";
61
+ } from "./index-xn5yh0pn.js";
56
62
  import {
57
63
  saveEmbeddingIfHashMatches,
58
64
  getProjectEmbeddings2
@@ -62,7 +68,7 @@ import {
62
68
  isEmbeddingEnabled,
63
69
  embedText,
64
70
  ensureMemoryEmbeddings2
65
- } from "./index-4nny4r40.js";
71
+ } from "./index-9xd7qveg.js";
66
72
  import {
67
73
  getMemorySelectColumns2,
68
74
  isMemoryRow2,
@@ -81,8 +87,16 @@ import {
81
87
  cleanSearchText,
82
88
  keywordRelevance,
83
89
  matchedSearchSnippet,
84
- getIndexedMessageCorpusSize
85
- } from "./index-yddeb86g.js";
90
+ getMessageIndexSourceIdentity,
91
+ isMessageIndexSourceCurrent,
92
+ getLastIndexedOrdinal,
93
+ getIndexedMessageCorpusSize,
94
+ getMessageIndexReconciliationStartOrdinal,
95
+ isMessageIndexReconciledThrough,
96
+ clearIndexedMessages,
97
+ indexSingleMessage,
98
+ indexMessagesAfterOrdinal
99
+ } from "./index-wpazxe9x.js";
86
100
  import {
87
101
  MESSAGE_FTS_SESSION_FILTER_SQL,
88
102
  withMessageFtsSessionFilter
@@ -90,6 +104,9 @@ import {
90
104
  import {
91
105
  computeNormalizedHash
92
106
  } from "./index-9x1f96r8.js";
107
+ import {
108
+ isKnownAutocommit
109
+ } from "./index-nrzkqte4.js";
93
110
 
94
111
  // ../plugin/src/features/magic-context/storage-notes.ts
95
112
  var NOTE_TYPES = new Set(["session", "smart"]);
@@ -1811,6 +1828,385 @@ function searchGitCommitsSync(db, projectPath, query, options) {
1811
1828
  });
1812
1829
  return results.slice(0, options.limit);
1813
1830
  }
1831
+ // ../plugin/src/features/magic-context/message-index-async.ts
1832
+ var indexCancellations = new Map;
1833
+ var sessionEpochs = new Map;
1834
+ var rebuildingSessions = new Set;
1835
+ function getMessageIndexEpoch(sessionId) {
1836
+ return sessionEpochs.get(sessionId) ?? 0;
1837
+ }
1838
+ function isMessageIndexSearchable(sessionId) {
1839
+ return !rebuildingSessions.has(sessionId);
1840
+ }
1841
+ var workerMeasurements = new WeakMap;
1842
+ function isDatabaseLockedError(error) {
1843
+ if (!error || typeof error !== "object")
1844
+ return false;
1845
+ const e = error;
1846
+ if (typeof e.code === "string") {
1847
+ if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
1848
+ return true;
1849
+ }
1850
+ if (typeof e.message === "string") {
1851
+ if (/database is locked/i.test(e.message))
1852
+ return true;
1853
+ if (/sqlite_(busy|locked)/i.test(e.message))
1854
+ return true;
1855
+ }
1856
+ return false;
1857
+ }
1858
+ var INCREMENTAL_DEBOUNCE_MS = 100;
1859
+ var RECONCILIATION_BATCH_SIZE = 100;
1860
+
1861
+ class MagicContextMessageIndexHeapHolder {
1862
+ reconciledSessions = new Set;
1863
+ reconciledSnapshots = new Map;
1864
+ stalledSessions = new Set;
1865
+ reconciliationScheduledSessions = new Set;
1866
+ clearAndReindexScheduledSessions = new Map;
1867
+ sessionLocks = new Map;
1868
+ incrementalTimers = new Map;
1869
+ pendingIncrementalKeys = new Set;
1870
+ completedIncrementalKeys = new Set;
1871
+ activeReconcilerBuffers = new Map;
1872
+ }
1873
+ var heapHolder = new MagicContextMessageIndexHeapHolder;
1874
+ function clearCompletedIncrementalKeys(sessionId) {
1875
+ const prefix = `${sessionId}\x00`;
1876
+ for (const key of heapHolder.completedIncrementalKeys) {
1877
+ if (key.startsWith(prefix))
1878
+ heapHolder.completedIncrementalKeys.delete(key);
1879
+ }
1880
+ }
1881
+ var PREPARE_RETRY_MS = 60000;
1882
+ async function sourceReady(source, sessionId) {
1883
+ const prepare = source?.prepare;
1884
+ return typeof prepare === "function" ? prepare(sessionId) : true;
1885
+ }
1886
+ function defer(fn) {
1887
+ const immediate = globalThis.setImmediate;
1888
+ if (typeof immediate === "function") {
1889
+ inRootAsyncContext2(() => immediate(fn));
1890
+ return;
1891
+ }
1892
+ inRootAsyncContext2(() => setTimeout(fn, 0));
1893
+ }
1894
+ function yieldToEventLoop() {
1895
+ return new Promise((resolve) => defer(resolve));
1896
+ }
1897
+ function runWithSessionLock(sessionId, operation) {
1898
+ const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
1899
+ const run = previous.catch(() => {
1900
+ return;
1901
+ }).then(async () => {
1902
+ await operation();
1903
+ });
1904
+ heapHolder.sessionLocks.set(sessionId, run);
1905
+ run.finally(() => {
1906
+ if (heapHolder.sessionLocks.get(sessionId) === run) {
1907
+ heapHolder.sessionLocks.delete(sessionId);
1908
+ }
1909
+ }).catch(() => {
1910
+ return;
1911
+ });
1912
+ return run;
1913
+ }
1914
+ function logIndexingError(sessionId, action, error) {
1915
+ if (isDatabaseLockedError(error)) {
1916
+ sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
1917
+ return;
1918
+ }
1919
+ sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
1920
+ log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
1921
+ }
1922
+ function logReconciliationStall(sessionId, reason) {
1923
+ if (heapHolder.stalledSessions.has(sessionId))
1924
+ return;
1925
+ heapHolder.stalledSessions.add(sessionId);
1926
+ sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
1927
+ }
1928
+ async function reconcileSessionIndex(db, sessionId, readMessages, epoch = getMessageIndexEpoch(sessionId)) {
1929
+ if (!await sourceReady(readMessages, sessionId)) {
1930
+ logReconciliationStall(sessionId, "raw message reader is not ready");
1931
+ return false;
1932
+ }
1933
+ await runWithSessionLock(sessionId, async () => {
1934
+ if (getMessageIndexEpoch(sessionId) !== epoch)
1935
+ return;
1936
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
1937
+ return;
1938
+ let fallbackSnapshot = null;
1939
+ try {
1940
+ const fullReader = typeof readMessages === "function" ? readMessages : null;
1941
+ const revision = readMessages.getRevision?.(sessionId);
1942
+ const previous = heapHolder.reconciledSnapshots.get(sessionId);
1943
+ 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;
1944
+ let cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
1945
+ let after = cursor === previous?.count ? previous.after : undefined;
1946
+ while (cursor < finalWatermark) {
1947
+ if (getMessageIndexEpoch(sessionId) !== epoch)
1948
+ return;
1949
+ const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
1950
+ const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
1951
+ const retainedMessages = fallbackSnapshot ?? messages;
1952
+ heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
1953
+ if (getMessageIndexEpoch(sessionId) !== epoch)
1954
+ return;
1955
+ withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
1956
+ const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
1957
+ if (nextCursor <= cursor)
1958
+ break;
1959
+ cursor = nextCursor;
1960
+ const last = messages.at(-1);
1961
+ after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
1962
+ if (cursor < finalWatermark) {
1963
+ await yieldToEventLoop();
1964
+ }
1965
+ }
1966
+ if (getMessageIndexEpoch(sessionId) !== epoch)
1967
+ return;
1968
+ if (isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
1969
+ heapHolder.reconciledSessions.add(sessionId);
1970
+ rebuildingSessions.delete(sessionId);
1971
+ if (revision !== undefined) {
1972
+ if (!after && finalWatermark > 0 && readMessages.readPage) {
1973
+ const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
1974
+ if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
1975
+ after = { timeCreated: last.createdAt, id: last.id };
1976
+ }
1977
+ heapHolder.reconciledSnapshots.set(sessionId, {
1978
+ revision,
1979
+ count: finalWatermark,
1980
+ after
1981
+ });
1982
+ }
1983
+ } else {
1984
+ logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
1985
+ }
1986
+ } finally {
1987
+ heapHolder.activeReconcilerBuffers.delete(sessionId);
1988
+ }
1989
+ });
1990
+ return true;
1991
+ }
1992
+ function scheduleReconciliation(db, sessionId, readMessages) {
1993
+ if (rebuildingSessions.has(sessionId)) {
1994
+ if (!heapHolder.clearAndReindexScheduledSessions.has(sessionId))
1995
+ scheduleClearAndReindex(db, sessionId, readMessages);
1996
+ return;
1997
+ }
1998
+ const epoch = getMessageIndexEpoch(sessionId);
1999
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
2000
+ return;
2001
+ }
2002
+ heapHolder.reconciliationScheduledSessions.add(sessionId);
2003
+ scheduleAfterBootQuiet(() => {
2004
+ defer(() => {
2005
+ let appendedDuringReconciliation = false;
2006
+ const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
2007
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2008
+ return;
2009
+ reconcileSessionIndex(db, sessionId, readMessages, epoch).then((ran) => {
2010
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2011
+ return;
2012
+ if (ran) {
2013
+ const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
2014
+ appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
2015
+ return;
2016
+ }
2017
+ inRootAsyncContext2(() => setTimeout(() => {
2018
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2019
+ return;
2020
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
2021
+ scheduleReconciliation(db, sessionId, readMessages);
2022
+ }, PREPARE_RETRY_MS)).unref?.();
2023
+ }).catch((error) => {
2024
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2025
+ return;
2026
+ logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
2027
+ if (isDatabaseLockedError(error))
2028
+ inRootAsyncContext2(() => setTimeout(() => {
2029
+ if (getMessageIndexEpoch(sessionId) === epoch)
2030
+ scheduleReconciliation(db, sessionId, readMessages);
2031
+ }, 1000)).unref();
2032
+ }).finally(() => {
2033
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2034
+ return;
2035
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
2036
+ if (appendedDuringReconciliation)
2037
+ scheduleReconciliation(db, sessionId, readMessages);
2038
+ });
2039
+ });
2040
+ });
2041
+ }
2042
+ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
2043
+ const schedulingKey = `${sessionId}\x00${messageId}`;
2044
+ const epoch = sessionEpochs.get(sessionId) ?? 0;
2045
+ if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
2046
+ return;
2047
+ const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
2048
+ if (activeTimer)
2049
+ clearTimeout(activeTimer);
2050
+ const timer = inRootAsyncContext2(() => setTimeout(() => {
2051
+ heapHolder.incrementalTimers.delete(schedulingKey);
2052
+ heapHolder.pendingIncrementalKeys.add(schedulingKey);
2053
+ const indexMessage = async () => {
2054
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
2055
+ return;
2056
+ const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
2057
+ if (!message)
2058
+ return;
2059
+ const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity(message)}`;
2060
+ if (heapHolder.completedIncrementalKeys.has(revisionKey))
2061
+ return;
2062
+ const currentWatermark = getLastIndexedOrdinal(db, sessionId);
2063
+ if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent(db, sessionId, message)) {
2064
+ heapHolder.completedIncrementalKeys.add(revisionKey);
2065
+ return;
2066
+ }
2067
+ const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
2068
+ await indexSingleMessageOffThread(db, sessionId, message);
2069
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
2070
+ return;
2071
+ const finalWatermark = getLastIndexedOrdinal(db, sessionId);
2072
+ if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
2073
+ heapHolder.reconciledSessions.add(sessionId);
2074
+ }
2075
+ heapHolder.completedIncrementalKeys.add(revisionKey);
2076
+ };
2077
+ sourceReady(messageSource, sessionId).then((ready) => {
2078
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
2079
+ return;
2080
+ if (ready)
2081
+ return runWithSessionLock(sessionId, indexMessage);
2082
+ setTimeout(() => {
2083
+ if (getMessageIndexEpoch(sessionId) === epoch)
2084
+ scheduleIncrementalIndex(db, sessionId, messageId, messageSource);
2085
+ }, PREPARE_RETRY_MS).unref?.();
2086
+ }).catch((error) => {
2087
+ if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
2088
+ return;
2089
+ heapHolder.reconciledSessions.delete(sessionId);
2090
+ logIndexingError(sessionId, `incremental index for ${messageId}`, error);
2091
+ if (isDatabaseLockedError(error))
2092
+ setTimeout(() => {
2093
+ if (getMessageIndexEpoch(sessionId) === epoch)
2094
+ scheduleIncrementalIndex(db, sessionId, messageId, messageSource);
2095
+ }, 1000).unref();
2096
+ }).finally(() => {
2097
+ if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
2098
+ heapHolder.pendingIncrementalKeys.delete(schedulingKey);
2099
+ });
2100
+ }, INCREMENTAL_DEBOUNCE_MS));
2101
+ heapHolder.incrementalTimers.set(schedulingKey, timer);
2102
+ }
2103
+ async function indexSingleMessageOffThread(db, sessionId, message) {
2104
+ const path = getSqliteDatabasePath2(db);
2105
+ if (!path)
2106
+ return withSqliteBackgroundWriter2(() => indexSingleMessage(db, sessionId, message));
2107
+ const cancellation = new Int32Array(new SharedArrayBuffer(4));
2108
+ const active = indexCancellations.get(sessionId) ?? new Set;
2109
+ active.add(cancellation);
2110
+ indexCancellations.set(sessionId, active);
2111
+ const result = await runSessionWarmupWorker({
2112
+ path,
2113
+ sessionId,
2114
+ indexMessage: message,
2115
+ harness: getHarness2(),
2116
+ indexCancellation: cancellation.buffer,
2117
+ ...indexCoordinationInput2()
2118
+ }, {}).finally(() => {
2119
+ active.delete(cancellation);
2120
+ if (active.size === 0)
2121
+ indexCancellations.delete(sessionId);
2122
+ });
2123
+ if (!("inserted" in result))
2124
+ throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
2125
+ if (result.measurements) {
2126
+ const sessions = workerMeasurements.get(db) ?? new Map;
2127
+ sessions.set(sessionId, result.measurements);
2128
+ workerMeasurements.set(db, sessions);
2129
+ if (result.measurements.skipped)
2130
+ log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
2131
+ }
2132
+ return result.inserted;
2133
+ }
2134
+ function scheduleClearAndReindex(db, sessionId, readMessages) {
2135
+ rebuildingSessions.add(sessionId);
2136
+ invalidateIncrementalWork(sessionId);
2137
+ heapHolder.reconciledSessions.delete(sessionId);
2138
+ heapHolder.reconciledSnapshots.delete(sessionId);
2139
+ heapHolder.reconciliationScheduledSessions.add(sessionId);
2140
+ clearCompletedIncrementalKeys(sessionId);
2141
+ const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
2142
+ if (existing) {
2143
+ existing.source = readMessages;
2144
+ return;
2145
+ }
2146
+ const pending = { source: readMessages };
2147
+ heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
2148
+ scheduleAfterBootQuiet(() => {
2149
+ defer(() => {
2150
+ let cleared = false;
2151
+ let ownsSchedule = false;
2152
+ let epoch = getMessageIndexEpoch(sessionId);
2153
+ runWithSessionLock(sessionId, () => {
2154
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
2155
+ return;
2156
+ ownsSchedule = true;
2157
+ epoch = getMessageIndexEpoch(sessionId);
2158
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
2159
+ heapHolder.reconciledSessions.delete(sessionId);
2160
+ heapHolder.reconciledSnapshots.delete(sessionId);
2161
+ clearCompletedIncrementalKeys(sessionId);
2162
+ clearIndexedMessages(db, sessionId);
2163
+ cleared = true;
2164
+ }).then(() => cleared && getMessageIndexEpoch(sessionId) === epoch ? reconcileSessionIndex(db, sessionId, pending.source, epoch) : undefined).catch((error) => {
2165
+ if (getMessageIndexEpoch(sessionId) !== epoch)
2166
+ return;
2167
+ heapHolder.reconciledSessions.delete(sessionId);
2168
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
2169
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
2170
+ logIndexingError(sessionId, "clear and reindex", error);
2171
+ }).finally(() => {
2172
+ if (ownsSchedule && getMessageIndexEpoch(sessionId) === epoch)
2173
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
2174
+ });
2175
+ });
2176
+ });
2177
+ }
2178
+ function clearSessionTracking(sessionId) {
2179
+ invalidateIncrementalWork(sessionId);
2180
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
2181
+ heapHolder.reconciledSessions.delete(sessionId);
2182
+ heapHolder.reconciledSnapshots.delete(sessionId);
2183
+ heapHolder.stalledSessions.delete(sessionId);
2184
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
2185
+ heapHolder.sessionLocks.delete(sessionId);
2186
+ heapHolder.activeReconcilerBuffers.delete(sessionId);
2187
+ }
2188
+ function invalidateIncrementalWork(sessionId) {
2189
+ sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
2190
+ for (const cancellation of indexCancellations.get(sessionId) ?? [])
2191
+ Atomics.store(cancellation, 0, 1);
2192
+ const prefix = `${sessionId}\x00`;
2193
+ for (const [key, timer] of heapHolder.incrementalTimers) {
2194
+ if (key.startsWith(prefix)) {
2195
+ clearTimeout(timer);
2196
+ heapHolder.incrementalTimers.delete(key);
2197
+ }
2198
+ }
2199
+ for (const key of heapHolder.pendingIncrementalKeys) {
2200
+ if (key.startsWith(prefix)) {
2201
+ heapHolder.pendingIncrementalKeys.delete(key);
2202
+ }
2203
+ }
2204
+ for (const key of heapHolder.completedIncrementalKeys) {
2205
+ if (key.startsWith(prefix))
2206
+ heapHolder.completedIncrementalKeys.delete(key);
2207
+ }
2208
+ }
2209
+
1814
2210
  // ../plugin/src/features/magic-context/literal-probes.ts
1815
2211
  var MAX_PROBES = 5;
1816
2212
  var MIN_PROBE_LENGTH = 3;
@@ -2342,6 +2738,8 @@ function createUnifiedSearchDiagnostics2() {
2342
2738
  };
2343
2739
  }
2344
2740
  function searchMessageHistory2(db, request) {
2741
+ if (!isMessageIndexSearchable(request.sessionId))
2742
+ return { results: [], suppressedLiveMessageMatches: 0 };
2345
2743
  const diagnostics = request.collectDiagnostics ? createUnifiedSearchDiagnostics2() : undefined;
2346
2744
  const capture = request.captureLimit ? { limit: request.captureLimit, results: [] } : undefined;
2347
2745
  const results = searchMessages({
@@ -3564,6 +3962,9 @@ function resolveMemoriesByIdsForSearch2(args) {
3564
3962
  });
3565
3963
  }
3566
3964
  async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3965
+ const messageIndexEpoch = getMessageIndexEpoch(sessionId);
3966
+ const messageIndexWasSearchable = isMessageIndexSearchable(sessionId);
3967
+ const messageIndexStillCurrent = () => messageIndexWasSearchable && isMessageIndexSearchable(sessionId) && getMessageIndexEpoch(sessionId) === messageIndexEpoch;
3567
3968
  const trimmedQuery = query.trim();
3568
3969
  const measurementStartedAt = Date.now();
3569
3970
  if (trimmedQuery.length === 0 || options.signal?.aborted) {
@@ -3606,7 +4007,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3606
4007
  const timings = options.stepTimings;
3607
4008
  let stepStartedAt = performance.now();
3608
4009
  let messageResults = [];
3609
- if (runMessages) {
4010
+ if (runMessages && messageIndexStillCurrent()) {
3610
4011
  const messageRequest = {
3611
4012
  sessionId,
3612
4013
  query: trimmedQuery,
@@ -3780,6 +4181,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
3780
4181
  }).immediate();
3781
4182
  }
3782
4183
  }
4184
+ if (!messageIndexStillCurrent())
4185
+ results = results.filter((result) => result.source !== "message");
3783
4186
  if (options.autoHint) {
3784
4187
  return results.map((result) => ({
3785
4188
  ...result,
@@ -3906,4 +4309,4 @@ ${bodyParts.join(`
3906
4309
  `)}`;
3907
4310
  }
3908
4311
 
3909
- export { getNoteByIdInScope, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNotes, dismissNote, markNoteReady, markNoteChecked, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, USER_FACING_FAILURES, renderUserFacingFailure, userFacingFailureCode, renderCapabilityRefusal, renderDreamFailure, dreamFailureCode, renderEmbeddingFailure, renderSingleStoreMigrationRequiredRefusal, SingleStoreMigrationRequiredError, projectNeedsSingleStoreMigration, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };
4312
+ export { getNoteByIdInScope, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNotes, dismissNote, markNoteReady, markNoteChecked, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, insertPrimerCandidates, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, USER_FACING_FAILURES, renderUserFacingFailure, userFacingFailureCode, renderCapabilityRefusal, renderDreamFailure, dreamFailureCode, renderEmbeddingFailure, renderSingleStoreMigrationRequiredRefusal, SingleStoreMigrationRequiredError, projectNeedsSingleStoreMigration, promoteSessionFactsDurable, embedPromotedFacts, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, indexCommitsForProject, embedUnembeddedCommits, getMessageIndexEpoch, isMessageIndexSearchable, scheduleReconciliation, scheduleIncrementalIndex, scheduleClearAndReindex, clearSessionTracking, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };
@@ -15,7 +15,7 @@ import {
15
15
  jsonHashSink,
16
16
  tagOrderConstraintIndex,
17
17
  tagIdentityRevisionKey
18
- } from "./index-g026ztby.js";
18
+ } from "./index-c474g0gj.js";
19
19
  import {
20
20
  DEFAULT_PROTECTED_TOOLS,
21
21
  normalizeProtectedToolName,
@@ -0,0 +1,18 @@
1
+ // ../plugin/src/shared/sqlite-helpers.ts
2
+ function closeQuietly(db) {
3
+ if (!db)
4
+ return;
5
+ try {
6
+ db.close();
7
+ } catch {}
8
+ }
9
+ function isKnownAutocommit(db) {
10
+ const state = db;
11
+ try {
12
+ return state.inTransaction === false || state.isTransaction === false;
13
+ } catch {
14
+ return false;
15
+ }
16
+ }
17
+
18
+ export { closeQuietly, isKnownAutocommit };
@@ -8,7 +8,7 @@ import {
8
8
  ensureColumn,
9
9
  healAllNullColumns,
10
10
  installV95PerfSchema
11
- } from "./index-g026ztby.js";
11
+ } from "./index-c474g0gj.js";
12
12
  import {
13
13
  resolveOpenCodeDbPath,
14
14
  openCodeDbPathExists,
@@ -41,19 +41,21 @@ import {
41
41
  hasPendingMigrations,
42
42
  getMainThreadMigrationBodyCount,
43
43
  runMigrations
44
- } from "./index-0s14xaca.js";
44
+ } from "./index-pb3ea2tq.js";
45
45
  import {
46
- closeQuietly,
47
46
  ensureColumn,
48
47
  installV95PerfSchema,
49
48
  installTagIdentityRevisionTrigger
50
- } from "./index-g026ztby.js";
49
+ } from "./index-c474g0gj.js";
51
50
  import {
52
51
  resolveOpenCodeDbPath,
53
52
  hasV1MessageTables,
54
53
  setDatabase,
55
54
  loadToolDefinitionMeasurements
56
55
  } from "./index-23t8ryqw.js";
56
+ import {
57
+ closeQuietly
58
+ } from "./index-nrzkqte4.js";
57
59
  import {
58
60
  logSlowWriteTransaction
59
61
  } from "./index-hqw0rt9k.js";
@@ -2003,7 +2005,7 @@ function finishDatabaseOpen(db, dbPath, explicitDbPath, latestSupportedVersion)
2003
2005
  state.running = startMessageFtsRowidMapBackfill2(db, signal).then(async () => {
2004
2006
  if (signal.aborted || !readsOpenCodeStore)
2005
2007
  return;
2006
- const { readRawSessionMessagePage, readRawSessionMessages } = await importPluginModule(() => import("./read-session-chunk-xrymr0pp.js"));
2008
+ const { readRawSessionMessagePage, readRawSessionMessages } = await importPluginModule(() => import("./read-session-chunk-ka6dhc77.js"));
2007
2009
  const { startMessageTimeBackfill } = await importPluginModule(() => import("./message-time-backfill-e3r8ddh1.js"));
2008
2010
  if (signal.aborted)
2009
2011
  return;