opencode 1.18 treats every export of a plugin module as a plugin
function. router-link.js exported a Map (), so the
loader rejected the entire module: chat.headers and tool.execute.after
never ran. The 29 node tests passed because they imported the module
directly, bypassing the loader.
- Move parentCache from a named export to a property on RouterLink
- Add loader-contract test: every module export must be a function
- Update test imports to use RouterLink.parentCache
Evidence: opencode.log at every start since 2026-09-26T08:02Z shows
"Plugin export is not a function" for router-link.js.