Dashboard › cli › Distillation
a131861b-3278-4c63-9f0f-60b1abcd2638["lore_tm_v1_cSCuvRmH9FGFTfEOI2a1__FrJXRamHG5zfbQ2rRC95g"]
packages/cli; its documentation site is in apps/cli-docs.gh-style developer-friendly UX, agent-friendly JSON/predictable behavior, and fast native binaries via Node SEA (fossilize) with SQLite API-response caching..env, JavaScript, Python, Go, Java, Ruby, and PHP; upward project-root detection; bidirectional word-boundary directory-name inference; regional API fan-out to us.sentry.io and de.sentry.io; monorepo aliases; Seer-powered issue explain and issue plan; and OAuth Device Flow.repo-setup before situation skills.packages/cli, read .cursor/rules/ultracite.mdc.package.json for the latest scripts; run commands from packages/cli, or from the repository root with pnpm --filter sentry run <script>.pnpm install from the repository root; pnpm run dev; pnpm run cli -- <args>; pnpm run build; pnpm run build:all; pnpm run typecheck; pnpm run lint; pnpm run lint:fix before committing; pnpm run test:unit; pnpm run test:e2e; pnpm exec vitest run test/lib/foo.test.ts; and pnpm exec vitest for watch mode.devDependencies, never dependencies, because esbuild bundles everything at build time; CI enforces this with pnpm run check:deps.pnpm add -D <package> using the -D flag.@sentry/api provides API-response types, import them directly rather than creating redundant Valibot schemas in src/types/sentry.ts.node:* APIs and has no Bun runtime; do not reintroduce Bun.*, bun:test, or bun CLI commands after the Bun-to-Node migration.readFile()/writeFile() from node:fs/promises; existsSync() and permission-aware mkdirSync(dir, { recursive: true, mode: 0o700 }) from node:fs; spawn()/execFile() and execSync() from node:child_process; which from src/lib/which.ts; the scanner in src/lib/scan/ for globs; setTimeout() from node:timers/promises; and JSON.parse(await readFile(path, "utf-8")) for JSON files.execFileSync with array arguments over string-based execSync when passing user-controlled values, to prevent shell injection.apps/cli-docs/src/content/docs/contributing.md by the project-structure block from script/generate-docs-sections.ts; inspect current commands with ls src/commands/ or sentry --help.src/bin.ts (entry point), src/app.ts (Stricli app), src/context.ts (dependency injection), src/commands/, src/lib/, src/types/, test/, ../../apps/cli-docs/, script/, .cursor/rules/, and biome.jsonc.src/commands/ include auth, cli, dashboard, event, issue, log, org, project, release, replay, repo, sourcemap, span, team, trace, trial, and local; standalone files include api.ts, explore.ts, help.ts, init.ts, and schema.ts.buildCommand from ../../lib/command.js, never directly from @stricli/core; the wrapper adds telemetry, injects --json/--fields, and handles output rendering.async *func() generators, yield new CommandOutput(data), and may return { hint }; output.human must receive the same object serialized to JSON.json flag, branch on flags.json, or call stdout.write(); the command wrapper owns those behaviors.src/lib/formatters/<domain>.ts, and files beyond approximately 400 lines should extract formatting helpers. References include src/lib/formatters/replay.ts, src/lib/formatters/trace.ts, and src/lib/formatters/human.ts.stderr.write() is banned in command files by a GritQL rule; use logger for diagnostics and CommandOutput for data output.buildRouteMap from ../../lib/route-map.js, never directly from @stricli/core; standard aliases are auto-injected as list → ls, view → show, delete → remove, rm, and create → new.parseSlashSeparatedArg from src/lib/arg-parsing.ts for [<org>/<project>/]<id> and parseOrgProjectArg() for targets; its target types are "auto-detect", "explicit", "project-search", and "org-all". Required identifiers such as trace IDs and span IDs must be positional arguments, not flags.issue merge A B C and project create web:javascript api:python-django; do not comma-split positional values because commas may be part of a value.project create project requires a name:platform pair, whether or not an explicit organization is supplied; there is no space-separated name/platform form, and project names cannot contain whitespace.value.split(","), or flags.x.flatMap((v) => v.split(",")) for repeatable array flags. Examples are --features errors,tracing, set-commits --path a,b, and auth login --scope a,b.mdKvTable(), colorTag(), escapeMarkdownCell(), and renderMarkdown(); never put raw muted()/chalk calls into output strings.renderMarkdown() should use isPlainOutput() ? text : muted(text); isPlainOutput() precedence is SENTRY_PLAIN_OUTPUT over NO_COLOR over FORCE_COLOR (TTY only) over !isTTY. It lives in src/lib/formatters/plain-detect.ts and is re-exported from markdown.ts.buildDeleteCommand() from src/lib/mutate-command.ts rather than buildCommand(); it injects --yes, --force, and --dry-run with aliases -y, -f, and -n, and blocks non-TTY execution unless --yes/--force is provided, while dry-run bypasses the guard.buildDeleteCommand() supports noForceFlag, noDryRunFlag, and noNonInteractiveGuard; mutation utilities include isConfirmationBypassed(flags), guardNonInteractive(flags), confirmByTyping(expected, message), requireExplicitTarget(parsed, entityType, usage), DESTRUCTIVE_FLAGS, and DESTRUCTIVE_ALIASES.DRY_RUN_FLAG and DRY_RUN_ALIASES from ../../lib/mutate-command.js.-c next, -c prev, and -c first; "last" is a silent alias for "next".LIST_CURSOR_FLAG from src/lib/list-command.js and buildPaginationContextKey, resolveCursor, advancePaginationState, and hasPreviousPage from src/lib/db/pagination.js; JSON envelopes include both nextCursor and hasPrev.paginationHint() from src/lib/list-command.ts, producing combinations such as "Prev: X | Next: Y"; do not manually assemble navParts.buildOrgListCommand for fully automatic simple org-scoped lists such as team/repo; 2. dispatchOrgScopedList with overrides for project/issue modes, where custom "org-all" handles pagination manually; 3. buildListCommand with manual pagination for trace/span/dashboard lists.--limit exceeds API_MAX_PER_PAGE (100), list commands must transparently fetch multiple pages until results.length >= limit or pages are exhausted, using Math.min(flags.limit, API_MAX_PER_PAGE) and bounded by MAX_PAGINATION_PAGES.per_page value larger than API_MAX_PER_PAGE to the API; the server silently caps oversized values and can cause fewer results than requested.src/lib/hex-id.ts are validateHexId(value, label) for 32-character trace/log hex IDs, validateSpanId(value) for 16-character span IDs, and validateTraceId(value) in src/lib/trace-id.ts; they strip UUID dashes as applicable, normalize lowercase, and throw ValidationError for invalid input."date", not "time"; sort types such as SpanSortValue should be exported by the API layer and imported by commands.pnpm run generate:docs runs generate:command-docs followed by generate:skill, and runs automatically within dev, build, typecheck, and test.docs/src/content/docs/commands/*.md are gitignored and derive from CLI metadata plus fragments in docs/src/fragments/commands/; generated skills under plugins/sentry-cli/skills/sentry-cli/ are committed and CI auto-commits them when stale.docs/src/fragments/commands/; pnpm run check:fragments validates fragment-to-route consistency, and positional placeholder values must be descriptive, such as "org/project/trace-id" rather than "args".src/types/*.ts, key files are sentry.ts, config.ts, oauth.ts, and seer.ts, exports flow through src/types/index.ts, and consumers should use type-only imports.upsert() or runUpsert() from src/lib/db/utils.ts; upsert() accepts conflict columns and supports { excludeFromUpdate: ["created_at"] }.CliError from src/lib/errors.ts; use EXIT.* constants rather than hardcoding numeric exit codes outside that file.CliError defaults to 1; HostScopeError uses 13; ApiError uses 30; AuthError uses 10–12 based on "not_authenticated", "expired", or "invalid"; ConfigError uses 20; and OutputError uses 60.