Skip to content

add command.Spec and command.Invocation types (PRINFRA-121) - #5

Merged
somanshreddy merged 1 commit into
mainfrom
03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor
Mar 31, 2026
Merged

somanshreddy merged 1 commit into
mainfrom
03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor

Conversation

@somanshreddy

@somanshreddy somanshreddy commented Mar 31, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Introduces the two core types that power every CLI command — generated or hand-written.

command.Spec is the immutable definition of a command. It describes what the command is: its API endpoint, HTTP method, flags, positional args, and behavioral metadata like pagination. Generated from the OpenAPI spec at build time, never mutated at runtime.

command.Invocation is the per-run resolved values — what the user actually typed. Path params, query params, and request body fields. Built fresh each time a command executes.

These two types have a hard boundary: Spec holds static metadata, Invocation holds runtime values. No field appears in both. This prevents the kind of drift where transport and presentation concerns get mixed in one struct (which was happening with the old RequestSpec).

-d/--data support in BuildInvocation: Some API endpoints require complex input types (discriminated unions, nested objects, arrays of objects) that can't be expressed as CLI flags. Every major CLI has an escape hatch for this — Stripe's -d, gh's --input, AWS's --cli-input-json. Ours is -d/--data. BuildInvocation handles the merge order when -d/--data is combined with flags: -d/--data loads first as the base, then positional args overlay, then flags overlay. Flag wins over -d/--data for the same field. This enables reusable JSON templates with per-invocation flag tweaks.

Validation: BuildInvocation validates enum values and int min/max bounds (from the OpenAPI spec) before the API call, returning exit code 2 (usage error) for invalid values.

Testing

15 unit tests covering: query param routing, body field routing, path/body/file positional args, unchanged flags omitted, enum validation (valid + invalid), min/max validation (5 subcases), -d/--data as base, flag overrides -d/--data, positional arg overrides -d/--data, nil body for query-only commands, string-slice flags.

Files

  • internal/command/spec.go — Spec, Invocation, ArgSpec, FlagSpec, PollConfig, Column types + BuildInvocation
  • internal/command/spec_test.go — 15 unit tests

somanshreddy commented Mar 31, 2026 •

Copy link
Copy Markdown
Collaborator Author

@linear

linear Bot commented Mar 31, 2026

Copy link
Copy Markdown
PRINFRA-121 CLI M1: OpenAPI codegen pipeline

Build the code generation pipeline that reads openapi/external-api.json and produces CommandSpec structs.

Scope

  • Go program in codegen/ using text/template
  • Parse OpenAPI spec, filter to v3 endpoints only
  • Generate CommandSpec data structs in gen/ (zero logic)
  • overrides.yaml for:
    • Positional arg promotion (prompt, text, file)
    • Command group naming (video-translations → translate, webhooks/endpoints → webhook)
    • Help examples per command
  • make generate SPEC=... target
  • Nested path collapsing (e.g., /webhooks/endpoints/{id}/rotate-secret → webhook rotate-secret)
  • Golden file tests for codegen output stability
  • Generate all ~30 commands, wire into Cobra at startup

Mapping Rules

  • OpenAPI tag → command group
  • POST → create, GET (list) → list, GET (by id) → get, DELETE → delete, PATCH → update
  • Path params → positional args, query params → flags, body fields → flags
  • overrides.yaml exceptions for positional promotion and group naming

Acceptance Criteria

  • make generate produces compilable CommandSpec files for all v3 endpoints
  • Adding a new endpoint to spec + re-running codegen produces new command
  • Generated help text includes descriptions and examples
  • Golden file tests pass
  • Override validation: make generate fails if overrides reference non-existent endpoints

Comment thread internal/command/spec.go
Comment thread internal/command/spec.go
Comment thread internal/command/spec.go
}

// PollConfig defines how --wait polling works for async commands.
type PollConfig struct {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

TODO: Will work on this in a future PR. Will have a better idea of the data structures then

Comment thread internal/command/spec.go
}

// Column defines a TUI table column for --human output.
type Column struct {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Future work

@somanshreddy
somanshreddy force-pushed the 03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor branch from 9e74e48 to bb1119f Compare March 31, 2026 21:06
@somanshreddy
somanshreddy marked this pull request as ready for review March 31, 2026 21:10
@somanshreddy
somanshreddy requested a review from jrusso1020 March 31, 2026 21:13
@somanshreddy
somanshreddy force-pushed the 03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor branch from bb1119f to 1b0e167 Compare March 31, 2026 21:25
New internal/command package with the core type system for generated
commands. Spec is the immutable definition (endpoint, method, flags,
args, behavioral metadata). Invocation holds per-run resolved values
(path params, query params, body). BuildInvocation handles merge order:
--json-body first, then positional args, then flags overlay.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@somanshreddy
somanshreddy force-pushed the 03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor branch from 1b0e167 to 5c35595 Compare March 31, 2026 21:55

somanshreddy commented Mar 31, 2026 •

Copy link
Copy Markdown
Collaborator Author

Merge activity

  • Mar 31, 10:38 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Mar 31, 10:38 PM UTC: @somanshreddy merged this pull request with Graphite.

@somanshreddy
somanshreddy merged commit 40b44e2 into main Mar 31, 2026
9 checks passed
@somanshreddy
somanshreddy deleted the 03-31-add_command.spec_command.invocation_types_generic_builder_refactor_executor branch March 31, 2026 22:38
@somanshreddy somanshreddy added this to the M1: Codegen Pipeline milestone Apr 3, 2026
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.

2 participants