Skip to content

feat: Add OpenCLIDescriber interface to expose a command's OpenCLI metadata#58

Merged
boblail merged 1 commit into
mainfrom
lail/opencli-describer
Jul 17, 2026
Merged

feat: Add OpenCLIDescriber interface to expose a command's OpenCLI metadata#58
boblail merged 1 commit into
mainfrom
lail/opencli-describer

Conversation

@boblail

@boblail boblail commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

Commands discovered via the OpenCLIContract parse a rich --help-opencli document (arguments, options, descriptions, examples, exit codes, hidden/interactive flags, ...), but until now that metadata was discarded — the Command interface only exposed name/summary/aliases/defaultCommand/subcommands. Consumers (e.g. the sq entrypoint) could therefore only reproduce a stripped-down OpenCLI document for commands they discover.

This adds an optional companion interface, OpenCLIDescriber, that surfaces each node's OpenCLI metadata, following the same pattern as ContractReporter (#57): the Command interface is unchanged, and consumers type-assert a discovered command to reach the richer data.

if d, ok := cmd.(exoskeleton.OpenCLIDescriber); ok {
    if c, _ := d.OpenCLICommand(); c != nil {
        // c.Arguments, c.Options, c.Description, c.Examples, ...
    }
}

Details

  • commandDescriptor gains an unexported openCLI *opencli.Command field, populated by opencliToDescriptor for every node in the tree. Its Commands field is stripped — children remain reachable via Subcommands(), keeping a single source of truth for the tree.
  • executableCommand threads that metadata through discover()/toCommands() and implements OpenCLICommand(). It returns nil (not a synthesized fallback) for commands discovered via any other contract.
  • OpenCLICommand() returns a copy describing only the node; its Commands field is not populated.
  • No change to the Command interface. Built-in commands do not implement OpenCLIDescriber.

Test plan

  • go test ./...
  • gofmt -l . / goimports -l . / go vet ./... clean
  • New tests: TestOpenCLICommandExposesMetadata (root + hidden subcommand carrying options/arguments/hidden), TestOpenCLICommandForNonOpenCLIContract (returns nil)
  • End-to-end verified against the sq entrypoint: sq <cmd> --help-opencli now reproduces the full OpenCLI document emitted by the underlying binary

…metadata

Commands discovered via the OpenCLI contract now retain their node-local
OpenCLI metadata (arguments, options, description, examples, exit codes,
hidden, interactive, ...) captured from `--help-opencli`. The new optional
`OpenCLIDescriber` interface surfaces it, mirroring the `ContractReporter`
pattern: consumers type-assert a discovered Command and call `OpenCLICommand()`.

`OpenCLICommand()` returns nil for commands discovered via other contracts.
The returned Command describes only its own node; its Commands field is not
populated, so callers walk Subcommands() to describe the tree.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@boblail
boblail merged commit f659546 into main Jul 17, 2026
4 checks passed
@boblail
boblail deleted the lail/opencli-describer branch July 17, 2026 20:28
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.

1 participant