Skip to main content
haia-trace reads a run of recorded events and assembles Operation Receipts — one verdict per payment operation — rendering them in the terminal or as JSON. Local-first: it reads and writes a project-local .trace/ directory. No daemon, no database, no network.

Install

Both expose the haia-trace command. Requires Node ≥ 22.

Commands

sample

Assemble receipts from bundled fixtures — no setup required.

build

Assemble one receipt per operation from a run’s events.

receipt

List the receipts build has written; show one verdict in full.

template

List the templates you can build against; scaffold your own.

The .trace/ directory

A run file is newline-delimited JSON, one event per line, append-only. It is the source of truth. A receipt is derived and reproducible: re-building the same run yields a byte-identical receipt, so build is “rebuild”. A receipt’s file name carries both the run and the operation, because an operation id is only guaranteed unique within its run — an adapter is free to number operations per session. receipt reads the store back, so nothing outside the CLI needs to know how the name is built.

Moving the root

--dir <path> relocates the whole root — haia-trace build --dir .my-trace — for a second project in one checkout, or a scratch run that should not touch the committed tree. What is inside the root never changes: events/, receipts/, templates/. --templates-dir <path> moves templates alone and outranks --dir. Every command that resolves a template takes both; receipt reads the store only, so it takes --dir alone. The recorder is the one thing --dir cannot reach: it names its own directory (createRunEventWriter(".trace/events")), so point it at events/ under whatever root you build with.

git

events/ and receipts/ are recorded and derived; templates/ is source you author. Ignore the two subdirectories, not the root:
A relocated root needs its own entries — the lines above cover .trace/ only. Derived output under .my-trace/ would be untracked but not ignored, so the next git add -A would commit it.

Output formats

Every command renders to the terminal by default. build, receipt list and receipt show also take --json and write a document to stdout instead; template list and template new do not. Diagnostics never go to stdout. A warning about receipt files that could not be read is written to stderr, so haia-trace receipt list --json | jq . stays valid and > out.json still shows the damage on your terminal. Colour and glyphs come from the terminal’s own capabilities and degrade to ASCII where Unicode is unsupported. A spinner appears only on an interactive terminal and only while build is actually folding events.

Exit codes

A verdict is an answer, not a failure. build exits 0 on a PARTIAL receipt — read --json and branch on completeness to gate on one. receipt list on an empty store is an answer too and exits 0, while receipt show with nothing to show is a failure and exits 1.

Templates that ship

Four: x402-buyer, x402-seller and x402-facilitator for the three sides of an x402 payment, and escrow-arc for an escrow on Arc. template lists what each one expects, and scaffolds your own for anything else.