Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions plugins/sentry-cli/skills/sentry-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,11 @@ sentry issue list my-org/frontend --query "is:resolved"
sentry issue list my-org/frontend --query "is:unresolved TypeError"
```

#### `sentry issue explain <issue-id>`
#### `sentry issue explain <issue>`

Analyze an issue's root cause using Seer AI

**Flags:**
- `--org <value> - Organization slug (required for short IDs if not auto-detected)`
- `--project <value> - Project slug (required for short suffixes if not auto-detected)`
- `--json - Output as JSON`
- `--force - Force new analysis even if one exists`

Expand All @@ -251,13 +249,11 @@ sentry issue explain G --org my-org --project my-project
sentry issue explain 123456789 --force
```

#### `sentry issue plan <issue-id>`
#### `sentry issue plan <issue>`

Generate a solution plan using Seer AI

**Flags:**
- `--org <value> - Organization slug (required for short IDs if not auto-detected)`
- `--project <value> - Project slug (required for short suffixes if not auto-detected)`
- `--cause <value> - Root cause ID to plan (required if multiple causes exist)`
- `--json - Output as JSON`

Expand All @@ -276,13 +272,11 @@ sentry issue plan 123456789 --cause 0
sentry issue plan MYPROJECT-ABC --org my-org --cause 1
```

#### `sentry issue view <issue-id>`
#### `sentry issue view <issue>`

View details of a specific issue

**Flags:**
- `--org <value> - Organization slug (required for short IDs if not auto-detected)`
- `--project <value> - Project slug (required for short suffixes if not auto-detected)`
- `--json - Output as JSON`
- `-w, --web - Open in browser`
- `--spans <value> - Show span tree with N levels of nesting depth`
Expand Down
28 changes: 14 additions & 14 deletions src/commands/issue/explain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,15 @@ import {
} from "../../lib/formatters/seer.js";
import { extractRootCauses } from "../../types/seer.js";
import {
buildCommandHint,
type IssueIdFlags,
issueIdFlags,
issueIdPositional,
pollAutofixState,
resolveOrgAndIssueId,
} from "./utils.js";

interface ExplainFlags extends IssueIdFlags {
type ExplainFlags = {
readonly json: boolean;
readonly force: boolean;
}
};

export const explainCommand = buildCommand({
docs: {
Expand All @@ -42,17 +39,22 @@ export const explainCommand = buildCommand({
" - Relevant code locations\n\n" +
"The analysis may take a few minutes for new issues.\n" +
"Use --force to trigger a fresh analysis even if one already exists.\n\n" +
"Issue formats:\n" +
" <org>/ID - Explicit org: sentry/EXTENSION-7, sentry/cli-G\n" +
" <project>-suffix - Project + suffix: cli-G, spotlight-electron-4Y\n" +
" ID - Short ID: CLI-G (searches across orgs)\n" +
" suffix - Suffix only: G (requires DSN context)\n" +
" numeric - Numeric ID: 123456789\n\n" +
"Examples:\n" +
" sentry issue explain 123456789\n" +
" sentry issue explain MYPROJECT-ABC --org my-org\n" +
" sentry issue explain G --org my-org --project my-project\n" +
" sentry issue explain sentry/EXTENSION-7\n" +
" sentry issue explain cli-G\n" +
" sentry issue explain 123456789 --json\n" +
" sentry issue explain 123456789 --force",
},
parameters: {
positional: issueIdPositional,
flags: {
...issueIdFlags,
json: {
kind: "boolean",
brief: "Output as JSON",
Expand All @@ -68,7 +70,7 @@ export const explainCommand = buildCommand({
async func(
this: SentryContext,
flags: ExplainFlags,
issueId: string
issueArg: string
): Promise<void> {
const { stdout, stderr, cwd } = this;

Expand All @@ -78,11 +80,9 @@ export const explainCommand = buildCommand({
try {
// Resolve org and issue ID
const { org, issueId: numericId } = await resolveOrgAndIssueId({
issueId,
org: flags.org,
project: flags.project,
issueArg,
cwd,
commandHint: buildCommandHint("explain", issueId),
command: "explain",
});
resolvedOrg = org;

Expand Down Expand Up @@ -137,7 +137,7 @@ export const explainCommand = buildCommand({
stdout.write(`${lines.join("\n")}\n`);
writeFooter(
stdout,
`To create a plan, run: sentry issue plan ${issueId}`
`To create a plan, run: sentry issue plan ${issueArg}`
);
} catch (error) {
// Handle API errors with friendly messages
Expand Down
2 changes: 1 addition & 1 deletion src/commands/issue/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
listIssues,
listProjects,
} from "../../lib/api-client.js";
import { parseOrgProjectArg } from "../../lib/arg-parsing.js";
import {
clearProjectAliases,
setProjectAliases,
Expand All @@ -28,7 +29,6 @@ import {
writeJson,
} from "../../lib/formatters/index.js";
import {
parseOrgProjectArg,
type ResolvedTarget,
resolveAllTargets,
} from "../../lib/resolve-target.js";
Expand Down
30 changes: 15 additions & 15 deletions src/commands/issue/plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,15 @@ import {
type RootCause,
} from "../../types/seer.js";
import {
buildCommandHint,
type IssueIdFlags,
issueIdFlags,
issueIdPositional,
pollAutofixState,
resolveOrgAndIssueId,
} from "./utils.js";

interface PlanFlags extends IssueIdFlags {
type PlanFlags = {
readonly cause?: number;
readonly json: boolean;
}
};

/**
* Validate that an autofix run exists and has completed root cause analysis.
Expand Down Expand Up @@ -141,18 +138,23 @@ export const planCommand = buildCommand({
"to identify the root cause. It will then generate a solution plan with " +
"specific implementation steps to fix the issue.\n\n" +
"If multiple root causes were identified, use --cause to specify which one.\n\n" +
"Issue formats:\n" +
" <org>/ID - Explicit org: sentry/EXTENSION-7, sentry/cli-G\n" +
" <project>-suffix - Project + suffix: cli-G, spotlight-electron-4Y\n" +
" ID - Short ID: CLI-G (searches across orgs)\n" +
" suffix - Suffix only: G (requires DSN context)\n" +
" numeric - Numeric ID: 123456789\n\n" +
"Prerequisites:\n" +
" - GitHub integration configured for your organization\n" +
" - Code mappings set up for your project\n\n" +
"Examples:\n" +
" sentry issue plan 123456789 --cause 0\n" +
" sentry issue plan MYPROJECT-ABC --org my-org --cause 1\n" +
" sentry issue plan G --org my-org --project my-project --cause 0",
" sentry issue plan sentry/EXTENSION-7 --cause 1\n" +
" sentry issue plan cli-G --cause 0",
},
parameters: {
positional: issueIdPositional,
flags: {
...issueIdFlags,
cause: {
kind: "parsed",
parse: numberParser,
Expand All @@ -169,7 +171,7 @@ export const planCommand = buildCommand({
async func(
this: SentryContext,
flags: PlanFlags,
issueId: string
issueArg: string
): Promise<void> {
const { stdout, stderr, cwd } = this;

Expand All @@ -179,22 +181,20 @@ export const planCommand = buildCommand({
try {
// Resolve org and issue ID
const { org, issueId: numericId } = await resolveOrgAndIssueId({
issueId,
org: flags.org,
project: flags.project,
issueArg,
cwd,
commandHint: buildCommandHint("plan", issueId),
command: "plan",
});
resolvedOrg = org;

// Get current autofix state
const currentState = await getAutofixState(org, numericId);

// Validate we have a completed root cause analysis
const { state, causes } = validateAutofixState(currentState, issueId);
const { state, causes } = validateAutofixState(currentState, issueArg);

// Validate cause selection
const causeId = validateCauseSelection(causes, flags.cause, issueId);
const causeId = validateCauseSelection(causes, flags.cause, issueArg);
const selectedCause = causes[causeId];

if (!flags.json) {
Expand Down
Loading
Loading