Skip to content

feat(build): bundle all tree-sitter grammars at build time - #43496

Closed
jpds wants to merge 5 commits into
anomalyco:devfrom
jpds:tree-sitter-grammar-bundling
Closed

jpds wants to merge 5 commits into
anomalyco:devfrom
jpds:tree-sitter-grammar-bundling

Conversation

@jpds

@jpds jpds commented Aug 19, 2026

Copy link
Copy Markdown

Issue for this PR

I guess somewhat related to the offline / air-gap features: #18492

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Takes the tree-sitter grammars and bundles them in at build time rather than calling out to the internet at runtime when a file is written. Also resolved an issue with a new grammar from unpkg.com not loading for some unknown reason, but worked fine once it had been bundled in by this mechanism.

Also changes the URLs from master to a fixed tag or latest Git commit hash for the nvim-treesitter repo for better reproducibility / change-control.

How did you verify your code works?

Deployed the Nix flake and verified the LLM writes to a file whilst the correct syntax highlighting is displayed.

Screenshots / recordings

If this is a UI change, please include a screenshot or recording.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

If you do not follow this template your PR will be automatically rejected.

@jpds
jpds force-pushed the tree-sitter-grammar-bundling branch from b5c6c83 to 0dc9bc7 Compare August 19, 2026 18:29
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

Solid approach overall: a single pinned manifest (sha256 for every asset), hash verification on both the Nix-provided and network-fetched paths, and a clean dev-vs-build split through the committed stub. Points to consider:

  • packages/opencode/script/build.ts (resolveGrammarAsset, ~L70) — When OPENTUI_BUNDLED_GRAMMARS_DIR is set but a file is missing, the code silently falls back to a network fetch. Inside a Nix sandbox (no network) this produces a confusing fetch failure far from the real cause. Why it matters: the whole point of the env var is hermetic builds. Suggestion: if the env var is set, treat it as authoritative — throw immediately naming the missing file instead of attempting fetch.

  • packages/opencode/script/build.ts (~L296-305) — Overwriting the tracked packages/tui/src/bundled-grammars.gen.ts and restoring it in a finally block means a SIGKILL/crash mid-release leaves Bun-only import ... with { type: "file" } syntax in a git-tracked file (and concurrent builds race on it). Suggestion: generate into a gitignored path (or temp file swapped in place) so the working tree is never mutated.

  • packages/opencode/script/bundled-grammars.json — Several grammars pair a wasm from one version with queries from another ref: python (wasm v0.23.6 vs highlights from v0.25.0), swift (wasm 0.7.1 vs highlights 0.7.3), diff (wasm v0.1.0 vs highlights v0.2.0). Tree-sitter queries referencing nodes renamed between versions fail at query-compile time and take down highlighting for that language. Suggestion: align each grammar's wasm and query refs to the same tag, or add a smoke test that compiles every query against its pinned wasm.

  • packages/tui/src/parsers-config.ts (bundledAsset) — Dev silently uses remote URLs while compiled binaries use embedded assets, so the two modes can render different highlighting (the manifest intentionally switched some query sources, e.g. python highlights moved off tree-sitter-python master). Suggestion: log once at startup which mode resolved, so user reports like "highlights look different in dev" are diagnosable.

  • packages/opencode/script/build.ts (~L88-105) — All ~80+ assets are fetched via unbounded Promise.all; release machines can hit GitHub raw rate limits (429), failing the whole build. Suggestion: cap concurrency (e.g. 8) with a tiny pool helper.

  • Nit: the language-prefix grouping logic now exists twice — lib.splitString "-" in nix/opencode.nix and languagePrefix() in bundled-grammars.ts. A future filename like "c-sharp-tree-sitter.wasm" would diverge silently. Suggestion: a CI test asserting the Nix grouping equals the TS grouping over the manifest.

No blocking issues found.

@jpds
jpds force-pushed the tree-sitter-grammar-bundling branch from 0dc9bc7 to 32a615b Compare August 24, 2026 15:11
@jpds

jpds commented Aug 24, 2026

Copy link
Copy Markdown
Author

These have been addressed, minus:

Several grammars pair a wasm from one version with queries from another ref: python (wasm v0.23.6 vs highlights from v0.25.0), swift (wasm 0.7.1 vs highlights 0.7.3), diff (wasm v0.1.0 vs highlights v0.2.0)

This I plan to do in a later PR.

Dev silently uses remote URLs while compiled binaries use embedded assets, so the two modes can render different highlighting (the manifest intentionally switched some query sources, e.g. python highlights moved off tree-sitter-python master). Suggestion: log once at startup which mode resolved, so user reports like "highlights look different in dev" are diagnosable.

This isn't a worthwhile thing to log / display to the user.

jpds added 5 commits September 5, 2026 12:21
The e2e grammar sweep caught three grammars whose pinned query files
reference node names missing from the pinned grammar wasm:

- diff: wasm 0.1.0 → 0.2.0 (query already pinned at 0.2.0)
- make: query nvim-treesitter@074aa442 → tree-sitter-make 1.1.1 (wasm 1.1.1)
- scala: query nvim-treesitter@074aa442 → tree-sitter-scala 0.24.0 (wasm 0.24.0)
@jpds
jpds force-pushed the tree-sitter-grammar-bundling branch from 32a615b to 655f774 Compare September 5, 2026 11:22
@github-actions

Copy link
Copy Markdown
Contributor

Automated PR Cleanup

Thank you for contributing to opencode.

Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions.

This PR was closed because it matched the following cleanup criteria:

  • The PR was created more than 1 month ago
  • The PR had fewer than 2 positive reactions
  • Positive reactions are counted as thumbs-up, heart, celebration, or rocket reactions on the PR

PRs created within the last month are not affected by this cleanup.

If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate.

Thanks again for taking the time to contribute.

@jpds

jpds commented Sep 20, 2026

Copy link
Copy Markdown
Author

@thdxr @rekram1-node Could you please assign this for review? Would be great if we weren't all calling out to GitHub (which doesn't have the greatest uptime record) for syntax highlighting.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants