Skip to content

feat(grammar): universal highlighting distribution — sublime, KDE, highlight.js, tree-sitter - #3996

Merged
hellovai merged 4 commits into
canaryfrom
vbv/grammar-distribution
Jul 13, 2026
Merged

hellovai merged 4 commits into
canaryfrom
vbv/grammar-distribution

Conversation

@hellovai

@hellovai hellovai commented Jul 12, 2026 •

Copy link
Copy Markdown
Contributor

Extends the grammar mirror pipeline (#3986) so every syntax-highlighting registry on the internet is fed from this monorepo, with mirrors as write-only build artifacts. Follows the plan in typescript2/pkg-grammar/DISTRIBUTION.md (included).

What's here

pkg-grammar (extended)

  • baml.sublime-syntax generated from the TextMate grammar by scripts/emit-sublime.ts (wired into build, drift-guard test). Validated against real syntect: bat renders every fixture with zero errors.
  • syntaxes/baml.xml — hand-authored KDE KSyntaxHighlighting definition (Kate, Pandoc via skylighting). Validates against the official KDE language.xsd. Dynamic rules support arbitrary raw-string # depth.
  • tests/fixtures/showcase__golden_sample.baml — canonical showcase sample, mirrored as samples/baml.sample for registry submissions (Shiki etc.).
  • Mirror hardening: SUPPORT.md registry matrix, frozen-path contract + read-only footer in the mirror README, DISTRIBUTION.md rollout playbook.

pkg-grammar-hljs (new) → mirrors to BoundaryML/baml-highlightjs, npm @boundaryml/baml-highlightjs

  • highlight.js 11 language definition with Jinja {{ }}/{% %} highlighting inside prompt bodies, raw/backtick/byte strings, full keyword taxonomy from the real lexer.
  • Tested against every pkg-grammar fixture (82 tests); browser/CDN dist build generated at mirror-assembly time.

pkg-grammar-treesitter (new) → mirrors to BoundaryML/baml-treesitter (nvim-treesitter / Zed / Helix)

  • Modern tree-sitter grammar for the full current language (interfaces, generics, lambdas, match patterns, let/const destructuring, backtick ${} bodies). No external scanner.
  • 80/80 fixtures parse with zero ERROR/MISSING; 63 corpus tests; highlight queries + jinja injection into prompt bodies.
  • The old BoundaryML/tree-sitter-baml (15 months stale) is untouched; the Zed pin migrates later.

Automation

  • sync-grammar-mirror.yml fans out to all three mirrors; npm-published mirrors get v* tags (bat/Package Control/Linguist pinning).
  • grammar-tests CI runs all three packages as a conformance gate: every port validates against the shared fixture corpus, so a language change a port doesn't handle fails the PR.

Bootstrap status (already done via gh)

  • BoundaryML/baml-highlightjs + BoundaryML/baml-treesitter created and seeded with assembled content (hljs tagged v0.1.0)
  • Write deploy keys added; BAML_HIGHLIGHTJS_DEPLOY_KEY / BAML_TREESITTER_DEPLOY_KEY secrets set on this repo
  • First manual npm publish of @boundaryml/baml-highlightjs (v0.1.0 on npm) + trusted publisher configured

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added Highlight.js and Tree-sitter BAML grammar support with expanded automated read-only mirror syncing and npm publishing.
    • Expanded the generated syntax-highlighting artifacts across the grammar family (including KDE and Sublime outputs).
    • Added support for constructor field shorthand (fields without :) in syntax highlighting.
  • Bug Fixes
    • Improved CI change detection to ensure grammar-impacting updates trigger full conformance runs.
  • Tests
    • Added/extended Highlight.js and Tree-sitter test suites with new fixtures and snapshot/golden validation.
  • Documentation
    • Added documentation for the new grammar packages and distribution/mirroring outputs.

…ghlight.js, tree-sitter

Extends the grammar mirror pipeline (#3986) so every syntax-highlighting
registry on the internet is fed from this monorepo, with mirrors as
write-only build artifacts:

- pkg-grammar: generated baml.sublime-syntax (bat/syntect/Sublime, validated
  against real syntect via bat on all fixtures), hand-authored KDE
  KSyntaxHighlighting definition (Kate/Pandoc, validates against the official
  XSD), canonical showcase__golden_sample.baml fixture (mirrored as
  samples/baml.sample), SUPPORT.md registry matrix, frozen-path contract in
  the mirror README, DISTRIBUTION.md rollout playbook.
- pkg-grammar-hljs (new): highlight.js language definition with
  Jinja-in-prompt highlighting, tested against every pkg-grammar fixture;
  mirrors to BoundaryML/baml-highlightjs → npm @boundaryml/baml-highlightjs.
- pkg-grammar-treesitter (new): modern tree-sitter grammar for the full
  expression language (no external scanner; 80/80 fixtures parse with zero
  ERROR/MISSING, 63 corpus tests, highlight + jinja injection queries);
  mirrors to BoundaryML/baml-treesitter for nvim/Zed/Helix.
- sync-grammar-mirror: fans out to all three mirrors and tags npm-published
  versions (v*) so bat/Package Control/Linguist can pin.
- ci: grammar-tests now runs all three packages as a conformance gate — a
  language change that a port doesn't handle fails the PR.

Bootstrap steps for the two new mirror repos (deploy keys, first npm
publish) are documented in typescript2/pkg-grammar/DISTRIBUTION.md.

Co-Authored-By: Claude Fable 5 <[email protected]>
@vercel

vercel Bot commented Jul 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 13, 2026 4:44am
promptfiddle Ready Ready Preview, Comment Jul 13, 2026 4:44am
promptfiddle2 Ready Ready Preview, Comment Jul 13, 2026 4:44am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This change adds Highlight.js and Tree-sitter grammars, generates Sublime Text and KDE syntax definitions, expands grammar fixtures and validation, and updates CI and mirror workflows for testing, assembly, publishing, and synchronization.

Changes

Grammar distribution

Layer / File(s) Summary
Grammar implementations and derived syntax
typescript2/pkg-grammar/..., typescript2/pkg-grammar-hljs/..., typescript2/pkg-grammar-treesitter/...
Adds Highlight.js and Tree-sitter grammars, Sublime and KDE syntax outputs, interpolation/string handling, and constructor-field shorthand support.
Fixtures and validation
typescript2/pkg-grammar/tests/..., typescript2/pkg-grammar-hljs/tests/..., typescript2/pkg-grammar-treesitter/test/...
Adds shared golden fixtures, Highlight.js snapshots and regression tests, Tree-sitter corpus coverage, and structural validation for KDE and Sublime outputs.
Packaging and mirror assembly
typescript2/pkg-grammar-*/package.json, scripts/assemble-mirror.mjs, mirror/*
Adds package metadata, mirror assembly scripts, generated mirror scaffolding, Highlight.js publishing, and Tree-sitter mirror generation.
CI, synchronization, and distribution docs
.github/workflows/..., typescript2/pkg-grammar/{README.md,DISTRIBUTION.md}, typescript2/pnpm-workspace.yaml
Extends grammar-aware CI, enables Tree-sitter builds, documents artifact distribution, and synchronizes TextMate, Highlight.js, and Tree-sitter mirrors.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GrammarSource
  participant CI
  participant MirrorWorkflow
  participant GrammarMirror
  participant NpmRegistry
  GrammarSource->>CI: Detect grammar package changes
  CI->>CI: Run grammar validation suites
  MirrorWorkflow->>GrammarMirror: Assemble and push mirror artifacts
  MirrorWorkflow->>NpmRegistry: Verify or publish Highlight.js package
Loading

Possibly related PRs

Poem

A rabbit hops through grammar’s glow,
With trees and highlights in a row.
Mirrors build and tests all cheer,
Syntax blooms from ear to ear.
“Bouncy builds!” the bunny cries.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.32% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: broader grammar distribution across Sublime, KDE, highlight.js, and tree-sitter.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch vbv/grammar-distribution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@vercel
vercel Bot temporarily deployed to Preview – beps July 12, 2026 23:28 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 12, 2026 23:35 Inactive
@github-actions

github-actions Bot commented Jul 12, 2026 •

Copy link
Copy Markdown

Binary size checks passed

✅ 7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
✅ baml-cli Linux 🔒 21.9 MB 9.4 MB file 21.5 MB +356.3 KB (+1.7%) OK
✅ packed-program Linux 🔒 15.8 MB 6.7 MB file 15.6 MB +138.7 KB (+0.9%) OK
✅ baml-cli macOS 🔒 16.8 MB 8.1 MB file 16.6 MB +283.0 KB (+1.7%) OK
✅ packed-program macOS 🔒 12.2 MB 5.9 MB file 12.1 MB +83.9 KB (+0.7%) OK
✅ baml-cli Windows 🔒 18.4 MB 8.3 MB file 18.1 MB +271.9 KB (+1.5%) OK
✅ packed-program Windows 🔒 13.1 MB 6.0 MB file 13.0 MB +65.0 KB (+0.5%) OK
✅ bridge_wasm WASM 14.6 MB 🔒 4.1 MB gzip 4.1 MB +72.4 KB (+1.8%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 12, 2026 23:49 Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/sync-grammar-mirror.yml (1)

56-170: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add explicit permissions: to these jobs.

Neither sync-textmate nor sync-highlightjs declares a permissions: block, so they run with the default (potentially broad) GITHUB_TOKEN scope. Both jobs only need to checkout the repo and run pnpm scripts (third-party dependency code executes here); the actual mirror pushes use a dedicated SSH deploy key, not GITHUB_TOKEN. Scope the token down, e.g. permissions: contents: read at the workflow or job level (the same likely applies to sync-treesitter, not flagged in the given hints but structurally identical).

permissions:
  contents: read

Also applies to: 172-269

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sync-grammar-mirror.yml around lines 56 - 170, Add an
explicit permissions block with contents: read to the sync-textmate and
sync-highlightjs jobs, and apply the same restriction to the structurally
identical sync-treesitter job if present. Keep the existing SSH deploy-key
behavior unchanged; these jobs should not receive broader GITHUB_TOKEN
permissions.

Source: Linters/SAST tools

🧹 Nitpick comments (3)
typescript2/pkg-grammar-hljs/mirror/publish.yml (1)

33-36: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Pin the Node.js version instead of latest.

Trusted publishing requires npm CLI >=11.5.1 and Node >=22.14.0 Trusted publishing requires npm CLI version 11.5.1 or later and Node version 22.14.0 or higher. The npm-version half is explicitly checked below (Lines 38-46), but the Node-version half relies implicitly on latest always exceeding that floor. Pinning to a specific major version keeps this publish workflow reproducible and avoids silent breakage from future Node releases, while still satisfying the floor.

♻️ Proposed fix
       - uses: actions/setup-node@v4
         with:
-          node-version: latest
+          node-version: "24"
           registry-url: https://registry.npmjs.org
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar-hljs/mirror/publish.yml` around lines 33 - 36, Update
the node-version setting in the setup-node action within the publish workflow to
a pinned Node.js version at or above 22.14.0, rather than latest. Keep the
existing registry-url and npm version validation unchanged.
typescript2/pkg-grammar/scripts/emit-sublime.ts (1)

235-237: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

include branch skips the exhaustive key-combination check used elsewhere.

match, begin, and patterns branches all explicitly reject unexpected key combinations (Lines 240-242, 262-264, 304-306), but include returns immediately without checking for stray name/match/patterns/captures on the same rule object. If such a construct is ever emitted upstream, it would be silently dropped rather than failing loudly — and the drift test wouldn't catch it, since it just re-runs this same emitter.

♻️ Proposed fix
     if (rule.include !== undefined) {
+      const extraKeys = Object.keys(rule).filter((key) => key !== "include");
+      if (extraKeys.length > 0) {
+        fail(where, `\`include\` rule combined with [${extraKeys.join(", ")}] is unhandled`);
+      }
       return [{ kind: "include", target: resolveInclude(rule.include, where) }];
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar/scripts/emit-sublime.ts` around lines 235 - 237,
Update the include branch in the rule-emission logic to perform the same
exhaustive key-combination validation as the match, begin, and patterns branches
before returning the include token. Reject any accompanying name, match,
patterns, captures, or other unsupported keys instead of silently ignoring them,
while preserving valid include-only rules.
typescript2/pkg-grammar/tests/kde-syntax.test.ts (1)

272-294: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Dynamic-context check only follows the context attribute, missing lineEndContext/lineEmptyContext/fallthroughContext.

Line 282 resolves el.attributes.context ?? "" only. The same file already tracks lineEndContext, lineEmptyContext, and fallthroughContext as valid ways to transition into a context (see the contextKeys array at line 185). A context reachable only via one of those three attributes, but containing a dynamic="true" RegExpr, would silently pass this check even without dynamic="true" on itself.

♻️ Suggested fix
     for (const contextsBlock of find(language, "contexts")) {
       walk(contextsBlock, (el) => {
         if (el.name === "context" || el.name === "contexts") return;
-        // A rule whose String captures a group and whose target context uses
-        // %N substitution must land in a dynamic="true" context.
-        const target = referencedContextName(el.attributes.context ?? "");
-        if (target === null) return;
-        const targetContext = contextsByName.get(target);
-        if (!targetContext) return;
-        const usesSubstitution = find(targetContext, "RegExpr").some(
-          (rule) => rule.attributes.dynamic === "true",
-        );
-        if (usesSubstitution && targetContext.attributes.dynamic !== "true") {
-          throw new Error(`context "${target}" has dynamic rules but is not dynamic="true"`);
-        }
+        // A rule whose String captures a group and whose target context uses
+        // %N substitution must land in a dynamic="true" context.
+        for (const key of ["context", "lineEndContext", "lineEmptyContext", "fallthroughContext"]) {
+          const target = referencedContextName(el.attributes[key] ?? "");
+          if (target === null) continue;
+          const targetContext = contextsByName.get(target);
+          if (!targetContext) continue;
+          const usesSubstitution = find(targetContext, "RegExpr").some(
+            (rule) => rule.attributes.dynamic === "true",
+          );
+          if (usesSubstitution && targetContext.attributes.dynamic !== "true") {
+            throw new Error(`context "${target}" has dynamic rules but is not dynamic="true"`);
+          }
+        }
       });
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar/tests/kde-syntax.test.ts` around lines 272 - 294,
Update the dynamic-context check in the test so it resolves every transition
attribute listed by contextKeys, including context, lineEndContext,
lineEmptyContext, and fallthroughContext, rather than only
el.attributes.context. Apply the existing referenced-context and dynamic-rule
validation to each resolved target while preserving the current behavior for
absent or unknown targets.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/sync-grammar-mirror.yml:
- Around line 142-147: Update the publish push commands in both mirror jobs,
including sync-highlightjs, to push the main branch and v${next} tag atomically
in a single git push --atomic operation. Replace the separate branch and tag
pushes while preserving the existing tag creation and version references.

In `@typescript2/pkg-grammar-hljs/mirror/README.md`:
- Line 48: Update the README script reference to use highlight.js’s prebuilt
browser-global bundle instead of the npm/CommonJS entrypoint, ensuring it
provides the global hljs expected by dist/baml.js.

In `@typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs`:
- Line 15: Validate the resolved output path before the rmSync cleanup in
assemble-mirror.mjs. Reject paths equal to or containing the working directory,
repository root, package root, or any ancestor of those roots, including --out .
and parent directories; only perform deletion after this guard passes.

In `@typescript2/pkg-grammar-hljs/src/baml.js`:
- Around line 35-44: Update IDENT and KEYWORDS.$pattern in the BAML grammar to
allow lexer-supported $-joined identifier segments, matching the identifier form
used by the tree-sitter grammar. Preserve existing optional leading-$ behavior
while permitting internal $ characters so names such as Foo$bar remain a single
token and do not receive partial keyword or title scopes.
- Around line 216-224: Update the SUBST grammar mode so interpolation braces are
nested recursively and the mode closes only at the matching outer brace,
preserving nested block and constructor-expression highlighting. Add a BAML
snapshot test in the existing baml.test.ts coverage for an interpolation
containing nested braces.

In `@typescript2/pkg-grammar-treesitter/grammar.js`:
- Around line 11-14: The raw-string grammar currently supports only four hash
delimiter levels; update the raw-string token definitions around the per-level
delimiter declarations to support arbitrary hash counts as required by the
language spec. If the Tree-sitter grammar cannot express unbounded delimiters,
explicitly narrow the documented supported range to four hashes instead.

In `@typescript2/pkg-grammar-treesitter/mirror/README.md`:
- Around line 45-48: Pin the baml grammar source in the [[grammar]]
configuration by replacing the mutable rev = "main" value with a specific
immutable commit revision from baml-treesitter. Keep the existing repository URL
and grammar name unchanged.

In `@typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs`:
- Around line 47-49: Validate the resolved output path in the assemble script
before the rmSync call, rejecting any path that is the repository directory, an
ancestor of it, or contained within it. Ensure the overlap check uses normalized
absolute paths and aborts before deletion, while allowing output paths outside
the repository tree.

In `@typescript2/pkg-grammar/DISTRIBUTION.md`:
- Around line 9-16: Update the fenced diagram in the distribution documentation
to specify the text language by changing its opening fence to use text, while
preserving the diagram content unchanged.

In
`@typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt`:
- Around line 352-360: Update the grammar scope expectations for the args
constructor block so the quoted value following text is tokenized as
string.quoted.double.baml, including the embedded comma, rather than raw
constructor-body text with punctuation.separator.comma.baml. Adjust the relevant
grammar rule or snapshot generation around the args constructor expression while
preserving the existing scopes for the hints array and constructor delimiters.

---

Outside diff comments:
In @.github/workflows/sync-grammar-mirror.yml:
- Around line 56-170: Add an explicit permissions block with contents: read to
the sync-textmate and sync-highlightjs jobs, and apply the same restriction to
the structurally identical sync-treesitter job if present. Keep the existing SSH
deploy-key behavior unchanged; these jobs should not receive broader
GITHUB_TOKEN permissions.

---

Nitpick comments:
In `@typescript2/pkg-grammar-hljs/mirror/publish.yml`:
- Around line 33-36: Update the node-version setting in the setup-node action
within the publish workflow to a pinned Node.js version at or above 22.14.0,
rather than latest. Keep the existing registry-url and npm version validation
unchanged.

In `@typescript2/pkg-grammar/scripts/emit-sublime.ts`:
- Around line 235-237: Update the include branch in the rule-emission logic to
perform the same exhaustive key-combination validation as the match, begin, and
patterns branches before returning the include token. Reject any accompanying
name, match, patterns, captures, or other unsupported keys instead of silently
ignoring them, while preserving valid include-only rules.

In `@typescript2/pkg-grammar/tests/kde-syntax.test.ts`:
- Around line 272-294: Update the dynamic-context check in the test so it
resolves every transition attribute listed by contextKeys, including context,
lineEndContext, lineEmptyContext, and fallthroughContext, rather than only
el.attributes.context. Apply the existing referenced-context and dynamic-rule
validation to each resolved target while preserving the current behavior for
absent or unknown targets.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a803bc40-59db-4af0-b32b-9c13d025ef54

📥 Commits

Reviewing files that changed from the base of the PR and between 124952b and 7ee03d6.

⛔ Files ignored due to path filters (1)
  • typescript2/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (46)
  • .github/workflows/ci.yaml
  • .github/workflows/sync-grammar-mirror.yml
  • typescript2/pkg-grammar-hljs/README.md
  • typescript2/pkg-grammar-hljs/mirror/README.md
  • typescript2/pkg-grammar-hljs/mirror/package.json
  • typescript2/pkg-grammar-hljs/mirror/publish.yml
  • typescript2/pkg-grammar-hljs/package.json
  • typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-hljs/src/baml.js
  • typescript2/pkg-grammar-hljs/tests/baml.test.ts
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__const_let_else_defer.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__retry_policy_valid_retry.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/generators.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/lsp_syntax_functions__jinja_control_prompt.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/ns_sentiment__sentiment.baml.html
  • typescript2/pkg-grammar-hljs/vitest.config.ts
  • typescript2/pkg-grammar-treesitter/.gitignore
  • typescript2/pkg-grammar-treesitter/README.md
  • typescript2/pkg-grammar-treesitter/grammar.js
  • typescript2/pkg-grammar-treesitter/mirror/README.md
  • typescript2/pkg-grammar-treesitter/package.json
  • typescript2/pkg-grammar-treesitter/queries/highlights.scm
  • typescript2/pkg-grammar-treesitter/queries/injections.scm
  • typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-treesitter/test/corpus/attributes.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/control_flow.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/declarations.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/expressions.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/patterns.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/strings.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/types.txt
  • typescript2/pkg-grammar-treesitter/tree-sitter.json
  • typescript2/pkg-grammar/DISTRIBUTION.md
  • typescript2/pkg-grammar/README.md
  • typescript2/pkg-grammar/baml.sublime-syntax
  • typescript2/pkg-grammar/mirror/README.md
  • typescript2/pkg-grammar/mirror/SUPPORT.md
  • typescript2/pkg-grammar/package.json
  • typescript2/pkg-grammar/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar/scripts/emit-sublime.ts
  • typescript2/pkg-grammar/syntaxes/baml.xml
  • typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml
  • typescript2/pkg-grammar/tests/kde-syntax.test.ts
  • typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt
  • typescript2/pkg-grammar/tests/sublime-syntax.test.ts
  • typescript2/pnpm-workspace.yaml

Comment thread typescript2/pkg-grammar/DISTRIBUTION.md Resolved
- src/baml.ts: new constructor-field-shorthand rule so colon-less fields
  (test args `text "..."`, `functions [F]`) scope name + value correctly —
  pre-existing gap CodeRabbit caught via the golden-sample snapshot.
- sync-grammar-mirror: push main and the version tag atomically so a
  half-failed push can never strand an untagged release.
- assemble-mirror scripts (all three): refuse --out paths overlapping the
  repo checkout before the recursive rmSync.
- pkg-grammar-hljs: identifiers use the lexer's full $-joined Word shape
  (Foo$bar, $stream are single tokens); backtick ${...} interpolation now
  tracks nested braces; README points at the real browser CDN bundle;
  +2 regression tests.
- pkg-grammar-treesitter: raw strings extended to 8 hash levels via
  MAX_RAW_STRING_HASHES, matching the TextMate MAX_DELIMITER = 8 bound;
  +1 corpus test; mirror README tells Helix users to pin a commit.
- DISTRIBUTION.md: language on the fenced diagram (MD040).

Co-Authored-By: Claude Fable 5 <[email protected]>
@vercel
vercel Bot temporarily deployed to Preview – beps July 13, 2026 00:03 Inactive
@hellovai

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 13, 2026 00:10 Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@typescript2/app-vscode-ext/syntaxes/baml.tmLanguage.json`:
- Around line 1700-1714: Update the constructor-field shorthand grammar around
"constructor-field-shorthand" so its begin boundary also recognizes a shorthand
field immediately following a same-line block comment, while preserving existing
start, brace, and comma boundaries. Add a regression fixture covering `/* note
*/ text "Jane"`, then update the canonical generator and regenerate the syntax
mirror.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3596083a-4d67-43f3-be29-3937ce873410

📥 Commits

Reviewing files that changed from the base of the PR and between 7ee03d6 and 106aa63.

📒 Files selected for processing (18)
  • .github/workflows/sync-grammar-mirror.yml
  • typescript2/app-vscode-ext/syntaxes/baml.tmLanguage.json
  • typescript2/pkg-grammar-hljs/mirror/README.md
  • typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-hljs/src/baml.js
  • typescript2/pkg-grammar-hljs/tests/baml.test.ts
  • typescript2/pkg-grammar-treesitter/README.md
  • typescript2/pkg-grammar-treesitter/grammar.js
  • typescript2/pkg-grammar-treesitter/mirror/README.md
  • typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-treesitter/test/corpus/strings.txt
  • typescript2/pkg-grammar/DISTRIBUTION.md
  • typescript2/pkg-grammar/baml.sublime-syntax
  • typescript2/pkg-grammar/baml.tmLanguage.json
  • typescript2/pkg-grammar/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar/src/baml.ts
  • typescript2/pkg-grammar/tests/snapshots/lsp_semantic__test_block.baml.scope.txt
  • typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt
🚧 Files skipped from review as they are similar to previous changes (12)
  • typescript2/pkg-grammar-treesitter/mirror/README.md
  • typescript2/pkg-grammar/baml.sublime-syntax
  • typescript2/pkg-grammar/DISTRIBUTION.md
  • typescript2/pkg-grammar-treesitter/README.md
  • .github/workflows/sync-grammar-mirror.yml
  • typescript2/pkg-grammar-hljs/mirror/README.md
  • typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-hljs/src/baml.js
  • typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-treesitter/grammar.js
  • typescript2/pkg-grammar-treesitter/test/corpus/strings.txt
  • typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Comments resolved and changes approved.

Was written as an internal rollout playbook; now it reads as a
contributor-facing doc: how to use the grammars in your own project,
where highlighting fixes go, which integrations are live vs. looking
for an owner, with maintainer wiring notes at the end.

Co-Authored-By: Claude Fable 5 <[email protected]>
@vercel
vercel Bot temporarily deployed to Preview – beps July 13, 2026 00:23 Inactive
@hellovai
hellovai enabled auto-merge July 13, 2026 00:28

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@typescript2/pkg-grammar/DISTRIBUTION.md`:
- Around line 52-55: Update the npm consumer row in DISTRIBUTION.md to
distinguish the established `@boundaryml/baml-grammar` package from the newly
seeded `@boundaryml/baml-highlightjs` package: mark highlightjs as pending initial
manual publish and OTP/trusted-publisher setup rather than “✅ live” and
auto-published. Keep the documented live status for baml-grammar and ensure the
table agrees with the maintainer note about first publication.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ac4971cd-80bf-4dba-b32b-20f04a8f6145

📥 Commits

Reviewing files that changed from the base of the PR and between 106aa63 and bc83917.

📒 Files selected for processing (1)
  • typescript2/pkg-grammar/DISTRIBUTION.md

Comment thread typescript2/pkg-grammar/DISTRIBUTION.md Resolved
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 13, 2026 00:30 Inactive
@hellovai

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 13, 2026 00:44 Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🧹 Nitpick comments (2)
typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml (1)

1-97: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider exercising the new constructor-field-shorthand construct here.

This is the shared conformance fixture for all four highlighter ports, but no constructor-instantiation expression appears in it — so the new constructor-field-shorthand rule (baml.tmLanguage.json lines 1700-1717) currently isn't validated by any of the Sublime/KDE/hljs/tree-sitter conformance tests that consume this file. Note the value must start with an unambiguous literal (string/number/bool/null/env/array/backtick) for the shorthand rule to trigger — a bare identifier won't match its lookahead.

Proposed addition
 test GoldenExtract {
   functions [ExtractResume]
   args {
     text "Jane Doe, 12 years of Rust"
     hints ["skills", "email"]
   }
 }
+
+class Point {
+  x int
+  y int
+}
+
+function MakePoint() -> Point {
+  Point { x: 1, y 2 }
+}

Worth confirming first whether constructor-literal syntax is already covered by another fixture under tests/fixtures/*.baml not in this review batch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml` around
lines 1 - 97, Add a constructor-instantiation expression to the shared
GoldenExtract fixture to exercise the new constructor-field-shorthand rule,
using a value that begins with an unambiguous supported literal such as a
string, number, boolean, null, env, array, or backtick expression. Keep the
example valid BAML syntax and avoid a bare identifier as the shorthand value;
first reuse an existing fixture if constructor-literal coverage already exists
there.
.github/workflows/sync-grammar-mirror.yml (1)

56-171: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add least-privilege permissions: to the mirror-sync jobs.

Neither sync-textmate nor sync-highlightjs declares a permissions: block, so the job's GITHUB_TOKEN gets the repo/org default (potentially broad). Since these jobs push to mirrors via a deploy-key SSH secret (not GITHUB_TOKEN) and only need actions/checkout for read, an explicit minimal block (e.g. contents: read) would tighten this. Same applies to sync-treesitter (Lines 272-326).

🔒 Example fix
   sync-textmate:
     name: Sync to BoundaryML/textMate-baml
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:

Also applies to: 173-270

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sync-grammar-mirror.yml around lines 56 - 171, Declare an
explicit least-privilege permissions block for the sync-textmate,
sync-highlightjs, and sync-treesitter jobs, granting only contents: read. Keep
the existing deploy-key SSH flow for mirror pushes unchanged and apply the same
permissions configuration consistently to all three jobs.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs`:
- Around line 62-76: Harden the source validation in assemble-mirror.mjs before
constructing the IIFE: require the actual default export declaration to be a
function named baml, and ensure the transformation targets that declaration
rather than an arbitrary first matching substring. Keep the generated wrapper’s
registerLanguage('baml', baml) binding valid and fail with the existing error
path when the expected declaration is absent.

In `@typescript2/pkg-grammar/scripts/assemble-mirror.mjs`:
- Line 19: Canonicalize the --out path before the recursive deletion overlap
check in the assembly script. Use realpathSync on the nearest existing ancestor,
then rebuild the canonical output path and perform the existing checkout-overlap
validation against it, preserving normal handling for paths that do not yet
exist.

In `@typescript2/pkg-grammar/syntaxes/baml.xml`:
- Around line 44-60: The singular `implement` keyword is inconsistent across the
lexer, BAML grammar, tree-sitter grammar, and highlights. Choose the intended
keyword spelling, then update the `declarations` list, `grammar.js`,
`queries/highlights.scm`, and the lexer/BAML grammar mirrors so all
representations consistently recognize or omit `implement` alongside
`implements`.

---

Nitpick comments:
In @.github/workflows/sync-grammar-mirror.yml:
- Around line 56-171: Declare an explicit least-privilege permissions block for
the sync-textmate, sync-highlightjs, and sync-treesitter jobs, granting only
contents: read. Keep the existing deploy-key SSH flow for mirror pushes
unchanged and apply the same permissions configuration consistently to all three
jobs.

In `@typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml`:
- Around line 1-97: Add a constructor-instantiation expression to the shared
GoldenExtract fixture to exercise the new constructor-field-shorthand rule,
using a value that begins with an unambiguous supported literal such as a
string, number, boolean, null, env, array, or backtick expression. Keep the
example valid BAML syntax and avoid a bare identifier as the shorthand value;
first reuse an existing fixture if constructor-literal coverage already exists
there.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 28bd6b79-cee3-47c9-b3b7-e69c663e2fbe

📥 Commits

Reviewing files that changed from the base of the PR and between 124952b and bc83917.

⛔ Files ignored due to path filters (1)
  • typescript2/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (50)
  • .github/workflows/ci.yaml
  • .github/workflows/sync-grammar-mirror.yml
  • typescript2/app-vscode-ext/syntaxes/baml.tmLanguage.json
  • typescript2/pkg-grammar-hljs/README.md
  • typescript2/pkg-grammar-hljs/mirror/README.md
  • typescript2/pkg-grammar-hljs/mirror/package.json
  • typescript2/pkg-grammar-hljs/mirror/publish.yml
  • typescript2/pkg-grammar-hljs/package.json
  • typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-hljs/src/baml.js
  • typescript2/pkg-grammar-hljs/tests/baml.test.ts
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__const_let_else_defer.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__retry_policy_valid_retry.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/generators.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/lsp_syntax_functions__jinja_control_prompt.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/ns_sentiment__sentiment.baml.html
  • typescript2/pkg-grammar-hljs/vitest.config.ts
  • typescript2/pkg-grammar-treesitter/.gitignore
  • typescript2/pkg-grammar-treesitter/README.md
  • typescript2/pkg-grammar-treesitter/grammar.js
  • typescript2/pkg-grammar-treesitter/mirror/README.md
  • typescript2/pkg-grammar-treesitter/package.json
  • typescript2/pkg-grammar-treesitter/queries/highlights.scm
  • typescript2/pkg-grammar-treesitter/queries/injections.scm
  • typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-treesitter/test/corpus/attributes.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/control_flow.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/declarations.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/expressions.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/patterns.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/strings.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/types.txt
  • typescript2/pkg-grammar-treesitter/tree-sitter.json
  • typescript2/pkg-grammar/DISTRIBUTION.md
  • typescript2/pkg-grammar/README.md
  • typescript2/pkg-grammar/baml.sublime-syntax
  • typescript2/pkg-grammar/baml.tmLanguage.json
  • typescript2/pkg-grammar/mirror/README.md
  • typescript2/pkg-grammar/mirror/SUPPORT.md
  • typescript2/pkg-grammar/package.json
  • typescript2/pkg-grammar/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar/scripts/emit-sublime.ts
  • typescript2/pkg-grammar/src/baml.ts
  • typescript2/pkg-grammar/syntaxes/baml.xml
  • typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml
  • typescript2/pkg-grammar/tests/kde-syntax.test.ts
  • typescript2/pkg-grammar/tests/snapshots/lsp_semantic__test_block.baml.scope.txt
  • typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt
  • typescript2/pkg-grammar/tests/sublime-syntax.test.ts
  • typescript2/pnpm-workspace.yaml

- src/baml.ts: shorthand constructor fields now also match after a
  same-line block comment (/* note */ text "..."); regression case added
  to the golden sample.
- pkg-grammar-treesitter: accept the singular `implement` keyword
  interchangeably with `implements` in both block and for-declaration
  positions, matching the compiler parser; highlight query + corpus test.
- assemble-mirror scripts: canonicalize paths through symlinks (realpath
  of nearest existing ancestor) before the overlap check.
- pkg-grammar-hljs assemble: dist wrapper guard now requires the exact
  `export default function baml(` shape it rewrites.

Co-Authored-By: Claude Fable 5 <[email protected]>
@hellovai

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@vercel
vercel Bot temporarily deployed to Preview – beps July 13, 2026 04:24 Inactive
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 13, 2026 04:31 Inactive
@hellovai
hellovai added this pull request to the merge queue Jul 13, 2026
@vercel
vercel Bot temporarily deployed to Preview – promptfiddle July 13, 2026 04:44 Inactive

@coderabbitai coderabbitai 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.

Actionable comments posted: 6

🧹 Nitpick comments (1)
.github/workflows/sync-grammar-mirror.yml (1)

56-171: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add explicit permissions: blocks to the sync jobs.

Static analysis flags both sync-textmate and sync-highlightjs (and, by the same reasoning, sync-treesitter) for relying on default GITHUB_TOKEN permissions. Since these jobs authenticate to the mirrors via dedicated deploy-key secrets rather than GITHUB_TOKEN, scoping down to permissions: contents: read (or similar minimal grant) at the job or workflow level would tighten the security posture without affecting functionality.

Also applies to: 173-270

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/sync-grammar-mirror.yml around lines 56 - 171, Add
explicit minimal GitHub Actions permissions for the sync workflow, setting
contents: read at the workflow or job level for sync-textmate, sync-highlightjs,
and sync-treesitter. Preserve the existing deploy-key authentication and
workflow behavior while ensuring these jobs do not rely on broader default
GITHUB_TOKEN permissions.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@typescript2/pkg-grammar-hljs/src/baml.js`:
- Around line 20-21: Extend the raw-string grammar registration in baml.js from
its current 1–3 hash levels to support 4–8 as well, preserving string
highlighting and embedded Jinja markup for every supported delimiter level.
- Around line 339-350: Update the INTERPOLATION_CONTAINS grammar list to include
RAW_STRINGS before QUOTED_STRING, ensuring raw strings inside interpolated
expressions consume internal braces and only the matching closing brace ends the
interpolation.

In `@typescript2/pkg-grammar-treesitter/grammar.js`:
- Around line 44-47: Update IDENT_REGEX to use the same optional-prefix
identifier expression as the Highlight.js mirror, allowing leading-$ identifiers
to contain hyphens and additional $-joined segments while still rejecting a
trailing $. Preserve the existing lexer-compatible handling for non-$-prefixed
words.

In `@typescript2/pkg-grammar-treesitter/package.json`:
- Line 9: Update the parse-fixtures script’s grep pattern to match only
tree-sitter’s actual ERROR or MISSING node markers, rather than those words
anywhere in the parse output. Preserve the existing failure counting, reporting,
and exit behavior.

In `@typescript2/pkg-grammar/baml.tmLanguage.json`:
- Around line 1643-1645: Update the grammar rule referenced by the
constructor-field-shorthand include so its begin pattern accepts all valid
$._expression starts, including identifiers, calls, namespace/type paths, nested
objects or lists, and lambdas, rather than only literal starts. Preserve the
existing property scope and constructor-field shorthand matching behavior.

In `@typescript2/pkg-grammar/tests/kde-syntax.test.ts`:
- Around line 272-294: Update the dynamic-context test in “marks contexts
entered by dynamic rules as dynamic” to iterate every context from
contextsByName directly, rather than only rules’ context= targets. For each
context, detect dynamic RegExpr rules and assert that the same context has
dynamic="true", covering contexts reached through lineEndContext,
lineEmptyContext, fallthroughContext, or not explicitly referenced.

---

Nitpick comments:
In @.github/workflows/sync-grammar-mirror.yml:
- Around line 56-171: Add explicit minimal GitHub Actions permissions for the
sync workflow, setting contents: read at the workflow or job level for
sync-textmate, sync-highlightjs, and sync-treesitter. Preserve the existing
deploy-key authentication and workflow behavior while ensuring these jobs do not
rely on broader default GITHUB_TOKEN permissions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 964ddb64-fb8e-438e-b53e-5863f3ebd403

📥 Commits

Reviewing files that changed from the base of the PR and between 124952b and 6efea55.

⛔ Files ignored due to path filters (1)
  • typescript2/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (50)
  • .github/workflows/ci.yaml
  • .github/workflows/sync-grammar-mirror.yml
  • typescript2/app-vscode-ext/syntaxes/baml.tmLanguage.json
  • typescript2/pkg-grammar-hljs/README.md
  • typescript2/pkg-grammar-hljs/mirror/README.md
  • typescript2/pkg-grammar-hljs/mirror/package.json
  • typescript2/pkg-grammar-hljs/mirror/publish.yml
  • typescript2/pkg-grammar-hljs/package.json
  • typescript2/pkg-grammar-hljs/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-hljs/src/baml.js
  • typescript2/pkg-grammar-hljs/tests/baml.test.ts
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__const_let_else_defer.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/baml_tests__retry_policy_valid_retry.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/generators.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/lsp_syntax_functions__jinja_control_prompt.baml.html
  • typescript2/pkg-grammar-hljs/tests/snapshots/ns_sentiment__sentiment.baml.html
  • typescript2/pkg-grammar-hljs/vitest.config.ts
  • typescript2/pkg-grammar-treesitter/.gitignore
  • typescript2/pkg-grammar-treesitter/README.md
  • typescript2/pkg-grammar-treesitter/grammar.js
  • typescript2/pkg-grammar-treesitter/mirror/README.md
  • typescript2/pkg-grammar-treesitter/package.json
  • typescript2/pkg-grammar-treesitter/queries/highlights.scm
  • typescript2/pkg-grammar-treesitter/queries/injections.scm
  • typescript2/pkg-grammar-treesitter/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar-treesitter/test/corpus/attributes.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/control_flow.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/declarations.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/expressions.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/patterns.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/strings.txt
  • typescript2/pkg-grammar-treesitter/test/corpus/types.txt
  • typescript2/pkg-grammar-treesitter/tree-sitter.json
  • typescript2/pkg-grammar/DISTRIBUTION.md
  • typescript2/pkg-grammar/README.md
  • typescript2/pkg-grammar/baml.sublime-syntax
  • typescript2/pkg-grammar/baml.tmLanguage.json
  • typescript2/pkg-grammar/mirror/README.md
  • typescript2/pkg-grammar/mirror/SUPPORT.md
  • typescript2/pkg-grammar/package.json
  • typescript2/pkg-grammar/scripts/assemble-mirror.mjs
  • typescript2/pkg-grammar/scripts/emit-sublime.ts
  • typescript2/pkg-grammar/src/baml.ts
  • typescript2/pkg-grammar/syntaxes/baml.xml
  • typescript2/pkg-grammar/tests/fixtures/showcase__golden_sample.baml
  • typescript2/pkg-grammar/tests/kde-syntax.test.ts
  • typescript2/pkg-grammar/tests/snapshots/lsp_semantic__test_block.baml.scope.txt
  • typescript2/pkg-grammar/tests/snapshots/showcase__golden_sample.baml.scope.txt
  • typescript2/pkg-grammar/tests/sublime-syntax.test.ts
  • typescript2/pnpm-workspace.yaml

Comment on lines +20 to +21
- raw strings #"..."# (1-3 hash levels) with Jinja {{ ... }} / {% ... %} /
{# ... #} template markup inside

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the target file and nearby context
git ls-files typescript2/pkg-grammar-hljs/src/baml.js
wc -l typescript2/pkg-grammar-hljs/src/baml.js
cat -n typescript2/pkg-grammar-hljs/src/baml.js | sed -n '1,260p'

# Look for raw-string handling in related grammar/highlighter files
rg -n "raw strings|rawString|MAX_RAW_STRING_HASHES|hash levels|Jinja" typescript2 -S

# Inspect the matching source locations if they exist
fd -a "baml.js|baml.*" typescript2

Repository: BoundaryML/baml

Length of output: 31760


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the other mirrors that define the supported raw-string delimiter count
cat -n typescript2/pkg-grammar/src/baml.ts | sed -n '360,410p'
cat -n typescript2/pkg-grammar-hljs/tests/baml.test.ts | sed -n '1,120p'
cat -n typescript2/pkg-grammar-treesitter/grammar.js | sed -n '60,90p'
cat -n typescript2/pkg-grammar-treesitter/grammar.js | sed -n '1170,1188p'
cat -n typescript2/pkg-grammar-treesitter/README.md | sed -n '65,85p'

Repository: BoundaryML/baml

Length of output: 11189


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check whether the hljs mirror has any tests covering 4+ hash raw strings
rg -n "#+\".*\"#+" typescript2/pkg-grammar-hljs/tests typescript2/pkg-grammar/tests -S
rg -n "MAX_RAW_STRING_HASHES|raw strings: nested hash levels|five hash delimiter" typescript2/pkg-grammar-hljs typescript2/pkg-grammar -S

Repository: BoundaryML/baml

Length of output: 3278


Mirror raw strings through 8 hash levels. baml.js only registers #"..."# to ###"..."###, so valid 4–8 hash prompt strings miss string and embedded Jinja highlighting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar-hljs/src/baml.js` around lines 20 - 21, Extend the
raw-string grammar registration in baml.js from its current 1–3 hash levels to
support 4–8 as well, preserving string highlighting and embedded Jinja markup
for every supported delimiter level.

Comment on lines +339 to +350
// Shared contents of an interpolated expression. The list includes
// NESTED_BRACES, and NESTED_BRACES reuses the list, so arbitrarily deep
// `{ ... }` nesting inside `${ ... }` is tracked and only the balancing `}`
// closes the interpolation.
const INTERPOLATION_CONTAINS = [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
QUOTED_STRING,
NUMBER,
ENV_VAR,
NESTED_BRACES
];

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant file first.
ast-grep outline typescript2/pkg-grammar-hljs/src/baml.js --view expanded

# Read the relevant section around the reported lines.
sed -n '280,390p' typescript2/pkg-grammar-hljs/src/baml.js

# Find raw-string and interpolation-related definitions/usages.
rg -n "RAW_STRINGS|QUOTED_STRING|SUBST|INTERPOLATION_CONTAINS|NESTED_BRACES|raw" typescript2/pkg-grammar-hljs/src/baml.js

Repository: BoundaryML/baml

Length of output: 3713


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '180,260p' typescript2/pkg-grammar-hljs/src/baml.js

Repository: BoundaryML/baml

Length of output: 2732


Recognize raw strings inside interpolation. INTERPOLATION_CONTAINS should include RAW_STRINGS before QUOTED_STRING; otherwise ${#"a " } b"#} can be parsed as a plain quoted string and close the interpolation at the internal }.

Proposed fix
  const INTERPOLATION_CONTAINS = [
    hljs.C_LINE_COMMENT_MODE,
    hljs.C_BLOCK_COMMENT_MODE,
+   ...RAW_STRINGS,
    QUOTED_STRING,
    NUMBER,
    ENV_VAR,
    NESTED_BRACES
  ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Shared contents of an interpolated expression. The list includes
// NESTED_BRACES, and NESTED_BRACES reuses the list, so arbitrarily deep
// `{ ... }` nesting inside `${ ... }` is tracked and only the balancing `}`
// closes the interpolation.
const INTERPOLATION_CONTAINS = [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
QUOTED_STRING,
NUMBER,
ENV_VAR,
NESTED_BRACES
];
// Shared contents of an interpolated expression. The list includes
// NESTED_BRACES, and NESTED_BRACES reuses the list, so arbitrarily deep
// `{ ... }` nesting inside `${ ... }` is tracked and only the balancing `}`
// closes the interpolation.
const INTERPOLATION_CONTAINS = [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
...RAW_STRINGS,
QUOTED_STRING,
NUMBER,
ENV_VAR,
NESTED_BRACES
];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar-hljs/src/baml.js` around lines 339 - 350, Update the
INTERPOLATION_CONTAINS grammar list to include RAW_STRINGS before QUOTED_STRING,
ensuring raw strings inside interpolated expressions consume internal braces and
only the matching closing brace ends the interpolation.

Comment on lines +44 to +47
// Matches the lexer's Word token: hyphens allowed inside, `$`-joined segments,
// or a `$`-prefixed word ($watch). A trailing `$` is rejected (see tokens.rs).
const IDENT_REGEX =
/(\$[a-zA-Z_][a-zA-Z0-9_]*)|([a-zA-Z_][a-zA-Z0-9_-]*(\$[a-zA-Z_][a-zA-Z0-9_-]*)*)/;

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Accept the full lexer form for $-prefixed identifiers.

The special leading-$ alternative rejects hyphens and additional $ segments, so valid identifiers such as $foo-bar or $foo$bar are split. Use the same optional-prefix expression as the Highlight.js mirror.

Proposed fix
 const IDENT_REGEX =
-  /(\$[a-zA-Z_][a-zA-Z0-9_]*)|([a-zA-Z_][a-zA-Z0-9_-]*(\$[a-zA-Z_][a-zA-Z0-9_-]*)*)/;
+  /\$?[a-zA-Z_][a-zA-Z0-9_-]*(?:\$[a-zA-Z_][a-zA-Z0-9_-]*)*/;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Matches the lexer's Word token: hyphens allowed inside, `$`-joined segments,
// or a `$`-prefixed word ($watch). A trailing `$` is rejected (see tokens.rs).
const IDENT_REGEX =
/(\$[a-zA-Z_][a-zA-Z0-9_]*)|([a-zA-Z_][a-zA-Z0-9_-]*(\$[a-zA-Z_][a-zA-Z0-9_-]*)*)/;
// Matches the lexer's Word token: hyphens allowed inside, `$`-joined segments,
// or a `$`-prefixed word ($watch). A trailing `$` is rejected (see tokens.rs).
const IDENT_REGEX =
/\$?[a-zA-Z_][a-zA-Z0-9_-]*(?:\$[a-zA-Z_][a-zA-Z0-9_-]*)*/;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar-treesitter/grammar.js` around lines 44 - 47, Update
IDENT_REGEX to use the same optional-prefix identifier expression as the
Highlight.js mirror, allowing leading-$ identifiers to contain hyphens and
additional $-joined segments while still rejecting a trailing $. Preserve the
existing lexer-compatible handling for non-$-prefixed words.

"scripts": {
"generate": "tree-sitter generate",
"test": "tree-sitter generate && tree-sitter test && pnpm run parse-fixtures",
"parse-fixtures": "sh -c 'fail=0; for f in ../pkg-grammar/tests/fixtures/*.baml; do n=$(tree-sitter parse \"$f\" | grep -cE \"ERROR|MISSING\"); if [ \"$n\" != 0 ]; then fail=1; echo \"FAIL($n) $f\"; fi; done; [ $fail = 0 ] && echo \"all fixtures parse clean\"; exit $fail' -",

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

grep pattern in parse-fixtures may produce false positives from string content.

grep -cE "ERROR|MISSING" matches any line containing those words anywhere in tree-sitter's S-expression output. If a BAML fixture contains "ERROR" or "MISSING" as string content, identifiers, or comments, the parse output will include them and the script will report a false failure. Anchor the pattern to tree-sitter's actual node markers instead.

🛡️ Proposed fix
-    "parse-fixtures": "sh -c 'fail=0; for f in ../pkg-grammar/tests/fixtures/*.baml; do n=$(tree-sitter parse \"$f\" | grep -cE \"ERROR|MISSING\"); if [ \"$n\" != 0 ]; then fail=1; echo \"FAIL($n) $f\"; fi; done; [ $fail = 0 ] && echo \"all fixtures parse clean\"; exit $fail' -",
+    "parse-fixtures": "sh -c 'fail=0; for f in ../pkg-grammar/tests/fixtures/*.baml; do n=$(tree-sitter parse \"$f\" | grep -cE \"\\(ERROR\\)|\\(MISSING\"); if [ \"$n\" != 0 ]; then fail=1; echo \"FAIL($n) $f\"; fi; done; [ $fail = 0 ] && echo \"all fixtures parse clean\"; exit $fail' -",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar-treesitter/package.json` at line 9, Update the
parse-fixtures script’s grep pattern to match only tree-sitter’s actual ERROR or
MISSING node markers, rather than those words anywhere in the parse output.
Preserve the existing failure counting, reporting, and exit behavior.

Comment on lines +1643 to +1645
{
"include": "#constructor-field-shorthand"
},

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether constructor-field shorthand supports non-literal values
# (identifiers, nested constructors, calls) in the compiler/tree-sitter grammar.
rg -n -i 'shorthand' -g '!node_modules'
fd grammar.js typescript2/pkg-grammar-treesitter --exec cat -n {} \; | rg -n -B3 -A15 'constructor_field'

Repository: BoundaryML/baml

Length of output: 153


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== matching files ==\n'
fd -a 'grammar.js|*.tmLanguage.json|*.ts|*.js|*.baml' . 2>/dev/null | sed -n '1,200p'

printf '\n== text search ==\n'
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  'constructor-field-shorthand|constructor-field|`#expression`|shorthand' .

printf '\n== tree-sitter grammar candidates ==\n'
fd -a 'grammar.js' . 2>/dev/null | sed -n '1,200p'

Repository: BoundaryML/baml

Length of output: 175


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== tracked files with relevant names ==\n'
git ls-files | rg '(^|/)(grammar\.js|.*tmLanguage\.json|.*\.(baml|ts|js|json))$' | sed -n '1,200p'

printf '\n== textual matches ==\n'
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  'constructor-field-shorthand|constructor-field|`#expression`|constructor_field|shorthand' .

printf '\n== possible corpus/tests ==\n'
git ls-files | rg 'corpus|test|spec|fixture|examples|playground|samples' | sed -n '1,200p'

Repository: BoundaryML/baml

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== grammar.js excerpt ==\n'
sed -n '850,920p' typescript2/pkg-grammar-treesitter/grammar.js

printf '\n== parser.rs excerpt ==\n'
sed -n '5340,5405p' baml_language/crates/baml_compiler_parser/src/parser.rs

printf '\n== corpus examples ==\n'
sed -n '180,240p' typescript2/pkg-grammar-treesitter/test/corpus/expressions.txt

Repository: BoundaryML/baml

Length of output: 6240


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n --hidden --glob 'typescript2/pkg-grammar-treesitter/test/corpus/*.txt' \
  -A4 -B4 'constructor_field_shorthand|constructor_field|object|constructor' \
  typescript2/pkg-grammar-treesitter/test/corpus

printf '\n== likely shorthand examples in BAML tests ==\n'
rg -n --hidden --glob 'baml_language/crates/baml_lsp2_actions_tests/test_files/**/*.baml' \
  '\{[^{}]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*\}' \
  baml_language/crates/baml_lsp2_actions_tests/test_files

Repository: BoundaryML/baml

Length of output: 32647


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '185,245p' typescript2/pkg-grammar-treesitter/test/corpus/expressions.txt

Repository: BoundaryML/baml

Length of output: 1605


Widen constructor-field-shorthand to match real expression starts.
constructor_field_shorthand accepts a full $._expression after the field name, but this begin rule only matches literal starts. Shorthand fields whose value starts with an identifier, call, namespace/type path, nested object/list, or lambda will miss variable.other.property.baml.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar/baml.tmLanguage.json` around lines 1643 - 1645,
Update the grammar rule referenced by the constructor-field-shorthand include so
its begin pattern accepts all valid $._expression starts, including identifiers,
calls, namespace/type paths, nested objects or lists, and lambdas, rather than
only literal starts. Preserve the existing property scope and constructor-field
shorthand matching behavior.

Comment on lines +272 to +294
it("marks contexts entered by dynamic rules as dynamic", () => {
const contextsByName = new Map(
find(language, "context").map((el) => [el.attributes.name, el]),
);

for (const contextsBlock of find(language, "contexts")) {
walk(contextsBlock, (el) => {
if (el.name === "context" || el.name === "contexts") return;
// A rule whose String captures a group and whose target context uses
// %N substitution must land in a dynamic="true" context.
const target = referencedContextName(el.attributes.context ?? "");
if (target === null) return;
const targetContext = contextsByName.get(target);
if (!targetContext) return;
const usesSubstitution = find(targetContext, "RegExpr").some(
(rule) => rule.attributes.dynamic === "true",
);
if (usesSubstitution && targetContext.attributes.dynamic !== "true") {
throw new Error(`context "${target}" has dynamic rules but is not dynamic="true"`);
}
});
}
});

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Dynamic-context check has incomplete coverage.

This only validates contexts that are the context= target of some other rule. Contexts reached only via lineEndContext/lineEmptyContext/fallthroughContext, or never explicitly referenced by a context= attribute at all, are skipped — so a context with an unmarked dynamic RegExpr rule could slip through undetected, defeating the test's stated purpose.

Iterate contexts directly instead:

♻️ Proposed fix
-  it("marks contexts entered by dynamic rules as dynamic", () => {
-    const contextsByName = new Map(
-      find(language, "context").map((el) => [el.attributes.name, el]),
-    );
-
-    for (const contextsBlock of find(language, "contexts")) {
-      walk(contextsBlock, (el) => {
-        if (el.name === "context" || el.name === "contexts") return;
-        // A rule whose String captures a group and whose target context uses
-        // %N substitution must land in a dynamic="true" context.
-        const target = referencedContextName(el.attributes.context ?? "");
-        if (target === null) return;
-        const targetContext = contextsByName.get(target);
-        if (!targetContext) return;
-        const usesSubstitution = find(targetContext, "RegExpr").some(
-          (rule) => rule.attributes.dynamic === "true",
-        );
-        if (usesSubstitution && targetContext.attributes.dynamic !== "true") {
-          throw new Error(`context "${target}" has dynamic rules but is not dynamic="true"`);
-        }
-      });
-    }
-  });
+  it("marks contexts entered by dynamic rules as dynamic", () => {
+    for (const context of find(language, "context")) {
+      const usesSubstitution = find(context, "RegExpr").some(
+        (rule) => rule.attributes.dynamic === "true",
+      );
+      expect(
+        !usesSubstitution || context.attributes.dynamic === "true",
+        `context "${context.attributes.name}" has dynamic rules but is not dynamic="true"`,
+      ).toBe(true);
+    }
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("marks contexts entered by dynamic rules as dynamic", () => {
const contextsByName = new Map(
find(language, "context").map((el) => [el.attributes.name, el]),
);
for (const contextsBlock of find(language, "contexts")) {
walk(contextsBlock, (el) => {
if (el.name === "context" || el.name === "contexts") return;
// A rule whose String captures a group and whose target context uses
// %N substitution must land in a dynamic="true" context.
const target = referencedContextName(el.attributes.context ?? "");
if (target === null) return;
const targetContext = contextsByName.get(target);
if (!targetContext) return;
const usesSubstitution = find(targetContext, "RegExpr").some(
(rule) => rule.attributes.dynamic === "true",
);
if (usesSubstitution && targetContext.attributes.dynamic !== "true") {
throw new Error(`context "${target}" has dynamic rules but is not dynamic="true"`);
}
});
}
});
it("marks contexts entered by dynamic rules as dynamic", () => {
for (const context of find(language, "context")) {
const usesSubstitution = find(context, "RegExpr").some(
(rule) => rule.attributes.dynamic === "true",
);
expect(
!usesSubstitution || context.attributes.dynamic === "true",
`context "${context.attributes.name}" has dynamic rules but is not dynamic="true"`,
).toBe(true);
}
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@typescript2/pkg-grammar/tests/kde-syntax.test.ts` around lines 272 - 294,
Update the dynamic-context test in “marks contexts entered by dynamic rules as
dynamic” to iterate every context from contextsByName directly, rather than only
rules’ context= targets. For each context, detect dynamic RegExpr rules and
assert that the same context has dynamic="true", covering contexts reached
through lineEndContext, lineEmptyContext, fallthroughContext, or not explicitly
referenced.

Merged via the queue into canary with commit 50301c7 Jul 13, 2026
54 checks passed
@hellovai
hellovai deleted the vbv/grammar-distribution branch July 13, 2026 05:00

This branch was previously deployed

3 inactive deployments
Preview – promptfiddle — 6efea552 Deployed Jul 13, 2026 by vercel[bot]
Preview – promptfiddle2 — 6efea552 Deployed Jul 13, 2026 by vercel[bot]
Preview – beps — 6efea552 Deployed Jul 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant