claude-usage-widget/memory.md

49 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 `<rect>`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$\<distro>\home\<user>\.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