Hook, progress, and wait output
The JSON that agents receive. The pieces are explained in Agent integration. Task and epic fields are described in Shared files.
Progress table
agboard progress --json and the hook return the same table:
{
"fetchedAt": "2026-10-17T00:48:47Z",
"project": { "id": "ef18518d…", "name": "agent-board", "createdAt": "2026-10-10T22:59:43Z" },
"version": "781ad752…",
"cursor": "f1:ef18518d…:781ad752…",
"epics": [
{
"id": "SPEC-MIGRATION",
"name": "Move the specifications into the repository",
"documentPath": "…/epics/SPEC-MIGRATION/EPIC.md",
"priorityError": false,
"tasks": [
{
"id": 98,
"title": "Clean up after the merge",
"assignee": "ai",
"taskStatus": "todo",
"agentStatus": "idle",
"isDraft": false,
"acceptance": { "done": 0, "total": 3 },
"acceptanceError": false,
"taskPath": "…/tasks/98/TASK.md"
}
]
}
],
"unassigned": []
}- Only non-Pending Todo and Doing tasks appear. Tasks are grouped by epic in
priorityorder; tasks without an epic are inunassigned. - With
--include-pendingand--include-done COUNT(onprogressandhook), the table also has apendingarray and adonearray.pendingholds Todo and Doing tasks waiting for a decision, in ID order, each with aquestionof up to 200 characters.doneholds theCOUNTmost recently completed tasks, newest first, limited to epics that still have a Todo or Doing task. Without the options neither field is present. - There are no bodies and no history. Agents read the
documentPathandtaskPathfiles they need. cursoris whatwait --aftertakes.- The paths appear only in local CLI and hook output, never in remote JSON.
- The earlier
planPathfield is no longer produced or accepted. See the data guide.
Hook output
agboard hook --agent claude|codex writes JSON for the agent:
{ "hookSpecificOutput": { "hookEventName": "PostToolUse", "additionalContext": "AGBOARD_PROGRESS\n{…}" } }additionalContextisAGBOARD_PROGRESSfollowed by the table above, orAGBOARD_ERRORfollowed by a body with acodeand a reason, and a reminder not to make board-dependent changes.AGBOARD_ERRORcodes:folder_unbound,bound_project_missing,project_not_found,board_unavailable, andcontext_too_large.- Limits: 64 KiB of input, 256 KiB for the table, 10 seconds per run. Over the limit, the hook reports
context_too_large; it never truncates and calls it a success.
Snapshot and wait
agboard snapshot --json and agboard wait --after <cursor> --json return the project snapshot: fetchedAt, project, version, cursor, epics, tasks (each with full history), nextTaskId, and problems. Use the new cursor for the next wait.
wait blocks until the project's version differs from the cursor. It exits with an error instead of a snapshot for wait_timeout, board_unavailable, cursor_invalid, and project_not_found; none of them means "answered". See Error codes.
wait --until task --idle-timeout <seconds> --json selects one eligible AI-owned Todo or Doing task with an Idle run state, including tasks that existed before listening began. The selection order matches the progress table. The result includes the task and local paths for its TASK.md and, when assigned to an epic, documentPath for its EPIC.md. Selection does not claim or edit the task.
Abbreviated example; task fields are omitted.
{"kind":"task","projectId":"<id>","cursor":"<cursor>","task":{"id":1},"taskPath":"…/tasks/1/TASK.md","documentPath":"…/epics/DESIGN/EPIC.md"}If the requested interval passes with no eligible task, the command returns a successful result (exit code 0):
{"kind":"idle_timeout","projectId":"<id>","idleTimeoutSeconds":300}The timeout is required and ranges from 1 to 86,400 seconds. Connection, project, data, and argument errors remain errors; they are not encoded as idle_timeout. See Error codes.
Decision requests
agboard state <id> pending --request-json <json> takes:
{
"question": "Should existing records be deleted or kept?",
"choices": [
{ "id": "delete", "label": "Delete them and start clean" },
{ "id": "keep", "label": "Keep them and migrate" }
],
"wait": {}
}question: 1 to 2,000 characters.choices: 2 to 10 items; eachidis 1 to 64 characters of[A-Za-z0-9_-]and unique in the request; eachlabelis 1 to 200 characters.- The command waits for an answer by default, including when
waitis omitted;wait: {}is a compatible explicit form.wait: nullandtimeoutSeconds: nullmean no timeout. An integertimeoutSeconds(1 to 86400) limits only the waiting command; the question stays Pending.--no-waitreturns after saving and notifying, without waiting. - The waiting command returns the updated task and the answer separately:
{ "task": { "…": "…" }, "answer": { "actor": "human", "choiceId": "keep", "choiceLabel": "Keep them and migrate", "text": null } }Sample cards of the first-run guide
The progress table, the hook output, and wait --until task leave out the cards that carry an onboardingSample identity, whatever their lane or state. See agent integration.

