Skip to content

feat(budget): spend budgets with overview display and scriptable --check#562

Open
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:pr/budget
Open

feat(budget): spend budgets with overview display and scriptable --check#562
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:pr/budget

Conversation

@ozymandiashh

Copy link
Copy Markdown
Contributor

Implements #561.

What this adds

A spend-budget feature, so codeburn does not just show where AI spend goes but lets you act on it: set a daily/weekly/monthly budget, see budget usage with a run-rate projection in overview, and get a scriptable over-budget signal from budget --check. There is no spend-budget feature today (context-budget.ts is the model context window, unrelated).

codeburn budget --monthly 100      # also --weekly / --daily, in your display currency
codeburn budget --list
codeburn budget --remove monthly
codeburn budget --check            # exits non-zero if any configured budget is over

How it surfaces

  1. overview shows one line under the totals when the period matches a configured cadence (today -> daily, last-7-days -> weekly, this-month -> monthly):

    Monthly budget: €67.40 of €100.00 (67%)  projected €98.20 by month end
    

    green under 80%, amber from 80%, red at 100%+, with a linear run-rate projection for the in-progress period.

  2. budget --check prints each configured budget's status and exits 1 if any is over budget, so it composes into a shell prompt, pre-commit, or cron/CI step without codeburn shipping any cross-platform notification machinery:

    codeburn budget --check || notify-send "Over AI budget"

Design decisions

  • The alert is the --check exit code, not a notification daemon. That keeps the feature small and composable and leaves the choice of how to be notified to the user.
  • Budgets are in the display currency (the one currency sets and overview shows). Spend is summed in USD and converted once via convertCost before comparison, so the line reads in the same units the user typed.
  • The overview budget line is suppressed when a filter is active (--provider, --project, --exclude). A global budget shown next to a filtered subset would read as falsely-green, so it is hidden rather than misleading.
  • budget --check uses the same date-range source as overview per cadence (daily -> today, weekly -> week, monthly -> month), so the spend window and the numbers agree between the two surfaces.
  • Default behavior is unchanged. With no budget configured, overview output and every other command are byte-for-byte identical. The feature is purely additive.

Implementation

  • src/budget.ts (new): a pure computeBudgetStatus returning { spent, budget, pct, projected, state }, where projected = spent * totalDays / elapsedDays and state is under (<80%), warn (>=80%), or over (>=100%). No I/O, fully unit-tested.
  • src/config.ts: a new optional budget field ({ daily?, weekly?, monthly? }, display-currency amounts).
  • src/main.ts: the budget command (set with finite > 0 validation, --list, --remove, --check that aggregates current-period spend via the existing session pipeline) and the overview wiring that builds the budget status for the matching tier.
  • src/overview.ts: the budget line in renderOverview, colored by state, with the projection only while the period is in progress.

Verification

  • Unit tests (tests/budget.test.ts): threshold boundaries, exact projection math, invalid-input guards.
  • CLI tests (tests/cli-budget.test.ts, isolated HOME): set/list/remove; invalid amount exits 1; --check exits 1 over and 0 under-or-none; the budget line is suppressed under filters; --check and overview -p week report the same weekly spend window.
  • Render tests (tests/overview.test.ts): the line appears with the right percent and projection when a budget is set, and is absent otherwise.
  • npx vitest run tests/budget.test.ts tests/cli-budget.test.ts tests/overview.test.ts passes. npm test is green except the pre-existing locale-dependent tests/overview.test.ts separator assertion. npx tsc --noEmit is clean. The offline build succeeds.
  • End to end on a real history: codeburn budget --monthly 1 then overview -p month renders Monthly budget: <real spend> of €1.00 (...) projected ... by month end, and budget --check exits 1.

Files

  • src/budget.ts (new), src/config.ts, src/main.ts, src/overview.ts
  • tests/budget.test.ts (new), tests/cli-budget.test.ts (new), tests/overview.test.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant