2g 0.2.0 → 0.3.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.
package/dist/2g.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"2g.mjs","sources":["../src/state.ts","../src/utils/serializeEvent.ts","../src/events.ts","../src/debug.ts","../src/utils/logStream.ts","../src/utils/broadcastChannel.ts","../src/utils/ipc.ts","../src/utils/processOrigin.ts","../src/utils/processExit.ts","../src/session.ts","../src/install.ts"],"sourcesContent":["import { EVENT_LOG_STATE_VERSION } from './constants';\nimport type { EventSink } from './utils/logStream';\nimport type { EventMeta } from './utils/serializeEvent';\n\nexport interface EventLoggerInfo {\n destination: 'file' | 'stdout' | 'stderr' | 'fd' | 'session' | 'ipc';\n isUserVisibleOutput: boolean;\n file?: string;\n fd?: number;\n sessionDir?: string;\n}\n\nexport interface EventLogState {\n logPath: string;\n primarySink?: EventSink;\n eventMeta?: EventMeta;\n eventLoggerInfo: EventLoggerInfo | null;\n debug: boolean;\n}\n\nconst STATE_SYMBOL = Symbol.for(`2g/state-${EVENT_LOG_STATE_VERSION}`);\n\ninterface EventLogGlobal {\n [STATE_SYMBOL]?: EventLogState;\n}\n\nexport const eventLogState = getEventLogState();\n\nexport function _resetEventLogState() {\n eventLogState.primarySink?.destroy();\n eventLogState.logPath = process.cwd();\n eventLogState.primarySink = undefined;\n eventLogState.eventMeta = undefined;\n eventLogState.eventLoggerInfo = null;\n eventLogState.debug = false;\n}\n\nfunction getEventLogState() {\n const globalScope = globalThis as EventLogGlobal;\n return (globalScope[STATE_SYMBOL] ??= {\n logPath: process.cwd(),\n eventLoggerInfo: null,\n debug: false,\n });\n}\n","import { performance } from 'node:perf_hooks';\n\nimport type { EventSink } from './logStream';\n\nconst TIME_ORIGIN = performance.timeOrigin;\n\nconst TIMESTAMP_FRACTIONS = Array.from(\n { length: 1000 },\n (_, us) => `.${`${us}`.padStart(3, '0')}`\n);\n\nlet cachedMs = -1;\nlet cachedMsJson = '';\nlet cachedWorkerId: string | undefined;\nlet cachedWorkerIdJson = '';\n\nexport interface EventMeta {\n _w?: string;\n}\n\nexport function serializeEvent(\n category: string,\n kind: string,\n payload: Record<string, unknown> | undefined,\n meta?: EventMeta,\n duration?: number,\n level?: number\n) {\n const timestamp = stringifyTimestamp();\n if (duration == null && !meta?._w && !level) {\n const rest = payload ? JSON.stringify(payload).slice(1) : '';\n return rest.length > 1\n ? `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp},${rest}\\n`\n : `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp}}\\n`;\n }\n\n let line = `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp}`;\n if (duration != null) line += `,\"_d\":${duration}`;\n if (level) line += `,\"_l\":${level}`;\n if (meta?._w) line += `,\"_w\":${stringifyWorkerId(meta._w)}`;\n return `${appendPayload(line, payload)}}\\n`;\n}\n\nexport function writeEvent(\n dest: EventSink,\n category: string,\n kind: string,\n payload: Record<string, unknown> | undefined,\n meta?: EventMeta,\n level?: number\n) {\n // Unserializable payloads (circular, BigInt) drop the event, never throw into the host\n try {\n dest._writeln(\n serializeEvent(category, kind, payload, meta, undefined, level)\n );\n } catch {}\n}\n\nexport function writeCompleteEvent(\n dest: EventSink,\n category: string,\n kind: string,\n startPayload: Record<string, unknown> | undefined,\n endPayload: Record<string, unknown> | undefined,\n delta: number,\n meta?: EventMeta,\n level?: number\n) {\n try {\n let line = `{\"_e\":\"${category}:${kind}\",\"_t\":${stringifyTimestamp()},\"_d\":${delta}`;\n if (level) line += `,\"_l\":${level}`;\n if (meta?._w) line += `,\"_w\":${stringifyWorkerId(meta._w)}`;\n dest._writeln(`${appendMergedPayload(line, startPayload, endPayload)}}\\n`);\n } catch {}\n}\n\nexport function getEventTimestamp() {\n return TIME_ORIGIN + performance.now();\n}\n\nfunction stringifyTimestamp() {\n const timestamp = TIME_ORIGIN + performance.now();\n const ms = Math.floor(timestamp);\n if (ms !== cachedMs) {\n cachedMs = ms;\n cachedMsJson = `${ms}`;\n }\n return cachedMsJson + TIMESTAMP_FRACTIONS[((timestamp - ms) * 1000) | 0];\n}\n\nfunction stringifyWorkerId(workerId: string) {\n if (workerId !== cachedWorkerId) {\n cachedWorkerId = workerId;\n cachedWorkerIdJson = JSON.stringify(workerId);\n }\n return cachedWorkerIdJson;\n}\n\nfunction appendPayload(line: string, payload?: Record<string, unknown>) {\n if (!payload) return line;\n const rest = JSON.stringify(payload);\n return rest && rest.length > 2 ? `${line},${rest.slice(1, -1)}` : line;\n}\n\nfunction appendMergedPayload(\n line: string,\n startPayload?: Record<string, unknown>,\n endPayload?: Record<string, unknown>\n) {\n if (!startPayload) return appendPayload(line, endPayload);\n if (!endPayload) return appendPayload(line, startPayload);\n return appendPayload(line, Object.assign(startPayload, endPayload));\n}\n","import path from 'node:path';\nimport { performance } from 'node:perf_hooks';\n\nimport { EVENT_LEVEL_DEBUG } from './constants';\nimport { eventLogState } from './state';\nimport { writeCompleteEvent, writeEvent } from './utils/serializeEvent';\nimport type { EventLogger, SerializedError, SpanEnd } from './types';\n\nconst NOOP_DONE: SpanEnd<any> = () => {};\n\nfunction serializeError(\n error: unknown,\n depth = 0\n): SerializedError | string | null {\n if (error == null) return null;\n if (!(error instanceof Error)) return String(error);\n const serialized: SerializedError = {\n name: error.name,\n message: error.message,\n };\n const code = (error as NodeJS.ErrnoException).code;\n if (typeof code === 'string') serialized.code = code;\n const stack = error.stack;\n if (stack) serialized.stack = stack;\n // The depth cap guards cyclic causes\n if (error.cause != null && depth < 4)\n serialized.cause = serializeError(error.cause, depth + 1)!;\n return serialized;\n}\n\nfunction createEventLogger<const Category extends string>(\n category: Category,\n level: number | undefined\n): EventLogger<Category> {\n function log(event: string, data?: Record<string, unknown>) {\n if (eventLogState.primarySink && (!level || eventLogState.debug))\n writeEvent(\n eventLogState.primarySink,\n category,\n event,\n data,\n eventLogState.eventMeta,\n level\n );\n }\n\n log.span = function span(_event: string, data?: Record<string, unknown>) {\n if (!eventLogState.primarySink || (level && !eventLogState.debug))\n return NOOP_DONE;\n const start = performance.now();\n return function done(event: string, endData?: Record<string, unknown>) {\n if (!eventLogState.primarySink) return;\n writeCompleteEvent(\n eventLogState.primarySink,\n category,\n event,\n data,\n endData,\n performance.now() - start,\n eventLogState.eventMeta,\n level\n );\n };\n };\n\n log.path = function relativePath(target: string | undefined | null) {\n return {\n toJSON(): string | null {\n try {\n return target != null && path.isAbsolute(target)\n ? path\n .relative(eventLogState.logPath, target)\n .replace(/\\\\/g, '/') || '.'\n : (target ?? null);\n } catch {\n return target || null;\n }\n },\n };\n };\n\n log.error = function error(error: unknown) {\n return {\n toJSON: () => serializeError(error),\n };\n };\n log.category = category;\n return log as EventLogger<Category>;\n}\n\nexport function events<const Category extends string>(\n category: Category\n): EventLogger<Category> {\n return createEventLogger(category, undefined);\n}\n\nevents.debug = function debug<const Category extends string>(\n category: Category\n): EventLogger<Category> {\n return createEventLogger(category, EVENT_LEVEL_DEBUG);\n};\n","import { LOG_DEBUG_ENV } from './constants';\nimport {\n compileEventFilter,\n matchesTapOptions,\n parseEventLine,\n} from './utils/eventFilter';\nimport type { EventSink } from './utils/logStream';\nimport { formatPrettyEvent, shouldColorizeStream } from './utils/pretty';\n\nexport function createDebugSink(\n value = process.env[LOG_DEBUG_ENV]\n): EventSink | null {\n const filter = compileLogDebugFilter(value);\n if (!filter) return null;\n\n const colorize = shouldColorizeStream(process.stderr);\n return {\n get writable() {\n return true;\n },\n _writeln(data: string) {\n // Ingested worker blocks can carry multiple lines per write\n let start = 0;\n let end: number;\n while ((end = data.indexOf('\\n', start)) !== -1) {\n const line = data.slice(start, end);\n start = end + 1;\n if (!line) continue;\n // LOG_DEBUG is itself the debug opt-in\n const event = parseEventLine(line, { debug: true });\n if (!event || !matchesTapOptions(event, { debug: true }, filter))\n continue;\n process.stderr.write(\n `${formatPrettyEvent(event, {\n colorize,\n stream: process.stderr,\n })}\\n`\n );\n }\n return true;\n },\n end(cb?: () => void) {\n cb?.();\n return this;\n },\n destroy() {},\n };\n}\n\nfunction compileLogDebugFilter(value: string | undefined) {\n const patterns = value\n ?.split(/[\\s,]+/)\n .map(pattern => pattern.trim())\n .filter(Boolean);\n if (!patterns?.length) return null;\n return compileEventFilter(patterns);\n}\n","import { Buffer } from 'node:buffer';\nimport { EventEmitter } from 'node:events';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst BUSY_WRITE_TIMEOUT = 100;\nconst HIGH_WATER_MARK = 16_384;\nconst WRITE_BATCH_SIZE = 65_536;\n\nexport interface EventSink {\n readonly writable: boolean;\n readonly file?: string | null;\n readonly buffered?: number;\n _writeln(data: string): boolean;\n flush?(cb: (error?: Error | null) => void): void;\n end(cb?: () => void): this;\n destroy(): void;\n}\n\nexport interface LogStreamOptions {\n closeFd?: boolean;\n}\n\nexport type LogStreamDrain = (\n data: string,\n cb: (error?: Error | null) => void\n) => void;\n\nexport type LogStreamOpener = (\n onOpened: (\n error: Error | null,\n fd?: number | null,\n drain?: LogStreamDrain\n ) => void,\n stream: LogStream\n) => void;\n\nexport class LogStream\n extends EventEmitter\n implements NodeJS.WritableStream, EventSink\n{\n #fd = -1;\n #file: string | null = null;\n #oldFd: number | null = null;\n #closeFd = true;\n\n #writing = false;\n #ending = false;\n #closing = false;\n #flushPending = false;\n #destroyed = false;\n #opening = false;\n #reopening = false;\n\n #output = '';\n #len = 0;\n #lines: string[] = [];\n #head = 0;\n #partialLine = 0;\n #busyRetries = 0;\n #draining = false;\n #scheduled = false;\n #drain?: LogStreamDrain;\n\n #onRelease = (err: NodeJS.ErrnoException | null, written: number) => {\n this.#release(err, written);\n };\n\n #onDrained = (error?: Error | null) => {\n if (error != null) {\n this.#fail(error as NodeJS.ErrnoException);\n } else {\n this.#release(null, Buffer.byteLength(this.#output));\n }\n };\n\n #onScheduledWrite = () => {\n this.#scheduled = false;\n if (\n !this.#writing &&\n !this.#destroyed &&\n (this.#lines.length - this.#head > this.#partialLine || this.#output)\n ) {\n this.#writeLine();\n }\n };\n\n constructor(\n dest: string | number | LogStreamOpener,\n options: LogStreamOptions = {}\n ) {\n super();\n this.#closeFd = options.closeFd !== false;\n if (typeof dest === 'number') {\n try {\n fs.fsyncSync(dest);\n } catch {}\n this.#fd = dest;\n process.nextTick(() => this.emit('ready'));\n } else if (typeof dest === 'string') {\n this.#openFile(dest);\n } else {\n this.#open(dest, null);\n }\n }\n\n get file(): string | null {\n return this.#file;\n }\n\n get fd(): number {\n return this.#fd;\n }\n\n get writing(): boolean {\n return this.#writing;\n }\n\n get buffered(): number {\n return this.#len;\n }\n\n get writable(): boolean {\n return !this.#destroyed && !this.#ending;\n }\n\n reopen(file = this.#file) {\n if (this.#file == null)\n throw new Error('Cannot reopen an fd-only LogStream');\n if (this.#destroyed || this.#ending) return;\n if (file) this.#file = file;\n if (this.#opening) {\n this.once('ready', () => this.reopen(file));\n return;\n }\n this.#reopening = true;\n if (!this.#writing) this.#reopen();\n }\n\n #reopen() {\n if (this.#file == null) return;\n this.#reopening = false;\n this.#oldFd = this.#fd;\n this.#openFile(this.#file);\n }\n\n #retryLine(error: NodeJS.ErrnoException) {\n if (error.code === 'EAGAIN' && this.#drain != null) {\n this.#draining = true;\n this.#drain(this.#output, this.#onDrained);\n } else if (this.#busyRetries === 0) {\n this.#busyRetries = 1;\n setImmediate(() => this.#writeLine());\n } else {\n this.#busyRetries = Math.min(this.#busyRetries * 2, BUSY_WRITE_TIMEOUT);\n setTimeout(() => this.#writeLine(), this.#busyRetries);\n }\n }\n\n #release(error: NodeJS.ErrnoException | null, written: number) {\n if (error) {\n if (error.code === 'EAGAIN' || error.code === 'EBUSY') {\n this.#retryLine(error);\n } else {\n this.#fail(error);\n }\n return;\n }\n\n this.#busyRetries = 0;\n this.emit('write', written);\n\n if (written === this.#output.length) {\n // Complete write; exact for ASCII, the common case for JSONL\n this.#len -= this.#output.length;\n this.#output = '';\n } else {\n const outputLength = Buffer.byteLength(this.#output);\n if (outputLength > written) {\n const output = Buffer.from(this.#output).toString('utf8', written);\n this.#len -= this.#output.length - output.length;\n this.#output = output;\n } else {\n this.#len -= this.#output.length;\n this.#output = '';\n }\n }\n\n if (this.#output) {\n this.#writeLine();\n } else if (this.#closing && !this.#ending) {\n this.#writing = false;\n this.#close();\n } else if (this.#lines.length - this.#head > this.#partialLine) {\n this.#writeLine();\n } else if (this.#reopening) {\n this.#writing = false;\n this.#reopen();\n } else if (this.#ending) {\n this.#writing = false;\n this.#close();\n } else {\n this.#writing = false;\n this.#draining = false;\n if (this.#flushPending) {\n this.emit('drain');\n }\n }\n }\n\n #openFile(file: string) {\n this.#open(onOpened => {\n fs.mkdir(path.dirname(file), { recursive: true }, () => {\n fs.open(file, 'a', 0o600, (error, fd) => {\n if (error || fd == null) {\n onOpened(error);\n return;\n }\n fs.fchmod(fd, 0o600, () => {\n onOpened(null, fd);\n });\n });\n });\n }, file);\n }\n\n #open(open: LogStreamOpener, file: string | null) {\n this.#opening = true;\n this.#writing = true;\n\n const onOpened = (\n error: Error | null,\n fd?: number | null,\n drain?: LogStreamDrain\n ) => {\n const oldFd = this.#oldFd;\n this.#oldFd = null;\n if (error) {\n this.#opening = false;\n this.#fail(error as NodeJS.ErrnoException);\n } else {\n this.#fd = fd ?? -1;\n this.#file = file;\n this.#drain = drain;\n this.#opening = false;\n this.#writing = false;\n this.emit('ready');\n if (oldFd != null && oldFd !== this.#fd && !isStdFd(oldFd)) {\n fsFsync(oldFd, () => fs.close(oldFd, () => {}));\n }\n if (this.#destroyed) return;\n if (this.#closing) {\n this.#close();\n } else if (\n (!this.#writing &&\n this.#lines.length - this.#head > this.#partialLine) ||\n this.#flushPending\n ) {\n this.#writeLine();\n }\n }\n };\n\n open(onOpened, this);\n }\n\n #close() {\n if (this.#fd === -1 && this.#opening) {\n this.once('ready', () => this.#close());\n return;\n }\n\n this.#destroyed = true;\n this.#partialLine = 0;\n this.#lines.length = 0;\n this.#head = 0;\n\n const onClose = (error?: NodeJS.ErrnoException | null) => {\n if (error) {\n this.emit('error', error);\n this.emit('close', error);\n } else {\n if (this.#ending && !this.#writing) this.emit('finish');\n this.emit('close');\n }\n };\n\n if (this.#fd < 0) {\n onClose();\n return;\n }\n\n fsFsync(this.#fd, error => {\n if (!error && this.#closeFd && !isStdFd(this.#fd)) {\n fs.close(this.#fd, onClose);\n } else {\n onClose(); // Error intentionally ignored, assume closed\n }\n });\n }\n\n #fail(error: NodeJS.ErrnoException) {\n this.#writing = false;\n if (this.listenerCount('error')) this.emit('error', error);\n this.#close();\n }\n\n #scheduleWrite() {\n if (!this.#scheduled) {\n this.#scheduled = true;\n setImmediate(this.#onScheduledWrite);\n }\n }\n\n #writeLine() {\n this.#writing = true;\n if (!this.#output) {\n const end = this.#lines.length - this.#partialLine;\n if (end > this.#head) {\n this.#output = this.#lines[this.#head++] || '';\n // Batch accumulated lines into one write to avoid per-line syscalls\n while (this.#head < end && this.#output.length < WRITE_BATCH_SIZE) {\n this.#output += this.#lines[this.#head++];\n }\n if (this.#head === this.#lines.length) {\n this.#lines.length = 0;\n this.#head = 0;\n }\n }\n }\n // A deep queue under backpressure stays writability-paced until it empties\n if (this.#drain != null && (this.#draining || this.#fd < 0)) {\n this.#drain(this.#output, this.#onDrained);\n } else {\n fs.write(this.#fd, this.#output, this.#onRelease);\n }\n }\n\n _end() {\n if (!this.#destroyed && !this.#ending) {\n this.#ending = true;\n if (this.#opening) {\n this.once('ready', () => this._end());\n } else if (!this.#writing && this.#fd >= 0) {\n if (this.#lines.length - this.#head > this.#partialLine) {\n this.#writeLine();\n } else {\n this.#close();\n }\n }\n }\n return this;\n }\n\n end(cb?: () => void): this;\n end(data: string | Uint8Array, cb?: () => void): this;\n end(str: string, encoding?: BufferEncoding, cb?: () => void): this;\n\n end(\n arg1?: Uint8Array | string | (() => void),\n arg2?: BufferEncoding | (() => void),\n arg3?: () => void\n ) {\n const maybeCb = arg3 || arg2 || arg1;\n const input = typeof arg1 !== 'function' ? arg1 : undefined;\n const encoding = typeof arg2 === 'string' ? arg2 : 'utf8';\n const cb = typeof maybeCb === 'function' ? maybeCb : undefined;\n if (typeof input === 'string') {\n this.write(input, encoding);\n } else if (input != null) {\n this.write(input);\n }\n if (cb) this.once('close', cb);\n return this._end();\n }\n\n destroy() {\n if (this.#destroyed || this.#closing) return;\n if (this.#writing || this.#opening) {\n this.#closing = true;\n } else if (this.#lines.length - this.#head > this.#partialLine) {\n // A scheduled write counts as pending: complete it before closing\n this.#closing = true;\n this.#writeLine();\n } else {\n this.#close();\n }\n }\n\n flush(cb?: (error?: Error | null) => void) {\n if (this.#destroyed) {\n cb?.();\n } else {\n const onDrain = () => {\n if (!this.#destroyed) {\n fsFsync(this.#fd, error => {\n this.#flushPending = false;\n if (error?.code === 'EBADF') {\n cb?.(); // If fd is closed, ignore the error\n } else {\n cb?.(error);\n }\n });\n } else {\n this.#flushPending = false;\n cb?.();\n }\n this.off('error', onError);\n };\n\n const onError = (err: Error) => {\n this.#flushPending = false;\n this.off('drain', onDrain);\n cb?.(err);\n };\n\n this.#flushPending = true;\n this.once('drain', onDrain);\n this.once('error', onError);\n\n if (!this.#writing) {\n if (\n this.#lines.length - this.#head > this.#partialLine ||\n this.#output\n ) {\n this.#writeLine();\n } else {\n process.nextTick(() => this.emit('drain'));\n }\n }\n }\n }\n\n _writeln(data: string): boolean {\n if (this.#destroyed) return false;\n this.#len += data.length;\n this.#lines.push(data);\n if (!this.#writing) this.#scheduleWrite();\n return this.#len < HIGH_WATER_MARK;\n }\n\n _write(data: string): boolean {\n if (this.#destroyed) {\n return false;\n }\n\n if (\n this.#partialLine === 0 &&\n data.charCodeAt(data.length - 1) === 10 /*'\\n'*/\n ) {\n return this._writeln(data);\n }\n\n this.#len += data.length;\n\n let startIdx = 0;\n let endIdx = -1;\n while ((endIdx = data.indexOf('\\n', startIdx)) > -1) {\n const line = data.slice(startIdx, endIdx + 1);\n if (this.#partialLine > 0) {\n this.#lines[this.#lines.length - 1] += line;\n } else {\n this.#lines.push(line);\n }\n this.#partialLine = 0;\n startIdx = ++endIdx;\n }\n\n if (startIdx < data.length) {\n const line = data.slice(startIdx);\n if (this.#partialLine > 0) {\n this.#lines[this.#lines.length - 1] += line;\n } else {\n this.#lines.push(data.slice(startIdx));\n }\n this.#partialLine = 1;\n }\n\n if (!this.#writing && this.#lines.length - this.#head > this.#partialLine) {\n this.#scheduleWrite();\n }\n\n return this.#len < HIGH_WATER_MARK;\n }\n\n write(\n buffer: Uint8Array | string,\n cb?: (err?: Error | null) => void\n ): boolean;\n write(\n str: string,\n encoding?: BufferEncoding,\n cb?: (err?: Error | null) => void\n ): boolean;\n\n write(\n input: Uint8Array | string,\n arg2?: BufferEncoding | ((err?: Error | null) => void),\n arg3?: (err?: Error | null) => void\n ): boolean {\n const maybeCb = arg3 || arg2;\n const encoding = typeof arg2 === 'string' ? arg2 : 'utf8';\n const data =\n typeof input === 'string' ? input : Buffer.from(input).toString(encoding);\n const cb = typeof maybeCb === 'function' ? maybeCb : undefined;\n try {\n return this._write(data);\n } finally {\n cb?.();\n }\n }\n\n [Symbol.dispose]() {\n this.destroy();\n }\n}\n\nconst isStdFd = (fd: number) => {\n switch (fd) {\n case 1:\n case 2:\n case process.stdout.fd:\n case process.stderr.fd:\n return true;\n default:\n return false;\n }\n};\n\nconst fsFsync = (\n fd: number,\n cb: (error?: NodeJS.ErrnoException | null) => void\n) => {\n try {\n fs.fsync(fd, cb);\n } catch (error: any) {\n cb(error);\n }\n};\n","import type net from 'node:net';\n\nimport { LogStream, type EventSink } from './logStream';\n\nconst MAX_SUBSCRIBER_BUFFERED = 4 * 1024 * 1024;\n\ninterface BroadcastSink {\n sink: EventSink;\n dropOnBackpressure: boolean;\n destroy(): void;\n}\n\n// Fallback for Windows named pipes, which expose no fd for LogStream to write to\nclass SocketSink implements EventSink {\n readonly #socket: net.Socket;\n\n constructor(socket: net.Socket) {\n this.#socket = socket;\n // A socket write error without an 'error' listener would crash the host\n socket.on('error', () => {});\n }\n\n get writable() {\n return this.#socket.writable;\n }\n\n get buffered() {\n return this.#socket.writableLength;\n }\n\n _writeln(data: string): boolean {\n return this.#socket.write(data);\n }\n\n end(cb?: () => void): this {\n this.#socket.end(cb);\n return this;\n }\n\n destroy() {\n this.#socket.destroy();\n }\n}\n\nconst createSocketSink = (socket: net.Socket): EventSink => {\n const fd = (socket as any)._handle?.fd;\n if (typeof fd === 'number' && fd >= 0) {\n return new LogStream(\n onOpened =>\n onOpened(null, fd, (data, cb) => {\n socket.write(data, cb);\n }),\n { closeFd: false }\n );\n }\n return new SocketSink(socket);\n};\n\n// Fans every line out to all sinks uniformly; only flush stays pinned to the\n// primary sink so a stalled live socket cannot delay a durability barrier\nexport class BroadcastChannel implements EventSink {\n readonly #primary: EventSink;\n readonly #sinks: BroadcastSink[] = [];\n #destroyed = false;\n\n constructor(primary: EventSink) {\n this.#primary = primary;\n this.#sinks.push({\n sink: primary,\n dropOnBackpressure: false,\n destroy: () => primary.destroy(),\n });\n }\n\n get writable() {\n if (this.#destroyed) return false;\n for (let i = 0; i < this.#sinks.length; i++) {\n if (this.#sinks[i].sink.writable) return true;\n }\n return false;\n }\n\n add(sink: EventSink | null) {\n if (!sink) return;\n if (this.#destroyed) sink.destroy();\n else\n this.#sinks.push({\n sink,\n dropOnBackpressure: false,\n destroy: () => sink.destroy(),\n });\n }\n\n attach(socket: net.Socket) {\n if (this.#destroyed) {\n socket.destroy();\n return;\n }\n socket.unref();\n const sink = createSocketSink(socket);\n const entry = {\n sink,\n dropOnBackpressure: true,\n destroy: () => {\n sink.destroy();\n socket.destroy();\n },\n };\n this.#sinks.push(entry);\n const detach = () => {\n const index = this.#sinks.indexOf(entry);\n if (index > -1) this.#sinks.splice(index, 1);\n entry.destroy();\n };\n socket.on('close', detach);\n socket.on('error', detach);\n }\n\n ingest(socket: net.Socket) {\n // Forward complete lines as one block; hold back only the partial tail\n let pending = '';\n socket.unref();\n socket.setEncoding('utf8');\n socket.on('data', (chunk: string) => {\n const data = pending ? pending + chunk : chunk;\n const end = data.lastIndexOf('\\n');\n if (end === data.length - 1) {\n pending = '';\n this._writeln(data);\n } else if (end === -1) {\n pending = data;\n } else {\n pending = data.slice(end + 1);\n this._writeln(data.slice(0, end + 1));\n }\n });\n socket.on('error', () => {});\n }\n\n _writeln(line: string): boolean {\n const sinks = this.#sinks;\n let writable = false;\n for (let i = sinks.length - 1; i >= 0; i--) {\n const entry = sinks[i];\n const accepted = entry.sink._writeln(line);\n if (\n !accepted &&\n entry.dropOnBackpressure &&\n (entry.sink.buffered ?? Infinity) > MAX_SUBSCRIBER_BUFFERED\n ) {\n sinks.splice(i, 1);\n entry.destroy();\n }\n writable = accepted || writable;\n }\n return writable;\n }\n\n flush(cb: (error?: Error | null) => void) {\n if (this.#primary.flush) this.#primary.flush(cb);\n else cb();\n }\n\n end(cb?: () => void): this {\n for (const entry of this.#sinks) {\n entry.sink.end(entry.sink === this.#primary ? cb : undefined);\n }\n return this;\n }\n\n destroy() {\n this.#destroyed = true;\n for (const entry of this.#sinks) entry.destroy();\n this.#sinks.length = 0;\n }\n}\n","import net from 'node:net';\n\nimport { INTERNAL_IPC_ENV } from '../constants';\nimport type { LogStreamOpener } from './logStream';\n\nconst CONNECT_RETRY_MS = 50;\nconst MAX_CONNECT_RETRY_MS = 750;\n\nexport function getParentIpcPath() {\n return process.env[INTERNAL_IPC_ENV];\n}\n\nexport function publishIpcPath(socketPath: string) {\n process.env[INTERNAL_IPC_ENV] = socketPath;\n return () => {\n if (process.env[INTERNAL_IPC_ENV] === socketPath)\n delete process.env[INTERNAL_IPC_ENV];\n };\n}\n\nexport interface OpenIpcOptions {\n retryMs?: number;\n maxRetryMs?: number;\n}\n\nexport function openIpc(\n socketPath: string,\n options: OpenIpcOptions = {}\n): LogStreamOpener {\n const retryMs = options.retryMs ?? CONNECT_RETRY_MS;\n const maxRetryMs = options.maxRetryMs ?? MAX_CONNECT_RETRY_MS;\n\n return (onOpened, stream) => {\n const startedAt = Date.now();\n const retry = (error: Error, attempt: () => void) => {\n if (Date.now() - startedAt > maxRetryMs) onOpened(error);\n else setTimeout(attempt, retryMs);\n };\n\n const attempt = () => {\n const socket = net.connect(socketPath);\n let opened = false;\n socket.once('connect', () => {\n const fd = (socket as any)._handle?.fd;\n opened = true;\n socket.unref();\n // The socket owns the borrowed fd; its close must stop the stream\n socket.once('close', () => stream.destroy());\n // A pending drain must keep the process alive until it flushes\n const drain = (data: string, cb: (error?: Error | null) => void) => {\n socket.ref();\n socket.write(data, error => {\n socket.unref();\n cb(error);\n });\n };\n if (typeof fd === 'number' && fd >= 0) {\n onOpened(null, fd, drain);\n } else {\n onOpened(null, null, drain);\n }\n });\n socket.once('error', error => {\n if (opened) return;\n socket.destroy();\n retry(error, attempt);\n });\n };\n attempt();\n };\n}\n","import { isMainThread, threadId } from 'node:worker_threads';\n\nimport { INTERNAL_PROCESS_ORIGIN_ENV } from '../constants';\n\nconst LOCAL_PROCESS_ORIGIN = Symbol.for('2g/process-origin');\n\ninterface EventLogGlobal {\n [LOCAL_PROCESS_ORIGIN]?: string;\n}\n\nexport interface ProcessOrigin {\n kind: 'worker_thread' | 'event_log_child' | 'child_process';\n id: string;\n}\n\nexport function setLocalProcessOrigin(id: string | undefined) {\n const globalScope = globalThis as EventLogGlobal;\n if (id) globalScope[LOCAL_PROCESS_ORIGIN] = id;\n else delete globalScope[LOCAL_PROCESS_ORIGIN];\n}\n\nexport function getProcessOrigin(): ProcessOrigin | null {\n if (!isMainThread) {\n return { kind: 'worker_thread', id: String(threadId) };\n }\n\n const localOrigin = (globalThis as EventLogGlobal)[LOCAL_PROCESS_ORIGIN];\n const inheritedOrigin = process.env[INTERNAL_PROCESS_ORIGIN_ENV];\n if (inheritedOrigin && inheritedOrigin !== localOrigin) {\n return {\n kind: 'event_log_child',\n id: inheritedOrigin,\n };\n }\n\n if (process.env.NODE_UNIQUE_ID) {\n return { kind: 'child_process', id: process.env.NODE_UNIQUE_ID };\n }\n\n return null;\n}\n\nexport function getProcessWorkerId() {\n const origin = getProcessOrigin();\n return origin ? `${origin.kind}:${origin.id}` : undefined;\n}\n\nexport function publishProcessOrigin() {\n const origin = String(process.pid);\n process.env[INTERNAL_PROCESS_ORIGIN_ENV] = origin;\n setLocalProcessOrigin(origin);\n return () => {\n if (process.env[INTERNAL_PROCESS_ORIGIN_ENV] === origin)\n delete process.env[INTERNAL_PROCESS_ORIGIN_ENV];\n setLocalProcessOrigin(undefined);\n };\n}\n","const PROCESS_CLEANUP = Symbol.for('2g/process-cleanup');\n\ninterface EventLogGlobal {\n [PROCESS_CLEANUP]?: ProcessCleanupState;\n}\n\ninterface ProcessCleanupState {\n registered: boolean;\n callbacks: Set<() => void>;\n}\n\nexport function registerProcessCleanup(callback: () => void) {\n const cleanup = getProcessCleanupState();\n cleanup.callbacks.add(callback);\n if (cleanup.registered) return;\n cleanup.registered = true;\n\n process.once('exit', runProcessCleanup);\n for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'] as const) {\n process.once(signal, () => {\n if (process.listenerCount(signal) > 0) return;\n runProcessCleanup();\n process.kill(process.pid, signal);\n });\n }\n}\n\nfunction getProcessCleanupState() {\n const globalScope = globalThis as EventLogGlobal;\n return (globalScope[PROCESS_CLEANUP] ??= {\n registered: false,\n callbacks: new Set(),\n });\n}\n\nfunction runProcessCleanup() {\n for (const callback of getProcessCleanupState().callbacks) {\n try {\n callback();\n } catch {}\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport net from 'node:net';\n\nimport {\n DEFAULT_SEGMENTS,\n DEFAULT_SEGMENT_SIZE,\n EVENT_LOG_FORMAT_VERSION,\n SESSION_FILES,\n} from './constants';\nimport { cleanStaleSessionsSync, getSessionBaseDir } from './clean';\nimport { createDebugSink } from './debug';\nimport { BroadcastChannel } from './utils/broadcastChannel';\nimport { LogStream, type EventSink } from './utils/logStream';\nimport { publishIpcPath } from './utils/ipc';\nimport { publishProcessOrigin } from './utils/processOrigin';\nimport { registerProcessCleanup } from './utils/processExit';\nimport {\n createSocketAddress,\n listenSocket,\n removeSocket,\n} from './utils/sessionSockets';\n\nexport interface SessionOptions {\n command?: string;\n version?: string;\n maxSegments?: number;\n maxSegmentSize?: number;\n}\n\nexport interface SessionMeta {\n pid: number;\n formatVersion: number;\n startedAt: number;\n command: string;\n cwd: string;\n maxSegments: number;\n version?: string;\n // Relative to meta.json, or a Windows named-pipe name\n socket: string;\n ipcSocket: string;\n origin: {\n argv: string[];\n execPath: string;\n cwd: string;\n ppid?: number;\n env?: {\n npmLifecycleEvent?: string;\n npmExecPath?: string;\n npmPackageName?: string;\n };\n };\n}\n\nexport interface SessionContext {\n sessionDir: string;\n meta: SessionMeta;\n sink: EventSink;\n destroy(): void;\n}\n\nexport function createSession(options: SessionOptions): SessionContext {\n const baseDir = getSessionBaseDir();\n const startedAt = Date.now();\n // The name is collision-free across PID reuse and never parsed by readers\n const sessionId = `${process.pid}-${startedAt.toString(36)}-${Math.random()\n .toString(36)\n .slice(2, 8)\n .padEnd(6, '0')}`;\n const sessionDir = path.join(baseDir, sessionId);\n // An unwritable tmpdir must not crash the host\n try {\n fs.mkdirSync(sessionDir, { recursive: true, mode: 0o700 });\n // A base dir created before permissions were restricted stays 0755\n fs.chmodSync(baseDir, 0o700);\n } catch {}\n\n const maxSegments = options.maxSegments ?? DEFAULT_SEGMENTS;\n const maxSegmentSize = options.maxSegmentSize ?? DEFAULT_SEGMENT_SIZE;\n const liveSocket = createSocketAddress(sessionDir, sessionId, 'live');\n const ipcSocket = createSocketAddress(sessionDir, sessionId, 'ipc');\n\n const fileStream = new LogStream(path.join(sessionDir, '0.jsonl'));\n const sink = new BroadcastChannel(fileStream);\n sink.add(createDebugSink());\n trackSegmentRotation(fileStream, sessionDir, maxSegments, maxSegmentSize);\n\n const liveServer = net.createServer(socket => sink.attach(socket));\n const ipcServer = net.createServer(socket => sink.ingest(socket));\n const closeLiveServer = listenSocket(liveServer, liveSocket.path);\n const closeIpcServer = listenSocket(ipcServer, ipcSocket.path);\n const restoreIpcPath = publishIpcPath(ipcSocket.path);\n const restoreProcessOrigin = publishProcessOrigin();\n\n const meta: SessionMeta = {\n pid: process.pid,\n formatVersion: EVENT_LOG_FORMAT_VERSION,\n startedAt,\n command: options.command ?? process.argv.slice(1).join(' '),\n cwd: process.cwd(),\n maxSegments,\n version: options.version,\n socket: liveSocket.name,\n ipcSocket: ipcSocket.name,\n origin: createSessionOrigin(),\n };\n // Without meta.json the session is invisible to tooling; logging still works\n try {\n writeJsonAtomic(path.join(sessionDir, SESSION_FILES.meta), meta);\n } catch {}\n\n let destroyed = false;\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n sink.destroy();\n closeLiveServer();\n closeIpcServer();\n restoreIpcPath();\n restoreProcessOrigin();\n // rmSync can throw EPERM/EBUSY and must not skip the restoration above\n removeSocket(liveSocket.path);\n removeSocket(ipcSocket.path);\n };\n\n registerProcessCleanup(destroy);\n\n // Stale-session cleanup stays off the install hot path\n setImmediate(() => {\n try {\n cleanStaleSessionsSync();\n } catch {}\n });\n\n return { sessionDir, meta, sink, destroy };\n}\n\nfunction trackSegmentRotation(\n stream: LogStream,\n sessionDir: string,\n maxSegments: number,\n maxSegmentSize: number\n) {\n let bytesWritten = 0;\n stream.on('write', written => {\n bytesWritten += written;\n if (bytesWritten < maxSegmentSize) return;\n bytesWritten = 0;\n rotateSegments(sessionDir, maxSegments);\n stream.reopen();\n });\n}\n\nfunction rotateSegments(sessionDir: string, maxSegments: number) {\n fs.rmSync(path.join(sessionDir, `${maxSegments - 1}.jsonl`), { force: true });\n for (let i = maxSegments - 1; i >= 1; i--) {\n const from = path.join(sessionDir, `${i - 1}.jsonl`);\n const to = path.join(sessionDir, `${i}.jsonl`);\n try {\n fs.renameSync(from, to);\n } catch {}\n }\n}\n\nfunction writeJsonAtomic(file: string, data: unknown) {\n const tmp = `${file}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 0o600 });\n fs.renameSync(tmp, file);\n}\n\nfunction createSessionOrigin(): SessionMeta['origin'] {\n const env = {\n npmLifecycleEvent: process.env.npm_lifecycle_event,\n npmExecPath: process.env.npm_execpath,\n npmPackageName: process.env.npm_package_name,\n };\n return {\n argv: process.argv.slice(1),\n execPath: process.execPath,\n cwd: process.cwd(),\n ppid: process.ppid || undefined,\n env: Object.values(env).some(Boolean) ? env : undefined,\n };\n}\n","import path from 'node:path';\n\nimport { events } from './events';\nimport {\n EVENT_LOG_FORMAT_VERSION,\n LOG_DEBUG_ENV,\n LOG_EVENTS_ENV,\n} from './constants';\nimport { eventLogState, type EventLoggerInfo } from './state';\nimport { createSession, type SessionOptions } from './session';\nimport {\n LogStream,\n type EventSink,\n type LogStreamOpener,\n type LogStreamOptions,\n} from './utils/logStream';\nimport { getParentIpcPath, openIpc } from './utils/ipc';\nimport { getProcessOrigin, getProcessWorkerId } from './utils/processOrigin';\nimport { redirectConsoleForFd } from './utils/redirectConsole';\n\nexport type { EventLoggerInfo } from './state';\n\nexport interface InstallEventLoggerOptions extends SessionOptions {\n session?: boolean;\n debug?: boolean;\n}\n\nconst rootEvent = events('root');\n\nexport function installEventLogger(\n targetOrOptions?: string | number | InstallEventLoggerOptions\n): void {\n if (eventLogState.primarySink) return;\n\n const options =\n targetOrOptions && typeof targetOrOptions === 'object'\n ? targetOrOptions\n : undefined;\n\n const explicitTarget =\n parseLogTarget(process.env[LOG_EVENTS_ENV]) ??\n parseLogTarget(\n typeof targetOrOptions === 'string' || typeof targetOrOptions === 'number'\n ? targetOrOptions\n : undefined\n );\n\n if (explicitTarget != null) {\n if (typeof explicitTarget === 'number')\n redirectConsoleForFd(explicitTarget);\n eventLogState.debug = options?.debug ?? true;\n eventLogState.eventLoggerInfo = getExplicitTargetInfo(explicitTarget);\n activateSink(createPrimarySink(explicitTarget));\n return;\n }\n\n const ipcPath = getParentIpcPath();\n if (ipcPath) {\n eventLogState.debug = options?.debug ?? !!process.env[LOG_DEBUG_ENV];\n connectToParent(ipcPath);\n return;\n }\n\n if (options && options.session !== false) {\n eventLogState.debug = options.debug ?? !!process.env[LOG_DEBUG_ENV];\n const session = createSession(options);\n eventLogState.logPath = session.sessionDir;\n eventLogState.eventLoggerInfo = {\n destination: 'session',\n isUserVisibleOutput: false,\n sessionDir: session.sessionDir,\n };\n activateSink(session.sink, options.version);\n return;\n }\n}\n\nexport const getEventLoggerInfo = (): EventLoggerInfo | null =>\n eventLogState.primarySink?.writable ? eventLogState.eventLoggerInfo : null;\n\nexport function flushEventLogger(): Promise<void> {\n return new Promise(resolve => {\n const sink = eventLogState.primarySink;\n if (sink?.flush) sink.flush(() => resolve());\n else resolve();\n });\n}\n\nfunction parseLogTarget(target: string | number | undefined) {\n if (typeof target === 'number') {\n return Number.isSafeInteger(target) && target > 0 ? target : undefined;\n }\n\n if (!target) return undefined;\n\n const fd = parseInt(target, 10);\n if (`${fd}` === target && fd > 0 && Number.isSafeInteger(fd)) return fd;\n\n try {\n const parsedPath = path.parse(target);\n const destination = path.format(parsedPath);\n eventLogState.logPath = parsedPath.dir || process.cwd();\n return destination;\n } catch {\n return undefined;\n }\n}\n\nfunction createPrimarySink(\n dest: string | number | LogStreamOpener,\n options?: LogStreamOptions\n) {\n const stream = new LogStream(dest, options);\n // A dead target restores the no-op hot path\n stream.once('error', () => {\n eventLogState.primarySink = undefined;\n eventLogState.eventLoggerInfo = null;\n });\n return stream;\n}\n\nfunction getExplicitTargetInfo(target: string | number): EventLoggerInfo {\n if (typeof target === 'number') {\n return {\n destination: target === 1 ? 'stdout' : target === 2 ? 'stderr' : 'fd',\n isUserVisibleOutput: target === 1 || target === 2,\n fd: target,\n };\n }\n\n return {\n destination: 'file',\n isUserVisibleOutput: false,\n file: target,\n };\n}\n\nfunction getInitMetadata(version?: string) {\n return {\n format: 'v0-jsonl',\n formatVersion: EVENT_LOG_FORMAT_VERSION,\n version: version ?? 'UNVERSIONED',\n processOrigin: getProcessOrigin() ?? undefined,\n };\n}\n\nfunction activateSink(sink: EventSink, version?: string) {\n eventLogState.primarySink = sink;\n rootEvent('init', getInitMetadata(version));\n}\n\nfunction connectToParent(ipcPath: string) {\n const workerId = getProcessWorkerId();\n if (workerId) eventLogState.eventMeta = { _w: workerId };\n\n eventLogState.primarySink = createPrimarySink(openIpc(ipcPath), {\n closeFd: false,\n });\n eventLogState.eventLoggerInfo = {\n destination: 'ipc',\n isUserVisibleOutput: false,\n };\n rootEvent('init', getInitMetadata());\n}\n"],"names":["STATE_SYMBOL","Symbol","for","EVENT_LOG_STATE_VERSION","eventLogState","getEventLogState","globalScope","globalThis","logPath","process","cwd","eventLoggerInfo","debug","TIME_ORIGIN","performance","timeOrigin","TIMESTAMP_FRACTIONS","Array","from","length","_","us","padStart","cachedMs","cachedMsJson","cachedWorkerId","cachedWorkerIdJson","writeEvent","dest","category","kind","payload","meta","level","_writeln","serializeEvent","duration","timestamp","stringifyTimestamp","_w","rest","JSON","stringify","slice","line","stringifyWorkerId","appendPayload","undefined","writeCompleteEvent","startPayload","endPayload","delta","appendMergedPayload","Object","assign","now","ms","Math","floor","workerId","NOOP_DONE","serializeError","error","depth","Error","String","serialized","name","message","code","stack","cause","createEventLogger","log","event","data","primarySink","eventMeta","span","_event","start","done","endData","path","relativePath","target","toJSON","isAbsolute","relative","replace","events","EVENT_LEVEL_DEBUG","createDebugSink","value","env","LOG_DEBUG_ENV","filter","compileLogDebugFilter","patterns","split","map","pattern","trim","Boolean","compileEventFilter","colorize","shouldColorizeStream","stderr","writable","end","indexOf","parseEventLine","matchesTapOptions","write","formatPrettyEvent","stream","cb","this","destroy","LogStream","EventEmitter","fd","file","oldFd","closeFd","writing","ending","closing","flushPending","destroyed","opening","reopening","output","len","lines","head","partialLine","busyRetries","draining","scheduled","drain","onRelease","#onRelease","err","written","release","onDrained","fail","Buffer","byteLength","onScheduledWrite","#onScheduledWrite","writeLine","constructor","options","super","fs","fsyncSync","nextTick","emit","openFile","open","buffered","reopen","once","retryLine","setImmediate","min","setTimeout","toString","close","onOpened","mkdir","dirname","recursive","fchmod","isStdFd","fsFsync","onClose","listenerCount","scheduleWrite","_end","arg1","arg2","arg3","maybeCb","input","flush","onDrain","off","onError","push","_write","charCodeAt","startIdx","endIdx","encoding","dispose","stdout","fsync","SocketSink","socket","on","writableLength","BroadcastChannel","primary","sinks","sink","dropOnBackpressure","i","add","attach","unref","_handle","createSocketSink","entry","detach","index","splice","ingest","pending","setEncoding","chunk","lastIndexOf","accepted","Infinity","openIpc","socketPath","retryMs","maxRetryMs","startedAt","Date","attempt","net","connect","opened","ref","retry","LOCAL_PROCESS_ORIGIN","setLocalProcessOrigin","id","getProcessOrigin","isMainThread","threadId","localOrigin","inheritedOrigin","INTERNAL_PROCESS_ORIGIN_ENV","NODE_UNIQUE_ID","PROCESS_CLEANUP","getProcessCleanupState","registered","callbacks","Set","runProcessCleanup","callback","createSession","baseDir","getSessionBaseDir","sessionId","pid","random","padEnd","sessionDir","join","mkdirSync","mode","chmodSync","maxSegments","DEFAULT_SEGMENTS","maxSegmentSize","DEFAULT_SEGMENT_SIZE","liveSocket","createSocketAddress","ipcSocket","fileStream","trackSegmentRotation","bytesWritten","rotateSegments","rmSync","force","to","renameSync","liveServer","createServer","ipcServer","closeLiveServer","listenSocket","closeIpcServer","restoreIpcPath","publishIpcPath","INTERNAL_IPC_ENV","restoreProcessOrigin","publishProcessOrigin","origin","formatVersion","EVENT_LOG_FORMAT_VERSION","command","argv","version","createSessionOrigin","writeJsonAtomic","tmp","writeFileSync","SESSION_FILES","removeSocket","registerProcessCleanup","cleanup","signal","kill","cleanStaleSessionsSync","npmLifecycleEvent","npm_lifecycle_event","npmExecPath","npm_execpath","npmPackageName","npm_package_name","execPath","ppid","values","some","rootEvent","installEventLogger","targetOrOptions","explicitTarget","parseLogTarget","LOG_EVENTS_ENV","redirectConsoleForFd","getExplicitTargetInfo","destination","isUserVisibleOutput","activateSink","createPrimarySink","ipcPath","getParentIpcPath","connectToParent","getProcessWorkerId","getInitMetadata","session","getEventLoggerInfo","flushEventLogger","Promise","resolve","Number","isSafeInteger","parseInt","parsedPath","parse","format","dir","processOrigin"],"mappings":"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"}
1
+ {"version":3,"file":"2g.mjs","sources":["../src/state.ts","../src/utils/serializeEvent.ts","../src/events.ts","../src/debug.ts","../src/utils/logStream.ts","../src/utils/broadcastChannel.ts","../src/utils/ipc.ts","../src/utils/processOrigin.ts","../src/utils/processExit.ts","../src/session.ts","../src/install.ts"],"sourcesContent":["import { EVENT_LOG_STATE_VERSION } from './constants';\nimport type { EventSink } from './utils/logStream';\nimport type { EventMeta } from './utils/serializeEvent';\n\nexport interface EventLoggerInfo {\n destination: 'file' | 'stdout' | 'stderr' | 'fd' | 'session' | 'ipc';\n isUserVisibleOutput: boolean;\n file?: string;\n fd?: number;\n sessionDir?: string;\n}\n\nexport interface EventLogState {\n logPath: string;\n primarySink?: EventSink;\n eventMeta?: EventMeta;\n eventLoggerInfo: EventLoggerInfo | null;\n debug: boolean;\n}\n\nconst STATE_SYMBOL = Symbol.for(`2g/state-${EVENT_LOG_STATE_VERSION}`);\n\ninterface EventLogGlobal {\n [STATE_SYMBOL]?: EventLogState;\n}\n\nexport const eventLogState = getEventLogState();\n\nexport function _resetEventLogState() {\n eventLogState.primarySink?.destroy();\n eventLogState.logPath = process.cwd();\n eventLogState.primarySink = undefined;\n eventLogState.eventMeta = undefined;\n eventLogState.eventLoggerInfo = null;\n eventLogState.debug = false;\n}\n\nfunction getEventLogState() {\n const globalScope = globalThis as EventLogGlobal;\n return (globalScope[STATE_SYMBOL] ??= {\n logPath: process.cwd(),\n eventLoggerInfo: null,\n debug: false,\n });\n}\n","import { performance } from 'node:perf_hooks';\n\nimport type { EventSink } from './logStream';\n\nconst TIME_ORIGIN = performance.timeOrigin;\n\nconst TIMESTAMP_FRACTIONS = Array.from(\n { length: 1000 },\n (_, us) => `.${`${us}`.padStart(3, '0')}`\n);\n\nlet cachedMs = -1;\nlet cachedMsJson = '';\nlet cachedWorkerId: string | undefined;\nlet cachedWorkerIdJson = '';\n\nexport interface EventMeta {\n _w?: string;\n}\n\nexport function serializeEvent(\n category: string,\n kind: string,\n payload: Record<string, unknown> | undefined,\n meta?: EventMeta,\n duration?: number,\n level?: number\n) {\n const timestamp = stringifyTimestamp();\n if (duration == null && !meta?._w && !level) {\n const rest = payload ? JSON.stringify(payload).slice(1) : '';\n return rest.length > 1\n ? `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp},${rest}\\n`\n : `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp}}\\n`;\n }\n\n let line = `{\"_e\":\"${category}:${kind}\",\"_t\":${timestamp}`;\n if (duration != null) line += `,\"_d\":${duration}`;\n if (level) line += `,\"_l\":${level}`;\n if (meta?._w) line += `,\"_w\":${stringifyWorkerId(meta._w)}`;\n return `${appendPayload(line, payload)}}\\n`;\n}\n\nexport function writeEvent(\n dest: EventSink,\n category: string,\n kind: string,\n payload: Record<string, unknown> | undefined,\n meta?: EventMeta,\n level?: number\n) {\n // Unserializable payloads (circular, BigInt) drop the event, never throw into the host\n try {\n dest._writeln(\n serializeEvent(category, kind, payload, meta, undefined, level)\n );\n } catch {}\n}\n\nexport function writeCompleteEvent(\n dest: EventSink,\n category: string,\n kind: string,\n startPayload: Record<string, unknown> | undefined,\n endPayload: Record<string, unknown> | undefined,\n delta: number,\n meta?: EventMeta,\n level?: number\n) {\n try {\n let line = `{\"_e\":\"${category}:${kind}\",\"_t\":${stringifyTimestamp()},\"_d\":${delta}`;\n if (level) line += `,\"_l\":${level}`;\n if (meta?._w) line += `,\"_w\":${stringifyWorkerId(meta._w)}`;\n dest._writeln(`${appendMergedPayload(line, startPayload, endPayload)}}\\n`);\n } catch {}\n}\n\nexport function getEventTimestamp() {\n return TIME_ORIGIN + performance.now();\n}\n\nfunction stringifyTimestamp() {\n const timestamp = TIME_ORIGIN + performance.now();\n const ms = Math.floor(timestamp);\n if (ms !== cachedMs) {\n cachedMs = ms;\n cachedMsJson = `${ms}`;\n }\n return cachedMsJson + TIMESTAMP_FRACTIONS[((timestamp - ms) * 1000) | 0];\n}\n\nfunction stringifyWorkerId(workerId: string) {\n if (workerId !== cachedWorkerId) {\n cachedWorkerId = workerId;\n cachedWorkerIdJson = JSON.stringify(workerId);\n }\n return cachedWorkerIdJson;\n}\n\nfunction appendPayload(line: string, payload?: Record<string, unknown>) {\n if (!payload) return line;\n const rest = JSON.stringify(payload);\n return rest && rest.length > 2 ? `${line},${rest.slice(1, -1)}` : line;\n}\n\nfunction appendMergedPayload(\n line: string,\n startPayload?: Record<string, unknown>,\n endPayload?: Record<string, unknown>\n) {\n if (!startPayload) return appendPayload(line, endPayload);\n if (!endPayload) return appendPayload(line, startPayload);\n return appendPayload(line, Object.assign(startPayload, endPayload));\n}\n","import path from 'node:path';\nimport { performance } from 'node:perf_hooks';\n\nimport { EVENT_LEVEL_DEBUG } from './constants';\nimport { eventLogState } from './state';\nimport { writeCompleteEvent, writeEvent } from './utils/serializeEvent';\nimport type { EventLogger, SerializedError, SpanEnd } from './types';\n\nconst NOOP_DONE: SpanEnd<any> = () => {};\n\nfunction serializeError(\n error: unknown,\n depth = 0\n): SerializedError | string | null {\n if (error == null) return null;\n if (!(error instanceof Error)) return String(error);\n const serialized: SerializedError = {\n name: error.name,\n message: error.message,\n };\n const code = (error as NodeJS.ErrnoException).code;\n if (typeof code === 'string') serialized.code = code;\n const stack = error.stack;\n if (stack) serialized.stack = stack;\n // The depth cap guards cyclic causes\n if (error.cause != null && depth < 4)\n serialized.cause = serializeError(error.cause, depth + 1)!;\n return serialized;\n}\n\nfunction createEventLogger<const Category extends string>(\n category: Category,\n level: number | undefined\n): EventLogger<Category> {\n function log(event: string, data?: Record<string, unknown>) {\n if (eventLogState.primarySink && (!level || eventLogState.debug))\n writeEvent(\n eventLogState.primarySink,\n category,\n event,\n data,\n eventLogState.eventMeta,\n level\n );\n }\n\n log.span = function span() {\n if (!eventLogState.primarySink || (level && !eventLogState.debug))\n return NOOP_DONE;\n const start = performance.now();\n return function done(event: string, data?: Record<string, unknown>) {\n if (!eventLogState.primarySink) return;\n writeCompleteEvent(\n eventLogState.primarySink,\n category,\n event,\n data,\n undefined,\n performance.now() - start,\n eventLogState.eventMeta,\n level\n );\n };\n };\n\n log.path = function relativePath(target: string | undefined | null) {\n return {\n toJSON(): string | null {\n try {\n return target != null && path.isAbsolute(target)\n ? path\n .relative(eventLogState.logPath, target)\n .replace(/\\\\/g, '/') || '.'\n : (target ?? null);\n } catch {\n return target || null;\n }\n },\n };\n };\n\n log.error = function error(error: unknown) {\n return {\n toJSON: () => serializeError(error),\n };\n };\n log.category = category;\n return log as EventLogger<Category>;\n}\n\nexport function events<const Category extends string>(\n category: Category\n): EventLogger<Category> {\n return createEventLogger(category, undefined);\n}\n\nevents.debug = function debug<const Category extends string>(\n category: Category\n): EventLogger<Category> {\n return createEventLogger(category, EVENT_LEVEL_DEBUG);\n};\n","import { LOG_DEBUG_ENV } from './constants';\nimport {\n compileEventFilter,\n matchesTapOptions,\n parseEventLine,\n} from './utils/eventFilter';\nimport type { EventSink } from './utils/logStream';\nimport { formatPrettyEvent, shouldColorizeStream } from './utils/pretty';\n\nexport function createDebugSink(\n value = process.env[LOG_DEBUG_ENV]\n): EventSink | null {\n const filter = compileLogDebugFilter(value);\n if (!filter) return null;\n\n const colorize = shouldColorizeStream(process.stderr);\n return {\n get writable() {\n return true;\n },\n _writeln(data: string) {\n // Ingested worker blocks can carry multiple lines per write\n let start = 0;\n let end: number;\n while ((end = data.indexOf('\\n', start)) !== -1) {\n const line = data.slice(start, end);\n start = end + 1;\n if (!line) continue;\n // LOG_DEBUG is itself the debug opt-in\n const event = parseEventLine(line, { debug: true });\n if (!event || !matchesTapOptions(event, { debug: true }, filter))\n continue;\n process.stderr.write(\n `${formatPrettyEvent(event, {\n colorize,\n stream: process.stderr,\n })}\\n`\n );\n }\n return true;\n },\n end(cb?: () => void) {\n cb?.();\n return this;\n },\n destroy() {},\n };\n}\n\nfunction compileLogDebugFilter(value: string | undefined) {\n const patterns = value\n ?.split(/[\\s,]+/)\n .map(pattern => pattern.trim())\n .filter(Boolean);\n if (!patterns?.length) return null;\n return compileEventFilter(patterns);\n}\n","import { Buffer } from 'node:buffer';\nimport { EventEmitter } from 'node:events';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nconst BUSY_WRITE_TIMEOUT = 100;\nconst HIGH_WATER_MARK = 16_384;\nconst WRITE_BATCH_SIZE = 65_536;\n\nexport interface EventSink {\n readonly writable: boolean;\n readonly file?: string | null;\n readonly buffered?: number;\n _writeln(data: string): boolean;\n flush?(cb: (error?: Error | null) => void): void;\n end(cb?: () => void): this;\n destroy(): void;\n}\n\nexport interface LogStreamOptions {\n closeFd?: boolean;\n}\n\nexport type LogStreamDrain = (\n data: string,\n cb: (error?: Error | null) => void\n) => void;\n\nexport type LogStreamOpener = (\n onOpened: (\n error: Error | null,\n fd?: number | null,\n drain?: LogStreamDrain\n ) => void,\n stream: LogStream\n) => void;\n\nexport class LogStream\n extends EventEmitter\n implements NodeJS.WritableStream, EventSink\n{\n #fd = -1;\n #file: string | null = null;\n #oldFd: number | null = null;\n #closeFd = true;\n\n #writing = false;\n #ending = false;\n #closing = false;\n #flushPending = false;\n #destroyed = false;\n #opening = false;\n #reopening = false;\n\n #output = '';\n #len = 0;\n #lines: string[] = [];\n #head = 0;\n #partialLine = 0;\n #busyRetries = 0;\n #draining = false;\n #scheduled = false;\n #drain?: LogStreamDrain;\n\n #onRelease = (err: NodeJS.ErrnoException | null, written: number) => {\n this.#release(err, written);\n };\n\n #onDrained = (error?: Error | null) => {\n if (error != null) {\n this.#fail(error as NodeJS.ErrnoException);\n } else {\n this.#release(null, Buffer.byteLength(this.#output));\n }\n };\n\n #onScheduledWrite = () => {\n this.#scheduled = false;\n if (\n !this.#writing &&\n !this.#destroyed &&\n (this.#lines.length - this.#head > this.#partialLine || this.#output)\n ) {\n this.#writeLine();\n }\n };\n\n constructor(\n dest: string | number | LogStreamOpener,\n options: LogStreamOptions = {}\n ) {\n super();\n this.#closeFd = options.closeFd !== false;\n if (typeof dest === 'number') {\n try {\n fs.fsyncSync(dest);\n } catch {}\n this.#fd = dest;\n process.nextTick(() => this.emit('ready'));\n } else if (typeof dest === 'string') {\n this.#openFile(dest);\n } else {\n this.#open(dest, null);\n }\n }\n\n get file(): string | null {\n return this.#file;\n }\n\n get fd(): number {\n return this.#fd;\n }\n\n get writing(): boolean {\n return this.#writing;\n }\n\n get buffered(): number {\n return this.#len;\n }\n\n get writable(): boolean {\n return !this.#destroyed && !this.#ending;\n }\n\n reopen(file = this.#file) {\n if (this.#file == null)\n throw new Error('Cannot reopen an fd-only LogStream');\n if (this.#destroyed || this.#ending) return;\n if (file) this.#file = file;\n if (this.#opening) {\n this.once('ready', () => this.reopen(file));\n return;\n }\n this.#reopening = true;\n if (!this.#writing) this.#reopen();\n }\n\n #reopen() {\n if (this.#file == null) return;\n this.#reopening = false;\n this.#oldFd = this.#fd;\n this.#openFile(this.#file);\n }\n\n #retryLine(error: NodeJS.ErrnoException) {\n if (error.code === 'EAGAIN' && this.#drain != null) {\n this.#draining = true;\n this.#drain(this.#output, this.#onDrained);\n } else if (this.#busyRetries === 0) {\n this.#busyRetries = 1;\n setImmediate(() => this.#writeLine());\n } else {\n this.#busyRetries = Math.min(this.#busyRetries * 2, BUSY_WRITE_TIMEOUT);\n setTimeout(() => this.#writeLine(), this.#busyRetries);\n }\n }\n\n #release(error: NodeJS.ErrnoException | null, written: number) {\n if (error) {\n if (error.code === 'EAGAIN' || error.code === 'EBUSY') {\n this.#retryLine(error);\n } else {\n this.#fail(error);\n }\n return;\n }\n\n this.#busyRetries = 0;\n this.emit('write', written);\n\n if (written === this.#output.length) {\n // Complete write; exact for ASCII, the common case for JSONL\n this.#len -= this.#output.length;\n this.#output = '';\n } else {\n const outputLength = Buffer.byteLength(this.#output);\n if (outputLength > written) {\n const output = Buffer.from(this.#output).toString('utf8', written);\n this.#len -= this.#output.length - output.length;\n this.#output = output;\n } else {\n this.#len -= this.#output.length;\n this.#output = '';\n }\n }\n\n if (this.#output) {\n this.#writeLine();\n } else if (this.#closing && !this.#ending) {\n this.#writing = false;\n this.#close();\n } else if (this.#lines.length - this.#head > this.#partialLine) {\n this.#writeLine();\n } else if (this.#reopening) {\n this.#writing = false;\n this.#reopen();\n } else if (this.#ending) {\n this.#writing = false;\n this.#close();\n } else {\n this.#writing = false;\n this.#draining = false;\n if (this.#flushPending) {\n this.emit('drain');\n }\n }\n }\n\n #openFile(file: string) {\n this.#open(onOpened => {\n fs.mkdir(path.dirname(file), { recursive: true }, () => {\n fs.open(file, 'a', 0o600, (error, fd) => {\n if (error || fd == null) {\n onOpened(error);\n return;\n }\n fs.fchmod(fd, 0o600, () => {\n onOpened(null, fd);\n });\n });\n });\n }, file);\n }\n\n #open(open: LogStreamOpener, file: string | null) {\n this.#opening = true;\n this.#writing = true;\n\n const onOpened = (\n error: Error | null,\n fd?: number | null,\n drain?: LogStreamDrain\n ) => {\n const oldFd = this.#oldFd;\n this.#oldFd = null;\n if (error) {\n this.#opening = false;\n this.#fail(error as NodeJS.ErrnoException);\n } else {\n this.#fd = fd ?? -1;\n this.#file = file;\n this.#drain = drain;\n this.#opening = false;\n this.#writing = false;\n this.emit('ready');\n if (oldFd != null && oldFd !== this.#fd && !isStdFd(oldFd)) {\n fsFsync(oldFd, () => fs.close(oldFd, () => {}));\n }\n if (this.#destroyed) return;\n if (this.#closing) {\n this.#close();\n } else if (\n (!this.#writing &&\n this.#lines.length - this.#head > this.#partialLine) ||\n this.#flushPending\n ) {\n this.#writeLine();\n }\n }\n };\n\n open(onOpened, this);\n }\n\n #close() {\n if (this.#fd === -1 && this.#opening) {\n this.once('ready', () => this.#close());\n return;\n }\n\n this.#destroyed = true;\n this.#partialLine = 0;\n this.#lines.length = 0;\n this.#head = 0;\n\n const onClose = (error?: NodeJS.ErrnoException | null) => {\n if (error) {\n this.emit('error', error);\n this.emit('close', error);\n } else {\n if (this.#ending && !this.#writing) this.emit('finish');\n this.emit('close');\n }\n };\n\n if (this.#fd < 0) {\n onClose();\n return;\n }\n\n fsFsync(this.#fd, error => {\n if (!error && this.#closeFd && !isStdFd(this.#fd)) {\n fs.close(this.#fd, onClose);\n } else {\n onClose(); // Error intentionally ignored, assume closed\n }\n });\n }\n\n #fail(error: NodeJS.ErrnoException) {\n this.#writing = false;\n if (this.listenerCount('error')) this.emit('error', error);\n this.#close();\n }\n\n #scheduleWrite() {\n if (!this.#scheduled) {\n this.#scheduled = true;\n setImmediate(this.#onScheduledWrite);\n }\n }\n\n #writeLine() {\n this.#writing = true;\n if (!this.#output) {\n const end = this.#lines.length - this.#partialLine;\n if (end > this.#head) {\n this.#output = this.#lines[this.#head++] || '';\n // Batch accumulated lines into one write to avoid per-line syscalls\n while (this.#head < end && this.#output.length < WRITE_BATCH_SIZE) {\n this.#output += this.#lines[this.#head++];\n }\n if (this.#head === this.#lines.length) {\n this.#lines.length = 0;\n this.#head = 0;\n }\n }\n }\n // A deep queue under backpressure stays writability-paced until it empties\n if (this.#drain != null && (this.#draining || this.#fd < 0)) {\n this.#drain(this.#output, this.#onDrained);\n } else {\n fs.write(this.#fd, this.#output, this.#onRelease);\n }\n }\n\n _end() {\n if (!this.#destroyed && !this.#ending) {\n this.#ending = true;\n if (this.#opening) {\n this.once('ready', () => this._end());\n } else if (!this.#writing && this.#fd >= 0) {\n if (this.#lines.length - this.#head > this.#partialLine) {\n this.#writeLine();\n } else {\n this.#close();\n }\n }\n }\n return this;\n }\n\n end(cb?: () => void): this;\n end(data: string | Uint8Array, cb?: () => void): this;\n end(str: string, encoding?: BufferEncoding, cb?: () => void): this;\n\n end(\n arg1?: Uint8Array | string | (() => void),\n arg2?: BufferEncoding | (() => void),\n arg3?: () => void\n ) {\n const maybeCb = arg3 || arg2 || arg1;\n const input = typeof arg1 !== 'function' ? arg1 : undefined;\n const encoding = typeof arg2 === 'string' ? arg2 : 'utf8';\n const cb = typeof maybeCb === 'function' ? maybeCb : undefined;\n if (typeof input === 'string') {\n this.write(input, encoding);\n } else if (input != null) {\n this.write(input);\n }\n if (cb) this.once('close', cb);\n return this._end();\n }\n\n destroy() {\n if (this.#destroyed || this.#closing) return;\n if (this.#writing || this.#opening) {\n this.#closing = true;\n } else if (this.#lines.length - this.#head > this.#partialLine) {\n // A scheduled write counts as pending: complete it before closing\n this.#closing = true;\n this.#writeLine();\n } else {\n this.#close();\n }\n }\n\n flush(cb?: (error?: Error | null) => void) {\n if (this.#destroyed) {\n cb?.();\n } else {\n const onDrain = () => {\n if (!this.#destroyed) {\n fsFsync(this.#fd, error => {\n this.#flushPending = false;\n if (error?.code === 'EBADF') {\n cb?.(); // If fd is closed, ignore the error\n } else {\n cb?.(error);\n }\n });\n } else {\n this.#flushPending = false;\n cb?.();\n }\n this.off('error', onError);\n };\n\n const onError = (err: Error) => {\n this.#flushPending = false;\n this.off('drain', onDrain);\n cb?.(err);\n };\n\n this.#flushPending = true;\n this.once('drain', onDrain);\n this.once('error', onError);\n\n if (!this.#writing) {\n if (\n this.#lines.length - this.#head > this.#partialLine ||\n this.#output\n ) {\n this.#writeLine();\n } else {\n process.nextTick(() => this.emit('drain'));\n }\n }\n }\n }\n\n _writeln(data: string): boolean {\n if (this.#destroyed) return false;\n this.#len += data.length;\n this.#lines.push(data);\n if (!this.#writing) this.#scheduleWrite();\n return this.#len < HIGH_WATER_MARK;\n }\n\n _write(data: string): boolean {\n if (this.#destroyed) {\n return false;\n }\n\n if (\n this.#partialLine === 0 &&\n data.charCodeAt(data.length - 1) === 10 /*'\\n'*/\n ) {\n return this._writeln(data);\n }\n\n this.#len += data.length;\n\n let startIdx = 0;\n let endIdx = -1;\n while ((endIdx = data.indexOf('\\n', startIdx)) > -1) {\n const line = data.slice(startIdx, endIdx + 1);\n if (this.#partialLine > 0) {\n this.#lines[this.#lines.length - 1] += line;\n } else {\n this.#lines.push(line);\n }\n this.#partialLine = 0;\n startIdx = ++endIdx;\n }\n\n if (startIdx < data.length) {\n const line = data.slice(startIdx);\n if (this.#partialLine > 0) {\n this.#lines[this.#lines.length - 1] += line;\n } else {\n this.#lines.push(data.slice(startIdx));\n }\n this.#partialLine = 1;\n }\n\n if (!this.#writing && this.#lines.length - this.#head > this.#partialLine) {\n this.#scheduleWrite();\n }\n\n return this.#len < HIGH_WATER_MARK;\n }\n\n write(\n buffer: Uint8Array | string,\n cb?: (err?: Error | null) => void\n ): boolean;\n write(\n str: string,\n encoding?: BufferEncoding,\n cb?: (err?: Error | null) => void\n ): boolean;\n\n write(\n input: Uint8Array | string,\n arg2?: BufferEncoding | ((err?: Error | null) => void),\n arg3?: (err?: Error | null) => void\n ): boolean {\n const maybeCb = arg3 || arg2;\n const encoding = typeof arg2 === 'string' ? arg2 : 'utf8';\n const data =\n typeof input === 'string' ? input : Buffer.from(input).toString(encoding);\n const cb = typeof maybeCb === 'function' ? maybeCb : undefined;\n try {\n return this._write(data);\n } finally {\n cb?.();\n }\n }\n\n [Symbol.dispose]() {\n this.destroy();\n }\n}\n\nconst isStdFd = (fd: number) => {\n switch (fd) {\n case 1:\n case 2:\n case process.stdout.fd:\n case process.stderr.fd:\n return true;\n default:\n return false;\n }\n};\n\nconst fsFsync = (\n fd: number,\n cb: (error?: NodeJS.ErrnoException | null) => void\n) => {\n try {\n fs.fsync(fd, cb);\n } catch (error: any) {\n cb(error);\n }\n};\n","import type net from 'node:net';\n\nimport { LogStream, type EventSink } from './logStream';\n\nconst MAX_SUBSCRIBER_BUFFERED = 4 * 1024 * 1024;\n\ninterface BroadcastSink {\n sink: EventSink;\n dropOnBackpressure: boolean;\n destroy(): void;\n}\n\n// Fallback for Windows named pipes, which expose no fd for LogStream to write to\nclass SocketSink implements EventSink {\n readonly #socket: net.Socket;\n\n constructor(socket: net.Socket) {\n this.#socket = socket;\n // A socket write error without an 'error' listener would crash the host\n socket.on('error', () => {});\n }\n\n get writable() {\n return this.#socket.writable;\n }\n\n get buffered() {\n return this.#socket.writableLength;\n }\n\n _writeln(data: string): boolean {\n return this.#socket.write(data);\n }\n\n end(cb?: () => void): this {\n this.#socket.end(cb);\n return this;\n }\n\n destroy() {\n this.#socket.destroy();\n }\n}\n\nconst createSocketSink = (socket: net.Socket): EventSink => {\n const fd = (socket as any)._handle?.fd;\n if (typeof fd === 'number' && fd >= 0) {\n return new LogStream(\n onOpened =>\n onOpened(null, fd, (data, cb) => {\n socket.write(data, cb);\n }),\n { closeFd: false }\n );\n }\n return new SocketSink(socket);\n};\n\n// Fans every line out to all sinks uniformly; only flush stays pinned to the\n// primary sink so a stalled live socket cannot delay a durability barrier\nexport class BroadcastChannel implements EventSink {\n readonly #primary: EventSink;\n readonly #sinks: BroadcastSink[] = [];\n #destroyed = false;\n\n constructor(primary: EventSink) {\n this.#primary = primary;\n this.#sinks.push({\n sink: primary,\n dropOnBackpressure: false,\n destroy: () => primary.destroy(),\n });\n }\n\n get writable() {\n if (this.#destroyed) return false;\n for (let i = 0; i < this.#sinks.length; i++) {\n if (this.#sinks[i].sink.writable) return true;\n }\n return false;\n }\n\n add(sink: EventSink | null) {\n if (!sink) return;\n if (this.#destroyed) sink.destroy();\n else\n this.#sinks.push({\n sink,\n dropOnBackpressure: false,\n destroy: () => sink.destroy(),\n });\n }\n\n attach(socket: net.Socket) {\n if (this.#destroyed) {\n socket.destroy();\n return;\n }\n socket.unref();\n const sink = createSocketSink(socket);\n const entry = {\n sink,\n dropOnBackpressure: true,\n destroy: () => {\n sink.destroy();\n socket.destroy();\n },\n };\n this.#sinks.push(entry);\n const detach = () => {\n const index = this.#sinks.indexOf(entry);\n if (index > -1) this.#sinks.splice(index, 1);\n entry.destroy();\n };\n socket.on('close', detach);\n socket.on('error', detach);\n }\n\n ingest(socket: net.Socket) {\n // Forward complete lines as one block; hold back only the partial tail\n let pending = '';\n socket.unref();\n socket.setEncoding('utf8');\n socket.on('data', (chunk: string) => {\n const data = pending ? pending + chunk : chunk;\n const end = data.lastIndexOf('\\n');\n if (end === data.length - 1) {\n pending = '';\n this._writeln(data);\n } else if (end === -1) {\n pending = data;\n } else {\n pending = data.slice(end + 1);\n this._writeln(data.slice(0, end + 1));\n }\n });\n socket.on('error', () => {});\n }\n\n _writeln(line: string): boolean {\n const sinks = this.#sinks;\n let writable = false;\n for (let i = sinks.length - 1; i >= 0; i--) {\n const entry = sinks[i];\n const accepted = entry.sink._writeln(line);\n if (\n !accepted &&\n entry.dropOnBackpressure &&\n (entry.sink.buffered ?? Infinity) > MAX_SUBSCRIBER_BUFFERED\n ) {\n sinks.splice(i, 1);\n entry.destroy();\n }\n writable = accepted || writable;\n }\n return writable;\n }\n\n flush(cb: (error?: Error | null) => void) {\n if (this.#primary.flush) this.#primary.flush(cb);\n else cb();\n }\n\n end(cb?: () => void): this {\n for (const entry of this.#sinks) {\n entry.sink.end(entry.sink === this.#primary ? cb : undefined);\n }\n return this;\n }\n\n destroy() {\n this.#destroyed = true;\n for (const entry of this.#sinks) entry.destroy();\n this.#sinks.length = 0;\n }\n}\n","import net from 'node:net';\n\nimport { INTERNAL_IPC_ENV } from '../constants';\nimport type { LogStreamOpener } from './logStream';\n\nconst CONNECT_RETRY_MS = 50;\nconst MAX_CONNECT_RETRY_MS = 750;\n\nexport function getParentIpcPath() {\n return process.env[INTERNAL_IPC_ENV];\n}\n\nexport function publishIpcPath(socketPath: string) {\n process.env[INTERNAL_IPC_ENV] = socketPath;\n return () => {\n if (process.env[INTERNAL_IPC_ENV] === socketPath)\n delete process.env[INTERNAL_IPC_ENV];\n };\n}\n\nexport interface OpenIpcOptions {\n retryMs?: number;\n maxRetryMs?: number;\n}\n\nexport function openIpc(\n socketPath: string,\n options: OpenIpcOptions = {}\n): LogStreamOpener {\n const retryMs = options.retryMs ?? CONNECT_RETRY_MS;\n const maxRetryMs = options.maxRetryMs ?? MAX_CONNECT_RETRY_MS;\n\n return (onOpened, stream) => {\n const startedAt = Date.now();\n const retry = (error: Error, attempt: () => void) => {\n if (Date.now() - startedAt > maxRetryMs) onOpened(error);\n else setTimeout(attempt, retryMs);\n };\n\n const attempt = () => {\n const socket = net.connect(socketPath);\n let opened = false;\n socket.once('connect', () => {\n const fd = (socket as any)._handle?.fd;\n opened = true;\n socket.unref();\n // The socket owns the borrowed fd; its close must stop the stream\n socket.once('close', () => stream.destroy());\n // A pending drain must keep the process alive until it flushes\n const drain = (data: string, cb: (error?: Error | null) => void) => {\n socket.ref();\n socket.write(data, error => {\n socket.unref();\n cb(error);\n });\n };\n if (typeof fd === 'number' && fd >= 0) {\n onOpened(null, fd, drain);\n } else {\n onOpened(null, null, drain);\n }\n });\n socket.once('error', error => {\n if (opened) return;\n socket.destroy();\n retry(error, attempt);\n });\n };\n attempt();\n };\n}\n","import { isMainThread, threadId } from 'node:worker_threads';\n\nimport { INTERNAL_PROCESS_ORIGIN_ENV } from '../constants';\n\nconst LOCAL_PROCESS_ORIGIN = Symbol.for('2g/process-origin');\n\ninterface EventLogGlobal {\n [LOCAL_PROCESS_ORIGIN]?: string;\n}\n\nexport interface ProcessOrigin {\n kind: 'worker_thread' | 'event_log_child' | 'child_process';\n id: string;\n}\n\nexport function setLocalProcessOrigin(id: string | undefined) {\n const globalScope = globalThis as EventLogGlobal;\n if (id) globalScope[LOCAL_PROCESS_ORIGIN] = id;\n else delete globalScope[LOCAL_PROCESS_ORIGIN];\n}\n\nexport function getProcessOrigin(): ProcessOrigin | null {\n if (!isMainThread) {\n return { kind: 'worker_thread', id: String(threadId) };\n }\n\n const localOrigin = (globalThis as EventLogGlobal)[LOCAL_PROCESS_ORIGIN];\n const inheritedOrigin = process.env[INTERNAL_PROCESS_ORIGIN_ENV];\n if (inheritedOrigin && inheritedOrigin !== localOrigin) {\n return {\n kind: 'event_log_child',\n id: String(process.pid),\n };\n }\n\n if (process.env.NODE_UNIQUE_ID) {\n return { kind: 'child_process', id: process.env.NODE_UNIQUE_ID };\n }\n\n return null;\n}\n\nexport function getProcessWorkerId() {\n const origin = getProcessOrigin();\n return origin ? `${origin.kind}:${origin.id}` : undefined;\n}\n\nexport function publishProcessOrigin() {\n const origin = String(process.pid);\n process.env[INTERNAL_PROCESS_ORIGIN_ENV] = origin;\n setLocalProcessOrigin(origin);\n return () => {\n if (process.env[INTERNAL_PROCESS_ORIGIN_ENV] === origin)\n delete process.env[INTERNAL_PROCESS_ORIGIN_ENV];\n setLocalProcessOrigin(undefined);\n };\n}\n","const PROCESS_CLEANUP = Symbol.for('2g/process-cleanup');\n\ninterface EventLogGlobal {\n [PROCESS_CLEANUP]?: ProcessCleanupState;\n}\n\ninterface ProcessCleanupState {\n registered: boolean;\n callbacks: Set<() => void>;\n}\n\nexport function registerProcessCleanup(callback: () => void) {\n const cleanup = getProcessCleanupState();\n cleanup.callbacks.add(callback);\n if (cleanup.registered) return;\n cleanup.registered = true;\n\n process.once('exit', runProcessCleanup);\n for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'] as const) {\n process.once(signal, () => {\n if (process.listenerCount(signal) > 0) return;\n runProcessCleanup();\n process.kill(process.pid, signal);\n });\n }\n}\n\nfunction getProcessCleanupState() {\n const globalScope = globalThis as EventLogGlobal;\n return (globalScope[PROCESS_CLEANUP] ??= {\n registered: false,\n callbacks: new Set(),\n });\n}\n\nfunction runProcessCleanup() {\n for (const callback of getProcessCleanupState().callbacks) {\n try {\n callback();\n } catch {}\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport net from 'node:net';\n\nimport {\n DEFAULT_SEGMENTS,\n DEFAULT_SEGMENT_SIZE,\n EVENT_LOG_FORMAT_VERSION,\n SESSION_FILES,\n} from './constants';\nimport { cleanStaleSessionsSync, getSessionBaseDir } from './clean';\nimport { createDebugSink } from './debug';\nimport { BroadcastChannel } from './utils/broadcastChannel';\nimport { LogStream, type EventSink } from './utils/logStream';\nimport { publishIpcPath } from './utils/ipc';\nimport { publishProcessOrigin } from './utils/processOrigin';\nimport { registerProcessCleanup } from './utils/processExit';\nimport {\n createSocketAddress,\n listenSocket,\n removeSocket,\n} from './utils/sessionSockets';\n\nexport interface SessionOptions {\n command?: string;\n version?: string;\n maxSegments?: number;\n maxSegmentSize?: number;\n}\n\nexport interface SessionMeta {\n pid: number;\n formatVersion: number;\n startedAt: number;\n command: string;\n cwd: string;\n maxSegments: number;\n version?: string;\n // Relative to meta.json, or a Windows named-pipe name\n socket: string;\n ipcSocket: string;\n origin: {\n argv: string[];\n execPath: string;\n cwd: string;\n ppid?: number;\n env?: {\n npmLifecycleEvent?: string;\n npmExecPath?: string;\n npmPackageName?: string;\n };\n };\n}\n\nexport interface SessionContext {\n sessionDir: string;\n meta: SessionMeta;\n sink: EventSink;\n destroy(): void;\n}\n\nexport function createSession(options: SessionOptions): SessionContext {\n const baseDir = getSessionBaseDir();\n const startedAt = Date.now();\n // The name is collision-free across PID reuse and never parsed by readers\n const sessionId = `${process.pid}-${startedAt.toString(36)}-${Math.random()\n .toString(36)\n .slice(2, 8)\n .padEnd(6, '0')}`;\n const sessionDir = path.join(baseDir, sessionId);\n // An unwritable tmpdir must not crash the host\n try {\n fs.mkdirSync(sessionDir, { recursive: true, mode: 0o700 });\n // A base dir created before permissions were restricted stays 0755\n fs.chmodSync(baseDir, 0o700);\n } catch {}\n\n const maxSegments = options.maxSegments ?? DEFAULT_SEGMENTS;\n const maxSegmentSize = options.maxSegmentSize ?? DEFAULT_SEGMENT_SIZE;\n const liveSocket = createSocketAddress(sessionDir, sessionId, 'live');\n const ipcSocket = createSocketAddress(sessionDir, sessionId, 'ipc');\n\n const fileStream = new LogStream(path.join(sessionDir, '0.jsonl'));\n const sink = new BroadcastChannel(fileStream);\n sink.add(createDebugSink());\n trackSegmentRotation(fileStream, sessionDir, maxSegments, maxSegmentSize);\n\n const liveServer = net.createServer(socket => sink.attach(socket));\n const ipcServer = net.createServer(socket => sink.ingest(socket));\n const closeLiveServer = listenSocket(liveServer, liveSocket.path);\n const closeIpcServer = listenSocket(ipcServer, ipcSocket.path);\n const restoreIpcPath = publishIpcPath(ipcSocket.path);\n const restoreProcessOrigin = publishProcessOrigin();\n\n const meta: SessionMeta = {\n pid: process.pid,\n formatVersion: EVENT_LOG_FORMAT_VERSION,\n startedAt,\n command: options.command ?? process.argv.slice(1).join(' '),\n cwd: process.cwd(),\n maxSegments,\n version: options.version,\n socket: liveSocket.name,\n ipcSocket: ipcSocket.name,\n origin: createSessionOrigin(),\n };\n // Without meta.json the session is invisible to tooling; logging still works\n try {\n writeJsonAtomic(path.join(sessionDir, SESSION_FILES.meta), meta);\n } catch {}\n\n let destroyed = false;\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n sink.destroy();\n closeLiveServer();\n closeIpcServer();\n restoreIpcPath();\n restoreProcessOrigin();\n // rmSync can throw EPERM/EBUSY and must not skip the restoration above\n removeSocket(liveSocket.path);\n removeSocket(ipcSocket.path);\n };\n\n registerProcessCleanup(destroy);\n\n // Stale-session cleanup stays off the install hot path\n setImmediate(() => {\n try {\n cleanStaleSessionsSync();\n } catch {}\n });\n\n return { sessionDir, meta, sink, destroy };\n}\n\nfunction trackSegmentRotation(\n stream: LogStream,\n sessionDir: string,\n maxSegments: number,\n maxSegmentSize: number\n) {\n let bytesWritten = 0;\n stream.on('write', written => {\n bytesWritten += written;\n if (bytesWritten < maxSegmentSize) return;\n bytesWritten = 0;\n rotateSegments(sessionDir, maxSegments);\n stream.reopen();\n });\n}\n\nfunction rotateSegments(sessionDir: string, maxSegments: number) {\n fs.rmSync(path.join(sessionDir, `${maxSegments - 1}.jsonl`), { force: true });\n for (let i = maxSegments - 1; i >= 1; i--) {\n const from = path.join(sessionDir, `${i - 1}.jsonl`);\n const to = path.join(sessionDir, `${i}.jsonl`);\n try {\n fs.renameSync(from, to);\n } catch {}\n }\n}\n\nfunction writeJsonAtomic(file: string, data: unknown) {\n const tmp = `${file}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 0o600 });\n fs.renameSync(tmp, file);\n}\n\nfunction createSessionOrigin(): SessionMeta['origin'] {\n const env = {\n npmLifecycleEvent: process.env.npm_lifecycle_event,\n npmExecPath: process.env.npm_execpath,\n npmPackageName: process.env.npm_package_name,\n };\n return {\n argv: process.argv.slice(1),\n execPath: process.execPath,\n cwd: process.cwd(),\n ppid: process.ppid || undefined,\n env: Object.values(env).some(Boolean) ? env : undefined,\n };\n}\n","import path from 'node:path';\n\nimport { events } from './events';\nimport {\n EVENT_LOG_FORMAT_VERSION,\n LOG_DEBUG_ENV,\n LOG_EVENTS_ENV,\n} from './constants';\nimport { eventLogState, type EventLoggerInfo } from './state';\nimport { createSession, type SessionOptions } from './session';\nimport {\n LogStream,\n type EventSink,\n type LogStreamOpener,\n type LogStreamOptions,\n} from './utils/logStream';\nimport { getParentIpcPath, openIpc } from './utils/ipc';\nimport { getProcessOrigin, getProcessWorkerId } from './utils/processOrigin';\nimport { redirectConsoleForFd } from './utils/redirectConsole';\n\nexport type { EventLoggerInfo } from './state';\n\nexport interface InstallEventLoggerOptions extends SessionOptions {\n session?: boolean;\n debug?: boolean;\n}\n\nconst rootEvent = events('root');\n\nexport function installEventLogger(\n targetOrOptions?: string | number | InstallEventLoggerOptions\n): void {\n if (eventLogState.primarySink) return;\n\n const options =\n targetOrOptions && typeof targetOrOptions === 'object'\n ? targetOrOptions\n : undefined;\n\n const explicitTarget =\n parseLogTarget(process.env[LOG_EVENTS_ENV]) ??\n parseLogTarget(\n typeof targetOrOptions === 'string' || typeof targetOrOptions === 'number'\n ? targetOrOptions\n : undefined\n );\n\n if (explicitTarget != null) {\n if (typeof explicitTarget === 'number')\n redirectConsoleForFd(explicitTarget);\n eventLogState.debug = options?.debug ?? true;\n eventLogState.eventLoggerInfo = getExplicitTargetInfo(explicitTarget);\n activateSink(createPrimarySink(explicitTarget));\n return;\n }\n\n const ipcPath = getParentIpcPath();\n if (ipcPath) {\n eventLogState.debug = options?.debug ?? !!process.env[LOG_DEBUG_ENV];\n connectToParent(ipcPath);\n return;\n }\n\n if (options && options.session !== false) {\n eventLogState.debug = options.debug ?? !!process.env[LOG_DEBUG_ENV];\n const session = createSession(options);\n eventLogState.logPath = session.sessionDir;\n eventLogState.eventLoggerInfo = {\n destination: 'session',\n isUserVisibleOutput: false,\n sessionDir: session.sessionDir,\n };\n activateSink(session.sink, options.version);\n return;\n }\n}\n\nexport const getEventLoggerInfo = (): EventLoggerInfo | null =>\n eventLogState.primarySink?.writable ? eventLogState.eventLoggerInfo : null;\n\nexport function flushEventLogger(): Promise<void> {\n return new Promise(resolve => {\n const sink = eventLogState.primarySink;\n if (sink?.flush) sink.flush(() => resolve());\n else resolve();\n });\n}\n\nfunction parseLogTarget(target: string | number | undefined) {\n if (typeof target === 'number') {\n return Number.isSafeInteger(target) && target > 0 ? target : undefined;\n }\n\n if (!target) return undefined;\n\n const fd = parseInt(target, 10);\n if (`${fd}` === target && fd > 0 && Number.isSafeInteger(fd)) return fd;\n\n try {\n const parsedPath = path.parse(target);\n const destination = path.format(parsedPath);\n eventLogState.logPath = parsedPath.dir || process.cwd();\n return destination;\n } catch {\n return undefined;\n }\n}\n\nfunction createPrimarySink(\n dest: string | number | LogStreamOpener,\n options?: LogStreamOptions\n) {\n const stream = new LogStream(dest, options);\n // A dead target restores the no-op hot path\n stream.once('error', () => {\n eventLogState.primarySink = undefined;\n eventLogState.eventLoggerInfo = null;\n });\n return stream;\n}\n\nfunction getExplicitTargetInfo(target: string | number): EventLoggerInfo {\n if (typeof target === 'number') {\n return {\n destination: target === 1 ? 'stdout' : target === 2 ? 'stderr' : 'fd',\n isUserVisibleOutput: target === 1 || target === 2,\n fd: target,\n };\n }\n\n return {\n destination: 'file',\n isUserVisibleOutput: false,\n file: target,\n };\n}\n\nfunction getInitMetadata(version?: string) {\n return {\n format: 'v0-jsonl',\n formatVersion: EVENT_LOG_FORMAT_VERSION,\n version: version ?? 'UNVERSIONED',\n processOrigin: getProcessOrigin() ?? undefined,\n };\n}\n\nfunction activateSink(sink: EventSink, version?: string) {\n eventLogState.primarySink = sink;\n rootEvent('init', getInitMetadata(version));\n}\n\nfunction connectToParent(ipcPath: string) {\n const workerId = getProcessWorkerId();\n if (workerId) eventLogState.eventMeta = { _w: workerId };\n\n eventLogState.primarySink = createPrimarySink(openIpc(ipcPath), {\n closeFd: false,\n });\n eventLogState.eventLoggerInfo = {\n destination: 'ipc',\n isUserVisibleOutput: false,\n };\n rootEvent('init', getInitMetadata());\n}\n"],"names":["STATE_SYMBOL","Symbol","for","EVENT_LOG_STATE_VERSION","eventLogState","getEventLogState","globalScope","globalThis","logPath","process","cwd","eventLoggerInfo","debug","TIME_ORIGIN","performance","timeOrigin","TIMESTAMP_FRACTIONS","Array","from","length","_","us","padStart","cachedMs","cachedMsJson","cachedWorkerId","cachedWorkerIdJson","writeEvent","dest","category","kind","payload","meta","level","_writeln","serializeEvent","duration","timestamp","stringifyTimestamp","_w","rest","JSON","stringify","slice","line","stringifyWorkerId","appendPayload","undefined","writeCompleteEvent","startPayload","endPayload","delta","appendMergedPayload","now","ms","Math","floor","workerId","NOOP_DONE","serializeError","error","depth","Error","String","serialized","name","message","code","stack","cause","createEventLogger","log","event","data","primarySink","eventMeta","span","start","done","path","relativePath","target","toJSON","isAbsolute","relative","replace","events","EVENT_LEVEL_DEBUG","createDebugSink","value","env","LOG_DEBUG_ENV","filter","compileLogDebugFilter","patterns","split","map","pattern","trim","Boolean","compileEventFilter","colorize","shouldColorizeStream","stderr","writable","end","indexOf","parseEventLine","matchesTapOptions","write","formatPrettyEvent","stream","cb","this","destroy","LogStream","EventEmitter","fd","file","oldFd","closeFd","writing","ending","closing","flushPending","destroyed","opening","reopening","output","len","lines","head","partialLine","busyRetries","draining","scheduled","drain","onRelease","#onRelease","err","written","release","onDrained","fail","Buffer","byteLength","onScheduledWrite","#onScheduledWrite","writeLine","constructor","options","super","fs","fsyncSync","nextTick","emit","openFile","open","buffered","reopen","once","retryLine","setImmediate","min","setTimeout","toString","close","onOpened","mkdir","dirname","recursive","fchmod","isStdFd","fsFsync","onClose","listenerCount","scheduleWrite","_end","arg1","arg2","arg3","maybeCb","input","flush","onDrain","off","onError","push","_write","charCodeAt","startIdx","endIdx","encoding","dispose","stdout","fsync","SocketSink","socket","on","writableLength","BroadcastChannel","primary","sinks","sink","dropOnBackpressure","i","add","attach","unref","_handle","createSocketSink","entry","detach","index","splice","ingest","pending","setEncoding","chunk","lastIndexOf","accepted","Infinity","openIpc","socketPath","retryMs","maxRetryMs","startedAt","Date","attempt","net","connect","opened","ref","retry","LOCAL_PROCESS_ORIGIN","setLocalProcessOrigin","id","getProcessOrigin","isMainThread","threadId","localOrigin","inheritedOrigin","INTERNAL_PROCESS_ORIGIN_ENV","pid","NODE_UNIQUE_ID","PROCESS_CLEANUP","getProcessCleanupState","registered","callbacks","Set","runProcessCleanup","callback","createSession","baseDir","getSessionBaseDir","sessionId","random","padEnd","sessionDir","join","mkdirSync","mode","chmodSync","maxSegments","DEFAULT_SEGMENTS","maxSegmentSize","DEFAULT_SEGMENT_SIZE","liveSocket","createSocketAddress","ipcSocket","fileStream","trackSegmentRotation","bytesWritten","rotateSegments","rmSync","force","to","renameSync","liveServer","createServer","ipcServer","closeLiveServer","listenSocket","closeIpcServer","restoreIpcPath","publishIpcPath","INTERNAL_IPC_ENV","restoreProcessOrigin","publishProcessOrigin","origin","formatVersion","EVENT_LOG_FORMAT_VERSION","command","argv","version","createSessionOrigin","writeJsonAtomic","tmp","writeFileSync","SESSION_FILES","removeSocket","registerProcessCleanup","cleanup","signal","kill","cleanStaleSessionsSync","npmLifecycleEvent","npm_lifecycle_event","npmExecPath","npm_execpath","npmPackageName","npm_package_name","execPath","ppid","Object","values","some","rootEvent","installEventLogger","targetOrOptions","explicitTarget","parseLogTarget","LOG_EVENTS_ENV","redirectConsoleForFd","getExplicitTargetInfo","destination","isUserVisibleOutput","activateSink","createPrimarySink","ipcPath","getParentIpcPath","connectToParent","getProcessWorkerId","getInitMetadata","session","getEventLoggerInfo","flushEventLogger","Promise","resolve","Number","isSafeInteger","parseInt","parsedPath","parse","format","dir","processOrigin"],"mappings":"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"}
@@ -502,7 +502,7 @@ function stripSuffix(e) {
502
502
  async function runExportCli(e) {
503
503
  if (parseHelp(e)) {
504
504
  !function printExportHelp() {
505
- process.stdout.write([ "Usage: 2g export [selector]", "", "Exports session events to Chrome Trace or OTLP JSON.", "", "Options:", " selector Substring of PID, CWD, or command; a running", " session wins ties", " --input <file> Read JSONL events from a file", " -o, --output <file> Write output to a file", " --format <format> chrome-trace or opentelemetry", " --json Print JSON output", " --since <time> Duration ago (5m, 90s), Unix time, or ISO date", " --filter <pattern> Event name prefix (whole segments), e.g. category,", " category:kind; * wildcards; comma-separated", " --spans Only span events (log.span() pairs carrying a _d", ' duration); a plain "ms" payload field is not a span', " --debug Include debug-level events", " --tail Follow live events after replaying history", " --timeout <duration> Stop tailing after an absolute duration", " Tail also stops after 30s without new events", "" ].join("\n"));
505
+ process.stdout.write([ "Usage: 2g export [selector]", "", "Exports session events to Chrome Trace or OTLP JSON.", "", "Options:", " selector Substring of PID, CWD, or command; a running", " session wins ties", " --input <file> Read JSONL events from a file", " -o, --output <file> Write output to a file", " --format <format> chrome-trace or opentelemetry", " --json Print JSON output", " --since <time> Duration ago (5m, 90s), Unix time, or ISO date", " --filter <pattern> Event name prefix (whole segments), e.g. category,", " category:kind; * wildcards; comma-separated", " --spans Keep only span events (log.span() pairs with a _d", " duration); omit to include point events too. A", ' plain "ms" payload field is not a span', " --debug Include debug events (only recorded when the", " command ran with LOG_DEBUG set)", " --tail Follow live events after replaying history", " --timeout <duration> Stop tailing after an absolute duration", " Tail also stops after 30s without new events", "" ].join("\n"));
506
506
  }();
507
507
  return;
508
508
  }
@@ -649,7 +649,7 @@ function escapeTsv(e) {
649
649
  async function runTapCli(e) {
650
650
  if (parseHelp(e)) {
651
651
  !function printTapHelp() {
652
- process.stdout.write([ "Usage: 2g tap [selector]", "", "Replays retained session history as JSONL, oldest first.", "", "Options:", " selector Substring of PID, CWD, or command; a running", " session wins ties", " --since <time> Duration ago (5m, 90s), Unix time, or ISO date", " --filter <pattern> Event name prefix (whole segments), e.g. category,", " category:kind; * wildcards; comma-separated", " --spans Only span events (log.span() pairs carrying a _d", ' duration); a plain "ms" payload field is not a span', " --debug Include debug-level events", " --format pretty Print a readable line per event", " --tail Follow live events after replaying history; runs", " until killed (use export with a timeout for a", " bounded follow)", "" ].join("\n"));
652
+ process.stdout.write([ "Usage: 2g tap [selector]", "", "Replays retained session history as JSONL, oldest first.", "", "Options:", " selector Substring of PID, CWD, or command; a running", " session wins ties", " --since <time> Duration ago (5m, 90s), Unix time, or ISO date", " --filter <pattern> Event name prefix (whole segments), e.g. category,", " category:kind; * wildcards; comma-separated", " --spans Keep only span events (log.span() pairs with a _d", " duration); omit to include point events too. A", ' plain "ms" payload field is not a span', " --debug Include debug events (only recorded when the", " command ran with LOG_DEBUG set)", " --format pretty Print a readable line per event", " --tail Follow live events after replaying history; runs", " until killed (use export with a timeout for a", " bounded follow)", "" ].join("\n"));
653
653
  }();
654
654
  return;
655
655
  }
@@ -707,7 +707,7 @@ async function main(e = process.argv.slice(2)) {
707
707
  const [n, ...o] = e;
708
708
  if (!n || "--help" === n || "-h" === n) {
709
709
  !function printHelp() {
710
- process.stdout.write([ "Usage: 2g <command>", "", "Reads structured JSONL event logs that instrumented CLIs record during runs", "into the system temp dir, with no setup: run a command, then tap it here.", "", "Commands:", " ps [selector] List recorded sessions", " --active, -a (running only) --json", "", " tap [selector] Replay session events as JSONL, oldest first", " --since <time> --filter <pattern> --spans --debug --format pretty", " --tail (follow live events after replay; runs until killed)", "", " export [selector] Export events to Chrome Trace or OTLP JSON", " --input <jsonl-file> -o, --output <file> --json", " --format chrome-trace|opentelemetry", " --since <time> --filter <pattern> --spans --debug", " --tail --timeout <duration> (absolute; tail also stops after 30s idle)", "", " typegen List every event name/payload a project can emit", " -p, --project <tsconfig> -o, --output <file> --format dts|json --json", "", " clean Remove stale sessions", " --all, -a (remove all exited sessions) --json", "", "Typical use:", " 2g ps -a # what is running now?", ' 2g tap "expo start" --tail # follow live events', ' 2g tap "expo start" --since 5m --format pretty # recent history, readable', ' 2g tap "expo start" --filter metro:bundling # narrow to one area', ' 2g export "expo start" -o trace.json # flame chart of a run', "", "Selectors match sessions by substring of PID, CWD, or command. If several", "match, and exactly one of them is running, it is chosen; otherwise 2g errors", "and lists the candidates.", "", "--filter takes comma-separated event-name prefixes matched on whole", 'segments: "category" and "category:kind" both match "category:kind:test";', "* matches anything. Discover names by tapping unfiltered or via typegen.", "", "--since accepts a duration ago (5m, 90s, 1h30m), Unix time, or ISO date.", '--spans keeps only span events (log.span() pairs with a "_d" duration in ms).', "", 'Events are single JSON lines: {"_e":"category:kind","_t":<epoch ms>,...}.', '"_d" is a span duration, "_w" a worker id; debug events need --debug.', "", "Set LOG_EVENTS=<file|fd> on an instrumented command to redirect its events;", "LOG_DEBUG=<filter> also mirrors matching events to stderr.", "", "Run 2g <command> --help for per-command help.", "" ].join("\n"));
710
+ process.stdout.write([ "Usage: 2g <command>", "", "Reads structured JSONL event logs that instrumented CLIs record during runs", "into the system temp dir, with no setup: run a command, then tap it here.", "", "Commands:", " ps [selector] List recorded sessions", " --active, -a (running only) --json", "", " tap [selector] Replay session events as JSONL, oldest first", " --since <time> --filter <pattern> --spans --debug --format pretty", " --tail (follow live events after replay; runs until killed)", "", " export [selector] Export events to Chrome Trace or OTLP JSON", " --input <jsonl-file> -o, --output <file> --json", " --format chrome-trace|opentelemetry", " --since <time> --filter <pattern> --spans --debug", " --tail --timeout <duration> (absolute; tail also stops after 30s idle)", "", " typegen List every event name/payload a project can emit", " -p, --project <tsconfig> -o, --output <file> --format dts|json --json", "", " clean Remove stale sessions", " --all, -a (remove all exited sessions) --json", "", "Typical use:", " 2g ps -a # what is running now?", ' 2g tap "expo start" --tail # follow live events', ' 2g tap "expo start" --since 5m --format pretty # recent history, readable', ' 2g tap "expo start" --filter metro:bundling # narrow to one area', ' 2g export "expo start" -o trace.json # flame chart of a run', "", "Selectors match sessions by substring of PID, CWD, or command. If several", "match, and exactly one of them is running, it is chosen; otherwise 2g errors", "and lists the candidates.", "", "--filter takes comma-separated event-name prefixes matched on whole", 'segments: "category" and "category:kind" both match "category:kind:test";', "* matches anything. Discover names by tapping unfiltered or via typegen.", "", "--since accepts a duration ago (5m, 90s, 1h30m), Unix time, or ISO date.", '--spans keeps only span events (log.span() pairs with a "_d" duration in', "ms); without it, point events are included alongside spans.", "", 'Events are single JSON lines: {"_e":"category:kind","_t":<epoch ms>,...}.', '"_d" is a span duration, "_w" a worker id; debug events need --debug.', "", "Set LOG_EVENTS=<file|fd> on an instrumented command to redirect its events.", "Debug events are only recorded when the command runs with LOG_DEBUG set.", "", "Pass LOG_DEBUG=<filter> when debugging; it also mirrors matching events to", "stderr. Reading them back needs --debug.", "", "Run 2g <command> --help for per-command help.", "" ].join("\n"));
711
711
  }();
712
712
  return 0;
713
713
  }