Maven is excellent at building Java projects.
It is also extremely talkative.
That verbosity is usually harmless when a developer is reading a terminal. For a coding agent, however, several thousand bytes of routine build output can displace source code, instructions, and the actual failure from the model’s working context.
So I built mvn-lite: a small, deterministic Bash wrapper that keeps successful Maven runs to one line and extracts only bounded, actionable evidence from failures.
I call it Introverted Maven.
Vanilla Maven████████████████████████████████6,753 bytes
mvn-lite▏16 bytes
In a real four-module Java application, successful output fell from 6,753 bytes to 16 bytes, and an invalid lifecycle failure fell from 2,730 bytes to 228 bytes. Maven’s exit status was preserved, complete failure logs were retained, and Maven arguments were not echoed in compact failure output.
Full measurements and methodology are available in the compatibility experiment report.
The goal is not to replace Maven’s diagnostics. It is to keep them from consuming an agent’s context unless they are needed.
The problem with ordinary Maven output
A routine Maven test run can produce dozens or hundreds of lines covering routine details such as:
- reactor ordering
- plugin execution
- compiler phases
- test totals
Most of this is useful when investigating a build, but almost none is useful when it succeeds.
A coding agent usually needs to know only:
PASS · 4.240 s
If the build fails, the agent needs a compact answer to a different question:
What is the next actionable thing I should inspect or fix?
A compact test failure might look like:
FAIL
Failure summary:
Test: com.example.AppTest.shouldRejectInvalidInput
Exception: java.lang.AssertionError: expected 400
Full Maven log:
/project/.agent-logs/maven/maven-20260730-100000-12345.log
Re-run with --full for complete live output.
The raw Maven output still matters. It simply does not need to occupy the main conversation by default.
Maven’s -q option is too blunt for this use case: it suppresses output before the wrapper can inspect it. mvn-lite captures normal Maven output privately, so it can still surface failing tests, compiler errors, unresolved dependencies, failed goals, and immediate causes when a build fails.
What mvn-lite does
In compact mode, mvn-lite prefers the project’s executable ./mvnw, then falls back to mvn from PATH. It adds batch mode and disables transfer progress and color when equivalent options were not already supplied, then:
- captures complete output locally;
- preserves Maven’s exit status;
- prints a one-line success or bounded failure summary;
- retains failed logs and points to the complete log;
- falls back to a bounded tail for unknown failures.
Successful logs are deleted by default but can be preserved with --keep-log. Ordinary Maven
output remains available through --full.
mvn-lite targets common local workflows: build, test, package, install, and verify. It recognizes high-value categories including compiler, test, dependency-resolution, failed-goal, and common Maven command errors.
Unknown output receives a bounded log tail rather than an invented interpretation, and the raw log remains authoritative.
Testing it in a real application
I tested mvn-lite in a real four-module Maven application. The selected module ran 102 unit tests using Maven 3.9.16 and the system-provided Bash 3.2 on macOS. The comparison covered vanilla Maven, the application’s former project-specific low-noise helper, and mvn-lite.
Bytes from stdout and stderr were the primary metric because they are exact and tokenizer-independent.
Estimated tokens use ceil(output bytes / 4) for relative comparison, not as an exact
model-token or billing measurement.
Successful build results
The successful run selected one module and ran its tests:
./mvnw -B -ntp -Dstyle.color=never -pl common test
| Runner | Bytes | Lines | Estimated tokens |
|---|---|---|---|
| Vanilla Maven | 6,753 | 90 | ~1,689 |
| Former project-specific helper | 18 | 1 | ~5 |
mvn-lite | 16 | 1 | ~4 |
mvn-lite produced PASS · 3.944 s, reducing successful agent-visible output by more
than 99.7%. It effectively matched the former helper; the two-byte difference is
operationally meaningless.
As an additional real-world check, I also ran mvn-lite against the Scriptella reactor under JDK 17. The normal Maven run produced hundreds of lines, while mvn-lite completed with a single PASS · 11.137 s line. See the Scriptella smoke test.
Failure results
The initial failure experiment invoked an invalid Maven lifecycle phase:
./mvnw definitely-not-a-maven-phase
The first mvn-lite version was smaller than vanilla Maven and the former helper, but it repeated
Maven’s complete list of valid lifecycle phases. The actionable information was only:
Maven: Unknown lifecycle phase "definitely-not-a-maven-phase"
I updated the parser to shorten recognized Maven command errors while preserving the complete original message in the raw log.
Actionable failure output after parser improvement
Agent-visible UTF-8 bytes, stdout + stderr
mvn-lite873mvn-lite22873.9% less output than the original mvn-lite
The updated wrapper reduced output by 91.6% relative to vanilla Maven, 83.6% relative to the former project-specific helper, and 73.9% relative to the first mvn-lite implementation. It still preserved Maven’s exit status, the invalid phase, the complete-log location, and rerun guidance.
Extracting the immediate cause
Some Maven plugin failures include the useful cause on the same line as the failed goal:
Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.2.5:test
(default-test) on project app:
Execution default-test failed:
Unable to create temporary directory
A useful compact summary needs both:
Goal: org.apache.maven.plugins:maven-surefire-plugin:3.2.5:test (default-test)
Cause: Unable to create temporary directory
mvn-lite extracts at most one immediate cause from bounded forms such as:
Execution ... failed: <cause>
It does not reconstruct arbitrary exception chains or stack traces.
During the final application integration, a restricted workspace prevented Surefire from creating its normal target/surefire directory. The installed wrapper preserved exit status 1, retained the complete log, identified the Surefire goal, surfaced Unable to create temporary directory, and remained bounded.
The same build passed after normal filesystem permissions were restored.
Try mvn-lite in your project
To try the latest version:
curl -fsSL \
https://raw.githubusercontent.com/ejboy/agent-scripts/main/scripts/mvn-lite \
-o mvn-lite
chmod +x mvn-lite
Review the script before running it in a sensitive repository. For a reproducible vendored copy, replace
main with a release tag such as v0.1.0.
Arguments pass through to Maven. Use --full when ordinary Maven output is needed:
./mvn-lite test
./mvn-lite -pl common test
./mvn-lite --full test
./mvn-lite --help-mvn-lite
Why not summarize the logs with an LLM?
mvn-lite extracts the useful signal locally instead of spending agent tokens on an LLM summary
or sending repository logs outside the environment. It requires no API key and falls back to a bounded log
tail instead of making a probabilistic guess.
Limitations
This was a focused compatibility and adoption experiment: one real multi-module application, one successful module build, one synthetic lifecycle error, one real Surefire environmental failure, warm incremental state, and single measured runs.
This article summarizes the main findings. The complete experiment report contains the full environment, controls, intermediate results, checksums, and supporting evidence.
The results do not establish a fixed savings percentage, diagnostic parity for every Maven plugin or failure category, or that Maven itself runs faster.
The claim is narrower:
For the measured local-development scenarios,
mvn-litedramatically reduced agent-visible output while preserving the exit status, actionable failure evidence, and access to the complete raw log.
The broader lesson
Coding agents change the economics of command-line output.
Traditional build tools assume that console output is cheap. A developer can scroll, search, collapse, or ignore it.
For an agent, output competes directly with source code, requirements, conversation history, repository context, and the actual diagnostic. A tool designed for agent workflows should:
- Make success extremely small.
- Preserve exit status and actionable failure evidence.
- Retain complete diagnostics outside the main context.
- Bound unknown-output fallbacks and avoid echoing sensitive arguments.
- Preserve an escape hatch to ordinary output.
That is what mvn-lite is trying to do.
Maven still knows everything it knew before.
It has simply learned when not to say it.
Try mvn-lite in an existing Maven project. Real-world failure cases and feedback are
especially useful.