Driving hiiu from an agent
Every command emits one JSON document on stdout and nothing else, so a coding agent can parse the same command a human ran.
hiiu is built to be driven by a coding agent, and the contract that makes that possible is small enough to state on one page.
stdout is data, stderr is chatter
Under --json, stdout carries exactly one JSON document and nothing else.
Every line of human progress goes to stderr. So this is safe:
hiiu analyze --json | jq '.routes | length'
The rule holds on every exit path, including the ones a CLI framework would
normally own. --help and --version are captured and re-emitted as JSON, and
invoking no command at all is a usage error rather than a help dump with exit
0. A runner and a human get the same answer from the same invocation.
Two shapes, one discriminator
ok is present in both, and it is how you tell them apart.
The command's own document, when it produced one:
{ "ok": true, "hiiu": "0.1.0", "checks": [{ "id": "node", "status": "ok" }] }
Otherwise an error envelope:
{
"ok": false,
"error": {
"code": "NO_SUPPORTED_APP",
"message": ". is not a supported frontend app.",
"exitCode": 3,
"hint": "Point hiiu at the directory holding the app's package.json."
}
}
A command that models its own failure returns its document and a non-zero
exit code rather than throwing: doctor emits its report
with ok: false and the failing checks named, and still exits 3. So do not
assume a non-zero exit means an envelope. Branch on ok, and read error only
when it is false.
Never prompt a runner
hiiu prompts only when stdout is a TTY, and --yes was not passed, and
--json was not passed, and CI is unset. Otherwise a missing required
answer is exit 3 immediately, and never a hang.
That matters more than it sounds: a blocked prompt in an unattended build is
not a slow build, it is a stuck one. If you are scripting hiiu, pass --yes
where a command would otherwise ask, and treat exit 3 as "it needed an answer
I did not give".
Determinism you can rely on
The read-only commands are pure functions of the directory they are given.
analyze, ir,
decisions, overlay and
agents-md touch no network, run no model, write
nothing anywhere, and two runs of one input are byte-identical. You can cache
their output against the revision without a staleness check.
Finding the design system
The command an agent will reach for most is not in the pipeline at all:
hiiu components search Button --json
It looks a component up in the app's own catalog by name, prop or usage, and
prints the import statement, how widely it is used, and examples harvested from
the app's own code. No match is a true answer, so it exits 0; an empty query
is a usage error at exit 2.
This replaces what would otherwise be an MCP server. A shell command needs no
server, works in any agent, and is named directly in the AGENTS.md that
hiiu fork writes into a workspace.
The generated AGENTS.md
hiiu agents-md ./path/to/app
prints the file a forked workspace gets: the rules an agent needs, plus the
design system to build with. fork writes it; this prints it, so you can read
what your agent is about to be told before handing anyone a workspace.
Reading these docs
Every page has a markdown twin at its own URL plus .md, /llms.txt indexes
them, and /llms-full.txt is all of them in one file. The twin is the same
file the page was rendered from, so nothing is lost in the conversion.
curl https://hiiu.eu/llms-full.txt
Exit codes are on the CLI contract page, and they are worth reading before you branch on one.