- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .gitignore | ||
| .markdownlint.yaml | ||
| .pre-commit-config.yaml | ||
| mortality | ||
| README.md | ||
| ROADMAP.md | ||
mortality
Periodic task timer for the terminally impatient. Pure POSIX sh, zero dependencies.
Features
- Two calling conventions — single task or batch from file / FIFO
- Periodic reminders — frequency increases exponentially as time runs low
- Post-timer prompt — mark done or extend by N minutes
- Batch mode — process tasks sequentially, no prompts, auto-breaks between
- FIFO streaming — feed tasks via named pipe, keeps running for more
- SIGINT handling — prompt to exit or resume on Ctrl+C
- Portable — runs on any system with
/bin/sh(Linux, macOS, BSD)
Requirements
A POSIX-compliant /bin/sh shell. That's it. No bc, perl, Python, or
other dependencies. Uses only shell builtins, sleep, date, and printf.
Installation
Drop the mortality script somewhere on your PATH and make it executable:
chmod +x mortality
cp mortality ~/.local/bin/
Or run it straight from the repo:
./mortality 30m "write documentation"
Usage
Single task
mortality <duration> <task description>
| Argument | Description | Example |
|---|---|---|
duration |
A number followed by m (minutes), h (hours), or s (seconds) |
30m, 1h, 45s |
task description |
What you're timing | "review PR #42" |
mortality 25m "code review"
mortality 1h "write design doc"
mortality 90s "standup update"
Task list (batch mode)
mortality <task-list.txt>
The file must contain one task per line in the format:
<duration>,<task description>
Example tasks.txt:
25m,code review
10m,standup
45m,write documentation
15s,stretch break
Empty lines are ignored. Duration format is the same as CLI mode.
Batch mode behavior
Unlike interactive mode, batch mode skips all prompts:
- Tasks start immediately — no
ENTER to startprompt - Tasks auto-complete — no
Done? (y/n)prompt (cannot extend) - Between tasks a break is automatically injected based on the just-completed task's length:
| Completed task duration | Break |
|---|---|
< 30m |
60s pause, then next task (no timer) |
>= 30m && < 1h |
60s pause, then 5m break timer |
>= 1h && < 4h |
60s pause, then 15m break timer |
>= 4h && <= 8h |
60s pause, then 60m break timer |
The MORTALITY_COMPLETE_FORMAT notification fires before the pause, so you can
chain notifications into external systems before the break starts.
FIFO / streaming mode
Pass a named pipe (FIFO) instead of a regular file for continuous operation:
mkfifo tasks.fifo
mortality tasks.fifo
Then feed tasks from another terminal or script:
echo '30m,write report' > tasks.fifo
echo '15m,review findings' > tasks.fifo
Mortality reads one task at a time, runs it with batch-mode rules (auto-start, auto-complete, break injection), then blocks waiting for the next task on the FIFO. It stays running until killed (Ctrl+C prompts to exit).
Note: Validation (
validate_tasklist) is skipped for FIFOs since the input stream never ends. Malformed lines will still be caught byparse_durationand cause an exit.
Interactive session
- Press ENTER to start the timer
- Timer runs silently — periodic reminders print time remaining:
- Every 60s during the last 5 minutes
- Doubles for each 10-minute chunk before that (2 min at 5-15m, 4 min at 15-25m, 8 min at 25-35m, ...)
- Time's up! — terminal bell rings
- Prompt:
Done? (y/n)y/Y— "Good job." and exits / moves to next taskn/N— asks "How many more minutes?" (default 5) and resumes timer
- Repeat from step 2 until done
Signal handling
Press Ctrl+C during any prompt or the countdown:
Interrupted. Exit? (y/n)
y/Y— exits cleanlyn/N— resumes the timer or re-prompts
External notifications
Set MORTALITY_PROMPT_CMD to a command that reads a line from stdin.
Each reminder message is piped to it in addition to stdout.
export MORTALITY_PROMPT_CMD='9p -a 10.24.10.22:564 write /message'
mortality 30m "deploy to production"
This lets you forward reminders to a notification system, pager, LED
display, or whatever $MORTALITY_PROMPT_CMD can reach.
Format strings
All notification messages are configurable via printf-compatible format strings. Available arguments depend on the message type.
MORTALITY_START_FORMAT — start message (default: Start Task:\n%s\nTimebox: %02d:%02d:%02d\n)
%s— task description%02d— hours, minutes, seconds
MORTALITY_UPDATE_FORMAT — periodic reminder (default: ... you have %02d:%02d:%02d left ...)
%02d— hours, minutes, seconds
MORTALITY_COMPLETE_FORMAT — task done message (default: Good job.)
%s— task description
MORTALITY_END_FORMAT — end message (default: Task Complete: %s)
%s— task description
Development
pre-commit install # install git hooks
pre-commit run --all # run all checks
Checks: shellcheck, shfmt (POSIX dialect), trailing whitespace, YAML lint, markdownlint.
Project status
Active development. See ROADMAP.md for planned phases and issues for current work.