Skip to content

/activity

Report real device usage from ActivityWatch. Covers per-app time, window titles, and active vs idle spans. Use when asked "what apps did I use", "how long was I in X", "what did I work on today", "how much was I active vs idle", or to mine usage patterns for automation.

shell
$ npx -y skills add bendrucker/claude --skill activity --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/activity
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Report real device usage from ActivityWatch. Covers per-app time, window titles, and active vs idle spans. Use when asked "what apps did I use", "how long was I in X", "what did I work on today", "how much was I active vs idle", or to mine usage patterns for automation.

SKILL.md

activity.SKILL.md
name: activitywatch:activity
description: Report real device usage from ActivityWatch. Covers per-app time, window titles, and active vs idle spans. Use when asked "what apps did I use", "how long was I in X", "what did I work on today", "how much was I active vs idle", or to mine usage patterns for automation.
argument-hint: "[query] [--recent <1d|7d|4w>] [-n <limit>]"
allowed-tools:
  - Bash
  - Read

Activity

Report how the device was actually used, from ActivityWatch's local capture. This skill only reads. It never writes to the db.

ActivityWatch runs `aw-server-rust` in the background (a LaunchAgent supervises it via `aw-qt`). It records the focused app and window title (`aw-watcher-window`) and active vs idle spans (`aw-watcher-afk`) into a SQLite db. DuckDB attaches that db read-only, which is safe while `aw-server` holds its own write connection.

Database

`~/Library/Application Support/activitywatch/aw-server-rust/sqlite.db`

Override with `AW_DB` (the wrapper resolves it, since DuckDB cannot expand `~` in `ATTACH`). If the file is missing, ActivityWatch is not installed or has not captured yet.

Querying

Run a named query with `scripts/aw-query.sh`. Each query supports `--recent <duration>` (`12h`, `1d`, `7d`, `4w`) to scope to a recent window, and `-n <limit>` to cap rows.

${CLAUDE_SKILL_DIR}/scripts/aw-query.sh top-apps
${CLAUDE_SKILL_DIR}/scripts/aw-query.sh top-apps --recent 1d
${CLAUDE_SKILL_DIR}/scripts/aw-query.sh window-titles --recent 7d -n 40
${CLAUDE_SKILL_DIR}/scripts/aw-query.sh afk --recent 1d

The aggregate queries (`top-apps`, `window-titles`, `afk`) return durations both formatted (`duration`, e.g. `1h 23m`) and raw (`seconds`) so results are readable and still sortable/summable. `app-timeline` lists individual focus events and returns raw `seconds` only.

Queries

  • **top-apps** — total focused time per app, most first. The headline "what did I use" answer.
  • **window-titles** — time per window title within each app. What you were actually doing, not just which app was open. Needs Accessibility granted to ActivityWatch.
  • **app-timeline** — focus events in reverse-chronological order (when you switched to what, for how long). Pair with `--recent 1d` to reconstruct a day.
  • **afk** — active (`not-afk`) vs idle (`afk`) time. How much of the window was actually at the keyboard.

Schema

Two tables in the attached `aw` database:

  • `buckets(id, name, type, client, hostname, created, data)` — one row per watcher. `type` is `currentwindow` (window watcher) or `afkstatus` (afk watcher).
  • `events(id, bucketrow, starttime, endtime, data)` — `bucketrow` joins to `buckets.id`. `starttime`/`endtime` are **nanoseconds since the Unix epoch** (divide by `1e9` for epoch seconds). `data` is JSON: `{app, title}` for `currentwindow`, `{status}` for `afkstatus`.

Duration of an event is `(endtime - starttime) / 1e9` seconds. The named queries live in [`resources/queries/`](resources/queries/).

Discovery

For questions the named queries don't cover, attach the db read-only and explore. `DESCRIBE` and a sample surface any watcher's shape (browser, editor, and custom watchers all land in `events.data` as JSON):

duckdb -c "INSTALL sqlite; LOAD sqlite; INSTALL json; LOAD json;
ATTACH '$HOME/Library/Application Support/activitywatch/aw-server-rust/sqlite.db' AS aw (TYPE sqlite, READ_ONLY);
SELECT type, count(*) FROM aw.buckets GROUP BY 1;
DESCRIBE aw.events;
SELECT data FROM aw.events LIMIT 5;"

Write ad-hoc queries in the same shape as the files in `resources/queries/`: join `events` to `buckets`, filter by `buckets.type`, extract fields with `json_extract_string(data, '$.field')`, and measure time as `(endtime - starttime) / 1e9`.

Read more
Read it on GitHub ↗
Ships withbendrucker-claude

My personal plugin marketplace for Claude Code, Anthropic's AI coding assistant.

Get the whole plugin, auto-invoked
Stats
15
Stars
0
Views
1
Forks
Active
Maintenance
TypeScript
Language
MIT
License
14h ago
Last commit
1y ago
Created

Repo: bendrucker/claude