- Rust 54%
- Svelte 33.6%
- TypeScript 5.9%
- CSS 3%
- JavaScript 2.3%
- Other 1.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| docs | ||
| nix | ||
| src | ||
| web | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| config.example.yaml | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| todo.md | ||
ActivityWatch Semantic Categorizer
A local, deterministic Rust service and Svelte UI that combines ActivityWatch window/AFK events with Wakapi editor metadata, splits them into an inspectable timeline, and applies hot-reloadable YAML rules.
Quick start
cp config.example.yaml ~/.config/aw-categorizer/config.yaml
npm --prefix web install
npm --prefix web run build
npm --prefix web test
cargo run -- validate
cargo run -- run
Open http://127.0.0.1:5666. ActivityWatch must be running locally. Wakapi may be remote: set its HTTPS URL, enable it, and point api_key_file at a local file containing the plain API key. Historical Wakapi reads are requested day-by-day using its WakaTime-compatible API.
Historical rebuilds are explicit and reversible:
cargo run -- reprocess --today
cargo run -- reprocess --from 2026-09-01 --to 2026-09-05
Rules are managed in the local UI and persisted as draft and active revisions in SQLite. Rules v2 supports parent/child inheritance, scoped fallbacks, reusable value sets, recursive boolean matchers, source-field capture with literal fallbacks, previews, and condition-level diagnostics. Publishing atomically activates the validated draft and recategorizes today plus the previous two local calendar days from cache. The YAML rules: section bootstraps a new database, and the UI can import or export Rules v2 YAML. See Rules v2.
ActivityWatch and Wakapi poll independently at their configured intervals. Normalized source events and per-source cursors are retained in SQLite, making restarts incremental and recent rule re-evaluation network-free.
The local Svelte interface uses checked-in shadcn-svelte primitives. It provides the timeline, daily totals, complete v1 filters, source synchronization health, and an accessible evidence drawer for inspecting classifications and provenance. Its Catppuccin Mocha-inspired appearance menu offers six browser-local accent choices, with Mauve as the default. Future ideas and their motivation are kept in todo.md.
API
GET /api/segments?from=2026-09-04&to=2026-09-05&project=ADOFAI&title=Editor&afk=falseGET /api/summarywith the same filtersGET /api/projects,/api/categories,/api/sources,/api/statusPOST /api/reprocesswith{ "from": "2026-09-04", "to": "2026-09-05" }GET /api/rules,PUT /api/rules/draft,POST /api/rules/preview,POST /api/rules/publishPOST /api/rules/import,GET /api/rules/export,GET /api/rules/fields
Use category=__uncategorized__ on segment or summary requests to select activity without a usable category classification.
The server rejects non-loopback bind addresses. It never modifies ActivityWatch or Wakapi data and does not submit timesheets.
Nix / Home Manager
The flake provides the full application package, a development shell, and homeManagerModules.default. Import the module, set services.aw-categorizer.enable = true, and provide the YAML file at the default XDG config path (or set configFile). The user service uses Restart=on-failure and remains loopback-only.