Skip to content

Instantly share code, notes, and snippets.

@nazt
Last active January 19, 2026 08:13
Show Gist options
  • Select an option

  • Save nazt/633735903bafc174e62ecea6d87e2ec9 to your computer and use it in GitHub Desktop.

Select an option

Save nazt/633735903bafc174e62ecea6d87e2ec9 to your computer and use it in GitHub Desktop.
OpenCode Plugin: Prepend prefix to all user messages (experimental.chat.messages.transform)
// OpenCode Plugin: Prepend prefix to all user messages
//
// DISCOVERY: Message structure uses msg.info.role, NOT msg.role!
// Structure: { info: { role: "user" }, parts: [{ type: "text", text: "..." }] }
//
// INSTALLATION:
// 1. Save this file to: ~/.config/opencode/plugins/prefix.ts (global)
// OR: .opencode/plugins/prefix.ts (project-level)
// 2. Restart OpenCode
// 3. Test by asking: "What are the first 5 characters of this message?"
//
// The AI should see your messages prefixed with "opencode-cli: " (or whatever PREFIX you set)
//
// Hook: experimental.chat.messages.transform
// This hook fires RIGHT BEFORE messages are sent to the LLM
//
// Author: Soul-Brews-Studio
// Date: 2026-01-19
// Gist: https://gist.github.com/nazt/633735903bafc174e62ecea6d87e2ec9
export const PrefixPlugin = () => ({
"experimental.chat.messages.transform": (_input: any, output: any) => {
const PREFIX = "opencode-cli:" // Change this to whatever prefix you want
if (output?.messages && Array.isArray(output.messages)) {
for (const msg of output.messages) {
// IMPORTANT: Role is in msg.info.role, not msg.role!
const role = msg.info?.role || msg.role
if (role === "user" && msg.parts && Array.isArray(msg.parts)) {
for (const part of msg.parts) {
if (part.type === "text" && part.text && !part.text.startsWith(PREFIX)) {
part.text = `${PREFIX} ${part.text}`
}
}
}
}
}
},
})
export default PrefixPlugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment