ds4-context-core 0.3.0-alpha.4 → 0.3.0-beta.1

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 (40) hide show
  1. package/README.md +5 -2
  2. package/dist/compaction/segmentation.d.ts +14 -0
  3. package/dist/compaction/segmentation.d.ts.map +1 -0
  4. package/dist/compaction/segmentation.js +81 -0
  5. package/dist/compaction/segmentation.js.map +1 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +5 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/manifest/context-manifest-storage.d.ts +63 -0
  11. package/dist/manifest/context-manifest-storage.d.ts.map +1 -0
  12. package/dist/manifest/context-manifest-storage.js +137 -0
  13. package/dist/manifest/context-manifest-storage.js.map +1 -0
  14. package/dist/manifest/context-manifest.d.ts +3 -0
  15. package/dist/manifest/context-manifest.d.ts.map +1 -1
  16. package/dist/persistence/database-client-lease.d.ts +46 -0
  17. package/dist/persistence/database-client-lease.d.ts.map +1 -0
  18. package/dist/persistence/database-client-lease.js +274 -0
  19. package/dist/persistence/database-client-lease.js.map +1 -0
  20. package/dist/persistence/repositories/context-manifest-repository.d.ts +24 -4
  21. package/dist/persistence/repositories/context-manifest-repository.d.ts.map +1 -1
  22. package/dist/persistence/repositories/context-manifest-repository.js +243 -44
  23. package/dist/persistence/repositories/context-manifest-repository.js.map +1 -1
  24. package/dist/persistence/sqlite.d.ts +14 -0
  25. package/dist/persistence/sqlite.d.ts.map +1 -1
  26. package/dist/persistence/sqlite.js +91 -22
  27. package/dist/persistence/sqlite.js.map +1 -1
  28. package/dist/persistence/storage-diagnostics.d.ts +51 -0
  29. package/dist/persistence/storage-diagnostics.d.ts.map +1 -0
  30. package/dist/persistence/storage-diagnostics.js +172 -0
  31. package/dist/persistence/storage-diagnostics.js.map +1 -0
  32. package/dist/persistence/storage-maintenance.d.ts +68 -0
  33. package/dist/persistence/storage-maintenance.d.ts.map +1 -0
  34. package/dist/persistence/storage-maintenance.js +676 -0
  35. package/dist/persistence/storage-maintenance.js.map +1 -0
  36. package/dist/persistence/write-coordinator.d.ts +1 -0
  37. package/dist/persistence/write-coordinator.d.ts.map +1 -1
  38. package/dist/persistence/write-coordinator.js +35 -11
  39. package/dist/persistence/write-coordinator.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,7 +1,16 @@
1
+ import { buildPersistedManifestProjection, storedManifestInventory, utf8ByteLength, } from "../../manifest/context-manifest-storage.js";
1
2
  import { SqliteWriteCoordinator } from "../write-coordinator.js";
3
+ export const MAX_RETAINED_CONTEXT_MANIFESTS = 128;
4
+ export const MAX_RETAINED_CALIBRATION_SAMPLES_PER_PROFILE = 200;
5
+ export const RETENTION_PRUNE_BATCH_ROWS = 32;
6
+ export const RETENTION_PRUNE_BATCH_BYTES = 8 * 1024 * 1024;
7
+ export const CALIBRATION_PRUNE_BATCH_ROWS = 32;
2
8
  function validTokenCount(value) {
3
9
  return Number.isSafeInteger(value) && value >= 0;
4
10
  }
11
+ function validEstimatorVersion(value) {
12
+ return /^[a-z0-9][a-z0-9._-]{0,79}$/iu.test(value);
13
+ }
5
14
  function providerUsage(input) {
6
15
  const totalInputTokens = input.inputTokens + input.cacheReadTokens + input.cacheWriteTokens;
7
16
  const rounded = (value) => Math.round(value * 1_000_000) / 1_000_000;
@@ -12,6 +21,21 @@ function providerUsage(input) {
12
21
  cacheWriteShare: totalInputTokens > 0 ? rounded(input.cacheWriteTokens / totalInputTokens) : 0,
13
22
  };
14
23
  }
