fix(ios): screentime compatibility patch with Greptile review fixes - #917
Conversation
- buckets: detect 'aw-import-screentime' as android-compatible buckets - queries: preserve 'title' attribute during android event merging - activity: add post-processing to support iOS attributes (mapping 'title' to 'app' for readability) - visualization: add 'Bundle IDs' view for technical detail while keeping 'Top Apps' human-readable
- Remap all iOS events regardless of title presence (use bundle ID as fallback app name) to prevent data mismatch with server-side aggregations - Preserve classname and title fields in re-aggregated app_events so downstream visualizations (Bundle IDs view) can access them - Add comment explaining that 'app' bucket type filter is guarded by name prefix to clarify intent and avoid confusion with other 'app'-type buckets
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #917 +/- ##
==========================================
- Coverage 38.55% 38.11% -0.45%
==========================================
Files 42 42
Lines 2233 2259 +26
Branches 439 454 +15
==========================================
Hits 861 861
- Misses 1294 1319 +25
- Partials 78 79 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Greptile SummaryAdds iOS Screen Time support across bucket discovery, query aggregation, activity-store post-processing, and selectable visualizations.
Confidence Score: 5/5The PR appears safe to merge with no unresolved blocking failures related to the previous review threads. No blocking failure remains. Important Files Changed
Reviews (6): Last reviewed commit: "fix(ios): use ScreenTime-preferred bucke..." | Re-trigger Greptile |
| @@ -116,10 +116,17 @@ export const useBucketsStore = defineStore('buckets', { | |||
| ); | |||
| }, | |||
| bucketsAndroid(): (host: string) => string[] { | |||
There was a problem hiding this comment.
I feel like it's incorrect to call screentime/iOS buckets for Android buckets. They probably deserve their own thing.
There was a problem hiding this comment.
Agreed — using 'android' as the umbrella for both Android watchers and iOS ScreenTime imports is awkward naming. I've taken a first step in 0918119 by adding a dedicated ios.available flag to the activity store, derived from whether any android bucket starts with aw-import-screentime. This lets visualizations distinguish iOS/ScreenTime from regular Android without touching the existing query paths. A fuller rename of bucketsAndroid/android.available could be a follow-up.
| :namefunc="e => e.data.title", | ||
| :colorfunc="e => e.data['$category']", | ||
| with_limit) | ||
| div(v-if="type == 'top_bundle_ids' && activityStore.android.available") |
There was a problem hiding this comment.
This wouldn't work for Android devices, but would still show up as available for them.
There was a problem hiding this comment.
Fixed in 0918119. Added ios.available to the activity store (true only when a ScreenTime bucket is present) and gated both the top_bundle_ids availability check and the template render condition on ios.available instead of android.available. Regular Android users no longer see Bundle IDs in the dropdown.
Two P1 issues found by Greptile: 1. top_titles widget was marked available when android.available=true, but the template only renders it when !android.available — so iOS users saw an empty widget. Revert available to window.available only. 2. App totals were re-aggregated from title_events (capped at 100 entries), discarding apps beyond the top 100. Fix: build a bundle-ID→name lookup from title_events, then remap app_events in-place so the server's complete aggregation is preserved.
|
@greptileai review |
|
Pushed two fixes addressing the P1 findings from Greptile (score 3/5): 1. Mobile title widget stays blank (
2. Truncated events corrupt app totals ( App totals were re-aggregated from Fix: build a bundle-ID → human-name lookup from Re-triggered Greptile to re-score. |
|
@greptileai review |
…nly not all Android
|
@greptileai review |
|
@greptileai review |
…ryByPeriod queries
|
@greptileai review |
|
Merge recommendation — converged after 6 Greptile rounds All blocking P1 findings have been addressed. Here's the summary: Fixed (blocking):
Addressed / acknowledged (non-blocking):
Remaining (acknowledged, non-blocking):
CI: Greptile ✅, lint ✅, build ✅, CodeQL ✅, tests ✅ (2 pending but same pattern as previous commits which passed) Domain risk: Bundle IDs visualization and iOS name remapping can only be fully validated with real ScreenTime import data — standard manual test would be importing via |
|
CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click. This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted. |
…ctivityWatch#917) * feat(ios): add support for iOS data visualization - buckets: detect 'aw-import-screentime' as android-compatible buckets - queries: preserve 'title' attribute during android event merging - activity: add post-processing to support iOS attributes (mapping 'title' to 'app' for readability) - visualization: add 'Bundle IDs' view for technical detail while keeping 'Top Apps' human-readable * Apply suggestion from @ErikBjare * fix(ios): address Greptile review on screentime compatibility patch - Remap all iOS events regardless of title presence (use bundle ID as fallback app name) to prevent data mismatch with server-side aggregations - Preserve classname and title fields in re-aggregated app_events so downstream visualizations (Bundle IDs view) can access them - Add comment explaining that 'app' bucket type filter is guarded by name prefix to clarify intent and avoid confusion with other 'app'-type buckets * fix(lint): reformat data object to satisfy prettier line-length rule * fix(ios): fix truncated app totals and blank titles widget Two P1 issues found by Greptile: 1. top_titles widget was marked available when android.available=true, but the template only renders it when !android.available — so iOS users saw an empty widget. Revert available to window.available only. 2. App totals were re-aggregated from title_events (capped at 100 entries), discarding apps beyond the top 100. Fix: build a bundle-ID→name lookup from title_events, then remap app_events in-place so the server's complete aggregation is preserved. * fix(ios): gate Bundle IDs on android.available and document name-lookup invariant * fix(ios): add ios.available flag, gate Bundle IDs on iOS/ScreenTime only not all Android * fix(ios): prefer ScreenTime bucket over Android watcher in hybrid-host query * fix(ios): use ScreenTime-preferred bucket in activeHistory and categoryByPeriod queries --------- Co-authored-by: Guracc <garaccioni.andrea@gmail.com> Co-authored-by: Erik Bjäreholt <erik.bjareholt@gmail.com>
This is a follow-up to #740 (by @Guracc), taking over at @ErikBjare's request to incorporate the Greptile review feedback before merging.
What this PR does
Adds iOS compatibility for ActivityWatch WebUI with data imported via the
aw-import-screentimeutility. Users see human-readable app names (e.g. "YouTube") instead of bundle IDs (e.g.com.google.ios.youtube), and a new "Bundle IDs" visualization lets them drill down to raw identifiers.Changes from #740
The original PR was functionally correct but had three issues flagged by Greptile:
1. Events without
titlewere silently skipped, causing a data mismatchThe original code only remapped events that had a
titlefield, but all events were already included in the server-side aggregation. Events without a title fell through with their original bundle ID asapp, mixing bundle IDs with human names in the aggregated output.Fix: always remap — set
classname = original bundle IDandapp = title || original bundle ID. Events without a human-readable title now appear under their bundle ID rather than being inconsistently mixed.2.
app_eventsre-aggregation discardedclassnameandtitlefieldsThe original re-aggregation created events with only
{ app, $category }, losingclassnameandtitle. This broke the Bundle IDs visualization that readse.data.classname, and generally madeapp_eventsstructurally inconsistent withtitle_events.Fix: preserve
classname,title, and$categoryin the re-aggregatedapp_events.3. Generic
'app'bucket type filter lacked explanatory contextbucketsByType(host, 'app')was already narrowed by.startsWith('aw-import-screentime'), so there was no functional bug, but the'app'type selection looked like it could match unintended buckets.Fix: added a comment explaining that
'app'is the screentime bucket type and the name prefix guard is the specificity mechanism.Files changed
src/stores/activity.ts— iOS post-processing and re-aggregation fixessrc/stores/buckets.ts— explanatory comment on bucket type filtersrc/stores/buckets.ts,src/queries.ts,src/components/SelectableVisualization.vue— original changes from Compatibility patch for aw-import-screentime #740 (rebased onto current master)Testing
Import iPhone screen time data via
aw-import-screentimeand verify:com.google.ios.youtube-style identifierstitlefield appear under their bundle ID (not dropped)