Skip to content

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.