You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Consolidate target parsing into positional parsers #1564
parseOrgTarget and parseOrgProjectTarget (packages/cli/src/lib/completion-target.ts, added in #1557) are identity parsers. They only mark a positional's completion kind. Each command still parses and validates the raw string itself inside func, using parseOrgProjectArg, parseSlashSeparatedArg, parseIssueArg, and similar helpers from src/lib/arg-parsing.ts.
Commands that share a target syntax repeat the same parse call, and the positional definition and its parsing live in different places.
Some flows depend on the raw string reaching func today: buildListCommand rewrites the first positional to catch plural-alias subcommand typos, maybeRecoverWithHelp treats a literal help argument as --help, and some commands auto-recover from the wrong entity type. Parse failures currently surface as CliError subclasses with specific exit codes. Errors thrown from a Stricli parser go through Stricli's argument-error handling instead.
Fixed by #1594 (merged 2026-10-23), which adds the target positional parser and moves trace list, replay list, feedback list, project view and project delete onto it. The PR used Refs #1564, so it didn't close this automatically. Closing per @BYK.
Reopening: #1594 landed the lazy parsed/resolved positional mechanism and migrated trace list, replay list, feedback list, project view and project delete, but the migration and some hardening are still open.
Harden destructive checks: right now the guard only runs when a destructive command reads .resolved. A command that reads .parsed and then mutates skips it. buildListCommand's re-wrap also drops the destructive mark (no destructive list commands exist today, so this can't trigger yet). The require-target-resolution lint rule is easy to get around.
LazyPositional: memoize parse failures (a failing .parsed re-parses on every read) and avoid unhandled rejections when .resolved is read but never awaited.
Migrate any remaining unblocked positionals. log list, replay view and replay download are variadic or depend on the number of arguments, so they stay in func.
ref(cli): Parse target positionals in Stricli's argument scanner #1655 (new): target positionals now parse in Stricli's argument scanner. Every argument parse error exits 252, positionals included, and the exit code docs say so. Pasting a Sentry URL as a target no longer switches the CLI to that URL's server during parsing; that now happens when the target resolves, after the auth guard. The destructive-command check runs in buildCommand, so it no longer depends on the command reading target.resolved. ref(cli): Parse target positionals in Stricli's argument scanner #1655 also replaces the parse-memoization and destructive-guard hardening I mentioned earlier.
Still to do: migrate LIST_TARGET_POSITIONAL users, including agent-conversation list, once #1575 lands, and look at the issue and dashboard targets after #1572. log list, replay view and replay download keep parsing in func.
issue list, dsn list and alert issues list (LIST_TARGET_POSITIONAL), project list (NAMED_LIST_TARGET_POSITIONAL), and every buildOrgListCommand list (team, repo, monitor, integration, …) go through dispatchOrgScopedList. It resolves each target mode in a different way, and some modes resolve to several projects (DSN detection, monorepos). That means orgOptionalTarget or projectBoundTarget can't stand in for these. One option is a "list target" bound positional: it parses [<org>/][<project>|<glob>] purely in the scanner, and .resolved applies the pasted URL's server and returns { parsed, filter } for dispatch. parseListTarget would need a pure variant for that, since it currently applies the URL context while it parses.
Issue and dashboard targets: feat(cli): Complete issues, dashboards, --query terms, and --period values #1572 only added completion (parseIssueTarget and parseDashboardTarget are still identity parsers). Most of these positionals are [<org>/[<project>/]]<id>, and what each part means depends on how many arguments were given, the same as trace view. Under the current rule they keep parsing in func.
log list, replay view and replay download stay out of scope, because they're variadic.
List targets (issue list, dsn list, alert issues list, project list, release list and the dispatch-based org lists): ref(cli): Parse list command targets in their positional #1711 adds a list-target positional. It parses with no side effects up front and applies a pasted URL's server at resolve time.
Arity-dependent and variadic targets:ref(cli): Parse arity-dependent arguments in the scanner #1714 adds the parser type for [<org>/[<project>/]]<id>. A small @stricli/core patch gives array positionals a combine hook that sees all the arguments at once, so these targets now fail in the scanner with exit 252. boundArguments wraps it with the same pure-parse/bound-resolve contract as boundPositional. log list, replay view and replay download are migrated.
Issue and dashboard IDs, trace view/logs, span list/view and log view fit the same primitive. I've left them for follow-ups so each PR stays reviewable. parseTraceTargetInput and parseDualModeInput already exist for the trace ones.
Activity
linear-code commentedon Oct 20, 2026
MCP-1099
ref(cli): Hand commands parsed targets instead of a lazy wrapper
ref(cli): Parse target positionals lazily behind the parsed type
ref(cli): Bind target resolution to the positional as a lazy promise
ref(cli): Derive target command names and guard destructive targets
ref(cli): Replace the target Proxy with a LazyPositional class
feat(cli): Parse and resolve org/project targets in their positional (#…
sentry-junior commentedon Oct 23, 2026
Fixed by #1594 (merged 2026-10-23), which adds the target positional parser and moves
trace list,replay list,feedback list,project viewandproject deleteonto it. The PR usedRefs #1564, so it didn't close this automatically. Closing per @BYK.fix(cli): Keep CliError exit codes for argument parser failures
sentry-junior commentedon Oct 23, 2026
Reopening: #1594 landed the lazy parsed/resolved positional mechanism and migrated
trace list,replay list,feedback list,project viewandproject delete, but the migration and some hardening are still open.Open PRs that this issue depends on
LIST_TARGET_POSITIONALusers, includingagent-conversation listNew PRs
exploreontoorgOptionalTarget, with org/project shell completionCliErrorexit code when a flag or positional parser throws (it used to exit with 252)Next, in priority order
.resolved. A command that reads.parsedand then mutates skips it.buildListCommand's re-wrap also drops the destructive mark (no destructive list commands exist today, so this can't trigger yet). Therequire-target-resolutionlint rule is easy to get around.LazyPositional: memoize parse failures (a failing.parsedre-parses on every read) and avoid unhandled rejections when.resolvedis read but never awaited.log list,replay viewandreplay downloadare variadic or depend on the number of arguments, so they stay infunc.I'll link the new PRs here as I open them.
ref(cli): Move explore onto the org-optional target positional (#1650)
sentry-junior commentedon Oct 25, 2026
Status update:
exploreonorgOptionalTarget): merged.CliError's exit code when an argument fails to parse.buildCommand, so it no longer depends on the command readingtarget.resolved. ref(cli): Parse target positionals in Stricli's argument scanner #1655 also replaces the parse-memoization and destructive-guard hardening I mentioned earlier.Still to do: migrate
LIST_TARGET_POSITIONALusers, includingagent-conversation list, once #1575 lands, and look at the issue and dashboard targets after #1572.log list,replay viewandreplay downloadkeep parsing infunc.feat(cli): Report argument parse errors to Sentry
ref(cli): Parse target positionals in Stricli's argument scanner (#1655)
sentry-junior commentedon Oct 28, 2026
Status update: #1572 and #1575 have both merged, so nothing blocks this issue anymore.
New PR
agent-conversation listontoorgOptionalTarget.Left over, and needs a design decision
issue list,dsn listandalert issues list(LIST_TARGET_POSITIONAL),project list(NAMED_LIST_TARGET_POSITIONAL), and everybuildOrgListCommandlist (team, repo, monitor, integration, …) go throughdispatchOrgScopedList. It resolves each target mode in a different way, and some modes resolve to several projects (DSN detection, monorepos). That meansorgOptionalTargetorprojectBoundTargetcan't stand in for these. One option is a "list target" bound positional: it parses[<org>/][<project>|<glob>]purely in the scanner, and.resolvedapplies the pasted URL's server and returns{ parsed, filter }for dispatch.parseListTargetwould need a pure variant for that, since it currently applies the URL context while it parses.parseIssueTargetandparseDashboardTargetare still identity parsers). Most of these positionals are[<org>/[<project>/]]<id>, and what each part means depends on how many arguments were given, the same astrace view. Under the current rule they keep parsing infunc.log list,replay viewandreplay downloadstay out of scope, because they're variadic.ref(cli): Move agent-conversation list onto the org-optional target p…
sentry-junior commentedon Oct 29, 2026
Update on the approved directions:
issue list,dsn list,alert issues list,project list,release listand the dispatch-based org lists): ref(cli): Parse list command targets in their positional #1711 adds a list-target positional. It parses with no side effects up front and applies a pasted URL's server at resolve time.[<org>/[<project>/]]<id>. A small@stricli/corepatch gives array positionals acombinehook that sees all the arguments at once, so these targets now fail in the scanner with exit 252.boundArgumentswraps it with the same pure-parse/bound-resolve contract asboundPositional.log list,replay viewandreplay downloadare migrated.trace view/logs,span list/viewandlog viewfit the same primitive. I've left them for follow-ups so each PR stays reviewable.parseTraceTargetInputandparseDualModeInputalready exist for the trace ones.