Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
19028f0
feat(alert): add alert issues and metrics list commands
betegon Mar 26, 2026
5401713
refactor(list): extract compound cursor and target resolution to shar…
betegon Mar 26, 2026
9821b07
chore: regenerate skill files
github-actions[bot] Mar 26, 2026
ed1f484
refactor(alert): rewrite alert list commands to use dispatchOrgScoped…
betegon Mar 26, 2026
e515403
refactor(alert): align alert list commands with sentry issue list str…
betegon Mar 27, 2026
30ed64b
refactor(alert): rewrite alert issues list as structural replica of i…
betegon Mar 27, 2026
e816ecc
refactor(alert): rewrite alert metrics list as structural replica of …
betegon Mar 27, 2026
b04ef40
refactor(alert): route org-all through handleResolvedOrgs in metrics …
betegon Mar 27, 2026
218f81b
refactor(alert): deduplicate shared list utilities into lib
betegon Mar 27, 2026
76bbdb7
fix(alert/metrics): skip listProjects for org-all/explicit modes
betegon Mar 27, 2026
2da76ee
Merge remote-tracking branch 'origin/main' into feat/alert-list-commands
MathurAditya724 Apr 23, 2026
9682a61
fix(alert): preserve pagination state in alert list results
MathurAditya724 Apr 23, 2026
9b4c5de
feat(alert): add issue and metric alert view commands
MathurAditya724 Apr 23, 2026
9283c59
fix(ci): satisfy alert route lint and fragment checks
MathurAditya724 Apr 23, 2026
ed3069f
fix(alert): tighten view resolution and list hasMore
MathurAditya724 Apr 23, 2026
4178c17
feat(alert): add delete and edit for issue and metric alert rules
MathurAditya724 Apr 23, 2026
6bb92f4
refactor(alert): share 404 guard and single GET for alert rules
MathurAditya724 Apr 23, 2026
348de42
feat(alert): add create commands and expand edit payload updates
MathurAditya724 Apr 23, 2026
46a4947
chore: regenerate docs
github-actions[bot] Apr 23, 2026
d069e86
fix(alert): resolve alert command typing regressions
MathurAditya724 Apr 23, 2026
95b4ded
chore: regenerate docs
github-actions[bot] Apr 23, 2026
4e91ee0
fix(time-range): make period examples timezone-stable
MathurAditya724 Apr 23, 2026
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
11 changes: 6 additions & 5 deletions docs/src/content/docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,21 @@ cli/
│ ├── app.ts # Stricli application setup
│ ├── context.ts # Dependency injection context
│ ├── commands/ # CLI commands
│ │ ├── alert/ # create, delete, edit, list, view
│ │ ├── auth/ # login, logout, refresh, status, token, whoami
│ │ ├── cli/ # defaults, feedback, fix, setup, upgrade
│ │ ├── dashboard/ # list, view, create, add, edit, delete
│ │ ├── event/ # view, list
│ │ ├── issue/ # list, events, explain, plan, view, resolve, unresolve, merge
│ │ ├── dashboard/ # add, create, delete, edit, list, view
│ │ ├── event/ # list, view
│ │ ├── issue/ # events, explain, list, merge, plan, resolve, unresolve, view
│ │ ├── log/ # list, view
│ │ ├── org/ # list, view
│ │ ├── project/ # create, delete, list, view
│ │ ├── release/ # list, view, create, finalize, delete, deploy, deploys, set-commits, propose-version
│ │ ├── release/ # create, delete, deploy, deploys, finalize, list, propose-version, set-commits, view
│ │ ├── repo/ # list
│ │ ├── sourcemap/ # inject, upload
│ │ ├── span/ # list, view
│ │ ├── team/ # list
│ │ ├── trace/ # list, view, logs
│ │ ├── trace/ # list, logs, view
│ │ ├── trial/ # list, start
│ │ ├── api.ts # Make an authenticated API request
│ │ ├── help.ts # Help command
Expand Down
84 changes: 84 additions & 0 deletions docs/src/fragments/commands/alert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@


## Examples

### Create an issue alert rule

```bash
# Create an issue alert rule with inline JSON condition/action
sentry alert issues create my-org/my-project \
--name "Error Spike" \
--condition '{"id":"sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"}' \
--action '{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}' \
--action-match any
```

### List issue alert rules

```bash
# List issue alert rules for a project
sentry alert issues list my-org/my-project

# Filter rules by name
sentry alert issues list my-org/my-project --query "spike"
```

### View an issue alert rule

```bash
# View by ID
sentry alert issues view my-org/my-project/12345

# View by name
sentry alert issues view my-org/my-project/"Error Spike"
```

### Edit and delete an issue alert rule

```bash
# Edit issue alert name/status
sentry alert issues edit my-org/my-project/12345 --name "Prod Error Spike" --status disabled

# Delete with preview
sentry alert issues delete my-org/my-project/12345 --dry-run
```

### Create a metric alert rule

```bash
# Create an organization metric alert rule
sentry alert metrics create my-org \
--name "P95 Latency" \
--query "environment:prod" \
--aggregate "p95(transaction.duration)" \
--dataset transactions \
--time-window 5 \
--trigger '{"alertThreshold":500,"actions":[{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}]}'
```

### List metric alert rules

```bash
# List metric alert rules for an organization
sentry alert metrics list my-org/
```

### View a metric alert rule

```bash
# View by ID
sentry alert metrics view my-org/67890

# View by name
sentry alert metrics view my-org/"P95 latency alert"
```

### Edit and delete a metric alert rule

```bash
# Edit metric alert query/window
sentry alert metrics edit my-org/67890 --query "environment:prod event.type:error" --time-window 15

# Delete without prompt
sentry alert metrics delete my-org/67890 --yes
```
17 changes: 17 additions & 0 deletions plugins/sentry-cli/skills/sentry-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,23 @@ Make an authenticated API request

→ Full flags and examples: `references/api.md`

### Alert

Manage Sentry alert rules

- `sentry alert issues list <org/project>` — List issue alert rules
- `sentry alert issues view <org/project/rule-id-or-name>` — View an issue alert rule
- `sentry alert issues create <org/project>` — Create an issue alert rule
- `sentry alert issues delete <org/project/rule-id-or-name>` — Delete an issue alert rule
- `sentry alert issues edit <org/project/rule-id-or-name>` — Edit an issue alert rule
- `sentry alert metrics list <org/project>` — List metric alert rules
- `sentry alert metrics view <org/rule-id-or-name>` — View a metric alert rule
- `sentry alert metrics create <org>` — Create a metric alert rule
- `sentry alert metrics delete <org/rule-id-or-name>` — Delete a metric alert rule
- `sentry alert metrics edit <org/rule-id-or-name>` — Edit a metric alert rule

→ Full flags and examples: `references/alert.md`

### CLI

CLI-related commands
Expand Down
213 changes: 213 additions & 0 deletions plugins/sentry-cli/skills/sentry-cli/references/alert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
---
name: sentry-cli-alert
version: 0.29.0-dev.0
description: Manage Sentry alert rules
requires:
bins: ["sentry"]
auth: true
---

# Alert Commands

Manage Sentry alert rules

### `sentry alert issues list <org/project>`

List issue alert rules

**Flags:**
- `-w, --web - Open in browser`
- `-n, --limit <value> - Maximum number of issue alert rules to list - (default: "25")`
- `-q, --query <value> - Filter rules by name`
- `-c, --cursor <value> - Pagination cursor (use "next" for next page, "prev" for previous)`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`

**Examples:**

```bash
# List issue alert rules for a project
sentry alert issues list my-org/my-project

