Generate one local, self-contained HTML activity view from commits in configured Git repositories, grouped by lanes you define.
The script asks the installed git executable for history and renders the
records it successfully reads as a commits-per-day heatmap and a lane-aware,
date-grouped feed. It starts no screen recorder, daemon, server, or telemetry
client. The current prototype does not yet fail closed on every Git/read error
or enforce offline behavior for every repository configuration, so its output
is a convenience view, not completeness or reproducibility evidence.
Some activity-tracking tools capture screens or run continuously. git-worklog instead reads configured Git commit history; it does not claim that commits are a complete record of work.
Above: the demo, generated from synthetic data by python3 make_demo.py — no
real project information.
The script uses only the Python standard library and git. A supported
Python/Git version matrix has not yet been qualified.
git clone https://github.com/espressolee/git-worklog
cd git-worklog
cp lanes.example.json lanes.json # edit for your repos (stays local, gitignored)
python3 worklog.py --open # writes worklog.html and opens itOther flags:
python3 worklog.py --days 30 # window (default 365)
python3 worklog.py --full-bodies # don't truncate long commit bodies
python3 worklog.py --verify # print collector diagnostic counts
python3 worklog.py --config other.json{
"roots": ["/path/to/your/repos", "~/work"],
"author": "git-author-pattern",
"since_days": 365,
"exclude_substrings": ["/clone", "/vendor/"],
"lane_rules": [
{"match": "infra", "lane": "Infra"},
{"match": "/experiments/", "lane": "Experiments"}
]
}The file must be valid JSON; comments are not supported. Repositories are
discovered below each root at depth 0–2. author is passed to Git's regex-based
--author filter, and the first matching lane rule wins.
- Lane rules are explicit, first-match path-substring rules evaluated on every
run. Moving or renaming a repository, or changing rule order, can change its
historical lane labels. Unmapped repositories render as
(unmapped)and are printed to stderr. - Merge commits are excluded. Full commit hashes are globally de-duplicated in sorted discovery order. If the same hash occurs in multiple repositories, only the first occurrence contributes an event and per-repository diagnostic count; alias and lane provenance are not retained.
- Display and bucket times use each commit's author timestamp and recorded
offset. The relative
--sincefilter is delegated to Git and can use a different commit clock, so interval-boundary correctness is not yet claimed.
git-worklog is a commit-history view, not a productivity score or a complete account of your work. It does not infer effort, quality, impact, or causality. The heatmap counts commits, labelled as such — there is no invented score, no lines-changed proxy.
Non-goals (kept out on purpose): no always-on capture, no cloud AI, no server, no database, no team analytics, no "score."
Privacy: generated HTML contains real commit subjects and, by default,
commit bodies plus repository and lane names. The default worklog.html path
matches this repository's .gitignore, but custom output paths may not. The
script does not upload the report, but it does not yet enforce private file
permissions or atomic publication. Treat every generated report as sensitive.
--verify prints totals and per-repository counts produced by the same
collector:
python3 worklog.py --days 365 --verifyThese numbers are diagnostic output, not an independent correctness check.
Counts are printed after global hash de-duplication, so a direct per-repository
git log count can differ for clones or shared history. Read failures can
currently be warnings while the command still exits successfully.
Byte-level determinism is not yet claimed. Relative time selection, the
generation timestamp, locale/timezone behavior, and current-date demo inputs
can change output. The known correctness gates are tracked in ROADMAP.md.
No config is needed. This builds throwaway repositories containing synthetic
commit content and renders demo/worklog.html:
python3 make_demo.py --openThe command deletes and recreates the repository's demo/ directory; do not
store your own files there.
The demo uses the current local date and timezone. It is a visual example, not a deterministic fixture or correctness self-test; commit IDs and rendered output can change across dates and timezone environments.
The source contains macOS/Linux/Windows browser-opening branches, but no
committed CI matrix yet qualifies any platform or Python/Git version range.
Without --open, the HTML file is still written and its path is printed.
-
gwl.py— the contract pipeline (recommended).generatevalidates the config, collects commits, checks ledger self-consistency, renders a deterministic HTML page, checks the page matches the ledger, and publishes a mode-restricted, namespace-atomic local bundle (ledger.json+worklog.html, mode 0600). Privacy and no-egress qualification remain G4. The G2 qualification gate separately compares the collector with an independent Git-source oracle; the runtime command does not rerun that source oracle. On a declared pre-publication contract, collection, verification, or publication failure, no final bundle is published. Built to the frozen contract indocs/M0_CONTRACT.md; milestones M0–M3 are committed, while G4–G5 and release qualification remain open.python3 gwl.py generate --config lanes.json \ --since 2026-01-01T00:00:00Z --until 2027-01-01T00:00:00Z --out ./bundle
-
worklog.py— the legacy quick view. The original prototype: one HTML file, no ledger, best-effort. Still used bymake_demo.py. It has the known blockers listed in the roadmap. When evaluating the two unreleased prototypes, prefergwl.py; do not rely on either as a released artifact before G4–G5 and release qualification.
See ROADMAP.md for the correctness contract, failure fixtures, release gates, and per-milestone status. The project will remain a Git-history view and will not become a productivity score.
Any successor product, research, or platform claim is governed separately by PLATFORM_ROADMAP.md. It requires retained external use, real economic commitment, preregistered comparison, independent reproduction, and privacy/security qualification; none is implied by the current contract pipeline or by completion of the v1 engineering gates.
MIT.
