Dashboard › cli › Distillation
17de5e21-7996-44a3-a052-b468c717cc1c["lore_tm_v1_kox2p8x8u7aj5TOB5e36JWtboNGY_krN-HK5cM8jhKI","lore_tm_v1_Dk72agEnJpOSZjLLvUkyyGcxtJaZ0pnQTMtGdxPeP2E","lore_tm_v1_YKdVOChAyKP1HCpEECiIKXLX2MIIfft2DRZX6bgH7bE"]
Date: Sep 9, 2026
/home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/introspect.ts is a shared route-tree introspection module used at runtime by sentry help --json and at build time by generate-skill.ts; it defines simplified RouteMapEntry, RouteTarget, RouteMap, Command, PositionalParams, PositionalParam, PositionalInfo, FlagDef, CommandInfo, FlagInfo, RouteInfo, ResolvedPath, and UnresolvedPath types because Stricliβs exported types require complex CommandContext generics and omit internal types.packages/cli/src/lib/introspect.ts, introspected commands retain non-standard metadata through Command.__jsonSchema, Command.__primaryUsage, and Command.__examples; CommandInfo includes path, brief, optional fullDescription, flags, positional, structured positionals, aliases, examples, and optional jsonFields.packages/cli/src/lib/introspect.ts, isRouteMap(target) recognizes a non-null object containing getAllEntries; isCommand(target) recognizes a non-null object containing parameters but not getAllEntries. Both accept unknown.packages/cli/src/lib/introspect.ts, getPositionalString() returns "" when absent; tuple parameters render as required <placeholder> or optional [<placeholder>], defaulting names to arg${i}; array parameters render as <placeholder...>, defaulting to <args...>.packages/cli/src/lib/introspect.ts, extractPositionals() returns [] when absent; tuple entries preserve placeholder, brief, and optional with defaults arg${i}, "", and false; an array positional becomes one optional entry whose placeholder ends in ..., defaulting to args....packages/cli/src/lib/introspect.ts, extractFlags() normalizes each flagβs name, brief, kind, default, optional, variadic, and hidden; optional defaults to whether the flag is boolean, while variadic and hidden default to false.packages/cli/src/lib/introspect.ts, buildCommandInfo() extracts JSON fields with extractSchemaFields(cmd.__jsonSchema), prefers cmd.__primaryUsage over generated positional text, defaults aliases to {}, prefers canonical cmd.__examples formatted as # ${description}\n${command} over supplied documentation examples, and omits jsonFields when extraction is empty.packages/cli/src/lib/introspect.ts, extractRouteGroupCommands() recursively walks nested visible route maps, skips hidden entries, builds paths prefixed with sentry, and loads optional documentation examples by full command path; extractAllRoutes() similarly returns metadata for every visible top-level route group or standalone command.packages/cli/src/lib/introspect.ts, resolveCommandPath(routeMap, path) returns null for an empty path, resolves standalone commands or groups recursively, skips hidden routes, rewrites nested paths with SENTRY_PREFIX_RE = /^sentry /, and returns UnresolvedPath when a segment fails to match. Fuzzy suggestions use fuzzyMatch() with MAX_SUGGESTIONS = 3 and are drawn from visible route names at the failed level./home/byk/Code/getsentry/cli-pr-1558/packages/cli/src/lib/list-command.ts, shared list limits are LIST_MAX_LIMIT = 1000, LIST_MIN_LIMIT = 1, and LIST_DEFAULT_LIMIT = 25; the API silently caps per_page at 100, so commands auto-paginate to satisfy larger requested limits up to the CLI ceiling.LIST_TARGET_POSITIONAL in packages/cli/src/lib/list-command.ts is an optional tuple positional named org/project; it accepts <org>/ for all projects, <org>/<project> for an explicit target, or bare <project> for project search. TARGET_PATTERN_NOTE clarifies that a bare name triggers search, while targetPatternExplanation() explains that the trailing slash on <org>/ is significant and can append an optional cursor note.FRESH_FLAG is a boolean --fresh flag with default false and brief Bypass cache, re-detect projects, and fetch fresh data; FRESH_ALIASES maps f to fresh, except commands such as log list where -f means --follow. applyFreshFlag() disables the response, DSN, and organization caches by calling disableResponseCache(), disableDsnCache(), and disableOrgCache() when enabled.--cursor navigation accepts next, last, prev, previous, and first, with last retained as a silent alias for next; opaque cursor strings such as 1735689600:0:0 are also accepted.400. parseCursorFlag() rejects values matching ALL_DIGITS_RE = /^\d+$/ with: '${value}' is not a valid cursor. Cursors look like "1735689600:0:0". Use "next" / "prev" to navigate pages.LIST_CURSOR_FLAG is a parsed optional --cursor flag using parseCursorFlag, with brief Navigate pages: "next", "prev", "first" (or raw cursor string); LIST_BASE_ALIASES maps n to limit and c to cursor.packages/cli/src/lib/list-command.ts, paginationHint() emits Prev: ..., Next: ..., or both joined by | depending on hasPrev and hasMore; appendQueryHint() preserves a query as -q "<query>", and appendSortHint() preserves a non-default sort as --sort "<value>".buildListLimitFlag(entityPlural, defaultValue) uses numberParser, defaults defaultValue to String(LIST_DEFAULT_LIMIT), and emits the brief Maximum number of ${entityPlural} to list.flags.period is always a TimeRange object because Stricli applies parsePeriod to both supplied values and defaults; command functions must not manually call parsePeriod(). LIST_PERIOD_FLAG uses parse: parsePeriod, brief: PERIOD_BRIEF, and default "7d"; commands needing another default, such as issue list with "90d", define the parsed flag inline. PERIOD_ALIASES maps t to period.aliases is always present at runtime, using an empty array when there are no aliases; RouteEntry.aliases remains typed as optional for defensive safety.packages/cli/src/lib/list-command.ts, plural-alias interception lazily builds _subcommandsByRoute from routes loaded via _require("../app.js"), collecting each childβs canonical name and aliases. The require() breaks the list-command β app β commands β list-command circular dependency; if loading fails under Vitest because Nodeβs ESM resolver cannot map .js to .ts through transitive imports, it logs Failed to load app routes for subcommand detection and degrades to treating positional targets as ordinary values.interceptSubcommand(target, stderr, routeName) trims a positional target and, when it matches a known subcommand of the singular route, writes Tip: "${trimmed}" is a subcommand. Running: sentry ${routeName} ${trimmed}\n through warning() and returns undefined; otherwise it returns the original target.buildListCommand() is a drop-in replacement for buildCommand() that: 1. intercepts subcommand names passed through plural aliases, 2. auto-injects --fresh and --cursor unless already defined, 3. auto-injects -f and -c aliases with opt-outs, and 4. calls applyFreshFlag(flags) before the original command function.buildListCommand() must always inject --fresh unless the command already defines it. ListCommandOptions.noCursorFlag suppresses --cursor and -c, while ListCommandOptions.noFreshAlias suppresses only -f; existing command-specific fresh, cursor, f, or c definitions take precedence.buildListCommand() is always the target using the org/project pattern. The wrapper applies interceptSubcommand() only when that argument is a string or undefined, uses this.stderr for the hint, then invokes the original function with the possibly replaced target.buildOrgListCommand() in packages/cli/src/lib/list-command.ts builds commands backed entirely by dispatchOrgScopedList(): it uses LIST_TARGET_POSITIONAL, a generated limit flag, and LIST_BASE_ALIASES; parses the target with parseOrgProjectArg(target); dispatches with cwd, flags, parsed, and orgSlugMatchBehavior: "redirect"; yields new CommandOutput(result); and returns the result hint only when result.items.length > 0.buildOrgListCommand() uses formatListHuman(): empty results render result.hint directly when present; non-empty results render config.displayTable(result.items) and append \n${result.header} when a header exists. JSON rendering uses jsonTransformListResult(result, fields), and the output schema is config.schema.