Skip to main content

Work Tempo

Work Tempo tracks source-code momentum across a Git workspace and its related repositories. It produces terminal summaries, a self-contained HTML report, and optional schema-versioned JSON for other local tools.

It measures:

  • Source and test LOC snapshots over time.
  • Added plus deleted source churn by month or day.
  • Language composition and per-repository contribution.
  • Documentation LOC and churn as separate informational metrics.

The optional native macOS menu-bar app opens on an aggregate of all tracked workspaces. Its menu-bar value and primary dashboard metric show source churn per day over the trailing closed days — 30 by default, configurable in Settings. An individual workspace remains selectable from the header.

Repository comparison and component classification are outside Work Tempo's scope.

Requirements

  • Python 3.10 or newer.
  • Git 2.30 or newer.

Work Tempo has no Python runtime dependencies outside the standard library.

Install

pipx install work-tempo   # or: pip install work-tempo

For local development:

git clone https://github.com/endario/work-tempo.git
cd work-tempo
python3 -m venv .venv
.venv/bin/pip install -e .

Then run it from a Git repository whose counted repositories have origin/main:

work-tempo

Within its fetch budget, each run attempts remote main for counted repositories (workspace root, initialized submodules, and configured extras). A repository skipped by that budget, or whose fetch fails, uses its last-fetched origin/main and marks the report; the collector never substitutes the checked-out branch. A local-only or master-default workspace needs an origin/main tracking ref. Counted submodules and extra repositories without one must acquire that ref or be excluded from the counting scope. Fetches run up to four at a time, bounded to 8 seconds per repository and 45 seconds per workspace.

The current directory is the default workspace. Analyze another checkout with:

work-tempo --root ~/projects/my-app

Without installation, use:

PYTHONPATH=src python3 -m work_tempo --root ~/projects/my-app

Reports

The default report covers the latest 18 monthly periods and writes HTML under the workspace-specific user cache directory. The exact path is printed after each run.

# Monthly history with explicit outputs
work-tempo --root ~/projects/my-app \
  --html /tmp/work-tempo.html \
  --json /tmp/work-tempo.json

# Daily view for the latest 30 days
work-tempo --root ~/projects/my-app --period day --days 30

# Terminal and JSON only
work-tempo --root ~/projects/my-app --no-html --json /tmp/work-tempo.json

# Optional three-month LOC forecast using the last six completed months
work-tempo --root ~/projects/my-app --forecast

Period boundaries use the active system timezone, falling back to UTC. The resolved timezone is included in JSON and HTML report metadata.

Workspace Scope

Work Tempo always considers the parent Git repository. It also discovers usable initialized submodules declared in .gitmodules and can aggregate additional repositories configured outside the workspace.

Create a personal configuration:

work-tempo --root ~/projects/my-app --init-config

This writes ~/projects/my-app/.work-tempo.local.json, which should remain untracked. For shared workspace policy, generate or maintain ~/projects/my-app/.work-tempo.json instead.

Configuration layers are applied in this order:

  1. Built-in generic defaults.
  2. Tracked .work-tempo.json.
  3. Untracked .work-tempo.local.json, or the file passed with --config.

Later keys replace earlier keys. Arrays replace rather than append. Each file is validated on its own before merging: an unknown key, a wrong type, or an unsupported schema_version is an error that names the key and file, so a typo cannot silently change the numbers.

Config files declare "schema_version": 1 or 2 (missing means 1). test_file_markers, the filename infixes that mark a test file, needs version 2; --init-config writes version 2. A version-2 file is rejected by older releases instead of being miscounted. Existing caches are recomputed once after upgrading. Run work-tempo --init-config to write every supported field with its default, or read src/work_tempo/defaults.json.

Additional repositories use paths relative to the main checkout:

{
  "schema_version": 1,
  "extra_repos": [
    {
      "label": "client-app",
      "path": "../client-app"
    },
    {
      "label": "shared-sdk",
      "path": "packages/shared-sdk"
    }
  ]
}

Only actual Git repository roots are counted. Missing or uninitialized configured repositories are reported and skipped.

Counting Model

LOC snapshots count newline-delimited tracked source files from the last origin/main commit available at each period cutoff. Source and tests are separated using conventional test directories and test/spec/e2e filename patterns.

Churn is added plus deleted lines from non-merge commits reachable from the captured origin/main tip, grouped by author date and filtered through the same current counting policy. Blank lines and comments count because WorkTempo measures physical source lines rather than semantic SLOC.

Generated, minified, dependency, build, cache, scratch, and vendor-like paths are excluded by default. Documentation is counted separately and does not contribute to source LOC, growth, or churn metrics.

Cache

