@cortexkit/opencode-magic-context 0.49.12 → 0.49.13

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 (116) hide show
  1. package/dist/auto-search-worker.js +3 -3
  2. package/dist/chunk-embedding-write-worker.js +89 -0
  3. package/dist/config/schema/agent-overrides.d.ts +12 -12
  4. package/dist/config/schema/magic-context.d.ts +88 -88
  5. package/dist/{conflict-warning-hook-f4x5wed7.js → conflict-warning-hook-mgq17yr3.js} +3 -3
  6. package/dist/{context-dam8p201.js → context-azqk0vfd.js} +31 -65
  7. package/dist/{derive-budgets-5306b1jt.js → derive-budgets-zn7yzd2d.js} +1 -1
  8. package/dist/{embedding-backfill-qbfcbp87.js → embedding-backfill-5e1t5wha.js} +6 -5
  9. package/dist/embedding-worker.js +1 -1
  10. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts +2 -0
  11. package/dist/features/magic-context/chunk-embedding-write-worker.d.ts.map +1 -0
  12. package/dist/features/magic-context/chunk-embedding-writer.d.ts +48 -0
  13. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -0
  14. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
  15. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +3 -2
  17. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/map-memories.d.ts +8 -1
  19. package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +2 -0
  21. package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
  23. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  25. package/dist/features/magic-context/dreamer/verify-prompt.d.ts +6 -1
  26. package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/verify.d.ts +25 -11
  28. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  29. package/dist/features/magic-context/mural/compress-cues.d.ts +3 -0
  30. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  31. package/dist/features/magic-context/project-embedding-registry.d.ts +5 -0
  32. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  33. package/dist/hooks/magic-context/auto-embed-session.d.ts +10 -0
  34. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -0
  35. package/dist/hooks/magic-context/embed-session-state.d.ts +8 -1
  36. package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
  37. package/dist/hooks/magic-context/hook.d.ts +3 -1
  38. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  39. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  40. package/dist/{index-yx5kgp2x.js → index-2jr1smmh.js} +92 -71
  41. package/dist/{index-fx90bvjd.js → index-3kdm78zp.js} +2 -2
  42. package/dist/{index-gf0psee3.js → index-3kx0kg0f.js} +60 -3
  43. package/dist/{index-6sytd5w3.js → index-aw1bh90w.js} +6 -6
  44. package/dist/{index-6sz25c3s.js → index-bxdg2nbt.js} +2 -2
  45. package/dist/{index-7h8a1xpc.js → index-e4dsjj1p.js} +1 -1
  46. package/dist/{index-05n6ykca.js → index-hnm8raee.js} +2 -2
  47. package/dist/{index-x2xjyq8f.js → index-qkd9zz0p.js} +8 -8
  48. package/dist/index-saews2s3.js +229 -0
  49. package/dist/{index-qtbdx42g.js → index-sj89f3b0.js} +12 -12
  50. package/dist/{index-wqs4q74r.js → index-v13skev1.js} +7 -7
  51. package/dist/{index-1wwh38fk.js → index-wj6ht7nm.js} +438 -132
  52. package/dist/{index-95s8xaj1.js → index-wz6mzzb1.js} +3 -3
  53. package/dist/{index-7zd5asz9.js → index-y1qysm3q.js} +196 -243
  54. package/dist/index.js +52 -90
  55. package/dist/{message-index-bounded-nq6rp8xa.js → message-index-bounded-vm64mqpq.js} +2 -2
  56. package/dist/{message-index-df7swgy1.js → message-index-seaqpb7c.js} +5 -5
  57. package/dist/migration-worker.js +2 -2
  58. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  59. package/dist/{project-embedding-registry-q0ysjyzc.js → project-embedding-registry-x45bv3qr.js} +5 -4
  60. package/dist/raw-ordinal-warmup-worker.js +2 -2
  61. package/dist/{recomp-orchestrator-a0mvby4e.js → recomp-orchestrator-dmbeadwt.js} +21 -20
  62. package/dist/{search-fm002702.js → search-5yd5ytzs.js} +14 -13
  63. package/dist/{send-session-notification-y2wg3fkh.js → send-session-notification-24r4esbh.js} +2 -2
  64. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  65. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  66. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  67. package/dist/{transform-postprocess-phase-s84rdf32.js → transform-postprocess-phase-72v86syx.js} +21 -20
  68. package/dist/v2/auto-search-worker.js +3 -3
  69. package/dist/v2/chunk-embedding-write-worker.js +88 -0
  70. package/dist/v2/{context-x60fa16g.js → context-w055w17c.js} +465 -190
  71. package/dist/v2/{derive-budgets-z25jw3py.js → derive-budgets-2zh4gm2c.js} +2 -2
  72. package/dist/v2/{embedding-backfill-mbjyza2a.js → embedding-backfill-jmaf8zrr.js} +6 -5
  73. package/dist/v2/embedding-worker.js +1 -1
  74. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  75. package/dist/v2/hooks/transform-features.d.ts +2 -2
  76. package/dist/v2/hooks/transform-features.d.ts.map +1 -1
  77. package/dist/v2/{message-index-bounded-pgv1ndpb.js → message-index-bounded-wepg5723.js} +2 -2
  78. package/dist/v2/{message-index-5nayhm1r.js → message-index-gcmd0ng0.js} +5 -5
  79. package/dist/v2/migration-worker.js +2 -2
  80. package/dist/v2/{project-embedding-registry-jbmjc0p4.js → project-embedding-registry-0msp56p8.js} +5 -4
  81. package/dist/v2/raw-ordinal-warmup-worker.js +2 -2
  82. package/dist/v2/{recomp-orchestrator-8w3449eb.js → recomp-orchestrator-ca7qt75a.js} +21 -20
  83. package/dist/v2/retrospective-raw-provider.d.ts.map +1 -1
  84. package/dist/v2/{search-mhmxgq0e.js → search-c86dcv14.js} +14 -13
  85. package/dist/v2/{send-session-notification-jevgj9fe.js → send-session-notification-8ghn9tnv.js} +2 -2
  86. package/dist/v2/{server-f7jfmrrz.js → server-34kwfsr4.js} +1 -1
  87. package/dist/v2/server-4gn3z5an.js +229 -0
  88. package/dist/v2/{server-4c10404h.js → server-6cdy4rc0.js} +2 -2
  89. package/dist/v2/{server-5gvkzzrf.js → server-b81w6sw3.js} +92 -69
  90. package/dist/v2/{server-9ewkzqgd.js → server-ef89gdsx.js} +2 -2
  91. package/dist/v2/{server-sz8jj92q.js → server-hek6z3w6.js} +194 -241
  92. package/dist/v2/{server-50mkkhy1.js → server-n8ch9683.js} +8 -8
  93. package/dist/v2/{server-vknbt0gq.js → server-qhfvvfxj.js} +60 -3
  94. package/dist/v2/{server-nmrm2rjy.js → server-t4prcjc1.js} +7 -7
  95. package/dist/v2/{server-25tg45b4.js → server-xh7jar6k.js} +6 -6
  96. package/dist/v2/{server-37ngj8qw.js → server-zc3e54vy.js} +1 -1
  97. package/dist/v2/server.js +9 -8
  98. package/dist/v2/store-reader.d.ts +1 -0
  99. package/dist/v2/store-reader.d.ts.map +1 -1
  100. package/dist/v2/{wrapup-orchestrator-r82y780v.js → wrapup-orchestrator-e1a2w6jh.js} +14 -13
  101. package/dist/{wrapup-orchestrator-vmt6z3q5.js → wrapup-orchestrator-2051r6qm.js} +22 -21
  102. package/package.json +6 -5
  103. package/src/shared/model-suggestion-retry.test.ts +34 -0
  104. package/src/shared/model-suggestion-retry.ts +23 -3
  105. package/src/shared/prompt-async-transport.test.ts +1 -1
  106. package/src/shared/prompt-async-transport.ts +16 -3
  107. package/dist/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
  108. package/dist/{index-2pgxcncf.js → index-dgs16axy.js} +0 -0
  109. package/dist/{index-9vqb5p1s.js → index-e20m7284.js} +0 -0
  110. package/dist/{index-8ketfacn.js → index-v10f1rjv.js} +3 -3
  111. package/dist/{index-tdn0zkw4.js → index-wk0n1cgt.js} +0 -0
  112. package/dist/v2/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
  113. package/dist/v2/{server-2x42esxd.js → server-g10mdym6.js} +0 -0
  114. package/dist/v2/{server-fa75w6gp.js → server-k2bzedxk.js} +0 -0
  115. package/dist/v2/{server-kn9n2qgd.js → server-tbe1femw.js} +3 -3
  116. /package/dist/v2/{server-83ygfha2.js → server-vbe4se57.js} +0 -0
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  inRootAsyncContext2,
3
+ getSqliteDatabasePath2,
3
4
  withSqliteBackgroundWriter2,
