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
2 changes: 1 addition & 1 deletion apps/cli-docs/src/content/docs/agent-guidance.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ When querying the Events API (directly or via `sentry api`), valid dataset value

## Common Mistakes

- **Wrong issue ID format**: Use `PROJECT-123` (short ID), not the numeric ID `123456789`. The short ID includes the project prefix.
- **Wrong issue ID format**: Use the full short ID (`PROJECT-123`) or the numeric issue ID from a Sentry URL (`123456789`). A bare suffix without its project prefix, such as `123`, is read as a numeric issue ID, not as a short ID.
- **Pre-authenticating unnecessarily**: Don't run `sentry auth login` before every command. The CLI detects missing/expired auth and prompts automatically. Only run `sentry auth login` to add an account. With several stored accounts, commands pick the one that knows the target organization or server automatically; use `sentry auth switch` only to change the default.
- **Missing `--json` for piping**: Human-readable output includes formatting. Use `--json` when parsing output programmatically.
- **Specifying org/project when not needed**: Auto-detection resolves org/project from `.sentryclirc` config files, DSNs, env vars, and directory names. Let it work first — only add `<org>/<project>` if the CLI says it can't detect the target or detects the wrong one.
Expand Down
53 changes: 25 additions & 28 deletions apps/cli-docs/src/content/docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ For monorepos or when DSN detection picks up the wrong project, use a [`.sentryc

### Supported Languages

The CLI scans source files for DSN URLs (the `https://…@….ingest.sentry.io/…` pattern) using a universal regex — no language-specific parsing is needed. Any text file with a recognized extension is scanned, including:
The CLI scans source files for DSN URLs (the `https://<key>@<host>/<project-id>` pattern, so self-hosted DSNs match too) using a universal regex — no language-specific parsing is needed. Any text file with a recognized extension is scanned, including:

<!-- GENERATED:START dsn-extensions -->
| Language Family | File Extensions |
|----------------|-----------------|
| JavaScript/TypeScript | `.js`, `.ts`, `.jsx`, `.tsx`, `.mjs`, `.cjs`, `.astro`, `.vue`, `.svelte` |
Expand All @@ -46,7 +47,9 @@ The CLI scans source files for DSN URLs (the `https://…@….ingest.sentry.io/
| Rust | `.rs` |
| Dart/Flutter | `.dart` |
| Elixir/Erlang | `.ex`, `.exs`, `.erl` |
| Config files | `.json`, `.yaml`, `.yml`, `.toml`, `.xml`, `.properties` |
| Lua | `.lua` |
| Config files | `.json`, `.yaml`, `.yml`, `.toml`, `.xml`, `.properties`, `.config` |
<!-- GENERATED:END dsn-extensions -->

### Caching

Expand All @@ -69,14 +72,9 @@ sentry issue list my-org/my-project
sentry issue list
```

The CLI will show which project was detected:

```
Detected project: my-app (from .env)

ID SHORT ID TITLE COUNT
123456789 MYAPP-ABC TypeError: Cannot read prop... 142
```
The list title names the project the CLI resolved (for example,
`Issues in my-org/my-app:`). View commands such as `sentry org view` also print a
`Detected from <source>` hint naming the file or variable the DSN came from.

## Monorepo Support & Alias System

Expand All @@ -92,36 +90,34 @@ When you run `sentry issue list`, the CLI:

Aliases are the shortest unique prefix of each project slug. For example:

<!-- GENERATED:START alias-unique-prefix -->
| Project Slug | Alias |
|--------------|-------|
| `frontend` | `f` |
|---|---|
| `frontend` | `fr` |
| `functions` | `fu` |
| `backend` | `b` |
<!-- GENERATED:END alias-unique-prefix -->

For projects with a common prefix (like `spotlight-electron`, `spotlight-website`), the prefix is stripped first:

<!-- GENERATED:START alias-common-prefix -->
| Project Slug | Alias |
|--------------|-------|
|---|---|
| `spotlight-electron` | `e` |
| `spotlight-website` | `w` |
| `spotlight-backend` | `b` |
<!-- GENERATED:END alias-common-prefix -->

### Using Alias-Suffix Format

After running `issue list`, you can reference issues using the `alias-suffix` format:
After running `issue list`, you can reference issues using the `alias-suffix` format.
When several projects are listed, the `SHORT ID` column shows each issue's
alias-suffix below its short ID (`SPOTLIGHT-ELEC-4Y` → `e-4y`):

```bash
# List issues - note the ALIAS column
sentry issue list
```

```
ALIAS SHORT ID TITLE COUNT
e SPOTLIGHT-ELEC-4Y TypeError: Cannot read prop... 142
w SPOTLIGHT-WEB-ABC Failed to fetch user data 89
b SPOTLIGHT-BACK-XYZ Connection timeout 34
```

```bash
# View issue using alias-suffix
sentry issue view e-4Y
Expand All @@ -135,13 +131,14 @@ sentry issue plan b-XYZ

### Cross-Organization Support

If you work with multiple organizations that have projects with the same slug, the CLI uses org-prefixed aliases:
If you work with multiple organizations that have projects with the same slug, the CLI prefixes those aliases with the shortest unique org prefix:

```
ALIAS SHORT ID TITLE
o1:api ORG1-API-123 Error in API handler
o2:api ORG2-API-456 Database connection failed
```
<!-- GENERATED:START alias-cross-org -->
| Org/Project | Alias |
|---|---|
| `acme/api` | `a/a` |
| `globex/api` | `g/a` |
<!-- GENERATED:END alias-cross-org -->

## Issue ID Formats

Expand Down
6 changes: 5 additions & 1 deletion apps/cli-docs/src/content/docs/library-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,16 @@ for zero overhead beyond the command's own logic.
For commands not easily expressed through the typed API, or when you want to
pass raw CLI flags, use `sdk.run()`:

<!-- GENERATED:START sdk-run-examples -->
```typescript
// Run any CLI command — returns parsed JSON by default
const version = await sdk.run("--version");
const issues = await sdk.run("issue", "list", "-l", "5");
// Show only unresolved issues
const issues = await sdk.run("issue", "list", "my-org/frontend", "--query", "is:unresolved");
// Help text for a command group
const help = await sdk.run("help", "issue");
```
Comment thread
sentry-junior[bot] marked this conversation as resolved.
<!-- GENERATED:END sdk-run-examples -->

## Authentication

Expand Down
36 changes: 15 additions & 21 deletions apps/cli-docs/src/fragments/commands/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,18 @@ experimentation only; do not run it with production credentials.
## Daemon-owned sessions

Use `--session <name>` to capture into the shared loopback daemon and retain data
after your foreground command exits. Sessions keep up to 500 envelopes for three
hours after closing and subsequent ingestion. Stopping or restarting the daemon
clears all sessions.

<!-- allow-commands: session lifecycle walkthrough across local subcommands -->
```bash
sentry local run --session web -- npm run dev
sentry local serve --session worker
sentry local session list --json
sentry local event list web --json
sentry local event view web <event-id> --json
sentry local envelope list web --json
sentry local session reset web
sentry local session close web
sentry local daemon status
sentry local daemon stop
```

`local session create <name> --json` returns separate SDK ingest and viewer read
capability URLs. Keep these URLs private. `--clientId <key>` makes retried session
creation idempotent. Use the session ID when multiple sessions share a label.
after your foreground command exits. Sessions keep up to 500 envelopes by default
(`--max-envelopes` accepts 1 to 50,000) for three hours after closing and
subsequent ingestion. Session commands start the daemon when it isn't running;
`sentry local daemon start` starts it ahead of time. Stopping or restarting the
daemon (`sentry local daemon restart`) clears all sessions.

The `sentry local run` examples above walk through a full session lifecycle:
capture, inspect sessions, events, and envelopes, then reset, close, and stop
the daemon. `sentry local serve --session worker` captures into a session the
same way without wrapping a command.

`sentry local session create <name> --json` returns separate SDK ingest and
viewer read capability URLs. Keep these URLs private. `--clientId <key>` makes
retried session creation idempotent. Use the session ID when multiple sessions
share a label.
11 changes: 2 additions & 9 deletions apps/cli-docs/src/fragments/commands/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@
## Release workflow

A typical CI release creates the release, associates commits, finalizes it, and
records a deploy:

<!-- allow-commands: multi-step CI release workflow -->
```bash
sentry release create my-org/1.0.0 --project my-project
sentry release set-commits my-org/1.0.0 --auto
sentry release finalize my-org/1.0.0
sentry release deploy my-org/1.0.0 production
```
records a deploy. The `sentry release create` examples above show the full
sequence.

## Important Notes

Expand Down
16 changes: 10 additions & 6 deletions packages/cli/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Guidelines for AI agents working in this codebase.

### Key Features

- **DSN Auto-Detection** - Scans `.env` files and source code (JS, Python, Go, Java, Ruby, PHP) to find Sentry DSNs
- **DSN Auto-Detection** - Scans `.env` files and source code (any file type in `TEXT_EXTENSIONS`, `src/lib/scan/constants.ts`) to find Sentry DSNs
- **Project Root Detection** - Walks up from CWD to find project boundaries using VCS, language, and build markers
- **Directory Name Inference** - Fallback project matching using bidirectional word boundary matching
- **Multi-Region Support** - Automatic region detection with fan-out to regional APIs (us.sentry.io, de.sentry.io)
Expand Down Expand Up @@ -123,9 +123,10 @@ Top-level layout:
`wasm-split.ts`, plus the hidden `bash-hook.ts`, `send-event.ts`, and
`send-envelope.ts`).
- **`src/lib/`** — shared utilities. Key subtrees: `api/` (domain API modules),
`db/` (SQLite layer), `dsn/` (DSN detection, with per-language extractors under
`dsn/languages/`), and `formatters/` (output formatting). See the file-locations
table below and the JSDoc in each module for details.
`db/` (SQLite layer), `dsn/` (DSN detection with one language-agnostic regex),
`scan/` (file walker and scanned extensions), and `formatters/` (output
formatting). See the file-locations table below and the JSDoc in each module
for details.
- **`src/types/`** — TypeScript types and Valibot schemas.
- **`test/`** — tests mirroring `src/` (unit, `*.property.test.ts`,
`*.model-based.test.ts`, `e2e/`, `fixtures/`, `mocks/`).
Expand Down Expand Up @@ -514,9 +515,12 @@ All command docs and skill files are generated via `pnpm run generate:docs` (whi
- **Examples belong to the command**: add them to `docs.examples` (`{ description, command }[]`, see `src/commands/agent-conversation/list.ts`). They render in `--help`, the generated docs, and the skill references. Don't hand-write examples in `fullDescription` (an `Examples:` block, or indented `sentry …` lines under any label) or an Examples heading in a fragment; the `sentry-cli/no-examples-in-full-description` lint rule and `pnpm run check:fragments` reject both.
- **Target syntax belongs to the positional**: describe accepted target forms in the positional `brief` (use `ORG_ALL_TARGET_BRIEF` or `PROJECT_TARGET_BRIEF` from `src/lib/list-command.ts` for `[<org>/][<project>]` targets), not in a `Target patterns:` block. The brief renders in `--help`, the generated docs, and the skill references.
- Use fragments in `apps/cli-docs/src/fragments/commands/` only for prose the command metadata can't carry: guides, permissions, caveats.
- `pnpm run check:fragments` also rejects any shell code block in a fragment that runs a `sentry` command, whatever its heading. For a real workflow, sample output, or cross-command guide, put `<!-- allow-commands: <reason> -->` on the line directly above the block.
- `pnpm run check:fragments` also rejects any shell code block in a fragment that runs a `sentry` command, whatever its heading. Multi-step workflows belong in `docs.examples` too: pass `command` an array of steps (see `release create` and `local run`), and every step is checked and shown in `--help`, the docs, and the skill. Reserve `<!-- allow-commands: <reason> -->` (on the line directly above the block) for sample output and guides that interleave non-`sentry` commands.
- `pnpm run check:fragments` validates fragment ↔ route consistency.
- Positional `placeholder` values must be descriptive: `"org/project/trace-id"` not `"args"`.
- Don't restate a value flag's `default` in its `brief`; help and docs already show it (`test/lib/flag-briefs.test.ts`).
- `pnpm run check:doc-examples` also checks string-literal `sdk.run(…)` calls in TypeScript fences and `@example` JSDoc (`src/index.ts`). They are found by parsing with the TypeScript compiler (`script/sdk-run-calls.ts`); don't add regex-based source parsing.
- Lists that mirror code (scanned DSN extensions, alias examples, destructive commands, detected agents, the `library-usage.md` `sdk.run()` sample built from `issue list` examples) are generated sections in `script/generate-docs-sections.ts`; add new mirrors there instead of hand-writing them.

### Valibot Schemas for Validation

Expand Down Expand Up @@ -1097,7 +1101,7 @@ vi.mock("./some-module", () => ({
| Add config types | `src/types/config.ts` |
| Add Seer types | `src/types/seer.ts` |
| Add utility | `src/lib/` |
| Add DSN language support | `src/lib/dsn/languages/` |
| Add DSN language support | `TEXT_EXTENSIONS` in `src/lib/scan/constants.ts` |
| Add DB operations | `src/lib/db/` |
| Build scripts | `script/` |
| Add property tests | `test/lib/<name>.property.test.ts` |
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ await sdk.dashboard.widget.add(

// Escape hatch for any CLI command
const version = await sdk.run("--version");
const text = await sdk.run("issue", "list", "-l", "5");
const text = await sdk.run("issue", "list", "-n", "5");
```

Options (all optional):
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"bench:save": "pnpm tsx script/bench.ts --save-baseline",
"bench:compare": "pnpm tsx script/bench.ts --compare",
"bench:sweep": "pnpm tsx script/bench-sweep.ts",
"check:fragments": "pnpm tsx script/check-fragments.ts",
"check:fragments": "pnpm tsx script/check-fragments.ts --strict",
"check:deps": "pnpm tsx script/check-no-deps.ts",
"check:errors": "pnpm tsx script/check-error-patterns.ts",
"check:patches": "pnpm tsx script/check-patches.ts",
Expand Down Expand Up @@ -146,6 +146,7 @@
"react": "^19.2.7",
"react-devtools-core": "^7.0.1",
"semver": "^7.8.5",
"shell-quote": "^1.10.0",
"string-width": "^8.2.1",
"tinyglobby": "^0.2.17",
"tsx": "^4.22.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ When querying the Events API (directly or via `sentry api`), valid dataset value

### Common Mistakes

- **Wrong issue ID format**: Use `PROJECT-123` (short ID), not the numeric ID `123456789`. The short ID includes the project prefix.
- **Wrong issue ID format**: Use the full short ID (`PROJECT-123`) or the numeric issue ID from a Sentry URL (`123456789`). A bare suffix without its project prefix, such as `123`, is read as a numeric issue ID, not as a short ID.
- **Pre-authenticating unnecessarily**: Don't run `sentry auth login` before every command. The CLI detects missing/expired auth and prompts automatically. Only run `sentry auth login` to add an account. With several stored accounts, commands pick the one that knows the target organization or server automatically; use `sentry auth switch` only to change the default.
- **Missing `--json` for piping**: Human-readable output includes formatting. Use `--json` when parsing output programmatically.
- **Specifying org/project when not needed**: Auto-detection resolves org/project from `.sentryclirc` config files, DSNs, env vars, and directory names. Let it work first — only add `<org>/<project>` if the CLI says it can't detect the target or detects the wrong one.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Create an issue alert rule
- `--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)`
- `--frequency <value> - Frequency in minutes (default: 30) - (default: 30)`
- `--frequency <value> - Frequency in minutes - (default: 30)`
- `--environment <value> - Environment filter`
- `--filter <value>... - Filter object JSON (repeatable, or pass one JSON array)`
- `-m, --filter-match <value> - Filter match mode: all or any`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Authenticate with Sentry

**Flags:**
- `--token <value> - Authenticate using an API token instead of OAuth`
- `--timeout <value> - Timeout for OAuth flow in seconds (default: 900) - (default: "900")`
- `--timeout <value> - Timeout for OAuth flow in seconds - (default: "900")`
- `--force - Replace the stored login for this server without prompting, instead of adding another account`
- `--url <value> - Sentry instance URL to authenticate against (e.g. https://sentry.example.com). Required for self-hosted; defaults to SaaS (https://sentry.io).`
- `--read-only - Request only read-only OAuth scopes (project:read, org:read, event:read, member:read, team:read). Useful for handing tokens to AI agents or CI jobs that should not be able to mutate Sentry state.`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ View a dashboard
- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data`
- `-r, --refresh <value> - Auto-refresh interval in seconds (default: 60, min: 10)`
- `-t, --period <value> - Time range: "7d", "2024-01-01..2024-02-01", ">=2024-01-01"`
- `--renderer <value> - Graphics renderer (defaults to auto; falls back to auto when unavailable) - (default: "auto")`
- `--renderer <value> - Graphics renderer (falls back to auto when unavailable) - (default: "auto")`
- `--no-graphics-cap - Use the terminal-native graphics width (may fall back to ASCII for very large dashboards)`

**Examples:**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ View a decoded Local event
Start the local dev server and tail events

**Flags:**
- `-p, --port <value> - Port to listen on (default 8969) - (default: "8969")`
- `-H, --host <value> - Hostname to bind to (default localhost) - (default: "localhost")`
- `-p, --port <value> - Port to listen on - (default: "8969")`
- `-H, --host <value> - Hostname to bind to - (default: "localhost")`
- `-q, --quiet - Suppress per-envelope tail output`
- `-f, --filter <value>... - Only show items of this type (repeatable: error, transaction, log, ai)`
- `-F, --format <value> - Output format: human (default) or json (NDJSON on stdout) - (default: "human")`
Expand All @@ -96,6 +96,9 @@ sentry local
# Use a custom port
sentry local --port 9000

# Receive into a daemon session that outlives this terminal
sentry local serve --session worker

# Only show errors and logs (filter out transactions)
sentry local -f error -f log

Expand Down Expand Up @@ -186,8 +189,8 @@ Run a command with the local dev server enabled
| `<command...>` | Command to run |

**Flags:**
- `-p, --port <value> - Port for the local server (default 8969) - (default: "8969")`
- `--host <value> - Hostname for the local server (default localhost) - (default: "localhost")`
- `-p, --port <value> - Port for the local server - (default: "8969")`
- `--host <value> - Hostname for the local server - (default: "localhost")`
- `-f, --filter <value>... - Only show items of this type (repeatable: error, transaction, log, ai)`
- `-V, --verify - Verify SDK sends events, then exit`
- `-t, --timeout <value> - Kill the child after N seconds (0 = no timeout; defaults to 30 s in --verify mode) - (default: "0")`
Expand All @@ -206,6 +209,20 @@ sentry local run -- npm run dev
# Run a Django dev server with the local server enabled
sentry local run -- python manage.py runserver

# Capture into a daemon session, inspect it after the app exits, then clean up
sentry local run --session web -- npm run dev
sentry local session list --json
sentry local session view web --json
sentry local session retention web --max-envelopes 2000
sentry local event list web --json
sentry local event view web <event-id> --json
sentry local envelope list web --json
sentry local envelope view web <envelope-id> --json
sentry local session reset web
sentry local session close web
sentry local daemon status
sentry local daemon stop

# Run your app and open the Sentry Local UI
sentry local run --open -- npm run dev

Expand Down
Loading
Loading