Skip to content

feat(cli): support reading spec from stdin via --file -#555

Merged
jdx merged 3 commits intomainfrom
feat/stdin-spec-input
Mar 22, 2026
Merged

feat(cli): support reading spec from stdin via --file -#555
jdx merged 3 commits intomainfrom
feat/stdin-spec-input

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Mar 22, 2026

Summary

  • Adds support for --file - to read specs from stdin on all generate subcommands, lint, and complete-word
  • Enables piping specs from other tools (e.g., jbang usage | usage generate markdown --file -)
  • Updates --file help text to document stdin support
  • Not supported for exec/shell subcommands which pass stdin through to the child process

Closes #546

Test plan

  • echo 'name "test" flag "-v --verbose" help="verbose"' | usage generate json --file - produces valid JSON output
  • Verify --file /path/to/file still works as before
  • Verify usage generate markdown --file - --out-file out.md works with piped input

🤖 Generated with Claude Code


Note

Low Risk
Low-risk CLI enhancement that only affects how usage specs are read when --file is set to -; primary risk is unintended behavior changes for edge-case file paths or stdin handling.

Overview
Adds support for piping a usage spec via stdin by treating --file - as “read spec from stdin” across complete-word, generate completion/manpage/markdown, and lint (via new shared helpers in cli/src/cli/generate/mod.rs).

Updates generated metadata/docs (usage.usage.kdl, manpage, reference JSON/markdown, Fig spec) to document the stdin behavior, and adjusts generated output labeling to use stdin instead of - where a source filename is surfaced (e.g., completion source_file and Fig @generated header).

Written by Cursor Bugbot for commit 98d3919. This will update automatically on new commits. Configure here.

jdx and others added 2 commits March 22, 2026 16:16
Allows passing "-" as the --file argument to read specs from stdin
on generate, lint, and complete-word subcommands. This enables piping
specs from other tools (e.g., `jbang usage | usage generate markdown --file -`).

Not supported for exec/shell subcommands which pass stdin through to
the child process.

Closes #546

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the usage CLI tool by adding support for reading usage specifications from stdin. This change allows users to pipe specifications from other tools directly into the CLI, improving workflow efficiency and integration capabilities. The update includes modifications to command-line argument parsing, documentation, and internal functions to handle the new input method.

Highlights

  • stdin Support: The pull request introduces the ability to read usage specifications from standard input (stdin) using the --file - option.
  • Command Compatibility: This feature is implemented for the generate, lint, and complete-word subcommands, enhancing their flexibility.
  • Documentation Updates: The help text for the --file option has been updated across various commands and documentation files to reflect the new stdin support.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Mar 22, 2026

Codecov Report

❌ Patch coverage is 29.62963% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.27%. Comparing base (00210b2) to head (98d3919).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
cli/src/cli/generate/mod.rs 38.46% 7 Missing and 1 partial ⚠️
cli/src/cli/generate/completion.rs 42.85% 2 Missing and 2 partials ⚠️
cli/src/cli/generate/fig.rs 0.00% 4 Missing ⚠️
cli/src/cli/generate/manpage.rs 0.00% 0 Missing and 1 partial ⚠️
cli/src/cli/generate/markdown.rs 0.00% 0 Missing and 1 partial ⚠️
cli/src/cli/lint.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #555      +/-   ##
==========================================
- Coverage   72.40%   70.27%   -2.14%     
==========================================
  Files          48       48              
  Lines        6830     7067     +237     
  Branches     6830     7067     +237     
==========================================
+ Hits         4945     4966      +21     
- Misses       1242     1325      +83     
- Partials      643      776     +133     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps
Copy link

greptile-apps bot commented Mar 22, 2026

Greptile Summary

This PR adds --file - stdin support to all spec-consuming subcommands (complete-word, lint, and all generate subcommands except exec/shell), enabling pipelines like jbang usage | usage generate markdown --file -.

Key changes:

  • Introduces parse_file_or_stdin(path) and updates file_or_spec in cli/src/cli/generate/mod.rs as the single authoritative routing point; all subcommands delegate to these helpers.
  • Makes the generate module pub(crate) so lint.rs can share the same helper without duplication.
  • Adds a consistent "stdin" label wherever a source-file path would otherwise appear in generated output (Fig prescript, completion source_file).
  • Updates all generated/documentation artifacts (man page, reference markdown, JSON, Fig spec) to match the new help text.
  • One pre-existing style opportunity in completion.rs: a Spec::default() is constructed for the None branch and immediately discarded by the subsequent match (see inline comment).

