Zerostack (gi-dellav/zerostack) — a minimal Rust coding agent. Wraps OpenRouter (default), OpenAI, Anthropic, Gemini, and Ollama.
- Source:
src/providers/zerostack.ts - Loading: eager (
src/providers/index.ts) - Test:
tests/providers/zerostack.test.ts
The platform data dir + zerostack/sessions/, mirroring Rust's dirs::data_dir (src/session/storage.rs in zerostack):
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/zerostack/sessions/ |
| Linux | $XDG_DATA_HOME/zerostack/sessions/ or ~/.local/share/zerostack/sessions/ |
ZS_DATA_DIR overrides the whole data dir (sessions live directly under it). A directory argument to createZerostackProvider(dir) overrides the sessions dir outright (used by tests).
JSON — one <uuid>.json file per session. Each file is a single Session object: a messages[] array (role, content, estimated_tokens) plus session-level metadata.
Cumulative, not per-call. Real billable tokens exist only as session totals — total_input_tokens, total_output_tokens — alongside model, provider, and working_dir. Individual messages carry only a rough estimated_tokens. So the parser emits one ParsedProviderCall per session from the totals; cost is recomputed with calculateCost (LiteLLM), not taken from the session's own total_cost.
None.
Per zerostack:<path>:<updated_at>:<id>.
- No cache breakdown. zerostack's
Usageonly carriesinput_tokensandoutput_tokens(src/agent/runner.rs); it folds any cached prompt tokens into the input count and discards the split before writing the session. So cache fields are always0and the cache % reads 0. Cost is re-priced at LiteLLM's standard input rate, which can slightly overestimate when caching was active — consistent with zerostack's own flatinput_token_cost. - No tool data. zerostack persists only final assistant text, not tool-call or bash records, so
toolsandbashCommandsare always empty. - OpenRouter model ids are prefixed (e.g.
deepseek/deepseek-v4-pro).modelDisplayNamestrips the route prefix before resolving;calculateCostresolves the prefixed id via LiteLLM's canonical-name handling. - Whole-session timestamp. All spend is attributed to
updated_at, since cumulative totals can't be split across days. - Unknown/local models (Ollama, custom) price at
$0, which is expected.
- Confirm whether the bug is in discovery (session files not picked up — check the data-dir resolution against
src/session/storage.rs) or parsing (totals mapped wrong). - The session struct is
Sessionin zerostack'ssrc/session/mod.rs. If a field is renamed upstream, updateZerostackSessionto match. - Add a fixture-format session to
tests/providers/zerostack.test.ts; do not mock the filesystem.