ActivityWatch Architecture¶
Scope
This section is the implementation source of truth for ActivityWatch ingestion, FSM derivation, continuity correction, and sync-boundary behavior.
Module map¶
| Layer | Responsibility | Primary files |
|---|---|---|
| API access | Fetch bucket metadata and event slices from ActivityWatch server | src/features/activitywatch/api.ts, src/features/activitywatch/sync.ts |
| Timeline derivation | Slice overlapping watcher streams into parallel compound timeline states | src/features/activitywatch/sync-derive.ts, src/features/activitywatch/fsm.ts |
| Intent inference | Per-profile FSM hypothesis generation and conflict allocation | src/features/activitywatch/fsm.ts |
| Calendar mutation | Sync-from-last-checked continuity rewrite or standard overlap mutation | src/features/activitywatch/sync.ts, src/features/activitywatch/sync-continuity.ts, src/features/activitywatch/sync-utils.ts |
| UI/settings | Profile/rule editing and sync controls | src/features/activitywatch/ui/ActivityWatchConfigComponent.tsx, src/features/activitywatch/ui/ActivityWatchSettingsModal.tsx |
Core contracts¶
- Strategy contract:
Sync from Last Checkedis the only strategy that advanceslastSyncTime; both manual and automatic runs advance it after a successful non-custom sync. - Debug-range contract:
Custom Date Rangeis manual-only debug/backfill behavior. It never advanceslastSyncTimeand automatic sync is disabled while it is selected. - Input contract: ActivityWatch bucket events are normalized to bucket events and sliced into
CompoundEventintervals. - Session contract: FSM emits profile candidates, then best-fit allocator emits final blocks.
- Output contract: Final blocks are materialized as timed single
OFCEvententries in the configured target calendar. - Calendar-read contract: ActivityWatch overlap and continuity logic must operate on normalized/cache-backed events, not raw provider reads, because providers such as Daily Note store profile/category ownership in titles or cache metadata rather than inline fields.