Summary
Please add a plugin hook that fires when OpenCode is done using a main session or a task-created subagent session in the current process, so plugins can reliably flush completed conversation state. Plugins can currently listen for the generic event hook and observe session.idle, but session.idle represents a completed run becoming idle, not a finalization point.
Use case
Memory, audit, analytics, sandbox, and snapshot plugins may batch writes for cost or latency reasons. For example, a memory plugin may persist every N user turns during active use. With only per-run idle events, up to N-1 pending turns can be skipped if the user exits before the next threshold is reached.
This is more visible for subagent sessions created by the task tool, because many subagent sessions have only one user prompt and may never reach a multi-turn threshold. A finalization hook would let plugins keep their normal batching behavior during active use while still flushing pending state when a main session or subagent session will not receive more turns in the current process.
Why session.idle is not enough
session.idle is useful as a per-run completion signal: it fires when a session becomes idle after work completes. That is different from a finalization signal. A plugin can choose to flush on every idle event, but that can be expensive for plugins that intentionally batch writes.
The missing lifecycle point is a reliable final flush opportunity when the user exits OpenCode, when a task-created subagent session finishes and will not continue, or when the current process is otherwise done with a session.
Requested API
Add a session.finalizing hook that fires before OpenCode stops using a main session or task-created subagent session in the current process.
The hook should include sessionID, should cover both main sessions and subagent sessions created by the task tool, should run after completed messages can be read by a plugin, and should be awaited so async persistence can finish before OpenCode finishes that session lifecycle step.
Related issues and PRs
This is complementary to #16626 (session.stopping for loop re-entry), #28695 (broader session lifecycle hooks), #9272 (session.before.idle), and #23503/#23650 (session.turn.completed, closed after inactivity).
Summary
Please add a plugin hook that fires when OpenCode is done using a main session or a task-created subagent session in the current process, so plugins can reliably flush completed conversation state. Plugins can currently listen for the generic
eventhook and observesession.idle, butsession.idlerepresents a completed run becoming idle, not a finalization point.Use case
Memory, audit, analytics, sandbox, and snapshot plugins may batch writes for cost or latency reasons. For example, a memory plugin may persist every N user turns during active use. With only per-run idle events, up to N-1 pending turns can be skipped if the user exits before the next threshold is reached.
This is more visible for subagent sessions created by the task tool, because many subagent sessions have only one user prompt and may never reach a multi-turn threshold. A finalization hook would let plugins keep their normal batching behavior during active use while still flushing pending state when a main session or subagent session will not receive more turns in the current process.
Why
session.idleis not enoughsession.idleis useful as a per-run completion signal: it fires when a session becomes idle after work completes. That is different from a finalization signal. A plugin can choose to flush on every idle event, but that can be expensive for plugins that intentionally batch writes.The missing lifecycle point is a reliable final flush opportunity when the user exits OpenCode, when a task-created subagent session finishes and will not continue, or when the current process is otherwise done with a session.
Requested API
Add a
session.finalizinghook that fires before OpenCode stops using a main session or task-created subagent session in the current process.The hook should include
sessionID, should cover both main sessions and subagent sessions created by the task tool, should run after completed messages can be read by a plugin, and should be awaited so async persistence can finish before OpenCode finishes that session lifecycle step.Related issues and PRs
This is complementary to #16626 (
session.stoppingfor loop re-entry), #28695 (broader session lifecycle hooks), #9272 (session.before.idle), and #23503/#23650 (session.turn.completed, closed after inactivity).