Dashboard › › Session se6753febdbf
se6753febdbf6c197Continue
Let me look at the generate-skill.ts and the SKILL.md directly to understand the generation mechanism before designing the solution myself.
Let me find the actual file locations first.
/home/byk/Code/getsentry/cli/.github/workflows/generate-skill.yml /home/byk/Code/getsentry/cli/script/generate-skill.ts
/home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md /home/byk/Code/opencode/packages/opencode/test/fixture/skills/cloudflare/SKILL.md /home/byk/Code/opencode/packages/opencode/test/fixture/skills/agents-sdk/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/setup-dev/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/sentry-security/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/sentry-javascript-bugs/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/sentry-backend-bugs/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/hybrid-cloud-test-gen/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/hybrid-cloud-rpc/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/hybrid-cloud-outboxes/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/react-component-documentation/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/notification-platform/SKILL.md /home/byk/Code/getsentry/sentry/.agents/skills/migrate-frontend-forms/SKILL...
/home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/api.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/trials.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/traces.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/sourcemap.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/logs.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/events.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/issues.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/teams.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/projects.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/organizations.md /home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/dashboards.md /home/byk/Code/getsentry/cli/plug...
Good, now let me read the key files.
<path>/home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md</path> <type>file</type> <content>1: --- 2: name: sentry-cli 3: version: 0.21.0-dev.0 4: description: Guide for using the Sentry CLI to interact with Sentry from the command line. Use when the user asks about viewing issues, events, projects, organizations, making API calls, or authenticating with Sentry via CLI. 5: requires: 6: bins: ["sentry"] 7: auth: true 8: --- 9: 10: # Sentry CLI Usage Guide 11: 12: Help users interact with Sentry from the command line using the `sentry` CLI. 13: 14: ## Agent Guidance 15: 16: Best practices and operational guidance for AI coding agents using the Sentry CLI. 17: 18: ### Key Principles 19: 20: - **Prefer CLI commands over raw API calls** — the CLI has dedicated commands for most tasks. Reach for `sentry issue view`, `sentry issue list`, `sentry trace view`, etc. before constructing API calls manually or fetching external documentation. ...
<path>/home/byk/Code/getsentry/cli/plugins/sentry-cli/skills/sentry-cli/references/issues.md</path> <type>file</type> <content>1: --- 2: name: sentry-cli-issues 3: version: 0.21.0-dev.0 4: description: List, view, and analyze Sentry issues with AI 5: requires: 6: bins: ["sentry"] 7: auth: true 8: --- 9: 10: # Issue Commands 11: 12: Manage Sentry issues 13: 14: ### `sentry issue list <org/project>` 15: 16: List issues in a project 17: 18: **Flags:** 19: - `-q, --query <value> - Search query (Sentry search syntax)` 20: - `-n, --limit <value> - Maximum number of issues to list - (default: "25")` 21: - `-s, --sort <value> - Sort by: date, new, freq, user - (default: "date")` 22: - `-t, --period <value> - Time period for issue activity (e.g. ...
<path>/home/byk/Code/getsentry/cli/script/generate-skill.ts</path>
<type>file</type>
<content>1: #!/usr/bin/env bun
2: /**
3: * Generate Skill Files from Stricli Command Metadata and Docs
4: *
5: * Introspects the CLI's route tree and merges with documentation
6: * to generate structured documentation for AI agents.
7: *
8: * Produces:
9: * - SKILL.md: compact index with agent guidance + command summaries
10: * - references/*.md: full per-group command documentation
11: * - index.json: skill discovery manifest for .well-known
12: *
13: * Usage:
14: * bun run script/generate-skill.ts
15: *
16: * Output:
17: * plugins/sentry-cli/skills/sentry-cli/SKILL.md
18: * plugins/sentry-cli/skills/sentry-cli/references/*.md
19: * docs/public/.well-known/skills/index.json
20: */
21:
22: import { rmSync } from "node:fs";
23: import { routes } from "../src/app.js";
24: import type {
25: CommandInfo,
26: FlagInfo,
27: RouteInfo,
28: RouteMap,
29: } from ...
Now let me look at the commands overview doc that feeds the supplementary sections:
<path>/home/byk/Code/getsentry/cli/docs/src/content/docs/commands/index.md</path> <type>file</type> <content>1: --- 2: title: Commands Overview 3: description: Overview of all Sentry CLI commands 4: --- 5: 6: The Sentry CLI provides commands for interacting with various Sentry resources. 7: 8: ## Available Commands 9: 10: | Command | Description | 11: |---------|-------------| 12: | [`auth`](./auth/) | Authentication management | 13: | [`cli`](./cli/) | CLI-related commands (feedback, upgrade) | 14: | [`org`](./org/) | Organization operations | 15: | [`project`](./project/) | Project operations | 16: | [`team`](./team/) | Team operations | 17: | [`issue`](./issue/) | Issue tracking | 18: | [`event`](./event/) | Event inspection | 19: | [`log`](./log/) | Log viewing and streaming | 20: | [`api`](./api/) | Direct API access | 21: 22: ## Global Options 23: 24: All commands support the following global options: 25: 26: - `--help` - Show help for the command 27: - `--version` - Show ...
<path>/home/byk/Code/getsentry/cli/docs/src/content/docs/agent-guidance.md</path> <type>file</type> <content>1: --- 2: title: Agent Guidance 3: description: Operational guidance for AI coding agents using the Sentry CLI 4: --- 5: 6: Best practices and operational guidance for AI coding agents using the Sentry CLI. 7: 8: ## Key Principles 9: 10: - **Prefer CLI commands over raw API calls** — the CLI has dedicated commands for most tasks. Reach for `sentry issue view`, `sentry issue list`, `sentry trace view`, etc. before constructing API calls manually or fetching external documentation. 11: - **Use `sentry schema` to explore the API** — if you need to discover API endpoints, run `sentry schema` to browse interactively or `sentry schema <resource>` to search. This is faster than fetching OpenAPI specs externally. 12: - **Use `sentry issue view <id>` to investigate issues** — when asked about a specific issue (e.g., `CLI-G5`, `PROJECT-123`), use `sentry issue view` directly. ...
Now let me also check the issues.md doc page to see if there's already field documentation there:
/home/byk/Code/getsentry/cli/docs/src/content/docs/commands/issue.md
<path>/home/byk/Code/getsentry/cli/docs/src/content/docs/commands/issue.md</path> <type>file</type> <content>1: --- 2: title: issue 3: description: Issue commands for the Sentry CLI 4: --- 5: 6: Track and manage Sentry issues. 7: 8: ## Commands 9: 10: ### `sentry issue list` 11: 12: List issues in a project. 13: 14: ```bash 15: # Explicit org and project 16: sentry issue list <org>/<project> 17: 18: # All projects in an organization 19: sentry issue list <org>/ 20: 21: # Search for project across all accessible orgs 22: sentry issue list <project> 23: 24: # Auto-detect from DSN or config 25: sentry issue list 26: ``` 27: 28: **Arguments:** 29: 30: | Argument | Description | 31: |----------|-------------| 32: | `<org>/<project>` | Explicit organization and project (e.g., `my-org/frontend`) | 33: | `<org>/` | All projects in the specified organization | 34: | `<project>` | Search for project by name across all accessible organizations | 35: 36: **Options:** 37: 38: | Option ...
Now I have the full picture. Let me write the plan.
Let me find the correct plan file path:
/home/byk/.local/share/opencode/plans/1772818927105-witty-river.md /home/byk/.local/share/opencode/plans/1773325283783-calm-moon.md /home/byk/.local/share/opencode/plans/1773405633236-crisp-otter.md /home/byk/.local/share/opencode/plans/1773790174920-glowing-canyon.md /home/byk/.local/share/opencode/plans/1773789960407-quiet-panda.md /home/byk/.local/share/opencode/plans/1773842831423-lucky-knight.md /home/byk/.local/share/opencode/plans/1773854691337-eager-canyon.md /home/byk/.local/share/opencode/plans/1773854675565-lucky-meadow.md /home/byk/.local/share/opencode/plans/1773866340206-glowing-circuit.md /home/byk/.local/share/opencode/plans/1774465624645-mighty-wizard.md /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/glowing-cactus/.opencode/plans/1773089915149-brave-falcon.md /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/glowing-cactus/.opencode/plans/1773089590442-eager-sailor.md /home/byk/.local/share/opencode/wo...
I see the plan file should be at the path specified in the instructions. Let me check the correct working directory:
--- /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/silent-panda/.opencode/plans/
The directory exists but the file doesn't yet. The write permission rule allows .opencode/plans/*.md — let me try with the relative pattern:
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/silent-panda
1772724649716-eager-star.md 1772724931632-nimble-moon.md 1772792640083-kind-planet.md 1772792854297-clever-falcon.md 1772989389018-witty-mountain.md
The permission pattern says .opencode/plans/*.md — this should match relative to the working directory. Let me try writing to the getsentry/cli plans directory which is in my working directory:
Plan written successfully
Good, the plan is written. Let me verify it:
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/silent-panda/.opencode/plans/1774536430174-nimble-engine.md</path> <type>file</type> <content>1: # Plan: Document available JSON fields in SKILL.md for issue list 2: 3: ## Problem 4: 5: When an AI agent needs `count`, `userCount`, `firstSeen`, or `lastSeen` from `sentry issue list`, it doesn't know these fields are available in the `--json` output. The SKILL.md only shows `--fields id,title,status` as an example with no field enumeration. So the agent falls back to `sentry api` (raw API call), which we want to avoid. 6: 7: **Root cause**: The fields ARE present in JSON output — the documentation just doesn't tell the agent they exist. 8: 9: ## Approach 10: 11: Add JSON field documentation to the **agent guidance doc** and the **issue commands doc**. These are the two source files that feed into the auto-generated SKILL.md: 12: 13: 1. `docs/src/content/docs/agent-guidance.md` → becomes the ...
The plan looks good. Let me now summarize the key findings and call plan_exit.
Here's a summary of what I found and the plan:
The issue is purely a documentation gap, not a code bug. The sentry issue list --json output already includes count, userCount, firstSeen, and lastSeen at the top level of each issue object — the collapse parameter only removes sub-objects like lifetime, filtered, stats, not these top-level fields. But the SKILL.md (which agents read) only shows --fields id,title,status as an example, with no enumeration of available fields. So agents don't know these fields exist and fall back to sentry api.
The fix is minimal — two documentation files:
docs/src/content/docs/agent-guidance.md — Replace the generic --fields id,title,status tip with one that lists common issue fields (count, userCount, firstSeen, lastSeen, etc.) and add a "Common Mistakes" entry warning against unnecessary sentry api fallbacks.
docs/src/content/docs/commands/issue.md — Add a "JSON Fields" table documenting the 16 most commonly-used fields with their types and descriptions, plus the JSON envelope structure.
Both files feed into the auto-generated SKILL.md via generate-skill.ts (no generator changes needed). Just run bun run generate:skill afterward.
I want you to fix issue 556 for this and derive the fields from that. Also make sure this information ends up in the help output of commands, especially when --json is passed
The user wants me to:
--json is passedLet me first find issue 556 and understand it, then update the plan accordingly. Let me find issue 556 and understand the exact requirements, then explore how help output works.
<skill_content name="sentry-cli"> # Skill: sentry-cli # Sentry CLI Usage Guide Help users interact with Sentry from the command line using the `sentry` CLI. ## Agent Guidance Best practices and operational guidance for AI coding agents using the Sentry CLI. ### Key Principles - **Prefer CLI commands over raw API calls** — the CLI has dedicated commands for most tasks. Reach for `sentry issue view`, `sentry issue list`, `sentry trace view`, etc. before constructing API calls manually or fetching external documentation. - **Use `sentry schema` to explore the API** — if you need to discover API endpoints, run `sentry schema` to browse interactively or `sentry schema <resource>` to search. This is faster than fetching OpenAPI specs externally. - **Use `sentry issue view <id>` to investigate issues** — when asked about a specific issue (e.g., `CLI-G5`, `PROJECT-123`), use `sentry issue view` directly. - **Use `--json` for machine-readable output** — pipe through `jq` for filtering. ...
The user wants me to:
--json is passedLet me find issue 556 first - this is likely on the getsentry/cli GitHub repo. Let me fetch the issue and explore the help output system to understand what needs to change.
title: feat(ci): integrate Linear Releases into release and nightly workflows state: OPEN author: betegon (Miguel Betegón) labels: comments: 2 assignees: projects: milestone: number: 556 -- Hooks up [Linear Releases](https://linear.app/docs/releases) to our CI so the team can see which issues shipped in each build. Two pipelines: - **Stable** — fires in `release.yml` after Craft completes, tracking everything that goes out to npm/GitHub/Brew - **Nightly** — fires in `publish-nightly` after the GHCR push, tagged with the nightly version string Linear scans commits for issue identifiers and attaches them to the release automatically. Secrets (`LINEAR_STABLE_RELEASE_KEY`, `LINEAR_NIGHTLY_RELEASE_KEY`) are already set in the repo.
Sorry I meant issue 566: https://github.com/getsentry/cli/issues/566
title: feat: add Zod schema registration to OutputConfig for typed JSON output state: OPEN author: BYK (Burak Yigit Kaya) labels: enhancement comments: 0 assignees: projects: milestone: number: 566 -- ## Summary Add an optional `schema` field to `OutputConfig<T>` so commands can register the Zod schema for their JSON output type. This enables: 1. **Typed SDK generation** — Build-time codegen can read schemas from the command tree and generate TypeScript return types automatically, eliminating the need for a manual type map. 2. **JSON output documentation** — The `--json` mode can be documented with exact field-level schemas, including which fields are optional, enum values, nested structures, etc. 3. **Runtime validation** — Optionally validate command output against the schema in dev/test modes to catch type drift. 4. **JSON Schema generation** — Export schemas as JSON Schema for consumers who want to validate output in other languages. ...
Now I understand the actual issue - #566 is about adding Zod schema registration to OutputConfig so commands can declare their JSON output schema. This enables typed SDK generation, JSON output documentation, and importantly - making field information available in help output.
Let me re-explore the codebase with this new understanding. I need to look at:
OutputConfig<T> in src/lib/formatters/output.ts or src/lib/command.ts
src/lib/introspect.ts - how command metadata is exposed
How --help output is generated, especially for --json
Existing Zod schemas in src/types/sentry.ts as reference implementations
How generate-skill.ts could consume these schemas to document available fields
The user wants field information to appear in help output when --json is passed, so I need to tackle this across three areas: registering schemas on commands, updating the help system to display available fields, and modifying SKILL.md generation to include field ...
task_id: ses_2d4bef1e7ffec31AQQDxqRWiTK (for resuming to continue this task if needed)
<task_result>
Here is the complete analysis:
---
## Full Output Handling Flow
### 1. Type Signatures
#### `OutputConfig<T>` (output.ts:127–161)
```typescript
export type OutputConfig<T> = {
human: HumanOutput<T>;
jsonExclude?: ReadonlyArray<keyof T & string>;
jsonTransform?: (data: T, fields?: string[]) => unknown;
};
```
- **`human`**: Either a plain `(data: T) => string` or a zero-arg factory `() => HumanRenderer<T>` for stateful rendering.
- **`jsonExclude`**: Top-level keys stripped from JSON output. Type-safe — constrained to `keyof T & string`. **Ignored** when `jsonTransform` is set.
- **`jsonTransform`**: Replaces the entire default JSON path. Receives raw data + parsed `--fields`. Used by list commands for `{ data, hasMore, nextCursor }` envelopes and view commands for flattening nested structures.
#### `HumanOutput<T>` (output.ts:116)
```typescript
export type HumanOutput<T> ...
task_id: ses_2d4bedca4ffec7NtkIUqGK29Xt (for resuming to continue this task if needed)
<task_result>
Now I have a comprehensive understanding. Let me compile the full report.
---
## Report: Introspection and Help Systems
### 1. `src/lib/introspect.ts` — Full Analysis
**Purpose:** A shared module for extracting structured metadata from Stricli's route tree. Used by both runtime (`sentry help --json`) and build-time (`generate-skill.ts`).
#### Types Produced
**`CommandInfo`** — Extracted metadata for a single leaf command:
```typescript
{ path, brief, fullDescription?, flags: FlagInfo[], positional: string, aliases, examples }
```
**`FlagInfo`** — Extracted metadata for a single flag:
```typescript
{ name, brief, kind: "boolean"|"parsed"|"enum", default?, optional, variadic, hidden }
```
**`RouteInfo`** — A route group with its subcommands:
```typescript
{ name, brief, commands: CommandInfo[] }
```
**`ResolvedPath`** — Discriminated union for path resolution results:
- `{ ...
task_id: ses_2d4bec8d8ffe304K3TfmD8bL41 (for resuming to continue this task if needed)
<task_result>
Here's the complete report:
---
## Complete Findings
### 1. ALL Zod Schemas in `src/types/sentry.ts`
| Schema | Validates | Has Runtime Validation |
|---|---|---|
| `RegionSchema` | Sentry region (name + URL) | ✅ |
| `UserRegionsResponseSchema` | `/users/me/regions/` endpoint response | ✅ |
| `SentryUserSchema` | `/auth/` endpoint response (id, email, username, name) | ✅ |
| `ReleaseSchema` | Release object embedded in issues (version, projects, etc.) | ✅ |
| `SpanSchema` | A single span in a trace (span_id, parent_span_id, timestamps, etc.) | ✅ |
| `SentryLogSchema` | Log entry from Explore/Events API (logs dataset) | ✅ |
| `LogsResponseSchema` | Response envelope for logs: `{ data: SentryLog[], meta? ...
Now I have a comprehensive understanding. Let me synthesize this:
Issue #566 wants to add Zod schema registration on OutputConfig<T> so commands can declare their JSON output schema.
The real problem: Agents don't know what fields sentry issue list --json returns. The user wants field info to show up in help output (especially when --json is passed).
Current state:
OutputConfig<T> has human, jsonExclude, jsonTransform — no schema fieldCommandInfo doesn't capture schema information eitherSentryIssue doesn't, and the JSON list envelope structure also lacks onejson and fields flags from documentationHelp system: Looking at how --help currently works and where schema information would need to be integrated.
...
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>260: * custom brief text), the injected `JSON_FLAG` is skipped. `--fields` is
261: * always injected when `output: { human: ... }` regardless.
262: *
263: * Flag keys use kebab-case because Stricli uses the literal object key as
264: * the CLI flag name (e.g. `"log-level"` → `--log-level`).
265: *
266: * @param builderArgs - Same shape as Stricli's buildCommand arguments,
267: * plus an optional `output` mode
268: * @returns A fully-wrapped Stricli Command
269: */
270: export function buildCommand<
271: const FLAGS extends BaseFlags = NonNullable<unknown>,
272: const ARGS extends BaseArgs = [],
273: const CONTEXT extends CommandContext = CommandContext,
274: >(
275: builderArgs: LocalCommandBuilderArguments<FLAGS, ARGS, CONTEXT>
276: ): Command<CONTEXT> {
277: const originalFunc = builderArgs.func;
278: const outputConfig = builderArgs.output;
279:
280: // Merge logging ...
<path>/home/byk/Code/getsentry/cli/src/lib/formatters/output.ts</path>
<type>file</type>
<content>100: // Factory: zero-arg function that returns a renderer
101: if (human.length === 0) {
102: return (human as () => HumanRenderer<T>)();
103: }
104: // Plain formatter: wrap in a stateless renderer
105: return { render: human as (data: T) => string };
106: }
107:
108: /**
109: * Human rendering for an {@link OutputConfig}.
110: *
111: * Two forms:
112: * - **Plain function** `(data: T) => string` — stateless, auto-wrapped.
113: * - **Factory** `() => HumanRenderer<T>` — called per invocation for
114: * stateful renderers (e.g., streaming tables with `finalize()`).
115: */
116: export type HumanOutput<T> = ((data: T) => string) | (() => HumanRenderer<T>);
117:
118: /**
119: * Output configuration declared on `buildCommand` for automatic rendering. ...
Now let me check the JSON_FLAG and FIELDS_FLAG definitions and how Stricli fullDescription works:
Found 7 matches
/home/byk/Code/getsentry/cli/src/lib/list-command.ts:
Line 9: * LIST_TARGET_POSITIONAL, LIST_JSON_FLAG, LIST_CURSOR_FLAG,
Line 92: export const LIST_JSON_FLAG = {
/home/byk/Code/getsentry/cli/src/lib/command.ts:
Line 190: export const JSON_FLAG = {
Line 208: export const FIELDS_FLAG = {
Line 260: * custom brief text), the injected `JSON_FLAG` is skipped. `--fields` is
Line 304: mergedFlags.json = JSON_FLAG;
Line 307: mergedFlags.fields = FIELDS_FLAG;
<path>/home/byk/Code/getsentry/cli/src/lib/formatters/output.ts</path>
<type>file</type>
<content>220: * Rendering context passed to {@link renderCommandOutput}.
221: * Contains the wrapper-injected flag values needed for output mode selection.
222: */
223: type RenderContext = {
224: /** Whether `--json` was passed */
225: json: boolean;
226: /** Pre-parsed `--fields` value */
227: fields?: string[];
228: /** ANSI prefix to prepend to the output (e.g., clear-screen escape) */
229: clearPrefix?: string;
230: };
231:
232: /**
233: * Apply `jsonExclude` keys to data, stripping excluded fields from
234: * objects or from each element of an array. Returns the data unchanged
235: * when no exclusions are configured.
236: */
237: function applyJsonExclude(
238: data: unknown,
239: excludeKeys: readonly string[] | undefined
240: ): unknown {
241: if (!excludeKeys || excludeKeys.length === 0) {
242: return data;
243: }
244: if (typeof data !== "object" || ...
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>188: * Outputs machine-readable JSON instead of human-readable text.
189: */
190: export const JSON_FLAG = {
191: kind: "boolean" as const,
192: brief: "Output as JSON",
193: default: false,
194: } as const;
195:
196: /**
197: * `--fields` flag injected by {@link buildCommand} when `output` config is set.
198: *
199: * Accepts a comma-separated list of field paths (dot-notation supported)
200: * to include in JSON output. Reduces token consumption for agent workflows.
201: *
202: * The raw string is **pre-parsed** into a `string[]` by the wrapper before
203: * the command's `func` receives it. Commands should declare their flags type
204: * as `fields?: string[]` (not `string`).
205: *
206: * Only meaningful when `--json` is also set — silently ignored otherwise. ...
Now let me check how fullDescription flows through to help and introspection:
Found 67 matches /home/byk/Code/getsentry/cli/src/commands/issue/list.ts: Line 1513: fullDescription: /home/byk/Code/getsentry/cli/src/commands/project/list.ts: Line 603: fullDescription: /home/byk/Code/getsentry/cli/src/lib/list-command.ts: Line 462: readonly fullDescription?: string; Line 545: readonly fullDescription?: string; /home/byk/Code/getsentry/cli/src/commands/span/list.ts: Line 429: fullDescription: /home/byk/Code/getsentry/cli/src/commands/trace/list.ts: Line 195: fullDescription: /home/byk/Code/getsentry/cli/src/commands/dashboard/list.ts: Line 364: fullDescription: /home/byk/Code/getsentry/cli/src/commands/repo/list.ts: Line 56: fullDescription: /home/byk/Code/getsentry/cli/src/commands/team/list.ts: Line 60: fullDescription: /home/byk/Code/getsentry/cli/src/lib/command.ts: Line 92: readonly fullDescription?: string; /home/byk/Code/getsentry/cli/src/commands/dashboard/view.ts: Line 128: ...
Good. Now let me look at how buildCommand passes docs through to Stricli and whether we can intercept it:
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>80: * that Stricli's `CommandBuilderArguments` enforces via `NoInfer`.
81: *
82: * Rather than silencing with `as any`, we cast through `unknown` to
83: * this type that matches Stricli's structural expectations while
84: * erasing the generic constraints we can no longer satisfy.
85: */
86: type StricliBuilderArgs<CONTEXT extends CommandContext> =
87: import("@stricli/core").CommandBuilderArguments<BaseFlags, BaseArgs, CONTEXT>;
88:
89: /** Command documentation */
90: type CommandDocumentation = {
91: readonly brief: string;
92: readonly fullDescription?: string;
93: };
94:
95: /**
96: * Command function type for Sentry CLI commands.
97: *
98: * ALL command functions are async generators. The framework iterates
99: * each yielded value and renders it through the output config. ...
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>475:
476: // OutputError handler: render data through the output system, then
477: // exit with the error's code. Stricli overwrites process.exitCode = 0
478: // after successful returns, so process.exit() is the only way to
479: // preserve a non-zero code. This lives in the framework — commands
480: // simply `throw new OutputError(data)`.
481: const handleOutputError = (err: unknown): never => {
482: if (err instanceof OutputError && outputConfig) {
483: // Only render if there's actual data to show
484: if (err.data !== null && err.data !== undefined) {
485: handleYieldedValue(
486: stdout,
487: new CommandOutput(err.data),
488: cleanFlags,
489: renderer
490: );
491: }
492: process.exit(err.exitCode);
493: }
494: throw err;
495: };
496:
497: // ...
Let me see how buildCommand passes docs through to Stricli at the bottom of the function:
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>530: commandPrefix?: readonly string[];
531: stderr: Writer;
532: },
533: args
534: );
535: if (recovered) {
536: return;
537: }
538:
539: handleOutputError(err);
540: }
541: };
542:
543: // Build the command with the wrapped function via Stricli.
544: // The cast is necessary because we modify both `parameters` (injecting
545: // hidden flags) and `func` (wrapping with telemetry/output logic),
546: // which breaks the original FLAGS/ARGS type alignment that Stricli's
547: // `CommandBuilderArguments` enforces via `NoInfer`.
548: return stricliCommand({
549: ...builderArgs,
550: parameters: mergedParams,
551: func: wrappedFunc,
552: } as unknown as StricliBuilderArgs<CONTEXT>);
553: }
(End of file - total 553 lines)
</content>
Now I have the complete picture. buildCommand spreads builderArgs (which includes docs: { brief, fullDescription }) into stricliCommand(). We can intercept and enrich fullDescription with schema field info before it reaches Stricli. Let me also look at the LocalCommandBuilderArguments type:
<path>/home/byk/Code/getsentry/cli/src/lib/command.ts</path>
<type>file</type>
<content>115: > = (
116: this: CONTEXT,
117: flags: FLAGS,
118: ...args: ARGS
119: // biome-ignore lint/suspicious/noConfusingVoidType: void is required here — generators that don't return a value have implicit void return, which is distinct from undefined in TypeScript's type system
120: ) => AsyncGenerator<unknown, CommandReturn | void, undefined>;
121:
122: /**
123: * Arguments for building a command with a local function.
124: * This is the subset of Stricli's CommandBuilderArguments that we support.
125: */
126: type LocalCommandBuilderArguments<
127: FLAGS extends BaseFlags,
128: ARGS extends BaseArgs,
129: CONTEXT extends CommandContext,
130: > = {
131: readonly parameters?: Record<string, unknown>;
132: readonly docs: CommandDocumentation;
133: readonly func: SentryCommandFunction<FLAGS, ARGS, CONTEXT>;
134: /**
135: * Output configuration — controls flag injection and ...
Now I have everything I need. Let me also check what SentryIssue looks like in detail and what SDK types exist:
Found 1 matches
/home/byk/Code/getsentry/cli/src/types/sentry.ts:
Line 95: export type SentryIssue = Omit<Partial<SdkIssueDetail>, "metadata"> & {
<path>/home/byk/Code/getsentry/cli/src/types/sentry.ts</path> <type>file</type> <content>1: /** 2: * Sentry API Types 3: * 4: * Types representing Sentry API resources. 5: * 6: * SDK-backed types (Organization, Project, Issue, Event, ProjectKey) are derived 7: * from `@sentry/api` response types using `Partial<SdkType> & RequiredCore`. 8: * This keeps all SDK-documented fields available with correct types while making 9: * non-core fields optional for flexibility (test mocks, partial API responses). 10: * 11: * Internal types not covered by the SDK (Region, User, logs) use Zod schemas 12: * for runtime validation. Event entry types (exceptions, breadcrumbs, etc.) 13: * are plain TypeScript interfaces since they are only used for type annotations. ...
<path>/home/byk/Code/getsentry/cli/src/types/sentry.ts</path>
<type>file</type>
<content>85: /**
86: * A Sentry issue.
87: *
88: * Based on the `@sentry/api` retrieve-issue response type.
89: * Core identifiers are required; other SDK fields are available but optional.
90: * Includes extensions for fields returned by the API but not in the OpenAPI spec.
91: *
92: * The `metadata` field is overridden from the SDK's discriminated union to a single
93: * object with all optional fields, matching how the API actually returns data.
94: */
95: export type SentryIssue = Omit<Partial<SdkIssueDetail>, "metadata"> & {
96: id: string;
97: shortId: string;
98: title: string;
99: /** Issue metadata (value, filename, function, etc.) */
100: metadata?: {
101: value?: string;
102: type?: string;
103: filename?: string;
104: function?: string;
105: title?: string;
106: display_title_with_tree_label?: boolean;
107: [key: string]: unknown;
108: };
109: ...
Now I have everything. Let me write the comprehensive plan:
Plan written successfully