Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Wuf

PyPI Latest Release Pepy Total Downloads GitHub License

WUF Unifies Footprints.

Wuf folds local Git and filesystem timestamp footprints onto one representative Monday-to-Sunday week. It highlights activity outside your intended working hours without pretending that timestamped events are hours worked.

Wuf terminal output

Wuf is local, private by design, terminal-only, and currently alpha.

Install

pip install wuf
wuf --help

For an isolated installation, use uv tool install wuf or pipx install wuf. Standalone binaries are available from GitHub releases.

Renamed from Workfold

Wuf is the continuation of Workfold under its shorter, permanent name. Wuf packages also install workfold as a compatibility command, but wuf is the canonical command going forward. Existing configuration should be renamed from workfold.toml to wuf.toml, and [tool.workfold] tables should become [tool.wuf].

Quick start

Run wuf inside a Git repository to see the current ISO week:

wuf

The selectors you will use most are:

wuf . -t 2w3d                    # rolling elapsed window
wuf . -t 2026-W31                # one ISO week
wuf . -p fs                      # current filesystem metadata
wuf . -p both                    # low-noise Git + filesystem view
wuf . -p portable -t all         # evidence stored in Git objects
wuf . -p full -t all --git-commits-from all-refs --include-ignored
wuf . -e git:tag:tagger fs:file:modified

They control separate parts of the request:

Selector Purpose Values
-t, --time Date scope this-week, 2w3d, YYYY-Www, DATE..DATE, all
-p, --profile Named event set git, fs, both, portable, full
-e, --events Exact event set (alternative to a profile) IDs and wildcards

The profiles answer different questions:

  • git: What does ordinary commit activity look like? This is the default.
  • fs: What birth and modification metadata exists for current regular files?
  • both: What does the combined low-noise Git and filesystem pattern look like?
  • portable: What dated evidence is stored inside Git objects?
  • full: Which timestamps exist across every supported Git and filesystem event kind?

Profiles expand only to event sets. Time, Git reachability, ignored files, and explicit exclusions remain independently configurable.

For exact control, -e/--events accepts identifiers such as git:commit:author, git:tag:tagger, and fs:file:modified; quote wildcards such as 'git:*'. -l/--list appends bounded event details. Paths must appear before either space-separated selector, or after an option-terminating --.

Schedules support daily intervals, breaks, overnight shifts, and all:

wuf . --hours 'Mo-Thu 08:00-16:30; Fr 08:00-14:00'
wuf . --hours 'Mo-Fr 22:00-06:00'
wuf . --hours all

See the usage guide for clustering, fixed bands, identity markers, day hiding, grids, exact event selection, configuration, and every CLI option.

Configuration

Put personal defaults in the platform configuration directory, or project defaults in wuf.toml:

timezone = "Europe/Berlin"
hours = "Mo-Thu 08:00-16:30; Fr 08:00-14:00"
profile = "portable"
cluster-anchor = "midnight"
band-label = "start"
show-empty-bands = true
count-grouping = "visual"
grid = "vertical"
hide-empty-days = ["weekend"]

[styles."git:tag:*"]
symbol = "◆"
color = "magenta"
outside-symbol = "◇"
outside-color = "bright_red"

Python projects may use [tool.wuf] in pyproject.toml instead. Values resolve as built-in → global → nearest project → CLI. Inspect the result and each value's origin without collecting timestamps:

wuf . --show-config

Use --config FILE for one exact file or --no-config for built-ins plus CLI only. The usage guide documents locations, discovery, merging, and every supported key.

Reading the chart

  • By default, circles are Git events and squares are filesystem events.
  • Default green/blue filled markers are inside the schedule; red hollow markers are outside. Colorless output preserves the shape distinction, and event style rules may replace both symbol pairs and their colors.
  • One symbol is one event; busy cells use exact ×N counts. Counts stay separate per event kind by default; --count-grouping visual merges kinds only when their resolved symbol and configured color match.
  • Empty time is compressed, and reports a meaningful gap.
  • Identity-marker mode replaces Git circles with codes mapped in the key.
  • Event-selector style rules can replace source-marker symbols and colors while keeping collection and coverage unchanged.

The summary independently splits all events by schedule and by calendar day. Weekend events can therefore also be outside working hours.

Accuracy and privacy

  • Events are discrete timestamp observations, not work sessions or duration.
  • Collection is local: Wuf does not contact a Git host or telemetry service.
  • Git history can be rewritten; reflogs can expire; filesystem metadata is a mutable snapshot and birth time depends on platform and filesystem support.
  • Coverage reports unavailable, unsupported, and unreadable evidence that can prevent a complete answer. Known timestamps outside the requested time or identity scope are not counted as coverage outcomes.

See the documentation for every CLI option, collector semantics, coverage guarantees, and platform notes.

Development

The Python package lives directly in wuf/; there is no src/ wrapper.

nix develop
uv sync --locked --extra dev
uv run --locked pytest
uv run --locked ruff check .
uv run --locked ruff format --check .
uv run --locked pyright

Use nix run .#docs-dev for the documentation site and nix run .#docs-check to validate it. The architecture guide documents the package boundaries, dependency rules, data pipeline, and test layout.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wuf-0.1.0a7.tar.gz (316.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wuf-0.1.0a7-py3-none-any.whl (254.7 kB view details)

Uploaded Python 3

File details

Details for the file wuf-0.1.0a7.tar.gz.

File metadata

  • Download URL: wuf-0.1.0a7.tar.gz
  • Upload date:
  • Size: 316.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for wuf-0.1.0a7.tar.gz
Algorithm Hash digest
SHA256 96949989c6f4f5534526f419cfde60d650d6543739e67fcbeca05bc679f90f5f
MD5 222a37f8cc482b3eb86a08ab49826eb0
BLAKE2b-256 646234b0d2156b7a9eb3816429fdfe51dc4015e9b65a128d7f437125e728be79

See more details on using hashes here.

Provenance

The following attestation bundles were made for wuf-0.1.0a7.tar.gz:

Publisher: release.yml on janthmueller/wuf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wuf-0.1.0a7-py3-none-any.whl.

File metadata

  • Download URL: wuf-0.1.0a7-py3-none-any.whl
  • Upload date:
  • Size: 254.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for wuf-0.1.0a7-py3-none-any.whl
Algorithm Hash digest
SHA256 00f86b86c1d69dcb690140a428ad75df45eb0d15f79e9d96247da23bfe49179c
MD5 bee9e744f6cf4c4978893a549aed4ae8
BLAKE2b-256 3657dc8d528e4bd3716c4b380fafc02c31fa8b2da2c3676289c0beb92242dfd7

See more details on using hashes here.

Provenance

The following attestation bundles were made for wuf-0.1.0a7-py3-none-any.whl:

Publisher: release.yml on janthmueller/wuf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0a7 This release

2 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