Repository navigation
ref(cli): Define the org/project target syntax as a PEG grammar - #1638
Merged
Merged
Conversation
Lists that copied code (destructive commands, detected agents, target syntax, skill file layout) are now generated from the code. New checks fail CI when a `sentry ...` example names a missing command or flag, passes a bare org slug as a project-first target, or when an installer option is missing from its help text or the install guide. `pnpm run cli` and `generate:docs` now create missing build-time files, and check:stale-refs flags `pnpm run cli -- <args>`, which pnpm forwards as a literal `--`. Co-Authored-By: Claude Opus <noreply@anthropic.com> Co-Authored-By: BYK <burak.kaya@sentry.io>
Address review feedback on the docs drift guards: - Type agent tables by `KnownAgent` (keys of AGENT_DISPLAY_NAMES), so a detectable agent without a display name is a compile error. Drop the map-structure test. - Key TARGET_FORMS by parse result type so TypeScript enforces that every type is documented, and have the generator parse each example and fail on a mismatch. Drop target-syntax.test.ts. - Check only structured `docs.examples`, not examples hand-written into `fullDescription`. - Scan the install scripts in check:env-coverage so installer variables must be in ENV_VAR_REGISTRY (and therefore configuration.md). Add the missing SENTRY_NO_MODIFY_PATH. check:installer-docs now covers only installer help text and flags. - Replace the pnpm-specific `pnpm run cli --` lint with a dev-only preload that drops a leading `--`, so the dev scripts work with any package manager. - Add check:destructive: derive SDK DELETE operations from @sentry/api, follow calls, imports, and barrel re-exports through src/, and fail when a command that sends a DELETE is not marked destructive. Co-Authored-By: BYK <burak.kaya@sentry.io>
Follow-up to #1594: `buildCommand` now calls `markDestructive` when `destructive: true`, instead of `buildDeleteCommand` doing it, so the `destructive` flag is the single source for the Safety Rules list and the auto-detect guard. `issue merge` and `trial start` get the guard if they move to lazy target positionals. check:doc-examples now recognizes target positionals by their `org/project` completion kind, which covers the new lazy target parsers as well as `parseOrgProjectTarget`.
Resolve conflicts with #1633, which moved the remaining hand-written examples into `docs.examples`: take main's version of the dashboard commands and the alert/dashboard fragments, then regenerate the skill references. check:doc-examples now covers the migrated examples and flagged: - `dashboard revisions` and `dashboard restore` examples that pass a bare `my-org` (a project lookup); changed to `my-org/` - examples that start with `sudo` or `NAME=value`, which the check misread as the command name; it now skips those prefixes Co-Authored-By: BYK <burak.kaya@sentry.io>
Replace the hand-written `<org>/<project>` parser with a peggy grammar (packages/cli/grammar/org-project-target.pegjs). parseOrgProjectArg keeps its signature and still handles blank input and Sentry URLs; character validation goes through options hooks so error messages are unchanged. The target syntax tables are now generated from `@form` annotations in the grammar, and generation fails when a `target` alternative is unannotated. This replaces TARGET_FORMS and documents the forms it missed: Sentry URLs, `/<name>`, and display names with and without an org. The parser generator moves to scripts/generate-parsers.mjs so toolkit-core and the CLI share it, check:generated, and the pre-commit hook. Closes #1637 Co-Authored-By: BYK <burak.kaya@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
#1633 added the `no-regex-markdown-parsing` lint rule. Replace the fenced block regex with the shared `markdownCodeBlocks` / `blankCodeBlocks` helpers in script/markdown.ts, which use the same lexer as the docs renderer.
…byk/cli-target-grammar
The Windows job checks out the grammar with CRLF line endings, so the annotation regexes never matched and docs generation failed.
# Conflicts: # apps/cli-docs/src/fragments/commands/index.md # packages/cli/CONTRIBUTING.md # packages/cli/script/generate-docs-sections.ts Co-Authored-By: BYK <burak.kaya@sentry.io>
BYK
requested changes
Oct 23, 2026
Stop committing the CLI target parser; src/generated/ is gitignored and lint/format-ignored again. generate:grammar builds it from generate:docs and ensure-generated, so build, typecheck, test, and cli runs get it. Parser types move out of string templates in generate-parsers.mjs into hand-written grammar/<name>.d.ts files. The generator copies them and rebases relative module specifiers it finds with the TypeScript parser. toolkit-core's parser stays committed and checked by check:generated.
BYK
approved these changes
Oct 23, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1637. Stacked on #1626 (it replaces
TARGET_FORMSfrom that PR), so the base isbyk/cli-docs-drift-guards.The
<org>/<project>target syntax is now one peggy grammar,packages/cli/grammar/org-project-target.pegjs. Both the parser and the docs table come from it.parseOrgProjectArgkeeps its signature. It still keeps the first non-blank line, auto-detects on empty input, and reads Sentry URLs itself. Everything else goes through the generated parser. Slug and@checks run throughoptionshooks (validateResourceId,rejectAtSelector), so error messages stay the same.parseSlashOrgProject,parseExplicitProjectList, and their helpers are deleted. The backtracking pitfall from the spike is documented in the grammar, and the existing@latesttest guards it: token rules only capture text, and validation runs in the winning alternative.targetalternative has// @form <syntax> — <meaning>lines above it, andgenerate-docs-sections.tsbuilds the table from them. Generation fails if an alternative has no@formor@invalidline. The check uses peggy's grammar AST, so a new form can't ship undocumented. The table now also lists the formsTARGET_FORMSwas missing: Sentry URLs,/<name>,<org>/<Project Name>, and<Project Name>. Omitted targets and URLs never reach the grammar, so they are annotated in the grammar header.packages/toolkit-core/script/generate-parsers.tsmoved toscripts/generate-parsers.mjs(pnpm run generate:parsers). One list of grammar specs covers both packages, andcheck:generatedand the pre-commit hook use it. The CLI output goes topackages/cli/src/generated/org-project-target-grammar.{js,d.ts}and is committed (.gitignoreexception). It is about 24 KB unminified. peggy moves from a toolkit-core devDependency to the root and the CLI. The lockfile only changes the importer entries.Migration check, not committed: I compared the new parser with a copy of the old one on 139,954 inputs. They were every string up to 4 characters over
a b / , space @ - _ ? # \n 1 % . A \t, the 53 literals inarg-parsing.test.ts, and some extra edge cases, each withmultion and off. There were 0 differences in results, error classes, messages, or fields. While doing this I found and fixed one real bug, which needed end-anchored token rules. Without them, PEG prefix matching turnedA #into aSyntaxError.Not in this PR:
parseIssueArg(step 4 of the issue), and removingnormalizeSlug/normalized.parseIssueArgandtrace-target.tsstill use the latter.originalSlugis still needed: it is how resolution tells a display name from a slug.via BYK.
--
View Junior Session in Sentry