On macOS, artifacts default to:

~/Library/Caches/WorkTempo/<workspace-name>-<workspace-key>/

Linux uses $XDG_CACHE_HOME/work-tempo or ~/.cache/work-tempo. Set WORK_TEMPO_CACHE_HOME to override the root.

# Rebuild the workspace cache
work-tempo --clear-cache

# Run without reading or writing a cache
work-tempo --no-cache

# Use an explicit cache file
work-tempo --cache /tmp/work-tempo-cache.json

Snapshot cache entries include repository identity, commit, and effective counting policy. Churn entries also include period kind and timezone. Rewritten origin/main history triggers a full churn rescan. Cutoff commits are cached by repository identity, source tip, and exact cutoff time. Cache schema 5 starts cold once after this upgrade because earlier label-based entries cannot prove which checkout produced them; interrupted snapshot counting resumes from its checkpoints.

JSON Compatibility

Reports currently use schema version 1. Additive fields may be introduced within version 1, and consumers must ignore unknown fields. Removing a field, changing its type or meaning, or changing period-series alignment requires a schema-version increment.

Development

PYTHONPATH=src python3 -m unittest discover -s tests -v
python3 -m compileall -q src tests

macOS menu-bar app

The local app requires macOS 14 or newer on Apple Silicon, Swift 6, and an installed work-tempo CLI. It resolves the collector from ~/.local/bin, Homebrew locations, and then PATH.

Build an ad-hoc signed app bundle:

scripts/build-macos-app.sh
open dist/WorkTempo.app

Install the local build in /Applications:

scripts/build-macos-app.sh --install
open /Applications/WorkTempo.app

Use the plus button to add individual Git repository roots. Each workspace keeps its own .work-tempo.json and .work-tempo.local.json counting policy. The default All Workspaces scope rejects overlapping reports and mixed timezones. Historical metrics share a common closed-day watermark, while current totals use each contributing report's latest snapshot. Both charts keep code and test activity above the axis and informational documentation below it.

The app renders saved reports immediately. Collection is sequential, skips unattended work in Low Power Mode, uses two workers, and checkpoints the collector cache so an interrupted history extension can resume.

App state and saved reports live under:

~/Library/Application Support/WorkTempo/

The collector's existing cache remains under ~/Library/Caches/WorkTempo/, shared with terminal runs. Removing a workspace from the app does not alter its source repository. To uninstall, quit WorkTempo and remove /Applications/WorkTempo.app; remove the Application Support directory separately only when its saved workspace list and reports are no longer wanted.

Swift development checks:

cd macos
swift test
swift build -c release

Design docs

  • Architecture: the collector, configuration, counting model, and cache.
  • macOS app: scheduling, aggregation, and metric definitions.

Releasing

Bump version in pyproject.toml in a pull request and merge it, then tag the merge commit vX.Y.Z and push the tag. The Publish workflow builds the package and uploads it to PyPI by trusted publishing, with no stored token.

Contributing

main takes changes only through a pull request that passes the tests and the identity check. Every commit is authored and committed under 5214595+ren-diao@users.noreply.github.com (or a bot's noreply address); an AI model may be credited with a Co-authored-by trailer. Turn the same check on locally with git config core.hooksPath .githooks.

Authors

Ren Diao, co-authored with Claude (Anthropic).

License

MIT

2mw2lt

Work Tempo is part of 2mw2lt — Too Much Work, Too Little Time — a steering partner that coordinates work across AI workers and trusted people. Its sibling unlimited reads AI-subscription usage.

Metadata

Release files for work-tempo 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for work-tempo 0.0.2
File Size Uploaded
work_tempo-0.0.2.tar.gz 56.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for work-tempo 0.0.2
File Interpreter ABI Platform
work_tempo-0.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 92.4 kB

Release files / work_tempo-0.0.2.tar.gz

Download URL work_tempo-0.0.2.tar.gz
Size 56.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a9642c33b005578c4847d8ec2ab38a787124ba00a34252b8a4fb34bafd7f5262
BLAKE2b-256 checksum
How to use checksums
2b561ffc5a1166a7be29dbb764b47d221b6d3e4ea941da9771f1d91ed2e48911
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release files / work_tempo-0.0.2-py3-none-any.whl

Download URL work_tempo-0.0.2-py3-none-any.whl
Size 35.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
05712630573d8dd04dc15095cbbf9d3e19871d1505f1fbc057f4690c8c4872eb
BLAKE2b-256 checksum
How to use checksums
41cddc6f73da28d913a666a47baed2e1eaa7fd44fba16e20f262470bab8b2fba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release history Release notifications | RSS feed

0.0.3

2 release files

This release

0.0.2 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page