feat(cli): add privacy-safe activity summaries - #116
Conversation
Greptile SummaryThe PR adds a locally aggregated
Confidence Score: 3/5The PR should not merge until browser buckets with unknown hostname metadata can no longer disclose another machine's domain activity in a host-specific summary. The new selector assigns every legacy unknown-host browser bucket to any requested hostname, so shared-server deployments can mix another machine's overlapping browser activity into privacy-oriented output. Files Needing Attention: aw_client/summary.py and tests/test_summary.py
|
| Filename | Overview |
|---|---|
| aw_client/summary.py | Adds bucket discovery and summary formatting, but unknown-host bucket inclusion can mix browser activity across machines. |
| aw_client/queries.py | Adds bounded server-side category, application, and domain aggregation using existing canonical event semantics. |
| aw_client/cli.py | Adds the summary command and consistently reuses the active client for category settings. |
| aw_client/classes.py | Generalizes category-settings retrieval to accept a compatible caller-provided client while preserving fallback behavior. |
| tests/test_summary.py | Covers aggregation, redaction, formatting, and CLI output, but codifies globally accepting unknown-host browser buckets. |
| README.md | Documents valid summary invocations, output sensitivity, and application/domain omission controls. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
CLI[summary command] --> Buckets[Discover browser buckets]
Buckets --> Query[Build privacySummary query]
Settings[Load category settings through active client] --> Query
Query --> Server[Local ActivityWatch aggregation]
Server --> Normalize[Normalize bounded result]
Normalize --> JSON[Provider-neutral JSON]
Normalize --> Table[Human-readable table]
Reviews (1): Last reviewed commit: "feat(cli): add privacy-safe activity sum..." | Re-trigger Greptile
| bucket_hostname = bucket.get("hostname") or data.get("hostname") | ||
| if bucket_hostname not in (None, "", "unknown", hostname): | ||
| continue |
There was a problem hiding this comment.
Unknown buckets break host isolation
If a shared ActivityWatch server contains browser buckets from multiple machines with missing or unknown hostname metadata, this predicate assigns all of them to the requested host, causing overlapping domains and durations from another machine to appear in the host-specific summary. How this was verified: The selected buckets are passed into the summary query and combined when their events overlap the requested machine's active browser periods.
Summary
aw-client summaryfor bounded, AFK-filtered category, application, and domain totalsWhy
ActivityWatch's agent/AI guidance recommends locally aggregated, review-before-send context instead of raw exports. Today, users need to write the query and normalization code themselves. This command turns that workflow into a reproducible CLI path without exposing raw titles, full URLs, document names, message subjects, or raw event history.
Related: ActivityWatch/activitywatch#1388
Related: ActivityWatch/aw-webui#925
Validation
ruff check aw_client tests/test_summary.pyruff format --check aw_client tests/test_summary.pymypy aw_client tests/test_summary.pyXDG_DATA_HOME=/tmp/activitywatch-test-data pytest -q tests/test_summary.py tests/test_auth.py tests/test_requestqueue.py— 17 passed