CLI tool for managing oh-my-openagent (OMO) profiles
Project description
omoctl
CLI tool for managing oh-my-openagent profiles in OpenCode.
Define profiles, patch models across providers, and switch between configurations with a single command.
Install
Run on demand with no install:
uvx omoctl --help
Or install permanently:
uv tool install omoctl
omoctl --help
Examples in this README use the bare
omoctlform. If you preferuvx, prefix every command (uvx omoctl update,uvx omoctl use claude, ...).
Prerequisites
- Python 3.11+
- bun or npm (for fetching OMO configs via
oh-my-opencode) - OpenCode installed with a populated model cache (
~/.cache/opencode/models.json— runopencodeonce to seed it)
Quick Start
omoctl update # fetch & build all profiles
omoctl list # see what's available
omoctl use claude # activate a profile
omoctl # show active profile
omoctl check # check config against available models/agents
Commands
| Command | Aliases | Description |
|---|---|---|
omoctl [status] |
— | Show active profile. Use -a/-n/-j to print only the alias, name, or JSON (e.g. omoctl -j) |
omoctl list |
ls |
List all profiles |
omoctl use <profile> |
apply, switch |
Activate a profile (by name or alias) |
omoctl update [profile] |
build, upgrade |
Fetch fresh OMO configs, apply patches, save. All profiles if omitted |
omoctl remove <profile> |
rm |
Remove a stored profile |
omoctl check |
validate |
Check config against available models, agents, and categories |
omoctl version |
— | Print version |
Config
Located at ~/.config/omoctl/config.yaml. Created on first run.
Minimal example
profiles:
- name: Claude
providers: [claude]
That's it. One profile, one provider. Run omoctl update and you're done.
Full example
active_profile: no-copilot
overrides:
disabled_hooks:
- context-window-monitor
patches:
- source: { provider: google }
target: { provider: proxy }
profiles:
- name: Claude
providers: [claude]
- name: Claude & OpenAI
providers: [claude, openai]
- name: No Copilot
providers: [claude, gemini, openai]
patches:
- source: { provider: google, model: gemini-3.1-pro-preview }
target: { provider: proxy, model: gemini-3-1-pro-xhigh, variant: null }
overrides:
disabled_hooks:
- context-window-monitor
- some-other-hook
Fields
| Field | Type | Description |
|---|---|---|
active_profile |
string | Profile to auto-activate after update. Optional |
overrides |
dict | OMO config overrides applied to all profiles |
patches |
list | Global patches applied to all profiles (see Patches) |
profiles |
list | Profile definitions (at least one required) |
Profile fields
| Field | Type | Description |
|---|---|---|
name |
string | Required. Display name. Also determines the alias (e.g. "No Copilot" -> no-copilot) |
providers |
list | Required. OMO providers to enable. Run omoctl check to see available providers |
patches |
list | Profile-specific patches. Take priority over global patches |
overrides |
dict | OMO config overrides. Deep-merged on top of the global overrides |
Patches
Patches rewrite models in the OMO config before saving. A patch has a source (what to match) and a target (what to replace it with).
Source
The source specifies what to match. All fields are optional but at least one must be set.
| Field | Type | Description |
|---|---|---|
provider |
string | Match models from this provider (e.g. google, anthropic) |
model |
string, list, or dict | Filter which models to match (see Model Filters) |
agent |
string | Match a specific agent (e.g. sisyphus, oracle) |
category |
string | Match a specific category (e.g. deep, quick) |
These combine: { agent: sisyphus, provider: google } matches sisyphus only when it uses a google model.
Target
| Field | Type | Description |
|---|---|---|
provider |
string | Target provider. Falls back to source provider if omitted |
model |
string, list, or dict | Target model (see Model Filters) |
variant |
string or null | "max" sets variant, null removes it, omit to keep existing |
Examples
patches:
# Redirect all google models to a proxy provider
- source: { provider: google }
target: { provider: proxy }
# Redirect a specific model to a specific target
- source: { provider: google, model: gemini-3.1-pro-preview }
target: { provider: proxy, model: gemini-3-1-pro-xhigh, variant: null }
# Override a specific agent
- source: { agent: sisyphus }
target: { provider: anthropic, model: claude-opus-4-7, variant: max }
# Override a category
- source: { category: ultrabrain }
target: { provider: openai, model: gpt-5.4, variant: xhigh }
Priority
- Profile patches are checked before global patches
- Agent/category patches take priority over provider-only patches
- Exact model matches beat filter matches
- More specific filters beat less specific ones
Model Filters
The model field in source/target accepts three formats:
Exact match — a string:
model: gemini-3.1-pro-preview
Keyword filter — a list of terms that must all match:
model: [gemini, pro]
Include/exclude filter — fine-grained control:
model:
include: [gemini, pro]
exclude: [flash]
Model IDs are split into words and numbers (e.g. claude-opus-4-7 -> words: [claude, opus], numbers: [4, 7]). Filters match against these parts.
File Layout
~/.config/omoctl/
config.yaml # your config
active # current active profile alias
profiles/
claude.json # stored OMO config per profile
no-copilot.json
~/.config/opencode/
oh-my-openagent.jsonc # active profile config (plain JSON, read by oh-my-openagent plugin)
Validation
omoctl check checks your config against live data:
- Patch source/target providers exist in the model cache
- Patch source/target models exist in their provider
- Patch agent names exist in the OMO config
- Patch category names exist in the OMO config
On failure, it prints each error with available options:
Validation failed with 2 error(s):
• global patch [0]: source provider 'nonexistent' not found.
• profile 'Test' patch [0]: source agent 'fake' not found. Available: atlas, explore, ...
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file omoctl-0.2.0.tar.gz.
File metadata
- Download URL: omoctl-0.2.0.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c314972f67c6665da35babb9ff33729bb673841ee20718ee83a14b43d81373a9
|
|
| MD5 |
2e1050d1de33b7c7269d8197b992e4ef
|
|
| BLAKE2b-256 |
217201fe6ae93cb3835459517bdc1b8928f13a6e7cda1d120bc5131964bba9ef
|
Provenance
The following attestation bundles were made for omoctl-0.2.0.tar.gz:
Publisher:
release.yml on anfreire/omoctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omoctl-0.2.0.tar.gz -
Subject digest:
c314972f67c6665da35babb9ff33729bb673841ee20718ee83a14b43d81373a9 - Sigstore transparency entry: 1615709021
- Sigstore integration time:
-
Permalink:
anfreire/omoctl@d614874d0b4a8ce77d18b0e6648ae4e5e614f006 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/anfreire
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d614874d0b4a8ce77d18b0e6648ae4e5e614f006 -
Trigger Event:
push
-
Statement type:
File details
Details for the file omoctl-0.2.0-py3-none-any.whl.
File metadata
- Download URL: omoctl-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0fcc85c78e3d7e82fa82ae1454803bb9d8b14d79dabf09e411c050f817b8f62
|
|
| MD5 |
e325461393f50a9d6011ad420f4009ab
|
|
| BLAKE2b-256 |
81d044297fc9744e39ff74ec838a4cc49dc31d90aa5bd5113da7106ddafa16ff
|
Provenance
The following attestation bundles were made for omoctl-0.2.0-py3-none-any.whl:
Publisher:
release.yml on anfreire/omoctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omoctl-0.2.0-py3-none-any.whl -
Subject digest:
e0fcc85c78e3d7e82fa82ae1454803bb9d8b14d79dabf09e411c050f817b8f62 - Sigstore transparency entry: 1615709023
- Sigstore integration time:
-
Permalink:
anfreire/omoctl@d614874d0b4a8ce77d18b0e6648ae4e5e614f006 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/anfreire
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d614874d0b4a8ce77d18b0e6648ae4e5e614f006 -
Trigger Event:
push
-
Statement type: