You are an expert at producing elegant and robust OpenCode systems.
The user has a request regarding OpenCode configuration, plugins, agents, or tools.
I have retrieved relevant documentation and context based on the user's request:
Context for query: '
Evaluate and attempt to repair the opencode plugin at @plugin/nucleus-protocol.ts.txt
Rename it back to a typescript file and do everything nessecary to fix it.'
Source: opencode-docs/plugins.mdx
title: Plugins
description: Write your own plugins to extend OpenCode.
Plugins allow you to extend OpenCode by hooking into various events and customizing behavior. You can create plugins to add new features, integrate with external services, or modify OpenCode's default behavior.
Create a plugin
A plugin is a JavaScript/TypeScript module that exports one or more plugin
functions. Each function receives a context object and returns a hooks object.
Location
Plugins are loaded from:
.opencode/plugindirectory either in your project- Or, globally in
~/.config/opencode/plugin
Basic structure
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}
The plugin function receives:
project: The current project information.directory: The current working directory.worktree: The git worktree path.client: An opencode SDK client for interacting with the AI.$: Bun's shell API for executing commands.
TypeScript support
For TypeScript plugins, you can import types from the plugin package:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}
Events
Plugins can subscribe to events as seen below in the Examples section. Here is a list of the different events available.
Command Events
command.executed
File Events
file.editedfile.watcher.updated
Installation Events
installation.updated
LSP Events
lsp.client.diagnosticslsp.updated
Message Events
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Permission Events
permission.repliedpermission.updated
Server Events
server.connected
Session Events
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Todo Events
todo.updated
Tool Events
tool.execute.aftertool.execute.before
TUI Events
tui.prompt.appendtui.command.executetui.toast.show
Examples
Here are some examples of plugins you can use to extend opencode.
Send notifications
Send notifications when certain events occur:
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
// Send notification on session completion
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}
We are using osascript to run AppleScript on macOS. Here we are using it to send notifications.
.env protection
Prevent opencode from reading .env files:
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "read" && output.args.filePath.includes(".env")) {
throw new Error("Do not read .env files")
}
},
}
}
Custom tools
Plugins can also add custom tools to opencode:
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
return {
tool: {
mytool: tool({
description: "This is a custom tool",
args: {
foo: tool.schema.string(),
},
async execute(args, ctx) {
return `Hello ${args.foo}!`
},
}),
},
}
}
The tool helper creates a custom tool that opencode can call. It takes a Zod schema function and returns a tool definition with:
description: What the tool doesargs: Zod schema for the tool's argumentsexecute: Function that runs when the tool is called
Your custom tools will be available to opencode alongside built-in tools.
========================================
Source: opencode-docs/index.mdx
title: Intro
description: Get started with OpenCode.
import { Tabs, TabItem } from "@astrojs/starlight/components"
import config from "../../../config.mjs"
export const console = config.console
OpenCode is an AI coding agent built for the terminal.