4
5
  withoutSqliteTransformPass2,
5
6
  isTransientSqliteError2
@@ -8,7 +9,6 @@ import {
8
9
  DEFAULT_LOCAL_EMBEDDING_MODEL
9
10
  } from "./server-th4y11y7.js";
10
11
  import {
11
- isUserHomeDirectory,
12
12
  setBootQuietPeriodForTests
13
13
  } from "./server-gvkm8xaj.js";
14
14
  import {
@@ -21,15 +21,15 @@ import {
21
21
  sanitizeDiagnosticText,
22
22
  log2
23
23
  } from "./server-f2xf5gcb.js";
24
- import {
25
- estimateTokens
26
- } from "./server-0ppsweh6.js";
27
24
  import {
28
25
  SYNAPSE_DEFAULT_MODEL,
29
26
  isSynapseEmbeddingTruncated,
30
27
  getSynapseBatchRequestKey,
31
28
  SynapseEmbeddingProvider
32
29
  } from "./server-rrqpvwqd.js";
30
+ import {
31
+ estimateTokens
32
+ } from "./server-0ppsweh6.js";
33
33
  import {
34
34
  DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS,
35
35
  CHUNK_WINDOW_SAFETY_RATIO,
@@ -47,7 +47,15 @@ import {
47
47
  countSessionCompartmentEmbedCoverage,
48
48
  countSessionCompartmentEmbedCoveragePolite,
49
49
  countUnembeddedSessionCompartmentsPolite
50
- } from "./server-vknbt0gq.js";
50
+ } from "./server-qhfvvfxj.js";
51
+ import {
52
+ acquireGitSweepLease,
53
+ renewGitSweepLease,
54
+ releaseGitSweepLease,
55
+ findMisScopedCompartmentChunkEmbeddingIdsForProject,
56
+ recordSessionProjectIdentity,
57
+ repairMisScopedCompartmentChunkEmbeddingsForProject
58
+ } from "./server-4gn3z5an.js";
51
59
  import {
52
60
  saveEmbeddingIfHashMatches,
53
61
  getMemoryEmbedCoverage,
@@ -59,11 +67,49 @@ import {
59
67
  resolveEmbeddingTextPrefixes,
60
68
  getEmbeddingProviderIdentity,
61
69
  LocalEmbeddingProvider
62
- } from "./server-2x42esxd.js";
70
+ } from "./server-g10mdym6.js";
63
71
  import {
64
72
  logSlowWriteTransaction
65
73
  } from "./server-6pmqg9m4.js";
66
74
 
75
+ // src/hooks/magic-context/embed-session-state.ts
76
+ var embedPauseBySession = new Set;
77
+ var embedRunStateBySession = new Map;
78
+ var activeEmbeddingSessions = new Map;
79
+ var autoEmbedAttemptedBySession = new Set;
80
+ var autoEmbedIdentityBySession = new Map;
81
+ var autoEmbedRetryAfterBySession = new Map;
82
+ function invalidateAutoEmbedSession(sessionId) {
83
+ autoEmbedAttemptedBySession.delete(sessionId);
84
+ autoEmbedIdentityBySession.delete(sessionId);
85
+ autoEmbedRetryAfterBySession.delete(sessionId);
86
+ }
87
+ function getEmbedDrainUiStatus(sessionId, progress) {
88
+ if (embedPauseBySession.has(sessionId)) {
89
+ return { status: "paused" };
90
+ }
91
+ const activeRun = embedRunStateBySession.get(sessionId);
92
+ if (activeRun && !activeRun.signal.aborted || progress?.kind === "embed" && progress.phase === "recomp") {
93
+ return { status: "running" };
94
+ }
95
+ if (progress?.kind === "embed" && (progress.phase === "failed" || progress.phase === "skipped") && progress.message) {
96
+ if (/provider/i.test(progress.message)) {
97
+ return { status: "stopped", detail: progress.message };
98
+ }
99
+ }
100
+ return { status: "idle" };
101
+ }
102
+ function clearEmbedSessionState(sessionId) {
103
+ activeEmbeddingSessions.delete(sessionId);
104
+ embedPauseBySession.delete(sessionId);
105
+ const ctrl = embedRunStateBySession.get(sessionId);
106
+ if (ctrl) {
107
+ ctrl.abort();
108
+ embedRunStateBySession.delete(sessionId);
109
+ }
110
+ invalidateAutoEmbedSession(sessionId);
111
+ }
112
+
67
113
  // src/shared/background-batch-drain.ts
68
114
  async function drainBackgroundBatches(step, options = {}) {
69
115
  const now = options.now ?? (() => performance.now());
@@ -145,6 +191,84 @@ function pruneSynapseBatchLedgerForProject(db, projectIdentity, ttlMs = SYNAPSE_
145
191
  // src/features/magic-context/project-embedding-registry.ts
146
192
  import { createHash as createHash3, randomUUID } from "node:crypto";
147
193
 
194
+ // src/features/magic-context/chunk-embedding-writer.ts
195
+ import { Worker } from "node:worker_threads";
196
+ function createChunkEmbeddingWriter(db) {
197
+ const path = getSqliteDatabasePath2(db);
198
+ if (!path)
199
+ return null;
200
+ if (path.startsWith("file:"))
201
+ throw new Error("chunk embedding writer requires a filesystem path");
202
+ const entry = new URL(import.meta.url.endsWith(".ts") ? "./chunk-embedding-write-worker.ts" : "./chunk-embedding-write-worker.js", import.meta.url);
203
+ const timeout = db.prepare("PRAGMA busy_timeout").get().timeout;
204
+ const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { path, harness: getHarness2(), timeout } }));
205
+ let pending;
206
+ let failure;
207
+ let deadline;
208
+ worker.on("message", (reply) => {
209
+ clearTimeout(deadline);
210
+ const request = pending;
211
+ pending = undefined;
212
+ if (reply.error)
213
+ request?.reject(new Error(reply.error));
214
+ else
215
+ request?.resolve(reply.value);
216
+ });
217
+ const fail = (error) => {
218
+ clearTimeout(deadline);
219
+ failure = error;
220
+ pending?.reject(error);
221
+ pending = undefined;
222
+ };
223
+ worker.on("error", fail);
224
+ worker.on("exit", (code) => fail(new Error(`chunk embedding writer exited (${code})`)));
225
+ worker.unref();
226
+ let queue = Promise.resolve();
227
+ const request = (message) => {
228
+ const result = queue.then(() => {
229
+ if (failure)
230
+ throw failure;
231
+ return new Promise((resolve, reject) => {
232
+ pending = { resolve, reject };
233
+ deadline = inRootAsyncContext2(() => setTimeout(() => {
234
+ fail(new Error("chunk embedding database operation timed out; coverage will be rechecked"));
235
+ worker.terminate();
236
+ }, 30000));
237
+ deadline.unref();
238
+ worker.postMessage(message);
239
+ });
240
+ });
241
+ queue = result.catch(() => {});
242
+ return result;
243
+ };
244
+ return {
245
+ async replace(rows, sourceKey) {
246
+ if (rows.some((row) => isSynapseEmbeddingTruncated(row.vector)))
247
+ return;
248
+ await request({ kind: "replace", rows, sourceKey });
249
+ },
250
+ project: (project, session) => request({ kind: "project", project, session }),
251
+ count: (project, session, model, tokens) => request({ kind: "count", project, session, model, tokens }),
252
+ candidates: (project, session, model, limit, excluded, tokens) => request({
253
+ kind: "candidates",
254
+ project,
255
+ session,
256
+ model,
257
+ limit,
258
+ excluded,
259
+ tokens
260
+ }),
261
+ backoff: (candidate, project, model) => request({ kind: "backoff", candidate, project, model }),
262
+ acquire: (project, holder) => request({ kind: "acquire", project, holder }),
263
+ renew: (project, holder) => request({ kind: "renew", project, holder }),
264
+ release: (project, holder) => request({ kind: "release", project, holder }),
265
+ async close() {
266
+ clearTimeout(deadline);
267
+ await worker.terminate();
268
+ }
269
+ };
270
+ }
271
+
148
272
  // src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
