qqq-cli 0.10.0

Local-first task queue for coding agent sessions
qqq-cli-0.10.0 is not a library.

qqq

Give your coding agents a shared queue.

You write the tasks. Agents claim the next ready one, report progress, and mark it done. qqq keeps the queue in your project, with a terminal dashboard for the work you want to inspect or change yourself.

qqq terminal dashboard showing a task tree, task details, and editor

Get started · Agent setup · Docs

Why a queue?

  • Multiple agents, clear ownership. Workers sharing the same local project claim separate tasks.
  • Dependencies that mean something. “Build the client” waits until “Build the API” is complete. Priorities choose which ready task comes next.
  • Context that survives a session. Descriptions, updates, screenshots, and history stay with the task when you return, retry, or hand off work.

SQLite stores tasks in .qqq/qqq.db; images live in .qqq/images/. No server or account needed. Your agent runs the code and checks; qqq tracks the work.

Install

cargo install qqq-cli --locked

Requires Rust 1.89+ and a C compiler. The command is qqq. Install from source for development features.

Try it

Start in an empty directory so the example task IDs match:

mkdir qqq-demo
cd qqq-demo
qqq init

qqq add "Build API"
qqq add "Build client" --parent 1
qqq list
ID     STATUS        PRI TASK
1      New             0 Build API
2      New             0 └── Build client

Claim the API task. Once your work is done, record an update and complete it:

qqq next --session agent-1
# Do the work, then:
qqq message 1 "API ready" --session agent-1
qqq edit 1 --complete --session agent-1
qqq next --session agent-1

The last command claims Build client. Completing its parent made it ready. Repeated next calls return your active task until you complete or release it. If no task is available, next exits with status 1 and prints the pickup message (or null with JSON output). This also applies to --dry-run; --wait keeps waiting instead. --explain remains a successful diagnostic, even for an empty queue.

For your own project, run qqq init at its root and use the IDs returned by add. Commands also work from subdirectories. Add .qqq/ to your .gitignore.

Recognized agent callers get JSON by default: native Codex sessions (CODEX_THREAD_ID or CODEX_SESSION_ID) and exact Herdr panes reporting an agent. Use global --human for readable text, or --json to request JSON explicitly. Ordinary shells keep readable output, including when piped. Help and version output stay text.

See and edit the work

Pipe multiline descriptions with qqq add --stdin, or load a complete plan with qqq import plan.json --dry-run followed by qqq import plan.json. Independent prerequisites can gate integration work while keeping its tree parent: qqq add "Integrate API and UI" --parent 1 --depends-on 2 --depends-on 3. Manage extras with edit's --depends-on, --remove-depends-on, and --clear-depends-on; all prerequisites must complete before a new claim.

Add tags with qqq add "Fix layout" --tag frontend --tag bug; lists show [frontend] [bug] Fix layout. Replace via qqq edit 1 --set-tags "frontend, bug", clear via --set-tags "", or edit selected task tags with Ctrl-L in TUI. On a new draft, Ctrl-L stages tags before Ctrl-S creates the task. Workers see the description and tags together when the task enters the queue. In the tag editor, Enter adds a line, Ctrl-S applies tags, Ctrl-U deletes the current line, and Esc/Ctrl-C cancels. Type a tag prefix to suggest existing project tags; Up/Down selects a suggestion and Tab completes the label at the caret. Custom tags remain available.

See batch schema and piping examples.

Preview changes to several saved tasks with qqq bulk --tag backend --add-tag review --priority 5 --json > preview.json, then confirm with qqq bulk --apply preview.json. Preview freezes exact IDs; stale changes reject whole batch. See bulk actions for selectors, tags, archive and conflict handling.

Reuse workflows with qqq add --template bug --var component=auth --dry-run. Project-local .qqq-recipes/*.json files declare parameters and one or more tasks; applying a recipe creates its whole dependency graph atomically. See recipe format and examples.

Inspect readiness, owners and blockers with qqq status. Preview selection reasons with qqq next --explain; neither command claims work. Both support --json. See queue diagnostics for filters and owner context.

qqq tui

Browse the tree, read task details, and edit descriptions in one window. Click a task to load it, scroll each pane, or use the keyboard:

Key Action
Shift+Up / Shift+Down Move between tasks and a blank draft
Ctrl+S Save
Ctrl+Z / Ctrl+Y Undo / redo description edits; keep history after save
Ctrl+D Toggle task in bulk selection; + marks selected rows
Ctrl+L Edit task or new draft tags; retain unsaved drafts
Ctrl+K Go to task ID; retain unsaved drafts
Ctrl+B Pick saved project view; retain editor and parked drafts
Ctrl+P Create child of selected task; in child draft, insert parent #ID
Ctrl+/ Filter tasks
Ctrl+G Open bulk actions when tasks marked, otherwise task actions
Ctrl+H Create a Herdr queue worker for a saved New task; otherwise open its linked agent
Esc Close the filter, clear the editor, then exit; changed drafts ask before discard
Ctrl+C Clear nonempty New Task; press again to exit when empty

The Ctrl+H creation dialog starts with an editable queue-worker prompt. Enter adds a line, Ctrl+S creates the agent, and Escape cancels. Its workspace uses the directory containing .qqq, even when the TUI runs from a subdirectory.

Ctrl+G menu includes e Mark error. Enter reason, confirm with y; marking error requires ownership of an in-progress task. Menu groups status actions, settings (Priority, Set parent), and archive visibility, with an empty line between groups. Arrows skip empty rows; short terminals keep selected action visible while scrolling menu.

Task details and qqq show display assignment in two aligned rows: Harness: session (name) and Orchestrator: session (name).

qqq add opens the built-in editor too. Prefer Vim or another editor? Set EDITOR and use qqq add --edit.

Give your agent the queue

Give each worker a unique, stable session ID, replacing agent-1 for each worker. To keep working as new tasks arrive, start with this /goal prompt:

/goal Use `qqq next --wait` to pick up the next task and work on it. Complete
each task after its checks pass, then get the next one. Loop indefinitely.
Keep the blocking wait running; don't wake up repeatedly to poll status.

--wait blocks until work is ready. --json returns full task data for the agent. A restarted worker using the same session gets its current task back; claims do not expire. Return or retry work when a worker gets stuck.

Native Codex session discovery can supply identity automatically. Optional Herdr integration links live agents and lets Ctrl+H create a queue worker from a saved New task. next always claims for its caller.

Route specialist workers by stored tags:

qqq next --wait --tag frontend --tag bug
qqq list --tag "UI review" --filter 'has_tag("frontend") and priority >= 5'

Repeated tags require every exact label; case and Unicode stay distinct. Existing owned tasks return even after selectors change. See tag matching and filter examples.

Save shared CLI/TUI selectors as project views:

qqq view save "Ready frontend" --tag frontend --readiness ready --max-completed 0
qqq list --view "Ready frontend"
qqq next --view "Ready frontend" --wait --json
qqq tui --view "Ready frontend"

Additional selectors combine with saved criteria using AND. Ctrl-B switches views without losing unsaved drafts. Commit .qqq-views.json to share definitions. See named views, visibility overrides and picker.

Keep going

MIT license.