Let's get started.
Prerequisites
To use OpenCode, you'll need:
A modern terminal emulator like:
API keys for the LLM providers you want to use.
Install
The easiest way to install OpenCode is through the install script.
curl -fsSL https://opencode.ai/install | bash
You can also install it with the following commands:
Using Node.js
<Tabs> <TabItem label="npm"> ```bash npm install -g opencode-ai ``` </TabItem> <TabItem label="Bun"> ```bash bun install -g opencode-ai ``` </TabItem> <TabItem label="pnpm"> ```bash pnpm install -g opencode-ai ``` </TabItem> <TabItem label="Yarn"> ```bash yarn global add opencode-ai ``` </TabItem>Using Homebrew on macOS and Linux
brew install opencodeUsing Paru on Arch Linux
paru -S opencode-bin
Windows
Using Chocolatey
choco install opencodeUsing Scoop
scoop bucket add extras scoop install extras/opencodeUsing NPM
npm install -g opencode-aiUsing Mise
mise use --pin -g ubi:sst/opencode
Support for installing OpenCode on Windows using Bun is currently in progress.
You can also grab the binary from the Releases.
Configure
With OpenCode you can use any LLM provider by configuring their API keys.
If you are new to using LLM providers, we recommend using OpenCode Zen.
It's a curated list of models that have been tested and verified by the OpenCode
team.
Run
opencode auth login, select opencode, and head to opencode.ai/auth.Sign in, add your billing details, and copy your API key.
Paste your API key.
$ opencode auth login ┌ Add credential │ ◇ Select provider │ opencode │ ● Create an api key at https://opencode.ai/auth │ ◆ Enter your API key │ _ └
Alternatively, you can select one of the other providers. Learn more.
Initialize
Now that you've configured a provider, you can navigate to a project that
you want to work on.
cd /path/to/project
And run OpenCode.
opencode
Next, initialize OpenCode for the project by running the following command.
/init
This will get OpenCode to analyze your project and create an AGENTS.md file in
the project root.
:::tip
You should commit your project's AGENTS.md file to Git.
:::
This helps OpenCode understand the project structure and the coding patterns
used.
Usage
You are now ready to use OpenCode to work on your project. Feel free to ask it
anything!
If you are new to using an AI coding agent, here are some examples that might
help.
Ask questions
You can ask OpenCode to explain the codebase to you.
:::tip
Use the @ key to fuzzy search for files in the project.
:::
How is authentication handled in @packages/functions/src/api/index.ts
This is helpful if there's a part of the codebase that you didn't work on.
Add features
You can ask OpenCode to add new features to your project. Though we first recommend asking it to create a plan.
Create a plan
OpenCode has a Plan mode that disables its ability to make changes and
instead suggest how it'll implement the feature.Switch to it using the Tab key. You'll see an indicator for this in the lower right corner.
<TAB>Now let's describe what we want it to do.
When a user deletes a note, we'd like to flag it as deleted in the database. Then create a screen that shows all the recently deleted notes. From this screen, the user can undelete a note or permanently delete it.You want to give OpenCode enough details to understand what you want. It helps
to talk to it like you are talking to a junior developer on your team.:::tip
Give OpenCode plenty of context and examples to help it understand what you
want.
:::Iterate on the plan
Once it gives you a plan, you can give it feedback or add more details.
We'd like to design this new screen using a design I've used before. [Image #1] Take a look at this image and use it as a reference.:::tip
Drag and drop images into the terminal to add them to the prompt.
:::OpenCode can scan any images you give it and add them to the prompt. You can
do this by dragging and dropping an image into the terminal.Build the feature
Once you feel comfortable with the plan, switch back to Build mode by
hitting the Tab key again.<TAB>And asking it to make the changes.
Sounds good! Go ahead and make the changes.
Make changes
For more straightforward changes, you can ask OpenCode to directly build it
without having to review the plan first.
We need to add authentication to the /settings route. Take a look at how this is
handled in the /notes route in @packages/functions/src/notes.ts and implement
the same logic in @packages/functions/src/settings.ts
You want to make sure you provide a good amount of detail so OpenCode makes the right
changes.
Undo changes
Let's say you ask OpenCode to make some changes.
Can you refactor the function in @packages/functions/src/api/index.ts?
But you realize that it is not what you wanted. You can undo the changes
using the /undo command.
/undo
OpenCode will now revert the changes you made and show your original message
again.
Can you refactor the function in @packages/functions/src/api/index.ts?
From here you can tweak the prompt and ask OpenCode to try again.
:::tip
You can run /undo multiple times to undo multiple changes.
:::
Or you can redo the changes using the /redo command.
/redo
Share
The conversations that you have with OpenCode can be shared with your
team.
/share
This will create a link to the current conversation and copy it to your clipboard.
:::note
Conversations are not shared by default.
:::
Here's an example conversation with OpenCode.
Customize
And that's it! You are now a pro at using OpenCode.
To make it your own, we recommend picking a theme, customizing the keybinds, configuring code formatters, creating custom commands, or playing around with the OpenCode config.
========================================
Source: opencode-docs/formatters.mdx
title: Formatters
description: OpenCode uses language specific formatters.
OpenCode automatically formats files after they are written or edited using language-specific formatters. This ensures that the code that is generated follows the code styles of your project.
Built-in
OpenCode comes with several built-in formatters for popular languages and frameworks. Below is a list of the formatters, supported file extensions, and commands or config options it needs.
| Formatter | Extensions | Requirements |
|---|---|---|
| gofmt | .go | gofmt command available |
| mix | .ex, .exs, .eex, .heex, .leex, .neex, .sface | mix command available |
| prettier | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and more | prettier dependency in package.json |
| biome | .js, .jsx, .ts, .tsx, .html, .css, .md, .json, .yaml, and more | biome.json(c) config file |
| zig | .zig, .zon | zig command available |
| clang-format | .c, .cpp, .h, .hpp, .ino, and more | .clang-format config file |
| ktlint | .kt, .kts | ktlint command available |
| ruff | .py, .pyi | ruff command available with config |
| uv | .py, .pyi | uv command available |
| rubocop | .rb, .rake, .gemspec, .ru | rubocop command available |
| standardrb | .rb, .rake, .gemspec, .ru | standardrb command available |
| htmlbeautifier | .erb, .html.erb | htmlbeautifier command available |
| air | .R | air command available |
So if your project has prettier in your package.json, OpenCode will automatically use it.
How it works
When OpenCode writes or edits a file, it:
- Checks the file extension against all enabled formatters.
- Runs the appropriate formatter command on the file.
- Applies the formatting changes automatically.
This process happens in the background, ensuring your code styles are maintained without any manual steps.
Configure
You can customize formatters through the formatter section in your OpenCode config.
{
"$schema": "https://opencode.ai/config.json",
"formatter": {}
}
Each formatter configuration supports the following:
| Property | Type | Description |
|---|---|---|
disabled |
boolean | Set this to true to disable the formatter |
command |
string[] | The command to run for formatting |
environment |
object | Environment variables to set when running the formatter |
extensions |
string[] | File extensions this formatter should handle |
Let's look at some examples.
Disabling formatters
To disable a specific formatter, set disabled to true:
{
"$schema": "https://opencode.ai/config.json",
"formatter": {
"prettier": {
"disabled": true
}
}
}
Custom formatters
You can override the built-in formatters or add new ones by specifying the command, environment variables, and file extensions:
{
"$schema": "https://opencode.ai/config.json",
"formatter": {
"prettier": {
"command": ["npx", "prettier", "--write", "$FILE"],
"environment": {
"NODE_ENV": "development"
},
"extensions": [".js", ".ts", ".jsx", ".tsx"]
},
"custom-markdown-formatter": {
"command": ["deno", "fmt", "$FILE"],
"extensions": [".md"]
}
}
}
The $FILE placeholder in the command will be replaced with the path to the file being formatted.
========================================
Source: agent/orchestrator.md
description: Meta-coordination agent. Decomposes goals, delegates to subagents, synthesizes results.
mode: primary
model: anthropic/claude-sonnet-4-20250514
temperature: 0.2
tools:
read: true
grep: true
glob: true
list: true
write: true
edit: true
bash: true
permission:
task:
"": allow
"orchestrator-": allow
Orchestrator Agent
You are the orchestrator. You coordinate work across specialized subagents.
Nucleus Protocol
Before proceeding with any goal, verify:
λ(goal). orchestrate ⟺ [
decomposable(goal) ∨ atomic(goal) // Can break down or is already atomic
∀ subtask. ∃ agent(capable) // Right agent exists for each part
∀ agent. context ⊇ required // Agents have what they need
∀ output. verifiable // Can check the work
rollback ∈ possible // Can recover from failure
]
ELSE:
decompose(goal) →
identify(capability_gaps) →
prepare(context) →
request(clarification | resources)
Delegation Protocol
When delegating to a subagent:
- Verify context sufficiency — Does the subagent have everything it needs?
- Define acceptance criteria — What does "done" look like?
- Establish rollback path — How do we recover if it fails?
- Instrument verification — How do we check the output?
Use @architect for planning and design decisions.
Use @implementer for code generation.
Use @reviewer for quality verification.
Use @researcher for information gathering.
Use @debugger for diagnosis and root cause analysis.
Anti-Patterns (NEVER DO)
- Delegating ambiguous tasks without clarification
- Proceeding without verification hooks
- Accepting unverified subagent outputs
- Losing track of parallel workstreams
- Committing irreversible changes without confirmation
When You Cannot Proceed
If nucleus conditions are not met, explicitly state:
NUCLEUS CHECK FAILED:
- Condition: [which condition failed]
- Missing: [what's needed]
- Request: [specific ask to resolve]
Do not apologize. Do not guess. Surface exactly what's needed.
========================================
Source: agent/assistant.md
description: Helpful agent that gives advice, technical explanation, and troubleshooting advice
mode: primary
You take the questioners query and provide advice to help fix their concerns and misunderstandings.
You look at recent changes and compare against against the upstream/dev branches implementations to find causes of problems if a first analysis proves ambiguous.
You do not make changes to the codebase other than to record the results of your
analysis in the folders .opencode directory at .opencode/assistant if it exists.
Create the directories if they don't exist.
========================================
User Request:
Evaluate and attempt to repair the opencode plugin at @plugin/nucleus-protocol.ts.txt
Rename it back to a typescript file and do everything nessecary to fix it.
Based on the documentation provided above, please help the user with their request.
If you are writing code (plugins, tools, config), ensure it follows the patterns seen in the documentation.