Confidence Score: 5/5

  • Safe to merge; the change is well-scoped, correctly implemented, and all generated artifacts are kept in sync.
  • The stdin routing logic is centralized in a single private helper, all callers are updated consistently, and the excluded subcommands (exec/shell) are intentionally left out with a clear rationale. The only note is a pre-existing minor redundancy in completion.rs that doesn't affect correctness.
  • No files require special attention.

Important Files Changed

Filename Overview
cli/src/cli/generate/mod.rs Adds the core parse_file_or_stdin helper and updates file_or_spec to route "-" to read_spec_from_stdin(); implementation is correct and well-centralized.
cli/src/cli/generate/completion.rs Updates completion generation to use parse_file_or_stdin; adds stdin-aware source_file label. Contains a pre-existing minor redundancy: Spec::default() is constructed for the None branch and immediately discarded by the second match.
cli/src/cli/generate/fig.rs Adds stdin-aware source label for the @generated comment header; correctly maps "-" to "stdin" in the prescript annotation.
cli/src/cli/lint.rs Imports parse_file_or_stdin from the newly-public generate module and uses it correctly for the positional <FILE> argument.
cli/src/cli/mod.rs Makes generate module pub(crate) so lint.rs can access the shared parse_file_or_stdin helper.

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI
    participant generate/mod.rs
    participant stdin
    participant Spec

    User->>CLI: usage generate <cmd> --file -
    CLI->>generate/mod.rs: file_or_spec(Some("-"), ...) OR parse_file_or_stdin("-")
    generate/mod.rs->>generate/mod.rs: file.as_os_str() == "-" ?
    generate/mod.rs->>stdin: read_to_string()
    stdin-->>generate/mod.rs: raw spec string
    generate/mod.rs->>Spec: input.parse()
    Spec-->>generate/mod.rs: Spec { ... }
    generate/mod.rs-->>CLI: Ok(Spec)
    CLI-->>User: generated output

    User->>CLI: usage generate <cmd> --file path/to/spec.kdl
    CLI->>generate/mod.rs: parse_file_or_stdin("path/to/spec.kdl")
    generate/mod.rs->>Spec: Spec::parse_file(path)
    Spec-->>generate/mod.rs: Spec { ... }
    generate/mod.rs-->>CLI: Ok(Spec)
    CLI-->>User: generated output
Loading

Comments Outside Diff (1)

  1. cli/src/cli/generate/completion.rs, line 49-56 (link)

    Redundant Spec::default() allocation

    When self.file is None, the first match constructs a Spec::default() that the immediately following match discards (setting spec back to None). The two matches can be collapsed into a single expression:

    This avoids the unnecessary heap allocation and makes the intent—"wrap the parsed spec in an Option, or None if no file was supplied"—immediately clear.

Fix All in Claude Code

Reviews (2): Last reviewed commit: "fix(cli): display "stdin" instead of "-"..." | Re-trigger Greptile

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for reading specs from stdin via --file -. This is achieved by adding a new helper function parse_file_or_stdin which is then used across various generate subcommands and the lint command. The changes also include updates to documentation, CLI help texts, and generated artifacts to reflect the new functionality. My review includes one suggestion to reduce code duplication by reusing the newly introduced helper function.

Comment on lines +44 to +48
if file.as_os_str() == "-" {
read_spec_from_stdin()
} else {
Spec::parse_file(file)
}

Choose a reason for hiding this comment

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

medium

This block of code duplicates the logic found in the newly introduced parse_file_or_stdin function. To improve maintainability and reduce code duplication, you can directly call parse_file_or_stdin here.

        parse_file_or_stdin(file)

When --file - is used, show "stdin" in generated file headers and
completion script comments instead of the raw "-" sentinel value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx merged commit 057b589 into main Mar 22, 2026
10 checks passed
@jdx jdx deleted the feat/stdin-spec-input branch March 22, 2026 16:33
jdx pushed a commit that referenced this pull request Mar 22, 2026
### 🚀 Features

- **(cli)** render all doc-related fields in --help output by
[@jdx](https://github.com/jdx) in
[#554](#554)
- **(cli)** support reading spec from stdin via --file - by
[@jdx](https://github.com/jdx) in
[#555](#555)

### 🐛 Bug Fixes

- **(zsh)** remove trailing space from completions and add directory
slash by [@jdx](https://github.com/jdx) in
[#556](#556)
- use field assignment for non-exhaustive Spec in benchmarks by
[@jdx](https://github.com/jdx) in
[#552](#552)

### 📦️ Dependency Updates

- update apple-actions/import-codesign-certs digest to fe74d46 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#550](#550)
- update codecov/codecov-action digest to 1af5884 by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#551](#551)
- lock file maintenance by
[@renovate[bot]](https://github.com/renovate[bot]) in
[#547](#547)
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.

support - for reading script from standard input

1 participant