All Posts
Follow
RSS
Date:
From:
Ben Sadik < contact@bensadik.net >
To:
You
Subject:

RFC: A convention for CLI tools to output LLM-optimized results

Cc:

AI coding agents like Claude Code, Codex, and OpenCode run CLI tools all the time: tests, linters, builds. But these tools talk to humans. They print colors, progress bars, banners, long stack traces, and a line for every test that passed.

The agent pays for every one of those tokens, and the noise makes it worse at its job. It only needs to know what failed and why.

So I wrote a small proposal: a --llm flag that tells a tool “an LLM is reading this, keep it short.”

Why not --json or --quiet?

--json is made for scripts. It includes everything, and it’s often 10 to 50 times bigger than a short text summary. LLMs read text from top to bottom; they don’t walk through keys.

--quiet hides too much. The agent learns that something failed, but not what or why.

What’s missing is something in between: short, plain text, and still enough to fix the problem.

The idea

Two things:

  • A --llm flag: jest --llm, eslint --llm, cargo build --llm.
  • An LLM_OUTPUT=1 environment variable, so an agent can turn it on once for every command it runs. A flag passed explicitly, like --json, still wins.

When it’s on, a tool should:

  • Drop decoration: colors, spinners, box drawings, banners.
  • Report failures, not successes, plus one summary line like FAIL 2/50.
  • Keep stack traces short: the error and the top frames from your own code. No node_modules, no code previews with arrows.
  • Use a flat format that reads top to bottom.
  • Still give enough detail to fix the problem. --llm is not --quiet.

The test is simple: could a good developer fix the bug with only this output and the codebase?

An example

A failing Jest run normally prints dozens of lines: PASS lines, code previews, arrows, full stack traces, and a summary table. With --llm, it becomes:

FAIL 2/50

--- src/auth.test.ts:42 "should reject expired tokens"
expected: 401
received: 200

--- src/auth.test.ts:67 "should refresh token on 403"
TypeError: refreshToken is not a function
  at handleResponse (src/api.ts:15)

Everything the agent needs, for a fraction of the tokens. If it wants the code around line 42, it can read the file itself.

How it could spread

No standards body, no committee. Like --verbose and --quiet, it only works if people use it:

  1. Build it into the tools agents run the most: Jest, ESLint, pytest.
  2. Send PRs upstream, or ship it as plugins.
  3. Have agent harnesses set LLM_OUTPUT=1 by default.

Later, the flag could take values like --llm=verbose. For now, it’s a simple on/off.

The full proposal, with the details and an FAQ, is on Codeberg. Ideas and contributions are welcome.