Skip to content

feat(command): add CommandSpec::raw_output for verbatim stdout commands - #92

Merged
jpage-godaddy merged 2 commits into
mainfrom
plain-text-output
Aug 10, 2026
Merged

feat(command): add CommandSpec::raw_output for verbatim stdout commands#92
jpage-godaddy merged 2 commits into
mainfrom
plain-text-output

Conversation

@jpage-godaddy

@jpage-godaddy jpage-godaddy commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds CommandSpec::raw_output(true) so a command's successful string result prints byte-for-byte to stdout, bypassing --output/--json/--human/--toon and the --fields/--filter/--expr pipeline entirely.
  • --output/--fields/--filter/--expr are hidden from a raw_output command's own --help (still parse harmlessly if passed anyway — same convention as --dry-run on non-mutating commands).
  • Guards against pairing raw_output with streaming commands or .with_pagination(...) (both debug_assert!).
  • Guarantees exactly one trailing newline without doubling one the handler's string already had (e.g. text read from a file) — caught in review, fixed with a regression test.

Fixes the case where a command whose only correct output is verbatim text (e.g. a GraphQL SDL dump) gets JSON-escaped instead of raw text when piped to a file — see DEVEX-993.

Test plan

  • cargo fmt --all --check
  • cargo clippy --all-targets -- -D warnings
  • RUSTDOCFLAGS='-D warnings' cargo doc --no-deps
  • cargo rustdoc --lib -- -W missing-docs (zero)
  • cargo test --all-targets (new coverage in tests/raw_output.rs, plus new panic-guard tests in tests/foundation.rs and a human.rs unit test)
  • cargo test --doc

🤖 Generated with Claude Code

Adds `.raw_output(true)` so a command's successful string result prints
byte-for-byte to stdout, bypassing --output/--json/--human/--toon and the
--fields/--filter/--expr pipeline entirely. Fixes the case where a command
whose only correct output is raw text (e.g. a GraphQL SDL dump) got
JSON-escaped when piped to a file. --output/--fields/--filter/--expr are
hidden from such a command's --help (still parse harmlessly if passed),
and raw_output is guarded against pairing with streaming or pagination.

DEVEX-993

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces CommandSpec::raw_output(true) to support commands whose only correct output is verbatim text, bypassing the normal output envelope/pipeline and hiding now-irrelevant formatting flags from the command’s help.

Changes:

  • Add CommandSpec::raw_output(true) and plumb raw_output through command registration into middleware rendering.
  • Update clap help/flag behavior so --output/--fields/--filter/--expr are hidden (but still accepted) for raw-output commands.
  • Add end-to-end and guardrail tests covering raw output rendering, help visibility, and invalid raw_output+pagination/streaming combinations.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cli-engine/tests/raw_output.rs Adds end-to-end tests asserting raw-output rendering and help flag hiding behavior.
cli-engine/tests/foundation.rs Updates middleware request helpers and adds panic-guard tests for unsupported raw_output combinations.
cli-engine/src/output/human.rs Adds a unit test documenting plain-string human formatting behavior relevant to raw text output expectations.
cli-engine/src/middleware.rs Implements the raw-output render bypass in the middleware render path.
cli-engine/src/command.rs Adds the raw_output flag to CommandSpec plus debug-assert guards for streaming constructors.
cli-engine/src/cli.rs Hides irrelevant output/pipeline flags for raw-output commands and asserts pagination incompatibility at clap-tree build time.
cli-engine/docs/concepts.md Documents the raw-output concept and intended behavior.
AGENTS.md Updates the command authoring checklist to include raw_output(true) guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli-engine/src/middleware.rs Outdated
The raw_output bypass unconditionally appended "\n", so a handler string
that already ended in a newline (e.g. text read from a file) rendered with
a doubled trailing newline, contradicting the documented "exactly one
trailing newline" guarantee. Strip at most one trailing newline before
appending ours.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (2)

cli-engine/src/middleware.rs:1018

  • The raw-output renderer claims to guarantee exactly one trailing newline, but strip_suffix('\n') only removes a single newline. If the handler returns text ending in multiple newlines (e.g. a blob with a trailing blank line), the output will still end with multiple newlines, violating that contract.
                    let body = text.strip_suffix('\n').unwrap_or(text);

cli-engine/src/output/human.rs:1167

  • This test comment says raw_output relies on format_plain_value, but the raw_output path renders directly from Value::String in middleware (it doesn't go through the human formatter). Updating the comment will avoid future confusion about the dependency.
        // No quoting/escaping — the exact convention `raw_output` bypass
        // relies on to render a `CommandResult` string byte-for-byte.

@jpage-godaddy
jpage-godaddy merged commit 84b0f00 into main Aug 10, 2026
4 checks passed
@jpage-godaddy
jpage-godaddy deleted the plain-text-output branch August 10, 2026 21:27
@github-actions github-actions Bot mentioned this pull request Aug 10, 2026
jpage-godaddy pushed a commit that referenced this pull request Aug 10, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>cli-engine: 0.8.4</summary>

##
[0.8.4](cli-engine-v0.8.3...cli-engine-v0.8.4)
(2026-08-10)


### Features

* **command:** add CommandSpec::raw_output for verbatim stdout commands
([#92](#92))
([84b0f00](84b0f00))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants