CLI Overview


The hq command-line tool is the only interface that agents use to interact with the AI Agents HQ coordination system. Agents never read or write JSON files directly — they always go through hq. This ensures that all safety mechanisms (file locking, CAS versioning, idempotency) are consistently applied.

The CLI is organized into two command groups:

  • hq task — Manage tasks (create, list, claim, complete, fail, heartbeat)
  • hq inbox — Send and read inter-agent messages

All commands output JSON to stdout, making them easy to parse programmatically. Error messages go to stderr.

Task Commands


hq task create

Creates a new task and assigns it to a team and tool.

hq task create
hq task create --team <name> --tool <tool> --subject <text> [flags]
FlagDescription
--team Required. The team name. Tasks are organized into teams, and each team has its own task directory. Example: --team frontend
--tool Required. Which AI tool should handle this task. Must be one of: claude, gemini, codex. This tells the orchestrator which agent to spawn. Example: --tool claude
--subject Required. A short title for the task. This is what agents see when listing tasks. Keep it under 100 characters. Example: --subject "Add input validation to signup form"
--description Optional. A longer explanation of what needs to be done. Include enough detail for the agent to work independently. Example: --description "Validate email format, check password strength (min 8 chars), and sanitize username input."
--profile Optional. A tool-specific profile to use. For Codex, this selects from profiles like reviewer, security-auditor, quick-fix, etc. Example: --profile reviewer
--blockedBy Optional. Comma-separated list of task IDs that must complete before this task can be started. If provided, the task starts in blocked status instead of pending. Example: --blockedBy 1,2,3
--required-mcps Optional. Comma-separated list of MCP (Model Context Protocol) server names that the agent needs access to. Example: --required-mcps filesystem,github

Example:

terminal
$ hq task create --team backend --tool claude --subject "Refactor auth middleware" --description "Extract JWT validation into a separate package" --blockedBy 3
{"id":4,"status":"blocked","subject":"Refactor auth middleware"}
Auto-assigned ID

You do not need to specify a task ID. The system automatically scans existing tasks and assigns the next available number (max existing ID + 1).

hq task list

Lists tasks for a team with optional filtering.

hq task list
hq task list --team <name> [flags]
FlagDescription
--team Required. The team name to list tasks for. Example: --team backend
--tool Optional. Filter to only show tasks assigned to a specific tool. Example: --tool claude
--status Optional. Filter to only show tasks with a specific status. Valid values: pending, in_progress, completed, failed, blocked, escalated. Example: --status pending
--ready-only Optional. Boolean flag (no value needed). When set, only shows tasks that are both pending AND have no unresolved blockers — i.e., tasks that an agent can immediately claim. Example: --ready-only

Example:

terminal
# List all tasks
$ hq task list --team backend
[{"id":1,"status":"completed",...},{"id":2,"status":"in_progress",...},{"id":3,"status":"pending",...}]
# List only tasks ready to claim
$ hq task list --team backend --ready-only
[{"id":3,"status":"pending",...}]
# List only Claude's tasks
$ hq task list --team backend --tool claude
[{"id":1,"status":"completed",...},{"id":3,"status":"pending",...}]
Empty results

If no tasks match your filters, the output is an empty JSON array: []. If the team does not exist at all, the output is null.

hq task claim

Claims a pending task for an agent. This is how an agent says "I am going to work on this."

hq task claim
hq task claim --team <name> --task <id> --agent <name> --tool <tool> --protocol-version <int>
FlagDescription
--team Required. The team name. Example: --team backend
--task Required. The task ID to claim. Example: --task 3
--agent Required. The agent's name. This is how the system identifies who is working on the task. Example: --agent claude-session-42
--tool Required. The tool the agent is running on. Must match the task's assigned tool. Example: --tool claude
--protocol-version Required. The protocol version the agent is running. Must match the system's current version (2). If it does not match, the command fails with exit code 12.

