Output, JSON & exit codes
jdx output is designed to be read by a language model with a finite context window: compact text by default, a complete JSON envelope on request, and exit codes an agent can branch on without parsing prose.
Text output#
- Two-space indentation, no box drawing or tables — they cost tokens and tokenize badly.
- A leading kind word on every entity line (
class,method,field,constructor). - Grouping headers instead of repeating the declaring type on every line.
- Explicit truncation: a footer says how much was shown and which flag shows the rest.
- Provenance: a
source:line names the artifact and whether the answer came from sources, bytecode or a decompiler. - A
next:line on single-entity answers with the most useful follow-up command. - No colour when piped. ANSI colour only on a terminal (
--no-colorturns it off there too).
jdx members java.util.List --limit 3
members of java.util.List
methods declared on java.util.List:
method public E getFirst()
method public E getLast()
method public E removeFirst()
+ 9 from java.lang.Object (--from java.lang.Object to expand)
3 of 63 members shown (--limit 63 to see more)
source: java.base (jrt)Real output — this example ran against the current jdx when the page was built.
Warnings#
Anything an agent should know but did not ask for is a named warning, never silent: duplicate
classes across jars (shading), sources that do not match the binary, corrupt class files,
multi-release variants, unresolvable supertypes, project-discovery fallbacks. Each has a stable
code (SOURCES_VERSION_MISMATCH, MULTI_RELEASE_VARIANT, …) in both text and JSON.
JSON output#
Add --json to any command (before or after the command name). The envelope is the same for
the CLI, jdx batch, the daemon, the HTTP API and MCP, and carries exactly the information of
the text output:
jdx members java.util.List --limit 2 --json
{"jdx":1,"ok":true,"command":"members","query":"java.util.List","result":{"groups":[{"declaring":"java.util.List","depth":0,"kind":"method","rows":[{"ref":"java.util.List#getFirst()","kind":"method","declaring":"java.util.List","signature":"public E getFirst()","depth":0,"overridden":["java.util.SequencedCollection"]},{"ref":"java.util.List#getLast()","kind":"method","declaring":"java.util.List","signature":"public E getLast()","depth":0,"overridden":["java.util.SequencedCollection"]}]}],"counts":{"constructors":0,"methods":63,"fields":0},"objectSummary":{"count":9,"expandHint":"--from java.lang.Object"}},"truncated":{"shown":2,"total":63,"hint":"--limit 63"},"warnings":[],"provenance":[{"artifact":"java.base","origin":"jrt"}]}Real output — this example ran against the current jdx when the page was built.
| Field | Meaning |
|---|---|
jdx |
envelope version (1) |
ok |
true on success; false carries error.code and, when ambiguous, candidates[] |
command, query |
what was asked |
result |
the command-specific answer |
truncated |
shown / total / hint when output was cut |
warnings |
{code, message} objects |
provenance |
where each answer came from: artifact, origin, file, lines |
Exit codes#
Exit codes are a public contract — they do not change between releases.
| Code | Meaning | What an agent should do |
|---|---|---|
0 |
success, results found | use the answer |
1 |
valid query, nothing found | read the did you mean list or widen the classpath |
2 |
ambiguous reference | retry with one of the printed candidates |
3 |
usage or argument error | fix the command (wrong flag, member ref where a type is required, …) |
4 |
no index or workspace resolved | pass --jars / --coord / -w, or run inside a project |
5 |
artifact read error | the jar is corrupt or unreadable |
6 |
internal error | report a bug |
The one documented exception is jdx diff --fail-on, which exits 1 when its gate trips
(API diff).
Bounded by default#
Listings stop at --limit (50 for most commands) and say so. For the biggest listings,
--brief drops headers and provenance, and --max-lines N sets a hard line budget — useful
when an agent is short on context. Neither changes --json output.
Deterministic#
The same inputs give byte-identical output: everything is sorted, and there are no timestamps, absolute paths or hash values in default output. Agents can cache answers, and diffs of jdx output are meaningful.