stitchkit 0.77.0 → 0.79.0

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 (99) hide show
  1. package/dist/agent-runtime-browser.js +53 -581
  2. package/dist/agent-runtime-coding-tools.js +6 -5
  3. package/dist/agent-runtime-harness.js +20 -93
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +65 -61
  6. package/dist/application/decisions.d.ts +28 -25
  7. package/dist/application/decisions.d.ts.map +1 -1
  8. package/dist/application/kernel.d.ts +2 -0
  9. package/dist/application/kernel.d.ts.map +1 -1
  10. package/dist/application/keyspace.d.ts +11 -1
  11. package/dist/application/keyspace.d.ts.map +1 -1
  12. package/dist/application/schedule.d.ts.map +1 -1
  13. package/dist/application/schemas.d.ts +2 -0
  14. package/dist/application/schemas.d.ts.map +1 -1
  15. package/dist/application/server-resource.d.ts.map +1 -1
  16. package/dist/application/watch-hub.d.ts.map +1 -1
  17. package/dist/application-diagnostic-journal.d.ts +21 -0
  18. package/dist/application-diagnostic-journal.d.ts.map +1 -0
  19. package/dist/application-diagnostic-journal.js +632 -0
  20. package/dist/application-opentelemetry.js +3 -2
  21. package/dist/application-schemas.js +14 -98
  22. package/dist/application.d.ts +1 -2
  23. package/dist/application.d.ts.map +1 -1
  24. package/dist/application.js +155 -882
  25. package/dist/cli.js +13 -11
  26. package/dist/contract/index.js +15 -10
  27. package/dist/files/boundary.d.ts.map +1 -1
  28. package/dist/files.js +1 -1
  29. package/dist/{index-7b188kmz.js → index-2qzskm8h.js} +15 -1
  30. package/dist/{index-k2zczx1g.js → index-2rwwmr7v.js} +3 -3
  31. package/dist/{index-8eywc9zv.js → index-3gye9wzb.js} +6 -3
  32. package/dist/index-4fpa9dy2.js +51 -0
  33. package/dist/{index-7qy2ex0m.js → index-5mtc969c.js} +2 -2
  34. package/dist/index-5s3zajp8.js +192 -0
  35. package/dist/{index-3cwck0rm.js → index-6s7n2v50.js} +60 -374
  36. package/dist/{index-s4c8wy8m.js → index-758zx2ha.js} +11 -90
  37. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  38. package/dist/{index-58jzmnn4.js → index-7ag81v2f.js} +355 -34
  39. package/dist/index-7gnkny4z.js +326 -0
  40. package/dist/index-7zbps32p.js +89 -0
  41. package/dist/index-85vfqd7m.js +135 -0
  42. package/dist/{index-m668wzyc.js → index-9s6z8vgf.js} +17 -141
  43. package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
  44. package/dist/index-b9aefrqd.js +20 -0
  45. package/dist/index-dre2ywck.js +48 -0
  46. package/dist/{index-nemjkxjp.js → index-dwf1f2ap.js} +16 -12
  47. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  48. package/dist/{index-ezmn6ac6.js → index-dxesg10d.js} +4 -4
  49. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  50. package/dist/{index-jqtsc9mj.js → index-egaabxkz.js} +3 -3
  51. package/dist/{index-vc1b0b1b.js → index-evcnmsc3.js} +49 -8
  52. package/dist/{index-nt1mp8km.js → index-fxz0v7vg.js} +84 -84
  53. package/dist/index-h4pj6fta.js +87 -0
  54. package/dist/{index-1rxswfbv.js → index-hb5pf3s4.js} +1 -1
  55. package/dist/{index-t8qyvrvg.js → index-k9ay6v6d.js} +21 -272
  56. package/dist/index-kzfs85xp.js +9 -0
  57. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  58. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  59. package/dist/index-p7hgdyhb.js +22 -0
  60. package/dist/index-pq95qkbf.js +0 -0
  61. package/dist/index-t0z5p5w6.js +318 -0
  62. package/dist/{index-s2rchahr.js → index-vwp69871.js} +13 -11
  63. package/dist/index-wc4x00bn.js +103 -0
  64. package/dist/{index-da1aqnhb.js → index-xcetq6j3.js} +8 -6
  65. package/dist/{index-f6n5n7nz.js → index-y01f4223.js} +33 -126
  66. package/dist/{index-35z5h2ty.js → index-ywd0y6m1.js} +18 -218
  67. package/dist/index.js +65 -1588
  68. package/dist/internal/deadline.d.ts +17 -0
  69. package/dist/internal/deadline.d.ts.map +1 -0
  70. package/dist/live.js +15 -89
  71. package/dist/node.js +17 -15
  72. package/dist/observability/context.d.ts.map +1 -1
  73. package/dist/observability/index.js +7 -6
  74. package/dist/primitives.js +5 -2
  75. package/dist/react.js +1 -1
  76. package/dist/remote.js +7 -6
  77. package/dist/server/event-bus.d.ts.map +1 -1
  78. package/dist/server/index.js +26 -38
  79. package/dist/telegram.js +1 -1
  80. package/dist/testing.js +86 -97
  81. package/dist/tool-invoker.js +11 -9
  82. package/dist/tools/async-operation-contract.d.ts +61 -0
  83. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  84. package/dist/tools/async-operation.d.ts +2 -47
  85. package/dist/tools/async-operation.d.ts.map +1 -1
  86. package/dist/tools/view-file-contract.d.ts +98 -0
  87. package/dist/tools/view-file-contract.d.ts.map +1 -0
  88. package/dist/tools/view-file.d.ts +4 -83
  89. package/dist/tools/view-file.d.ts.map +1 -1
  90. package/dist/tools-contract.d.ts +29 -0
  91. package/dist/tools-contract.d.ts.map +1 -0
  92. package/dist/tools-contract.js +24 -0
  93. package/dist/tools.d.ts +3 -3
  94. package/dist/tools.d.ts.map +1 -1
  95. package/dist/tools.js +59 -95
  96. package/llms-full.txt +146 -14
  97. package/package.json +14 -7
  98. package/dist/index-ksp6e2ye.js +0 -24
  99. package/dist/index-vj3vvpaa.js +0 -307
