hoangsonww / hoangsonww/Claude-Code-Agent-Monitor
[Feature]: Cost budgets with burn-down forecasting and pre-emptive guardrails
- Dominant language
- TypeScript
- Stars
- 1k
- Forks
- 234
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 18
Description
### What problem does this solve?
Cost is currently reported **after the fact**. `/api/pricing/cost`, the Analytics page and `ccam cost` all answer "what did I already spend", and the only forward-looking control is the alerting engine's `token_threshold` rule, which fires once a single session crosses a fixed token count.
That leaves three real gaps for anyone running Claude Code or Codex all day:
1. **No period budget.** There is no way to say "this project gets $40/week" or "$15/day across all providers". Spend is only visible per session, and the aggregate has to be eyeballed on the Analytics page.
2. **No forecast.** By the time a `token_threshold` alert fires, the money is already gone. What you actually want is "at the current burn rate you will cross the monthly budget on the 19th" — hours or days before it happens.
3. **No per-project attribution against a target.** `sessions.cwd` already gives us the project dimension, and Sessions has multi-project filters, but Analytics has no notion of a per-project spend target to measure against.
### Proposed solution
A budget layer that sits on top of the existing pricing engine (no new cost math — reuse `server/lib/scoped-stats.js` and the `/api/pricing/cost` computation).
**Data model** — one new table, additive and migration-safe:
```sql
CREATE TABLE IF NOT EXISTS cost_budgets (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
-- NULL scope_value = "all projects"; otherwise a cwd prefix, so nested
-- repos roll up into the parent budget the same way Sessions filters do.
scope_type TEXT NOT NULL CHECK(scope_type IN ('global','project','provider')),
scope_value TEXT,
period TEXT NOT NULL CHECK(period IN ('daily','weekly','monthly')),
limit_usd REAL NOT NULL,
warn_at_percent INTEGER NOT NULL DEFAULT 80,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
```
**API** — `GET/POST/PATCH/DELETE /api/budgets` for CRUD, plus `GET /api/budgets/status` returning, per budget: `spent_usd`, `limit_usd`, `percent_used`, `period_start`, `period_end`, `burn_rate_usd_per_hour`, and `projected_end_usd` / `projected_exhaustion_at` from a linear fit over the elapsed portion of the period.
**Alerting** — a fifth `rule_type`, `budget_threshold`, evaluated in the existing `sweepTimeRules()` pass in `server/lib/alerts.js`. It fires on *projection* crossing as well as actual crossing, so it reuses the whole downstream stack for free: `alert_events`, cooldowns, the `alert_triggered` broadcast, web-push, and every configured webhook target.
**UI** — a Budgets card in Settings for CRUD, and a compact burn-down strip on Analytics: spent vs. limit, elapsed vs. remaining period, and a dashed projection line against the budget ceiling.
**CLI** — `ccam budgets` (list + status) so a headless box can `ccam budgets --json | jq` in a cron job.
### Alternatives considered
- **Just use `token_threshold` rules.** It is per-session and counts tokens, not dollars, so it can't express "$40/week across this project" and never warns before the spend happens.
- **Compute budgets client-side on the Analytics page.** Would work visually, but then the alerting engine, webhooks and the CLI can't see budgets at all — the useful half of the feature is the notification, not the chart.
- **Hard-stop enforcement** (block spawning new runs when over budget). Deliberately out of scope for a first cut: the dashboard is an observer, and silently refusing to launch an agent is a much bigger behavioral change than warning about one.
### Area
Analytics / Tokens
### How important is this to you?
Would significantly improve my workflow
### Additional context
Overlaps intentionally with the alerting engine from #3 — this proposal *extends* it with a new rule type rather than building a parallel notification path. Distinct from #7 (scheduled reports), which summarizes the past on a timer; budgets are a live guardrail with a forward projection.
Contributor guide
Assessment
This issue has not been assessed yet.