← All @molecule/* packages · App templates

@molecule/api-agent-transcript

Core interface · agent-transcript · API (Node) · v1.0.0 · Apache-2.0

Reads a coding agent's session export (Claude Code, Codex, Molecule IDE) into one normalized session: turns, models and the files the agent wrote

npm install @molecule/api-agent-transcript

npm · Source on GitHub

How it works

@molecule/api-agent-transcript is the agent-transcript core interface on the API (Node) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 4 providers: @molecule/api-agent-transcript-autodetect, @molecule/api-agent-transcript-claude-code, @molecule/api-agent-transcript-codex, @molecule/api-agent-transcript-molecule-ide.

import { readFileSync } from 'node:fs'
import { readTranscript, setProvider } from '@molecule/api-agent-transcript'
import { provider } from '@molecule/api-agent-transcript-autodetect'

setProvider(provider)

const session = readTranscript({
  text: readFileSync('transcripts/my-post/claude-code-export.txt', 'utf8'),
  fileName: 'claude-code-export.txt',
})
for (const turn of session.turns) {
  console.log(
    turn.role,
    turn.model ?? session.model,
    turn.text.slice(0, 60),
    turn.files.map((f) => f.path),
  )
}

Providers (4): @molecule/api-agent-transcript-autodetect, @molecule/api-agent-transcript-claude-code, @molecule/api-agent-transcript-codex, @molecule/api-agent-transcript-molecule-ide

Works with: @molecule/api-bond, @molecule/api-i18n

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

One normalized shape for a coding agent's session, whatever harness recorded it.

Defines AgentSession — the turns of a conversation (the user's messages as typed, the assistant's prose replies, and the files each assistant turn wrote) — and the AgentTranscriptReader contract that format bonds implement. Use it to publish, search, audit or attribute what an agent wrote: @molecule/api-text-provenance takes these sessions to mark which paragraphs of a document came from the AI.

Readers, one per real export format: @molecule/api-agent-transcript-claude-code (the /export text and the session .jsonl), -codex (the Markdown export and the rollout .jsonl), -molecule-ide (a Molecule IDE conversation's JSON). @molecule/api-agent-transcript-autodetect bundles all three and picks the one that recognizes each file — bond that unless you only ever read one format.

Quick Start

import { readFileSync } from 'node:fs'
import { readTranscript, setProvider } from '@molecule/api-agent-transcript'
import { provider } from '@molecule/api-agent-transcript-autodetect'

setProvider(provider)

const session = readTranscript({
  text: readFileSync('transcripts/my-post/claude-code-export.txt', 'utf8'),
  fileName: 'claude-code-export.txt',
})
for (const turn of session.turns) {
  console.log(
    turn.role,
    turn.model ?? session.model,
    turn.text.slice(0, 60),
    turn.files.map((f) => f.path),
  )
}

Type

core

Installation

npm install @molecule/api-agent-transcript @molecule/api-bond @molecule/api-i18n

API

Interfaces

AgentFileWrite

A file the assistant wrote or edited during a turn.

interface AgentFileWrite {
  /** The path as the session recorded it (absolute or relative to the session's working directory). */
  path: string
  /** `create` = the whole file was written; `edit` = part of an existing file was replaced. */
  kind: 'create' | 'edit'
  /**
   * The text the assistant put into the file: the whole file for `create`, the
   * inserted/replacement text for `edit`. Empty when the export omits it.
   */
  text: string
  /** False when the export shows only part of the text (collapsed, truncated or elided). */
  complete: boolean
}

AgentSession

A whole session, normalized.

interface AgentSession {
  /** The reader that produced it, e.g. `claude-code`, `codex`, `molecule-ide`. */
  format: string
  /** The harness's own name for itself, e.g. `Claude Code`. */
  harness: string
  /** The harness version, when the export records it. */
  harnessVersion?: string
  /** The session's model when a single one is named for the whole session. Per-turn models are on each turn. */
  model?: string
  /** ISO 8601 start time, when recorded. */
  startedAt?: string
  /** The turns, in order. */
  turns: AgentTurn[]
}