# Filter rules by name
sentry alert issues list my-org/my-project --query "spike"
```

### `sentry alert issues view <org/project/rule-id-or-name>`

View an issue alert rule

**Flags:**
- `-w, --web - Open issue alert rules page in browser`

**Examples:**

```bash
# View by ID
sentry alert issues view my-org/my-project/12345

# View by name
sentry alert issues view my-org/my-project/"Error Spike"
```

### `sentry alert issues create <org/project>`

Create an issue alert rule

**Flags:**
- `--name <value> - Rule name`
- `-c, --condition <value>... - Condition object JSON (repeatable, or pass one JSON array)`
- `-a, --action <value>... - Action object JSON (repeatable, or pass one JSON array)`
- `-m, --action-match <value> - Condition/action match mode: all or any`
- `--frequency <value> - Frequency in minutes (default: 30) - (default: 30)`
- `--environment <value> - Environment filter`
- `--filter <value>... - Filter object JSON (repeatable, or pass one JSON array)`
- `--filter-match <value> - Filter match mode: all or any`
- `--owner <value> - Owner (team:user style value accepted by Sentry API)`
- `-n, --dry-run - Show what would happen without making changes`

**Examples:**

```bash
# Create an issue alert rule with inline JSON condition/action
sentry alert issues create my-org/my-project \
--name "Error Spike" \
--condition '{"id":"sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"}' \
--action '{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}' \
--action-match any
```

### `sentry alert issues delete <org/project/rule-id-or-name>`

Delete an issue alert rule

**Flags:**
- `-y, --yes - Skip confirmation prompt`
- `-f, --force - Force the operation without confirmation`
- `-n, --dry-run - Show what would happen without making changes`

**Examples:**

```bash
# Edit issue alert name/status
sentry alert issues edit my-org/my-project/12345 --name "Prod Error Spike" --status disabled

# Delete with preview
sentry alert issues delete my-org/my-project/12345 --dry-run
```

### `sentry alert issues edit <org/project/rule-id-or-name>`

Edit an issue alert rule

**Flags:**
- `--name <value> - New rule name`
- `--status <value> - Rule status: active or disabled`
- `-c, --condition <value>... - Condition object JSON (repeatable, or pass one JSON array)`
- `-a, --action <value>... - Action object JSON (repeatable, or pass one JSON array)`
- `-m, --action-match <value> - Condition/action match mode: all or any`
- `--frequency <value> - Frequency in minutes`
- `--environment <value> - Environment value (pass empty string to clear)`
- `--filter <value>... - Filter object JSON (repeatable, or pass one JSON array)`
- `--filter-match <value> - Filter match mode: all or any`
- `--owner <value> - Owner value (pass empty string to clear)`

### `sentry alert metrics list <org/project>`

List metric alert rules

**Flags:**
- `-w, --web - Open in browser`
- `-n, --limit <value> - Maximum number of metric alert rules to list - (default: "25")`
- `-q, --query <value> - Filter rules by name`
- `-c, --cursor <value> - Pagination cursor (use "next" for next page, "prev" for previous)`
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`

**Examples:**

```bash
# List metric alert rules for an organization
sentry alert metrics list my-org/
```

### `sentry alert metrics view <org/rule-id-or-name>`

View a metric alert rule

**Flags:**
- `-w, --web - Open metric alert rules page in browser`

**Examples:**

```bash
# View by ID
sentry alert metrics view my-org/67890

# View by name
sentry alert metrics view my-org/"P95 latency alert"
```

### `sentry alert metrics create <org>`

Create a metric alert rule

**Flags:**
- `--name <value> - Rule name`
- `--query <value> - Metric query filter string`
- `--aggregate <value> - Aggregate expression (for example count(), p95(transaction.duration))`
- `--dataset <value> - Dataset (errors, transactions, sessions, events, spans, metrics)`
- `--time-window <value> - Evaluation window in minutes`
- `-t, --trigger <value>... - Trigger object JSON (repeatable, or pass one JSON array)`
- `-p, --project <value>... - Project slug filter (repeatable or comma-separated)`
- `--environment <value> - Environment filter`
- `--owner <value> - Owner value accepted by Sentry API`
- `-n, --dry-run - Show what would happen without making changes`

