Skip to content

feat(cli): derive catalog defaults and validate enum groups - #66

Open
TristanSpeakEasy wants to merge 8 commits into
mainfrom
feat/cli-catalog-defaults-groups
Open

TristanSpeakEasy wants to merge 8 commits into
mainfrom
feat/cli-catalog-defaults-groups

Conversation

@TristanSpeakEasy

@TristanSpeakEasy TristanSpeakEasy commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Why

Offline enum catalogs support a scalar default and a flat list, but shared enums also need to show which values command presets select and organise options into sections. Command defaults should come from the commands themselves, rather than a second configuration that can drift.

What changed

  • Derive default_for from effective command and route presets in Go, following the bound schema through references, composition and array items. Different route defaults use the actual selector in their labels; defaults shared by every route use the plain command name.
  • Add schema-level x-speakeasy-enum-groups, accepting a sparse value-to-title map or positional string list. Go validates malformed shapes, non-string titles, unknown values, duplicate map keys and list lengths instead of silently dropping invalid input.
  • Preserve enum order within groups and order sections by their first enum member. Ungrouped values join a trailing fallback Other section only when an explicit group exists. If a group is already titled Other, merge the remainder into it in enum order without moving the declared section or creating a duplicate heading.
  • Preserve scalar catalog default, its machine-output boolean, legacy flat output and spacing when the new metadata is absent. Replace this PR's proposed nested catalog defaults and groups keys with presets and the enum extension.
  • Update documentation, fixtures, human/JSON assertions and the CLI changeset, including coverage for an explicit non-trailing Other group. The independent PHP fix was merged in fix(php): qualify enum defaults in model constructors #71; this PR has no PHP or permissions-file diff against main. Review SDK generation has no catalog output changes.

Configuration and output example

Given a request property choice referencing this enum:

WidgetChoice:
  type: string
  enum: [alpha, beta, gamma, delta]
  x-speakeasy-enum-groups:
    alpha: Primary
    beta: Primary
    gamma: Secondary
  x-speakeasy-cli-catalog:
    command: widget-options

Commands declare their defaults once, through presets:

x-speakeasy-cli-commands:
  version: 1
  commands:
    create-widget:
      op: createWidget
      preset: {$.choice: alpha}
    inspect-widget:
      op: createWidget
      preset: {$.choice: gamma}

cli widget-options displays:

Primary:
  alpha (default: create-widget)
  beta

Secondary:
  gamma (default: inspect-widget)

Other:
  delta

Each enum member is one CliCatalogValue row. CliCatalog.Groups collects those same rows into human-output sections; CliCatalog.Values flattens them in the same section order for machine output. Group titles do not alter enum values or request bodies.

JSON remains a flat array. For example, the first row contains value: "alpha", default: false, default_for: ["create-widget"] and group: "Primary". Only an explicit scalar catalog default changes the existing default boolean.

A positional group list must match the original enum declaration, including null and duplicate slots. Null slots create no rows; duplicate values use their first non-empty title. Empty titles and omitted map entries are ungrouped. SDK enum-description rendering is outside this change.

Testing

  • go test ./internal/extensions ./internal/validation ./internal/schemas ./internal/ast -count=1 passed, including schema association, route overrides, union ambiguity, enum-group validation and metadata equality/clone checks.
  • Primary CLI generation, compilation and staticcheck passed. After merging main, ./scripts/test-target.sh cli primary passed with 1,584 tests. Focused catalog tests also passed with go test -C testSDKs/sdk-cli-primary ./tests -run '^TestCatalog' -count=1 -v.
  • Review CLI generation, compilation and staticcheck passed. ./scripts/test-target.sh cli review passed with 589 tests and two existing skips.
  • Human and JSON catalog smoke checks passed. npm run format, all template TypeScript checks, both module tidy checks and git diff --check passed.
  • make lint is blocked by local permissions generation. After restoring the generated file, running golangci-lint directly reports only the existing gofmt complaint in unchanged templates/perms.go. No permissions-file changes are included. The full cross-target runtime matrix was not run locally; CI checks are pending.

Public-safety check

  • This change contains no credentials, customer documents, private repository URLs, private filesystem paths, or unredacted private logs.
  • Title, body, comments, and commit messages name no customers or customer-derived identifiers, private paths or trackers, or workflow provenance, and are understandable without private context (.claude/skills/public-repo-communication/SKILL.md).
  • Generated fixtures and review SDK changes are public-safe.
  • I reviewed git diff --check.

@TristanSpeakEasy
TristanSpeakEasy requested a review from a team as a code owner October 2, 2026 03:10
@TristanSpeakEasy TristanSpeakEasy added the enhancement New feature or request label Oct 2, 2026
@TristanSpeakEasy TristanSpeakEasy added the enhancement New feature or request label Oct 2, 2026

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 6 files

Shadow auto-approve: would not auto-approve because issues were found.

Fix all with cubic | Re-trigger cubic