149
273
  var saveStatements = new WeakMap;
150
274
  var loadProjectStatements = new WeakMap;
@@ -327,142 +451,6 @@ function enforceProjectCap(db, projectPath, maxCommits) {
327
451
  return evicted;
328
452
  }
329
453
 
330
- // src/features/magic-context/git-commits/sweep-coordinator.ts
331
- var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
332
- var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
333
- var GIT_SWEEP_NON_INDEXABLE_REPROBE_MS = 24 * 60 * 60 * 1000;
334
- var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
335
- function runImmediate(db, body) {
336
- db.exec("BEGIN IMMEDIATE");
337
- const transactionStartedAt = performance.now();
338
- let committed = false;
339
- try {
340
- const result = body();
341
- db.exec("COMMIT");
342
- committed = true;
343
- logSlowWriteTransaction("git_sweep_lease", transactionStartedAt);
344
- return result;
345
- } finally {
346
- if (!committed) {
347
- try {
348
- db.exec("ROLLBACK");
349
- } catch {}
350
- }
351
- }
352
- }
353
- function rowToState(row) {
354
- return {
355
- projectPath: row.project_path,
356
- leaseHolder: row.lease_holder,
357
- leaseExpiresAt: row.lease_expires_at,
358
- lastSweptAt: row.last_swept_at
359
- };
360
- }
361
- function getGitSweepCoordinatorState(db, projectPath) {
362
- const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
363
- FROM git_sweep_coordinator
364
- WHERE project_path = ?`).get(projectPath);
365
- return row ? rowToState(row) : null;
366
- }
367
- function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
368
- const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
369
- const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
370
- return runImmediate(db, () => {
371
- const now = Date.now();
372
- const row = getGitSweepCoordinatorState(db, projectPath);
373
- if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
374
- return {
375
- acquired: false,
376
- projectPath,
377
- reason: "lease_active",
378
- leaseHolder: row.leaseHolder,
379
- leaseExpiresAt: row.leaseExpiresAt,
380
- lastSweptAt: row.lastSweptAt,
381
- nextAllowedAt: null
382
- };
383
- }
384
- if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
385
- const nextAllowedAt = row.lastSweptAt + cooldownMs;
386
- if (nextAllowedAt > now) {
387
- return {
388
- acquired: false,
389
- projectPath,
390
- reason: "cooldown_active",
391
- leaseHolder: row.leaseHolder,
392
- leaseExpiresAt: row.leaseExpiresAt,
393
- lastSweptAt: row.lastSweptAt,
394
- nextAllowedAt
395
- };
396
- }
397
- }
398
- const leaseExpiresAt = now + leaseTtlMs;
399
- db.prepare(`INSERT INTO git_sweep_coordinator (
400
- project_path,
401
- lease_holder,
402
- lease_expires_at,
403
- last_swept_at
404
- ) VALUES (?, ?, ?, NULL)
405
- ON CONFLICT(project_path) DO UPDATE SET
406
- lease_holder = excluded.lease_holder,
407
- lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
408
- return {
409
- acquired: true,
410
- projectPath,
411
- holderId,
412
- acquiredAt: now,
413
- leaseExpiresAt
414
- };
415
- });
416
- }
417
- function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
418
- return runImmediate(db, () => {
419
- const now = Date.now();
420
- const leaseExpiresAt = now + leaseTtlMs;
421
- const result = db.prepare(`UPDATE git_sweep_coordinator
422
- SET lease_expires_at = ?
423
- WHERE project_path = ?
424
- AND lease_holder = ?
425
- AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
426
- return result.changes === 1;
427
- });
428
- }
429
- function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
430
- return runImmediate(db, () => {
431
- const now = Date.now();
432
- const result = db.prepare(`UPDATE git_sweep_coordinator
433
- SET lease_holder = NULL,
434
- lease_expires_at = NULL,
435
- last_swept_at = ?
436
- WHERE project_path = ?
437
- AND lease_holder = ?
438
- AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
439
- return result.changes === 1;
440
- });
441
- }
442
- function parkGitSweepNonIndexable(db, projectPath, holderId, reprobeMs = GIT_SWEEP_NON_INDEXABLE_REPROBE_MS) {
443
- return runImmediate(db, () => {
444
- const now = Date.now();
445
- const sweptAt = now + reprobeMs - GIT_SWEEP_COOLDOWN_MS;
446
- const result = db.prepare(`UPDATE git_sweep_coordinator
447
- SET lease_holder = NULL,
448
- lease_expires_at = NULL,
449
- last_swept_at = ?
450
- WHERE project_path = ?
451
- AND lease_holder = ?
452
- AND lease_expires_at > ?`).run(sweptAt, projectPath, holderId, now);
453
- return result.changes === 1;
454
- });
455
- }
456
- function releaseGitSweepLease(db, projectPath, holderId) {
457
- runImmediate(db, () => {
458
- db.prepare(`UPDATE git_sweep_coordinator
459
- SET lease_holder = NULL,
460
- lease_expires_at = NULL
461
- WHERE project_path = ?
462
- AND lease_holder = ?`).run(projectPath, holderId);
463
- });
464
- }
465
-
466
454
  // src/features/magic-context/memory/embedding-openai.ts
