stdout Is an API When Your User Is an Agent

articleaicliinfrastructureagent-loopshateoastooling

joelclaw CLI's HATEOAS JSON envelope contract already implements this pattern — validates the design direction and may surface gaps

Justin Poehnelt makes the case that CLIs built for human eyes are actively hostile to AI agents — and that fixing them requires treating stdout as a first-class API surface. The insight sounds obvious once you hear it, but most CLIs are still optimized for terminal readability: colored output, progress spinners, human-formatted tables, prose error messages. None of that survives an agent trying to parse it.

The core move is the same one the joelclaw CLI makes: structured JSON output on every command, consistent envelope format, exit codes that mean something. When an agent calls a CLI, it needs machine-parseable responses with predictable shape — not ANSI escape codes and a spinner that times out. The HATEOAS JSON contract in the joelclaw CLI exists exactly for this reason: every command returns a typed envelope that another tool can reason about without scraping text. This article is validation that pattern was worth building.

What makes this worth reading isn’t the conclusion (JSON output = good) but likely the specific failure modes it catalogs — the ways CLIs accidentally break agent workflows through ambiguous exit codes, inconsistent error surfaces, help text that’s useful to humans but noise to parsers. Justin is a Google Chrome DevRel who does a lot of work at the intersection of browser automation and agent tooling, so this comes from actual production friction, not theory.

The gap worth checking: does the joelclaw CLI handle error cases with the same structural consistency as success cases? A CLI that returns clean JSON on success but dumps a stack trace on failure is only half-done. Agents fail silently on unstructured errors.

Key Ideas

  • CLIs designed for human terminal output are a hostile environment for AI agents — ANSI codes, spinners, and prose errors all break machine parsing
  • stdout is an API when the caller is an agent; design it like one from the start rather than retrofitting
  • Consistent envelope format (like HATEOAS JSON) lets agents parse responses without conditional logic per command
  • Exit codes need semantic meaning — 0 for success, non-zero with structured error payload, no ambiguity
  • Error messages should be machine-readable first; human-readable is a secondary concern in agent-facing CLIs
  • Help text and self-description matter — agents can use --help output as context if it’s structured enough
  • The joelclaw CLI already implements this pattern via typed JSON envelopes; this article may surface edge cases worth hardening