From 616c8c415178e40b4f4f8851fc49c464e71e4f99 Mon Sep 17 00:00:00 2001
From: "sentry-junior[bot]"
<264270552+sentry-junior[bot]@users.noreply.github.com>
Date: Tue, 3 Nov 2026 23:15:15 +0000
Subject: [PATCH 1/9] ref(cli): Read output fields from generated data, not
schemas
Closes #1914 (parts 2 and 3; part 1, the manifest, was #1918).
Command output schemas move to build-only `src/output-schemas/.ts`,
one module per top-level command. `script/generate-output-schemas.ts`
(part of `generate:docs`, listed in `ensure-generated.mjs`) imports each
module through tsx, reads every exported valibot `...Schema` with the
field extraction that used to run at startup (now
`script/lib/output-schema-fields.ts`), and writes its fields and
`--fields` paths to the gitignored `src/generated/output-schemas/.ts`
under the same export name.
- Commands import that data as `output.schema` and only types from
`src/output-schemas/`, so a run loads its own route's field lists and
none of the schemas. The data is typed `OutputSchemaFields`,
so `SchemaMatches` still checks a command's data against its schema.
- `buildFieldsFlag`, `enrichDocsWithSchema` and `buildCommand` read
`schema.fields` / `schema.paths`; commands carry `__jsonFields` instead
of `__jsonSchema`, read by `introspect.ts` and `generate-sdk.ts`.
- Schemas that also validate API responses (`SentryLogSchema`,
`TransactionListItemSchema`, `ConversationListItemSchema`,
`DashboardRevisionSchema`) stay put and are re-exported.
- Org-scoped lists pass the item schema (`orgListItemSchema(Entity)`),
built in `src/output-schemas/`.
- New lint rule `sentry-cli/no-runtime-output-schema-imports` rejects
value imports of `src/output-schemas/` from runtime code, including
`import { type X }`, which `verbatimModuleSyntax` keeps.
Help, `help --json`, `--fields` parsing and completion, the skill files
and the docs pages are byte-identical to main; the SDK files differ only
in a comment naming `__jsonFields`.
---
.oxlintrc.json | 1 +
packages/cli/AGENTS.md | 31 +-
packages/cli/lint-rules/cli-oxlint-plugin.js | 30 +
packages/cli/package.json | 3 +-
packages/cli/script/ensure-generated.mjs | 1 +
.../cli/script/generate-output-schemas.ts | 102 +++
packages/cli/script/generate-sdk.ts | 20 +-
.../cli/script/lib/output-schema-fields.ts | 228 ++++++
.../src/commands/agent-conversation/list.ts | 6 +-
.../cli/src/commands/alert/issues/create.ts | 10 +-
.../cli/src/commands/alert/issues/delete.ts | 6 +-
.../cli/src/commands/alert/issues/edit.ts | 6 +-
.../cli/src/commands/alert/metrics/create.ts | 10 +-
.../cli/src/commands/alert/metrics/delete.ts | 6 +-
.../cli/src/commands/alert/metrics/edit.ts | 6 +-
packages/cli/src/commands/auth/list.ts | 2 +-
packages/cli/src/commands/dashboard/create.ts | 20 +-
packages/cli/src/commands/dashboard/list.ts | 6 +-
.../cli/src/commands/dashboard/restore.ts | 15 +-
.../cli/src/commands/dashboard/revisions.ts | 6 +-
packages/cli/src/commands/dashboard/view.ts | 8 +-
.../cli/src/commands/dashboard/widget/add.ts | 2 +-
.../src/commands/dashboard/widget/delete.ts | 2 +-
.../cli/src/commands/dashboard/widget/edit.ts | 2 +-
packages/cli/src/commands/event/list.ts | 2 +-
packages/cli/src/commands/event/view.ts | 8 +-
packages/cli/src/commands/feedback/list.ts | 7 +-
packages/cli/src/commands/feedback/resolve.ts | 2 +-
packages/cli/src/commands/feedback/spam.ts | 2 +-
.../cli/src/commands/feedback/unresolve.ts | 2 +-
packages/cli/src/commands/feedback/view.ts | 2 +-
packages/cli/src/commands/integration/list.ts | 10 +-
packages/cli/src/commands/issue/events.ts | 2 +-
packages/cli/src/commands/issue/list.ts | 7 +-
packages/cli/src/commands/issue/tags.ts | 19 +-
packages/cli/src/commands/issue/view.ts | 2 +-
packages/cli/src/commands/log/list.ts | 2 +-
packages/cli/src/commands/monitor/list.ts | 7 +-
packages/cli/src/commands/org/list.ts | 80 +-
packages/cli/src/commands/org/view.ts | 2 +-
packages/cli/src/commands/project/list.ts | 6 +-
packages/cli/src/commands/project/view.ts | 26 +-
packages/cli/src/commands/release/archive.ts | 6 +-
packages/cli/src/commands/release/create.ts | 45 +-
packages/cli/src/commands/release/delete.ts | 23 +-
packages/cli/src/commands/release/deploy.ts | 37 +-
packages/cli/src/commands/release/deploys.ts | 3 +-
packages/cli/src/commands/release/finalize.ts | 32 +-
packages/cli/src/commands/release/list.ts | 30 +-
packages/cli/src/commands/release/restore.ts | 6 +-
.../cli/src/commands/release/set-commits.ts | 3 +-
packages/cli/src/commands/release/view.ts | 3 +-
packages/cli/src/commands/replay/list.ts | 7 +-
packages/cli/src/commands/replay/view.ts | 2 +-
packages/cli/src/commands/repo/list.ts | 10 +-
packages/cli/src/commands/span/list.ts | 2 +-
packages/cli/src/commands/team/list.ts | 7 +-
packages/cli/src/commands/trace/list.ts | 6 +-
packages/cli/src/commands/trial/list.ts | 47 +-
packages/cli/src/lib/command.ts | 26 +-
packages/cli/src/lib/db/accounts.ts | 2 +-
packages/cli/src/lib/formatters/dashboard.ts | 2 +-
packages/cli/src/lib/formatters/issue.ts | 3 +-
packages/cli/src/lib/formatters/output.ts | 261 +-----
packages/cli/src/lib/formatters/replay.ts | 2 +-
packages/cli/src/lib/formatters/trace.ts | 2 +-
packages/cli/src/lib/introspect.ts | 18 +-
packages/cli/src/lib/list-command.ts | 3 +-
packages/cli/src/lib/org-list.ts | 56 +-
.../src/{types => output-schemas}/account.ts | 0
.../src/output-schemas/agent-conversation.ts | 7 +
.../alert.ts} | 3 +-
packages/cli/src/output-schemas/dashboard.ts | 138 ++++
packages/cli/src/output-schemas/event.ts | 143 ++++
packages/cli/src/output-schemas/feedback.ts | 113 +++
.../cli/src/output-schemas/integration.ts | 52 ++
packages/cli/src/output-schemas/issue.ts | 211 +++++
packages/cli/src/output-schemas/log.ts | 7 +
packages/cli/src/output-schemas/monitor.ts | 120 +++
packages/cli/src/output-schemas/org-list.ts | 29 +
packages/cli/src/output-schemas/org.ts | 117 +++
.../src/{types => output-schemas}/output.ts | 5 +-
packages/cli/src/output-schemas/project.ts | 84 ++
packages/cli/src/output-schemas/release.ts | 195 +++++
packages/cli/src/output-schemas/replay.ts | 148 ++++
packages/cli/src/output-schemas/repo.ts | 50 ++
packages/cli/src/output-schemas/span.ts | 39 +
packages/cli/src/output-schemas/team.ts | 57 ++
packages/cli/src/output-schemas/trace.ts | 7 +
packages/cli/src/output-schemas/trial.ts | 45 ++
packages/cli/src/types/dashboard.ts | 90 +--
packages/cli/src/types/feedback.ts | 116 +--
packages/cli/src/types/index.ts | 34 +-
packages/cli/src/types/replay.ts | 135 +---
packages/cli/src/types/sentry.ts | 745 +-----------------
packages/cli/test/commands/span/list.test.ts | 5 +-
packages/cli/test/lib/api/monitors.test.ts | 2 +-
.../cli/test/lib/formatters/output.test.ts | 25 -
.../test/script/output-schema-fields.test.ts | 26 +
99 files changed, 2236 insertions(+), 1873 deletions(-)
create mode 100644 packages/cli/script/generate-output-schemas.ts
create mode 100644 packages/cli/script/lib/output-schema-fields.ts
rename packages/cli/src/{types => output-schemas}/account.ts (100%)
create mode 100644 packages/cli/src/output-schemas/agent-conversation.ts
rename packages/cli/src/{commands/alert/output-schemas.ts => output-schemas/alert.ts} (98%)
create mode 100644 packages/cli/src/output-schemas/dashboard.ts
create mode 100644 packages/cli/src/output-schemas/event.ts
create mode 100644 packages/cli/src/output-schemas/feedback.ts
create mode 100644 packages/cli/src/output-schemas/integration.ts
create mode 100644 packages/cli/src/output-schemas/issue.ts
create mode 100644 packages/cli/src/output-schemas/log.ts
create mode 100644 packages/cli/src/output-schemas/monitor.ts
create mode 100644 packages/cli/src/output-schemas/org-list.ts
create mode 100644 packages/cli/src/output-schemas/org.ts
rename packages/cli/src/{types => output-schemas}/output.ts (86%)
create mode 100644 packages/cli/src/output-schemas/project.ts
create mode 100644 packages/cli/src/output-schemas/release.ts
create mode 100644 packages/cli/src/output-schemas/replay.ts
create mode 100644 packages/cli/src/output-schemas/repo.ts
create mode 100644 packages/cli/src/output-schemas/span.ts
create mode 100644 packages/cli/src/output-schemas/team.ts
create mode 100644 packages/cli/src/output-schemas/trace.ts
create mode 100644 packages/cli/src/output-schemas/trial.ts
create mode 100644 packages/cli/test/script/output-schema-fields.test.ts
diff --git a/.oxlintrc.json b/.oxlintrc.json
index 7bc2fbad1..18ac71c5a 100644
--- a/.oxlintrc.json
+++ b/.oxlintrc.json
@@ -100,6 +100,7 @@
"sentry-cli/no-examples-in-full-description": "error",
"sentry-cli/no-regex-markdown-parsing": "error",
"sentry-cli/json-transform-uses-fields": "error",
+ "sentry-cli/no-runtime-output-schema-imports": "error",
"no-restricted-imports": [
"error",
{
diff --git a/packages/cli/AGENTS.md b/packages/cli/AGENTS.md
index ea2829268..ce438b02d 100644
--- a/packages/cli/AGENTS.md
+++ b/packages/cli/AGENTS.md
@@ -232,29 +232,46 @@ Lint enforcement: `stderr.write()` is banned in command files (GritQL rule). Use
`output.schema` drives `--fields` completion, the JSON field table in `--help`, and the skill references. Nothing validates output against it, so declare each field once and derive the TypeScript type from the schema; the compiler then keeps the two in sync ([#1824](https://github.com/getsentry/toolkit/issues/1824)).
+The schemas live in `src/output-schemas/.ts` (one module per top-level command), which only the build loads ([#1914](https://github.com/getsentry/toolkit/issues/1914)). `script/generate-output-schemas.ts` (part of `generate:docs`) reads each exported `…Schema` and writes its field list and `--fields` paths to the gitignored `src/generated/output-schemas/.ts`, under the same export name. A command imports that data as its `output.schema`, so a run loads only its own route's field lists, and none of the schemas:
+
+- Import the schema data from `src/generated/output-schemas/`, and everything else from `src/output-schemas/` with `import type` only. Lint (`sentry-cli/no-runtime-output-schema-imports`) rejects a value import, or `import { type X }`, which `verbatimModuleSyntax` keeps as a runtime import.
+- Export the type the command needs next to its schema (`export type ReleaseDeleteOutput = InferOutput`), or `import type` the schema and write `typeof`.
+- A schema that also validates an API response at runtime (`SentryLogSchema`, `TransactionListItemSchema`, `ConversationListItemSchema`, `DashboardRevisionSchema`) stays where it is and is re-exported from its area's module.
+- `src/output-schemas/` must not import `src/generated/output-schemas/`: the generator loads the former to write the latter.
+
- **API fields** keep their `@sentry/api` type and come from the generated `@sentry/api/valibot` schema (`vXxxResponse.entries`, wrapped in `pipe(field, description(…))` when it needs a description).
-- **Fields the CLI adds** (target context such as `org`/`orgSlug`, flags such as `dryRun`/`deleted`, computed values such as `url`, `trace`, `period`) are written once as a valibot `object` of output fields. Spread its `entries` into the schema, and get the type with `InferOutput`, or `WithOutputFields` (`src/types/output.ts`) when the fields sit on (or override) an API object.
+- **Fields the CLI adds** (target context such as `org`/`orgSlug`, flags such as `dryRun`/`deleted`, computed values such as `url`, `trace`, `period`) are written once as a valibot `object` of output fields. Spread its `entries` into the schema, and get the type with `InferOutput`, or `WithOutputFields` (`src/output-schemas/output.ts`) when the fields sit on (or override) an API object.
- Type the `human` formatter's parameter (and `jsonTransform`'s, when set) with the derived type. `buildCommand`, `buildListCommand`, and `buildDeleteCommand` infer the output type from `output` and check every `CommandOutput` that `func` yields against it. Annotate a yield (`new CommandOutput