OpenClaw's persistent task database. Coordinate sub-agents, checkpoint progress, survive session boundaries.
HZL (https://github.com/tmchow/hzl) is a local-first task ledger (database-backed, optionally cloud-synced for backup) that an agent can use to:
This skill teaches an agent how to use the `hzl` CLI.
**OpenClaw has NO native task tracking tools.** Unlike Claude Code (which has TodoWrite) or Codex (which has update_plan), OpenClaw relies on memory and markdown files for tracking work. This makes HZL especially valuable for OpenClaw.
**Use HZL by default for any non-trivial task tracking:**
Multi-session or multi-agent work are common reasons to use HZL, not requirements.
Use HZL for single-session, single-agent work when the task is non-trivial.
**Why HZL is the right choice for OpenClaw:**
Without HZL, OpenClaw tracks tasks in-context (burns space, fragments during compaction) or in markdown files (requires manual management, no nesting/dependencies, no dashboard). HZL provides:
**Only skip HZL for:**
**Rule of thumb:** If you feel tempted to make a multi-step plan or there is any chance you will not finish in this session, use HZL.
Example: "Investigate failing tests and fix root cause" -> use HZL because it likely involves multiple subtasks, even if you expect to finish within a session.
Personal tasks: HZL is not a polished human to-do app, but it is usable for personal task tracking, and it can also serve as a backend for a lightweight UI.
Use a single `openclaw` project. Requests and initiatives become **parent tasks**, not new projects.
**Wrong (creates sprawl):**
```bash
hzl project create "garage-sensors"
hzl project create "query-perf"
```
**Correct (single project, parent tasks):**
```bash
hzl project list
hzl task add "Install garage sensors" -P openclaw
hzl task add "Wire sensor to hub" --parent abc123
hzl task add "Configure alerts" --parent abc123
```
Why this matters:
HZL supports one level of nesting (parent → subtasks). Scope parent tasks to completable outcomes.
**The completability test:** "I finished [parent task]" should describe a real outcome.
**Scope by problem, not technical layer.** A full-stack feature (frontend + backend + tests) is usually one parent if it ships together.
**Split into multiple parents when:**
**Adding context:** Use `-d` for details, `-l` for reference docs:
```bash
hzl task add "Install garage sensors" -P openclaw \
-d "Per linked spec. Mount sensors at 7ft height." \
-l docs/sensor-spec.md,https://example.com/wiring-guide
```
**Don't duplicate specs into descriptions**—this creates drift. Reference docs instead.
**If no docs exist**, include enough detail for another agent to complete the task:
```bash
hzl task add "Configure motion alerts" -P openclaw -d "$(cat <<'EOF'
Trigger alert when motion detected between 10pm-6am.
Use Home Assistant automation. Notify via Pushover.
EOF
)"
```
Description supports markdown (16KB max).
The following commands **PERMANENTLY DELETE HZL DATA** and cannot be undone:
| Command | Effect |
|---------|--------|
| `hzl init --force` | **DELETES ALL DATA.** Prompts for confirmation. |
| `hzl init --force --yes` | **DELETES ALL DATA WITHOUT CONFIRMATION.** Extremely dangerous. |
| `hzl task prune ... --yes` | **PERMANENTLY DELETES** old done/archived tasks and their event history. |
**AI agents: NEVER run these commands unless the user EXPLICITLY asks you to delete data.**
**Setup:**
```bash
hzl project list # Always check first
hzl project create openclaw # Only if needed
```
**Adding work:**
```bash
hzl task add "Feature X" -P openclaw -s ready # Ready to claim
hzl task add "Subtask A" --parent <id> # Subtask
hzl task add "Subtask B" --parent <id> --depends-on <subtask-a-id> # With dependency
```
**Working on a task:**
```bash
hzl task next -P openclaw # Next available task
hzl task next --parent <id> # Next subtask of parent
hzl task next -P openclaw --claim # Find and claim in one step
hzl task claim <id> # Claim specific task
hzl task checkpoint <id> "milestone X" # Notable progress or before pausing
```
**Changing status:**
```bash
hzl task set-status <id> ready # Make claimable (from backlog)
hzl task set-status <id> backlog # Move back to planning
```
Statuses: `backlog` → `ready` → `in_progress` → `done` (or `blocked`)
**When blocked:**
```bash
hzl task block <id> --comment "Waiting for API keys from DevOps"
hzl task unblock <id> # When resolved
```
**Finishing work:**
```bash
hzl task comment <id> "Implemented X, tested Y" # Optional: final notes
hzl task complete <id>
hzl task show <parent-id> --json # Any subtasks left?
hzl task complete <parent-id> # If all done, complete parent
```
**Troubleshooting:**
| Error | Fix |
|-------|-----|
| "not claimable (status: backlog)" | `hzl task set-status <id> ready` |
| "Cannot complete: status is X" | Claim first: `hzl task claim <id>` |
---
```bash
hzl init # Initialize (safe, won't overwrite)
hzl init --reset-config # Reset config to default location
hzl status # Database mode, paths, sync state
hzl doctor # Health check for debugging
hzl task add "<title>" -P openclaw --priority 2 --tags backend,auth
hzl task add "<title>" -P openclaw --depends-on <other-id>
hzl task add "<title>" -P openclaw -s in_progress --assignee <name> # Create and claim
hzl task list -P openclaw --available # Ready tasks with met dependencies
hzl task list --parent <id> # Subtasks of a parent
hzl task list --root # Top-level tasks only
hzl task add-dep <task-id> <depends-on-id>
hzl validate # Check for circular dependencies
hzl serve # Start on port 3456 (network accessible)
hzl serve --host 127.0.0.1 # Restrict to localhost only
hzl serve --background # Fork to background
hzl serve --status # Check if running
hzl serve --stop # Stop background server
hzl task claim <id> --assignee <agent-id> --lease 30
hzl task stuck
hzl task steal <id> --if-expired --author <agent-id>
```
Tip: When a tool needs to parse output, prefer `--json`.
HZL tracks authorship at two levels:
| Concept | What it tracks | Set by |
|---------|----------------|--------|
| **Assignee** | Who owns the task | `--assignee` on `claim` or `add` |
| **Event author** | Who performed an action | `--author` on other commands |
The `--assignee` flag on `claim` and `add` (with `-s in_progress`) sets task ownership. The `--author` flag on other commands (checkpoint, comment, block, etc.) records who performed each action:
```bash
hzl task claim 1 --assignee alice
hzl task checkpoint 1 "Reviewed the code" --author bob
```
For AI agents that need session tracking, use `--agent-id` on claim:
```bash
hzl task claim 1 --assignee "Claude Code" --agent-id "session-abc123"
```
1) Create (or reuse) a stable project name.
2) Decompose into tasks.
3) Use dependencies to encode sequencing, not just priority.
4) Validate.
```bash
hzl project create myapp-auth
hzl task add "Clarify requirements + acceptance criteria" -P myapp-auth --priority 5
hzl task add "Design API + data model" -P myapp-auth --priority 4 --depends-on <reqs-id>
hzl task add "Implement endpoints" -P myapp-auth --priority 3 --depends-on <design-id>
hzl task add "Write tests" -P myapp-auth --priority 2 --depends-on <impl-id>
hzl task add "Docs + rollout plan" -P myapp-auth --priority 1 --depends-on <tests-id>
hzl validate
```
Checkpoint at notable milestones or before pausing work. A checkpoint should be short and operational:
```bash
hzl task claim <id> --assignee orchestrator
hzl task checkpoint <id> "Implemented login flow. Next: add token refresh." --progress 50
hzl task checkpoint <id> "Added token refresh. Testing complete." --progress 100
hzl task complete <id>
```
You can also set progress without a checkpoint:
```bash
hzl task progress <id> 75
```
When stuck on external dependencies, mark the task as blocked:
```bash
hzl task claim <id> --assignee orchestrator
hzl task checkpoint <id> "Implemented login flow. Blocked: need API key for staging."
hzl task block <id> --comment "Blocked: waiting for staging API key from DevOps"
hzl task unblock <id> --comment "Unblocked: received API key from DevOps"
hzl task checkpoint <id> "Got API key, resuming work"
hzl task complete <id>
```
**Comment best practices:** Include context about the action, not just the state:
Blocked tasks stay visible in the dashboard (Blocked column) and keep their assignee, but don't appear in `--available` lists.
Use leases when delegating, so you can detect abandoned work and recover.
```bash
hzl task add "Implement REST endpoints" -P myapp-auth --priority 3 --json
hzl task claim <id> --assignee subagent-claude-code --lease 30
```
Delegate with explicit instructions:
Monitor:
```bash
hzl task show <id> --json
hzl task stuck
hzl task steal <id> --if-expired --author orchestrator
```
Use parent/subtask hierarchy to organize complex work:
```bash
hzl task add "Implement vacation booking" -P portland-trip --priority 2
hzl task add "Research flights" --parent abc123
hzl task add "Book hotel" --parent abc123 --depends-on <flights-id>
hzl task add "Plan activities" --parent abc123
hzl task show abc123
hzl task next --parent abc123
```
**Important:** `hzl task next` only returns leaf tasks (tasks without children). Parent tasks are organizational containers—they are never returned as "next available work."
**Finishing subtasks:** After completing each subtask, check if the parent has remaining work:
```bash
hzl task complete <subtask-id>
hzl task show abc123 --json # Any subtasks left?
hzl task complete abc123 # If all done, complete parent
```
HZL includes a built-in Kanban dashboard for monitoring task state. The dashboard shows tasks in columns (Backlog → Blocked → Ready → In Progress → Done), with filtering by date and project.
For always-on access on your OpenClaw box, set up as a systemd service (Linux only):
```bash
mkdir -p ~/.config/systemd/user
hzl serve --print-systemd > ~/.config/systemd/user/hzl-web.service
systemctl --user daemon-reload
systemctl --user enable --now hzl-web
loginctl enable-linger $USER
systemctl --user status hzl-web
```
The dashboard will be available at `http://<your-box>:3456` (accessible over Tailscale).
To use a different port:
```bash
hzl serve --port 8080 --print-systemd > ~/.config/systemd/user/hzl-web.service
```
**macOS note:** systemd is Linux-only. On macOS, use `hzl serve --background` or create a launchd plist manually.
```bash
hzl serve # Start in foreground (port 3456)
hzl serve --background # Fork to background process
hzl serve --status # Check if background server is running
hzl serve --stop # Stop background server
hzl serve --host 127.0.0.1 # Restrict to localhost only
```
Use `--background` for temporary sessions. Use systemd for always-on access.
1. **Always use `--json`** for programmatic output
2. **Checkpoint at milestones** or before pausing work
3. **Check for comments** before completing tasks
4. **Use a single `openclaw` project** for all work
5. **Use dependencies** to express sequencing, not priority
6. **Use leases** for long-running work to enable stuck detection
7. **Review checkpoints** before stealing stuck tasks
HZL is deliberately limited:
These are features for your orchestration layer, not for the task tracker.
Leave a review
No reviews yet. Be the first to review this skill!