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:
@@ -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.
|
||||
Reference in New Issue
Block a user