What happen
parseModeChange() in src/plugins/opencode/plugin.js deactivates on a bare /\bnormal mode\b/i test, so any prompt containing the phrase turns caveman off — vim's normal mode being the obvious collision. Natural-language activation in the same function has no isQuestion guard, so asking about caveman switches it on.
if (/\b(stop|disable|deactivate|turn off)\b.*\bcaveman\b/i.test(prompt) ||
/\bcaveman\b.*\b(stop|disable|deactivate|turn off)\b/i.test(prompt) ||
/\bnormal mode\b/i.test(prompt)) { // <- no anchor, no caveman context
return 'off';
}
This looks like a port gap rather than a fresh bug. src/hooks/caveman-mode-tracker.js guards both cases already — #598 anchored "normal mode" to a command position or caveman context (its comment calls out "how do I exit vim normal mode" by name) and added the isQuestion check. The opencode port never picked either up, so the two implementations disagree.
Expected
The opencode plugin should behave like the canonical tracker: "normal mode" counts only in command position or alongside "caveman", and questions are not commands.
Before/after example
Input: how do I exit vim normal mode?
Got: parseModeChange -> 'off' (caveman silently deactivated; user never mentioned caveman)
Want: parseModeChange -> null
Input: what is caveman mode?
Got: parseModeChange -> 'full' (caveman silently activated by a question)
Want: parseModeChange -> null
Verified side by side against the canonical hook on the same prompts — caveman-mode-tracker.js leaves the flag alone for both, the opencode port does not.
Platform
Version / install method
main @ 0d95a81, repo checkout.
Happy to send a PR porting the two guards from caveman-mode-tracker.js verbatim, with tests.
Found while auditing the repo for functional bugs; diagnosis and patch drafted with Claude Code, then verified by hand against a checkout (the outputs above are real runs of both implementations, not predictions).
What happen
parseModeChange()insrc/plugins/opencode/plugin.jsdeactivates on a bare/\bnormal mode\b/itest, so any prompt containing the phrase turns caveman off — vim's normal mode being the obvious collision. Natural-language activation in the same function has noisQuestionguard, so asking about caveman switches it on.This looks like a port gap rather than a fresh bug.
src/hooks/caveman-mode-tracker.jsguards both cases already — #598 anchored "normal mode" to a command position or caveman context (its comment calls out"how do I exit vim normal mode"by name) and added theisQuestioncheck. The opencode port never picked either up, so the two implementations disagree.Expected
The opencode plugin should behave like the canonical tracker: "normal mode" counts only in command position or alongside "caveman", and questions are not commands.
Before/after example
Verified side by side against the canonical hook on the same prompts —
caveman-mode-tracker.jsleaves the flag alone for both, the opencode port does not.Platform
Version / install method
main@0d95a81, repo checkout.Happy to send a PR porting the two guards from
caveman-mode-tracker.jsverbatim, with tests.Found while auditing the repo for functional bugs; diagnosis and patch drafted with Claude Code, then verified by hand against a checkout (the outputs above are real runs of both implementations, not predictions).