# memory — claude-usage-widget Durable memory for this project. Read at session start, update before session end. Date format: `YYYY-MM-DD`. ## Decisions & rationale - **Tauri 2 (Rust + Svelte 5 + Vite + TS)** over Electron — smaller binary (~10 MB vs ~150 MB), native Windows transparency, real always-on-top z-order. Chose Svelte over React because the widget has only three SVG primitives; React boilerplate isn't worth it. - **Inline SVG, no chart library** — `BlockRing` is one circle, `WeeklyBar` is seven ``s, `ModelStack` is a stacked single-row bar. Adding Chart.js / ECharts / uPlot for ~80 lines of SVG would balloon the bundle for nothing. - **JSONL-only data source, no Anthropic API** — Anthropic doesn't expose a local cap-state file, but the JSONL transcripts contain everything we need to derive usage (this is what `ccusage` does). Avoids needing an admin key and keeps the widget fully offline. - **Widget runs on Windows host, not in WSLg** — needs to pin to the Windows desktop, autostart on login, and share the always-on-top z-order with native Windows apps. WSLg windows can't do that. The widget reads WSL transcripts via the `\\wsl$\\home\\.claude\projects\` UNC mount. - **`notify` watcher + 60s tokio poll fallback** — `ReadDirectoryChangesW` on the WSL 9P mount is unreliable; the poll backstops it. 60 s is a pragmatic balance vs CPU. - **All filesystem reads happen Rust-side** — the JS `capabilities/default.json` does NOT grant `tauri-plugin-fs`. Keeps the webview sandbox tight. - **Block algorithm** — `block_start = floor_to_hour(first_ts_of_block)`, `block_end = block_start + 5h`, new block on ≥5h gap OR when previous block ends. This matches ccusage and the way Anthropic's docs describe the rolling window. - **Weekly = rolling 7 days, no calendar anchoring** — Anthropic's reported Max-plan weekly reset day is buggy and shifts (see GH issues #54974, #52921). The honest thing is "past 7 days from now." - **Caps are user-configurable in Settings** with placeholder defaults (200k tokens / 5h block, 2M tokens / week). No authoritative local source for the real caps. ## Open questions / TODOs - [ ] **Forgejo host setup** is incomplete on this WSL machine: no `~/.ssh/id_ed25519`, no `tea` CLI, no global `git config user.{name,email}`. Repo currently lives only locally; **`git remote add origin` and `git push -u origin main` are pending** that setup. See `~/claude/CLAUDE.md` § "One-time host setup" for the exact steps. - [ ] **Watcher does not re-bind on settings change.** If user changes WSL distro override in Settings, `set_settings` calls `refresh_and_emit` and updates `state.roots`, but the `notify` watcher is still pinned to the *old* roots. v0 workaround: restart the widget after changing distro. Better fix: rebuild `WatcherHandle` on settings change. - [ ] Tune cap defaults once we have a few weeks of real data — current 200k / 2M values are guesses. - [ ] Decide whether to expose a tray icon for relaunch after `quit_app` (currently the widget can only be reopened via Start Menu / autostart). - [ ] Consider whether to fold in the pricing / `$ estimate` view later — out of scope for v0 per user. - [ ] Verify subagent dedupe assumption: do subagent JSONLs ever contain assistant lines that aren't also in the parent transcript? If yes, we MUST count them; if always duplicate, we MUST skip them. Code uses `requestId || uuid` set, which is safe either way. - [ ] Replace placeholder Tauri icons in `src-tauri/icons/` before release (`pnpm tauri icon source.png`). - [ ] First `cargo check` / `pnpm install` has not run — toolchain absent in WSL. Build will happen on Windows host; expect minor compile warnings on first try. ## Session log ### 2026-05-08 / 2026-05-09 - Planned the project (approved plan at `~/.claude/plans/snug-mapping-milner.md`) and built the full scaffold in one session that crossed midnight UTC. - Authored Tauri config (frameless, transparent, alwaysOnTop, skipTaskbar, 280×360), Cargo.toml, capabilities/default.json. - Authored Rust modules: `state.rs`, `settings.rs`, `paths.rs`, `jsonl.rs`, `usage.rs` (with unit tests for block boundaries), `watch.rs`, `commands.rs`, `lib.rs`, `main.rs`. - Authored Svelte 5 frontend: `App`, `TitleBar`, `BlockRing`, `WeeklyBar`, `ModelStack`, `Settings` components plus `ipc.ts`, `types.ts`, `format.ts`, `styles.css`. - Wrote `scripts/seed-fake-jsonl.ps1` verification helper and `README.md` build instructions. - 5 commits on `main` branch, all local. Forgejo host setup incomplete (see TODOs) — push deferred to next session. - Toolchain (rust/node/pnpm) NOT installed in this WSL environment — that's expected; the build runs on the Windows host. `cargo check` / `pnpm install` not yet run. ## External references - Approved plan: `/home/megaproxy/.claude/plans/snug-mapping-milner.md` - Tauri 2 prerequisites: https://v2.tauri.app/start/prerequisites/ - Tauri 2 window customization: https://v2.tauri.app/learn/window-customization/ - Tauri 2 autostart plugin: https://v2.tauri.app/plugin/autostart/ - Tauri 2 capabilities: https://v2.tauri.app/security/capabilities/ - ccusage (algorithm reference): https://github.com/ryoppippi/ccusage - Claude Max weekly reset issues (context for "rolling 7d" choice): https://github.com/anthropics/claude-code/issues/54974 · https://github.com/anthropics/claude-code/issues/52921