Introduces a local-first time tracker for Zed editor sessions, including background activity tracking, automatic git commit logging, and markdown report generation. Includes install script, systemd service template, and setup instructions in README.
5.1 KiB
Zed Hours Tracker
A lightweight, local-first, background time tracker for Zed editor sessions, with automatic git commit logging. No cloud, no accounts, no manual timers.
Works on Arch Linux + Wayland and is designed to be portable to other projects.
What it does
- Detects when you are working in Zed on this project by monitoring the active window title (Wayland) and filesystem activity.
- Writes heartbeats to
.zed-hours/heartbeats.jsonl:- timestamp
- project path
- focused file (if detectable)
- idle status
- Logs git commits automatically via
post-commithook to.zed-hours/commits.jsonl. - Generates markdown reports combining heartbeats + commits into daily summaries.
Files
| File | Purpose |
|---|---|
install.py |
Install git hook and create .zed-hours/ data directory |
log_commit.py |
Called by git hook; do not run directly usually |
zed_tracker.py |
Background tracker for Zed activity |
generate_report.py |
Generate a markdown hours report |
README.md |
This file |
Installation
Run from the project root:
python3 tools/time_tracking/install.py
This will:
- create
.zed-hours/in the project root; - install a
post-commitgit hook that logs commits; - create a default config file.
Running the tracker
The tracker is intentionally a simple script you run in the background.
Option A: One-off test
python3 tools/time_tracking/zed_tracker.py --project-root $(pwd)
Press Ctrl+C to stop.
Option B: Zed tasks (run from the editor)
This project includes Zed tasks so you can trigger tracker actions with the task runner shortcut (alt+shift+t or ctrl+shift+t depending on your keymap). The default working directory for Zed tasks is the project root, so the commands use relative paths.
| Task | Action |
|---|---|
Zed Hours: Install tracker |
Install git hook, config, and systemd service |
Zed Hours: Start tracker (foreground) |
Start the tracker in a Zed terminal panel |
Zed Hours: Generate report (today) |
Generate today's report |
Zed Hours: Generate report (yesterday) |
Generate yesterday's report |
Zed Hours: Generate report (last 14 days) |
Generate a 14-day report |
Zed Hours: Open latest report |
Print path to latest report |
Zed Hours: Status |
Show heartbeat/commit/report counts |
Option C: Background via systemd user service (recommended for daily use)
A sample service file is generated by install.py at:
~/.config/systemd/user/zed-hours-gem360.service
Enable it:
systemctl --user daemon-reload
systemctl --user enable --now zed-hours-gem360.service
systemctl --user status zed-hours-gem360.service
Logs:
journalctl --user -u zed-hours-gem360.service -f
To stop:
systemctl --user stop zed-hours-gem360.service
Option C: tmux / screen
tmux new -s zed-hours -d 'python3 tools/time_tracking/zed_tracker.py --project-root $(pwd)'
Generating a report
python3 tools/time_tracking/generate_report.py --from 2026-08-03 --to yesterday
Output is written to .zed-hours/reports/YYYY-MM-DD_to_YYYY-MM-DD.md.
You can also run:
python3 tools/time_tracking/generate_report.py --today
How activity detection works on Wayland
Wayland does not expose a global active-window API for security reasons. The tracker tries several methods, in order:
- Hyprland:
hyprctl activewindow - Sway:
swaymsg -t get_tree - GNOME / Mutter: D-Bus
GetActiveWindowviagdbus - KDE / KWin: D-Bus via
qdbus - Fallback: monitor filesystem activity inside the project root using
inotifyor polling recent file access/modification times.
If all window-detection methods fail, the fallback still gives you a reliable signal that someone is actively editing files in this project.
Reusing in another project
Copy the tools/time_tracking/ directory to the new project and run:
python3 tools/time_tracking/install.py
The scripts detect the project root automatically from the current working directory.
Data format
.zed-hours/heartbeats.jsonl
{"timestamp": "2026-08-26T09:15:00", "project": "/home/fegger/Code/ixsol/gem360-git", "file": "README.md", "active": true, "source": "hyprctl"}
.zed-hours/commits.jsonl
{"type": "commit", "timestamp": "2026-08-26T09:20:00", "repo": "/home/fegger/Code/ixsol/gem360-git", "branch": "va_module", "sha": "abc12345", "message": "[ADD] feature X", "author": "Florian Egger"}
.zed-hours/config.json
{
"project_root": "/home/fegger/Code/ixsol/gem360-git",
"heartbeat_interval_seconds": 60,
"idle_threshold_seconds": 300,
"log_dir": ".zed-hours"
}
Notes
- This tool is intentionally simple and local. It is not a replacement for a commercial time tracker, but it is a reliable fallback when you forget to log hours.
- The tracker does not send data anywhere.
- Heartbeat granularity is one minute by default. Tune it in
config.json. - Because of Wayland security, window detection may not give the exact filename. The filesystem fallback compensates for this.