docs: document the plural forms

pull/9120/head
Aiden Cline 2026-01-17 13:09:27 -06:00
parent 5a199b04cb
commit 58f7da6e9f
8 changed files with 57 additions and 53 deletions

View File

@ -157,10 +157,10 @@ Configure agents in your `opencode.json` config file:
You can also define agents using markdown files. Place them in: You can also define agents using markdown files. Place them in:
- Global: `~/.config/opencode/agent/` - Global: `~/.config/opencode/agents/`
- Per-project: `.opencode/agent/` - Per-project: `.opencode/agents/`
```markdown title="~/.config/opencode/agent/review.md" ```markdown title="~/.config/opencode/agents/review.md"
--- ---
description: Reviews code for quality and best practices description: Reviews code for quality and best practices
mode: subagent mode: subagent
@ -419,7 +419,7 @@ You can override these permissions per agent.
You can also set permissions in Markdown agents. You can also set permissions in Markdown agents.
```markdown title="~/.config/opencode/agent/review.md" ```markdown title="~/.config/opencode/agents/review.md"
--- ---
description: Code review without edits description: Code review without edits
mode: subagent mode: subagent
@ -637,7 +637,7 @@ Do you have an agent you'd like to share? [Submit a PR](https://github.com/anoma
### Documentation agent ### Documentation agent
```markdown title="~/.config/opencode/agent/docs-writer.md" ```markdown title="~/.config/opencode/agents/docs-writer.md"
--- ---
description: Writes and maintains project documentation description: Writes and maintains project documentation
mode: subagent mode: subagent
@ -659,7 +659,7 @@ Focus on:
### Security auditor ### Security auditor
```markdown title="~/.config/opencode/agent/security-auditor.md" ```markdown title="~/.config/opencode/agents/security-auditor.md"
--- ---
description: Performs security audits and identifies vulnerabilities description: Performs security audits and identifies vulnerabilities
mode: subagent mode: subagent

View File