467
455
  import { createHash as createHash2 } from "node:crypto";
468
456
 
@@ -979,88 +967,6 @@ class OpenAICompatibleEmbeddingProvider {
979
967
  }
980
968
  }
981
969
 
982
- // src/features/magic-context/session-project-storage.ts
983
- var SESSION_CHUNK_REPAIR_BATCH_SIZE = 100;
984
- var upsertSessionProjectStatements = new WeakMap;
985
- var repairSessionChunkProjectStatements = new WeakMap;
986
- var misScopedProjectChunkStatements = new WeakMap;
987
- var MIS_SCOPED_PROJECT_CHUNK_IDS_SQL = `
988
- SELECT e.id FROM compartment_chunk_embeddings e
989
- JOIN session_projects sp ON sp.session_id = e.session_id AND sp.harness = e.harness
990
- WHERE e.project_path = ? AND sp.project_path <> e.project_path
991
- UNION ALL
992
- SELECT e.id FROM session_projects sp
993
- JOIN compartment_chunk_embeddings e ON e.session_id = sp.session_id
994
- WHERE sp.project_path = ? AND e.harness = sp.harness AND e.project_path <> sp.project_path`;
995
- function getUpsertSessionProjectStatement(db) {
996
- let stmt = upsertSessionProjectStatements.get(db);
997
- if (!stmt) {
998
- stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
999
- VALUES (?, ?, ?, ?)
1000
- ON CONFLICT(session_id, harness) DO UPDATE SET
1001
- project_path = excluded.project_path,
1002
- updated_at = excluded.updated_at
1003
- WHERE session_projects.project_path <> excluded.project_path`);
1004
- upsertSessionProjectStatements.set(db, stmt);
1005
- }
1006
- return stmt;
1007
- }
1008
- function getRepairSessionChunkProjectStatement(db) {
1009
- let stmt = repairSessionChunkProjectStatements.get(db);
1010
- if (!stmt) {
1011
- stmt = db.prepare(`UPDATE compartment_chunk_embeddings
1012
- SET project_path = ?
1013
- WHERE id IN (
1014
- SELECT id
1015
- FROM compartment_chunk_embeddings
1016
- WHERE session_id = ?
1017
- AND harness = ?
1018
- AND project_path <> ?
1019
- LIMIT ?
1020
- )`);
1021
- repairSessionChunkProjectStatements.set(db, stmt);
1022
- }
1023
- return stmt;
1024
- }
1025
- function findMisScopedCompartmentChunkEmbeddingIdsForProject(db, projectPath) {
1026
- return db.prepare(`SELECT id FROM (${MIS_SCOPED_PROJECT_CHUNK_IDS_SQL}) LIMIT 25`).all(projectPath, projectPath).map(({ id }) => id);
1027
- }
1028
- function recordSessionProjectIdentity(db, sessionId, projectPath) {
1029
- if (!sessionId || !projectPath)
1030
- return;
1031
- if (!projectPath.startsWith("git:") && !projectPath.startsWith("dir:") && isUserHomeDirectory(projectPath))
1032
- return;
1033
- const harness = getHarness2();
1034
- const now = Date.now();
1035
- let previousProjectPath;
1036
- db.transaction(() => {
1037
- const existing = db.prepare("SELECT project_path FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, harness);
1038
- previousProjectPath = existing?.project_path;
1039
- getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
1040
- getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath, SESSION_CHUNK_REPAIR_BATCH_SIZE);
1041
- }).immediate();
1042
- return previousProjectPath === projectPath ? undefined : { previousProjectPath, projectPath };
1043
- }
1044
- function hasRecordedSessionProjectIdentity(db, sessionId) {
1045
- const row = db.prepare("SELECT 1 AS found FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, getHarness2());
1046
- return row?.found === 1;
1047
- }
1048
- function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath, ids = findMisScopedCompartmentChunkEmbeddingIdsForProject(db, projectPath)) {
1049
- if (!projectPath || ids.length === 0)
1050
- return 0;
1051
- return db.prepare(`UPDATE compartment_chunk_embeddings
1052
- SET project_path = (SELECT sp.project_path FROM session_projects sp
1053
- WHERE sp.session_id = compartment_chunk_embeddings.session_id
1054
- AND sp.harness = compartment_chunk_embeddings.harness)
1055
- WHERE id IN (${ids.map(() => "?").join(",")}) AND EXISTS (
1056
- SELECT 1 FROM session_projects sp
1057
- WHERE sp.session_id = compartment_chunk_embeddings.session_id
1058
- AND sp.harness = compartment_chunk_embeddings.harness
1059
- AND sp.project_path <> compartment_chunk_embeddings.project_path
1060
- AND (sp.project_path = ? OR compartment_chunk_embeddings.project_path = ?)
1061
- )`).run(...ids, projectPath, projectPath).changes;
1062
- }
1063
-
1064
970
  // src/features/magic-context/shadow-backfill-state.ts
1065
971
  var SHADOW_BACKFILL_PROVENANCE_KEY = "_magicContextShadowBackfill";
1066
972
  function parseJsonRecord(value) {
@@ -2756,7 +2662,16 @@ async function embedCompartmentChunkBatch(db, projectIdentity, batchSize, signal
2756
2662
  if (!snapshot?.historyEnabled || snapshot.chunkModelId === "off")
2757
2663
  return 0;
2758
2664
  repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectIdentity);
2759
- const candidates = await loadUnembeddedCompartmentChunkCandidatesPolite(db, projectIdentity, snapshot.chunkModelId, batchSize, getProjectEmbeddingMaxInputTokens2(projectIdentity), true);
2665
+ const priorModels = db.prepare(`SELECT COUNT(*) AS total,
2666
+ COALESCE(MAX(model_id = ?), 0) AS current
2667
+ FROM compartment_chunk_embeddings WHERE compartment_id = ?`);
2668
+ const candidates = await loadUnembeddedCompartmentChunkCandidatesPolite(db, projectIdentity, snapshot.chunkModelId, batchSize, getProjectEmbeddingMaxInputTokens2(projectIdentity), true, (candidate) => {
2669
+ const activity = activeEmbeddingSessions.get(candidate.sessionId);
2670
+ if (activity?.project === projectIdentity && activity.model === snapshot.chunkModelId && !embedPauseBySession.has(candidate.sessionId))
2671
+ return true;
2672
+ const prior = priorModels.get(snapshot.chunkModelId, candidate.id);
2673
+ return prior.total === 0 || prior.current !== 0;
2674
+ });
2760
2675
  if (candidates.length === 0)
2761
2676
  return 0;
2762
2677
  const { embedded } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, signal);
@@ -2766,7 +2681,7 @@ function getLastEmbeddingFailureForProject(projectIdentity) {
2766
2681
  const registration = projectRegistrations.get(projectIdentity);
2767
2682
  return registration?.provider?.getLastFailureReason?.() ?? null;
2768
2683
  }
2769
- async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal) {
2684
+ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal, writer) {
2770
2685
  const noWork = [];
2771
2686
  const failed = [];
2772
2687
  const failureReasons = [];
@@ -2781,7 +2696,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
2781
2696
  continue;
2782
2697
  const canonicalText = mappedText || buildCompartmentSummaryFallbackText(db, candidate.id);
2783
2698
  if (canonicalText.length === 0) {
2784
- recordChunkEmbedBackoff(db, candidate, projectIdentity, modelId);
2699
+ if (writer)
2700
+ await writer.backoff(candidate, projectIdentity, modelId);
2701
+ else
2702
+ recordChunkEmbedBackoff(db, candidate, projectIdentity, modelId);
2785
2703
  noWork.push(candidate.id);
2786
2704
  continue;
2787
2705
  }
@@ -2838,6 +2756,8 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
2838
2756
  if (result) {
2839
2757
  let writeSliceStarted = performance.now();
2840
2758
  for (const item of slice) {
2759
+ if (signal?.aborted || getProjectChunkEmbeddingModelId2(projectIdentity) !== modelId)
2760
+ break;
2841
2761
  if (persistedIds.has(item.candidate.id))
2842
2762
  continue;
2843
2763
  const vectors = item.windows.map((window) => result.vectors.get(`chunk:${item.candidate.id}:${window.windowIndex}`));
@@ -2852,7 +2772,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
2852
2772
  modelId,
2853
2773
  vector: vectors[index]
2854
2774
  }));
2855
- replaceCompartmentChunkEmbeddings(db, rows, item.windowSourceKey);
2775
+ if (writer)
2776
+ await writer.replace(rows, item.windowSourceKey);
2777
+ else
2778
+ replaceCompartmentChunkEmbeddings(db, rows, item.windowSourceKey);
2856
2779
  persistedIds.add(item.candidate.id);
2857
2780
  enqueueShadowEmbeddingItems2(projectIdentity, "chunk", [
2858
2781
  String(item.candidate.id)
@@ -2877,7 +2800,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
2877
2800
  if (!signal?.aborted) {
2878
2801
  for (const item of slice) {
2879
2802
  if (!persistedIds.has(item.candidate.id)) {
2880
- recordChunkEmbedBackoff(db, item.candidate, projectIdentity, modelId);
2803
+ if (writer)
2804
+ await writer.backoff(item.candidate, projectIdentity, modelId);
2805
+ else
2806
+ recordChunkEmbedBackoff(db, item.candidate, projectIdentity, modelId);
2881
2807
  failed.push(item.candidate.id);
2882
2808
  }
2883
2809
  }
@@ -2932,11 +2858,28 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
2932
2858
  if (!snapshot?.historyEnabled || snapshot.chunkModelId === "off") {
2933
2859
  return { status: "disabled", embedded: 0, total: 0 };
2934
2860
  }
2935
- recordSessionProjectIdentity(db, sessionId, projectIdentity);
2861
+ if (options?.automatic && !options.databaseWorker) {
2862
+ const worker = createChunkEmbeddingWriter(db);
2863
+ if (worker) {
2864
+ try {
2865
+ return await embedSessionCompartmentChunks2(db, projectIdentity, sessionId, {
2866
+ ...options,
2867
+ databaseWorker: worker
2868
+ });
2869
+ } finally {
2870
+ await worker.close();
2871
+ }
2872
+ }
2873
+ }
2874
+ const writer = options?.databaseWorker ?? null;
2875
+ if (writer)
2876
+ await writer.project(projectIdentity, sessionId);
2877
+ else
2878
+ recordSessionProjectIdentity(db, sessionId, projectIdentity);
2936
2879
  const maxInputTokens = getProjectEmbeddingMaxInputTokens2(projectIdentity);
2937
- const total = await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens);
2880
+ const total = writer ? await writer.count(projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) : await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens);
2938
2881
  const holderId = `session-embed-${randomUUID()}`;
2939
- const lease = acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
2882
+ const lease = writer ? await writer.acquire(projectIdentity, holderId) : acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
2940
2883
  if (!lease.acquired)
2941
2884
  return { status: "busy", embedded: 0, total };
2942
2885
  let leaseLost = false;
@@ -2946,9 +2889,9 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
2946
2889
  drainAbort.abort();
2947
2890
  else
2948
2891
  options?.signal?.addEventListener("abort", forwardCallerAbort, { once: true });
2949
- const renewal = inRootAsyncContext2(() => setInterval(() => {
2892
+ const renewal = inRootAsyncContext2(() => setInterval(async () => {
2950
2893
  try {
2951
- if (!renewGitSweepLease(db, projectIdentity, holderId)) {
2894
+ if (!(writer ? await writer.renew(projectIdentity, holderId) : renewGitSweepLease(db, projectIdentity, holderId))) {
2952
2895
  leaseLost = true;
2953
2896
  drainAbort.abort();
2954
2897
  }
@@ -2966,11 +2909,18 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
2966
2909
  try {
2967
2910
  options?.onProgress?.({ embedded, total });
2968
2911
  for (;; ) {
2969
- if (leaseLost || drainAbort.signal.aborted || isEmbeddingHostBusy2()) {
2912
+ if (leaseLost || drainAbort.signal.aborted || !options?.automatic && isEmbeddingHostBusy2() || getProjectEmbeddingSnapshot2(projectIdentity)?.generation !== snapshot.generation) {
2970
2913
  aborted = true;
2971
2914
  break;
2972
2915
  }
2973
- const candidates = await loadUnembeddedSessionChunkCandidatesPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds], maxInputTokens, true);
2916
+ if (options?.automatic && isEmbeddingHostBusy2()) {
2917
+ await new Promise((resolve) => setTimeout(resolve, 100));
2918
+ if (drainAbort.signal.aborted) {
2919
+ aborted = true;
2920
+ break;
2921
+ }
2922
+ }
2923
+ const candidates = writer ? await writer.candidates(projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds], maxInputTokens) : await loadUnembeddedSessionChunkCandidatesPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds], maxInputTokens, true);
2974
2924
  if (candidates.length === 0)
2975
2925
  break;
2976
2926
  const {
@@ -2978,8 +2928,8 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
2978
2928
  noWork,
2979
2929
  failed,
2980
2930
  failureReasons: batchFailureReasons
2981
- } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, drainAbort.signal);
2982
- if (leaseLost || !renewGitSweepLease(db, projectIdentity, holderId)) {
2931
+ } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, drainAbort.signal, writer);
2932
+ if (leaseLost || !(writer ? await writer.renew(projectIdentity, holderId) : renewGitSweepLease(db, projectIdentity, holderId))) {
2983
2933
  leaseLost = true;
2984
2934
  drainAbort.abort();
2985
2935
  aborted = true;
@@ -3007,7 +2957,10 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
3007
2957
  clearInterval(renewal);
3008
2958
  options?.signal?.removeEventListener("abort", forwardCallerAbort);
3009
2959
  try {
3010
- releaseGitSweepLease(db, projectIdentity, holderId);
2960
+ if (writer)
2961
+ await writer.release(projectIdentity, holderId);
2962
+ else
2963
+ releaseGitSweepLease(db, projectIdentity, holderId);
3011
2964
  } catch (error) {
3012
2965
  log2("[magic-context] embed drain: lease release failed (will TTL-expire):", error);
3013
2966
  }
@@ -3017,7 +2970,7 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
3017
2970
  if (aborted)
3018
2971
  return { status: "aborted", embedded, total, failed: failedIds.length };
3019
2972
  if (providerDown || failedIds.length > 0) {
3020
- const remaining = Math.max(failedIds.length, await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) - skipIds.length);
2973
+ const remaining = Math.max(failedIds.length, (writer ? await writer.count(projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) : await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens)) - skipIds.length);
3021
2974
  if (remaining > 0) {
3022
2975
  return {
3023
2976
  status: "stalled",
@@ -3152,4 +3105,4 @@ function _resetProjectEmbeddingRegistryForTests2() {
3152
3105
  setBootQuietPeriodForTests(null);
3153
3106
  }
3154
3107
 
3155
- export { drainBackgroundBatches, recordEmbeddingMeasurement, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitSha, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, OpenAICompatibleEmbeddingProvider, recordSessionProjectIdentity, hasRecordedSessionProjectIdentity, describeShadowBackfillWriteRefusal2, listShadowBackfillStalls2, getShadowBackfillStopReason2, markProjectLoadUntrusted2, contentSha2562, drainProjectEmbeddingIdentityMaintenance2, drainStaleEmbeddingIdentitiesForProject2, registerProjectEmbedding2, registerProjectShadowEmbedding2, getShadowEmbeddingMeasurementCohort2, getPrimaryEmbeddingMeasurementCohort2, embedShadowTextForProject2, enqueueShadowEmbeddingItems2, getShadowBackfillRemaining2, flushShadowEmbeddingBacklog2, registerProjectInObservationMode2, unregisterProjectShadowEmbedding2, unregisterProjectEmbedding2, getProjectEmbeddingSnapshot2, installProjectEmbeddingSearchBridge2, getProjectChunkEmbeddingModelId2, getProjectEmbeddingMaxInputTokens2, embedTextForProject2, embedBatchForProject2, embedItemsForProject2, embedUnembeddedMemoriesForProject2, embedUnembeddedMemoriesForProjectOutcome2, drainCommitBacklogForProject2, embedUnembeddedCompartmentChunksForProject2, embedSessionCompartmentChunks2, getEmbeddingCoverageStatus2, getAutoEmbeddingSessionCoverage2, sweepAllRegisteredProjects2, _setTestProviderFactoryForProject2, _resetProjectEmbeddingRegistryForTests2 };
3108
+ export { embedPauseBySession, embedRunStateBySession, activeEmbeddingSessions, autoEmbedAttemptedBySession, autoEmbedIdentityBySession, autoEmbedRetryAfterBySession, invalidateAutoEmbedSession, getEmbedDrainUiStatus, clearEmbedSessionState, drainBackgroundBatches, recordEmbeddingMeasurement, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitSha, enforceProjectCap, OpenAICompatibleEmbeddingProvider, describeShadowBackfillWriteRefusal2, listShadowBackfillStalls2, getShadowBackfillStopReason2, markProjectLoadUntrusted2, contentSha2562, drainProjectEmbeddingIdentityMaintenance2, drainStaleEmbeddingIdentitiesForProject2, registerProjectEmbedding2, registerProjectShadowEmbedding2, getShadowEmbeddingMeasurementCohort2, getPrimaryEmbeddingMeasurementCohort2, embedShadowTextForProject2, enqueueShadowEmbeddingItems2, getShadowBackfillRemaining2, flushShadowEmbeddingBacklog2, registerProjectInObservationMode2, unregisterProjectShadowEmbedding2, unregisterProjectEmbedding2, getProjectEmbeddingSnapshot2, installProjectEmbeddingSearchBridge2, getProjectChunkEmbeddingModelId2, getProjectEmbeddingMaxInputTokens2, embedTextForProject2, embedBatchForProject2, embedItemsForProject2, embedUnembeddedMemoriesForProject2, embedUnembeddedMemoriesForProjectOutcome2, drainCommitBacklogForProject2, embedUnembeddedCompartmentChunksForProject2, embedSessionCompartmentChunks2, getEmbeddingCoverageStatus2, getAutoEmbeddingSessionCoverage2, sweepAllRegisteredProjects2, _setTestProviderFactoryForProject2, _resetProjectEmbeddingRegistryForTests2 };
@@ -51,7 +51,7 @@ import {
51
51
  hasPendingMigrations,
52
52
  getMainThreadMigrationBodyCount,
53
53
  runMigrations
54
- } from "./server-fa75w6gp.js";
54
+ } from "./server-k2bzedxk.js";
55
55
  import {
56
56
  ensureColumn,
57
57
  installV95PerfSchema,
@@ -68,6 +68,12 @@ import {
68
68
  import {
69
69
  getErrorMessage
70
70
  } from "./server-y8v6yerm.js";
71
+ import {
72
+ closeQuietly
73
+ } from "./server-8ajstryz.js";
74
+ import {
75
+ logSlowWriteTransaction
76
+ } from "./server-6pmqg9m4.js";
71
77
  import {
72
78
  shouldEnforcePrivateStoragePermissions,
73
79
  ensureStorageDirectorySync,
@@ -76,12 +82,6 @@ import {
76
82
  copyStorageTreeSync,
77
83
  tightenStorageTreeSync
78
84
  } from "./server-fvnzcnww.js";
79
- import {
80
- closeQuietly
81
- } from "./server-8ajstryz.js";
82
- import {
83
- logSlowWriteTransaction
84
- } from "./server-6pmqg9m4.js";
85
85
 
86
86
  // src/features/magic-context/storage-db.ts
87
87
  import {
@@ -2704,4 +2704,4 @@ function getDatabasePersistenceError(db) {
2704
2704
  return persistenceErrorByDatabase.get(db) ?? null;
2705
2705
  }
2706
2706
 
2707
- export { FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, formatFailClosedBlockingSummary, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, startBootDeadline, getUnconfirmedMigrationHolders, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, BOOT_SQLITE_BUSY_TIMEOUT_MS, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, initializeDatabase, openDatabase, openCurrentDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError };
2707
+ export { FAIL_CLOSED_DOCTOR_COMMAND, formatFailClosedBlockingMessage, formatFailClosedBlockingSummary, createFailClosedBlockingError, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, startBootDeadline, getUnconfirmedMigrationHolders, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, BOOT_SQLITE_BUSY_TIMEOUT_MS, getDatabasePath, getPersistedSchemaVersion, enforceSchemaFence, setSqlitePragmaConfig, runSqliteOptimize, initializeDatabase, openDatabase, openCurrentDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError };