This guide is for administrators, platform engineers, and developers who need to deploy, configure, secure, extend, or understand the internals of oh-my-opencode (package oh-my-opencode, also oh-my-openagent, invoked as omo). It is the deep companion to the User Guide — every configuration option, the system architecture, the security model, operational procedures, and a developer-level map of the codebase.
oh-my-opencode is a Bun/TypeScript monorepo (v4.7.5) authored by YeonGyu-Kim. It ships two harness adapters from one engine: an OpenCode plugin (plugin id oh-my-openagent) and a Codex plugin (omo-codex, branded LazyCodex).
1. Executive Summary
| Aspect | Summary |
|---|---|
| What it is | A "batteries-included" agent harness layered onto OpenCode/Codex: agents, parallel background workers, multi-model routing with fallback, LSP/AST tools, hash-anchored editing, orchestration modes, team mode, and ~58 lifecycle hooks. |
| Form factor | A host-loaded plugin, not a service. It runs inside the OpenCode/Codex process on the developer's machine. There is no server you operate; "deployment" means installing and configuring the plugin. |
| Runtime | Bun (bundled in prebuilt platform binaries) + Node.js ≥ 20 for the CLI installer and Codex components. |
| Distribution | npm package with per-platform prebuilt binaries as optional dependencies. Bin aliases: oh-my-opencode, oh-my-openagent, omo, lazycodex, lazycodex-ai. |
| Configuration | A strictly-validated (zod) oh-my-opencode.jsonc/.json file in the OpenCode config dir and/or per-project .opencode/. |
| Telemetry | Anonymous daily-active event to PostHog; no prompts/content/hostnames. Fully opt-out via env vars. |
| License | Root: SUL-1.0. Codex components and platform binaries: MIT. |
Operational reality: because oh-my-opencode runs in-process on each user's machine, the administrator's job is (1) establishing a known-good configuration, (2) controlling which features/models are enabled, (3) managing model access and fallback, and (4) supporting users via omo doctor. There is no central database, message broker, or backend to run.
2. Architecture
2.1 High-level
Developer machine
┌──────────────────────────────────────────────────────────────┐
│ OpenCode (host) │
│ └── oh-my-opencode plugin (id: "oh-my-openagent") │
│ server() bootstrap │
│ ├── loadPluginConfig() ← oh-my-opencode.jsonc │
│ ├── createManagers() │
│ │ ├── BackgroundManager (parallel sub-agents) │
│ │ ├── TmuxSessionManager (panes for team/bg) │
│ │ ├── SkillMcpManager (skill-backed MCP) │
│ │ └── ConfigHandler (agents/models/tools) │
│ ├── createTools() → tool registry (filtered) │
│ ├── createHooks() → core + continuation + skill │
│ └── createPluginInterface() │
│ │
│ Bundled MCP servers (spawned as needed): │
│ ast-grep (omo-ast-grep) · git-bash (omo-git-bash) · lsp │
│ context7 · grep_app · websearch (exa/tavily) │
└──────────────────────────────────────────────────────────────┘
│ models (HTTP) │ optional
▼ ▼
Providers: Anthropic / OpenAI / Gemini OpenClaw gateway
Copilot / MiniMax / Kimi / Z.ai / … (Discord · Telegram)
The plugin's server() function (in src/index.ts → src/testing/create-plugin-module.ts) is the single entry point OpenCode calls at startup. It:
- Initializes config context and migrates any legacy workspace/config files.
- Loads and validates
oh-my-opencodeconfig. - Creates the long-lived managers (background, tmux, skill-MCP, config handler).
- Builds the tool registry (honoring
disabled_tools,max_tools, etc.). - Wires the hook set (core, continuation, and skill hooks).
- Optionally starts OpenClaw and a tmux availability check.
- Returns the plugin interface (hooks + tools) to OpenCode.
2.2 Monorepo layout
The repository is a Bun workspace. Top-level areas:
| Path | Responsibility |
|---|---|
src/ |
The OpenCode plugin engine (the bulk of the code). |
src/agents/ |
Agent definitions (Sisyphus, Atlas, Prometheus, Hephaestus, Sisyphus-Junior, …) and the dynamic prompt builder. |
src/hooks/ |
~58 lifecycle hooks (see §5). |
src/tools/ |
Custom tools (hashline-edit, look-at, grep, glob, delegate-task, background-task, session-manager, skill, task, call-omo-agent, interactive-bash). |
src/features/ |
Larger subsystems: background-agent, team-mode, tmux-subagent, skill loaders, claude-code-* loaders, context-injector, boulder-state, tool-metadata-store. |
src/cli/ |
The omo CLI (install, run, doctor, cleanup, boulder, mcp-oauth, install-codex, …). |
src/config/ |
The zod configuration schema (OhMyOpenCodeConfigSchema). |
src/mcp/ |
Built-in MCP registrations (context7, websearch, etc.). |
src/plugin/, src/plugin-handlers/ |
Plugin event handling, config/provider/tool handlers, session lifecycle. |
src/shared/ |
Cross-cutting utilities (config dir resolution, downloaders, tmux helpers, model availability, archive safety). |
src/openclaw/ |
Discord/Telegram remote control gateway. |
packages/* |
Pure-TS shared cores (model-core, prompts-core, rules-engine, hashline-core, agents-md-core, comment-checker-core, boulder-state, ast-grep-core, utils) plus MCP servers (ast-grep-mcp, git-bash-mcp, lsp-tools-mcp). |
packages/omo-codex/ |
The Codex harness adapter (LazyCodex): vendored Codex plugin namespace + TypeScript installer + telemetry. |
packages/oh-my-opencode-<platform>/ |
Per-platform prebuilt binary packages. |
packages/web/ |
The marketing/docs website (Next.js, deployed to Cloudflare). Not part of the runtime. |
script/ |
Build, packaging, publishing, and marketplace-sync scripts. |
2.3 The two harness adapters
oh-my-opencode is engineered so the same capabilities work across two different host agents:
- OpenCode plugin — the primary target. Loaded in-process via the
@opencode-ai/pluginAPI. Full feature set. - omo-codex / LazyCodex — a Codex plugin built from
packages/omo-codex. It ships as discrete Codex components (comment-checker, git-bash, lsp, rules, telemetry, start-work-continuation, ultrawork, ulw-loop), each a small Codex plugin wired through Codex'sSessionStart/UserPromptSubmit/PostToolUse/Stop/PostCompacthooks. Installed vialazycodex-ai installinto~/.codex/plugins/cache/sisyphuslabs/omo/<version>under thesisyphuslabsmarketplace.
Shared logic lives in packages/*-core so both adapters stay behavior-equivalent (cross-package equivalence is enforced by tests, e.g. telemetry constants).
2.4 Parallelism model
Heavy lifting is parallelized through the BackgroundManager (src/features/background-agent/):
- Spawns child sessions for delegated/background tasks with concurrency control (
ConcurrencyManager), per-provider/per-model concurrency caps, and a parent-wake notifier that resumes the parent when children complete. - Enforces a circuit breaker (max tool calls per sub-agent) and multiple staleness/TTL timeouts to reclaim stuck or crashed tasks.
- Detects and prevents session parent cycles and runaway subagent spawning.
When tmux is enabled, the TmuxSessionManager mirrors each child/team session into a pane for visualization and reaps zombie panes.
3. Requirements
| Component | Requirement |
|---|---|
| Host | OpenCode (primary) or OpenAI Codex CLI (LazyCodex). |
| Node.js | ≥ 20 (CLI installer; Codex components declare engines.node >= 20). |
| Runtime | Bun (embedded in prebuilt binaries; install separately only for from-source builds). |
| OS / CPU | macOS arm64/x64, Linux x64/arm64 (glibc or musl), Windows x64. "baseline" binary variants target CPUs without AVX2. |
Optional: tmux |
For team-mode / background-agent pane visualization. |
| Optional: ripgrep | Auto-downloaded by the bundled grep tool on first use. |
| Optional: language servers | For the LSP tools (e.g. typescript-language-server). |
| Model access | One or more provider subscriptions/keys (see §6.4). |
4. Configuration Mastery
4.1 Config file location and precedence
oh-my-opencode reads oh-my-opencode.jsonc (preferred) or oh-my-opencode.json from:
- The global OpenCode config directory (e.g.
~/.config/opencode/oh-my-opencode.jsonc), and - Per-project locations under the project's
.opencode/directory.
Project config is merged over global config. A legacy oh-my-openagent.jsonc/.json file is automatically migrated to the oh-my-opencode name (a .bak is left behind). The config directory is resolved by src/shared/opencode-config-dir.ts, honoring OPENCODE_CONFIG_DIR / XDG_CONFIG_HOME and OpenCode-vs-desktop build differences.
Important
The config is validated strictly by
OhMyOpenCodeConfigSchema(zod). Unknown-shaped values and out-of-range numbers are rejected, andomo doctorsurfaces the exact field. Add"$schema"pointing at the published schema (oh-my-opencode.schema.json, exported by the package as./schema.json) for editor autocompletion.
{
"$schema": "./node_modules/oh-my-opencode/dist/oh-my-opencode.schema.json",
"default_run_agent": "sisyphus",
"hashline_edit": true,
"model_fallback": true
}
4.2 Top-level configuration reference
Every top-level key of OhMyOpenCodeConfigSchema:
| Key | Type | Default | Purpose |
|---|---|---|---|
$schema |
string | — | JSON-schema reference for editor tooling. |
new_task_system_enabled |
boolean | false |
Enable the new task system. |
default_run_agent |
string | — | Default agent for omo run (env override: OPENCODE_DEFAULT_AGENT). |
agent_order |
string[] (≤64, each ≤128 chars) | — | Display order of agents in the selector. Invalid names are ignored with a toast. |
agent_definitions |
string[] | — | Paths to external agent definition files (.md/.json). |
disabled_mcps |
string[] | — | MCP server names to disable (built-in or custom). |
disabled_agents |
string[] | — | Agent names to disable. |
disabled_skills |
string[] (builtin names) | — | Built-in skills to disable. |
disabled_hooks |
string[] | — | Hook names to disable. |
disabled_commands |
string[] (builtin names) | — | Built-in commands to disable. |
disabled_tools |
string[] | — | Tools to disable, e.g. ["todowrite","todoread"]. |
disabled_providers |
string[] | — | Provider prefixes excluded from every fallback chain at load (e.g. github-copilot). |
mcp_env_allowlist |
string[] | — | Env var names allowed to pass through to MCP servers. |
hashline_edit |
boolean | false |
Enable the hashline_edit tool/hook integration. |
model_fallback |
boolean | false |
Enable automatic model switching on model errors. |
agents |
map → AgentOverride | — | Per-agent overrides (see §4.3). |
categories |
map → CategoryConfig | — | Category → model routing (see §4.4). |
claude_code |
ClaudeCodeConfig | — | Toggle import of Claude Code assets (see §4.6). |
sisyphus_agent |
SisyphusAgentConfig | — | Sisyphus builder/planner toggles. |
comment_checker |
CommentCheckerConfig | — | Custom comment-checker prompt. |
experimental |
ExperimentalConfig | — | Experimental feature flags (see §4.7). |
auto_update |
boolean | — | Enable the auto-update checker. |
skills |
SkillsConfig | — | Skill sources / enable / disable (see §4.8). |
ralph_loop |
RalphLoopConfig | — | Ralph Loop defaults (see §4.9). |
runtime_fallback |
boolean | RuntimeFallbackConfig | false |
Runtime model fallback (see §4.10). |
background_task |
BackgroundTaskConfig | — | Background/sub-agent execution tuning (see §4.11). |
notification |
NotificationConfig | — | Session-notification force-enable. |
model_capabilities |
ModelCapabilitiesConfig | — | models.dev capability refresh settings (see §4.12). |
openclaw |
OpenClawConfig | enabled:false |
Discord/Telegram remote control (see §7.3). |
i18n |
I18nConfig | — | Locale override (locale), else LANG. |
team_mode |
TeamModeConfig | enabled:false |
Multi-agent team mode (see §4.13). |
keyword_detector |
KeywordDetectorConfig | — | Enable/disable keyword expansions. |
babysitting |
BabysittingConfig | timeout_ms:120000 |
Unstable-agent babysitter timeout. |
git_master |
GitMasterConfig | see §4.14 | Commit footer / co-author / git env prefix. |
browser_automation_engine |
BrowserAutomationConfig | provider:"playwright" |
Browser automation backend. |
websearch |
WebsearchConfig | provider exa |
Web search provider (exa/tavily). |
tmux |
TmuxConfig | enabled:false |
tmux pane layout/isolation (see §4.15). |
sisyphus |
SisyphusConfig | — | Sisyphus task storage settings. |
start_work |
StartWorkConfig | auto_commit:true |
start-work auto-commit. |
default_mode |
DefaultModeConfig | both false |
Auto-activate ultrawork / ralph loop per session. |
_migrations |
string[] | — | Internal migration history (do not edit by hand). |
4.3 Agent overrides (agents)
agents maps an agent name (built-in or custom) to an override object. Built-in overridable names include sisyphus, sisyphus-junior, hephaestus, prometheus, atlas, metis, momus, oracle, librarian, explore, multimodal-looker, plus OpenCode's build/plan and OpenCode-Builder. Custom keys (e.g. "technical-writer") are also accepted.
Override fields (AgentOverrideConfigSchema):
| Field | Type | Notes |
|---|---|---|
model |
string | Deprecated — prefer category. Inherited from category if omitted. |
category |
string | Category to inherit model + settings from (preferred over model). |
fallback_models |
string | string[] | object[] | Ordered fallback chain (objects may set variant, reasoningEffort, temperature, etc.). |
variant |
string | Model variant (e.g. high). |
skills |
string[] | Skills injected into the agent prompt. |
temperature |
number 0–2 | Sampling temperature. |
top_p |
number 0–1 | Nucleus sampling. |
prompt |
string | Replace the agent prompt. |
prompt_append |
string | Append to the prompt. Supports file:// URIs (file:///abs, file://./rel, file://~/home). |
tools |
map string→boolean | Enable/disable specific tools for this agent. |
disable |
boolean | Disable the agent. |
description |
string | Override the description. |
mode |
subagent|primary|all |
Where the agent can be used. |
color |
#RRGGBB |
TUI color. |
displayName |
string | Localized display name in the selector. |
permission |
object | Per-agent permission overrides. |
maxTokens |
number | Max response tokens (passed to the SDK). |
thinking |
{type, budgetTokens} |
Anthropic extended thinking. |
reasoningEffort |
none|minimal|low|medium|high|xhigh|max |
OpenAI reasoning effort. |
textVerbosity |
low|medium|high |
Output verbosity. |
providerOptions |
map | Provider-specific options (passed through). |
ultrawork |
{model, variant} |
Per-message override applied when the ultrawork keyword fires. |
{
"agents": {
"sisyphus": { "category": "ultrabrain", "temperature": 0.1 },
"momus": { "category": "quick" },
"technical-writer": {
"model": "anthropic/claude-sonnet-4-6",
"temperature": 0.3,
"prompt_append": "file://./prompts/tech-writer.md"
}
}
}
4.4 Categories (categories)
Categories decouple "what kind of work" from "which model". Built-in category names: visual-engineering, ultrabrain, deep, artistry, quick, unspecified-low, unspecified-high, writing. Each maps to a CategoryConfig:
| Field | Type | Notes |
|---|---|---|
description |
string | Shown in the task prompt. |
model |
string | The model for this category. |
fallback_models |
string/array/object[] | Fallback chain. |
variant |
string | Model variant. |
temperature / top_p |
number | Sampling. |
maxTokens |
number | Max response tokens. |
thinking |
object | Anthropic extended thinking. |
reasoningEffort |
enum | OpenAI reasoning effort (none…max). |
textVerbosity |
enum | Output verbosity. |
tools |
map | Tool enable/disable. |
prompt_append |
string | Appended prompt text. |
max_prompt_tokens |
int > 0 | Cap input prompt size. |
is_unstable_agent |
boolean | Force background/monitored mode (auto-enabled for gemini/minimax). |
disable |
boolean | Exclude from delegation. |
{
"categories": {
"ultrabrain": { "model": "anthropic/claude-opus-4-6", "reasoningEffort": "high" },
"quick": { "model": "openai/gpt-5.4", "reasoningEffort": "low" },
"writing": { "model": "anthropic/claude-sonnet-4-6", "temperature": 0.4 }
}
}
4.5 Fallback models
fallback_models (on agents and categories) accepts a string, a string array, or an array of objects. Object form:
{ "model": "openai/gpt-5.4", "variant": "high", "reasoningEffort": "high", "temperature": 0.3 }
disabled_providers removes whole provider prefixes from every chain at load time; if a primary model points at a disabled provider, it is replaced by the first allowed entry in the same chain.
4.6 Claude Code interop (claude_code)
oh-my-opencode can import assets from a local Claude Code setup:
| Field | Type | Imports |
|---|---|---|
mcp |
boolean | Claude Code MCP servers. |
commands |
boolean | Claude Code commands. |
skills |
boolean | Claude Code skills. |
agents |
boolean | Claude Code agents. |
hooks |
boolean | Claude Code hooks. |
plugins |
boolean | Claude Code plugins. |
plugins_override |
map string→boolean | Per-plugin enable/disable. |
Relevant env toggles: OPENCODE_DISABLE_CLAUDE_CODE, OPENCODE_DISABLE_CLAUDE_CODE_PLUGINS, CLAUDE_CONFIG_DIR, CLAUDE_PLUGINS_HOME.
4.7 Experimental flags (experimental)
| Field | Type | Notes |
|---|---|---|
aggressive_truncation |
boolean | Truncate aggressively. |
auto_resume |
boolean | Auto-resume sessions. |
preemptive_compaction |
boolean | Compact before hitting context limits. |
truncate_all_tool_outputs |
boolean | Truncate all tool outputs. |
dynamic_context_pruning |
object | Prune context dynamically (dedup, supersede-writes, purge-errors; protects task, todowrite, session tools, lsp_rename, etc.). |
task_system |
boolean | Experimental task system for the todowrite disabler. |
plugin_load_timeout_ms |
number ≥ 1000 | Timeout for loading plugin components (default 10000). |
safe_hook_creation |
boolean | Wrap hook creation in try/catch so one bad hook can't crash the plugin. |
disable_omo_env |
boolean | Disable the auto-injected <omo-env> prompt context. |
hashline_edit |
boolean | Enable hashline editing (also a top-level key). |
model_fallback_title |
boolean | Append fallback model info to the session title on fallback. |
max_tools |
int ≥ 1 | Cap registered tools (e.g. for OpenAI's 128-tool limit; accounts for ~20 OpenCode built-ins). |
4.8 Skills (skills)
Either a list of skill names, or an object with sources, enable, disable, plus per-skill definition entries:
{
"skills": {
"sources": [{ "path": "skill/", "recursive": true, "glob": "**/SKILL.md" }],
"enable": ["frontend-ui-ux"],
"disable": ["remove-ai-slops"]
}
}
A skill definition may set description, template, from, model, agent, subtask, argument-hint, allowed-tools, metadata, and disable.
4.9 Ralph Loop (ralph_loop)
| Field | Type | Default |
|---|---|---|
enabled |
boolean | false |
default_max_iterations |
number 1–1000 | 100 |
state_dir |
string | .opencode/ |
default_strategy |
reset|continue |
continue |
4.10 Runtime fallback (runtime_fallback)
Boolean true, or an object:
| Field | Type | Default |
|---|---|---|
enabled |
boolean | false |
retry_on_errors |
number[] | [429,500,502,503,504] |
max_fallback_attempts |
number 1–20 | 3 |
cooldown_seconds |
number ≥ 0 | 60 |
timeout_seconds |
number ≥ 0 | 30 (0 disables timeout escalation) |
notify_on_fallback |
boolean | true |
{ "runtime_fallback": { "enabled": true, "timeout_seconds": 30, "max_fallback_attempts": 3 } }
4.11 Background tasks (background_task)
| Field | Type | Notes |
|---|---|---|
defaultConcurrency |
number ≥ 1 | Default parallel sub-agents. |
providerConcurrency |
map provider→number | Per-provider caps. |
modelConcurrency |
map model→number | Per-model caps. |
maxDepth |
int ≥ 1 | Max sub-agent nesting depth. |
staleTimeoutMs |
ms ≥ 60000 | Interrupt tasks idle this long (default 180000). |
messageStalenessTimeoutMs |
ms ≥ 60000 | Timeout for tasks that never reported progress (default 1800000). |
taskTtlMs |
ms ≥ 300000 | Absolute TTL for non-terminal tasks (default 1800000). |
sessionGoneTimeoutMs |
ms ≥ 10000 | Shorter timeout when a session vanished/crashed (default 60000). |
taskCleanupDelayMs |
ms ≥ 60000 | Delay before removing finished tasks from memory (default 600000). |
syncPollTimeoutMs |
ms ≥ 60000 | Sync task poll timeout. |
maxToolCalls |
int ≥ 10 | Circuit-breaker tool-call cap per sub-agent (default 200). |
circuitBreaker |
object | {enabled, maxToolCalls≥10, consecutiveThreshold≥5}. |
4.12 Model capabilities (model_capabilities)
| Field | Type | Notes |
|---|---|---|
enabled |
boolean | Use the capability table. |
auto_refresh_on_start |
boolean | Refresh from models.dev at startup. |
refresh_timeout_ms |
int > 0 | Refresh timeout. |
source_url |
URL | Override the models.dev source. |
Refresh manually with omo refresh-model-capabilities. Related env: ANTHROPIC_1M_CONTEXT, VERTEX_ANTHROPIC_1M_CONTEXT.
4.13 Team mode (team_mode)
| Field | Type | Default |
|---|---|---|
enabled |
boolean | false |
tmux_visualization |
boolean | false |
max_parallel_members |
int 1–8 | 4 |
max_members |
int 1–8 | 8 |
max_messages_per_run |
int ≥ 1 | 10000 |
max_wall_clock_minutes |
int ≥ 1 | 120 |
max_member_turns |
int ≥ 1 | 500 |
base_dir |
string | — |
message_payload_max_bytes |
int ≥ 1024 | 32768 |
recipient_unread_max_bytes |
int ≥ 1024 | 262144 |
mailbox_poll_interval_ms |
int ≥ 500 | 3000 |
Team-mode tool access is gated by the team-tool-gating hook: lead-only actions are rejected for members, and a session can't join two teams.
4.14 Git master (git_master)
| Field | Type | Default |
|---|---|---|
commit_footer |
boolean | string | true ("Ultraworked with Sisyphus" footer; or a custom string) |
include_co_authored_by |
boolean | true |
git_env_prefix |
string | "GIT_MASTER=1" (must be empty or shell-safe KEY=VALUE pairs; metacharacters are rejected) |
Caution
git_env_prefixis validated against a strict pattern to prevent shell injection. A value likeA=1; rm -rf /is rejected. Set it to""to disable.
4.15 tmux (tmux)
| Field | Type | Default |
|---|---|---|
enabled |
boolean | false |
layout |
main-horizontal|main-vertical|tiled|even-horizontal|even-vertical |
main-vertical |
main_pane_size |
number 20–80 | 60 |
main_pane_min_width |
number ≥ 40 | 120 |
agent_pane_min_width |
number ≥ 20 | 40 |
isolation |
inline|window|session |
inline |
isolation controls where agent panes appear: in your current window (inline), a separate window (window), or a fully detached session (session).
4.16 Other blocks
keyword_detector—{ enabled_expansions?, disabled_keywords? }overultrawork,search,analyze,team,hyperplan,hyperplan-ultrawork.browser_automation_engine—provider:playwright(default, via@playwright/mcp),agent-browser(Vercel CLI),dev-browser(persistent state), orplaywright-cli(token-efficient).websearch—provider:exa(default, no key) ortavily(requiresTAVILY_API_KEY).sisyphus_agent—{ disabled, default_builder_enabled, planner_enabled, replace_plan, tdd (default true) }.sisyphus—{ tasks: { storage_path?, task_list_id?, claude_code_compat } }.default_mode—{ ultrawork:false, ralph_loop:false }to auto-activate per session.comment_checker—{ custom_prompt }(use{{comments}}placeholder).notification—{ force_enable }.babysitting—{ timeout_ms: 120000 }.
5. Hooks Reference
Hooks are the mechanism by which oh-my-opencode modifies host behavior at lifecycle points. The full set (HookNameSchema) — disable any via disabled_hooks:
todo-continuation-enforcer, session-recovery, session-notification, comment-checker, tool-output-truncator, question-label-truncator, directory-agents-injector, directory-readme-injector, empty-task-response-detector, think-mode, model-fallback, anthropic-context-window-limit-recovery, preemptive-compaction, rules-injector, background-notification, auto-update-checker, startup-toast, keyword-detector, agent-usage-reminder, non-interactive-env, interactive-bash-session, thinking-block-validator, tool-pair-validator, ralph-loop, category-skill-reminder, compaction-context-injector, compaction-todo-preserver, claude-code-hooks, auto-slash-command, edit-error-recovery, json-error-recovery, delegate-task-retry, prometheus-md-only, sisyphus-junior-notepad, team-tool-gating, no-sisyphus-gpt, no-hephaestus-non-gpt, start-work, atlas, unstable-agent-babysitter, task-resume-info, stop-continuation-guard, tasks-todowrite-disabler, runtime-fallback, write-existing-file-guard, notepad-write-guard, bash-file-read-guard, anthropic-effort, hashline-read-enhancer, read-image-resizer, todo-description-override, webfetch-redirect-guard, fsync-skip-warning, plan-format-validator, legacy-plugin-toast.
Representative groupings:
| Group | Hooks | Effect |
|---|---|---|
| Continuation / loops | todo-continuation-enforcer, start-work, stop-continuation-guard, ralph-loop, atlas |
Keep the agent working until a unit of work is genuinely complete. |
| Reliability / recovery | session-recovery, runtime-fallback, model-fallback, edit-error-recovery, json-error-recovery, delegate-task-retry, anthropic-context-window-limit-recovery |
Recover from API/model/edit failures automatically. |
| Context management | rules-injector, directory-agents-injector, directory-readme-injector, compaction-context-injector, compaction-todo-preserver, context/preemptive-compaction |
Inject project rules/context and survive compaction. |
| Guardrails | write-existing-file-guard, notepad-write-guard, tool-pair-validator, thinking-block-validator, plan-format-validator, bash-file-read-guard, team-tool-gating |
Block unsafe or malformed actions. |
| Model policy | no-sisyphus-gpt, no-hephaestus-non-gpt, anthropic-effort, think-mode |
Keep specific agents on appropriate model families. |
| UX | keyword-detector, auto-slash-command, startup-toast, agent-usage-reminder, category-skill-reminder, background-notification, session-notification |
Keyword expansion, notifications, reminders. |
| Editing aids | hashline-read-enhancer, read-image-resizer, todo-description-override, tool-output-truncator, webfetch-redirect-guard |
Improve tool ergonomics. |
6. Security
6.1 Trust model
oh-my-opencode runs in-process with the host agent on a developer machine and has the same filesystem/network reach as that agent. It is not a network service and exposes no inbound ports of its own (the optional OpenClaw reply listener and any MCP servers are the exceptions — see below). Treat the configuration file as security-relevant: it determines which models, tools, and remote integrations are active.
6.2 Built-in safety mechanisms
| Mechanism | Where | Protects against |
|---|---|---|
| Archive entry validation | src/shared/archive-entry-validator.ts, binary-downloader.ts, zip-extractor.ts |
Path-traversal / absolute-path entries in downloaded tarballs/zips (e.g. ripgrep, binaries). Unsafe entries are rejected. |
| git env prefix validation | src/config/schema/git-env-prefix.ts |
Shell injection via git_master.git_env_prefix — only KEY=VALUE pairs allowed. |
| MCP env cleaning / allowlist | src/features/skill-mcp-manager/env-cleaner.ts, mcp_env_allowlist |
Leaking host secrets (API keys, tokens) into spawned MCP server environments — sensitive vars are stripped unless allowlisted. |
| Codex marketplace path checks | src/cli/install-codex/codex-marketplace.ts |
Path traversal / unsafe plugin sources during Codex install (local sources must start with ./ and stay within the marketplace root). |
| Subagent spawn limits | src/features/background-agent/subagent-spawn-limits.ts |
Session parent cycles and runaway recursive spawning. |
| Circuit breaker | background_task.circuitBreaker |
Runaway sub-agents burning unlimited tokens. |
| Team tool gating | src/hooks/team-tool-gating |
Members performing lead-only actions or cross-team interference. |
| Server auth injection | src/shared/opencode-server-auth.ts |
Honors OPENCODE_SERVER_USERNAME/OPENCODE_SERVER_PASSWORD when attaching to a server. |
| picomatch ReDoS pin | src/dependency-security.test.ts |
Enforces a ReDoS-safe picomatch (≥ 4.0.4) and forbids first-party effect imports. |
6.3 Telemetry and privacy
- A single anonymous daily-active event is sent to PostHog per machine per UTC day (OpenCode side and, separately, Codex side). It includes platform/OS/CPU/locale metadata and a SHA-256-hashed install id — never prompts, file contents, API keys, or raw hostnames. Person profiles are disabled.
- Opt out with any of:
OMO_DISABLE_POSTHOG=1,OMO_SEND_ANONYMOUS_TELEMETRY=0(and Codex-specificOMO_CODEX_DISABLE_POSTHOG=1,OMO_CODEX_SEND_ANONYMOUS_TELEMETRY=0). Test runs setOMO_DISABLE_POSTHOG. - Dedup state lives at
$XDG_DATA_HOME/omo-codex/posthog-activity.json(or~/.local/share/...), written atomically. - Endpoint overrides:
POSTHOG_HOST(defaulthttps://us.i.posthog.com),POSTHOG_API_KEY. - The bundled LSP, rules, and comment-checker components run entirely locally and make no network calls.
Important
For locked-down/offline fleets, set
OMO_DISABLE_POSTHOG=1andauto_update: false(and considerdisabled_mcpsforcontext7/websearch, which reach the network). Thewebfetch-redirect-guardhook also constrains outbound web fetches.
6.4 Provider credentials
Model and integration credentials are supplied as environment variables and never stored by oh-my-opencode beyond what OpenCode/Codex manage. Recognized provider/integration env vars include ANTHROPIC_API_KEY, OPENAI_API_KEY, GITHUB_TOKEN, CONTEXT7_API_KEY, EXA_API_KEY, TAVILY_API_KEY, and the OAuth flows handled by omo login/logout/status. The MCP env-cleaner prevents these from leaking into unrelated MCP subprocesses unless explicitly allowlisted via mcp_env_allowlist.
7. Operations
7.1 Install, validate, repair
npx oh-my-opencode install # interactive
npx oh-my-opencode install --no-tui \
--claude max20 --openai yes # scripted
omo doctor # full health check
omo doctor --status # compact dashboard
omo doctor --json # machine-readable
omo doctor --verbose # detailed diagnostics
omo cleanup [--project <path>] [--json] # remove Codex/omx artifacts
omo doctor checks (via src/cli/doctor/checks/) host detection, config validity, model resolution, MCP reachability, and agent registration. It is the first tool to reach for in any incident.
7.2 Updates
If auto_update is enabled, the auto-update-checker hook notifies users when a newer version is available. For controlled fleets, disable it (auto_update: false) and roll updates through your package manager. Verify a published release is not a stale binary (a real past incident, community issue #4635) with omo version / omo get-local-version after upgrading.
7.3 OpenClaw remote control (optional)
openclaw enables outbound notifications and an inbound reply listener over Discord/Telegram. Outbound uses gateways (HTTP or command) and hooks; inbound uses replyListener:
{
"openclaw": {
"enabled": true,
"gateways": { "notify": { "type": "http", "url": "https://...", "method": "POST" } },
"hooks": { "onIdle": { "gateway": "notify", "instruction": "Ask the user what to do next" } },
"replyListener": {
"telegramBotToken": "...", "telegramChatId": "...",
"authorizedDiscordUserIds": ["123..."],
"pollIntervalMs": 3000, "rateLimitPerMinute": 10, "maxMessageLength": 500
}
}
}
The reply listener is rate-limited (rateLimitPerMinute, default 10) and message-size-capped. Restrict who can drive the agent with authorizedDiscordUserIds. Relevant env: OPENCLAW_REPLY_CHANNEL, OPENCLAW_REPLY_TARGET, OPENCLAW_REPLY_THREAD, OMO_OPENCLAW_DEBUG, OMO_OPENCLAW_COMMAND_TIMEOUT_MS.
Warning
OpenClaw's reply listener accepts inbound messages that steer an autonomous coding agent. Treat its credentials and the authorized-user list as production secrets, and prefer it only on machines you control.
7.4 Logs and debugging
| Knob | Effect |
|---|---|
omo doctor --verbose |
Detailed diagnostics. |
COMMENT_CHECKER_DEBUG |
Comment-checker debug output. |
NODE_DEBUG=codex-rules |
Codex rules hook phase timing (stderr). |
OMO_OPENCLAW_DEBUG |
OpenClaw dispatch debugging. |
OMO_DISABLE_PROCESS_CLEANUP |
Disable background-agent process cleanup (debugging only). |
7.5 Disabling features safely
To reduce surface area or work around a bad interaction, disable narrowly rather than uninstalling:
{
"disabled_hooks": ["auto-update-checker", "startup-toast"],
"disabled_mcps": ["context7", "websearch"],
"disabled_agents": ["multimodal-looker"],
"disabled_skills": ["remove-ai-slops"],
"disabled_commands":["ralph-loop"],
"disabled_tools": ["todowrite", "todoread"]
}
8. Code Quality & Conventions
- Language/runtime: TypeScript built and bundled with Bun;
tsgo(TypeScript native preview) for type-checking;zodv4 for all runtime validation. - Tests: Extensive
bun testsuites colocated with source (the repo is heavily test-covered — most extracted "error messages" are in fact test assertions). Codex components usevitest/node --test. CI runs across Ubuntu, macOS, and Windows. - Style: Strict TS (
exactOptionalPropertyTypes,noUncheckedIndexedAccess,verbatimModuleSyntax, etc.); Biome for lint/format on the web and Codex components. - BDD naming: Tests follow
#given / #when / #thenconventions. - Workspace cores: Logic shared across harnesses lives in pure-TS
packages/*-corelibraries with no host dependency, keeping the OpenCode and Codex adapters equivalent. - Bundling shims:
src/shared/bun-*-shim.tsprovide Node fallbacks for Bun-only APIs so bundled output runs under plain Node (e.g. OpenCode Desktop).
8.1 Build, type-check, publish
bun run build # bundle src/index.ts + cli + schema (Bun target)
bun run typecheck # tsgo across root + packages
bun test # full test suite
bun run build:binaries # per-platform binaries (script/build-binaries.ts)
bun run build:schema # regenerate oh-my-opencode.schema.json
bun run build:model-capabilities # refresh bundled model capability table
Publishing is driven by script/publish.ts (env: BUMP, VERSION, REPUBLISH, SKIP_PLATFORM_PACKAGES) and marketplace sync by script/sync-lazycodex-marketplace.ts.
9. Internals: Subsystem Deep-Dive
| Subsystem | Key files | What to know |
|---|---|---|
| Plugin bootstrap | src/index.ts, src/testing/create-plugin-module.ts, src/create-managers.ts, src/create-tools.ts, src/create-hooks.ts |
The composable server() entry: load config → managers → tools → hooks → interface. Telemetry and OpenClaw start here, wrapped so failures never block load. |
| Config | src/config/schema/*.ts, src/plugin-config.ts, src/shared/opencode-config-dir.ts |
One zod object (OhMyOpenCodeConfigSchema) is the source of truth; merge order is global → project; legacy filenames auto-migrate. |
| Background agents | src/features/background-agent/* |
BackgroundManager, ConcurrencyManager, ParentWakeNotifier, TaskStateManager, TaskHistory, spawn-limit and circuit-breaker logic. |
| Team mode | src/features/team-mode/* |
Registry, mailbox, runtime, state-store, tasklist, worktree, tmux layout; gated by team-tool-gating. |
| tmux | src/features/tmux-subagent/*, src/shared/tmux/* |
Pane lifecycle, zombie-pane reaping, server health detection (issue #3894 guards spurious panes). |
| Model routing | packages/model-core/*, src/shared/model-*, src/hooks/model-fallback, src/hooks/runtime-fallback |
Category→model resolution, capability table (models.dev), fallback chains, unstable-agent detection. |
| Editing | packages/hashline-core/*, src/tools/hashline-edit/* |
Hash-anchored edit primitives and validation; bounds/anchor checks raise precise errors. |
| Code intel tools | packages/ast-grep-*, packages/lsp-tools-mcp, src/tools/grep/glob |
Structural search, language-server diagnostics/rename, bundled ripgrep. |
| Rules / context | packages/rules-engine/*, packages/agents-md-core/*, src/hooks/rules-injector |
Discover and inject CONTEXT.md, .omo/rules/**, .claude/rules/**, .cursor/rules/**, .github/instructions/**, with per-session dedup. |
| Boulder / start-work | packages/boulder-state/*, src/features/boulder-state, src/hooks/start-work |
Durable work tracking in .omo/boulder.json + .omo/plans/; continuation hooks push incomplete work to completion. |
| Codex adapter | packages/omo-codex/*, src/cli/install-codex/* |
Builds/installs the Codex plugin namespace and its components; marketplace validation and cache linking. |
| OpenClaw | src/openclaw/* |
Outbound gateways + inbound reply listener with rate limiting. |
9.1 Known issues & community-reported behavior
From the issue tracker (useful when supporting users):
- Model routing can be dropped on restart, falling back to defaults (#3570).
- Certain MiniMax variants stop mid-plan; mitigated by unstable-agent babysitting (#3198).
run --jsonmay exit before a background parent-wake completes (#4721).- Stale model capabilities require
refresh-model-capabilitiesfor newly-released models (#4692, #3535, #3649). - Builtin shared-skills may not appear as slash commands on some OpenCode Desktop builds (#4714).
- A published platform binary once shipped a stale version — verify after upgrade (#4635).
9.2 Suggested improvements
- Centralize hardcoded model references into configurable constants (open community proposal #839) — would simplify fleet-wide model policy.
- Free/alternative paths for MCP features where some currently assume paid services (#642).
- Provider-prefix robustness for newer providers (e.g.
minimax-cn) so capability detection and routing don't lag model launches (#3535, #4707). - Harden restart-time config reload so model routing can't silently revert to defaults (#3570).
10. Quick Reference
CLI
omo install [--no-tui] [--claude no|yes|max20] [--openai ...] [--gemini ...]
[--copilot ...] [--opencode-zen ...] [--zai-coding-plan ...]
[--kimi-for-coding ...] [--opencode-go ...] [--vercel-ai-gateway ...]
[--codex-autonomous] [--skip-auth]
omo run <message> [-a agent] [-m provider/model] [-d dir] [-p port]
[--attach url] [--session-id id] [--on-complete cmd]
[--json] [--verbose] [--no-timestamp]
omo doctor [--status] [--verbose] [--json]
omo cleanup [--codex-home path] [--project path] [--json]
omo get-local-version [-d dir] [--json]
omo refresh-model-capabilities [-d dir] [--source-url url] [--json]
omo boulder [-d dir] [-w work-id] [--json]
omo ulw-loop [args...]
omo version
omo login|logout|status <server-name> [--server-url url] [--client-id id] [--scopes ...]
npx lazycodex-ai install [--codex-autonomous]
Built-in agents
sisyphus, sisyphus-junior, hephaestus, prometheus, atlas, oracle, librarian, explore, multimodal-looker, metis, momus (plus OpenCode build/plan).
Categories
ultrabrain, deep, visual-engineering, artistry, writing, quick, unspecified-low, unspecified-high.
Keywords
ultrawork/ulw, search, analyze, team, hyperplan, hyperplan-ultrawork.
Commands
/ralph-loop, /ulw-loop, /cancel-ralph, /refactor, /start-work, /stop-continuation, /remove-ai-slops, /hyperplan.
Bundled MCP servers
ast-grep (omo-ast-grep), git-bash (omo-git-bash), lsp (lsp-tools-mcp), context7, grep_app, websearch (exa/tavily).
Key environment variables
| Variable | Purpose |
|---|---|
OPENCODE_DEFAULT_AGENT |
Default agent for run. |
OPENCODE_CONFIG_DIR / XDG_CONFIG_HOME |
Config directory resolution. |
OMO_DISABLE_POSTHOG / OMO_SEND_ANONYMOUS_TELEMETRY |
Telemetry opt-out. |
OMO_CODEX_DISABLE_POSTHOG / OMO_CODEX_SEND_ANONYMOUS_TELEMETRY |
Codex telemetry opt-out. |
ANTHROPIC_API_KEY / OPENAI_API_KEY / GITHUB_TOKEN |
Provider credentials. |
CONTEXT7_API_KEY / EXA_API_KEY / TAVILY_API_KEY |
MCP/web-search keys. |
ANTHROPIC_1M_CONTEXT / VERTEX_ANTHROPIC_1M_CONTEXT |
Enable 1M-token context. |
OPENCODE_SERVER_USERNAME / OPENCODE_SERVER_PASSWORD |
Server auth when attaching. |
CODEX_RULES_* |
Codex rules component config (mode, char caps, enabled sources). |
Config file
oh-my-opencode.jsonc / oh-my-opencode.json — OpenCode config dir (global) and project .opencode/. Validated by OhMyOpenCodeConfigSchema. Schema published as oh-my-opencode.schema.json (package export ./schema.json).