diff --git a/apps/cli-docs/src/components/Terminal.astro b/apps/cli-docs/src/components/Terminal.astro
index 1cb79c0a88..e2a694e5c0 100644
--- a/apps/cli-docs/src/components/Terminal.astro
+++ b/apps/cli-docs/src/components/Terminal.astro
@@ -31,7 +31,7 @@ if (background) {
$
- sentry auth login
+ sentry auth
●
diff --git a/apps/cli-docs/src/content/docs/getting-started.mdx b/apps/cli-docs/src/content/docs/getting-started.mdx
index ee60060583..603bb42f4d 100644
--- a/apps/cli-docs/src/content/docs/getting-started.mdx
+++ b/apps/cli-docs/src/content/docs/getting-started.mdx
@@ -106,7 +106,7 @@ Or run directly without installing:
The easiest way to authenticate is via OAuth device flow:
```bash
-sentry auth login
+sentry auth
```
You'll be given a URL and a code to enter. Once you authorize the application
@@ -120,7 +120,7 @@ Sentry CLI configuration directory (`~/.sentry/` by default, overridable with
Alternatively, you can use an API token directly:
```bash
-sentry auth login --token YOUR_SENTRY_API_TOKEN
+sentry auth --token YOUR_SENTRY_API_TOKEN
```
You can create API tokens in your [Sentry account settings](https://sentry.io/settings/account/api/auth-tokens/).
@@ -149,7 +149,7 @@ sentry auth logout
Using a self-hosted Sentry instance? Set `SENTRY_URL` to point at it:
```bash
-SENTRY_URL=https://sentry.example.com sentry auth login
+SENTRY_URL=https://sentry.example.com sentry auth
```
See the [Self-Hosted](../self-hosted/) guide for full setup details.
diff --git a/apps/cli-docs/src/fragments/commands/auth.md b/apps/cli-docs/src/fragments/commands/auth.md
index 51395146eb..9157ccb78f 100644
--- a/apps/cli-docs/src/fragments/commands/auth.md
+++ b/apps/cli-docs/src/fragments/commands/auth.md
@@ -5,9 +5,12 @@
### OAuth login (recommended)
```bash
-sentry auth login
+sentry auth
```
+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.
+
1. A URL and device code will be displayed
2. Open the URL in your browser
3. Enter the code when prompted
@@ -18,7 +21,7 @@ sentry auth login
### Token login
```bash
-sentry auth login --token YOUR_SENTRY_API_TOKEN
+sentry auth --token YOUR_SENTRY_API_TOKEN
```
### Read-only OAuth login
@@ -27,7 +30,7 @@ Request only read-only scopes — useful for tokens handed to AI agents or
CI jobs that should not mutate Sentry state:
```bash
-sentry auth login --read-only
+sentry auth --read-only
```
### Custom OAuth scopes
@@ -35,8 +38,8 @@ sentry auth login --read-only
Request specific scopes (repeatable, comma-separated):
```bash
-sentry auth login --scope project:read --scope org:read
-sentry auth login --scope project:read,event:read
+sentry auth --scope project:read --scope org:read
+sentry auth --scope project:read,event:read
```
### Self-hosted Sentry
@@ -44,14 +47,14 @@ sentry auth login --scope project:read,event:read
Use `--url` (recommended) or the `SENTRY_URL` environment variable:
```bash
-sentry auth login --url https://sentry.example.com
-SENTRY_URL=https://sentry.example.com sentry auth login
+sentry auth --url https://sentry.example.com
+SENTRY_URL=https://sentry.example.com sentry auth
```
For token-based auth with self-hosted:
```bash
-sentry auth login --token YOUR_TOKEN --url https://sentry.example.com
+sentry auth --token YOUR_TOKEN --url https://sentry.example.com
```
See [Self-Hosted Sentry](../self-hosted/) for details.
diff --git a/apps/cli-docs/src/fragments/commands/init.md b/apps/cli-docs/src/fragments/commands/init.md
index e7e80d9d74..adc6e6f95c 100644
--- a/apps/cli-docs/src/fragments/commands/init.md
+++ b/apps/cli-docs/src/fragments/commands/init.md
@@ -2,7 +2,7 @@
> **Experimental:** `sentry init` is experimental and may modify your source files. Always review changes before committing.
-**Prerequisites:** You must be authenticated first. Run `sentry auth login` if you haven't already.
+**Prerequisites:** You must be authenticated first. Run `sentry auth` if you haven't already.
## Examples
diff --git a/packages/cli/README.md b/packages/cli/README.md
index 052c1d534a..86a1d85082 100644
--- a/packages/cli/README.md
+++ b/packages/cli/README.md
@@ -52,7 +52,7 @@ bunx sentry --help
```bash
# Authenticate with Sentry
-sentry auth login
+sentry auth
# List issues (auto-detects project from your codebase)
sentry issue list
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 2e2ac49f34..c1294f269c 100644
--- a/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md
+++ b/packages/cli/plugins/sentry-cli/skills/sentry-cli/SKILL.md
@@ -284,8 +284,8 @@ npm install -g sentry
### Authentication
```bash
-sentry auth login
-sentry auth login --token YOUR_SENTRY_API_TOKEN
+sentry auth
+sentry auth --token YOUR_SENTRY_API_TOKEN
sentry auth status
sentry auth logout
```
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 26b90c01ae..766e0f9034 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
@@ -26,19 +26,19 @@ Authenticate with Sentry
**Examples:**
```bash
-sentry auth login
+sentry auth
-sentry auth login --token YOUR_SENTRY_API_TOKEN
+sentry auth --token YOUR_SENTRY_API_TOKEN
-sentry auth login --read-only
+sentry auth --read-only
-sentry auth login --scope project:read --scope org:read
-sentry auth login --scope project:read,event:read
+sentry auth --scope project:read --scope org:read
+sentry auth --scope project:read,event:read
-sentry auth login --url https://sentry.example.com
-SENTRY_URL=https://sentry.example.com sentry auth login
+sentry auth --url https://sentry.example.com
+SENTRY_URL=https://sentry.example.com sentry auth
-sentry auth login --token YOUR_TOKEN --url https://sentry.example.com
+sentry auth --token YOUR_TOKEN --url https://sentry.example.com
```
### `sentry auth logout`
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 2324b3b93d..99f49ca221 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
@@ -236,6 +236,10 @@ 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
@@ -265,10 +269,6 @@ sentry issue unresolve CLI-G5
sentry issue reopen CLI-G5 # alias
```
-### `sentry issue unresolve `
-
-Reopen a resolved issue
-
### `sentry issue archive `
Archive (ignore) an issue
diff --git a/packages/cli/script/generate-skill-markdown.ts b/packages/cli/script/generate-skill-markdown.ts
index fd2f22b696..eb19074f46 100644
--- a/packages/cli/script/generate-skill-markdown.ts
+++ b/packages/cli/script/generate-skill-markdown.ts
@@ -18,10 +18,20 @@ export function extractCommandPathFromHeading(
export function matchExampleToCommand(
code: string,
commandPaths: readonly string[],
- groupFallback: string
+ groupFallback: string,
+ defaultCommandPath?: string
): string | undefined {
- return (
- commandPaths.find((path) => code.includes(path)) ??
- (code.includes(groupFallback) ? groupFallback : 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;
}
diff --git a/packages/cli/script/generate-skill.ts b/packages/cli/script/generate-skill.ts
index fc7df43dfe..e87189dbb6 100644
--- a/packages/cli/script/generate-skill.ts
+++ b/packages/cli/script/generate-skill.ts
@@ -60,6 +60,34 @@ import {
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;
+}
+
const SKILL_DIR = "plugins/sentry-cli/skills/sentry-cli";
const OUTPUT_PATH = `${SKILL_DIR}/SKILL.md`;
const REFERENCES_DIR = `${SKILL_DIR}/references`;
@@ -290,10 +318,10 @@ npm install -g sentry
\`\`\`bash
# OAuth login (recommended)
-sentry auth login
+sentry auth
# Or use an API token
-sentry auth login --token YOUR_SENTRY_API_TOKEN
+sentry auth --token YOUR_SENTRY_API_TOKEN
# Check auth status
sentry auth status
@@ -341,10 +369,14 @@ function collectCommandPaths(
*/
function associateCodeBlocks(
tokens: Token[],
- commandPaths: string[],
- commandGroup: string,
- examples: Map
+ 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;
@@ -359,7 +391,12 @@ function associateCodeBlocks(
if (currentCmd && examples.has(currentCmd)) {
appendExample(examples, currentCmd, code);
} else {
- const target = matchExampleToCommand(code, commandPaths, groupFallback);
+ const target = matchExampleToCommand(
+ code,
+ commandPaths,
+ groupFallback,
+ defaultCommandPath
+ );
if (target) {
appendExample(examples, target, code);
}
@@ -377,7 +414,8 @@ function associateCodeBlocks(
* by matching code blocks to commands via heading context or content analysis.
*/
async function loadCommandExamples(
- commandGroup: string
+ commandGroup: string,
+ defaultCommandName?: string
): Promise