diff --git a/.oxlintrc.json b/.oxlintrc.json index 233e8d2e0..09ad86aca 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -72,6 +72,8 @@ "sentry-cli/no-generic-is-record": "error", "sentry-cli/prefer-paginate-helper": "error", "sentry-cli/no-namespace-import": "error", + "sentry-cli/no-examples-in-full-description": "error", + "sentry-cli/no-regex-markdown-parsing": "error", "no-restricted-imports": [ "error", { @@ -89,6 +91,12 @@ "sentry-cli/no-skipped-tests": "error" } }, + { + "files": ["packages/cli/script/**/*.ts"], + "rules": { + "sentry-cli/no-regex-markdown-parsing": "error" + } + }, { "files": ["packages/cli/src/**/*.{ts,tsx}"], "rules": { diff --git a/apps/cli-docs/src/fragments/commands/alert.md b/apps/cli-docs/src/fragments/commands/alert.md index 9b6d80c1d..302e1d80a 100644 --- a/apps/cli-docs/src/fragments/commands/alert.md +++ b/apps/cli-docs/src/fragments/commands/alert.md @@ -1,108 +1,8 @@ -## 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 '{"type":"first_seen_event","comparison":true,"conditionResult":true}' \ - --action '{"type":"email","data":{},"config":{"targetType":"team","targetIdentifier":"1"}}' -``` - -### 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 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 an issue alert rule - -```bash -# Delete with preview -sentry alert issues delete my-org/my-project/12345 --dry-run -``` - -### Create a metric alert rule - -```bash -# Alert when P95 span duration goes above 500ms -sentry alert metrics create my-org \ - --name "P95 Latency" \ - --project my-app \ - --query "environment:prod" \ - --aggregate "p95(span.duration)" \ - --dataset spans \ - --time-window 5 \ - --trigger '{"alertThreshold":500}' - -# Alert on any matching log line and notify through an existing alert -sentry alert metrics create my-org \ - --name "AI chat failures" \ - --project my-app \ - --query "action:ai.chat result:error" \ - --aggregate "count()" \ - --dataset logs \ - --time-window 5 \ - --trigger '{"alertThreshold":0,"resolveThreshold":0}' \ - --workflow 12345 -``` +## Metric alert triggers Triggers take `alertThreshold`, an optional `label` (`critical` or `warning`), `resolveThreshold`, and `thresholdType` (`0` above, `1` below). Notification actions are not part of triggers; pass `--workflow` with the ID of an existing alert to notify. - -### 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 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 a metric alert rule - -```bash -# Delete without prompt -sentry alert metrics delete my-org/67890 --yes -``` diff --git a/apps/cli-docs/src/fragments/commands/api.md b/apps/cli-docs/src/fragments/commands/api.md index 94185ab20..852926a6b 100644 --- a/apps/cli-docs/src/fragments/commands/api.md +++ b/apps/cli-docs/src/fragments/commands/api.md @@ -1,81 +1,21 @@ -## Examples +## Endpoints Endpoints are relative to `/api/0/` — the prefix is added automatically. Absolute HTTP(S) Sentry URLs also work; their origin is validated against your authenticated host. -### GET requests - -```bash -# List organizations -sentry api organizations/ - -# Get a specific issue -sentry api issues/123456789/ -``` - If a successful GET response is interrupted while downloading, the CLI retries within its existing limit of three attempts. This also applies to complete API responses read by other commands. The request timeout covers these response bodies; streaming responses such as SSE are excluded. -### POST requests - -```bash -# Create a release -sentry api organizations/my-org/releases/ \ - -X POST -F version=1.0.0 - -# With inline JSON body -sentry api issues/123456789/ \ - -X POST -d '{"status": "resolved"}' -``` - -### PUT requests - -```bash -# Update an issue status -sentry api issues/123456789/ \ - -X PUT -F status=resolved - -# Assign an issue -sentry api issues/123456789/ \ - -X PUT --field assignedTo="user@example.com" -``` - -### DELETE requests - -```bash -sentry api projects/my-org/my-project/ -X DELETE -``` - -### Advanced usage - -```bash -# Add custom headers -sentry api organizations/ -H "X-Custom: value" - -# Read body from a file -sentry api projects/my-org/my-project/releases/ -X POST --input release.json - -# Verbose mode (shows full HTTP request/response) -sentry api organizations/ --verbose - -# Preview the request without sending -sentry api organizations/ --dry-run -``` - -### Dataset Names +## Dataset Names When querying the Events API (`/events/` endpoint), valid dataset values are: `spans`, `logs`, `errors`, `tracemetrics`, `profile_functions`, and `uptime_results`. -### Binary responses - -Endpoints that return binary data — image attachments, minidumps, debug files — are streamed to stdout as raw bytes, so you can redirect them straight to a file: +## Binary responses -```bash -sentry api "https://sentry.io/api/0/projects/my-org/my-project/events/EVENT_ID/attachments/ATTACHMENT_ID/?download=1" > screenshot.png -``` +Endpoints that return binary data — image attachments, minidumps, debug files — are streamed to stdout as raw bytes, so you can redirect them straight to a file. When the response is a PNG or JPEG image **and** you're on a graphics-capable terminal, the image is rendered inline instead of dumping raw bytes into your session. Terminals that speak the newer kitty graphics protocol (kitty, WezTerm, Ghostty, recent Konsole) are used in preference to sixel, which remains the fallback for older terminals. Redirecting or piping stdout always keeps the raw bytes. Set `SENTRY_NO_GRAPHICS=1` (or run `sentry cli defaults graphics off`) to disable inline rendering; `SENTRY_NO_SIXEL` is still honored as a deprecated alias. diff --git a/apps/cli-docs/src/fragments/commands/auth.md b/apps/cli-docs/src/fragments/commands/auth.md index f4318a80e..171656835 100644 --- a/apps/cli-docs/src/fragments/commands/auth.md +++ b/apps/cli-docs/src/fragments/commands/auth.md @@ -1,12 +1,6 @@ -## Examples - -### OAuth login (recommended) - -```bash -sentry auth -``` +## OAuth login Bare `sentry auth` logs in when you're logged out and shows status when you're already authenticated. `sentry auth login` always starts the login flow. @@ -18,49 +12,19 @@ already authenticated. `sentry auth login` always starts the login flow. 5. The CLI stores the OAuth credentials and, when the server provides a refresh token, automatically refreshes the access token -### Token login - -```bash -sentry auth --token YOUR_SENTRY_API_TOKEN -``` - -### Read-only OAuth login - -Request only read-only scopes — useful for tokens handed to AI agents or -CI jobs that should not mutate Sentry state: - -```bash -sentry auth --read-only -``` - -### Custom OAuth scopes - -Request specific scopes (repeatable, comma-separated): +Use `--read-only` to request only read-only scopes — useful for tokens handed +to AI agents or CI jobs that should not mutate Sentry state. Use `--scope` to +request specific scopes (repeatable, comma-separated). -```bash -sentry auth --scope project:read --scope org:read -sentry auth --scope project:read,event:read -``` - -### Self-hosted Sentry +## Self-hosted Sentry Pass `--url` to log in to a self-hosted instance. Setting `SENTRY_HOST` or `SENTRY_URL` alone is not enough: the CLI refuses to log in to a self-hosted host unless `--url` confirms it. -```bash -sentry auth --url https://sentry.example.com -``` - -For token-based auth with self-hosted: - -```bash -sentry auth --token YOUR_TOKEN --url https://sentry.example.com -``` - See [Self-Hosted Sentry](../../self-hosted/) for details. -### Multiple accounts +## Multiple accounts The CLI can store several accounts at once — for example a work and a personal account, or a SaaS and a self-hosted login. When you're already logged in, @@ -70,19 +34,8 @@ credentials instead of adding a duplicate. `--force` skips the prompt and replaces the stored login for that server instead (or adds one when that server has none); accounts on other servers are never replaced. -```bash -# Add (or log in again to) a specific account without prompting -sentry auth login jane@example.com -sentry auth login jane@example.com --url https://sentry.example.com -sentry auth login jane@example.com:sentry.example.com # same as --url - -# Show stored accounts; * marks the active one -sentry auth list - -# Switch the account commands use (pick from a searchable list without an argument) -sentry auth switch jane@example.com -sentry auth switch -``` +Use `sentry auth list` to show stored accounts and `sentry auth switch` to +change the active one. Sentry approves a device-flow login as whoever is signed in to the browser, so `sentry auth login ` checks the approved account and refuses (saving @@ -139,62 +92,6 @@ account's server. `SENTRY_HOST`/`SENTRY_URL` and `SENTRY_AUTH_TOKEN` (with `SENTRY_FORCE_ENV_TOKEN=1`) still take precedence over the active account. Default organization and project settings are shared by all accounts. -### Logout - -```bash -# Log out of the active account (the most recently used other account becomes active) -sentry auth logout - -# Log out of specific accounts (space- or comma-separated) -sentry auth logout jane@example.com -sentry auth logout jane@example.com,jane@personal.dev - -# Pick the account on one server when the same email is stored twice -sentry auth logout jane@example.com --url https://sentry.example.com - -# Log out of every stored account -sentry auth logout all -``` - -### Refresh the OAuth access token - -```bash -sentry auth refresh - -# Refresh with read-only scopes -sentry auth refresh --read-only - -# Refresh with specific scopes -sentry auth refresh --scope project:read --scope org:read -``` - -### Print stored token - -```bash -sentry auth token -``` - -### Check auth status - -```bash -sentry auth status -``` - -``` -✓ Authenticated -User: username -Access token expires: in 4 weeks -Automatic refresh: enabled -``` - -```bash -# Show the raw token -sentry auth status --show-token - -# View current user -sentry auth whoami -``` - ## Credential Storage Auth tokens are stored in the Sentry CLI configuration directory diff --git a/apps/cli-docs/src/fragments/commands/build.md b/apps/cli-docs/src/fragments/commands/build.md index b8cf4c258..e7c3f52bf 100644 --- a/apps/cli-docs/src/fragments/commands/build.md +++ b/apps/cli-docs/src/fragments/commands/build.md @@ -1,18 +1,5 @@ -## Examples - -```bash -# Download a build artifact by ID -sentry build download 1234567890 - -# Download to a specific path -sentry build download 1234567890 --output ./app.ipa - -# Output the result as JSON -sentry build download 1234567890 --json -``` - ## Important Notes - `build upload` supports **Android APK/AAB** and **iOS XCArchive/IPA**. An diff --git a/apps/cli-docs/src/fragments/commands/cli.md b/apps/cli-docs/src/fragments/commands/cli.md index 798e84b9c..7b13f5050 100644 --- a/apps/cli-docs/src/fragments/commands/cli.md +++ b/apps/cli-docs/src/fragments/commands/cli.md @@ -1,45 +1,8 @@ -## Examples - -### Check for updates - -```bash -sentry cli upgrade --check -``` - -``` -Installation method: curl -Current version: 0.4.0 -Channel: stable -Latest version: 0.5.0 - -Run 'sentry cli upgrade' to update. -``` - -### Upgrade - -```bash -# Upgrade to latest stable -sentry cli upgrade - -# Upgrade to a specific version -sentry cli upgrade 0.5.0 - -# Force re-download -sentry cli upgrade --force -``` - -### Release Channels - -```bash -# Switch to nightly builds -sentry cli upgrade nightly - -# Switch back to stable -sentry cli upgrade stable -``` +## Release Channels +`sentry cli upgrade nightly` and `sentry cli upgrade stable` switch channels. After switching, bare `sentry cli upgrade` will continue tracking that channel. | Channel | Description | @@ -47,7 +10,7 @@ After switching, bare `sentry cli upgrade` will continue tracking that channel. | `stable` | Latest stable release (default) | | `nightly` | Built from `main`, updated on every commit | -### Installation Detection +## Installation Detection The CLI detects how it was installed and uses the appropriate upgrade method: @@ -62,118 +25,13 @@ The CLI detects how it was installed and uses the appropriate upgrade method: Nightly builds are only available as standalone binaries (via the curl install method). Switching to nightly from a Homebrew or package manager install will automatically migrate to a standalone binary. -### View and manage defaults - -```bash -# Show all current defaults -sentry cli defaults - -# Set default organization -sentry cli defaults org my-org - -# Set default project -sentry cli defaults project my-project - -# Set default Sentry URL (self-hosted) -sentry cli defaults url https://sentry.example.com - -# Set custom HTTP headers (self-hosted, e.g. for IAP/proxies) -sentry cli defaults headers "X-IAP: token" - -# Set a custom CA certificate (self-hosted, behind a TLS proxy) -sentry cli defaults ca-cert /path/to/ca.pem - -# Disable telemetry -sentry cli defaults telemetry off - -# Hide Tip: hints in command output -sentry cli defaults tips off - -# Clear a single default -sentry cli defaults org --clear - -# Clear all defaults -sentry cli defaults --clear -``` - -### Import legacy settings - -Import settings from `.sentryclirc` files used by the legacy `sentry-cli`: - -```bash -# Auto-detect and import .sentryclirc -sentry cli import - -# Preview what would be imported -sentry cli import --dry-run - -# Skip confirmation prompt -sentry cli import --yes - -# Explicitly trust a self-hosted URL -sentry cli import --url https://sentry.example.com - -# Skip API validation of the imported token -sentry cli import --skip-validation -``` - -### Send feedback - -```bash -# Send positive feedback -sentry cli feedback i love this tool - -# Report an issue -sentry cli feedback the issue view is confusing -``` +## Feedback Feedback is sent via Sentry's telemetry system. If telemetry is disabled (`SENTRY_CLI_NO_TELEMETRY=1`, `DO_NOT_TRACK=1`, or `sentry cli defaults telemetry off`), feedback cannot be sent. -### Fix configuration issues - -```bash -sentry cli fix -``` - -### Print shell completions - -```bash -# Print completions for your current shell (auto-detected from $SHELL) -sentry cli completion - -# Generate for a specific shell -sentry cli completion zsh > ~/.local/share/zsh/site-functions/_sentry -eval "$(sentry cli completion bash)" -sentry cli completion fish > ~/.config/fish/completions/sentry.fish -``` - -### Configure shell integration - -```bash -# Run full setup (PATH, completions, agent skills) -sentry cli setup - -# Skip agent skill installation -sentry cli setup --no-agent-skills - -# Skip PATH and completion modifications -sentry cli setup --no-modify-path --no-completions -``` +## Shell integration For zsh, setup initializes completion when needed and registers Sentry even if another tool has already initialized it. Running setup again repairs completion configuration from older installs. Restart your shell or source your `.zshrc` after setup to load the changes. - -### Uninstall - -```bash -# Show what would be removed (dry run) -sentry cli uninstall --dry-run - -# Uninstall, keeping config directory -sentry cli uninstall --yes --keep-config - -# Full uninstall with confirmation -sentry cli uninstall -``` diff --git a/apps/cli-docs/src/fragments/commands/code-mappings.md b/apps/cli-docs/src/fragments/commands/code-mappings.md index 8d47cb6f0..3c2ba6412 100644 --- a/apps/cli-docs/src/fragments/commands/code-mappings.md +++ b/apps/cli-docs/src/fragments/commands/code-mappings.md @@ -1,22 +1,5 @@ - -## Examples - -```bash -# Upload code mappings from a JSON file -sentry code-mappings upload mappings.json - -# Specify repository explicitly -sentry code-mappings upload mappings.json --repo owner/repo - -# Specify repository and default branch -sentry code-mappings upload mappings.json --repo owner/repo --default-branch develop - -# Output as JSON -sentry code-mappings upload mappings.json --json -``` - ## Input Format The JSON file must contain an array of objects with `stackRoot` and `sourceRoot`: diff --git a/apps/cli-docs/src/fragments/commands/dart-symbol-map.md b/apps/cli-docs/src/fragments/commands/dart-symbol-map.md index 9ff976fcb..d30aad78a 100644 --- a/apps/cli-docs/src/fragments/commands/dart-symbol-map.md +++ b/apps/cli-docs/src/fragments/commands/dart-symbol-map.md @@ -1,18 +1,5 @@ -## Examples - -```bash -# Upload a dart symbol map with a debug ID -sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json - -# Validate without uploading -sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json --no-upload - -# Output as JSON -sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json --json -``` - ## Important Notes - The `--debug-id` flag is **required** — it associates the map with a native diff --git a/apps/cli-docs/src/fragments/commands/dashboard.md b/apps/cli-docs/src/fragments/commands/dashboard.md index 9d8a1f2e1..afd1cd2a4 100644 --- a/apps/cli-docs/src/fragments/commands/dashboard.md +++ b/apps/cli-docs/src/fragments/commands/dashboard.md @@ -1,48 +1,6 @@ -## Examples - -### List dashboards - -```bash -# List all dashboards -sentry dashboard list - -# Filter by name pattern -sentry dashboard list "Backend*" - -# Open dashboard list in browser -sentry dashboard list -w -``` - -``` -ID TITLE WIDGETS CREATED -12345 General 4 2024-01-15 -12346 Frontend Performance 6 2024-02-20 -12347 Backend Errors 3 2024-03-10 -``` - -### View a dashboard - -```bash -# View by title -sentry dashboard view 'Frontend Performance' - -# View by ID -sentry dashboard view 12345 - -# View by ID in an explicit organization -sentry dashboard view my-org/12345 - -# Include project context in the same argument -sentry dashboard view my-org/my-project/12345 - -# Auto-refresh every 30 seconds -sentry dashboard view "Backend Performance" --refresh 30 - -# Open in browser -sentry dashboard view 12345 -w -``` +## Dashboard references Numeric IDs accept `org/ID` and `org/project/ID` in `view`, `revisions`, `restore`, and the widget commands. Dashboards belong to the organization; @@ -52,109 +10,8 @@ Titles containing `/` are still supported. If a title looks like a qualified numeric ID, pass the organization separately to select it by title: `sentry dashboard view my-org/ "incidents/2026"`. -``` -Dashboard: Frontend Performance (ID: 12345) -URL: https://my-org.sentry.io/dashboard/12345/ - -Widgets: - #0 Error Count big_number count() - #1 Errors Over Time line count() - #2 Errors by Browser bar count() group by browser.name - #3 Top Endpoints table count(), p95(span.duration) group by transaction -``` - -### Create a dashboard - -```bash -sentry dashboard create 'Frontend Performance' -``` - -``` -Created dashboard: Frontend Performance (ID: 12348) -URL: https://my-org.sentry.io/dashboard/12348/ -``` - -### Add widgets - -```bash -# Simple counter widget -sentry dashboard widget add 'My Dashboard' "Error Count" \ - --display big_number --query count - -# Use an ID in an explicit organization -sentry dashboard widget add my-org/12345 "Error Count" \ - --display big_number --query count - -# Line chart with group-by -sentry dashboard widget add 'My Dashboard' "Errors by Browser" \ - --display line --query count --group-by browser.name - -# Table with multiple aggregates, sorted descending -sentry dashboard widget add 'My Dashboard' "Top Endpoints" \ - --display table \ - --query count --query p95:span.duration \ - --group-by transaction \ - --sort -count --limit 10 - -# With search filter -sentry dashboard widget add 'My Dashboard' "Slow Requests" \ - --display bar --query p95:span.duration \ - --where "span.op:http.client" \ - --group-by span.description -``` - -### Edit widgets - -```bash -# Change display type -sentry dashboard widget edit 12345 --title 'Error Count' --display bar - -# Rename a widget -sentry dashboard widget edit 'My Dashboard' --index 0 --new-title 'Total Errors' - -# Change the query -sentry dashboard widget edit 12345 --title 'Error Rate' --query p95:span.duration -``` - -### Delete widgets - -```bash -# Delete by title -sentry dashboard widget delete 'My Dashboard' --title 'Error Count' - -# Delete by index -sentry dashboard widget delete 12345 --index 2 -``` - -### View revision history - -```bash -# List revisions by dashboard title -sentry dashboard revisions 'Frontend Performance' - -# List revisions by dashboard ID -sentry dashboard revisions 12345 - -# With explicit org -sentry dashboard revisions my-org 12345 -``` - -### Restore a previous revision - -```bash -# Restore by dashboard title and revision number -sentry dashboard restore 'Frontend Performance' --revision 3 - -# Restore by dashboard ID -sentry dashboard restore 12345 --revision 1 - -# With explicit org -sentry dashboard restore my-org 12345 --revision 1 -``` - -:::tip -Use `sentry dashboard revisions` to find the revision number before restoring. -::: +Use `sentry dashboard revisions` to find a revision number before running +`sentry dashboard restore`. ## Query Shorthand diff --git a/apps/cli-docs/src/fragments/commands/debug-files.md b/apps/cli-docs/src/fragments/commands/debug-files.md index 979839c15..da8bcc3f7 100644 --- a/apps/cli-docs/src/fragments/commands/debug-files.md +++ b/apps/cli-docs/src/fragments/commands/debug-files.md @@ -1,56 +1,5 @@ - -## Examples - -```bash -# Inspect a debug information file (auto-detects the format) -sentry debug-files check ./libexample.so -sentry debug-files check MyApp.dSYM/Contents/Resources/DWARF/MyApp -sentry debug-files check ./app.pdb --json - -# List the source files a debug file references (and whether they're available) -sentry debug-files print-sources ./libexample.so -sentry debug-files print-sources ./app.pdb --json - -# Locate debug files for one or more debug identifiers on disk -sentry debug-files find -sentry debug-files find --type dsym --path ./build -sentry debug-files find --no-cwd --no-well-known -p /symbols --json - -# Bundle a debug file's referenced source files (run on the build machine) -sentry debug-files bundle-sources ./libexample.so -sentry debug-files bundle-sources ./app.pdb --output ./app.src.zip - -# Bundle JVM sources with a debug ID -sentry debug-files bundle-jvm --output ./out --debug-id ./src - -# Exclude additional directories -sentry debug-files bundle-jvm --output ./out --debug-id --exclude generated --exclude build-tools ./src - -# Output as JSON -sentry debug-files bundle-jvm --output ./out --debug-id --json ./src - -# Upload debug information files (scans directories recursively) -sentry debug-files upload ./build -sentry debug-files upload ./libexample.so --include-sources - -# .zip archives are scanned in place; use --no-zips to skip them -sentry debug-files upload ./symbols.zip -sentry debug-files upload ./build --no-zips - -# Restrict by type or debug id, and wait for server-side processing -sentry debug-files upload ./dsyms --type dsym --wait -sentry debug-files upload ./build --id --require-all - -# Unity: upload IL2CPP line mappings (optionally with referenced C# sources) -sentry debug-files upload ./build --il2cpp-mapping -sentry debug-files upload ./build --il2cpp-mapping --include-sources - -# Preview what would be uploaded without uploading (no credentials needed) -sentry debug-files upload ./build --no-upload -``` - ## Notes on `find` - `debug-files find` locates debug files **locally** by debug identifier — it diff --git a/apps/cli-docs/src/fragments/commands/docs.md b/apps/cli-docs/src/fragments/commands/docs.md index c1b073749..ecd019143 100644 --- a/apps/cli-docs/src/fragments/commands/docs.md +++ b/apps/cli-docs/src/fragments/commands/docs.md @@ -1,24 +1,8 @@ -## Examples -### Ask a documentation question -```bash -sentry docs "How do I configure tracing in Next.js?" -``` +## Answers and sources -The answer includes inline links and a Sources section containing the Sentry -documentation pages used to answer the question. - -### Search the documentation index - -```bash -sentry docs list "source maps" -``` - -``` -TITLE DESCRIPTION URL -Source Maps Upload source maps for JavaScript https://docs.sentry.io/... -``` - -Use `--limit` to restrict the number of results or `--json` for structured -output. +`sentry docs` answers include inline links and a Sources section containing the +Sentry documentation pages used to answer the question. Use `sentry docs list` +to search the documentation index instead; `--limit` restricts the number of +results and `--json` returns structured output. diff --git a/apps/cli-docs/src/fragments/commands/dsn.md b/apps/cli-docs/src/fragments/commands/dsn.md index 25cf2d906..0e661b508 100644 --- a/apps/cli-docs/src/fragments/commands/dsn.md +++ b/apps/cli-docs/src/fragments/commands/dsn.md @@ -1,23 +1,6 @@ -## Examples -```bash -# List client keys for detected projects, including monorepos -sentry dsn list - -# List enabled and disabled DSNs for one project -sentry dsn list my-org/my-project - -# List DSNs across all accessible projects in an organization -sentry dsn list my-org/ - -# Navigate between pages -sentry dsn list my-org/ --limit 10 -c next -sentry dsn list my-org/ --limit 10 -c prev - -# Select public DSN fields as JSON -sentry dsn list my-org/my-project --json --fields name,dsn,isActive -``` +## Output and targets Each entry shows the project, name, enabled status, creation date, and public DSN available in Sentry's **Settings → Projects → Client Keys (DSN)**. A missing diff --git a/apps/cli-docs/src/fragments/commands/event.md b/apps/cli-docs/src/fragments/commands/event.md index 1cb7e39fb..1c273cf96 100644 --- a/apps/cli-docs/src/fragments/commands/event.md +++ b/apps/cli-docs/src/fragments/commands/event.md @@ -1,41 +1,11 @@ - -## Examples - -### Sending Events - -```bash -# Send an error event (default level) -sentry event send -m "Something went wrong" - -# Specify level, release, and environment -sentry event send -m "Deploy check" -l info -r 1.0.0 -E production - -# Add tags and extra data -sentry event send -m "Payment failed" --tag env:prod --tag region:us-east --extra amount:99.99 - -# Set user context -sentry event send -m "Login error" --user id:42 --user email:alice@example.com - -# Custom fingerprint to group related events together -sentry event send -m "DB timeout" --fingerprint db-timeout --fingerprint {{ default }} -``` - -### Send from a JSON file - -```bash -# Send a serialized Sentry Event object -sentry event send ./crash.json - -# Send without re-parsing (raw mode — also supports pre-built envelopes) -sentry event send --raw ./crash.json -sentry event send --raw ./captured.envelope -``` +## Sending from a file Prefix relative file paths with `./` to distinguish them from a project target. +`--raw` sends the file without re-parsing and also accepts pre-built envelopes. -### DSN authentication +## DSN authentication `sentry event send` authenticates with ingest via a **DSN**, not a user token. An explicit DSN, `SENTRY_DSN`, and project auto-detection do not require login. @@ -49,83 +19,12 @@ The DSN is resolved in priority order: 2. `SENTRY_DSN` environment variable 3. Auto-detection from the current project (`.env`, source code, env files) -```bash -# Explicit DSN -sentry event send "https://key@o123.ingest.us.sentry.io/456" -m "Test" +## Attachments -# Via environment variable -export SENTRY_DSN="https://key@o123.ingest.us.sentry.io/456" -sentry event send -m "Test" - -# Project target (logged-in session; CLI fetches its sole active DSN) -sentry event send cli -m "Test" - -# Org/project target -sentry event send sentry/cli -m "Test" - -# Auto-detect from the current project -sentry event send -m "Test" -``` - -### Listing Events - -```bash -# List events for an issue (using short ID) -sentry event list PROJ-ABC - -# List events for an issue (using numeric ID) -sentry event list 123456789 - -# Filter by search query -sentry event list PROJ-ABC --query "browser:Chrome" - -# Include full event bodies (stacktraces) -sentry event list PROJ-ABC --full - -# Limit results and time range -sentry event list PROJ-ABC --limit 50 --period 24h - -# Paginate through results -sentry event list PROJ-ABC -c next -sentry event list PROJ-ABC -c prev - -# Output as JSON -sentry event list PROJ-ABC --json -``` - -### Viewing Events +`sentry event view --json` lists an event's attachment metadata. Download an +attachment with `sentry api`: ```bash -sentry event view abc123def456abc123def456abc12345 -``` - -``` -Event: abc123def456abc123def456abc12345 -Issue: FRONT-ABC -Timestamp: 2024-01-20 14:22:00 - -Exception: - TypeError: Cannot read property 'foo' of undefined - at processData (app.js:123:45) - at handleClick (app.js:89:12) - at HTMLButtonElement.onclick (app.js:45:8) - -Tags: - browser: Chrome 120 - os: Windows 10 - environment: production - release: 1.2.3 - -Context: - url: https://example.com/app - user_id: 12345 -``` - -```bash -# Open in browser -sentry event view abc123def456abc123def456abc12345 -w - -# Download an attachment listed by `sentry event view --json` sentry api "https://sentry.io/api/0/projects/my-org/my-project/events/EVENT_ID/attachments/ATTACHMENT_ID/?download=1" > screenshot.png ``` diff --git a/apps/cli-docs/src/fragments/commands/explore.md b/apps/cli-docs/src/fragments/commands/explore.md index 70adfa6c9..7dc9a995c 100644 --- a/apps/cli-docs/src/fragments/commands/explore.md +++ b/apps/cli-docs/src/fragments/commands/explore.md @@ -1,101 +1,10 @@ -## Examples - -### Top errors (default) - -```bash -# Top errors in the last 24 hours, scoped to a project -sentry explore my-org/cli - -# All projects in an org -sentry explore my-org/ - -# Bare project slug (searches across orgs) -sentry explore cli - -# Auto-detect from DSN/config -sentry explore -``` - -### Spike analysis - -```bash -# Errors with user impact for a specific UTC window -sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" \ - --period "2024-01-15T00:00:00Z/2024-01-16T00:00:00Z" - -# Filter by specific error type (combines with auto-injected project filter) -sentry explore my-org/cli -F title -F "count()" \ - -q "error.type:TypeError" --period 1h -``` - -### Span queries (performance) - -```bash -# Span operation latency by route -sentry explore my-org/cli -F span.op -F "p50(span.duration)" \ - -F "p95(span.duration)" --dataset spans --period 1h - -# Top spans by count -sentry explore my-org/cli -F span.op -F "count()" \ - --dataset spans --sort "-count()" -``` - -### Metrics +## Metrics Use `--metric` (`-m`) to query metrics by name. The CLI auto-resolves the metric's type and unit. - -```bash -# Sum a custom metric (e.g., LLM token usage) across an org -sentry explore my-org/ -m llm.token_usage --dataset metrics --period 7d - -# Break down by a tag column (e.g., model name) -sentry explore my-org/seer -F gen_ai.request.model \ - -m llm.token_usage --dataset metrics --period 7d - -# Use a different aggregation (default is sum) -sentry explore my-org/ -m cache.hit_rate --agg avg --dataset metrics -``` - You can also use the raw tracemetrics format: `aggregation(value,metric_name,metric_type,unit)`. -```bash -sentry explore my-org/ \ - -F "sum(value,llm.token_usage,distribution,none)" \ - --dataset metrics --period 7d -``` - -### Replays - -```bash -# List recent replays -sentry explore my-org/cli --dataset replays --period 24h - -# Filter replays by activity level -sentry explore my-org/cli --dataset replays -F activity -F duration \ - -F "count_errors" --period 7d -``` - -### Logs - -```bash -# Log severity counts in the last hour -sentry explore my-org/cli -F severity -F "count()" \ - --dataset logs --period 1h -``` - -### JSON output for scripting - -```bash -# Pipe to jq for filtering -sentry explore my-org/cli -F title -F "count()" --json | jq '.data[:5]' - -# Get raw data for analysis -sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" \ - --json --limit 100 -``` - ## Datasets | Dataset | Description | diff --git a/apps/cli-docs/src/fragments/commands/feedback.md b/apps/cli-docs/src/fragments/commands/feedback.md index 0e2320d1a..370da1362 100644 --- a/apps/cli-docs/src/fragments/commands/feedback.md +++ b/apps/cli-docs/src/fragments/commands/feedback.md @@ -1,129 +1,35 @@ -## Examples -### List User Feedback -Modern User Feedback is stored as Feedback issues. The command always limits -issue searches to `issue.category:feedback`; it does not use the legacy User -Reports API. +## Feedback issues -```bash -# Auto-detect the organization from the current project -sentry feedback list +Modern User Feedback is stored as Feedback issues. `sentry feedback list` +always limits issue searches to `issue.category:feedback`; it does not use the +legacy User Reports API. -# List Feedback for one project -sentry feedback list my-org/frontend +The unresolved inbox from the last 14 days is shown by default. Use `--status` +to select another mailbox (`resolved`, `spam`, or `all`) and `--period` to +expand the time range. Use `--json` for the standard paginated envelope. +Navigate pages in either direction with `--cursor next` and `--cursor prev`. -# List Feedback across every project in an organization -sentry feedback list my-org/ +## Viewing Feedback -# Search for a project across accessible organizations -sentry feedback list frontend -``` - -The unresolved inbox from the last 14 days is shown by default. Select another -mailbox or expand the time range with flags: - -```bash -sentry feedback list my-org/frontend --status resolved -sentry feedback list my-org/frontend --status spam -sentry feedback list my-org/frontend --status all --period 90d -sentry feedback list my-org/frontend --query "message:*checkout*" -``` - -Use `--json` for the standard paginated envelope. Navigate pages in either -direction with `--cursor next` and `--cursor prev`. - -### View User Feedback - -```bash -# Most recent unresolved Feedback, with detected or explicit organization -sentry feedback view @latest -sentry feedback view my-org/@latest - -# Short ID or numeric ID -sentry feedback view FRONTEND-2SDJ -sentry feedback view 5146636313 - -# Explicit organization -sentry feedback view my-org/FRONTEND-2SDJ - -# `view` is the default command; `show` is an alias -sentry feedback my-org/FRONTEND-2SDJ -sentry feedback show my-org/FRONTEND-2SDJ - -# Open the Feedback item in Sentry -sentry feedback view my-org/FRONTEND-2SDJ --web -``` - -`@latest` selects the most recently active unresolved Feedback. +`@latest` selects the most recently active unresolved Feedback. `view` is the +default command, and `show` is an alias. The detail view includes the complete message and, when available, its latest event, linked error, Session Replays, and attachment metadata. If the supplied ID belongs to another issue category, use `sentry issue view` instead. -### Resolve User Feedback - -```bash -# Resolve a Feedback item immediately -sentry feedback resolve my-org/FRONTEND-2SDJ - -# Resolve the most recently active unresolved Feedback -sentry feedback resolve my-org/@latest - -# Return the updated Feedback, or select specific fields -sentry feedback resolve my-org/FRONTEND-2SDJ --json --fields id,shortId,status -``` +## Updating Feedback `resolve` accepts the same IDs and URLs as `view` and reads the current state before selecting a Feedback item. It rejects other issue categories before making changes. JSON output contains the updated Feedback issue from Sentry. -### Reopen User Feedback - -```bash -# Find resolved Feedback -sentry feedback list --status resolved - -# Reopen a Feedback item using its short ID or numeric ID -sentry feedback unresolve FRONTEND-2SDJ -sentry feedback unresolve 5146636313 - -# `reopen` is an alias for `unresolve` -sentry feedback reopen FRONTEND-2SDJ - -# Specify an organization explicitly when needed -sentry feedback unresolve my-org/FRONTEND-2SDJ - -# Return selected fields from the updated Feedback -sentry feedback unresolve FRONTEND-2SDJ --json --fields id,shortId,status -``` - -`unresolve` marks Feedback as `unresolved`, reopening resolved Feedback or -returning spam to the inbox. It uses the same identifier resolution and category -check as `resolve`. Other issue categories are rejected before making changes. -JSON output contains the updated Feedback issue from Sentry. - -### Mark User Feedback as spam - -```bash -# Move a Feedback item to the spam mailbox -sentry feedback spam FRONTEND-2SDJ -sentry feedback spam 5146636313 - -# Specify an organization explicitly when needed -sentry feedback spam my-org/FRONTEND-2SDJ - -# Return selected fields from the updated Feedback -sentry feedback spam FRONTEND-2SDJ --json --fields id,shortId,status -``` - -To return spam to the unresolved inbox: - -```bash -# Find spam and return a Feedback item to the unresolved inbox -sentry feedback list --status spam -sentry feedback unresolve FRONTEND-2SDJ -``` +`unresolve` (alias `reopen`) marks Feedback as `unresolved`, reopening resolved +Feedback or returning spam to the inbox. It uses the same identifier resolution +and category check as `resolve`. Other issue categories are rejected before +making changes. JSON output contains the updated Feedback issue from Sentry. `spam` checks that the target is Feedback before updating it. Sentry stores spam with status `ignored`, which is also the value returned in JSON output. Use diff --git a/apps/cli-docs/src/fragments/commands/info.md b/apps/cli-docs/src/fragments/commands/info.md index de341e208..4baa38f41 100644 --- a/apps/cli-docs/src/fragments/commands/info.md +++ b/apps/cli-docs/src/fragments/commands/info.md @@ -1,15 +1,4 @@ -## Examples -```bash -# Print the resolved config and verify authentication -sentry info - -# Verify only authentication (don't require a default org/project) -sentry info --no-defaults - -# Machine-readable status for external tooling (always exits 0) -sentry info --config-status-json -``` ## Important Notes diff --git a/apps/cli-docs/src/fragments/commands/init.md b/apps/cli-docs/src/fragments/commands/init.md index 0cc4aa942..d8c93fa03 100644 --- a/apps/cli-docs/src/fragments/commands/init.md +++ b/apps/cli-docs/src/fragments/commands/init.md @@ -6,34 +6,6 @@ In organization, team, and monorepo app selectors, type to filter the loaded choices by name or slug. The filter appears as `/text` below the list. Matching ignores case and tolerates small typos, including in unfinished prefixes such as `frone` for `frontend-web`. Queries with one or two characters match literal text only. Use arrow keys to navigate, Enter to select, and Backspace to edit. Esc clears an active filter; with no filter, Esc cancels. Ctrl+C always cancels. -## Examples - -```bash -# Interactive setup -sentry init - -# Non-interactive agent/CI setup -sentry init --yes --features errors,tracing,replay - -# Dry run to preview changes -sentry init --dry-run - -# Target a subdirectory -sentry init ./my-app - -# Use a specific org (auto-detect project) -sentry init acme/ - -# Use a specific org and project -sentry init acme/my-app - -# Assign a team when creating a new project -sentry init acme/ --team backend - -# Enable specific features -sentry init --features profiling,replay -``` - ## Target Syntax | Syntax | Meaning | diff --git a/apps/cli-docs/src/fragments/commands/issue.md b/apps/cli-docs/src/fragments/commands/issue.md index 2c3256152..7f7384b7f 100644 --- a/apps/cli-docs/src/fragments/commands/issue.md +++ b/apps/cli-docs/src/fragments/commands/issue.md @@ -1,55 +1,6 @@ -## Examples - -### List issues - -```bash -# List issues in a specific project -sentry issue list my-org/frontend - -# Several projects in the same org -sentry issue list my-org/frontend,backend,worker - -# All projects in an org -sentry issue list my-org/ - -# Search for a project across organizations -sentry issue list frontend -``` - -``` -ID SHORT ID TITLE COUNT USERS -123456789 FRONT-ABC TypeError: Cannot read prop... 1.2k 234 -987654321 FRONT-DEF ReferenceError: x is not de... 456 89 -``` - -**Filter by status and search:** - -```bash -# Show only unresolved issues -sentry issue list my-org/frontend --query "is:unresolved" - -# Show resolved issues -sentry issue list my-org/frontend --query "is:resolved" - -# Sort by frequency -sentry issue list my-org/frontend --sort freq --limit 20 - -# Sort by Sentry's "recommended" relevance ranking (the default on sentry.io; -# self-hosted instances default to "date" and require a recent Sentry version -# to accept --sort recommended) -sentry issue list my-org/frontend --sort recommended - -# Multiple filters (space-separated = implicit AND) -sentry issue list --query "is:unresolved level:error assigned:me" - -# Negation and wildcards -sentry issue list --query "!browser:Chrome message:*timeout*" - -# Match multiple values for one key (in-list syntax) -sentry issue list --query "browser:[Chrome,Firefox]" -``` +## Search syntax :::caution[Search syntax] Sentry search uses **implicit AND** — space-separated terms are all required. @@ -61,169 +12,49 @@ Sentry search uses **implicit AND** — space-separated terms are all required. Full syntax reference: [Sentry Search Docs](https://docs.sentry.io/concepts/search/) ::: -### Magic selectors - -Use `@latest` and `@most_frequent` to target issues without knowing their ID: +## Magic selectors -```bash -# View the most recent issue -sentry issue view @latest +Use `@latest` and `@most_frequent` to target issues without knowing their ID. -# Explain the most frequently occurring issue -sentry issue explain @most_frequent - -# Generate a fix plan for the latest issue -sentry issue plan @latest -``` - -### Common mistakes +## Common mistakes - **Don't use the issue command name as an issue prefix** — `sentry issue explain issue-1` is parsed as project `issue` + suffix `1`. Use a real project prefix: `sentry issue explain FRONT-1` or a numeric ID: `sentry issue explain 123456789`. - **Issue short IDs use uppercase prefixes** — `CLI-G`, not `cli-g`. The CLI tolerates lowercase input in most commands, but agents should prefer the canonical form. - **`org/project` targets use slugs, not numeric IDs** — `sentry issue list my-org/6775615880` fails when `6775615880` is a project ID copied from a URL. Run `sentry project list my-org/` to find the slug (e.g. `frontend`). - **Prefer auto-detect over guessing slugs** — omit the target when possible; the CLI resolves org/project from DSNs, `.env` files, and your working directory. -### List events for an issue - -```bash -# List recent events for an issue -sentry issue events FRONT-ABC - -# Filter events by search query -sentry issue events FRONT-ABC --query "browser:Chrome" - -# Show full event details -sentry issue events FRONT-ABC --full - -# Limit results and filter by time period -sentry issue events FRONT-ABC --limit 50 --period 24h - -# Paginate through results -sentry issue events FRONT-ABC -c next -``` - -### View an issue - -```bash -sentry issue view FRONT-ABC - -# Multiple issues in one invocation (space-separated, not commas) -sentry issue view FRONT-ABC BACK-2 -``` +## Short IDs and organizations Full short IDs such as `FRONT-ABC` use your configured organization: `SENTRY_ORG`, then `.sentryclirc`, then the default set with `sentry cli defaults org`. The lookup -stays within that organization. To select another organization, include it explicitly: - -```bash -sentry issue view my-org/FRONT-ABC -``` +stays within that organization. To select another organization, include it +explicitly, as in `sentry issue view my-org/FRONT-ABC`. Project aliases such as `f-abc` keep the organization associated with the alias. Without a configured organization, the CLI uses a matching detected project or searches your accessible organizations. If the short ID matches in multiple organizations, specify the organization explicitly. -``` -Issue: TypeError: Cannot read property 'foo' of undefined -Short ID: FRONT-ABC -Status: unresolved -First seen: 2024-01-15 10:30:00 -Last seen: 2024-01-20 14:22:00 -Events: 1,234 -Users affected: 234 - -Latest event: - Browser: Chrome 120 - OS: Windows 10 - URL: https://example.com/app -``` - -```bash -# Open one or more issues in the browser (up to 5 tabs by default) -sentry issue view FRONT-ABC BACK-2 -w - -# Explicitly allow more than 5 tabs -sentry issue view FRONT-ABC BACK-2 API-3 WEB-4 IOS-5 OPS-6 -w --force -``` - -```bash -# GitHub-style identifiers work too (the "#" replaces the final slash) -sentry issue view my-org/my-project#FRONT-ABC -sentry issue view my-project#FRONT-ABC -``` - -**JSON output for agents and scripting:** +## JSON output `--json` returns the issue fields at the top level plus the latest event under `event`, the resolved `org` slug, related `replayIds`, and `trace` context. Prefer this over the human output when parsing programmatically. One issue ID still returns a single object; multiple IDs return an array of those objects. -```bash -# Full JSON (issue fields + latest event + trace/replay context) -sentry issue view FRONT-ABC --json - -# Multiple issues: JSON is an array of the same objects -sentry issue view FRONT-ABC BACK-2 --json - -# Select specific top-level fields to keep output small -sentry issue view FRONT-ABC --json --fields shortId,title,culprit,count,userCount,permalink - -# Pull named fields off the latest event instead of the whole `event` object — -# the event's `request` entry can include live session data (cookies, headers, -# body), so extract only what you need -sentry issue view FRONT-ABC --json --fields event.id,event.title,event.dateCreated -``` - -Common `jq` shapes for the `--json` output. The latest event's data lives under +In the `--json` output, the latest event's data lives under `event.entries[]`, each tagged with a `type` (`"exception"`, `"request"`, `"breadcrumbs"`, …) and a `data` payload — not as top-level `event.request` / -`event.exception` keys: - -```bash -# Issue summary -sentry issue view FRONT-ABC --json | jq '{shortId, title, count, userCount, permalink}' - -# Latest event id + culprit -sentry issue view FRONT-ABC --json | jq '{event: .event.id, culprit}' - -# Just the request URL and method (avoids the full request/session blob) -sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == "request") | .data | {url, method}' - -# Exception type and value from the latest event -sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == "exception") | .data.values[0] | {type, value}' -``` - -### Explain issues with Seer AI - -```bash -# Analyze root cause (may take a few minutes for new issues) -sentry issue explain 123456789 - -# By short ID with org prefix -sentry issue explain my-org/MYPROJECT-ABC - -# Analyze multiple issues in one invocation -sentry issue explain FRONT-ABC BACK-2 - -# Force a fresh analysis -sentry issue explain 123456789 --force -``` +`event.exception` keys. With `--json`, one explained issue preserves the existing array of root causes. Multiple issues return an array of labeled objects containing `issue`, `org`, `issueId`, and `rootCauses`. -### Generate a plan with Seer AI - -```bash -# Generate a fix plan (automatically runs explain if needed) -sentry issue plan 123456789 +## Seer AI plans -# Force a fresh plan even if one already exists -sentry issue plan 123456789 --force -``` +`sentry issue plan` generates a fix plan and runs root cause analysis first if +needed. **Requirements:** @@ -232,34 +63,7 @@ sentry issue plan 123456789 --force - Code mappings set up to link stack frames to source files - Root cause analysis is run automatically if needed (the `plan` command triggers `explain` first) -### Resolve and reopen issues - -```bash -# Resolve immediately (no regression tracking) -sentry issue resolve CLI-G5 - -# Resolve in a specific release — future events on newer releases are -# regression-flagged -sentry issue resolve CLI-G5 --in 0.26.1 - -# Monorepo-style releases work too (no special parsing) -sentry issue resolve CLI-G5 --in spotlight@1.2.3 - -# Resolve in the next release (tied to current HEAD) -sentry issue resolve CLI-G5 --in @next -sentry issue resolve CLI-G5 -i @next - -# Resolve in the current git HEAD — auto-detects the Sentry repo from -# your git origin remote (hard-errors if it can't) -sentry issue resolve CLI-G5 --in @commit - -# Explicit commit + repo (no git inspection; repo must be registered in Sentry) -sentry issue resolve CLI-G5 --in @commit:getsentry/cli@abc123def - -# Reopen a resolved issue -sentry issue unresolve CLI-G5 -sentry issue reopen CLI-G5 # alias -``` +## Resolving in a release :::note[How `@commit` auto-detects] `--in @commit` reads `HEAD` and the `origin` remote, parses the remote as @@ -269,58 +73,20 @@ error pointing you at `--in @commit:@` or `sentry repo list /` — no silent fallback to a different resolution mode. ::: -### Merge fragmented issues +## Merging issues Consolidate multiple issues (e.g. same logical error split by Sentry's -default stack-trace grouping) into a single canonical group: - -```bash -# Let Sentry auto-pick the parent (typically the largest by event count) -sentry issue merge CLI-K9 CLI-15H CLI-15N - -# Pin the canonical parent explicitly — accepts the same formats as -# positional args, including org-qualified and project-alias forms -sentry issue merge CLI-K9 CLI-15H CLI-15N --into CLI-K9 -sentry issue merge my-org/CLI-K9 my-org/CLI-15H --into my-org/CLI-K9 -sentry issue merge cli-k9 cli-15h --into cli-k9 # alias form +default stack-trace grouping) into a single canonical group with +`sentry issue merge`. Without `--into`, Sentry picks the parent (typically +the largest by event count). -# Cross-org merges are rejected — all issues must share an organization -# Non-error issue types (performance, info, etc.) cannot be merged -``` +All merged issues must share an organization; cross-org merges are rejected. +Non-error issue types (performance, info, etc.) cannot be merged. -### Archive and ignore issues +## Archiving issues Archive an issue to suppress alerts. Without `--until`, the issue is archived -forever. Use `--until` to set a condition for automatic unarchival: - -```bash -# Archive forever (fully silenced) -sentry issue archive CLI-G5 - -# Smart detection — unarchives when Sentry detects a spike in event frequency -sentry issue archive CLI-G5 --until auto - -# Duration-based -sentry issue archive CLI-G5 --until 1h # 1 hour -sentry issue archive CLI-G5 --until 7d # 7 days -sentry issue archive CLI-G5 --until 2026-12-31 # specific date - -# Count-based — unarchive after N more events -sentry issue archive CLI-G5 --until 100x - -# User-based — unarchive after N more users affected -sentry issue archive CLI-G5 --until 10u - -# Compound — count within a time window -sentry issue archive CLI-G5 --until 100x/1h # 100 events within 1 hour -sentry issue archive CLI-G5 --until 10u/1d # 10 users within 1 day - -# Verbose forms also work -sentry issue archive CLI-G5 --until 10events/2hours - -# 'ignore' is an alias for 'archive' -sentry issue ignore CLI-G5 --until auto -``` +forever. Use `--until` to set a condition for automatic unarchival. :::tip[`--until` syntax reference] | Format | Meaning | @@ -335,16 +101,10 @@ sentry issue ignore CLI-G5 --until auto | *(omitted)* | Archive forever | ::: -### Link an external issue +## Linking external issues -Link an existing tracker issue or GitHub pull request to a Sentry issue: - -```bash -sentry issue link FRONT-123 https://github.com/example/app/issues/42 -sentry issue link FRONT-123 https://github.com/example/app/pull/43 -sentry issue link FRONT-123 https://example.atlassian.net/browse/APP-42 -sentry issue link FRONT-123 https://linear.app/example/issue/APP-42/fix-error -``` +`sentry issue link` links an existing tracker issue or GitHub pull request to a +Sentry issue. The matching integration must already be installed in the Sentry organization. Linking requires a Sentry version with native issue URL resolution and guarded @@ -360,11 +120,6 @@ For other Apps, an issue select can be supplied by exact ID or label with `--field`, for example `--app custom --field task_id=123`. Sentry checks that the app's callback identifies the requested URL before saving the association. -```bash -sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --dry-run -sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --json -``` - `--dry-run` discovers the integration and prepares the link without submitting a write. The provider validates the remote issue when the link is submitted. An existing matching link succeeds with `changed: false`. A Sentry App that @@ -380,7 +135,7 @@ resolve the Sentry issue. This command does not create a tracker issue or link a commit. Existing integration status-sync settings continue to apply after linking. -#### Link permissions +### Link permissions Linking requires `event:write` and access to the Sentry project. Discovering Sentry Apps also requires `org:read`. Both scopes are included in the default @@ -389,16 +144,9 @@ requested scopes, the CLI offers reauthorization after a permission error. Use `sentry auth login` to request the current default scopes. Environment tokens must be updated separately. -### Unlink an external issue - -Remove an association without deleting either issue: +## Unlinking external issues -```bash -sentry issue unlink FRONT-123 https://github.com/example/app/issues/42 -sentry issue unlink FRONT-123 https://github.com/example/app/pull/43 --yes -sentry issue unlink my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 --yes -sentry issue unlink FRONT-123 https://linear.app/example/issue/APP-42/fix-error --dry-run -``` +`sentry issue unlink` removes an association without deleting either issue. Use `--yes` for non-interactive execution. `--dry-run` shows whether the link exists without removing it. If the association is already absent, the command @@ -411,7 +159,7 @@ For a custom Sentry App, select it with `--app `; unlink does not require the app to expose a link form. Use `--integration ` to disambiguate native integration links. -#### Unlink permissions +### Unlink permissions Unlink requires **`event:write` and access to the Sentry project**; `event:admin` is also accepted. The organization's “Let Members Delete Events” setting does diff --git a/apps/cli-docs/src/fragments/commands/local.md b/apps/cli-docs/src/fragments/commands/local.md index e1097e51f..18120282d 100644 --- a/apps/cli-docs/src/fragments/commands/local.md +++ b/apps/cli-docs/src/fragments/commands/local.md @@ -6,26 +6,6 @@ No DSN is required either. If your app has no DSN configured, events flow **only If a server is already running on the port, the command attaches as an SSE consumer instead of starting a duplicate. -## Examples - -```bash -# Start the server and tail events (default) -sentry local - -# Run your app with the local server auto-enabled -sentry local run -- npm run dev -sentry local run -- python manage.py runserver - -# Use a custom port -sentry local --port 9000 - -# Only show errors and logs (filter out transactions) -sentry local -f error -f log - -# Run quietly (suppress per-envelope tail output) -sentry local --quiet -``` - ## `sentry local run` Runs a command with `SENTRY_SPOTLIGHT` injected into the environment. The Sentry SDK automatically detects this variable and sends envelopes to the local server. No code changes needed. diff --git a/apps/cli-docs/src/fragments/commands/log.md b/apps/cli-docs/src/fragments/commands/log.md index 1390e2f83..977a8fffe 100644 --- a/apps/cli-docs/src/fragments/commands/log.md +++ b/apps/cli-docs/src/fragments/commands/log.md @@ -1,111 +1,22 @@ -## Examples -### List logs - -```bash -# List last 100 logs (default) -sentry log list -``` - -``` -TIMESTAMP LEVEL MESSAGE -2024-01-20 14:22:01 info User login successful -2024-01-20 14:22:03 debug Processing request for /api/users -2024-01-20 14:22:05 error Database connection timeout -2024-01-20 14:22:06 warn Retry attempt 1 of 3 - -Showing 4 logs. -``` - -**Filter logs:** - -```bash -# Show only error logs -sentry log list -q 'severity:error' - -# Filter by message content -sentry log list -q 'database' - -# Match a regular expression (key://pattern//) -sentry log list -q 'message://^Timeout after \d+ms//' - -# Limit results -sentry log list --limit 50 -``` - -### Stream logs in real-time - -```bash -# Stream with default 2-second poll interval -sentry log list -f - -# Stream with custom 5-second poll interval -sentry log list -f 5 - -# Stream error logs from a specific project -sentry log list my-org/backend -f -q 'severity:error' -``` - -### View a log entry +## Log IDs Copy the full ID from the `ID` column in `sentry log list` or `sentry trace logs` into `sentry log view`. An abbreviated prefix can match multiple logs and cannot be expanded into a unique full ID by itself. -Log ID lookups automatically narrow the search when a usable timestamp can be -determined from each ID. Otherwise, they use a 90-day lookup window. If a partial -scan leaves IDs missing, the CLI retries those IDs once with the highest -available scan accuracy. - -```bash -sentry log view 968c763c740cfda8b6728f27fb9e9b01 -``` - -``` -Log 968c763c740c... -════════════════════ - -ID: 968c763c740cfda8b6728f27fb9e9b01 -Timestamp: 2024-01-20 14:22:05 -Severity: ERROR - -Message: - Database connection timeout after 30s - -─── Context ─── - -Project: backend -Environment: production -Release: 1.2.3 - -─── Trace ─── - -Trace ID: abc123def456abc123def456abc12345 -Span ID: 1234567890abcdef - -─── Source Location ─── - -Function: connect_to_database -File: src/db/connection.py:142 -``` - -```bash -# With explicit project -sentry log view my-org/backend 968c763c740cfda8b6728f27fb9e9b01 - -# Open in browser -sentry log view 968c763c740cfda8b6728f27fb9e9b01 -w -``` - -## Finding Log IDs - Log IDs can be found: 1. In the output of `sentry log list` (the ID column) 2. In the Sentry UI when viewing log entries 3. In the `sentry.item_id` field of JSON output +Log ID lookups automatically narrow the search when a usable timestamp can be +determined from each ID. Otherwise, they use a 90-day lookup window. If a partial +scan leaves IDs missing, the CLI retries those IDs once with the highest +available scan accuracy. + ## JSON Output Use `--json` for machine-readable output: diff --git a/apps/cli-docs/src/fragments/commands/monitor.md b/apps/cli-docs/src/fragments/commands/monitor.md index fd2f16782..63e423387 100644 --- a/apps/cli-docs/src/fragments/commands/monitor.md +++ b/apps/cli-docs/src/fragments/commands/monitor.md @@ -1,28 +1,5 @@ -## Examples - -```bash -# Wrap a command with cron monitor check-ins (DSN-based) -SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 \ - sentry monitor run nightly-job -- python manage.py cron - -# The -- separator is optional when the command has no flags -sentry monitor run nightly-job npm run task - -# Create/update the monitor on the first check-in via --schedule (crontab) -sentry monitor run nightly-job -s "0 0 * * *" --max-runtime 30 --timezone UTC -- ./backup.sh - -# List cron monitors in an org -sentry monitor list my-org/ - -# Paginate through monitors -sentry monitor list my-org/ -c next - -# Output as JSON -sentry monitor list --json -``` - ## Check-in lifecycle `monitor run` sends an `in_progress` check-in when the wrapped command starts, diff --git a/apps/cli-docs/src/fragments/commands/org.md b/apps/cli-docs/src/fragments/commands/org.md index 8e7de48c5..006803d1e 100644 --- a/apps/cli-docs/src/fragments/commands/org.md +++ b/apps/cli-docs/src/fragments/commands/org.md @@ -1,17 +1,12 @@ -## Examples +## Filtering organizations -```bash -# List organizations -sentry org list -``` +Pass a filter to `sentry org list` to only list organizations whose slug or +name matches it, best matches first. Matching ignores case and accepts exact +matches, prefixes, substrings, small typos, or a glob such as `'acme-*'`. -``` -SLUG NAME ROLE -my-org My Organization owner -another-org Another Org member -``` +## Multiple accounts With several stored accounts (see `sentry auth list`), `sentry org list` lists the organizations of every logged-in account together, each fetched with that @@ -31,40 +26,3 @@ SLUG NAME ACCOUNT my-org My Organization jane@example.com:sentry.io acme-internal Acme Internal jane@acme.com:sentry.acme.com ``` - -```bash -# Only one account's organizations -sentry org list --account jane@acme.com -# The same email on several servers: add the server -sentry org list -a jane@example.com:sentry.io -``` - -```bash -# Only organizations whose slug or name matches "acme", best matches first -# (case-insensitive; prefix, substring, and small typos match too) -sentry org list acme -# ...or matches a glob -sentry org list 'acme-*' -``` - -```bash -# View organization details -sentry org view my-org -``` - -``` -Organization: My Organization -Slug: my-org -Role: owner -Projects: 5 -Teams: 3 -Members: 12 -``` - -```bash -# Open in browser -sentry org view my-org -w - -# JSON output -sentry org list --json -``` diff --git a/apps/cli-docs/src/fragments/commands/platform.md b/apps/cli-docs/src/fragments/commands/platform.md index f08f8543c..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/platform.md +++ b/apps/cli-docs/src/fragments/commands/platform.md @@ -1,17 +0,0 @@ - - -## Examples - -```bash -# List all valid Sentry platform identifiers -sentry platform list - -# Filter by substring -sentry platform list --search python - -# Shortcut for `sentry platform list` -sentry platforms - -# Output as JSON -sentry platform list --json -``` diff --git a/apps/cli-docs/src/fragments/commands/proguard.md b/apps/cli-docs/src/fragments/commands/proguard.md index 5f0bf843c..77c9b5e00 100644 --- a/apps/cli-docs/src/fragments/commands/proguard.md +++ b/apps/cli-docs/src/fragments/commands/proguard.md @@ -1,33 +1,5 @@ -## Examples - -### Upload mapping files - -```bash -# Upload a ProGuard/R8 mapping file -sentry proguard upload ./app/build/outputs/mapping/release/mapping.txt - -# Upload multiple mapping files -sentry proguard upload mapping-release.txt mapping-debug.txt - -# Validate without uploading (dry-run) -sentry proguard upload mapping.txt --no-upload - -# Fail if no mapping files are provided (useful in CI) -sentry proguard upload ./mapping/ --require-one -``` - -### Compute UUID - -```bash -# Compute the UUID for a ProGuard/R8 mapping file -sentry proguard uuid ./app/build/outputs/mapping/release/mapping.txt - -# Output as JSON (includes the file path) -sentry proguard uuid mapping.txt --json -``` - ## Important Notes - The UUID is **deterministically derived from the mapping file contents** — diff --git a/apps/cli-docs/src/fragments/commands/project.md b/apps/cli-docs/src/fragments/commands/project.md index 69e644e59..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/project.md +++ b/apps/cli-docs/src/fragments/commands/project.md @@ -1,66 +0,0 @@ - - -## Examples - -```bash -# List all projects in an org -sentry project list my-org/ -``` - -``` -ORG SLUG PLATFORM TEAM -my-org frontend javascript web-team -my-org backend python api-team -my-org mobile-ios cocoa mobile-team -``` - -```bash -# Several projects in the same org -sentry project list my-org/frontend,backend - -# Filter by platform -sentry project list my-org/ --platform javascript - -# View project details -sentry project view my-org/frontend -``` - -``` -Project: frontend -Organization: my-org -Platform: javascript -Team: web-team -DSN: https://abc123@sentry.io/123456 -``` - -```bash -# Open project in browser -sentry project view my-org/frontend -w -``` - -### Create a project - -```bash -# Every project is a name:platform pair; project names cannot contain whitespace -# Create a new project -sentry project create my-new-app:javascript-nextjs - -# Create several projects with their own platforms -sentry project create web:javascript api:python-django worker:node - -# Create under a specific org and team -sentry project create my-org/my-new-app:python --team backend-team - -# Preview without creating -sentry project create my-new-app:node --dry-run -``` - -### Delete a project - -```bash -# Delete a project (will prompt for confirmation) -sentry project delete my-org/old-project - -# Delete without confirmation -sentry project delete my-org/old-project --yes -``` diff --git a/apps/cli-docs/src/fragments/commands/react-native.md b/apps/cli-docs/src/fragments/commands/react-native.md index 2d8e5d035..98409e9f7 100644 --- a/apps/cli-docs/src/fragments/commands/react-native.md +++ b/apps/cli-docs/src/fragments/commands/react-native.md @@ -1,21 +1,4 @@ -## Examples -```bash -# Upload a bundle + sourcemap by debug ID (called by the Gradle plugin) -sentry react-native gradle \ - --bundle index.android.bundle \ - --sourcemap index.android.bundle.map - -# Also associate with a release and distribution(s) -sentry react-native gradle \ - --bundle index.android.bundle \ - --sourcemap index.android.bundle.map \ - --release com.example.app@1.0.0 \ - --dist 1000 - -# Xcode build phase (usually added automatically to your build script) -sentry react-native xcode -``` ## Xcode build step (`react-native xcode`) diff --git a/apps/cli-docs/src/fragments/commands/release.md b/apps/cli-docs/src/fragments/commands/release.md index a09cfe71e..a310ac31a 100644 --- a/apps/cli-docs/src/fragments/commands/release.md +++ b/apps/cli-docs/src/fragments/commands/release.md @@ -1,58 +1,11 @@ -## Examples +## Release workflow -```bash -# List releases (auto-detect org) -sentry release list - -# List releases in a specific org -sentry release list my-org/ - -# View release details -sentry release view 1.0.0 -sentry release view my-org/1.0.0 - -# Create and finalize a release -sentry release create 1.0.0 --finalize - -# Create a release, then finalize separately -sentry release create 1.0.0 -sentry release set-commits 1.0.0 --auto -sentry release finalize 1.0.0 - -# Set commits from local git history -sentry release set-commits 1.0.0 --local - -# Create a deploy -sentry release deploy 1.0.0 production -sentry release deploy 1.0.0 staging "Deploy #42" +A typical CI release creates the release, associates commits, finalizes it, and +records a deploy: -# Propose a version from git HEAD -sentry release create $(sentry release propose-version) - -# List deploys for a release -sentry release deploys 1.0.0 -sentry release deploys my-org/1.0.0 - -# Archive a release (hide it from the default list, but keep it) -sentry release archive 1.0.0 -sentry release archive my-org/1.0.0 --dry-run # Preview without archiving - -# Restore a previously archived release -sentry release restore 1.0.0 -sentry release restore my-org/1.0.0 - -# Delete a release -sentry release delete my-org/1.0.0 -sentry release delete my-org/1.0.0 --yes # Skip confirmation -sentry release delete my-org/1.0.0 --dry-run # Preview without deleting - -# Output as JSON -sentry release list --json -sentry release view 1.0.0 --json - -# Full release workflow with explicit org +```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 diff --git a/apps/cli-docs/src/fragments/commands/replay.md b/apps/cli-docs/src/fragments/commands/replay.md index 5351b0cd0..5f9bfc83b 100644 --- a/apps/cli-docs/src/fragments/commands/replay.md +++ b/apps/cli-docs/src/fragments/commands/replay.md @@ -1,59 +1,8 @@ -## Examples -### List replays +## Replay file format -```bash -# List recent replays for a project -sentry replay list my-org/frontend - -# Search across all projects in an org -sentry replay list my-org/ --query "environment:production" - -# Change the time window and sort -sentry replay list my-org/frontend --period 24h --sort errors - -# Paginate through results -sentry replay list my-org/frontend -c next -sentry replay list my-org/frontend -c prev - -# Output machine-readable data -sentry replay list my-org/frontend --json -``` - -### View a replay - -```bash -# View a replay by ID using auto-detected org/project context -sentry replay view 346789a703f6454384f1de473b8b9fcc - -# View a replay with an explicit org -sentry replay view my-org/346789a703f6454384f1de473b8b9fcc - -# View a replay with explicit org/project context -sentry replay view my-org/frontend/346789a703f6454384f1de473b8b9fcc - -# Open a replay in the browser -sentry replay view my-org/346789a703f6454384f1de473b8b9fcc --web - -# View the replay linked to a trace -sentry replay view my-org/frontend/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -``` - -### Download a replay - -```bash -# Download a replay as rrweb JSON to ./.rrweb.json -sentry replay download my-org/346789a703f6454384f1de473b8b9fcc - -# Choose where the file goes -sentry replay download my-org/346789a703f6454384f1de473b8b9fcc --output ./replay.json - -# Download from a replay URL -sentry replay download https://sentry.io/organizations/my-org/explore/replays/346789a703f6454384f1de473b8b9fcc/ -``` - -The file is a flat, time-ordered array of rrweb events, ready for +`sentry replay download` writes a flat, time-ordered array of rrweb events, ready for [rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player) or [rrvideo](https://github.com/rrweb-io/rrweb/tree/master/packages/rrvideo). Sentry's custom events (breadcrumbs, performance spans) are kept. diff --git a/apps/cli-docs/src/fragments/commands/repo.md b/apps/cli-docs/src/fragments/commands/repo.md index e62b2a747..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/repo.md +++ b/apps/cli-docs/src/fragments/commands/repo.md @@ -1,14 +0,0 @@ - - -## Examples - -```bash -# List repositories (auto-detect org) -sentry repo list - -# List repos in a specific org with pagination -sentry repo list my-org/ -c next - -# Output as JSON -sentry repo list --json -``` diff --git a/apps/cli-docs/src/fragments/commands/schema.md b/apps/cli-docs/src/fragments/commands/schema.md index 79ae96ee9..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/schema.md +++ b/apps/cli-docs/src/fragments/commands/schema.md @@ -1,26 +0,0 @@ - - -## Examples - -```bash -# List all API resources -sentry schema - -# Browse issue endpoints -sentry schema issues - -# View details for a specific operation -sentry schema issues list - -# Look up an endpoint by its exact operation ID -sentry schema listOrganizationEvents - -# Look up an endpoint by HTTP method and path -sentry schema "GET /api/0/organizations/{organization_id_or_slug}/issues/" - -# Search for monitoring-related endpoints -sentry schema --search monitor - -# Flat list of every endpoint -sentry schema --all -``` diff --git a/apps/cli-docs/src/fragments/commands/snapshots.md b/apps/cli-docs/src/fragments/commands/snapshots.md index ee58e6f1f..b471ce140 100644 --- a/apps/cli-docs/src/fragments/commands/snapshots.md +++ b/apps/cli-docs/src/fragments/commands/snapshots.md @@ -1,33 +1,5 @@ -## Examples - -```bash -# Upload a folder of screenshots as a snapshot for an app -sentry snapshots upload ./screenshots --app-id com.example.app - -# Upload only a subset of images (removals/renames not inferred on PRs) -sentry snapshots upload ./screenshots --app-id my-app --selective - -# Only flag images that differ by more than 1% -sentry snapshots upload ./screenshots --app-id my-app --diff-threshold 0.01 - -# Compare two directories of snapshot images locally -sentry snapshots diff ./baseline ./head - -# Fail (non-zero exit) if any images changed, with a custom threshold -sentry snapshots diff ./baseline ./head --fail-on-diff --threshold 0.02 - -# Download a specific baseline snapshot by ID -sentry snapshots download --snapshot-id 1234567890 - -# Download the latest baseline for an app, filtered by branch -sentry snapshots download --app-id my-app --branch main - -# Extract images to a specific directory -sentry snapshots download --app-id my-app --output ./baseline/ -``` - ## Important Notes - `snapshots upload` scans a folder for PNG/JPEG images (skipping hidden files), diff --git a/apps/cli-docs/src/fragments/commands/sourcemap.md b/apps/cli-docs/src/fragments/commands/sourcemap.md index 77c8aa307..eb8a884c5 100644 --- a/apps/cli-docs/src/fragments/commands/sourcemap.md +++ b/apps/cli-docs/src/fragments/commands/sourcemap.md @@ -1,8 +1,6 @@ -## Examples - -### Inject debug IDs +## Debug ID injection `sentry sourcemap inject` is a purely local file operation — it does not make any API calls and does not require authentication. You can run it in CI before authenticating. @@ -13,46 +11,13 @@ register their ID are left unchanged. `sourcemap upload` applies the same injection by default, unless `--no-rewrite` is passed. Binary bundles with an existing debug ID in their sourcemap are left unchanged. -```bash -# Inject debug IDs into all JS files in dist/ -sentry sourcemap inject ./dist - -# Preview changes without writing -sentry sourcemap inject ./dist --dry-run - -# Only process specific extensions -sentry sourcemap inject ./build --ext .js,.mjs -``` - -### Upload sourcemaps - -```bash -# Upload sourcemaps from dist/ -sentry sourcemap upload ./dist - -# Associate with a release -sentry sourcemap upload ./dist --release 1.0.0 - -# Set a custom URL prefix -sentry sourcemap upload ./dist --url-prefix '~/static/js/' -``` - -### Resolve sourcemap linkage - -```bash -# Report how each JS file's sourcemap resolves and whether a debug ID -# has been injected (read-only — never modifies files) -sentry sourcemap resolve ./dist - -# Machine-readable output -sentry sourcemap resolve ./dist --json -``` +## Resolving sourcemap linkage Use `sentry sourcemap resolve` to debug why `sentry sourcemap upload` may -not find the expected sourcemaps. It reports, for each JavaScript file, -whether the companion `.map` was located (by convention or via a -`sourceMappingURL` directive), whether the map is inline (`data:` URL) or -remote, and whether a Sentry debug ID is present. +not find the expected sourcemaps. It is read-only and never modifies files. +For each JavaScript file, it reports whether the companion `.map` was located +(by convention or via a `sourceMappingURL` directive), whether the map is inline +(`data:` URL) or remote, and whether a Sentry debug ID is present. ## Error handling diff --git a/apps/cli-docs/src/fragments/commands/span.md b/apps/cli-docs/src/fragments/commands/span.md index 2cece9e9f..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/span.md +++ b/apps/cli-docs/src/fragments/commands/span.md @@ -1,48 +0,0 @@ - - -## Examples - -### List spans - -```bash -# List recent spans in the current project -sentry span list - -# Find all DB spans -sentry span list -q "op:db" - -# Slow spans in the last 24 hours -sentry span list -q "duration:>100ms" --period 24h - -# List spans within a specific trace -sentry span list abc123def456abc123def456abc12345 - -# Paginate through results -sentry span list -c next -``` - -### Filter by project in a trace - -```bash -# Show only spans from one project within a trace -sentry span list my-org/cli-server/abc123def456abc123def456abc12345 - -# Or use --query to filter by project -sentry span list abc123def456abc123def456abc12345 -q "project:cli-server" - -# Multiple projects at once -sentry span list abc123def456abc123def456abc12345 -q "project:[cli-server,api]" -``` - -### View spans - -```bash -# View a single span -sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890 - -# View multiple spans at once -sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890 b2c3d4e5f6789012 - -# With explicit org/project -sentry span view my-org/backend/abc123def456abc123def456abc12345 a1b2c3d4e5f67890 -``` diff --git a/apps/cli-docs/src/fragments/commands/status.md b/apps/cli-docs/src/fragments/commands/status.md index 40b5e6639..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/status.md +++ b/apps/cli-docs/src/fragments/commands/status.md @@ -1,29 +0,0 @@ - - -## Examples - -```bash -# Show the current status of Sentry's services -sentry status -``` - -``` -✓ All Systems Operational - -### Components - -● Dashboard — Operational -● US Error Ingestion — Operational - -See https://status.sentry.io for full details. -``` - -```bash -# Get machine-readable status (useful in scripts) -sentry status --json -``` - -```bash -# Check a self-hosted or regional status page (Statuspage CNAME) -sentry status --url https://status.acme.com -``` diff --git a/apps/cli-docs/src/fragments/commands/team.md b/apps/cli-docs/src/fragments/commands/team.md index 3606123f4..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/team.md +++ b/apps/cli-docs/src/fragments/commands/team.md @@ -1,14 +0,0 @@ - - -## Examples - -```bash -# List teams -sentry team list my-org/ - -# Paginate through teams -sentry team list my-org/ -c next - -# Output as JSON -sentry team list --json -``` diff --git a/apps/cli-docs/src/fragments/commands/trace.md b/apps/cli-docs/src/fragments/commands/trace.md index cd2924ea2..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/trace.md +++ b/apps/cli-docs/src/fragments/commands/trace.md @@ -1,61 +0,0 @@ - - -## Examples - -### List traces - -```bash -# List last 20 traces (default) -sentry trace list - -# Sort by slowest first -sentry trace list --sort duration - -# Filter by transaction name, last 24 hours -sentry trace list -q "transaction:GET /api/users" --period 24h - -# Paginate through results -sentry trace list my-org/backend -c next -``` - -### View a trace - -```bash -# View trace details with span tree -sentry trace view abc123def456abc123def456abc12345 - -# Open trace in browser -sentry trace view abc123def456abc123def456abc12345 -w - -# Auto-recover from an issue short ID -sentry trace view PROJ-123 -``` - -### Cross-project traces - -```bash -# Filter trace view to one project's spans -sentry trace view my-org/cli-server/abc123def456abc123def456abc12345 - -# Full trace across all projects (default) -sentry trace view my-org/abc123def456abc123def456abc12345 - -# Filter trace logs by project -sentry trace logs my-org/cli-server/abc123def456abc123def456abc12345 - -# Multiple projects via --query -sentry trace logs abc123def456abc123def456abc12345 -q "project:[cli-server,api]" -``` - -### View trace logs - -```bash -# View logs for a trace -sentry trace logs abc123def456abc123def456abc12345 - -# Search with a longer time window -sentry trace logs --period 30d abc123def456abc123def456abc12345 - -# Filter logs within a trace -sentry trace logs -q 'severity:error' abc123def456abc123def456abc12345 -``` diff --git a/apps/cli-docs/src/fragments/commands/trial.md b/apps/cli-docs/src/fragments/commands/trial.md index 0847a9be6..e69de29bb 100644 --- a/apps/cli-docs/src/fragments/commands/trial.md +++ b/apps/cli-docs/src/fragments/commands/trial.md @@ -1,20 +0,0 @@ - - -## Examples - -```bash -# List all trials for the current org -sentry trial list - -# List trials for a specific org -sentry trial list my-org - -# Start a Seer trial -sentry trial start seer - -# Start a trial for a specific org -sentry trial start replays my-org - -# Start a Business plan trial (opens browser) -sentry trial start plan -``` diff --git a/apps/cli-docs/src/fragments/commands/wasm-split.md b/apps/cli-docs/src/fragments/commands/wasm-split.md index 3b768a444..feb9c935f 100644 --- a/apps/cli-docs/src/fragments/commands/wasm-split.md +++ b/apps/cli-docs/src/fragments/commands/wasm-split.md @@ -1,23 +1,4 @@ -## Examples - -```bash -# Add a build id to a module, in place, and print it -sentry wasm-split app.wasm - -# Capture the build id for a later upload -BUILD_ID=$(sentry wasm-split app.wasm) - -# Split debug data into a companion and ship a stripped binary -sentry wasm-split app.wasm --debug-out app.debug.wasm --strip - -# Also drop function names from the shipped binary -sentry wasm-split app.wasm -d app.debug.wasm --strip --strip-names - -# Point browsers at a companion served from a CDN -sentry wasm-split app.wasm -o dist/app.wasm -d dist/app.debug.wasm --strip \ - --external-dwarf-url https://cdn.example.com/debug/app.debug.wasm -``` ## Important Notes diff --git a/packages/cli/AGENTS.md b/packages/cli/AGENTS.md index 2e8d0c163..f97fb6ba6 100644 --- a/packages/cli/AGENTS.md +++ b/packages/cli/AGENTS.md @@ -284,6 +284,16 @@ All non-trivial human output must use the markdown rendering pipeline: Reference: `formatters/trace.ts` (`formatAncestorChain`), `formatters/human.ts` (`plainSafeMuted`) +### Parsing Markdown + +Never parse markdown structure (headings, code fences, lists) with regexes. Use the `marked` lexer, which is already a dependency: + +- Scripts: use the helpers in `script/markdown.ts` (`markdownHeadings()`, `blankCodeBlocks()`), or `marked.lexer()` directly for other token types. +- Runtime code: follow `src/lib/formatters/markdown.ts` and `src/lib/release-notes.ts`. +- Regexes are fine on the plain text of a parsed token, such as matching heading text. + +The `sentry-cli/no-regex-markdown-parsing` lint rule flags regexes that match headings or code fences in `src/` and `script/`. + ### Create & Delete Command Standards Mutation (create/delete) commands use shared infrastructure from `src/lib/mutate-command.ts`, @@ -449,7 +459,7 @@ All command docs and skill files are generated via `pnpm run generate:docs` (whi - **Command docs** (`apps/cli-docs/src/content/docs/commands/*.md`) and the configuration page (`apps/cli-docs/src/content/docs/configuration.md`) are **gitignored** and generated from CLI metadata + hand-written fragments in `apps/cli-docs/src/fragments/` (paths live in `script/paths.ts`). - **Skill files** (`plugins/sentry-cli/skills/sentry-cli/`) are **committed** (consumed by external plugin systems) and auto-committed by CI when stale. -- **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 an `Examples:` block in `fullDescription` or a `## Examples` section in a fragment for new commands. +- **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 an `Examples:` block in `fullDescription` or an Examples heading in a fragment; the `sentry-cli/no-examples-in-full-description` lint rule and `pnpm run check:fragments` reject both. - 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` validates fragment ↔ route consistency. - Positional `placeholder` values must be descriptive: `"org/project/trace-id"` not `"args"`. diff --git a/packages/cli/lint-rules/cli-oxlint-plugin.js b/packages/cli/lint-rules/cli-oxlint-plugin.js index d1035dd58..cb305e28e 100644 --- a/packages/cli/lint-rules/cli-oxlint-plugin.js +++ b/packages/cli/lint-rules/cli-oxlint-plugin.js @@ -1,3 +1,5 @@ +import { marked } from "marked"; + const name = "sentry-cli"; function member(node, property) { @@ -51,6 +53,55 @@ function silentBody(block, parameter) { ); } +/** Static text of a string expression; dynamic parts become line breaks. */ +function staticText(node) { + if (node?.type === "Literal") { + return typeof node.value === "string" ? node.value : ""; + } + if (node?.type === "TemplateLiteral") { + return node.quasis.map((quasi) => quasi.value.cooked ?? "").join("\n"); + } + if (node?.type === "BinaryExpression" && node.operator === "+") { + return staticText(node.left) + staticText(node.right); + } + if (node?.type === "ConditionalExpression") { + return `${staticText(node.consequent)}\n${staticText(node.alternate)}`; + } + return ""; +} + +/** Matches a heading or label line that opens an Examples section. */ +const EXAMPLES_LABEL_RE = /^examples?:?$/i; + +/** Whether help text has an Examples heading or an `Examples:` label line. */ +function hasExamplesSection(text) { + return marked + .lexer(text) + .some((token) => + token.type === "heading" + ? EXAMPLES_LABEL_RE.test(token.text.trim()) + : token.type === "paragraph" && + token.text + .split("\n") + .some((line) => EXAMPLES_LABEL_RE.test(line.trim())), + ); +} + +/** Regex sources that match markdown headings or code fences. */ +const MARKDOWN_STRUCTURE_RE = /(?:(? + file.includes("/src/commands/") || file.endsWith("/src/app.ts") + ? { + Property(node) { + const key = node.key?.name ?? node.key?.value; + if ( + key === "fullDescription" && + hasExamplesSection(staticText(node.value)) + ) + report(node); + }, + } + : {}, + ), + "no-regex-markdown-parsing": rule( + "Parse markdown structure with marked instead of regexes.", + (_context, file, report) => + file.includes("/src/") || file.includes("/script/") + ? { + Literal(node) { + if (MARKDOWN_STRUCTURE_RE.test(regexSource(node))) report(node); + }, + NewExpression(node) { + if (MARKDOWN_STRUCTURE_RE.test(regexSource(node))) report(node); + }, + } + : {}, + ), "no-skipped-tests": rule( "Do not leave disabled tests in the suite.", (_context, file, report) => diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md index 933993124..478eb2d67 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md @@ -359,6 +359,21 @@ The CLI must be installed and authenticated before use. ```bash curl https://cli.sentry.dev/install -fsS | bash curl https://cli.sentry.dev/install -fsS | bash -s -- --version nightly +# Pin to a specific stable version +curl https://cli.sentry.dev/install -fsS | SENTRY_VERSION=0.42.2 bash + +# Pin to nightly +curl https://cli.sentry.dev/install -fsS | SENTRY_VERSION=nightly bash +# Skip shell config modifications (~/.zshrc, ~/.bashrc, etc.) +curl https://cli.sentry.dev/install -fsS | bash -s -- --no-modify-path + +# Skip shell completion installation +curl https://cli.sentry.dev/install -fsS | bash -s -- --no-completions + +# Skip AI agent skill installation +curl https://cli.sentry.dev/install -fsS | bash -s -- --no-agent-skills +curl https://cli.sentry.dev/install -fsS | SENTRY_INSTALL_DIR="$HOME/.local/bin" bash +curl https://cli.sentry.dev/install -fsS | SENTRY_INIT=1 bash # Or install via npm/pnpm/bun npm install -g sentry diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/alert.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/alert.md index b7b150e57..a73f20d1b 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/alert.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/alert.md @@ -42,11 +42,14 @@ View an issue alert rule **Examples:** ```bash -# View by ID +# View an issue alert rule by ID (organization and project auto-detected) +sentry alert issues view 12345 + +# View by ID in an explicit project 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 view my-org/my-project/'Error Spike' ``` ### `sentry alert issues create []` @@ -67,11 +70,11 @@ Create an issue alert rule **Examples:** ```bash -# Create an issue alert rule with inline JSON condition/action -sentry alert issues create my-org/my-project \ - --name "Error Spike" \ - --condition '{"type":"first_seen_event","comparison":true,"conditionResult":true}' \ - --action '{"type":"email","data":{},"config":{"targetType":"team","targetIdentifier":"1"}}' +# Alert on new issues and email a team +sentry alert issues create my-org/my-project --name 'New Issues' --condition '{"type":"first_seen_event","comparison":true,"conditionResult":true}' --action '{"type":"email","data":{},"config":{"targetType":"team","targetIdentifier":"1"}}' + +# Preview a high-priority alert that emails a user at most every 30 minutes +sentry alert issues create my-org/my-project --name 'High Priority' --condition '{"type":"new_high_priority_issue","comparison":true,"conditionResult":true}' --action '{"type":"email","data":{},"config":{"targetType":"user","targetIdentifier":"56789"}}' --frequency 30 --dry-run ``` ### `sentry alert issues delete ` @@ -86,7 +89,13 @@ Delete an issue alert rule **Examples:** ```bash -# Delete with preview +# Delete an issue alert rule (prompts for confirmation) +sentry alert issues delete my-org/my-project/12345 + +# Delete a rule selected by name without prompting +sentry alert issues delete my-org/my-project/'My Rule' --yes + +# Preview the deletion sentry alert issues delete my-org/my-project/12345 --dry-run ``` @@ -108,8 +117,17 @@ Edit an issue alert rule **Examples:** ```bash -# Edit issue alert name/status -sentry alert issues edit my-org/my-project/12345 --name "Prod Error Spike" --status disabled +# Rename an issue alert rule +sentry alert issues edit my-org/my-project/12345 --name 'Prod errors' + +# Disable a rule selected by name +sentry alert issues edit my-org/my-project/'Old name' --status disabled + +# Rename and enable a rule (organization and project auto-detected) +sentry alert issues edit 12345 --name 'Renamed' --status active + +# Replace the rule's conditions +sentry alert issues edit my-org/my-project/12345 --condition '{"type":"first_seen_event","comparison":true,"conditionResult":true}' ``` ### `sentry alert metrics list []` @@ -140,11 +158,14 @@ View a metric alert rule **Examples:** ```bash -# View by ID -sentry alert metrics view my-org/67890 +# View a metric alert rule by ID (organization auto-detected) +sentry alert metrics view 12345 + +# View by ID in an explicit organization +sentry alert metrics view my-org/12345 # View by name -sentry alert metrics view my-org/"P95 latency alert" +sentry alert metrics view my-org/'P95 latency alert' ``` ### `sentry alert metrics create ` @@ -168,25 +189,10 @@ Create a metric alert rule ```bash # Alert when P95 span duration goes above 500ms -sentry alert metrics create my-org \ - --name "P95 Latency" \ - --project my-app \ - --query "environment:prod" \ - --aggregate "p95(span.duration)" \ - --dataset spans \ - --time-window 5 \ - --trigger '{"alertThreshold":500}' - -# Alert on any matching log line and notify through an existing alert -sentry alert metrics create my-org \ - --name "AI chat failures" \ - --project my-app \ - --query "action:ai.chat result:error" \ - --aggregate "count()" \ - --dataset logs \ - --time-window 5 \ - --trigger '{"alertThreshold":0,"resolveThreshold":0}' \ - --workflow 12345 +sentry alert metrics create my-org/ --name 'P95 latency' --project my-project --query 'environment:prod' --aggregate 'p95(span.duration)' --dataset spans --time-window 5 --trigger '{"alertThreshold":500}' + +# Preview an alert on any matching log line that notifies through an existing alert +sentry alert metrics create my-org/ --name 'AI chat failures' --project my-project --query 'action:ai.chat result:error' --aggregate 'count()' --dataset logs --time-window 5 --trigger '{"alertThreshold":0,"resolveThreshold":0}' --workflow 12345 --dry-run ``` ### `sentry alert metrics delete ` @@ -201,8 +207,11 @@ Delete a metric alert rule **Examples:** ```bash -# Delete without prompt -sentry alert metrics delete my-org/67890 --yes +# Delete a metric alert rule (prompts for confirmation) +sentry alert metrics delete my-org/12345 + +# Delete a rule selected by name without prompting +sentry alert metrics delete my-org/'P95 alert' --yes ``` ### `sentry alert metrics edit ` @@ -225,8 +234,17 @@ Edit a metric alert rule **Examples:** ```bash -# Edit metric alert query/window -sentry alert metrics edit my-org/67890 --query "environment:prod event.type:error" --time-window 15 +# Rename a metric alert rule +sentry alert metrics edit my-org/12345 --name 'Error budget' + +# Disable a rule +sentry alert metrics edit my-org/12345 --status disabled + +# Change the query and time window +sentry alert metrics edit my-org/12345 --query "environment:prod event.type:error" --time-window 15 + +# Switch the dataset +sentry alert metrics edit my-org/12345 --time-window 15 --dataset spans ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/api.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/api.md index 6fe3ff6e3..a10382895 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/api.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/api.md @@ -36,35 +36,36 @@ sentry api organizations/ sentry api issues/123456789/ # Create a release -sentry api organizations/my-org/releases/ \ - -X POST -F version=1.0.0 - -# With inline JSON body -sentry api issues/123456789/ \ - -X POST -d '{"status": "resolved"}' +sentry api organizations/my-org/releases/ -X POST -F version=1.0.0 # Update an issue status -sentry api issues/123456789/ \ - -X PUT -F status=resolved +sentry api issues/123456789/ -X PUT -F status=resolved + +# Send an inline JSON body +sentry api issues/123456789/ -X PUT -d '{"status":"resolved"}' + +# Set a nested field +sentry api projects/my-org/my-project/ -X PUT -F options[sampleRate]=0.5 # Assign an issue -sentry api issues/123456789/ \ - -X PUT --field assignedTo="user@example.com" +sentry api issues/123456789/ -X PUT --field assignedTo="user@example.com" +# Delete a project sentry api projects/my-org/my-project/ -X DELETE # Add custom headers sentry api organizations/ -H "X-Custom: value" -# Read body from a file +# Read the request body from a file sentry api projects/my-org/my-project/releases/ -X POST --input release.json -# Verbose mode (shows full HTTP request/response) +# Show the full HTTP request and response sentry api organizations/ --verbose -# Preview the request without sending +# Preview the request without sending it sentry api organizations/ --dry-run +# Save a binary response, such as an event attachment, to a file sentry api "https://sentry.io/api/0/projects/my-org/my-project/events/EVENT_ID/attachments/ATTACHMENT_ID/?download=1" > screenshot.png ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/auth.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/auth.md index b8c75eeae..374b97f1d 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/auth.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/auth.md @@ -15,6 +15,13 @@ Authenticate with Sentry List stored accounts +**Examples:** + +```bash +# Show stored accounts (* marks the active one) +sentry auth list +``` + ### `sentry auth login []` Authenticate with Sentry @@ -30,18 +37,32 @@ Authenticate with Sentry **Examples:** ```bash -sentry auth +# Log in with OAuth (device flow) +sentry auth login + +# Log in with an API token +sentry auth login --token YOUR_SENTRY_API_TOKEN -sentry auth --token YOUR_SENTRY_API_TOKEN +# Request only read-only scopes +sentry auth login --read-only -sentry auth --read-only +# Request specific scopes (repeatable or comma-separated) +sentry auth login --scope project:read --scope org:read -sentry auth --scope project:read --scope org:read -sentry auth --scope project:read,event:read +# Log in to a self-hosted instance +sentry auth login --url https://sentry.example.com -sentry auth --url https://sentry.example.com +# Log in to a self-hosted instance with a token +sentry auth login --token YOUR_TOKEN --url https://sentry.example.com -sentry auth --token YOUR_TOKEN --url https://sentry.example.com +# Add (or log in again to) a specific account without prompting +sentry auth login jane@example.com + +# Add an account on a specific server +sentry auth login jane@example.com --url https://sentry.example.com + +# Same as --url, using the account notation +sentry auth login jane@example.com:sentry.example.com ``` ### `sentry auth logout ` @@ -57,8 +78,10 @@ Log out of Sentry # Log out of the active account (the most recently used other account becomes active) sentry auth logout -# Log out of specific accounts (space- or comma-separated) +# Log out of a specific account sentry auth logout jane@example.com + +# Log out of several accounts (space- or comma-separated) sentry auth logout jane@example.com,jane@personal.dev # Pick the account on one server when the same email is stored twice @@ -80,13 +103,20 @@ Refresh your OAuth access token **Examples:** ```bash +# Refresh the OAuth access token when it is close to expiring sentry auth refresh -# Refresh with read-only scopes -sentry auth refresh --read-only +# Refresh even if the token is still valid +sentry auth refresh --force -# Refresh with specific scopes +# Re-authenticate with specific scopes sentry auth refresh --scope project:read --scope org:read + +# Re-authenticate with read-only scopes +sentry auth refresh --read-only + +# Output the refresh result as JSON +sentry auth refresh --json ``` ### `sentry auth status` @@ -100,13 +130,11 @@ View authentication status **Examples:** ```bash +# Check authentication status sentry auth status -# Show the raw token +# Include the raw token sentry auth status --show-token - -# View current user -sentry auth whoami ``` ### `sentry auth switch []` @@ -119,17 +147,14 @@ Switch the active account **Examples:** ```bash -# Add (or log in again to) a specific account without prompting -sentry auth login jane@example.com -sentry auth login jane@example.com --url https://sentry.example.com -sentry auth login jane@example.com:sentry.example.com # same as --url - -# Show stored accounts; * marks the active one -sentry auth list +# Pick the active account from a searchable list +sentry auth switch -# Switch the account commands use (pick from a searchable list without an argument) +# Switch to a specific account sentry auth switch jane@example.com -sentry auth switch + +# Pick the account on one server when the same email is stored twice +sentry auth switch jane@example.com --url https://sentry.example.com ``` ### `sentry auth token` @@ -139,6 +164,7 @@ Print the stored authentication token **Examples:** ```bash +# Print the stored auth token sentry auth token ``` @@ -149,4 +175,11 @@ Show the currently authenticated identity **Flags:** - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` +**Examples:** + +```bash +# Show the current user +sentry auth whoami +``` + All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/cli.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/cli.md index 15a3e3767..e2d4e6531 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/cli.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/cli.md @@ -21,9 +21,13 @@ Print the shell completion script # Print completions for your current shell (auto-detected from $SHELL) sentry cli completion -# Generate for a specific shell +# Install zsh completions sentry cli completion zsh > ~/.local/share/zsh/site-functions/_sentry + +# Load bash completions into the current shell eval "$(sentry cli completion bash)" + +# Install fish completions sentry cli completion fish > ~/.config/fish/completions/sentry.fish ``` @@ -42,13 +46,16 @@ View and manage default settings # Show all current defaults sentry cli defaults -# Set default organization +# Same as above (aliases: ls, show) +sentry cli defaults list + +# Set the default organization sentry cli defaults org my-org -# Set default project +# Set the default project sentry cli defaults project my-project -# Set default Sentry URL (self-hosted) +# Set the default Sentry URL (self-hosted) sentry cli defaults url https://sentry.example.com # Set custom HTTP headers (self-hosted, e.g. for IAP/proxies) @@ -60,14 +67,20 @@ sentry cli defaults ca-cert /path/to/ca.pem # Disable telemetry sentry cli defaults telemetry off +# Stop installing agent skills on upgrade +sentry cli defaults agent-skills off + +# Disable inline terminal images +sentry cli defaults graphics off + # Hide Tip: hints in command output sentry cli defaults tips off # Clear a single default sentry cli defaults org --clear -# Clear all defaults -sentry cli defaults --clear +# Clear all defaults without prompting +sentry cli defaults --clear --yes ``` ### `sentry cli feedback ` @@ -94,7 +107,14 @@ Diagnose and repair CLI database issues **Examples:** ```bash +# Fix database issues sentry cli fix + +# Fix root-owned files +sudo sentry cli fix + +# Show what would be fixed without making changes +sentry cli fix --dry-run ``` ### `sentry cli import` @@ -110,13 +130,13 @@ Import settings from legacy .sentryclirc files **Examples:** ```bash -# Auto-detect and import .sentryclirc +# Scan for .sentryclirc files and import interactively sentry cli import # Preview what would be imported sentry cli import --dry-run -# Skip confirmation prompt +# Skip the confirmation prompt (CI-safe) sentry cli import --yes # Explicitly trust a self-hosted URL @@ -145,11 +165,20 @@ Configure shell integration # Run full setup (PATH, completions, agent skills) sentry cli setup +# Record the install method +sentry cli setup --method curl + +# Place the binary and configure the shell +sentry cli setup --install + +# Skip PATH modification +sentry cli setup --no-modify-path + +# Skip shell completions +sentry cli setup --no-completions + # Skip agent skill installation sentry cli setup --no-agent-skills - -# Skip PATH and completion modifications -sentry cli setup --no-modify-path --no-completions ``` ### `sentry cli uninstall` @@ -165,10 +194,10 @@ Uninstall Sentry CLI **Examples:** ```bash -# Show what would be removed (dry run) +# Show what would be removed sentry cli uninstall --dry-run -# Uninstall, keeping config directory +# Uninstall, keeping the config directory sentry cli uninstall --yes --keep-config # Full uninstall with confirmation @@ -189,22 +218,32 @@ Update the Sentry CLI to the latest version **Examples:** ```bash +# Update to the latest version on the persisted channel +sentry cli upgrade + +# Check for updates without installing sentry cli upgrade --check -# Upgrade to latest stable -sentry cli upgrade +# Switch to the nightly channel and update +sentry cli upgrade nightly -# Upgrade to a specific version +# Switch back to the stable channel and update +sentry cli upgrade stable + +# Install a specific stable version sentry cli upgrade 0.5.0 -# Force re-download +# Force re-download even if up to date sentry cli upgrade --force -# Switch to nightly builds -sentry cli upgrade nightly +# Force using npm to upgrade +sentry cli upgrade --method npm -# Switch back to stable -sentry cli upgrade stable +# Upgrade from cached patches (no network) +sentry cli upgrade --offline + +# Skip reinstalling agent skills +sentry cli upgrade --no-agent-skills ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/code-mappings.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/code-mappings.md index dd8b92ed6..890f1a51e 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/code-mappings.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/code-mappings.md @@ -25,10 +25,10 @@ Upload code mappings for stack trace linking # Upload code mappings from a JSON file sentry code-mappings upload mappings.json -# Specify repository explicitly +# Specify the repository explicitly sentry code-mappings upload mappings.json --repo owner/repo -# Specify repository and default branch +# Specify the repository and default branch sentry code-mappings upload mappings.json --repo owner/repo --default-branch develop # Output as JSON diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dart-symbol-map.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dart-symbol-map.md index 5179747fa..0a5c91ae4 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dart-symbol-map.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dart-symbol-map.md @@ -22,7 +22,7 @@ Upload a Dart/Flutter symbol map to Sentry **Examples:** ```bash -# Upload a dart symbol map with a debug ID +# Upload a Dart symbol map with a debug ID sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json # Validate without uploading diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dashboard.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dashboard.md index 60ee3c5ae..4d05a546a 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dashboard.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dashboard.md @@ -24,13 +24,31 @@ List dashboards **Examples:** ```bash -# List all dashboards +# List dashboards (organization auto-detected) sentry dashboard list -# Filter by name pattern -sentry dashboard list "Backend*" +# List dashboards in an explicit organization +sentry dashboard list my-org/ -# Open dashboard list in browser +# Use the organization of an explicit project +sentry dashboard list my-org/my-project + +# Filter by title glob +sentry dashboard list 'Backend*' + +# Filter within an organization +sentry dashboard list my-org/ '*API*' + +# Fetch the next page +sentry dashboard list -c next + +# Fetch the previous page +sentry dashboard list -c prev + +# Output JSON with the pagination envelope +sentry dashboard list --json + +# Open the dashboard list in the browser sentry dashboard list -w ``` @@ -49,10 +67,10 @@ View a dashboard **Examples:** ```bash -# View by title +# View a dashboard by title sentry dashboard view 'Frontend Performance' -# View by ID +# View a dashboard by ID sentry dashboard view 12345 # View by ID in an explicit organization @@ -61,10 +79,22 @@ sentry dashboard view my-org/12345 # Include project context in the same argument sentry dashboard view my-org/my-project/12345 +# Pass the organization separately, e.g. for titles that contain a slash +sentry dashboard view my-org/ "incidents/2026" + +# Override the time period +sentry dashboard view 12345 --period 7d + +# Render charts with sixel graphics +sentry dashboard view 12345 --renderer sixel + # Auto-refresh every 30 seconds -sentry dashboard view "Backend Performance" --refresh 30 +sentry dashboard view 'Backend Performance' --refresh 30 -# Open in browser +# Output as JSON +sentry dashboard view 12345 --json + +# Open in the browser sentry dashboard view 12345 -w ``` @@ -75,7 +105,14 @@ Create a dashboard **Examples:** ```bash +# Create a dashboard (organization auto-detected) sentry dashboard create 'Frontend Performance' + +# Create a dashboard in an explicit organization +sentry dashboard create my-org/ 'My Dashboard' + +# Use the organization of an explicit project +sentry dashboard create my-org/my-project 'My Dashboard' ``` ### `sentry dashboard widget add ` @@ -99,30 +136,20 @@ Add a widget to a dashboard **Examples:** ```bash -# Simple counter widget -sentry dashboard widget add 'My Dashboard' "Error Count" \ - --display big_number --query count +# Add a counter widget +sentry dashboard widget add 'My Dashboard' "Error Count" --display big_number --query count -# Use an ID in an explicit organization -sentry dashboard widget add my-org/12345 "Error Count" \ - --display big_number --query count +# Use a dashboard ID in an explicit organization +sentry dashboard widget add my-org/12345 "Error Count" --display big_number --query count # Line chart with group-by -sentry dashboard widget add 'My Dashboard' "Errors by Browser" \ - --display line --query count --group-by browser.name +sentry dashboard widget add 'My Dashboard' "Errors by Browser" --display line --query count --group-by browser.name # Table with multiple aggregates, sorted descending -sentry dashboard widget add 'My Dashboard' "Top Endpoints" \ - --display table \ - --query count --query p95:span.duration \ - --group-by transaction \ - --sort -count --limit 10 - -# With search filter -sentry dashboard widget add 'My Dashboard' "Slow Requests" \ - --display bar --query p95:span.duration \ - --where "span.op:http.client" \ - --group-by span.description +sentry dashboard widget add 'My Dashboard' "Top Endpoints" --display table --query count --query p95:span.duration --group-by transaction --sort -count --limit 10 + +# Bar chart with a search filter +sentry dashboard widget add 'My Dashboard' "Slow Requests" --display bar --query p95:span.duration --where "span.op:http.client" --group-by span.description ``` ### `sentry dashboard widget edit ` @@ -148,14 +175,17 @@ Edit a widget in a dashboard **Examples:** ```bash -# Change display type -sentry dashboard widget edit 12345 --title 'Error Count' --display bar +# Change a widget's display type +sentry dashboard widget edit 12345 --title 'Error Rate' --display bar + +# Change the query of a widget selected by index +sentry dashboard widget edit 'My Dashboard' --index 0 --query p95:span.duration # Rename a widget -sentry dashboard widget edit 'My Dashboard' --index 0 --new-title 'Total Errors' +sentry dashboard widget edit 12345 --title 'Old Name' --new-title 'New Name' -# Change the query -sentry dashboard widget edit 12345 --title 'Error Rate' --query p95:span.duration +# Move and resize a widget +sentry dashboard widget edit 12345 --index 0 --col 0 --row 0 --width 6 --height 2 ``` ### `sentry dashboard widget delete ` @@ -172,11 +202,14 @@ Delete a widget from a dashboard **Examples:** ```bash -# Delete by title -sentry dashboard widget delete 'My Dashboard' --title 'Error Count' +# Delete a widget by title +sentry dashboard widget delete 'My Dashboard' --title 'Error Rate' -# Delete by index -sentry dashboard widget delete 12345 --index 2 +# Delete a widget by index +sentry dashboard widget delete 12345 --index 0 + +# Preview the deletion +sentry dashboard widget delete 12345 --index 0 --dry-run ``` ### `sentry dashboard revisions ` @@ -196,8 +229,14 @@ sentry dashboard revisions 'Frontend Performance' # List revisions by dashboard ID sentry dashboard revisions 12345 -# With explicit org +# Pass the organization explicitly sentry dashboard revisions my-org 12345 + +# Fetch the next page +sentry dashboard revisions my-org 12345 -c next + +# Output as JSON +sentry dashboard revisions my-org 12345 --json ``` ### `sentry dashboard restore ` @@ -214,10 +253,13 @@ Restore a dashboard revision sentry dashboard restore 'Frontend Performance' --revision 3 # Restore by dashboard ID -sentry dashboard restore 12345 --revision 1 +sentry dashboard restore 12345 --revision 42 + +# Pass the organization explicitly +sentry dashboard restore my-org 12345 --revision 42 -# With explicit org -sentry dashboard restore my-org 12345 --revision 1 +# Output the restored dashboard as JSON +sentry dashboard restore 12345 --revision 42 --json ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/debug-files.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/debug-files.md index 06ad6b1dd..dff599fa3 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/debug-files.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/debug-files.md @@ -15,6 +15,19 @@ Work with debug information files Inspect a debug information file +**Examples:** + +```bash +# Inspect a debug information file (auto-detects the format) +sentry debug-files check ./libexample.so + +# Inspect the DWARF file inside a dSYM +sentry debug-files check MyApp.dSYM/Contents/Resources/DWARF/MyApp + +# Output the report as JSON +sentry debug-files check ./app.pdb --json +``` + ### `sentry debug-files find ` Locate debug files for given debug identifiers @@ -25,6 +38,19 @@ Locate debug files for given debug identifiers - `--no-cwd - Do not look for debug files in the current directory` - `-p, --path ... - Add a directory to search recursively (repeatable)` +**Examples:** + +```bash +# Locate debug files for a debug identifier on disk +sentry debug-files find + +# Search only for dSYMs, including an extra directory +sentry debug-files find --type dsym --path ./build + +# Search only an explicit directory and output JSON +sentry debug-files find --no-cwd --no-well-known -p /symbols --json +``` + ### `sentry debug-files upload ` Upload debug information files to Sentry @@ -44,10 +70,51 @@ Upload debug information files to Sentry - `--wait - Wait for server-side processing and report any errors` - `--wait-for - Wait up to this many seconds for server-side processing` +**Examples:** + +```bash +# Upload debug information files (scans directories recursively) +sentry debug-files upload ./build + +# Attach a source bundle to each file +sentry debug-files upload ./libexample.so --include-sources + +# Scan a .zip archive in place +sentry debug-files upload ./symbols.zip + +# Skip .zip archives +sentry debug-files upload ./build --no-zips + +# Upload only dSYMs and wait for server-side processing +sentry debug-files upload ./dsyms --type dsym --wait + +# Fail unless the requested debug ID is found +sentry debug-files upload ./build --id --require-all + +# Unity: upload IL2CPP line mappings +sentry debug-files upload ./build --il2cpp-mapping + +# Unity: upload IL2CPP line mappings with referenced C# sources +sentry debug-files upload ./build --il2cpp-mapping --include-sources + +# Preview what would be uploaded (no credentials needed) +sentry debug-files upload ./build --no-upload +``` + ### `sentry debug-files print-sources ` List the source files a debug file references +**Examples:** + +```bash +# List the source files a debug file references (and whether they're available) +sentry debug-files print-sources ./libexample.so + +# Output the list as JSON +sentry debug-files print-sources ./app.pdb --json +``` + ### `sentry debug-files bundle-sources ` Bundle a debug file's source files for source context @@ -55,6 +122,16 @@ Bundle a debug file's source files for source context **Flags:** - `-o, --output - Output path for the source bundle ZIP (default: .src.zip)` +**Examples:** + +```bash +# Bundle a debug file's referenced source files (run on the build machine) +sentry debug-files bundle-sources ./libexample.so + +# Write the bundle to a specific path +sentry debug-files bundle-sources ./app.pdb --output ./app.src.zip +``` + ### `sentry debug-files bundle-jvm ` Create a JVM source bundle for source context @@ -67,24 +144,6 @@ Create a JVM source bundle for source context **Examples:** ```bash -# Inspect a debug information file (auto-detects the format) -sentry debug-files check ./libexample.so -sentry debug-files check MyApp.dSYM/Contents/Resources/DWARF/MyApp -sentry debug-files check ./app.pdb --json - -# List the source files a debug file references (and whether they're available) -sentry debug-files print-sources ./libexample.so -sentry debug-files print-sources ./app.pdb --json - -# Locate debug files for one or more debug identifiers on disk -sentry debug-files find -sentry debug-files find --type dsym --path ./build -sentry debug-files find --no-cwd --no-well-known -p /symbols --json - -# Bundle a debug file's referenced source files (run on the build machine) -sentry debug-files bundle-sources ./libexample.so -sentry debug-files bundle-sources ./app.pdb --output ./app.src.zip - # Bundle JVM sources with a debug ID sentry debug-files bundle-jvm --output ./out --debug-id ./src @@ -93,25 +152,6 @@ sentry debug-files bundle-jvm --output ./out --debug-id --exclude generat # Output as JSON sentry debug-files bundle-jvm --output ./out --debug-id --json ./src - -# Upload debug information files (scans directories recursively) -sentry debug-files upload ./build -sentry debug-files upload ./libexample.so --include-sources - -# .zip archives are scanned in place; use --no-zips to skip them -sentry debug-files upload ./symbols.zip -sentry debug-files upload ./build --no-zips - -# Restrict by type or debug id, and wait for server-side processing -sentry debug-files upload ./dsyms --type dsym --wait -sentry debug-files upload ./build --id --require-all - -# Unity: upload IL2CPP line mappings (optionally with referenced C# sources) -sentry debug-files upload ./build --il2cpp-mapping -sentry debug-files upload ./build --il2cpp-mapping --include-sources - -# Preview what would be uploaded without uploading (no credentials needed) -sentry debug-files upload ./build --no-upload ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/docs.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/docs.md index 0c523242d..32cbb70e0 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/docs.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/docs.md @@ -21,7 +21,14 @@ Find Sentry documentation pages by keyword **Examples:** ```bash +# Search the documentation index sentry docs list "source maps" + +# Limit the number of results +sentry docs list "session replay privacy" --limit 5 + +# Output as JSON +sentry docs list "source maps" --json ``` ### `sentry docs query ` @@ -31,7 +38,17 @@ Ask a cited question about Sentry documentation **Examples:** ```bash +# Ask a documentation question sentry docs "How do I configure tracing in Next.js?" + +# Use the explicit subcommand +sentry docs query "How do I upload source maps?" + +# Use the search alias +sentry docs search "How does session replay mask text?" + +# Output the answer as JSON +sentry docs "How do I configure tracing?" --json ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dsn.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dsn.md index cc9caabd1..5180797aa 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dsn.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/dsn.md @@ -32,8 +32,10 @@ sentry dsn list my-org/my-project # List DSNs across all accessible projects in an organization sentry dsn list my-org/ -# Navigate between pages +# Fetch the next page sentry dsn list my-org/ --limit 10 -c next + +# Fetch the previous page sentry dsn list my-org/ --limit 10 -c prev # Select public DSN fields as JSON diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/event.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/event.md index 0c5da357d..d28e1cfbf 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/event.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/event.md @@ -69,13 +69,11 @@ View details of one or more events **Examples:** ```bash +# View an event sentry event view abc123def456abc123def456abc12345 -# Open in browser +# Open in the browser sentry event view abc123def456abc123def456abc12345 -w - -# Download an attachment listed by `sentry event view --json` -sentry api "https://sentry.io/api/0/projects/my-org/my-project/events/EVENT_ID/attachments/ATTACHMENT_ID/?download=1" > screenshot.png ``` ### `sentry event list ` @@ -113,12 +111,15 @@ List events for an issue **Examples:** ```bash -# List events for an issue (using short ID) +# List events for an issue (short ID) sentry event list PROJ-ABC -# List events for an issue (using numeric ID) +# List events for an issue (numeric ID) sentry event list 123456789 +# List events for the most recent issue +sentry event list @latest --limit 50 + # Filter by search query sentry event list PROJ-ABC --query "browser:Chrome" @@ -128,8 +129,10 @@ sentry event list PROJ-ABC --full # Limit results and time range sentry event list PROJ-ABC --limit 50 --period 24h -# Paginate through results +# Fetch the next page sentry event list PROJ-ABC -c next + +# Fetch the previous page sentry event list PROJ-ABC -c prev # Output as JSON @@ -179,27 +182,20 @@ sentry event send -m "DB timeout" --fingerprint db-timeout --fingerprint {{ defa # Send a serialized Sentry Event object sentry event send ./crash.json -# Send without re-parsing (raw mode — also supports pre-built envelopes) +# Send without re-parsing (raw mode) sentry event send --raw ./crash.json + +# Send a pre-built envelope sentry event send --raw ./captured.envelope -# Explicit DSN +# Send with an explicit DSN sentry event send "https://key@o123.ingest.us.sentry.io/456" -m "Test" -# Via environment variable -export SENTRY_DSN="https://key@o123.ingest.us.sentry.io/456" -sentry event send -m "Test" - -# Project target (logged-in session; CLI fetches its sole active DSN) -sentry event send cli -m "Test" - -# Org/project target -sentry event send sentry/cli -m "Test" - -# Auto-detect from the current project -sentry event send -m "Test" +# Send to a project (logged-in session; the CLI fetches its sole active DSN) +sentry event send my-project -m "Test" -sentry send-event # same as: sentry event send +# Send to an org/project target +sentry event send my-org/my-project -m "Test" ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/explore.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/explore.md index 3b144b770..66adbc780 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/explore.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/explore.md @@ -34,62 +34,47 @@ Query aggregate event data (Explore) # Top errors in the last 24 hours, scoped to a project sentry explore my-org/cli -# All projects in an org +# All projects in an organization sentry explore my-org/ -# Bare project slug (searches across orgs) +# Bare project slug (searches across organizations) sentry explore cli -# Auto-detect from DSN/config +# Auto-detect the project from DSN/config sentry explore # Errors with user impact for a specific UTC window -sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" \ - --period "2024-01-15T00:00:00Z/2024-01-16T00:00:00Z" +sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" --period "2024-01-15T00:00:00Z..2024-01-16T00:00:00Z" -# Filter by specific error type (combines with auto-injected project filter) -sentry explore my-org/cli -F title -F "count()" \ - -q "error.type:TypeError" --period 1h +# Filter by error type (combined with the project filter) +sentry explore my-org/cli -F title -F "count()" -q "error.type:TypeError" --period 1h -# Span operation latency by route -sentry explore my-org/cli -F span.op -F "p50(span.duration)" \ - -F "p95(span.duration)" --dataset spans --period 1h +# Span operation latency +sentry explore my-org/cli -F span.op -F "p50(span.duration)" -F "p95(span.duration)" --dataset spans --period 1h # Top spans by count -sentry explore my-org/cli -F span.op -F "count()" \ - --dataset spans --sort "-count()" +sentry explore my-org/cli -F span.op -F "count()" --dataset spans --sort "-count()" -# Sum a custom metric (e.g., LLM token usage) across an org +# Sum a custom metric (e.g., LLM token usage) across an organization sentry explore my-org/ -m llm.token_usage --dataset metrics --period 7d -# Break down by a tag column (e.g., model name) -sentry explore my-org/seer -F gen_ai.request.model \ - -m llm.token_usage --dataset metrics --period 7d +# Break a metric down by a tag column +sentry explore my-org/seer -F gen_ai.request.model -m llm.token_usage --dataset metrics --period 7d -# Use a different aggregation (default is sum) +# Use a different metric aggregation (default is sum) sentry explore my-org/ -m cache.hit_rate --agg avg --dataset metrics -sentry explore my-org/ \ - -F "sum(value,llm.token_usage,distribution,none)" \ - --dataset metrics --period 7d - -# List recent replays -sentry explore my-org/cli --dataset replays --period 24h +# Use the raw tracemetrics format +sentry explore my-org/ -F "sum(value,llm.token_usage,distribution,none)" --dataset metrics --period 7d # Filter replays by activity level -sentry explore my-org/cli --dataset replays -F activity -F duration \ - -F "count_errors" --period 7d +sentry explore my-org/cli --dataset replays -F activity -F duration -F count_errors --period 7d # Log severity counts in the last hour -sentry explore my-org/cli -F severity -F "count()" \ - --dataset logs --period 1h +sentry explore my-org/cli -F severity -F "count()" --dataset logs --period 1h -# Pipe to jq for filtering +# Pipe JSON to jq sentry explore my-org/cli -F title -F "count()" --json | jq '.data[:5]' - -# Get raw data for analysis -sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" \ - --json --limit 100 ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/feedback.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/feedback.md index 7e3ba03aa..07bd9fe76 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/feedback.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/feedback.md @@ -54,7 +54,7 @@ List and search User Feedback **Examples:** ```bash -# Auto-detect the organization from the current project +# List Feedback (organization auto-detected) sentry feedback list # List Feedback for one project @@ -66,9 +66,16 @@ sentry feedback list my-org/ # Search for a project across accessible organizations sentry feedback list frontend +# Show resolved Feedback sentry feedback list my-org/frontend --status resolved + +# Show the spam mailbox sentry feedback list my-org/frontend --status spam + +# Show every status over the last 90 days sentry feedback list my-org/frontend --status all --period 90d + +# Search Feedback messages sentry feedback list my-org/frontend --query "message:*checkout*" ``` @@ -115,20 +122,23 @@ View a User Feedback item **Examples:** ```bash -# Most recent unresolved Feedback, with detected or explicit organization +# View the most recent unresolved Feedback sentry feedback view @latest + +# Most recent unresolved Feedback in an explicit organization sentry feedback view my-org/@latest -# Short ID or numeric ID +# View by short ID sentry feedback view FRONTEND-2SDJ + +# View by numeric ID sentry feedback view 5146636313 -# Explicit organization +# View in an explicit organization sentry feedback view my-org/FRONTEND-2SDJ -# `view` is the default command; `show` is an alias +# `view` is the default command sentry feedback my-org/FRONTEND-2SDJ -sentry feedback show my-org/FRONTEND-2SDJ # Open the Feedback item in Sentry sentry feedback view my-org/FRONTEND-2SDJ --web @@ -169,13 +179,16 @@ Mark User Feedback as resolved **Examples:** ```bash -# Resolve a Feedback item immediately +# Resolve a Feedback item (organization auto-detected) +sentry feedback resolve FRONTEND-2SDJ + +# Resolve a Feedback item in an explicit organization sentry feedback resolve my-org/FRONTEND-2SDJ # Resolve the most recently active unresolved Feedback sentry feedback resolve my-org/@latest -# Return the updated Feedback, or select specific fields +# Return selected fields from the updated Feedback sentry feedback resolve my-org/FRONTEND-2SDJ --json --fields id,shortId,status ``` @@ -214,25 +227,20 @@ Return User Feedback to the inbox **Examples:** ```bash -# Find resolved Feedback -sentry feedback list --status resolved - -# Reopen a Feedback item using its short ID or numeric ID +# Reopen a Feedback item, or return it from spam to the inbox sentry feedback unresolve FRONTEND-2SDJ + +# Reopen by numeric ID sentry feedback unresolve 5146636313 # `reopen` is an alias for `unresolve` sentry feedback reopen FRONTEND-2SDJ -# Specify an organization explicitly when needed +# Specify an organization explicitly sentry feedback unresolve my-org/FRONTEND-2SDJ # Return selected fields from the updated Feedback sentry feedback unresolve FRONTEND-2SDJ --json --fields id,shortId,status - -# Find spam and return a Feedback item to the unresolved inbox -sentry feedback list --status spam -sentry feedback unresolve FRONTEND-2SDJ ``` ### `sentry feedback spam ` @@ -272,9 +280,11 @@ Mark User Feedback as spam ```bash # Move a Feedback item to the spam mailbox sentry feedback spam FRONTEND-2SDJ + +# Mark as spam by numeric ID sentry feedback spam 5146636313 -# Specify an organization explicitly when needed +# Specify an organization explicitly sentry feedback spam my-org/FRONTEND-2SDJ # Return selected fields from the updated Feedback diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/init.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/init.md index d04ccc67c..f29278ccc 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/init.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/init.md @@ -38,12 +38,18 @@ sentry init --dry-run # Target a subdirectory sentry init ./my-app -# Use a specific org (auto-detect project) +# Use a specific organization (auto-detect project) sentry init acme/ -# Use a specific org and project +# Use a specific organization and project sentry init acme/my-app +# Search for a project across organizations +sentry init my-app + +# Use a specific project in a subdirectory +sentry init acme/my-app ./my-project + # Assign a team when creating a new project sentry init acme/ --team backend diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/issue.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/issue.md index 0403fd9b4..d2488db45 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/issue.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/issue.md @@ -54,10 +54,10 @@ List issues in a project # List issues in a specific project sentry issue list my-org/frontend -# Several projects in the same org +# Several projects in the same organization sentry issue list my-org/frontend,backend,worker -# All projects in an org +# All projects in an organization sentry issue list my-org/ # Search for a project across organizations @@ -66,24 +66,19 @@ sentry issue list frontend # Show only unresolved issues sentry issue list my-org/frontend --query "is:unresolved" -# Show resolved issues -sentry issue list my-org/frontend --query "is:resolved" - # Sort by frequency sentry issue list my-org/frontend --sort freq --limit 20 -# Sort by Sentry's "recommended" relevance ranking (the default on sentry.io; -# self-hosted instances default to "date" and require a recent Sentry version -# to accept --sort recommended) +# Sort by Sentry's recommended relevance ranking sentry issue list my-org/frontend --sort recommended -# Multiple filters (space-separated = implicit AND) +# Multiple filters (space-separated terms are combined with AND) sentry issue list --query "is:unresolved level:error assigned:me" # Negation and wildcards sentry issue list --query "!browser:Chrome message:*timeout*" -# Match multiple values for one key (in-list syntax) +# Match multiple values for one key sentry issue list --query "browser:[Chrome,Firefox]" ``` @@ -125,6 +120,9 @@ List events for a specific issue # List recent events for an issue sentry issue events FRONT-ABC +# List events for the most recent issue +sentry issue events @latest --limit 50 + # Filter events by search query sentry issue events FRONT-ABC --query "browser:Chrome" @@ -134,8 +132,11 @@ sentry issue events FRONT-ABC --full # Limit results and filter by time period sentry issue events FRONT-ABC --limit 50 --period 24h -# Paginate through results +# Fetch the next page sentry issue events FRONT-ABC -c next + +# Output as JSON +sentry issue events FRONT-ABC --json ``` ### `sentry issue explain ` @@ -149,19 +150,16 @@ Analyze one or more issues using Seer AI **Examples:** ```bash -# View the most recent issue -sentry issue view @latest +# Analyze the root cause of an issue (may take a few minutes for new issues) +sentry issue explain 123456789 + +# Explain the most recent issue +sentry issue explain @latest # Explain the most frequently occurring issue sentry issue explain @most_frequent -# Generate a fix plan for the latest issue -sentry issue plan @latest - -# Analyze root cause (may take a few minutes for new issues) -sentry issue explain 123456789 - -# By short ID with org prefix +# Use a short ID with an organization prefix sentry issue explain my-org/MYPROJECT-ABC # Analyze multiple issues in one invocation @@ -169,6 +167,9 @@ sentry issue explain FRONT-ABC BACK-2 # Force a fresh analysis sentry issue explain 123456789 --force + +# Output root causes as JSON +sentry issue explain 123456789 --json ``` ### `sentry issue plan ` @@ -182,9 +183,15 @@ Generate a solution plan using Seer AI **Examples:** ```bash -# Generate a fix plan (automatically runs explain if needed) +# Generate a fix plan (runs explain first if needed) sentry issue plan 123456789 +# Generate a fix plan for the most recent issue +sentry issue plan @latest + +# Use a short ID with an organization prefix +sentry issue plan my-org/MYPROJECT-ABC + # Force a fresh plan even if one already exists sentry issue plan 123456789 --force ``` @@ -230,47 +237,40 @@ View details of one or more issues **Examples:** ```bash +# View an issue sentry issue view FRONT-ABC -# Multiple issues in one invocation (space-separated, not commas) +# View the most recent issue +sentry issue view @latest + +# View several issues (space-separated, not commas) sentry issue view FRONT-ABC BACK-2 +# Select an organization explicitly sentry issue view my-org/FRONT-ABC -# Open one or more issues in the browser (up to 5 tabs by default) +# Use a GitHub-style identifier (the "#" replaces the final slash) +sentry issue view my-org/my-project#FRONT-ABC + +# Open issues in the browser (up to 5 tabs by default) sentry issue view FRONT-ABC BACK-2 -w -# Explicitly allow more than 5 tabs +# Allow more than 5 browser tabs sentry issue view FRONT-ABC BACK-2 API-3 WEB-4 IOS-5 OPS-6 -w --force -# GitHub-style identifiers work too (the "#" replaces the final slash) -sentry issue view my-org/my-project#FRONT-ABC -sentry issue view my-project#FRONT-ABC - # Full JSON (issue fields + latest event + trace/replay context) sentry issue view FRONT-ABC --json -# Multiple issues: JSON is an array of the same objects -sentry issue view FRONT-ABC BACK-2 --json - -# Select specific top-level fields to keep output small +# Select top-level fields to keep output small sentry issue view FRONT-ABC --json --fields shortId,title,culprit,count,userCount,permalink -# Pull named fields off the latest event instead of the whole `event` object — -# the event's `request` entry can include live session data (cookies, headers, -# body), so extract only what you need +# Select fields from the latest event instead of the whole event sentry issue view FRONT-ABC --json --fields event.id,event.title,event.dateCreated -# Issue summary -sentry issue view FRONT-ABC --json | jq '{shortId, title, count, userCount, permalink}' - -# Latest event id + culprit -sentry issue view FRONT-ABC --json | jq '{event: .event.id, culprit}' - -# Just the request URL and method (avoids the full request/session blob) +# Extract the request URL and method from the latest event sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == "request") | .data | {url, method}' -# Exception type and value from the latest event +# Extract the exception type and value from the latest event sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == "exception") | .data.values[0] | {type, value}' ``` @@ -281,37 +281,46 @@ Mark an issue as resolved **Flags:** - `-i, --in - Resolve in a release, next release, or commit ('' | '@next' | '@commit' | '@commit:@')` -### `sentry issue unresolve ` - -Reopen a resolved issue - **Examples:** ```bash # Resolve immediately (no regression tracking) sentry issue resolve CLI-G5 -# Resolve in a specific release — future events on newer releases are -# regression-flagged +# Resolve in a specific release (newer releases flag regressions) sentry issue resolve CLI-G5 --in 0.26.1 -# Monorepo-style releases work too (no special parsing) +# Monorepo-style release versions work too sentry issue resolve CLI-G5 --in spotlight@1.2.3 -# Resolve in the next release (tied to current HEAD) +# Resolve in the next release sentry issue resolve CLI-G5 --in @next -sentry issue resolve CLI-G5 -i @next -# Resolve in the current git HEAD — auto-detects the Sentry repo from -# your git origin remote (hard-errors if it can't) +# Resolve in the current git HEAD (auto-detects the Sentry repo from your origin remote) sentry issue resolve CLI-G5 --in @commit -# Explicit commit + repo (no git inspection; repo must be registered in Sentry) +# Resolve in an explicit commit and repo (no git inspection) sentry issue resolve CLI-G5 --in @commit:getsentry/cli@abc123def +# Resolve an issue in an explicit organization +sentry issue resolve my-org/CLI-G5 +``` + +### `sentry issue unresolve ` + +Reopen a resolved issue + +**Examples:** + +```bash # Reopen a resolved issue sentry issue unresolve CLI-G5 -sentry issue reopen CLI-G5 # alias + +# `reopen` is an alias for `unresolve` +sentry issue reopen CLI-G5 + +# Reopen an issue in an explicit organization +sentry issue unresolve my-org/CLI-G5 ``` ### `sentry issue archive ` @@ -327,28 +336,34 @@ Archive (ignore) an issue # Archive forever (fully silenced) sentry issue archive CLI-G5 -# Smart detection — unarchives when Sentry detects a spike in event frequency +# Unarchive when Sentry detects a spike in event frequency sentry issue archive CLI-G5 --until auto -# Duration-based -sentry issue archive CLI-G5 --until 1h # 1 hour -sentry issue archive CLI-G5 --until 7d # 7 days -sentry issue archive CLI-G5 --until 2026-12-31 # specific date +# Archive for 1 hour +sentry issue archive CLI-G5 --until 1h + +# Archive for 7 days +sentry issue archive CLI-G5 --until 7d + +# Archive until a specific date +sentry issue archive CLI-G5 --until 2026-12-31 -# Count-based — unarchive after N more events +# Unarchive after 100 more events sentry issue archive CLI-G5 --until 100x -# User-based — unarchive after N more users affected +# Unarchive after 10 more users are affected sentry issue archive CLI-G5 --until 10u -# Compound — count within a time window -sentry issue archive CLI-G5 --until 100x/1h # 100 events within 1 hour -sentry issue archive CLI-G5 --until 10u/1d # 10 users within 1 day +# Unarchive after 100 events within 1 hour +sentry issue archive CLI-G5 --until 100x/1h -# Verbose forms also work +# Unarchive after 10 users within 1 day +sentry issue archive CLI-G5 --until 10u/1d + +# Use the verbose condition form sentry issue archive CLI-G5 --until 10events/2hours -# 'ignore' is an alias for 'archive' +# `ignore` is an alias for `archive` sentry issue ignore CLI-G5 --until auto ``` @@ -362,17 +377,17 @@ Merge 2+ issues into a single canonical group **Examples:** ```bash -# Let Sentry auto-pick the parent (typically the largest by event count) +# Let Sentry pick the parent (typically the largest by event count) sentry issue merge CLI-K9 CLI-15H CLI-15N -# Pin the canonical parent explicitly — accepts the same formats as -# positional args, including org-qualified and project-alias forms +# Pin the canonical parent explicitly sentry issue merge CLI-K9 CLI-15H CLI-15N --into CLI-K9 + +# Use organization-qualified IDs sentry issue merge my-org/CLI-K9 my-org/CLI-15H --into my-org/CLI-K9 -sentry issue merge cli-k9 cli-15h --into cli-k9 # alias form -# Cross-org merges are rejected — all issues must share an organization -# Non-error issue types (performance, info, etc.) cannot be merged +# Use project-alias IDs +sentry issue merge cli-k9 cli-15h --into cli-k9 ``` ### `sentry issue link ` @@ -388,12 +403,22 @@ Link an existing external issue **Examples:** ```bash +# Link a GitHub issue sentry issue link FRONT-123 https://github.com/example/app/issues/42 + +# Link a GitHub pull request sentry issue link FRONT-123 https://github.com/example/app/pull/43 -sentry issue link FRONT-123 https://example.atlassian.net/browse/APP-42 + +# Link a Jira issue in an explicit organization +sentry issue link my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 + +# Link a Linear issue sentry issue link FRONT-123 https://linear.app/example/issue/APP-42/fix-error +# Prepare the link without submitting it sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --dry-run + +# Output the result as JSON sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --json ``` @@ -411,9 +436,16 @@ Unlink an external issue **Examples:** ```bash +# Unlink a GitHub issue (prompts for confirmation) sentry issue unlink FRONT-123 https://github.com/example/app/issues/42 + +# Unlink a GitHub pull request without prompting sentry issue unlink FRONT-123 https://github.com/example/app/pull/43 --yes + +# Unlink a Jira issue in an explicit organization sentry issue unlink my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 --yes + +# Check whether a link exists without removing it sentry issue unlink FRONT-123 https://linear.app/example/issue/APP-42/fix-error --dry-run ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/local.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/local.md index 83a431d62..3bed51cc3 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/local.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/local.md @@ -63,6 +63,22 @@ Start the local dev server and tail events - `--max-envelopes - Maximum envelopes retained by this receiver or session` - `--session - Create a daemon-owned telemetry session with this label` +**Examples:** + +```bash +# Start the server and tail events +sentry local + +# Use a custom port +sentry local --port 9000 + +# Only show errors and logs (filter out transactions) +sentry local -f error -f log + +# Suppress per-envelope tail output +sentry local --quiet +``` + ### `sentry local session create ` Create a Local telemetry session @@ -115,60 +131,11 @@ Run a command with the local dev server enabled **Examples:** ```bash -# Start the server and tail events (default) -sentry local - -# Run your app with the local server auto-enabled +# Run a Node.js dev server with the local server enabled sentry local run -- npm run dev -sentry local run -- python manage.py runserver -# Use a custom port -sentry local --port 9000 - -# Only show errors and logs (filter out transactions) -sentry local -f error -f log - -# Run quietly (suppress per-envelope tail output) -sentry local --quiet - -# Start the server and open the UI -sentry local --open - -# Run your app with the UI -sentry local run --open -- npm run dev - -sentry local -f error -f log # only errors and logs - -sentry local -f ai # only AI/agent spans -sentry local -f ai -f error # agent spans and errors - -sentry local --format json - -sentry local run --format json \ - --filter error --filter transaction --filter log --filter ai \ - -- npm run dev - -sentry local serve --format json --attributes - -SENTRY_SPOTLIGHT=http://localhost:8969/stream \ - pnpm --filter sentry exec tsx test/fixtures/local-agent-server.ts - -curl http://127.0.0.1:3030/api/users/42 -curl -X POST http://127.0.0.1:3030/api/agent/run \ - -H 'content-type: application/json' \ - -d '{"prompt":"Where is the rate limit configured?"}' -curl -i http://127.0.0.1:3030/api/broken - -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 --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 +# Run a Django dev server with the local server enabled +sentry local run -- python manage.py runserver ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/log.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/log.md index d7bd5f463..5493fde94 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/log.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/log.md @@ -37,7 +37,7 @@ List logs from a project **Examples:** ```bash -# List last 100 logs (default) +# List the last 100 logs sentry log list # Show only error logs @@ -49,18 +49,22 @@ sentry log list -q 'database' # Match a regular expression (key://pattern//) sentry log list -q 'message://^Timeout after \d+ms//' -# Limit results +# Show the last 50 logs sentry log list --limit 50 -# Stream with default 2-second poll interval +# List logs for a trace +sentry log list abc123def456abc123def456abc12345 + +# Stream logs (2-second poll interval) sentry log list -f -# Stream with custom 5-second poll interval +# Stream logs (5-second poll interval) sentry log list -f 5 # Stream error logs from a specific project sentry log list my-org/backend -f -q 'severity:error' +# Filter JSON output with jq sentry log list --json | jq '.data[] | select(.severity == "error")' ``` @@ -75,12 +79,13 @@ View details of one or more log entries **Examples:** ```bash +# View a log entry sentry log view 968c763c740cfda8b6728f27fb9e9b01 -# With explicit project +# Specify the project explicitly sentry log view my-org/backend 968c763c740cfda8b6728f27fb9e9b01 -# Open in browser +# Open in the browser sentry log view 968c763c740cfda8b6728f27fb9e9b01 -w ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/monitor.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/monitor.md index c7d4b573a..bd56732ae 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/monitor.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/monitor.md @@ -25,6 +25,19 @@ Wrap a command with cron monitor check-ins - `--failure-issue-threshold - Consecutive failures before an issue is created (requires --schedule)` - `--recovery-threshold - Consecutive successes before an issue is resolved (requires --schedule)` +**Examples:** + +```bash +# Wrap a command with cron monitor check-ins (DSN-based) +SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 sentry monitor run nightly-job -- python manage.py cron + +# The -- separator is optional when the command has no flags +sentry monitor run nightly-job npm run task + +# Create or update the monitor on the first check-in +sentry monitor run nightly-job -s "0 0 * * *" --max-runtime 30 --timezone UTC -- ./backup.sh +``` + ### `sentry monitor list []` List cron monitors @@ -50,20 +63,13 @@ List cron monitors **Examples:** ```bash -# Wrap a command with cron monitor check-ins (DSN-based) -SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 \ - sentry monitor run nightly-job -- python manage.py cron - -# The -- separator is optional when the command has no flags -sentry monitor run nightly-job npm run task - -# Create/update the monitor on the first check-in via --schedule (crontab) -sentry monitor run nightly-job -s "0 0 * * *" --max-runtime 30 --timezone UTC -- ./backup.sh +# List monitors (organization auto-detected) +sentry monitor list -# List cron monitors in an org +# List cron monitors in an organization sentry monitor list my-org/ -# Paginate through monitors +# Fetch the next page sentry monitor list my-org/ -c next # Output as JSON diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/org.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/org.md index fc4ed42e9..cfb1b424d 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/org.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/org.md @@ -20,39 +20,44 @@ List organizations - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` - `-a, --account - Only list organizations of this account (email, username, or account id; : for one server; env:SENTRY_AUTH_TOKEN)` -### `sentry org view []` - -View details of an organization - -**Flags:** -- `-w, --web - Open in browser` -- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` - **Examples:** ```bash # List organizations sentry org list +# Only organizations whose slug or name matches (fuzzy, best matches first) +sentry org list acme + +# Only organizations matching a glob +sentry org list 'acme-*' + # Only one account's organizations sentry org list --account jane@acme.com -# The same email on several servers: add the server + +# Same email on several servers: add the server sentry org list -a jane@example.com:sentry.io -# Only organizations whose slug or name matches "acme", best matches first -# (case-insensitive; prefix, substring, and small typos match too) -sentry org list acme -# ...or matches a glob -sentry org list 'acme-*' +# Output as JSON +sentry org list --json +``` + +### `sentry org view []` +View details of an organization + +**Flags:** +- `-w, --web - Open in browser` +- `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` + +**Examples:** + +```bash # View organization details sentry org view my-org -# Open in browser +# Open in the browser sentry org view my-org -w - -# JSON output -sentry org list --json ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/platform.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/platform.md index c684a5a08..279e016ba 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/platform.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/platform.md @@ -27,9 +27,6 @@ sentry platform list # Filter by substring sentry platform list --search python -# Shortcut for `sentry platform list` -sentry platforms - # Output as JSON sentry platform list --json ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/proguard.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/proguard.md index 98d82f876..8da0b3234 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/proguard.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/proguard.md @@ -29,10 +29,10 @@ sentry proguard upload ./app/build/outputs/mapping/release/mapping.txt # Upload multiple mapping files sentry proguard upload mapping-release.txt mapping-debug.txt -# Validate without uploading (dry-run) +# Validate without uploading sentry proguard upload mapping.txt --no-upload -# Fail if no mapping files are provided (useful in CI) +# Fail if no mapping files are found (useful in CI) sentry proguard upload ./mapping/ --require-one ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/project.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/project.md index 7b5262aaf..1b630fabc 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/project.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/project.md @@ -22,18 +22,20 @@ Create one or more projects **Examples:** ```bash -# Every project is a name:platform pair; project names cannot contain whitespace -# Create a new project +# Create a project (every project is a name:platform pair) sentry project create my-new-app:javascript-nextjs # Create several projects with their own platforms sentry project create web:javascript api:python-django worker:node -# Create under a specific org and team +# Create under a specific organization and team sentry project create my-org/my-new-app:python --team backend-team # Preview without creating sentry project create my-new-app:node --dry-run + +# Output the created project as JSON +sentry project create my-app:go --json ``` ### `sentry project delete ` @@ -48,11 +50,14 @@ Delete a project **Examples:** ```bash -# Delete a project (will prompt for confirmation) +# Delete a project (prompts for confirmation) sentry project delete my-org/old-project # Delete without confirmation sentry project delete my-org/old-project --yes + +# Preview the deletion +sentry project delete my-org/old-project --dry-run ``` ### `sentry project list []` @@ -65,6 +70,19 @@ List projects - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` - `-c, --cursor - Navigate pages: "next", "prev", "first" (or raw cursor string)` +**Examples:** + +```bash +# List all projects in an organization +sentry project list my-org/ + +# Several projects in the same organization +sentry project list my-org/frontend,backend + +# Filter by platform +sentry project list my-org/ --platform javascript +``` + ### `sentry project view []` View details of a project @@ -76,19 +94,10 @@ View details of a project **Examples:** ```bash -# List all projects in an org -sentry project list my-org/ - -# Several projects in the same org -sentry project list my-org/frontend,backend - -# Filter by platform -sentry project list my-org/ --platform javascript - # View project details sentry project view my-org/frontend -# Open project in browser +# Open the project in the browser sentry project view my-org/frontend -w ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/react-native.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/react-native.md index 3ab79f766..0bd9a1e86 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/react-native.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/react-native.md @@ -23,6 +23,16 @@ Upload a React Native bundle + sourcemap (Gradle build step) - `--wait - Wait for the server to fully process the uploaded files` - `--wait-for - Wait for processing, but at most this many seconds` +**Examples:** + +```bash +# Upload a bundle and sourcemap by debug ID (called by the Gradle plugin) +sentry react-native gradle --bundle index.android.bundle --sourcemap index.android.bundle.map + +# Also associate with a release and distribution +sentry react-native gradle --bundle index.android.bundle --sourcemap index.android.bundle.map --release com.example.app@1.0.0 --dist 1000 +``` + ### `sentry react-native xcode ` Upload React Native sourcemaps (Xcode build step) @@ -41,19 +51,7 @@ Upload React Native sourcemaps (Xcode build step) **Examples:** ```bash -# Upload a bundle + sourcemap by debug ID (called by the Gradle plugin) -sentry react-native gradle \ - --bundle index.android.bundle \ - --sourcemap index.android.bundle.map - -# Also associate with a release and distribution(s) -sentry react-native gradle \ - --bundle index.android.bundle \ - --sourcemap index.android.bundle.map \ - --release com.example.app@1.0.0 \ - --dist 1000 - -# Xcode build phase (usually added automatically to your build script) +# Run as the Xcode build phase (usually added automatically to your build script) sentry react-native xcode ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/release.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/release.md index e8b750e73..19315e782 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/release.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/release.md @@ -24,6 +24,31 @@ List releases with adoption and health metrics - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` - `-c, --cursor - Navigate pages: "next", "prev", "first" (or raw cursor string)` +**Examples:** + +```bash +# List releases (project auto-detected) +sentry release list + +# List all releases in an organization +sentry release list my-org/ + +# List releases for one project +sentry release list my-org/my-project + +# Sort by crash-free sessions +sentry release list --sort cfs + +# Filter by environment +sentry release list --environment production + +# Show the last 7 days of health data +sentry release list --period 7d + +# Output as JSON +sentry release list --json +``` + ### `sentry release view ` View release details with health metrics @@ -31,6 +56,22 @@ View release details with health metrics **Flags:** - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` +**Examples:** + +```bash +# View release details +sentry release view 1.0.0 + +# View a release in an explicit organization +sentry release view my-org/1.0.0 + +# View a release whose version contains a package name +sentry release view "sentry-cli@0.24.0" + +# Output as JSON +sentry release view 1.0.0 --json +``` + ### `sentry release create ` Create a release @@ -42,6 +83,31 @@ Create a release - `--url - URL to the release source` - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Create a release +sentry release create 1.0.0 + +# Create a release in an explicit organization +sentry release create my-org/1.0.0 + +# Create and finalize a release +sentry release create 1.0.0 --finalize + +# Create a release for specific projects +sentry release create 1.0.0 --project proj-a,proj-b + +# Create a release from a proposed version +sentry release create $(sentry release propose-version) + +# Set the release ref and URL +sentry release create 1.0.0 --ref main --url https://github.com/org/repo/releases/tag/1.0.0 + +# Preview without creating +sentry release create 1.0.0 --dry-run +``` + ### `sentry release finalize ` Finalize a release @@ -51,6 +117,22 @@ Finalize a release - `--url - URL for the release` - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Finalize a release +sentry release finalize 1.0.0 + +# Finalize a release in an explicit organization +sentry release finalize my-org/1.0.0 + +# Set a custom release timestamp +sentry release finalize 1.0.0 --released 2025-01-01T00:00:00Z + +# Preview without finalizing +sentry release finalize 1.0.0 --dry-run +``` + ### `sentry release delete ` Delete a release @@ -60,6 +142,19 @@ Delete a release - `-f, --force - Force the operation without confirmation` - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Delete a release (prompts for confirmation) +sentry release delete my-org/1.0.0 + +# Skip confirmation +sentry release delete my-org/1.0.0 --yes + +# Preview without deleting +sentry release delete my-org/1.0.0 --dry-run +``` + ### `sentry release archive ` Archive a release @@ -67,6 +162,19 @@ Archive a release **Flags:** - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Archive a release (hide it from the default list, but keep it) +sentry release archive 1.0.0 + +# Archive a release in an explicit organization +sentry release archive my-org/1.0.0 + +# Preview without archiving +sentry release archive my-org/1.0.0 --dry-run +``` + ### `sentry release restore ` Restore an archived release @@ -74,6 +182,19 @@ Restore an archived release **Flags:** - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Restore a previously archived release +sentry release restore 1.0.0 + +# Restore a release in an explicit organization +sentry release restore my-org/1.0.0 + +# Preview without restoring +sentry release restore 1.0.0 --dry-run +``` + ### `sentry release deploy []` Create a deploy for a release @@ -85,10 +206,42 @@ Create a deploy for a release - `-t, --time - Deploy duration in seconds (sets started = now - time, finished = now)` - `-n, --dry-run - Show what would happen without making changes` +**Examples:** + +```bash +# Create a deploy +sentry release deploy 1.0.0 production + +# Create a named deploy in an explicit organization +sentry release deploy my-org/1.0.0 staging "Deploy #42" + +# Attach a deploy URL +sentry release deploy 1.0.0 production --url https://example.com + +# Record a deploy duration in seconds +sentry release deploy 1.0.0 production --time 120 + +# Preview without creating +sentry release deploy 1.0.0 production --dry-run +``` + ### `sentry release deploys ` List deploys for a release +**Examples:** + +```bash +# List deploys for a release +sentry release deploys 1.0.0 + +# List deploys for a release in an explicit organization +sentry release deploys my-org/1.0.0 + +# Output as JSON +sentry release deploys 1.0.0 --json +``` + ### `sentry release set-commits ` Set commits for a release @@ -102,67 +255,43 @@ Set commits for a release - `--from - Read the local range ..HEAD (e.g. previous release tag). Implies --local.` - `--initial-depth - Number of commits to read with --local - (default: "20")` -### `sentry release propose-version` - -Propose a release version - **Examples:** ```bash -# List releases (auto-detect org) -sentry release list - -# List releases in a specific org -sentry release list my-org/ +# Associate commits using the repository integration +sentry release set-commits 1.0.0 --auto -# View release details -sentry release view 1.0.0 -sentry release view my-org/1.0.0 +# Set commits from local git history +sentry release set-commits my-org/1.0.0 --local -# Create and finalize a release -sentry release create 1.0.0 --finalize +# Read up to 50 local commits +sentry release set-commits 1.0.0 --local --initial-depth 50 -# Create a release, then finalize separately -sentry release create 1.0.0 -sentry release set-commits 1.0.0 --auto -sentry release finalize 1.0.0 +# Only include commits that touch specific paths +sentry release set-commits 1.0.0 --path apps/mobile,packages/shared-ui -# Set commits from local git history -sentry release set-commits 1.0.0 --local +# Read local commits since a previous release tag +sentry release set-commits 1.0.0 --from v0.9.0 -# Create a deploy -sentry release deploy 1.0.0 production -sentry release deploy 1.0.0 staging "Deploy #42" +# Set an explicit commit range +sentry release set-commits 1.0.0 --commit owner/repo@abc123..def456 -# Propose a version from git HEAD -sentry release create $(sentry release propose-version) +# Clear the release's commits +sentry release set-commits 1.0.0 --clear +``` -# List deploys for a release -sentry release deploys 1.0.0 -sentry release deploys my-org/1.0.0 +### `sentry release propose-version` -# Archive a release (hide it from the default list, but keep it) -sentry release archive 1.0.0 -sentry release archive my-org/1.0.0 --dry-run # Preview without archiving +Propose a release version -# Restore a previously archived release -sentry release restore 1.0.0 -sentry release restore my-org/1.0.0 +**Examples:** -# Delete a release -sentry release delete my-org/1.0.0 -sentry release delete my-org/1.0.0 --yes # Skip confirmation -sentry release delete my-org/1.0.0 --dry-run # Preview without deleting +```bash +# Propose a version from git HEAD +sentry release propose-version # Output as JSON -sentry release list --json -sentry release view 1.0.0 --json - -# Full release workflow with explicit org -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 +sentry release propose-version --json ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/replay.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/replay.md index d332a2798..b9a9c63d6 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/replay.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/replay.md @@ -63,20 +63,34 @@ List recent Session Replays **Examples:** ```bash +# List recent replays (project auto-detected) +sentry replay list + # List recent replays for a project sentry replay list my-org/frontend -# Search across all projects in an org +# Search across all projects in an organization sentry replay list my-org/ --query "environment:production" # Change the time window and sort sentry replay list my-org/frontend --period 24h --sort errors -# Paginate through results +# Find replays for a user +sentry replay list my-org/frontend -q "user.email:foo@example.com" + +# Filter by environments +sentry replay list my-org/frontend -e production -e canary + +# Show more results +sentry replay list my-org/frontend --limit 50 + +# Fetch the next page sentry replay list my-org/frontend -c next + +# Fetch the previous page sentry replay list my-org/frontend -c prev -# Output machine-readable data +# Output as JSON sentry replay list my-org/frontend --json ``` @@ -132,20 +146,23 @@ View a Session Replay **Examples:** ```bash -# View a replay by ID using auto-detected org/project context +# View a replay by ID (organization and project auto-detected) sentry replay view 346789a703f6454384f1de473b8b9fcc -# View a replay with an explicit org +# View a replay in an explicit organization sentry replay view my-org/346789a703f6454384f1de473b8b9fcc # View a replay with explicit org/project context sentry replay view my-org/frontend/346789a703f6454384f1de473b8b9fcc -# Open a replay in the browser -sentry replay view my-org/346789a703f6454384f1de473b8b9fcc --web +# View a replay from its URL +sentry replay view https://sentry.io/organizations/my-org/explore/replays/346789a703f6454384f1de473b8b9fcc/ # View the replay linked to a trace sentry replay view my-org/frontend/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +# Open a replay in the browser +sentry replay view my-org/346789a703f6454384f1de473b8b9fcc --web ``` ### `sentry replay download ` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/repo.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/repo.md index 0e1c779b9..55a7e17ec 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/repo.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/repo.md @@ -37,10 +37,13 @@ List repositories **Examples:** ```bash -# List repositories (auto-detect org) +# List repositories (organization auto-detected) sentry repo list -# List repos in a specific org with pagination +# List repositories in an organization +sentry repo list my-org/ + +# Fetch the next page sentry repo list my-org/ -c next # Output as JSON diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/snapshots.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/snapshots.md index 332f5b68a..d52b90e44 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/snapshots.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/snapshots.md @@ -22,6 +22,16 @@ Compare two directories of snapshot images - `--fail-on-diff - Exit non-zero if any diffs (changed/added/removed/errored) are found` - `--selective - Treat images missing from head as skipped instead of removed` +**Examples:** + +```bash +# Compare two directories of snapshot images locally +sentry snapshots diff ./baseline ./head + +# Exit non-zero if any images changed, with a custom threshold +sentry snapshots diff ./baseline ./head --fail-on-diff --threshold 0.02 +``` + ### `sentry snapshots download` Download baseline snapshot images @@ -32,6 +42,19 @@ Download baseline snapshot images - `--branch - Git branch filter (only with --app-id)` - `-o, --output - Directory for extracted images (default: ./snapshots-base/)` +**Examples:** + +```bash +# Download a specific baseline snapshot by ID +sentry snapshots download --snapshot-id 1234567890 + +# Download the latest baseline for an app, filtered by branch +sentry snapshots download --app-id my-app --branch main + +# Extract images to a specific directory +sentry snapshots download --app-id my-app --output ./baseline/ +``` + ### `sentry snapshots upload ` Upload snapshots to a project @@ -64,21 +87,6 @@ sentry snapshots upload ./screenshots --app-id my-app --selective # Only flag images that differ by more than 1% sentry snapshots upload ./screenshots --app-id my-app --diff-threshold 0.01 - -# Compare two directories of snapshot images locally -sentry snapshots diff ./baseline ./head - -# Fail (non-zero exit) if any images changed, with a custom threshold -sentry snapshots diff ./baseline ./head --fail-on-diff --threshold 0.02 - -# Download a specific baseline snapshot by ID -sentry snapshots download --snapshot-id 1234567890 - -# Download the latest baseline for an app, filtered by branch -sentry snapshots download --app-id my-app --branch main - -# Extract images to a specific directory -sentry snapshots download --app-id my-app --output ./baseline/ ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/sourcemap.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/sourcemap.md index 0998bdd9a..ac4e07050 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/sourcemap.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/sourcemap.md @@ -63,6 +63,7 @@ sentry sourcemap upload ./dist --release 1.0.0 # Set a custom URL prefix sentry sourcemap upload ./dist --url-prefix '~/static/js/' +# Don't fail when no sourcemaps are found sentry sourcemap upload ./dist --allow-empty ``` @@ -78,11 +79,10 @@ Resolve and report sourcemap linkage for JavaScript files **Examples:** ```bash -# Report how each JS file's sourcemap resolves and whether a debug ID -# has been injected (read-only — never modifies files) +# Report how each JS file's sourcemap resolves and whether a debug ID is injected sentry sourcemap resolve ./dist -# Machine-readable output +# Output as JSON sentry sourcemap resolve ./dist --json ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/span.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/span.md index 3e9b03334..dc1b07242 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/span.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/span.md @@ -49,20 +49,20 @@ sentry span list -q "op:db" # Slow spans in the last 24 hours sentry span list -q "duration:>100ms" --period 24h +# Sort by slowest first +sentry span list --sort duration + # List spans within a specific trace sentry span list abc123def456abc123def456abc12345 -# Paginate through results -sentry span list -c next - # Show only spans from one project within a trace sentry span list my-org/cli-server/abc123def456abc123def456abc12345 -# Or use --query to filter by project -sentry span list abc123def456abc123def456abc12345 -q "project:cli-server" - -# Multiple projects at once +# Filter a trace's spans to several projects sentry span list abc123def456abc123def456abc12345 -q "project:[cli-server,api]" + +# Fetch the next page +sentry span list -c next ``` ### `sentry span view ` @@ -82,7 +82,7 @@ sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890 # View multiple spans at once sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890 b2c3d4e5f6789012 -# With explicit org/project +# Specify the organization and project explicitly sentry span view my-org/backend/abc123def456abc123def456abc12345 a1b2c3d4e5f67890 ``` diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/team.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/team.md index 4e923f18c..8de6462e6 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/team.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/team.md @@ -35,10 +35,13 @@ List teams **Examples:** ```bash -# List teams +# List teams (organization auto-detected) +sentry team list + +# List teams in an organization sentry team list my-org/ -# Paginate through teams +# Fetch the next page sentry team list my-org/ -c next # Output as JSON diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trace.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trace.md index 577995ca6..10da3d987 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trace.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trace.md @@ -37,16 +37,19 @@ List recent traces in a project **Examples:** ```bash -# List last 20 traces (default) +# List recent traces sentry trace list +# Show more traces +sentry trace list --limit 50 + # Sort by slowest first sentry trace list --sort duration -# Filter by transaction name, last 24 hours +# Filter by transaction name in the last 24 hours sentry trace list -q "transaction:GET /api/users" --period 24h -# Paginate through results +# Fetch the next page sentry trace list my-org/backend -c next ``` @@ -63,26 +66,20 @@ View details of a specific trace **Examples:** ```bash -# View trace details with span tree +# View trace details with the span tree sentry trace view abc123def456abc123def456abc12345 -# Open trace in browser -sentry trace view abc123def456abc123def456abc12345 -w - -# Auto-recover from an issue short ID -sentry trace view PROJ-123 +# Show the full trace across all projects +sentry trace view my-org/abc123def456abc123def456abc12345 -# Filter trace view to one project's spans +# Filter the span tree to one project sentry trace view my-org/cli-server/abc123def456abc123def456abc12345 -# Full trace across all projects (default) -sentry trace view my-org/abc123def456abc123def456abc12345 - -# Filter trace logs by project -sentry trace logs my-org/cli-server/abc123def456abc123def456abc12345 +# Recover the trace from an issue short ID +sentry trace view PROJ-123 -# Multiple projects via --query -sentry trace logs abc123def456abc123def456abc12345 -q "project:[cli-server,api]" +# Open the trace in the browser +sentry trace view abc123def456abc123def456abc12345 -w ``` ### `sentry trace logs ` @@ -103,11 +100,20 @@ View logs associated with a trace # View logs for a trace sentry trace logs abc123def456abc123def456abc12345 +# Filter trace logs to one project +sentry trace logs my-org/cli-server/abc123def456abc123def456abc12345 + +# Filter trace logs to several projects +sentry trace logs abc123def456abc123def456abc12345 -q "project:[cli-server,api]" + # Search with a longer time window sentry trace logs --period 30d abc123def456abc123def456abc12345 -# Filter logs within a trace +# Only error logs sentry trace logs -q 'severity:error' abc123def456abc123def456abc12345 + +# Output as JSON +sentry trace logs --json abc123def456abc123def456abc12345 ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trial.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trial.md index af511f1ab..c3bc44764 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trial.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trial.md @@ -26,27 +26,37 @@ List product trials | `isStarted` | boolean | Whether the trial has started | | `lengthDays` | number \| null | Trial duration in days | -### `sentry trial start []` - -Start a product trial - **Examples:** ```bash -# List all trials for the current org +# List all trials for the current organization sentry trial list -# List trials for a specific org +# List trials for a specific organization sentry trial list my-org +# Output as JSON +sentry trial list --json +``` + +### `sentry trial start []` + +Start a product trial + +**Examples:** + +```bash # Start a Seer trial sentry trial start seer -# Start a trial for a specific org +# Start a trial for a specific organization sentry trial start replays my-org -# Start a Business plan trial (opens browser) +# Start a Business plan trial (opens the browser) sentry trial start plan + +# Output the result as JSON +sentry trial start --json seer ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/wasm-split.md b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/wasm-split.md index 33179e2cb..d8b7b15d3 100644 --- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/wasm-split.md +++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/wasm-split.md @@ -27,10 +27,10 @@ Add build ids to WebAssembly modules and split out debug data **Examples:** ```bash -# Add a build id to a module, in place, and print it +# Add a build ID to a module in place and print it sentry wasm-split app.wasm -# Capture the build id for a later upload +# Capture the build ID for a later upload BUILD_ID=$(sentry wasm-split app.wasm) # Split debug data into a companion and ship a stripped binary @@ -40,8 +40,7 @@ sentry wasm-split app.wasm --debug-out app.debug.wasm --strip sentry wasm-split app.wasm -d app.debug.wasm --strip --strip-names # Point browsers at a companion served from a CDN -sentry wasm-split app.wasm -o dist/app.wasm -d dist/app.debug.wasm --strip \ - --external-dwarf-url https://cdn.example.com/debug/app.debug.wasm +sentry wasm-split app.wasm -o dist/app.wasm -d dist/app.debug.wasm --strip --external-dwarf-url https://cdn.example.com/debug/app.debug.wasm ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/packages/cli/script/check-fragments.ts b/packages/cli/script/check-fragments.ts index 64b3a9abe..c0d0fdcf8 100644 --- a/packages/cli/script/check-fragments.ts +++ b/packages/cli/script/check-fragments.ts @@ -8,6 +8,7 @@ * 3. Fragment files don't accidentally contain frontmatter or the generated marker * 4. Top-level fragments (e.g., configuration.md) exist * 5. Fragment content covers all subcommands in a route (warnings only) + * 6. Fragments don't contain Examples sections (examples belong in docs.examples) * * Usage: * tsx script/check-fragments.ts # Warnings for missing subcommands @@ -17,6 +18,7 @@ import { mkdirSync, readdirSync } from "node:fs"; import { access, readFile, writeFile } from "node:fs/promises"; import type { RouteInfo, RouteMap } from "../src/lib/introspect.js"; +import { markdownHeadings } from "./markdown.js"; import { DOCS_FRAGMENTS } from "./paths.js"; // Ensure skill-content stub exists (see generate-command-docs.ts for rationale) @@ -89,6 +91,9 @@ for (const name of actualFragments) { } } +/** Matches heading text that starts an Examples section. */ +const EXAMPLES_HEADING_RE = /^examples?\b/i; + // Check 3: Fragment content validation for (const file of fragmentFiles) { const content = await readFile(`${FRAGMENTS_DIR}/${file}`, "utf-8"); @@ -104,6 +109,16 @@ for (const file of fragmentFiles) { `Fragment contains generated marker: ${FRAGMENTS_DIR}/${file} (the "${GENERATED_END_MARKER}" marker should not appear in fragment files)`, ); } + + if ( + markdownHeadings(content).some(({ text }) => + EXAMPLES_HEADING_RE.test(text.trim()), + ) + ) { + errors.push( + `Fragment contains an Examples section: ${FRAGMENTS_DIR}/${file} (move command examples to the command's docs.examples metadata so they appear in help, generated docs, and skills)`, + ); + } } // --------------------------------------------------------------------------- @@ -134,13 +149,6 @@ for (const name of REQUIRED_TOP_LEVEL_FRAGMENTS) { const warnings: string[] = []; -const FENCED_CODE_BLOCK_RE = /^(`{3,}|~{3,}).*\n[\s\S]*?\n\1\s*$/gm; - -/** Strip fenced code blocks from markdown to avoid matching bash comments as headings. */ -function stripCodeBlocks(md: string): string { - return md.replace(FENCED_CODE_BLOCK_RE, ""); -} - /** * Check whether a fragment mentions a specific subcommand. * @@ -182,15 +190,12 @@ function fragmentMentionsSubcommand( } } - // Check 3: Heading that mentions the leaf name (outside code blocks) - const proseOnly = stripCodeBlocks(content); + // Check 3: Heading (levels 1-4, outside code blocks) that mentions the leaf name const escapedLeaf = leaf.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - const headingRe = new RegExp(`^#{1,4}\\s+.*\\b${escapedLeaf}\\b`, "im"); - if (headingRe.test(proseOnly)) { - return true; - } - - return false; + const leafRe = new RegExp(`\\b${escapedLeaf}\\b`, "i"); + return markdownHeadings(content).some( + ({ depth, text }) => depth <= 4 && leafRe.test(text), + ); } /** diff --git a/packages/cli/script/check-stale-references.ts b/packages/cli/script/check-stale-references.ts index 4fda955b2..359d65921 100644 --- a/packages/cli/script/check-stale-references.ts +++ b/packages/cli/script/check-stale-references.ts @@ -23,6 +23,7 @@ import { readdirSync } from "node:fs"; import { readFile } from "node:fs/promises"; +import { blankCodeBlocks } from "./markdown.js"; import { DOCS_CONTENT } from "./paths.js"; const pkg = JSON.parse(await readFile("package.json", "utf-8")); @@ -99,17 +100,6 @@ function getScriptFiles(): string[] { const FILES_TO_SCAN = [...DOC_FILES, ...getScriptFiles()]; -// --------------------------------------------------------------------------- -// Code block stripping (avoid false positives on user install examples) -// --------------------------------------------------------------------------- - -const FENCED_CODE_BLOCK_RE = /^(`{3,}|~{3,}).*\n[\s\S]*?\n\1\s*$/gm; - -/** Strip fenced code blocks from markdown content to avoid false positives. */ -function stripCodeBlocks(content: string): string { - return content.replace(FENCED_CODE_BLOCK_RE, ""); -} - // --------------------------------------------------------------------------- // Main // --------------------------------------------------------------------------- @@ -132,23 +122,19 @@ for (const filePath of FILES_TO_SCAN) { continue; } - // For markdown files, strip code blocks to avoid matching user install examples + // For markdown files, blank code blocks to avoid matching user install + // examples. Blanking keeps line numbers aligned with the original file. const isMarkdown = filePath.endsWith(".md") || filePath.endsWith(".mdx"); - const scannable = isMarkdown ? stripCodeBlocks(content) : content; + const scannable = isMarkdown ? blankCodeBlocks(content) : content; const lines = scannable.split("\n"); for (let i = 0; i < lines.length; i++) { const line = lines[i]; for (const { pattern, reason } of PATTERNS) { if (pattern.test(line)) { - // Find the original line number in the un-stripped content - // For scripts (no stripping), i is the actual line number - const originalLine = isMarkdown - ? findOriginalLineNumber(content, line) - : i + 1; findings.push({ file: filePath, - line: originalLine, + line: i + 1, text: line.trim(), reason, }); @@ -157,24 +143,6 @@ for (const filePath of FILES_TO_SCAN) { } } -/** - * Find the 1-indexed line number of a text line in the original content. - * Falls back to 0 if not found (shouldn't happen in practice). - */ -function findOriginalLineNumber( - original: string, - strippedLine: string, -): number { - const trimmed = strippedLine.trim(); - const lines = original.split("\n"); - for (let i = 0; i < lines.length; i++) { - if (lines[i].trim() === trimmed) { - return i + 1; - } - } - return 0; -} - if (findings.length === 0) { console.log( `✓ No stale package manager references found (current: ${currentPM}, checked: ${FILES_TO_SCAN.length} files)`, diff --git a/packages/cli/script/generate-skill-markdown.ts b/packages/cli/script/generate-skill-markdown.ts index f470c079f..2fb810b4f 100644 --- a/packages/cli/script/generate-skill-markdown.ts +++ b/packages/cli/script/generate-skill-markdown.ts @@ -1,42 +1,8 @@ /** - * Markdown parsing helpers shared by the skill generator and its tests. + * Markdown rendering helpers shared by the docs and skill generators. */ import type { PositionalInfo } from "../src/lib/introspect.js"; -/** Matches a generated command heading and stops before positional usage. */ -const COMMAND_HEADING_RE = - /^`sentry\s+([^<[`\s]+(?:\s+[^<[`\s]+)*)(?:\s*(?:<|\[)[^`]*)?`$/; - -/** Extract the literal command path from a generated command heading. */ -export function extractCommandPathFromHeading( - heading: string, -): string | undefined { - const match = COMMAND_HEADING_RE.exec(heading); - return match?.[1] ? `sentry ${match[1]}` : undefined; -} - -/** Find the command whose literal path appears in a loose example block. */ -export function matchExampleToCommand( - code: string, - commandPaths: readonly string[], - groupFallback: string, - defaultCommandPath?: string, -): string | undefined { - // Prefer the longest path so `sentry auth login` wins over bare `sentry auth` - // when both would otherwise match via includes(). - const byLengthDesc = [...commandPaths].sort((a, b) => b.length - a.length); - const matched = byLengthDesc.find((path) => code.includes(path)); - if (matched) { - return matched; - } - if (!code.includes(groupFallback)) { - return; - } - // Bare group examples (`sentry auth`) belong on the default subcommand when - // one exists (login), not on a synthetic group-only path. - return defaultCommandPath ?? groupFallback; -} - /** Render structured command examples in the same form for docs and skills. */ export function formatCommandExamples(examples: readonly string[]): string { if (examples.length === 0) { diff --git a/packages/cli/script/generate-skill.ts b/packages/cli/script/generate-skill.ts index 2ebe69b2b..7cdfa283e 100644 --- a/packages/cli/script/generate-skill.ts +++ b/packages/cli/script/generate-skill.ts @@ -2,8 +2,9 @@ /** * Generate Skill Files from Stricli Command Metadata and Docs * - * Introspects the CLI's route tree and merges with documentation - * to generate structured documentation for AI agents. + * Introspects the CLI's route tree (including command-owned examples) and + * merges it with hand-written guidance to generate structured documentation + * for AI agents. * * Produces: * - SKILL.md: compact index with agent guidance + command summaries @@ -23,13 +24,12 @@ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import { access, readFile, writeFile } from "node:fs/promises"; -import type { Token } from "marked"; -import { marked } from "marked"; +import { formatCommandExamples } from "./generate-skill-markdown.js"; import { - extractCommandPathFromHeading, - formatCommandExamples, - matchExampleToCommand, -} from "./generate-skill-markdown.js"; + demoteHeadings, + markdownCodeBlocks, + markdownSection, +} from "./markdown.js"; import { DOCS_CONTENT, DOCS_PUBLIC } from "./paths.js"; // Bootstrap: ensure the generated skill-content module exists before @@ -56,40 +56,7 @@ import type { RouteInfo, RouteMap, } from "../src/lib/introspect.js"; -import { - buildCommandInfo, - extractRouteGroupCommands, - isCommand, - isRouteMap, -} from "../src/lib/introspect.js"; - -/** - * Resolve the default subcommand name for a route map, if configured. - * - * Hidden dispatcher routes (e.g. auth's `default`) map bare group examples - * onto the user-facing command they primarily document (login). - */ -function findDefaultCommandName(routeMap: RouteMap): string | undefined { - if (!routeMap.getDefaultCommand) { - return; - } - const defaultCmd = routeMap.getDefaultCommand(); - if (!defaultCmd) { - return; - } - for (const sub of routeMap.getAllEntries()) { - if (sub.target === defaultCmd) { - const name = sub.name.original; - // Auth uses a hidden "default" dispatcher; bare `sentry auth` examples - // document the login path. - if (name === "default") { - return "login"; - } - return name; - } - } - return; -} +import { extractAllRoutes } from "../src/lib/introspect.js"; const SKILL_DIR = "plugins/sentry-cli/skills/sentry-cli"; const OUTPUT_PATH = `${SKILL_DIR}/SKILL.md`; @@ -106,9 +73,6 @@ async function getPackageVersion(): Promise { /** Regex to match YAML frontmatter at the start of a file */ const FRONTMATTER_REGEX = /^---\n[\s\S]*?\n---\n/; -/** Regex to match code blocks with optional language specifier */ -const CODE_BLOCK_REGEX = /```(\w*)\n([\s\S]*?)```/g; - /** Regex to extract npm command from PackageManagerCode Astro component (handles multi-line) */ const PACKAGE_MANAGER_REGEX = / lang === "bash", + ); const npmCommand = extractPackageManagerCommand(rawContent); if (codeBlocks.length > 0 || npmCommand) { lines.push("```bash"); @@ -261,7 +182,9 @@ function generateAuthSection(authSection: string): string[] { const lines: string[] = []; lines.push("### Authentication"); lines.push(""); - const codeBlocks = extractCodeBlocks(authSection, "bash"); + const codeBlocks = markdownCodeBlocks(authSection).filter( + ({ lang }) => lang === "bash", + ); if (codeBlocks.length > 0) { lines.push("```bash"); for (const block of codeBlocks) { @@ -289,12 +212,12 @@ async function loadPrerequisites(): Promise { lines.push(""); lines.push("The CLI must be installed and authenticated before use."); lines.push(""); - const installSection = extractSection(content, "Install Script"); + const installSection = markdownSection(content, "Install Script"); if (installSection) { lines.push(...generateInstallSection(installSection, rawContent)); } lines.push(""); - const authSection = extractSection(content, "Authentication"); + const authSection = markdownSection(content, "Authentication"); if (authSection) { lines.push(...generateAuthSection(authSection)); } @@ -331,115 +254,6 @@ sentry auth status \`\`\``; } -/** Append a code block to a map entry, creating the array if needed */ -function appendExample( - map: Map, - key: string, - code: string, -): void { - const list = map.get(key) ?? []; - list.push(code); - map.set(key, list); -} - -/** - * Collect all command paths from `### \`sentry ...\`` headings in a token list. - * Initializes each path with an empty array in the examples map. - */ -function collectCommandPaths( - tokens: Token[], - examples: Map, -): string[] { - const paths: string[] = []; - for (const token of tokens) { - if (token.type !== "heading" || token.depth !== 3) { - continue; - } - const cmdPath = extractCommandPathFromHeading(token.text); - if (cmdPath) { - paths.push(cmdPath); - if (!examples.has(cmdPath)) { - examples.set(cmdPath, []); - } - } - } - return paths; -} - -/** - * Walk tokens sequentially and associate each bash code block with - * the appropriate command path — either by heading context or content matching. - */ -function associateCodeBlocks( - tokens: Token[], - context: { - commandPaths: string[]; - commandGroup: string; - examples: Map; - defaultCommandPath?: string; - }, -): void { - const { commandPaths, commandGroup, examples, defaultCommandPath } = context; - const groupFallback = `sentry ${commandGroup}`; - let currentCmd: string | null = null; - - for (const token of tokens) { - if (token.type === "heading" && token.depth === 3) { - currentCmd = extractCommandPathFromHeading(token.text) ?? null; - } - if (token.type !== "code" || token.lang !== "bash") { - continue; - } - const code = token.text.trim(); - if (currentCmd && examples.has(currentCmd)) { - appendExample(examples, currentCmd, code); - } else { - const target = matchExampleToCommand( - code, - commandPaths, - groupFallback, - defaultCommandPath, - ); - if (target) { - appendExample(examples, target, code); - } - } - } -} - -/** - * Load examples for a specific command group from docs using the `marked` - * AST parser. Walks the token tree to find command headings and associate - * bash code blocks with each command. - * - * Handles both auto-generated reference sections (`### \`sentry ...\`` headings) - * and hand-written custom sections (`## Examples` with descriptive headings) - * by matching code blocks to commands via heading context or content analysis. - */ -async function loadCommandExamples( - commandGroup: string, - defaultCommandName?: string, -): Promise> { - const docContent = await loadDoc(`commands/${commandGroup}.md`); - if (!docContent) { - return new Map(); - } - - const tokens = marked.lexer(docContent); - const examples = new Map(); - const commandPaths = collectCommandPaths(tokens, examples); - const defaultCommandPath = defaultCommandName - ? `sentry ${commandGroup} ${defaultCommandName}` - : undefined; - associateCodeBlocks(tokens, { - commandPaths, - commandGroup, - examples, - defaultCommandPath, - }); - return examples; -} - /** Load supplementary content from commands/index.md */ async function loadCommandsOverview(): Promise<{ globalOptions: string; @@ -450,9 +264,9 @@ async function loadCommandsOverview(): Promise<{ if (!content) { return null; } - const globalSection = extractSection(content, "Global Options"); - const jsonSection = extractSection(content, "JSON Output"); - const webSection = extractSection(content, "Opening in Browser"); + const globalSection = markdownSection(content, "Global Options"); + const jsonSection = markdownSection(content, "JSON Output"); + const webSection = markdownSection(content, "Opening in Browser"); return { globalOptions: globalSection || "", jsonOutput: jsonSection || "", @@ -468,48 +282,6 @@ async function loadAgentGuidance(): Promise { return await loadDoc("agent-guidance.md"); } -// --------------------------------------------------------------------------- -// Route Introspection (with async doc loading) -// --------------------------------------------------------------------------- - -/** - * Walk the route tree and extract command information with doc examples. - * This is the async version that loads documentation examples from disk. - */ -async function extractRoutes(routeMap: RouteMap): Promise { - const result: RouteInfo[] = []; - for (const entry of routeMap.getAllEntries()) { - if (entry.hidden) { - continue; - } - const routeName = entry.name.original; - const target = entry.target; - const defaultCommandName = isRouteMap(target) - ? findDefaultCommandName(target) - : undefined; - const docExamples = await loadCommandExamples( - routeName, - defaultCommandName, - ); - if (isRouteMap(target)) { - result.push({ - name: routeName, - brief: target.brief, - commands: extractRouteGroupCommands(target, routeName, docExamples), - }); - } else if (isCommand(target)) { - const path = `sentry ${routeName}`; - const examples = docExamples.get(path) ?? []; - result.push({ - name: routeName, - brief: target.brief, - commands: [buildCommandInfo(target, path, examples)], - }); - } - } - return result; -} - // --------------------------------------------------------------------------- // Sorting // --------------------------------------------------------------------------- @@ -800,7 +572,7 @@ async function generateAllSkillFiles( ): Promise { const files: GeneratedFiles = new Map(); const version = await getPackageVersion(); - const routeInfos = await extractRoutes(routeMap); + const routeInfos = extractAllRoutes(routeMap); const prerequisites = await loadPrerequisites(); const supplementary = await generateSupplementarySections(); const agentGuidance = await loadAgentGuidance(); @@ -842,11 +614,7 @@ async function generateAllSkillFiles( if (agentGuidance) { indexSections.push("## Agent Guidance"); indexSections.push(""); - const nestedGuidance = agentGuidance.replace( - /^(#{2,6})\s/gm, - (_, hashes: string) => `#${hashes} `, - ); - indexSections.push(nestedGuidance); + indexSections.push(demoteHeadings(agentGuidance)); indexSections.push(""); } diff --git a/packages/cli/script/markdown.ts b/packages/cli/script/markdown.ts new file mode 100644 index 000000000..c226e04cf --- /dev/null +++ b/packages/cli/script/markdown.ts @@ -0,0 +1,84 @@ +/** + * Markdown structure helpers for doc-checking scripts. + * + * Backed by the `marked` lexer so headings and code blocks are recognized the + * same way the docs renderer sees them. Use these instead of regexes when a + * script needs markdown structure. + */ +import { marked, type Tokens } from "marked"; + +/** A markdown heading with its level and plain heading text. */ +export type MarkdownHeading = { depth: number; text: string }; + +/** Collect the top-level headings of a markdown document. */ +export function markdownHeadings(md: string): MarkdownHeading[] { + return marked + .lexer(md) + .filter((token) => token.type === "heading") + .map((token) => ({ depth: token.depth, text: token.text })); +} + +/** + * Blank out top-level code blocks while keeping their line breaks, so line + * numbers in the result still match the original document. + */ +export function blankCodeBlocks(md: string): string { + return marked + .lexer(md) + .map((token) => + token.type === "code" + ? "\n".repeat(token.raw.split("\n").length - 1) + : token.raw, + ) + .join(""); +} + +/** + * Body of the section under the first heading whose text equals `heading`, + * up to the next heading of the same or a higher level. Returns null when the + * heading is missing. + */ +export function markdownSection(md: string, heading: string): string | null { + const tokens = marked.lexer(md); + const start = tokens.findIndex( + (token) => token.type === "heading" && token.text.trim() === heading, + ); + if (start === -1) { + return null; + } + const { depth } = tokens[start] as Tokens.Heading; + const rest = tokens.slice(start + 1); + const end = rest.findIndex( + (token) => token.type === "heading" && token.depth <= depth, + ); + return (end === -1 ? rest : rest.slice(0, end)) + .map((token) => token.raw) + .join("") + .trim(); +} + +/** A fenced or indented code block with its language (first info-string word). */ +export type MarkdownCodeBlock = { code: string; lang: string }; + +/** Collect the top-level code blocks of a markdown document. */ +export function markdownCodeBlocks(md: string): MarkdownCodeBlock[] { + return marked + .lexer(md) + .filter((token) => token.type === "code") + .map((token) => ({ + code: token.text.trim(), + lang: (token.lang ?? "").split(" ")[0] ?? "", + })); +} + +/** Demote every top-level ATX heading of level 2 or deeper by one level. */ +export function demoteHeadings(md: string): string { + return marked + .lexer(md) + .map((token) => + token.type === "heading" && token.depth >= 2 && token.raw.startsWith("#") + ? `#${token.raw}` + : token.raw, + ) + .join(""); +} diff --git a/packages/cli/src/commands/alert/issues/create.ts b/packages/cli/src/commands/alert/issues/create.ts index d322200d6..05cd8726e 100644 --- a/packages/cli/src/commands/alert/issues/create.ts +++ b/packages/cli/src/commands/alert/issues/create.ts @@ -79,15 +79,20 @@ export const createCommand = buildCommand({ " --filter an action-filter condition (same shape as --condition)\n\n" + "Match mode: --filter-match all|any controls how the action-filter\n" + "conditions combine. Issue-alert triggers always evaluate as 'any-short'\n" + - "(they fire on a single error detector), so there is no trigger match flag.\n\n" + - "Examples:\n" + - " sentry alert issues create my-org/my-app --name 'New Issues' \\\n" + - ' --condition \'{"type":"first_seen_event","comparison":true,"conditionResult":true}\' \\\n' + - ' --action \'{"type":"email","data":{},"config":{"targetType":"team","targetIdentifier":"1"}}\'\n\n' + - " sentry alert issues create my-org/my-app --name 'High Priority' \\\n" + - ' --condition \'{"type":"new_high_priority_issue","comparison":true,"conditionResult":true}\' \\\n' + - ' --action \'{"type":"email","data":{},"config":{"targetType":"user","targetIdentifier":"56789"}}\' \\\n' + - " --frequency 30 --dry-run", + "(they fire on a single error detector), so there is no trigger match flag.", + examples: [ + { + description: "Alert on new issues and email a team", + command: + 'sentry alert issues create my-org/my-project --name \'New Issues\' --condition \'{"type":"first_seen_event","comparison":true,"conditionResult":true}\' --action \'{"type":"email","data":{},"config":{"targetType":"team","targetIdentifier":"1"}}\'', + }, + { + description: + "Preview a high-priority alert that emails a user at most every 30 minutes", + command: + 'sentry alert issues create my-org/my-project --name \'High Priority\' --condition \'{"type":"new_high_priority_issue","comparison":true,"conditionResult":true}\' --action \'{"type":"email","data":{},"config":{"targetType":"user","targetIdentifier":"56789"}}\' --frequency 30 --dry-run', + }, + ], }, output: { human: formatCreated, diff --git a/packages/cli/src/commands/alert/issues/delete.ts b/packages/cli/src/commands/alert/issues/delete.ts index f31b1449b..04796b36c 100644 --- a/packages/cli/src/commands/alert/issues/delete.ts +++ b/packages/cli/src/commands/alert/issues/delete.ts @@ -51,11 +51,21 @@ export const deleteCommand = buildDeleteCommand({ fullDescription: "Permanently remove an issue alert rule from a project. This cannot be undone.\n\n" + "You will be asked to type org/project/rule-id to confirm, unless you pass " + - "--yes or --force, or use --dry-run to preview only.\n\n" + - "Examples:\n" + - " sentry alert issues delete my-org/my-app/12345\n" + - " sentry alert issues delete my-org/my-app/'My Rule' --yes\n" + - " sentry alert issues delete my-org/my-app/12345 --dry-run", + "--yes or --force, or use --dry-run to preview only.", + examples: [ + { + description: "Delete an issue alert rule (prompts for confirmation)", + command: "sentry alert issues delete my-org/my-project/12345", + }, + { + description: "Delete a rule selected by name without prompting", + command: "sentry alert issues delete my-org/my-project/'My Rule' --yes", + }, + { + description: "Preview the deletion", + command: "sentry alert issues delete my-org/my-project/12345 --dry-run", + }, + ], }, output: { human: formatDeleted, diff --git a/packages/cli/src/commands/alert/issues/edit.ts b/packages/cli/src/commands/alert/issues/edit.ts index d4d91d1eb..0bb7ec6df 100644 --- a/packages/cli/src/commands/alert/issues/edit.ts +++ b/packages/cli/src/commands/alert/issues/edit.ts @@ -171,12 +171,30 @@ export const editCommand = buildCommand({ fullDescription: "Update an issue alert rule by id or name. You must set at least one of --name or " + "--status.\n\n" + - "The CLI loads the current rule, applies your changes, and updates it via the API.\n\n" + - "Examples:\n" + - " sentry alert issues edit my-org/my-app/12 --name 'Prod errors'\n" + - " sentry alert issues edit my-org/my-app/'Old name' --status disabled\n" + - " sentry alert issues edit 12 --name 'Renamed' --status active\n" + - ' sentry alert issues edit my-org/my-app/12 --condition \'{"id":"sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"}\'', + "The CLI loads the current rule, applies your changes, and updates it via the API.", + examples: [ + { + description: "Rename an issue alert rule", + command: + "sentry alert issues edit my-org/my-project/12345 --name 'Prod errors'", + }, + { + description: "Disable a rule selected by name", + command: + "sentry alert issues edit my-org/my-project/'Old name' --status disabled", + }, + { + description: + "Rename and enable a rule (organization and project auto-detected)", + command: + "sentry alert issues edit 12345 --name 'Renamed' --status active", + }, + { + description: "Replace the rule's conditions", + command: + 'sentry alert issues edit my-org/my-project/12345 --condition \'{"type":"first_seen_event","comparison":true,"conditionResult":true}\'', + }, + ], }, output: { human: formatEdited, diff --git a/packages/cli/src/commands/alert/issues/list.ts b/packages/cli/src/commands/alert/issues/list.ts index a7778109e..5ac18c872 100644 --- a/packages/cli/src/commands/alert/issues/list.ts +++ b/packages/cli/src/commands/alert/issues/list.ts @@ -536,6 +536,16 @@ export const listCommand = buildListCommand("alert issues", { `${targetPatternExplanation()}\n\n` + "In monorepos with multiple Sentry projects, shows alert rules from all detected projects.\n\n" + "Use --cursor / -c next / -c prev to paginate through larger result sets.", + examples: [ + { + description: "List issue alert rules for a project", + command: "sentry alert issues list my-org/my-project", + }, + { + description: "Filter rules by name", + command: 'sentry alert issues list my-org/my-project --query "spike"', + }, + ], }, output: { human: formatIssueAlertListHuman, diff --git a/packages/cli/src/commands/alert/issues/view.ts b/packages/cli/src/commands/alert/issues/view.ts index 0144e227f..140ccb24c 100644 --- a/packages/cli/src/commands/alert/issues/view.ts +++ b/packages/cli/src/commands/alert/issues/view.ts @@ -42,12 +42,22 @@ function formatIssueAlertView(data: IssueRuleResolution): string { export const viewCommand = buildCommand({ docs: { brief: "View an issue alert rule", - fullDescription: - "View a single issue alert rule by ID or name.\n\n" + - "Examples:\n" + - " sentry alert issues view 12345\n" + - " sentry alert issues view my-org/my-project/12345\n" + - " sentry alert issues view my-org/my-project/'Error Spike'", + fullDescription: "View a single issue alert rule by ID or name.", + examples: [ + { + description: + "View an issue alert rule by ID (organization and project auto-detected)", + command: "sentry alert issues view 12345", + }, + { + description: "View by ID in an explicit project", + command: "sentry alert issues view my-org/my-project/12345", + }, + { + description: "View by name", + command: "sentry alert issues view my-org/my-project/'Error Spike'", + }, + ], }, output: { human: formatIssueAlertView, diff --git a/packages/cli/src/commands/alert/metrics/create.ts b/packages/cli/src/commands/alert/metrics/create.ts index ee225ff0f..9516ba514 100644 --- a/packages/cli/src/commands/alert/metrics/create.ts +++ b/packages/cli/src/commands/alert/metrics/create.ts @@ -84,16 +84,20 @@ export const createCommand = buildCommand({ " thresholdType 0 alerts above the threshold (default), 1 below. Without resolveThreshold\n" + " the rule resolves at the critical threshold. Native detector conditions\n" + ' ({"type":"gt","comparison":N,"conditionResult":75}) are passed through as-is.\n' + - " Notifications are not part of triggers: pass --workflow with an existing alert id.\n\n" + - "Examples:\n" + - " sentry alert metrics create my-org/ --name 'P95 latency' \\\n" + - " --query 'environment:prod' --aggregate 'p95(span.duration)' \\\n" + - " --dataset spans --time-window 5 --project my-app \\\n" + - " --trigger '{\"alertThreshold\":500}'\n\n" + - " sentry alert metrics create my-org/ --name 'AI chat failures' \\\n" + - " --query 'action:ai.chat result:error' --aggregate 'count()' --dataset logs \\\n" + - ' --time-window 5 --trigger \'{"alertThreshold":0,"resolveThreshold":0}\' \\\n' + - " --project my-app --workflow 123 --dry-run", + " Notifications are not part of triggers: pass --workflow with an existing alert id.", + examples: [ + { + description: "Alert when P95 span duration goes above 500ms", + command: + "sentry alert metrics create my-org/ --name 'P95 latency' --project my-project --query 'environment:prod' --aggregate 'p95(span.duration)' --dataset spans --time-window 5 --trigger '{\"alertThreshold\":500}'", + }, + { + description: + "Preview an alert on any matching log line that notifies through an existing alert", + command: + "sentry alert metrics create my-org/ --name 'AI chat failures' --project my-project --query 'action:ai.chat result:error' --aggregate 'count()' --dataset logs --time-window 5 --trigger '{\"alertThreshold\":0,\"resolveThreshold\":0}' --workflow 12345 --dry-run", + }, + ], }, output: { human: formatCreated, diff --git a/packages/cli/src/commands/alert/metrics/delete.ts b/packages/cli/src/commands/alert/metrics/delete.ts index 3a97f0157..42b9b93ec 100644 --- a/packages/cli/src/commands/alert/metrics/delete.ts +++ b/packages/cli/src/commands/alert/metrics/delete.ts @@ -47,10 +47,17 @@ export const deleteCommand = buildDeleteCommand({ brief: "Delete a metric alert rule", fullDescription: "Permanently remove a metric alert rule from an organization. " + - "Type org/rule-id to confirm, or use --yes / --force, or --dry-run.\n\n" + - "Examples:\n" + - " sentry alert metrics delete my-org/12345\n" + - " sentry alert metrics delete my-org/'P95 alert' --yes", + "Type org/rule-id to confirm, or use --yes / --force, or --dry-run.", + examples: [ + { + description: "Delete a metric alert rule (prompts for confirmation)", + command: "sentry alert metrics delete my-org/12345", + }, + { + description: "Delete a rule selected by name without prompting", + command: "sentry alert metrics delete my-org/'P95 alert' --yes", + }, + ], }, output: { human: formatDeleted, diff --git a/packages/cli/src/commands/alert/metrics/edit.ts b/packages/cli/src/commands/alert/metrics/edit.ts index ea073dcce..798727707 100644 --- a/packages/cli/src/commands/alert/metrics/edit.ts +++ b/packages/cli/src/commands/alert/metrics/edit.ts @@ -177,11 +177,27 @@ export const editCommand = buildCommand({ brief: "Edit a metric alert rule", fullDescription: "Update a metric alert rule. Pass at least one of --name or --status. " + - "Status 'active' enables the rule; 'disabled' sets it to disabled (API status 1).\n\n" + - "Examples:\n" + - " sentry alert metrics edit my-org/9 --name 'Error budget'\n" + - " sentry alert metrics edit my-org/9 --status disabled\n" + - " sentry alert metrics edit my-org/9 --time-window 15 --dataset spans", + "Status 'active' enables the rule; 'disabled' sets it to disabled (API status 1).", + examples: [ + { + description: "Rename a metric alert rule", + command: "sentry alert metrics edit my-org/12345 --name 'Error budget'", + }, + { + description: "Disable a rule", + command: "sentry alert metrics edit my-org/12345 --status disabled", + }, + { + description: "Change the query and time window", + command: + 'sentry alert metrics edit my-org/12345 --query "environment:prod event.type:error" --time-window 15', + }, + { + description: "Switch the dataset", + command: + "sentry alert metrics edit my-org/12345 --time-window 15 --dataset spans", + }, + ], }, output: { human: formatEdited, diff --git a/packages/cli/src/commands/alert/metrics/list.ts b/packages/cli/src/commands/alert/metrics/list.ts index f5f01fe17..99ac2b3ba 100644 --- a/packages/cli/src/commands/alert/metrics/list.ts +++ b/packages/cli/src/commands/alert/metrics/list.ts @@ -535,6 +535,12 @@ export const listCommand = buildListCommand("alert metrics", { `${targetPatternExplanation()}\n\n` + "Metric alert rules are org-scoped; the project part is ignored when provided.\n\n" + "Use --cursor / -c next / -c prev to paginate through larger result sets.", + examples: [ + { + description: "List metric alert rules for an organization", + command: "sentry alert metrics list my-org/", + }, + ], }, output: { human: formatMetricAlertListHuman, diff --git a/packages/cli/src/commands/alert/metrics/view.ts b/packages/cli/src/commands/alert/metrics/view.ts index 977295d96..1c5fa1863 100644 --- a/packages/cli/src/commands/alert/metrics/view.ts +++ b/packages/cli/src/commands/alert/metrics/view.ts @@ -44,12 +44,22 @@ function formatMetricAlertView(data: MetricRuleResolution): string { export const viewCommand = buildCommand({ docs: { brief: "View a metric alert rule", - fullDescription: - "View a single metric alert rule by ID or name.\n\n" + - "Examples:\n" + - " sentry alert metrics view 12345\n" + - " sentry alert metrics view my-org/12345\n" + - " sentry alert metrics view my-org/'p95 latency alert'", + fullDescription: "View a single metric alert rule by ID or name.", + examples: [ + { + description: + "View a metric alert rule by ID (organization auto-detected)", + command: "sentry alert metrics view 12345", + }, + { + description: "View by ID in an explicit organization", + command: "sentry alert metrics view my-org/12345", + }, + { + description: "View by name", + command: "sentry alert metrics view my-org/'P95 latency alert'", + }, + ], }, output: { human: formatMetricAlertView, diff --git a/packages/cli/src/commands/api.ts b/packages/cli/src/commands/api.ts index 5c6bb6d31..b00846361 100644 --- a/packages/cli/src/commands/api.ts +++ b/packages/cli/src/commands/api.ts @@ -1537,13 +1537,68 @@ export const apiCommand = buildCommand({ " key[sub]=value Nested object: {key: {sub: value}}\n" + " key[]=value Array append: {key: [value]}\n" + " key[] Empty array: {key: []}\n\n" + - "Use --raw-field/-f to send values as strings without JSON parsing.\n\n" + - "Examples:\n" + - " sentry api organizations/\n" + - " sentry api issues/123/ -X PUT -F status=resolved\n" + - ' sentry api issues/123/ -X PUT -d \'{"status":"resolved"}\'\n' + - " sentry api projects/my-org/my-project/ -F options[sampleRate]=0.5\n" + - " sentry api teams/my-org/my-team/members/ -F user[email]=user@example.com", + "Use --raw-field/-f to send values as strings without JSON parsing.", + examples: [ + { + description: "List organizations", + command: "sentry api organizations/", + }, + { + description: "Get a specific issue", + command: "sentry api issues/123456789/", + }, + { + description: "Create a release", + command: + "sentry api organizations/my-org/releases/ -X POST -F version=1.0.0", + }, + { + description: "Update an issue status", + command: "sentry api issues/123456789/ -X PUT -F status=resolved", + }, + { + description: "Send an inline JSON body", + command: + 'sentry api issues/123456789/ -X PUT -d \'{"status":"resolved"}\'', + }, + { + description: "Set a nested field", + command: + "sentry api projects/my-org/my-project/ -X PUT -F options[sampleRate]=0.5", + }, + { + description: "Assign an issue", + command: + 'sentry api issues/123456789/ -X PUT --field assignedTo="user@example.com"', + }, + { + description: "Delete a project", + command: "sentry api projects/my-org/my-project/ -X DELETE", + }, + { + description: "Add custom headers", + command: 'sentry api organizations/ -H "X-Custom: value"', + }, + { + description: "Read the request body from a file", + command: + "sentry api projects/my-org/my-project/releases/ -X POST --input release.json", + }, + { + description: "Show the full HTTP request and response", + command: "sentry api organizations/ --verbose", + }, + { + description: "Preview the request without sending it", + command: "sentry api organizations/ --dry-run", + }, + { + description: + "Save a binary response, such as an event attachment, to a file", + command: + 'sentry api "https://sentry.io/api/0/projects/my-org/my-project/events/EVENT_ID/attachments/ATTACHMENT_ID/?download=1" > screenshot.png', + }, + ], }, parameters: { positional: { diff --git a/packages/cli/src/commands/auth/list.ts b/packages/cli/src/commands/auth/list.ts index d2b018fd1..2ef0a91ab 100644 --- a/packages/cli/src/commands/auth/list.ts +++ b/packages/cli/src/commands/auth/list.ts @@ -32,6 +32,12 @@ export const listCommand = buildCommand({ "(an organization auth token's own URL, or sentry.io), with the user\n" + "it belongs to when the server says. It is never stored and can't be\n" + "switched to: commands targeting an organization it can access use it.", + examples: [ + { + description: "Show stored accounts (* marks the active one)", + command: "sentry auth list", + }, + ], }, output: { human: formatAccountList, diff --git a/packages/cli/src/commands/auth/login.ts b/packages/cli/src/commands/auth/login.ts index 56299e96c..3e106e24f 100644 --- a/packages/cli/src/commands/auth/login.ts +++ b/packages/cli/src/commands/auth/login.ts @@ -541,12 +541,48 @@ export const loginCommand = buildCommand({ "are kept). Pass an email (or :, as 'sentry org list'\n" + "shows it) to add or log in again to that account without prompting:\n" + "Sentry approves the request as whoever is signed in to the browser,\n" + - "so a login approved as another user is refused and nothing is saved.\n\n" + - "Examples:\n" + - " sentry auth login\n" + - " sentry auth login jane@acme.com\n" + - " sentry auth login jane@acme.com --url https://sentry.acme.com\n" + - " sentry auth login jane@acme.com:sentry.acme.com", + "so a login approved as another user is refused and nothing is saved.", + examples: [ + { + description: "Log in with OAuth (device flow)", + command: "sentry auth login", + }, + { + description: "Log in with an API token", + command: "sentry auth login --token YOUR_SENTRY_API_TOKEN", + }, + { + description: "Request only read-only scopes", + command: "sentry auth login --read-only", + }, + { + description: "Request specific scopes (repeatable or comma-separated)", + command: "sentry auth login --scope project:read --scope org:read", + }, + { + description: "Log in to a self-hosted instance", + command: "sentry auth login --url https://sentry.example.com", + }, + { + description: "Log in to a self-hosted instance with a token", + command: + "sentry auth login --token YOUR_TOKEN --url https://sentry.example.com", + }, + { + description: + "Add (or log in again to) a specific account without prompting", + command: "sentry auth login jane@example.com", + }, + { + description: "Add an account on a specific server", + command: + "sentry auth login jane@example.com --url https://sentry.example.com", + }, + { + description: "Same as --url, using the account notation", + command: "sentry auth login jane@example.com:sentry.example.com", + }, + ], }, parameters: { flags: { diff --git a/packages/cli/src/commands/auth/logout.ts b/packages/cli/src/commands/auth/logout.ts index afb27f0df..6d271f081 100644 --- a/packages/cli/src/commands/auth/logout.ts +++ b/packages/cli/src/commands/auth/logout.ts @@ -91,12 +91,32 @@ export const logoutCommand = buildCommand({ "accounts (email, username, user ID, or account ID; space- or\n" + "comma-separated) to remove those instead, or 'all' to remove every\n" + "stored account. When the same email is stored for several servers, add\n" + - "--url to pick the one on that server.\n\n" + - "Examples:\n" + - " sentry auth logout\n" + - " sentry auth logout jane@acme.com,jane@personal.dev\n" + - " sentry auth logout jane@acme.com --url https://sentry.acme.com\n" + - " sentry auth logout all", + "--url to pick the one on that server.", + examples: [ + { + description: + "Log out of the active account (the most recently used other account becomes active)", + command: "sentry auth logout", + }, + { + description: "Log out of a specific account", + command: "sentry auth logout jane@example.com", + }, + { + description: "Log out of several accounts (space- or comma-separated)", + command: "sentry auth logout jane@example.com,jane@personal.dev", + }, + { + description: + "Pick the account on one server when the same email is stored twice", + command: + "sentry auth logout jane@example.com --url https://sentry.example.com", + }, + { + description: "Log out of every stored account", + command: "sentry auth logout all", + }, + ], }, output: { human: formatLogoutResult }, parameters: { diff --git a/packages/cli/src/commands/auth/refresh.ts b/packages/cli/src/commands/auth/refresh.ts index 62c2d80e3..8eae3422c 100644 --- a/packages/cli/src/commands/auth/refresh.ts +++ b/packages/cli/src/commands/auth/refresh.ts @@ -99,23 +99,30 @@ When --scope or --read-only is passed, re-authenticates via the OAuth device flow with the requested scopes instead of refreshing the existing token. This is the preferred way to add or change scopes on an existing session (similar to \`gh auth refresh -s \`). - -Examples: - $ sentry auth refresh - ✓ Access token refreshed successfully. Access token valid for 59 minutes. - - $ sentry auth refresh --force - ✓ Access token refreshed successfully. Access token valid for 1 hour. - - $ sentry auth refresh --scope event:read --scope org:read - Re-authenticating with scopes: event:read, org:read... - - $ sentry auth refresh --read-only - Re-authenticating with read-only scopes... - - $ sentry auth refresh --json - {"success":true,"refreshed":true,"expiresIn":3600,"expiresAt":"..."} - `.trim(), +`.trim(), + examples: [ + { + description: + "Refresh the OAuth access token when it is close to expiring", + command: "sentry auth refresh", + }, + { + description: "Refresh even if the token is still valid", + command: "sentry auth refresh --force", + }, + { + description: "Re-authenticate with specific scopes", + command: "sentry auth refresh --scope project:read --scope org:read", + }, + { + description: "Re-authenticate with read-only scopes", + command: "sentry auth refresh --read-only", + }, + { + description: "Output the refresh result as JSON", + command: "sentry auth refresh --json", + }, + ], }, output: { human: formatRefreshResult }, parameters: { diff --git a/packages/cli/src/commands/auth/status.ts b/packages/cli/src/commands/auth/status.ts index cea9a17c5..a714a6ca8 100644 --- a/packages/cli/src/commands/auth/status.ts +++ b/packages/cli/src/commands/auth/status.ts @@ -200,6 +200,16 @@ export const statusCommand = buildCommand({ fullDescription: "Display information about your current authentication status, " + "including whether you're logged in and your default organization/project settings.", + examples: [ + { + description: "Check authentication status", + command: "sentry auth status", + }, + { + description: "Include the raw token", + command: "sentry auth status --show-token", + }, + ], }, output: { human: formatAuthStatus }, parameters: { diff --git a/packages/cli/src/commands/auth/switch.ts b/packages/cli/src/commands/auth/switch.ts index ef69f6a81..c38c1894a 100644 --- a/packages/cli/src/commands/auth/switch.ts +++ b/packages/cli/src/commands/auth/switch.ts @@ -81,11 +81,23 @@ export const switchCommand = buildCommand({ "'jane@acme.com') is used with a warning when it is the only one. When\n" + "the same user is stored on several servers, add --url (or use\n" + "'@'). Without an argument, pick from a\n" + - "searchable list interactively.\n\n" + - "Examples:\n" + - " sentry auth switch\n" + - " sentry auth switch jane@acme.com\n" + - " sentry auth switch jane@acme.com --url https://sentry.acme.com", + "searchable list interactively.", + examples: [ + { + description: "Pick the active account from a searchable list", + command: "sentry auth switch", + }, + { + description: "Switch to a specific account", + command: "sentry auth switch jane@example.com", + }, + { + description: + "Pick the account on one server when the same email is stored twice", + command: + "sentry auth switch jane@example.com --url https://sentry.example.com", + }, + ], }, output: { human: formatAccountSwitch }, parameters: { diff --git a/packages/cli/src/commands/auth/token.ts b/packages/cli/src/commands/auth/token.ts index c9c89b3b1..5217e75e7 100644 --- a/packages/cli/src/commands/auth/token.ts +++ b/packages/cli/src/commands/auth/token.ts @@ -18,6 +18,12 @@ export const tokenCommand = buildCommand({ "Print the stored authentication token to stdout.\n\n" + "This outputs the raw token without any formatting, making it suitable for " + "piping to other commands or scripts.", + examples: [ + { + description: "Print the stored auth token", + command: "sentry auth token", + }, + ], }, parameters: {}, output: { human: (token: string) => token }, diff --git a/packages/cli/src/commands/auth/whoami.ts b/packages/cli/src/commands/auth/whoami.ts index 267850ab0..b16584884 100644 --- a/packages/cli/src/commands/auth/whoami.ts +++ b/packages/cli/src/commands/auth/whoami.ts @@ -58,6 +58,9 @@ export const whoamiCommand = buildCommand({ "For user-scoped tokens (OAuth, personal access tokens), this fetches " + "the user from the Sentry API. For organization auth tokens (`sntrys_`), " + "it shows which organization the token belongs to.", + examples: [ + { description: "Show the current user", command: "sentry auth whoami" }, + ], }, output: { human: formatWhoami, diff --git a/packages/cli/src/commands/build/download.ts b/packages/cli/src/commands/build/download.ts index b69b8ff39..df827141e 100644 --- a/packages/cli/src/commands/build/download.ts +++ b/packages/cli/src/commands/build/download.ts @@ -59,6 +59,20 @@ export const downloadCommand = buildCommand({ "Usage:\n" + " sentry build download 1234567890\n" + " sentry build download 1234567890 --output ./app.ipa", + examples: [ + { + description: "Download a build artifact by ID", + command: "sentry build download 1234567890", + }, + { + description: "Download to a specific path", + command: "sentry build download 1234567890 --output ./app.ipa", + }, + { + description: "Output the result as JSON", + command: "sentry build download 1234567890 --json", + }, + ], }, output: { human: formatDownloadResult, diff --git a/packages/cli/src/commands/cli/completion.ts b/packages/cli/src/commands/cli/completion.ts index 1198594e9..9f5684f8d 100644 --- a/packages/cli/src/commands/cli/completion.ts +++ b/packages/cli/src/commands/cli/completion.ts @@ -26,10 +26,28 @@ export const completionCommand = buildCommand({ fullDescription: "Print the shell completion script for the given shell to stdout.\n\n" + "Supported shells: bash, zsh, fish.\n" + - "When no shell is given, it is detected from the $SHELL environment variable.\n\n" + - "Examples:\n" + - " sentry cli completion zsh > ~/.local/share/zsh/site-functions/_sentry\n" + - ' eval "$(sentry cli completion bash)"', + "When no shell is given, it is detected from the $SHELL environment variable.", + examples: [ + { + description: + "Print completions for your current shell (auto-detected from $SHELL)", + command: "sentry cli completion", + }, + { + description: "Install zsh completions", + command: + "sentry cli completion zsh > ~/.local/share/zsh/site-functions/_sentry", + }, + { + description: "Load bash completions into the current shell", + command: 'eval "$(sentry cli completion bash)"', + }, + { + description: "Install fish completions", + command: + "sentry cli completion fish > ~/.config/fish/completions/sentry.fish", + }, + ], }, output: { human: (script: string) => script, diff --git a/packages/cli/src/commands/cli/defaults.ts b/packages/cli/src/commands/cli/defaults.ts index acffce630..7e90c57d6 100644 --- a/packages/cli/src/commands/cli/defaults.ts +++ b/packages/cli/src/commands/cli/defaults.ts @@ -248,22 +248,6 @@ export const defaultsCommand = buildCommand({ "View and manage persistent CLI default settings.\n\n" + "With no arguments, shows all current defaults. Pass a key and value\n" + "to set a default, or use `--clear` to remove defaults.\n\n" + - "## Examples\n\n" + - "```\n" + - "sentry cli defaults # Show all defaults\n" + - "sentry cli defaults list # Same as above (alias: ls, show)\n" + - "sentry cli defaults org my-org # Set default organization\n" + - "sentry cli defaults project my-proj # Set default project\n" + - "sentry cli defaults telemetry off # Disable telemetry\n" + - "sentry cli defaults agent-skills off # Stop installing agent skills on upgrade\n" + - "sentry cli defaults graphics off # Disable inline terminal images\n" + - "sentry cli defaults tips off # Hide Tip: hints in command output\n" + - "sentry cli defaults url https://... # Set Sentry URL (self-hosted)\n" + - "sentry cli defaults headers 'X-IAP: t' # Set custom headers (self-hosted)\n" + - "sentry cli defaults ca-cert /path/to/ca.pem # Trust a custom CA certificate\n" + - "sentry cli defaults org --clear # Clear a specific default\n" + - "sentry cli defaults --clear --yes # Clear all defaults\n" + - "```\n\n" + "## Recognized keys\n\n" + "| Key | Description |\n" + "|-----|------------|\n" + @@ -276,6 +260,62 @@ export const defaultsCommand = buildCommand({ "| `url` | Sentry instance URL (for self-hosted installations) |\n" + "| `headers` | Custom HTTP headers for self-hosted proxies (semicolon-separated `Name: Value`) |\n" + "| `ca-cert` | Path to PEM file with custom CA certificates (for corporate proxies) |", + examples: [ + { + description: "Show all current defaults", + command: "sentry cli defaults", + }, + { + description: "Same as above (aliases: ls, show)", + command: "sentry cli defaults list", + }, + { + description: "Set the default organization", + command: "sentry cli defaults org my-org", + }, + { + description: "Set the default project", + command: "sentry cli defaults project my-project", + }, + { + description: "Set the default Sentry URL (self-hosted)", + command: "sentry cli defaults url https://sentry.example.com", + }, + { + description: + "Set custom HTTP headers (self-hosted, e.g. for IAP/proxies)", + command: 'sentry cli defaults headers "X-IAP: token"', + }, + { + description: + "Set a custom CA certificate (self-hosted, behind a TLS proxy)", + command: "sentry cli defaults ca-cert /path/to/ca.pem", + }, + { + description: "Disable telemetry", + command: "sentry cli defaults telemetry off", + }, + { + description: "Stop installing agent skills on upgrade", + command: "sentry cli defaults agent-skills off", + }, + { + description: "Disable inline terminal images", + command: "sentry cli defaults graphics off", + }, + { + description: "Hide Tip: hints in command output", + command: "sentry cli defaults tips off", + }, + { + description: "Clear a single default", + command: "sentry cli defaults org --clear", + }, + { + description: "Clear all defaults without prompting", + command: "sentry cli defaults --clear --yes", + }, + ], }, output: { human: formatDefaultsResult, diff --git a/packages/cli/src/commands/cli/feedback.ts b/packages/cli/src/commands/cli/feedback.ts index d8a9e5de9..2d73780a2 100644 --- a/packages/cli/src/commands/cli/feedback.ts +++ b/packages/cli/src/commands/cli/feedback.ts @@ -33,6 +33,16 @@ export const feedbackCommand = buildCommand({ fullDescription: "Submit feedback about your experience with the Sentry CLI. " + "All text after 'feedback' is sent as your message.", + examples: [ + { + description: "Send positive feedback", + command: "sentry cli feedback i love this tool", + }, + { + description: "Report an issue", + command: "sentry cli feedback the issue view is confusing", + }, + ], }, output: { human: formatFeedbackResult }, parameters: { diff --git a/packages/cli/src/commands/cli/fix.ts b/packages/cli/src/commands/cli/fix.ts index e069fe4df..07de427bd 100644 --- a/packages/cli/src/commands/cli/fix.ts +++ b/packages/cli/src/commands/cli/fix.ts @@ -669,11 +669,15 @@ export const fixCommand = buildCommand({ "deletes data.\n\n" + "If files are owned by root (e.g. after `sudo brew install`), run with sudo\n" + "to transfer ownership back to the current user:\n\n" + - " sudo sentry cli fix\n\n" + - "Examples:\n" + - " sentry cli fix # Fix database issues\n" + - " sudo sentry cli fix # Fix root-owned files\n" + - " sentry cli fix --dry-run # Show what would be fixed without making changes", + " sudo sentry cli fix", + examples: [ + { description: "Fix database issues", command: "sentry cli fix" }, + { description: "Fix root-owned files", command: "sudo sentry cli fix" }, + { + description: "Show what would be fixed without making changes", + command: "sentry cli fix --dry-run", + }, + ], }, output: { human: formatFixResult }, parameters: { diff --git a/packages/cli/src/commands/cli/import.ts b/packages/cli/src/commands/cli/import.ts index 6518e9b67..2d22537f3 100644 --- a/packages/cli/src/commands/cli/import.ts +++ b/packages/cli/src/commands/cli/import.ts @@ -271,12 +271,29 @@ export const importCommand = buildCommand({ " - Organization -> default organization\n" + " - Project -> default project\n\n" + "Security: token and URL must come from the same file to be trusted.\n" + - "Cross-file URL requires explicit --url confirmation.\n\n" + - "Examples:\n" + - " sentry cli import # Scan and import interactively\n" + - " sentry cli import --yes # Auto-confirm (CI-safe)\n" + - " sentry cli import --dry-run # Preview without changes\n" + - " sentry cli import --url # Trust a specific URL", + "Cross-file URL requires explicit --url confirmation.", + examples: [ + { + description: "Scan for .sentryclirc files and import interactively", + command: "sentry cli import", + }, + { + description: "Preview what would be imported", + command: "sentry cli import --dry-run", + }, + { + description: "Skip the confirmation prompt (CI-safe)", + command: "sentry cli import --yes", + }, + { + description: "Explicitly trust a self-hosted URL", + command: "sentry cli import --url https://sentry.example.com", + }, + { + description: "Skip API validation of the imported token", + command: "sentry cli import --skip-validation", + }, + ], }, parameters: { flags: { diff --git a/packages/cli/src/commands/cli/setup.ts b/packages/cli/src/commands/cli/setup.ts index 5c7bd8d89..ca334b96a 100644 --- a/packages/cli/src/commands/cli/setup.ts +++ b/packages/cli/src/commands/cli/setup.ts @@ -628,14 +628,33 @@ export const setupCommand = buildCommand({ "With --install, also handles binary placement from a temporary\n" + "download location (used by the install script and upgrade command).\n\n" + "This command is called automatically by the install script,\n" + - "but can also be run manually after downloading the binary.\n\n" + - "Examples:\n" + - " sentry cli setup # Auto-detect and configure\n" + - " sentry cli setup --method curl # Record install method\n" + - " sentry cli setup --install # Place binary and configure\n" + - " sentry cli setup --no-modify-path # Skip PATH modification\n" + - " sentry cli setup --no-completions # Skip shell completions\n" + - " sentry cli setup --no-agent-skills # Skip agent skill installation", + "but can also be run manually after downloading the binary.", + examples: [ + { + description: "Run full setup (PATH, completions, agent skills)", + command: "sentry cli setup", + }, + { + description: "Record the install method", + command: "sentry cli setup --method curl", + }, + { + description: "Place the binary and configure the shell", + command: "sentry cli setup --install", + }, + { + description: "Skip PATH modification", + command: "sentry cli setup --no-modify-path", + }, + { + description: "Skip shell completions", + command: "sentry cli setup --no-completions", + }, + { + description: "Skip agent skill installation", + command: "sentry cli setup --no-agent-skills", + }, + ], }, parameters: { flags: { diff --git a/packages/cli/src/commands/cli/uninstall.ts b/packages/cli/src/commands/cli/uninstall.ts index ed6bfe27a..cba15b5ff 100644 --- a/packages/cli/src/commands/cli/uninstall.ts +++ b/packages/cli/src/commands/cli/uninstall.ts @@ -430,6 +430,20 @@ export const uninstallCommand = buildDeleteCommand({ "Remove the Sentry CLI binary, shell completions, PATH entries, " + "agent skill files, and configuration directory. Reverses the " + "changes made by `sentry cli setup`.", + examples: [ + { + description: "Show what would be removed", + command: "sentry cli uninstall --dry-run", + }, + { + description: "Uninstall, keeping the config directory", + command: "sentry cli uninstall --yes --keep-config", + }, + { + description: "Full uninstall with confirmation", + command: "sentry cli uninstall", + }, + ], }, output: { human: formatUninstallHuman, diff --git a/packages/cli/src/commands/cli/upgrade.ts b/packages/cli/src/commands/cli/upgrade.ts index 1bea6ee0c..ee84b5c33 100644 --- a/packages/cli/src/commands/cli/upgrade.ts +++ b/packages/cli/src/commands/cli/upgrade.ts @@ -944,17 +944,45 @@ export const upgradeCommand = buildCommand({ " stable (default) Latest stable release\n" + " nightly Built from main, updated on every commit\n\n" + "The channel is persisted so that subsequent bare `sentry cli upgrade` calls\n" + - "use the same channel.\n\n" + - "Examples:\n" + - " sentry cli upgrade # Update to latest (using persisted channel)\n" + - " sentry cli upgrade nightly # Switch to nightly channel and update\n" + - " sentry cli upgrade stable # Switch back to stable channel and update\n" + - " sentry cli upgrade 0.5.0 # Install a specific stable version\n" + - " sentry cli upgrade --check # Check for updates without installing\n" + - " sentry cli upgrade --force # Force re-download even if up to date\n" + - " sentry cli upgrade --method npm # Force using npm to upgrade\n" + - " sentry cli upgrade --offline # Upgrade from cached patches (no network)\n" + - " sentry cli upgrade --no-agent-skills # Skip reinstalling agent skills", + "use the same channel.", + examples: [ + { + description: "Update to the latest version on the persisted channel", + command: "sentry cli upgrade", + }, + { + description: "Check for updates without installing", + command: "sentry cli upgrade --check", + }, + { + description: "Switch to the nightly channel and update", + command: "sentry cli upgrade nightly", + }, + { + description: "Switch back to the stable channel and update", + command: "sentry cli upgrade stable", + }, + { + description: "Install a specific stable version", + command: "sentry cli upgrade 0.5.0", + }, + { + description: "Force re-download even if up to date", + command: "sentry cli upgrade --force", + }, + { + description: "Force using npm to upgrade", + command: "sentry cli upgrade --method npm", + }, + { + description: "Upgrade from cached patches (no network)", + command: "sentry cli upgrade --offline", + }, + { + description: "Skip reinstalling agent skills", + command: "sentry cli upgrade --no-agent-skills", + }, + ], }, output: { human: formatUpgradeResult }, parameters: { diff --git a/packages/cli/src/commands/code-mappings/upload.ts b/packages/cli/src/commands/code-mappings/upload.ts index 1df1bcc7e..0face558c 100644 --- a/packages/cli/src/commands/code-mappings/upload.ts +++ b/packages/cli/src/commands/code-mappings/upload.ts @@ -180,6 +180,25 @@ export const uploadCommand = buildCommand({ " sentry code-mappings upload mappings.json --repo owner/repo --default-branch develop\n" + " sentry code-mappings upload mappings.json --json\n\n" + "Requires an Organization Token with `org:ci` scope.", + examples: [ + { + description: "Upload code mappings from a JSON file", + command: "sentry code-mappings upload mappings.json", + }, + { + description: "Specify the repository explicitly", + command: "sentry code-mappings upload mappings.json --repo owner/repo", + }, + { + description: "Specify the repository and default branch", + command: + "sentry code-mappings upload mappings.json --repo owner/repo --default-branch develop", + }, + { + description: "Output as JSON", + command: "sentry code-mappings upload mappings.json --json", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/dart-symbol-map/upload.ts b/packages/cli/src/commands/dart-symbol-map/upload.ts index c86ad33dc..c09ed485c 100644 --- a/packages/cli/src/commands/dart-symbol-map/upload.ts +++ b/packages/cli/src/commands/dart-symbol-map/upload.ts @@ -172,6 +172,23 @@ export const uploadCommand = buildCommand({ " sentry dart-symbol-map upload --debug-id mapping.json --no-upload\n" + " sentry dart-symbol-map upload --debug-id mapping.json --json\n\n" + "Supported on Sentry SaaS and self-hosted >= 25.8.0.", + examples: [ + { + description: "Upload a Dart symbol map with a debug ID", + command: + "sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json", + }, + { + description: "Validate without uploading", + command: + "sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json --no-upload", + }, + { + description: "Output as JSON", + command: + "sentry dart-symbol-map upload --debug-id 12345678-1234-1234-1234-123456789abc mapping.json --json", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/dashboard/create.ts b/packages/cli/src/commands/dashboard/create.ts index bba1f915b..6fa32d468 100644 --- a/packages/cli/src/commands/dashboard/create.ts +++ b/packages/cli/src/commands/dashboard/create.ts @@ -143,12 +143,22 @@ export const createCommand = buildCommand({ brief: "Create a dashboard", fullDescription: "Create a new Sentry dashboard.\n\n" + - "Examples:\n" + - " sentry dashboard create 'My Dashboard'\n" + - " sentry dashboard create my-org/ 'My Dashboard'\n" + - " sentry dashboard create my-org/my-project 'My Dashboard'\n\n" + "Add widgets after creation with:\n" + ' sentry dashboard widget add "My Widget" --display line --query count', + examples: [ + { + description: "Create a dashboard (organization auto-detected)", + command: "sentry dashboard create 'Frontend Performance'", + }, + { + description: "Create a dashboard in an explicit organization", + command: "sentry dashboard create my-org/ 'My Dashboard'", + }, + { + description: "Use the organization of an explicit project", + command: "sentry dashboard create my-org/my-project 'My Dashboard'", + }, + ], }, output: { human: formatDashboardCreated, diff --git a/packages/cli/src/commands/dashboard/list.ts b/packages/cli/src/commands/dashboard/list.ts index 6dfd52213..f2f69078f 100644 --- a/packages/cli/src/commands/dashboard/list.ts +++ b/packages/cli/src/commands/dashboard/list.ts @@ -370,18 +370,45 @@ export const listCommand = buildListCommand("dashboard", { fullDescription: "List dashboards in a Sentry organization.\n\n" + "The optional name argument supports glob patterns for filtering by title.\n" + - "Glob matching is case-insensitive. Quote patterns to prevent shell expansion.\n\n" + - "Examples:\n" + - " sentry dashboard list # auto-detect org\n" + - " sentry dashboard list my-org/ # explicit org\n" + - " sentry dashboard list my-org/my-project # org from explicit project\n" + - " sentry dashboard list 'Error*' # filter by title glob\n" + - " sentry dashboard list my-org '*API*' # bare org + filter\n" + - " sentry dashboard list my-org/ '*API*' # org/ + filter\n" + - " sentry dashboard list -c next # next page\n" + - " sentry dashboard list -c prev # previous page\n" + - " sentry dashboard list --json # JSON with pagination envelope\n" + - " sentry dashboard list --web", + "Glob matching is case-insensitive. Quote patterns to prevent shell expansion.", + examples: [ + { + description: "List dashboards (organization auto-detected)", + command: "sentry dashboard list", + }, + { + description: "List dashboards in an explicit organization", + command: "sentry dashboard list my-org/", + }, + { + description: "Use the organization of an explicit project", + command: "sentry dashboard list my-org/my-project", + }, + { + description: "Filter by title glob", + command: "sentry dashboard list 'Backend*'", + }, + { + description: "Filter within an organization", + command: "sentry dashboard list my-org/ '*API*'", + }, + { + description: "Fetch the next page", + command: "sentry dashboard list -c next", + }, + { + description: "Fetch the previous page", + command: "sentry dashboard list -c prev", + }, + { + description: "Output JSON with the pagination envelope", + command: "sentry dashboard list --json", + }, + { + description: "Open the dashboard list in the browser", + command: "sentry dashboard list -w", + }, + ], }, output: { human: formatDashboardListHuman, diff --git a/packages/cli/src/commands/dashboard/restore.ts b/packages/cli/src/commands/dashboard/restore.ts index 8bd9d5345..0e4eaa340 100644 --- a/packages/cli/src/commands/dashboard/restore.ts +++ b/packages/cli/src/commands/dashboard/restore.ts @@ -58,12 +58,25 @@ export const restoreCommand = buildCommand({ brief: "Restore a dashboard revision", fullDescription: "Restore a Sentry dashboard to a previous revision.\n\n" + - "Use `sentry dashboard revisions` to list available revisions first.\n\n" + - "Examples:\n" + - " sentry dashboard restore 12345 --revision 42\n" + - " sentry dashboard restore my-org 12345 --revision 42\n" + - " sentry dashboard restore 'My Dashboard' --revision 42\n" + - " sentry dashboard restore 12345 --revision 42 --json", + "Use `sentry dashboard revisions` to list available revisions first.", + examples: [ + { + description: "Restore by dashboard title and revision number", + command: "sentry dashboard restore 'Frontend Performance' --revision 3", + }, + { + description: "Restore by dashboard ID", + command: "sentry dashboard restore 12345 --revision 42", + }, + { + description: "Pass the organization explicitly", + command: "sentry dashboard restore my-org 12345 --revision 42", + }, + { + description: "Output the restored dashboard as JSON", + command: "sentry dashboard restore 12345 --revision 42 --json", + }, + ], }, output: { human: formatRestoreHuman, diff --git a/packages/cli/src/commands/dashboard/revisions.ts b/packages/cli/src/commands/dashboard/revisions.ts index 7cc551bac..35bfa9cb2 100644 --- a/packages/cli/src/commands/dashboard/revisions.ts +++ b/packages/cli/src/commands/dashboard/revisions.ts @@ -119,13 +119,29 @@ export const revisionsCommand = buildCommand({ fullDescription: "List revision history for a Sentry dashboard.\n\n" + "Shows saved revisions with their IDs, titles, authors, and timestamps.\n" + - "Use `sentry dashboard restore` to revert to a previous revision.\n\n" + - "Examples:\n" + - " sentry dashboard revisions 12345\n" + - " sentry dashboard revisions 'My Dashboard'\n" + - " sentry dashboard revisions my-org 12345\n" + - " sentry dashboard revisions my-org 12345 --json\n" + - " sentry dashboard revisions my-org 12345 -c next", + "Use `sentry dashboard restore` to revert to a previous revision.", + examples: [ + { + description: "List revisions by dashboard title", + command: "sentry dashboard revisions 'Frontend Performance'", + }, + { + description: "List revisions by dashboard ID", + command: "sentry dashboard revisions 12345", + }, + { + description: "Pass the organization explicitly", + command: "sentry dashboard revisions my-org 12345", + }, + { + description: "Fetch the next page", + command: "sentry dashboard revisions my-org 12345 -c next", + }, + { + description: "Output as JSON", + command: "sentry dashboard revisions my-org 12345 --json", + }, + ], }, output: { human: formatRevisionsHuman, diff --git a/packages/cli/src/commands/dashboard/view.ts b/packages/cli/src/commands/dashboard/view.ts index 36b53b633..08a70c3a8 100644 --- a/packages/cli/src/commands/dashboard/view.ts +++ b/packages/cli/src/commands/dashboard/view.ts @@ -168,19 +168,50 @@ export const viewCommand = buildCommand({ "View a Sentry dashboard with rendered widget data.\n\n" + "Fetches actual data for each widget and displays sparkline charts,\n" + "tables, and big numbers in the terminal.\n\n" + - "The dashboard can be specified by numeric ID or title.\n\n" + - "Examples:\n" + - " sentry dashboard view 12345\n" + - " sentry dashboard view 'My Dashboard'\n" + - " sentry dashboard view my-org 12345\n" + - " sentry dashboard view my-org 'My Dashboard'\n" + - " sentry dashboard view my-org/my-project 12345\n" + - " sentry dashboard view 12345 --json\n" + - " sentry dashboard view 12345 --period 7d\n" + - " sentry dashboard view 12345 --renderer sixel\n" + - " sentry dashboard view 12345 -r\n" + - " sentry dashboard view 12345 -r 30\n" + - " sentry dashboard view 12345 --web", + "The dashboard can be specified by numeric ID or title.", + examples: [ + { + description: "View a dashboard by title", + command: "sentry dashboard view 'Frontend Performance'", + }, + { + description: "View a dashboard by ID", + command: "sentry dashboard view 12345", + }, + { + description: "View by ID in an explicit organization", + command: "sentry dashboard view my-org/12345", + }, + { + description: "Include project context in the same argument", + command: "sentry dashboard view my-org/my-project/12345", + }, + { + description: + "Pass the organization separately, e.g. for titles that contain a slash", + command: 'sentry dashboard view my-org/ "incidents/2026"', + }, + { + description: "Override the time period", + command: "sentry dashboard view 12345 --period 7d", + }, + { + description: "Render charts with sixel graphics", + command: "sentry dashboard view 12345 --renderer sixel", + }, + { + description: "Auto-refresh every 30 seconds", + command: "sentry dashboard view 'Backend Performance' --refresh 30", + }, + { + description: "Output as JSON", + command: "sentry dashboard view 12345 --json", + }, + { + description: "Open in the browser", + command: "sentry dashboard view 12345 -w", + }, + ], }, output: { human: createDashboardViewRenderer, diff --git a/packages/cli/src/commands/dashboard/widget/add.ts b/packages/cli/src/commands/dashboard/widget/add.ts index 6d75dddee..72ac87233 100644 --- a/packages/cli/src/commands/dashboard/widget/add.ts +++ b/packages/cli/src/commands/dashboard/widget/add.ts @@ -82,14 +82,6 @@ export const addCommand = buildCommand({ fullDescription: "Add a widget to an existing Sentry dashboard.\n\n" + "The dashboard can be specified by numeric ID or title.\n\n" + - "Examples:\n" + - " sentry dashboard widget add 'My Dashboard' \"Error Count\" \\\n" + - " --display big_number --query count\n\n" + - " sentry dashboard widget add 'My Dashboard' \"Errors by Browser\" \\\n" + - " --display line --query count --group-by browser.name\n\n" + - " sentry dashboard widget add 'My Dashboard' \"Top Endpoints\" \\\n" + - " --display table --query count --query p95:span.duration \\\n" + - " --group-by transaction --sort -count --limit 10\n\n" + "Query shorthand (--query flag):\n" + " count → count() (bare name = no-arg aggregate)\n" + " p95:span.duration → p95(span.duration) (colon = function with arg)\n" + @@ -99,6 +91,33 @@ export const addCommand = buildCommand({ " -count → -count() (descending)\n\n" + "Layout flags (--col/-x, --row/-y, --width, --height) control widget position\n" + "and size in the 6-column dashboard grid. Omitted values use auto-layout.", + examples: [ + { + description: "Add a counter widget", + command: + "sentry dashboard widget add 'My Dashboard' \"Error Count\" --display big_number --query count", + }, + { + description: "Use a dashboard ID in an explicit organization", + command: + 'sentry dashboard widget add my-org/12345 "Error Count" --display big_number --query count', + }, + { + description: "Line chart with group-by", + command: + "sentry dashboard widget add 'My Dashboard' \"Errors by Browser\" --display line --query count --group-by browser.name", + }, + { + description: "Table with multiple aggregates, sorted descending", + command: + "sentry dashboard widget add 'My Dashboard' \"Top Endpoints\" --display table --query count --query p95:span.duration --group-by transaction --sort -count --limit 10", + }, + { + description: "Bar chart with a search filter", + command: + 'sentry dashboard widget add \'My Dashboard\' "Slow Requests" --display bar --query p95:span.duration --where "span.op:http.client" --group-by span.description', + }, + ], }, output: { human: formatWidgetAdded, diff --git a/packages/cli/src/commands/dashboard/widget/delete.ts b/packages/cli/src/commands/dashboard/widget/delete.ts index ff630df0e..c2865d3c4 100644 --- a/packages/cli/src/commands/dashboard/widget/delete.ts +++ b/packages/cli/src/commands/dashboard/widget/delete.ts @@ -55,11 +55,22 @@ export const deleteCommand = buildDeleteCommand( fullDescription: "Remove a widget from an existing Sentry dashboard.\n\n" + "The dashboard can be specified by numeric ID or title.\n" + - "Identify the widget by --index (0-based) or --title.\n\n" + - "Examples:\n" + - " sentry dashboard widget delete 12345 --index 0\n" + - " sentry dashboard widget delete 'My Dashboard' --title 'Error Rate'\n" + - " sentry dashboard widget delete 12345 --index 0 --dry-run", + "Identify the widget by --index (0-based) or --title.", + examples: [ + { + description: "Delete a widget by title", + command: + "sentry dashboard widget delete 'My Dashboard' --title 'Error Rate'", + }, + { + description: "Delete a widget by index", + command: "sentry dashboard widget delete 12345 --index 0", + }, + { + description: "Preview the deletion", + command: "sentry dashboard widget delete 12345 --index 0 --dry-run", + }, + ], }, output: { human: formatWidgetDeleted, diff --git a/packages/cli/src/commands/dashboard/widget/edit.ts b/packages/cli/src/commands/dashboard/widget/edit.ts index bb26892ec..6c33b395d 100644 --- a/packages/cli/src/commands/dashboard/widget/edit.ts +++ b/packages/cli/src/commands/dashboard/widget/edit.ts @@ -197,12 +197,29 @@ export const editCommand = buildCommand({ "Identify the widget by --index (0-based) or --title.\n" + "Only provided flags are changed — omitted values are preserved.\n\n" + "Layout flags (--col/-x, --row/-y, --width, --height) control widget position\n" + - "and size in the 6-column dashboard grid.\n\n" + - "Examples:\n" + - " sentry dashboard widget edit 12345 --title 'Error Rate' --display bar\n" + - " sentry dashboard widget edit 'My Dashboard' --index 0 --query p95:span.duration\n" + - " sentry dashboard widget edit 12345 --title 'Old Name' --new-title 'New Name'\n" + - " sentry dashboard widget edit 12345 --index 0 --col 0 --row 0 --width 6 --height 2", + "and size in the 6-column dashboard grid.", + examples: [ + { + description: "Change a widget's display type", + command: + "sentry dashboard widget edit 12345 --title 'Error Rate' --display bar", + }, + { + description: "Change the query of a widget selected by index", + command: + "sentry dashboard widget edit 'My Dashboard' --index 0 --query p95:span.duration", + }, + { + description: "Rename a widget", + command: + "sentry dashboard widget edit 12345 --title 'Old Name' --new-title 'New Name'", + }, + { + description: "Move and resize a widget", + command: + "sentry dashboard widget edit 12345 --index 0 --col 0 --row 0 --width 6 --height 2", + }, + ], }, output: { human: formatWidgetEdited, diff --git a/packages/cli/src/commands/debug-files/bundle-jvm.ts b/packages/cli/src/commands/debug-files/bundle-jvm.ts index 8efc8e3f5..bf81e10a6 100644 --- a/packages/cli/src/commands/debug-files/bundle-jvm.ts +++ b/packages/cli/src/commands/debug-files/bundle-jvm.ts @@ -56,6 +56,23 @@ export const bundleJvmCommand = buildCommand({ "Groovy, or Clojure source files. The bundle is a ZIP archive that " + "can be uploaded to Sentry for source context in JVM stack traces.\n\n" + "This command is local-only — it makes no network requests.", + examples: [ + { + description: "Bundle JVM sources with a debug ID", + command: + "sentry debug-files bundle-jvm --output ./out --debug-id ./src", + }, + { + description: "Exclude additional directories", + command: + "sentry debug-files bundle-jvm --output ./out --debug-id --exclude generated --exclude build-tools ./src", + }, + { + description: "Output as JSON", + command: + "sentry debug-files bundle-jvm --output ./out --debug-id --json ./src", + }, + ], }, output: { human: formatBundleResult, diff --git a/packages/cli/src/commands/debug-files/bundle-sources.ts b/packages/cli/src/commands/debug-files/bundle-sources.ts index 117921c51..be984d812 100644 --- a/packages/cli/src/commands/debug-files/bundle-sources.ts +++ b/packages/cli/src/commands/debug-files/bundle-sources.ts @@ -83,6 +83,18 @@ export const bundleSourcesCommand = buildCommand({ " sentry debug-files bundle-sources ./libexample.so\n" + " sentry debug-files bundle-sources ./app.pdb -o ./app.src.zip\n\n" + "Exits non-zero if no referenced source files are found on disk.", + examples: [ + { + description: + "Bundle a debug file's referenced source files (run on the build machine)", + command: "sentry debug-files bundle-sources ./libexample.so", + }, + { + description: "Write the bundle to a specific path", + command: + "sentry debug-files bundle-sources ./app.pdb --output ./app.src.zip", + }, + ], }, output: { human: formatBundleResult, diff --git a/packages/cli/src/commands/debug-files/check.ts b/packages/cli/src/commands/debug-files/check.ts index 29822086e..dc592d8c9 100644 --- a/packages/cli/src/commands/debug-files/check.ts +++ b/packages/cli/src/commands/debug-files/check.ts @@ -125,6 +125,22 @@ export const checkCommand = buildCommand({ " sentry debug-files check MyApp.dSYM/Contents/Resources/DWARF/MyApp\n" + " sentry debug-files check ./app.pdb --json\n\n" + "Exits non-zero if the file is not usable for symbolication.", + examples: [ + { + description: + "Inspect a debug information file (auto-detects the format)", + command: "sentry debug-files check ./libexample.so", + }, + { + description: "Inspect the DWARF file inside a dSYM", + command: + "sentry debug-files check MyApp.dSYM/Contents/Resources/DWARF/MyApp", + }, + { + description: "Output the report as JSON", + command: "sentry debug-files check ./app.pdb --json", + }, + ], }, output: { human: formatCheckResult, diff --git a/packages/cli/src/commands/debug-files/find.ts b/packages/cli/src/commands/debug-files/find.ts index 16a7c6785..594fd021f 100644 --- a/packages/cli/src/commands/debug-files/find.ts +++ b/packages/cli/src/commands/debug-files/find.ts @@ -120,6 +120,22 @@ export const findCommand = buildCommand({ " sentry debug-files find [...]\n" + " sentry debug-files find --type dsym --path ./build\n" + " sentry debug-files find --no-cwd --no-well-known -p /symbols", + examples: [ + { + description: "Locate debug files for a debug identifier on disk", + command: "sentry debug-files find ", + }, + { + description: "Search only for dSYMs, including an extra directory", + command: + "sentry debug-files find --type dsym --path ./build", + }, + { + description: "Search only an explicit directory and output JSON", + command: + "sentry debug-files find --no-cwd --no-well-known -p /symbols --json", + }, + ], }, // Purely local filesystem search — no Sentry API calls, no auth needed. auth: false, diff --git a/packages/cli/src/commands/debug-files/print-sources.ts b/packages/cli/src/commands/debug-files/print-sources.ts index 1c9c83ff1..b2e2a3206 100644 --- a/packages/cli/src/commands/debug-files/print-sources.ts +++ b/packages/cli/src/commands/debug-files/print-sources.ts @@ -114,6 +114,17 @@ export const printSourcesCommand = buildCommand({ "Usage:\n" + " sentry debug-files print-sources ./libexample.so\n" + " sentry debug-files print-sources ./app.pdb --json", + examples: [ + { + description: + "List the source files a debug file references (and whether they're available)", + command: "sentry debug-files print-sources ./libexample.so", + }, + { + description: "Output the list as JSON", + command: "sentry debug-files print-sources ./app.pdb --json", + }, + ], }, output: { human: formatPrintSources, diff --git a/packages/cli/src/commands/debug-files/upload.ts b/packages/cli/src/commands/debug-files/upload.ts index 2477063e6..06c127858 100644 --- a/packages/cli/src/commands/debug-files/upload.ts +++ b/packages/cli/src/commands/debug-files/upload.ts @@ -558,6 +558,48 @@ export const uploadCommand = buildCommand({ "BCSymbolMap resolution (legacy --symbol-maps) is not supported: it " + "only applies to Apple Bitcode, which Apple has deprecated. Use the " + "legacy Rust sentry-cli if you still need it.", + examples: [ + { + description: + "Upload debug information files (scans directories recursively)", + command: "sentry debug-files upload ./build", + }, + { + description: "Attach a source bundle to each file", + command: "sentry debug-files upload ./libexample.so --include-sources", + }, + { + description: "Scan a .zip archive in place", + command: "sentry debug-files upload ./symbols.zip", + }, + { + description: "Skip .zip archives", + command: "sentry debug-files upload ./build --no-zips", + }, + { + description: "Upload only dSYMs and wait for server-side processing", + command: "sentry debug-files upload ./dsyms --type dsym --wait", + }, + { + description: "Fail unless the requested debug ID is found", + command: + "sentry debug-files upload ./build --id --require-all", + }, + { + description: "Unity: upload IL2CPP line mappings", + command: "sentry debug-files upload ./build --il2cpp-mapping", + }, + { + description: + "Unity: upload IL2CPP line mappings with referenced C# sources", + command: + "sentry debug-files upload ./build --il2cpp-mapping --include-sources", + }, + { + description: "Preview what would be uploaded (no credentials needed)", + command: "sentry debug-files upload ./build --no-upload", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/docs/list.ts b/packages/cli/src/commands/docs/list.ts index 216d772a7..f1ca06ce9 100644 --- a/packages/cli/src/commands/docs/list.ts +++ b/packages/cli/src/commands/docs/list.ts @@ -36,8 +36,21 @@ export const listCommand = buildCommand({ docs: { brief: "Find Sentry documentation pages by keyword", fullDescription: - "Search the Sentry documentation index without synthesizing an answer. Returns ranked page titles, descriptions, and URLs.\n\n" + - 'Examples:\n sentry docs list "nextjs tracing"\n sentry docs list "session replay privacy" --limit 5\n sentry docs list "source maps" --json', + "Search the Sentry documentation index without synthesizing an answer. Returns ranked page titles, descriptions, and URLs.", + examples: [ + { + description: "Search the documentation index", + command: 'sentry docs list "source maps"', + }, + { + description: "Limit the number of results", + command: 'sentry docs list "session replay privacy" --limit 5', + }, + { + description: "Output as JSON", + command: 'sentry docs list "source maps" --json', + }, + ], }, output: { human: formatListHuman }, parameters: { diff --git a/packages/cli/src/commands/docs/query.ts b/packages/cli/src/commands/docs/query.ts index ae9af6993..ad81a7d4e 100644 --- a/packages/cli/src/commands/docs/query.ts +++ b/packages/cli/src/commands/docs/query.ts @@ -30,8 +30,25 @@ export const queryCommand = buildCommand({ brief: "Ask a cited question about Sentry documentation", fullDescription: "Answer a natural-language Sentry documentation question using current docs.sentry.io pages. " + - "The command automatically uses safe local project metadata (manifests and config presence only) to tailor the answer.\n\n" + - 'Examples:\n sentry docs "How do I configure Next.js tracing?"\n sentry docs query "How do I upload source maps?"\n sentry docs search "How does session replay mask text?"\n sentry docs "How do I configure tracing?" --json', + "The command automatically uses safe local project metadata (manifests and config presence only) to tailor the answer.", + examples: [ + { + description: "Ask a documentation question", + command: 'sentry docs "How do I configure tracing in Next.js?"', + }, + { + description: "Use the explicit subcommand", + command: 'sentry docs query "How do I upload source maps?"', + }, + { + description: "Use the search alias", + command: 'sentry docs search "How does session replay mask text?"', + }, + { + description: "Output the answer as JSON", + command: 'sentry docs "How do I configure tracing?" --json', + }, + ], }, output: { human: formatQueryHuman }, parameters: { diff --git a/packages/cli/src/commands/dsn/list.ts b/packages/cli/src/commands/dsn/list.ts index 10809fd5c..25d6cb847 100644 --- a/packages/cli/src/commands/dsn/list.ts +++ b/packages/cli/src/commands/dsn/list.ts @@ -302,14 +302,36 @@ export const listCommand = buildListCommand("dsn", { "Use / to list DSNs across all accessible projects in an organization.\n" + "Omit the target to detect projects from your config or DSNs, including monorepos.\n" + `${targetPatternExplanation()}\n\n` + - "Examples:\n" + - " sentry dsn list\n" + - " sentry dsn list my-org/my-project\n" + - " sentry dsn list my-org/\n" + - " sentry dsn list my-org/ -c next\n" + - " sentry dsn list my-org/my-project -c next\n" + - " sentry dsn list my-org/my-project --json\n\n" + "JSON fields: org, project, name, dsn, isActive, dateCreated.", + examples: [ + { + description: + "List client keys for detected projects, including monorepos", + command: "sentry dsn list", + }, + { + description: "List enabled and disabled DSNs for one project", + command: "sentry dsn list my-org/my-project", + }, + { + description: + "List DSNs across all accessible projects in an organization", + command: "sentry dsn list my-org/", + }, + { + description: "Fetch the next page", + command: "sentry dsn list my-org/ --limit 10 -c next", + }, + { + description: "Fetch the previous page", + command: "sentry dsn list my-org/ --limit 10 -c prev", + }, + { + description: "Select public DSN fields as JSON", + command: + "sentry dsn list my-org/my-project --json --fields name,dsn,isActive", + }, + ], }, output: { human: formatDsnList, diff --git a/packages/cli/src/commands/event/list.ts b/packages/cli/src/commands/event/list.ts index 52adad8bb..3761f952a 100644 --- a/packages/cli/src/commands/event/list.ts +++ b/packages/cli/src/commands/event/list.ts @@ -86,13 +86,45 @@ export const listCommand = buildListCommand("event", { " /ID - Explicit org: sentry/EXTENSION-7\n" + " -suffix - Project + suffix: cli-G\n" + " ID - Short ID: CLI-G\n" + - " numeric - Numeric ID: 123456789\n\n" + - "Examples:\n" + - " sentry event list CLI-G\n" + - " sentry event list @latest --limit 50\n" + - " sentry event list 123456789 --full\n" + - ' sentry event list CLI-G -q "user.email:foo@bar.com"\n' + - " sentry event list CLI-G --json", + " numeric - Numeric ID: 123456789", + examples: [ + { + description: "List events for an issue (short ID)", + command: "sentry event list PROJ-ABC", + }, + { + description: "List events for an issue (numeric ID)", + command: "sentry event list 123456789", + }, + { + description: "List events for the most recent issue", + command: "sentry event list @latest --limit 50", + }, + { + description: "Filter by search query", + command: 'sentry event list PROJ-ABC --query "browser:Chrome"', + }, + { + description: "Include full event bodies (stacktraces)", + command: "sentry event list PROJ-ABC --full", + }, + { + description: "Limit results and time range", + command: "sentry event list PROJ-ABC --limit 50 --period 24h", + }, + { + description: "Fetch the next page", + command: "sentry event list PROJ-ABC -c next", + }, + { + description: "Fetch the previous page", + command: "sentry event list PROJ-ABC -c prev", + }, + { + description: "Output as JSON", + command: "sentry event list PROJ-ABC --json", + }, + ], }, output: { human: formatEventsHuman, diff --git a/packages/cli/src/commands/event/send.ts b/packages/cli/src/commands/event/send.ts index a7de06fd6..91663e108 100644 --- a/packages/cli/src/commands/event/send.ts +++ b/packages/cli/src/commands/event/send.ts @@ -140,6 +140,58 @@ built entirely from the file contents. | \`--logfile\` | Attach last 100 log lines as breadcrumbs | | \`--with-categories\` | Parse 'CATEGORY: message' from logfile lines | `, + examples: [ + { + description: "Send an error event (default level)", + command: 'sentry event send -m "Something went wrong"', + }, + { + description: "Specify level, release, and environment", + command: + 'sentry event send -m "Deploy check" -l info -r 1.0.0 -E production', + }, + { + description: "Add tags and extra data", + command: + 'sentry event send -m "Payment failed" --tag env:prod --tag region:us-east --extra amount:99.99', + }, + { + description: "Set user context", + command: + 'sentry event send -m "Login error" --user id:42 --user email:alice@example.com', + }, + { + description: "Custom fingerprint to group related events together", + command: + 'sentry event send -m "DB timeout" --fingerprint db-timeout --fingerprint {{ default }}', + }, + { + description: "Send a serialized Sentry Event object", + command: "sentry event send ./crash.json", + }, + { + description: "Send without re-parsing (raw mode)", + command: "sentry event send --raw ./crash.json", + }, + { + description: "Send a pre-built envelope", + command: "sentry event send --raw ./captured.envelope", + }, + { + description: "Send with an explicit DSN", + command: + 'sentry event send "https://key@o123.ingest.us.sentry.io/456" -m "Test"', + }, + { + description: + "Send to a project (logged-in session; the CLI fetches its sole active DSN)", + command: 'sentry event send my-project -m "Test"', + }, + { + description: "Send to an org/project target", + command: 'sentry event send my-org/my-project -m "Test"', + }, + ], }, auth: "dsn", output: { diff --git a/packages/cli/src/commands/event/view.ts b/packages/cli/src/commands/event/view.ts index fe311a80e..f97d27d19 100644 --- a/packages/cli/src/commands/event/view.ts +++ b/packages/cli/src/commands/event/view.ts @@ -1178,6 +1178,16 @@ export const viewCommand = buildCommand({ "Attachment metadata (id, name, size, mimetype, download URL) is included when available.\n" + "Download bytes with:\n" + ' sentry api "" > file', + examples: [ + { + description: "View an event", + command: "sentry event view abc123def456abc123def456abc12345", + }, + { + description: "Open in the browser", + command: "sentry event view abc123def456abc123def456abc12345 -w", + }, + ], }, output: { human: formatEventView, diff --git a/packages/cli/src/commands/explore.ts b/packages/cli/src/commands/explore.ts index 699ad570c..f9d21594e 100644 --- a/packages/cli/src/commands/explore.ts +++ b/packages/cli/src/commands/explore.ts @@ -606,18 +606,84 @@ export const exploreCommand = buildListCommand("explore", { " / All projects in org\n" + " Bare slug — searches across orgs\n" + " (omitted) Auto-detect from DSN/config\n\n" + - "Examples:\n" + - ' sentry explore my-org/cli -F title -F "count()"\n' + - ' sentry explore my-org/ -F title -F "count()" -F "count_unique(user)" --period 1h\n' + - ' sentry explore my-org/cli -F span.op -F "p50(span.duration)" ' + - "--dataset spans\n" + - " sentry explore my-org/cli --dataset replays -F id -F user.email -F count_errors\n" + - ' sentry explore -F span.op -F "count()" --dataset spans --period 1h\n' + - " sentry explore --json\n\n" + "Metrics (auto mode — resolves type/unit automatically):\n" + " sentry explore my-org/ -m llm.token_usage --dataset metrics\n" + " sentry explore my-org/seer -F gen_ai.request.model -m llm.token_usage --dataset metrics --period 7d\n" + " sentry explore my-org/ -m cache.hit_rate --agg avg --dataset metrics", + examples: [ + { + description: "Top errors in the last 24 hours, scoped to a project", + command: "sentry explore my-org/cli", + }, + { + description: "All projects in an organization", + command: "sentry explore my-org/", + }, + { + description: "Bare project slug (searches across organizations)", + command: "sentry explore cli", + }, + { + description: "Auto-detect the project from DSN/config", + command: "sentry explore", + }, + { + description: "Errors with user impact for a specific UTC window", + command: + 'sentry explore my-org/cli -F title -F "count()" -F "count_unique(user)" --period "2024-01-15T00:00:00Z..2024-01-16T00:00:00Z"', + }, + { + description: "Filter by error type (combined with the project filter)", + command: + 'sentry explore my-org/cli -F title -F "count()" -q "error.type:TypeError" --period 1h', + }, + { + description: "Span operation latency", + command: + 'sentry explore my-org/cli -F span.op -F "p50(span.duration)" -F "p95(span.duration)" --dataset spans --period 1h', + }, + { + description: "Top spans by count", + command: + 'sentry explore my-org/cli -F span.op -F "count()" --dataset spans --sort "-count()"', + }, + { + description: + "Sum a custom metric (e.g., LLM token usage) across an organization", + command: + "sentry explore my-org/ -m llm.token_usage --dataset metrics --period 7d", + }, + { + description: "Break a metric down by a tag column", + command: + "sentry explore my-org/seer -F gen_ai.request.model -m llm.token_usage --dataset metrics --period 7d", + }, + { + description: "Use a different metric aggregation (default is sum)", + command: + "sentry explore my-org/ -m cache.hit_rate --agg avg --dataset metrics", + }, + { + description: "Use the raw tracemetrics format", + command: + 'sentry explore my-org/ -F "sum(value,llm.token_usage,distribution,none)" --dataset metrics --period 7d', + }, + { + description: "Filter replays by activity level", + command: + "sentry explore my-org/cli --dataset replays -F activity -F duration -F count_errors --period 7d", + }, + { + description: "Log severity counts in the last hour", + command: + 'sentry explore my-org/cli -F severity -F "count()" --dataset logs --period 1h', + }, + { + description: "Pipe JSON to jq", + command: + "sentry explore my-org/cli -F title -F \"count()\" --json | jq '.data[:5]'", + }, + ], }, output: { human: formatExploreHuman, diff --git a/packages/cli/src/commands/feedback/list.ts b/packages/cli/src/commands/feedback/list.ts index d146db42e..2e4ee148f 100644 --- a/packages/cli/src/commands/feedback/list.ts +++ b/packages/cli/src/commands/feedback/list.ts @@ -146,6 +146,42 @@ export const listCommand = buildListCommand("feedback", { " resolved Resolved feedback\n" + " spam Feedback marked as spam\n" + " all All feedback statuses", + examples: [ + { + description: "List Feedback (organization auto-detected)", + command: "sentry feedback list", + }, + { + description: "List Feedback for one project", + command: "sentry feedback list my-org/frontend", + }, + { + description: "List Feedback across every project in an organization", + command: "sentry feedback list my-org/", + }, + { + description: "Search for a project across accessible organizations", + command: "sentry feedback list frontend", + }, + { + description: "Show resolved Feedback", + command: "sentry feedback list my-org/frontend --status resolved", + }, + { + description: "Show the spam mailbox", + command: "sentry feedback list my-org/frontend --status spam", + }, + { + description: "Show every status over the last 90 days", + command: + "sentry feedback list my-org/frontend --status all --period 90d", + }, + { + description: "Search Feedback messages", + command: + 'sentry feedback list my-org/frontend --query "message:*checkout*"', + }, + ], }, output: { human: formatFeedbackList, diff --git a/packages/cli/src/commands/feedback/resolve.ts b/packages/cli/src/commands/feedback/resolve.ts index 0a14702aa..19777580a 100644 --- a/packages/cli/src/commands/feedback/resolve.ts +++ b/packages/cli/src/commands/feedback/resolve.ts @@ -17,11 +17,26 @@ export const resolveCommand = buildCommand({ fullDescription: "Resolve a User Feedback item immediately.\n\n" + "Accepts the same IDs and URLs as sentry feedback view. Use @latest to resolve the most recently active unresolved Feedback.\n\n" + - "The resolved issue must have issue.category:feedback. Other issue categories are rejected before any changes are made.\n\n" + - "Examples:\n" + - " sentry feedback resolve FRONTEND-2SDJ\n" + - " sentry feedback resolve my-org/FRONTEND-2SDJ\n" + - " sentry feedback resolve my-org/@latest", + "The resolved issue must have issue.category:feedback. Other issue categories are rejected before any changes are made.", + examples: [ + { + description: "Resolve a Feedback item (organization auto-detected)", + command: "sentry feedback resolve FRONTEND-2SDJ", + }, + { + description: "Resolve a Feedback item in an explicit organization", + command: "sentry feedback resolve my-org/FRONTEND-2SDJ", + }, + { + description: "Resolve the most recently active unresolved Feedback", + command: "sentry feedback resolve my-org/@latest", + }, + { + description: "Return selected fields from the updated Feedback", + command: + "sentry feedback resolve my-org/FRONTEND-2SDJ --json --fields id,shortId,status", + }, + ], }, output: { human: formatResolvedFeedback, diff --git a/packages/cli/src/commands/feedback/spam.ts b/packages/cli/src/commands/feedback/spam.ts index 055044723..d1c008cb8 100644 --- a/packages/cli/src/commands/feedback/spam.ts +++ b/packages/cli/src/commands/feedback/spam.ts @@ -17,12 +17,26 @@ export const spamCommand = buildCommand({ fullDescription: "Move a User Feedback item to the spam mailbox.\n\n" + "Accepts the same IDs and URLs as sentry feedback view. Other issue categories are rejected before any changes are made.\n\n" + - "Sentry stores spam Feedback with status ignored. Use sentry feedback unresolve to return it to the unresolved inbox.\n\n" + - "Examples:\n" + - " sentry feedback spam FRONTEND-2SDJ\n" + - " sentry feedback spam my-org/FRONTEND-2SDJ\n" + - " sentry feedback list --status spam\n" + - " sentry feedback unresolve FRONTEND-2SDJ", + "Sentry stores spam Feedback with status ignored. Use sentry feedback unresolve to return it to the unresolved inbox.", + examples: [ + { + description: "Move a Feedback item to the spam mailbox", + command: "sentry feedback spam FRONTEND-2SDJ", + }, + { + description: "Mark as spam by numeric ID", + command: "sentry feedback spam 5146636313", + }, + { + description: "Specify an organization explicitly", + command: "sentry feedback spam my-org/FRONTEND-2SDJ", + }, + { + description: "Return selected fields from the updated Feedback", + command: + "sentry feedback spam FRONTEND-2SDJ --json --fields id,shortId,status", + }, + ], }, output: { human: formatSpamFeedback, diff --git a/packages/cli/src/commands/feedback/unresolve.ts b/packages/cli/src/commands/feedback/unresolve.ts index 4a2754e07..c51bb1cec 100644 --- a/packages/cli/src/commands/feedback/unresolve.ts +++ b/packages/cli/src/commands/feedback/unresolve.ts @@ -17,11 +17,31 @@ export const unresolveCommand = buildCommand({ fullDescription: "Mark a User Feedback item as unresolved. Reopen resolved Feedback or restore it from spam.\n\n" + "Accepts the same IDs and URLs as sentry feedback view. Other issue categories are rejected before any changes are made.\n\n" + - "Use sentry feedback list --status resolved or --status spam to find Feedback to return to the inbox.\n\n" + - "Examples:\n" + - " sentry feedback unresolve FRONTEND-2SDJ\n" + - " sentry feedback reopen FRONTEND-2SDJ\n" + - " sentry feedback unresolve my-org/FRONTEND-2SDJ", + "Use sentry feedback list --status resolved or --status spam to find Feedback to return to the inbox.", + examples: [ + { + description: + "Reopen a Feedback item, or return it from spam to the inbox", + command: "sentry feedback unresolve FRONTEND-2SDJ", + }, + { + description: "Reopen by numeric ID", + command: "sentry feedback unresolve 5146636313", + }, + { + description: "`reopen` is an alias for `unresolve`", + command: "sentry feedback reopen FRONTEND-2SDJ", + }, + { + description: "Specify an organization explicitly", + command: "sentry feedback unresolve my-org/FRONTEND-2SDJ", + }, + { + description: "Return selected fields from the updated Feedback", + command: + "sentry feedback unresolve FRONTEND-2SDJ --json --fields id,shortId,status", + }, + ], }, output: { human: formatReopenedFeedback, diff --git a/packages/cli/src/commands/feedback/view.ts b/packages/cli/src/commands/feedback/view.ts index 58eed6362..bac24b63a 100644 --- a/packages/cli/src/commands/feedback/view.ts +++ b/packages/cli/src/commands/feedback/view.ts @@ -108,6 +108,37 @@ export const viewCommand = buildCommand({ "Full short IDs use SENTRY_ORG, .sentryclirc, or 'sentry cli defaults' for the org.\n" + "Without a configured org, the CLI uses a matching DSN or searches accessible orgs.\n\n" + "The resolved issue must have issue.category:feedback. Use 'sentry issue view' for other issue categories.", + examples: [ + { + description: "View the most recent unresolved Feedback", + command: "sentry feedback view @latest", + }, + { + description: + "Most recent unresolved Feedback in an explicit organization", + command: "sentry feedback view my-org/@latest", + }, + { + description: "View by short ID", + command: "sentry feedback view FRONTEND-2SDJ", + }, + { + description: "View by numeric ID", + command: "sentry feedback view 5146636313", + }, + { + description: "View in an explicit organization", + command: "sentry feedback view my-org/FRONTEND-2SDJ", + }, + { + description: "`view` is the default command", + command: "sentry feedback my-org/FRONTEND-2SDJ", + }, + { + description: "Open the Feedback item in Sentry", + command: "sentry feedback view my-org/FRONTEND-2SDJ --web", + }, + ], }, output: { human: formatFeedbackView, diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index a2ff367fb..d13379522 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -118,6 +118,22 @@ export const infoCommand = buildCommand({ "Use `--config-status-json` for a machine-readable status dump (for " + "external tooling); it always exits 0. Use `--no-defaults` to verify " + "only authentication, without requiring a default org/project.", + examples: [ + { + description: "Print the resolved config and verify authentication", + command: "sentry info", + }, + { + description: + "Verify only authentication (don't require a default org/project)", + command: "sentry info --no-defaults", + }, + { + description: + "Machine-readable status for external tooling (always exits 0)", + command: "sentry info --config-status-json", + }, + ], }, // Reports auth status (including "Unauthorized") — must run without auth. auth: false, diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index eb26d2b35..02b2a4fda 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -299,14 +299,43 @@ export const initCommand = buildCommand< "install the SDK, and configure Sentry.\n\n" + "Supports org/project syntax and a directory positional. Path-like\n" + "arguments (starting with . / ~) are treated as the directory;\n" + - "everything else is treated as the target.\n\n" + - "Examples:\n" + - " sentry init\n" + - " sentry init acme/\n" + - " sentry init acme/my-app\n" + - " sentry init my-app\n" + - " sentry init acme/my-app ./my-project\n" + - " sentry init ./my-project", + "everything else is treated as the target.", + examples: [ + { description: "Interactive setup", command: "sentry init" }, + { + description: "Non-interactive agent/CI setup", + command: "sentry init --yes --features errors,tracing,replay", + }, + { + description: "Dry run to preview changes", + command: "sentry init --dry-run", + }, + { description: "Target a subdirectory", command: "sentry init ./my-app" }, + { + description: "Use a specific organization (auto-detect project)", + command: "sentry init acme/", + }, + { + description: "Use a specific organization and project", + command: "sentry init acme/my-app", + }, + { + description: "Search for a project across organizations", + command: "sentry init my-app", + }, + { + description: "Use a specific project in a subdirectory", + command: "sentry init acme/my-app ./my-project", + }, + { + description: "Assign a team when creating a new project", + command: "sentry init acme/ --team backend", + }, + { + description: "Enable specific features", + command: "sentry init --features profiling,replay", + }, + ], }, parameters: { positional: { diff --git a/packages/cli/src/commands/issue/archive.ts b/packages/cli/src/commands/issue/archive.ts index 276cdb939..ee001bc72 100644 --- a/packages/cli/src/commands/issue/archive.ts +++ b/packages/cli/src/commands/issue/archive.ts @@ -342,17 +342,53 @@ export const archiveCommand = buildCommand({ "Compound conditions — add a time window with /:\n" + " --until 10x/5m Unarchive when 10 events occur within 5 minutes\n" + " --until 5u/1h Unarchive when 5 users are affected within 1 hour\n\n" + - "Verbose forms are also accepted: 10events, 10users, 30minutes, 2hours, 7days\n\n" + - "Examples:\n" + - " sentry issue archive CLI-12Z # Archive forever\n" + - " sentry issue archive CLI-12Z --until auto # Smart spike detection\n" + - " sentry issue archive CLI-12Z -u auto # Same (short alias)\n" + - " sentry issue archive CLI-12Z --until 1h # Archive for 1 hour\n" + - " sentry issue archive CLI-12Z --until 7d # Archive for 7 days\n" + - " sentry issue archive CLI-12Z --until 100x # Until 100 more events\n" + - " sentry issue archive CLI-12Z --until 100x/1h # 100 events within 1 hour\n" + - " sentry issue archive CLI-12Z --until 10u/1d # 10 users within 1 day\n" + - " sentry issue ignore CLI-12Z --until auto # 'ignore' alias works too", + "Verbose forms are also accepted: 10events, 10users, 30minutes, 2hours, 7days", + examples: [ + { + description: "Archive forever (fully silenced)", + command: "sentry issue archive CLI-G5", + }, + { + description: "Unarchive when Sentry detects a spike in event frequency", + command: "sentry issue archive CLI-G5 --until auto", + }, + { + description: "Archive for 1 hour", + command: "sentry issue archive CLI-G5 --until 1h", + }, + { + description: "Archive for 7 days", + command: "sentry issue archive CLI-G5 --until 7d", + }, + { + description: "Archive until a specific date", + command: "sentry issue archive CLI-G5 --until 2026-12-31", + }, + { + description: "Unarchive after 100 more events", + command: "sentry issue archive CLI-G5 --until 100x", + }, + { + description: "Unarchive after 10 more users are affected", + command: "sentry issue archive CLI-G5 --until 10u", + }, + { + description: "Unarchive after 100 events within 1 hour", + command: "sentry issue archive CLI-G5 --until 100x/1h", + }, + { + description: "Unarchive after 10 users within 1 day", + command: "sentry issue archive CLI-G5 --until 10u/1d", + }, + { + description: "Use the verbose condition form", + command: "sentry issue archive CLI-G5 --until 10events/2hours", + }, + { + description: "`ignore` is an alias for `archive`", + command: "sentry issue ignore CLI-G5 --until auto", + }, + ], }, output: { human: formatArchived, diff --git a/packages/cli/src/commands/issue/events.ts b/packages/cli/src/commands/issue/events.ts index f17c15ce9..8c1b9f111 100644 --- a/packages/cli/src/commands/issue/events.ts +++ b/packages/cli/src/commands/issue/events.ts @@ -76,13 +76,37 @@ export const eventsCommand = buildListCommand("issue", { " /ID - Explicit org: sentry/EXTENSION-7\n" + " -suffix - Project + suffix: cli-G\n" + " ID - Short ID: CLI-G\n" + - " numeric - Numeric ID: 123456789\n\n" + - "Examples:\n" + - " sentry issue events CLI-G\n" + - " sentry issue events @latest --limit 50\n" + - " sentry issue events 123456789 --full\n" + - ' sentry issue events CLI-G -q "user.email:foo@bar.com"\n' + - " sentry issue events CLI-G --json", + " numeric - Numeric ID: 123456789", + examples: [ + { + description: "List recent events for an issue", + command: "sentry issue events FRONT-ABC", + }, + { + description: "List events for the most recent issue", + command: "sentry issue events @latest --limit 50", + }, + { + description: "Filter events by search query", + command: 'sentry issue events FRONT-ABC --query "browser:Chrome"', + }, + { + description: "Show full event details", + command: "sentry issue events FRONT-ABC --full", + }, + { + description: "Limit results and filter by time period", + command: "sentry issue events FRONT-ABC --limit 50 --period 24h", + }, + { + description: "Fetch the next page", + command: "sentry issue events FRONT-ABC -c next", + }, + { + description: "Output as JSON", + command: "sentry issue events FRONT-ABC --json", + }, + ], }, output: { human: formatEventsHuman, diff --git a/packages/cli/src/commands/issue/explain.ts b/packages/cli/src/commands/issue/explain.ts index ab970fa12..67c51eef4 100644 --- a/packages/cli/src/commands/issue/explain.ts +++ b/packages/cli/src/commands/issue/explain.ts @@ -101,15 +101,38 @@ export const explainCommand = buildCommand({ "Full short IDs use SENTRY_ORG, .sentryclirc, or 'sentry cli defaults' for the org.\n" + "Without a configured org, the CLI uses a matching DSN or searches accessible orgs.\n\n" + "Multiple issue IDs can be passed as separate arguments or newline-separated\n" + - "within a single argument.\n\n" + - "Examples:\n" + - " sentry issue explain @latest\n" + - " sentry issue explain 123456789\n" + - " sentry issue explain sentry/EXTENSION-7\n" + - " sentry issue explain cli-G\n" + - " sentry issue explain CLI-G BACK-2\n" + - " sentry issue explain 123456789 --json\n" + - " sentry issue explain 123456789 --force", + "within a single argument.", + examples: [ + { + description: + "Analyze the root cause of an issue (may take a few minutes for new issues)", + command: "sentry issue explain 123456789", + }, + { + description: "Explain the most recent issue", + command: "sentry issue explain @latest", + }, + { + description: "Explain the most frequently occurring issue", + command: "sentry issue explain @most_frequent", + }, + { + description: "Use a short ID with an organization prefix", + command: "sentry issue explain my-org/MYPROJECT-ABC", + }, + { + description: "Analyze multiple issues in one invocation", + command: "sentry issue explain FRONT-ABC BACK-2", + }, + { + description: "Force a fresh analysis", + command: "sentry issue explain 123456789 --force", + }, + { + description: "Output root causes as JSON", + command: "sentry issue explain 123456789 --json", + }, + ], }, output: { human: formatIssueExplain, diff --git a/packages/cli/src/commands/issue/index.ts b/packages/cli/src/commands/issue/index.ts index 64538c81d..76b7c653a 100644 --- a/packages/cli/src/commands/issue/index.ts +++ b/packages/cli/src/commands/issue/index.ts @@ -47,16 +47,6 @@ export const issueRoute = buildRouteMap({ "Magic selectors (available for view, events, explain, plan, resolve, unresolve, archive):\n" + " @latest Most recent unresolved issue\n" + " @most_frequent Issue with the highest event frequency\n\n" + - "Examples:\n" + - " sentry issue view @latest\n" + - " sentry issue view FRONT-ABC BACK-2\n" + - " sentry issue explain FRONT-ABC BACK-2\n" + - " sentry issue events CLI-G\n" + - " sentry issue resolve CLI-12Z --in 0.26.1\n" + - " sentry issue archive CLI-AB --until auto\n" + - " sentry issue merge CLI-K9 CLI-15H CLI-15N\n" + - " sentry issue explain @most_frequent\n" + - " sentry issue plan my-org/@latest\n\n" + "Alias: `sentry issues` → `sentry issue list`", hideRoute: {}, }, diff --git a/packages/cli/src/commands/issue/link.ts b/packages/cli/src/commands/issue/link.ts index 9b6a7fa1e..003c01d3e 100644 --- a/packages/cli/src/commands/issue/link.ts +++ b/packages/cli/src/commands/issue/link.ts @@ -28,13 +28,39 @@ export const linkCommand = buildCommand({ "The integration must be installed in your Sentry organization.\n" + "This does not create a remote issue or resolve the Sentry issue.\n\n" + "Requires event:write and access to the Sentry project.\n" + - "Sentry Apps also require org:read for discovery.\n\n" + - "Examples:\n" + - " sentry issue link FRONT-123 https://github.com/example/app/issues/42\n" + - " sentry issue link FRONT-123 https://github.com/example/app/pull/43\n" + - " sentry issue link my-org/FRONT-123 https://example.atlassian.net/browse/APP-42\n" + - " sentry issue link FRONT-123 https://linear.app/example/issue/APP-42/fix-error\n" + - " sentry issue link FRONT-123 https://github.com/example/app/issues/42 --dry-run", + "Sentry Apps also require org:read for discovery.", + examples: [ + { + description: "Link a GitHub issue", + command: + "sentry issue link FRONT-123 https://github.com/example/app/issues/42", + }, + { + description: "Link a GitHub pull request", + command: + "sentry issue link FRONT-123 https://github.com/example/app/pull/43", + }, + { + description: "Link a Jira issue in an explicit organization", + command: + "sentry issue link my-org/FRONT-123 https://example.atlassian.net/browse/APP-42", + }, + { + description: "Link a Linear issue", + command: + "sentry issue link FRONT-123 https://linear.app/example/issue/APP-42/fix-error", + }, + { + description: "Prepare the link without submitting it", + command: + "sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --dry-run", + }, + { + description: "Output the result as JSON", + command: + "sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --json", + }, + ], }, output: { human: formatIssueLinkResult }, parameters: { diff --git a/packages/cli/src/commands/issue/list.ts b/packages/cli/src/commands/issue/list.ts index c5be1e075..0bd5a8c37 100644 --- a/packages/cli/src/commands/issue/list.ts +++ b/packages/cli/src/commands/issue/list.ts @@ -1651,6 +1651,51 @@ export const listCommand = buildListCommand("issue", { " Dates: age:-24h (last 24h), firstSeen:+7d (older than 7d)\n" + " Docs: https://docs.sentry.io/concepts/search/\n\n" + "Alias: `sentry issues` → `sentry issue list`", + examples: [ + { + description: "List issues in a specific project", + command: "sentry issue list my-org/frontend", + }, + { + description: "Several projects in the same organization", + command: "sentry issue list my-org/frontend,backend,worker", + }, + { + description: "All projects in an organization", + command: "sentry issue list my-org/", + }, + { + description: "Search for a project across organizations", + command: "sentry issue list frontend", + }, + { + description: "Show only unresolved issues", + command: 'sentry issue list my-org/frontend --query "is:unresolved"', + }, + { + description: "Sort by frequency", + command: "sentry issue list my-org/frontend --sort freq --limit 20", + }, + { + description: "Sort by Sentry's recommended relevance ranking", + command: "sentry issue list my-org/frontend --sort recommended", + }, + { + description: + "Multiple filters (space-separated terms are combined with AND)", + command: + 'sentry issue list --query "is:unresolved level:error assigned:me"', + }, + { + description: "Negation and wildcards", + command: + 'sentry issue list --query "!browser:Chrome message:*timeout*"', + }, + { + description: "Match multiple values for one key", + command: 'sentry issue list --query "browser:[Chrome,Firefox]"', + }, + ], }, output: issueListOutput, parameters: { diff --git a/packages/cli/src/commands/issue/merge.ts b/packages/cli/src/commands/issue/merge.ts index d8ced7e9d..54f2e6442 100644 --- a/packages/cli/src/commands/issue/merge.ts +++ b/packages/cli/src/commands/issue/merge.ts @@ -262,11 +262,27 @@ export const mergeCommand = buildCommand({ "choice has fewer events, Sentry may still pick a different parent,\n" + "in which case a warning is printed to stderr.\n\n" + "All issues must belong to the same organization. Only error-type\n" + - "issues can be merged (the API rejects performance/info issues).\n\n" + - "Examples:\n" + - " sentry issue merge CLI-K9 CLI-15H CLI-15N\n" + - " sentry issue merge CLI-K9 CLI-15H --into CLI-K9\n" + - " sentry issue merge my-org/CLI-AB my-org/CLI-CD", + "issues can be merged (the API rejects performance/info issues).", + examples: [ + { + description: + "Let Sentry pick the parent (typically the largest by event count)", + command: "sentry issue merge CLI-K9 CLI-15H CLI-15N", + }, + { + description: "Pin the canonical parent explicitly", + command: "sentry issue merge CLI-K9 CLI-15H CLI-15N --into CLI-K9", + }, + { + description: "Use organization-qualified IDs", + command: + "sentry issue merge my-org/CLI-K9 my-org/CLI-15H --into my-org/CLI-K9", + }, + { + description: "Use project-alias IDs", + command: "sentry issue merge cli-k9 cli-15h --into cli-k9", + }, + ], }, output: { human: formatMerged, diff --git a/packages/cli/src/commands/issue/plan.ts b/packages/cli/src/commands/issue/plan.ts index 9fd648967..2742d7bb4 100644 --- a/packages/cli/src/commands/issue/plan.ts +++ b/packages/cli/src/commands/issue/plan.ts @@ -218,13 +218,25 @@ export const planCommand = buildCommand({ "Without a configured org, the CLI uses a matching DSN or searches accessible orgs.\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 @latest\n" + - " sentry issue plan 123456789\n" + - " sentry issue plan sentry/EXTENSION-7\n" + - " sentry issue plan cli-G\n" + - " sentry issue plan 123456789 --force", + " - Code mappings set up for your project", + examples: [ + { + description: "Generate a fix plan (runs explain first if needed)", + command: "sentry issue plan 123456789", + }, + { + description: "Generate a fix plan for the most recent issue", + command: "sentry issue plan @latest", + }, + { + description: "Use a short ID with an organization prefix", + command: "sentry issue plan my-org/MYPROJECT-ABC", + }, + { + description: "Force a fresh plan even if one already exists", + command: "sentry issue plan 123456789 --force", + }, + ], }, output: { human: formatPlanOutput, diff --git a/packages/cli/src/commands/issue/resolve.ts b/packages/cli/src/commands/issue/resolve.ts index cf59c01bf..07c0e09ce 100644 --- a/packages/cli/src/commands/issue/resolve.ts +++ b/packages/cli/src/commands/issue/resolve.ts @@ -104,14 +104,41 @@ export const resolveCommand = buildCommand({ " (omitted) Resolve immediately (no regression tracking)\n\n" + "@commit auto-detection requires a git repository whose 'origin' remote\n" + "maps to a Sentry-registered repo. The command errors out clearly if any\n" + - "part of the detection fails — use the explicit form to override.\n\n" + - "Examples:\n" + - " sentry issue resolve CLI-12Z\n" + - " sentry issue resolve CLI-12Z --in 0.26.1\n" + - " sentry issue resolve CLI-196 --in @next\n" + - " sentry issue resolve CLI-XX --in @commit\n" + - " sentry issue resolve CLI-XX -i @commit:getsentry/cli@abc123\n" + - " sentry issue resolve my-org/CLI-AB", + "part of the detection fails — use the explicit form to override.", + examples: [ + { + description: "Resolve immediately (no regression tracking)", + command: "sentry issue resolve CLI-G5", + }, + { + description: + "Resolve in a specific release (newer releases flag regressions)", + command: "sentry issue resolve CLI-G5 --in 0.26.1", + }, + { + description: "Monorepo-style release versions work too", + command: "sentry issue resolve CLI-G5 --in spotlight@1.2.3", + }, + { + description: "Resolve in the next release", + command: "sentry issue resolve CLI-G5 --in @next", + }, + { + description: + "Resolve in the current git HEAD (auto-detects the Sentry repo from your origin remote)", + command: "sentry issue resolve CLI-G5 --in @commit", + }, + { + description: + "Resolve in an explicit commit and repo (no git inspection)", + command: + "sentry issue resolve CLI-G5 --in @commit:getsentry/cli@abc123def", + }, + { + description: "Resolve an issue in an explicit organization", + command: "sentry issue resolve my-org/CLI-G5", + }, + ], }, output: { human: formatResolved, diff --git a/packages/cli/src/commands/issue/unlink.ts b/packages/cli/src/commands/issue/unlink.ts index ee84dcd16..b1f86df81 100644 --- a/packages/cli/src/commands/issue/unlink.ts +++ b/packages/cli/src/commands/issue/unlink.ts @@ -30,12 +30,29 @@ export const unlinkCommand = buildDeleteCommand({ "Remove an external tracker issue or GitHub pull request reference from a Sentry issue.\n" + "This does not delete the external issue or change the Sentry issue's status.\n\n" + "Requires event:write and access to the Sentry project.\n" + - "Older Sentry versions may still require event:admin.\n\n" + - "Examples:\n" + - " sentry issue unlink FRONT-123 https://github.com/example/app/issues/42\n" + - " sentry issue unlink FRONT-123 https://github.com/example/app/pull/43 --yes\n" + - " sentry issue unlink my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 --yes\n" + - " sentry issue unlink FRONT-123 https://linear.app/example/issue/APP-42/fix-error --dry-run", + "Older Sentry versions may still require event:admin.", + examples: [ + { + description: "Unlink a GitHub issue (prompts for confirmation)", + command: + "sentry issue unlink FRONT-123 https://github.com/example/app/issues/42", + }, + { + description: "Unlink a GitHub pull request without prompting", + command: + "sentry issue unlink FRONT-123 https://github.com/example/app/pull/43 --yes", + }, + { + description: "Unlink a Jira issue in an explicit organization", + command: + "sentry issue unlink my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 --yes", + }, + { + description: "Check whether a link exists without removing it", + command: + "sentry issue unlink FRONT-123 https://linear.app/example/issue/APP-42/fix-error --dry-run", + }, + ], }, output: { human: formatIssueLinkResult }, parameters: { diff --git a/packages/cli/src/commands/issue/unresolve.ts b/packages/cli/src/commands/issue/unresolve.ts index 07775118b..af2c06c4f 100644 --- a/packages/cli/src/commands/issue/unresolve.ts +++ b/packages/cli/src/commands/issue/unresolve.ts @@ -30,11 +30,21 @@ export const unresolveCommand = buildCommand({ docs: { brief: "Reopen a resolved issue", fullDescription: - "Mark an issue as unresolved. Inverse of `sentry issue resolve`.\n\n" + - "Examples:\n" + - " sentry issue unresolve CLI-12Z\n" + - " sentry issue reopen CLI-12Z\n" + - " sentry issue unresolve my-org/CLI-AB", + "Mark an issue as unresolved. Inverse of `sentry issue resolve`.", + examples: [ + { + description: "Reopen a resolved issue", + command: "sentry issue unresolve CLI-G5", + }, + { + description: "`reopen` is an alias for `unresolve`", + command: "sentry issue reopen CLI-G5", + }, + { + description: "Reopen an issue in an explicit organization", + command: "sentry issue unresolve my-org/CLI-G5", + }, + ], }, output: { human: formatUnresolved, diff --git a/packages/cli/src/commands/issue/view.ts b/packages/cli/src/commands/issue/view.ts index 1ef587fcb..a69e684c4 100644 --- a/packages/cli/src/commands/issue/view.ts +++ b/packages/cli/src/commands/issue/view.ts @@ -256,6 +256,62 @@ export const viewCommand = buildCommand({ `With --web, up to ${MAX_WEB_ISSUES} issues open by default; pass --force to open all.\n\n` + "In multi-project mode (after 'issue list'), use alias-suffix format (e.g., 'f-g' " + "where 'f' is the project alias shown in the list).", + examples: [ + { description: "View an issue", command: "sentry issue view FRONT-ABC" }, + { + description: "View the most recent issue", + command: "sentry issue view @latest", + }, + { + description: "View several issues (space-separated, not commas)", + command: "sentry issue view FRONT-ABC BACK-2", + }, + { + description: "Select an organization explicitly", + command: "sentry issue view my-org/FRONT-ABC", + }, + { + description: + 'Use a GitHub-style identifier (the "#" replaces the final slash)', + command: "sentry issue view my-org/my-project#FRONT-ABC", + }, + { + description: "Open issues in the browser (up to 5 tabs by default)", + command: "sentry issue view FRONT-ABC BACK-2 -w", + }, + { + description: "Allow more than 5 browser tabs", + command: + "sentry issue view FRONT-ABC BACK-2 API-3 WEB-4 IOS-5 OPS-6 -w --force", + }, + { + description: + "Full JSON (issue fields + latest event + trace/replay context)", + command: "sentry issue view FRONT-ABC --json", + }, + { + description: "Select top-level fields to keep output small", + command: + "sentry issue view FRONT-ABC --json --fields shortId,title,culprit,count,userCount,permalink", + }, + { + description: + "Select fields from the latest event instead of the whole event", + command: + "sentry issue view FRONT-ABC --json --fields event.id,event.title,event.dateCreated", + }, + { + description: "Extract the request URL and method from the latest event", + command: + "sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == \"request\") | .data | {url, method}'", + }, + { + description: + "Extract the exception type and value from the latest event", + command: + "sentry issue view FRONT-ABC --json | jq '.event.entries[] | select(.type == \"exception\") | .data.values[0] | {type, value}'", + }, + ], }, output: { human: formatIssueView, diff --git a/packages/cli/src/commands/local/run.ts b/packages/cli/src/commands/local/run.ts index 0ed949819..a89395d02 100644 --- a/packages/cli/src/commands/local/run.ts +++ b/packages/cli/src/commands/local/run.ts @@ -394,10 +394,17 @@ export const runCommand = buildCommand({ "framework-prefixed client variants (NEXT_PUBLIC_, VITE_, etc.), and\n" + "SENTRY_TRACES_SAMPLE_RATE=1. Use --format json to stream versioned\n" + "NDJSON observations to stdout for agents. Use --open to launch the\n" + - "Sentry Local UI.\n\n" + - "Example:\n" + - " sentry local run -- npm run dev\n" + - " sentry local run -- python manage.py runserver", + "Sentry Local UI.", + examples: [ + { + description: "Run a Node.js dev server with the local server enabled", + command: "sentry local run -- npm run dev", + }, + { + description: "Run a Django dev server with the local server enabled", + command: "sentry local run -- python manage.py runserver", + }, + ], }, parameters: { positional: { diff --git a/packages/cli/src/commands/local/server.ts b/packages/cli/src/commands/local/server.ts index 2f36982e5..7635fd6d0 100644 --- a/packages/cli/src/commands/local/server.ts +++ b/packages/cli/src/commands/local/server.ts @@ -998,6 +998,21 @@ export const serverCommand = buildCommand({ "as an SSE consumer and tails events from it. Otherwise it starts\n" + "its own server. Use --open to launch the Sentry Local UI.\n\n" + "Press Ctrl-C to stop.", + examples: [ + { + description: "Start the server and tail events", + command: "sentry local", + }, + { description: "Use a custom port", command: "sentry local --port 9000" }, + { + description: "Only show errors and logs (filter out transactions)", + command: "sentry local -f error -f log", + }, + { + description: "Suppress per-envelope tail output", + command: "sentry local --quiet", + }, + ], }, parameters: { flags: { diff --git a/packages/cli/src/commands/log/list.ts b/packages/cli/src/commands/log/list.ts index 46eeec7af..6539621c7 100644 --- a/packages/cli/src/commands/log/list.ts +++ b/packages/cli/src/commands/log/list.ts @@ -712,14 +712,47 @@ export const listCommand = buildListCommand( "Trace filtering:\n" + " sentry log list # Filter by trace (auto-detect org)\n" + " sentry log list / # Filter by trace (explicit org)\n\n" + - "Examples:\n" + - " sentry log list # List last 100 logs\n" + - " sentry log list -f # Stream logs (2s poll interval)\n" + - " sentry log list -f 5 # Stream logs (5s poll interval)\n" + - " sentry log list --limit 50 # Show last 50 logs\n" + - " sentry log list -q 'severity:error' # Filter to errors only\n" + - " sentry log list abc123def456abc123def456abc123de # Filter by trace\n\n" + "Alias: `sentry logs` → `sentry log list`", + examples: [ + { description: "List the last 100 logs", command: "sentry log list" }, + { + description: "Show only error logs", + command: "sentry log list -q 'severity:error'", + }, + { + description: "Filter by message content", + command: "sentry log list -q 'database'", + }, + { + description: "Match a regular expression (key://pattern//)", + command: "sentry log list -q 'message://^Timeout after \\d+ms//'", + }, + { + description: "Show the last 50 logs", + command: "sentry log list --limit 50", + }, + { + description: "List logs for a trace", + command: "sentry log list abc123def456abc123def456abc12345", + }, + { + description: "Stream logs (2-second poll interval)", + command: "sentry log list -f", + }, + { + description: "Stream logs (5-second poll interval)", + command: "sentry log list -f 5", + }, + { + description: "Stream error logs from a specific project", + command: "sentry log list my-org/backend -f -q 'severity:error'", + }, + { + description: "Filter JSON output with jq", + command: + "sentry log list --json | jq '.data[] | select(.severity == \"error\")'", + }, + ], }, output: { human: createLogRenderer, diff --git a/packages/cli/src/commands/log/view.ts b/packages/cli/src/commands/log/view.ts index ddfbfd296..661fffe6e 100644 --- a/packages/cli/src/commands/log/view.ts +++ b/packages/cli/src/commands/log/view.ts @@ -570,6 +570,21 @@ export const viewCommand = buildCommand({ "Multiple log IDs can be passed as separate arguments or newline-separated\n" + "within a single argument (handy when piping from other commands).\n\n" + "The log ID is the 32-character hexadecimal identifier shown in log listings.", + examples: [ + { + description: "View a log entry", + command: "sentry log view 968c763c740cfda8b6728f27fb9e9b01", + }, + { + description: "Specify the project explicitly", + command: + "sentry log view my-org/backend 968c763c740cfda8b6728f27fb9e9b01", + }, + { + description: "Open in the browser", + command: "sentry log view 968c763c740cfda8b6728f27fb9e9b01 -w", + }, + ], }, output: { human: formatLogViewHuman, diff --git a/packages/cli/src/commands/monitor/list.ts b/packages/cli/src/commands/monitor/list.ts index 17d8cad70..537c419ea 100644 --- a/packages/cli/src/commands/monitor/list.ts +++ b/packages/cli/src/commands/monitor/list.ts @@ -83,12 +83,22 @@ const docs: OrgListCommandDocs = { "Pagination:\n" + " sentry monitor list / -c next # fetch next page\n" + " sentry monitor list / -c prev # fetch previous page\n\n" + - "Examples:\n" + - " sentry monitor list # auto-detect or list all\n" + - " sentry monitor list my-org/ # list monitors in my-org (paginated)\n" + - " sentry monitor list --limit 10\n" + - " sentry monitor list --json\n\n" + "Alias: `sentry monitors` → `sentry monitor list`", + examples: [ + { + description: "List monitors (organization auto-detected)", + command: "sentry monitor list", + }, + { + description: "List cron monitors in an organization", + command: "sentry monitor list my-org/", + }, + { + description: "Fetch the next page", + command: "sentry monitor list my-org/ -c next", + }, + { description: "Output as JSON", command: "sentry monitor list --json" }, + ], }; export const listCommand = buildOrgListCommand( diff --git a/packages/cli/src/commands/monitor/run.ts b/packages/cli/src/commands/monitor/run.ts index 502c8fc63..2d0ff197a 100644 --- a/packages/cli/src/commands/monitor/run.ts +++ b/packages/cli/src/commands/monitor/run.ts @@ -173,6 +173,23 @@ sentry monitor run nightly-job -s "0 0 * * *" --max-runtime 30 --timezone UTC -- \`\`\` The wrapped command receives the \`SENTRY_MONITOR_SLUG\` environment variable.`, + examples: [ + { + description: "Wrap a command with cron monitor check-ins (DSN-based)", + command: + "SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 sentry monitor run nightly-job -- python manage.py cron", + }, + { + description: + "The -- separator is optional when the command has no flags", + command: "sentry monitor run nightly-job npm run task", + }, + { + description: "Create or update the monitor on the first check-in", + command: + 'sentry monitor run nightly-job -s "0 0 * * *" --max-runtime 30 --timezone UTC -- ./backup.sh', + }, + ], }, auth: "dsn", parameters: { diff --git a/packages/cli/src/commands/org/list.ts b/packages/cli/src/commands/org/list.ts index ccc5e43f7..11cea5aff 100644 --- a/packages/cli/src/commands/org/list.ts +++ b/packages/cli/src/commands/org/list.ts @@ -415,15 +415,28 @@ export const listCommand = buildCommand({ "Pass a filter to only list organizations whose slug or name matches it,\n" + "ignoring case: exactly, as a prefix or substring, or with a small typo\n" + "(best matches first), or as a glob like 'acme-*'.\n\n" + - "Examples:\n" + - " sentry org list\n" + - " sentry org list acme\n" + - " sentry org list 'acme-*'\n" + - " sentry org list --limit 10\n" + - " sentry org list --account jane@example.com\n" + - " sentry org list -a jane@example.com:sentry.example.com\n" + - " sentry org list --json\n\n" + "Alias: `sentry orgs` → `sentry org list`", + examples: [ + { description: "List organizations", command: "sentry org list" }, + { + description: + "Only organizations whose slug or name matches (fuzzy, best matches first)", + command: "sentry org list acme", + }, + { + description: "Only organizations matching a glob", + command: "sentry org list 'acme-*'", + }, + { + description: "Only one account's organizations", + command: "sentry org list --account jane@acme.com", + }, + { + description: "Same email on several servers: add the server", + command: "sentry org list -a jane@example.com:sentry.io", + }, + { description: "Output as JSON", command: "sentry org list --json" }, + ], }, output: { human: formatOrgListHuman }, parameters: { diff --git a/packages/cli/src/commands/org/view.ts b/packages/cli/src/commands/org/view.ts index c8b6fc261..7228efff5 100644 --- a/packages/cli/src/commands/org/view.ts +++ b/packages/cli/src/commands/org/view.ts @@ -36,6 +36,16 @@ export const viewCommand = buildCommand({ " 1. Positional argument \n" + " 2. Config defaults\n" + " 3. SENTRY_DSN environment variable or source code detection", + examples: [ + { + description: "View organization details", + command: "sentry org view my-org", + }, + { + description: "Open in the browser", + command: "sentry org view my-org -w", + }, + ], }, output: { human: formatOrgDetails }, parameters: { diff --git a/packages/cli/src/commands/platform/list.ts b/packages/cli/src/commands/platform/list.ts index eb8f35dcf..0ba9beac5 100644 --- a/packages/cli/src/commands/platform/list.ts +++ b/packages/cli/src/commands/platform/list.ts @@ -38,11 +38,18 @@ export const listCommand = buildCommand({ brief: "List all valid Sentry platform identifiers", fullDescription: "List every valid Sentry platform identifier — the full set behind " + - "`sentry project create :`. Use --search to filter.\n\n" + - "Examples:\n" + - " sentry platform list List all valid platforms\n" + - " sentry platform list --search python Filter by substring\n" + - " sentry platform list --json Machine-readable output", + "`sentry project create :`. Use --search to filter.", + examples: [ + { + description: "List all valid Sentry platform identifiers", + command: "sentry platform list", + }, + { + description: "Filter by substring", + command: "sentry platform list --search python", + }, + { description: "Output as JSON", command: "sentry platform list --json" }, + ], }, output: { human: formatPlatformsHuman, diff --git a/packages/cli/src/commands/proguard/upload.ts b/packages/cli/src/commands/proguard/upload.ts index 97632cc2f..740f09712 100644 --- a/packages/cli/src/commands/proguard/upload.ts +++ b/packages/cli/src/commands/proguard/upload.ts @@ -163,6 +163,25 @@ export const uploadCommand = buildCommand({ " sentry proguard upload mapping.txt --uuid 5db7294d-87fc-5726-a5c0-4a90679657a5\n" + " sentry proguard upload mapping.txt --no-upload\n" + " sentry proguard upload mapping.txt --json", + examples: [ + { + description: "Upload a ProGuard/R8 mapping file", + command: + "sentry proguard upload ./app/build/outputs/mapping/release/mapping.txt", + }, + { + description: "Upload multiple mapping files", + command: "sentry proguard upload mapping-release.txt mapping-debug.txt", + }, + { + description: "Validate without uploading", + command: "sentry proguard upload mapping.txt --no-upload", + }, + { + description: "Fail if no mapping files are found (useful in CI)", + command: "sentry proguard upload ./mapping/ --require-one", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/proguard/uuid.ts b/packages/cli/src/commands/proguard/uuid.ts index de9de27a8..664bc12f4 100644 --- a/packages/cli/src/commands/proguard/uuid.ts +++ b/packages/cli/src/commands/proguard/uuid.ts @@ -31,6 +31,17 @@ export const uuidCommand = buildCommand({ "Usage:\n" + " sentry proguard uuid ./app/build/outputs/mapping/release/mapping.txt\n" + " sentry proguard uuid mapping.txt --json", + examples: [ + { + description: "Compute the UUID for a ProGuard/R8 mapping file", + command: + "sentry proguard uuid ./app/build/outputs/mapping/release/mapping.txt", + }, + { + description: "Output as JSON (includes the file path)", + command: "sentry proguard uuid mapping.txt --json", + }, + ], }, // Purely local file operation — no Sentry API calls, no auth needed. auth: false, diff --git a/packages/cli/src/commands/project/create.ts b/packages/cli/src/commands/project/create.ts index 9032726b8..36bde4a9b 100644 --- a/packages/cli/src/commands/project/create.ts +++ b/packages/cli/src/commands/project/create.ts @@ -616,13 +616,31 @@ export const createCommand = buildCommand({ "by passing multiple pairs as separate arguments. All projects share one org.\n\n" + "Projects are created under a team. Without --team, a default team is\n" + "chosen: your teams first, preferring ones you administer, then the oldest.\n" + - "If no teams exist, one is created.\n\n" + - "Examples:\n" + - " sentry project create my-app:node\n" + - " sentry project create acme-corp/my-app:javascript-nextjs\n" + - " sentry project create web:javascript api:python-django worker:node\n" + - " sentry project create my-app:python-django --team backend\n" + - " sentry project create my-app:go --json", + "If no teams exist, one is created.", + examples: [ + { + description: "Create a project (every project is a name:platform pair)", + command: "sentry project create my-new-app:javascript-nextjs", + }, + { + description: "Create several projects with their own platforms", + command: + "sentry project create web:javascript api:python-django worker:node", + }, + { + description: "Create under a specific organization and team", + command: + "sentry project create my-org/my-new-app:python --team backend-team", + }, + { + description: "Preview without creating", + command: "sentry project create my-new-app:node --dry-run", + }, + { + description: "Output the created project as JSON", + command: "sentry project create my-app:go --json", + }, + ], }, output: { human: formatProjectCreateOutput, diff --git a/packages/cli/src/commands/project/delete.ts b/packages/cli/src/commands/project/delete.ts index 3598d0554..e31d45c84 100644 --- a/packages/cli/src/commands/project/delete.ts +++ b/packages/cli/src/commands/project/delete.ts @@ -135,13 +135,21 @@ export const deleteCommand = buildDeleteCommand({ brief: "Delete a project", fullDescription: "Permanently delete a Sentry project. This action cannot be undone.\n\n" + - "Requires explicit target — auto-detection is disabled for safety.\n\n" + - "Examples:\n" + - " sentry project delete acme-corp/my-app\n" + - " sentry project delete my-app\n" + - " sentry project delete acme-corp/my-app --yes\n" + - " sentry project delete acme-corp/my-app --force\n" + - " sentry project delete acme-corp/my-app --dry-run", + "Requires explicit target — auto-detection is disabled for safety.", + examples: [ + { + description: "Delete a project (prompts for confirmation)", + command: "sentry project delete my-org/old-project", + }, + { + description: "Delete without confirmation", + command: "sentry project delete my-org/old-project --yes", + }, + { + description: "Preview the deletion", + command: "sentry project delete my-org/old-project --dry-run", + }, + ], }, output: { human: formatProjectDeleted, diff --git a/packages/cli/src/commands/project/list.ts b/packages/cli/src/commands/project/list.ts index de3fae11e..9a4734f48 100644 --- a/packages/cli/src/commands/project/list.ts +++ b/packages/cli/src/commands/project/list.ts @@ -714,6 +714,20 @@ export const listCommand = buildListCommand("project", { " sentry project list --limit 50 # show more results\n" + " sentry project list --json # output as JSON\n\n" + "Alias: `sentry projects` → `sentry project list`", + examples: [ + { + description: "List all projects in an organization", + command: "sentry project list my-org/", + }, + { + description: "Several projects in the same organization", + command: "sentry project list my-org/frontend,backend", + }, + { + description: "Filter by platform", + command: "sentry project list my-org/ --platform javascript", + }, + ], }, output: { human: (data: ListResult) => { diff --git a/packages/cli/src/commands/project/view.ts b/packages/cli/src/commands/project/view.ts index aa4e2bb5f..37bbd31a9 100644 --- a/packages/cli/src/commands/project/view.ts +++ b/packages/cli/src/commands/project/view.ts @@ -268,6 +268,16 @@ export const viewCommand = buildCommand({ " sentry project view # find project across all orgs\n\n" + `${TARGET_PATTERN_NOTE}\n\n` + "In monorepos with multiple Sentry projects, shows details for all detected projects.", + examples: [ + { + description: "View project details", + command: "sentry project view my-org/frontend", + }, + { + description: "Open the project in the browser", + command: "sentry project view my-org/frontend -w", + }, + ], }, output: { human: formatProjectViewHuman, diff --git a/packages/cli/src/commands/react-native/gradle.ts b/packages/cli/src/commands/react-native/gradle.ts index c19c848cb..26aa731c9 100644 --- a/packages/cli/src/commands/react-native/gradle.ts +++ b/packages/cli/src/commands/react-native/gradle.ts @@ -130,6 +130,19 @@ export const gradleCommand = buildCommand({ "Use `--wait`/`--wait-for` to block until the server finishes processing " + "the upload. Indexed/file RAM bundles (a pre-Hermes format) are not " + "supported; use a plain or Hermes bundle.", + examples: [ + { + description: + "Upload a bundle and sourcemap by debug ID (called by the Gradle plugin)", + command: + "sentry react-native gradle --bundle index.android.bundle --sourcemap index.android.bundle.map", + }, + { + description: "Also associate with a release and distribution", + command: + "sentry react-native gradle --bundle index.android.bundle --sourcemap index.android.bundle.map --release com.example.app@1.0.0 --dist 1000", + }, + ], }, output: { human: formatGradleResult, diff --git a/packages/cli/src/commands/react-native/xcode.ts b/packages/cli/src/commands/react-native/xcode.ts index 05dd18bcd..338298fdd 100644 --- a/packages/cli/src/commands/react-native/xcode.ts +++ b/packages/cli/src/commands/react-native/xcode.ts @@ -432,6 +432,13 @@ export const xcodeCommand = buildCommand({ "app Info.plist (unless `--no-auto-release`); outside an Xcode build the " + "release is discovered via `xcodebuild`. Use `--wait`/`--wait-for` to " + "block until the server finishes processing the upload.", + examples: [ + { + description: + "Run as the Xcode build phase (usually added automatically to your build script)", + command: "sentry react-native xcode", + }, + ], }, auth: false, output: { diff --git a/packages/cli/src/commands/release/archive.ts b/packages/cli/src/commands/release/archive.ts index 4b474ad4e..44faac56a 100644 --- a/packages/cli/src/commands/release/archive.ts +++ b/packages/cli/src/commands/release/archive.ts @@ -52,11 +52,22 @@ export const archiveCommand = buildCommand({ fullDescription: "Mark a release as archived. Archived releases are hidden from the " + "default `sentry release list` but are retained and can be restored " + - "with `sentry release restore`.\n\n" + - "Examples:\n" + - " sentry release archive 1.0.0\n" + - " sentry release archive my-org/1.0.0\n" + - " sentry release archive 1.0.0 --dry-run", + "with `sentry release restore`.", + examples: [ + { + description: + "Archive a release (hide it from the default list, but keep it)", + command: "sentry release archive 1.0.0", + }, + { + description: "Archive a release in an explicit organization", + command: "sentry release archive my-org/1.0.0", + }, + { + description: "Preview without archiving", + command: "sentry release archive my-org/1.0.0 --dry-run", + }, + ], }, output: { human: formatReleaseArchived, diff --git a/packages/cli/src/commands/release/create.ts b/packages/cli/src/commands/release/create.ts index fe93cfdfb..9b326585e 100644 --- a/packages/cli/src/commands/release/create.ts +++ b/packages/cli/src/commands/release/create.ts @@ -48,16 +48,38 @@ export const createCommand = buildCommand({ "Create a new Sentry release.\n\n" + "The version must match the `release` value in Sentry.init().\n" + "Use `org/version` to specify the org — the `org/` prefix is the org slug, not\n" + - "part of the version. E.g., `sentry/1.0.0` means org=sentry, version=1.0.0.\n\n" + - "Examples:\n" + - " sentry release create 1.0.0\n" + - " sentry release create my-org/1.0.0\n" + - " sentry release create 1.0.0 --project my-project\n" + - " sentry release create 1.0.0 --project proj-a,proj-b\n" + - " sentry release create 1.0.0 --finalize\n" + - " sentry release create 1.0.0 --ref main\n" + - " sentry release create 1.0.0 --url https://github.com/org/repo/releases/tag/1.0.0\n" + - " sentry release create 1.0.0 --dry-run", + "part of the version. E.g., `sentry/1.0.0` means org=sentry, version=1.0.0.", + examples: [ + { + description: "Create a release", + command: "sentry release create 1.0.0", + }, + { + description: "Create a release in an explicit organization", + command: "sentry release create my-org/1.0.0", + }, + { + description: "Create and finalize a release", + command: "sentry release create 1.0.0 --finalize", + }, + { + description: "Create a release for specific projects", + command: "sentry release create 1.0.0 --project proj-a,proj-b", + }, + { + description: "Create a release from a proposed version", + command: "sentry release create $(sentry release propose-version)", + }, + { + description: "Set the release ref and URL", + command: + "sentry release create 1.0.0 --ref main --url https://github.com/org/repo/releases/tag/1.0.0", + }, + { + description: "Preview without creating", + command: "sentry release create 1.0.0 --dry-run", + }, + ], }, output: { human: (data: Record) => { diff --git a/packages/cli/src/commands/release/delete.ts b/packages/cli/src/commands/release/delete.ts index 12f4b1000..5a28df3b6 100644 --- a/packages/cli/src/commands/release/delete.ts +++ b/packages/cli/src/commands/release/delete.ts @@ -82,13 +82,21 @@ type DeleteFlags = { export const deleteCommand = buildDeleteCommand({ docs: { brief: "Delete a release", - fullDescription: - "Permanently delete a Sentry release.\n\n" + - "Examples:\n" + - " sentry release delete 1.0.0\n" + - " sentry release delete my-org/1.0.0\n" + - " sentry release delete 1.0.0 --yes\n" + - " sentry release delete 1.0.0 --dry-run", + fullDescription: "Permanently delete a Sentry release.", + examples: [ + { + description: "Delete a release (prompts for confirmation)", + command: "sentry release delete my-org/1.0.0", + }, + { + description: "Skip confirmation", + command: "sentry release delete my-org/1.0.0 --yes", + }, + { + description: "Preview without deleting", + command: "sentry release delete my-org/1.0.0 --dry-run", + }, + ], }, output: { human: formatReleaseDeleted, diff --git a/packages/cli/src/commands/release/deploy.ts b/packages/cli/src/commands/release/deploy.ts index f47d498b0..93bc22d26 100644 --- a/packages/cli/src/commands/release/deploy.ts +++ b/packages/cli/src/commands/release/deploy.ts @@ -87,13 +87,30 @@ export const deployCommand = buildCommand({ docs: { brief: "Create a deploy for a release", fullDescription: - "Create a deploy record for a release in a specific environment.\n\n" + - "Examples:\n" + - " sentry release deploy 1.0.0 production\n" + - ' sentry release deploy my-org/1.0.0 staging "Deploy #42"\n' + - " sentry release deploy 1.0.0 production --url https://example.com\n" + - " sentry release deploy 1.0.0 production --time 120\n" + - " sentry release deploy 1.0.0 production --dry-run", + "Create a deploy record for a release in a specific environment.", + examples: [ + { + description: "Create a deploy", + command: "sentry release deploy 1.0.0 production", + }, + { + description: "Create a named deploy in an explicit organization", + command: 'sentry release deploy my-org/1.0.0 staging "Deploy #42"', + }, + { + description: "Attach a deploy URL", + command: + "sentry release deploy 1.0.0 production --url https://example.com", + }, + { + description: "Record a deploy duration in seconds", + command: "sentry release deploy 1.0.0 production --time 120", + }, + { + description: "Preview without creating", + command: "sentry release deploy 1.0.0 production --dry-run", + }, + ], }, output: { human: formatDeployCreated, diff --git a/packages/cli/src/commands/release/deploys.ts b/packages/cli/src/commands/release/deploys.ts index e8cb9f954..33c4884ee 100644 --- a/packages/cli/src/commands/release/deploys.ts +++ b/packages/cli/src/commands/release/deploys.ts @@ -35,12 +35,21 @@ function formatDeployList(deploys: SentryDeploy[]): string { export const deploysCommand = buildCommand({ docs: { brief: "List deploys for a release", - fullDescription: - "List all deploys recorded for a specific release.\n\n" + - "Examples:\n" + - " sentry release deploys 1.0.0\n" + - " sentry release deploys my-org/1.0.0\n" + - " sentry release deploys 1.0.0 --json", + fullDescription: "List all deploys recorded for a specific release.", + examples: [ + { + description: "List deploys for a release", + command: "sentry release deploys 1.0.0", + }, + { + description: "List deploys for a release in an explicit organization", + command: "sentry release deploys my-org/1.0.0", + }, + { + description: "Output as JSON", + command: "sentry release deploys 1.0.0 --json", + }, + ], }, output: { human: formatDeployList, diff --git a/packages/cli/src/commands/release/finalize.ts b/packages/cli/src/commands/release/finalize.ts index f74c19b10..3d2b625a7 100644 --- a/packages/cli/src/commands/release/finalize.ts +++ b/packages/cli/src/commands/release/finalize.ts @@ -43,13 +43,26 @@ function formatReleaseFinalized(data: Record): string { export const finalizeCommand = buildCommand({ docs: { brief: "Finalize a release", - fullDescription: - "Mark a release as finalized by setting its release date.\n\n" + - "Examples:\n" + - " sentry release finalize 1.0.0\n" + - " sentry release finalize my-org/1.0.0\n" + - " sentry release finalize 1.0.0 --released 2025-01-01T00:00:00Z\n" + - " sentry release finalize 1.0.0 --dry-run", + fullDescription: "Mark a release as finalized by setting its release date.", + examples: [ + { + description: "Finalize a release", + command: "sentry release finalize 1.0.0", + }, + { + description: "Finalize a release in an explicit organization", + command: "sentry release finalize my-org/1.0.0", + }, + { + description: "Set a custom release timestamp", + command: + "sentry release finalize 1.0.0 --released 2025-01-01T00:00:00Z", + }, + { + description: "Preview without finalizing", + command: "sentry release finalize 1.0.0 --dry-run", + }, + ], }, output: { human: formatReleaseFinalized, diff --git a/packages/cli/src/commands/release/list.ts b/packages/cli/src/commands/release/list.ts index 7a24cf605..0b4a65ebe 100644 --- a/packages/cli/src/commands/release/list.ts +++ b/packages/cli/src/commands/release/list.ts @@ -648,15 +648,34 @@ export const listCommand = buildListCommand("release", { "Pagination:\n" + " sentry release list / -c next # fetch next page\n" + " sentry release list / -c prev # fetch previous page\n\n" + - "Examples:\n" + - " sentry release list # auto-detect project\n" + - " sentry release list my-org/ # all releases in org\n" + - " sentry release list my-org/my-proj # project-scoped\n" + - " sentry release list --sort cfs # sort by crash-free sessions\n" + - " sentry release list --environment production # filter by env\n" + - " sentry release list --period 7d # last 7 days of health data\n" + - " sentry release list --json\n\n" + "Alias: `sentry releases` → `sentry release list`", + examples: [ + { + description: "List releases (project auto-detected)", + command: "sentry release list", + }, + { + description: "List all releases in an organization", + command: "sentry release list my-org/", + }, + { + description: "List releases for one project", + command: "sentry release list my-org/my-project", + }, + { + description: "Sort by crash-free sessions", + command: "sentry release list --sort cfs", + }, + { + description: "Filter by environment", + command: "sentry release list --environment production", + }, + { + description: "Show the last 7 days of health data", + command: "sentry release list --period 7d", + }, + { description: "Output as JSON", command: "sentry release list --json" }, + ], }, output: { human: formatListHuman, diff --git a/packages/cli/src/commands/release/propose-version.ts b/packages/cli/src/commands/release/propose-version.ts index 53ab09f31..070f5ad4f 100644 --- a/packages/cli/src/commands/release/propose-version.ts +++ b/packages/cli/src/commands/release/propose-version.ts @@ -83,10 +83,17 @@ export const proposeVersionCommand = buildCommand({ " 14. TRAVIS_COMMIT (Travis CI)\n" + " 15. Git HEAD SHA (fallback)\n\n" + "Useful in CI scripts:\n" + - " sentry release create $(sentry release propose-version)\n\n" + - "Examples:\n" + - " sentry release propose-version\n" + - " sentry release propose-version --json", + " sentry release create $(sentry release propose-version)", + examples: [ + { + description: "Propose a version from git HEAD", + command: "sentry release propose-version", + }, + { + description: "Output as JSON", + command: "sentry release propose-version --json", + }, + ], }, output: { human: formatProposedVersion, diff --git a/packages/cli/src/commands/release/restore.ts b/packages/cli/src/commands/release/restore.ts index 261ad41a9..d354d0396 100644 --- a/packages/cli/src/commands/release/restore.ts +++ b/packages/cli/src/commands/release/restore.ts @@ -50,11 +50,21 @@ export const restoreCommand = buildCommand({ brief: "Restore an archived release", fullDescription: "Restore an archived release by setting its status back to open, " + - "making it visible in the default `sentry release list` again.\n\n" + - "Examples:\n" + - " sentry release restore 1.0.0\n" + - " sentry release restore my-org/1.0.0\n" + - " sentry release restore 1.0.0 --dry-run", + "making it visible in the default `sentry release list` again.", + examples: [ + { + description: "Restore a previously archived release", + command: "sentry release restore 1.0.0", + }, + { + description: "Restore a release in an explicit organization", + command: "sentry release restore my-org/1.0.0", + }, + { + description: "Preview without restoring", + command: "sentry release restore 1.0.0 --dry-run", + }, + ], }, output: { human: formatReleaseRestored, diff --git a/packages/cli/src/commands/release/set-commits.ts b/packages/cli/src/commands/release/set-commits.ts index f9b0c4218..fea3bb954 100644 --- a/packages/cli/src/commands/release/set-commits.ts +++ b/packages/cli/src/commands/release/set-commits.ts @@ -360,16 +360,39 @@ export const setCommitsCommand = buildCommand({ "whole range (--initial-depth does not apply), and combines with --path to\n" + "scope a monorepo release to the files that changed since the last release.\n" + "Like --path, it cannot be combined with --auto or --commit. Requires a\n" + - "full (non-shallow) checkout spanning the range.\n\n" + - "Examples:\n" + - " sentry release set-commits 1.0.0 --auto\n" + - " sentry release set-commits my-org/1.0.0 --local\n" + - " sentry release set-commits 1.0.0 --local --initial-depth 50\n" + - " sentry release set-commits 1.0.0 --path apps/mobile,packages/shared-ui\n" + - " sentry release set-commits 1.0.0 --from v0.9.0\n" + - " sentry release set-commits 1.0.0 --from v0.9.0 --path apps/mobile,apps/shared\n" + - " sentry release set-commits 1.0.0 --commit owner/repo@abc123..def456\n" + - " sentry release set-commits 1.0.0 --clear", + "full (non-shallow) checkout spanning the range.", + examples: [ + { + description: "Associate commits using the repository integration", + command: "sentry release set-commits 1.0.0 --auto", + }, + { + description: "Set commits from local git history", + command: "sentry release set-commits my-org/1.0.0 --local", + }, + { + description: "Read up to 50 local commits", + command: "sentry release set-commits 1.0.0 --local --initial-depth 50", + }, + { + description: "Only include commits that touch specific paths", + command: + "sentry release set-commits 1.0.0 --path apps/mobile,packages/shared-ui", + }, + { + description: "Read local commits since a previous release tag", + command: "sentry release set-commits 1.0.0 --from v0.9.0", + }, + { + description: "Set an explicit commit range", + command: + "sentry release set-commits 1.0.0 --commit owner/repo@abc123..def456", + }, + { + description: "Clear the release's commits", + command: "sentry release set-commits 1.0.0 --clear", + }, + ], }, output: { human: formatCommitsSet, diff --git a/packages/cli/src/commands/release/view.ts b/packages/cli/src/commands/release/view.ts index c819e5533..4214806ad 100644 --- a/packages/cli/src/commands/release/view.ts +++ b/packages/cli/src/commands/release/view.ts @@ -162,12 +162,25 @@ export const viewCommand = buildCommand({ brief: "View release details with health metrics", fullDescription: "Show detailed information about a Sentry release, including\n" + - "per-project adoption and crash-free metrics.\n\n" + - "Examples:\n" + - " sentry release view 1.0.0\n" + - " sentry release view my-org/1.0.0\n" + - ' sentry release view "sentry-cli@0.24.0"\n' + - " sentry release view 1.0.0 --json", + "per-project adoption and crash-free metrics.", + examples: [ + { + description: "View release details", + command: "sentry release view 1.0.0", + }, + { + description: "View a release in an explicit organization", + command: "sentry release view my-org/1.0.0", + }, + { + description: "View a release whose version contains a package name", + command: 'sentry release view "sentry-cli@0.24.0"', + }, + { + description: "Output as JSON", + command: "sentry release view 1.0.0 --json", + }, + ], }, output: { human: formatReleaseDetails, diff --git a/packages/cli/src/commands/replay/download.ts b/packages/cli/src/commands/replay/download.ts index d26a44780..996e30840 100644 --- a/packages/cli/src/commands/replay/download.ts +++ b/packages/cli/src/commands/replay/download.ts @@ -57,12 +57,25 @@ export const downloadCommand = buildCommand({ " - auto-detect org from config or DSN\n" + " / - explicit organization\n" + " // - explicit org/project context\n" + - " - parse org and replay ID from a Sentry URL\n\n" + - "Examples:\n" + - " sentry replay download 346789a703f6454384f1de473b8b9fcc\n" + - " sentry replay download sentry/346789a703f6454384f1de473b8b9fcc\n" + - " sentry replay download sentry/346789a703f6454384f1de473b8b9fcc --output ./replay.json\n" + - " sentry replay download https://sentry.io/organizations/sentry/explore/replays/346789a703f6454384f1de473b8b9fcc/", + " - parse org and replay ID from a Sentry URL", + examples: [ + { + description: + "Download a replay as rrweb JSON to ./.rrweb.json", + command: + "sentry replay download my-org/346789a703f6454384f1de473b8b9fcc", + }, + { + description: "Choose where the file goes", + command: + "sentry replay download my-org/346789a703f6454384f1de473b8b9fcc --output ./replay.json", + }, + { + description: "Download from a replay URL", + command: + "sentry replay download https://sentry.io/organizations/my-org/explore/replays/346789a703f6454384f1de473b8b9fcc/", + }, + ], }, output: { human: formatReplayDownloadResult, diff --git a/packages/cli/src/commands/replay/list.ts b/packages/cli/src/commands/replay/list.ts index 47eeed5aa..74266fe99 100644 --- a/packages/cli/src/commands/replay/list.ts +++ b/packages/cli/src/commands/replay/list.ts @@ -259,15 +259,51 @@ export const listCommand = buildListCommand("replay", { " sentry replay list / # list replays for one project\n" + " sentry replay list # find project across all orgs\n\n" + `${targetPatternExplanation()}\n\n` + - "Examples:\n" + - " sentry replay list\n" + - " sentry replay list sentry/\n" + - " sentry replay list sentry/cli --limit 50\n" + - " sentry replay list sentry/cli --sort duration\n" + - ' sentry replay list sentry/cli -q "user.email:foo@example.com"\n' + - " sentry replay list sentry/cli -e production -e canary\n" + - " sentry replay list sentry/cli --period 24h\n\n" + "Alias: `sentry replays` → `sentry replay list`", + examples: [ + { + description: "List recent replays (project auto-detected)", + command: "sentry replay list", + }, + { + description: "List recent replays for a project", + command: "sentry replay list my-org/frontend", + }, + { + description: "Search across all projects in an organization", + command: 'sentry replay list my-org/ --query "environment:production"', + }, + { + description: "Change the time window and sort", + command: + "sentry replay list my-org/frontend --period 24h --sort errors", + }, + { + description: "Find replays for a user", + command: + 'sentry replay list my-org/frontend -q "user.email:foo@example.com"', + }, + { + description: "Filter by environments", + command: "sentry replay list my-org/frontend -e production -e canary", + }, + { + description: "Show more results", + command: "sentry replay list my-org/frontend --limit 50", + }, + { + description: "Fetch the next page", + command: "sentry replay list my-org/frontend -c next", + }, + { + description: "Fetch the previous page", + command: "sentry replay list my-org/frontend -c prev", + }, + { + description: "Output as JSON", + command: "sentry replay list my-org/frontend --json", + }, + ], }, output: { human: formatReplayListHuman, diff --git a/packages/cli/src/commands/replay/view.ts b/packages/cli/src/commands/replay/view.ts index 85df327b2..ee2e5132e 100644 --- a/packages/cli/src/commands/replay/view.ts +++ b/packages/cli/src/commands/replay/view.ts @@ -347,13 +347,38 @@ export const viewCommand = buildCommand({ " - auto-detect org from config or DSN\n" + " / - explicit organization\n" + " // - explicit org/project context\n" + - " - parse org and replay ID from a Sentry URL\n\n" + - "Examples:\n" + - " sentry replay view 346789a703f6454384f1de473b8b9fcc\n" + - " sentry replay view sentry/346789a703f6454384f1de473b8b9fcc\n" + - " sentry replay view sentry/cli/346789a703f6454384f1de473b8b9fcc\n" + - " sentry replay view https://sentry.io/organizations/sentry/explore/replays/346789a703f6454384f1de473b8b9fcc/\n" + - " sentry replay view --web sentry/346789a703f6454384f1de473b8b9fcc", + " - parse org and replay ID from a Sentry URL", + examples: [ + { + description: + "View a replay by ID (organization and project auto-detected)", + command: "sentry replay view 346789a703f6454384f1de473b8b9fcc", + }, + { + description: "View a replay in an explicit organization", + command: "sentry replay view my-org/346789a703f6454384f1de473b8b9fcc", + }, + { + description: "View a replay with explicit org/project context", + command: + "sentry replay view my-org/frontend/346789a703f6454384f1de473b8b9fcc", + }, + { + description: "View a replay from its URL", + command: + "sentry replay view https://sentry.io/organizations/my-org/explore/replays/346789a703f6454384f1de473b8b9fcc/", + }, + { + description: "View the replay linked to a trace", + command: + "sentry replay view my-org/frontend/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + }, + { + description: "Open a replay in the browser", + command: + "sentry replay view my-org/346789a703f6454384f1de473b8b9fcc --web", + }, + ], }, output: { human: formatReplayDetails, diff --git a/packages/cli/src/commands/repo/list.ts b/packages/cli/src/commands/repo/list.ts index 313b6d397..c5c4fc080 100644 --- a/packages/cli/src/commands/repo/list.ts +++ b/packages/cli/src/commands/repo/list.ts @@ -66,12 +66,22 @@ const docs: OrgListCommandDocs = { "Pagination:\n" + " sentry repo list / -c next # fetch next page\n" + " sentry repo list / -c prev # fetch previous page\n\n" + - "Examples:\n" + - " sentry repo list # auto-detect or list all\n" + - " sentry repo list my-org/ # list repositories in my-org (paginated)\n" + - " sentry repo list --limit 10\n" + - " sentry repo list --json\n\n" + "Alias: `sentry repos` → `sentry repo list`", + examples: [ + { + description: "List repositories (organization auto-detected)", + command: "sentry repo list", + }, + { + description: "List repositories in an organization", + command: "sentry repo list my-org/", + }, + { + description: "Fetch the next page", + command: "sentry repo list my-org/ -c next", + }, + { description: "Output as JSON", command: "sentry repo list --json" }, + ], }; export const listCommand = buildOrgListCommand(repoListConfig, docs, "repo"); diff --git a/packages/cli/src/commands/schema.ts b/packages/cli/src/commands/schema.ts index ce0301861..8b5a2463a 100644 --- a/packages/cli/src/commands/schema.ts +++ b/packages/cli/src/commands/schema.ts @@ -423,15 +423,35 @@ export const schemaCommand = buildCommand({ brief: "Browse the Sentry API schema", fullDescription: "Browse and search the Sentry API schema. Shows available resources, " + - "operations, and endpoint details. Use with --json for machine-readable output.\n\n" + - "Examples:\n" + - " sentry schema List all API resources\n" + - " sentry schema issues Show endpoints for a resource\n" + - " sentry schema issues list Show details for one endpoint\n" + - " sentry schema listOrganizationEvents Show details by operation ID\n" + - ' sentry schema "GET /api/0/organizations/{organization_id_or_slug}/issues/"\n' + - " sentry schema --all Flat list of all endpoints\n" + - " sentry schema --search monitor Search endpoints by keyword", + "operations, and endpoint details. Use with --json for machine-readable output.", + examples: [ + { description: "List all API resources", command: "sentry schema" }, + { + description: "Browse issue endpoints", + command: "sentry schema issues", + }, + { + description: "View details for a specific operation", + command: "sentry schema issues list", + }, + { + description: "Look up an endpoint by its exact operation ID", + command: "sentry schema listOrganizationEvents", + }, + { + description: "Look up an endpoint by HTTP method and path", + command: + 'sentry schema "GET /api/0/organizations/{organization_id_or_slug}/issues/"', + }, + { + description: "Search for monitoring-related endpoints", + command: "sentry schema --search monitor", + }, + { + description: "Flat list of every endpoint", + command: "sentry schema --all", + }, + ], }, output: { human: formatSchemaHuman, diff --git a/packages/cli/src/commands/snapshots/diff.ts b/packages/cli/src/commands/snapshots/diff.ts index 7d198cf68..d841cd045 100644 --- a/packages/cli/src/commands/snapshots/diff.ts +++ b/packages/cli/src/commands/snapshots/diff.ts @@ -237,6 +237,18 @@ export const diffCommand = buildCommand({ " sentry snapshots diff ./baseline ./head\n" + " sentry snapshots diff ./baseline ./head --threshold 0.02 --output ./diffs/\n" + " sentry snapshots diff ./baseline ./head --fail-on-diff", + examples: [ + { + description: "Compare two directories of snapshot images locally", + command: "sentry snapshots diff ./baseline ./head", + }, + { + description: + "Exit non-zero if any images changed, with a custom threshold", + command: + "sentry snapshots diff ./baseline ./head --fail-on-diff --threshold 0.02", + }, + ], }, output: { human: formatDiffReport, diff --git a/packages/cli/src/commands/snapshots/download.ts b/packages/cli/src/commands/snapshots/download.ts index 51e53ff03..4ccbf713b 100644 --- a/packages/cli/src/commands/snapshots/download.ts +++ b/packages/cli/src/commands/snapshots/download.ts @@ -159,6 +159,22 @@ export const downloadCommand = buildCommand({ " sentry snapshots download --snapshot-id 1234567890\n" + " sentry snapshots download --app-id my-app --branch main\n" + " sentry snapshots download --app-id my-app --output ./baseline/", + examples: [ + { + description: "Download a specific baseline snapshot by ID", + command: "sentry snapshots download --snapshot-id 1234567890", + }, + { + description: + "Download the latest baseline for an app, filtered by branch", + command: "sentry snapshots download --app-id my-app --branch main", + }, + { + description: "Extract images to a specific directory", + command: + "sentry snapshots download --app-id my-app --output ./baseline/", + }, + ], }, output: { human: formatDownloadResult, diff --git a/packages/cli/src/commands/snapshots/upload.ts b/packages/cli/src/commands/snapshots/upload.ts index 523a6eb50..954b4467b 100644 --- a/packages/cli/src/commands/snapshots/upload.ts +++ b/packages/cli/src/commands/snapshots/upload.ts @@ -345,6 +345,24 @@ export const uploadCommand = buildCommand({ " sentry snapshots upload ./screenshots --app-id com.example.app\n" + " sentry snapshots upload ./shots --app-id my-app --diff-threshold 0.01\n" + " sentry snapshots upload ./shots --app-id my-app --selective", + examples: [ + { + description: "Upload a folder of screenshots as a snapshot for an app", + command: + "sentry snapshots upload ./screenshots --app-id com.example.app", + }, + { + description: + "Upload only a subset of images (removals/renames not inferred on PRs)", + command: + "sentry snapshots upload ./screenshots --app-id my-app --selective", + }, + { + description: "Only flag images that differ by more than 1%", + command: + "sentry snapshots upload ./screenshots --app-id my-app --diff-threshold 0.01", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/sourcemap/inject.ts b/packages/cli/src/commands/sourcemap/inject.ts index 5184e439c..531e6bdc1 100644 --- a/packages/cli/src/commands/sourcemap/inject.ts +++ b/packages/cli/src/commands/sourcemap/inject.ts @@ -70,6 +70,20 @@ export const injectCommand = buildCommand({ " sentry sourcemap inject ./build --ext .js,.mjs\n" + " sentry sourcemap inject ./out --dry-run\n" + " sentry sourcemap inject ./maybe-empty --allow-empty", + examples: [ + { + description: "Inject debug IDs into all JS files in dist/", + command: "sentry sourcemap inject ./dist", + }, + { + description: "Preview changes without writing", + command: "sentry sourcemap inject ./dist --dry-run", + }, + { + description: "Only process specific extensions", + command: "sentry sourcemap inject ./build --ext .js,.mjs", + }, + ], }, // Purely local file operation — no Sentry API calls, no auth needed. auth: false, diff --git a/packages/cli/src/commands/sourcemap/resolve.ts b/packages/cli/src/commands/sourcemap/resolve.ts index c16571c3d..04f862c00 100644 --- a/packages/cli/src/commands/sourcemap/resolve.ts +++ b/packages/cli/src/commands/sourcemap/resolve.ts @@ -115,6 +115,17 @@ export const resolveCommand = buildCommand({ " sentry sourcemap resolve ./dist\n" + " sentry sourcemap resolve ./build --ext .js,.mjs\n" + " sentry sourcemap resolve ./out --json", + examples: [ + { + description: + "Report how each JS file's sourcemap resolves and whether a debug ID is injected", + command: "sentry sourcemap resolve ./dist", + }, + { + description: "Output as JSON", + command: "sentry sourcemap resolve ./dist --json", + }, + ], }, // Purely local file operation — no Sentry API calls, no auth needed. auth: false, diff --git a/packages/cli/src/commands/sourcemap/upload.ts b/packages/cli/src/commands/sourcemap/upload.ts index a99f06ac7..39d7bc23d 100644 --- a/packages/cli/src/commands/sourcemap/upload.ts +++ b/packages/cli/src/commands/sourcemap/upload.ts @@ -222,6 +222,24 @@ export const uploadCommand = buildCommand({ " sentry sourcemap upload ./dist --no-rewrite\n" + " sentry sourcemap upload ./dist --ext .js,.mjs\n" + " sentry sourcemap upload ./maybe-empty --allow-empty", + examples: [ + { + description: "Upload sourcemaps from dist/", + command: "sentry sourcemap upload ./dist", + }, + { + description: "Associate with a release", + command: "sentry sourcemap upload ./dist --release 1.0.0", + }, + { + description: "Set a custom URL prefix", + command: "sentry sourcemap upload ./dist --url-prefix '~/static/js/'", + }, + { + description: "Don't fail when no sourcemaps are found", + command: "sentry sourcemap upload ./dist --allow-empty", + }, + ], }, output: { human: formatUploadResult, diff --git a/packages/cli/src/commands/span/list.ts b/packages/cli/src/commands/span/list.ts index da83d9a9f..b8533eebd 100644 --- a/packages/cli/src/commands/span/list.ts +++ b/packages/cli/src/commands/span/list.ts @@ -555,15 +555,43 @@ export const listCommand = buildListCommand("span", { " sentry span list -c next # fetch next page (project mode)\n" + " sentry span list -c prev # fetch previous page\n" + " sentry span list -c next # fetch next page (trace mode)\n\n" + - "Examples:\n" + - " sentry span list # List recent spans in project\n" + - ' sentry span list -q "op:db" # Find all DB spans\n' + - ' sentry span list -q "duration:>100ms" # Slow spans\n' + - " sentry span list --period 24h # Last 24 hours only\n" + - " sentry span list --sort duration # Sort by slowest first\n" + - " sentry span list # Spans in a specific trace\n" + - ' sentry span list -q "op:db" # DB spans in a trace\n\n' + "Alias: `sentry spans` → `sentry span list`", + examples: [ + { + description: "List recent spans in the current project", + command: "sentry span list", + }, + { + description: "Find all DB spans", + command: 'sentry span list -q "op:db"', + }, + { + description: "Slow spans in the last 24 hours", + command: 'sentry span list -q "duration:>100ms" --period 24h', + }, + { + description: "Sort by slowest first", + command: "sentry span list --sort duration", + }, + { + description: "List spans within a specific trace", + command: "sentry span list abc123def456abc123def456abc12345", + }, + { + description: "Show only spans from one project within a trace", + command: + "sentry span list my-org/cli-server/abc123def456abc123def456abc12345", + }, + { + description: "Filter a trace's spans to several projects", + command: + 'sentry span list abc123def456abc123def456abc12345 -q "project:[cli-server,api]"', + }, + { + description: "Fetch the next page", + command: "sentry span list -c next", + }, + ], }, output: { human: formatSpanListHuman, diff --git a/packages/cli/src/commands/span/view.ts b/packages/cli/src/commands/span/view.ts index d15185b86..c25f81ff7 100644 --- a/packages/cli/src/commands/span/view.ts +++ b/packages/cli/src/commands/span/view.ts @@ -374,11 +374,24 @@ export const viewCommand = buildCommand({ " sentry span view # auto-detect\n" + " sentry span view // # explicit\n\n" + "The first argument is the trace ID (optionally prefixed with org/project),\n" + - "followed by one or more span IDs.\n\n" + - "Examples:\n" + - " sentry span view a1b2c3d4e5f67890\n" + - " sentry span view a1b2c3d4e5f67890 b2c3d4e5f6789012\n" + - " sentry span view sentry/my-project/ a1b2c3d4e5f67890", + "followed by one or more span IDs.", + examples: [ + { + description: "View a single span", + command: + "sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890", + }, + { + description: "View multiple spans at once", + command: + "sentry span view abc123def456abc123def456abc12345 a1b2c3d4e5f67890 b2c3d4e5f6789012", + }, + { + description: "Specify the organization and project explicitly", + command: + "sentry span view my-org/backend/abc123def456abc123def456abc12345 a1b2c3d4e5f67890", + }, + ], }, output: { human: formatSpanViewHuman, diff --git a/packages/cli/src/commands/status/show.ts b/packages/cli/src/commands/status/show.ts index e9d82aaf0..8990e2417 100644 --- a/packages/cli/src/commands/status/show.ts +++ b/packages/cli/src/commands/status/show.ts @@ -32,6 +32,21 @@ export const showCommand = buildCommand({ "This works even when the Sentry API is degraded or unreachable, so " + "you can tell whether an issue is on Sentry's side. Point `--url` at a " + "different Statuspage instance to check a self-hosted or regional page.", + examples: [ + { + description: "Show the current status of Sentry's services", + command: "sentry status", + }, + { + description: "Get machine-readable status (useful in scripts)", + command: "sentry status --json", + }, + { + description: + "Check a self-hosted or regional status page (Statuspage CNAME)", + command: "sentry status --url https://status.acme.com", + }, + ], }, output: { human: formatSentryStatus }, parameters: { diff --git a/packages/cli/src/commands/team/list.ts b/packages/cli/src/commands/team/list.ts index bd4da02db..9dfd9b194 100644 --- a/packages/cli/src/commands/team/list.ts +++ b/packages/cli/src/commands/team/list.ts @@ -67,12 +67,22 @@ const docs: OrgListCommandDocs = { "Pagination:\n" + " sentry team list / -c next # fetch next page\n" + " sentry team list / -c prev # fetch previous page\n\n" + - "Examples:\n" + - " sentry team list # auto-detect or list all\n" + - " sentry team list my-org/ # list teams in my-org (paginated)\n" + - " sentry team list --limit 10\n" + - " sentry team list --json\n\n" + "Alias: `sentry teams` → `sentry team list`", + examples: [ + { + description: "List teams (organization auto-detected)", + command: "sentry team list", + }, + { + description: "List teams in an organization", + command: "sentry team list my-org/", + }, + { + description: "Fetch the next page", + command: "sentry team list my-org/ -c next", + }, + { description: "Output as JSON", command: "sentry team list --json" }, + ], }; export const listCommand = buildOrgListCommand(teamListConfig, docs, "team"); diff --git a/packages/cli/src/commands/trace/list.ts b/packages/cli/src/commands/trace/list.ts index cc55d4b0a..47d969cb9 100644 --- a/packages/cli/src/commands/trace/list.ts +++ b/packages/cli/src/commands/trace/list.ts @@ -205,13 +205,27 @@ export const listCommand = buildListCommand("trace", { " sentry trace list / # explicit org and project\n" + " sentry trace list # find project across all orgs\n\n" + `${TARGET_PATTERN_NOTE}\n\n` + - "Examples:\n" + - " sentry trace list # List last 10 traces\n" + - " sentry trace list --limit 50 # Show more traces\n" + - " sentry trace list --sort duration # Sort by slowest first\n" + - " sentry trace list --period 24h # Last 24 hours only\n" + - ' sentry trace list -q "transaction:GET /api/users" # Filter by transaction\n\n' + "Alias: `sentry traces` → `sentry trace list`", + examples: [ + { description: "List recent traces", command: "sentry trace list" }, + { + description: "Show more traces", + command: "sentry trace list --limit 50", + }, + { + description: "Sort by slowest first", + command: "sentry trace list --sort duration", + }, + { + description: "Filter by transaction name in the last 24 hours", + command: + 'sentry trace list -q "transaction:GET /api/users" --period 24h', + }, + { + description: "Fetch the next page", + command: "sentry trace list my-org/backend -c next", + }, + ], }, output: { human: formatTraceListHuman, diff --git a/packages/cli/src/commands/trace/logs.ts b/packages/cli/src/commands/trace/logs.ts index fe840480f..d48960a81 100644 --- a/packages/cli/src/commands/trace/logs.ts +++ b/packages/cli/src/commands/trace/logs.ts @@ -108,13 +108,37 @@ export const logsCommand = buildCommand({ " sentry trace logs // # filter to project\n\n" + "When a project is specified, only logs from that project are shown.\n" + "Use --query 'project:[a,b]' to filter to multiple projects.\n\n" + - "The trace ID is the 32-character hexadecimal identifier.\n\n" + - "Examples:\n" + - " sentry trace logs abc123def456abc123def456abc123de\n" + - " sentry trace logs myorg/abc123def456abc123def456abc123de\n" + - " sentry trace logs myorg/backend/abc123def456abc123def456abc123de\n" + - " sentry trace logs --period 7d abc123def456abc123def456abc123de\n" + - " sentry trace logs --json abc123def456abc123def456abc123de", + "The trace ID is the 32-character hexadecimal identifier.", + examples: [ + { + description: "View logs for a trace", + command: "sentry trace logs abc123def456abc123def456abc12345", + }, + { + description: "Filter trace logs to one project", + command: + "sentry trace logs my-org/cli-server/abc123def456abc123def456abc12345", + }, + { + description: "Filter trace logs to several projects", + command: + 'sentry trace logs abc123def456abc123def456abc12345 -q "project:[cli-server,api]"', + }, + { + description: "Search with a longer time window", + command: + "sentry trace logs --period 30d abc123def456abc123def456abc12345", + }, + { + description: "Only error logs", + command: + "sentry trace logs -q 'severity:error' abc123def456abc123def456abc12345", + }, + { + description: "Output as JSON", + command: "sentry trace logs --json abc123def456abc123def456abc12345", + }, + ], }, output: { human: formatTraceLogsHuman, diff --git a/packages/cli/src/commands/trace/view.ts b/packages/cli/src/commands/trace/view.ts index f8cfe10bf..48808f697 100644 --- a/packages/cli/src/commands/trace/view.ts +++ b/packages/cli/src/commands/trace/view.ts @@ -475,6 +475,29 @@ export const viewCommand = buildCommand({ " sentry trace view // # explicit org and project\n" + " sentry trace view # find project across all orgs\n\n" + "The trace ID is the 32-character hexadecimal identifier.", + examples: [ + { + description: "View trace details with the span tree", + command: "sentry trace view abc123def456abc123def456abc12345", + }, + { + description: "Show the full trace across all projects", + command: "sentry trace view my-org/abc123def456abc123def456abc12345", + }, + { + description: "Filter the span tree to one project", + command: + "sentry trace view my-org/cli-server/abc123def456abc123def456abc12345", + }, + { + description: "Recover the trace from an issue short ID", + command: "sentry trace view PROJ-123", + }, + { + description: "Open the trace in the browser", + command: "sentry trace view abc123def456abc123def456abc12345 -w", + }, + ], }, output: { human: formatTraceView, diff --git a/packages/cli/src/commands/trial/list.ts b/packages/cli/src/commands/trial/list.ts index 25ca08a9d..249b9e407 100644 --- a/packages/cli/src/commands/trial/list.ts +++ b/packages/cli/src/commands/trial/list.ts @@ -203,11 +203,18 @@ export const listCommand = buildCommand({ fullDescription: "List product trials for an organization, including available,\n" + "active, and expired trials.\n\n" + - "Examples:\n" + - " sentry trial list\n" + - " sentry trial list my-org\n" + - " sentry trial list --json\n\n" + "Alias: `sentry trials` → `sentry trial list`", + examples: [ + { + description: "List all trials for the current organization", + command: "sentry trial list", + }, + { + description: "List trials for a specific organization", + command: "sentry trial list my-org", + }, + { description: "Output as JSON", command: "sentry trial list --json" }, + ], }, output: { human: formatTrialListHuman, diff --git a/packages/cli/src/commands/trial/start.ts b/packages/cli/src/commands/trial/start.ts index 05a0506d7..e1f01445d 100644 --- a/packages/cli/src/commands/trial/start.ts +++ b/packages/cli/src/commands/trial/start.ts @@ -82,13 +82,22 @@ export const startCommand = buildCommand({ fullDescription: "Start a product trial for an organization.\n\n" + `Valid trial names: ${NAMES_LIST}\n\n` + - "Use 'plan' to start a Business plan trial (opens billing page).\n\n" + - "Examples:\n" + - " sentry trial start seer\n" + - " sentry trial start seer my-org\n" + - " sentry trial start replays\n" + - " sentry trial start plan\n" + - " sentry trial start --json seer", + "Use 'plan' to start a Business plan trial (opens billing page).", + examples: [ + { description: "Start a Seer trial", command: "sentry trial start seer" }, + { + description: "Start a trial for a specific organization", + command: "sentry trial start replays my-org", + }, + { + description: "Start a Business plan trial (opens the browser)", + command: "sentry trial start plan", + }, + { + description: "Output the result as JSON", + command: "sentry trial start --json seer", + }, + ], }, output: { human: formatStartResult }, parameters: { diff --git a/packages/cli/src/commands/wasm-split.ts b/packages/cli/src/commands/wasm-split.ts index e53c5815a..b2f4b6f2d 100644 --- a/packages/cli/src/commands/wasm-split.ts +++ b/packages/cli/src/commands/wasm-split.ts @@ -68,6 +68,32 @@ export const wasmSplitCommand = buildCommand({ " sentry wasm-split app.wasm\n" + " sentry wasm-split app.wasm -d app.debug.wasm --strip\n" + " BUILD_ID=$(sentry wasm-split app.wasm)", + examples: [ + { + description: "Add a build ID to a module in place and print it", + command: "sentry wasm-split app.wasm", + }, + { + description: "Capture the build ID for a later upload", + command: "BUILD_ID=$(sentry wasm-split app.wasm)", + }, + { + description: + "Split debug data into a companion and ship a stripped binary", + command: + "sentry wasm-split app.wasm --debug-out app.debug.wasm --strip", + }, + { + description: "Also drop function names from the shipped binary", + command: + "sentry wasm-split app.wasm -d app.debug.wasm --strip --strip-names", + }, + { + description: "Point browsers at a companion served from a CDN", + command: + "sentry wasm-split app.wasm -o dist/app.wasm -d dist/app.debug.wasm --strip --external-dwarf-url https://cdn.example.com/debug/app.debug.wasm", + }, + ], }, // Purely local file operation — no Sentry API calls, no auth needed. auth: false, diff --git a/packages/cli/src/lib/introspect.ts b/packages/cli/src/lib/introspect.ts index fb144c72a..5a86214d6 100644 --- a/packages/cli/src/lib/introspect.ts +++ b/packages/cli/src/lib/introspect.ts @@ -296,13 +296,8 @@ export function extractFlags( * * @param cmd - The Stricli command to introspect * @param path - Full command path (e.g. "sentry issue list") - * @param examples - Optional usage examples */ -export function buildCommandInfo( - cmd: Command, - path: string, - examples: string[] = [], -): CommandInfo { +export function buildCommandInfo(cmd: Command, path: string): CommandInfo { const jsonFields = cmd.__jsonSchema ? extractSchemaFields(cmd.__jsonSchema) : undefined; @@ -321,11 +316,9 @@ export function buildCommandInfo( cmd.__primaryUsage ?? getPositionalString(cmd.parameters.positional), positionals, aliases: cmd.parameters.aliases ?? {}, - examples: cmd.__examples?.length - ? cmd.__examples.map( - ({ description, command }) => `# ${description}\n${command}`, - ) - : examples, + examples: (cmd.__examples ?? []).map( + ({ description, command }) => `# ${description}\n${command}`, + ), jsonFields: jsonFields?.length ? jsonFields : undefined, }; } @@ -335,12 +328,10 @@ export function buildCommandInfo( * * @param routeMap - The route map to introspect * @param routeName - Parent route name (e.g. "issue") - * @param docExamples - Optional examples loaded from documentation */ export function extractRouteGroupCommands( routeMap: RouteMap, routeName: string, - docExamples: Map = new Map(), ): CommandInfo[] { const commands: CommandInfo[] = []; @@ -352,13 +343,10 @@ export function extractRouteGroupCommands( const subTarget = subEntry.target; if (isCommand(subTarget)) { const path = `sentry ${routeName} ${subEntry.name.original}`; - const examples = docExamples.get(path) ?? []; - commands.push(buildCommandInfo(subTarget, path, examples)); + commands.push(buildCommandInfo(subTarget, path)); } else if (isRouteMap(subTarget)) { const nestedPrefix = `${routeName} ${subEntry.name.original}`; - commands.push( - ...extractRouteGroupCommands(subTarget, nestedPrefix, docExamples), - ); + commands.push(...extractRouteGroupCommands(subTarget, nestedPrefix)); } } @@ -367,8 +355,6 @@ export function extractRouteGroupCommands( /** * Walk the entire route tree and extract metadata for all visible routes. - * This is a synchronous version that doesn't load documentation examples - * (unlike the async version in generate-skill.ts). * * @param routeMap - Top-level Stricli route map * @returns Array of route info for each visible top-level entry diff --git a/packages/cli/test/lib/introspect.test.ts b/packages/cli/test/lib/introspect.test.ts index ed14813bd..3d0e942b8 100644 --- a/packages/cli/test/lib/introspect.test.ts +++ b/packages/cli/test/lib/introspect.test.ts @@ -242,6 +242,12 @@ describe("buildCommandInfo", () => { const cmd = makeCommand({ brief: "List things", fullDescription: "List all the things.", + __examples: [ + { + description: "List things in an org", + command: "sentry thing list myorg", + }, + ], parameters: { positional: { kind: "tuple", @@ -258,9 +264,7 @@ describe("buildCommandInfo", () => { }, }); - const info = buildCommandInfo(cmd, "sentry thing list", [ - "sentry thing list myorg", - ]); + const info = buildCommandInfo(cmd, "sentry thing list"); expect(info.path).toBe("sentry thing list"); expect(info.brief).toBe("List things"); expect(info.fullDescription).toBe("List all the things."); @@ -268,7 +272,9 @@ describe("buildCommandInfo", () => { expect(info.flags).toHaveLength(1); expect(info.flags[0].name).toBe("limit"); expect(info.aliases).toEqual({ l: "limit" }); - expect(info.examples).toEqual(["sentry thing list myorg"]); + expect(info.examples).toEqual([ + "# List things in an org\nsentry thing list myorg", + ]); }); test("handles command with no positional args", () => { diff --git a/packages/cli/test/script/generate-skill-markdown.test.ts b/packages/cli/test/script/generate-skill-markdown.test.ts index bc2f7659a..217d46b36 100644 --- a/packages/cli/test/script/generate-skill-markdown.test.ts +++ b/packages/cli/test/script/generate-skill-markdown.test.ts @@ -1,12 +1,10 @@ -/** Tests for generated command-heading and example association parsing. */ +/** Tests for command metadata rendered into generated docs and skills. */ import { lstat, readFile, realpath } from "node:fs/promises"; import { describe, expect, test } from "vitest"; import { - extractCommandPathFromHeading, formatCommandArguments, formatCommandExamples, - matchExampleToCommand, } from "../../script/generate-skill-markdown.js"; import { listCommand } from "../../src/commands/agent-conversation/list.js"; import { viewCommand } from "../../src/commands/agent-conversation/view.js"; @@ -15,25 +13,7 @@ import { mergeCommand } from "../../src/commands/issue/merge.js"; import { createCommand } from "../../src/commands/project/create.js"; import { buildCommandInfo } from "../../src/lib/introspect.js"; -describe("extractCommandPathFromHeading", () => { - test.each([ - ["`sentry issue view `", "sentry issue view"], - ["`sentry issue view `", "sentry issue view"], - [ - "`sentry project create [/]:...`", - "sentry project create", - ], - ["`sentry auth status`", "sentry auth status"], - ])("extracts the command path from %s", (heading, expected) => { - expect(extractCommandPathFromHeading(heading)).toBe(expected); - }); - - test("ignores descriptive headings", () => { - expect(extractCommandPathFromHeading("Create a project")).toBeUndefined(); - }); -}); - -describe("matchExampleToCommand", () => { +describe("command metadata in generated references", () => { test("derives conversation signatures and examples from command metadata", () => { const list = buildCommandInfo( listCommand as never, @@ -116,43 +96,6 @@ describe("matchExampleToCommand", () => { ); }); - test("associates a project create block with its command", () => { - const code = [ - "# Create projects", - "sentry project create web:javascript api:python-django", - ].join("\n"); - - expect( - matchExampleToCommand( - code, - ["sentry project create", "sentry project delete"], - "sentry project", - ), - ).toBe("sentry project create"); - }); - - test("maps bare group examples to the default subcommand", () => { - expect( - matchExampleToCommand( - "sentry auth\nsentry auth --token YOUR_SENTRY_API_TOKEN", - ["sentry auth login", "sentry auth logout", "sentry auth status"], - "sentry auth", - "sentry auth login", - ), - ).toBe("sentry auth login"); - }); - - test("prefers longer command paths over shorter prefixes", () => { - expect( - matchExampleToCommand( - "sentry auth login --token TOKEN", - ["sentry auth login", "sentry auth status"], - "sentry auth", - "sentry auth login", - ), - ).toBe("sentry auth login"); - }); - test("the generated project reference retains create examples", async () => { const reference = await readFile( "plugins/sentry-cli/skills/sentry-cli/references/project.md", diff --git a/packages/cli/test/script/markdown.test.ts b/packages/cli/test/script/markdown.test.ts new file mode 100644 index 000000000..0e8e6ade5 --- /dev/null +++ b/packages/cli/test/script/markdown.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, test } from "vitest"; +import { + blankCodeBlocks, + demoteHeadings, + markdownCodeBlocks, + markdownHeadings, + markdownSection, +} from "../../script/markdown.js"; + +const DOC = [ + "## Usage", + "", + "```bash", + "# not a heading", + "sentry yarn add", + "```", + "", + "### Examples", + "Text after.", + "", +].join("\n"); + +describe("markdownHeadings", () => { + test("returns headings and skips comments inside code blocks", () => { + expect(markdownHeadings(DOC)).toEqual([ + { depth: 2, text: "Usage" }, + { depth: 3, text: "Examples" }, + ]); + }); +}); + +describe("blankCodeBlocks", () => { + test("removes code block content while keeping line numbers", () => { + const blanked = blankCodeBlocks(DOC); + expect(blanked).not.toContain("yarn add"); + expect(blanked.split("\n")).toHaveLength(DOC.split("\n").length); + expect(blanked.split("\n")[8]).toBe("Text after."); + }); +}); + +describe("markdownSection", () => { + test("keeps code comments inside the section instead of ending it", () => { + const doc = + "## Install\n\n```bash\n# pin a version\nrun\n```\n\n## Next\n\nAfter.\n"; + const section = markdownSection(doc, "Install"); + expect(section).toContain("# pin a version"); + expect(section).toContain("run"); + expect(section).not.toContain("After."); + }); + + test("returns null for a missing heading", () => { + expect(markdownSection(DOC, "Missing")).toBeNull(); + }); +}); + +describe("markdownCodeBlocks", () => { + test("returns code with its language", () => { + expect(markdownCodeBlocks(DOC)).toEqual([ + { code: "# not a heading\nsentry yarn add", lang: "bash" }, + ]); + }); +}); + +describe("demoteHeadings", () => { + test("demotes level 2+ headings and leaves code comments alone", () => { + const demoted = demoteHeadings(DOC); + expect(demoted).toContain("### Usage"); + expect(demoted).toContain("#### Examples"); + expect(demoted).toContain("\n# not a heading\n"); + }); +}); diff --git a/scripts/cli-lint-rules.test.mjs b/scripts/cli-lint-rules.test.mjs index 1a37bf62f..044717720 100644 --- a/scripts/cli-lint-rules.test.mjs +++ b/scripts/cli-lint-rules.test.mjs @@ -143,3 +143,77 @@ tester.run("no-raw-metadata-queries", plugin.rules["no-raw-metadata-queries"], { }, ], }); + +tester.run( + "no-examples-in-full-description", + plugin.rules["no-examples-in-full-description"], + { + valid: [ + { + filename: commands, + code: "buildCommand({ docs: { fullDescription: 'Lists items.', examples: [{ description: 'List', command: 'sentry list' }] } });", + }, + { + filename: commands, + code: "buildCommand({ docs: { fullDescription: 'Format: count()\\n Example: p50(value)' } });", + }, + { + filename: commands, + code: "throw new ValidationError('Bad input.\\n\\nExamples:\\n sentry list');", + }, + { + filename: source, + code: "const docs = { fullDescription: `${base}\\n\\nExamples:\\n${rendered}` };", + }, + ], + invalid: [ + { + filename: commands, + code: "buildCommand({ docs: { fullDescription: 'Lists items.\\n\\n' + 'Examples:\\n' + ' sentry list\\n' } });", + errors: 1, + }, + { + filename: commands, + code: "buildRouteMap({ docs: { fullDescription: `Manage items.\\n\\nExample:\\n sentry item view 1` } });", + errors: 1, + }, + { + filename: commands, + code: "buildCommand({ docs: { fullDescription: 'Manage items.\\n\\n' + '## Examples\\n\\n' + 'sentry item list\\n' } });", + errors: 1, + }, + ], + }, +); + +tester.run( + "no-regex-markdown-parsing", + plugin.rules["no-regex-markdown-parsing"], + { + valid: [ + { filename: source, code: "const query = /[^/?#\\s]+/;" }, + { filename: source, code: "const issue = /#(\\d+)/;" }, + { + filename: "/repo/packages/cli/test/example.test.ts", + code: "expect(output).toMatch(/^## Usage/m);", + }, + ], + invalid: [ + { + filename: "/repo/packages/cli/script/example.ts", + code: "const fence = /^(`{3,}|~{3,}).*\\n[\\s\\S]*?\\n\\1\\s*$/gm;", + errors: 1, + }, + { + filename: source, + code: "const heading = /^#{1,6}\\s+examples?/im;", + errors: 1, + }, + { + filename: "/repo/packages/cli/script/example.ts", + code: "const heading = new RegExp(`^#{1,4}\\\\s+${name}`, 'im');", + errors: 1, + }, + ], + }, +);