Files
orca/src/shared/codex-rollout-jsonl-cursor.ts
T
Neil c74ff91b85 Show task names for Codex subagents (#32243)
* fix: name Codex subagents from rollout metadata

* Hide generic default role in child agent rows

* Reject non-regular Codex identity transcripts without blocking
2026-10-23 02:16:32 -07:00

136 lines
3.6 KiB
TypeScript

import {
closeSync,
constants,
fstatSync,
openSync,
readSync,
readdirSync,
statSync,
type Stats
} from 'node:fs'
const TRANSCRIPT_READ_MAX_BYTES = 1024 * 1024
const TRANSCRIPT_LINE_MAX_BYTES = 256 * 1024
const TRANSCRIPT_DIRECTORY_MAX_ENTRIES = 4096
/** Resume point for an incremental read of one Codex rollout file. */
export type JsonlCursor = {
filePath?: string
offset: number
carry: string
}
export type JsonRecord = Record<string, unknown>
export function record(value: unknown): JsonRecord | undefined {
return typeof value === 'object' && value !== null ? (value as JsonRecord) : undefined
}
export function readJsonlFirstRecord(filePath: string): JsonRecord | undefined {
let fd: number | undefined
try {
// Nonblocking open prevents a FIFO from stalling hook handling before the descriptor check.
fd = openSync(
filePath,
constants.O_RDONLY | (process.platform === 'win32' ? 0 : constants.O_NONBLOCK)
)
if (!fstatSync(fd).isFile()) {
return undefined
}
const buffer = Buffer.allocUnsafe(64 * 1024)
const bytesRead = readSync(fd, buffer, 0, buffer.length, 0)
const newline = buffer.subarray(0, bytesRead).indexOf(0x0a)
if (newline === -1) {
return undefined
}
return record(JSON.parse(buffer.toString('utf8', 0, newline)))
} catch {
return undefined
} finally {
if (fd !== undefined) {
closeSync(fd)
}
}
}
/** Returns undefined when the file is unreadable, distinguishing a vanished rollout from one with no new lines.
* `lineFilter` skips JSON.parse for raw lines the caller can reject by substring. */
export function readJsonlCursor(
cursor: JsonlCursor,
lineFilter?: (line: string) => boolean
): JsonRecord[] | undefined {
if (!cursor.filePath) {
return undefined
}
let stats: Stats
try {
stats = statSync(cursor.filePath)
} catch {
return undefined
}
if (!stats.isFile()) {
return undefined
}
if (stats.size < cursor.offset) {
cursor.offset = 0
cursor.carry = ''
}
if (stats.size === cursor.offset) {
return []
}
const bytesToRead = Math.min(stats.size - cursor.offset, TRANSCRIPT_READ_MAX_BYTES)
const start = stats.size - cursor.offset > bytesToRead ? stats.size - bytesToRead : cursor.offset
const buffer = Buffer.allocUnsafe(bytesToRead)
let bytesRead = 0
let fd: number | undefined
try {
fd = openSync(cursor.filePath, 'r')
bytesRead = readSync(fd, buffer, 0, bytesToRead, start)
} catch {
return undefined
} finally {
if (fd !== undefined) {
closeSync(fd)
}
}
const skippedPrefix = start !== cursor.offset
const content = `${skippedPrefix ? '' : cursor.carry}${buffer.toString('utf8', 0, bytesRead)}`
const lines = content.split('\n')
cursor.offset = start + bytesRead
cursor.carry = lines.pop() ?? ''
if (skippedPrefix) {
lines.shift()
}
const records: JsonRecord[] = []
for (const line of lines) {
if (
(lineFilter && !lineFilter(line)) ||
Buffer.byteLength(line, 'utf8') > TRANSCRIPT_LINE_MAX_BYTES
) {
continue
}
try {
const parsed = record(JSON.parse(line) as unknown)
if (parsed) {
records.push(parsed)
}
} catch {
// A malformed rollout line must not block later lifecycle events.
}
}
return records
}
export function readTranscriptDirectory(directory: string): string[] {
let entries: string[]
try {
entries = readdirSync(directory)
} catch {
return []
}
if (entries.length > TRANSCRIPT_DIRECTORY_MAX_ENTRIES) {
entries = entries.slice(-TRANSCRIPT_DIRECTORY_MAX_ENTRIES)
}
return entries
}