Dashboard › cli › Session 1JSvy5NElggD
1JSvy5NElggDSkZFvIn /home/byk/Code/getsentry/cli-pr-1558, perform a read-only exhaustive audit of every kind: "array" positional under packages/cli/src/commands (expected 33). For each route/file, determine: (a) whether zero positional values is a valid successful invocation, conditionally valid because flags supply the input, or invalid; (b) whether the command deliberately handles zero itself with ContextError/ValidationError/hint and therefore adding Stricli minimum would change its established error/output contract; (c) the public usage syntax implied by code/docs/tests; (d) whether minimum: 0, minimum: 1, a higher minimum, or no runtime metadata change is justified. Pay special attention to event send, schema, issue merge, project create, debug-files upload/find, help, local run, monitor run, dashboard commands, and commands with compound positional grammar. Do not edit files. Return a concise complete table covering all 33 and recommend the smallest safe implementation that satisfies: introspection derives collection optionality from Stricli minimum; optional arrays render [<x...>]; issue merge remains publicly required; existing typed command errors are not replaced by scanner errors unless already intended. Include exact file:line evidence for non-obvious cases.
/home/byk/Code/getsentry/cli-pr-1558/AGENTS.md /home/byk/Code/getsentry/cli-pr-1558/packages/cli/AGENTS.md
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/CONTRIBUTING.md
<path>/home/byk/Code/getsentry/cli-pr-1558/AGENTS.md</path> <type>file</type> <content> 1: # Jared (Outpost agent) 2: 3: Autonomous GitHub coding agent. Work in `/workspace/repo`. 4: 5: ## Model tiers 6: 7: The primary model is chosen per event (see `src/agents/models.ts`): heavy for 8: code-producing situations, cheaper for lightweight ones. 9: 10: | Role | Subagent | Model | 11: | --- | --- | --- | 12: | Triage / plan / review (heavy) | (primary Jared) | Claude Opus 4.8 | 13: | Triage / plan / review (light) | (primary Jared) | xAI Grok 4.3 | 14: | Explore | `explore` | OpenAI gpt-5-mini | 15: | Implement | `implement` | Moonshot kimi-k2.7-code | 16: | Ship (commit/push/PR) | `ship` | xAI Grok (`grok-build-0.1`) | 17: 18: Pipeline: triage → explore → plan → implement → review → ship. 19: (`worker` is a deprecated alias of `implement`.) 20: 21: Operators also talk to Jared directly from the Outpost dashboard. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/AGENTS.md</path> <type>file</type> <content> 1: # AGENTS.md 2: 3: Guidelines for AI agents working in this codebase. 4: 5: ## Project Overview 6: 7: **Sentry CLI** is a command-line interface for [Sentry](https://sentry.io), built with Node.js, [pnpm](https://pnpm.io), and [Stricli](https://bloomberg.github.io/stricli/). It lives in `packages/cli` of a pnpm workspace; the docs site lives in `apps/cli-docs`. 8: 9: ### Goals 10: 11: - **Zero-config experience** - Auto-detect project context from DSNs in source code and env files 12: - **AI-powered debugging** - Integrate Seer AI for root cause analysis and fix plans 13: - **Developer-friendly** - Follow `gh` CLI conventions for intuitive UX 14: - **Agent-friendly** - JSON output and predictable behavior for AI coding agents 15: - **Fast** - Native binaries via Node SEA (fossilize), SQLite caching for API responses 16: 17: ### Key Features 18: 19: - **DSN Auto-Detection** - ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/CONTRIBUTING.md</path> <type>file</type> <content> 1: # Contributing to Sentry CLI 2: 3: This guide documents the patterns and conventions used in this CLI for consistency. 4: 5: ## Command Patterns 6: 7: We follow [gh CLI](https://cli.github.com/) conventions for best-in-class developer experience. 8: 9: ### List Commands 10: 11: List commands use **optional positional arguments** for context with smart auto-detection. 12: 13: ```bash 14: sentry org list [--limit N] [--json] 15: sentry project list [org] [--limit N] [--json] 16: sentry issue list [<org>/<project>] [--json] 17: ``` 18: 19: **Target syntax**: 20: - `<org>/<project>` - Explicit organization and project (e.g., `my-org/frontend`) 21: - `<org>/` - All projects in the specified organization 22: - `<project>` - Search for project by name across all accessible organizations 23: - *(omit)* - Auto-detect from DSN or config 24: 25: **Rationale**: Positional ...
File not found: /home/byk/Code/getsentry/cli-pr-1558/.cursor/rules/ultracite.mdc
No files found
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "sentry",
3: "version": "0.45.0-dev.0",
4: "description": "Sentry CLI - A command-line interface for using Sentry built by robots and humans for robots and humans",
5: "repository": {
6: "type": "git",
7: "url": "git+https://github.com/getsentry/cli.git"
8: },
9: "main": "./dist/index.cjs",
10: "type": "module",
11: "types": "./dist/index.d.cts",
12: "exports": {
13: ".": {
14: "import": {
15: "types": "./dist/index.d.mts",
16: "default": "./dist/index.mjs"
17: },
18: "require": {
19: "types": "./dist/index.d.cts",
20: "default": "./dist/index.cjs"
21: }
22: }
23: },
24: "bin": {
25: "sentry": "./dist/bin.cjs"
26: },
27: "files": [
28: "dist/bin.cjs",
29: "dist/index.cjs",
30: "dist/index.mjs",
31: "dist/index.d.cts",
32: "dist/index.d.mts",
33: ...
Found 33 matches /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/react-native/xcode.ts: Line 491: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/view.ts: Line 1082: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/view.ts: Line 484: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/send.ts: Line 142: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/logs.ts: Line 130: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/cli/feedback.ts: Line 41: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/cli/defaults.ts: Line 308: kind: "array", /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/docs/query.ts: Line 40: kind: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/send.ts</path>
<type>file</type>
<content>
1: /**
2: * `sentry event send` — Send a Sentry event from CLI flags or a JSON file.
3: *
4: * Unlike most commands, this authenticates via a DSN (not a Bearer token),
5: * so no `sentry auth login` is required. The DSN can be provided via:
6: * 1. --dsn flag
7: * 2. SENTRY_DSN environment variable
8: */
9:
10: import type { DsnComponents, Event } from "@sentry/core";
11: import { createEventEnvelope, makeDsn, serializeEnvelope } from "@sentry/core";
12: import type { SentryContext } from "../../context.js";
13: import { buildCommand } from "../../lib/command.js";
14: import {
15: buildEventFromFlags,
16: type SendEventFlags,
17: } from "../../lib/envelope/event-builder.js";
18: import {
19: readFileBytes,
20: requireDsn,
21: sendEnvelopeRequest,
22: } from "../../lib/envelope/transport.js";
23: import { ConfigError, ValidationError } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/schema.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry schema
3: *
4: * Browse and search the Sentry API schema. Shows available resources,
5: * operations, and endpoint details from the generated API index.
6: *
7: * Usage:
8: * sentry schema → list all resources
9: * sentry schema --all → flat list of all endpoints
10: * sentry schema --search <query> → search endpoints by keyword
11: * sentry schema <resource> → show endpoints for a resource
12: * sentry schema <resource> <op> → show detailed endpoint info
13: * sentry schema monitor* → glob search for resources
14: */
15:
16: import type { SentryContext } from "../context.js";
17: import {
18: type ApiEndpoint,
19: getAllEndpoints,
20: getEndpoint,
21: getEndpointsByResource,
22: getResourceSummaries,
23: type ResourceSummary,
24: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/issue/merge.ts</path> <type>file</type> <content> 1: /** 2: * sentry issue merge 3: * 4: * Merge 2+ issues into a single canonical group. Sentry's web UI has this 5: * as a bulk action; here we expose it as a direct command. 6: * 7: * ## Flow 8: * 9: * 1. Collect 2+ issue args (variadic positional) 10: * 2. Resolve each to a numeric group ID + org via `resolveIssue` 11: * 3. Verify all issues are in the same org (cross-org merge rejected by API) 12: * 4. Optionally pin the canonical parent via `--into` 13: * 5. Call `mergeIssues(org, groupIds)` — the API auto-picks the parent 14: * unless we pre-sort with our chosen parent first 15: * 6. Emit the merge result 16: * 17: * Sentry picks the parent by size (largest by event count). ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/project/create.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry project create
3: *
4: * Create one or more Sentry projects.
5: * Supports `[<org>/]<name>:<platform>` pairs for one or more projects.
6: *
7: * ## Flow
8: *
9: * 1. Parse one or more name:platform pairs and extract any org prefix
10: * 2. Resolve org → positional prefix > env vars > config defaults > DSN auto-detection
11: * (all names must share one org)
12: * 3. For each name: resolve team + create project (fetch DSN, build URL)
13: * 4. Display results (one block per project)
14: *
15: * Every project is a `name:platform` pair (e.g. `sentry project create
16: * web:javascript api:python-django`). The platform must always be attached
17: * with `:` — there is no space-separated form, with or without an explicit
18: * org. Project names cannot contain whitespace.
19: */
20:
21: import type { SentryContext } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/debug-files/upload.ts</path> <type>file</type> <content> 1: /** 2: * sentry debug-files upload <path>... 3: * 4: * Scan files and directories for native debug information files (Mach-O/dSYM, 5: * ELF, PE/PDB, Portable PDB, WASM, Breakpad, source bundles), filter them, and 6: * upload them to Sentry via the DIF chunk-upload protocol. 7: * 8: * Org/project are resolved via the standard cascade (DSN auto-detection, env 9: * vars, config defaults), so `--no-upload` (dry-run) needs no credentials. 10: * 11: * Honors the server-advertised `max_file_size` (oversized files are skipped) 12: * and `max_wait` (clamps the processing wait). `.zip` archives are scanned in 13: * place (disable with `--no-zips`); `--derived-data` additionally scans Xcode's 14: * DerivedData folder on macOS. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/debug-files/find.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry debug-files find <id>...
3: *
4: * Locate debug-information files for one or more debug identifiers by searching
5: * well-known locations (Xcode DerivedData), the current directory, and any
6: * extra `--path` directories. Local-only — no API calls.
7: *
8: * Exits non-zero when any requested id could not be located, mirroring the
9: * legacy `sentry-cli difutil find`.
10: */
11:
12: import { stat } from "node:fs/promises";
13: import { homedir } from "node:os";
14: import { join } from "node:path";
15: import type { SentryContext } from "../../context.js";
16: import { buildCommand } from "../../lib/command.js";
17: import {
18: FIND_DIF_TYPES,
19: type FindResult,
20: findDebugFiles,
21: } from "../../lib/dif/find.js";
22: import { ValidationError } from "../../lib/errors.js";
23: import { colorTag, renderMarkdown } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/help.ts</path>
<type>file</type>
<content>
1: /**
2: * Help Command
3: *
4: * Provides help information for the CLI.
5: * - `sentry help` or `sentry` (no args): Shows branded help with banner
6: * - `sentry help <command>`: Shows detailed help for that command
7: * - `sentry help --json`: Emits full command tree as structured JSON
8: * - `sentry help --json <command>`: Emits specific command/group metadata as JSON
9: */
10:
11: import type { SentryContext } from "../context.js";
12: import { buildCommand } from "../lib/command.js";
13: import { OutputError } from "../lib/errors.js";
14: import { CommandOutput } from "../lib/formatters/output.js";
15: import {
16: formatHelpHuman,
17: introspectAllCommands,
18: introspectCommand,
19: } from "../lib/help.js";
20:
21: export const helpCommand = buildCommand({
22: auth: false,
23: docs: {
24: brief: "Display help for a command",
25: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/local/run.ts</path> <type>file</type> <content> 1: /** 2: * sentry local run 3: * 4: * Run a command with the local dev server enabled. Injects 5: * `SENTRY_SPOTLIGHT` (read automatically by server-side SDKs) plus the 6: * framework-prefixed client variants (`NEXT_PUBLIC_SENTRY_SPOTLIGHT`, 7: * `VITE_SENTRY_SPOTLIGHT`, etc.) so the spotlight URL also reaches 8: * browser bundles regardless of bundler. 9: * 10: * If no server is already running on the target port, one is started 11: * automatically in the background and shut down when the child exits. 12: * If one is already running, this command attaches to it as an SSE consumer 13: * so events still tail to the terminal. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/monitor/run.ts</path> <type>file</type> <content> 1: /** 2: * sentry monitor run 3: * 4: * Wrap an arbitrary command with cron monitor check-ins. Sends an 5: * `in_progress` check-in when the command starts, then `ok`/`error` (with 6: * duration) on completion based on the child's exit code. 7: * 8: * Check-ins are sent via DSN (not an auth token), reusing the envelope 9: * transport in `src/lib/envelope/`. The DSN is resolved from `--dsn`, the 10: * `SENTRY_DSN` env var, or by auto-detecting it from the project sources. 11: * 12: * The wrapped command inherits the parent's stdio and signals (SIGINT/SIGTERM 13: * are forwarded), and its exit code is preserved. Check-in send failures are 14: * non-fatal — they are logged and the wrapped command still runs and exits 15: * with its own code. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/react-native/xcode.ts</path>
<type>file</type>
<content>
420: brief: "Upload React Native sourcemaps (Xcode build step)",
421: fullDescription:
422: "Upload React Native sourcemaps from an Xcode build phase. In a release " +
423: "build the RN build script is wrapped so the produced bundle and " +
424: "sourcemap are captured and uploaded; in a simulator build with " +
425: "`--allow-fetch` they are fetched from the packager; in a debug build " +
426: "the script simply runs.\n\n" +
427: "Release/distribution come from `SENTRY_RELEASE`/`SENTRY_DIST` or the " +
428: "app Info.plist (unless `--no-auto-release`); outside an Xcode build the " +
429: "release is discovered via `xcodebuild`. Use `--wait`/`--wait-for` to " +
430: "block until the server finishes processing the upload.",
431: },
432: auth: false,
433: output: {
434: human: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/view.ts</path>
<type>file</type>
<content>
1020: * when agents paste dozens of IDs.
1021: *
1022: * When all fetches fail, re-throws the error from the primary (first) event.
1023: */
1024: export async function fetchMultipleEvents(
1025: options: FetchMultipleOptions
1026: ): Promise<SentryEvent[]> {
1027: const { eventIds, org, project, prefetchedEvent, primaryId } = options;
1028: const log = logger.withTag("event.view");
1029: const limit = pLimit(ORG_FANOUT_CONCURRENCY);
1030:
1031: const results = await Promise.allSettled(
1032: eventIds.map((id) =>
1033: limit(() =>
1034: fetchEventWithContext(
1035: id === primaryId ? prefetchedEvent : null,
1036: org,
1037: project,
1038: id
1039: )
1040: )
1041: )
1042: );
1043:
1044: const events: SentryEvent[] = [];
1045: for (let i = 0; i < results.length; i++) {
1046: ...
Found 17 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/view.ts:
Line 170: const USAGE_HINT = "sentry event view <org>/<project> <event-id>";
Line 239: throw new ContextError("Issue ID", BARE_LATEST_HINT, [
Line 354: export function parsePositionalArgs(args: string[]): ParsedPositionalArgs {
Line 355: if (args.length === 0) {
Line 356: throw new ContextError("Event ID", USAGE_HINT, []);
Line 361: throw new ContextError("Event ID", USAGE_HINT, []);
Line 384: throw new ContextError("Event ID", USAGE_HINT, [
Line 390: if (args.length === 1) {
Line 414: const extraEventIds = args.length > 2 ? args.slice(2) : undefined;
Line 440: throw new ContextError("Issue ID", BARE_LATEST_HINT, [
Line 447: const extraEventIds = args.length > 2 ? args.slice(2) : undefined;
Line 460: const extraEventIds = args.length > 2 ? args.slice(2) : undefined;
Line 471: const extraEventIds = args.length > 2 ? ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/view.ts</path>
<type>file</type>
<content>
150: }
151: return data.events.map(transform);
152: }
153:
154: /**
155: * Build a CLI-native replay hint when the event is linked to a replay.
156: */
157: function replayHint(org: string, event: SentryEvent): string | undefined {
158: const replayId = getReplayIdFromEvent(event);
159: return replayId
160: ? `Related replay: sentry replay view ${org}/${replayId}`
161: : undefined;
162: }
163:
164: function joinHintParts(parts: Array<string | undefined>): string | undefined {
165: const hints = parts.filter((part): part is string => Boolean(part));
166: return hints.length > 0 ? hints.join(" | ") : undefined;
167: }
168:
169: /** Usage hint for ContextError messages */
170: const USAGE_HINT = "sentry event view <org>/<project> <event-id>";
171:
172: /**
173: * Expand positional args by splitting each on newlines. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/view.ts</path>
<type>file</type>
<content>
410:
411: const issue = await getIssueByShortId(org, issueShortId);
412: let project: string | undefined;
413: if (issue.project?.slug) {
414: setOrgProjectContext([org], [issue.project.slug]);
415: project = issue.project.slug;
416: }
417:
418: const event = await getLatestEvent(org, issue.id);
419: const traceId = event?.contexts?.trace?.trace_id;
420: if (!traceId) {
421: throw new ValidationError(
422: `Could not find a trace for issue '${issueShortId}'. The latest event has no trace context.\n\n` +
423: `Try: sentry issue view ${issueShortId}`
424: );
425: }
426:
427: return { traceId, org, project };
428: }
429:
430: /**
431: * Fetch per-span details when --full or --json is active.
432: *
433: * Extracted from func() to keep cognitive complexity under the Biome
434: * limit of 15. ...
Found 15 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/view.ts:
Line 25: ContextError,
Line 46: parseTraceTargetWithRecovery,
Line 61: /** Usage hint for ContextError messages */
Line 62: const USAGE_HINT = "sentry trace view [<org>/<project>/]<trace-id>";
Line 138: export function preProcessArgs(args: string[]): {
Line 145: if (args.length === 0) {
Line 155: if (args.length === 1 && looksLikeIssueShortId(first)) {
Line 162: if (args.length < 2) {
Line 407: throw new ContextError("Organization", `sentry issue view ${issueShortId}`);
Line 527: const parsed = await parseTraceTargetWithRecovery(
Line 529: USAGE_HINT
Line 535: USAGE_HINT
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/logs.ts:
Line 90: const USAGE_HINT = "sentry trace logs [<org>/[<project>/]]<trace-id>";
Line 186: const parsed = parseTraceTarget(args, USAGE_HINT);
Line 188: const { ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/view.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry trace view
3: *
4: * View detailed information about a distributed trace.
5: */
6:
7: import type { SentryContext } from "../../context.js";
8: import {
9: attributesToDict,
10: fetchMultiSpanDetails,
11: getDetailedTrace,
12: getIssueByShortId,
13: getLatestEvent,
14: getProject,
15: type TraceItemDetail,
16: } from "../../lib/api-client.js";
17: import {
18: detectSwappedViewArgs,
19: looksLikeIssueShortId,
20: spansFlag,
21: } from "../../lib/arg-parsing.js";
22: import { openInBrowser } from "../../lib/browser.js";
23: import { buildCommand } from "../../lib/command.js";
24: import {
25: ContextError,
26: ResolutionError,
27: ValidationError,
28: } from "../../lib/errors.js";
29: import {
30: computeTraceSummary,
31: formatSimpleSpanTree,
32: formatTraceSummary,
33: } from "../../lib/formatters/index.js";
34: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/trace/logs.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry trace logs
3: *
4: * View logs associated with a distributed trace.
5: */
6:
7: import type { SentryContext } from "../../context.js";
8: import { type LogSortDirection, listTraceLogs } from "../../lib/api-client.js";
9: import {
10: buildProjectQuery,
11: parseLogSort,
12: validateLimit,
13: } from "../../lib/arg-parsing.js";
14: import { openInBrowser } from "../../lib/browser.js";
15: import { buildCommand } from "../../lib/command.js";
16: import { toSearchQueryError } from "../../lib/errors.js";
17: import { filterFields } from "../../lib/formatters/json.js";
18: import { formatLogTable } from "../../lib/formatters/log.js";
19: import { CommandOutput, formatFooter } from "../../lib/formatters/output.js";
20: import {
21: applyFreshFlag,
22: FRESH_ALIASES,
23: FRESH_FLAG,
24: LIST_MAX_LIMIT,
25: } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/cli/feedback.ts</path>
<type>file</type>
<content>
1: /**
2: * Feedback Command
3: *
4: * Allows users to submit feedback about the CLI.
5: * All arguments after 'feedback' are joined into a single message.
6: *
7: * @example sentry cli feedback i love this tool
8: * @example sentry cli feedback the issue view is confusing
9: */
10:
11: import { isatty } from "node:tty";
12: // biome-ignore lint/performance/noNamespaceImport: Sentry SDK recommends namespace import
13: import * as Sentry from "@sentry/node-core/light";
14: import type { SentryContext } from "../../context.js";
15: import { buildCommand } from "../../lib/command.js";
16: import { ConfigError, ValidationError } from "../../lib/errors.js";
17: import { formatFeedbackResult } from "../../lib/formatters/human.js";
18: import { CommandOutput } from "../../lib/formatters/output.js";
19: import { logger } from "../../lib/logger.js";
20:
21: /** ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/cli/defaults.ts</path>
<type>file</type>
<content>
260: };
261:
262: // ---------------------------------------------------------------------------
263: // Command
264: // ---------------------------------------------------------------------------
265:
266: const log = logger.withTag("defaults");
267:
268: export const defaultsCommand = buildCommand({
269: auth: false,
270: docs: {
271: brief: "View and manage default settings",
272: fullDescription:
273: "View and manage persistent CLI default settings.\n\n" +
274: "With no arguments, shows all current defaults. Pass a key and value\n" +
275: "to set a default, or use `--clear` to remove defaults.\n\n" +
276: "## Examples\n\n" +
277: "```\n" +
278: "sentry cli defaults # Show all defaults\n" +
279: "sentry cli defaults org my-org # Set default organization\n" +
280: "sentry cli ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/docs/query.ts</path>
<type>file</type>
<content>
1: import type { SentryContext } from "../../context.js";
2: import { buildCommand } from "../../lib/command.js";
3: import { detectDocsContext } from "../../lib/docs-context.js";
4: import { queryDocs } from "../../lib/docs-service.js";
5: import { ValidationError } from "../../lib/errors.js";
6: import { CommandOutput } from "../../lib/formatters/output.js";
7: import { withProgress } from "../../lib/polling.js";
8:
9: type QueryFlags = { readonly fields?: string[]; readonly json: boolean };
10: type QueryOutput = {
11: answer: string;
12: detectedContext: Awaited<ReturnType<typeof detectDocsContext>>;
13: sources: string[];
14: };
15:
16: /** Friendly wait messages for a docs-MCP request without measurable stages. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/docs/list.ts</path>
<type>file</type>
<content>
1: import type { SentryContext } from "../../context.js";
2: import { validateLimit } from "../../lib/arg-parsing.js";
3: import { buildCommand } from "../../lib/command.js";
4: import { type DocsListResponse, listDocs } from "../../lib/docs-service.js";
5: import { ValidationError } from "../../lib/errors.js";
6: import { muted } from "../../lib/formatters/colors.js";
7: import { CommandOutput } from "../../lib/formatters/output.js";
8: import { formatTable } from "../../lib/formatters/table.js";
9:
10: type ListFlags = {
11: readonly fields?: string[];
12: readonly json: boolean;
13: readonly limit: number;
14: };
15:
16: function parseLimit(value: string): number {
17: return validateLimit(value, 1, 20);
18: }
19:
20: function formatListHuman(data: DocsListResponse): string {
21: if (data.results.length === 0) {
22: return muted("No documentation ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/build/upload.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry build upload <paths...>
3: *
4: * Upload mobile builds to Sentry for preprod size analysis. Each build is
5: * normalized into a deterministic wrapper ZIP and uploaded via the
6: * chunk-upload + preprod-artifacts assemble protocol.
7: *
8: * This PR supports Android APK/AAB. iOS XCArchive/IPA is ported separately;
9: * git/VCS metadata collection is added in a follow-up. Sentry SaaS only.
10: */
11:
12: import { mkdtemp, rm, stat } from "node:fs/promises";
13: import { tmpdir } from "node:os";
14: import { join } from "node:path";
15: import type { SentryContext } from "../../context.js";
16: import {
17: type BuildUploadMetadata,
18: uploadBuild,
19: } from "../../lib/api/preprod-artifacts.js";
20: import {
21: detectBuildFormatFromFile,
22: normalizeBuildDirectory,
23: normalizeBuildFile,
24: normalizeIpa,
25: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/proguard/upload.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry proguard upload <path>...
3: *
4: * Upload ProGuard/R8 mapping files to Sentry using the DIF
5: * chunk-upload protocol. Each mapping file is bundled as
6: * `proguard/<uuid>.txt` where UUID is derived from the file content.
7: * Org/project resolved via standard cascade (DSN auto-detection,
8: * env vars, config defaults).
9: */
10:
11: import { readFile } from "node:fs/promises";
12: import type { SentryContext } from "../../context.js";
13: import type { ProguardMapping } from "../../lib/api/proguard.js";
14: import { uploadProguardMappings } from "../../lib/api/proguard.js";
15: import { buildCommand } from "../../lib/command.js";
16: import { ContextError, ValidationError } from "../../lib/errors.js";
17: import { mdKvTable, renderMarkdown } from "../../lib/formatters/markdown.js";
18: import { CommandOutput } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/span/view.ts</path>
<type>file</type>
<content>
300: const data = attributesToDict(detail.attributes);
301: if (Object.keys(data).length > 0) {
302: base.data = data;
303: }
304: }
305:
306: return base;
307: });
308: }
309:
310: /**
311: * Format span view data for human-readable terminal output.
312: *
313: * Renders each span's details (KV table + ancestor chain) and optionally
314: * shows the child span tree. When attribute details are available, notable
315: * custom attributes are appended after the standard fields.
316: * Multiple spans are separated by `---`.
317: */
318: function formatSpanViewHuman(data: SpanViewData): string {
319: const parts: string[] = [];
320: for (let i = 0; i < data.results.length; i++) {
321: if (i > 0) {
322: parts.push("\n---\n");
323: }
324: const result = data.results[i];
325: if (!result) {
326: ...
Found 24 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/span/view.ts:
Line 16: import { ContextError, ValidationError } from "../../lib/errors.js";
Line 53: /** Usage hint for ContextError messages */
Line 54: const USAGE_HINT =
Line 85: * @throws {ContextError} If insufficient arguments or a single bare span ID
Line 94: * the single-slash case). Throws a trace-focused {@link ContextError} when
Line 98: * @throws {ContextError} When the trace-target prefix fails validation.
Line 128: traceTarget = parseSlashSeparatedTraceTarget(tracePrefix, USAGE_HINT);
Line 134: // trace-focused ContextError that preserves the underlying detail
Line 139: throw new ContextError("Trace ID", USAGE_HINT, [
Line 151: export function parsePositionalArgs(args: string[]): SpanViewArgs {
Line 152: if (args.length === 0) {
Line 153: throw new ContextError("Trace ID and span ID", USAGE_HINT, []);
Line 158: throw new ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/span/view.ts</path>
<type>file</type>
<content>
45:
46: type ViewFlags = {
47: readonly json: boolean;
48: readonly spans: number;
49: readonly fresh: boolean;
50: readonly fields?: string[];
51: };
52:
53: /** Usage hint for ContextError messages */
54: const USAGE_HINT =
55: "sentry span view [<org>/<project>/]<trace-id> <span-id> [<span-id>...]";
56:
57: /** Result of the initial positional-arg parse for `span view`. */
58: type SpanViewArgs =
59: | {
60: /** Args are already resolved (auto-split `<trace-id>/<span-id>`). */
61: kind: "resolved";
62: traceTarget: ReturnType<typeof parseSlashSeparatedTraceTarget>;
63: rawSpanIds: string[];
64: }
65: | {
66: /**
67: * First arg is the raw trace target (needs async recovery); the rest
68: * are raw span IDs. Command layer calls `parseTraceTargetWithRecovery`. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/span/list.ts</path>
<type>file</type>
<content>
130: for (const a of alias) {
131: expanded.add(a);
132: }
133: } else {
134: expanded.add(f);
135: }
136: }
137:
138: // Remove anything already requested by SPAN_FIELDS or its output aliases
139: for (const known of KNOWN_SPAN_FIELDS) {
140: expanded.delete(known);
141: }
142:
143: return expanded.size > 0 ? Array.from(expanded) : undefined;
144: }
145:
146: /** Accepted values for the --sort flag (matches trace list) */
147: const VALID_SORT_VALUES: SpanSortValue[] = ["date", "duration"];
148:
149: /** Default sort order for span results */
150: const DEFAULT_SORT: SpanSortValue = "date";
151:
152: /** Default time period for span queries */
153: const DEFAULT_PERIOD = "7d";
154:
155: /** Pagination storage key for trace-scoped span listing */
156: export const PAGINATION_KEY = "span-list";
157:
158: /** ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/edit.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard widget edit
3: *
4: * Edit a widget in an existing dashboard using inline flags.
5: */
6:
7: import type { SentryContext } from "../../../context.js";
8: import { getDashboard, updateDashboard } from "../../../lib/api-client.js";
9: import { parseOrgProjectArg } from "../../../lib/arg-parsing.js";
10: import { buildCommand, numberParser } from "../../../lib/command.js";
11: import { ValidationError } from "../../../lib/errors.js";
12: import { formatWidgetEdited } from "../../../lib/formatters/human.js";
13: import { CommandOutput } from "../../../lib/formatters/output.js";
14: import { buildDashboardUrl } from "../../../lib/sentry-urls.js";
15: import {
16: type DashboardDetail,
17: type DashboardWidget,
18: type DashboardWidgetQuery,
19: FALLBACK_LAYOUT,
20: parseAggregate,
21: parseSortExpression,
22: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/edit.ts</path>
<type>file</type>
<content>
320: },
321: },
322: async *func(this: SentryContext, flags: EditFlags, ...args: string[]) {
323: const { cwd } = this;
324:
325: if (flags.index === undefined && !flags.title) {
326: throw new ValidationError(
327: "Specify --index or --title to identify the widget to edit.\n\n" +
328: "Example:\n" +
329: " sentry dashboard widget edit <dashboard> --title 'My Widget' --display bar",
330: "index"
331: );
332: }
333:
334: // Resolve dataset aliases (e.g. "errors" → "error-events") once, up front.
335: // Replace flags.dataset with the canonical value so every downstream
336: // consumer — validateEnumsAndAggregates, validateAggregateNames, and the
337: // PUT body — sees the normalized name. Without this, dataset-aware
338: // aggregate validation (e.g. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/delete.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard widget delete
3: *
4: * Remove a widget from an existing dashboard.
5: *
6: * Uses `buildDeleteCommand` — auto-injects `--yes`/`--force`/`--dry-run`
7: * flags. Non-interactive guard is disabled (`noNonInteractiveGuard`) because
8: * widget deletion is reversible (re-add the widget). `--yes`/`--force` are
9: * accepted but have no effect today (no confirmation prompt); `--dry-run`
10: * shows which widget would be removed without modifying the dashboard.
11: */
12:
13: import type { SentryContext } from "../../../context.js";
14: import { getDashboard, updateDashboard } from "../../../lib/api-client.js";
15: import { parseOrgProjectArg } from "../../../lib/arg-parsing.js";
16: import { numberParser } from "../../../lib/command.js";
17: import { ValidationError } from "../../../lib/errors.js";
18: import { ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/add.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard widget add
3: *
4: * Add a widget to an existing dashboard using inline flags.
5: */
6:
7: import type { SentryContext } from "../../../context.js";
8: import { getDashboard, updateDashboard } from "../../../lib/api-client.js";
9: import { parseOrgProjectArg } from "../../../lib/arg-parsing.js";
10: import { buildCommand, numberParser } from "../../../lib/command.js";
11: import { ValidationError } from "../../../lib/errors.js";
12: import { formatWidgetAdded } from "../../../lib/formatters/human.js";
13: import { CommandOutput } from "../../../lib/formatters/output.js";
14: import { buildDashboardUrl } from "../../../lib/sentry-urls.js";
15: import {
16: assignDefaultLayout,
17: type DashboardDetail,
18: type DashboardWidget,
19: FALLBACK_LAYOUT,
20: prepareDashboardForUpdate,
21: validateWidgetLayout,
22: type ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/view.ts</path>
<type>file</type>
<content>
130: widgets: widgets.map((w, i) => ({
131: title: w.title,
132: displayType: w.displayType,
133: widgetType: w.widgetType,
134: description: (w as Record<string, unknown>).description as
135: | string
136: | undefined,
137: layout: w.layout,
138: queries: w.queries,
139: data: widgetResults.get(i) ?? {
140: type: "error" as const,
141: message: "No data returned",
142: },
143: })),
144: };
145: }
146:
147: /**
148: * Resolve the effective time range for a dashboard view.
149: *
150: * Priority: explicit --period flag > dashboard's saved period > 24h default.
151: * Dashboard period is a raw string from the API that needs parsing. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/revisions.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard revisions
3: *
4: * List revision history for a Sentry dashboard with cursor-based pagination.
5: */
6:
7: import type { SentryContext } from "../../context.js";
8: import { MAX_PAGINATION_PAGES } from "../../lib/api/infrastructure.js";
9: import {
10: API_MAX_PER_PAGE,
11: listDashboardRevisionsPaginated,
12: } from "../../lib/api-client.js";
13: import { parseOrgProjectArg } from "../../lib/arg-parsing.js";
14: import { buildCommand } from "../../lib/command.js";
15: import {
16: advancePaginationState,
17: buildPaginationContextKey,
18: hasPreviousPage,
19: resolveCursor,
20: } from "../../lib/db/pagination.js";
21: import { filterFields } from "../../lib/formatters/json.js";
22: import { colorTag, escapeMarkdownCell } from "../../lib/formatters/markdown.js";
23: import { CommandOutput } from ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/restore.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard restore
3: *
4: * Restore a dashboard to a previous revision.
5: */
6:
7: import type { SentryContext } from "../../context.js";
8: import { restoreDashboardRevision } from "../../lib/api-client.js";
9: import { parseOrgProjectArg } from "../../lib/arg-parsing.js";
10: import { buildCommand } from "../../lib/command.js";
11: import { ValidationError } from "../../lib/errors.js";
12: import { colorTag, escapeMarkdownCell } from "../../lib/formatters/markdown.js";
13: import { CommandOutput } from "../../lib/formatters/output.js";
14: import { formatRelativeTime } from "../../lib/formatters/time-utils.js";
15: import { withProgress } from "../../lib/polling.js";
16: import { buildDashboardUrl } from "../../lib/sentry-urls.js";
17: import type { DashboardDetail } from "../../types/dashboard.js";
18: import {
19: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/list.ts</path>
<type>file</type>
<content>
340: * plus a link to the dashboards page in Sentry.
341: */
342: function buildHint(
343: result: DashboardListResult,
344: orgSlug: string
345: ): string | undefined {
346: const filterArg = result.titleFilter ? ` '${result.titleFilter}'` : "";
347: const navRaw = paginationHint({
348: hasPrev: !!result.hasPrev,
349: hasMore: !!result.hasMore,
350: prevHint: `sentry dashboard list ${orgSlug}/${filterArg} -c prev`,
351: nextHint: `sentry dashboard list ${orgSlug}/${filterArg} -c next`,
352: });
353: const nav = navRaw ? ` ${navRaw}` : "";
354: const url = buildDashboardsListUrl(orgSlug);
355:
356: if (result.dashboards.length === 0) {
357: // Empty results — show nav hint if prev/next exist, otherwise nothing
358: return nav ? `No dashboards found.${nav}` : undefined;
359: }
360:
361: return `Showing ...
Found 34 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/edit.ts:
Line 11: import { ValidationError } from "../../../lib/errors.js";
Line 326: throw new ValidationError(
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/delete.ts:
Line 17: import { ValidationError } from "../../../lib/errors.js";
Line 112: throw new ValidationError(
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/widget/add.ts:
Line 11: import { ValidationError } from "../../../lib/errors.js";
Line 58: if (args.length < 2) {
Line 59: throw new ValidationError(
Line 66: if (args.length > 3) {
Line 67: throw new ValidationError(
Line 68: `Too many positional arguments (got ${args.length}, expected at most 3).\n\n` +
Line 245: throw new ValidationError(
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/create.ts:
Line 14: import { ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/resolve.ts</path>
<type>file</type>
<content>
60: * @param cwd - Current working directory for auto-detection
61: * @param usageHint - Usage example for error messages
62: * @returns Organization slug
63: */
64: export async function resolveOrgFromTarget(
65: parsed: ReturnType<typeof parseOrgProjectArg>,
66: cwd: string,
67: usageHint: string
68: ): Promise<string> {
69: switch (parsed.type) {
70: case "explicit":
71: case "org-all": {
72: const org = await resolveEffectiveOrg(parsed.org);
73: setOrgProjectContext([org], []);
74: return org;
75: }
76: case "project-search":
77: case "auto-detect": {
78: // resolveOrg already sets telemetry context
79: const resolved = await resolveOrg({ cwd });
80: if (!resolved) {
81: throw new ContextError("Organization", usageHint);
82: }
83: return resolved.org;
84: }
85: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/dashboard/create.ts</path>
<type>file</type>
<content>
1: /**
2: * sentry dashboard create
3: *
4: * Create a new dashboard in a Sentry organization.
5: */
6:
7: import type { SentryContext } from "../../context.js";
8: import { createDashboard, getProject } from "../../lib/api-client.js";
9: import {
10: type ParsedOrgProject,
11: parseOrgProjectArg,
12: } from "../../lib/arg-parsing.js";
13: import { buildCommand } from "../../lib/command.js";
14: import { ContextError, ValidationError } from "../../lib/errors.js";
15: import { formatDashboardCreated } from "../../lib/formatters/human.js";
16: import { CommandOutput } from "../../lib/formatters/output.js";
17: import {
18: fetchProjectId,
19: resolveAllTargets,
20: resolveOrg,
21: resolveProjectBySlug,
22: toNumericId,
23: } from "../../lib/resolve-target.js";
24: import { buildDashboardUrl } from "../../lib/sentry-urls.js";
25: import { ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/view.ts</path>
<type>file</type>
<content>
430: hint =
431: "Expired log IDs are no longer retrievable — check non-expired IDs and re-run";
432: } else if (retentionDays) {
433: hint = `Make sure the log IDs are correct and were sent within the last ${retentionDays} days`;
434: } else {
435: hint = "Make sure the log IDs are correct";
436: }
437: throw new ResolutionError(
438: `${idList.length} log(s)`,
439: `not found in ${org}/${project}`,
440: hint,
441: idList.map((id) => `ID: ${id}`)
442: );
443: }
444:
445: /**
446: * Data returned by the log view command.
447: * Used by both JSON and human output paths. ...
Found 13 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/view.ts:
Line 70: const USAGE_HINT = "sentry log view <org>/<project> <log-id> [<log-id>...]";
Line 116: export function parsePositionalArgs(args: string[]): {
Line 122: if (args.length === 0) {
Line 123: throw new ContextError("Log ID", USAGE_HINT, []);
Line 128: throw new ContextError("Log ID", USAGE_HINT, []);
Line 131: if (args.length === 1) {
Line 145: throw new ContextError("Log ID", USAGE_HINT, []);
Line 158: throw new ContextError("Log ID", USAGE_HINT, []);
Line 173: throw new ContextError("Log ID", USAGE_HINT, []);
Line 188: if (args.length === 2) {
Line 201: throw new ContextError("Log ID", USAGE_HINT, []);
Line 285: throw new ContextError("Specific project", USAGE_HINT, []);
Line 546: throw new ContextError("Organization and project", USAGE_HINT);
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/view.ts</path>
<type>file</type>
<content>
55: import type { DetailedSentryLog, TraceItemDetail } from "../../types/index.js";
56:
57: const log = logger.withTag("log-view");
58:
59: /** Matches SPAN_DETAIL_CONCURRENCY in traces.ts */
60: const LOG_DETAIL_CONCURRENCY = 15;
61:
62: type ViewFlags = {
63: readonly json: boolean;
64: readonly web: boolean;
65: readonly fresh: boolean;
66: readonly fields?: string[];
67: };
68:
69: /** Usage hint for ContextError messages */
70: const USAGE_HINT = "sentry log view <org>/<project> <log-id> [<log-id>...]";
71:
72: /**
73: * Resolve a single-slash positional arg (`before/after`) as `org/log-id`, or
74: * return `null` when `after` is not a valid 32-char hex log ID and should fall
75: * through to `parseSlashSeparatedArg`. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/list.ts</path>
<type>file</type>
<content>
680: fields && fields.length > 0
681: ? logList.logs.map((log) => filterFields(log, fields))
682: : logList.logs;
683: return { data: items, hasMore: logList.hasMore };
684: }
685: // Single item (follow mode): return bare object for JSONL
686: return fields && fields.length > 0 ? filterFields(data, fields) : data;
687: }
688:
689: /** Validate flag combinations that are invalid regardless of mode. */
690: function validateFollowFlags(flags: ListFlags): void {
691: if (flags.follow && flags.sort === "oldest") {
692: throw new ValidationError(
693: '--sort "oldest" cannot be used with --follow. Follow mode streams new logs as they arrive.',
694: "sort"
695: );
696: }
697: }
698:
699: export const listCommand = buildListCommand(
700: "log",
701: {
702: docs: {
703: brief: "List logs from a ...
Found 10 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/view.ts:
Line 122: if (args.length === 0) {
Line 131: if (args.length === 1) {
Line 188: if (args.length === 2) {
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/list.ts:
Line 66: parseDualModeArgs,
Line 111: const TRACE_USAGE_HINT = "sentry log list [<org>/[<project>/]]<trace-id>";
Line 160: * Thin wrapper around {@link parseDualModeArgs} that binds the
Line 163: function parseLogListArgs(
Line 165: ): ReturnType<typeof parseDualModeArgs> {
Line 166: return parseDualModeArgs(args, TRACE_USAGE_HINT);
Line 808: TRACE_USAGE_HINT
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/log/list.ts</path>
<type>file</type>
<content>
90: */
91: type LogListResult = {
92: logs: LogLike[];
93: /** Trace ID, present for trace-filtered queries */
94: traceId?: string;
95: /** Whether more results are available beyond the limit */
96: hasMore: boolean;
97: /** Extra field names requested via `--fields`, used to render additional columns in human mode. */
98: extraFields?: string[];
99: };
100:
101: /** Output yielded by log list: either a batch (single-fetch) or an individual item (follow). ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/send-envelope.ts</path>
<type>file</type>
<content>
1: /**
2: * `sentry send-envelope` — Deprecated. Suggests `sentry event send --raw`.
3: *
4: * Kept as a hidden backward-compat alias that prints a deprecation notice
5: * and forwards to `sentry event send --raw`.
6: */
7:
8: import type { SentryContext } from "../context.js";
9: import { buildCommand } from "../lib/command.js";
10: import { CliError, EXIT } from "../lib/errors.js";
11:
12: export const sendEnvelopeCommand = buildCommand({
13: docs: {
14: brief: "Send a Sentry envelope file (deprecated)",
15: fullDescription:
16: "This command has been replaced by `sentry event send --raw <file>`.\n\n" +
17: "Use `sentry event send --raw ./captured.envelope` instead.",
18: },
19: auth: false,
20: skipRcUrlCheck: true,
21: output: {
22: human: () => "",
23: },
24: parameters: {
25: positional: {
26: kind: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/replay/view.ts</path>
<type>file</type>
<content>
300: errorCount: null,
301: logCount: null,
302: performanceIssueCount: null,
303: spanCount: null,
304: };
305: }
306: })
307: );
308: }
309:
310: async function enrichReplayView(
311: org: string,
312: replay: ReplayDetails
313: ): Promise<
314: Pick<ReplayViewData, "activity" | "relatedIssues" | "relatedTraces">
315: > {
316: const [activity, relatedIssues, relatedTraces] = await Promise.all([
317: fetchReplayActivity(org, replay),
318: fetchRelatedReplayIssues(org, replay),
319: fetchRelatedReplayTraces(org, replay),
320: ]);
321:
322: return { activity, relatedIssues, relatedTraces };
323: }
324:
325: export const viewCommand = buildCommand({
326: docs: {
327: brief: "View a Session Replay",
328: fullDescription:
329: "View detailed information about a Session ...
Found 15 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/replay/view.ts:
Line 23: ContextError,
Line 69: const USAGE_HINT =
Line 88: throw new ContextError("Replay ID", USAGE_HINT, []);
Line 102: throw new ContextError("Replay ID", USAGE_HINT, []);
Line 110: USAGE_HINT
Line 125: export function parsePositionalArgs(args: string[]): ParsedPositionalArgs {
Line 126: if (args.length === 0) {
Line 127: throw new ContextError("Replay ID", USAGE_HINT, []);
Line 129: if (args.length > 2) {
Line 131: `Too many positional arguments (got ${args.length}, expected at most 2).\n\nUsage: ${USAGE_HINT}`,
Line 138: throw new ContextError("Replay ID", USAGE_HINT, []);
Line 147: throw new ContextError("Replay ID", USAGE_HINT, [
Line 152: if (args.length === 1) {
Line 158: throw new ContextError("Replay ID", USAGE_HINT, []);
Line 162: args.length === 2 ? ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/replay/view.ts</path>
<type>file</type>
<content>
55:
56: type ViewFlags = {
57: readonly json: boolean;
58: readonly web: boolean;
59: readonly fresh: boolean;
60: readonly fields?: string[];
61: };
62:
63: type ParsedPositionalArgs = {
64: replayId: string;
65: targetArg: string | undefined;
66: warning?: string;
67: };
68:
69: const USAGE_HINT =
70: "sentry replay view [<org>/<project>/]<replay-id> | <replay-url>";
71: const MAX_ACTIVITY_EVENTS = 6;
72: const MAX_RELATED_ERRORS = 3;
73: const MAX_RELATED_TRACES = 2;
74:
75: const log = logger.withTag("replay.view");
76:
77: /**
78: * Parse a single positional argument as a replay target.
79: *
80: * Handles bare replay IDs, `<org>/<replay-id>`, `<org>/<project>/<replay-id>`,
81: * and Sentry replay URLs. ...
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trial/start.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trial/list.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trace/view.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trace/view.property.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trace/view.func.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trace/logs.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/trace/list.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/team/list.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/status/show.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/span/view.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/span/list.test.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/sourcemap/...
<path>/home/byk/Code/getsentry/cli-pr-1558</path> <type>directory</type> <entries> .craft.yml .git .github/ .gitignore .lore.md .nojekyll .npmrc AGENTS.md apps/ CHANGELOG.md codemods/ docs/ LICENSE.md node_modules/ package.json packages/ pnpm-lock.yaml pnpm-workspace.yaml README.md (19 entries) </entries>
<path>/home/byk/Code/getsentry/cli-pr-1558/.git</path> <type>file</type> <content> 1: gitdir: /home/byk/Code/getsentry/cli/.git/worktrees/cli-pr-1558 (End of file - total 1 lines) </content>
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/trace-target.ts</path>
<type>file</type>
<content>
1: /**
2: * Shared Trace-Target Parsing & Resolution
3: *
4: * Provides a unified abstraction for commands that accept trace IDs
5: * with optional org/project context. Trace IDs are globally unique,
6: * so these formats are all supported:
7: *
8: * - `<trace-id>` — auto-detect org/project from DSN/config
9: * - `<org>/<trace-id>` — org-scoped (for org-only APIs like trace-logs)
10: * - `<org>/<project>/<trace-id>` — fully explicit
11: *
12: * Also handles two-arg forms:
13: * - `<org>/<project> <trace-id>` — target as first arg, trace ID as second
14: * - `<org> <trace-id>` — org as first arg, trace ID as second
15: *
16: * Used by: span list, span view, trace view, trace logs.
17: */
18:
19: import { normalizeSlug, parseOrgProjectArg } from "./arg-parsing.js";
20: import { ContextError, ValidationError } from "./errors.js";
21: import {
22: ...
Found 1 matches /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/trace-target.ts: Line 604: export function parseDualModeArgs(
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/trace-target.ts</path>
<type>file</type>
<content>
560: const _exhaustive: never = parsed;
561: throw new ValidationError(`Unexpected target type: ${_exhaustive}`);
562: }
563: }
564: }
565:
566: // ---------------------------------------------------------------------------
567: // Dual-mode argument disambiguation (project vs trace)
568: // ---------------------------------------------------------------------------
569:
570: /**
571: * Result from dual-mode argument disambiguation.
572: *
573: * Used by commands that support both project-scoped listing (no trace ID)
574: * and trace-scoped listing (trace ID provided), like `span list` and
575: * `log list`. ...
No files found
Found 100 matches (more matches available)
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/introspect.ts:
Line 73: minimum?: number;
Line 77: /** A single positional parameter with optional brief and placeholder */
Line 81: optional?: boolean;
Line 91: optional: boolean;
Line 103: optional?: boolean;
Line 134: optional: boolean;
Line 216: return p.optional ? `[${placeholder}]` : placeholder;
Line 221: if (params.kind === "array") {
Line 224: return (params.minimum ?? 0) === 0 ? `[${value}]` : value;
Line 234: * the parameter is optional. Used by documentation generators to build
Line 251: optional: p.optional ?? false,
Line 256: if (params.kind === "array") {
Line 261: optional: (params.minimum ?? 0) === 0,
Line 288: optional: def.optional ?? def.kind === "boolean",
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/command.ts:
Line 20: * optionally returns a `{ hint }` ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/introspect.ts</path>
<type>file</type>
<content>
1: /**
2: * Route Tree Introspection
3: *
4: * Shared module for extracting structured metadata from Stricli's route tree.
5: * Used at runtime by `sentry help --json` and at build time by `generate-skill.ts`.
6: *
7: * While @stricli/core exports RouteMap and Command types, they require complex
8: * generic parameters (CommandContext) and don't export internal types like
9: * RouteMapEntry or FlagParameter. These simplified types are purpose-built
10: * for introspection and documentation generation.
11: */
12:
13: import type { CommandExample } from "./command.js";
14: import {
15: extractSchemaFields,
16: type SchemaFieldInfo,
17: } from "./formatters/output.js";
18: import { fuzzyMatch } from "./fuzzy.js";
19:
20: // ---------------------------------------------------------------------------
21: // Stricli Runtime Types (simplified for introspection)
22: ...
M packages/cli/script/generate-command-docs.ts M packages/cli/script/generate-skill-markdown.ts M packages/cli/src/lib/introspect.ts M packages/cli/test/lib/introspect.property.test.ts M packages/cli/test/lib/introspect.test.ts M packages/cli/test/script/generate-skill-markdown.test.ts ac72db51b (HEAD -> fix/agent-conversation-reference-root-cause) fix(docs): preserve public positional semantics c55566af4 fix(docs): derive command references from metadata c0b071f81 fix(docs): correct agent conversation argument syntax ec83887a1 (origin/main, origin/HEAD) fix(event): Prevent immediate retry of rate-limited org in event view fallback (#1566) e7beceb6b feat(telemetry): refresh coding agent detection (#1571) .../src/fragments/commands/agent-conversation.md | 33 --------- .../plugins/sentry-cli/skills/sentry-cli/SKILL.md | 46 ++++++------ .../sentry-cli/references/agent-conversation.md | 13 ++-- .../skills/sentry-cli/references/alert.md | 6 +- ...
diff --git a/packages/cli/script/generate-command-docs.ts b/packages/cli/script/generate-command-docs.ts
index ac02d200b..291b4efa0 100644
--- a/packages/cli/script/generate-command-docs.ts
+++ b/packages/cli/script/generate-command-docs.ts
@@ -25,7 +25,10 @@
import { mkdirSync, rmSync } from "node:fs";
import { access, readFile, writeFile } from "node:fs/promises";
-import { formatCommandExamples } from "./generate-skill-markdown.js";
+import {
+ formatCommandArguments,
+ formatCommandExamples,
+} from "./generate-skill-markdown.js";
import { DOCS_CONTENT, DOCS_FRAGMENTS } from "./paths.js";
// Ensure src/generated/skill-content.ts exists before importing the route tree.
@@ -50,7 +53,6 @@ import type { EnvVarEntry } from "../src/lib/env-registry.js";
import type {
CommandInfo,
FlagInfo,
- PositionalInfo,
RouteInfo,
RouteMap,
} from "../src/lib/introspect.js";
@@ -135,34 +137,6 @@ function formatFlagRow(
return `| \`${syntax}\` | ${desc} |`;
}
-/**
- * ...
Found 8 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/issue/merge.func.test.ts:
Line 99: expect(err.message).toContain("needs at least 2 issue IDs");
Line 111: expect(err.message).toContain("needs at least 2 issue IDs");
Line 124: expect(err.message).toContain("needs at least 2 issue IDs");
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/project/create.test.ts:
Line 774: expect(err.message).toContain("Project specification is required");
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/local/run.test.ts:
Line 117: "No command provided and could not auto-detect"
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/dashboard/create.test.ts:
Line 141: expect(err.message).toContain("Dashboard title is required");
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/cli.test.ts:
Line 75: "Please provide a feedback message."
Line 87: "Please ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/issue/merge.func.test.ts</path>
<type>file</type>
<content>
60: project: { id: "1", slug: "cli", name: "cli" },
61: ...overrides,
62: } as SentryIssue;
63: }
64:
65: function createMockContext() {
66: const stdoutWrite = vi.fn(() => true);
67: return {
68: context: {
69: stdout: { write: stdoutWrite },
70: stderr: { write: vi.fn(() => true) },
71: cwd: "/tmp",
72: },
73: stdoutWrite,
74: };
75: }
76:
77: describe("mergeCommand.func()", () => {
78: let resolveIssueSpy: ReturnType<typeof spyOn>;
79: let mergeSpy: ReturnType<typeof spyOn>;
80:
81: beforeEach(() => {
82: resolveIssueSpy = vi.spyOn(issueUtils, "resolveIssue");
83: mergeSpy = vi.spyOn(apiClient, "mergeIssues");
84: });
85:
86: afterEach(() => {
87: resolveIssueSpy.mockRestore();
88: mergeSpy.mockRestore();
89: });
90:
91: test("rejects when fewer than 2 issues are provided (0 ...
Found 10 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/introspect.ts:
Line 62: __primaryUsage?: string;
Line 311: if (cmd.__primaryUsage && positional && positionals.length === 1) {
Line 312: positionals[0] = { ...positional, syntax: cmd.__primaryUsage };
Line 321: cmd.__primaryUsage ?? getPositionalString(cmd.parameters.positional),
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/command.ts:
Line 107: * `customUsage` is present, its first line is the canonical signature suffix;
Line 464: formatUsageLine: (args: { readonly prefix: readonly string[] }) => string;
Line 466: const primaryUsage = docs.customUsage?.[0];
Line 470: metadata.__primaryUsage = input;
Line 471: metadata.formatUsageLine = ({ prefix }) => [...prefix, input].join(" ");
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/help.ts:
Line 122: entry.target.__primaryUsage ??
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/command.ts</path>
<type>file</type>
<content>
80: type BaseArgs = readonly unknown[];
81:
82: /**
83: * Type-erased Stricli builder arguments.
84: *
85: * At the `stricliCommand()` call site we've modified both `parameters`
86: * (injected hidden flags) and `func` (wrapped with telemetry/output
87: * logic), which breaks the original `FLAGS`/`ARGS` generic alignment
88: * that Stricli's `CommandBuilderArguments` enforces via `NoInfer`.
89: *
90: * Rather than silencing with `as any`, we cast through `unknown` to
91: * this type that matches Stricli's structural expectations while
92: * erasing the generic constraints we can no longer satisfy.
93: */
94: type StricliBuilderArgs<CONTEXT extends CommandContext> =
95: import("@stricli/core").CommandBuilderArguments<BaseFlags, BaseArgs, CONTEXT>;
96:
97: /** A runnable example stored with a command definition for generated docs. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/command.ts</path>
<type>file</type>
<content>
440: /** Convert extended command docs into native Stricli help documentation. */
441: function prepareNativeDocs(
442: docs: CommandDocumentation
443: ): StricliBuilderArgs<CommandContext>["docs"] {
444: const { examples, ...nativeDocs } = docs;
445: if (!examples?.length) {
446: return nativeDocs;
447: }
448:
449: const renderedExamples = examples
450: .map(({ description, command }) => ` ${command} # ${description}`)
451: .join("\n");
452: return {
453: ...nativeDocs,
454: fullDescription: `${nativeDocs.fullDescription ?? nativeDocs.brief}\n\nExamples:\n${renderedExamples}`,
455: };
456: }
457:
458: /** Retain extended documentation fields that Stricli does not expose. ...
ripgrep execution failed
No files found
File not found: /home/byk/Code/getsentry/cli-pr-1558/node_modules/@stricli
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli</path> <type>directory</type> <entries> auto-complete/ core/ (2 entries) </entries>
No files found
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core</path> <type>directory</type> <entries> dist/ package.json README.md (3 entries) </entries>
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.d.ts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.js /home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.d.cts /home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.cjs
Found 16 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.js:
Line 440: * If specified, indicates the minimum number of arguments that are expected and the last argument count.
Line 821: if (typeof positional.minimum === "number" && positionalIndex < positional.minimum) {
Line 824: positional.minimum,
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.d.cts:
Line 33: * Simple interface that mirrors NodeJS.Process but only requires the minimum API required by Stricli.
Line 1035: readonly minimum?: number;
Line 1298: * If specified, indicates the minimum number of arguments that are expected and the last argument count.
Line 1300: readonly limit?: [minimum: number, count: number];
Line 1301: constructor(placeholder: Placeholder, limit?: [minimum: number, count: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.d.ts</path>
<type>file</type>
<content>
1010: */
1011: readonly default?: string;
1012: readonly optional?: boolean;
1013: }
1014: interface RequiredPositionalParameter<T, CONTEXT extends CommandContext> extends BasePositionalParameter<T, CONTEXT> {
1015: /**
1016: * Parameter is required and cannot be set as optional.
1017: */
1018: readonly optional?: false;
1019: }
1020: interface OptionalPositionalParameter<T, CONTEXT extends CommandContext> extends BasePositionalParameter<T, CONTEXT> {
1021: /**
1022: * Parameter is optional and must be specified as such.
1023: */
1024: readonly optional: true;
1025: }
1026: /**
1027: * Definition of a positional parameter that will eventually be parsed to an argument.
1028: * Required properties may vary depending on the type argument `T`. ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/node_modules/@stricli/core/dist/index.js</path>
<type>file</type>
<content>
790: } else if (nextFlags.length > 1) {
791: const nextFlagExpectingArg = nextFlags.find((nextFlag) => !isNiladic(nextFlag));
792: const externalFlagName = asExternal(nextFlagExpectingArg.namedFlag[0], config.caseStyle);
793: throw new UnsatisfiedFlagError(externalFlagName);
794: } else {
795: activeFlag = nextFlags[0].namedFlag;
796: }
797: return;
798: }
799: }
800: if (activeFlag) {
801: storeInput(flagInputs, config.caseStyle, activeFlag, input);
802: activeFlag = void 0;
803: } else {
804: if (positional.kind === "tuple") {
805: if (positionalIndex >= positional.parameters.length) {
806: throw new UnexpectedPositionalError(positional.parameters.length, input);
807: }
808: } ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/docs/index.ts</path>
<type>file</type>
<content>
1: import { buildRouteMap } from "../../lib/route-map.js";
2: import { listCommand } from "./list.js";
3: import { queryCommand } from "./query.js";
4:
5: export const docsRoute = buildRouteMap({
6: routes: { list: listCommand, query: queryCommand },
7: aliases: { search: "query" },
8: defaultCommand: "query",
9: docs: {
10: brief: "Search and query current Sentry documentation",
11: fullDescription:
12: "Ask cited documentation questions or search the docs index.\n\n" +
13: "Commands:\n query Ask a natural-language question (default; alias: search)\n list Find matching documentation pages by keyword",
14: hideRoute: {},
15: },
16: });
(End of file - total 16 lines)
</content>
Found 4 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/cli/index.ts:
Line 3: import { defaultsCommand } from "./defaults.js";
Line 4: import { feedbackCommand } from "./feedback.js";
Line 14: defaults: defaultsCommand,
Line 15: feedback: feedbackCommand,
Found 2 matches /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/project/create.ts: Line 609: customUsage: ["[<org>/]<name>:<platform>..."], /home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/agent-conversation/view.ts: Line 75: customUsage: [USAGE],
No files found
Found 31 matches /home/byk/Code/getsentry/cli-pr-1558/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/schema.md: Line 14: ### `sentry schema <resource...>` /home/byk/Code/getsentry/cli-pr-1558/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/local.md: Line 27: ### `sentry local run <command...>` /home/byk/Code/getsentry/cli-pr-1558/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/trace.md: Line 53: ### `sentry trace view <org/project/trace-id...>` Line 88: ### `sentry trace logs <org/project/trace-id...>` /home/byk/Code/getsentry/cli-pr-1558/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/span.md: Line 14: ### `sentry span list <org/project/trace-id...>` Line 68: ### `sentry span view <trace-id/span-id...>` /home/byk/Code/getsentry/cli-pr-1558/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/monitor.md: Line 14: ### `sentry monitor run <monitor-slug ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/commands/event/send.ts</path>
<type>file</type>
<content>
276: async *func(
277: this: SentryContext,
278: flags: SendEventFlags & {
279: dsn?: string;
280: raw?: boolean;
281: json?: boolean;
282: },
283: ...files: string[]
284: ) {
285: const dsn = requireDsn(flags);
286: let dsnComponents: ReturnType<typeof makeDsn>;
287: try {
288: dsnComponents = makeDsn(dsn);
289: } catch (err) {
290: log.debug("makeDsn threw for DSN input", err);
291: dsnComponents = undefined;
292: }
293: if (!dsnComponents) {
294: throw new ValidationError(`Invalid DSN: ${dsn}`, "dsn");
295: }
296:
297: if (files.length > 0) {
298: for (const file of files) {
299: const { body, eventId } = await buildFilePayload(
300: file,
301: flags.raw ?? ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/project/create.test.ts</path>
<type>file</type>
<content>
740: // Sentry may append a random suffix when the desired slug is taken
741: createProjectWithDsnSpy.mockResolvedValue({
742: project: { ...sampleProject, slug: "my-app-0g", name: "my-app" },
743: dsn: "https://abc@o123.ingest.us.sentry.io/999",
744: url: "https://sentry.io/organizations/acme-corp/projects/my-app-0g/",
745: });
746:
747: const { context, stdoutWrite } = createMockContext();
748: const func = await createCommand.loader();
749: await func.call(context, { json: false }, "my-app:node");
750:
751: const output = stdoutWrite.mock.calls.map((c) => c[0]).join("");
752: // Plain mode renders code spans as plain text without padding
753: expect(output).toContain("Slug my-app-0g was assigned");
754: expect(output).toContain("my-app is already taken");
755: });
756:
757: test("does not ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/local/run.test.ts</path>
<type>file</type>
<content>
75:
76: beforeEach(async () => {
77: tmpDir = await mkdtemp(join(TEST_TMP_DIR, "run-test-"));
78: });
79:
80: afterEach(async () => {
81: try {
82: await rm(tmpDir, { recursive: true, force: true });
83: } catch {
84: // ignore cleanup errors
85: }
86: });
87:
88: function makeContext(cwd?: string) {
89: return {
90: stdout: { write: vi.fn(() => true) },
91: stderr: { write: vi.fn(() => true) },
92: cwd: cwd ?? tmpDir,
93: };
94: }
95:
96: describe("sentry local run", () => {
97: beforeEach(() => {
98: spawnCapture.args = undefined;
99: spawnCapture.env = undefined;
100: spawnCapture.stdio = undefined;
101: });
102:
103: test("throws ValidationError when no command and no auto-detect", async () => {
104: const func = (await runCommand.loader()) as unknown as RunFunc;
105: const ctx = ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/dashboard/create.test.ts</path>
<type>file</type>
<content>
115:
116: const output = stdoutWrite.mock.calls.map((c) => c[0]).join("");
117: const parsed = JSON.parse(output);
118: expect(parsed.id).toBe("123");
119: expect(parsed.title).toBe("My Dashboard");
120: expect(parsed.url).toContain("dashboard/123");
121: });
122:
123: test("human output contains 'Created dashboard' and title", async () => {
124: const { context, stdoutWrite } = createMockContext();
125: const func = await createCommand.loader();
126: await func.call(context, { json: false }, "My Dashboard");
127:
128: const output = stdoutWrite.mock.calls.map((c) => c[0]).join("");
129: expect(output).toContain("Created dashboard");
130: expect(output).toContain("My Dashboard");
131: });
132:
133: test("throws ValidationError when title is missing", async () => {
134: const { context } = ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/help.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Tests for the Help Command
3: *
4: * Tests `sentry help --json` output for full tree, specific groups,
5: * specific commands, and not-found cases.
6: */
7:
8: import { run } from "@stricli/core";
9: import { describe, expect, test } from "vitest";
10: import { app } from "../../src/app.js";
11: import type { SentryContext } from "../../src/context.js";
12:
13: /**
14: * Run a help command and capture stdout output.
15: */
16: async function runHelp(args: string[]): Promise<string> {
17: let output = "";
18: const mockContext: SentryContext = {
19: process,
20: env: process.env,
21: cwd: process.cwd(),
22: homeDir: "/tmp",
23: configDir: "/tmp",
24: stdout: {
25: write(data: string | Uint8Array) {
26: output +=
27: typeof data === "string" ? data : new TextDecoder().decode(data);
28: ...
Found 21 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/platform/list.test.ts:
Line 59: test("--search filters to matching platforms only", async () => {
Line 70: test("--search --json filters the JSON array too", async () => {
Line 81: test("--search with no matches exits non-zero with empty results, not a broken table", async () => {
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/bash-hook.test.ts:
Line 132: test("accepts --allow-xcode-infoplist-preprocessing without error", async () => {
Line 134: "--allow-xcode-infoplist-preprocessing",
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/schema.test.ts:
Line 5: * dump the full resource list (byte-identical to a successful browse) instead
Line 85: test("glob pattern matching resources returns their endpoints", () => {
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/release/deploy.test.ts:
Line 144: test("throws when no ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/schema.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Schema Command Tests
3: *
4: * Covers resolveResourceQuery — in particular the no-match paths that used to
5: * dump the full resource list (byte-identical to a successful browse) instead
6: * of reporting that nothing matched. See getsentry/cli#1424.
7: */
8:
9: import { describe, expect, test } from "vitest";
10: import { resolveResourceQuery } from "../../src/commands/schema.js";
11: import { OutputError, ResolutionError } from "../../src/lib/errors.js";
12:
13: describe("resolveResourceQuery", () => {
14: test("returns endpoints for a known resource", () => {
15: const result = resolveResourceQuery("issues");
16: expect(result.kind).toBe("endpoints");
17: if (result.kind === "endpoints") {
18: expect(result.endpoints.length).toBeGreaterThan(0);
19: for (const ep of result.endpoints) {
20: ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/span/list.test.ts</path>
<type>file</type>
<content>
70: // parseSort
71: // ============================================================================
72:
73: describe("parseSort", () => {
74: test("accepts 'date'", () => {
75: expect(parseSort("date")).toBe("date");
76: });
77:
78: test("accepts 'duration'", () => {
79: expect(parseSort("duration")).toBe("duration");
80: });
81:
82: test("rejects 'time' (use 'date' instead)", () => {
83: expect(() => parseSort("time")).toThrow("Invalid sort value");
84: });
85:
86: test("throws for invalid value", () => {
87: expect(() => parseSort("name")).toThrow("Invalid sort value");
88: });
89:
90: test("throws for empty string", () => {
91: expect(() => parseSort("")).toThrow("Invalid sort value");
92: });
93: });
94:
95: // ============================================================================
96: // parseSpanListArgs — ...
Found 57 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/log/view.func.test.ts:
Line 131: await func.call(context, { json: true, web: false }, "my-org/proj", ID1);
Line 145: await func.call(context, { json: false, web: false }, "my-org/proj", ID1);
Line 298: await func.call(context, { json: false, web: true }, "my-org/proj", ID1);
Line 335: await func.call(context, { json: true, web: false }, "my-project", ID1);
Line 351: await func.call(context, { json: false, web: false }, "my-org/", ID1);
Line 359: test("auto-detect resolves org/project and fetches logs", async () => {
Line 369: // No target arg — triggers auto-detect
Line 370: await func.call(context, { json: false, web: false }, ID1);
Line 385: test("throws ContextError when auto-detect returns null", async () => {
Line 392: await func.call(context, { json: false, web: false }, ID1);
Line 410: await ...
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/dashboard/resolve.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Dashboard Resolution Utility Tests
3: *
4: * Tests for positional argument parsing, dashboard ID resolution,
5: * and org resolution in src/commands/dashboard/resolve.ts.
6: */
7:
8: import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
9: import {
10: applyGroupLimitAutoDefault,
11: autoDefaultGroupLimit,
12: DEFAULT_GROUP_BY_LIMIT,
13: enrichDashboardError,
14: normalizeDataset,
15: parseDashboardListArgs,
16: parseDashboardPositionalArgs,
17: resolveDashboardId,
18: resolveOrgFromTarget,
19: resolveWidgetIndex,
20: validateWidgetEnums,
21: } from "../../../src/commands/dashboard/resolve.js";
22:
23: vi.mock("../../../src/lib/api-client.js", async (importOriginal) => {
24: const actual =
25: await importOriginal<typeof import("../../../src/lib/api-client.js")>();
26: return ...
Found 8 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/debug-files/upload.test.ts:
Line 313: test("--id without --require-all does not fail (dry-run)", async () => {
Line 551: test("--require-all is honored when the queue is empty (real upload)", async () => {
Line 557: // The only --id requested doesn't match the fixture, so the queue is empty.
Line 571: test("--id without --require-all does not fail on a real upload", async () => {
Line 683: test("a PE without an embedded PPDB yields nothing", async () => {
Line 727: test("no il2cpp DIF is produced without --il2cpp-mapping", async () => {
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/debug-files/print-sources.test.ts:
Line 6: * can be exercised without committed binaries.
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/debug-files/bundle-jvm.test.ts:
Line 125: test("handles empty directory gracefully", async () => {
Found 5 matches
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/debug-files/upload.test.ts:
Line 182: // ── --derived-data ───────────────────────────────────────────────
Line 184: test("--derived-data is additive: explicit paths still scan", async () => {
Line 188: "--derived-data",
Line 199: "--derived-data alone on non-macOS exits non-zero (no scan targets)",
Line 201: const { exitCode } = await runUpload(["--derived-data", "--no-upload"]);
<path>/home/byk/Code/getsentry/cli-pr-1558/packages/cli/test/commands/debug-files/upload.test.ts</path>
<type>file</type>
<content>
160: const path = await writeBreakpad();
161: const { exitCode } = await runUpload([
162: path,
163: "--no-upload",
164: "--wait",
165: "--wait-for",
166: "30",
167: ]);
168: expect(exitCode).not.toBe(0);
169: });
170:
171: test("unknown --type exits non-zero", async () => {
172: const path = await writeBreakpad();
173: const { exitCode } = await runUpload([
174: path,
175: "--type",
176: "bogus",
177: "--no-upload",
178: ]);
179: expect(exitCode).not.toBe(0);
180: });
181:
182: // ── --derived-data ───────────────────────────────────────────────
183:
184: test("--derived-data is additive: explicit paths still scan", async () => {
185: await writeBreakpad();
186: const { output, exitCode } = await runUpload([
187: tempDir,
188: ...
🔴 (16:28) User established repository workflow order: always load the `repo-setup` skill before any situation skills. Skills live under `.agents/skills/`, are generated from the canonical `skills/` tree, and are synchronized by `scripts/sync-skills.mjs`. 🔴 (16:28) User supplied repository guidance from `/home/byk/Code/getsentry/cli-pr-1558/AGENTS.md`: the agent pipeline is triage → explore → pl…
🟡 (16:28) [requested-audit] User requested a read-only exhaustive audit in `/home/byk/Code/getsentry/cli-pr-1558` of every `kind: "array"` positional under `packages/cli/src/commands`; expected count: exactly 33. User explicitly instructed not to edit files. 🟡 (16:28) User requested a concise, complete table covering all 33 array positionals, organized by route/file, determining for each: (a) w…