@ -15,11 +15,11 @@ Custom commands are in addition to the built-in commands like `/init`, `/undo`,
## Create command files ## Create command files
Create markdown files in the `command/` directory to define custom commands. Create markdown files in the `commands/` directory to define custom commands.
Create `.opencode/command/test.md`: Create `.opencode/commands/test.md`:
```md title=".opencode/command/test.md" ```md title=".opencode/commands/test.md"
--- ---
description: Run tests with coverage description: Run tests with coverage
agent: build agent: build
@ -42,7 +42,7 @@ Use the command by typing `/` followed by the command name.
## Configure ## Configure
You can add custom commands through the OpenCode config or by creating markdown files in the `command/` directory. You can add custom commands through the OpenCode config or by creating markdown files in the `commands/` directory.
--- ---
@ -79,10 +79,10 @@ Now you can run this command in the TUI:
You can also define commands using markdown files. Place them in: You can also define commands using markdown files. Place them in:
- Global: `~/.config/opencode/command/` - Global: `~/.config/opencode/commands/`
- Per-project: `.opencode/command/` - Per-project: `.opencode/commands/`
```markdown title="~/.config/opencode/command/test.md" ```markdown title="~/.config/opencode/commands/test.md"
--- ---
description: Run tests with coverage description: Run tests with coverage
agent: build agent: build
@ -112,7 +112,7 @@ The prompts for the custom commands support several special placeholders and syn
Pass arguments to commands using the `$ARGUMENTS` placeholder. Pass arguments to commands using the `$ARGUMENTS` placeholder.
```md title=".opencode/command/component.md" ```md title=".opencode/commands/component.md"
--- ---
description: Create a new component description: Create a new component
--- ---
@ -138,7 +138,7 @@ You can also access individual arguments using positional parameters:
For example: For example:
```md title=".opencode/command/create-file.md" ```md title=".opencode/commands/create-file.md"
--- ---
description: Create a new file with content description: Create a new file with content
--- ---
@ -167,7 +167,7 @@ Use _!`command`_ to inject [bash command](/docs/tui#bash-commands) output into y
For example, to create a custom command that analyzes test coverage: For example, to create a custom command that analyzes test coverage:
```md title=".opencode/command/analyze-coverage.md" ```md title=".opencode/commands/analyze-coverage.md"
--- ---
description: Analyze test coverage description: Analyze test coverage
--- ---
@ -180,7 +180,7 @@ Based on these results, suggest improvements to increase coverage.
Or to review recent changes: Or to review recent changes:
```md title=".opencode/command/review-changes.md" ```md title=".opencode/commands/review-changes.md"
--- ---
description: Review recent changes description: Review recent changes
--- ---
@ -199,7 +199,7 @@ Commands run in your project's root directory and their output becomes part of t
Include files in your command using `@` followed by the filename. Include files in your command using `@` followed by the filename.
```md title=".opencode/command/review-component.md" ```md title=".opencode/commands/review-component.md"
--- ---
description: Review component description: Review component
--- ---

View File

@ -51,6 +51,10 @@ Config sources are loaded in this order (later sources override earlier ones):
This means project configs can override global defaults, and global configs can override remote organizational defaults. This means project configs can override global defaults, and global configs can override remote organizational defaults.
:::note
The `.opencode` and `~/.config/opencode` directories use **plural names** for subdirectories: `agents/`, `commands/`, `modes/`, `plugins/`, `skills/`, `tools/`, and `themes/`. Singular names (e.g., `agent/`) are also supported for backwards compatibility.
:::
--- ---
### Remote ### Remote
@ -330,7 +334,7 @@ You can configure specialized agents for specific tasks through the `agent` opti
} }
``` ```
You can also define agents using markdown files in `~/.config/opencode/agent/` or `.opencode/agent/`. [Learn more here](/docs/agents). You can also define agents using markdown files in `~/.config/opencode/agents/` or `.opencode/agents/`. [Learn more here](/docs/agents).
--- ---
@ -394,7 +398,7 @@ You can configure custom commands for repetitive tasks through the `command` opt
} }
``` ```
You can also define commands using markdown files in `~/.config/opencode/command/` or `.opencode/command/`. [Learn more here](/docs/commands). You can also define commands using markdown files in `~/.config/opencode/commands/` or `.opencode/commands/`. [Learn more here](/docs/commands).
--- ---
@ -530,7 +534,7 @@ You can configure MCP servers you want to use through the `mcp` option.
[Plugins](/docs/plugins) extend OpenCode with custom tools, hooks, and integrations. [Plugins](/docs/plugins) extend OpenCode with custom tools, hooks, and integrations.
Place plugin files in `.opencode/plugin/` or `~/.config/opencode/plugin/`. You can also load plugins from npm through the `plugin` option. Place plugin files in `.opencode/plugins/` or `~/.config/opencode/plugins/`. You can also load plugins from npm through the `plugin` option.
```json title="opencode.json" ```json title="opencode.json"
{ {

View File

@ -17,8 +17,8 @@ Tools are defined as **TypeScript** or **JavaScript** files. However, the tool d
They can be defined: They can be defined:
- Locally by placing them in the `.opencode/tool/` directory of your project. - Locally by placing them in the `.opencode/tools/` directory of your project.
- Or globally, by placing them in `~/.config/opencode/tool/`. - Or globally, by placing them in `~/.config/opencode/tools/`.
--- ---
@ -26,7 +26,7 @@ They can be defined:
The easiest way to create tools is using the `tool()` helper which provides type-safety and validation. The easiest way to create tools is using the `tool()` helper which provides type-safety and validation.
```ts title=".opencode/tool/database.ts" {1} ```ts title=".opencode/tools/database.ts" {1}
import { tool } from "@opencode-ai/plugin" import { tool } from "@opencode-ai/plugin"
export default tool({ export default tool({
@ -49,7 +49,7 @@ The **filename** becomes the **tool name**. The above creates a `database` tool.
You can also export multiple tools from a single file. Each export becomes **a separate tool** with the name **`<filename>_<exportname>`**: You can also export multiple tools from a single file. Each export becomes **a separate tool** with the name **`<filename>_<exportname>`**:
```ts title=".opencode/tool/math.ts" ```ts title=".opencode/tools/math.ts"
import { tool } from "@opencode-ai/plugin" import { tool } from "@opencode-ai/plugin"
export const add = tool({ export const add = tool({
@ -112,7 +112,7 @@ export default {
Tools receive context about the current session: Tools receive context about the current session:
```ts title=".opencode/tool/project.ts" {8} ```ts title=".opencode/tools/project.ts" {8}
import { tool } from "@opencode-ai/plugin" import { tool } from "@opencode-ai/plugin"
export default tool({ export default tool({
@ -136,7 +136,7 @@ You can write your tools in any language you want. Here's an example that adds t
First, create the tool as a Python script: First, create the tool as a Python script:
```python title=".opencode/tool/add.py" ```python title=".opencode/tools/add.py"
import sys import sys
a = int(sys.argv[1]) a = int(sys.argv[1])
@ -146,7 +146,7 @@ print(a + b)
Then create the tool definition that invokes it: Then create the tool definition that invokes it:
```ts title=".opencode/tool/python-add.ts" {10} ```ts title=".opencode/tools/python-add.ts" {10}
import { tool } from "@opencode-ai/plugin" import { tool } from "@opencode-ai/plugin"
export default tool({ export default tool({
@ -156,7 +156,7 @@ export default tool({
b: tool.schema.number().describe("Second number"), b: tool.schema.number().describe("Second number"),
}, },
async execute(args) { async execute(args) {
const result = await Bun.$`python3 .opencode/tool/add.py ${args.a} ${args.b}`.text() const result = await Bun.$`python3 .opencode/tools/add.py ${args.a} ${args.b}`.text()
return result.trim() return result.trim()
}, },
}) })

View File

@ -87,10 +87,10 @@ Configure modes in your `opencode.json` config file:
You can also define modes using markdown files. Place them in: You can also define modes using markdown files. Place them in:
- Global: `~/.config/opencode/mode/` - Global: `~/.config/opencode/modes/`
- Project: `.opencode/mode/` - Project: `.opencode/modes/`
```markdown title="~/.config/opencode/mode/review.md" ```markdown title="~/.config/opencode/modes/review.md"
--- ---
model: anthropic/claude-sonnet-4-20250514 model: anthropic/claude-sonnet-4-20250514
temperature: 0.1 temperature: 0.1
@ -268,9 +268,9 @@ You can create your own custom modes by adding them to the configuration. Here a
### Using markdown files ### Using markdown files
Create mode files in `.opencode/mode/` for project-specific modes or `~/.config/opencode/mode/` for global modes: Create mode files in `.opencode/modes/` for project-specific modes or `~/.config/opencode/modes/` for global modes:
```markdown title=".opencode/mode/debug.md" ```markdown title=".opencode/modes/debug.md"
--- ---
temperature: 0.1 temperature: 0.1
tools: tools:
@ -294,7 +294,7 @@ Focus on:
Do not make any changes to files. Only investigate and report. Do not make any changes to files. Only investigate and report.
``` ```
```markdown title="~/.config/opencode/mode/refactor.md" ```markdown title="~/.config/opencode/modes/refactor.md"
--- ---
model: anthropic/claude-sonnet-4-20250514 model: anthropic/claude-sonnet-4-20250514
temperature: 0.2 temperature: 0.2

View File

@ -174,7 +174,7 @@ Refer to the [Granular Rules (Object Syntax)](#granular-rules-object-syntax) sec
You can also configure agent permissions in Markdown: You can also configure agent permissions in Markdown:
```markdown title="~/.config/opencode/agent/review.md" ```markdown title="~/.config/opencode/agents/review.md"
--- ---
description: Code review without edits description: Code review without edits
mode: subagent mode: subagent

View File

@ -19,8 +19,8 @@ There are two ways to load plugins.
Place JavaScript or TypeScript files in the plugin directory. Place JavaScript or TypeScript files in the plugin directory.
- `.opencode/plugin/` - Project-level plugins - `.opencode/plugins/` - Project-level plugins
- `~/.config/opencode/plugin/` - Global plugins - `~/.config/opencode/plugins/` - Global plugins
Files in these directories are automatically loaded at startup. Files in these directories are automatically loaded at startup.
@ -57,8 +57,8 @@ Plugins are loaded from all sources and all hooks run in sequence. The load orde
1. Global config (`~/.config/opencode/opencode.json`) 1. Global config (`~/.config/opencode/opencode.json`)
2. Project config (`opencode.json`) 2. Project config (`opencode.json`)
3. Global plugin directory (`~/.config/opencode/plugin/`) 3. Global plugin directory (`~/.config/opencode/plugins/`)
4. Project plugin directory (`.opencode/plugin/`) 4. Project plugin directory (`.opencode/plugins/`)
Duplicate npm packages with the same name and version are loaded once. However, a local plugin and an npm plugin with similar names are both loaded separately. Duplicate npm packages with the same name and version are loaded once. However, a local plugin and an npm plugin with similar names are both loaded separately.
@ -85,7 +85,7 @@ Local plugins and custom tools can use external npm packages. Add a `package.jso
OpenCode runs `bun install` at startup to install these. Your plugins and tools can then import them. OpenCode runs `bun install` at startup to install these. Your plugins and tools can then import them.
```ts title=".opencode/plugin/my-plugin.ts" ```ts title=".opencode/plugins/my-plugin.ts"
import { escape } from "shescape" import { escape } from "shescape"
export const MyPlugin = async (ctx) => { export const MyPlugin = async (ctx) => {
@ -103,7 +103,7 @@ export const MyPlugin = async (ctx) => {
### Basic structure ### Basic structure
```js title=".opencode/plugin/example.js" ```js title=".opencode/plugins/example.js"
export const MyPlugin = async ({ project, client, $, directory, worktree }) => { export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!") console.log("Plugin initialized!")
@ -215,7 +215,7 @@ Here are some examples of plugins you can use to extend opencode.
Send notifications when certain events occur: Send notifications when certain events occur:
```js title=".opencode/plugin/notification.js" ```js title=".opencode/plugins/notification.js"
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => { export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return { return {
event: async ({ event }) => { event: async ({ event }) => {
@ -240,7 +240,7 @@ If youre using the OpenCode desktop app, it can send system notifications aut
Prevent opencode from reading `.env` files: Prevent opencode from reading `.env` files:
```javascript title=".opencode/plugin/env-protection.js" ```javascript title=".opencode/plugins/env-protection.js"
export const EnvProtection = async ({ project, client, $, directory, worktree }) => { export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return { return {
"tool.execute.before": async (input, output) => { "tool.execute.before": async (input, output) => {
@ -258,7 +258,7 @@ export const EnvProtection = async ({ project, client, $, directory, worktree })
Plugins can also add custom tools to opencode: Plugins can also add custom tools to opencode:
```ts title=".opencode/plugin/custom-tools.ts" ```ts title=".opencode/plugins/custom-tools.ts"
import { type Plugin, tool } from "@opencode-ai/plugin" import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => { export const CustomToolsPlugin: Plugin = async (ctx) => {
@ -292,7 +292,7 @@ Your custom tools will be available to opencode alongside built-in tools.
Use `client.app.log()` instead of `console.log` for structured logging: Use `client.app.log()` instead of `console.log` for structured logging:
```ts title=".opencode/plugin/my-plugin.ts" ```ts title=".opencode/plugins/my-plugin.ts"
export const MyPlugin = async ({ client }) => { export const MyPlugin = async ({ client }) => {
await client.app.log({ await client.app.log({
service: "my-plugin", service: "my-plugin",
@ -311,7 +311,7 @@ Levels: `debug`, `info`, `warn`, `error`. See [SDK documentation](https://openco
Customize the context included when a session is compacted: Customize the context included when a session is compacted:
```ts title=".opencode/plugin/compaction.ts" ```ts title=".opencode/plugins/compaction.ts"
import type { Plugin } from "@opencode-ai/plugin" import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => { export const CompactionPlugin: Plugin = async (ctx) => {
@ -335,7 +335,7 @@ The `experimental.session.compacting` hook fires before the LLM generates a cont
You can also replace the compaction prompt entirely by setting `output.prompt`: You can also replace the compaction prompt entirely by setting `output.prompt`:
```ts title=".opencode/plugin/custom-compaction.ts" ```ts title=".opencode/plugins/custom-compaction.ts"
import type { Plugin } from "@opencode-ai/plugin" import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => { export const CustomCompactionPlugin: Plugin = async (ctx) => {

View File

@ -13,8 +13,8 @@ Skills are loaded on-demand via the native `skill` tool—agents see available s
Create one folder per skill name and put a `SKILL.md` inside it. Create one folder per skill name and put a `SKILL.md` inside it.
OpenCode searches these locations: OpenCode searches these locations:
- Project config: `.opencode/skill/<name>/SKILL.md` - Project config: `.opencode/skills/<name>/SKILL.md`
- Global config: `~/.config/opencode/skill/<name>/SKILL.md` - Global config: `~/.config/opencode/skills/<name>/SKILL.md`
- Project Claude-compatible: `.claude/skills/<name>/SKILL.md` - Project Claude-compatible: `.claude/skills/<name>/SKILL.md`
- Global Claude-compatible: `~/.claude/skills/<name>/SKILL.md` - Global Claude-compatible: `~/.claude/skills/<name>/SKILL.md`
@ -23,9 +23,9 @@ OpenCode searches these locations:
## Understand discovery ## Understand discovery
For project-local paths, OpenCode walks up from your current working directory until it reaches the git worktree. For project-local paths, OpenCode walks up from your current working directory until it reaches the git worktree.
It loads any matching `skill/*/SKILL.md` in `.opencode/` and any matching `.claude/skills/*/SKILL.md` along the way. It loads any matching `skills/*/SKILL.md` in `.opencode/` and any matching `.claude/skills/*/SKILL.md` along the way.
Global definitions are also loaded from `~/.config/opencode/skill/*/SKILL.md` and `~/.claude/skills/*/SKILL.md`. Global definitions are also loaded from `~/.config/opencode/skills/*/SKILL.md` and `~/.claude/skills/*/SKILL.md`.
--- ---
@ -71,7 +71,7 @@ Keep it specific enough for the agent to choose correctly.
## Use an example ## Use an example
Create `.opencode/skill/git-release/SKILL.md` like this: Create `.opencode/skills/git-release/SKILL.md` like this:
```markdown ```markdown
--- ---