Command Reference
Current Mate CLI commands and their execution contexts.
Setup And Linking
| Command | Context | Purpose |
|---|---|---|
mate companion setup | Companion root | Create or reconfigure a companion explicitly. |
mate companion link | Working repository, TTY | Select or clone a companion, write the link, and install its requirements. |
mate companion list [--json] | Linked context | List linked repositories. |
mate companion open | Linked context | Add the working repository and companion to the preferred editor. |
mate companion tui | Linked context, TTY | Open a shell in the resolved companion. |
mate companion sync | Linked context | Sync the companion with its Git upstream, interactively at a terminal. |
mate companion update [--yes] | Linked context | Regenerate the companion’s Mate-managed files with the newest stable Mate. |
mate working cleanup | Working repository | Remove Mate’s local integration from a linked working repository. |
mate companion link does not accept flags. Its selection and any required
installation confirmation are interactive. The default workflow is:
mate install
mate companion link
mate opencodemate companion update requires a stable Mate that is also the newest stable
release; otherwise it stops and asks you to run mate update first. It
regenerates the companion’s Mate-managed files, skills, and OpenSpec output,
raises engines.mate to the running version, and then offers to commit and push
exactly the files it wrote. --yes commits and pushes without asking. Outside
an interactive shell and without --yes, the changes stay uncommitted. A file
you had edited locally before the update is reported, not silently overwritten.
mate working cleanup runs from a working repository linked to a companion. It
removes the local .mate projection, Mate’s Git excludes, and the OpenSpec
store pointer, and updates the Claude settings Mate wrote. Tracked files and
product work are untouched, and the next link or launch recreates what it needs.
Run from a companion or a repository that is not linked, it exits non-zero.
Installation And Health
| Command | Purpose |
|---|---|
mate install [--yes] | Install and verify core requirements or refresh the active companion requirements. |
mate doctor | Show context, policy, selected capabilities, and tool status. |
mate config [--vscode] | Open the global ~/.mate configuration directory. |
mate install --yes skips interactive confirmation and is required when the
process has no TTY. It can run before a companion is linked; in that context it
installs only Mate’s core requirements.
Comment Guidance
Shared agent guidance prefers sparse, concise comments explaining non-obvious intent, constraints, or workarounds—not filler or restatements of code. Use JSDoc for JS/TS API documentation and line or ordinary block comments for local notes, including JSX-supported expression comments. Preserve required documentation and contract details, tool directives, legal notices, and language-appropriate syntax. Concision does not mean terse implementation code or rewriting unchanged comments.
This is guidance, not an automated comment checker or completion gate. Repository-owned conventions and unrelated verification requirements are unchanged; stricter rules require an explicit repository decision. Existing companions receive the wording through normal managed-guidance regeneration.
Agent Launch
mate claude [-- agent-args...]
mate opencode [-- agent-args...]Launch commands use a linked Working Repository by default. The companion’s allowed agents list must include the requested agent. To launch from the Companion Repository without a Working Repository, use the reserved token after the separator:
mate opencode -- --companionCompanion-scoped launches run the adapter from the Companion Repository, keep
companion Git and runtime synchronization, policy enforcement, and capability
preflight, but skip Working-Repository projection, automatic indexing, and
Working-Repository-only hooks. The agent environment carries no
MATE_REPO_PATH or MATE_REPO_ID.
Mate synchronizes managed companion files before launch. If the companion’s configuration uses Git auto mode, it also fetches and merges the configured upstream first:
mate claude -- --no-git
mate opencode -- --no-gitThe --no-git switch is Mate’s option only when it appears after the --
separator. --companion selects the companion scope and --yes suppresses the
interactive confirmation; these are also Mate options only after the separator.
All other arguments after the separator are forwarded to the agent.
Confirmation is shown only when standard input is a TTY. Non-interactive launches proceed without a prompt.
OpenCode: Wrap, Prepare, Launch
mate opencode from a Working Repository syncs the companion with Git, wraps the
repository for OpenCode when that wrap is missing or out of date, re-projects the
companion copies and runs the capability preflight, then starts plain opencode.
mate claude runs the same preparation and wraps the repository for Claude. At a
terminal the companion Git sync is interactive, and a sync that still
fails stops the launch. When another companion sync is running, the launch says so
and waits for it. It sets no OPENCODE_CONFIG_DIR, so your global OpenCode
configuration (~/.config/opencode) applies as usual; an OPENCODE_CONFIG_DIR or
OPENCODE_CONFIG_CONTENT you set yourself is passed through. With -- --no-git
only the local preparation runs.
Because the wrap carries everything, plain opencode in a wrapped repository is
equivalent: before the session starts, the Mate plugin re-projects the companion
copies and runs the capability preflight, waiting at most 30 seconds, and enables
Mate’s MCP servers once that is done. It never waits on the network: the companion
Git sync then runs in the background, fast-forward only, on every session start.
Changes it brings in are re-projected into the running session. It cannot prompt, so
a diverged history, a local edit the update would overwrite, or an unreachable
remote is reported as a warning to restart with mate opencode, whose attended sync
can resolve it, and the session keeps running on the current companion. This also
holds when OpenCode’s shared background service was started from another directory.
Claude: Wrap, Then Launch
mate claude works like mate opencode: a launch is a wrap followed by a launch.
Its preparation wraps the repository for Claude when that wrap is missing (never
wrapped, or wrapped only for OpenCode) and reconciles it when it is out of date,
before Claude starts. The launch then passes only what a wrap cannot deliver: the
companion guidance, Mate’s own plugin, and any Claude plugin folder of an enabled
Capability that the wrap could not publish. Capability hooks, Capability plugin
folders (context-mode’s among them), Mate’s MCP servers, the companion skills and
access to the companion directory come from the wrap, so each loads once. A
companion-scoped launch has no wrap, so it passes every plugin folder itself. If the wrap fails, the launch stops before Claude starts
and names the document that failed.
There is no launch-only mode for Claude any more: every mate claude from a
Working Repository writes the wrap’s git-excluded documents and may write the
repository’s entry in ~/.claude.json. A companion-scoped launch
(mate claude -- --companion) has no Working Repository and wraps nothing.
Plain claude in a Claude-wrapped repository is prepared too: a SessionStart
hook runs the local preparation (companion files, the Claude documents, the
capability preflight), waiting at most 30 seconds, then starts the companion Git
sync in the background, fast-forward only. A failure or warning is shown to you,
never to the model, and the session starts either way. Capability MCP servers may
start before the preflight finishes. Capability plugin folders, context-mode’s
among them, load as well in a folder Claude Code trusts. Claude loads plugins
before the SessionStart hook runs, so a Capability enabled since the last
preparation loads from the session after it. mate doctor lists the folders and
whether plain sessions load each one.
Mate’s managed Claude settings turn off Claude Code features that compete with
Mate’s own workflow: they deny the EnterPlanMode and DesignSync tools and set
enableArtifact: false, beside autoMemoryEnabled: false. Those tool denies are
fixed. While secret guardrails are on, the managed deny list also carries Read
and Edit deny rules for the default secret files (the Edit rule also covers
Write); see
Secret Guardrails. ExitPlanMode stays
allowed, so plan mode entered by hand (Shift+Tab) can still be left. A managed
launch applies these settings through --settings, and deny rules from there
cannot be re-allowed from your own settings.
The managed settings also hide Claude Code’s commit and pull request attribution
with attribution: { "commit": "", "pr": "", "sessionUrl": false }, so the
session is never told to add a Co-Authored-By: Claude trailer. Mate writes the
object form, never attribution: false, which Claude Code before v2.1.281 rejects
along with the whole settings file. Your own setting wins: when your user settings,
or the repository’s .claude/settings.json or .claude/settings.local.json, set
attribution (or the older includeCoAuthoredBy), Mate leaves the key out. A
managed launch checks again at every start. Model co-author trailers are still
refused; see Commit Attribution.
Wrapping
mate wrap [--companion PATH]
mate unwrapmate wrap makes sessions you start yourself (claude, opencode) load the
companion. For OpenCode it writes .opencode/opencode.json regions (Mate plugin,
companion skills, references.mate, permissions, MCP servers, and settings from the
companion’s own .opencode/opencode.json that your repository does not set) and
copies the companion’s .opencode/ files (commands, agents, skills, plugins, tools)
into your repository’s .opencode/ as regular, git-excluded files. Mate records
every copy it owns:
- a file your repository already has at the same path wins; Mate warns and leaves it;
- an owned copy you edited locally is replaced on the next re-projection, with a warning naming the companion file to edit instead;
- a file removed from the companion is withdrawn from your repository.
Paths into the Mate installation go through ~/.mate/runtime/, which every mate
run keeps pointing at the installed version, so a wrapped repository survives a
reinstall or Node switch. Installing or upgrading does not create that directory;
the first mate run does. Until then, plain opencode in a wrapped repository starts
without the companion guidance and reports the missing directory, so run mate once
after upgrading. If you uninstalled Mate, run mate unwrap (or mate once after
reinstalling).
For Claude it writes .claude/settings.local.json regions (the artifact-path
guard, banner, guidance and session-prepare hooks, every enabled Capability’s
hooks, permissions, the secret-file deny rules while secret guardrails are on, and
the same disabled features as a managed launch: the EnterPlanMode and
DesignSync deny entries and enableArtifact: false) and the repository’s MCP
servers into ~/.claude.json. That file is rewritten only when the servers
change. An enableArtifact value you already set in
.claude/settings.local.json is left as it is. The wrap also places the managed
attribution value, unless one of your Claude settings already sets attribution;
an attribution you set in .claude/settings.local.json is left as it is.
The wrap also links each companion skill folder (.claude/skills/<name>) and each
companion command folder, such as OpenSpec’s .claude/commands/opsx/, into your
repository’s .claude/, so /opsx:* works in plain claude too. A path your
repository already has wins, and mate unwrap removes only the links Mate created.
Each enabled Capability’s Claude plugin folder is published as its own local
marketplace and enabled in .claude/settings.local.json (extraKnownMarketplaces
and enabledPlugins). Claude Code loads it from the folder itself, without
copying it.
- Marketplace file. A folder’s marketplace file is
.claude-plugin/marketplace.json. If the plugin’s author ships one that lists the plugin, as context-mode does, Mate uses it. Otherwise Mate writes its own, namedmate-plugin-<plugin>, and removes it when the Capability is disabled. Mate never changes a marketplace file it did not write. A file of Mate’s that no longer matches what Mate writes is rewritten at the next pass; until a rewrite succeeds, the wrap does not enable the folder, andmate claudepasses it instead. - Folders that are not published load only through
mate claude. Each is named once per command, with the reason: in one note frommate wrap, in one warning frommate claude, and not at all bymate session prepare, which plain sessions run. A folder is not published when:- the folder holds a marketplace file that Mate did not write and that does not list the plugin;
- the plugin’s name cannot form a marketplace name;
- your Claude Code configuration already uses the marketplace name with another source, for example context-mode added from GitHub. Mate leaves your marketplace alone;
- Mate could not write its marketplace file into the folder, for example because the folder is read-only. The message gives the error.
- Claude Code’s records. Claude Code records these plugins in
~/.claude/plugins/. Those records stay aftermate unwrap, and have no effect once the plugin is no longer enabled.
Both session kinds work in a wrapped repository: plain claude / opencode and
mate claude / mate opencode. Every managed launch wraps the repository for its
runtime, so mate wrap is only needed for a repository you want to use with plain
sessions before your first managed launch there. Session preparation keeps the
documents current, so a Capability enabled after the wrap reaches the next session
without re-wrapping. mate unwrap withdraws the documents and the owned copies and
keeps the repository link; the withdrawal holds until the next mate claude or
mate opencode there, which wraps again.
Session Preparation
mate session prepare --repo <dir> [--json] [--sync]Runs what a managed launch prepares, without starting an agent, for each runtime
the repository is wrapped for. Without --sync it touches no remote: it syncs and
self-heals companion files, reconciles the wrapped documents in one pass (for
OpenCode including the copies), and runs the capability preflight per runtime. When another companion sync
holds the lock, it skips at once. With --sync it first fetches and fast-forwards
the companion, then runs that local preparation only when the companion moved. A
diverged history, an overlapping local edit or an unreachable remote is a warning
to restart with the managed launch of a wrapped runtime (mate opencode or
mate claude), not a failure. Every companion sync (managed
launches, mate companion sync, session-start repairs and this command) is
serialized through one lock per companion under ~/.mate/locks/. The command
refuses a repository wrapped for neither runtime and names mate wrap. --json
prints each step’s outcome, the runtimes each step answered for, and the warnings.
It reports no Claude plugin-folder problems; mate wrap and mate doctor name
them. The OpenCode plugin and the Claude session-prepare hook call this for you.
Exit Status And Signals
A launch exits with a status reflecting how the agent process ended: zero when the agent exited zero, non-zero when it did not. The JSON result is still printed, but it no longer stands in for the status.
A launch also forwards SIGINT and SIGTERM to the agent process it spawned
and waits for that process to exit before exiting itself, so nothing is left
running behind it. An agent that ends on a forwarded signal is reported as the
signalled stop it was — 128 + signal, the usual shell convention — so a
caller can tell a clean shutdown from a crash. At a terminal this is unchanged
in practice: Ctrl-C reaches the whole foreground process group, so the agent is
stopped once and the shell is returned.
This has no opt-out: a caller that read success from a zero exit will see agent failures.
Capabilities
| Command | Purpose |
|---|---|
mate cap openspec <subcommand> [args...] | Run OpenSpec through the active context. |
mate cap graphify <subcommand> [args...] | Run Graphify through the active context. |
mate cap index | Refresh enabled Graphify and TokenSave indexes. |
mate cap index --graphify | Refresh only Graphify. |
mate cap index --tokensave | Refresh only TokenSave. |
The two index flags cannot be combined. When both Graphify and TokenSave are enabled, the default index flow refreshes TokenSave and then refreshes Graphify against the resulting state.
Every Graphify extraction Mate runs, and every one an agent runs through the
graphify wrapper, leaves secret files out: Mate rewrites the secret region of
the repository’s .graphifyignore and passes the secret patterns as
--exclude. Afterwards it removes any secret that still reached the output and
keeps the rest of the graph. A secret never stops the run. See
Secret Guardrails.
Artifacts And Updates
| Command | Purpose |
|---|---|
mate artifact pending [--json] | List archived changes and drifted specs that are not published yet. |
mate artifact publish <target> [options] | Commit, tag, and push one archived change. |
mate update | Upgrade an npm-managed Mate installation and reinstall requirements. |
mate update --check | Check for an update without installing it. |
mate artifact pending is read-only. It lists each archived OpenSpec change
whose files are still uncommitted in the companion, with the canonical specs it
applied, and separately lists uncommitted specs no pending change accounts for.
The publish target is a dated archive anchor (YYYY-MM-DD-<name>) or a change
name that matches exactly one archive. Publishing never archives: archive the
change first. Options:
--specs [<path>...]publishes drifted canonical specs as their own publication instead of a change; with paths, only those specs.--allpublishes every pending change in order, then the remaining spec drift, and stops at the first conflict or error.--type openspecselects the publisher; it is the default.--no-pushcommits and tags locally without pushing.--jsonprints machine-readable results.
mate artifact finish is the deprecated name of publish: it still works but
prints a warning. Update accepts --yes to skip its confirmation prompt.
mate artifact publish scans the files it is about to commit for secrets
before the commit step. A finding stops the publication at a secret-scan
step with no commit, tag, or push, and reports each file, line, and rule id
without the value. With secrets.guardrails: false the scan is skipped with a
one-line notice.
Exit And Recovery Behavior
Unknown commands print the current usage text and exit non-zero. Missing or
stale installation state is repaired automatically when every requirement is
already available. If a requirement is missing, the companion is ambiguous, or
the Mate engine requirement is unsatisfied, Mate prints the reason and points
to mate install instead.
Doctor, setup, link, update, help, and version remain available so the state
can be repaired.