What happens when you claim:

  1. The system checks that the protocol version matches
  2. The system loads the task and acquires a file lock
  3. The system verifies the task is claimable:
  • Status must be pending (fresh task) or failed (retry attempt)
  • If the task is in_progress, it can only be claimed if the lease has expired (crash recovery)
  • The tool must match
  • The task must have no unresolved blockers
  1. The system sets status to in_progress, owner to the agent name, and sets a 30-minute lease
  2. The version number is incremented

Example:

terminal
$ hq task claim --team backend --task 3 --agent worker-1 --tool claude --protocol-version 2
{"id":3,"status":"in_progress","owner":"worker-1","leaseOwner":"worker-1","version":2}
Claim failures

If the claim fails, check the exit code:

  • Exit 10 (CAS conflict): Another agent already claimed it. Pick a different task.
  • Exit 11 (Stale lease): The task's lease check failed. This should not normally happen.
  • Exit 12 (Protocol mismatch): Your protocol version is outdated. Restart the agent.
  • Exit 13 (Validation error): The task is not claimable (wrong status, tool mismatch, or has blockers).

hq task complete

Marks a task as completed. This is how an agent says "I finished the work."

hq task complete
hq task complete --team <name> --task <id> --agent <name> --summary <text> --protocol-version <int> --idempotency-key <key> [--notify <agent>]
FlagDescription
--team Required. The team name. Example: --team backend
--task Required. The task ID to complete. Example: --task 3
--agent Required. The agent's name. Must match the current lease holder. Example: --agent worker-1
--summary Required. A description of what was accomplished. This is stored in the task's summary field (the original description is preserved unchanged). Example: --summary "Extracted JWT validation into pkg/auth/jwt.go with full test coverage."
--protocol-version Required. Must match the current protocol version (2).
--idempotency-key Required. A unique key to prevent duplicate completions. Use the format: {task_id}-{agent_name}-complete. Example: --idempotency-key "3-worker-1-complete"
--notify Optional. Agent name to notify via inbox on completion. Sends a task_completed event with the task ID and summary as payload. Best-effort — warns on failure but does not fail the completion. Example: --notify team-lead

What happens when you complete:

  1. Idempotency check — if this key was already used, return success immediately (no-op)
  2. Protocol version check
  3. Load task with file lock
  4. Verify the agent holds the current lease
  5. Set status to completed, store the summary in the summary field (description is preserved), clear the lease
  6. Increment version
  7. Auto-unblock (best-effort): Scan all tasks in the team. For any task that has this task's ID in its blockedBy list, remove it. If a task's blockedBy becomes empty, change its status from blocked to pending. If auto-unblock fails, a warning is logged to stderr but the completion still succeeds.
  8. Notify (optional): If --notify was provided, send a task_completed inbox event to the specified agent. Best-effort — warns on failure.

Example:

terminal
$ hq task complete --team backend --task 3 --agent worker-1 --summary "Refactored auth middleware. All tests pass." --protocol-version 2 --idempotency-key "3-worker-1-complete"
{"id":3,"status":"completed","version":3}

hq task fail

Reports that an agent could not complete a task.

hq task fail
hq task fail --team <name> --task <id> --agent <name> --reason <text> --protocol-version <int>
FlagDescription
--team Required. The team name.
--task Required. The task ID.
--agent Required. The agent's name.
--reason Required. Why the task failed. Example: --reason "Dependency package not available in the project"
--protocol-version Required. Must match current protocol version (2).

What happens when you fail:

  1. Protocol version check
  2. Load task with file lock
  3. Set status to failed, stateReason to agent_error, store the reason text in the failureDetail field (description is preserved)
  4. Clear the lease (so another agent can retry)
  5. Increment failureCount
  6. Auto-escalate: If failureCount reaches 3, set status to escalated and stateReason to human_escalation

Example:

