packages/agent-transcript/README.md

Agent transcripts

The service and native-seat CLI share harness transcript parsing, bounded display records and redaction. Herdr discovery still supplies native session references for fleet observation; clankie seat-sync receives Claude's explicit hook path on the Claude host. No service request reads that path remotely.

SeatTranscriptUploadSchema permits at most 100 normalized messages/tools per request and optional native hook activity on the final page. UserPromptSubmit also carries turnStart: true; same-turn PostToolUse progress does not, so Stop settlement can distinguish a newer turn from late tool activity. It excludes host image paths and internal channel delivery records. The seat-sync host filters those internal entries before upload while preserving visible replies, tools and final hook activity; the upload schema remains strict. Claude channel deliveries carry isMeta: true and promptSource: "system" in the native journal. The native reader retains those channel envelopes as internal delivery receipts before filtering other metadata; ordinary transcript parsing still hides them.

The native reader retains the existing 9,000-entry display tail, follows the active Claude/Pi parent chain (including parallel Claude tool results), and tails flat Codex/Grok records incrementally. Native-seat hooks publish settled history, not live model drafts. Older records outside that tail are not a full transcript archive; publishing a viewed image uses Clankie's existing file-delivery path.

herdrSeatTranscriptEntries applies parseHerdrSeatTranscript's projection to records a caller has already decoded, without modifying them. Seat telemetry keeps the complete lines of each native file's last 2 MiB decoded. On an append that leaves the window's cut and decoded bytes unchanged, it decodes only the new lines before projecting the window again.

sessions.ts reads the same transcripts from any host that can list its Claude/Codex/Grok/Pi files and return a byte range of one (AgentTranscriptHost; @clankie/agent-hosts supplies local and SSH hosts). A tail widens from 256 KiB toward the host's 4 MiB read cap. A cursor carries the session, the byte offset and a hash of the bytes before it, so a page after it detects a replaced file and restarts from the tail. Pages re-read 256 KiB before the cursor so tool results and Claude's parent chain resolve, and report only entries that changed.

subagents.ts derives a seat's native subagents (Claude Code Agent/Task calls, Codex child rollouts and OpenCode task parts) for the fleet roster (ADR 0208). It tails the session incrementally from at most 2 MiB before the end and keeps only labels and states, never content. The service calls it only for local seats it already has an address for (ADR 0188).

Codex labels combine nickname and task path from session_meta. Only direct children in the parent's own Codex home are read. Parent FINAL_ANSWER envelopes, targeted wait/close results and list_agents statuses settle them on the next read; generic wait acknowledgements do not. Successful followup and newer child task_started records reset completion. Without a current parent status, five minutes of file idleness is a heuristic fallback, not proof that a process exited. At most 64 children, 4,096 recent headers (64 KiB each) and 32 addressed parent sessions are retained. Partial lines wait for the next read; file replacement or truncation restarts the bounded tail.

Recent subagent entries carry optional id, startedAt and endedAt fields (VUH-1607). Readers use native call IDs (Claude) or child thread UUIDs (Codex) and source timestamps. Running entries omit the ending; older entries without these fields still validate. A Codex idle ending is estimated at last file write plus five minutes. Missing source timestamps remain unknown rather than using the fleet read's wall clock.

OpenCode task projection consumes only the registered local profile's bounded v1 records supplied by the service's existing SQLite history reader (OpenCode 1.18.18 or newer that passes its schema probe). It uses native call IDs, agent type/description labels and task start/end times. A background tool result with a running task envelope stays running until its synthetic parent completion/error notification. Child references must match the parent's direct child in that profile; continuations retain distinct call IDs. The read bounds are 500 parent messages, 2,000 parts and 4 MiB, retaining 64 calls and eight recent entries. No global owner store or child transcript is scanned, and no file-idleness completion is inferred.

On explicit child selection, readNativeSubagentSession resolves a local Claude call ID or Codex child UUID through its already-addressed parent. Claude uses a matching native result's agentId and the derived nested child path; its header must name that parent and agent. Only this selected-child mode includes sidechains. Codex shares the roster's bounded direct-child header discovery. Both retain ordinary redaction, cursor isolation and the 4 MiB window cap, with source checks before each byte read. Missing locators, changed sources and escaped paths refuse. The service resolves OpenCode task call IDs within the same registered profile, rechecking the parent task and database relation after reading. None of these readers register, resume or send to the child.