AGENTS.md@packages/editors/vscode · git:20260608.0702a11 · 2026-06-08 · sha256 7dc4d6214e1b7e13
AGENTS.md@packages/editors/vscode git:20260608.0702a11A
Immutable. This exact content never changes and is served at /api/v1/blob/7dc4d6214e1b7e13.
# AGENTS.md for the `webjs` VSCode extension
The all-in-one editor extension for webjs, shipping to the **VS
Marketplace** and **Open VSX** (the latter is what Cursor, Antigravity,
Windsurf, and VSCodium pull from). It is phase 1 of the editor-plugin
epic (#381).
Framework-wide rules (workflow, JSDoc-in-`packages/`, no-build, commit
conventions, autonomous-mode behaviour) live in the framework root
[`../../AGENTS.md`](../../AGENTS.md) and apply here. Read that first.
This file only covers what is specific to the extension.
## What it contributes (all DECLARATIVE, in `package.json`)
1. **Template highlighting.** Three original TextMate injection grammars
(`syntaxes/webjs-{html,css,svg}.json`) open an embedded HTML / CSS /
SVG block inside `` html` `` / `` css` `` / `` svg` `` tagged
templates and scope `${...}` holes as TypeScript. Authored from
scratch (NOT copied from lit-html), so there is no Lit dependency and
no attribution burden.
2. **Language-service intelligence.** The bundled `@webjsdev/intellisense`
tsserver plugin, auto-registered via
`contributes.typescriptServerPlugins` (no `tsconfig.json` edit). Gives
webjs-aware go-to-definition, attribute completion from
`static properties`, and tag diagnostics.
3. **Snippets** (`snippets/webjs.json`) for the common recipes and
**commands** (`webjs.check` / `webjs.create` / `webjs.docs`, wired in
`src/extension.js`).
## The no-Lit-dependency invariant (the whole point of phase 1)
The extension must NOT depend on any Lit extension or grammar. Two
mechanisms keep it that way, and both are load-bearing:
- **Highlighting** uses our own grammars, never `vscode-lit-html`.
- **Intelligence** bundles `@webjsdev/intellisense`, which is standalone as
of Phase 3 (#386): it has its own template parser and no `ts-lit-plugin`
dependency, so the esbuilt bundle (`scripts/build.mjs`) is the whole
webjs language service with no Lit code at all.
`test/extension.test.mjs` asserts no `ts-lit-plugin` / `lit-html` string
appears in the manifest and that the built bundle neither requires nor
references `ts-lit-plugin`.
## Build + packaging (the monorepo gotcha)
VSCode resolves a contributed `typescriptServerPlugins` entry by NAME
from `<extension>/node_modules/<name>`, so the plugin must ship inside
the vsix under that exact path. But vsce's npm path runs
`npm list --production`, which from a workspace member resolves the
WHOLE monorepo (repo root + every sibling), ballooning the vsix to
~86 MB. So:
- `scripts/build.mjs` esbuilds the plugin into a single self-contained
CJS bundle at `node_modules/@webjsdev/intellisense/` (real files, no
further deps).
- `scripts/package.mjs` copies the publishable tree into a standalone
staging dir OUTSIDE the workspace, with a manifest whose only
dependency is the vendored plugin, then runs vsce there. Result: a
~13-file, ~100 KB vsix carrying only the extension and the one plugin.
Always package via `npm run package` (never bare `vsce package` from
this dir, or you get the 86 MB blowup). `npm run build` alone just
regenerates the vendored plugin (what the tests exercise).
## Not on npm
The extension ships to the VS Marketplace + Open VSX, NOT npm. It is
`private: true`. Do not add it to any npm publish flow.
It IS tracked in the unified changelog (#413): it is in
`scripts/backfill-changelog.js`'s `PACKAGES` list and a version bump
requires a `changelog/vscode/<version>.md` (the pre-commit gate enforces
it, exactly like an npm package). The entry carries `npm: false` in its
frontmatter, which is how the `publish-npm` / `publish-github-packages` /
`publish-release` scripts know to skip the registry while still rendering
it on the website `/changelog` feed.
## Module map
```
package.json The manifest. `contributes` is where the value lives.
src/extension.js CommonJS entry; wires the three commands only.
syntaxes/webjs-*.json TextMate injection grammars (html/css/svg).
snippets/webjs.json Recipe snippets.
scripts/build.mjs esbuild the vendored, Lit-free tsserver plugin.
scripts/package.mjs Stage outside the workspace + run vsce.
test/extension.test.mjs Dependency-free manifest + grammar + bundle checks.
icon.png Marketplace icon (the webjs brand mark).
PUBLISHING.md How to publish to both registries.
```
## Tests
`test/extension.test.mjs` is dependency-free (no vscode-textmate /
oniguruma): it validates the manifest as data, checks every contributed
file exists and is consistent, converts each grammar `begin` pattern to
a JS RegExp and asserts it matches the real `` tag` `` forms while
rejecting look-alikes (`` nothtml` ``), and runs `build.mjs` to prove
the vendored plugin is self-contained and Lit-free. Run from the repo
root via `npm test` (picked up under `packages/editors/vscode/test`).
Full per-feature behaviour of the tsserver plugin itself lives in
[`../intellisense/AGENTS.md`](../intellisense/AGENTS.md).
---
Framework-wide rules and full API reference:
@../../AGENTS.md