24
+ function hydrateManifest(row) {
25
+ const manifest = parseManifest(row.manifest_json);
26
+ if (row.actual_tokens === null)
27
+ return manifest;
28
+ const usage = providerUsage({
29
+ inputTokens: row.input_tokens ?? row.actual_tokens,
30
+ cacheReadTokens: row.cache_read_tokens ?? 0,
31
+ cacheWriteTokens: row.cache_write_tokens ?? 0,
32
+ });
33
+ return {
34
+ ...manifest,
35
+ actualInputTokens: row.actual_tokens,
36
+ providerUsage: usage,
37
+ };
38
+ }
15
39
  export class ContextManifestRepository {
16
40
  database;
17
41
  writes;
@@ -20,90 +44,202 @@ export class ContextManifestRepository {
20
44
  this.writes = writes;
21
45
  }
22
46
  save(manifest) {
23
- this.writes.execute("context-manifest-save", () => this.database.prepare(`
24
- INSERT INTO context_manifests(
25
- manifest_id, session_id, created_at, provider, model,
26
- estimated_tokens, actual_tokens, manifest_json,
27
- prompt_hash, policy_version, planner_version,
28
- branch_leaf_id, context_window, output_reserve,
29
- hard_input_limit, target_input_tokens, pi_reported_tokens,
30
- input_tokens, cache_read_tokens, cache_write_tokens
31
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
32
- ON CONFLICT(manifest_id) DO UPDATE SET
33
- estimated_tokens = excluded.estimated_tokens,
34
- actual_tokens = excluded.actual_tokens,
35
- manifest_json = excluded.manifest_json,
36
- prompt_hash = excluded.prompt_hash,
37
- pi_reported_tokens = excluded.pi_reported_tokens,
38
- input_tokens = excluded.input_tokens,
39
- cache_read_tokens = excluded.cache_read_tokens,
40
- cache_write_tokens = excluded.cache_write_tokens
41
- `).run(manifest.id, manifest.sessionId, manifest.createdAt, manifest.provider, manifest.model, manifest.estimatedInputTokens, manifest.actualInputTokens ?? null, JSON.stringify(manifest), manifest.promptHash, manifest.policyVersion, manifest.plannerVersion, manifest.branchLeafId ?? null, manifest.contextWindow, manifest.outputReserve, manifest.hardInputLimit, manifest.targetInputTokens, manifest.piReportedContextTokens ?? null, manifest.providerUsage?.inputTokens ?? null, manifest.providerUsage?.cacheReadTokens ?? null, manifest.providerUsage?.cacheWriteTokens ?? null));
47
+ const projection = buildPersistedManifestProjection(manifest);
48
+ if (projection.status === "skipped-oversize")
49
+ return projection;
50
+ const pruned = this.writes.transaction("context-manifest-save", () => {
51
+ this.database.prepare(`
52
+ INSERT INTO context_manifests(
53
+ manifest_id, session_id, created_at, provider, model,
54
+ estimated_tokens, actual_tokens, manifest_json,
55
+ prompt_hash, policy_version, planner_version,
56
+ branch_leaf_id, context_window, output_reserve,
57
+ hard_input_limit, target_input_tokens, pi_reported_tokens,
58
+ input_tokens, cache_read_tokens, cache_write_tokens
59
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
60
+ ON CONFLICT(manifest_id) DO UPDATE SET
61
+ session_id = excluded.session_id,
62
+ created_at = excluded.created_at,
63
+ provider = excluded.provider,
64
+ model = excluded.model,
65
+ estimated_tokens = excluded.estimated_tokens,
66
+ actual_tokens = COALESCE(excluded.actual_tokens, context_manifests.actual_tokens),
67
+ manifest_json = excluded.manifest_json,
68
+ prompt_hash = excluded.prompt_hash,
69
+ policy_version = excluded.policy_version,
70
+ planner_version = excluded.planner_version,
71
+ branch_leaf_id = excluded.branch_leaf_id,
72
+ context_window = excluded.context_window,
73
+ output_reserve = excluded.output_reserve,
74
+ hard_input_limit = excluded.hard_input_limit,
75
+ target_input_tokens = excluded.target_input_tokens,
76
+ pi_reported_tokens = excluded.pi_reported_tokens,
77
+ input_tokens = COALESCE(excluded.input_tokens, context_manifests.input_tokens),
78
+ cache_read_tokens = COALESCE(excluded.cache_read_tokens, context_manifests.cache_read_tokens),
79
+ cache_write_tokens = COALESCE(excluded.cache_write_tokens, context_manifests.cache_write_tokens)
80
+ `).run(projection.manifest.id, projection.manifest.sessionId, projection.manifest.createdAt, projection.manifest.provider, projection.manifest.model, projection.manifest.estimatedInputTokens, projection.manifest.actualInputTokens ?? null, projection.serialized, projection.manifest.promptHash, projection.manifest.policyVersion, projection.manifest.plannerVersion, projection.manifest.branchLeafId ?? null, projection.manifest.contextWindow, projection.manifest.outputReserve, projection.manifest.hardInputLimit, projection.manifest.targetInputTokens, projection.manifest.piReportedContextTokens ?? null, projection.manifest.providerUsage?.inputTokens ?? null, projection.manifest.providerUsage?.cacheReadTokens ?? null, projection.manifest.providerUsage?.cacheWriteTokens ?? null);
81
+ return this.pruneContextManifests();
82
+ });
83
+ return {
84
+ status: "stored",
85
+ completeness: projection.inventory.completeness,
86
+ sourceBytes: projection.sourceBytes,
87
+ storedBytes: projection.storedBytes,
88
+ prunedManifests: pruned.rows,
89
+ prunedBytes: pruned.bytes,
90
+ };
42
91
  }
43
92
  get(manifestId) {
44
- const row = this.database.prepare("SELECT manifest_json, actual_tokens FROM context_manifests WHERE manifest_id = ?").get(manifestId);
45
- return row ? parseManifest(row.manifest_json) : undefined;
93
+ return this.getStored(manifestId)?.manifest;
94
+ }
95
+ getStored(manifestId) {
96
+ const row = this.database.prepare(`
97
+ SELECT manifest_json, actual_tokens, input_tokens, cache_read_tokens, cache_write_tokens
98
+ FROM context_manifests WHERE manifest_id = ?
99
+ `).get(manifestId);
100
+ return row ? storedManifest(row) : undefined;
46
101
  }
47
102
  getLatest(sessionId) {
103
+ return this.getLatestStored(sessionId)?.manifest;
104
+ }
105
+ getLatestStored(sessionId) {
48
106
  const row = this.database.prepare(`
49
- SELECT manifest_json, actual_tokens
107
+ SELECT manifest_json, actual_tokens, input_tokens, cache_read_tokens, cache_write_tokens
50
108
  FROM context_manifests
51
109
  WHERE session_id = ?
52
110
  ORDER BY created_at DESC, rowid DESC
53
111
  LIMIT 1
54
112
  `).get(sessionId);
55
- return row ? parseManifest(row.manifest_json) : undefined;
113
+ return row ? storedManifest(row) : undefined;
56
114
  }
57
- recordProviderUsage(manifestId, usage, createdAt) {
115
+ recordProviderUsage(manifestId, usage, createdAt, estimatorVersion = "chars-v1") {
58
116
  if (!validTokenCount(usage.inputTokens)
59
117
  || !validTokenCount(usage.cacheReadTokens)
60
118
  || !validTokenCount(usage.cacheWriteTokens)
61
119
  || !Number.isSafeInteger(createdAt)
62
- || createdAt < 0) {
120
+ || createdAt < 0
121
+ || !validEstimatorVersion(estimatorVersion)) {
63
122
  return this.get(manifestId);
64
123
  }
65
124
  const recordedUsage = providerUsage(usage);
66
125
  if (recordedUsage.totalInputTokens <= 0)
67
126
  return this.get(manifestId);
68
- return this.writes.transaction("context-manifest-provider-usage", () => {
127
+ const outcome = this.writes.transaction("context-manifest-provider-usage", () => {
69
128
  const row = this.database.prepare(`
70
- SELECT manifest_json, actual_tokens
129
+ SELECT provider, model, estimated_tokens, actual_tokens
71
130
  FROM context_manifests
72
131
  WHERE manifest_id = ?
73
132
  `).get(manifestId);
74
133
  if (!row)
75
- return undefined;
76
- const manifest = parseManifest(row.manifest_json);
134
+ return "missing";
77
135
  if (row.actual_tokens !== null)
78
- return manifest;
79
- const updated = {
80
- ...manifest,
81
- actualInputTokens: recordedUsage.totalInputTokens,
82
- providerUsage: recordedUsage,
83
- };
136
+ return "already-recorded";
84
137
  this.database.prepare(`
85
138
  UPDATE context_manifests
86
- SET actual_tokens = ?, input_tokens = ?, cache_read_tokens = ?,
87
- cache_write_tokens = ?, manifest_json = ?
88
- WHERE manifest_id = ?
89
- `).run(recordedUsage.totalInputTokens, recordedUsage.inputTokens, recordedUsage.cacheReadTokens, recordedUsage.cacheWriteTokens, JSON.stringify(updated), manifestId);
90
- if (manifest.estimatedInputTokens > 0) {
139
+ SET actual_tokens = ?, input_tokens = ?, cache_read_tokens = ?, cache_write_tokens = ?
140
+ WHERE manifest_id = ? AND actual_tokens IS NULL
141
+ `).run(recordedUsage.totalInputTokens, recordedUsage.inputTokens, recordedUsage.cacheReadTokens, recordedUsage.cacheWriteTokens, manifestId);
142
+ if (row.estimated_tokens !== null && row.estimated_tokens > 0) {
91
143
  this.database.prepare(`
92
144
  INSERT INTO token_calibration(
93
145
  provider, model, estimated, actual, ratio, created_at,
94
146
  manifest_id, estimator_version, input_tokens, cache_read_tokens, cache_write_tokens
95
147
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
96
- `).run(manifest.provider, manifest.model, manifest.estimatedInputTokens, recordedUsage.totalInputTokens, recordedUsage.totalInputTokens / manifest.estimatedInputTokens, createdAt, manifestId, manifest.modelAwareness?.calibration.estimator ?? "chars-v1", recordedUsage.inputTokens, recordedUsage.cacheReadTokens, recordedUsage.cacheWriteTokens);
148
+ `).run(row.provider, row.model, row.estimated_tokens, recordedUsage.totalInputTokens, recordedUsage.totalInputTokens / row.estimated_tokens, createdAt, manifestId, estimatorVersion, recordedUsage.inputTokens, recordedUsage.cacheReadTokens, recordedUsage.cacheWriteTokens);
149
+ this.pruneCalibrationSamples(row.provider, row.model, estimatorVersion);
97
150
  }
98
- return updated;
151
+ return "recorded";
99
152
  });
153
+ return outcome === "missing" ? undefined : this.get(manifestId);
100
154
  }
101
- recordActualInput(manifestId, actualInputTokens, createdAt) {
155
+ recordActualInput(manifestId, actualInputTokens, createdAt, estimatorVersion = "chars-v1") {
102
156
  return this.recordProviderUsage(manifestId, {
103
157
  inputTokens: actualInputTokens,
104
158
  cacheReadTokens: 0,
105
159
  cacheWriteTokens: 0,
106
- }, createdAt);
160
+ }, createdAt, estimatorVersion);
161
+ }
162
+ /** Applies unbounded retention only to an explicitly selected offline working copy. */
163
+ applyMaintenanceRetention() {
164
+ return this.writes.transaction("context-manifest-maintenance-prune", () => {
165
+ const stale = this.database.prepare(`
166
+ SELECT count(*) AS count,
167
+ COALESCE(sum(length(CAST(manifest_json AS BLOB))), 0) AS bytes
168
+ FROM context_manifests
169
+ WHERE rowid NOT IN (
170
+ SELECT rowid FROM context_manifests
171
+ ORDER BY created_at DESC, rowid DESC
172
+ LIMIT ?
173
+ )
174
+ `).get(MAX_RETAINED_CONTEXT_MANIFESTS);
175
+ this.database.prepare(`
176
+ UPDATE token_calibration
177
+ SET manifest_id = NULL
178
+ WHERE manifest_id IN (
179
+ SELECT manifest_id FROM context_manifests
180
+ WHERE rowid NOT IN (
181
+ SELECT rowid FROM context_manifests
182
+ ORDER BY created_at DESC, rowid DESC
183
+ LIMIT ?
184
+ )
185
+ )
186
+ `).run(MAX_RETAINED_CONTEXT_MANIFESTS);
187
+ this.database.prepare(`
188
+ DELETE FROM context_manifests
189
+ WHERE rowid NOT IN (
190
+ SELECT rowid FROM context_manifests
191
+ ORDER BY created_at DESC, rowid DESC
192
+ LIMIT ?
193
+ )
194
+ `).run(MAX_RETAINED_CONTEXT_MANIFESTS);
195
+ const calibrationDelete = this.database.prepare(`
196
+ DELETE FROM token_calibration
197
+ WHERE calibration_id IN (
198
+ SELECT calibration_id FROM (
199
+ SELECT calibration_id,
200
+ row_number() OVER (
201
+ PARTITION BY provider, model, estimator_version
202
+ ORDER BY created_at DESC, calibration_id DESC
203
+ ) AS retention_rank
204
+ FROM token_calibration
205
+ ) WHERE retention_rank > ?
206
+ )
207
+ `).run(MAX_RETAINED_CALIBRATION_SAMPLES_PER_PROFILE);
208
+ const retained = this.database.prepare(`
209
+ SELECT manifest_id, manifest_json
210
+ FROM context_manifests
211
+ ORDER BY created_at DESC, rowid DESC
212
+ `).all();
213
+ const update = this.database.prepare("UPDATE context_manifests SET manifest_json = ? WHERE manifest_id = ?");
214
+ const detach = this.database.prepare("UPDATE token_calibration SET manifest_id = NULL WHERE manifest_id = ?");
215
+ const remove = this.database.prepare("DELETE FROM context_manifests WHERE manifest_id = ?");
216
+ let rewrittenManifests = 0;
217
+ let rolledUpManifests = 0;
218
+ let skippedOversizeManifests = 0;
219
+ for (const row of retained) {
220
+ const projection = buildPersistedManifestProjection(parseManifest(row.manifest_json));
221
+ if (projection.status === "skipped-oversize") {
222
+ detach.run(row.manifest_id);
223
+ remove.run(row.manifest_id);
224
+ skippedOversizeManifests++;
225
+ continue;
226
+ }
227
+ if (projection.serialized !== row.manifest_json) {
228
+ update.run(projection.serialized, row.manifest_id);
229
+ rewrittenManifests++;
230
+ }
231
+ if (projection.inventory.completeness === "excluded-rollup")
232
+ rolledUpManifests++;
233
+ }
234
+ return {
235
+ prunedManifests: stale.count,
236
+ prunedManifestBytes: stale.bytes,
237
+ prunedCalibrationSamples: Number(calibrationDelete.changes),
238
+ rewrittenManifests,
239
+ rolledUpManifests,
240
+ skippedOversizeManifests,
241
+ };
242
+ });
107
243
  }
108
244
  listCalibrationSamples(provider, model, limit, estimatorVersion = "chars-v1") {
109
245
  if (!Number.isInteger(limit) || limit <= 0)
@@ -125,6 +261,69 @@ export class ContextManifestRepository {
125
261
  createdAt: row.created_at,
126
262
  }));
127
263
  }
264
+ pruneContextManifests() {
265
+ const row = this.database.prepare("SELECT count(*) AS count FROM context_manifests").get();
266
+ const excess = Math.max(0, row.count - MAX_RETAINED_CONTEXT_MANIFESTS);
267
+ if (excess === 0)
268
+ return { rows: 0, bytes: 0 };
269
+ const stale = this.database.prepare(`
270
+ SELECT manifest_id, length(CAST(manifest_json AS BLOB)) AS serialized_bytes
271
+ FROM context_manifests
272
+ ORDER BY created_at ASC, rowid ASC
273
+ LIMIT ?
274
+ `).all(Math.min(RETENTION_PRUNE_BATCH_ROWS, excess));
275
+ const selected = [];
276
+ let bytes = 0;
277
+ for (const candidate of stale) {
278
+ if (selected.length > 0 && bytes + candidate.serialized_bytes > RETENTION_PRUNE_BATCH_BYTES)
279
+ break;
280
+ selected.push(candidate);
281
+ bytes += candidate.serialized_bytes;
282
+ }
283
+ if (selected.length === 0)
284
+ return { rows: 0, bytes: 0 };
285
+ const placeholders = selected.map(() => "?").join(", ");
286
+ const manifestIds = selected.map((item) => item.manifest_id);
287
+ this.database.prepare(`
288
+ UPDATE token_calibration
289
+ SET manifest_id = NULL
290
+ WHERE manifest_id IN (${placeholders})
291
+ `).run(...manifestIds);
292
+ this.database.prepare(`
293
+ DELETE FROM context_manifests
294
+ WHERE manifest_id IN (${placeholders})
295
+ `).run(...manifestIds);
296
+ return { rows: selected.length, bytes };
297
+ }
298
+ pruneCalibrationSamples(provider, model, estimatorVersion) {
299
+ const stale = this.database.prepare(`
300
+ SELECT calibration_id FROM (
301
+ SELECT calibration_id, created_at,
302
+ row_number() OVER (
303
+ ORDER BY created_at DESC, calibration_id DESC
304
+ ) AS retention_rank
305
+ FROM token_calibration
306
+ WHERE provider = ? AND model = ? AND estimator_version = ?
307
+ )
308
+ WHERE retention_rank > ?
309
+ ORDER BY created_at ASC, calibration_id ASC
310
+ LIMIT ?
311
+ `).all(provider, model, estimatorVersion, MAX_RETAINED_CALIBRATION_SAMPLES_PER_PROFILE, CALIBRATION_PRUNE_BATCH_ROWS);
312
+ if (stale.length === 0)
313
+ return;
314
+ const placeholders = stale.map(() => "?").join(", ");
315
+ this.database.prepare(`
316
+ DELETE FROM token_calibration
317
+ WHERE calibration_id IN (${placeholders})
318
+ `).run(...stale.map((item) => item.calibration_id));
319
+ }
320
+ }
321
+ function storedManifest(row) {
322
+ const manifest = hydrateManifest(row);
323
+ return {
324
+ manifest,
325
+ inventory: storedManifestInventory(manifest, utf8ByteLength(row.manifest_json)),
326
+ };
128
327
  }
