The src/config/ module is responsible for:
Multi-Source Configuration Merging
~/.config/opencode/oh-my-opencode-slim.json (or $XDG_CONFIG_HOME)<directory>/.opencode/oh-my-opencode-slim.jsonOH_MY_OPENCODE_SLIM_PRESETPreset System
Wildcard/Exclusion Syntax
"*" (all) and "!item" (exclude) syntaxparseList() function for flexible filteringBackward Compatibility
explore → explorer)getAgentOverride() checks both current name and aliasesConfiguration Schema Hierarchy
PluginConfig
├── preset?: string
├── presets?: Record<string, Preset>
├── agents?: Record<string, AgentOverrideConfig>
├── disabled_mcps?: string[]
├── tmux?: TmuxConfig
└── background?: BackgroundTaskConfig
AgentOverrideConfig
├── model?: string
├── temperature?: number
├── variant?: string
├── skills?: string[]
└── mcps?: string[]
TmuxConfig
├── enabled: boolean
├── layout: TmuxLayout
└── main_pane_size: number
Agent Names
ORCHESTRATOR_NAME: 'orchestrator'SUBAGENT_NAMES: ['explorer', 'librarian', 'oracle', 'designer', 'fixer']ALL_AGENT_NAMES: All agents combinedAGENT_ALIASES: Legacy name mappingsTypeScript Types
PluginConfig: Main configuration objectAgentOverrideConfig: Per-agent configuration overridesTmuxConfig: Tmux integration settingsTmuxLayout: Layout enum (main-horizontal, main-vertical, tiled, even-horizontal, even-vertical)Preset: Named agent configuration presetsAgentName: Union type of all agent namesMcpName: Union type of available MCPs ('websearch', 'context7', 'grep_app')BackgroundTaskConfig: Background task concurrency settingsExported Functions
loadPluginConfig(directory: string): PluginConfig - Load and merge all configsloadAgentPrompt(agentName: string): { prompt?, appendPrompt? } - Load custom promptsgetAgentOverride(config, name): AgentOverrideConfig | undefined - Get agent config with alias supportparseList(items, allAvailable): string[] - Parse wildcard/exclusion listsgetAvailableMcpNames(config?): string[] - Get enabled MCPsgetAgentMcpList(agentName, config?): string[] - Get MCPs for specific agentloadPluginConfig(directory)
│
├─→ Load user config from ~/.config/opencode/oh-my-opencode-slim.json
│ └─→ Validate with PluginConfigSchema
│ └─→ Return null if invalid/missing
│
├─→ Load project config from <directory>/.opencode/oh-my-opencode-slim.json
│ └─→ Validate with PluginConfigSchema
│ └─→ Return null if invalid/missing
│
├─→ Deep merge configs (project overrides user)
│ ├─→ Top-level: project replaces user
│ └─→ Nested (agents, tmux): deep merge
│
├─→ Apply environment preset override (OH_MY_OPENCODE_SLIM_PRESET)
│
└─→ Resolve and merge preset
├─→ Find preset in config.presets[preset]
├─→ Deep merge preset agents with root agents
└─→ Warn if preset not found
loadAgentPrompt(agentName, preset?)
│
├─→ Build prompt search dirs
│ ├─→ If preset is safe (`[a-zA-Z0-9_-]+`):
│ │ 1) ~/.config/opencode/oh-my-opencode-slim/{preset}
│ │ 2) ~/.config/opencode/oh-my-opencode-slim
│ └─→ Otherwise:
│ 1) ~/.config/opencode/oh-my-opencode-slim
│
├─→ Read first existing {agentName}.md from search dirs
│ └─→ If found → replacement prompt
│
└─→ Read first existing {agentName}_append.md from search dirs
└─→ If found → append prompt
getAgentMcpList(agentName, config)
│
├─→ Get agent override config (with alias support)
│
├─→ If agent has explicit mcps config
│ └─→ Return parseList(agent.mcps, availableMcps)
│
└─→ Otherwise return DEFAULT_AGENT_MCPS[agentName]
deepMerge(base, override)
│
├─→ If base is undefined → return override
├─→ If override is undefined → return base
│
└─→ For each key in override
├─→ If both values are non-array objects
│ └─→ Recursively deepMerge
└─→ Otherwise → override replaces base
External Dependencies
zod: Runtime schema validationnode:fs, node:os, node:path: File system operationsInternal Dependencies
src/cli/config-io.ts - JSONC comment stripping utilityDirect Consumers
src/index.ts - Main plugin entry pointsrc/skills/ - Agent skill implementationssrc/agent/ - Agent configuration and initializationConfiguration Usage Patterns
Plugin Initialization
const config = loadPluginConfig(projectDir);
Agent Configuration
const agentOverride = getAgentOverride(config, agentName);
const model = agentOverride?.model ?? DEFAULT_MODELS[agentName];
MCP Assignment
const mcps = getAgentMcpList(agentName, config);
Prompt Customization
const { prompt, appendPrompt } = loadAgentPrompt(agentName, config?.preset);
Polling Configuration
POLL_INTERVAL_MS (500ms): Standard polling intervalPOLL_INTERVAL_SLOW_MS (1000ms): Slower polling for background tasksPOLL_INTERVAL_BACKGROUND_MS (2000ms): Background task pollingTimeouts
DEFAULT_TIMEOUT_MS (2 minutes): Default operation timeoutMAX_POLL_TIME_MS (5 minutes): Maximum polling durationStability
STABLE_POLLS_THRESHOLD (3): Number of stable polls before considering state settled| Agent | Default MCPs |
|---|---|
| orchestrator | ['websearch'] |
| designer | [] |
| oracle | [] |
| librarian | ['websearch', 'context7', 'grep_app'] |
| explorer | [] |
| fixer | [] |
| Agent | Model |
|---|---|
| orchestrator | runtime-resolved |
| oracle | openai/gpt-5.4 |
| librarian | openai/gpt-5.4-mini |
| explorer | openai/gpt-5.4-mini |
| designer | openai/gpt-5.4-mini |
| fixer | openai/gpt-5.4-mini |
src/config/
├── index.ts # Public API exports
├── loader.ts # Config loading and merging logic
├── schema.ts # Zod schemas and TypeScript types
├── constants.ts # Agent names, defaults, timeouts
├── utils.ts # Helper functions (agent overrides)
└── agent-mcps.ts # MCP configuration and resolution
Configuration Loading
Prompt Loading
Preset Resolution
Adding New Agents
SUBAGENT_NAMES in constants.tsDEFAULT_MODELSDEFAULT_AGENT_MCPS in agent-mcps.tsAdding New MCPs
McpNameSchema enum in schema.tsDEFAULT_AGENT_MCPS as neededAdding New Configuration Options
PluginConfigSchema in schema.tsloader.ts if nested