timeman
A terminal based stopwatch and countdown timer, built with OpenTUI and shipped as standalone binaries — no runtime required.
- CLI interface (default): Lightweight inline mode that lives in your scrollback.
- TUI interface: Full-screen terminal UI via
-i/--interactive. - Notifications: Bell + toast when a countdown completes.
- Session timeline: Stopwatch summary with per-session start/end times in your local time zone.
- Session history: Every stopwatch session is saved. Review, delete and retitle them from the TUI with
h. - Drift-proof timing: Durations use a monotonic clock, so a system clock jump (DST, NTP sync) never corrupts them.
Installation
npm:
npm install -g timeman-cli
bun:
bun add -g timeman-cli
pip / uv (same binary, published as time-manager for continuity with the original Python package):
pip install time-manager
# or
uv tool install time-manager
curl (Linux, macOS — downloads the binary from the latest GitHub release):
curl -fsSL https://raw.githubusercontent.com/rehanhaider/time-manager/main/install.sh | bash
Every method installs the tm command. npm/bun also install timeman, pip also installs time-manager, and curl installs just tm.
Supported platforms: Linux x64/arm64 (glibc and musl), macOS x64/arm64, Windows x64 (via npm/bun).
Usage
tm sw # stopwatch (also: tm stopwatch)
tm cd 5 m # 5-minute countdown (also: tm countdown 5 m)
Stopwatch
tm sw
tm sw -p "Project Alpha" # name the session for the summary
tm sw -i # full-screen TUI
Keys: space start/stop · r reset · q quit · h history (TUI only).
On exit you get a session timeline — one bar per start/stop run, with total time:
╭──────────────── Project Alpha: 0 hrs 25 mins ────────────────╮
│ Session #1 13:53 ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 14:03 IST (0 hrs 10 mins) │
│ │
│ Session #2 14:10 ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 14:25 IST (0 hrs 15 mins) │
╰──────────────────────────────────────────────────────────────╯
Session history
Both modes save every session when you quit. Only the TUI reads them back, so press h from tm sw -i. There is no tm log command.
The first screen rolls your projects up over a billing period, largest first:
This Week This Month Last Month All Time
August 2026 · 11 hrs 52 mins logged
╭────────────────────────────────────────────────────────────────────────╮
│ PROJECT SHARE TOTAL LAST │
│ │
│ ▸Project Alpha ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 4 hrs 10 mins Sun │
│ Client Review ▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬ 4 hrs 5 mins Mon │
│ Deep Work ▬▬▬▬▬▬▬▬▬▬▬▬▬ 2 hrs 47 mins Sat │
│ Untitled ▬▬▬▬ 0 hrs 50 mins Fri │
╰────────────────────────────────────────────────────────────────────────╯
Keys: ↑↓ project · ←→ period · enter line items · esc back · q quit.
enter breaks one project into invoice lines, one per day, with its sessions underneath:
Client Review · Last Month · 4 hrs 5 mins
╭────────────────────────────────────────────────────────────────────────╮
│ Mon 31 Aug ───────────────────────────────────────── 2 hrs 25 mins │
│ ▸ 13:15 → 15:40 2 hrs 25 mins │
│ │
│ Thu 27 Aug ───────────────────────────────────────── 1 hr 40 mins │
│ 10:00 → 11:40 1 hr 40 mins │
╰────────────────────────────────────────────────────────────────────────╯
Keys: ↑↓ session · d delete · r rename the project · esc back · q quit.
A row shows the wall-clock span alongside the time actually on the clock. Pause mid-session and the duration comes out shorter than the span. d asks for y/n on the row itself. r retitles every session filed under that project, which is how Untitled gets fixed after you forget -p.
Sessions live in a SQLite database at ~/.local/share/timeman/history.db, or ~/Library/Application Support/timeman on macOS and %LOCALAPPDATA%\timeman on Windows. TIMEMAN_HOME overrides that directory. The newest 5,000 sessions are kept.
Countdown
tm cd 90 s # units: s/sec/seconds, m/min/minutes, h/hr/hours
tm cd 5 # unit defaults to minutes
tm cd 1 h -i # full-screen TUI
Keys: space pause/resume · q quit. The display turns yellow under 30 seconds and red under 10; when time is up you get a terminal bell and a toast.
Development
Requires Bun >= 1.3.14.
bun install # install dependencies
bun run dev sw # run from source
bun test # tests
bunx tsc --noEmit # typecheck
Building distribution artifacts:
bun install --os="*" --cpu="*" # stage native packages for every platform (one-time)
make build # compile binaries for all 7 targets into dist/bin
make package # assemble npm packages (dist/npm) + release tarballs (dist/release)
Releasing
Everything publishes locally from this machine — no CI, no secrets on GitHub.
make bump(orTYPE=minor make bump), commit.make package— builds all binaries, npm packages, wheels, and release tarballs.make publish— rehearsal: npm--dry-run+ TestPyPI.PROD=TRUE make publish— the real thing: npm packages, PyPI wheels, and a GitHub releasev<version>with the binaries (which the curl installer downloads).
Credentials: npm token in ~/.npmrc, PyPI tokens in .env (PYPI_PUBLISH_TOKEN, TEST_PYPI_PUBLISH_TOKEN), and an authenticated gh CLI for the release upload.
History
This project was originally written in Python with Textual and published to PyPI as time-manager (last Python release: 0.3.1; the implementation is preserved in git history). From 0.4.0 on, the PyPI package ships the same compiled binary as the npm package — pip install time-manager keeps working with no Python runtime involved.
License
MIT
Release files for time-manager 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| time_manager-0.5.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| time_manager-0.5.0-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| time_manager-0.5.0-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| time_manager-0.5.0-py3-none-manylinux_2_27_x86_64.whl | Python 3 | none | Linux glibc 2.27+ x86-64 | Details |
| time_manager-0.5.0-py3-none-manylinux_2_27_aarch64.whl | Python 3 | none | Linux glibc 2.27+ ARM64 | Details |
| time_manager-0.5.0-py3-none-macosx_12_0_x86_64.whl | Python 3 | none | macOS 12.0+ x86-64 | Details |
| time_manager-0.5.0-py3-none-macosx_12_0_arm64.whl | Python 3 | none | macOS 12.0+ ARM64 | Details |
Total release size: 258.2 MB
Release files / time_manager-0.5.0-py3-none-win_amd64.whl
| Download URL | time_manager-0.5.0-py3-none-win_amd64.whl |
|---|---|
| Size | 39.9 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
5910c5284ce7ccc231d2949e287cfc670cd48eef02a5bb7bb3abce770189237b
|
|
BLAKE2b-256 checksum How to use checksums |
6c5c450fc1dfb6898bbfc485affc7137a3b296891cdf18908feef3ccd264a7f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-musllinux_1_2_x86_64.whl
| Download URL | time_manager-0.5.0-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 42.6 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
9b9e98888d7c4580e8497f4bb2b9045964cc918a0500db068869401b3dd47fdb
|
|
BLAKE2b-256 checksum How to use checksums |
fb8200faba60f984ead1af5fbb7c29f8d8d48a71a8af0c27df0663631e67feab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-musllinux_1_2_aarch64.whl
| Download URL | time_manager-0.5.0-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 42.1 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
6f50065640c1a8489c465d5771bc206ede4ff1e7d995d862fbdb5822c2f08292
|
|
BLAKE2b-256 checksum How to use checksums |
530436803c58ca906e0b59ab51f587820e500bc6be0d85b3abd12a635f2c1eaf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-manylinux_2_27_x86_64.whl
| Download URL | time_manager-0.5.0-py3-none-manylinux_2_27_x86_64.whl |
|---|---|
| Size | 40.3 MB |
| Tags | Linux glibc 2.27+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
7fb394f8181fb27ddc03745a7a258fefe889bfcbe81d4273a31dd89e7b5c8c09
|
|
BLAKE2b-256 checksum How to use checksums |
dd9d590dac888d371bf9cfde49e1ad5d0f3130e73176e2c51cbfb6c1d3c8e368
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-manylinux_2_27_aarch64.whl
| Download URL | time_manager-0.5.0-py3-none-manylinux_2_27_aarch64.whl |
|---|---|
| Size | 39.9 MB |
| Tags | Linux glibc 2.27+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
c8e6d7051e71a52be4760fc1ce4a76f634b9008c49f6fa84fc8e422d7fef3f80
|
|
BLAKE2b-256 checksum How to use checksums |
67817c154dd20103e37ee515fa2f74be6da1c723f5f5e89305235b2a5bf8b97f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-macosx_12_0_x86_64.whl
| Download URL | time_manager-0.5.0-py3-none-macosx_12_0_x86_64.whl |
|---|---|
| Size | 28.0 MB |
| Tags | Python 3 macOS 12.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
00bc47f5b67d09e65de75bb1225cfae51b274fe8673c03234b3a453b29441005
|
|
BLAKE2b-256 checksum How to use checksums |
8bbe6a68da1e966fb3224cea68acad8cbb53669bf4bec33f7c1fe2214db37c25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|
Release files / time_manager-0.5.0-py3-none-macosx_12_0_arm64.whl
| Download URL | time_manager-0.5.0-py3-none-macosx_12_0_arm64.whl |
|---|---|
| Size | 25.5 MB |
| Tags | Python 3 macOS 12.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
811d87f7b10d50ebb1c9f9ed9a94be7a9c1d34f2c81768285d98d3692d865514
|
|
BLAKE2b-256 checksum How to use checksums |
6173373674ecc9a70f333bafe16608447f42077eb68339b4ad468c0ba2256d73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.17
|