# 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 1. **Detects when you are working in Zed** on this project by monitoring the active window title (Wayland) and filesystem activity. 2. **Writes heartbeats** to `.zed-hours/heartbeats.jsonl`: - timestamp - project path - focused file (if detectable) - idle status 3. **Logs git commits** automatically via `post-commit` hook to `.zed-hours/commits.jsonl`. 4. **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: ```bash python3 tools/time_tracking/install.py ``` This will: - create `.zed-hours/` in the project root; - install a `post-commit` git 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 ```bash 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: ```bash systemctl --user daemon-reload systemctl --user enable --now zed-hours-gem360.service systemctl --user status zed-hours-gem360.service ``` Logs: ```bash journalctl --user -u zed-hours-gem360.service -f ``` To stop: ```bash systemctl --user stop zed-hours-gem360.service ``` ### Option C: `tmux` / `screen` ```bash tmux new -s zed-hours -d 'python3 tools/time_tracking/zed_tracker.py --project-root $(pwd)' ``` --- ## Generating a report ```bash 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: ```bash 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: 1. **Hyprland**: `hyprctl activewindow` 2. **Sway**: `swaymsg -t get_tree` 3. **GNOME / Mutter**: D-Bus `GetActiveWindow` via `gdbus` 4. **KDE / KWin**: D-Bus via `qdbus` 5. **Fallback**: monitor filesystem activity inside the project root using `inotify` or 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: ```bash python3 tools/time_tracking/install.py ``` The scripts detect the project root automatically from the current working directory. --- ## Data format ### `.zed-hours/heartbeats.jsonl` ```json {"timestamp": "2026-08-26T09:15:00", "project": "/home/fegger/Code/ixsol/gem360-git", "file": "README.md", "active": true, "source": "hyprctl"} ``` ### `.zed-hours/commits.jsonl` ```json {"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` ```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.