-
Notifications
You must be signed in to change notification settings - Fork 0
JSON Output
Every git task command accepts a global --format json flag (it can go anywhere:
git task ls --format json or git task --format json ls). It prints exactly one JSON document
on stdout and nothing else: no hint text, no automation chatter, no partial lines. That holds on
failure too, so it's always safe to parse the same way regardless of outcome.
This is the contract to build any external tool (script, CI check, dashboard, bot) against. Web Server Integration builds directly on what's documented here.
Check ok first if you want the structured reason for a failure; don't rely on the process exit
code alone to distinguish a validation problem from a genuine crash, since both exit 1. version
is git-task's own version, so a long-lived integration can detect a shape change if the response
format ever evolves.
warnings[] carries non-fatal issues collected during the command (each with message, an
optional detail, and an optional scope, e.g. the name of one repo skipped during a multi-repo
ls). A response can be ok: true and still carry warnings.
stdout carries only the JSON document. Even on failure, git-task still writes a human-readable
✖ Error: ... line to stderr, unaffected by --format json. This is deliberate, so errors
stay visible when a JSON caller's own logging pipes stderr somewhere a person reads. If you're
capturing output, keep stdout and stderr separate and parse only stdout.
error.kind is one of:
| Kind | Meaning |
|---|---|
not_a_repo |
Not run inside a git repository. |
identity_missing |
No usable name/email in git config to attribute a write to. |
not_found |
The id/name/entity referenced doesn't exist. |
ambiguous_id |
A hash prefix matched more than one task. |
validation |
Bad input: a missing required field, conflicting flags, a malformed expression. |
conflict |
e.g. adding a label/link that's already present, or a task edited concurrently by another writer (see Web Server Integration). |
rejected |
A remote rejected a push (non-fast-forward), same as git itself. |
remote |
A network/remote operation failed for another reason. |
io |
A filesystem operation failed. |
internal |
Anything not otherwise classified. Exhaustive classification isn't the goal; expect to see this occasionally, it doesn't mean something is broken. |
error.context is a free-form object whose keys depend on kind, present only when there's
something useful to attach. Common ones: not_found carries query/entity; ambiguous_id
carries query/matches; validation carries field/missing.
Any response that includes a task (show, export, each entry of ls, and the task field of
every mutating command's response) uses this shape:
| Field | Type | Notes |
|---|---|---|
id |
string | The real id (creation commit hash). |
display_id |
string |
KEY-<hash prefix>, e.g. SRV-9057e58a. |
key |
string | This repo's effective address key. |
title, description
|
string | |
kind |
string |
bug | story | task | epic | subtask. |
status |
string | Free-form. |
priority |
string or null |
low | medium | high. |
assignee |
string or null | Email. |
assignee_name |
string or null | Resolved display name, already looked up for you. |
reporter |
string | Email of whoever created the task. |
reporter_name |
string | Resolved display name. |
labels, fixed_versions, affected_versions
|
array of string | Always present, empty array if unset. |
due, milestone
|
string or null | |
parent |
string or null | Resolved local id for a same-repo parent; null for a cross-repo one or no parent. |
parent_display_id |
string or null | |
parent_repo |
string or null |
null for same-repo/no parent; the target repo's identifier for a cross-repo parent. |
children |
array |
Only populated by show. Every other response leaves it empty rather than paying for the scan; see ChildJson below. |
links |
array of LinkJson
|
See below. |
comments |
array of CommentJson
|
id, author, author_name, timestamp, text, edited. |
deleted |
boolean | |
created, updated
|
number | Unix timestamps. |
history |
array, or omitted | The full op-chain (see below). Only present on show/export, or ls --with-history. |
LinkJson: kind (blocks \| relates \| dup), target (resolved local id, or null for a
cross-repo link), target_display_id (always present), target_repo (null for a same-repo
link, the target repo's identifier for a cross-repo one).
ChildJson: id (null for a cross-repo child), display_id, title, kind, status, repo
(null for a same-repo child).
Every *_name field is already resolved from the repo's contributor directory; don't re-derive a
display name from an email yourself.
new, edit, status, comment, label, version, epic, link, and delete all return
this shape as data:
{
"task": { /* TaskJson, without history */ },
"ops": ["SetStatus", "AddLabel"],
"automation": [ /* AutomationEvent[], any rules that fired as a result */ ],
"created": true // only present, and true, for `new`
}task reflects the state after automation has run: if a rule changed something the command
itself didn't touch, this is what you'll see, not the state right after your own edit. ops is
just the tags of the operations your own command appended; a fired rule's own operations live
inside its own automation[] entry instead, so you can tell which changes were yours and which
were automatic.
-
ls:datais{ scope, filters_applied, repos: [{ name, project, path, key, branch, tasks: TaskJson[] }], contributors, statuses, total }.contributorsis an email-to-name map merged across every repo in the response;statusesis the distinct set of status strings seen. Pass--with-historyto include each task'shistory; omitted by default to keep the listing small. -
export:datais a bare array ofTaskJson(always withhistoryincluded), not wrapped in an object. -
show:datais a singleTaskJson, withhistoryandchildren[]populated. -
log: does not currently branch on--format json; it always prints the human-readable audit trail. For a machine-readable operation history, readhistoryfromshow --format json(orexport) instead. -
config show/fields/config rule list:datais the effective config document; see Configuration. -
repos/projects/register/unregister/project ...:dataincludes the complete, current registry (repos: RepoEntryJson[]) after the change, so a caller refreshes its view in one round trip rather than issuing a follow-upreposcall. -
push/pull:data.refs/data.tasksreport a per-task outcome (ok/rejectedfor push;new/fast_forwarded/merged/up_to_datefor pull). -
whoami:datais{ repo, global, effective }, each an identity document (name,email,source), letting a script check what identity would be used before it writes anything.
- A missing required field on
new(or any command that would otherwise prompt) never blocks on stdin under--format json, even at a real terminal: it returns avalidationerror listing exactly what's missing. Checkgit task fields --format jsonahead of time if you're generating tasks from another system and don't already know the repo's requirements. - Anything that would otherwise be interactive-only (bare
edit, bareconfig rule add,automation add) returns avalidationerror under--format jsoninstead of hanging; the error message names the flags to pass instead. -
--repo/--projectselectors, and the address form (SRV-hashvs. a bare hash), behave identically under--format jsonand in text mode; only the output shape changes.
Next: Web Server Integration for turning this into an actual service.
git-task
Start here
Using tasks
Building on git-task
Contributing