Reference

Every command, flag, format and limit in Abbreviatory v0.6.0. For a first run, the quick start is shorter. The same reference is in the code repository as docs/reference.md.

Commands

Command What it does
abbreviatory reduce [flags] [file] Reduce a file, or standard input, and print the report
abbreviatory run [flags] -- CMD Run a command, reduce what it prints, compare with its last run, exit with its status
abbreviatory history [KEY] List the run histories, or the runs of one
abbreviatory expand [-store dir] REF Print the original bytes a reference stands for
abbreviatory serve [-addr 127.0.0.1:7878] [-token T] Serve reduce, expand and histories over HTTP
abbreviatory mcp Serve them to a coding agent over the Model Context Protocol
abbreviatory prune [-older 168h] [-max-size 500MB] Remove old stored originals
abbreviatory formats List the input formats
abbreviatory version Print the version

Exit codes: run exits with the command’s own status (127 if the command isn’t found). Otherwise 0 when it worked, 1 when the work failed (unreadable input, a budget too small, a reference not in the store), 2 for a usage mistake.

Flags for reduce and run

Flag Default What it does
-budget N 4096 Most bytes of output. At least 512
-preserve LIST errors,failures,warnings What is always shown or referenced. Empty for nothing
-keep REGEX Also keep lines matching this. Repeatable
-format NAME auto auto, a family (test-output, build, logs, json), or one of the formats below
-json off Print a JSON object with the counts and the report
-no-store off Don’t keep the original. The report then has no references
-key NAME Keep a run history under NAME and report what changed. run names one after the project and the command
-full off With a history, the whole report even when nothing changed
-warnings off With a history, compare warnings with the last run too: new ones listed and marked (new), those gone listed
-no-history off run only: keep no history
-store DIR cache directory Where originals and histories are kept. Also $ABBREVIATORY_STORE

Formats

Name What it reads
gotest-json go test -json: one record per test, with its output; build failures and tests that never finished too
gotest Plain and -v go test output, subtests, panics, build errors
pytest pytest, verbose or not: FAILURES and ERRORS sections matched to the short summary, the warnings summary, the final count
junit JUnit XML reports, one record per testcase
cargo-test cargo test: every test, the failures with their output and panic message, the test result: counts. In a workspace a test is named with its crate’s test binary
cargo cargo build, check and clippy: each rustc error and warning with its snippet and notes, headed by its location (at src/main.rs:12:27)
tsc The TypeScript compiler, plain (src/cart.ts(9,7): error TS2322) and pretty, and watch mode; the last Found N errors is the count
eslint ESLint’s stylish, compact and unix formats: each problem by file, line, column and rule
gradle javac’s and kotlinc’s errors and warnings, failed tests by task, and “What went wrong” as one error with the messages repeated in it
maven Compiler errors and warnings, failed tests by module with their exception and stack trace, each “Failed to execute goal” as one error; the closing advice is information
npm npm and pnpm: an error block as one error headed by its code, ERR_PNPM_ errors, deprecation warnings, the audit count
logs Anything that is text: levels, stack traces, Python tracebacks, Go panics
json One JSON document, shown as a valid JSON outline
diff git diff, git show, git log -p, diff -u and -r, merge diffs: commits, every file with its added and removed lines and a reference, then the changes. The same change in several places is shown once with a count; lock files and generated code are listed, not spelled out; conflict markers are errors, trailing whitespace a warning
http curl -i, curl -v and redirect chains: status lines (4xx and 5xx are errors), the headers that matter, curl’s errors, and the body. A JSON body is outlined with its error fields kept; other bodies are read like a log
listing find, fd, ls -l, ls -R, tree, du: files grouped by directory and extension, with counts, total size, the most common extensions and the largest files; “Permission denied” lines are errors

Detection tries HTTP responses, test runners, Maven, JSON, the other build tools, diffs and listings, in that order, and reads anything else as a log. It takes colour codes out first, so CARGO_TERM_COLOR=always and eslint --color are fine.

The level of a log line comes from upper-case words near its start (ERROR, WARN, FATAL, CRITICAL and others), level= and JSON level fields, bracketed levels, glog prefixes, compiler style error: and warning:, and the first line of a panic or traceback.

The Report

[abbreviatory] <format>, <lines> (<size>), ref <ID>
<counts>
FAILED (n):
- <test> [ref ID:gN]
    <the failure message>
ERRORS (<kinds>, <lines>):
- x<count> <the first line of the group> [ref ID:gN]
MATCHED --keep (...):
WARNINGS (...):
OTHER (...):
not shown: <what was left out> [ref ID:<kind>]

How the budget is spent: the header, the counts and the “not shown” lines are set aside first. Then every failure, error, keep-rule match and warning gets its one line. Then detail lines are shared out in rounds (2 each, then 6, 16 and 40), so every failure shows some of its message before any shows all of it. Other groups fill what’s left, most frequent first.

If even the header and the counts don’t fit, reduce fails and says how many bytes it needs. When an input is so small that showing it whole is no longer than reducing it, it’s shown whole.

References

A reference is ID:selector. The ID is a hash of the input, so the same input always gets the same ID.

Selector Expands to
none The whole input
gN The original lines of group N
fail, error, warn, info, pass, skip Every line of that kind
keep Every line a -keep rule matched
L10 or L10-40 Those input lines
/items/3 For JSON: that value, as it is in the input
errors For JSON: every error field with its value

Lines come back byte for byte, in input order.

Run History