Comment thread templates/templates/cli/includes/templating.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 1 file (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Adds optional per-command defaults and ordered groups to generated CLI enum catalogs, gated so existing output is unchanged; tests cover legacy, grouped, and malformed cases, and invalid groups fall back to Other.

Re-trigger cubic

@TristanSpeakEasy

Copy link
Copy Markdown
Member Author

Catalog normalization updated in dd77aea:

  • Trim command names and group titles.
  • Omit groups with empty, unknown-only or already-claimed values.
  • If no declared group matches, retain flat schema-order output without an Other heading or JSON group fields. Invalid groups already retained all enum values; this changes their presentation.
  • Base dynamic widths on resolved defaults and groups, so ineffective metadata preserves legacy spacing.

Added human and JSON assertions for these cases, including a long-label fixture that checks exact legacy spacing, and updated the documentation.

Validation passed: primary CLI generation, compilation and staticcheck; focused catalog tests; template type-check; formatting and diff checks; and human-output smoke checks. The full test matrix is left to CI. Full repository lint was not repeated because the existing local permissions-file formatting failure is unchanged.

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 4 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Adds optional per-command defaults and ordered groups to generated CLI enum catalogs, with tests, docs, changeset, and a release-workflow version-check snapshot; existing output is preserved when the new options are unused.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 4 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Adds optional per-command defaults and ordered groups to CLI enum catalogs while preserving legacy output when unused, fixes PHP constructor enum default namespace qualification with a regression test, and adds a release-tag version guard; all changes are additive or corrective with test coverage.

Re-trigger cubic

@AshGodfrey AshGodfrey left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  • The PHP enum-default qualification fix (php/includes/sanitization.ts, php/includes/templating.ts, the PHP test, and the second changeset) is an independent bug fix with its own changelog entry. It is correct as far as I can tell, since usageLocation already exists on TemplateValueContext, but it should probably land in its own PR so the PHP changelog entry and any revert are not tied to a CLI feature.
  • testSharedEnumConstructorDefault does not call CommonHelpers::recordTest, unlike the other tests in that file.

Comment thread templates/templates/cli/includes/templating.ts
@AshGodfrey
AshGodfrey self-requested a review October 2, 2026 13:06
@ThomasRooney

Copy link
Copy Markdown
Member

Propose this refinement in configuration:

  1. default is calculated based on preset in each command, rather than doubly specified. To make this work, would recommend the logic lives on the go side similar to where we evaluate which openapi node is associated with the expression.
  2. x-speakeasy-enum-groups is created inline with the x-speakeasy-enum-descriptions extension, with linting / validation for this living on the go side to avoid generating invalid inputs (rather than drop them). This would simplify the test cases and DX significantly, and also be something we could do to improve SDK-generated enum descriptions..

@ThomasRooney ThomasRooney left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Temporarily blocking this with proposals for improved interface to reach same functionality. Non-blocking though: happy for push-back / review dismissal if you disagree.

@TristanSpeakEasy

Copy link
Copy Markdown
Member Author

@AshGodfrey, the PHP enum-constructor fix from your review is now in #71 and removed from this PR in bfe14f5. Its changeset is included only in #71.

The regression test now uses an independent enum-default fixture, calls CommonHelpers::recordTest, and is registered and enabled in the PHP coverage inventory. The focused test passes with both the default and explicit alternate value. Primary/review generation, PHPStan, Pint and PHP template checks passed.

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 4 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Adds optional per-command defaults and ordered groups to generated CLI enum catalogs, preserving legacy output when unused, with tests/docs, plus a CI release-tag version guard. Additive, tested, bounded; the PHP fix was reverted.

Re-trigger cubic

@TristanSpeakEasy TristanSpeakEasy changed the title feat(cli): add catalog command defaults and groups feat(cli): derive catalog defaults and validate enum groups Oct 5, 2026
@TristanSpeakEasy

Copy link
Copy Markdown
Member Author

@ThomasRooney, implemented the interface proposed in your comment in 09dfd39:

  • Command-specific catalog defaults now come from effective command/route presets. Go follows the bound schema through refs, composition and array items rather than matching property names or enum values across catalogs. Route-specific defaults include the actual selector; shared defaults use the plain command name.
  • Groups now use the schema-level x-speakeasy-enum-groups extension, with sparse map and positional list forms. Go validation rejects unknown values, duplicate map keys, wrong list lengths, non-string titles and malformed shapes. Titles are trimmed, groups follow enum order, and unmatched values go under Other only when an explicit group exists.
  • The existing scalar catalog default and machine default boolean remain unchanged. default_for comes only from presets. The proposed nested catalog defaults/groups keys are no longer accepted.
  • The PR description and CLI documentation now include configuration/output examples and explain how the row list and grouped view relate. SDK enum-description rendering is outside this change.

Validation: focused Go suites, primary/review CLI generation and staticcheck, 1,455 primary runtime tests, 547 review tests (two existing skips), and regenerated catalog tests passed. Repository lint still fails only on the existing gofmt complaint in unchanged templates/perms.go. The primary full run preceded the final Go corrections; focused Go and regenerated catalog checks passed afterwards. CI checks are pending.

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 19 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.
Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread templates/templates/cli/includes/templating.ts Outdated
Comment thread templates/templates/cli/README.md Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

0 issues found across 4 files (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would auto-approve. Adds extension-gated enum grouping and preset-derived defaults without changing legacy output. Validation confirms the previously identified issues are fixed.

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants