A herdr plugin that runs lazytask — a modern, keyboard-driven terminal UI for task management — in a split pane beside your work, plus a few Taskwarrior quick actions. Press one key to open the pane, press it again to close it (or use a second key to open it in its own tab).
lazytask is built on TaskChampion, the same engine that powers Taskwarrior 3.x. It runs standalone — no task binary required — and keeps its own SQLite-backed replica.
Install and configure from any machine:
herdr plugin install mdetweil/herdr-lazytask
# or pin a released version:
herdr plugin install mdetweil/herdr-lazytask --ref v0.1.0
Requires herdr >= 0.7.0, the lazytask binary on PATH, and bash + python3. The Taskwarrior quick actions additionally need the task CLI.
Install lazytask itself (the pane won't open without it):
# any of these:
curl -L https://github.com/OsamaMahmood/lazytask/releases/latest/download/lazytask-x86_64-unknown-linux-gnu.tar.gz | tar xz && sudo mv lazytask /usr/local/bin/
# or: cargo install lazytaskAdd the launcher keybindings to your active herdr config.toml (~/.config/herdr/config.toml):
[[keys.command]] # lazytask: open in a split (toggle)
key = "prefix+a"
type = "plugin_action"
command = "herdr.lazytask.open"
[[keys.command]] # lazytask: open in its own tab
key = "prefix+shift+a"
type = "plugin_action"
command = "herdr.lazytask.open-tab"Run herdr server reload-config. prefix+a then behaves as: not open → open in a split; open but unfocused → focus; focused → close.
Why
a?prefix+g(goto) andprefix+shift+g(new worktree) are herdr defaults andprefix+tis commonly taken by other plugins.astands for a-tasks / add tasks. Rebind to any free key — see Keybindings.
Press prefix+a. A lazytask pane opens next to your current directory. Press it again and the pane closes; the launcher never opens a second copy. Press prefix+shift+a instead and lazytask opens in its own tab, where it stays even as you switch between work — it's your persistent task manager.
Inside lazytask everything is keyboard-driven — the full keymap is one F1 away. The essentials: a add, e edit, d done, / filter, r reports, s sync.
For quick task mutations without opening the TUI, the plugin ships Taskwarrior actions you can bind to keys (or run from herdr's command palette):
| Action | What it does |
|---|---|
add |
Open a popup and add a task |
done |
Pick a pending task and mark it complete |
start |
Pick a pending task and start it |
stop |
Pick a pending task and suspend it |
open-today |
Open the Today's Tasks dashboard in a split |
report (startup) |
Show pending/due-today/overdue counts on launch |
lazytask and the task CLI do not share data:
- The lazytask pane manages its own TaskChampion replica at
~/.local/share/lazytask/(config at~/.config/lazytask/config.toml). Tasks added in the pane live here. - The quick actions (
add/done/start/stop/today/report) call thetaskCLI and operate on your Taskwarrior data (~/.task/).
If you use both, you will see two different task lists. Pick one as your source of truth, or migrate your Taskwarrior tasks into the TaskChampion store and drop the task-based actions. (lazytask is storage-compatible with Taskwarrior 3.x replicas, so a one-time import/export is possible.)
Per-user plugin state lives in $HERDR_PLUGIN_CONFIG_DIR (falls back to ~/.config/herdr-lazytask):
panel.conf # optional overrides, shell-sourceable
-
RUNTIME_LAZYASK_BIN— absolute path to a specific lazytask binary. By default the launchers resolvelazytaskfromPATH:RUNTIME_LAZYASK_BIN=/opt/homebrew/bin/lazytask
-
HERDR_LAZYASK_BIN— same effect when exported in the environment; wins overpanel.conf.
The plugin owns exactly two actions: herdr.lazytask.open and herdr.lazytask.open-tab. Rebind them by editing the [[keys.command]] entries in your herdr config.toml and running herdr server reload-config. Pick keys that don't collide with herdr defaults (prefix+g, prefix+l, etc.) or your other plugins.
The lazygit-style launcher pattern, adapted for lazytask:
prefix+ainvokesscripts/open-lazytask.sh— an idempotent launcher scoped to the current tab: open if absent, focus if unfocused, close if focused. It identifies the pane by its manifest title ("Lazytask") plus a foreground-process check viaherdr pane process-info, and serializes concurrent invokes with a lock so double-keypresses can't create duplicate panes.prefix+shift+ainvokesscripts/open-lazytask-tab.sh— the same logic across the workspace's tabs: open in a new tab, switch to the existing tab, focus, or toggle off.- The pane runs
scripts/run-lazytask.sh, which resolves the binary andexecs lazytask. A missing binary surfaces as a readable error inside the pane instead of an instant, silent death.
herdr-plugin.toml # plugin manifest (panes, actions, startup hook)
scripts/
runtime-env.sh # resolve lazytask binary (PATH / RUNTIME_LAZYASK_BIN)
run-lazytask.sh # pane entrypoint: exec lazytask
open-lazytask.sh # action: open/focus/toggle in the current tab
open-lazytask-tab.sh # action: open/switch/toggle across tabs
src/ # Rust binary for the Taskwarrior quick actions
main.rs # CLI dispatch (add/done/start/stop/open-today/report)
today.rs # "Today's Tasks" dashboard
add.rs, pick.rs # popup UIs
tasks.rs # `task` CLI wrapper
term.rs, config.rs # terminal + config helpers
cargo build --release # build the quick-action binary
./target/release/herdr-lazytask --help
cargo clippy # lintsherdr plugin link does not run the manifest's [[build]] command, so build the binary before linking a local checkout. Trigger the launcher actions through herdr keybindings — an action's context always resolves from the pane that currently has UI focus.
- The lazytask pane and the Taskwarrior quick actions manage separate task stores (see above).
- lazytask sync settings are held in memory only (per lazytask's own docs); re-enter them each session.
- The launchers require
python3(used for JSON handling instead ofjq).
MIT — see LICENSE.