**Examples:**

```bash
# Create an organization metric alert rule
sentry alert metrics create my-org \
--name "P95 Latency" \
--query "environment:prod" \
--aggregate "p95(transaction.duration)" \
--dataset transactions \
--time-window 5 \
--trigger '{"alertThreshold":500,"actions":[{"id":"sentry.mail.actions.NotifyEmailAction","targetType":"Team","targetIdentifier":1}]}'
```

### `sentry alert metrics delete <org/rule-id-or-name>`

Delete a metric alert rule

**Flags:**
- `-y, --yes - Skip confirmation prompt`
- `-f, --force - Force the operation without confirmation`
- `-n, --dry-run - Show what would happen without making changes`

**Examples:**

```bash
# Edit metric alert query/window
sentry alert metrics edit my-org/67890 --query "environment:prod event.type:error" --time-window 15

# Delete without prompt
sentry alert metrics delete my-org/67890 --yes
```

### `sentry alert metrics edit <org/rule-id-or-name>`

Edit a metric alert rule

**Flags:**
- `--name <value> - New rule name`
- `--status <value> - active or disabled`
- `--query <value> - Metric query filter`
- `--aggregate <value> - Aggregate expression`
- `--dataset <value> - Dataset (errors, transactions, sessions, events, spans, metrics)`
- `--time-window <value> - Evaluation window in minutes`
- `-t, --trigger <value>... - Trigger object JSON (repeatable, or pass one JSON array)`
- `-p, --project <value>... - Project slug filter (repeatable or comma-separated)`
- `--environment <value> - Environment value (pass empty string to clear)`
- `--owner <value> - Owner value (pass empty string to clear)`

All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags.
13 changes: 9 additions & 4 deletions script/generate-docs-sections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,18 @@ function isStandaloneCommand(route: RouteInfo): boolean {

/**
* Get subcommand names for a route group (e.g., "list, view, create").
* Extracts the last path segment from each command's path.
* Extracts the last path segment from each command's path, deduplicated
* and sorted (nested routes like `issues` / `metrics` would otherwise repeat
* the same subcommand list twice, e.g. for `alert/`).
*/
function getSubcommandNames(route: RouteInfo): string[] {
return route.commands.map((cmd) => {
function getSubcommandLabel(route: RouteInfo): string {
const raw = route.commands.map((cmd) => {
const parts = cmd.path.split(" ");
return parts.at(-1) ?? route.name;
});
return Array.from(new Set(raw))
.sort((a, b) => a.localeCompare(b))
.join(", ");
}

/**
Expand Down Expand Up @@ -144,7 +149,7 @@ function generateProjectStructure(allRoutes: RouteInfo[]): string {

// Render group directories (always use ├── since standalones follow)
for (const route of groups) {
const subcmds = getSubcommandNames(route).join(", ");
const subcmds = getSubcommandLabel(route);
lines.push(`│ │ ├── ${`${route.name}/`.padEnd(13)}# ${subcmds}`);
}

Expand Down
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
UnexpectedPositionalError,
UnsatisfiedPositionalError,
} from "@stricli/core";
import { alertRoute } from "./commands/alert/index.js";
import { apiCommand } from "./commands/api.js";
import { authRoute } from "./commands/auth/index.js";
import { whoamiCommand } from "./commands/auth/whoami.js";
Expand Down Expand Up @@ -79,6 +80,7 @@ const PLURAL_TO_SINGULAR: Record<string, string> = {
export const routes = buildRouteMap({
routes: {
help: helpCommand,
alert: alertRoute,
auth: authRoute,
cli: cliRoute,
dashboard: dashboardRoute,
Expand Down
Loading
Loading