M2.5.3: marchwarden costs CLI command #29

Merged
archeious merged 1 commit from feat/costs-command into main 2026-04-08 21:59:08 +00:00
Collaborator

Closes Issue #26

Summary

Operator-facing marchwarden costs subcommand that reads the JSONL ledger from M2.5.2 and pretty-prints a rich summary.

Output

  • Cost Summary panel — total calls, total spend, total tokens (input/output split), Tavily search count, warning for any calls with unknown model prices
  • Per-Day table sorted by date
  • Per-Model table sorted by model id
  • Highest-Cost Call panel with trace_id for follow-up

Flags

Flag Purpose
--since ISO date or relative shorthand (7d, 24h, 2w, 1m)
--until same
--model filter to a specific model_id
--json emit raw filtered ledger entries instead of the table
--ledger override default path (mostly for tests)

Drive-by fix

The Dockerfile predated the obs/ package added in M2.5.1 and didn't COPY it. Tests had been passing because they mount /app over the install, but the installed marchwarden entry point inside the image couldn't import obs. Added COPY obs ./obs to restore parity.

Tests

6 new tests covering summary rendering, model filter, since-date filter, JSON output, and the empty-ledger friendly path. 110/110 passing.

Verified end-to-end

$ marchwarden costs
╭──────── Cost Summary ────────╮
│ Calls: 1                     │
│ Total spend: $0.0494         │
│ Total tokens: 10,247 (in 9,107 / out 1,140) │
│ Tavily searches: 1           │
╰──────────────────────────────╯
                Per Day
 Date         Calls    Tokens   Spend (USD)
 2026-04-08       1    10,247       $0.0494
                Per Model
 Model                Calls    Tokens   Spend (USD)
 claude-sonnet-4-6        1    10,247       $0.0494
╭──── Highest-Cost Call ────╮
│ trace_id: 69bc298b-...   │
│ question: What is the    │
│   capital of Utah?       │
│ spend: $0.0494           │
╰──────────────────────────╯

Phase 2.5 complete after this merge

M2.5.1 (logger), M2.5.2 (ledger), M2.5.3 (CLI) — operational logging + cost visibility milestone done. Phase 3 (stress testing) is next.

Closes Issue #26 ## Summary Operator-facing `marchwarden costs` subcommand that reads the JSONL ledger from M2.5.2 and pretty-prints a rich summary. ## Output - **Cost Summary** panel — total calls, total spend, total tokens (input/output split), Tavily search count, warning for any calls with unknown model prices - **Per-Day** table sorted by date - **Per-Model** table sorted by model id - **Highest-Cost Call** panel with `trace_id` for follow-up ## Flags | Flag | Purpose | |---|---| | `--since` | ISO date or relative shorthand (`7d`, `24h`, `2w`, `1m`) | | `--until` | same | | `--model` | filter to a specific `model_id` | | `--json` | emit raw filtered ledger entries instead of the table | | `--ledger` | override default path (mostly for tests) | ## Drive-by fix The Dockerfile predated the `obs/` package added in M2.5.1 and didn't `COPY` it. Tests had been passing because they mount `/app` over the install, but the installed `marchwarden` entry point inside the image couldn't import `obs`. Added `COPY obs ./obs` to restore parity. ## Tests 6 new tests covering summary rendering, model filter, since-date filter, JSON output, and the empty-ledger friendly path. **110/110 passing.** ## Verified end-to-end ``` $ marchwarden costs ╭──────── Cost Summary ────────╮ │ Calls: 1 │ │ Total spend: $0.0494 │ │ Total tokens: 10,247 (in 9,107 / out 1,140) │ │ Tavily searches: 1 │ ╰──────────────────────────────╯ Per Day Date Calls Tokens Spend (USD) 2026-04-08 1 10,247 $0.0494 Per Model Model Calls Tokens Spend (USD) claude-sonnet-4-6 1 10,247 $0.0494 ╭──── Highest-Cost Call ────╮ │ trace_id: 69bc298b-... │ │ question: What is the │ │ capital of Utah? │ │ spend: $0.0494 │ ╰──────────────────────────╯ ``` ## Phase 2.5 complete after this merge M2.5.1 (logger), M2.5.2 (ledger), M2.5.3 (CLI) — operational logging + cost visibility milestone done. Phase 3 (stress testing) is next.
claude-code added 1 commit 2026-04-08 21:57:54 +00:00
Adds operator-facing `marchwarden costs` subcommand that reads the
JSONL ledger from M2.5.2 and pretty-prints a rich summary:

- Cost Summary panel: total calls, total spend, total tokens (input/
  output split), Tavily search count, warning for any calls with
  unknown model prices
- Per-Day table sorted by date
- Per-Model table sorted by model id
- Highest-Cost Call panel with trace_id and question

Flags:
  --since   ISO date or relative shorthand (7d, 24h, 2w, 1m)
  --until   same
  --model   filter to a specific model_id
  --json    emit raw filtered ledger entries instead of the table
  --ledger  override default path (mostly for tests)

Also fixes a Dockerfile gap: the obs/ package added in M2.5.1 was
not being COPYed into the image, so the installed `marchwarden`
entry point couldn't import it. Tests had been passing because
they mounted /app over the install. Adding `COPY obs ./obs`
restores parity.

Tests cover summary rendering, model filter, since-date filter,
JSON output, and the empty-ledger friendly path. 110/110 passing.
End-to-end verified against the real cost ledger.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
archeious approved these changes 2026-04-08 21:59:02 +00:00
archeious merged commit 4816b9386e into main 2026-04-08 21:59:08 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: archeious/marchwarden#29
No description provided.