Generate CLI output schemas from command output types

Fermée
#1,824 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Une pull request liée a déjà été fusionnée.

  • #1830 par @sentry-junior — fusionnée

Évaluation

Difficulté
5/5
Temps estimé
Plus d'une semaine
Accessibilité débutants
12/100
Type d'issue
Refactorisation
Clarté
Plutôt claire
Activité
À l'abandon
Stack technique
typescript
Domaine
cli, tooling

Piste de recherche

Start with packages/cli/src/commands/alert/output-schemas.ts to see how API fields and hand-written CLI fields are declared alongside the TypeScript output types. The existing completion-target and command-api generators are the model for any build step, and packages/cli/AGENTS.md is where the new declaration convention would be documented. This is design work, and PR #1830 is already open against it, so pick it up only after confirming with maintainers which option is chosen.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

CLI

Problem

Command output schemas (OutputConfig.schema) drive --fields completion, the JSON field tables in --help, and the generated skill references. Since #1783, the fields that come from the Sentry API are taken from the generated @sentry/api/valibot response schemas (for example packages/cli/src/commands/alert/output-schemas.ts). Fields the CLI adds itself are still written by hand, next to a TypeScript output type that describes the same data:

  • target context: org, project, orgSlug, targetProject
  • status and result flags: the alert status label, deleted, dryRun (DryRunOutputField)
  • computed values: dsn, url, dashboard period/fetchedAt, widget data

So every command declares its JSON output twice: once as the TypeScript type its func yields and output.human consumes, and once as a valibot schema. Nothing checks that the two agree. The schema is documentation only (nothing validates output against it), so drift goes unnoticed. A field added to the type silently stops completing, and a renamed field keeps completing a path that no longer exists. Raised by @BYK in https://github.com/getsentry/toolkit/pull/1783#discussion_r4448809546 ("Shouldn't this be auto-generated?").

Goal

One source of truth per command's JSON output: the API part from @sentry/api, and the CLI-added part derived from the command's output type instead of written by hand.

Options

  1. Generate schemas from TypeScript types at build time. Add a generate:* step, like the existing completion-target and command-api generators, that reads each command's declared output type and emits a valibot (or plain field-path) description. Candidates: the TS compiler API, or a types-to-schema tool. Descriptions would come from TSDoc on the type's properties.
    • Pros: types stay the source of truth, and descriptions sit next to the fields.
    • Cons: output types are often inferred or built from Pick/intersections over SDK types. The generator has to resolve those, and it has to know which type belongs to which command.
  2. Invert it: schema first, types derived. Write the CLI-added entries once as valibot and derive the TS type with InferOutput<typeof Schema>, so func's return type and output.human's parameter come from the schema.
    • Pros: no new generator, and the compiler enforces that the two agree.
    • Cons: valibot becomes the authoring format for output types, which means touching many commands.
  3. Keep both, add a type-level check. Keep hand-written schemas, but add a compile-time assertion per command, e.g. Expect<Equal<keyof InferOutput<typeof Schema>, keyof Output>>, or a test that compares field paths.
    • Pros: smallest change.
    • Cons: still two copies to maintain, and only drift is caught.

Option 2 looks like the best fit for buildCommand. Option 1 is worth it only if descriptions can come from TSDoc reliably.

Dependencies

  • Descriptions for API fields need the upstream change from the #1783 plan: @sentry/api's generated valibot has no v.description() actions today, so the CLI wraps generated fields in pipe(field, description(...)) by hand. Until that lands, this issue only covers the CLI-added fields.
  • Related: #1387 (migrate fully to @sentry/api SDK types), and #1808 / the sentry-cli/json-transform-uses-fields lint rule (jsonTransform must apply fields).

Done when

  • No command's output schema writes out by hand a field that also exists in its TypeScript output type, or a test/compile error fails when they diverge.
  • --fields completion, --help field tables and the skill references keep working unchanged, and the generated docs don't change unexpectedly.
  • packages/cli/AGENTS.md documents how to declare output for a new command.

via @BYK.

--

View Session in Sentry

Langage dominant
TypeScript
Étoiles
957
Forks
174
Merge moyen
13 h 16 min
PR mergées (30 j)
407

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de getsentry/toolkit

Toutes les issues de getsentry/toolkit

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.