You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow the user to add/override parsers for a given file extension #29
changed the title [-]Allow the user to override parsers for a given file extension[/-][+]Allow the user to add/override parsers for a given file extension[/+]on Aug 19, 2026
Keys are normalized (lowercased, leading dot added), so "CXX" and ".cxx" are the same entry. Values must be a registered parser language (typescript, cpp, python, … plus text for the fallback parser) — unknown names produce a config warning listing the valid ones. Both new extensions and existing mappings can be remapped, exactly as in your example.
The mapping is resolved per call and never mutates the process-wide chunker registry, so it stays workspace-scoped and coexists safely with pluggable chunkers[].
opencode-rag init (now emits an empty chunking section, so the key is discoverable)
the dashboard API (PUT /api/config with a chunking section)
What it affects
The override is honored consistently on every extension-sensitive surface:
Indexing/chunking — getChunker() picks the target parser, and chunking.nodeTypes is looked up under the target language (so nodeTypes.cpp applies to a remapped .c file).
get_file_skeleton (plugin tool and MCP) — resolves to the target parser's grammar recipe.
Read-tool code fences — the language label comes from the override.
Embedding metadata header — the [type] label follows the override, so a remapped .c file is embedded as [cpp], matching the chunk's metadata.language.
Extensions named in chunking.parsers are implicitly added to the scan set — you don't need to repeat them in indexing.includeExtensions.
Note
Changing a mapping changes chunk boundaries for already-indexed files without touching their content hashes, so re-run opencode-rag index --force after editing.
Fixed in #29 — the feature itself landed in e35e8df; this change closes the remaining gaps where the mapping was silently ignored (TUI live edits, the embedding metadata label, the eval indexer, init, and the dashboard API) plus a bug where a no-op override (.tsx → typescript) degraded the skeleton recipe.
That covers both cases from your example: a new extension (.cu → C++) and an existing mapping being overridden (.c → C++).
Keys are file extensions, normalized (lowercased, leading dot added) — "CXX" and ".cxx" are the same entry.
Values are registered parser languages (typescript, cpp, python, … plus text for the fallback parser). Unknown names produce a config warning listing the valid ones.
The mapping is resolved per call and never mutates the process-wide chunker registry, so it stays workspace-scoped and coexists safely with pluggable chunkers[].
opencode-rag init — now emits an empty chunking section, so the key is discoverable in a generated config
the dashboard API (PUT /api/config with a chunking section)
What it affects
The override is honoured consistently on every extension-sensitive surface:
Surface
Effect
Indexing / chunking
getChunker() picks the target parser, and chunking.nodeTypes is looked up under the target language — so nodeTypes.cpp applies to a remapped .c file
get_file_skeleton (plugin tool + MCP)
resolves to the target parser's grammar recipe
Read-tool code fences
the language label comes from the override
Embedding metadata header
the [type] label follows the override, so a remapped .c file is embedded as [cpp] — matching its own chunk metadata
Scan set
extensions named in the map are implicitly added, so you don't need to repeat them in indexing.includeExtensions
One caveat
Changing a mapping changes chunk boundaries for already-indexed files without touching their content hashes — so re-run opencode-rag index --force after editing.
Released in v2.5.0 (on npm as opencode-rag-plugin@2.5.0).
The implementation landed in e35e8df; this release also closes the places where the mapping was still being ignored — the TUI's live edits, the embedding metadata label, the eval indexer, opencode-rag init, and the dashboard API — plus a bug where a no-op override (.tsx → typescript) degraded the skeleton recipe.
Activity
[-]Allow the user to override parsers for a given file extension[/-][+]Allow the user to add/override parsers for a given file extension[/+]MrDoe commentedon Aug 29, 2026
This can be useful. But right now I'm on vacation, so I'm planning to implement this in September.
fix(chunking): make chunking.parsers work on every surface (issue #29)
MrDoe commentedon Oct 20, 2026
Thanks for the suggestion — this is now implemented.
What landed
The extension → parser mapping is configurable via a new
chunking.parsersconfig section:{ "chunking": { "parsers": { ".c": "cpp", ".cu": "cpp" } } }Keys are normalized (lowercased, leading dot added), so
"CXX"and".cxx"are the same entry. Values must be a registered parser language (typescript,cpp,python, … plustextfor the fallback parser) — unknown names produce a config warning listing the valid ones. Both new extensions and existing mappings can be remapped, exactly as in your example.The mapping is resolved per call and never mutates the process-wide chunker registry, so it stays workspace-scoped and coexists safely with pluggable
chunkers[].Where to set it
opencode-rag.jsonopencode-rag init(now emits an emptychunkingsection, so the key is discoverable)PUT /api/configwith achunkingsection)What it affects
The override is honored consistently on every extension-sensitive surface:
getChunker()picks the target parser, andchunking.nodeTypesis looked up under the target language (sonodeTypes.cppapplies to a remapped.cfile).get_file_skeleton(plugin tool and MCP) — resolves to the target parser's grammar recipe.[type]label follows the override, so a remapped.cfile is embedded as[cpp], matching the chunk'smetadata.language.Extensions named in
chunking.parsersare implicitly added to the scan set — you don't need to repeat them inindexing.includeExtensions.Note
Changing a mapping changes chunk boundaries for already-indexed files without touching their content hashes, so re-run
opencode-rag index --forceafter editing.Fixed in #29 — the feature itself landed in
e35e8df; this change closes the remaining gaps where the mapping was silently ignored (TUI live edits, the embedding metadata label, the eval indexer,init, and the dashboard API) plus a bug where a no-op override (.tsx→typescript) degraded the skeleton recipe.MrDoe commentedon Oct 20, 2026
Shipped in v2.5.0
Thanks again for the suggestion — this is now implemented and released.
The config
The extension → parser mapping is configurable through a new
chunking.parserssection inopencode-rag.json:{ "chunking": { "parsers": { ".c": "cpp", ".cu": "cpp" } } }That covers both cases from your example: a new extension (
.cu→ C++) and an existing mapping being overridden (.c→ C++)."CXX"and".cxx"are the same entry.typescript,cpp,python, … plustextfor the fallback parser). Unknown names produce a config warning listing the valid ones.chunkers[].Where to set it
opencode-rag.jsonopencode-rag init— now emits an emptychunkingsection, so the key is discoverable in a generated configPUT /api/configwith achunkingsection)What it affects
The override is honoured consistently on every extension-sensitive surface:
getChunker()picks the target parser, andchunking.nodeTypesis looked up under the target language — sonodeTypes.cppapplies to a remapped.cfileget_file_skeleton(plugin tool + MCP)[type]label follows the override, so a remapped.cfile is embedded as[cpp]— matching its own chunk metadataindexing.includeExtensionsOne caveat
Changing a mapping changes chunk boundaries for already-indexed files without touching their content hashes — so re-run
opencode-rag index --forceafter editing.Released in v2.5.0 (on npm as
opencode-rag-plugin@2.5.0).The implementation landed in
e35e8df; this release also closes the places where the mapping was still being ignored — the TUI's live edits, the embedding metadata label, the eval indexer,opencode-rag init, and the dashboard API — plus a bug where a no-op override (.tsx→typescript) degraded the skeleton recipe.