da-transcript

command module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 1 Imported by: 0

README

da-transcript

CI

Merge every docker-agent session belonging to a project into one chronological transcript, laid out for the terminal.

An agent driven from more than one place at once — a chat bridge, a scheduled run, someone at the TUI — gets a separate docker-agent session for each. da-transcript walks docker-agent's SQLite store and interleaves them into a single stream, each run of blocks opening under a banner naming the session it belongs to and the directory it ran in. A subagent's tag ends in ↓ and its banner rule is dashed rather than solid.

What it's for

To audit a run after it happened: where the agent went wrong, and what to change so it does not go wrong the same way again. For a background run — a scheduled job, an agent driven from a chat bridge, a subagent that did most of the editing — nobody watched it happen, so the transcript is the only record there is.

--tools full prints the arguments each call was made with, the output that came back, the error when it failed, and how long it took. That is where the tooling problems show up — a description bad enough that the arguments are always wrong, output truncated before the useful part, an error the agent can't act on and retries three times over, a skill invoked two steps too late. --reasoning adds what the model thought it was doing right before the wrong turn.

And because every session under the project lands in one ordered stream, a mistake that repeats across a week of runs is one da-transcript --all | grep … away — a pattern rather than an anecdote.

Install

Requires docker-agent v1.113 or later (a store at schema migration 025 or newer).

Grab an archive for your platform (Linux or macOS, amd64 or arm64) from the releases page, or install it with the Go toolchain:

go install github.com/Chi-teck/da-transcript@latest

Or build from a checkout:

CGO_ENABLED=0 go build -o da-transcript .   # or: task build

Usage

da-transcript                      # last 24h of sessions run under the cwd
da-transcript --all --tools full   # everything, with full tool output
da-transcript --list               # just the sessions, no messages
da-transcript --follow             # keep printing new turns as they complete

Scope is the working directory, the way git scopes itself: the sessions whose working directory sits inside --root are the ones you get. --everywhere ignores the root and takes the whole database. The path at the right of a banner is the directory that session ran in, written out whole rather than relative to the root: a transcript is usually redirected to a file and read somewhere else, where a relative path names nothing. docker-agent run --worktree (and --worktree-pr) records the worktree it creates as the session's directory, not the project it came from: <data-dir>/worktrees/<name>, ~/.cagent/worktrees/<name> by default. So --root <project> misses those sessions; --everywhere, or --root at the worktree (or at its parent, for all of them), finds them. A subagent written before docker-agent v1.138 has no directory of its own and is listed under its parent's.

The flag before a tag says where the rest of that session is:

Flag Meaning
⚑ the session starts here — this is its first block
⚐ its earlier blocks fall before the window, so there is more above; widen --since, or read it whole with --session ID --all
↻ the stream has shown it before and come back to it — the earlier part is further up this same output
◷ --follow only, never in the opening transcript: what follows is older than something already printed above it, as when a background subagent has just finished, a step was held while other sessions went on, or a session was forked or branched meanwhile. It takes the place of the other three flags.

Times are local — whatever $TZ resolves to, and the same zone --since/--until are read in. The zone is not printed, so use TZ=UTC da-transcript … if a transcript written with --out will be read elsewhere.

Times have one-second resolution, the store's. An assistant block's time is when the model finished the step (docker-agent stamps a step at its end), so it means answered at, not started at. A tool's duration runs from that time to its result, in whole seconds, so it includes any wait for approval.

Lines are laid out to the width in COLUMNS if it is set, else the terminal's, else 100 — for a pipe, or a file written with --out — and never narrower than 60 columns or wider than 1000.

Options

Run da-transcript --help for the full list. The ones you reach for:

Flag What it does
--root, --everywhere which sessions are in scope
--since, --until, --all the time window — 2h, 30m, 3d, today, yesterday, or an ISO timestamp
--tools {compact,full,none} tool call detail
--reasoning, --stats include reasoning blocks / per-step token and cost lines
--session narrow to sessions whose id contains a fragment
-f, --follow, --interval tail new messages (cursor-driven, poll every N seconds, 0.1 to 3600)
-o, --out write to a file instead of stdout (a new file is created 0600; colour off unless --color always; width from COLUMNS, else 100)
--db the store, default ~/.cagent/session.db
--version print the version and exit

For a run with --data-dir or -s/--session-db, point --db at <data-dir>/session.db or that file; docker-agent serve api keeps its own session.db in the directory it was started in, or its --working-dir.

Following

--follow prints a step only once it is complete. While the model is still writing it, or one of its calls has no result yet (a transfer_task running its subagent, a call waiting for approval), the step waits, and the rest of its own session waits behind it; other sessions keep printing. After 30 s, a held step gets one line on stderr: warning: waiting on transfer_task in 3fa9c2: unfinished since … — the rest of that session is held until it completes or the session goes on. docker-agent writes a subagent to the store only when it ends, so its whole run shows up at once: after the transfer_task step that called it, or, for a background agent, under ◷ if anything newer was printed while it ran.

Known limits

These are --follow's; a run without it is unaffected except where an item says so.

  • A step cut off and then abandoned (Esc, then nothing more in that session; rarely a reasoning-only step that ended empty) holds its session until the session goes on: --follow leaves it out and warns once, while a run without --follow shows it.
  • A message edited through serve api after --follow printed it is not printed again.
  • A step read while it streams has no time yet, so --follow dates it by the item before it, its prompt or the last tool result. If that is older than --since, the step is skipped even when it started inside the window, and its results are drawn on their own when they land, as tool blocks whose call reads ?; a --since that takes in that item keeps the step. A run without --follow shows it once it ends.
  • A call whose step is older than --since but which is still running when --follow starts gets its result drawn on its own when it lands, as a tool block whose call reads ?; a run without --follow with the same --since shows neither.
  • A fork or branch made during --follow prints its copied history (within the window) as a new session under ◷, and a run without --follow also shows that history twice, once per session.

Development

task check         # gofmt, go vet, golangci-lint, go test — the pre-commit gate
task test:update   # regenerate the golden files, then re-run the tests
task build         # CGO_ENABLED=0 go build -o da-transcript .

Expected output is fixed by the golden files in internal/app/testdata/. CI runs the same checks on every push to a *.x branch and on every pull request; pushing a v* tag publishes a release.

License

MIT — see LICENSE.

Documentation

Overview

Command da-transcript merges every docker-agent session belonging to a project into one chronological transcript.

An agent driven from more than one place at once — a chat bridge, a scheduled run, someone at the TUI — gets a separate docker-agent session for each, so reading back what it actually did means reading several sessions side by side. This walks docker-agent's SQLite store and interleaves them into one chronological stream, each run of blocks under a banner naming the session it belongs to, so the conversations stay apart where they overlap.

Point --root at any checkout: the sessions whose working directory sits inside it are the ones you get.

Message bodies are printed exactly as the agent received them, except that an attached file or binary data is named rather than quoted, escape sequences, control characters and invisible format characters are made harmless, and tabs are expanded to 8-column stops. Whatever a bridge prepends to a prompt is body text like any other and is never edited out.

The database is opened read-only; nothing here writes to it.

Output is laid out for the terminal: widths are measured in display cells rather than code points, the session table's columns are budgeted against the terminal width, long lines wrap back onto their own indent, truncated tool output is flagged, --follow is cursor-driven and writes where the transcript went, and the flag parser takes no abbreviations.

Directories

Path Synopsis
internal
app
Package app is da-transcript itself: the flags, the store, the rendering and the tail.
Package app is da-transcript itself: the flags, the store, the rendering and the tail.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL