Skip to main content
Eleven commands. Each states what it does and what it deliberately does not — the boundary is the part that would otherwise be guessed. Four rules hold throughout. Nothing a colleague can observe happens implicitly. Only to11 skill release makes a skill reach anyone else. Nothing writes to a directory it did not create unless --force is given — and that covers anything already on the machine, not only skills you wrote yourself. Every command accepts --help and prints its own usage, flags and conflicts, as text. Long options take two dashes. A single dash is only ever a single-letter short option, and the only two are -h for --help and -v for --version. -location is refused rather than accepted as a synonym, so the documented spelling and the working spelling cannot drift apart. Nothing edits a preference. Turning a skill off, holding a version and choosing a label are lines in a configuration file — you edit it, and sync applies it.

to11

The root command. Does — with no arguments, print the command list and where the two configuration locations live, with whether each exists. Does not — do any work; contact the platform; read or write configuration; guess a subcommand from a near-miss. An unknown subcommand prints the command list to stderr and exits non-zero.

to11 init

Configures one location. Does — resolve identity and project; list environments so a label is chosen from real values; add the project to the config, or update the entry already naming it; create the target directories; offer refresh hooks; run an initial sync. Re-running offers what is configured, so changing one thing is a single answer. Does not — create projects or environments; manage skills; install an agent; install itself; make any offer silently; write outside the location’s own config directory and its target directories; write a project id — the file names workspace/project, and an id that cannot be resolved to one fails the command. A credential scoped to one project is not asked which project. It already names one, and that is what is written. --project takes either form — workspace/project or proj_… — told apart by shape. One flag rather than two, so a run cannot name one project twice and contradict itself. The hooks are installed in your own agent settings, and never in a repository. A session-start hook there fires whatever directory the agent opens in, and sync reconciles every location, so one set keeps both current. to11 init --location repo therefore offers no hook, and --no-hook alongside it is accepted and reported as unnecessary. One hook per refresh mode, each running to11 as it resolves on your PATH rather than the location the CLI was installed at when you ran init. A mode counts as installed when its event already runs a command naming that mode, however the rest of the command is written, and under a matcher that reaches where the mode fires — an absent matcher, "" or "*", or the mode’s own scope. A PreToolUse entry scoped to Bash is therefore not the skill refresh, and the Skill-scoped hook is added beside it. init adds only what is missing and changes or removes nothing, so an entry you have edited yourself survives every later run, and re-running never leaves a second copy.

to11 logout

Does — delete the stored credential for the default identity or for --profile, and report what was removed. Does not — remove API keys; remove configuration; delete installed skills. Logging out leaves skills on disk — logging out is not a request for your agent to stop working. Conflicts--profile with --all.

to11 whoami

Does — print the identity, its organizations, the active profile, and which credential kind is in use. The answer comes from the platform, so it is a real check rather than a local echo. Does not — modify anything; list skills; fall back to a cached answer when the platform is unreachable — a stale identity answer is worse than none.
With an API key it says so, and never prints the key:

to11 skill

Does — with no subcommand, print the subcommand list. Does not — sync, list, or contact the platform. Inert by design: a bare parent command that did work would make the most exploratory thing you can type the thing with the most side effects.

to11 skill sync

Reconciles every configured location to what your configuration resolves to. Does — fetch the rendered skills for each target and write them; remove skills configuration no longer resolves; skip and report anything edited on disk; report per skill and per location what changed; leave previous skills in place when a fetch fails, so a broken network still beats nothing. Does not — publish or modify anything upstream; touch a directory it did not create; partially write a skill; prompt for anything; skip because a refresh ran recently — an explicit sync always runs. One flag, not several. A directory already there, a skill you edited, and a directory your configuration dropped but you have since changed are one request: make the machine match the configuration, whatever is in the way. Each refusal --force waives exists to stop a sync destroying work nobody agreed to lose, and the flag is that agreement. A directory your configuration stops asking for — a skill removed, or a target removed — is taken back when it still holds what we wrote. One you have edited is reported on every sync and left alone, because those bytes are the only copy of that work. --force removes it too. Conflicts--dry-run with --force (a write requested in a mode that writes nothing).
The summary counts what did not change as well as what did. 1 updated on its own does not say whether that was one skill out of one or one out of forty, so a run that changed something also says how many already matched their configuration. Those skills get no line of their own — a person reading this wants the diff, and the count is the context the diff is missing. A sync that changes nothing prints one line saying so: an empty terminal is indistinguishable from a crash. There is no count on that line, because the words already carry it.

--remove-all is how you get out

Removal is a sync whose desired state is empty, so it takes the same path and the same report as any other sync. Does — remove every skill installed in the current context, and name every path it touched. A directory you have edited is reported and left, exactly as when a single target is dropped — as is one the CLI cannot read at all. Each stays yours, and stays recorded so it can be named again, until to11 skill sync --remove-all --force. With nothing left to hold, the state file is cleared. --dry-run prints the same thing without doing it — the directories it would keep included. Does not — touch anything not in the state file; delete your configuration or your refresh hooks. Those are one file each, and deleting a file you own is not something a sync should do quietly. It works in the current context only, and never scans the disk. Removal in a repository removes that repository’s; removal at home removes home’s. The platform is untouched, so onboarding again restores everything you can still access.

to11 skill list

Does — report, per location, every skill the CLI manages, every skill your configuration names but does not install, and every skill directory that is not ours; each with one state and where it came from. Does not — browse the catalog; fetch bodies; install; write anything; print an empty list when nothing is configured. Absent skills are listed by default. A skill configuration names but that is not on disk is a row with a state, and that state is the only answer to why is a skill I expected missing.
TARGET names the targets a row is configured for, whether or not the skill has been installed to them. A row configured for more than one names them all. There is no --location or --state filter: every row names both.

to11 skill store

Pushes a new version upstream. It moves no label, so nobody else receives it. Does — take a slug and a content source; create the skill if it does not exist; save a new version; put that version on this machine; pin the skill to it in your configuration so your machine and your config agree; report whether the skill was created or a version added, and that it is not published. It also converts what it reads into the one stored text form before posting: CRLF becomes LF, a byte-order mark is dropped, and a file that is not valid UTF-8 is reported rather than sent. A Windows folder imports without anyone editing it by hand. Does not — move a label; make anything reach anyone else; overwrite an earlier version — a version is immutable and store only ever adds; turn a skill into a chat prompt or the reverse; guess a description for a new skill. Conflicts — exactly one of --dir, --from, --body is required. The description’s source depends on the content source. Creating takes it from --description, falling back to the entry document’s frontmatter — with any source, because --from and --body are stored as a SKILL.md as well. A new skill with neither is the error; the flag alone is not required. On a skill that already exists, --from and --body take it from the flag, while --dir takes it from the entry document and prints --description ignored: the entry document carries the description of an imported directory. A directory is the skill’s own record of what it is, so the flag cannot quietly disagree with the file the agent reads. An entry document carrying no description updates nothing and leaves the stored one standing. Creating and adding are reported differently, and that is the guard against a typo:
A mistyped slug creates a new skill rather than failing, so the word created is what tells you that you meant stored. A new skill nobody has published is harmless — no label points at it, so the recovery is to store into the right slug and leave the stray one unpublished. A slug belongs to whichever kind claimed it first. A project holding a chat prompt called code-review cannot also hold a skill called code-review, so a store can fail on a name you have never used for a skill:
The way out only runs one way. A skill’s slug can be changed and a chat prompt’s cannot, so the skill is what moves aside — which is also the thing nobody depends on yet. The version you just stored is what lands on disk, not what your label currently publishes. You are looking at your own work, so seeing the released version under its name would be worse than seeing nothing. It is written as pinned, and sync leaves it alone until you release or unpin it. The files are rendered by the platform, exactly as an installed skill is — frontmatter and all — so what you read on disk is the artifact an agent receives, not the bytes you uploaded.

to11 skill release

Moves a label to a stored version. The only command that makes a skill reach anyone else. Does — two things, one remote and one local. It moves the label to a stored version, defaulting to the newest; and it removes the pin from your own configuration when that pin named the version just released. Does not — create or modify content; release a version that fails validation; move more than one label; act silently. Conflicts — an unknown version is an error listing what exists.
The last line is deliberate. This is the only command whose effect reaches other people, and you should not have to infer that from the absence of a warning. A pin at a different version is left alone: it names a version you are still deliberately holding. If the label moves and the config edit then fails, you are released but still pinned locally — visible rather than silent, with the row showing both versions. Re-running is safe.

to11 code

Runs a coding agent with its traffic going through the to11 gateway. Does — take an agent name, check that the configured provider can serve the session, set the environment pointing the agent at the gateway, group the session’s turns under one conversation, pass every remaining argument to the agent untouched, and exit with the agent’s exit code. Does not — install the agent; manage providers or credentials; choose the agent’s model; modify the agent’s arguments; interpret its output; put the API key anywhere it could be read. Conflicts--no-gateway with either other flag. Everything after the agent name is the agent’s and is never parsed as ours, including flags that collide with these. claude is the only agent in this release. Anything else is an error naming what is supported, rather than an attempt that fails somewhere inside the agent’s own startup. It prints nothing on the way through, so a captured session is byte-for-byte what the agent produced — no “routing through to11” confirmation, ever. The one exception is on stderr, when something is wrong enough that the agent would fail confusingly.

It needs a code.claude.yaml

A routed session names the provider it routes to, in code.claude.yaml. Without one there is no routed session:
to11 init writes the file, so a configured machine already has one.

The check before the agent starts

The three coordinates are checked against the platform before Claude Code is launched, and the session does not start when one of them is wrong:
Each coordinate has its own error: no such project, no such environment, no such provider, a provider that is archived, and a provider not active in the named environment — the last naming the environments it is active in. --no-gateway does not route and checks nothing. The refresh hook modes launch no agent and check nothing.

The model

ANTHROPIC_MODEL is read and checked, never written. The agent chooses its model; this command decides where its traffic goes.

Refresh hook modes

Modes an agent harness invokes to refresh skills. Not for typing by hand, and each takes no agent name. Each names a mode, not an action, so what a refresh point does can change in the CLI without rewriting a file in your agent configuration. Every mode exits zero in every state, writes nothing to either stream, and emits no hook decision. A refresh does not get a vote on whether your work proceeds.

to11 version

Does — print the CLI version and exit zero. Does not — contact the platform; check for updates; read configuration. So it answers on a machine with no configuration and no network, which is the state you are in when you are working out why nothing else works.
to11 --version prints the same thing.