Implements OpenCode lifecycle hooks that transform, process, and manage chat messages and attachments during the plugin's message pipeline. These hooks are invoked by OpenCode's experimental.chat.messages.transform API to modify message content before it reaches models or after responses are generated.
createApplyPatchHook(), createAutoUpdateCheckerHook()) that returns a hook function matching the OpenCode hook signature.src/hooks/hook-registry.ts). Hooks register handlers via registry.register(hookPoint, handler); src/index.ts dispatches through registry.dispatch() instead of calling each hook directly.src/hooks/session-lifecycle.ts) that owns cleanup callback registration and pending-session signaling channel with timestamp TTL. Stateful hooks register cleanup callbacks instead of implementing their own session.deleted handlers.createAutoUpdateCheckerHook guards with hasChecked; createTaskSessionManagerHook manages session lifecycle). Other hooks remain stateless - each factory decides based on its needs.MessageWithParts[] type, allowing transformation of user messages, assistant responses, and system messages.MessageInfo: Metadata about a message (role, agent, sessionID, id)MessagePart: Individual content part of a message (text, file, image, tool use, etc.)MessageWithParts: Complete message with metadata and array of partsprocessImageAttachments - Extracts image data URLs from messages, saves them to .opencode/images/ directory, and replaces image parts with text references containing file paths.createTaskSessionManagerHook that manage session state and lifecycle.createJsonErrorRecoveryHook that detect and recover from JSON parsing errors.createPhaseReminderHook that add contextual reminders to messages.createDelegateTaskRetryHook that handle task retry logic.1. OpenCode receives chat messages
2. Plugin's `experimental.chat.messages.transform` hook is invoked
3. Each registered hook receives the message array sequentially
4. Hooks transform messages (e.g., extract images, add metadata, validate structure)
5. Transformed messages are sent to the model
6. Model responses are transformed by hooks in reverse order
7. Final messages are returned to OpenCode
1. Hook receives messages with image parts (type='image' or type='file' with image/* mime)
2. For each user message with images:
a. Decode data URLs to binary data
b. Generate SHA1 hash of image data for unique identification
c. Save image to `.opencode/images/[sessionID]/` directory
d. Create unique filename with hash to prevent collisions
e. Replace image parts with text reference containing file paths
f. Add informational text about image attachment for model context
3. Cleanup old images older than 60 minutes (debounced every 10 minutes)
1. Plugin initializes (src/index.ts)
2. Hook factories are called, returning handler maps
3. Handlers are registered with HookRegistry via `hookRegistry.register(hookPoint, handler)`
4. `src/index.ts` dispatches via `hookRegistry.dispatch()` per hook point
5. OpenCode invokes hooks during message lifecycle
src/index.ts - registers hooks with OpenCode during plugin initializationexperimental.chat.messages.transform API callsMessageWithParts, MessageInfo, and hook signaturesdisabledAgents set to skip processing when required agents are unavailable.opencode/images/ within the project workspace