129
328
  function parseManifest(value) {
130
329
  const parsed = JSON.parse(value);
@@ -1 +1 @@
1
- {"version":3,"file":"context-manifest-repository.js","sourceRoot":"","sources":["../../../src/persistence/repositories/context-manifest-repository.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-manifest-repository.js","sourceRoot":"","sources":["../../../src/persistence/repositories/context-manifest-repository.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { MemoryRepository } from "./repositories/memory-repository.ts";
9
9
  import { ProjectKnowledgeRepository } from "./repositories/project-knowledge-repository.ts";
10
10
  import { SessionIndexRepository, type SessionIdentity, type SessionIndexStats } from "./repositories/session-index-repository.ts";
11
11
  import { SummaryRepository } from "./repositories/summary-repository.ts";
12
+ import { type StorageDiagnostics } from "./storage-diagnostics.ts";
12
13
  import { SqliteWriteCoordinator } from "./write-coordinator.ts";
13
14
  export type SessionRecord = SessionIdentity;
14
15
  export type { SessionIndexStats } from "./repositories/session-index-repository.ts";
@@ -25,12 +26,22 @@ export interface OpenDatabaseOptions {
25
26
  now?: number;
26
27
  busyTimeoutMs?: number;
27
28
  writeRetryTimeoutMs?: number;
29
+ /** Disabled only for explicit offline working copies managed by core maintenance APIs. */
30
+ clientLease?: boolean;
31
+ clientId?: string;
32
+ pid?: number;
33
+ }
34
+ export interface DatabaseCheckpointResult {
35
+ busy: number;
36
+ logFrames: number;
37
+ checkpointedFrames: number;
28
38
  }
29
39
  export declare class ContextDatabase {
30
40
  readonly path: string;
31
41
  private readonly database;
32
42
  private readonly logger;
33
43
  readonly writes: SqliteWriteCoordinator;
44
+ private readonly clientLease?;
34
45
  readonly schemaVersion: number;
35
46
  readonly migrations: readonly AppliedMigration[];
36
47
  readonly sessionIndex: SessionIndexRepository;
@@ -49,6 +60,9 @@ export declare class ContextDatabase {
49
60
  getSessionStats(sessionId: string): SessionIndexStats;
50
61
  listTables(): string[];
51
62
  health(): DatabaseHealth;
63
+ storageDiagnostics(activeProjectPath?: string): StorageDiagnostics;
64
+ optimize(): void;
65
+ checkpoint(mode?: "PASSIVE" | "FULL" | "RESTART" | "TRUNCATE"): DatabaseCheckpointResult;
52
66
  close(): void;
53
67
  private assertOpen;
54
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAA2C,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAC;AAC5F,OAAO,EACL,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAGL,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAoBD,qBAAa,eAAe;IAexB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,QAAQ,CAAC,MAAM,EAAE,sBAAsB;IAjBzC,QAAQ,CAAC,aAAa,SAA0B;IAChD,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,sBAAsB,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;IACtD,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;IAmBP,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,eAAe;IAyD7E,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAK5C,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB;IAKrD,UAAU,IAAI,MAAM,EAAE;IAUtB,MAAM,IAAI,cAAc;IAiBxB,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/persistence/sqlite.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@ import { MemoryRepository } from "./repositories/memory-repository.js";
12
12
  import { ProjectKnowledgeRepository } from "./repositories/project-knowledge-repository.js";
13
13
  import { SessionIndexRepository, } from "./repositories/session-index-repository.js";
14
14
  import { SummaryRepository } from "./repositories/summary-repository.js";
15
+ import { createDatabaseClientLease, } from "./database-client-lease.js";
16
+ import { collectStorageDiagnostics, unavailableStorageDiagnostics, } from "./storage-diagnostics.js";
15
17
  import { DEFAULT_BUSY_TIMEOUT_MS, DEFAULT_WRITE_RETRY_TIMEOUT_MS, SqliteWriteCoordinator, } from "./write-coordinator.js";
16
18
  function firstColumn(row) {
17
19
  if (!row || typeof row !== "object")
@@ -37,6 +39,7 @@ export class ContextDatabase {
37
39
  database;
38
40
  logger;
39
41
  writes;
42
+ clientLease;
40
43
  schemaVersion = CURRENT_SCHEMA_VERSION;
41
44
  migrations;
42
45
  sessionIndex;
@@ -49,11 +52,12 @@ export class ContextDatabase {
49
52
  summaries;
50
53
  projectKnowledge;
51
54
  closed = false;
52
- constructor(path, database, logger, writes, migrations) {
55
+ constructor(path, database, logger, writes, migrations, clientLease) {
53
56
  this.path = path;
54
57
  this.database = database;
55
58
  this.logger = logger;
56
59
  this.writes = writes;
60
+ this.clientLease = clientLease;
57
61
  this.migrations = migrations;
58
62
  this.sessionIndex = new SessionIndexRepository(database, writes);
59
63
  this.artifacts = new ArtifactRepository(database, writes);
@@ -78,17 +82,32 @@ export class ContextDatabase {
78
82
  || writeRetryTimeoutMs > 300_000) {
79
83
  throw new Error("writeRetryTimeoutMs must be an integer between busyTimeoutMs and 300000");
80
84
  }
85
+ let clientLease;
81
86
  if (!memory) {
82
87
  const directory = dirname(path);
83
88
  mkdirSync(directory, { recursive: true, mode: 0o700 });
84
89
  bestEffortChmod(directory, 0o700);
90
+ if (options.clientLease !== false) {
91
+ clientLease = createDatabaseClientLease(path, {
92
+ ...(options.clientId ? { clientId: options.clientId } : {}),
93
+ ...(options.pid ? { pid: options.pid } : {}),
94
+ ...(options.now !== undefined ? { createdAt: options.now } : {}),
95
+ });
96
+ }
97
+ }
98
+ let database;
99
+ try {
100
+ database = new DatabaseSync(path, {
101
+ enableForeignKeyConstraints: true,
102
+ enableDoubleQuotedStringLiterals: false,
103
+ allowExtension: false,
104
+ timeout: busyTimeoutMs,
105
+ });
106
+ }
107
+ catch (error) {
108
+ clientLease?.release();
109
+ throw error;
85
110
  }
86
- const database = new DatabaseSync(path, {
87
- enableForeignKeyConstraints: true,
88
- enableDoubleQuotedStringLiterals: false,
89
- allowExtension: false,
90
- timeout: busyTimeoutMs,
91
- });
92
111
  const writes = new SqliteWriteCoordinator(database, {
93
112
  busyTimeoutMs,
94
113
  retryTimeoutMs: writeRetryTimeoutMs,
@@ -112,10 +131,15 @@ export class ContextDatabase {
112
131
  busyTimeoutMs: writes.busyTimeoutMs,
113
132
  writeRetryTimeoutMs: writes.retryTimeoutMs,
114
133
  });
115
- return new ContextDatabase(path, database, logger, writes, migrations);
134
+ return new ContextDatabase(path, database, logger, writes, migrations, clientLease);
116
135
  }
117
136
  catch (error) {
118
- database.close();
137
+ try {
138
+ database.close();
139
+ }
140
+ finally {
141
+ clientLease?.release();
142
+ }
119
143
  throw error;
120
144
  }
121
145
  }
@@ -138,24 +162,69 @@ export class ContextDatabase {
138
162
  }
139
163
  health() {
140
164
  this.assertOpen();
141
- const quickCheck = String(firstColumn(this.database.prepare("PRAGMA quick_check").get()));
142
- const journalMode = String(firstColumn(this.database.prepare("PRAGMA journal_mode").get()));
143
- const foreignKeys = Number(firstColumn(this.database.prepare("PRAGMA foreign_keys").get())) === 1;
144
- const schemaVersion = Number(firstColumn(this.database.prepare("PRAGMA user_version").get()));
145
- return {
146
- ok: quickCheck === "ok" && foreignKeys && schemaVersion === CURRENT_SCHEMA_VERSION,
147
- quickCheck,
148
- journalMode,
149
- foreignKeys,
150
- schemaVersion,
151
- appliedMigrations: this.migrations.length,
152
- };
165
+ try {
166
+ const rawQuickCheck = String(firstColumn(this.database.prepare("PRAGMA quick_check").get()));
167
+ const quickCheck = rawQuickCheck === "ok" ? "ok" : "failed";
168
+ const journalMode = String(firstColumn(this.database.prepare("PRAGMA journal_mode").get()));
169
+ const foreignKeys = Number(firstColumn(this.database.prepare("PRAGMA foreign_keys").get())) === 1;
170
+ const schemaVersion = Number(firstColumn(this.database.prepare("PRAGMA user_version").get()));
171
+ return {
172
+ ok: quickCheck === "ok" && foreignKeys && schemaVersion === CURRENT_SCHEMA_VERSION,
173
+ quickCheck,
174
+ journalMode,
175
+ foreignKeys,
176
+ schemaVersion,
177
+ appliedMigrations: this.migrations.length,
178
+ };
179
+ }
180
+ catch {
181
+ return {
182
+ ok: false,
183
+ quickCheck: "unavailable",
184
+ journalMode: "unknown",
185
+ foreignKeys: false,
186
+ schemaVersion: -1,
187
+ appliedMigrations: this.migrations.length,
188
+ };
189
+ }
190
+ }
191
+ storageDiagnostics(activeProjectPath) {
192
+ this.assertOpen();
193
+ try {
194
+ return collectStorageDiagnostics(this.database, this.path, activeProjectPath);
195
+ }
196
+ catch {
197
+ return unavailableStorageDiagnostics();
198
+ }
199
+ }
200
+ optimize() {
201
+ this.assertOpen();
202
+ this.writes.execute("storage-optimize", () => this.database.exec("PRAGMA optimize"));
203
+ }
204
+ checkpoint(mode = "TRUNCATE") {
205
+ this.assertOpen();
206
+ return this.writes.execute("storage-checkpoint", () => {
207
+ const row = this.database.prepare(`PRAGMA wal_checkpoint(${mode})`).get();
208
+ if (!row || typeof row !== "object")
209
+ throw new Error("SQLite checkpoint returned no status");
210
+ const values = Object.values(row).map(Number);
211
+ return {
212
+ busy: values[0] ?? 0,
213
+ logFrames: values[1] ?? 0,
214
+ checkpointedFrames: values[2] ?? 0,
215
+ };
216
+ });
153
217
  }
154
218
  close() {
155
219
  if (this.closed)
156
220
  return;
157
221
  this.closed = true;
158
- this.database.close();
222
+ try {
223
+ this.database.close();
224
+ }
225
+ finally {
226
+ this.clientLease?.release();
227
+ }
159
228
  this.logger.debug("database.closed", { databasePath: this.path });
160
229
  }
161
230
  assertOpen() {