relayburn-cli 2.7.5

The `burn` CLI — published to crates.io. Crate name is relayburn-cli because `burn` is taken on crates.io; the binary keeps the `burn` invocation.
Documentation
[package]
name = "relayburn-cli"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "The `burn` CLI — published to crates.io. Crate name is relayburn-cli because `burn` is taken on crates.io; the binary keeps the `burn` invocation."

[[bin]]
name = "burn"
path = "src/main.rs"

# A library target is added alongside the `burn` binary so internal
# modules can be unit-tested with `cargo test -p relayburn-cli` and so
# future integration tests under `tests/` can reach them without
# re-declaring the module tree. The binary path
# (`src/main.rs`) and the library path (`src/lib.rs`) live side-by-side
# — cargo treats them as two separate compile units that share the
# same package metadata.
[lib]
name = "relayburn_cli"
path = "src/lib.rs"

[dependencies]
# The CLI is the canonical external embedder of the SDK — every read
# verb the binary surfaces will wrap a `relayburn-sdk` call once #248
# fills in the CLI source.
#
# Version requirement is the current MAJOR.MINOR (caret semantics:
# `>=1.10.0, <2.0.0`). The publish workflow rewrites this to match
# the workspace MAJOR.MINOR on every release so the local workspace
# path (currently 1.10.0) and the published `relayburn-sdk` on
# crates.io always satisfy the dep at publish time.
relayburn-sdk = { path = "../relayburn-sdk", version = "2.7" }

# clap v4 derive — argument parsing root and subcommand dispatch. The
# scaffold defines globals + subcommand stubs only; per-command flag
# wiring lands in the Wave 2 fan-out PRs.
clap = { workspace = true }

# `comfy-table` is used by the shared table renderer in `render::table`.
# Picked over `tabled` because it ships with sane Unicode/ASCII presets
# and a simple builder API that maps cleanly onto a `Vec<Vec<String>>`
# of rows. Wave 2 commands render tabular output through this helper.
comfy-table = "7"

# TTY-only spinners for long-running CLI work. The draw target is stderr so
# stdout stays script-friendly.
indicatif = "0.17"
console = "0.15"
dialoguer = "0.11"

# Structured diagnostics for people debugging burn itself. Normal CLI output
# stays quiet; set RELAYBURN_LOG or RUST_LOG to enable compact stderr logs.
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }

# Used by `render::json` to emit the structured-output mode the TS CLI's
# `--json` global produces. `serde` derive lives here too because the
# rendering helpers are generic over `Serialize` types from the SDK.
#
# `preserve_order` keeps insertion order on `serde_json::Map` so the
# pretty-printed JSON in `commands/overhead.rs` (and any future verb that
# round-trips through `to_value` / `to_writer_pretty`) matches the TS
# CLI's `JSON.stringify` output byte-for-byte. The SDK already enables
# this feature; cargo's feature unification means the CLI inherits it
# transitively today, but pinning it here is defense-in-depth so a
# future SDK refactor can't silently regress the golden snapshots.
serde = { workspace = true }
serde_json = { workspace = true, features = ["preserve_order"] }

# `anyhow` for the binary entrypoint; typed errors flow through
# `relayburn_sdk::LedgerError` and friends. `render::error::report_error`
# does the SDK-error → stderr/exit-code mapping.
anyhow = { workspace = true }
thiserror = { workspace = true }

# Harness substrate unit tests still use `async-trait` and `phf`. `tokio::sync`
# is needed by MCP / ingest presenters, and `rt` is required by read-path
# commands so they can drive `relayburn_sdk::ingest_all` from otherwise-sync
# presenter bodies via a current-thread runtime.
async-trait = "0.1"
phf = { version = "0.11", features = ["macros"] }
# `signal` is needed for the `burn ingest --watch` SIGINT/SIGTERM trap
# (#248 D8); the watch loop blocks the foreground until a stop signal
# comes in. `rt` drives the current-thread runtime that wraps the SDK's
# async ingest verb from otherwise-sync presenter bodies.
tokio = { workspace = true, features = ["sync", "rt", "signal"] }

# `IndexMap` preserves first-seen iteration order, which matters for the
# Wave 2 read-path commands so their grouped output (`summary --by-model`,
# the per-cell fidelity block) ties cost-sorts the same way the TS CLI's
# `Map`-backed implementation does. Mirrors the SDK's own dependency.
indexmap = { version = "2", features = ["serde"] }

[dev-dependencies]
# `assert_cmd` drives the binary in the smoke test under `tests/`.
# `predicates` provides the matchers `assert_cmd` wants.
assert_cmd = "2"
predicates = "3"

# `tempfile` gives smoke tests an isolated `RELAYBURN_HOME` so they don't
# touch the developer's real ledger when exercising `state` / `ingest`
# verbs end-to-end.
tempfile = "3"

# Async test harness for the `harnesses` module unit tests (lookup, factory
# round-trips). `rt-multi-thread` + `macros` lets `#[tokio::test]` resolve
# and gives spawned watch-loop ticks a runtime to land on.
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync"] }

# `tests/golden.rs` loads `invocations.json` to drive both the TS-CLI snapshot
# capture and the Rust diff runner. `serde` / `serde_json` are workspace deps
# already pulled in via `[dependencies]`, so this entry is documentation only.
#
# The in-tree fixture is JSONL-only (the SQLite binaries are gitignored); the
# diff runner just deletes any prior sqlite before invoking the binary, and
# the SDK's `Ledger::open` rebuilds `burn.sqlite` from `ledger.jsonl`
# automatically (see `relayburn_sdk::ledger::bootstrap`). No JSONL parsing in
# the test helper itself.