Add Zed Hours Tracker tooling

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.
This commit is contained in:
2026-09-11 10:27:56 +02:00
commit bfff093dc6
5 changed files with 943 additions and 0 deletions
+185
View File
@@ -0,0 +1,185 @@
# 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.