Import Apple's Screen Time App.InFocus telemetry (stored in Biome SEGB files) into ActivityWatch buckets. All CLI commands emit JSON to stdout so you can easily pipe the results into jq, persist them, or feed them to other tools.
- Enumerate Screen Time devices by reading
~/Library/Biome/sync/sync.db. - Decode
App.InFocusSEGB files into stitched ActivityWatch events. - Preview stitched timelines before importing anything.
- Push events directly into an ActivityWatch server (testing or production) with per-device buckets.
- Inspect raw protobuf fields for debugging.
- macOS with Screen Time enabled (the tool reads from
~/Library/Biome/streams/restricted/App.InFocus/remote/…). - Full Disk Access for the terminal/IDE you use to run the CLI.
- Python 3.10–3.13 and uv.
- An ActivityWatch server (default port 5600, testing port 5666).
uv sync
source .venv/bin/activate
aw-import-screentime --helpuv sync also installs ccl-segb from GitHub, which is required to parse the binary SEGB stream Apple stores on disk.
Apple stores the data this tool consumes under ~/Library/Biome. Make sure your shell/IDE already has Full Disk Access so it can read:
~/Library/Biome/sync/sync.db(device metadata)~/Library/Biome/streams/restricted/App.InFocus/remote/<device_id>/*
If the directories are empty, unlock Screen Time in System Settings, ensure “Share Across Devices” is enabled on both macOS and iOS, and wait for iCloud to sync the files locally.
Usage: aw-import-screentime [OPTIONS] COMMAND [ARGS]...
Options:
--log-level [ERROR|WARNING|INFO|DEBUG]
--tz [local|utc] Timestamp timezone for stitched events.
--config PATH Reserved for future config support.
--version Print the CLI version and exit.
--help Show this message and exit.
Commands:
devices
events
fileAll commands emit JSON structures; logs go to stderr via Rich. The --since option (available on events and file) accepts ISO-8601 timestamps or relative values such as 24h, 7d, now-15m, yesterday, or today.
List DevicePeer identifiers discovered in sync.db.
aw-import-screentime devices --paths | jq .--platformlets you query a different Apple platform (default2, which is iOS).--pathsincludes the resolved stream directory for each device.
Dry-run the stitching pipeline for one or more devices. This never contacts ActivityWatch; it is useful for inspecting what would be imported.
aw-import-screentime events preview \
--device ABCDEF0123456789 \
--limit 10 \
--since 24h \
--storefront us --storefront se \
| jq .--limitcontrols how many files per device are read (0= all).--sinceclips the resulting intervals to recent activity.--storefrontcontrols the App Store locales used to enrich bundle titles (defaults to["us"]).
Run the same decoding logic as preview, but stream the events into ActivityWatch. A bucket named aw-import-screentime_ios_ios-<device_id> is created per device (append --bucket-suffix if you want a custom suffix).
# Import the last 24h from every device into an ActivityWatch test server on port 5600
aw-import-screentime events import --since 24h --limit 20--testingswitches theActivityWatchClientinto testing mode (port5666). Use this whenever you are talking toaw-server --testing.--portoverrides the ActivityWatch port explicitly, e.g.--port 5666if you prefer to spell it out.--bucket-suffixappends a suffix to each bucket name (handy for experiments).--device,--limit,--since, and--storefrontmirror thepreviewcommand.
Inspect a single SEGB file either as raw protobuf entries or stitched intervals.
# Stitched summary (default)
aw-import-screentime file ~/Library/Biome/streams/restricted/App.InFocus/remote/00000000-0000-0000-0000-000000000000/00012345 --max-events 10 | jq .
# Raw protobuf dump
aw-import-screentime file ... --raw --raw-limit 5 | jq .--raw/--stitchedtoggles the output mode.--raw-limitcaps how many protobuf entries are decoded.--max-eventslimits how many stitched events are included in the JSON payload (set to0for everything).--sinceand--storefrontbehave like theeventscommands.
ActivityWatch exposes a dedicated testing port (5666) when you launch aw-server --testing. Use one of the following when experimenting against that instance:
aw-import-screentime events import --testing ...(preferred; it switches both the ActivityWatch port and client label).aw-import-screentime events import --port 5666 ...(if you want to specify the port manually).
Both options keep the production data on port 5600 untouched while you verify the importer.
- Only the App.InFocus stream is decoded today; other Screen Time streams (notifications, website usage, etc.) are ignored.
- If Biome has not synced yet, the CLI simply reports empty devices.
- macOS sometimes logs incomplete foreground durations; intervals are stitched best-effort and may be shorter than what you see in Screen Time.app.
- App title enrichment depends on live App Store lookups and therefore needs network access the first time a bundle is seen.