Skip to content

ref(cli): replace argv-hoist preprocessor with a Stricli top-level-flags patch - #1340

Open
jared-outpost[bot] wants to merge 5 commits into
mainfrom
issue-1339-toplevel-flags-patch
Open

ref(cli): replace argv-hoist preprocessor with a Stricli top-level-flags patch#1340
jared-outpost[bot] wants to merge 5 commits into
mainfrom
issue-1339-toplevel-flags-patch

Conversation

@jared-outpost

@jared-outpost jared-outpost Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Global flags before the subcommand (sentry --verbose issue list) used to be relocated to the tail of argv by argv-hoist.ts, because Stricli only parses flags at the leaf command and treats a global flag in a route position as an unknown subcommand.

This teaches Stricli's route scanner about a fixed allow-list of Sentry global flags via the existing @stricli/core patch (same mechanism as the -H removal), so buildRouteScanner recognizes --verbose, --json, --org, --project, --log-level, --fields (and the -v alias, plus =-inline/value forms) at any route depth and forwards them to the leaf command instead of failing route resolution. The patch also drops Stricli's built-in -v=version alias so -v stays the CLI's --verbose alias at every position; --version remains the version flag.

argv-hoist.ts is deleted. The two transforms Stricli can't do at arbitrary route depth stay as thin app-boundary glue in argv-glue.ts: --version normalization (Stricli only prints it at argv[0]) and the --help --json rewrite to the help command (Stricli intercepts --help and ignores --json).

Scope note: the last checklist item from the issue — upstreaming the top-level-flags behavior to Stricli — is intentionally left out of this PR; the local patch stays until/unless accepted.

Testing

  • pnpm exec vitest run test/lib/argv-glue.test.ts test/lib/argv-glue.integration.test.ts test/commands/help.test.ts test/commands/bash-hook.test.ts (77 passed)
  • pnpm run check:patches, tsc --noEmit, biome check on changed files — all clean
  • Manual smoke via run(app, preprocessArgv(argv)): issue list --help --json and --help --json emit structured JSON; cli --version and --version print the version; --verbose/--org/-v before or between route segments reach the leaf; -- passthru is not consumed as a global flag

Closes #1339

…ags patch

Global flags placed before the subcommand (`sentry --verbose issue list`)
used to be relocated to the tail of argv by the `argv-hoist.ts` preprocessor,
because Stricli only parses flags at the leaf command and treats a global flag
in a route position as an unknown subcommand.

This teaches Stricli's route scanner about a fixed allow-list of Sentry global
flags via the existing `@stricli/core` patch (same mechanism as the `-H`
removal), so `buildRouteScanner` recognizes `--verbose`, `--json`, `--org`,
`--project`, `--log-level`, `--fields` (and the `-v` alias, plus `=`-inline and
value forms) at any route depth and forwards them to the leaf command instead
of failing route resolution. The patch also drops Stricli's built-in
`-v`=version alias so `-v` stays the CLI's `--verbose` alias at every position;
`--version` remains the version flag.

`argv-hoist.ts` is gone. The two transforms Stricli can't do at arbitrary route
depth remain as thin app-boundary glue in `argv-glue.ts`: `--version`
normalization (Stricli only prints it at argv[0]) and the `--help --json`
rewrite to the `help` command (Stricli intercepts `--help` and ignores `--json`).

- Regenerate the `@stricli/core` patch (both dist/index.{js,cjs}).
- Guard the new patch effects in `check:patches` (requiredMarker support).
- Replace argv-hoist tests with argv-glue unit tests + a run(app,...)
  integration suite covering global flags at depth, value-flag consumption,
  the `-v` regression, and `--` escape passthrough.

Closes #1339
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-1340/

Built to branch gh-pages at 2026-08-03 10:23 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@jared-outpost
jared-outpost Bot marked this pull request as ready for review August 2, 2026 14:30
@jared-outpost
jared-outpost Bot requested a review from BYK August 2, 2026 14:30
@github-actions github-actions Bot added the risk: high PR risk score: high label Aug 2, 2026
@jared-outpost

jared-outpost Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

marked ready — full CI is green (Build: lint/typecheck, unit + e2e tests, binary + npm smoke builds; plus Warden, Semgrep, CodeQL, Socket, dependency review). check:patches passes with the new required-marker guards for the scanner allow-list and the dropped -v=version alias. self-review turned up nothing outstanding.

