Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .opencode/plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Working examples of OpenCode plugins. Drop-in to any project — pure JS, no npm
| Plugin | What it does |
|---|---|
| [`protect-secrets.js`](protect-secrets.js) | Blocks any tool call (read/write/bash) touching `.env*`, `secrets/`, `credentials*`, SSH keys, `.npmrc`, `.pypirc`. |
| [`audit-log.js`](audit-log.js) | Appends a one-line JSON record of every successful tool call to `.opencode/audit.jsonl`. |
| [`audit-log.js`](audit-log.js) | Appends a one-line JSON record of every completed tool call to `.opencode/audit.jsonl`. |

## How they load

Expand All @@ -25,7 +25,7 @@ tail -f .opencode/audit.jsonl # watch tool calls live
Sample line:

```json
{"ts":"2026-05-18T19:30:12.451Z","tool":"edit","ok":true,"input_keys":["file_path","old_string","new_string"]}
{"ts":"2026-06-08T19:30:12.451Z","tool":"edit","arg_keys":["filePath","oldString","newString"],"title":"src/api/auth.ts"}
```

## Disabling temporarily
Expand Down
21 changes: 9 additions & 12 deletions .opencode/plugins/audit-log.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// .opencode/plugins/audit-log.js
//
// Append a JSONL record of every successful tool call to .opencode/audit.jsonl.
// Append a JSONL record of every completed tool call to .opencode/audit.jsonl.
// Useful as an after-the-fact paper trail of what the agent did this session.
//
// Toggle off by deleting this file or by gating with an env var:
Expand All @@ -15,19 +15,16 @@ export const AuditLog = async ({ directory }) => {
await mkdir(dirname(logPath), { recursive: true });

return {
event: async ({ event }) => {
if (event?.type !== "tool.execute.after") return;

// `tool.execute.after` is a top-level hook with an (input, output) signature,
// fired once a tool call completes. `input.tool`/`input.args` describe the
// call; `output.title` is OpenCode's short summary of the result.
"tool.execute.after": async (input, output) => {
const record = {
ts: new Date().toISOString(),
tool: event.tool,
ok: !event.error,
// Capture small inputs only — full inputs can be huge (file content, diffs)
input_keys: event.input ? Object.keys(event.input) : [],
// Truncate long error messages
error: event.error
? String(event.error).slice(0, 240)
: undefined,
tool: input.tool,
// Capture argument keys only — full args can be huge (file content, diffs)
arg_keys: input.args ? Object.keys(input.args) : [],
title: output?.title,
};

await appendFile(logPath, JSON.stringify(record) + "\n");
Expand Down
27 changes: 15 additions & 12 deletions .opencode/plugins/protect-secrets.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,30 @@

const SENSITIVE = /(^|\/)(\.env(\..*)?|secrets|credentials|id_rsa|id_ed25519|\.npmrc|\.pypirc)(\b|\/)/i;

function pathFromInput(toolName, input) {
if (!input || typeof input !== "object") return "";
// Pull the most likely path/command field out of a tool's arguments.
// `read`/`edit`/`write` use `filePath`; `bash` uses `command`; others vary.
function targetFromArgs(args) {
if (!args || typeof args !== "object") return "";
return (
input.path ??
input.file_path ??
input.filePath ??
input.target ??
input.command ?? // for bash tool, scan the command line itself
args.filePath ??
args.path ??
args.file_path ??
args.target ??
args.command ?? // bash: scan the command line itself
""
);
}

export const ProtectSecrets = async () => {
return {
event: async ({ event }) => {
if (event?.type !== "tool.execute.before") return;

const candidate = pathFromInput(event.tool, event.input);
// `tool.execute.before` is a top-level hook with an (input, output) signature.
// `input.tool` is the tool name; `output.args` holds its (mutable) arguments.
// Throwing here aborts the tool call before it runs.
"tool.execute.before": async (input, output) => {
const candidate = targetFromArgs(output?.args);
if (candidate && SENSITIVE.test(String(candidate))) {
throw new Error(
`[protect-secrets] blocked ${event.tool} on sensitive path: ${candidate}`
`[protect-secrets] blocked ${input.tool} on sensitive path: ${candidate}`
);
}
},
Expand Down
52 changes: 29 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
A practical guide to [OpenCode](https://opencode.ai) — from your first prompt to custom agents, skills, plugins, and MCP integrations. Built around clear mental models and real examples, not marketing.

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)
[![OpenCode v1.15.4](https://img.shields.io/badge/OpenCode-v1.15.4-7C3AED?style=flat-square)](https://github.com/anomalyco/opencode/releases)
[![Last reviewed](https://img.shields.io/badge/last%20reviewed-May%202026-22c55e?style=flat-square)](#updates--deprecations)
[![OpenCode v1.16.2](https://img.shields.io/badge/OpenCode-v1.16.2-7C3AED?style=flat-square)](https://github.com/anomalyco/opencode/releases)
[![Last reviewed](https://img.shields.io/badge/last%20reviewed-June%202026-22c55e?style=flat-square)](#updates--deprecations)
[![PRs welcome](https://img.shields.io/badge/PRs-welcome-ff69b4?style=flat-square)](CONTRIBUTING.md)

```bash
Expand Down Expand Up @@ -115,7 +115,7 @@ scoop install opencode # Windows
choco install opencode # Windows
sudo pacman -S opencode # Arch
paru -S opencode-bin # Arch (AUR)
mise use -g opencode # mise users
mise use -g github:anomalyco/opencode # mise users
nix run nixpkgs#opencode # Nix
```

Expand Down Expand Up @@ -201,7 +201,7 @@ Per-agent model override:
{
"agent": {
"plan": { "model": "anthropic/claude-haiku-4-5" },
"deep-thinker": { "model": "openai/gpt-5", "reasoningEffort": "high" }
"deep-thinker": { "model": "openai/gpt-5", "options": { "reasoningEffort": "high" } }
}
}
```
Expand All @@ -217,23 +217,23 @@ A curated, pay-as-you-go AI gateway. The OpenCode team tests and tunes models fo
/models # browse the lineup
```

**Pricing snapshot** *(verified 2026-05-18; check [opencode.ai/docs/zen](https://opencode.ai/docs/zen) for current)*
**Pricing snapshot** *(verified 2026-06-08; check [opencode.ai/docs/zen](https://opencode.ai/docs/zen) for current)*

| Model ID | Input / Output (per MTok) | Reach for it when… |
|---|---|---|
| `opencode/claude-opus-4-7` | $5 / $25 | Complex reasoning, large refactors |
| `opencode/claude-opus-4-8` | $5 / $25 | Flagship reasoning — complex refactors, large multi-file work |
| `opencode/claude-sonnet-4-6` | $3 / $15 | Balanced everyday coding |
| `opencode/claude-haiku-4-5` | $1 / $5 | Fast, lightweight tasks |
| `opencode/gpt-5.5` *(≤272K)* | $5 / $30 | Long-context, OpenAI ecosystem |
| `opencode/gpt-5.4-mini` | $0.75 / $4.50 | Cost-efficient frontier |
| `opencode/gemini-3.1-pro` | $2 / $12 | Multimodal, Google ecosystem |
| `opencode/qwen3.6-plus` | $0.50 / $3 | Budget-friendly heavy lifting |
| `opencode/qwen3.7-plus` | $0.40 / $1.60 | Budget-friendly heavy lifting |

**Free tier** *(rotating, time-limited, for community feedback):* `deepseek-v4-flash-free`, `minimax-m2.5-free`, `nemotron-3-super-free`, `big-pickle` *(stealth)*.
**Free tier** *(rotating, time-limited, for community feedback):* `big-pickle` *(stealth)*, `deepseek-v4-flash-free`, `mimo-v2.5-free`, `nemotron-3-ultra-free`.

> 40+ models total — full list, cached-read/write rates, GPT 5 Codex variants, GLM, Kimi, Claude Opus 4.5/4.6/4.1, etc.: [opencode.ai/docs/zen](https://opencode.ai/docs/zen) · Deeper guide: [`docs/zen.md`](docs/zen.md).
> 50+ models total — full list, cached-read/write rates, GPT-5 Codex variants, Gemini, GLM, Kimi, MiniMax, Grok, and the Claude Opus 4.8/4.7/4.5/4.1 line: [opencode.ai/docs/zen](https://opencode.ai/docs/zen) · Deeper guide: [`docs/zen.md`](docs/zen.md).

> 💡 **Pattern: cheap explorer / strong executor.** Use a cheap model (`qwen3.6-plus`, `gpt-5.4-mini`) for `explore` and `scout` subagents that read a lot, and a stronger one (`claude-sonnet-4-6` or `claude-opus-4-7`) for the main `build` agent that does the editing.
> 💡 **Pattern: cheap explorer / strong executor.** Use a cheap model (`qwen3.7-plus`, `gpt-5.4-mini`) for `explore` and `scout` subagents that read a lot, and a stronger one (`claude-sonnet-4-6` or `claude-opus-4-8`) for the main `build` agent that does the editing.

---

Expand Down Expand Up @@ -362,7 +362,7 @@ opencode github install # add a workflow file to your repo
opencode pr 123 # check out PR #123 and start a session
```

Useful `run` flags: `--continue` / `--session <id>` (resume), `--share` (publish), `--format json` (machine-readable), `--file <path>` (attach), `--dangerously-skip-permissions` (auto-approve everything not `deny` — **CI only**).
Useful `run` flags: `--continue` / `--session <id>` (resume), `--fork` (branch a session), `--share` (publish), `--format json` (machine-readable), `--file <path>` (attach), `--replay` (interactive replay, v1.16+), `--dangerously-skip-permissions` (auto-approve everything not `deny` — **CI only**).

Sessions, stats, sharing:

Expand Down Expand Up @@ -529,7 +529,7 @@ Plus npm packages via the `plugin` array in `opencode.json`:

Auto-installed via Bun, cached under `~/.cache/opencode/node_modules/`.

Plugins receive `{ project, directory, worktree, client, $ }` and return event handlers. `$` is the Bun shell. Events span tools, files, sessions, messages, permissions, LSP, TUI — ~25 total.
Plugins receive `{ project, directory, worktree, client, $ }` and return hooks. `$` is the Bun shell. Two shapes: typed hooks like `tool.execute.before`/`shell.env` that get `(input, output)`, and a generic `event` handler for the lifecycle stream (files, sessions, messages, permissions, LSP, TUI — ~26 events).

This repo ships two working examples in [`.opencode/plugins/`](.opencode/plugins/):

Expand Down Expand Up @@ -588,11 +588,11 @@ Filename → agent name. `frontend-engineer.md` → `@frontend-engineer` (subage
| `subagent` | `@<name>` mentions only (runs in a child session) |
| `all` | Both |

Bash permissions accept a **glob-pattern map** (`{"*": "ask", "git status*": "allow", "rm -rf*": "deny"}`) — most-specific match wins.
Bash permissions accept a **glob-pattern map** (`{"*": "ask", "git status*": "allow", "rm -rf*": "deny"}`) — rules match in order and the **last matching rule wins**, so list the catch-all `*` first.

> 📐 This repo ships **drop-in specialist prompts** in [`specialized-agents/`](specialized-agents/) — backend, frontend, code reviewer, security reviewer, tech lead, database, UX. Copy any of them into `.opencode/agents/<name>.md` to use.

> 📚 Deep dive — full frontmatter key list, all 17 permission keys, JSON-form alternative: [`docs/agents.md`](docs/agents.md) · [`docs/reference/permissions.md`](docs/reference/permissions.md).
> 📚 Deep dive — full frontmatter key list, all 15 permission keys, JSON-form alternative: [`docs/agents.md`](docs/agents.md) · [`docs/reference/permissions.md`](docs/reference/permissions.md).

---

Expand Down Expand Up @@ -671,16 +671,22 @@ Set `bash` permission to `"ask"` at the project level, or use the glob form to w

*[→ Full changelog in `docs/reference/changelog.md`](docs/reference/changelog.md)*

**Current release:** **v1.15.4** *(2026-05-17)*. Run `opencode upgrade` to get it.
**Current release:** **v1.16.2** *(2026-06-05)*. Run `opencode upgrade` to get it.

**Recent highlights:**
**New in v1.16:**

- 🆕 **Agent Skills compatibility** — auto-discoverable workflows via `SKILL.md` (Claude Code-compatible).
- 🆕 **Glob-pattern bash permissions** — fine-grained allow/ask/deny per command pattern.
- 🆕 **Remote MCP with auto-OAuth** — Dynamic Client Registration handled out of the box.
- 🆕 **Desktop app (beta)** — macOS, Windows, Linux at [opencode.ai/download](https://opencode.ai/download).
- 🆕 **ACP server (`opencode acp`)** — Agent Client Protocol for editor integrations.
- 🆕 **Managed configs** — macOS `/Library/Application Support/opencode/`, Linux `/etc/opencode/`, Windows `%ProgramData%\opencode`, plus macOS MDM preferences.
- 🆕 **File-based agents & skill discovery** — drop-in agent markdown files and `SKILL.md` discovery are GA; scaffold an agent with `opencode agent create`.
- 🆕 **Workspace cloning & session mobility** — managed workspace clones keep dirty/untracked files, and you can move sessions between workspaces and directories.
- 🆕 **`opencode run --replay`** — interactively replay a run as it streams.
- 🆕 **OpenAI models via AWS Bedrock** — plus GitHub Copilot token-based usage tracking.
- ⚡ **~38% faster startup**, and a desktop app refresh (color themes, thinking-level selector, Servers tab).

**Still recent (v1.15):**

- **Glob-pattern bash permissions** — fine-grained allow/ask/deny per command pattern (rules match in order, last match wins).
- **Remote MCP with auto-OAuth** — Dynamic Client Registration handled out of the box.
- **ACP server (`opencode acp`)** — Agent Client Protocol for editor integrations.
- **Managed configs** — macOS `/Library/Application Support/opencode/`, Linux `/etc/opencode/`, Windows `%ProgramData%\opencode`, plus macOS MDM preferences.
- 📝 **AGENTS.md** is canonical; `CLAUDE.md` is now a fallback only.

> 💡 Source of truth: [GitHub releases](https://github.com/anomalyco/opencode/releases).
Expand All @@ -705,4 +711,4 @@ Set `bash` permission to `"ask"` at the project level, or use the glob form to w

> Features, pricing, and availability change frequently. Always check the [official OpenCode documentation](https://opencode.ai/docs/) for the most current information.

*Last reviewed 2026-05-18 · OpenCode v1.15.4 · Spotted something stale? [Open an issue](../../issues) or send a PR — see [`CONTRIBUTING.md`](CONTRIBUTING.md).*
*Last reviewed 2026-06-08 · OpenCode v1.16.2 · Spotted something stale? [Open an issue](../../issues) or send a PR — see [`CONTRIBUTING.md`](CONTRIBUTING.md).*
25 changes: 14 additions & 11 deletions docs/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Two locations, same format:
| Project | `.opencode/agents/<name>.md` |
| Global | `~/.config/opencode/agents/<name>.md` |

> 🆕 File-based agent loading is GA as of v1.16. Scaffold one interactively with `opencode agent create` (it prompts for location, description, mode, model, and permissions), or just write the markdown by hand.

```markdown
---
description: Senior frontend engineer — Tailwind + React + TypeScript expert
Expand Down Expand Up @@ -61,10 +63,10 @@ Verified against the [config JSON schema's `AgentConfig`](https://opencode.ai/co
| `model` | `provider/model-id` | Per-agent model override |
| `temperature` · `top_p` | number | Sampling controls |
| `permission` | object | Per-tool `allow`/`ask`/`deny` (see below) |
| `tools` | object | Boolean per tool — `{"websearch": false}` |
| `tools` | object | *Deprecated — prefer `permission`.* Boolean per tool — `{"websearch": false}` |
| `prompt` *(JSON form only)* | string | System prompt; alternative to markdown body |
| `maxSteps` | number | Hard cap on agent steps in one invocation |
| `steps` | array | Scripted step sequence (advanced) |
| `steps` | number | Max agentic iterations before a forced text-only response |
| `maxSteps` | number | *Deprecated — use `steps`.* |
| `disable` | boolean | Disable an agent entirely |
| `hidden` | boolean | Hide from the UI but keep available |
| `color` | string | UI accent color |
Expand Down Expand Up @@ -100,7 +102,6 @@ Permission keys (verified against `PermissionConfig` in the [config JSON schema]
| `todowrite` | the in-session todo list |
| `question` | the `question` tool |
| `external_directory` | files outside the project root |
| `repo_clone` · `repo_overview` | repo-level operations |
| `webfetch` · `websearch` | network access |
| `lsp` | language server tools |
| `skill` | agent skill loading |
Expand All @@ -110,18 +111,18 @@ Three values everywhere: `"allow"` (no prompt) · `"ask"` (prompt user) · `"den

### Glob-pattern bash

The `bash` key can be a single value or a glob-map. **Order matters**: most specific patterns first.
The `bash` key can be a single value or a glob-map. **Order matters**: rules are matched in order and the **last matching rule wins**, so put the catch-all `*` first and the more specific overrides after it.

```json
{
"permission": {
"bash": {
"rm -rf*": "deny",
"git push --force*": "deny",
"*": "ask",
"git status*": "allow",
"git diff*": "allow",
"pnpm test*": "allow",
"*": "ask"
"git push --force*": "deny",
"rm -rf*": "deny"
}
}
}
Expand All @@ -136,9 +137,9 @@ Use this to keep an agent productive (no constant prompting for safe reads) whil
"agent": {
"explore": { "model": "opencode/qwen3.6-plus" },
"scout": { "model": "opencode/qwen3.6-plus" },
"plan": { "model": "opencode/claude-opus-4-7" },
"plan": { "model": "opencode/claude-opus-4-8" },
"build": { "model": "opencode/claude-sonnet-4-6" },
"deep-thinker": { "model": "openai/gpt-5", "reasoningEffort": "high" }
"deep-thinker": { "model": "openai/gpt-5", "options": { "reasoningEffort": "high" } }
}
}
```
Expand All @@ -150,6 +151,8 @@ If unspecified:

## Tools per agent

> ⚠️ The `tools` map is **deprecated** in favor of the `permission` field (set a tool to `"deny"` to disable it). It still works and remains the simplest way to gate MCP tools by glob, but prefer `permission` for new configs.

The `tools` map enables/disables individual tools by name, including MCP tools (use glob patterns):

```json
Expand Down Expand Up @@ -224,6 +227,6 @@ permission:

## Drop-in specialists

This repo ships 10 production-ready prompts in [`specialized-agents/`](../specialized-agents/). Copy any of them to `.opencode/agents/<name>.md` to use as a starting point.
This repo ships 7 production-ready prompts in [`specialized-agents/`](../specialized-agents/) — backend, frontend, code reviewer, security reviewer, tech lead, database, and UX. Copy any of them to `.opencode/agents/<name>.md` to use as a starting point.

> 📚 Full agent reference: [opencode.ai/docs/agents](https://opencode.ai/docs/agents).
4 changes: 2 additions & 2 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ Invoke with: `/scaffold-component UserAvatar`
description: Deep architectural review (isolated context)
agent: build
subtask: true
model: opencode/claude-opus-4-7
model: opencode/claude-opus-4-8
---

You are reviewing the architectural integrity of $ARGUMENTS.
Expand Down Expand Up @@ -157,7 +157,7 @@ If a command always runs with a particular model or agent, put it in the frontma
---
description: Long, deep refactor planning (Opus only)
agent: plan
model: opencode/claude-opus-4-7
model: opencode/claude-opus-4-8
---
```

Expand Down
7 changes: 5 additions & 2 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,18 @@ For servers that require pre-registered credentials:
}
```

### Managing OAuth from the CLI
### Managing servers from the CLI

```bash
opencode mcp add # interactively register a local or remote server
opencode mcp list # show servers and auth status
opencode mcp auth sentry # complete or refresh OAuth flow
opencode mcp logout sentry # forget stored credentials
opencode mcp debug sentry # diagnose connection issues
opencode mcp list # show servers and auth status
```

`opencode mcp add` walks you through type, command/URL, and headers, then writes the entry to your config — the no-hand-editing alternative to the JSON blocks above.

## Token budget warning

MCP tools land in the model's tool surface every turn. Heavy servers (e.g., a full GitHub MCP with dozens of tools) can easily eat 10K+ tokens of context — purely for tool *descriptions* the model may never actually call.
Expand Down
Loading
Loading