Skip to main content
oh-my-openagent (omo) is an agent harness that loads into an existing command-line host. Three editions ship from the same project:

Division of ownership

The line between Nix and runtime state is deliberate:
  • Nix owns the opencode.json plugin entry (programs.opencode.extraSettings.plugin in nix-ai’s root module) and the omo-senpi bunx wrapper (modules/ai-tools.nix, version pinned in lib/versions.nix). The pin carries no Renovate annotation: every omo-ai release is a prerelease and the latest dist-tag points at a placeholder, so bump manually against npm view omo-ai@beta version.
  • Runtime state owns everything else: ~/.omo/omo.jsonc (agent→model mappings), provider auth (~/.local/share/opencode/auth.json, ~/.codex/auth.json), the Light edition’s plugin cache and hook trust hashes. The installers are idempotent. Rerun them after an omo upgrade.
  • The bin named omo belongs to the Light toolkit (~/.local/bin, first on PATH). The standalone Senpi command is therefore exposed as omo-senpi.

Why the plugin entry is declarative

OpenCode’s global config is a home-manager-owned store symlink. The Ultimate installer writes its plugin registration through that symlink unconditionally. That fails against the read-only store and would be clobbered by the next switch anyway. Declaring "oh-my-openagent@latest" (the tagged form the installer itself writes) means the only thing left for the installer to manage is ~/.omo runtime state. Codex is the mirror image: nix-ai renders config.toml defaults through a deep-merge activation that preserves every key Nix does not manage (only mcp_servers is stripped). The installer’s [marketplaces.sisyphuslabs], [plugins."omo@sisyphuslabs"], [features.multi_agent_v2], and [hooks.state] blocks therefore survive every darwin-rebuild switch, verified by switching after install and grepping the merged file.

Upgrading

  1. Bump omoSenpi in nix-ai’s lib/versions.nix (manual, beta channel).
  2. Rerun both installers:
  3. Restart each host once. Codex shows a hooks review after plugin upgrades; re-approve. The hashes changed because the files did.
Autonomous mode (--codex-autonomous) is deliberately not used. nix-ai pins approval_policy = "never" with a workspace-write sandbox and no network. The next rebuild would revert the installer’s danger-full-access keys into a mixed posture.

Verification

A real opencode run prints Sisyphus - ultraworker · <model> when the plugin is live; a plain answer with no header means it is not loaded.

Known upstream skew

The latest published release disagrees with itself about agent model config. Its doctor command flags the installer-generated models[] arrays as invalid, while calling the documented model/fallback_models shape deprecated. Its own config migrate is a no-op. Either shape loads (exit 0); the normalized shape avoids the startup-blocking warnings. Model IDs in generated chains can also drift behind the live provider catalog (for example gpt-5-nano). Fallback chains absorb it at runtime.