Dashboard › cli › Distillation
bffd04a5-03f9-404f-98fd-d71d4f4a6c77["lore_tm_v1_2UsnoAIaFkdFNPObXctlrHoR2v7pyPl2vRE4B9If--Y","lore_tm_v1_4N_pMoD68LtLOWXuDu0Eg9lEIWeN9r7rH3SatWmtXCk","lore_tm_v1_mctRORgOP6zISIkhTKKpHiuzfsutY9kEQm8FvMtYGaY","lore_tm_v1_WmXssG0W_0e57NTUtrwm7UXdvcpNkVFS0FKgSKfuv6E","lore_tm_v1_IKgg57Se5rJVfo7rCcCI0J4MRI6Km-erlcpSRdLrKxo","lore_tm_v1_2hLW99MA_2mNFVNdjg0uV5KxzZN3XcRntX9q3neP7e0","lore_tm_v1_sTfqXvsHcYzcmTrAvZKwNAl4V-0D_5ZO4IwWsxcwAS8","lore_tm_v1_2Ncx2phcGXummgbp7nX6gQFpHTBSfPzYFPMVUX3JEec","lore_tm_v1_dP8rsCYilu-T9CVXgQE4SC-EyEsV31JjlbOvMCt0OFI","lore_tm_v1_NoSug79Sss9svMLPR0ezKocXtmtFn5w16CPWPWj0NeQ"]
packages/cli/src/commands/cli/defaults.ts defines unauthenticated defaultsCommand for viewing and managing persistent CLI defaults. Recognized keys are org, project, telemetry, agent-skills, graphics, url, headers, and ca-cert; key aliases are accepted through KEY_ALIASES.defaultsCommand accepts at most 2 positional arguments, <key> [<value>]; additional arguments raise ValidationError("Too many arguments. Usage: sentry cli defaults [<key> [<value>]]", "args").defaultsCommand either shows getAllDefaults() plus computeTelemetryEffective(), or clears all defaults when --clear is used. Clearing all invokes guardNonInteractive(flags), accepts confirmation bypass through --yes/-y or --force/-f, otherwise prompts with the complete organization/project/telemetry/URL/headers/ca-cert/agent-skills/graphics list.defaultsCommand <key> --clear rejects an accompanying value, records changed: { key: canonical, previousValue, newValue: null }, and clears through the corresponding DEFAULTS_REGISTRY handler.defaultsCommand <key> shows defaults without mutation and includes telemetryEffective only for canonical key telemetry; <key> <value> sets through handler.set(valueArg) and reports the prior and normalized resulting values in changed.telemetry, if computeTelemetryEffective().source starts with env: and its effective enabled state differs from the saved preference, defaultsCommand warns that the named environment variable overrides the preference. telemetryEffective is excluded from JSON output.packages/cli/src/commands/dashboard/widget/add.ts defines sentry dashboard widget add [<org/project>] <dashboard> <title>. parseAddPositionalArgs() requires 2β3 positional arguments, always treats the final argument as the widget title, and passes preceding arguments to dashboard resolution.count to count(), colon forms such as p95:span.duration to p95(span.duration), and parenthesized expressions through unchanged; sort shorthand maps count to ascending count() and -count to descending -count().--display/-d; optional --dataset; repeatable --query/-q; --where/-w; repeatable --group-by/-g; --sort/-s; --limit/-n; layout flags --col/-x, --row/-y, --width, and --height; and --layout/-l, defaulting to sequential.errors β error-events are normalized once through normalizeDataset(flags.dataset) before validation or network calls. Every downstream consumer must receive the canonical dataset value, and code below normalization must never reference flags.dataset.sequential and dense; any other --layout value raises ValidationError. Individual ranges are validated before dashboard retrieval: columns are 0β5, rows are 0-based, widths are 1β6, and heights have minimum 1.assignDefaultLayout(newWidget, updateBody.widgets, layoutMode) to obtain default position and dimensions, then override only explicitly provided col, row, width, and height values.validateWidgetLayout({ col: finalLayout.x, width: finalLayout.w }, finalLayout) to catch cross-dimensional overflow such as x=5 plus auto-width 6 exceeding the 6-column grid.prepareDashboardForUpdate(current), appends the new widget, updates through updateDashboard(orgSlug, dashboardId, updateBody), and outputs the updated dashboard, added widget, and buildDashboardUrl(orgSlug, dashboardId).packages/cli/src/commands/dashboard/widget/delete.ts defines widget deletion through buildDeleteCommand; auto-injected --yes, --force, and --dry-run are accepted. { noNonInteractiveGuard: true } is used because widget deletion is reversible; --yes and --force currently have no effect because there is no confirmation prompt.--index/-i (0-based) or --title/-t; if neither is supplied it raises ValidationError("Specify --index or --title to identify the widget to delete.", "index").--dry-run returns the unmodified current dashboard, target widgetTitle, URL, and dryRun: true; its JSON transform emits { dryRun: true, widgetTitle, widgetCount, url }. A real deletion splices the resolved widget from prepareDashboardForUpdate(current).widgets, performs the update, and emits JSON { deleted: true, widgetTitle, widgetCount, url }.packages/cli/src/commands/dashboard/widget/edit.ts defines widget editing by --index/-i or --title/-t; omitted mutation flags preserve existing values, while --new-title changes the widget title.mergeQueries() only creates replacement query state when query, where, group-by, or sort changes. It removes stale fields from the existing query so prepareWidgetQueries() recomputes them, and selectively replaces aggregates, conditions, columns, and ordering.mergeLayout() preserves the existing layout when no layout flags are provided; otherwise it overlays explicit col, row, width, and height onto the existing layout or FALLBACK_LAYOUT.--query or --dataset changes, using the effective merged aggregates and dataset. Display/dataset enum validation uses effective merged values. Sort-reference validation runs only when --sort is explicitly passed, avoiding rejection of preserved or auto-defaulted stale sort state.buildReplacement() applies applyGroupLimitAutoDefault(), preserves existing title/display/query/layout/widget type unless explicitly changed, avoids setting widgetType when neither the edit nor existing widget provides one so parseWidgetInput() does not incorrectly default it to spans, and returns prepareWidgetQueries(parseWidgetInput(raw)).normalizeDataset(flags.dataset). When normalization changes the value, the implementation creates normalizedFlags = { ...flags, dataset: normalizedDataset }; all downstream enum checks, aggregate validation, widget lookup, replacement construction, and PUT content use normalizedFlags, allowing aliases such as --dataset errors to validate count_if against canonical error-events.FALLBACK_LAYOUT, it revalidates the final merged col and width after replacement because the early check did not know fallback dimensions.parseDashboardPositionalArgs() in packages/cli/src/commands/dashboard/resolve.ts accepts a single dashboard ID/title with auto-detected organization, a target plus dashboard reference, or a full Sentry dashboard URL. With two arguments, a bare first slug is normalized to slug/; full URLs apply URL context and extract organization/dashboard ID./ is always treated as a title filter, never as a project-search target. To specify an organization, callers must use org/ or two arguments such as org 'filter'.parseDashboardListArgs() accounts for buildListCommandβs interceptSubcommand behavior, which may replace args[0] with undefined when the first positional matches a subcommand such as view or create; it filters null, undefined, and empty-string entries before operations such as .includes("/").sentry dashboard view; an organization-only URL applies its base URL context, warns that the organization was extracted, normalizes the target to <org>/, and joins remaining arguments with spaces as the title filter.packages/cli/src/commands/dashboard/view.ts defines dashboard rendering with actual widget data, including sparklines, tables, and big numbers. It accepts dashboard numeric IDs, titles, explicit organization/project targets, and dashboard URLs through shared positional parsing.--web/-w, --fresh and FRESH_ALIASES, --refresh/-r, --period/-t, --renderer with values auto, kitty, or sixel, and --no-graphics-cap.60 seconds when -r has no value and requires an explicit interval of at least 10 seconds; invalid or smaller values throw --refresh interval must be at least 10 seconds.abortableSleep(ms, signal) resolves rather than rejects when aborted, removes its abort listener after the timer fires, and supports clean async-generator shutdown.--period, then the dashboardβs saved period parsed through parsePeriod(), then TIME_RANGE_24H.buildViewData() includes dashboard ID, title, period, ISO fetchedAt, URL, creation date, environments, renderer preference, graphics cap, and each widgetβs title, display type, widget type, description, layout, queries, and data. Missing widget results become { type: "error", message: "No data returned" }; rendererPreference and graphicsCap are excluded from JSON output.applyFreshFlag(flags), resolves organization and dashboard ID, opens buildDashboardUrl() and returns immediately for --web, otherwise retrieves the dashboard with progress text Fetching dashboard..., enriches view errors, resolves the organization region, and computes the effective time range.