terminal
# First failure
$ hq task fail --team backend --task 3 --agent worker-1 --reason "Cannot find required module" --protocol-version 2
{"id":3,"status":"failed","failureCount":1}
# After 3 failures, auto-escalates
$ hq task fail --team backend --task 3 --agent worker-3 --reason "Still cannot resolve dependency" --protocol-version 2
{"id":3,"status":"escalated","failureCount":3,"stateReason":"human_escalation"}

hq task heartbeat

Extends the lease on a task. Agents should send this every 10 minutes for long-running tasks.

hq task heartbeat
hq task heartbeat --team <name> --task <id> --agent <name>
FlagDescription
--team Required. The team name.
--task Required. The task ID.
--agent Required. The agent's name. Must match the current lease holder.

Example:

terminal
$ hq task heartbeat --team backend --task 3 --agent worker-1
{"id":3,"leaseOwner":"worker-1","leaseUntil":1739886600000}

The leaseUntil value is a Unix timestamp in milliseconds, set to 30 minutes from now.

Inbox Commands


hq inbox send

Sends a message to another agent's inbox.

hq inbox send
hq inbox send --team <name> --to <agent> --from <agent> --type <type> --payload <json> --protocol-version <int> --idempotency-key <key>
FlagDescription
--team Required. The team name.
--to Required. The recipient agent's name. The message is delivered to this agent's inbox.
--from Required. The sender agent's name.
--type Required. The event type. Must be one of: task_completed, review_approved, research_findings, error_report, ad_hoc_request.
--payload Required. A JSON string containing the message data. Must be valid JSON. Example: --payload '{"taskId":3,"summary":"Done"}'
--protocol-version Required. Must match current protocol version (2).
--idempotency-key Required. Unique key to prevent duplicate messages. Format: {task_id}-{agent_name}-{action}. Example: --idempotency-key "3-worker-1-report"

Example:

terminal
$ hq inbox send --team backend --to lead --from worker-1 --type task_completed --protocol-version 2 --idempotency-key "3-worker-1-report" --payload '{"taskId":3,"summary":"Auth middleware refactored."}'
{"event_id":1,"type":"task_completed","from":"worker-1","to":"lead"}

hq inbox read

Reads messages from an agent's inbox.

hq inbox read
hq inbox read --team <name> --agent <name> [--since-event <id>]
FlagDescription
--team Required. The team name.
--agent Required. The agent whose inbox to read.
--since-event Optional. Only return events with an event ID greater than this value. Used for polling — an agent remembers the last event ID it processed and only asks for newer events. Example: --since-event 5

Example:

terminal
# Read all messages
$ hq inbox read --team backend --agent lead
[{"event_id":1,...},{"event_id":2,...},{"event_id":3,...}]
# Read only new messages since event 2
$ hq inbox read --team backend --agent lead --since-event 2
[{"event_id":3,...}]
# Empty inbox
$ hq inbox read --team backend --agent new-agent
[]

Exit Codes


Every hq command returns a numeric exit code that indicates what happened. Agents can use these codes to decide what to do next without parsing error messages.

Code
Name
Meaning
What to Do
0
Success
The operation completed successfully
Continue with next step
10
CAS Conflict
Another agent modified the task between your read and write
Re-read the task and retry (or pick a different task)
11
Stale Lease
The lease check failed
The agent's lease expired; re-claim the task
12
Protocol Mismatch
The agent's protocol version does not match the system's
Restart the agent with updated code
13
Validation Error
Invalid input (wrong status, tool mismatch, missing fields, has blockers)
Check the error message on stderr and fix the input
14
Permission Denied
File permission violation (wrong mode on ~/.hq files)
Check that ~/.hq directories are 0700 and files are 0600
Exit codes in scripts

In bash, you can check the exit code with $? after running any hq command. A return of 0 means success, while 10 means CAS conflict (someone else already claimed it).

terminal
$ hq task claim --team demo --task 1 --agent worker --tool claude --protocol-version 2
$ echo $?
0
# 0 means success
$ hq task claim --team demo --task 1 --agent other --tool claude --protocol-version 2
$ echo $?
10
# 10 means CAS conflict — someone else already claimed it