anthropics / anthropics/claude-code

[BUG] Plugin manifest experimental.syntaxHighlighting.hljsLanguages validates but never registers a grammar

Abierto
#93,944 1 comentario 0 reacciones 0 asignados Ver en GitHub
area:plugins bug platform:macos
Lenguaje dominante
Python
Estrellas
145k
Forks
23.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

### Preflight Checklist

- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code

### What's Wrong?

A plugin manifest can declare `experimental.syntaxHighlighting.hljsLanguages` to register a custom highlight.js grammar. `claude plugin validate` accepts it with no warning — but at runtime nothing happens at all: the grammar is never fetched, no language is registered, and no error is raised anywhere.

The 2.1.270 bundle clearly contains the machinery:

- the manifest schema — an array (max 16) of `{ id, remote, integrity }`, where `id` matches `^[a-z][a-z0-9_-]*$`, `remote` matches `npm:[@ver]` or `github:/@#.js`, and `integrity` is an SRI hash; the object is `.strict()`;
- a registry — `addPluginLanguage`, `registerResolvedPluginLanguage`, `clearPluginLanguages`, `isReservedLanguageId`, `isPluginLanguageId`;
- a telemetry event `plugin_hljs_languages` with a `resolve_failed` outcome;
- the error string ``plugin hljs grammar '${id}' failed to resolve at registration: ${reason}``;
- extension resolution that already consults plugin languages: the file extension is lowercased, checked against the built-in maps, then against `isPluginLanguageId(ext)`.

So the feature appears to be shipped on the schema and registry side, but nothing connects the manifest to the registry at session start.

### What Should Happen?

Either the declared language registers and `.gd` diffs / ```gd fences get highlighted, or a diagnostic is shown explaining why it was refused. Silently accepting a manifest and doing nothing gives the plugin author no way to tell the difference between "not supported yet" and "my manifest is wrong".

### Error Messages/Logs

```shell
# A full session started with --debug-file. The plugin loads:

[DEBUG] Loaded 4 installed plugins from ~/.claude/plugins/installed_plugins.json
[DEBUG] Found 1 enabled plugins with scopes: gdscript-highlight@gdscript-local(user)
[DEBUG] Loading plugin gdscript-highlight from source: "./gdscript-highlight"
[DEBUG] Total plugin workflows loaded: 0
[DEBUG] Total plugin commands loaded: 0
[DEBUG] Total plugin agents loaded: 0
[DEBUG] Total plugin skills loaded: 0
[DEBUG] Registered 0 hooks from 1 plugins
[DEBUG] Loaded plugins - Enabled: 1, Disabled: 3, Commands: 0, Agents: 0, Errors: 0

# grep over the whole 300-line debug log:
# hljs 0
# grammar 0
# syntaxHighlighting 0
# experimental 0
#
# and no [ERROR] line about a grammar — while unrelated [ERROR] lines from the
# same run (a failing MCP server, a lock acquisition) do land in the same file.
```

### Steps to Reproduce

1. Create a plugin with this manifest:

```json
{
"name": "gdscript-highlight",
"version": "0.1.0",
"description": "GDScript syntax highlighting",
"author": { "name": "..." },
"experimental": {
"syntaxHighlighting": {
"hljsLanguages": [
{
"id": "gd",
"remote": "github:Repiteo/highlightjs-gdscript@cc1d048b6c3127c1badf233daf411f8fe9914b0b#src/languages/gdscript.js",
"integrity": "sha256-5eI3NzW6c7bciH+BpEEMuV4ooUj58R8N1BlwTIjBZvc="
}
]
}
}
}
```

2. `claude plugin validate ` → `✔ Validation passed`, no warning.
3. Start a session, open a `.gd` diff or render a ```gd fenced block → no highlighting.
4. Check every plausible cache — `~/.claude`, `~/Library/Caches`, `~/.cache`, `~/.local/share/claude`, `/tmp`, `$TMPDIR` → the grammar was never downloaded.

Tried both plugin load paths, with identical results:

- a skills-directory plugin (`gdscript-highlight@skills-dir`, discovered in place);
- a plugin installed from a local marketplace via `claude plugin install`, copied into `~/.claude/plugins/cache/gdscript-local/gdscript-highlight/0.1.0/` (verified the `experimental` block survives the copy).

Tried both remote forms in a single manifest — one entry `github:`, one `npm:@exercism/highlightjs-gdscript@0.0.1`. Neither is fetched, so this is not a URL-parsing problem in one of the two forms.

The remote itself is fine: the URL returns HTTP 200, the file's sha256 matches the declared `integrity`, and it is a plain `export default function (hljs) { … }` module — the shape `e.default ?? e` expects.

`gd` and `gdscript` are not reserved ids: the string `gdscript` does not occur anywhere in the 2.1.270 bundle.

### Claude Model

Opus

### Is this a regression?

No, this never worked

### Last Working Version

N/A

### Claude Code Version

2.1.270

### Platform

Claude subscription

### Operating System

macOS

### Terminal/Shell

iTerm2 / zsh

### Additional Information

The field is undocumented: the public plugins reference describes `experimental` as exactly `themes`, `monitors`, `evals`, and neither the repository CHANGELOG nor the docs changelog mentions `syntaxHighlighting` or `hljsLanguages`. If the mechanism is simply not wired up yet, that is a perfectly good answer — but the validator accepting the block makes it look supported.

Two questions that would help plugin authors either way:

1. Is `experimental.syntaxHighlighting.hljsLanguages` expected to work in 2.1.270, or is the loader side not connected yet / behind a rollout flag?
2. If a plugin is not the intended route for adding a language, could GDScript be added to the bundled highlight.js languages? `.gd` has no entry in the extension-to-language table at all, which is the root of #48181 — open since April.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.