Repository navigation
[FEATURE]: Plugin hooks should be able to inject AI-visible messages into conversation context #17412
Description
Activity
github-actions commented on Mar 13, 2026
This issue might be a duplicate of existing issues. Please check:
- Ability to intercept or emulate agent messages in plugins #14451: Requests the same capability — injecting AI-visible messages from a plugin (intercepting/emulating agent messages in the conversation context)
(Note: #12472 and #16626 are already referenced in your issue.)
Paging interested parties
Tagging folks from related discussions who may find this relevant:
- @ArtyMcLabin — you opened Native Claude Code hooks compatibility (PreToolUse, PostToolUse, Stop) #12472 for native Claude Code hooks compat, this issue narrows the scope to the specific missing primitive: message injection into conversation context
- @yehudacohen — your
session.stoppingwork in feat: add session.stopping hook for plugins #16598 / [FEATURE]: add session.stopping plugin hook to allow re-entering the agent loop #16626 is the prerequisite for the Stop hook side of this. Theoutput.inject()+output.continue()API proposed here would build directly on top of that - @marcusquinn — you offered to validate the aidevops workflow against feat: add session.stopping hook for plugins #16598, the same
output.inject()pattern would cover your PostToolUse lint-on-edit use case - @ppiankov — your pastewatch MCP secret enforcement case is a perfect example:
tool.execute.beforecan block the tool today, but injecting a message like "use pastewatch_read_file instead" so the AI actually sees it requires this feature - @gl33mer @parkuman @nagy135 — you've been following the hooks discussion, this adds concrete benchmark data (96.7% vs 6.7%) showing the impact of missing message injection
The core argument: OpenCode's plugin system can already intercept tool calls, but skills that need ongoing behavioral enforcement (planning, linting, security) degrade severely because there's no way to inject reminders the AI actually sees. Compaction makes it worse — behavioral rules from initial skill loading are the first thing lost.
🐱 Gentle nudge to the team
/\_____/\
/ o o \
( == ^ == )
) (
( )
( ( ) ( ) )
(__(__)___(__)__)
"plz... can haz
output.inject()?"
Hey OpenCode team — would love to get some eyes on this from the core maintainers:
- @thdxr — you're assigned to Native Claude Code hooks compatibility (PreToolUse, PostToolUse, Stop) #12472 which covers the broader Claude Code hooks compat. This issue distills the single most impactful missing primitive: letting plugin hooks inject messages into the AI's conversation. The benchmark data (96.7% → ~6.7% without enforcement hooks) makes a strong case. Would love to hear if
output.inject()ontool.execute.afteris something that fits the plugin architecture direction. - @adamdotdevin @nexxeln @Hona — as core team members, curious if this aligns with the plugin system roadmap. The proposed API is minimal (one new method on the output object), but it would unlock an entire category of enforcement-based skills that currently only work on Claude Code.
- @jayair @fwang — you've both been active contributors. The
session.stoppingdraft PR (feat: add session.stopping hook for plugins #16598) by @yehudacohen already tackles half of this (the Stop hook side). The other half (PostToolUse message injection) is arguably simpler to implement. - @kujtimiihoxha — your work on the plugin system internals means you'd know best whether
output.inject()is feasible within the current hook execution pipeline.
This isn't just about one skill — it's about making OpenCode's skill ecosystem competitive for any workflow that needs the AI to stay on track beyond initial instructions. The data shows it's a 10x difference. 🙏
Seems like the core problem is already resolved by experimental.chat.messages.transform. However, I still found the DX and UX undesirable, so I opened a follow-up #29633.
github-actions commented on Jul 27, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
Feature hasn't been suggested before.
Describe the enhancement you want to request
Problem
OpenCode's plugin hooks (
tool.execute.before,tool.execute.after,session.idle) can intercept and modify tool calls, but they cannot inject messages into the AI's conversation context. This makes it impossible to build skills that require ongoing behavioral enforcement — the AI simply forgets after a few tool calls, and near-guaranteed forgets after compaction.Evidence: planning-with-files skill benchmark
The planning-with-files skill enforces a structured 3-file planning pattern (task_plan.md, findings.md, progress.md). On Claude Code, it uses
PreToolUse/PostToolUse/Stophooks to continuously remind the AI. The hooks inject messages the AI sees in conversation — not just intercept tool calls.Benchmark results (10 parallel subagents, 5 task types, 30 objectively verifiable assertions):
What happens on OpenCode today
We run this same skill on OpenCode. The SKILL.md loads, the AI starts strong, then:
We've tried mitigations: AGENTS.md rules,
agent.promptinjection for subagents, TodoWrite tracking. None survive compaction reliably.The gap
tool.execute.beforesession.idleis fire-and-forget)Proposed API
For
tool.execute.after— allow injecting a message the AI sees:For
session.stopping(per #16598) — allow continuation with injected message:Implementation
We've submitted a proof-of-concept PR that implements the
tool.execute.afterinjection side:The implementation is ~57 lines across 2 files:
injectfield to thetool.execute.afteroutput typeflushInjectedMessages()helper persists injected entries as synthetic user messages (same pattern as existing subtask summary messages)injectis optional, existing plugins are unaffectedWhy this matters
Skills are OpenCode's strongest differentiator. But any skill requiring behavioral enforcement beyond initial instructions (planning, linting, security guardrails, SOP compliance) degrades severely without message injection. The benchmark data shows a 96.7% → estimated ~30% drop — making an entire category of skills non-viable.
Related
session.stoppinglifecycle event (prerequisite for Stop hook)