| name | cmx |
| description | Drive cmx, the package manager for curated agentic context (agents and skills) across AI coding assistants. Use this skill whenever the user mentions cmx, context mixer, installing or updating agent/skill files for Claude Code/Copilot/Cursor/Windsurf/Gemini CLI/opencode/Codex CLI/Pi/Crush/ Amp/Zed/OpenHands/Hermes/Devin, cmx sources, cmx doctor, adopting orphaned skills, reconciling drifted skills across tools, or managing a canonical home for hand-authored agents/skills. Also use when the user asks "what agents/skills do I have installed", "is anything out of date", "add this repo as a source", or wants to survey/clean up a messy multi-tool AI assistant setup. Even if the user doesn't say "cmx" by name, use this skill whenever the task is installing, updating, listing, searching, or auditing agent/skill files that AI coding assistants read from disk.
|
| license | MIT |
| compatibility | Rust binary `cmx`. All commands work in every build; an `llm`-feature build with a configured gateway additionally generates `info` summaries and `diff` analyses (both degrade gracefully without one). |
| metadata | {"version":"0.0.0","author":"Stacey Vetzal"} |
cmx — Context Mixer
cmx installs, updates, and reconciles two kinds of artifacts — agents and
skills — across every AI coding assistant on the machine (Claude Code,
Copilot, Cursor, Windsurf, Gemini CLI, opencode, Codex CLI, Pi, Crush, Amp,
Zed, OpenHands, Hermes, Devin). Artifacts come from sources (a local path
or git repo you register) and are tracked in a lock file so cmx always knows
what's installed, from where, and at what version.
Every command accepts a global --platform <name> flag to constrain the
operation to one assistant; when omitted, install/uninstall act across
every platform already in use, and other commands default to Claude.
Agent contract 1 — read state with --json, not tables
Every data-reporting command accepts --json. When you (an agent) are
reading cmx state to reason about it, always pass --json and parse with
jq. The human tables are lossy on purpose (truncated descriptions,
presentation words, aligned columns); the JSON is the source of truth and
carries full descriptions, null for absent values, and stable enum strings.
Use the bare human form only when displaying output to the user verbatim.
Shapes you can rely on (JSON to stdout; empty results are valid JSON):
cmx list --json / cmx skill|agent list --json / cmx outdated --json
{"artifacts": [{"name", "kind": "skill"|"agent", "scope": "global"|"local",
"source", "platforms": [..],
"installed_version": str|null, "available_version": str|null,
"status": "ok"|"unversioned"|"outdated"|..,
"locally_modified": bool (outdated only)}]}
(version null = no version metadata in frontmatter, not "not installed")
cmx search <q> --json → results with full untruncated "description"
cmx info <name> --json → flat object: path, version, installed_at, source,
installed_checksum/source_checksum/disk_checksum,
locally_modified, activation_description,
summary (str|null — null when no LLM available)
cmx doctor --json → {"artifacts": [{name, kind, scope, state, diverged,
locations: [{path, platform, state, version}], ..}],
"summary": {tracked, drifted, untracked, orphaned,
external, missing, diverged,
set_inconsistent},
"showing": "needs_attention"|"all",
"scope", "platforms_surveyed", "set_inconsistencies"}
cmx config show --json → {gateway, model, external: [..], platforms: [..],
platforms_inferred}
cmx home path --json → {"path": ..}
cmx set list --json → {"scope", "sets": [..]}; set show --json analogous
Idioms:
cmx outdated --json | jq -r '.artifacts[].name'
cmx doctor --json | jq -r '.artifacts[] | select(.diverged) | .name'
cmx doctor --json | jq -e '.summary.orphaned == 0' >/dev/null
cmx list --json | jq -e '.artifacts[] | select(.name=="foo")'
cmx info foo --json | jq -r '.locally_modified'
Exit codes are API: cmx doctor exits 2 when it finds actionable
issues, 0 when clean (both human and --json forms). Any other non-zero
exit means the command itself failed.
Agent contract 2 — mutations plan by default
The reconciliation commands — skill|agent sync, skill|agent promote,
set activate, set deactivate (and set delete --purge) — are
plan/apply: run bare, they print a concrete plan (exact files, paths,
versions, per-file +/− counts), write nothing, and exit 0. Re-run the
identical command with --apply to execute exactly that plan. Read the plan
before applying. (--dry-run survives one release as a deprecated alias for
the default plan mode and warns on stderr.)
install, uninstall, and update execute immediately (package-manager
convention) — but when --force overwrites local edits on install/update,
cmx first prints the exact file paths whose changes are being discarded.
--force always means "override a safety refusal", never "skip confirmation".
Help text marks the boundary: [Mutates] = writes immediately,
[Mutates with --apply] = plans by default. Unmarked commands are read-only.
Errors teach the next step — argument mistakes print a try: <exact command>
line, unknown artifact names suggest near-matches (Did you mean 'cli-ux'?),
and LLM/gateway failures degrade to a one-line note (never a hard failure of
the surrounding command). Trust stderr guidance; don't guess flags.
Command grammar (verified against --help)
cmx source {add,list,browse,update,remove}
cmx set {create,list,show,add,remove,activate,deactivate,delete,rename}
cmx agent {install,list,info,diff,update,sync,promote,uninstall,unadopt,adopt}
cmx skill {install,list,info,diff,update,sync,promote,uninstall,unadopt,adopt}
cmx list [--all] [--json]
cmx doctor [--local] [--all] [--json] (deprecated: --adopt-all, --from)
cmx home {init,path}
cmx outdated [--json]
cmx search <query> [--json]
cmx info <name> [--json]
cmx completions <bash|zsh|fish|elvish|powershell>
cmx config {show,gateway,model,external,platforms}
cmx init [--local] [--force] [--remove] [--json]
agent and skill take the identical set of subcommands — pick the one that
matches what you're managing.
Sources — where artifacts come from
cmx source add <name> <path-or-url>
cmx source list [--json]
cmx source browse <name> [--json]
cmx source update [<name>]
cmx source remove <name>
cmx set — activation groups for managing context cost
Every installed artifact is standing context (its trigger description loads
every turn). A set is a named group of artifacts you can install/uninstall
together as a unit, without losing the grouping — the cheaper alternative to
hoarding installs or losing track of what you had.
cmx set create <name> [--desc <text>] [--from-plugin <source>:<plugin>] [--local]
cmx set list [--json]
cmx set show <name> [--json]
cmx set add <name> <artifact>...
cmx set remove <name> <artifact>...
cmx set activate <name> [--apply]
cmx set deactivate <name> [--apply] [--force]
cmx set delete <name> [--purge] [--apply]
cmx set rename <old> <new>
activate/deactivate is install/uninstall with remembered membership, not a
separate on-disk state — deactivating an unused set reclaims its context cost
entirely. cmx doctor reports set-consistency issues (an active set with
missing members, or an inactive set with lingering installs) alongside its
other checks.
Install, list, and inspect artifacts
cmx skill install <name> [<name>...]
cmx skill install --all
cmx skill install <name> --local
cmx skill install <name> --force
cmx skill list [--all] [--json]
cmx skill info <name> [--json]
cmx skill uninstall <name> [<name>...] [--local]
cmx agent install/list/info/uninstall work the same way for agents.
Keeping things current
cmx outdated --json | jq -r '.artifacts[].name'
cmx skill update <name>
cmx skill update --all
cmx skill update <name> --force
Without --platform, update targets only the default platform (Claude); --all
means all artifacts, not all platforms. To converge sibling install copies across
platforms, use sync, not update.
Check cmx info <name> --json | jq .locally_modified before updating a
single artifact — a true means plain update will refuse and you must
decide between --force (discard edits) and promote (keep them; below).
Reconciling drift across tools and canonical homes
Skills installed in more than one assistant's directory can diverge (an agent
edits the Claude copy but not the Cursor copy). Three commands handle this:
cmx skill diff <name>
cmx skill diff <name> --full
cmx skill sync <name> [--from <platform>] [--apply] [--local]
cmx skill promote <name> [--from <platform>] [--apply]
Decision rule (doctor prints the same guidance): update pulls from source to
one platform; sync reconciles between install locations (use this when you
want every install copy to match); promote pushes in-place edits back to the
canonical home.
Canonical home and adoption
cmx keeps a tool-neutral canonical copy of hand-authored artifacts, separate
from any one assistant's install directory.
cmx home init
cmx home path [--json]
cmx skill adopt <name> [<name>...] [--all] [--from-dir <dir>] [--local]
cmx skill unadopt <name> [<name>...] [--external]
cmx doctor — the system-wide survey
cmx doctor is read-only: it walks every platform's install directories
and cross-references lock files, reporting artifacts that are missing,
untracked (orphaned), drifted, diverged across tools, or external.
cmx doctor --json
cmx doctor
cmx doctor --local
cmx doctor --all
cmx skill adopt --all
cmx agent adopt --all
Exit code contract: 2 = actionable issues found, 0 = clean, anything
else = the command itself failed. Script against this.
After any mutation, re-run cmx doctor to confirm the drift is actually gone.
An exit 0 from update / sync / promote means the command ran, not that
every sibling copy is now reconciled.
Search and config
cmx search <query> [--json]
cmx config show [--json]
cmx config gateway <openai|ollama>
cmx config model <name>
cmx config external {list,add,remove}
cmx config platforms {list,add,remove}
Shell completions
cmx completions zsh
cmx init — cmx's own companion skill
cmx installs this skill through the same shared installer library
(cmx-core) that other fleet tools use, at global scope by default.
cmx init
cmx init --local
cmx init --force
cmx init --remove [--local]
cmx init --json
cmx init protects existing copies with two safety refusals, both exiting
non-zero and both overridden by --force: it won't downgrade an installed
copy newer than the bundled one, and it won't overwrite a copy with local
edits (detected against disk, same as info/diff) — the skip hints
--force to overwrite or cmx skill promote cmx to keep the edits. When
--force discards edits it prints the exact file paths first. --global
is accepted as a no-op alias (global is already the default) so scripts
written before this alias existed keep working.
Typical workflows (agent-shaped)
Set up a new machine:
cmx source add guidelines https://github.com/svetzal/guidelines
cmx skill install --all
cmx doctor --json | jq .summary
Survey and fix a messy multi-tool setup:
cmx doctor --local --all --json > /tmp/survey.json
jq -r '.artifacts[] | select(.state=="orphaned") | .name' /tmp/survey.json
cmx skill adopt --all && cmx agent adopt --all
jq -r '.artifacts[] | select(.diverged) | .name' /tmp/survey.json
A skill drifted after an agent edited it in Cursor but not Claude:
cmx skill diff <name>
cmx skill promote <name> --from cursor
cmx skill promote <name> --from cursor --apply
Stay current:
cmx source update
cmx outdated --json | jq -r '.artifacts[] | select(.locally_modified | not) | .name' \
| xargs -n1 cmx skill update
Tips
- Prefer
--all for bulk install/update over enumerating names by hand.
sync reconciles between install locations; update pulls from the
source; promote pushes in-place edits back to the canonical home. Use
diff to inspect — never resolve drift with raw file edits.
source:name (e.g. guidelines:code-review) pins an install to one source
when the same artifact name exists in more than one.
- Global scope is the default everywhere
--local is offered; pass --local
only when you specifically want a project-scoped install.
- Plans are cheap and read-only — when unsure what a reconcile command will
do, run it bare and read the plan; nothing happens until
--apply.