@@ -0,0 +1,632 @@
1
+ import {
2
+ DiagnosticJournalCloseResultSchema,
3
+ DiagnosticJournalFrameSchema,
4
+ DiagnosticJournalLimitsSchema,
5
+ DiagnosticJournalLockPolicySchema,
6
+ DiagnosticJournalStatusSchema,
7
+ DiagnosticJournalSubmitResultSchema,
8
+ DiagnosticJournalWaitResultSchema,
9
+ parseDiagnosticJournalMode
10
+ } from "./index-wc4x00bn.js";
11
+ import {
12
+ createBoundedChannel
13
+ } from "./index-7gnkny4z.js";
14
+ import {
15
+ isRecord
16
+ } from "./index-77fekveh.js";
17
+
18
+ // src/application/diagnostic-journal.ts
19
+ import { randomUUID } from "node:crypto";
20
+
21
+ // src/application/diagnostic-journal-manager.ts
22
+ import { z } from "zod";
23
+
24
+ // src/application/diagnostic-journal-storage.ts
25
+ import { constants as constants2 } from "node:fs";
26
+ import { lstat, open as open2, readdir, realpath, rename, unlink as unlink2 } from "node:fs/promises";
27
+ import { basename, dirname, isAbsolute, resolve } from "node:path";
28
+
29
+ // src/application/diagnostic-journal-lock.ts
30
+ import { execFile } from "node:child_process";
31
+ import { constants } from "node:fs";
32
+ import { open, readFile, unlink } from "node:fs/promises";
33
+ import { hostname, platform } from "node:os";
34
+ import { promisify } from "node:util";
35
+ function isExisting(error) {
36
+ return isRecord(error) && error.code === "EEXIST";
37
+ }
38
+ function readOwner(text) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(text);
42
+ } catch {
43
+ return;
44
+ }
45
+ if (!isRecord(parsed))
46
+ return;
47
+ const { pid, host, acquiredAt, machine } = parsed;
48
+ if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid <= 0)
49
+ return;
50
+ if (typeof host !== "string" || host.length === 0)
51
+ return;
52
+ if (typeof acquiredAt !== "string")
53
+ return;
54
+ const identified = typeof machine === "string" && machine.length > 0 ? { machine } : {};
55
+ return { pid, host, acquiredAt, ...identified };
56
+ }
57
+ var detectedIdentity;
58
+ async function firstReadableLine(paths) {
59
+ for (const path of paths) {
60
+ try {
61
+ const text = (await readFile(path, "utf8")).trim();
62
+ if (text.length > 0)
63
+ return text;
64
+ } catch {}
65
+ }
66
+ return null;
67
+ }
68
+ var run = promisify(execFile);
69
+ function parsePlatformUuid(dump) {
70
+ return /"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(dump)?.[1] ?? null;
71
+ }
72
+ async function readDarwinPlatformUuid(command = "ioreg") {
73
+ try {
74
+ const { stdout } = await run(command, ["-rd1", "-c", "IOPlatformExpertDevice"], {
75
+ timeout: 2000,
76
+ maxBuffer: 1 << 20,
77
+ encoding: "utf8"
78
+ });
79
+ return parsePlatformUuid(stdout);
80
+ } catch {
81
+ return null;
82
+ }
83
+ }
84
+ async function machineIdentity(declared) {
85
+ if (declared !== undefined)
86
+ return declared;
87
+ if (detectedIdentity !== undefined)
88
+ return detectedIdentity;
89
+ detectedIdentity = platform() === "darwin" ? await readDarwinPlatformUuid() : await firstReadableLine(["/etc/machine-id", "/var/lib/dbus/machine-id"]);
90
+ return detectedIdentity;
91
+ }
92
+ function attribute(owner, identity) {
93
+ if (identity !== null && owner.machine !== undefined) {
94
+ return owner.machine === identity ? "this-machine" : "another-machine";
95
+ }
96
+ return owner.host === hostname() ? "this-machine" : "unattributable";
97
+ }
98
+ async function probeLiveness(owner) {
99
+ try {
100
+ process.kill(owner.pid, 0);
101
+ } catch (error) {
102
+ return isRecord(error) && error.code === "ESRCH" ? "gone" : "alive";
103
+ }
104
+ return await isZombieProcess(owner.pid) ? "gone" : "alive";
105
+ }
106
+ async function isZombieProcess(pid, seam = {}) {
107
+ const { procRoot = "/proc", psCommand = "ps" } = seam;
108
+ try {
109
+ const stat = await readFile(`${procRoot}/${pid}/stat`, "utf8");
110
+ return stat.slice(stat.lastIndexOf(")") + 1).trimStart().startsWith("Z");
111
+ } catch {}
112
+ try {
113
+ const { stdout } = await run(psCommand, ["-o", "state=", "-p", String(pid)], {
114
+ timeout: 2000,
115
+ maxBuffer: 1 << 16,
116
+ encoding: "utf8"
117
+ });
118
+ return stdout.trim().startsWith("Z");
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+ async function diagnose(owner, declaredIdentity) {
124
+ if (!owner)
125
+ return { attribution: "unattributable", liveness: "not-probed", owner: null };
126
+ const attribution = attribute(owner, await machineIdentity(declaredIdentity));
127
+ const record = {
128
+ pid: owner.pid,
129
+ host: owner.host,
130
+ acquiredAt: owner.acquiredAt,
131
+ ...owner.machine !== undefined && { machine: owner.machine }
132
+ };
133
+ if (attribution !== "this-machine")
134
+ return { attribution, liveness: "not-probed", owner: record };
135
+ return { attribution, liveness: await probeLiveness(owner), owner: record };
136
+ }
137
+ async function readLockOwner(lockPath) {
138
+ let handle;
139
+ try {
140
+ handle = await open(lockPath, constants.O_RDONLY | constants.O_NOFOLLOW);
141
+ return readOwner(await handle.readFile("utf8"));
142
+ } catch {
143
+ return;
144
+ } finally {
145
+ await handle?.close().catch(() => {
146
+ return;
147
+ });
148
+ }
149
+ }
150
+ async function createExclusive(lockPath, mode, declaredIdentity) {
151
+ const handle = await open(lockPath, "wx", mode);
152
+ const identity = await machineIdentity(declaredIdentity);
153
+ const owner = {
154
+ pid: process.pid,
155
+ host: hostname(),
156
+ acquiredAt: new Date().toISOString(),
157
+ ...identity !== null && { machine: identity }
158
+ };
159
+ await handle.writeFile(`${JSON.stringify(owner)}
160
+ `, "utf8");
161
+ return handle;
162
+ }
163
+ async function acquireDiagnosticJournalLock(lockPath, mode, policy, declaredIdentity) {
164
+ try {
165
+ return {
166
+ handle: await createExclusive(lockPath, mode, declaredIdentity),
167
+ reclaimedStale: false
168
+ };
169
+ } catch (error) {
170
+ if (policy !== "reclaim-stale" || !isExisting(error))
171
+ throw error;
172
+ const owner = await readLockOwner(lockPath);
173
+ const diagnosis = await diagnose(owner, declaredIdentity);
174
+ if (!owner || diagnosis.liveness !== "gone") {
175
+ if (isRecord(error))
176
+ Object.assign(error, { journalLock: diagnosis });
177
+ throw error;
178
+ }
179
+ await unlink(lockPath).catch(() => {
180
+ return;
181
+ });
182
+ return {
183
+ handle: await createExclusive(lockPath, mode, declaredIdentity),
184
+ reclaimedStale: true
185
+ };
186
+ }
187
+ }
188
+
189
+ // src/application/diagnostic-journal-storage.ts
190
+ class DiagnosticJournalStorageError extends Error {
191
+ phase;
192
+ constructor(phase, message, options) {
193
+ super(message, options);
194
+ this.phase = phase;
195
+ this.name = "DiagnosticJournalStorageError";
196
+ }
197
+ }
198
+ function isMissing(error) {
199
+ return isRecord(error) && error.code === "ENOENT";
200
+ }
201
+ async function removeIfPresent(path) {
202
+ try {
203
+ const info = await lstat(path);
204
+ if (info.isSymbolicLink() || !info.isFile()) {
205
+ throw new Error("Diagnostic journal generations must be regular files");
206
+ }
207
+ await unlink2(path);
208
+ } catch (error) {
209
+ if (!isMissing(error))
210
+ throw error;
211
+ }
212
+ }
213
+ async function moveIfPresent(from, to) {
214
+ try {
215
+ const info = await lstat(from);
216
+ if (info.isSymbolicLink() || !info.isFile()) {
217
+ throw new Error("Diagnostic journal generations must be regular files");
218
+ }
219
+ await rename(from, to);
220
+ return true;
221
+ } catch (error) {
222
+ if (isMissing(error))
223
+ return false;
224
+ throw error;
225
+ }
226
+ }
227
+ function generation(path, index) {
228
+ return `${path}.${index}`;
229
+ }
230
+ function generationIndex(name, prefix) {
231
+ if (!name.startsWith(prefix))
232
+ return;
233
+ const suffix = name.slice(prefix.length);
234
+ if (!/^\d+$/.test(suffix))
235
+ return;
236
+ const value = Number(suffix);
237
+ return Number.isSafeInteger(value) && value > 0 ? value : undefined;
238
+ }
239
+ async function createRotatingDiagnosticJournalStorage(config) {
240
+ if (!isAbsolute(config.path) || resolve(config.path) !== config.path) {
241
+ throw new TypeError("Diagnostic journal path must be normalized and absolute");
242
+ }
243
+ const parent = await realpath(dirname(config.path));
244
+ const journalPath = resolve(parent, basename(config.path));
245
+ const lockPath = `${journalPath}.lock`;
246
+ const { handle: lock, reclaimedStale } = await acquireDiagnosticJournalLock(lockPath, config.mode, config.lock, config.machineIdentity);
247
+ let handle;
248
+ let currentFileBytes = 0;
249
+ let retainedFiles = 1;
250
+ let rotations = 0;
251
+ let partialTails = 0;
252
+ let closed = false;
253
+ const openCurrent = async () => {
254
+ handle = await open2(journalPath, constants2.O_APPEND | constants2.O_CREAT | constants2.O_RDWR | constants2.O_NOFOLLOW, config.mode);
255
+ const info = await handle.stat();
256
+ if (!info.isFile()) {
257
+ await handle.close();
258
+ handle = undefined;
259
+ throw new Error("Diagnostic journal path must be a regular file");
260
+ }
261
+ currentFileBytes = Number(info.size);
262
+ };
263
+ const rotate = async () => {
264
+ try {
265
+ await handle?.close();
266
+ handle = undefined;
267
+ if (config.maxFiles === 1) {
268
+ await removeIfPresent(journalPath);
269
+ } else {
270
+ await removeIfPresent(generation(journalPath, config.maxFiles - 1));
271
+ for (let index = config.maxFiles - 2;index >= 1; index -= 1) {
272
+ await moveIfPresent(generation(journalPath, index), generation(journalPath, index + 1));
273
+ }
274
+ await moveIfPresent(journalPath, generation(journalPath, 1));
275
+ }
276
+ retainedFiles = Math.min(config.maxFiles, retainedFiles + 1);
277
+ rotations += 1;
278
+ await openCurrent();
279
+ } catch (error) {
280
+ throw new DiagnosticJournalStorageError("rotation", "Diagnostic journal rotation failed", { cause: error });
281
+ }
282
+ };
283
+ try {
284
+ const names = await readdir(parent);
285
+ const prefix = `${basename(journalPath)}.`;
286
+ let existingGenerations = 0;
287
+ for (const name of names) {
288
+ const index = generationIndex(name, prefix);
289
+ if (index === undefined)
290
+ continue;
291
+ if (index >= config.maxFiles) {
292
+ await removeIfPresent(resolve(parent, name));
293
+ } else {
294
+ const info = await lstat(resolve(parent, name));
295
+ if (info.isSymbolicLink() || !info.isFile()) {
296
+ throw new Error("Diagnostic journal generations must be regular files");
297
+ }
298
+ existingGenerations += 1;
299
+ }
300
+ }
301
+ retainedFiles = Math.min(config.maxFiles, existingGenerations + 1);
302
+ await openCurrent();
303
+ if (currentFileBytes > 0) {
304
+ const tail = new Uint8Array(1);
305
+ const read = await handle?.read(tail, 0, 1, currentFileBytes - 1);
306
+ if (read?.bytesRead === 1 && tail[0] !== 10) {
307
+ partialTails += 1;
308
+ await rotate();
309
+ }
310
+ }
311
+ } catch (error) {
312
+ await handle?.close().catch(() => {
313
+ return;
314
+ });
315
+ await lock.close().catch(() => {
316
+ return;
317
+ });
318
+ await unlink2(lockPath).catch(() => {
319
+ return;
320
+ });
321
+ throw error;
322
+ }
323
+ const snapshot = () => ({
324
+ currentFileBytes,
325
+ retainedFiles,
326
+ rotations,
327
+ partialTails
328
+ });
329
+ return {
330
+ reclaimedStale,
331
+ async append(bytes) {
332
+ if (closed || !handle) {
333
+ throw new DiagnosticJournalStorageError("write", "Diagnostic journal storage is closed");
334
+ }
335
+ let rotated = false;
336
+ if (currentFileBytes > 0 && currentFileBytes + bytes.byteLength > config.maxFileBytes) {
337
+ await rotate();
338
+ rotated = true;
339
+ }
340
+ try {
341
+ await handle.writeFile(bytes);
342
+ currentFileBytes += bytes.byteLength;
343
+ return { ...snapshot(), rotated };
344
+ } catch (error) {
345
+ throw new DiagnosticJournalStorageError("write", "Diagnostic journal write failed", {
346
+ cause: error
347
+ });
348
+ }
349
+ },
350
+ snapshot,
351
+ async close() {
352
+ if (closed)
353
+ return;
354
+ closed = true;
355
+ let failure;
356
+ try {
357
+ await handle?.close();
358
+ } catch (error) {
359
+ failure = error;
360
+ }
361
+ try {
362
+ await lock.close();
363
+ await unlink2(lockPath);
364
+ } catch (error) {
365
+ failure ??= error;
366
+ }
367
+ if (failure !== undefined) {
368
+ throw new DiagnosticJournalStorageError("close", "Diagnostic journal close failed", {
369
+ cause: failure
370
+ });
371
+ }
372
+ }
373
+ };
374
+ }
375
+
376
+ // src/application/diagnostic-journal-manager.ts
377
+ function waitBudget(options) {
378
+ if (options.timeoutMs === undefined)
379
+ return;
380
+ if (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs <= 0) {
381
+ throw new TypeError("Diagnostic journal timeoutMs must be a positive safe integer");
382
+ }
383
+ return options.timeoutMs;
384
+ }
385
+ function createDiagnosticJournalManager(config, storage) {
386
+ const limits = DiagnosticJournalLimitsSchema.parse(config.limits);
387
+ const encoder = new TextEncoder;
388
+ const channel = createBoundedChannel({
389
+ policy: "ordered",
390
+ maxItems: limits.maxPendingItems,
391
+ maxBytes: limits.maxPendingBytes,
392
+ sizeOf: (frame) => frame.bytes.byteLength
393
+ });
394
+ const refusals = {
395
+ closed: 0,
396
+ failed: 0,
397
+ invalid: 0,
398
+ oversized: 0,
399
+ "item-capacity": 0,
400
+ "byte-capacity": 0
401
+ };
402
+ const progressWaiters = new Set;
403
+ let state = "open";
404
+ let received = 0;
405
+ let accepted = 0;
406
+ let refused = 0;
407
+ let written = 0;
408
+ let failedRecords = 0;
409
+ let pendingItems = 0;
410
+ let pendingBytes = 0;
411
+ let inFlight = false;
412
+ let rotationFailures = 0;
413
+ let lastAcceptedSequence = 0;
414
+ let lastWrittenSequence = 0;
415
+ let lastSettledSequence = 0;
416
+ let lastFailure;
417
+ let physicalClosed = false;
418
+ const isFailed = () => state === "failed";
419
+ const notifyProgress = () => {
420
+ for (const waiter of progressWaiters)
421
+ waiter();
422
+ };
423
+ const reportFailure = (failure) => {
424
+ if (!config.onFailure)
425
+ return;
426
+ Promise.resolve().then(() => config.onFailure?.(failure)).catch(() => {
427
+ return;
428
+ });
429
+ };
430
+ const markFailure = (error, fallbackPhase, sequence) => {
431
+ const phase = error instanceof DiagnosticJournalStorageError ? error.phase : fallbackPhase;
432
+ if (phase === "rotation")
433
+ rotationFailures += 1;
434
+ lastFailure = { phase, ...sequence !== undefined && { sequence } };
435
+ state = "failed";
436
+ channel.close({ mode: "drain" });
437
+ reportFailure({ phase, error, ...sequence !== undefined && { sequence } });
438
+ };
439
+ const worker = (async () => {
440
+ for await (const frame of channel) {
441
+ inFlight = true;
442
+ if (isFailed()) {
443
+ failedRecords += 1;
444
+ } else {
445
+ try {
446
+ await storage.append(frame.bytes);
447
+ written += 1;
448
+ lastWrittenSequence = frame.sequence;
449
+ } catch (error) {
450
+ failedRecords += 1;
451
+ markFailure(error, "write", frame.sequence);
452
+ }
453
+ }
454
+ pendingItems -= 1;
455
+ pendingBytes -= frame.bytes.byteLength;
456
+ lastSettledSequence = frame.sequence;
457
+ inFlight = false;
458
+ notifyProgress();
459
+ }
460
+ try {
461
+ await storage.close();
462
+ } catch (error) {
463
+ markFailure(error, "close");
464
+ }
465
+ physicalClosed = true;
466
+ if (!isFailed())
467
+ state = "closed";
468
+ notifyProgress();
469
+ })();
470
+ worker.catch((error) => {
471
+ markFailure(error, "close");
472
+ physicalClosed = true;
473
+ notifyProgress();
474
+ });
475
+ const refuse = (reason) => {
476
+ refused += 1;
477
+ refusals[reason] += 1;
478
+ return DiagnosticJournalSubmitResultSchema.parse({ outcome: "refused", reason });
479
+ };
480
+ const waitUntil = (predicate, options) => {
481
+ const timeoutMs = waitBudget(options);
482
+ if (predicate())
483
+ return Promise.resolve("settled");
484
+ if (options.signal?.aborted)
485
+ return Promise.resolve("cancelled");
486
+ return new Promise((resolve2) => {
487
+ let settled = false;
488
+ let timer;
489
+ const finish = (outcome) => {
490
+ if (settled)
491
+ return;
492
+ settled = true;
493
+ progressWaiters.delete(onProgress);
494
+ options.signal?.removeEventListener("abort", onAbort);
495
+ if (timer)
496
+ clearTimeout(timer);
497
+ resolve2(outcome);
498
+ };
499
+ const onProgress = () => {
500
+ if (predicate())
501
+ finish("settled");
502
+ };
503
+ const onAbort = () => finish("cancelled");
504
+ progressWaiters.add(onProgress);
505
+ options.signal?.addEventListener("abort", onAbort, { once: true });
506
+ if (timeoutMs !== undefined)
507
+ timer = setTimeout(() => finish("timed-out"), timeoutMs);
508
+ onProgress();
509
+ });
510
+ };
511
+ const getStatus = () => {
512
+ const file = storage.snapshot();
513
+ return DiagnosticJournalStatusSchema.parse({
514
+ state,
515
+ epoch: config.epoch,
516
+ limits,
517
+ lock: config.lock,
518
+ received,
519
+ accepted,
520
+ refused,
521
+ refusals,
522
+ written,
523
+ failedRecords,
524
+ pendingItems,
525
+ pendingBytes,
526
+ inFlight,
527
+ rotations: file.rotations,
528
+ rotationFailures,
529
+ partialTails: file.partialTails,
530
+ currentFileBytes: file.currentFileBytes,
531
+ retainedFiles: file.retainedFiles,
532
+ ...lastAcceptedSequence > 0 && { lastAcceptedSequence },
533
+ ...lastWrittenSequence > 0 && { lastWrittenSequence },
534
+ ...lastSettledSequence > 0 && { lastSettledSequence },
535
+ ...lastFailure && { lastFailure }
536
+ });
537
+ };
538
+ return {
539
+ submit(event) {
540
+ received += 1;
541
+ if (state === "failed")
542
+ return refuse("failed");
543
+ if (state !== "open")
544
+ return refuse("closed");
545
+ const parsed = config.eventSchema.safeParse(event);
546
+ if (!parsed.success)
547
+ return refuse("invalid");
548
+ const json = z.json().safeParse(parsed.data);
549
+ if (!json.success)
550
+ return refuse("invalid");
551
+ const payload = encoder.encode(JSON.stringify(json.data));
552
+ if (payload.byteLength > limits.maxEventBytes)
553
+ return refuse("oversized");
554
+ if (pendingItems >= limits.maxPendingItems)
555
+ return refuse("item-capacity");
556
+ const sequence = lastAcceptedSequence + 1;
557
+ const frame = DiagnosticJournalFrameSchema.parse({
558
+ schemaVersion: 1,
559
+ epoch: config.epoch,
560
+ sequence,
561
+ event: json.data
562
+ });
563
+ const bytes = encoder.encode(`${JSON.stringify(frame)}
564
+ `);
565
+ if (bytes.byteLength > limits.maxFileBytes)
566
+ return refuse("oversized");
567
+ if (pendingBytes + bytes.byteLength > limits.maxPendingBytes) {
568
+ return refuse("byte-capacity");
569
+ }
570
+ const offered = channel.offer({ sequence, bytes });
571
+ if (offered.outcome === "refused") {
572
+ return refuse(offered.reason === "not-open" ? "closed" : "item-capacity");
573
+ }
574
+ accepted += 1;
575
+ pendingItems += 1;
576
+ pendingBytes += bytes.byteLength;
577
+ lastAcceptedSequence = sequence;
578
+ return DiagnosticJournalSubmitResultSchema.parse({
579
+ outcome: "accepted",
580
+ epoch: config.epoch,
581
+ sequence
582
+ });
583
+ },
584
+ async flush(options = {}) {
585
+ const throughSequence = lastAcceptedSequence;
586
+ const outcome = await waitUntil(() => lastSettledSequence >= throughSequence, options);
587
+ return DiagnosticJournalWaitResultSchema.parse({
588
+ outcome,
589
+ state,
590
+ throughSequence,
591
+ settledSequence: lastSettledSequence
592
+ });
593
+ },
594
+ getStatus,
595
+ async close(options = {}) {
596
+ if (state === "open") {
597
+ state = "draining";
598
+ channel.close({ mode: "drain" });
599
+ }
600
+ const wait = await waitUntil(() => physicalClosed, options);
601
+ return DiagnosticJournalCloseResultSchema.parse({
602
+ outcome: wait === "settled" ? "closed" : wait,
603
+ state,
604
+ pendingItems
605
+ });
606
+ }
607
+ };
608
+ }
609
+
610
+ // src/application/diagnostic-journal.ts
611
+ async function createDiagnosticJournal(config) {
612
+ const limits = DiagnosticJournalLimitsSchema.parse(config.limits);
613
+ const lock = DiagnosticJournalLockPolicySchema.parse(config.lock ?? "refuse");
614
+ const storage = await createRotatingDiagnosticJournalStorage({
615
+ path: config.path,
616
+ maxFileBytes: limits.maxFileBytes,
617
+ maxFiles: limits.maxFiles,
618
+ mode: parseDiagnosticJournalMode(config.mode),
619
+ lock,
620
+ ...config.machineIdentity !== undefined && { machineIdentity: config.machineIdentity }
621
+ });
622
+ return createDiagnosticJournalManager({
623
+ eventSchema: config.eventSchema,
624
+ epoch: randomUUID(),
625
+ limits,
626
+ lock: { policy: lock, reclaimedStale: storage.reclaimedStale },
627
+ ...config.onFailure && { onFailure: config.onFailure }
628
+ }, storage);
629
+ }
630
+ export {
631
+ createDiagnosticJournal
632
+ };
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  ActivitySnapshotSchema,
3
3
  ManagedScheduleStatusSchema
4
- } from "./index-3cwck0rm.js";
4
+ } from "./index-6s7n2v50.js";
5
5
  import {
6
6
  ApplicationSnapshotSchema
7
- } from "./index-8eywc9zv.js";
7
+ } from "./index-3gye9wzb.js";
8
+ import"./index-7gnkny4z.js";
8
9
 
9
10
  // src/application/opentelemetry.ts
10
11
  var MAX_ACTIVITY_SOURCES = 64;