From dc76e2cd1188a48a7ff5d19256eaceb384b83d02 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 21 Feb 2026 17:05:30 +0900 Subject: [PATCH] docs: rewrite configuration.md for clarity and concision Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- docs/reference/configuration.md | 1345 +++++++------------------------ 1 file changed, 288 insertions(+), 1057 deletions(-) diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index b7ebfb253..58370754c 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -1,157 +1,153 @@ # Configuration Reference -Configuration for oh-my-opencode. +## File Locations -## Quick Start +Priority order (project overrides user): -Most users do not need to configure anything manually. Run the interactive installer: +1. `.opencode/oh-my-opencode.jsonc` / `.opencode/oh-my-opencode.json` +2. User config (`.jsonc` preferred over `.json`): -```bash -bunx oh-my-opencode install -``` +| Platform | Path | +|----------|------| +| macOS/Linux | `~/.config/opencode/oh-my-opencode.jsonc` | +| Windows | `%APPDATA%\opencode\oh-my-opencode.jsonc` | -It asks about your providers (Claude, OpenAI, Gemini, etc.) and generates optimal config automatically. - -**Want to customize?** Here are the common patterns: - -```jsonc -{ - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json", - - // Override specific agent models - "agents": { - "oracle": { "model": "openai/gpt-5.2" }, // Use GPT for debugging - "librarian": { "model": "zai-coding-plan/glm-4.7" }, // Cheap model for research - "explore": { "model": "opencode/gpt-5-nano" } // Free model for grep - }, - - // Override category models (used by task) - "categories": { - "quick": { "model": "opencode/gpt-5-nano" }, // Fast/cheap for trivial tasks - "visual-engineering": { "model": "google/gemini-3-pro" } // Gemini for UI - } -} -``` - -**Find available models:** Run `opencode models` to see all models in your environment. - -## Config File Locations - -Config file locations (priority order): - -1. `.opencode/oh-my-opencode.jsonc` or `.opencode/oh-my-opencode.json` (project; prefers `.jsonc` when both exist) -2. User config (platform-specific; prefers `.jsonc` when both exist): - -| Platform | User Config Path | -| --------------- | --------------------------------------------------------------------------------------------------------------------------- | -| **Windows** | `~/.config/opencode/oh-my-opencode.jsonc` (preferred) or `~/.config/opencode/oh-my-opencode.json` (fallback); `%APPDATA%\opencode\oh-my-opencode.jsonc` / `%APPDATA%\opencode\oh-my-opencode.json` (fallback) | -| **macOS/Linux** | `~/.config/opencode/oh-my-opencode.jsonc` (preferred) or `~/.config/opencode/oh-my-opencode.json` (fallback) | - -Schema autocomplete supported: +JSONC supports `// line comments`, `/* block comments */`, and trailing commas. +Schema autocomplete: ```json -{ - "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json" -} +{ "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json" } ``` -### JSONC Support +Run `bunx oh-my-opencode install` for guided setup. Run `opencode models` to list available models. -The `oh-my-opencode` configuration file supports JSONC (JSON with Comments): -- Line comments: `// comment` -- Block comments: `/* comment */` -- Trailing commas: `{ "key": "value", }` +## My Setup -When both `oh-my-opencode.jsonc` and `oh-my-opencode.json` files exist, `.jsonc` takes priority. - -**Example with comments:** +Here's my personal `~/.config/opencode/oh-my-opencode.jsonc`. Adapt to your providers. ```jsonc { "$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json", - /* Agent overrides - customize models for specific tasks */ "agents": { - "oracle": { - "model": "openai/gpt-5.2" // GPT for strategic reasoning - }, - "explore": { - "model": "opencode/gpt-5-nano" // Free & fast for exploration + /* + * Sisyphus: Main orchestrator. + * Kimi K2.5 for daily driving; ultrawork escalates to Claude Opus. + * Alternatives: anthropic/claude-opus-4-6, zai-coding-plan/glm-5 + */ + "sisyphus": { + "model": "kimi-for-coding/k2p5", + "ultrawork": { "model": "anthropic/claude-opus-4-6", "variant": "max" } }, + + /* + * Librarian + Explore: parallel research/grep. Cheap models are fine. + * Alternatives: opencode/gpt-5-nano, github-copilot/gpt-5, anthropic/claude-haiku-4-5 + */ + "librarian": { "model": "zai-coding-plan/glm-4.7" }, + "explore": { "model": "github-copilot/grok-code-fast-1" }, + + /* + * Oracle: architecture consultation + hard debugging. + * Alternatives: anthropic/claude-opus-4-6, google/gemini-3-pro + */ + "oracle": { "model": "openai/gpt-5.2", "variant": "high" }, + + // Prometheus inherits sisyphus model; just add prompt guidance. + "prometheus": { "prompt_append": "Leverage deep & quick agents heavily, always in parallel." } }, + + "categories": { + // quick — trivial tasks. Alternatives: anthropic/claude-haiku-4-5, google/gemini-3-flash + "quick": { "model": "opencode/gpt-5-nano" }, + + // unspecified-low — moderate tasks. Alternatives: anthropic/claude-sonnet-4-6, openai/gpt-5 + "unspecified-low": { "model": "kimi-for-coding/k2p5" }, + + // unspecified-high — complex work. Alternatives: anthropic/claude-opus-4-6 (max), openai/gpt-5.3-codex + "unspecified-high": { "model": "anthropic/claude-sonnet-4-6", "variant": "max" }, + + // writing — docs/prose. Alternatives: anthropic/claude-sonnet-4-6, openai/gpt-5.2 + "writing": { "model": "kimi-for-coding/k2p5" }, + + // git — custom category for git ops + "git": { + "model": "opencode/gpt-5-nano", + "description": "All git operations", + "prompt_append": "Focus on atomic commits, clear messages, and safe operations." + }, + + // batch — custom category for spamming parallel low-stakes tasks + "batch": { + "model": "opencode/gpt-5-nano", + "description": "Parallel batch processing. Needs very explicit prompts.", + "prompt_append": "RESPOND CONCISELY. FOLLOW INSTRUCTIONS EXACTLY.", + "is_unstable_agent": true + } + }, + + // Limit expensive providers; let cheap ones run freely. + "background_task": { + "providerConcurrency": { "anthropic": 3, "openai": 3, "opencode": 10, "zai-coding-plan": 10 }, + "modelConcurrency": { "anthropic/claude-opus-4-6": 2, "opencode/gpt-5-nano": 20 } + }, + + "experimental": { "aggressive_truncation": true, "task_system": true }, + "tmux": { "enabled": false } } ``` ## Agents -Override built-in agent settings: +Override built-in agent settings in `agents`: ```json { "agents": { - "explore": { - "model": "anthropic/claude-haiku-4-5", - "temperature": 0.5 - }, - "multimodal-looker": { - "disable": true - } + "explore": { "model": "anthropic/claude-haiku-4-5", "temperature": 0.5 }, + "multimodal-looker": { "disable": true } } } ``` -Each agent supports: `model`, `fallback_models`, `temperature`, `top_p`, `prompt`, `prompt_append`, `tools`, `disable`, `description`, `mode`, `color`, `permission`, `category`, `variant`, `maxTokens`, `thinking`, `reasoningEffort`, `textVerbosity`, `providerOptions`. +Available agents: `sisyphus`, `hephaestus`, `prometheus`, `oracle`, `librarian`, `explore`, `multimodal-looker`, `metis`, `momus`, `atlas` -### Additional Agent Options +Disable via `disabled_agents`: `{ "disabled_agents": ["oracle", "multimodal-looker"] }` -| Option | Type | Description | -| ------------------- | -------------- | ----------------------------------------------------------------------------------------------- | -| `fallback_models` | string/array | Fallback models for runtime switching on API errors. Single string or array of model strings. | -| `category` | string | Category name to inherit model and other settings from category defaults | -| `variant` | string | Model variant (e.g., `max`, `high`, `medium`, `low`, `xhigh`) | -| `maxTokens` | number | Maximum tokens for response. Passed directly to OpenCode SDK. | -| `thinking` | object | Extended thinking configuration for Anthropic models. See [Thinking Options](#thinking-options) below. | -| `reasoningEffort` | string | OpenAI reasoning effort level. Values: `low`, `medium`, `high`, `xhigh`. | -| `textVerbosity` | string | Text verbosity level. Values: `low`, `medium`, `high`. | -| `providerOptions` | object | Provider-specific options passed directly to OpenCode SDK. | +### Agent Options -#### Thinking Options (Anthropic) +| Option | Type | Description | +| --- | --- | --- | +| `model` | string | Model override (`provider/model`) | +| `fallback_models` | string\|array | Fallback models on API errors | +| `temperature` | number | Sampling temperature | +| `top_p` | number | Top-p sampling | +| `prompt` | string | Replace system prompt | +| `prompt_append` | string | Append to system prompt | +| `tools` | array | Allowed tools list | +| `disable` | boolean | Disable this agent | +| `mode` | string | Agent mode | +| `color` | string | UI color | +| `permission` | object | Per-tool permissions (see below) | +| `category` | string | Inherit model from category | +| `variant` | string | Model variant: `max`, `high`, `medium`, `low`, `xhigh` | +| `maxTokens` | number | Max response tokens | +| `thinking` | object | Anthropic extended thinking (see below) | +| `reasoningEffort` | string | OpenAI reasoning: `low`, `medium`, `high`, `xhigh` | +| `textVerbosity` | string | Text verbosity: `low`, `medium`, `high` | +| `providerOptions` | object | Provider-specific options | + +### Thinking (Anthropic) ```json { "agents": { - "oracle": { - "thinking": { - "type": "enabled", - "budgetTokens": 200000 - } - } + "oracle": { "thinking": { "type": "enabled", "budgetTokens": 200000 } } } } ``` -| Option | Type | Default | Description | -| ------------- | ------- | ------- | -------------------------------------------- | -| `type` | string | - | `enabled` or `disabled` | -| `budgetTokens`| number | - | Maximum budget tokens for extended thinking | - -Use `prompt_append` to add extra instructions without replacing the default system prompt: - -```json -{ - "agents": { - "librarian": { - "prompt_append": "Always use the elisp-dev-mcp for Emacs Lisp documentation lookups." - } - } -} -``` - -You can also override settings for `Sisyphus` (the main orchestrator) and `build` (the default agent) using the same options. - -### Permission Options - -Fine-grained control over what agents can do: +### Permissions ```json { @@ -167,308 +163,110 @@ Fine-grained control over what agents can do: } ``` -| Permission | Description | Values | -| -------------------- | -------------------------------------- | --------------------------------------------------------------------------- | -| `edit` | File editing permission | `ask` / `allow` / `deny` | -| `bash` | Bash command execution | `ask` / `allow` / `deny` or per-command: `{ "git": "allow", "rm": "deny" }` | -| `webfetch` | Web request permission | `ask` / `allow` / `deny` | -| `doom_loop` | Allow infinite loop detection override | `ask` / `allow` / `deny` | -| `external_directory` | Access files outside project root | `ask` / `allow` / `deny` | - -Or disable via `disabled_agents` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: - -```json -{ - "disabled_agents": ["oracle", "multimodal-looker"] -} -``` - -Available agents: `sisyphus`, `hephaestus`, `prometheus`, `oracle`, `librarian`, `explore`, `multimodal-looker`, `metis`, `momus`, `atlas` +| Permission | Values | +| --- | --- | +| `edit` | `ask` / `allow` / `deny` | +| `bash` | `ask` / `allow` / `deny` or per-command: `{ "git": "allow", "rm": "deny" }` | +| `webfetch` | `ask` / `allow` / `deny` | +| `doom_loop` | `ask` / `allow` / `deny` | +| `external_directory` | `ask` / `allow` / `deny` | ## Categories -Categories enable domain-specific task delegation via the `task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent. +Domain-specific model delegation used by the `task()` tool. ### Built-in Categories -All 8 categories come with optimal model defaults, but **you must configure them to use those defaults**: +| Category | Default Model | Description | +| --- | --- | --- | +| `visual-engineering` | `google/gemini-3-pro` (high) | Frontend, UI/UX, design, animation | +| `ultrabrain` | `openai/gpt-5.3-codex` (xhigh) | Deep logical reasoning, complex architecture | +| `deep` | `openai/gpt-5.3-codex` (medium) | Autonomous problem-solving, thorough research | +| `artistry` | `google/gemini-3-pro` (high) | Creative/unconventional approaches | +| `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks, typo fixes, single-file changes | +| `unspecified-low` | `anthropic/claude-sonnet-4-6` | General tasks, low effort | +| `unspecified-high` | `anthropic/claude-opus-4-6` (max) | General tasks, high effort | +| `writing` | `kimi-for-coding/k2p5` | Documentation, prose, technical writing | -| Category | Built-in Default Model | Description | -| -------------------- | ---------------------------------- | -------------------------------------------------------------------- | -| `visual-engineering` | `google/gemini-3-pro` (high) | Frontend, UI/UX, design, styling, animation | -| `ultrabrain` | `openai/gpt-5.3-codex` (xhigh) | Deep logical reasoning, complex architecture decisions | -| `deep` | `openai/gpt-5.3-codex` (medium) | Goal-oriented autonomous problem-solving, thorough research before action | -| `artistry` | `google/gemini-3-pro` (high) | Highly creative/artistic tasks, novel ideas | -| `quick` | `anthropic/claude-haiku-4-5` | Trivial tasks - single file changes, typo fixes, simple modifications| -| `unspecified-low` | `anthropic/claude-sonnet-4-6` | Tasks that do not fit other categories, low effort required | -| `unspecified-high` | `anthropic/claude-opus-4-6` (max) | Tasks that do not fit other categories, high effort required | -| `writing` | `kimi-for-coding/k2p5` | Documentation, prose, technical writing | +> **Note**: Built-in defaults only apply if the category is present in your config. Otherwise the system default model is used. -### Model Resolution Priority +### Category Options -**Categories DO NOT use their built-in defaults unless configured.** Model resolution follows this priority: +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `model` | string | - | Model override | +| `fallback_models` | string\|array | - | Fallback models on API errors | +| `temperature` | number | - | Sampling temperature | +| `top_p` | number | - | Top-p sampling | +| `maxTokens` | number | - | Max response tokens | +| `thinking` | object | - | Anthropic extended thinking | +| `reasoningEffort` | string | - | OpenAI reasoning effort | +| `textVerbosity` | string | - | Text verbosity | +| `tools` | array | - | Allowed tools | +| `prompt_append` | string | - | Append to system prompt | +| `variant` | string | - | Model variant | +| `description` | string | - | Shown in `task()` tool prompt | +| `is_unstable_agent` | boolean | `false` | Force background mode + monitoring. Auto-enabled for Gemini models. | -``` -1. User-configured model (in oh-my-opencode.json) -2. Category's built-in default (if you add category to config) -3. System default model (from opencode.json) -``` - -**Example Problem:** - -```json -// opencode.json -{ "model": "anthropic/claude-sonnet-4-6" } - -// oh-my-opencode.json (empty categories section) -{} - -// Result: ALL categories use claude-sonnet-4-6 (wasteful!) -// - quick tasks use Sonnet instead of Haiku (expensive) -// - ultrabrain uses Sonnet instead of GPT-5.2 (inferior reasoning) -// - visual tasks use Sonnet instead of Gemini (suboptimal for UI) -``` - -### Recommended Configuration - -**To use optimal models for each category, add them to your config:** - -```json -{ - "categories": { - "visual-engineering": { - "model": "google/gemini-3-pro" - }, - "ultrabrain": { - "model": "openai/gpt-5.3-codex", - "variant": "xhigh" - }, - "deep": { - "model": "openai/gpt-5.3-codex", - "variant": "medium" - }, - "artistry": { - "model": "google/gemini-3-pro", - "variant": "high" - }, - "quick": { - "model": "anthropic/claude-haiku-4-5" // Fast + cheap for trivial tasks - }, - "unspecified-low": { - "model": "anthropic/claude-sonnet-4-6" - }, - "unspecified-high": { - "model": "anthropic/claude-opus-4-6", - "variant": "max" - }, - "writing": { - "model": "kimi-for-coding/k2p5" - } - } -} -``` - -**Only configure categories you have access to.** Unconfigured categories fall back to your system default model. - -### Usage - -```javascript -// Via task tool -task(category="visual-engineering", prompt="Create a responsive dashboard component") -task(category="ultrabrain", prompt="Design the payment processing flow") - -// Or target a specific agent directly (bypasses categories) -task(agent="oracle", prompt="Review this architecture") -``` - -### Custom Categories - -Add your own categories or override built-in ones: - -```json -{ - "categories": { - "data-science": { - "model": "anthropic/claude-sonnet-4-6", - "temperature": 0.2, - "prompt_append": "Focus on data analysis, ML pipelines, and statistical methods." - }, - "visual-engineering": { - "model": "google/gemini-3-pro-preview", - "prompt_append": "Use shadcn/ui components and Tailwind CSS." - } - } -} -``` - -Each category supports: `model`, `fallback_models`, `temperature`, `top_p`, `maxTokens`, `thinking`, `reasoningEffort`, `textVerbosity`, `tools`, `prompt_append`, `variant`, `description`, `is_unstable_agent`. - -### Additional Category Options - -| Option | Type | Default | Description | -| ------------------- | ------------ | ------- | --------------------------------------------------------------------------------------------------- | -| `fallback_models` | string/array | - | Fallback models for runtime switching on API errors. Single string or array of model strings. | -| `description` | string | - | Human-readable description of the category's purpose. Shown in delegate_task prompt. | -| `is_unstable_agent` | boolean | `false` | Mark agent as unstable - forces background mode for monitoring. Auto-enabled for gemini models. | +Disable via `disabled_categories`: `{ "disabled_categories": ["ultrabrain"] }` ## Model Resolution -At runtime, Oh My OpenCode uses a 3-step resolution process to determine which model to use for each agent and category. This happens dynamically based on your configuration and available models. +3-step priority at runtime: -### Overview - -**Problem**: Users have different provider configurations. The system needs to select the best available model for each task at runtime. - -**Solution**: A simple 3-step resolution flow: -1. **Step 1: User Override** — If you specify a model in `oh-my-opencode.json`, use exactly that -2. **Step 2: Provider Fallback** — Try each provider in the requirement's priority order until one is available -3. **Step 3: System Default** — Fall back to OpenCode's configured default model - -### Resolution Flow - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ MODEL RESOLUTION FLOW │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ Step 1: USER OVERRIDE │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ User specified model in oh-my-opencode.json? │ │ -│ │ YES → Use exactly as specified │ │ -│ │ NO → Continue to Step 2 │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ Step 2: PROVIDER PRIORITY FALLBACK │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ For each provider in requirement.providers order: │ │ -│ │ │ │ -│ │ Example for Sisyphus: │ │ -│ │ anthropic → github-copilot → opencode → antigravity │ │ -│ │ │ │ │ │ │ │ -│ │ ▼ ▼ ▼ ▼ │ │ -│ │ Try: anthropic/claude-opus-4-6 │ │ -│ │ Try: github-copilot/claude-opus-4-6 │ │ -│ │ Try: opencode/claude-opus-4-6 │ │ -│ │ ... │ │ -│ │ │ │ -│ │ Found in available models? → Return matched model │ │ -│ │ Not found? → Try next provider │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ (all providers exhausted) │ -│ Step 3: SYSTEM DEFAULT │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ Return systemDefaultModel (from opencode.json) │ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` +1. **User override** — model set in `oh-my-opencode.json` → used exactly as-is +2. **Provider fallback chain** — tries each provider in priority order until one is available +3. **System default** — falls back to OpenCode's configured default model ### Agent Provider Chains -Each agent has a defined provider priority chain. The system tries providers in order until it finds an available model: - -| Agent | Model (no prefix) | Provider Priority Chain | -|-------|-------------------|-------------------------| -| **Sisyphus** | `claude-opus-4-6` | anthropic/github-copilot/opencode → kimi-for-coding → opencode → zai-coding-plan → opencode | -| **Hephaestus** | `gpt-5.3-codex` | openai/github-copilot/opencode (requires provider) | -| **oracle** | `gpt-5.2` | openai/github-copilot/opencode → google/github-copilot/opencode → anthropic/github-copilot/opencode | -| **librarian** | `glm-4.7` | zai-coding-plan → opencode → anthropic/github-copilot/opencode | +| Agent | Default Model | Provider Priority | +| --- | --- | --- | +| **Sisyphus** | `claude-opus-4-6` | anthropic → github-copilot → opencode → kimi-for-coding → zai-coding-plan | +| **Hephaestus** | `gpt-5.3-codex` | openai → github-copilot → opencode | +| **oracle** | `gpt-5.2` | openai → google → anthropic (via github-copilot/opencode) | +| **librarian** | `glm-4.7` | zai-coding-plan → opencode → anthropic | | **explore** | `grok-code-fast-1` | github-copilot → anthropic/opencode → opencode | -| **multimodal-looker** | `gemini-3-flash` | google/github-copilot/opencode → openai/github-copilot/opencode → zai-coding-plan → kimi-for-coding → opencode → anthropic/github-copilot/opencode → opencode | -| **Prometheus (Planner)** | `claude-opus-4-6` | anthropic/github-copilot/opencode → kimi-for-coding → opencode → openai/github-copilot/opencode → google/github-copilot/opencode | -| **Metis (Plan Consultant)** | `claude-opus-4-6` | anthropic/github-copilot/opencode → kimi-for-coding → opencode → openai/github-copilot/opencode → google/github-copilot/opencode | -| **Momus (Plan Reviewer)** | `gpt-5.2` | openai/github-copilot/opencode → anthropic/github-copilot/opencode → google/github-copilot/opencode | -| **Atlas** | `k2p5` | kimi-for-coding → opencode → anthropic/github-copilot/opencode → openai/github-copilot/opencode → google/github-copilot/opencode | +| **multimodal-looker** | `gemini-3-flash` | google → openai → zai-coding-plan → kimi-for-coding → opencode → anthropic | +| **Prometheus** | `claude-opus-4-6` | anthropic → kimi-for-coding → opencode → openai → google | +| **Metis** | `claude-opus-4-6` | anthropic → kimi-for-coding → opencode → openai → google | +| **Momus** | `gpt-5.2` | openai → anthropic → google (via github-copilot/opencode) | +| **Atlas** | `k2p5` | kimi-for-coding → opencode → anthropic → openai → google | ### Category Provider Chains -Categories follow the same resolution logic: +| Category | Default Model | Provider Priority | +| --- | --- | --- | +| **visual-engineering** | `gemini-3-pro` | google → zai-coding-plan → anthropic → kimi-for-coding | +| **ultrabrain** | `gpt-5.3-codex` | openai → google → anthropic (via github-copilot/opencode) | +| **deep** | `gpt-5.3-codex` | openai → anthropic → google (via github-copilot/opencode) | +| **artistry** | `gemini-3-pro` | google → anthropic → openai (via github-copilot/opencode) | +| **quick** | `claude-haiku-4-5` | anthropic → google → opencode (via github-copilot/opencode) | +| **unspecified-low** | `claude-sonnet-4-6` | anthropic → openai → google (via github-copilot/opencode) | +| **unspecified-high** | `claude-opus-4-6` | anthropic → openai → google (via github-copilot/opencode) | +| **writing** | `k2p5` | kimi-for-coding → google → anthropic | -| Category | Model (no prefix) | Provider Priority Chain | -|----------|-------------------|-------------------------| -| **visual-engineering** | `gemini-3-pro` | google/github-copilot/opencode → zai-coding-plan → anthropic/github-copilot/opencode → kimi-for-coding | -| **ultrabrain** | `gpt-5.3-codex` | openai/github-copilot/opencode → google/github-copilot/opencode → anthropic/github-copilot/opencode | -| **deep** | `gpt-5.3-codex` | openai/github-copilot/opencode → anthropic/github-copilot/opencode → google/github-copilot/opencode | -| **artistry** | `gemini-3-pro` | google/github-copilot/opencode → anthropic/github-copilot/opencode → openai/github-copilot/opencode | -| **quick** | `claude-haiku-4-5` | anthropic/github-copilot/opencode → google/github-copilot/opencode → opencode | -| **unspecified-low** | `claude-sonnet-4-6` | anthropic/github-copilot/opencode → openai/github-copilot/opencode → google/github-copilot/opencode | -| **unspecified-high** | `claude-opus-4-6` | anthropic/github-copilot/opencode → openai/github-copilot/opencode → google/github-copilot/opencode | -| **writing** | `k2p5` | kimi-for-coding → google/github-copilot/opencode → anthropic/github-copilot/opencode | - -### Checking Your Configuration - -Use the `doctor` command to see how models resolve with your current configuration: - -```bash -bunx oh-my-opencode doctor --verbose -``` - -The "Model Resolution" check shows: -- Each agent/category's model requirement -- Provider fallback chain -- User overrides (if configured) -- Effective resolution path - -### Manual Override - -Override any agent or category model in `oh-my-opencode.json`: - -```json -{ - "agents": { - "Sisyphus": { - "model": "anthropic/claude-sonnet-4-6" - }, - "oracle": { - "model": "openai/o3" - } - }, - "categories": { - "visual-engineering": { - "model": "anthropic/claude-opus-4-6" - } - } -} -``` - -When you specify a model override, it takes precedence (Step 1) and the provider fallback chain is skipped entirely. +Run `bunx oh-my-opencode doctor --verbose` to see effective model resolution for your config. ## Skills -### Built-in Skills +Built-in skills: `playwright` (default), `agent-browser`, `git-master` -Oh My OpenCode includes built-in skills that provide additional capabilities: +Disable built-in skills via `disabled_skills`: `{ "disabled_skills": ["playwright"] }` -- **playwright** (default) / **agent-browser**: Browser automation for web scraping, testing, screenshots, and browser interactions. See [Browser Automation](#browser-automation) for switching between providers. -- **git-master**: Git expert for atomic commits, rebase/squash, and history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with `task(category='quick', load_skills=['git-master'], ...)` to save context. - -Disable built-in skills via `disabled_skills` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: - -```json -{ - "disabled_skills": ["playwright"] -} -``` - -Available built-in skills: `playwright`, `agent-browser`, `git-master` - -### Skills Configuration - -Configure advanced skills settings including custom skill sources, enabling/disabling specific skills, and defining custom skills. +### Skills Config ```json { "skills": { "sources": [ - { "path": "./custom-skills", "recursive": true }, + { "path": "./my-skills", "recursive": true }, "https://example.com/skill.yaml" ], - "enable": ["my-custom-skill"], + "enable": ["my-skill"], "disable": ["other-skill"], "my-skill": { - "description": "Custom skill description", + "description": "What it does", "template": "Custom prompt template", "from": "source-file.ts", "model": "custom/model", @@ -477,92 +275,27 @@ Configure advanced skills settings including custom skill sources, enabling/disa "argument-hint": "usage hint", "license": "MIT", "compatibility": ">= 3.0.0", - "metadata": { - "author": "Your Name" - }, - "allowed-tools": ["tool1", "tool2"] + "metadata": { "author": "Your Name" }, + "allowed-tools": ["read", "bash"] } } } ``` -#### Sources - -Load skills from local directories or remote URLs: - -```json -{ - "skills": { - "sources": [ - { "path": "./custom-skills", "recursive": true }, - { "path": "./single-skill.yaml" }, - "https://example.com/skill.yaml", - "https://raw.githubusercontent.com/user/repo/main/skills/*" - ] - } -} -``` - -| Option | Default | Description | -| ----------- | ------- | ---------------------------------------------- | -| `path` | - | Local file/directory path or remote URL | -| `recursive` | `false` | Recursively load from directory | -| `glob` | - | Glob pattern for file selection | - -#### Enable/Disable Skills - -```json -{ - "skills": { - "enable": ["skill-1", "skill-2"], - "disable": ["disabled-skill"] - } -} -``` - -#### Custom Skill Definition - -Define custom skills directly in your config: - -| Option | Default | Description | -| ---------------- | ------- | ------------------------------------------------------------------------------------ | -| `description` | - | Human-readable description of the skill | -| `template` | - | Custom prompt template for the skill | -| `from` | - | Source file to load template from | -| `model` | - | Override model for this skill | -| `agent` | - | Override agent for this skill | -| `subtask` | `false` | Whether to run as a subtask | -| `argument-hint` | - | Hint for how to use the skill | -| `license` | - | Skill license | -| `compatibility` | - | Required oh-my-opencode version compatibility | -| `metadata` | - | Additional metadata as key-value pairs | -| `allowed-tools` | - | Array of tools this skill is allowed to use | - -**Example: Custom skill** - -```json -{ - "skills": { - "data-analyst": { - "description": "Specialized for data analysis tasks", - "template": "You are a data analyst. Focus on statistical analysis, visualization, and data interpretation.", - "model": "openai/gpt-5.2", - "allowed-tools": ["read", "bash", "lsp_diagnostics"] - } - } -} -``` +| `sources` option | Default | Description | +| --- | --- | --- | +| `path` | - | Local path or remote URL | +| `recursive` | `false` | Recurse into subdirectories | +| `glob` | - | Glob pattern for file selection | ## Sisyphus Agent -When enabled (default), Sisyphus provides a powerful orchestrator with optional specialized agents: - -- **Sisyphus**: Primary orchestrator agent (Claude Opus 4.6) -- **OpenCode-Builder**: OpenCode's default build agent, renamed due to SDK limitations (disabled by default) -- **Prometheus (Planner)**: OpenCode's default plan agent with work-planner methodology (enabled by default) -- **Metis (Plan Consultant)**: Pre-planning analysis agent that identifies hidden requirements and AI failure points - -**Configuration Options:** +| Option | Default | Description | +| --- | --- | --- | +| `disabled` | `false` | Disable all Sisyphus orchestration, restore original build/plan | +| `default_builder_enabled` | `false` | Enable OpenCode-Builder agent (off by default) | +| `planner_enabled` | `true` | Enable Prometheus (Planner) agent | +| `replace_plan` | `true` | Demote default plan agent to subagent mode | ```json { @@ -575,96 +308,33 @@ When enabled (default), Sisyphus provides a powerful orchestrator with optional } ``` -**Example: Enable OpenCode-Builder:** - -```json -{ - "sisyphus_agent": { - "default_builder_enabled": true - } -} -``` - -This enables OpenCode-Builder agent alongside Sisyphus. The default build agent is always demoted to subagent mode when Sisyphus is enabled. - -**Example: Disable all Sisyphus orchestration:** - -```json -{ - "sisyphus_agent": { - "disabled": true - } -} -``` - -You can also customize Sisyphus agents like other agents: - -```json -{ - "agents": { - "Sisyphus": { - "model": "anthropic/claude-sonnet-4", - "temperature": 0.3 - }, - "OpenCode-Builder": { - "model": "anthropic/claude-opus-4" - }, - "Prometheus (Planner)": { - "model": "openai/gpt-5.2" - }, - "Metis (Plan Consultant)": { - "model": "anthropic/claude-sonnet-4-6" - } - } -} -``` - -| Option | Default | Description | -| ------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| `disabled` | `false` | When `true`, disables all Sisyphus orchestration and restores original build/plan as primary. | -| `default_builder_enabled` | `false` | When `true`, enables OpenCode-Builder agent (same as OpenCode build, renamed due to SDK limitations). Disabled by default. | -| `planner_enabled` | `true` | When `true`, enables Prometheus (Planner) agent with work-planner methodology. Enabled by default. | -| `replace_plan` | `true` | When `true`, demotes default plan agent to subagent mode. Set to `false` to keep both Prometheus (Planner) and default plan available. | +Sisyphus agents can also be customized under `agents` using their names: `Sisyphus`, `OpenCode-Builder`, `Prometheus (Planner)`, `Metis (Plan Consultant)`. ## Background Tasks -Configure concurrency limits for background agent tasks. This controls how many parallel background agents can run simultaneously. - ```json { "background_task": { "defaultConcurrency": 5, "staleTimeoutMs": 180000, - "providerConcurrency": { - "anthropic": 3, - "openai": 5, - "google": 10 - }, - "modelConcurrency": { - "anthropic/claude-opus-4-6": 2, - "google/gemini-3-flash": 10 - } + "providerConcurrency": { "anthropic": 3, "openai": 5, "google": 10 }, + "modelConcurrency": { "anthropic/claude-opus-4-6": 2 } } } ``` -| Option | Default | Description | -| --------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- | -| `defaultConcurrency` | - | Default maximum concurrent background tasks for all providers/models | -| `staleTimeoutMs` | `180000` | Stale timeout in milliseconds - interrupt tasks with no activity for this duration (minimum: 60000 = 1 minute) | -| `providerConcurrency` | - | Per-provider concurrency limits. Keys are provider names (e.g., `anthropic`, `openai`, `google`) | -| `modelConcurrency` | - | Per-model concurrency limits. Keys are full model names (e.g., `anthropic/claude-opus-4-6`). Overrides provider limits. | +| Option | Default | Description | +| --- | --- | --- | +| `defaultConcurrency` | - | Max concurrent tasks (all providers) | +| `staleTimeoutMs` | `180000` | Interrupt tasks with no activity (min: 60000) | +| `providerConcurrency` | - | Per-provider limits (key = provider name) | +| `modelConcurrency` | - | Per-model limits (key = `provider/model`). Overrides provider limits. | -**Priority Order**: `modelConcurrency` > `providerConcurrency` > `defaultConcurrency` - -**Use Cases**: -- Limit expensive models (e.g., Opus) to prevent cost spikes -- Allow more concurrent tasks for fast/cheap models (e.g., Gemini Flash) -- Respect provider rate limits by setting provider-level caps +Priority: `modelConcurrency` > `providerConcurrency` > `defaultConcurrency` ## Runtime Fallback -Automatically switch to backup models when the primary model encounters retryable API errors (rate limits, overload, etc.) or provider key misconfiguration errors (for example, missing API key). This keeps conversations running without manual intervention. +Auto-switches to backup models on API errors. ```json { @@ -679,122 +349,59 @@ Automatically switch to backup models when the primary model encounters retryabl } ``` -| Option | Default | Description | -| ----------------------- | ---------------------- | --------------------------------------------------------------------------- | -| `enabled` | `true` | Enable runtime fallback | -| `retry_on_errors` | `[400, 429, 503, 529]` | HTTP status codes that trigger fallback (rate limit, service unavailable). Also supports certain classified provider errors (for example, missing API key) that do not expose HTTP status codes. | -| `max_fallback_attempts` | `3` | Maximum fallback attempts per session (1-20) | -| `cooldown_seconds` | `60` | Cooldown in seconds before retrying a failed model | -| `timeout_seconds` | `30` | Timeout in seconds for an in-flight fallback request before forcing the next fallback model. **Set to `0` to disable auto-retry signal detection** (see below). | -| `notify_on_fallback` | `true` | Show toast notification when switching to a fallback model | +| Option | Default | Description | +| --- | --- | --- | +| `enabled` | `true` | Enable runtime fallback | +| `retry_on_errors` | `[400,429,503,529]` | HTTP codes that trigger fallback. Also handles classified provider key errors. | +| `max_fallback_attempts` | `3` | Max fallback attempts per session (1–20) | +| `cooldown_seconds` | `60` | Seconds before retrying a failed model | +| `timeout_seconds` | `30` | Seconds before forcing next fallback. **Set to `0` to disable timeout-based escalation and provider retry message detection.** | +| `notify_on_fallback` | `true` | Toast notification on model switch | -### timeout_seconds: Understanding the 0 Value - -**IMPORTANT**: Setting `timeout_seconds: 0` **disables auto-retry signal detection**. This is a critical behavior change: - -| Setting | Behavior | -|---------|----------| -| `timeout_seconds: 30` (default) | **Full fallback coverage**: Error-based fallback (429, 503, etc.) + auto-retry signal detection (provider messages like "retrying in 8h") | -| `timeout_seconds: 0` | **Limited fallback**: Only error-based fallback works. Provider retry messages are **completely ignored**. Timeout-based escalation is **disabled**. | - -**When `timeout_seconds: 0`:** -- HTTP errors (429, 503, 529) still trigger fallback -- Provider key errors (missing API key) still trigger fallback -- Provider retry messages ("retrying in Xh") are **ignored** -- Timeout-based escalation is **disabled** -- Hanging requests do **not** advance to the next fallback model - -**Recommendation**: Use a non-zero value (e.g., `30` seconds) to enable full fallback coverage. Only set to `0` if you explicitly want to disable auto-retry signal detection. - -### How It Works - -1. When an API error matching `retry_on_errors` occurs (or a classified provider key error such as missing API key), the hook intercepts it -2. The next request automatically uses the next available model from `fallback_models` -3. Failed models enter a cooldown period before being retried -4. If `timeout_seconds > 0` and a fallback provider hangs, timeout advances to the next fallback model -5. Toast notification (optional) informs you of the model switch - -### Configuring Fallback Models - -Define `fallback_models` at the agent or category level: +Define `fallback_models` per agent or category: ```json { "agents": { "sisyphus": { - "model": "anthropic/claude-opus-4-5", + "model": "anthropic/claude-opus-4-6", "fallback_models": ["openai/gpt-5.2", "google/gemini-3-pro"] } - }, - "categories": { - "ultrabrain": { - "model": "openai/gpt-5.2-codex", - "fallback_models": ["anthropic/claude-opus-4-5", "google/gemini-3-pro"] - } } } ``` -When the primary model fails: -1. First fallback: `openai/gpt-5.2` -2. Second fallback: `google/gemini-3-pro` -3. After `max_fallback_attempts`, returns to primary model - ## Hooks -Disable specific built-in hooks via `disabled_hooks` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: +Disable built-in hooks via `disabled_hooks`: ```json -{ - "disabled_hooks": ["comment-checker", "agent-usage-reminder"] -} +{ "disabled_hooks": ["comment-checker", "agent-usage-reminder"] } ``` Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`, `preemptive-compaction`, `auto-slash-command`, `sisyphus-junior-notepad`, `no-sisyphus-gpt`, `start-work`, `runtime-fallback` -**Note on `directory-agents-injector`**: This hook is **automatically disabled** when running on OpenCode 1.1.37+ because OpenCode now has native support for dynamically resolving AGENTS.md files from subdirectories (PR #10678). This prevents duplicate AGENTS.md injection. For older OpenCode versions, the hook remains active to provide the same functionality. - -**Note on `no-sisyphus-gpt`**: Disabling this hook is **STRONGLY discouraged**. Sisyphus is NOT optimized for GPT models — running Sisyphus with GPT performs worse than vanilla Codex and wastes your money. This hook automatically switches to Hephaestus when a GPT model is detected, which is the correct agent for GPT. Only disable this if you fully understand the consequences. - -**Note on `auto-update-checker` and `startup-toast`**: The `startup-toast` hook is a sub-feature of `auto-update-checker`. To disable only the startup toast notification while keeping update checking enabled, add `"startup-toast"` to `disabled_hooks`. To disable all update checking features (including the toast), add `"auto-update-checker"` to `disabled_hooks`. +**Notes:** +- `directory-agents-injector` — auto-disabled on OpenCode 1.1.37+ (native AGENTS.md support) +- `no-sisyphus-gpt` — **do not disable**. Sisyphus is not optimized for GPT; this hook switches to Hephaestus automatically. +- `startup-toast` is a sub-feature of `auto-update-checker`. Disable just the toast by adding `startup-toast` to `disabled_hooks`. ## Hashline Edit -Oh My OpenCode replaces OpenCode's built-in `Edit` tool with a hash-anchored version that uses `LINE#ID` references (e.g. `5#VK`) instead of bare line numbers. This prevents stale-line edits by validating content hash before applying each change. - -Enabled by default. Set `hashline_edit: false` to opt out and restore standard file editing. +Replaces the built-in `Edit` tool with a hash-anchored version using `LINE#ID` references to prevent stale-line edits. Enabled by default. ```json -{ - "hashline_edit": false -} +{ "hashline_edit": false } ``` -| Option | Default | Description | -|--------|---------|-------------| -| `hashline_edit` | `true` | Enable hash-anchored `Edit` tool and companion hooks. When `false`, falls back to standard editing without hash validation. | - -When enabled, two companion hooks are also active: - -- **`hashline-read-enhancer`** — Appends `LINE#ID:content` annotations to `Read` output so agents always have fresh anchors. -- **`hashline-edit-diff-enhancer`** — Shows a unified diff in `Edit` / `Write` output for immediate change visibility. - -To disable only the hooks while keeping the hash-anchored Edit tool: - -```json -{ - "disabled_hooks": ["hashline-read-enhancer", "hashline-edit-diff-enhancer"] -} -``` +When enabled, two companion hooks are active: `hashline-read-enhancer` (annotates Read output) and `hashline-edit-diff-enhancer` (shows diffs). Disable them individually via `disabled_hooks`. ## Commands -Disable specific built-in commands via `disabled_commands` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: +Disable built-in commands via `disabled_commands`: ```json -{ - "disabled_commands": ["init-deep", "start-work"] -} +{ "disabled_commands": ["init-deep", "start-work"] } ``` Available commands: `init-deep`, `start-work` @@ -803,56 +410,20 @@ Available commands: `init-deep`, `start-work` ### Browser Automation -Choose between two browser automation providers: +| Provider | Interface | Installation | +| --- | --- | --- | +| `playwright` (default) | MCP tools | Auto-installed via npx | +| `agent-browser` | Bash CLI | `bun add -g agent-browser && agent-browser install` | -| Provider | Interface | Features | Installation | -|----------|-----------|----------|--------------| -| **playwright** (default) | MCP tools | Playwright MCP server with structured tool calls | Auto-installed via npx | -| **agent-browser** | Bash CLI | Vercel's CLI with session management, parallel browsers | Requires `bun add -g agent-browser` | - -**Switch providers** via `browser_automation_engine` in `oh-my-opencode.json`: +Switch provider: ```json -{ - "browser_automation_engine": { - "provider": "agent-browser" - } -} +{ "browser_automation_engine": { "provider": "agent-browser" } } ``` -#### Playwright (Default) +### Tmux -Uses the official Playwright MCP server (`@playwright/mcp`). Browser automation happens through structured MCP tool calls. - -#### agent-browser - -Uses [Vercel's agent-browser CLI](https://github.com/vercel-labs/agent-browser). Key advantages: -- **Session management**: Run multiple isolated browser instances with `--session` flag -- **Persistent profiles**: Keep browser state across restarts with `--profile` -- **Snapshot-based workflow**: Get element refs via `snapshot -i`, interact with `@e1`, `@e2`, etc. -- **CLI-first**: All commands via Bash - great for scripting - -**Installation required**: -```bash -bun add -g agent-browser -agent-browser install # Download Chromium -``` - -**Example workflow**: -```bash -agent-browser open https://example.com -agent-browser snapshot -i # Get interactive elements with refs -agent-browser fill @e1 "user@example.com" -agent-browser click @e2 -agent-browser screenshot result.png -agent-browser close -``` - -### Tmux Integration - -Run background subagents in separate tmux panes for **visual multi-agent execution**. See your agents working in parallel, each in their own terminal pane. - -**Enable tmux integration** via `tmux` in `oh-my-opencode.json`: +Run background subagents in separate tmux panes. Requires running inside tmux with `opencode --port `. ```json { @@ -867,267 +438,43 @@ Run background subagents in separate tmux panes for **visual multi-agent executi ``` | Option | Default | Description | -|--------|---------|-------------| -| `enabled` | `false` | Enable tmux subagent pane spawning. Only works when running inside an existing tmux session. | -| `layout` | `main-vertical` | Tmux layout for agent panes. See [Layout Options](#layout-options) below. | -| `main_pane_size` | `60` | Main pane size as percentage (20-80). | -| `main_pane_min_width` | `120` | Minimum width for main pane in columns. | -| `agent_pane_min_width` | `40` | Minimum width for each agent pane in columns. | - -#### Layout Options - -| Layout | Description | -|--------|-------------| -| `main-vertical` | Main pane left, agent panes stacked on right (default) | -| `main-horizontal` | Main pane top, agent panes stacked bottom | -| `tiled` | All panes in equal-sized grid | -| `even-horizontal` | All panes in horizontal row | -| `even-vertical` | All panes in vertical stack | - -#### Requirements - -1. **Must run inside tmux**: The feature only activates when OpenCode is already running inside a tmux session -2. **Tmux installed**: Requires tmux to be available in PATH -3. **Server mode**: OpenCode must run with `--port` flag to enable subagent pane spawning - -#### How It Works - -When `tmux.enabled` is `true` and you are inside a tmux session: -- Background agents (via `task(run_in_background=true)`) spawn in new tmux panes -- Each pane shows the subagent's real-time output -- Panes are automatically closed when the subagent completes -- Layout is automatically adjusted based on your configuration - -#### Running OpenCode with Tmux Subagent Support - -To enable tmux subagent panes, OpenCode must run in **server mode** with the `--port` flag. This starts an HTTP server that subagent panes connect to via `opencode attach`. - -**Basic setup**: -```bash -# Start tmux session -tmux new -s dev - -# Run OpenCode with server mode (port 4096) -opencode --port 4096 - -# Now background agents will appear in separate panes -``` - -**Recommended: Shell Function** - -For convenience, create a shell function that automatically handles tmux sessions and port allocation. Here is an example for Fish shell: - -```fish -# ~/.config/fish/config.fish -function oc - set base_name (basename (pwd)) - set path_hash (echo (pwd) | md5 | cut -c1-4) - set session_name "$base_name-$path_hash" - - # Find available port starting from 4096 - function __oc_find_port - set port 4096 - while test $port -lt 5096 - if not lsof -i :$port >/dev/null 2>&1 - echo $port - return 0 - end - set port (math $port + 1) - end - echo 4096 - end - - set oc_port (__oc_find_port) - set -x OPENCODE_PORT $oc_port - - if set -q TMUX - # Already inside tmux - just run with port - opencode --port $oc_port $argv - else - # Create tmux session and run opencode - set oc_cmd "OPENCODE_PORT=$oc_port opencode --port $oc_port $argv; exec fish" - if tmux has-session -t "$session_name" 2>/dev/null - tmux new-window -t "$session_name" -c (pwd) "$oc_cmd" - tmux attach-session -t "$session_name" - else - tmux new-session -s "$session_name" -c (pwd) "$oc_cmd" - end - end - - functions -e __oc_find_port -end -``` - -**Bash/Zsh equivalent**: - -```bash -# ~/.bashrc or ~/.zshrc -oc() { - local base_name=$(basename "$PWD") - local path_hash=$(echo "$PWD" | md5sum | cut -c1-4) - local session_name="${base_name}-${path_hash}" - - # Find available port - local port=4096 - while [ $port -lt 5096 ]; do - if ! lsof -i :$port >/dev/null 2>&1; then - break - fi - port=$((port + 1)) - done - - export OPENCODE_PORT=$port - - if [ -n "$TMUX" ]; then - opencode --port $port "$@" - else - local oc_cmd="OPENCODE_PORT=$port opencode --port $port $*; exec $SHELL" - if tmux has-session -t "$session_name" 2>/dev/null; then - tmux new-window -t "$session_name" -c "$PWD" "$oc_cmd" - tmux attach-session -t "$session_name" - else - tmux new-session -s "$session_name" -c "$PWD" "$oc_cmd" - fi - fi -} -``` - -**How subagent panes work**: - -1. Main OpenCode starts HTTP server on specified port (e.g., `http://localhost:4096`) -2. When a background agent spawns, Oh My OpenCode creates a new tmux pane -3. The pane runs: `opencode attach http://localhost:4096 --session ` -4. Each subagent pane shows real-time streaming output -5. Panes are automatically closed when the subagent completes - -**Environment variables**: - -| Variable | Description | -|----------|-------------| -| `OPENCODE_PORT` | Default port for the HTTP server (used if `--port` not specified) | - -**Server Mode Reference** - -OpenCode's server mode exposes an HTTP API for programmatic interaction: - -```bash -# Standalone server (no TUI) -opencode serve --port 4096 - -# TUI with server (recommended for tmux integration) -opencode --port 4096 -``` - -| Flag | Default | Description | -|------|---------|-------------| -| `--port` | `4096` | Port for HTTP server | -| `--hostname` | `127.0.0.1` | Hostname to listen on | - -For more details, see the [OpenCode Server documentation](https://opencode.ai/docs/server/). +| --- | --- | --- | +| `enabled` | `false` | Enable tmux pane spawning | +| `layout` | `main-vertical` | `main-vertical` / `main-horizontal` / `tiled` / `even-horizontal` / `even-vertical` | +| `main_pane_size` | `60` | Main pane % (20–80) | +| `main_pane_min_width` | `120` | Min main pane columns | +| `agent_pane_min_width` | `40` | Min agent pane columns | ### Git Master -Configure git-master skill behavior: - ```json -{ - "git_master": { - "commit_footer": true, - "include_co_authored_by": true - } -} +{ "git_master": { "commit_footer": true, "include_co_authored_by": true } } ``` -| Option | Default | Description | -| ------------------------ | ------- | -------------------------------------------------------------------------------- | -| `commit_footer` | `true` | Adds "Ultraworked with Sisyphus" footer to commit messages. | -| `include_co_authored_by` | `true` | Adds `Co-authored-by: Sisyphus ` trailer to commits. | - ### Comment Checker -Configure comment-checker hook behavior. The comment checker warns when excessive comments are added to code. - ```json -{ - "comment_checker": { - "custom_prompt": "Your custom warning message. Use {{comments}} placeholder for detected comments XML." - } -} +{ "comment_checker": { "custom_prompt": "Your message. Use {{comments}} placeholder." } } ``` -| Option | Default | Description | -| ------------- | ------- | -------------------------------------------------------------------------- | -| `custom_prompt` | - | Custom warning message to replace the default. Use `{{comments}}` placeholder. | - ### Notification -Configure notification behavior for background task completion. - ```json -{ - "notification": { - "force_enable": true - } -} +{ "notification": { "force_enable": true } } ``` -| Option | Default | Description | -| -------------- | ------- | ---------------------------------------------------------------------------------------------- | -| `force_enable` | `false` | Force enable session-notification even if external notification plugins are detected. Default: `false`. | +`force_enable` (`false`) — force session-notification even if external notification plugins are detected. ### MCPs -Exa, Context7 and grep.app MCP enabled by default. - -- **websearch**: Real-time web search powered by [Exa AI](https://exa.ai) - searches the web and returns relevant content -- **context7**: Fetches up-to-date official documentation for libraries -- **grep_app**: Ultra-fast code search across millions of public GitHub repositories via [grep.app](https://grep.app) - -Do not want them? Disable via `disabled_mcps` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: +Built-in MCPs (enabled by default): `websearch` (Exa AI), `context7` (library docs), `grep_app` (GitHub code search). ```json -{ - "disabled_mcps": ["websearch", "context7", "grep_app"] -} +{ "disabled_mcps": ["websearch", "context7", "grep_app"] } ``` ### LSP -OpenCode provides LSP tools for analysis. -Oh My OpenCode adds refactoring tools (rename, code actions). -All OpenCode LSP configs and custom settings (from `opencode.jsonc` / `opencode.json`) are supported, plus additional Oh My OpenCode-specific settings. -For config discovery, `.jsonc` takes precedence over `.json` when both exist (applies to both `opencode.*` and `oh-my-opencode.*`). - -Add LSP servers via the `lsp` option in `~/.config/opencode/oh-my-opencode.jsonc` / `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.jsonc` / `.opencode/oh-my-opencode.json`: - -```json -{ - "lsp": { - "typescript-language-server": { - "command": ["typescript-language-server", "--stdio"], - "extensions": [".ts", ".tsx"], - "priority": 10 - }, - "pylsp": { - "disabled": true - } - } -} -``` - -Each server supports: `command`, `extensions`, `priority`, `env`, `initialization`, `disabled`. - -| Option | Type | Default | Description | -| -------------- | -------- | ------- | ---------------------------------------------------------------------- | -| `command` | array | - | Command to start the LSP server (executable + args) | -| `extensions` | array | - | File extensions this server handles (e.g., `[".ts", ".tsx"]`) | -| `priority` | number | - | Server priority when multiple servers match a file | -| `env` | object | - | Environment variables for the LSP server (key-value pairs) | -| `initialization`| object | - | Custom initialization options passed to the LSP server | -| `disabled` | boolean | `false` | Whether to disable this LSP server | - -**Example with advanced options:** - ```json { "lsp": { @@ -1135,207 +482,93 @@ Each server supports: `command`, `extensions`, `priority`, `env`, `initializatio "command": ["typescript-language-server", "--stdio"], "extensions": [".ts", ".tsx"], "priority": 10, - "env": { - "NODE_OPTIONS": "--max-old-space-size=4096" - }, - "initialization": { - "preferences": { - "includeInlayParameterNameHints": "all", - "includeInlayFunctionParameterTypeHints": true - } - } - } + "env": { "NODE_OPTIONS": "--max-old-space-size=4096" }, + "initialization": { "preferences": { "includeInlayParameterNameHints": "all" } } + }, + "pylsp": { "disabled": true } } } ``` +| Option | Type | Description | +| --- | --- | --- | +| `command` | array | Command to start LSP server | +| `extensions` | array | File extensions (e.g. `[".ts"]`) | +| `priority` | number | Priority when multiple servers match | +| `env` | object | Environment variables | +| `initialization` | object | Init options passed to server | +| `disabled` | boolean | Disable this server | + ## Experimental -Opt-in experimental features that may change or be removed in future versions. Use with caution. - ```json { "experimental": { - "truncate_all_tool_outputs": true, - "aggressive_truncation": true, - "auto_resume": true, + "truncate_all_tool_outputs": false, + "aggressive_truncation": false, + "auto_resume": false, "disable_omo_env": false, + "task_system": false, "dynamic_context_pruning": { "enabled": false, "notification": "detailed", - "turn_protection": { - "enabled": true, - "turns": 3 - }, - "protected_tools": ["task", "todowrite", "lsp_rename"], - "strategies": { - "deduplication": { - "enabled": true - }, - "supersede_writes": { - "enabled": true, - "aggressive": false - }, - "purge_errors": { - "enabled": true, - "turns": 5 - } - } - } - } -} -``` - -| Option | Default | Description | -| --------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `truncate_all_tool_outputs` | `false` | Truncates ALL tool outputs instead of just whitelisted tools (Grep, Glob, LSP, AST-grep). Tool output truncator is enabled by default - disable via `disabled_hooks`. | -| `aggressive_truncation` | `false` | When token limit is exceeded, aggressively truncates tool outputs to fit within limits. More aggressive than the default truncation behavior. Falls back to summarize/revert if insufficient. | -| `auto_resume` | `false` | Automatically resumes session after successful recovery from thinking block errors or thinking disabled violations. Extracts last user message and continues. | -| `disable_omo_env` | `false` | When `true`, disables auto-injected `` block generation (date, time, timezone, locale). When unset or `false`, current behavior is preserved. Setting this to `true` will improve the cache hit rate and reduce the API cost. | -| `dynamic_context_pruning` | See below | Dynamic context pruning configuration for managing context window usage automatically. See [Dynamic Context Pruning](#dynamic-context-pruning) below. | - -### Dynamic Context Pruning - -Dynamic context pruning automatically manages context window by intelligently pruning old tool outputs. This feature helps maintain performance in long sessions. - -```json -{ - "experimental": { - "dynamic_context_pruning": { - "enabled": false, - "notification": "detailed", - "turn_protection": { - "enabled": true, - "turns": 3 - }, + "turn_protection": { "enabled": true, "turns": 3 }, "protected_tools": ["task", "todowrite", "todoread", "lsp_rename", "session_read", "session_write", "session_search"], "strategies": { - "deduplication": { - "enabled": true - }, - "supersede_writes": { - "enabled": true, - "aggressive": false - }, - "purge_errors": { - "enabled": true, - "turns": 5 - } + "deduplication": { "enabled": true }, + "supersede_writes": { "enabled": true, "aggressive": false }, + "purge_errors": { "enabled": true, "turns": 5 } } } } } ``` -| Option | Default | Description | -| ----------------- | ------- | ----------------------------------------------------------------------------------------- | -| `enabled` | `false` | Enable dynamic context pruning | -| `notification` | `detailed` | Notification level: `off`, `minimal`, or `detailed` | -| `turn_protection` | See below | Turn protection settings - prevent pruning recent tool outputs | - -#### Turn Protection - -| Option | Default | Description | -| --------- | ------- | ------------------------------------------------------------ | -| `enabled` | `true` | Enable turn protection | -| `turns` | `3` | Number of recent turns to protect from pruning (1-10) | - -#### Protected Tools - -Tools that should never be pruned (default): - -```json -["task", "todowrite", "todoread", "lsp_rename", "session_read", "session_write", "session_search"] -``` - -#### Pruning Strategies - -| Strategy | Option | Default | Description | -| ------------------- | ------------ | ------- | ---------------------------------------------------------------------------- | -| **deduplication** | `enabled` | `true` | Remove duplicate tool calls (same tool + same args) | -| **supersede_writes**| `enabled` | `true` | Prune write inputs when file subsequently read | -| | `aggressive` | `false` | Aggressive mode: prune any write if ANY subsequent read | -| **purge_errors** | `enabled` | `true` | Prune errored tool inputs after N turns | -| | `turns` | `5` | Number of turns before pruning errors (1-20) | - -**Warning**: These features are experimental and may cause unexpected behavior. Enable only if you understand the implications. +| Option | Default | Description | +| --- | --- | --- | +| `truncate_all_tool_outputs` | `false` | Truncate all tool outputs (not just whitelisted) | +| `aggressive_truncation` | `false` | Aggressively truncate when token limit exceeded | +| `auto_resume` | `false` | Auto-resume after thinking block recovery | +| `disable_omo_env` | `false` | Disable auto-injected `` block (date/time/locale). Improves cache hit rate. | +| `task_system` | `false` | Enable Sisyphus task system | +| `dynamic_context_pruning.enabled` | `false` | Auto-prune old tool outputs to manage context window | +| `dynamic_context_pruning.notification` | `detailed` | Pruning notifications: `off` / `minimal` / `detailed` | +| `turn_protection.turns` | `3` | Recent turns protected from pruning (1–10) | +| `strategies.deduplication` | `true` | Remove duplicate tool calls | +| `strategies.supersede_writes` | `true` | Prune write inputs when file later read | +| `strategies.supersede_writes.aggressive` | `false` | Prune any write if ANY subsequent read exists | +| `strategies.purge_errors.turns` | `5` | Turns before pruning errored tool inputs | ## Environment Variables -| Variable | Description | -| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| `OPENCODE_CONFIG_DIR` | Override the OpenCode configuration directory. Useful for profile isolation with tools like [OCX](https://github.com/kdcokenny/ocx) ghost mode. | +| Variable | Description | +| --- | --- | +| `OPENCODE_CONFIG_DIR` | Override OpenCode config directory (useful for profile isolation) | ## Provider-Specific ### Google Auth -**Recommended**: For Google Gemini authentication, install the [`opencode-antigravity-auth`](https://github.com/NoeFabris/opencode-antigravity-auth) plugin (`@latest`). It provides multi-account load balancing, variant-based thinking levels, dual quota system (Antigravity + Gemini CLI), and active maintenance. See [Installation > Google Gemini](../guide/installation.md#google-gemini-antigravity-oauth). +Install [`opencode-antigravity-auth`](https://github.com/NoeFabris/opencode-antigravity-auth) for Google Gemini. Provides multi-account load balancing, dual quota, and variant-based thinking. -### Ollama Provider +### Ollama -**IMPORTANT**: When using Ollama as a provider, you **must** disable streaming to avoid JSON parsing errors. - -#### Required Configuration +**Must** disable streaming to avoid JSON parse errors: ```json { "agents": { - "explore": { - "model": "ollama/qwen3-coder", - "stream": false - } + "explore": { "model": "ollama/qwen3-coder", "stream": false } } } ``` -#### Why `stream: false` is Required +Common models: `ollama/qwen3-coder`, `ollama/ministral-3:14b`, `ollama/lfm2.5-thinking` -Ollama returns NDJSON (newline-delimited JSON) when streaming is enabled, but Claude Code SDK expects a single JSON object. This causes `JSON Parse error: Unexpected EOF` when agents attempt tool calls. - -**Example of the problem**: -```json -// Ollama streaming response (NDJSON - multiple lines) -{"message":{"tool_calls":[...]}, "done":false} -{"message":{"content":""}, "done":true} - -// Claude Code SDK expects (single JSON object) -{"message":{"tool_calls":[...], "content":""}, "done":true} -``` - -#### Supported Models - -Common Ollama models that work with oh-my-opencode: - -| Model | Best For | Configuration | -|-------|----------|---------------| -| `ollama/qwen3-coder` | Code generation, build fixes | `{"model": "ollama/qwen3-coder", "stream": false}` | -| `ollama/ministral-3:14b` | Exploration, codebase search | `{"model": "ollama/ministral-3:14b", "stream": false}` | -| `ollama/lfm2.5-thinking` | Documentation, writing | `{"model": "ollama/lfm2.5-thinking", "stream": false}` | - -#### Troubleshooting - -If you encounter `JSON Parse error: Unexpected EOF`: - -1. **Verify `stream: false` is set** in your agent configuration -2. **Check Ollama is running**: `curl http://localhost:11434/api/tags` -3. **Test with curl**: - ```bash - curl -s http://localhost:11434/api/chat \ - -d '{"model": "qwen3-coder", "messages": [{"role": "user", "content": "Hello"}], "stream": false}' - ``` -4. **See detailed troubleshooting**: [Ollama Troubleshooting](../troubleshooting/ollama.md) - -#### Future SDK Fix - -The proper long-term fix requires Claude Code SDK to parse NDJSON responses correctly. Until then, use `stream: false` as a workaround. - -**Tracking**: https://github.com/code-yeongyu/oh-my-opencode/issues/1124 +See [Ollama Troubleshooting](../troubleshooting/ollama.md) for `JSON Parse error: Unexpected EOF` issues. ### Sisyphus Tasks -Configure Sisyphus Tasks system for advanced task management. - ```json { "sisyphus": { @@ -1348,10 +581,8 @@ Configure Sisyphus Tasks system for advanced task management. } ``` -#### Tasks Configuration - -| Option | Default | Description | -| -------------------- | ------------------ | ------------------------------------------------------------------------- | -| `enabled` | `false` | Enable Sisyphus Tasks system | -| `storage_path` | `.sisyphus/tasks` | Storage path for tasks (relative to project root) | -| `claude_code_compat` | `false` | Enable Claude Code path compatibility mode | +| Option | Default | Description | +| --- | --- | --- | +| `enabled` | `false` | Enable Sisyphus Tasks system | +| `storage_path` | `.sisyphus/tasks` | Storage path (relative to project root) | +| `claude_code_compat` | `false` | Enable Claude Code path compatibility mode |