@modelprofile.com/flexharness 2.1.0 → 3.0.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.
@@ -1,24 +1,249 @@
1
1
  import * as plugins from './plugins.js';
2
- import { FlexHarnessStoreConflictError, FlexHarnessStoreFormatError, FlexHarnessValidationError, } from './errors.js';
3
- import { assertFlexHarnessSnapshot, cloneSerializable } from './utils.json.js';
4
- function validateSave(snapshot, expectedRevision) {
5
- assertFlexHarnessSnapshot(snapshot);
2
+ import { FlexHarnessStoreCommitUncertainError, FlexHarnessStoreConflictError, FlexHarnessStoreFormatError, FlexHarnessValidationError, } from './errors.js';
3
+ import { assertFlexPermissionSnapshot, assertFlexProjectionSnapshot, assertFlexScopeSnapshot, assertJsonSerializable, cloneSerializable, } from './utils.json.js';
4
+ function validateIdentifier(value, name) {
5
+ if (typeof value !== 'string' || !value.trim()) {
6
+ throw new FlexHarnessValidationError(`${name} must be a non-empty string.`);
7
+ }
8
+ }
9
+ function validateExpectedRevision(expectedRevision) {
6
10
  if (!Number.isSafeInteger(expectedRevision) || expectedRevision < 0) {
7
11
  throw new FlexHarnessValidationError('expectedRevision must be a non-negative integer.');
8
12
  }
13
+ }
14
+ function validateSnapshotSave(snapshot, expectedRevision, validator) {
15
+ validator(snapshot);
16
+ validateExpectedRevision(expectedRevision);
9
17
  if (snapshot.revision !== expectedRevision + 1) {
10
18
  throw new FlexHarnessStoreFormatError(`Snapshot revision ${snapshot.revision} must equal expected revision ${expectedRevision} plus one.`);
11
19
  }
12
20
  return cloneSerializable(snapshot);
13
21
  }
14
- export class InMemoryFlexHarnessStore {
22
+ function providerKey(storageKey, sessionId) {
23
+ validateIdentifier(storageKey, 'storageKey');
24
+ validateIdentifier(sessionId, 'sessionId');
25
+ return JSON.stringify([storageKey, sessionId]);
26
+ }
27
+ function assertProjectionSession(snapshot, sessionId) {
28
+ for (const message of snapshot.messages) {
29
+ if (message.sessionId !== sessionId) {
30
+ throw new FlexHarnessStoreFormatError(`Projection message "${message.messageId}" does not belong to session "${sessionId}".`);
31
+ }
32
+ }
33
+ for (const terminal of snapshot.stagedTerminals) {
34
+ if (terminal.userMessage.sessionId !== sessionId
35
+ || terminal.assistantMessage.sessionId !== sessionId) {
36
+ throw new FlexHarnessStoreFormatError(`Staged terminal "${terminal.runId}" does not belong to session "${sessionId}".`);
37
+ }
38
+ }
39
+ }
40
+ function normalizeJsonObjectUndefined(value, path = '$') {
41
+ const seen = new WeakSet();
42
+ const visit = (current, currentPath) => {
43
+ if (current === null
44
+ || typeof current === 'string'
45
+ || typeof current === 'boolean')
46
+ return current;
47
+ if (typeof current === 'number') {
48
+ if (!Number.isFinite(current)) {
49
+ throw new FlexHarnessStoreFormatError(`${currentPath} contains a non-finite number.`);
50
+ }
51
+ return current;
52
+ }
53
+ if (typeof current !== 'object') {
54
+ throw new FlexHarnessStoreFormatError(`${currentPath} contains ${typeof current}, which is not JSON-safe.`);
55
+ }
56
+ if (seen.has(current)) {
57
+ throw new FlexHarnessStoreFormatError(`${currentPath} contains a circular reference.`);
58
+ }
59
+ const prototype = Object.getPrototypeOf(current);
60
+ if (!Array.isArray(current) && prototype !== Object.prototype && prototype !== null) {
61
+ throw new FlexHarnessStoreFormatError(`${currentPath} contains a non-plain object.`);
62
+ }
63
+ if (Object.getOwnPropertySymbols(current).length > 0) {
64
+ throw new FlexHarnessStoreFormatError(`${currentPath} contains a symbol-keyed property.`);
65
+ }
66
+ seen.add(current);
67
+ if (Array.isArray(current)) {
68
+ const result = current.map((entry, index) => {
69
+ if (!(index in current) || entry === undefined) {
70
+ throw new FlexHarnessStoreFormatError(`${currentPath}[${index}] is not JSON-safe.`);
71
+ }
72
+ return visit(entry, `${currentPath}[${index}]`);
73
+ });
74
+ seen.delete(current);
75
+ return result;
76
+ }
77
+ const result = {};
78
+ for (const key of Object.getOwnPropertyNames(current)) {
79
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
80
+ if (!descriptor.enumerable || !('value' in descriptor)) {
81
+ throw new FlexHarnessStoreFormatError(`${currentPath}.${key} is not a plain JSON property.`);
82
+ }
83
+ if (descriptor.value !== undefined) {
84
+ result[key] = visit(descriptor.value, `${currentPath}.${key}`);
85
+ }
86
+ }
87
+ seen.delete(current);
88
+ return result;
89
+ };
90
+ const normalized = visit(value, path);
91
+ assertJsonSerializable(normalized, path);
92
+ return normalized;
93
+ }
94
+ function assertNonEmptyString(value, path) {
95
+ if (typeof value !== 'string' || !value.trim()) {
96
+ throw new FlexHarnessStoreFormatError(`${path} must be a non-empty string.`);
97
+ }
98
+ }
99
+ function assertNonNegativeInteger(value, path) {
100
+ if (!Number.isSafeInteger(value) || Number(value) < 0) {
101
+ throw new FlexHarnessStoreFormatError(`${path} must be a non-negative integer.`);
102
+ }
103
+ }
104
+ function assertExactKeys(value, keys, path) {
105
+ const invalidKey = Object.keys(value).find((key) => !keys.includes(key));
106
+ if (invalidKey) {
107
+ throw new FlexHarnessStoreFormatError(`${path}.${invalidKey} is not supported.`);
108
+ }
109
+ }
110
+ function assertRecord(value, path) {
111
+ if (!value
112
+ || typeof value !== 'object'
113
+ || Array.isArray(value)
114
+ || (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)) {
115
+ throw new FlexHarnessStoreFormatError(`${path} must be a plain object.`);
116
+ }
117
+ }
118
+ function createAgentEventSnapshot(sessionId, events, revision) {
119
+ return {
120
+ schemaVersion: 2,
121
+ sessionId,
122
+ revision,
123
+ updatedAt: events.reduce((latest, event) => Math.max(latest, event.timestamp), 0),
124
+ events: normalizeJsonObjectUndefined([...events], '$events'),
125
+ };
126
+ }
127
+ function validateAgentEventSnapshot(value, sessionId) {
128
+ assertJsonSerializable(value, '$snapshot');
129
+ try {
130
+ return plugins.validateAgentEventSnapshotV2(value, sessionId);
131
+ }
132
+ catch (error) {
133
+ throw new FlexHarnessStoreFormatError(`$snapshot is not a canonical schema-2 Agent event snapshot: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
134
+ }
135
+ }
136
+ function validateAgentEventArchive(value, sessionId, archiveId) {
137
+ assertJsonSerializable(value, '$archive');
138
+ try {
139
+ return plugins.validateAgentEventArchiveV2(value, sessionId, archiveId);
140
+ }
141
+ catch (error) {
142
+ throw new FlexHarnessStoreFormatError(`$archive is not a canonical schema-2 Agent event archive: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
143
+ }
144
+ }
145
+ function validateToolJobSnapshot(value) {
146
+ assertJsonSerializable(value, '$snapshot');
147
+ assertRecord(value, '$snapshot');
148
+ assertExactKeys(value, ['schemaVersion', 'revision', 'updatedAt', 'jobs'], '$snapshot');
149
+ if (value.schemaVersion !== 1) {
150
+ throw new FlexHarnessStoreFormatError('Tool job snapshot schemaVersion must be 1.');
151
+ }
152
+ assertNonNegativeInteger(value.revision, '$snapshot.revision');
153
+ assertNonNegativeInteger(value.updatedAt, '$snapshot.updatedAt');
154
+ if (!Array.isArray(value.jobs)) {
155
+ throw new FlexHarnessStoreFormatError('$snapshot.jobs must be an array.');
156
+ }
157
+ const executionIds = new Set();
158
+ for (let index = 0; index < value.jobs.length; index++) {
159
+ const path = `$snapshot.jobs[${index}]`;
160
+ assertRecord(value.jobs[index], path);
161
+ const job = value.jobs[index];
162
+ assertExactKeys(job, [
163
+ 'executionId',
164
+ 'type',
165
+ 'state',
166
+ 'request',
167
+ 'exitCode',
168
+ 'stdout',
169
+ 'stderr',
170
+ 'signal',
171
+ 'startedAt',
172
+ 'updatedAt',
173
+ 'finishedAt',
174
+ ], path);
175
+ assertNonEmptyString(job.executionId, `${path}.executionId`);
176
+ if (executionIds.has(job.executionId)) {
177
+ throw new FlexHarnessStoreFormatError(`$snapshot.jobs contains duplicate job "${job.executionId}".`);
178
+ }
179
+ executionIds.add(job.executionId);
180
+ assertNonEmptyString(job.type, `${path}.type`);
181
+ if (!['running', 'finished', 'failed', 'aborted'].includes(String(job.state))) {
182
+ throw new FlexHarnessStoreFormatError(`${path}.state is invalid.`);
183
+ }
184
+ if (job.request !== undefined) {
185
+ const requestPath = `${path}.request`;
186
+ assertRecord(job.request, requestPath);
187
+ assertExactKeys(job.request, ['type', 'command', 'cwd', 'timeoutMs', 'metadata'], requestPath);
188
+ assertNonEmptyString(job.request.type, `${requestPath}.type`);
189
+ if (job.request.command !== undefined) {
190
+ const commandPath = `${requestPath}.command`;
191
+ assertRecord(job.request.command, commandPath);
192
+ assertExactKeys(job.request.command, ['executable', 'args'], commandPath);
193
+ assertNonEmptyString(job.request.command.executable, `${commandPath}.executable`);
194
+ if (!Array.isArray(job.request.command.args)) {
195
+ throw new FlexHarnessStoreFormatError(`${commandPath}.args must be an array.`);
196
+ }
197
+ for (let argumentIndex = 0; argumentIndex < job.request.command.args.length; argumentIndex++) {
198
+ if (typeof job.request.command.args[argumentIndex] !== 'string') {
199
+ throw new FlexHarnessStoreFormatError(`${commandPath}.args[${argumentIndex}] must be a string.`);
200
+ }
201
+ }
202
+ }
203
+ if (job.request.cwd !== undefined && typeof job.request.cwd !== 'string') {
204
+ throw new FlexHarnessStoreFormatError(`${requestPath}.cwd must be a string.`);
205
+ }
206
+ if (job.request.timeoutMs !== undefined) {
207
+ assertNonNegativeInteger(job.request.timeoutMs, `${requestPath}.timeoutMs`);
208
+ }
209
+ if (job.request.metadata !== undefined) {
210
+ assertRecord(job.request.metadata, `${requestPath}.metadata`);
211
+ }
212
+ }
213
+ if (job.exitCode !== undefined && job.exitCode !== null && !Number.isSafeInteger(job.exitCode)) {
214
+ throw new FlexHarnessStoreFormatError(`${path}.exitCode must be an integer or null.`);
215
+ }
216
+ for (const key of ['stdout', 'stderr', 'signal']) {
217
+ if (job[key] !== undefined && typeof job[key] !== 'string') {
218
+ throw new FlexHarnessStoreFormatError(`${path}.${key} must be a string.`);
219
+ }
220
+ }
221
+ for (const key of ['startedAt', 'updatedAt', 'finishedAt']) {
222
+ if (job[key] !== undefined)
223
+ assertNonNegativeInteger(job[key], `${path}.${key}`);
224
+ }
225
+ }
226
+ return value;
227
+ }
228
+ function createToolJobSnapshot(jobs, revision) {
229
+ const snapshot = {
230
+ schemaVersion: 1,
231
+ revision,
232
+ updatedAt: Date.now(),
233
+ jobs: normalizeJsonObjectUndefined([...jobs], '$jobs'),
234
+ };
235
+ return validateToolJobSnapshot(snapshot);
236
+ }
237
+ class InMemoryScopeStore {
15
238
  snapshots = new Map();
16
239
  async load(storageKey) {
240
+ validateIdentifier(storageKey, 'storageKey');
17
241
  const snapshot = this.snapshots.get(storageKey);
18
242
  return snapshot ? cloneSerializable(snapshot) : undefined;
19
243
  }
20
244
  async save(storageKey, snapshot, expectedRevision) {
21
- const validated = validateSave(snapshot, expectedRevision);
245
+ validateIdentifier(storageKey, 'storageKey');
246
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexScopeSnapshot);
22
247
  const actualRevision = this.snapshots.get(storageKey)?.revision ?? 0;
23
248
  if (actualRevision !== expectedRevision) {
24
249
  throw new FlexHarnessStoreConflictError(storageKey, expectedRevision, actualRevision);
@@ -26,86 +251,392 @@ export class InMemoryFlexHarnessStore {
26
251
  this.snapshots.set(storageKey, validated);
27
252
  }
28
253
  }
29
- /**
30
- * Atomic and CAS-safe across instances in this process. It intentionally does not
31
- * claim cross-process safety because no operating-system lock is held.
32
- */
33
- export class JsonFileFlexHarnessStore {
34
- static fileQueues = new Map();
35
- directory;
36
- constructor(options) {
37
- if (!options.directory) {
38
- throw new FlexHarnessValidationError('JsonFileFlexHarnessStore requires a directory.');
254
+ class InMemoryProjectionStore {
255
+ snapshots = new Map();
256
+ async load(storageKey, sessionId) {
257
+ const key = providerKey(storageKey, sessionId);
258
+ const snapshot = this.snapshots.get(key);
259
+ return snapshot ? cloneSerializable(snapshot) : undefined;
260
+ }
261
+ async save(storageKey, sessionId, snapshot, expectedRevision) {
262
+ const key = providerKey(storageKey, sessionId);
263
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexProjectionSnapshot);
264
+ assertProjectionSession(validated, sessionId);
265
+ const actualRevision = this.snapshots.get(key)?.revision ?? 0;
266
+ if (actualRevision !== expectedRevision) {
267
+ throw new FlexHarnessStoreConflictError(key, expectedRevision, actualRevision);
39
268
  }
40
- this.directory = plugins.path.resolve(options.directory);
269
+ this.snapshots.set(key, validated);
41
270
  }
42
- async load(storageKey) {
43
- const filePath = this.filePath(storageKey);
44
- return JsonFileFlexHarnessStore.inFileQueue(filePath, async () => {
45
- await this.preparePath(filePath);
46
- return this.readSnapshot(filePath);
47
- });
271
+ async deleteSession(storageKey, sessionId) {
272
+ this.snapshots.delete(providerKey(storageKey, sessionId));
48
273
  }
49
- async save(storageKey, snapshot, expectedRevision) {
50
- const validated = validateSave(snapshot, expectedRevision);
51
- const filePath = this.filePath(storageKey);
52
- await JsonFileFlexHarnessStore.inFileQueue(filePath, async () => {
53
- await this.preparePath(filePath);
54
- const current = await this.readSnapshot(filePath);
55
- const actualRevision = current?.revision ?? 0;
56
- if (actualRevision !== expectedRevision) {
57
- throw new FlexHarnessStoreConflictError(storageKey, expectedRevision, actualRevision);
274
+ }
275
+ class InMemoryPermissionStore {
276
+ snapshots = new Map();
277
+ async load(storageKey, sessionId) {
278
+ const snapshot = this.snapshots.get(providerKey(storageKey, sessionId));
279
+ return snapshot ? cloneSerializable(snapshot) : undefined;
280
+ }
281
+ async save(storageKey, sessionId, snapshot, expectedRevision) {
282
+ const key = providerKey(storageKey, sessionId);
283
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexPermissionSnapshot);
284
+ const actualRevision = this.snapshots.get(key)?.revision ?? 0;
285
+ if (actualRevision !== expectedRevision) {
286
+ throw new FlexHarnessStoreConflictError(key, expectedRevision, actualRevision);
287
+ }
288
+ this.snapshots.set(key, validated);
289
+ }
290
+ async deleteSession(storageKey, sessionId) {
291
+ this.snapshots.delete(providerKey(storageKey, sessionId));
292
+ }
293
+ }
294
+ class InMemoryAgentEventStore {
295
+ sessionId;
296
+ eventSchemaVersion = 2;
297
+ snapshot;
298
+ archives = new Map();
299
+ constructor(sessionId) {
300
+ this.sessionId = sessionId;
301
+ }
302
+ assertSession(sessionId) {
303
+ if (sessionId !== this.sessionId) {
304
+ throw new FlexHarnessValidationError(`Agent event store is bound to session "${this.sessionId}", not "${sessionId}".`);
305
+ }
306
+ }
307
+ async load(sessionId) {
308
+ this.assertSession(sessionId);
309
+ return this.snapshot ? cloneSerializable(this.snapshot) : undefined;
310
+ }
311
+ async save(sessionId, events, expectedRevision) {
312
+ this.assertSession(sessionId);
313
+ validateExpectedRevision(expectedRevision);
314
+ const snapshot = createAgentEventSnapshot(sessionId, events, expectedRevision + 1);
315
+ validateAgentEventSnapshot(snapshot, sessionId);
316
+ const actualRevision = this.snapshot?.revision ?? 0;
317
+ if (actualRevision !== expectedRevision) {
318
+ throw new plugins.AgentEventStoreConflictError(sessionId, expectedRevision, actualRevision);
319
+ }
320
+ this.snapshot = cloneSerializable(snapshot);
321
+ return snapshot.revision;
322
+ }
323
+ async archive(archive) {
324
+ this.assertSession(archive.sessionId);
325
+ const normalized = normalizeJsonObjectUndefined(archive, '$archive');
326
+ const validated = validateAgentEventArchive(normalized, this.sessionId, archive.archiveId);
327
+ const existing = this.archives.get(archive.archiveId);
328
+ if (existing) {
329
+ if (JSON.stringify(existing.events.map((event) => event.id))
330
+ !== JSON.stringify(validated.events.map((event) => event.id))) {
331
+ throw new Error(`Archive "${archive.archiveId}" already exists with different events.`);
58
332
  }
59
- await this.writeSnapshot(filePath, validated);
60
- });
333
+ return;
334
+ }
335
+ this.archives.set(archive.archiveId, cloneSerializable(validated));
336
+ }
337
+ async loadArchive(sessionId, archiveId) {
338
+ this.assertSession(sessionId);
339
+ validateIdentifier(archiveId, 'archiveId');
340
+ const archive = this.archives.get(archiveId);
341
+ return archive ? cloneSerializable(archive) : undefined;
342
+ }
343
+ clear() {
344
+ this.snapshot = undefined;
345
+ this.archives.clear();
346
+ }
347
+ }
348
+ class InMemoryAgentEventStoreProvider {
349
+ stores = new Map();
350
+ getStore(storageKey, sessionId) {
351
+ const key = providerKey(storageKey, sessionId);
352
+ let store = this.stores.get(key);
353
+ if (!store) {
354
+ store = new InMemoryAgentEventStore(sessionId);
355
+ this.stores.set(key, store);
356
+ }
357
+ return store;
358
+ }
359
+ async deleteSession(storageKey, sessionId) {
360
+ const key = providerKey(storageKey, sessionId);
361
+ const store = this.stores.get(key);
362
+ if (!store)
363
+ return;
364
+ store.clear();
365
+ this.stores.delete(key);
366
+ }
367
+ }
368
+ class InMemoryToolJobStore {
369
+ snapshot;
370
+ async load(abortSignal) {
371
+ abortSignal?.throwIfAborted();
372
+ return this.snapshot ? cloneSerializable(this.snapshot) : undefined;
373
+ }
374
+ async save(jobs, expectedRevision, abortSignal) {
375
+ abortSignal?.throwIfAborted();
376
+ validateExpectedRevision(expectedRevision);
377
+ const snapshot = createToolJobSnapshot(jobs, expectedRevision + 1);
378
+ const actualRevision = this.snapshot?.revision ?? 0;
379
+ if (actualRevision !== expectedRevision) {
380
+ throw new plugins.ToolJobStoreConflictError(expectedRevision, actualRevision);
381
+ }
382
+ this.snapshot = cloneSerializable(snapshot);
383
+ return snapshot.revision;
384
+ }
385
+ clear() {
386
+ this.snapshot = undefined;
387
+ }
388
+ }
389
+ class InMemoryToolJobStoreProvider {
390
+ stores = new Map();
391
+ getStore(storageKey, sessionId) {
392
+ const key = providerKey(storageKey, sessionId);
393
+ let store = this.stores.get(key);
394
+ if (!store) {
395
+ store = new InMemoryToolJobStore();
396
+ this.stores.set(key, store);
397
+ }
398
+ return store;
399
+ }
400
+ async deleteSession(storageKey, sessionId) {
401
+ const key = providerKey(storageKey, sessionId);
402
+ const store = this.stores.get(key);
403
+ if (!store)
404
+ return;
405
+ store.clear();
406
+ this.stores.delete(key);
407
+ }
408
+ }
409
+ export class InMemoryFlexHarnessStores {
410
+ scopes = new InMemoryScopeStore();
411
+ projections = new InMemoryProjectionStore();
412
+ permissions = new InMemoryPermissionStore();
413
+ agentEvents = new InMemoryAgentEventStoreProvider();
414
+ jobs = new InMemoryToolJobStoreProvider();
415
+ }
416
+ const jsonDomains = ['scopes', 'projections', 'permissions', 'events', 'archives', 'jobs'];
417
+ function aggregateStoreErrors(errors, message) {
418
+ return errors.length === 1 ? errors[0] : new AggregateError(errors, message);
419
+ }
420
+ class JsonFileRoot {
421
+ static fileQueues = new Map();
422
+ directory;
423
+ retainedFileHandles = new Set();
424
+ fileHandleClosures = new Map();
425
+ constructor(directory) {
426
+ this.directory = plugins.path.resolve(directory);
61
427
  }
62
- static inFileQueue(filePath, operation) {
63
- const previous = JsonFileFlexHarnessStore.fileQueues.get(filePath) ?? Promise.resolve();
428
+ static inQueue(key, operation) {
429
+ const previous = JsonFileRoot.fileQueues.get(key) ?? Promise.resolve();
64
430
  const result = previous.catch(() => undefined).then(operation);
65
431
  const barrier = result.then(() => undefined, () => undefined);
66
- JsonFileFlexHarnessStore.fileQueues.set(filePath, barrier);
432
+ JsonFileRoot.fileQueues.set(key, barrier);
67
433
  void barrier.then(() => {
68
- if (JsonFileFlexHarnessStore.fileQueues.get(filePath) === barrier) {
69
- JsonFileFlexHarnessStore.fileQueues.delete(filePath);
70
- }
434
+ if (JsonFileRoot.fileQueues.get(key) === barrier)
435
+ JsonFileRoot.fileQueues.delete(key);
71
436
  });
72
437
  return result;
73
438
  }
74
- filePath(storageKey) {
75
- const digest = plugins.crypto.createHash('sha256').update(storageKey).digest('hex');
76
- return plugins.path.join(this.directory, `${digest}.json`);
439
+ digest(value) {
440
+ return plugins.crypto.createHash('sha256').update(value).digest('hex');
441
+ }
442
+ scopePath(domain, storageKey) {
443
+ validateIdentifier(storageKey, 'storageKey');
444
+ return plugins.path.join(this.directory, domain, `${this.digest(storageKey)}.json`);
445
+ }
446
+ sessionPath(domain, storageKey, sessionId) {
447
+ validateIdentifier(storageKey, 'storageKey');
448
+ validateIdentifier(sessionId, 'sessionId');
449
+ return plugins.path.join(this.directory, domain, this.digest(storageKey), `${this.digest(sessionId)}.json`);
450
+ }
451
+ archivePath(storageKey, sessionId, archiveId) {
452
+ validateIdentifier(archiveId, 'archiveId');
453
+ return plugins.path.join(this.archiveSessionPath(storageKey, sessionId), `${this.digest(archiveId)}.json`);
77
454
  }
78
- async preparePath(filePath) {
455
+ archiveSessionPath(storageKey, sessionId) {
456
+ validateIdentifier(storageKey, 'storageKey');
457
+ validateIdentifier(sessionId, 'sessionId');
458
+ return plugins.path.join(this.directory, 'archives', this.digest(storageKey), this.digest(sessionId));
459
+ }
460
+ eventQueueKey(storageKey, sessionId) {
461
+ return `event:${this.sessionPath('events', storageKey, sessionId)}`;
462
+ }
463
+ async prepareRoot() {
464
+ await this.retryRetainedFileHandles();
79
465
  await plugins.fs.mkdir(this.directory, { recursive: true, mode: 0o700 });
80
466
  await plugins.fs.chmod(this.directory, 0o700);
81
- await this.cleanupTemps(filePath);
467
+ await Promise.all(jsonDomains.map(async (domain) => {
468
+ const path = plugins.path.join(this.directory, domain);
469
+ await plugins.fs.mkdir(path, { recursive: true, mode: 0o700 });
470
+ await plugins.fs.chmod(path, 0o700);
471
+ }));
472
+ }
473
+ closeFileHandle(handle) {
474
+ const existing = this.fileHandleClosures.get(handle);
475
+ if (existing)
476
+ return existing;
477
+ let closure;
478
+ closure = handle.close().then(() => {
479
+ this.retainedFileHandles.delete(handle);
480
+ }, (error) => {
481
+ this.retainedFileHandles.add(handle);
482
+ throw error;
483
+ }).finally(() => {
484
+ if (this.fileHandleClosures.get(handle) === closure) {
485
+ this.fileHandleClosures.delete(handle);
486
+ }
487
+ });
488
+ this.fileHandleClosures.set(handle, closure);
489
+ return closure;
490
+ }
491
+ async retryRetainedFileHandles() {
492
+ const results = await Promise.allSettled([...this.retainedFileHandles].map((handle) => this.closeFileHandle(handle)));
493
+ const errors = results
494
+ .filter((result) => result.status === 'rejected')
495
+ .map((result) => result.reason);
496
+ if (errors.length > 0) {
497
+ throw aggregateStoreErrors(errors, 'Failed to close retained JSON store file handles.');
498
+ }
499
+ }
500
+ async dispose() {
501
+ await Promise.allSettled([...this.fileHandleClosures.values()]);
502
+ await this.retryRetainedFileHandles();
503
+ }
504
+ async prepareDirectory(directory) {
505
+ await this.prepareRoot();
506
+ await plugins.fs.mkdir(directory, { recursive: true, mode: 0o700 });
507
+ let current = directory;
508
+ while (current !== this.directory && current.startsWith(`${this.directory}${plugins.path.sep}`)) {
509
+ await plugins.fs.chmod(current, 0o700);
510
+ current = plugins.path.dirname(current);
511
+ }
82
512
  }
83
513
  async cleanupTemps(filePath) {
514
+ const directory = plugins.path.dirname(filePath);
84
515
  const prefix = `${plugins.path.basename(filePath)}.`;
85
- const entries = await plugins.fs.readdir(this.directory, { withFileTypes: true });
86
- await Promise.all(entries
516
+ const entries = await plugins.fs.readdir(directory, { withFileTypes: true });
517
+ const cleanupResults = await Promise.allSettled(entries
87
518
  .filter((entry) => entry.isFile() && entry.name.startsWith(prefix) && entry.name.endsWith('.tmp'))
88
519
  .map(async (entry) => {
89
520
  try {
90
- await plugins.fs.unlink(plugins.path.join(this.directory, entry.name));
521
+ await plugins.fs.unlink(plugins.path.join(directory, entry.name));
91
522
  }
92
523
  catch (error) {
93
- if (error.code !== 'ENOENT') {
524
+ if (error.code !== 'ENOENT')
94
525
  throw error;
95
- }
96
526
  }
97
527
  }));
528
+ const cleanupErrors = cleanupResults
529
+ .filter((result) => result.status === 'rejected')
530
+ .map((result) => result.reason);
531
+ if (cleanupErrors.length > 0) {
532
+ throw aggregateStoreErrors(cleanupErrors, `Failed to clean temporary files for ${filePath}.`);
533
+ }
98
534
  }
99
- async readSnapshot(filePath) {
535
+ async attemptDirectorySync(directory) {
536
+ let handle;
537
+ let syncError;
538
+ let closeError;
539
+ try {
540
+ handle = await plugins.fs.open(directory, 'r');
541
+ await handle.sync();
542
+ }
543
+ catch (error) {
544
+ syncError = error;
545
+ }
546
+ if (handle) {
547
+ try {
548
+ await this.closeFileHandle(handle);
549
+ }
550
+ catch (error) {
551
+ closeError = error;
552
+ }
553
+ }
554
+ return { syncError, closeError };
555
+ }
556
+ async writeExact(handle, serialized) {
557
+ let offset = 0;
558
+ while (offset < serialized.length) {
559
+ const { bytesWritten } = await handle.write(serialized, offset, serialized.length - offset, offset);
560
+ if (bytesWritten === 0) {
561
+ throw new Error('Writing the store temporary file made no progress.');
562
+ }
563
+ offset += bytesWritten;
564
+ }
565
+ }
566
+ async syncParentAfterWrite(filePath, serialized) {
567
+ const directory = plugins.path.dirname(filePath);
568
+ const firstAttempt = await this.attemptDirectorySync(directory);
569
+ if (firstAttempt.syncError === undefined && firstAttempt.closeError === undefined)
570
+ return;
571
+ let comparisonError;
572
+ try {
573
+ const persisted = await plugins.fs.readFile(filePath);
574
+ if (!persisted.equals(serialized)) {
575
+ throw new Error(`Destination bytes at ${filePath} do not match the committed write.`);
576
+ }
577
+ }
578
+ catch (error) {
579
+ comparisonError = error;
580
+ }
581
+ const retryAttempt = await this.attemptDirectorySync(directory);
582
+ if (comparisonError === undefined
583
+ && retryAttempt.syncError === undefined
584
+ && firstAttempt.closeError === undefined
585
+ && retryAttempt.closeError === undefined)
586
+ return;
587
+ const errors = [
588
+ firstAttempt.syncError,
589
+ firstAttempt.closeError,
590
+ comparisonError,
591
+ retryAttempt.syncError,
592
+ retryAttempt.closeError,
593
+ ].filter((error) => error !== undefined);
594
+ throw new FlexHarnessStoreCommitUncertainError(filePath, 'write', {
595
+ cause: aggregateStoreErrors(errors, `Could not confirm the store write at ${filePath}.`),
596
+ });
597
+ }
598
+ async syncParentAfterDelete(deletedPath, operation) {
599
+ const directory = plugins.path.dirname(deletedPath);
600
+ const firstAttempt = await this.attemptDirectorySync(directory);
601
+ if (firstAttempt.syncError === undefined && firstAttempt.closeError === undefined)
602
+ return;
603
+ let comparisonError;
604
+ try {
605
+ await plugins.fs.stat(deletedPath);
606
+ comparisonError = new Error(`Deleted path ${deletedPath} still exists.`);
607
+ }
608
+ catch (error) {
609
+ if (error.code !== 'ENOENT')
610
+ comparisonError = error;
611
+ }
612
+ const retryAttempt = await this.attemptDirectorySync(directory);
613
+ if (comparisonError === undefined
614
+ && retryAttempt.syncError === undefined
615
+ && firstAttempt.closeError === undefined
616
+ && retryAttempt.closeError === undefined)
617
+ return;
618
+ const errors = [
619
+ firstAttempt.syncError,
620
+ firstAttempt.closeError,
621
+ comparisonError,
622
+ retryAttempt.syncError,
623
+ retryAttempt.closeError,
624
+ ]
625
+ .filter((error) => error !== undefined);
626
+ throw new FlexHarnessStoreCommitUncertainError(deletedPath, operation, {
627
+ cause: aggregateStoreErrors(errors, `Could not confirm the store deletion at ${deletedPath}.`),
628
+ });
629
+ }
630
+ async read(filePath, validate) {
631
+ await this.prepareDirectory(plugins.path.dirname(filePath));
100
632
  let serialized;
101
633
  try {
102
634
  await plugins.fs.chmod(filePath, 0o600);
103
635
  serialized = await plugins.fs.readFile(filePath, 'utf8');
104
636
  }
105
637
  catch (error) {
106
- if (error.code === 'ENOENT') {
638
+ if (error.code === 'ENOENT')
107
639
  return undefined;
108
- }
109
640
  throw error;
110
641
  }
111
642
  let parsed;
@@ -113,44 +644,406 @@ export class JsonFileFlexHarnessStore {
113
644
  parsed = JSON.parse(serialized);
114
645
  }
115
646
  catch (error) {
116
- throw new FlexHarnessStoreFormatError(`Malformed JSON snapshot at ${filePath}.`, {
117
- cause: error,
118
- });
647
+ throw new FlexHarnessStoreFormatError(`Malformed JSON at ${filePath}.`, { cause: error });
119
648
  }
120
649
  try {
121
- assertFlexHarnessSnapshot(parsed);
650
+ return validate(parsed);
122
651
  }
123
652
  catch (error) {
124
653
  if (error instanceof FlexHarnessStoreFormatError) {
125
- throw new FlexHarnessStoreFormatError(`Invalid snapshot at ${filePath}: ${error.message}`, {
654
+ throw new FlexHarnessStoreFormatError(`Invalid JSON at ${filePath}: ${error.message}`, {
126
655
  cause: error,
127
656
  });
128
657
  }
129
658
  throw error;
130
659
  }
131
- return cloneSerializable(parsed);
132
660
  }
133
- async writeSnapshot(filePath, snapshot) {
661
+ async write(filePath, value) {
662
+ assertJsonSerializable(value);
663
+ const serialized = Buffer.from(`${JSON.stringify(value, null, 2)}\n`, 'utf8');
664
+ const directory = plugins.path.dirname(filePath);
665
+ await this.prepareDirectory(directory);
666
+ await this.cleanupTemps(filePath);
134
667
  const tempPath = `${filePath}.${process.pid}.${plugins.crypto.randomUUID()}.tmp`;
135
- let fileHandle;
668
+ let handle;
669
+ let operationError;
670
+ let operationFailed = false;
671
+ let renamed = false;
136
672
  try {
137
- fileHandle = await plugins.fs.open(tempPath, 'wx', 0o600);
138
- await fileHandle.writeFile(`${JSON.stringify(snapshot, null, 2)}\n`, 'utf8');
139
- await fileHandle.sync();
140
- await fileHandle.close();
141
- fileHandle = undefined;
142
- await plugins.fs.chmod(tempPath, 0o600);
673
+ handle = await plugins.fs.open(tempPath, 'wx', 0o600);
674
+ await this.writeExact(handle, serialized);
675
+ await handle.sync();
676
+ await this.closeFileHandle(handle);
677
+ handle = undefined;
143
678
  await plugins.fs.rename(tempPath, filePath);
144
- await plugins.fs.chmod(filePath, 0o600);
679
+ renamed = true;
680
+ await this.syncParentAfterWrite(filePath, serialized);
145
681
  }
146
- finally {
147
- await fileHandle?.close().catch(() => undefined);
148
- await plugins.fs.unlink(tempPath).catch((error) => {
149
- if (error.code !== 'ENOENT') {
150
- throw error;
151
- }
682
+ catch (error) {
683
+ operationError = error;
684
+ operationFailed = true;
685
+ }
686
+ const cleanupErrors = [];
687
+ if (handle) {
688
+ try {
689
+ await this.closeFileHandle(handle);
690
+ }
691
+ catch (error) {
692
+ cleanupErrors.push(error);
693
+ }
694
+ }
695
+ try {
696
+ await plugins.fs.unlink(tempPath);
697
+ }
698
+ catch (error) {
699
+ if (error.code !== 'ENOENT')
700
+ cleanupErrors.push(error);
701
+ }
702
+ if (!operationFailed && cleanupErrors.length === 0)
703
+ return;
704
+ if (renamed
705
+ && operationError instanceof FlexHarnessStoreCommitUncertainError
706
+ && cleanupErrors.length === 0) {
707
+ throw operationError;
708
+ }
709
+ const errors = [];
710
+ if (operationFailed)
711
+ errors.push(operationError);
712
+ errors.push(...cleanupErrors);
713
+ const cause = aggregateStoreErrors(errors, `Store write or cleanup failed at ${filePath}.`);
714
+ if (renamed) {
715
+ throw new FlexHarnessStoreCommitUncertainError(filePath, 'write', { cause });
716
+ }
717
+ throw cause;
718
+ }
719
+ async deleteFile(filePath) {
720
+ await this.prepareDirectory(plugins.path.dirname(filePath));
721
+ try {
722
+ await plugins.fs.unlink(filePath);
723
+ }
724
+ catch (error) {
725
+ if (error.code !== 'ENOENT')
726
+ throw error;
727
+ }
728
+ await this.syncParentAfterDelete(filePath, 'delete-file');
729
+ }
730
+ async deleteDirectory(directory) {
731
+ await this.prepareDirectory(plugins.path.dirname(directory));
732
+ await plugins.fs.rm(directory, { recursive: true, force: true });
733
+ await this.syncParentAfterDelete(directory, 'delete-directory');
734
+ }
735
+ }
736
+ class JsonScopeStore {
737
+ root;
738
+ constructor(root) {
739
+ this.root = root;
740
+ }
741
+ async load(storageKey) {
742
+ const filePath = this.root.scopePath('scopes', storageKey);
743
+ return JsonFileRoot.inQueue(filePath, async () => {
744
+ const snapshot = await this.root.read(filePath, (value) => {
745
+ assertFlexScopeSnapshot(value);
746
+ return value;
747
+ });
748
+ return snapshot ? cloneSerializable(snapshot) : undefined;
749
+ });
750
+ }
751
+ async save(storageKey, snapshot, expectedRevision) {
752
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexScopeSnapshot);
753
+ const filePath = this.root.scopePath('scopes', storageKey);
754
+ await JsonFileRoot.inQueue(filePath, async () => {
755
+ const current = await this.root.read(filePath, (value) => {
756
+ assertFlexScopeSnapshot(value);
757
+ return value;
152
758
  });
759
+ const actualRevision = current?.revision ?? 0;
760
+ if (actualRevision !== expectedRevision) {
761
+ throw new FlexHarnessStoreConflictError(storageKey, expectedRevision, actualRevision);
762
+ }
763
+ await this.root.write(filePath, validated);
764
+ });
765
+ }
766
+ }
767
+ class JsonProjectionStore {
768
+ root;
769
+ constructor(root) {
770
+ this.root = root;
771
+ }
772
+ async load(storageKey, sessionId) {
773
+ const filePath = this.root.sessionPath('projections', storageKey, sessionId);
774
+ return JsonFileRoot.inQueue(filePath, async () => {
775
+ const snapshot = await this.root.read(filePath, (value) => {
776
+ assertFlexProjectionSnapshot(value);
777
+ assertProjectionSession(value, sessionId);
778
+ return value;
779
+ });
780
+ return snapshot ? cloneSerializable(snapshot) : undefined;
781
+ });
782
+ }
783
+ async save(storageKey, sessionId, snapshot, expectedRevision) {
784
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexProjectionSnapshot);
785
+ assertProjectionSession(validated, sessionId);
786
+ const filePath = this.root.sessionPath('projections', storageKey, sessionId);
787
+ await JsonFileRoot.inQueue(filePath, async () => {
788
+ const current = await this.root.read(filePath, (value) => {
789
+ assertFlexProjectionSnapshot(value);
790
+ assertProjectionSession(value, sessionId);
791
+ return value;
792
+ });
793
+ const actualRevision = current?.revision ?? 0;
794
+ if (actualRevision !== expectedRevision) {
795
+ throw new FlexHarnessStoreConflictError(providerKey(storageKey, sessionId), expectedRevision, actualRevision);
796
+ }
797
+ await this.root.write(filePath, validated);
798
+ });
799
+ }
800
+ async deleteSession(storageKey, sessionId) {
801
+ const filePath = this.root.sessionPath('projections', storageKey, sessionId);
802
+ await JsonFileRoot.inQueue(filePath, () => this.root.deleteFile(filePath));
803
+ }
804
+ }
805
+ class JsonPermissionStore {
806
+ root;
807
+ constructor(root) {
808
+ this.root = root;
809
+ }
810
+ async load(storageKey, sessionId) {
811
+ const filePath = this.root.sessionPath('permissions', storageKey, sessionId);
812
+ return JsonFileRoot.inQueue(filePath, async () => {
813
+ const snapshot = await this.root.read(filePath, (value) => {
814
+ assertFlexPermissionSnapshot(value);
815
+ return value;
816
+ });
817
+ return snapshot ? cloneSerializable(snapshot) : undefined;
818
+ });
819
+ }
820
+ async save(storageKey, sessionId, snapshot, expectedRevision) {
821
+ const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexPermissionSnapshot);
822
+ const filePath = this.root.sessionPath('permissions', storageKey, sessionId);
823
+ await JsonFileRoot.inQueue(filePath, async () => {
824
+ const current = await this.root.read(filePath, (value) => {
825
+ assertFlexPermissionSnapshot(value);
826
+ return value;
827
+ });
828
+ const actualRevision = current?.revision ?? 0;
829
+ if (actualRevision !== expectedRevision) {
830
+ throw new FlexHarnessStoreConflictError(providerKey(storageKey, sessionId), expectedRevision, actualRevision);
831
+ }
832
+ await this.root.write(filePath, validated);
833
+ });
834
+ }
835
+ async deleteSession(storageKey, sessionId) {
836
+ const filePath = this.root.sessionPath('permissions', storageKey, sessionId);
837
+ await JsonFileRoot.inQueue(filePath, () => this.root.deleteFile(filePath));
838
+ }
839
+ }
840
+ async function clearJsonAgentEventSession(root, storageKey, sessionId) {
841
+ const filePath = root.sessionPath('events', storageKey, sessionId);
842
+ const archiveDirectory = root.archiveSessionPath(storageKey, sessionId);
843
+ await JsonFileRoot.inQueue(root.eventQueueKey(storageKey, sessionId), async () => {
844
+ await root.deleteFile(filePath);
845
+ await root.deleteDirectory(archiveDirectory);
846
+ });
847
+ }
848
+ class JsonAgentEventStore {
849
+ root;
850
+ storageKey;
851
+ sessionId;
852
+ eventSchemaVersion = 2;
853
+ constructor(root, storageKey, sessionId) {
854
+ this.root = root;
855
+ this.storageKey = storageKey;
856
+ this.sessionId = sessionId;
857
+ }
858
+ assertSession(sessionId) {
859
+ if (sessionId !== this.sessionId) {
860
+ throw new FlexHarnessValidationError(`Agent event store is bound to session "${this.sessionId}", not "${sessionId}".`);
153
861
  }
154
862
  }
863
+ async load(sessionId) {
864
+ this.assertSession(sessionId);
865
+ const filePath = this.root.sessionPath('events', this.storageKey, this.sessionId);
866
+ return JsonFileRoot.inQueue(this.root.eventQueueKey(this.storageKey, this.sessionId), async () => {
867
+ const snapshot = await this.root.read(filePath, (value) => validateAgentEventSnapshot(value, this.sessionId));
868
+ return snapshot ? cloneSerializable(snapshot) : undefined;
869
+ });
870
+ }
871
+ async save(sessionId, events, expectedRevision) {
872
+ this.assertSession(sessionId);
873
+ validateExpectedRevision(expectedRevision);
874
+ const snapshot = createAgentEventSnapshot(sessionId, events, expectedRevision + 1);
875
+ validateAgentEventSnapshot(snapshot, sessionId);
876
+ const filePath = this.root.sessionPath('events', this.storageKey, this.sessionId);
877
+ return JsonFileRoot.inQueue(this.root.eventQueueKey(this.storageKey, this.sessionId), async () => {
878
+ const current = await this.root.read(filePath, (value) => validateAgentEventSnapshot(value, this.sessionId));
879
+ const actualRevision = current?.revision ?? 0;
880
+ if (actualRevision !== expectedRevision) {
881
+ throw new plugins.AgentEventStoreConflictError(sessionId, expectedRevision, actualRevision);
882
+ }
883
+ await this.root.write(filePath, snapshot);
884
+ return snapshot.revision;
885
+ });
886
+ }
887
+ async archive(archive) {
888
+ this.assertSession(archive.sessionId);
889
+ const normalized = normalizeJsonObjectUndefined(archive, '$archive');
890
+ const validated = validateAgentEventArchive(normalized, this.sessionId, archive.archiveId);
891
+ const filePath = this.root.archivePath(this.storageKey, this.sessionId, archive.archiveId);
892
+ await JsonFileRoot.inQueue(this.root.eventQueueKey(this.storageKey, this.sessionId), async () => {
893
+ const current = await this.root.read(filePath, (value) => validateAgentEventArchive(value, this.sessionId, archive.archiveId));
894
+ if (current) {
895
+ if (JSON.stringify(current.events.map((event) => event.id))
896
+ !== JSON.stringify(validated.events.map((event) => event.id))) {
897
+ throw new Error(`Archive "${archive.archiveId}" already exists with different events.`);
898
+ }
899
+ return;
900
+ }
901
+ await this.root.write(filePath, validated);
902
+ });
903
+ }
904
+ async loadArchive(sessionId, archiveId) {
905
+ this.assertSession(sessionId);
906
+ const filePath = this.root.archivePath(this.storageKey, this.sessionId, archiveId);
907
+ return JsonFileRoot.inQueue(this.root.eventQueueKey(this.storageKey, this.sessionId), async () => {
908
+ const archive = await this.root.read(filePath, (value) => validateAgentEventArchive(value, this.sessionId, archiveId));
909
+ return archive ? cloneSerializable(archive) : undefined;
910
+ });
911
+ }
912
+ async clear() {
913
+ await clearJsonAgentEventSession(this.root, this.storageKey, this.sessionId);
914
+ }
915
+ }
916
+ class JsonAgentEventStoreProvider {
917
+ root;
918
+ stores = new Map();
919
+ constructor(root) {
920
+ this.root = root;
921
+ }
922
+ getStore(storageKey, sessionId) {
923
+ const key = providerKey(storageKey, sessionId);
924
+ let store = this.stores.get(key);
925
+ if (!store) {
926
+ store = new JsonAgentEventStore(this.root, storageKey, sessionId);
927
+ this.stores.set(key, store);
928
+ }
929
+ return store;
930
+ }
931
+ releaseSession(storageKey, sessionId) {
932
+ this.stores.delete(providerKey(storageKey, sessionId));
933
+ }
934
+ async deleteSession(storageKey, sessionId) {
935
+ const key = providerKey(storageKey, sessionId);
936
+ const store = this.stores.get(key);
937
+ if (store) {
938
+ await store.clear();
939
+ }
940
+ else {
941
+ await clearJsonAgentEventSession(this.root, storageKey, sessionId);
942
+ }
943
+ this.stores.delete(key);
944
+ }
945
+ }
946
+ async function clearJsonToolJobSession(root, storageKey, sessionId) {
947
+ const filePath = root.sessionPath('jobs', storageKey, sessionId);
948
+ await JsonFileRoot.inQueue(filePath, () => root.deleteFile(filePath));
949
+ }
950
+ class JsonToolJobStore {
951
+ root;
952
+ storageKey;
953
+ sessionId;
954
+ constructor(root, storageKey, sessionId) {
955
+ this.root = root;
956
+ this.storageKey = storageKey;
957
+ this.sessionId = sessionId;
958
+ }
959
+ filePath() {
960
+ return this.root.sessionPath('jobs', this.storageKey, this.sessionId);
961
+ }
962
+ async load(abortSignal) {
963
+ abortSignal?.throwIfAborted();
964
+ const filePath = this.filePath();
965
+ return JsonFileRoot.inQueue(filePath, async () => {
966
+ abortSignal?.throwIfAborted();
967
+ const snapshot = await this.root.read(filePath, validateToolJobSnapshot);
968
+ abortSignal?.throwIfAborted();
969
+ return snapshot ? cloneSerializable(snapshot) : undefined;
970
+ });
971
+ }
972
+ async save(jobs, expectedRevision, abortSignal) {
973
+ abortSignal?.throwIfAborted();
974
+ validateExpectedRevision(expectedRevision);
975
+ const snapshot = createToolJobSnapshot(jobs, expectedRevision + 1);
976
+ const filePath = this.filePath();
977
+ return JsonFileRoot.inQueue(filePath, async () => {
978
+ abortSignal?.throwIfAborted();
979
+ const current = await this.root.read(filePath, validateToolJobSnapshot);
980
+ const actualRevision = current?.revision ?? 0;
981
+ if (actualRevision !== expectedRevision) {
982
+ throw new plugins.ToolJobStoreConflictError(expectedRevision, actualRevision);
983
+ }
984
+ abortSignal?.throwIfAborted();
985
+ await this.root.write(filePath, snapshot);
986
+ return snapshot.revision;
987
+ });
988
+ }
989
+ async clear() {
990
+ await clearJsonToolJobSession(this.root, this.storageKey, this.sessionId);
991
+ }
992
+ }
993
+ class JsonToolJobStoreProvider {
994
+ root;
995
+ stores = new Map();
996
+ constructor(root) {
997
+ this.root = root;
998
+ }
999
+ getStore(storageKey, sessionId) {
1000
+ const key = providerKey(storageKey, sessionId);
1001
+ let store = this.stores.get(key);
1002
+ if (!store) {
1003
+ store = new JsonToolJobStore(this.root, storageKey, sessionId);
1004
+ this.stores.set(key, store);
1005
+ }
1006
+ return store;
1007
+ }
1008
+ releaseSession(storageKey, sessionId) {
1009
+ this.stores.delete(providerKey(storageKey, sessionId));
1010
+ }
1011
+ async deleteSession(storageKey, sessionId) {
1012
+ const key = providerKey(storageKey, sessionId);
1013
+ const store = this.stores.get(key);
1014
+ if (store) {
1015
+ await store.clear();
1016
+ }
1017
+ else {
1018
+ await clearJsonToolJobSession(this.root, storageKey, sessionId);
1019
+ }
1020
+ this.stores.delete(key);
1021
+ }
1022
+ }
1023
+ /**
1024
+ * Atomic and CAS-safe across instances in this process. No operating-system lock
1025
+ * is held, so this store intentionally does not claim cross-process safety.
1026
+ */
1027
+ export class JsonFileFlexHarnessStores {
1028
+ scopes;
1029
+ projections;
1030
+ permissions;
1031
+ agentEvents;
1032
+ jobs;
1033
+ root;
1034
+ constructor(options) {
1035
+ if (!options?.directory?.trim()) {
1036
+ throw new FlexHarnessValidationError('JsonFileFlexHarnessStores requires a directory.');
1037
+ }
1038
+ this.root = new JsonFileRoot(options.directory);
1039
+ this.scopes = new JsonScopeStore(this.root);
1040
+ this.projections = new JsonProjectionStore(this.root);
1041
+ this.permissions = new JsonPermissionStore(this.root);
1042
+ this.agentEvents = new JsonAgentEventStoreProvider(this.root);
1043
+ this.jobs = new JsonToolJobStoreProvider(this.root);
1044
+ }
1045
+ dispose() {
1046
+ return this.root.dispose();
1047
+ }
155
1048
  }
156
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdG9yZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN0b3Jlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLDJCQUEyQixFQUMzQiwwQkFBMEIsR0FDM0IsTUFBTSxhQUFhLENBQUM7QUFFckIsT0FBTyxFQUFFLHlCQUF5QixFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0UsU0FBUyxZQUFZLENBQ25CLFFBQThCLEVBQzlCLGdCQUF3QjtJQUV4Qix5QkFBeUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLGdCQUFnQixHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3BFLE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFDRCxJQUFJLFFBQVEsQ0FBQyxRQUFRLEtBQUssZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLDJCQUEyQixDQUNuQyxxQkFBcUIsUUFBUSxDQUFDLFFBQVEsaUNBQWlDLGdCQUFnQixZQUFZLENBQ3BHLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNyQyxDQUFDO0FBRUQsTUFBTSxPQUFPLHdCQUF3QjtJQUNsQixTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQWdDLENBQUM7SUFFOUQsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFrQjtRQUNsQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoRCxPQUFPLFFBQVEsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMs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
1049
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdG9yZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN0b3Jlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsb0NBQW9DLEVBQ3BDLDZCQUE2QixFQUM3QiwyQkFBMkIsRUFDM0IsMEJBQTBCLEdBQzNCLE1BQU0sYUFBYSxDQUFDO0FBWXJCLE9BQU8sRUFDTCw0QkFBNEIsRUFDNUIsNEJBQTRCLEVBQzVCLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsaUJBQWlCLEdBQ2xCLE1BQU0saUJBQWlCLENBQUM7QUFPekIsU0FBUyxrQkFBa0IsQ0FBQyxLQUFhLEVBQUUsSUFBWTtJQUNyRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyxHQUFHLElBQUksOEJBQThCLENBQUMsQ0FBQztJQUM5RSxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsZ0JBQXdCO0lBQ3hELElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLElBQUksZ0JBQWdCLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDcEUsTUFBTSxJQUFJLDBCQUEwQixDQUFDLGtEQUFrRCxDQUFDLENBQUM7SUFDM0YsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUMzQixRQUF3QixFQUN4QixnQkFBd0IsRUFDeEIsU0FBNkM7SUFFN0MsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BCLHdCQUF3QixDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDM0MsSUFBSSxRQUFRLENBQUMsUUFBUSxLQUFLLGdCQUFnQixHQUFHLENBQUMsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBSSwyQkFBMkIsQ0FDbkMs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