@BYK — flagging the two deliberate calls for your read: the top-level-flag token set is hardcoded in the @stricli/core patch (minified dist can't import GLOBAL_FLAGS, so global-flags.ts documents the coupling), and the app-boundary glue in argv-glue.ts is intentionally kept for --version-at-depth and --help --json since Stricli only handles those at fixed positions. upstreaming to Stricli is left as follow-up per the issue's last checklist item.

Comment thread packages/cli/src/cli.ts
Comment thread packages/cli/patches/@stricli%2Fcore@1.2.8.patch Outdated
Without argv hoisting, global flags can sit between `cli` and its
subcommand (`sentry cli --verbose setup`), so the positional `args[1]`
check in shouldSuppressNotification no longer sees `setup`/`fix` and
update notifications leak into those management commands. Resolve the
subcommand by skipping global flags (and value-flag values) after `cli`.

Flagged by Cursor Bugbot on #1340.
Comment thread packages/cli/src/lib/argv-glue.ts
Comment thread packages/cli/src/lib/version-check.ts
shouldSuppressNotification only matched `cli` at args[0], so global
flags placed before the command (`sentry --verbose cli setup`) — now
possible since flags are no longer hoisted — leaked update
notifications into management commands. Locate the `cli` group past
leading global flags, and stop rewriteHelpJsonRequest at `--` without
discarding `--help --json` already seen before it.

Flagged by Cursor Bugbot and Seer on #1340.
Comment thread packages/cli/src/lib/version-check.ts
Comment thread packages/cli/src/lib/version-check.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 388f884. Configure here.

Comment thread packages/cli/patches/@stricli%2Fcore@1.2.8.patch
The top-level-flags scanner patch latched the next token as a value for
value-taking global flags (`--org`, `--fields`, `--log-level`,
`--project`) *before* the --help/-h interception. So `sentry --org
--help` (value flag given without a value) consumed --help as the org
value and help never fired. Skip the latch for help tokens so they fall
through to the help handler, matching Stricli's leaf parser, which never
consumes a following flag as a value.

Flagged by Cursor Bugbot on #1340.
@BYK

BYK commented Aug 3, 2026

Copy link
Copy Markdown
Member

Jared, you need to make this a generic patch: something we can send as a PR upstream. I see SENTRY_TOP_LEVEL_VALUE_FLAGS etc hard-coded in the patch. They should be pluggable, maybe passed in during init or config or something. Rework your patch to make it a generic patch.

… option

Rework the @stricli/core route-scanner patch so the top-level (global) flags
allow-list is passed in via a new `scanner.topLevelFlags` config option instead
of hardcoding SENTRY_TOP_LEVEL_*_FLAGS in the patch. The scanner now reads the
allow-list (booleanFlags/valueFlags sets) from config and is inert when unset,
keeping stock Stricli behavior unchanged — this makes the top-level-flags
feature upstreamable.

The Sentry CLI supplies the allow-list from GLOBAL_FLAGS via buildTopLevelFlags()
wired into app.ts's scanner config, so adding a global flag stays a one-line
change. Adds the topLevelFlags field to ScannerConfiguration in the patched .d.ts,
updates check:patches to assert matchTopLevelFlag, and adds a test pinning the
derivation contract.

Addresses review feedback from @BYK on #1340.
@jared-outpost

jared-outpost Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

reworked the patch to be generic/upstreamable in 3b43098. the scanner no longer hardcodes SENTRY_TOP_LEVEL_*_FLAGS — it reads a scanner.topLevelFlags allow-list (booleanFlags/valueFlags sets) from config, and is inert when unset so stock Stricli behavior is unchanged. matchTopLevelFlag(input, config.topLevelFlags) replaces the hardcoded matcher, withDefaults carries the option through, and the option is documented on ScannerConfiguration in the patched .d.ts.

the Sentry-specific allow-list is now supplied at init: app.ts passes topLevelFlags: buildTopLevelFlags(), derived from GLOBAL_FLAGS, so adding a global flag stays a one-line change with no patch edits. added a test pinning the derivation contract; check:patches, tsc, biome, and the argv-glue integration suite are green.

the -v/-H alias edits in the patch are separate pre-existing Sentry concerns and were left as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace argv-hoist preprocessor with a Stricli "top-level flags" patch

1 participant