English | ็ฎไฝไธญๆ | ๆฅๆฌ่ช
Tauri 2 desktop app ยท Local system dashboard ยท AI session cost metering
A local-first, privacy-preserving desktop workbench for your machine: processes, ports, dev servers, and AI coding-session token costs โ all visible in one place. All data stays on your device. Dark & light themes. UI available in English, ็ฎไฝไธญๆ and ๆฅๆฌ่ช.
Windows-only for now: port collection uses netstat -ano and packaging
targets NSIS. macOS / Linux are untested and not yet packaged.
๐ Project homepage โ every mirror hosts its own copy of the landing page (see the mirror table below); each copy automatically links back to its own repository and releases.
No dev environment needed (Windows 10 / 11 x64). Each GitHub mirror below publishes its own Release with the same installer โ pick the platform you prefer:
| Channel | File | Notes |
|---|---|---|
| Recommended | Workbench_<version>_x64-setup.exe (Releases โ latest) |
NSIS installer, ~4 MB |
| Portable | workbench.exe (Releases โ latest) |
Single file, no registry writes |
The installer is not code-signed, so Windows SmartScreen may show an "Unknown publisher" warning โ choose More info โ Run anyway. This is because signing certificates cost money, not because the file is unsafe.
Identical code, five platforms; each runs its own CI and publishes its own releases where supported:
| Platform | Repository | Landing page |
|---|---|---|
| GitHub | X33834/workbench | x33834.github.io/workbench |
| GitHub | badhope/workbench | badhope.github.io/workbench |
| GitHub | Morningstar202604/workbench | morningstar202604.github.io/workbench |
| Gitee | badhope/workbench | โ (downloads on its Releases page) |
| GitCode | badhope/workbench | โ (downloads on its Releases page) |
Captured in browser demo mode (
npm run preview): outside Tauri the app injects static demo data fromsrc/lib/demo.ts; all paths and host names are placeholders, no real machine data.
| Overview | Processes |
|---|---|
![]() |
![]() |
| CPU / memory trends, disks, process groups | Full snapshot, virtual scrolling, kill confirmation |
| Servers & ports | AI sessions & cost |
|---|---|
![]() |
![]() |
| netstat parsing, dev-framework tags | Session preview, token metering, budgets |
| Projects | Tasks |
|---|---|
![]() |
![]() |
| Local projects, Git branch detection | Drag-and-drop kanban |
| Settings | Logs |
|---|---|
![]() |
![]() |
| Theme, refresh interval, budgets, import/export | Built-in log viewer, tail reading |
Regenerate screenshots yourself: npm run build, then npm run preview,
then run a headless Chrome with
--remote-debugging-port=9222, then node scripts/shoot_docs.mjs.
The script asserts demo mode is active and refuses to shoot otherwise, so real
data can never leak into the repo.
| Module | What it does |
|---|---|
| ๐ฅ Overview | CPU / memory trend charts, disk usage donut, process group stats |
| โ Processes | Full snapshot, CPU / memory sorting, virtual scrolling (viewport-only rows), kill with confirmation, AI agent detection |
| ๐ Servers & ports | netstat listener detection, dev-framework tags (Vite / Next / Djangoโฆ) |
| ๐ค AI sessions | opencode online sessions, local Claude / Codex session preview |
| ๐ฐ Cost metering | Token usage, daily trends, budget alerts, Anthropic cache pricing |
| ๐ Projects | Local project registry, automatic Git branch detection |
| โ Tasks | Kanban board (drag to change status) |
| โ Settings | Theme / refresh interval, budget thresholds, JSON import & export |
| ๐ Logs | Built-in viewer, auto refresh, tail reading |
- Three-level confidence: measured (API-reported usage) โ estimated (character heuristic) โ zero_pricing
- 40+ model prices built in;
pricing_overrides.jsonoverrides are currently read-only (drop the file in manually, no UI editor yet) - Anthropic cache semantics:
input_tokensexcludes cache;cache_read_input_tokensbilled at 0.1ร,cache_creation_input_tokensat 1.25ร - Day attribution: measured and estimated rows are bucketed per JSONL-line
timestamp(falls back to the previous day / file mtime when missing), so appending to a session never rewrites historical days - Unknown models are never priced: unrecognized models are flagged
unknownand recorded aszero_pricingโ no invented unit prices - Idempotent: each session file keeps only its latest snapshot (replaced
whole-group by
file_path), so re-scans never stack stale rows - Estimates can be disabled: the "include estimated rows" toggle live-updates overview / trend / model breakdowns
- Budget alerts: system notifications, de-duplicated to avoid nagging
- Scan scope: the cost scan covers every session file under
~/.claude/projectsand~/.codex/sessions(the UI preview shows the 10 most recent)
- Closing the window hides to tray; tray left-click toggles visibility, the tray menu really exits the process
- Global hotkey
Ctrl+Shift+Wtoggles window visibility (degrades to a warning if the hotkey is taken; startup is never blocked) - Logs roll per launch (> 5 MB archives to
workbench.log.1), the Logs page reads on demand from the tail - Killing PID 0/4 and critical system processes (csrss / lsass / services โฆ) is rejected outright
| Item | Requirement |
|---|---|
| OS | Windows 10 / 11 (x64) โ the only verified platform |
| Runtime | WebView2 Runtime (preinstalled on Windows 11; recent Windows 10 usually has it) |
| Disk | ~35 MB installed; portable single file ~15 MB |
| Privileges | No admin required; killing a process needs same-or-higher privileges |
| Network | None required. The only optional probe is the local opencode service when you open the AI sessions page |
- Grab
Workbench_<version>_x64-setup.exefrom the latest release - If SmartScreen appears: More info โ Run anyway
- Launch "Workbench" from the Start menu
Requires Node.js โฅ 20, Rust โฅ 1.77, WebView2.
npm installTypes crossing the IPC boundary are not hand-written in src/types.ts; they
are generated from the Rust structs:
cd src-tauri
cargo test --test export_bindings # regenerates src/generated/*.tssrc/types.ts only re-exports; src/generated/ is the committed contract
snapshot. After changing a Rust struct you must re-run the command above,
otherwise the CI drift gate will reject the PR.
npm run tauri dev # desktop dev mode (hot reload)
npm run dev # frontend only, browser demo mode, no Rust needednpm run tauri buildArtifacts land in src-tauri/target/release/bundle/.
| Layer | Choice |
|---|---|
| Runtime | Tauri 2 (Rust + OS webview) |
| Frontend | React 19 + TypeScript (strict) + Vite 8 |
| State | Zustand 5 (persist) |
| Styling | Tailwind CSS 4 + dual-theme CSS variables |
| Charts | ECharts 6 (tree-shaken, dark/light themes registered) |
| Virtualization | @tanstack/react-virtual 3 (variable-height expanded rows) |
| Subscriptions | Zustand 5 useShallow selectors + memo page components |
| IPC | Tauri IPC + spawn_blocking |
| Contracts | ts-rs 12 generates src/generated/*.ts from Rust structs, CI drift-gated |
| Process data | sysinfo |
| Ports | netstat parser (POSIX / Windows dialects) |
| i18n | English default, switchable ็ฎไฝไธญๆ / ๆฅๆฌ่ช |
| Quality gates | ESLint 10 + Prettier 3 + vitest 5 + clippy -D warnings |
workbench/
โโโ src/ # frontend
โ โโโ pages/ # 8 feature pages (lazy loaded)
โ โโโ lib/ # store / api / echarts / chartTheme / i18n / util
โ โโโ generated/ # ts-rs generated IPC contract types (do not edit)
โ โโโ ui.tsx # shared component library
โ โโโ types.ts # type re-exports + frontend-only types
โ โโโ App.tsx # app shell
โ โโโ styles/global.css # global styles & theme variables
โโโ src-tauri/ # Rust backend
โ โโโ capabilities/ # Tauri permission set (minimal)
โ โโโ icons/ # app icons (generated by scripts/make_icons.py)
โ โโโ src/
โ โ โโโ commands.rs # IPC command layer
โ โ โโโ procs.rs # process snapshot + kill
โ โ โโโ ports.rs # netstat parsing
โ โ โโโ devserver.rs # dev-framework detection
โ โ โโโ ai.rs # AI session fetching
โ โ โโโ pricing.rs # model price matching
โ โ โโโ session_meter.rs# JSONL token cost parsing
โ โ โโโ cost_store.rs # cost data persistence
โ โ โโโ ipc_guard.rs # IPC argument whitelist
โ โ โโโ lib.rs # Tauri bootstrap
โ โโโ tests/ # IPC contract export test
โโโ docs/ # GitHub Pages landing page + screenshots
โโโ scripts/ # icon & screenshot helper scripts
โโโ .github/workflows/ # CI / Release / Pages
npm run format:check # Prettier
npm run lint # ESLint (zero warnings)
npm run test # frontend unit tests (vitest, 48 cases)
npm run coverage # coverage
npm run build # tsc + vite build
cd src-tauri
cargo test # backend tests + IPC contract export
cargo clippy --all-targets -- -D warnings # zero-warning gatePure Rust logic (netstat parsing, framework detection, price matching, token
extraction, JSON storage, IPC guard) carries #[cfg(test)] unit tests; the
frontend is covered by vitest (util / store / shared components / error
boundary). CI runs formatting, lint, type check, build, both test suites,
clippy with zero warnings, and verifies src/generated/ matches the Rust
structs.
How is the cost metering computed? Is it accurate?
It parses the usage fields in local Claude Code / Codex session JSONL files
and prices them against 40+ built-in model prices, with three confidence
levels:
- measured โ real usage reported by the API, most accurate
- estimated โ no usage, heuristic by character count (can be disabled)
- zero_pricing โ model unrecognized, recorded as free rather than priced with a made-up unit price
Anthropic cache tokens follow the official semantics (read 0.1ร, write 1.25ร).
Does it upload my data anywhere?
No. Projects, tasks, the cost ledger and logs all live in the local app data
directory. The app only does two local things: read netstat for ports, and
read local session files for costs. The only optional network call is probing
the local opencode service (default port 4096); on failure it just shows "not
detected".
Can killing a process break my system?
No. PID 0/4 and critical system processes (csrss, lsass, servicesโฆ) are rejected by the backend; the frontend asks for confirmation first; and the target identity is re-verified after refresh to avoid PID-reuse mistakes.
Where did the window go after I closed it? How do I quit?
Hiding to the tray is intentional (the app is meant to keep monitoring). Right
click the tray icon and choose "Quit"; the hotkey Ctrl+Shift+W
toggles visibility anytime.
Windows says "Unknown publisher" โ what do I do?
The installer is not code-signed (certificates cost money), so SmartScreen steps in. Choose More info โ Run anyway, or grab the portable exe instead.
Done and planned. Vote or propose new ideas in the Issues.
- Real-time process / port / dev-server monitoring
- AI session cost metering with budget alerts
- Projects & task kanban
- Dark / light themes, log viewer
- Multilingual UI (English / ็ฎไฝไธญๆ / ๆฅๆฌ่ช)
- Cross-platform support (macOS / Linux collection & packaging)
- Installer code signing
- UI editor for
pricing_overrides.json - Sharded cost ledger (100k+ records)
- Page-level end-to-end tests
- Windows-only verified: port collection shells out to
cmd /c netstat -ano; the POSIX branch inports.rsis currently never exercised - Frontend interaction paths rely on manual verification: vitest covers util / store / shared components / error boundary, but the 8 pages have no E2E tests
- The cost ledger is a single
cost_data.json(writes are serialized); very large histories will make full read/write sluggish pricing_overrides.jsonis read-only by design for now, no write path- The installer is unsigned; first launch may trigger a SmartScreen prompt
- The tray menu text is currently Chinese only (frontend UI is fully trilingual)
| File | Purpose | Location |
|---|---|---|
data.json |
Projects & tasks | app data dir |
cost_data.json |
Cost records + pricing settings | app data dir |
pricing_overrides.json |
User price overrides (read-only, drop in manually) | app data dir |
workbench.log |
Runtime logs | app data dir |
*.corrupt-<timestamp> |
Untouched backup of a data file that failed to parse (never overwritten by the next save) | app data dir |
On Windows the app data dir is %APPDATA%\com.workbench.desktop.
- Contribution workflow & conventions: CONTRIBUTING.md
- Security vulnerabilities: private channel, see SECURITY.md
- Community code of conduct: CODE_OF_CONDUCT.md
- Changelog: CHANGELOG.md
MIT ยฉ 2026 x1882







