1 Commits

Author SHA1 Message Date
Yeachan-Heo
3ba60be514 Expose session cost and budget state in the Rust CLI
The CLI already tracked token usage, but it did not translate that usage into model-aware cost reporting or offer a spend guardrail. This change adds a max-cost flag, integrates estimated USD totals into /status and /cost, emits near-budget warnings, and blocks new turns once the configured budget has been exhausted.

The workspace verification request also surfaced stale runtime test fixtures that still referenced removed permission enum variants, so those test-only call sites were updated to current permission modes to keep full clippy and workspace test coverage green.

Constraint: Reuse existing runtime usage/pricing helpers instead of adding a new billing layer
Constraint: Keep the feature centered in existing CLI/status surfaces with no new dependencies
Rejected: Move budget enforcement into runtime usage/session abstractions | broader refactor than needed for this CLI-scoped feature
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If resumed sessions later need historically accurate per-turn pricing across model switches, persist model metadata before changing the cost math
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace
Not-tested: Live network-backed prompt/REPL budget behavior against real Anthropic responses
2026-04-01 00:57:54 +00:00
4 changed files with 234 additions and 504 deletions

3
rust/Cargo.lock generated
View File

@@ -1091,11 +1091,8 @@ dependencies = [
"compat-harness", "compat-harness",
"crossterm", "crossterm",
"pulldown-cmark", "pulldown-cmark",
"reqwest",
"runtime", "runtime",
"serde",
"serde_json", "serde_json",
"sha2",
"syntect", "syntect",
"tokio", "tokio",
"tools", "tools",

View File

@@ -84,15 +84,6 @@ cargo run -p rusty-claude-cli -- logout
This removes only the stored OAuth credentials and preserves unrelated JSON fields in `credentials.json`. This removes only the stored OAuth credentials and preserves unrelated JSON fields in `credentials.json`.
### Self-update
```bash
cd rust
cargo run -p rusty-claude-cli -- self-update
```
The command checks the latest GitHub release for `instructkr/clawd-code`, compares it to the current binary version, downloads the matching binary asset plus checksum manifest, verifies SHA-256, replaces the current executable, and prints the release changelog. If no published release or matching asset exists, it exits safely with an explanatory message.
## Usage examples ## Usage examples
### 1) Prompt mode ### 1) Prompt mode
@@ -171,7 +162,6 @@ cargo run -p rusty-claude-cli -- --resume session.json /memory /config
- `dump-manifests` — print extracted upstream manifest counts - `dump-manifests` — print extracted upstream manifest counts
- `bootstrap-plan` — print the current bootstrap skeleton - `bootstrap-plan` — print the current bootstrap skeleton
- `system-prompt [--cwd PATH] [--date YYYY-MM-DD]` — render the synthesized system prompt - `system-prompt [--cwd PATH] [--date YYYY-MM-DD]` — render the synthesized system prompt
- `self-update` — update the installed binary from the latest GitHub release when a matching asset is available
- `--help` / `-h` — show CLI help - `--help` / `-h` — show CLI help
- `--version` / `-V` — print the CLI version and build info locally (no API call) - `--version` / `-V` — print the CLI version and build info locally (no API call)
- `--output-format text|json` — choose non-interactive prompt output rendering - `--output-format text|json` — choose non-interactive prompt output rendering

View File

@@ -11,11 +11,8 @@ commands = { path = "../commands" }
compat-harness = { path = "../compat-harness" } compat-harness = { path = "../compat-harness" }
crossterm = "0.28" crossterm = "0.28"
pulldown-cmark = "0.13" pulldown-cmark = "0.13"
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
runtime = { path = "../runtime" } runtime = { path = "../runtime" }
serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
sha2 = "0.10"
syntect = "5" syntect = "5"
tokio = { version = "1", features = ["rt-multi-thread", "time"] } tokio = { version = "1", features = ["rt-multi-thread", "time"] }
tools = { path = "../tools" } tools = { path = "../tools" }

File diff suppressed because it is too large Load Diff