agent-inspect 4.2.0 → 4.4.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 (97) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/API.md +3 -0
  3. package/docs/CLI.md +36 -0
  4. package/docs/SCHEMA.md +27 -1
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-5VSPJEZ7.mjs → chunk-ORHDQUT6.mjs} +385 -10
  7. package/packages/cli/dist/chunk-ORHDQUT6.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +2548 -1567
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +2028 -1495
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-VQT7QLGV.mjs → src-FJOHPC4X.mjs} +3 -3
  13. package/packages/cli/dist/{src-VQT7QLGV.mjs.map → src-FJOHPC4X.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +397 -12
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +105 -9
  17. package/packages/core/dist/advanced.d.ts +105 -9
  18. package/packages/core/dist/advanced.mjs +219 -17
  19. package/packages/core/dist/advanced.mjs.map +1 -1
  20. package/packages/core/dist/checks.cjs +117 -18
  21. package/packages/core/dist/checks.cjs.map +1 -1
  22. package/packages/core/dist/checks.d.cts +11 -3
  23. package/packages/core/dist/checks.d.ts +11 -3
  24. package/packages/core/dist/checks.mjs +42 -1
  25. package/packages/core/dist/checks.mjs.map +1 -1
  26. package/packages/core/dist/{chunk-2ZXEMWGK.mjs → chunk-3USJVBLA.mjs} +3 -3
  27. package/packages/core/dist/{chunk-2ZXEMWGK.mjs.map → chunk-3USJVBLA.mjs.map} +1 -1
  28. package/packages/core/dist/{chunk-HY7H3CQM.mjs → chunk-CAWPF22J.mjs} +4 -3
  29. package/packages/core/dist/chunk-CAWPF22J.mjs.map +1 -0
  30. package/packages/core/dist/{chunk-XUNJMAPD.mjs → chunk-KNYL56KZ.mjs} +38 -3
  31. package/packages/core/dist/chunk-KNYL56KZ.mjs.map +1 -0
  32. package/packages/core/dist/{chunk-IZBJAZGF.mjs → chunk-P366CCL2.mjs} +34 -3
  33. package/packages/core/dist/chunk-P366CCL2.mjs.map +1 -0
  34. package/packages/core/dist/{chunk-4JVGFNQH.mjs → chunk-ULCGIRTC.mjs} +95 -8
  35. package/packages/core/dist/chunk-ULCGIRTC.mjs.map +1 -0
  36. package/packages/core/dist/chunk-VFO76UH3.mjs +228 -0
  37. package/packages/core/dist/chunk-VFO76UH3.mjs.map +1 -0
  38. package/packages/core/dist/{chunk-NQZPZ2FN.mjs → chunk-WRE4CNPF.mjs} +6 -3
  39. package/packages/core/dist/chunk-WRE4CNPF.mjs.map +1 -0
  40. package/packages/core/dist/{chunk-A4V2H3YU.mjs → chunk-ZWA5RWMV.mjs} +40 -4
  41. package/packages/core/dist/chunk-ZWA5RWMV.mjs.map +1 -0
  42. package/packages/core/dist/{context-DjY-jvQk.d.cts → context-BbfkMYjz.d.cts} +5 -3
  43. package/packages/core/dist/{context-BDZmi53V.d.ts → context-Cp8NRbBX.d.ts} +5 -3
  44. package/packages/core/dist/diff.cjs.map +1 -1
  45. package/packages/core/dist/diff.d.cts +3 -3
  46. package/packages/core/dist/diff.d.ts +3 -3
  47. package/packages/core/dist/diff.mjs +1 -1
  48. package/packages/core/dist/exporters.cjs +137 -1
  49. package/packages/core/dist/exporters.cjs.map +1 -1
  50. package/packages/core/dist/exporters.d.cts +6 -3
  51. package/packages/core/dist/exporters.d.ts +6 -3
  52. package/packages/core/dist/exporters.mjs +71 -6
  53. package/packages/core/dist/exporters.mjs.map +1 -1
  54. package/packages/core/dist/index.cjs +181 -6
  55. package/packages/core/dist/index.cjs.map +1 -1
  56. package/packages/core/dist/index.d.cts +14 -7
  57. package/packages/core/dist/index.d.ts +14 -7
  58. package/packages/core/dist/index.mjs +51 -7
  59. package/packages/core/dist/index.mjs.map +1 -1
  60. package/packages/core/dist/{inspect-event-CYAV7Hxm.d.cts → inspect-event-IqwOHbGo.d.cts} +1 -1
  61. package/packages/core/dist/{inspect-event-CYAV7Hxm.d.ts → inspect-event-IqwOHbGo.d.ts} +1 -1
  62. package/packages/core/dist/{log-config-BNQ9UTmP.d.cts → log-config-CW8w5YQ9.d.cts} +1 -1
  63. package/packages/core/dist/{log-config-D3Yp1SZN.d.ts → log-config-SRA4xTp8.d.ts} +1 -1
  64. package/packages/core/dist/logs.d.cts +3 -3
  65. package/packages/core/dist/logs.d.ts +3 -3
  66. package/packages/core/dist/{persisted-inspect-event-BLvb0jSX.d.ts → persisted-inspect-event-DruwqARZ.d.ts} +1 -1
  67. package/packages/core/dist/{persisted-inspect-event-D5SjBz9b.d.cts → persisted-inspect-event-Gd-W8vB7.d.cts} +1 -1
  68. package/packages/core/dist/persisted.cjs +67 -1
  69. package/packages/core/dist/persisted.cjs.map +1 -1
  70. package/packages/core/dist/persisted.d.cts +5 -5
  71. package/packages/core/dist/persisted.d.ts +5 -5
  72. package/packages/core/dist/persisted.mjs +3 -3
  73. package/packages/core/dist/readers.cjs +72 -3
  74. package/packages/core/dist/readers.cjs.map +1 -1
  75. package/packages/core/dist/readers.d.cts +2 -2
  76. package/packages/core/dist/readers.d.ts +2 -2
  77. package/packages/core/dist/readers.mjs +5 -5
  78. package/packages/core/dist/readers.mjs.map +1 -1
  79. package/packages/core/dist/{types-CQun9LW6.d.ts → types-B1X87dUW.d.cts} +16 -2
  80. package/packages/core/dist/{types-C-llnPH0.d.cts → types-BVkjSd0q.d.ts} +16 -2
  81. package/packages/core/dist/types-CvsKGweN.d.cts +12 -0
  82. package/packages/core/dist/types-CvsKGweN.d.ts +12 -0
  83. package/packages/core/dist/writers.cjs +2 -1
  84. package/packages/core/dist/writers.cjs.map +1 -1
  85. package/packages/core/dist/writers.d.cts +2 -2
  86. package/packages/core/dist/writers.d.ts +2 -2
  87. package/packages/core/dist/writers.mjs +3 -4
  88. package/packages/core/dist/writers.mjs.map +1 -1
  89. package/packages/cli/dist/chunk-5VSPJEZ7.mjs.map +0 -1
  90. package/packages/core/dist/chunk-4JVGFNQH.mjs.map +0 -1
  91. package/packages/core/dist/chunk-A4V2H3YU.mjs.map +0 -1
  92. package/packages/core/dist/chunk-EDTQHZPM.mjs +0 -88
  93. package/packages/core/dist/chunk-EDTQHZPM.mjs.map +0 -1
  94. package/packages/core/dist/chunk-HY7H3CQM.mjs.map +0 -1
  95. package/packages/core/dist/chunk-IZBJAZGF.mjs.map +0 -1
  96. package/packages/core/dist/chunk-NQZPZ2FN.mjs.map +0 -1
  97. package/packages/core/dist/chunk-XUNJMAPD.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/writers/index.ts"],"names":[],"mappings":"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","file":"writers.mjs","sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n preparePersistedInspectEventForWrite,\n resolveTraceSafetyOptions,\n} from \"../trace-event-safety.js\";\nimport type { PersistedInspectEvent } from \"../types/persisted-inspect-event.js\";\nimport { getTraceFilePath } from \"../utils.js\";\n\nexport interface TraceWriterStats {\n writtenEvents: number;\n droppedEvents: number;\n flushCount: number;\n lastFlushAt?: string;\n lastError?: string;\n}\n\nexport interface TraceWriter {\n write(event: PersistedInspectEvent): Promise<void>;\n flush?(): Promise<void>;\n close?(): Promise<void>;\n getStats?(): TraceWriterStats;\n}\n\nexport interface MemoryTraceWriter extends TraceWriter {\n getEvents(): PersistedInspectEvent[];\n clear(): void;\n}\n\nexport interface FileTraceWriterOptions {\n /**\n * Directory for per-run JSONL traces. Defaults to AgentInspect's default\n * trace directory when neither `dir` nor `filePath` is supplied.\n */\n dir?: string;\n /**\n * Explicit JSONL output path. When supplied, all accepted events are written\n * to this file rather than deriving a per-run file from `event.runId`.\n */\n filePath?: string;\n}\n\nexport type BufferedFileWriterOverflowMode = \"drop-oldest\" | \"drop-newest\";\n\nexport interface BufferedFileWriterOptions extends FileTraceWriterOptions {\n /**\n * Maximum number of events retained before overflow policy applies.\n * Defaults to 1000.\n */\n maxQueueSize?: number;\n /**\n * Flush delay after the first queued event. Defaults to 250ms.\n */\n flushIntervalMs?: number;\n /**\n * Maximum events appended by one filesystem batch. Defaults to 100.\n */\n maxBatchSize?: number;\n /**\n * Overflow policy when `maxQueueSize` is reached. Defaults to `drop-oldest`.\n */\n overflow?: BufferedFileWriterOverflowMode;\n}\n\nexport interface CompositeTraceWriterOptions {\n writers: TraceWriter[];\n}\n\nconst DEFAULT_TRACE_SAFETY = resolveTraceSafetyOptions();\n\nfunction createInitialStats(): TraceWriterStats {\n return {\n writtenEvents: 0,\n droppedEvents: 0,\n flushCount: 0,\n };\n}\n\nfunction markFlush(stats: TraceWriterStats): void {\n stats.flushCount += 1;\n stats.lastFlushAt = new Date().toISOString();\n}\n\nfunction cloneStats(stats: TraceWriterStats): TraceWriterStats {\n return { ...stats };\n}\n\nfunction normalizeError(error: unknown): string {\n if (error instanceof Error && error.message.trim() !== \"\") {\n return error.message;\n }\n if (typeof error === \"string\" && error.trim() !== \"\") {\n return error;\n }\n return \"Unknown trace writer error\";\n}\n\nfunction recordDropped(stats: TraceWriterStats, error: unknown): void {\n stats.droppedEvents += 1;\n stats.lastError = normalizeError(error);\n}\n\nfunction prepareWriterEvent(\n event: PersistedInspectEvent,\n): PersistedInspectEvent | undefined {\n return preparePersistedInspectEventForWrite(event, DEFAULT_TRACE_SAFETY);\n}\n\nfunction resolveFilePath(\n event: PersistedInspectEvent,\n options: FileTraceWriterOptions,\n): string {\n if (options.filePath && options.filePath.trim() !== \"\") {\n return path.resolve(options.filePath);\n }\n return getTraceFilePath(event.runId, options.dir);\n}\n\nfunction serializeEvent(event: PersistedInspectEvent): string {\n return `${JSON.stringify(event)}\\n`;\n}\n\nasync function appendEventLine(\n event: PersistedInspectEvent,\n options: FileTraceWriterOptions,\n): Promise<void> {\n const filePath = resolveFilePath(event, options);\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(filePath, serializeEvent(event), \"utf-8\");\n}\n\nasync function appendEventBatch(\n events: PersistedInspectEvent[],\n options: FileTraceWriterOptions,\n): Promise<{ written: number; dropped: number; lastError?: string }> {\n const byPath = new Map<string, string[]>();\n let dropped = 0;\n let lastError: string | undefined;\n\n for (const event of events) {\n try {\n const filePath = resolveFilePath(event, options);\n const line = serializeEvent(event);\n const lines = byPath.get(filePath);\n if (lines) {\n lines.push(line);\n } else {\n byPath.set(filePath, [line]);\n }\n } catch (error) {\n dropped += 1;\n lastError = normalizeError(error);\n }\n }\n\n let written = 0;\n for (const [filePath, lines] of byPath) {\n try {\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(filePath, lines.join(\"\"), \"utf-8\");\n written += lines.length;\n } catch (error) {\n dropped += lines.length;\n lastError = normalizeError(error);\n }\n }\n\n return lastError\n ? { written, dropped, lastError }\n : { written, dropped };\n}\n\nexport function memoryWriter(): MemoryTraceWriter {\n const events: PersistedInspectEvent[] = [];\n const stats = createInitialStats();\n\n return {\n async write(event) {\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n events.push(safe);\n stats.writtenEvents += 1;\n },\n async flush() {\n markFlush(stats);\n },\n async close() {\n // Memory writer has no external resources. Keep close idempotent.\n },\n getStats() {\n return cloneStats(stats);\n },\n getEvents() {\n return events.map((event) => structuredClone(event));\n },\n clear() {\n events.length = 0;\n },\n };\n}\n\nexport function nullWriter(): TraceWriter {\n const stats = createInitialStats();\n\n return {\n async write() {\n stats.writtenEvents += 1;\n },\n async flush() {\n markFlush(stats);\n },\n async close() {\n // Null writer has no external resources. Keep close idempotent.\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nexport function fileWriter(options: FileTraceWriterOptions = {}): TraceWriter {\n const stats = createInitialStats();\n let closed = false;\n let queue: Promise<void> = Promise.resolve();\n\n const enqueue = (event: PersistedInspectEvent): Promise<void> => {\n const operation = queue.then(async () => {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n try {\n await appendEventLine(event, options);\n stats.writtenEvents += 1;\n } catch (error) {\n recordDropped(stats, error);\n }\n });\n\n queue = operation.catch(() => {\n // Individual operations are already isolated above. This catch keeps the\n // internal queue alive even if an unexpected implementation error slips\n // through.\n });\n\n return operation.catch(() => {\n // Instrumentation failures must not replace application errors.\n });\n };\n\n return {\n write(event) {\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return Promise.resolve();\n }\n return enqueue(safe);\n },\n async flush() {\n await queue;\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await queue;\n closed = true;\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value <= 0) return fallback;\n return Math.floor(value);\n}\n\nfunction nonNegativeInteger(value: number | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value < 0) return fallback;\n return Math.floor(value);\n}\n\nexport function bufferedFileWriter(\n options: BufferedFileWriterOptions = {},\n): TraceWriter {\n const stats = createInitialStats();\n const maxQueueSize = positiveInteger(options.maxQueueSize, 1000);\n const flushIntervalMs = nonNegativeInteger(options.flushIntervalMs, 250);\n const maxBatchSize = positiveInteger(options.maxBatchSize, 100);\n const overflow = options.overflow ?? \"drop-oldest\";\n const pending: PersistedInspectEvent[] = [];\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let chain: Promise<void> = Promise.resolve();\n\n const clearTimer = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const scheduleFlush = (): void => {\n if (closed || timer !== undefined || pending.length === 0) return;\n timer = setTimeout(() => {\n timer = undefined;\n void drain(false);\n }, flushIntervalMs);\n if (\n timer &&\n typeof timer === \"object\" &&\n \"unref\" in timer &&\n typeof timer.unref === \"function\"\n ) {\n timer.unref();\n }\n };\n\n const drainBatch = async (drainAll: boolean): Promise<void> => {\n clearTimer();\n do {\n const batch = pending.splice(0, maxBatchSize);\n if (batch.length === 0) break;\n const result = await appendEventBatch(batch, options);\n stats.writtenEvents += result.written;\n stats.droppedEvents += result.dropped;\n if (result.lastError) {\n stats.lastError = result.lastError;\n }\n } while (drainAll && pending.length > 0);\n if (pending.length > 0) scheduleFlush();\n };\n\n const drain = (drainAll: boolean): Promise<void> => {\n const operation = chain.then(() => drainBatch(drainAll));\n chain = operation.catch(() => {\n // Keep later flushes alive even if an unexpected implementation error\n // escapes the batch isolation above.\n });\n return operation.catch(() => {\n // Instrumentation failures must not replace application errors.\n });\n };\n\n return {\n async write(event) {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n\n if (pending.length >= maxQueueSize) {\n if (overflow === \"drop-newest\") {\n recordDropped(stats, \"Trace writer queue overflow\");\n return;\n }\n pending.shift();\n recordDropped(stats, \"Trace writer queue overflow\");\n }\n\n try {\n pending.push(safe);\n } catch (error) {\n recordDropped(stats, error);\n return;\n }\n\n scheduleFlush();\n },\n async flush() {\n await drain(true);\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await drain(true);\n closed = true;\n clearTimer();\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nexport function compositeWriter(\n writersOrOptions: TraceWriter[] | CompositeTraceWriterOptions,\n): TraceWriter {\n const stats = createInitialStats();\n const writers = Array.isArray(writersOrOptions)\n ? [...writersOrOptions]\n : [...writersOrOptions.writers];\n let closed = false;\n\n const recordChildFailure = (error: unknown): void => {\n stats.droppedEvents += 1;\n stats.lastError = normalizeError(error);\n };\n\n return {\n async write(event) {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n\n const childResults = await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.write(structuredClone(safe));\n return true;\n } catch (error) {\n recordChildFailure(error);\n return false;\n }\n }),\n );\n\n if (childResults.some(Boolean)) {\n stats.writtenEvents += 1;\n } else {\n recordDropped(stats, \"No composite trace writer accepted the event\");\n }\n },\n async flush() {\n await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.flush?.();\n } catch (error) {\n stats.lastError = normalizeError(error);\n }\n }),\n );\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.close?.();\n } catch (error) {\n stats.lastError = normalizeError(error);\n }\n }),\n );\n closed = true;\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/writers/index.ts"],"names":[],"mappings":"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","file":"writers.mjs","sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n preparePersistedInspectEventForWrite,\n resolveTraceSafetyOptions,\n} from \"../trace-event-safety.js\";\nimport type { PersistedInspectEvent } from \"../types/persisted-inspect-event.js\";\nimport { getTraceFilePath } from \"../utils.js\";\n\nexport interface TraceWriterStats {\n writtenEvents: number;\n droppedEvents: number;\n flushCount: number;\n lastFlushAt?: string;\n lastError?: string;\n}\n\nexport interface TraceWriter {\n write(event: PersistedInspectEvent): Promise<void>;\n flush?(): Promise<void>;\n close?(): Promise<void>;\n getStats?(): TraceWriterStats;\n}\n\nexport interface MemoryTraceWriter extends TraceWriter {\n getEvents(): PersistedInspectEvent[];\n clear(): void;\n}\n\nexport interface FileTraceWriterOptions {\n /**\n * Directory for per-run JSONL traces. Defaults to AgentInspect's default\n * trace directory when neither `dir` nor `filePath` is supplied.\n */\n dir?: string;\n /**\n * Explicit JSONL output path. When supplied, all accepted events are written\n * to this file rather than deriving a per-run file from `event.runId`.\n */\n filePath?: string;\n}\n\nexport type BufferedFileWriterOverflowMode = \"drop-oldest\" | \"drop-newest\";\n\nexport interface BufferedFileWriterOptions extends FileTraceWriterOptions {\n /**\n * Maximum number of events retained before overflow policy applies.\n * Defaults to 1000.\n */\n maxQueueSize?: number;\n /**\n * Flush delay after the first queued event. Defaults to 250ms.\n */\n flushIntervalMs?: number;\n /**\n * Maximum events appended by one filesystem batch. Defaults to 100.\n */\n maxBatchSize?: number;\n /**\n * Overflow policy when `maxQueueSize` is reached. Defaults to `drop-oldest`.\n */\n overflow?: BufferedFileWriterOverflowMode;\n}\n\nexport interface CompositeTraceWriterOptions {\n writers: TraceWriter[];\n}\n\nconst DEFAULT_TRACE_SAFETY = resolveTraceSafetyOptions();\n\nfunction createInitialStats(): TraceWriterStats {\n return {\n writtenEvents: 0,\n droppedEvents: 0,\n flushCount: 0,\n };\n}\n\nfunction markFlush(stats: TraceWriterStats): void {\n stats.flushCount += 1;\n stats.lastFlushAt = new Date().toISOString();\n}\n\nfunction cloneStats(stats: TraceWriterStats): TraceWriterStats {\n return { ...stats };\n}\n\nfunction normalizeError(error: unknown): string {\n if (error instanceof Error && error.message.trim() !== \"\") {\n return error.message;\n }\n if (typeof error === \"string\" && error.trim() !== \"\") {\n return error;\n }\n return \"Unknown trace writer error\";\n}\n\nfunction recordDropped(stats: TraceWriterStats, error: unknown): void {\n stats.droppedEvents += 1;\n stats.lastError = normalizeError(error);\n}\n\nfunction prepareWriterEvent(\n event: PersistedInspectEvent,\n): PersistedInspectEvent | undefined {\n return preparePersistedInspectEventForWrite(event, DEFAULT_TRACE_SAFETY);\n}\n\nfunction resolveFilePath(\n event: PersistedInspectEvent,\n options: FileTraceWriterOptions,\n): string {\n if (options.filePath && options.filePath.trim() !== \"\") {\n return path.resolve(options.filePath);\n }\n return getTraceFilePath(event.runId, options.dir);\n}\n\nfunction serializeEvent(event: PersistedInspectEvent): string {\n return `${JSON.stringify(event)}\\n`;\n}\n\nasync function appendEventLine(\n event: PersistedInspectEvent,\n options: FileTraceWriterOptions,\n): Promise<void> {\n const filePath = resolveFilePath(event, options);\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(filePath, serializeEvent(event), \"utf-8\");\n}\n\nasync function appendEventBatch(\n events: PersistedInspectEvent[],\n options: FileTraceWriterOptions,\n): Promise<{ written: number; dropped: number; lastError?: string }> {\n const byPath = new Map<string, string[]>();\n let dropped = 0;\n let lastError: string | undefined;\n\n for (const event of events) {\n try {\n const filePath = resolveFilePath(event, options);\n const line = serializeEvent(event);\n const lines = byPath.get(filePath);\n if (lines) {\n lines.push(line);\n } else {\n byPath.set(filePath, [line]);\n }\n } catch (error) {\n dropped += 1;\n lastError = normalizeError(error);\n }\n }\n\n let written = 0;\n for (const [filePath, lines] of byPath) {\n try {\n await mkdir(path.dirname(filePath), { recursive: true });\n await appendFile(filePath, lines.join(\"\"), \"utf-8\");\n written += lines.length;\n } catch (error) {\n dropped += lines.length;\n lastError = normalizeError(error);\n }\n }\n\n return lastError\n ? { written, dropped, lastError }\n : { written, dropped };\n}\n\nexport function memoryWriter(): MemoryTraceWriter {\n const events: PersistedInspectEvent[] = [];\n const stats = createInitialStats();\n\n return {\n async write(event) {\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n events.push(safe);\n stats.writtenEvents += 1;\n },\n async flush() {\n markFlush(stats);\n },\n async close() {\n // Memory writer has no external resources. Keep close idempotent.\n },\n getStats() {\n return cloneStats(stats);\n },\n getEvents() {\n return events.map((event) => structuredClone(event));\n },\n clear() {\n events.length = 0;\n },\n };\n}\n\nexport function nullWriter(): TraceWriter {\n const stats = createInitialStats();\n\n return {\n async write() {\n stats.writtenEvents += 1;\n },\n async flush() {\n markFlush(stats);\n },\n async close() {\n // Null writer has no external resources. Keep close idempotent.\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nexport function fileWriter(options: FileTraceWriterOptions = {}): TraceWriter {\n const stats = createInitialStats();\n let closed = false;\n let queue: Promise<void> = Promise.resolve();\n\n const enqueue = (event: PersistedInspectEvent): Promise<void> => {\n const operation = queue.then(async () => {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n try {\n await appendEventLine(event, options);\n stats.writtenEvents += 1;\n } catch (error) {\n recordDropped(stats, error);\n }\n });\n\n queue = operation.catch(() => {\n // Individual operations are already isolated above. This catch keeps the\n // internal queue alive even if an unexpected implementation error slips\n // through.\n });\n\n return operation.catch(() => {\n // Instrumentation failures must not replace application errors.\n });\n };\n\n return {\n write(event) {\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return Promise.resolve();\n }\n return enqueue(safe);\n },\n async flush() {\n await queue;\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await queue;\n closed = true;\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nfunction positiveInteger(value: number | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value <= 0) return fallback;\n return Math.floor(value);\n}\n\nfunction nonNegativeInteger(value: number | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n if (!Number.isFinite(value) || value < 0) return fallback;\n return Math.floor(value);\n}\n\nexport function bufferedFileWriter(\n options: BufferedFileWriterOptions = {},\n): TraceWriter {\n const stats = createInitialStats();\n const maxQueueSize = positiveInteger(options.maxQueueSize, 1000);\n const flushIntervalMs = nonNegativeInteger(options.flushIntervalMs, 250);\n const maxBatchSize = positiveInteger(options.maxBatchSize, 100);\n const overflow = options.overflow ?? \"drop-oldest\";\n const pending: PersistedInspectEvent[] = [];\n let closed = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let chain: Promise<void> = Promise.resolve();\n\n const clearTimer = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const scheduleFlush = (): void => {\n if (closed || timer !== undefined || pending.length === 0) return;\n timer = setTimeout(() => {\n timer = undefined;\n void drain(false);\n }, flushIntervalMs);\n if (\n timer &&\n typeof timer === \"object\" &&\n \"unref\" in timer &&\n typeof timer.unref === \"function\"\n ) {\n timer.unref();\n }\n };\n\n const drainBatch = async (drainAll: boolean): Promise<void> => {\n clearTimer();\n do {\n const batch = pending.splice(0, maxBatchSize);\n if (batch.length === 0) break;\n const result = await appendEventBatch(batch, options);\n stats.writtenEvents += result.written;\n stats.droppedEvents += result.dropped;\n if (result.lastError) {\n stats.lastError = result.lastError;\n }\n } while (drainAll && pending.length > 0);\n if (pending.length > 0) scheduleFlush();\n };\n\n const drain = (drainAll: boolean): Promise<void> => {\n const operation = chain.then(() => drainBatch(drainAll));\n chain = operation.catch(() => {\n // Keep later flushes alive even if an unexpected implementation error\n // escapes the batch isolation above.\n });\n return operation.catch(() => {\n // Instrumentation failures must not replace application errors.\n });\n };\n\n return {\n async write(event) {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n\n if (pending.length >= maxQueueSize) {\n if (overflow === \"drop-newest\") {\n recordDropped(stats, \"Trace writer queue overflow\");\n return;\n }\n pending.shift();\n recordDropped(stats, \"Trace writer queue overflow\");\n }\n\n try {\n pending.push(safe);\n } catch (error) {\n recordDropped(stats, error);\n return;\n }\n\n scheduleFlush();\n },\n async flush() {\n await drain(true);\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await drain(true);\n closed = true;\n clearTimer();\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n\nexport function compositeWriter(\n writersOrOptions: TraceWriter[] | CompositeTraceWriterOptions,\n): TraceWriter {\n const stats = createInitialStats();\n const writers = Array.isArray(writersOrOptions)\n ? [...writersOrOptions]\n : [...writersOrOptions.writers];\n let closed = false;\n\n const recordChildFailure = (error: unknown): void => {\n stats.droppedEvents += 1;\n stats.lastError = normalizeError(error);\n };\n\n return {\n async write(event) {\n if (closed) {\n recordDropped(stats, \"Trace writer is closed\");\n return;\n }\n\n const safe = prepareWriterEvent(event);\n if (safe === undefined) {\n recordDropped(stats, \"Invalid persisted inspect event\");\n return;\n }\n\n const childResults = await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.write(structuredClone(safe));\n return true;\n } catch (error) {\n recordChildFailure(error);\n return false;\n }\n }),\n );\n\n if (childResults.some(Boolean)) {\n stats.writtenEvents += 1;\n } else {\n recordDropped(stats, \"No composite trace writer accepted the event\");\n }\n },\n async flush() {\n await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.flush?.();\n } catch (error) {\n stats.lastError = normalizeError(error);\n }\n }),\n );\n markFlush(stats);\n },\n async close() {\n if (closed) return;\n await Promise.all(\n writers.map(async (writer) => {\n try {\n await writer.close?.();\n } catch (error) {\n stats.lastError = normalizeError(error);\n }\n }),\n );\n closed = true;\n },\n getStats() {\n return cloneStats(stats);\n },\n };\n}\n"]}