AgentTranscriptReader

The contract every transcript reader bond implements.

A reader recognizes its own format with detect() and never guesses: it returns false for anything it does not positively recognize, so a composing reader (@molecule/api-agent-transcript-autodetect) can try each in turn.

interface AgentTranscriptReader {
  /** A stable id for the format family, e.g. `claude-code`. */
  readonly format: string
  /** A human label, e.g. `Claude Code`. */
  readonly label: string
  /**
   * Whether this reader recognizes the input.
   *
   * @param input - The transcript.
   * @returns True only when the input is positively this reader's format.
   */
  detect(input: TranscriptInput): boolean
  /**
   * Read the transcript into a normalized session.
   *
   * @param input - The transcript.
   * @returns The session.
   * @throws {Error} When the input is not this reader's format.
   */
  read(input: TranscriptInput): AgentSession
}

AgentTurn

One turn of the conversation. Consecutive assistant messages before the next user message form one turn.

interface AgentTurn {
  /** Who spoke. */
  role: AgentTurnRole
  /**
   * What was said. For `user`: the message as typed (the harness's injected
   * context is never included). For `assistant`: its prose replies, joined by a
   * blank line — tool calls are not prose; the files they wrote are in `files`.
   */
  text: string
  /** ISO 8601 time of the turn's first message, when the export records it. */
  timestamp?: string
  /** The model that produced an assistant turn, when the export records it. */
  model?: string
  /** Files an assistant turn wrote. Always empty for user turns. */
  files: AgentFileWrite[]
}

TranscriptInput

A transcript to read: its text, and its file name when known (some readers use the extension as a hint).

interface TranscriptInput {
  /** The file's full text. */
  text: string
  /** The file name or path, e.g. `session.jsonl`, `codex-session.md`. */
  fileName?: string
}

Types

AgentTurnRole

Who said a turn. Tool calls and their results are folded into the assistant turn that made them.

type AgentTurnRole = 'user' | 'assistant'

Functions

canReadTranscript(input)

Whether the bonded reader recognizes a transcript.

function canReadTranscript(input: TranscriptInput): boolean
  • input — The transcript text and, when known, its file name.

Returns: True when the bonded reader can read it.

getProvider()

Retrieves the bonded transcript reader, throwing if none is configured.

function getProvider(): AgentTranscriptReader

Returns: The bonded reader.

hasProvider()

Checks whether a transcript reader is bonded.

function hasProvider(): boolean

Returns: true if a reader is bonded.

readTranscript(input)

Read a transcript into a normalized session with the bonded reader.

function readTranscript(input: TranscriptInput): AgentSession
  • input — The transcript text and, when known, its file name.

Returns: The normalized session.

setProvider(provider)

Registers a transcript reader as the active one. Called during application startup.

function setProvider(provider: AgentTranscriptReader): void
  • provider — The reader to bond.

Available Providers

ProviderPackage
Agent transcript autodetect@molecule/api-agent-transcript-autodetect
Claude Code transcript reader@molecule/api-agent-transcript-claude-code
Codex CLI transcript reader@molecule/api-agent-transcript-codex
Molecule IDE transcript reader@molecule/api-agent-transcript-molecule-ide

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-i18n ^1.0.1

Runtime Dependencies

  • @molecule/api-bond

  • @molecule/api-i18n

  • A user turn is only what the person typed. Harness-injected context (environment blocks, slash-command echoes, platform auto-continue messages, tool results) is dropped by every reader, so a user turn is safe to show as "the prompt".

  • Assistant text is prose only. Tool calls are not text; the files they wrote are in turn.files (create = whole file, edit = the replacement text). Content an agent put in a file counts as the agent's writing.

  • Exports lose detail, and complete: false says so. Claude Code's /export renders markdown (headings lose their #, bold loses its **) and collapses some edits; prefer its session .jsonl when you have it. A Molecule IDE conversation may elide long file contents.

  • Readers never guess: detect() is false for anything not positively recognized, and read() throws on it. Keep the transcript's original file name when you have it — it is a detection hint.

  • Parsing is pure and synchronous; nothing is fetched or written.