Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Cross-package release notes for relayburn. Package changelogs contain package-le

- `relayburn-cli` (Rust): wire `burn summary` and `burn hotspots` as thin presenters over `relayburn-sdk`, matching the TS CLI's flag set and stdout byte-for-byte (default + `--json`). Un-ignores the four matching golden invocations. (#248 D1)
- `relayburn-cli` (Rust): port `burn overhead` and `burn overhead trim` as thin presenters over `relayburn_sdk::overhead` / `::overhead_trim`. Output (human + `--json`) is byte-equivalent with the TS CLI. (#248 D2)
- `relayburn-cli` (Rust): wire `burn compare` as a presenter over `relayburn_sdk::analyze::compare` building blocks (`build_compare_table` + the per-turn fidelity gate), matching the TS CLI flag set (positional comma-separated model list, `--include-partial` / `--fidelity` / `--since` / `--project` / `--session` / `--min-sample` / `--csv` / `--no-archive`) and producing byte-equivalent stdout for the cli-golden `compare` / `compare-json` invocations. (#248 D3)
- `relayburn-sdk-node` (Rust): napi-rs bindings skeleton — `#[napi]` shims for every public verb in `relayburn-sdk` (`summary`, `sessionCost`, `overhead`, `overheadTrim`, `hotspots`, `search`, `exportLedger`, `exportStamps`, async `ingest`, plus `ledgerOpen`), with u64 token counts surfaced as JS `BigInt`, ISO-8601 timestamps as `String`, async verbs returning `Promise<T>`, and a typed `BurnError` mapping for SDK failures. (#247)
- `relayburn-cli` (Rust): introduce the harness substrate — `HarnessAdapter` trait, lazy compile-time `phf` registry (`lookup` / `list_harness_names`), and the shared `pending_stamp::adapter` factory codex + opencode will reuse. Adapter slots in the registry are reserved but empty pending the Wave 2 PRs (#248-d/e/f). `relayburn-sdk` re-exports `start_watch_loop`, `WatchController`, `write_pending_stamp`, `PendingStampHarness`, and friends so the CLI doesn't have to reach into private SDK modules. (#248)
- `relayburn-cli` (Rust): scaffold the clap v4 derive root with global `--json` / `--ledger-path` / `--no-color` flags, eight stub subcommands (`summary`, `hotspots`, `overhead`, `compare`, `run`, `state`, `ingest`, `mcp-server`), and shared `render::{table,json,error}` helpers. Stubs exit `1` with a `not yet implemented` message (or a `{"error": …}` envelope under `--json`); Wave 2 fan-out PRs replace each stub with a thin presenter over `relayburn-sdk`. (#248 part a)
Expand Down
71 changes: 70 additions & 1 deletion crates/relayburn-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub enum Command {
Overhead(OverheadArgs),

/// Compare cost across two or more models on the same workload.
Compare,
Compare(CompareArgs),

/// Run an agent CLI under a harness wrapper that ingests its
/// session log on exit.
Expand All @@ -123,6 +123,75 @@ pub enum Command {
McpServer,
}

/// Per-command flag set for `burn compare`. Mirrors
/// `packages/cli/src/commands/compare.ts` so the CLI surfaces match
/// byte-for-byte; see that file for the canonical help text.
///
/// The first positional argument is a comma-separated model list
/// (`claude-sonnet-4-6,claude-haiku-4-5`). The presenter rejects fewer
/// than two distinct models with exit code 2 and a stderr message; this
/// is enforced at runtime rather than by clap so we get the same error
/// message shape as the TS CLI (`burn compare: needs at least 2
/// models...`).
#[derive(Debug, Clone, ClapArgs)]
pub struct CompareArgs {
/// Comma-separated model list (e.g. `claude-sonnet-4-6,claude-haiku-4-5`).
/// Required at runtime — see the struct doc comment for the
/// minimum-models contract.
#[arg(value_name = "MODELS")]
pub models: Option<String>,

/// Comma-separated list of effective providers to include
/// (e.g. `synthetic,anthropic,openai`).
#[arg(long, value_name = "LIST")]
pub provider: Option<String>,

/// Relative range (e.g. `24h`, `7d`, `4w`) or ISO timestamp.
/// Defaults to all time.
#[arg(long, value_name = "WHEN")]
pub since: Option<String>,

/// Filter by project path or git-canonical projectKey.
#[arg(long, value_name = "PATH")]
pub project: Option<String>,

/// Filter by sessionId.
#[arg(long, value_name = "ID")]
pub session: Option<String>,

/// Filter by stamped workflowId.
#[arg(long, value_name = "ID")]
pub workflow: Option<String>,

/// Filter by stamped agentId.
#[arg(long, value_name = "ID")]
pub agent: Option<String>,

/// Insufficient-sample threshold; cells below this get flagged in
/// the coverage-notes block. Default 5.
#[arg(long = "min-sample", value_name = "N")]
pub min_sample: Option<u64>,

/// Minimum fidelity class to include
/// (`full | usage-only | aggregate-only | cost-only | partial`).
/// Default `usage-only`.
#[arg(long, value_name = "CLASS")]
pub fidelity: Option<String>,

/// Shorthand for `--fidelity partial`.
#[arg(long = "include-partial")]
pub include_partial: bool,

/// Emit a stable CSV with one row per (model, category) pair.
#[arg(long)]
pub csv: bool,

/// Bypass the SQLite archive and stream the ledger directly.
/// Honored when env `RELAYBURN_ARCHIVE=0`.
#[arg(long = "no-archive")]
pub no_archive: bool,
}

/// `burn overhead [trim]` argument set. The top-level form takes the
/// shared `--project` / `--since` / `--kind` flags; the optional
/// `trim` subcommand layers on `--top` for recommendation count.
Expand Down
Loading
Loading