What is Workwarrior anyways?
Once you start ‘hacking’ a tool together it’s easy to forget its origins. How did this thing really get started? Are my original intentions holding or have things evolved into something entirely different?
In my case, the project had no name or real definition for the longest time. The quest wasn’t at all about computers at its core, it was about the long-term challenge to stay organized in each dimension of business. I think this intention for ‘easy organization’ did hold at each step, and it’s why Workwarrior is now a strong set of tools capable of scaling to thousands of users.
After a few years of business ownership, I was feeling overwhelmed by a dozen or more business apps that were soaking up my time. I had gotten used to having attention divided across tools and devices but the whole work flow was starting to not make sense anymore. Poor Return on Time. I was also nearing 40 and feeling the strong urge to get back to the command line and get back in control of my computer. A season of learning Linux had begun, so I created a playful constraint and decided that I could only look for software solutions in the terminal.
As I pursued a better toolbox for business, I started out with an upside down goal: how to use the computer in very advanced and professional ways for the least amount of time per week possible? How to make the tool set so tight that it helps gradually increase our time away from the computer while increasing its benefits? In plain terms, how do I get back to doing what I do? How to harness the computer for manual business administration, record keeping, communications and product development so I can develop and master my crafts and talents that exist away from the desk and away from the ‘desktop’?
I had a faint hunch that the tools talk together better within the terminal. So I created a simple criteria for inclusion: is the tool absolutely necessary to running a business, or say a family, or any activity for that matter? The genesis of a new rule: what is the minimal set of functions needed to run a business or project? The unnamed project’s first rule: functions are indivisible timeless human activities.
Therefore, the functions I was hunting for and battling to define must be hidden in plain sight as plain names not technological ones. The clay for the jars that will hold the tecnology would be found within human terminology not industry jargon.
For business leadership, defined as “repsonsibility for all operations and outcomes”, the minimal set of indivisible functions seemed to be: exchange or money tracking, work tracking, time logging, work journals, and list making
The task became simpler: match potential tools with these universal functions.
For accounting there’s ledger, hledger and beancount. I studied the ins and outs of each before landing on hledger. Ledger the original “plain text accounting” tool and beancount have things only they do well and need to be included any future product solution.
Next, I discovered JRNL for notes and just ran with it.
Taskwarrior and Timewarrior are clearly best at what they do. Before too long though things can get a bit blurry as you try to triage through screens and screens of tasks. Taskwarrior has great annotaiton functions but few devs are making routine use of them. It nailed down the essence of task tracking but to be more accessible it needed a few adjustments.
So I did what any [very novice] developer would do. Having discovered the magic of aliases I began manually editing my bashrc file as one giant config and orchestration file. By the time I was finished weaving together aliases and snippets of bash script, my bashrc file had over 1100 lines! Thankfully, I was still too green and excited about coding to see a problem with this approach. As with many Linux users, it was the first system file I ever edited so it served as a perfect scratchpad for sewing the tools together. Of course, what I had in practice was the equivalent of a hodge podge quilt whose patches were hanging on by threads. However, the common vocabulary and early commands that made the tools pull in the same direction was enough to glimpse a new horizon that I then charged full speed for.
I was starting to see opportunities to systematize the linkages between these tools by creating a “functions and extensions” architecture. The top 4-5 business tools that made the cut would be a core nucleus around a second ring of capabilities. After viewing all the quality Taskwarrior extensions developed by the developer community, and after experimenting with dozens of them, the opportunity to patch together an augmented family of functions anchored by hledger became plain to see.
As of Summer 2026, Workwarrior is a robust command line application with extreme depth. Via command ‘ww browser’ it’s also a very effective local browser application tool that routes all its main activity through the CLI that interacts with the core tools direclty. With these foundations in place, we used a simple ‘rofi’ solution to enable popups and overlays that give rich access to all functionality. With the popups the tool is ready to serve from the background where business leadership should be.
To read about Workwarrio’s technical design checkout the “Workwarrior Standard” repo where all project documetnation lives or visit workwarrior.org. Below is the readme from the tool’s repo located at babbworks/workwarrior. Send your feedback of any type to workwarrior@babb.tel.
Workwarrior README
Workwarrior wraps five open-source tools — TaskWarrior, TimeWarrior, JRNL, Hledger, and Bugwarrior — into a single profile-based productivity system. Each profile is an isolated workspace: its own tasks, time tracking, journals, double-entry ledgers, and configuration. Switch contexts instantly. Nothing bleeds between profiles.
The system runs from the terminal, from a locally-served browser UI, or both at once. A natural language command layer translates plain English into tool commands using 627 compiled heuristic rules before optionally falling back to a local LLM.
What is it?
Workwarrior is a profile-based productivity system for the terminal. It wraps TaskWarrior, TimeWarrior, JRNL, Hledger, and Bugwarrior into a single unified shell — each profile an isolated workspace with its own tasks, time tracking, journals, and double-entry ledgers. Switch contexts instantly. A browser UI, natural language command layer, and GitHub integration are built in.
The Problem
Productivity tools force you into one paradigm. Task managers don’t track time. Time trackers don’t do accounting. Journals live in a separate app. And none of them understand that you might have three completely different work contexts that should never touch each other. Power users who want the full stack end up wiring together five tools manually and re-doing it every time they switch machines or add a context.
How it Works
ww is a bash dispatcher that routes all commands to service scripts. p-work activates a profile by setting environment variables that all five tools read — no symlinks, no config switching. A 627-rule heuristic engine translates natural language input into tool commands without requiring AI. The browser UI (ww browser) serves a Python 3 HTTP server with 15+ panels, real-time SSE updates, and a unified command input.
Current Status
Active development. Profile system, browser UI, natural language engine, GitHub two-way sync, and UDA management all working. Weapons (Gun, Sword, Next, Schedule) operational. Questions, export, and group batch operations functional. Documentation covers full architecture and all service domains.
The Vision
A productivity operating system for people who live in the terminal — one that understands that tasks, time, money, and notes are not separate concerns but different views of the same working life. The long-term goal is a system that knows your projects, tracks their economics, and can answer questions like “what did I spend time on last month and what did it earn?”
Industry Context
TaskWarrior, TimeWarrior, JRNL, and Hledger each have dedicated user bases but are rarely used together. No existing tool provides profile isolation, unified commands, and a browser UI across all four. Workwarrior targets developers, consultants, and operators who manage multiple clients or contexts from the terminal and need their productivity stack to be as rigorous as their code.
p-work
task add "Ship the API" project:backend priority:H due:friday +release
j "Sprint 12 kicked off — targeting Friday for the API release"
timew start backend sprint
l balance
ww browser
Why Workwarrior Exists
Most productivity tools force you into one paradigm. Task managers don’t track time. Time trackers don’t do accounting. Journals live in a separate app. Ledgers live in another. And none of them understand that you might have three completely different work contexts that should never touch each other.
Workwarrior doesn’t replace these tools — it orchestrates them. TaskWarrior handles tasks. TimeWarrior tracks time. JRNL manages journals. Hledger does double-entry accounting. Each is best-in-class at what it does. Workwarrior adds the layer that makes them work together: profile isolation, unified commands, a browser UI, natural language input, and a growing set of services that connect everything.
The result is a system where p-work puts you in your work context with all five tools pointed at the right data, p-personal switches to your personal context, and ww browser gives you a visual dashboard over whichever profile is active — all without any of these tools knowing the others exist.
Profiles
A profile is a directory containing everything for one work context:
profiles/<name>/
.taskrc TaskWarrior config and UDAs
.task/ Task database + hooks
.timewarrior/ TimeWarrior database
journals/ JRNL journal files (multiple named journals supported)
ledgers/ Hledger ledger files (multiple named ledgers supported)
jrnl.yaml Journal name → file mapping
ledgers.yaml Ledger name → file mapping
Activating a profile sets environment variables that all tools read. No symlinks, no config switching, no path hacking. Just env vars:
ww profile create work # Create a new profile
p-work # Activate it — sets TASKRC, TASKDATA, TIMEWARRIORDB, etc.
task list # TaskWarrior sees only this profile's tasks
timew summary # TimeWarrior sees only this profile's time
j "Meeting notes" # Writes to this profile's journal
l balance # Shows this profile's ledger balances
Profiles support multiple named resources. A single profile can have journals called strategy, engineering, and personal, each mapping to a different file. Same for ledgers, and the infrastructure anticipates multiple task lists and time tracking instances per profile.
Profiles can be backed up, restored, imported from archives, grouped for batch operations, and removed cleanly with ww remove (which scrubs all references from config, state, aliases, and templates).
The Browser UI
ww browser launches a locally-served web interface — no cloud, no accounts, no external dependencies. Python 3 stdlib only.
The UI has a dark terminal aesthetic with a collapsible sidebar, 15+ panels, and a unified command input that accepts both direct ww commands and natural language:
- Tasks — full task list with inline editing, UDA display, start/stop/done buttons, add task form, annotation management
- Time — today’s total, weekly breakdown, recent intervals, start/stop controls
- Journals — entry list with expand/collapse, new entry form, multi-journal selector
- Ledgers — account balances, recent transactions, income statement, balance sheet, new transaction form
- CMD — unified command input with natural language translation and route indicator (⚡ AI or ⚙ heuristic)
- CTRL — AI mode toggle (off / local-only / local+remote), prompt settings, UI configuration
- Models — LLM provider and model registry
- Groups, Sync, Questions, Profile — and more
The server uses SSE for real-time updates and supports switching profiles and named resources from the browser.
ww browser # Start on port 7777 and open browser
ww browser --port 9090 # Custom port
ww browser stop # Stop the server
Natural Language Commands
The CMD service accepts plain English and translates it into tool commands. It tries 627 compiled heuristic regex rules first — no network, no latency, no LLM needed. If no rule matches, it optionally falls back to a local LLM (ollama) or a remote provider.
Inputs that work without AI:
"add a task to review the budget" → task add review the budget
"create task deploy server due friday" → task add deploy server due:friday
"start tracking time on code review" → timew start code review
"stop tracking" → timew stop
"show my profiles" → profile list
"finish task 5 and stop tracking" → task 5 done + timew stop
"add task fix login and annotate it with → task add fix login
check mobile layout" task annotate LAST check mobile layout
The heuristic engine covers all 19 command domains with 6 phrasing variations per command: passthrough, imperative, declarative, interrogative, shorthand, and verbose. Compound commands (joined by “and”, “then”, “also”, “plus”) are split and matched independently.
Rules are compiled by ww compile-heuristics, which scans all command sources, generates regex patterns, validates them against a synthetic corpus, resolves conflicts, fills coverage gaps, and writes the output. The engine is self-improving: every CMD submission is logged, and the --digest flag analyzes past AI translations to generate new rules.
ww compile-heuristics # Recompile rules
ww compile-heuristics --verbose # Show every rule with test results
ww compile-heuristics --digest # Include CMD log analysis
Weapons
Weapons are tools that manipulate profile data in special ways — creating, slicing, and packaging tasks.
| Weapon | What it does |
|---|---|
| Gun | Bulk task series generator with deadline spacing. Wraps taskgun. |
| Sword | Splits a task into N sequential subtasks with dependency chains and due date offsets. Native to ww. |
| Next | CFS-inspired scheduler that recommends the optimal next task based on urgency, deadlines, and context. |
| Schedule | Auto-scheduler that assigns time blocks to tasks. Wraps taskcheck. |
ww sword 5 -p 3 # Split task 5 into 3 sequential parts
ww sword 5 -p 4 --interval 2d # 2-day intervals between parts
ww gun <args> # Generate bulk task series
ww next # What should I work on?
ww schedule # Auto-schedule tasks
GitHub Integration
Two sync engines, complementary:
Bugwarrior (one-way pull) — pulls issues from GitHub, GitLab, Jira, Trello, and 20+ services into TaskWarrior. Configured per-profile.
ww github-sync (two-way) — links individual tasks to GitHub issues for bidirectional sync. Pushes task changes to GitHub, pulls GitHub changes to TaskWarrior. Handles field mapping, conflict resolution, annotation↔comment sync, and label encoding for UDA values.
i pull # Pull issues from configured services
i status # Show sync state
ww issues sync # Two-way sync all linked tasks
ww issues push # Push local changes to GitHub
ww issues enable <task> <issue#> <org/repo> # Link a task to an issue
ww issues custom # Configure services interactively
AI Integration
Optional. The system works fully without AI — the heuristic engine handles routine commands. AI adds flexibility for unusual phrasings and complex instructions.
# config/ai.yaml
mode: local-only # off | local-only | local+remote
preferred_provider: ollama
access_points:
cmd_ai: true # Enable AI in CMD service
Per-profile overrides via profiles/<name>/ai.yaml. Model fallback chains try multiple models before giving up. Controls available via CLI (ww ctrl ai-on/off/status) and browser CTRL panel.
ww model add-provider ollama ollama http://localhost:11434
ww model set-default llama3.2
ww ctrl ai-status # Show resolved AI state
UDA System
TaskWarrior’s User Defined Attributes are a first-class concept in Workwarrior. Profiles can carry 100+ UDAs covering project metadata, financial fields, compliance tracking, people, equipment, and more.
ww profile uda list # All UDAs with source badges
ww profile uda add goals # Interactive UDA creation
ww profile uda remove <name> # Remove with safety warnings
ww profile uda group work # Group UDAs for batch operations
ww profile uda perm goals nosync # Set sync permissions per-UDA
UDAs are classified by source: [github] for bugwarrior-injected fields, [extension] for tool-added fields, [custom] for user-defined. The browser UI renders all UDAs in the task inline editor.
Installation
Requires bash or zsh on macOS or Linux. Python 3 for the browser UI.
git clone <repo-url> ~/ww
cd ~/ww
./install.sh
source ~/.bashrc
The installer presents a version card for each tool showing installed, latest, and minimum required versions. On macOS it auto-installs via brew. On Linux it shows the right command for your distro.
ww deps install # Install/check core toolchain
ww deps check # Show dependency status
ww tui install # Install taskwarrior-tui (optional)
ww mcp install # Install MCP server for AI agents (optional)
Services
Everything in Workwarrior is a service. The ww dispatcher routes commands to service scripts in services/<category>/.
| Domain | What it does |
|---|---|
ww profile |
Create, list, info, delete, backup, import, restore, UDA management, urgency tuning, density scoring |
ww journal |
Add, list, remove, rename named journals |
ww ledger |
Add, list, remove, rename named ledgers |
ww group |
Profile groups for batch operations |
ww model |
LLM provider/model registry |
ww ctrl |
AI mode, prompt settings, UI configuration |
ww find |
Cross-profile search |
ww issues |
GitHub two-way sync + bugwarrior pull |
ww custom |
Interactive configuration wizards |
ww extensions |
TaskWarrior/TimeWarrior extension registry |
ww export |
Profile data export (JSON, CSV, markdown) |
ww questions |
Template-based capture workflows |
ww browser |
Locally-served web UI |
ww remove |
Profile removal with archive/delete/scrub |
ww shortcut |
Shortcut/alias reference |
ww deps |
Dependency management |
ww compile-heuristics |
Recompile NL→command rules |
Shell functions injected at init: task, timew, j, l, i, q, list, search, and p-<name> for each profile.
Project Structure
bin/
ww CLI dispatcher — all commands route here
ww-init.sh Shell bootstrap (sourced at shell start)
lib/ Core bash libraries
core-utils.sh Profile validation, path resolution
profile-manager.sh Profile lifecycle
shell-integration.sh Shell function injection, alias management
sync-*.sh, github-*.sh GitHub two-way sync engine (10 files)
dependency-installer.sh Platform-aware tool installer
... 20+ library files
services/ Service scripts
browser/ Browser UI (Python3 HTTP + SSE + static assets)
ctrl/ AI mode and settings
cmd/ Unified command service + JSONL logging
remove/ Profile removal
models/ LLM provider/model registry
questions/ Template-based workflows
custom/ Config wizards + GitHub sync
profile/ Profile lifecycle + UDA management
groups/, find/, export/, extensions/, ...
weapons/
gun/ Bulk task series (taskgun)
sword/ Task splitting with dependency chains
scripts/
compile-heuristics.py Heuristic rule compiler
config/
ai.yaml AI mode and access points
models.yaml LLM provider/model registry
ctrl.yaml CTRL service settings
groups.yaml Profile group definitions
shortcuts.yaml Shortcut definitions
profiles/ User profiles (created at runtime, gitignored)
Documentation
docs/overviews/INDEX.md— full technical overview with architecture, data flows, per-component docsdocs/usage-examples.md— practical workflows and CLI patternsdocs/INSTALL.md— detailed installation policy and platform notesdocs/search-guides/— search guides per tool (task, time, journal, ledger, list)docs/service-development.md— how to build and register new services
Testing
bats tests/ # Run all BATS test suites
bats tests/test-models-service.bats # Run a specific suite
python3 -m pytest services/browser/ # Browser and heuristic engine tests