With a history, each run is compared with the one before it. A failed test is known by its name, with its package for go test, its test binary for cargo, its task for Gradle and its module for Maven. Anything else, a log error, a compiler error or a failed build, is known by its text with numbers and IDs aside. Gradle’s “What went wrong” and Maven’s “Failed to execute goal” are known by their first line, so fixing one error under them doesn’t make them new.

Gradle (without testLogging) and Maven don’t name passing tests. A failing test missing from the next run counts as fixed if its task or module ran its tests, and as not run otherwise, such as after a compile error.

In the report Meaning
new failing now, not in the last run
fixed (logs and compilers: gone) failing in the last run, passing now
not run a test failing in the last run that was skipped or didn’t run this time
still failing (logs: recurring) failing in both, marked with how many runs in a row
flaky (logs: intermittent) changed between passing and failing 3 or more times in the last 10 runs

With -warnings, warnings are compared too, known by their text with numbers aside. New ones are listed under the summary line and marked (new), and those gone are listed with a reference into the last run; either makes the run a change. The run just before must have had -warnings too, or the report says the warnings weren’t compared. Past 50,000 kinds of warning in a run they aren’t compared either.

New failures come first in the report, marked (new). Fixed ones carry a reference into the run where they last failed. When the same failures are there as last time, the report is one line, unless you pass -full. A history keeps the last 50 runs and is removed after 90 days unused.

MCP Server

abbreviatory mcp speaks the Model Context Protocol on standard input and output. Add it to a coding agent as the command abbreviatory mcp; for Claude Code that’s claude mcp add abbreviatory -- abbreviatory mcp. It offers four tools:

Tool What it does
run Runs a command given as an array, such as ["go", "test", "./..."], reduces what it prints and compares with the last run. Takes cwd, timeout_seconds (600 by default), stdin, key and no_history
reduce Reduces output given as text, or a file given as path
expand Returns the original lines behind a reference, up to 4 MB unless max_bytes says more
history Lists the histories, or the runs of one with key

Every tool also takes budget, format, preserve, keep, full, warnings and no_store, as the flags. A command that runs past its time limit, or whose request the agent cancels, is stopped along with what it started.

HTTP Service

abbreviatory serve listens on 127.0.0.1:7878. To listen where other machines can reach it, give it a token with -token or $ABBREVIATORY_TOKEN; it then asks every request for Authorization: Bearer TOKEN.

Request What it does
POST /reduce The body is the input, the options are query parameters named as the flags. Returns the JSON of reduce -json, or the report alone with Accept: text/plain
GET /expand/{ref} The original bytes behind a reference
GET /runs, GET /runs/{key} The histories, or one history’s runs
GET /healthz Status and version, without the token

The command line, the MCP server and the HTTP service share one core, and the test suite checks they give the same reports, expansions and histories on every fixture.

GitHub Action

abbreviatory/engine@v0.6.0 runs a command, writes the report to the job summary, keeps the run history in the Actions cache and fails the step when the command fails.

- uses: abbreviatory/engine@v0.6.0
  with:
    run: go test -json ./...
    warnings: true
Input Default What it does
run The command, one shell command line run with bash
working-directory . Where to run it
key History name; empty means one made from the directory and the command
budget, format, keep, warnings, full As the flags; keep takes one expression per line
summary true Append the report to the job summary
cache true Keep the history in the Actions cache
cache-key abbreviatory-<job>-<matrix index> Start of the cache key; jobs that should share a history give the same one
fail true Fail the step when the command fails; false reports only
version the pinned release An Abbreviatory release, or latest

Outputs: exit-code, result (pass, fail, or error when Abbreviatory itself couldn’t run, which fails the step whatever fail says), new, fixed, failing, new-warnings, report (a text file) and json. The action needs bash and jq, which GitHub’s runners have.

Limits in v0.6.0

  • Known formats only. Free prose, or a log format it doesn’t recognise, is reduced only by folding repeats and finding level words.
  • Numbers don’t count for grouping. Two errors that differ only in a number, a port or a status code are one group. The first is shown, and the count says how many.
  • Some inputs are read whole. JSON documents and JUnit reports are read in one piece, up to 256 MB. Logs and test output stream with no size limit.
  • References need the stored original. With -no-store, or after pruning, they can’t be expanded.
  • Plain go test and pytest only name failures. Without -v, a failing test that disappears counts as fixed, even if it was deleted or skipped.
  • History tracks failures and errors, and warnings with -warnings. Keep-rule matches aren’t compared, and warnings are compared by kind, not by how often they appear. A log error whose wording changes counts as new.
  • CI needs the store kept between runs. CI machines start empty, so cache the store directory, or every run is run 1.
  • HTTP bodies end at the next status line. A body with no final newline that runs straight into the next response (curl -L with -i) runs into it. A JSON body longer than 64 kB on one line, or over 16 MB, is read like a log.
  • Listings guess some directories. du -a can’t tell a file without an extension from a directory, and in tree output without its closing count an empty directory counts as a file.
  • The HTTP service has no TLS. Put it behind a proxy that has, if it’s reachable beyond the machine.
  • Build tools in their default human formats. Not cargo’s --message-format=json or ESLint’s JSON and SARIF. A tool run inside another (tsc through npm run build) is read as the first one found. Yarn’s output is read as a log. cargo test -- --nocapture can put a test’s ok on a later line, and then the test isn’t counted. In tsc’s watch mode, errors from earlier compilations stay in the report.
  • The MCP run tool runs what the agent asks. It runs commands as you, the same as an agent’s own shell tool would.