Problem
--pretty-json currently preserves valid, parseable JSON by pretty-printing the same structured payload emitted by --json. Adding ANSI escape sequences directly to that output would make the stream easier for humans to scan, but it would also make the payload invalid JSON for tools that pipe, parse, or archive the command output.
At the same time, several orchestrated commands still expose subprocess output as plain text. That makes --json and --pretty-json less useful for agents, CI consumers, and future dashboards because important details from PHPUnit, Rector, ECS, PHP-CS-Fixer, PhpMetrics, phpDocumentor, and Composer-backed checks remain embedded in raw strings instead of stable structured fields.
Proposal
Evaluate and implement a non-intrusive colored pretty JSON experience while preserving the machine-readable contract of JSON modes. If color is supported, it MUST be explicitly terminal-safe and MUST NOT silently corrupt JSON consumed by automation.
In the same design, extend command result payloads so full tool executions can return structured summaries instead of only raw subprocess strings. The color work should build on those structured results rather than becoming a standalone syntax-highlighting shortcut that is hard to evolve.
Goals
- Keep
--json and the default --pretty-json output valid JSON for scripts, CI, and agents.
- Provide a terminal-friendly way to inspect pretty JSON with color when it is safe and explicit.
- Convert known orchestrated tool results into structured JSON summaries where the upstream tool exposes parseable data.
- Preserve raw output as a fallback/debug field when a tool does not provide enough structured data.
Expected Behavior
Maintainers can keep using composer dev-tools ... --pretty-json as parseable JSON. If a colored mode is introduced, it is opt-in or otherwise impossible to confuse with strict JSON output. Agents and CI consumers can inspect fields such as command label, exit code, duration, artifacts, violations, changed files, coverage summaries, or generated report paths without scraping terminal output.
Implementation Strategy
Start by documenting the output contract for JSON modes and deciding whether color belongs behind a distinct option, a terminal-only renderer, or a separate command/output sink. Avoid adding ANSI escapes to strict JSON output.
Then incrementally enrich command results by mapping existing tool outputs into stable arrays. Useful candidates include:
- PHPUnit: test count, assertions, failures, errors, skipped tests, coverage artifact paths, and exit code.
- Rector: changed files, applied rules when available, dry-run status, and exit code.
- ECS/PHP-CS-Fixer: violations/fixed files, formatter output, and exit code.
- PhpMetrics: generated report paths, summary JSON location, package analysis status, and exit code.
- phpDocumentor docs/wiki: generated target paths, warnings when available, and exit code.
- Composer-backed checks: analyzed command, lockfile/package metadata when available, and exit code.
The implementation should reuse the current logger/process queue surfaces where possible, and only introduce new classes when a focused parser or renderer has a clear boundary.
Requirements
--json MUST remain compact, valid JSON without ANSI escape sequences.
--pretty-json MUST remain valid JSON unless a separate, explicitly documented color mode is introduced.
- Any colored terminal rendering MUST be disabled automatically for non-decorated output, redirected streams, or agent contexts where JSON is expected to be parsed.
- Structured subprocess summaries MUST include enough metadata to debug failures without relying solely on raw output.
- Raw subprocess output MAY remain available, but it SHOULD NOT be the only representation for supported tools.
- Documentation for affected commands MUST explain the strict JSON contract, any colored terminal mode, and the structured fields that are guaranteed.
Non-goals
- Do not color strict JSON output by injecting ANSI escape sequences into
--json or default --pretty-json.
- Do not implement a full terminal UI or replace existing command logs.
- Do not require every external tool to be parsed in one PR; this can ship incrementally per command/tool.
Benefits
This keeps JSON modes reliable for automation while making human inspection nicer and future agent workflows more precise. It also reduces brittle string scraping by giving structured consumers first-class fields for command outcomes and generated artifacts.
Acceptance Criteria
Functional Criteria
Architectural / Isolation Criteria
Problem
--pretty-jsoncurrently preserves valid, parseable JSON by pretty-printing the same structured payload emitted by--json. Adding ANSI escape sequences directly to that output would make the stream easier for humans to scan, but it would also make the payload invalid JSON for tools that pipe, parse, or archive the command output.At the same time, several orchestrated commands still expose subprocess output as plain text. That makes
--jsonand--pretty-jsonless useful for agents, CI consumers, and future dashboards because important details from PHPUnit, Rector, ECS, PHP-CS-Fixer, PhpMetrics, phpDocumentor, and Composer-backed checks remain embedded in raw strings instead of stable structured fields.Proposal
Evaluate and implement a non-intrusive colored pretty JSON experience while preserving the machine-readable contract of JSON modes. If color is supported, it MUST be explicitly terminal-safe and MUST NOT silently corrupt JSON consumed by automation.
In the same design, extend command result payloads so full tool executions can return structured summaries instead of only raw subprocess strings. The color work should build on those structured results rather than becoming a standalone syntax-highlighting shortcut that is hard to evolve.
Goals
--jsonand the default--pretty-jsonoutput valid JSON for scripts, CI, and agents.Expected Behavior
Maintainers can keep using
composer dev-tools ... --pretty-jsonas parseable JSON. If a colored mode is introduced, it is opt-in or otherwise impossible to confuse with strict JSON output. Agents and CI consumers can inspect fields such as command label, exit code, duration, artifacts, violations, changed files, coverage summaries, or generated report paths without scraping terminal output.Implementation Strategy
Start by documenting the output contract for JSON modes and deciding whether color belongs behind a distinct option, a terminal-only renderer, or a separate command/output sink. Avoid adding ANSI escapes to strict JSON output.
Then incrementally enrich command results by mapping existing tool outputs into stable arrays. Useful candidates include:
The implementation should reuse the current logger/process queue surfaces where possible, and only introduce new classes when a focused parser or renderer has a clear boundary.
Requirements
--jsonMUST remain compact, valid JSON without ANSI escape sequences.--pretty-jsonMUST remain valid JSON unless a separate, explicitly documented color mode is introduced.Non-goals
--jsonor default--pretty-json.Benefits
This keeps JSON modes reliable for automation while making human inspection nicer and future agent workflows more precise. It also reduces brittle string scraping by giving structured consumers first-class fields for command outcomes and generated artifacts.
Acceptance Criteria
Functional Criteria
--jsonand default--pretty-jsonremain parseable byjson_decode()in tests.Architectural / Isolation Criteria
composer/composercoupling while DevTools is being decoupled from Composer internals.