{"id":18162288,"url":"https://github.com/tillkuhn/billy-idle","last_synced_at":"2026-04-29T23:04:58.655Z","repository":{"id":260128814,"uuid":"864118850","full_name":"tillkuhn/billy-idle","owner":"tillkuhn","description":"💤 Billy Idle - Lightweight MacOS (In)activity Tracker written in Go","archived":false,"fork":false,"pushed_at":"2025-03-14T15:40:39.000Z","size":342,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T16:36:23.515Z","etag":null,"topics":["go","grpc","hours","macos","sqlite","time-tracking","timer","tool","work"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tillkuhn.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-27T14:24:58.000Z","updated_at":"2025-03-14T15:40:43.000Z","dependencies_parsed_at":"2024-12-20T16:47:39.369Z","dependency_job_id":"5124fde0-1fd3-4eda-a7af-21ffe45b8afb","html_url":"https://github.com/tillkuhn/billy-idle","commit_stats":null,"previous_names":["tillkuhn/billy-idle"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tillkuhn%2Fbilly-idle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tillkuhn%2Fbilly-idle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tillkuhn%2Fbilly-idle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tillkuhn%2Fbilly-idle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tillkuhn","download_url":"https://codeload.github.com/tillkuhn/billy-idle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595374,"owners_count":20963942,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","grpc","hours","macos","sqlite","time-tracking","timer","tool","work"],"created_at":"2024-11-02T09:04:39.946Z","updated_at":"2026-04-29T23:04:58.649Z","avatar_url":"https://github.com/tillkuhn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"image:https://github.com/tillkuhn/billy-idle/actions/workflows/go.yml/badge.svg[ci-build]\n\n== 💤 Billy Idle - Lightweight macOS (In)activity Tracker\n\nSimple busy / idle time tracker inspired by the ancient article https://www.dssw.co.uk/blog/2015-01-21-inactivity-and-idle-time/[Inactivity and Idle Time on OS X].\n\n== Background\n\nAccording to the article, OS X has a timer called *HIDIdleTime* that tracks the last time you interacted with the computer, e.g. moved the mouse, typed a key, or interacted with the computer.\n\n*billy-idle* simply queries this value periodically using the `ioreg` utility that ships with macOS, and matches it against a pre-defined threshold.\nIf exceeded, it will create a record for the busy time period in database.\nThis data can later be used as input for time tracking tools or statistics.\n\n== Example Time Tracking Report\n\n----\nFriday January 10, 2025 (2025-01-10) Daily Report\n----------------------------------------------------------------------------------------------------\n  🕰  | TIME RANGE          | 🐝 BUSY RECORD\n-----+---------------------+--------------------------------------------------------------------------------\n  🌙 | 03:00:13 → 03:11:28 | Spent 11m Feeding a mallard named The Notorious D.O.G. with mushroom stew\n  ☕  | 08:42:52 → 11:55:07 | Spent 3h12m Driving a Pickup truck Mark Lt to Minneapolis #874\n  🌞 | 12:24:19 → 12:35:00 | Spent 10m Drinking a Belgian And French Ale Orval Trappist Ale with 2.6% #875\n  🌞 | 13:24:14 → 15:08:20 | Spent 1h44m Building App Tealgrammar 5.8.4 in Orc #876\n  🌞 | 15:09:27 → 15:24:27 | Spent 15m Driving a Van A4 Cabriolet to Orlando #877\n  🌞 | 15:24:27 → now      | Still busy with Eating a Frozen kahlua creme topped with Clementine #878\n-----+---------------------+--------------------------------------------------------------------------------\n  🧮 | 5H23M +BREAK: 5H23M | BUSY+IDLE: 15H15M  SKIP(\u003c5M): 4  \u003eREG(7H48M): -2H25M \u003eMAX(10H): -4H37M\n-----+---------------------+--------------------------------------------------------------------------------\nSuggestestion: 09:00 → 14:23 (inc. 0m break), you're expected to be busy for another 2h25m\n----\n\n== Example Punch Clock Report\n\n----\n  CW | 📅 DATE     | WEEKDAY   | 🐝 BUSY | ⏲️  PLAN | 🕰 OVERTIME\n-----+-------------+-----------+---------+----------+-------------\n  1  |  2025-01-01 | Wednesday | 0m      | 0m       | 0m\n     |  2025-01-02 | Thursday  | 7h50m   | 7h48m    | 2m\n     |  2025-01-03 | Friday    | 8h10m   |          | 22m\n     |             |           |         |          |\n  2  |  2025-01-06 | Monday    | 9h      | 7h48m    | 1h12m\n     |  2025-01-07 | Tuesday   | 8h50m   |          | 1h2m\n     |  2025-01-08 | Wednesday | 8h40m   |          | 52m\n-----+-------------+-----------+---------+----------+-------------\n                       TOTAL   | 42H30M  |              3H30M\n                               | 6 DAYS  |               \u003e39H\n----\n\n== Run from source\n\n[source,shell]\n----\n$ go run main.go\n\n2024/10/01 17:13:29 🎬 billy started version=v0.0.2 built=2024-10-01T15:13:28Z pid=37477 go=go1.23.1 arch=arm64\n2024/10/01 17:13:29 🥫 Open database file=~/.billy-idle/default/db.sqlite3 sqlite=3.46.0\n2024/10/01 17:13:29 👀 Tracker started in idle mode with auto-idle\u003e=2m0s interval=10s\n2024/10/01 17:13:29 🐝 Enter busy mode after 0s idle time rec=#13\n2024/10/01 17:15:33 💤 Checkpoint idleTime=11s state=idle lastSwitch=0s ago lastCheck=5s ago\n2024/10/01 17:15:38 🛑 Received signal interrupt, initiate shutdown\n2024/10/01 17:15:38 🛑 Tracker stopped after 0s busy time rec=#10\n2024/10/01 17:15:38 🥫 Close database in ~/.billy-idle/dev\n----\n\nNOTE: Binary packages for macOS amd64 and arm64 are coming soon, the same goes for docker images on ghcr.io\n\n== Install as launchd managed service (experimental)\n\nPlist files in ~/Library/LaunchAgents/ are run at login with the id of the logged in user.\nSee https://stackoverflow.com/a/13372744/4292075[SO: launchctl and .plist file],\nhttps://ieftimov.com/posts/create-manage-macos-launchd-agents-golang/[Create and manage MacOS LaunchAgents using Go]\nand  https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html#//apple_ref/doc/uid/10000172i-SW7-BCIEDDBJ[Launching Custom Daemons Using launchd]\n\n[source,shell]\n----\n$ cp com.github.tillkuhn.billy-idle.plist ~/Library/LaunchAgents\n$ launchctl load ~/Library/LaunchAgents/com.github.tillkuhn.billy-idle.plist\n$ launchctl start com.github.tillkuhn.billy-idle\n\n# in case of Load failed: 5: Input/output error, try this first\n$ launchctl unload ~/Library/LaunchAgents/com.github.tillkuhn.billy-idle.plist\n----\n\n== CLI Arguments\n\n.CLI Usage for track subcommand\n[source,shell]\n----\nStarts the tracker in daemon mode to record busy and idle times.\n\nUsage:\n  billy-idle track [flags]\n\nFlags:\n  -a, --app-root string     App root Directory e.g. for SQLite DB (defaults to $HOME/.billy-idle (default \"/Users/tillkuhn/.billy-idle\")\n  -c, --cmd string          Command to retrieve HIDIdleTime (default \"ioreg\")\n      --drop-create         Drop and re-create db schema on startup\n  -e, --env string          Environment (default \"dev\")\n  -h, --help                help for track\n  -m, --idle duration       Max tolerated idle time before client enters idle state (default 10s)\n  -i, --interval duration   Interval to check for idle time (default 2s)\n\nGlobal Flags:\n  -d, --debug   Debug checkpoints\n----\n\n.CLI Usage for report subcommand\n[source,shell]\n----\nGenerates a report based on the recorded idle and busy times.\n\nUsage:\n  billy-idle report [flags]\n\nFlags:\n  -a, --app-root string     App Directory e.g. for SQLite DB (defaults to $HOME/.billy-idle/\u003cenv\u003e (default \"/Users/tillkuhn/.billy-idle\")\n  -e, --env string          Environment (default \"default\")\n  -h, --help                help for report\n      --max-busy duration   Max allowed time busy period per day (w/o breaks), report only (default 10h0m0s)\n      --min-busy duration   Minimum time for a busy record to count for the report (default 5m0s)\n      --no-color            Disable color output\n      --reg-busy duration   Regular busy period per day (w/o breaks), report only (default 7h48m0s)\n\nGlobal Flags:\n  -d, --debug   Debug checkpoints\n----\n\n.CLI Usage for punch subcommand\n[source,shell]\n----\nPunch busy time\n\nUsage:\n  billy-idle punch [flags]\n\nFlags:\n  -h, --help   help for punch\n\nGlobal Flags:\n  -d, --debug   Debug checkpoints\n----\n\n== Experimental Grafana Cloud Integration\n\n*Billy Idle* includes an experimental feature to push tracking metrics to Grafana Cloud using InfluxDB Line Protocol. This enables real-time monitoring and visualization of productivity data in Grafana dashboards.\n\n=== Configuration\n\nAdd these flags to enable Grafana Cloud integration:\n\n[source,shell]\n----\n--grafana-host=\"\"      # Grafana Hostname (e.g., https://prometheus-prod-xx-prod-eu-west-2.grafana.net)\n--grafana-auth=\"\"      # Grafana Auth in format \"username:token\"\n----\n\n=== Usage\n\n[source,shell]\n----\n# Development mode with Grafana Cloud\nmake run-grafana\n# Expands to:\ngo run main.go --debug track --env dev --idle 10s --interval 5s --port 50051 --grafana-host=$GRAFANA_HOST --grafana-auth=$GRAFANA_AUTH\n----\n\n=== Metrics Format\n\nThe feature pushes metrics using InfluxDB Line Protocol:\n\n----\nbilly_idle,env=dev,client=myclient busy_secs=15,busy_status=true 1736164800000000000\n----\n\n* **Measurement**: `billy_idle`\n* **Tags**: `env` (environment), `client` (client ID)\n* **Fields**: `busy_secs` (current idle time), `busy_status` (busy/idle state)\n* **Timestamp**: Current time\n\n=== Requirements\n\n- Grafana Cloud account with InfluxDB API access\n- Username and API token for authentication\n- Network access to Grafana Cloud endpoints\n\nThe feature gracefully degrades - if Grafana configuration is not provided, tracking continues normally without cloud integration.\n\n== Database Support\n\n*Billy Idle* currently only support a local https://gitlab.com/cznic/sqlite[sqlite] database, more precisely `modernc.org/sqlite` which is a cgo-free port of SQLite.\nBut it shouldn't be a big deal to add support for a remote https://www.postgresql.org[PostgreSQL] Database.\n\nimage:docs/sqlite.png[]\n\n== Development\n\n[source,shell]\n----\n$ make\nUsage: make \u003cOPTIONS\u003e ... \u003cTARGETS\u003e\n\nAvailable targets are:\n\nbuild                build all targets\nbuild-mac            build for mac current arch using default goreleaser target path\nclean                Clean output directory\nhelp                 Shows the help\ninstall              Install as launchd managed service\nlint                 Lint go code\nlogs                 Show agent logs\nminor                Create Minor Release\nrelease              run goreleaser in snapshot mode\nreport               Show report for default db\nreport-dev           Show report for dev db\nrun                  Run app in tracker mode, add -drop-create to recreate db\nrun-help             Run app in help mode\nrun-mac              run mac build\ntest                 Run tests with coverage, implies lint\ntidy                 Add missing and remove unused modules\nupdate               Update all go dependencies\n----\n\n== 🎸 Credits\n\nimage:https://upload.wikimedia.org/wikipedia/commons/thumb/7/74/Billy_idol_ill_artlibre_jnl.png/640px-Billy_idol_ill_artlibre_jnl.png[]\n\nSource: https://commons.wikimedia.org/wiki/File:Billy_idol_ill_artlibre_jnl.png[Wikimedia Commons], terms of the https://en.wikipedia.org/wiki/en:Free_Art_License[Free Art License] apply.\n\n== Contribution\n\nIf you want to contribute to *rubin* please have a look at the xref:CONTRIBUTING.md[]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftillkuhn%2Fbilly-idle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftillkuhn%2Fbilly-idle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftillkuhn%2Fbilly-idle/lists"}