Documentation
A guide to running coding agents you don't fully trust — safely, and at scale. It explains not just how each piece works, but why it works that way.
The idea
Coding agents are at their best with the guardrails off — free to edit any file and run any command without stopping to ask. That's also exactly when you don't want one running loose on your laptop.
Coop's answer is simple: run the agent inside a
disposable container that can only see the one repo
you're working on. Your home directory, SSH keys, cloud
credentials, and every other project simply aren't in
there. The repo's own secrets — .env files,
private keys, a secrets/ folder — are
blanked out before the agent ever starts.
The container is the boundary — not a list of permissions you have to get exactly right. You don't audit what the agent is allowed to do; you put it somewhere it can't do harm. The worst an off-the-rails agent can manage is a mess in one repo you can restore from git.
Everything else is built on that one box. Run an agent interactively, hand work off like a pull request, point a whole fleet at a backlog overnight, or convene a council of models on a hard problem — it's the same cage every time.
Install
One binary, no Go toolchain, no clone. A container runtime is the only requirement.
curl -fsSL https://raw.githubusercontent.com/AndrewDryga/coop/main/install.sh | sh
This drops coop into
~/.local/bin, and — if a container runtime
is already installed — builds the sandbox image and runs
coop doctor for you. If no runtime was
found, do that one step yourself once a runtime is in
place:
coop build && coop doctor
For the runtime, take your pick: Apple
container
(macOS 26+), Docker, or Podman — coop auto-detects
whichever you have. The coop binary itself
is fully static with no other dependencies.
PATH it checks a keyless Sigstore
signature; otherwise it falls back to a SHA-256 check
and tells you the signature wasn't verified. Prefer to
build from source?
git clone https://github.com/AndrewDryga/coop && cd coop && make install
works too.
Quickstart
The shortest path from nothing to a sandboxed agent that lands reviewed work.
cd ~/code/your-repo # 1. any git repo coop doctor # 2. prove the isolation holds coop login claude # 3. sign in once — paste a code, no browser coop claude # 4. a sandboxed agent, brakes off, secrets hidden
That's the whole everyday flow. When you'd rather not work in your live checkout — for a bigger or riskier change — hand it to a fork instead and review the result like a PR:
coop tasks add "wire up --json" # 1. queue the work as a task coop fork feature claude --loop # 2. a fork works the queue in its own clone… coop fork review feature # 3. …you read the diff like a PR… coop fork merge feature # 4. …and land it on your branch
Anything you type after the agent's name is passed
straight through to it, so
coop claude --continue resumes the last
session, still sandboxed. From here, the rest of this
guide goes feature by feature — but you already know
enough to be useful.
The sandbox
What's inside the box, what's deliberately left out, and why that line is the entire security model.
Your repo is bind-mounted into the container at the same path it has on your machine. That matters for two reasons: the agent edits your real files (you watch the changes land live in your editor), and absolute paths line up between coop, the loop, and your IDE. Everything outside that one directory — the rest of your disk — is just not present in the container.
Your git identity, not the box's
The container has no ~/.gitconfig of its
own, so coop mounts a curated one: your name and email
(commits are authored as you), your global
gitignore, and commit.gpgsign=false. Your
signing key never enters the box — so commits made inside
it are authored as you but left unsigned.
If you sign your commits
(commit.gpgsign=true in your global git
config), coop closes that gap on the host, where your key
lives: it re-signs the box's commits with your key on
every path that produces them — when an interactive or
editor box exits, after each coop loop cycle,
and as a fork lands through coop fork merge.
You can also re-sign the current branch's unpushed range
yourself with coop sign. Your history ends up
signed by you, exactly as if you'd typed the
commits — so a protected main that requires
signatures accepts work an agent did in a box.
More on forks below.
Secrets stay out
Two layers keep credentials away from the agent: secrets are hidden by name, and a content scan catches the ones hiding inside ordinary files.
Files and folders that look like secrets —
.env, *.pem,
*.tfvars, secrets/,
.ssh, and a long list of well-known names —
are shadowed: an empty in-memory
filesystem covers secret directories, and a blank
read-only file covers secret files. The agent sees that
the file exists, but it's empty and can't be written.
Templates (*.example,
*.sample, *.template) stay
visible on purpose, so the agent can still learn the
shape of your config.
.coopignore, not
.gitignore.
A normal run mounts your whole working tree, so
a secret that's gitignored-but-still-on-disk (a real
serviceAccount.json, say) is fully visible
to the agent — gitignoring it does not hide it.
Anything that must live in the tree but stay secret
belongs in .coopignore.
The built-in list can't know your repo holds a
config/credentials.yaml. Drop a
.coopignore at the repo root — one pattern
per line — and those paths are hidden everywhere the box
can see:
prod.yml # basename — matched at any depth config/credentials.yaml # a slash makes it a repo-relative path vault/ # a directory — hidden whole
That handles secrets identified by their name. But a
token can also hide inside an ordinary file.
coop check-secrets reads your files looking
for secret-shaped content — known provider token formats
and high-entropy strings — and reports each as
file:line, exiting non-zero on a hit so it
doubles as a pre-flight or CI gate. The same scan runs
automatically every time you merge a fork.
Prove it
Security you can't verify is just a promise.
coop doctor attacks its own box and shows
you, check by check, that it holds.
Run it any time — and especially after you change
config. doctor plants a decoy secret in
your repo, launches the box, and then tries to break in:
from inside the container it confirms the
secret is unreadable and unwritable while ordinary
source stays readable, and on the host it
confirms a fork carries neither the secret nor anywhere
to push to. If anything fails, it tells you exactly
what.
Run an agent
The everyday command: a sandboxed agent in your repo, brakes off.
coop claude # Claude — no permission prompts, secrets hidden coop codex # the same box, Codex instead coop gemini # …or Gemini coop grok # …or Grok (xAI) coop shell # just a shell in the box, to look around coop run -- npm test # run one command in the box and exit
Each agent launches with its most autonomous flags on purpose. Outside a sandbox that's reckless; inside one it's the whole point — you get an agent that doesn't nag you for permission on every step, and the box makes sure it can't reach anything that matters.
Forks — hand off work like a PR
Give a task to an agent the way you'd give it to a contractor: it works in its own copy, you review the diff, and you decide what lands.
A fork is a throwaway local clone of your repo, handed
to the agent instead of your live working tree. Because
its origin is a local path, the agent has
nowhere to push — and since a clone only carries
committed content, gitignored secrets never even come
along.
Use it for anything bigger or riskier than a quick edit, and any time you want to run several attempts at once. The agent never touches your checkout, so you can keep working while it does — and you stay the only person who lands anything.
The lifecycle mirrors a pull request: open → work → review → land. You review the diff in your terminal (a brief, then the changes) or in your IDE. Landing rebases the fork onto your current branch for linear history — and because that rebase runs on the host where your key lives, the commits can be signed even though the box committed them unsigned.
Set a gate and every landing earns its place:
COOP_GATE="make check" re-runs your tests
in the box on the rebased tree and rolls back if they go
red. A content scan also flags any secret-shaped or
oversized files on the way in.
Landing brings over code, not queue state: a
fork works a copy of the
.agent/tasks/ queue, so after a merge the
parent still lists the tasks the fork finished — mark
them done or remove them, and run
coop tasks watch for the deduped view
across the parent and its forks while they run.
Fusion — a council of models
Don't bet the run on one model's blind spots. Let one model lead while a configured council weighs in before every response or task.
In coop fusion, one model is the
governor: it does the real work — edits, runs
the gate, commits. Explicit peers and preset consult
roles form a one-or-many-member council, consulted
read-only and in parallel where practical. The governor
synthesizes their strongest conclusions.
The combined answer reliably beats any single model
working alone.
There's no extra service or protocol — the leader simply asks each council member from its own shell before it answers or starts a task. Each consultation adds one read-only run per member, so cost scales with the council you configure.
coop fusion claude --peer codex --peer gemini # a council: claude governs, peers weigh in coop claude --peer codex # lighter, opt-in: one peer on hard calls only
Credentials & failover
Hold more than one account for an agent so a long run never has to park on a rate limit.
Sign in to several subscriptions as named credentials. When a loop hits a limit on one, it rotates to another that's still fresh and keeps going — only ever waiting once every account is capped.
coop login claude@work # a second account… coop login claude@personal # …and a third coop credentials # list them + which are signed in
API-token users can put provider keys in
~/.config/coop/agents/env. Accepted keys are
ANTHROPIC_API_KEY,
ANTHROPIC_AUTH_TOKEN, and
CLAUDE_CODE_OAUTH_TOKEN for Claude;
OPENAI_API_KEY for Codex;
GEMINI_API_KEY or
GOOGLE_API_KEY for Gemini; and
XAI_API_KEY for Grok. Coop recognizes an
env-only login as the provider's default credential and
scopes every accepted key like a file-backed login. A
bare key imports an existing ambient value; if it is
unset, the entry is omitted. A present import or later
assignment wins over earlier entries. The env token is
one effective default credential, not a substitute for
additional named-account logins; Coop removes those env
keys when a file-backed named account runs so the global
token cannot override it, including when that account is
marked as the default.
There's no pool to configure: a loop rotates whatever
its lead's target ladder expands
to. A bare provider:model rung in that ladder
fans out across every
signed-in account (the marked default first), so with no
setup a loop already uses all your accounts; a pinned
provider:model@account runs just one. Limits
are tracked per (model, account), so
claude:opus@personal stays usable while
claude:opus@work cools down. Mark which account a
plain coop <agent> uses with
coop credentials <agent> <name>
default.
Only the active credential is ever mounted into the box, so a running agent sees just the account it's using — never your whole vault. Switching mid-run loses nothing: each iteration is a fresh run, and the queue plus git carry the progress.
Pick the model
The model is its own axis — pick it per run in the
target (claude:opus), or as a standing
recipe in a preset. A credential is just an account;
models don't live on it.
coop claude:opus # one run on the big model coop claude:opus/xhigh # …at max reasoning effort (low·medium·high·xhigh·max) coop claude:opus@work # …pinned to a specific account coop frontier # a standing lead model + roles, from a preset coop models # the model menu per agent
Precedence is most-specific-first: the model in the
target (claude:opus), then
the active ladder entry's model (a
loop stepping through a preset), then
COOP_LOOP_MODEL (loop runs only), then
COOP_<AGENT>_MODEL. Coop never
validates a model id — whatever the agent's own CLI
accepts works, and a bad one fails loudly in the agent's
own error, so new models work the day they ship.
Reasoning effort is a sibling axis — add
/effort to the same target
(claude:opus/xhigh, codex/high):
low · medium ·
high · xhigh ·
max. Coop passes the level straight to the
agent's CLI (Claude's --effort, Codex's
model_reasoning_effort, Grok's
--reasoning-effort) and never validates it;
Gemini has no effort control, so a /effort
on it is rejected up front. It mirrors the model's
precedence, and one env var carries both axes:
COOP_<AGENT>_MODEL,
COOP_LOOP_MODEL, and
COOP_REVIEW_MODEL take
model/effort (e.g. opus/high) —
no separate effort var.
This is what makes the
orchestrator pattern cheap to run.
coop init scaffolds two starter subagents:
deep-reasoner (pinned to Opus —
architecture, complex debugging) and
fast-worker (pinned to Sonnet — mechanical
work). A lead on a bigger model spends its tokens on
planning and synthesis while each delegated turn bills
at the subagent's cheaper model. Add
--peer codex --peer gemini — naming
each peer — and the lead can also ask them
read-only — peer engineers with different blind spots,
no plugins required. Wrap the whole arrangement in a
preset.
Presets — the whole arrangement in one file
A lead model, its fallback ladder, and the roles it routes work to — declared once as a file, instead of assembled from flags every time.
The fusion and orchestrator
patterns above are wired up by hand — a model here, a
--peer codex there. A preset
captures the whole recipe in
.agent/presets/<name>/preset.yaml:
who leads, on which models, and the named roles it can
hand work to. Run it by naming it in the who-runs slot —
coop <name>, coop loop <name>,
fusion, acp, or a fork.
coop presets init # scaffold the documented "frontier" recipe coop presets # list every preset (a broken one shows its error) coop loop frontier # run the loop under it
The lead's agent: holds one target or a
fallback ladder of them — the same ladder a loop rotates
(a bare provider:model fans across every
account; provider:model@account pins one).
Each role sets a mode that decides how
the lead reaches it:
| Mode | What it is |
|---|---|
native |
a Claude subagent that runs inside the lead's
own session — no separate box. coop generates it
(coop-<role>, from the role's
model + prompt) in the box, or set
subagent: to reuse an existing one.
It's Claude's own subagent, so it needs a Claude
lead; under a Codex, Gemini, or Grok lead this
role degrades to a read-only
coop-consult <role> (same model
+ persona)
|
consult |
a read-only peer, asked as
coop-consult <role> — runs the
role's target or fallback ladder, with the role's
prompt as the peer's persona; it can't edit files
|
delegate |
a write-capable worker via
coop-delegate: it may edit the
worktree but never commits — fallback requires
an unchanged clean worktree; the lead reviews the
diff, runs the gate, and commits
|
# .agent/presets/frontier/preset.yaml lead: agent: [claude:claude-fable-5, claude:claude-opus-4-8@work] roles: thinker: # deep thinking, in the lead's session mode: native agent: claude:claude-opus-4-8 # coop generates a coop-thinker subagent from this prompt: roles/thinker.md critic: # read-only cross-vendor review mode: consult agent: [codex:gpt-5.6-sol, grok:grok-4.5] fast: # cheap, write-capable mechanical work mode: delegate agent: [gemini:gemini-3.5-flash, codex:gpt-5.4-mini]
coop turns the YAML into the lead's routing contract
— each role, when to use it, and the exact
invocation — and mounts the
coop-consult /
coop-delegate wrappers. A native role
generates its subagent
(coop-<role>) in the box from the
role's model + prompt, never written to your repo.
coop presets init scaffolds the starter
prompt files under roles/; an explicit
target on the command line
(claude:opus@work) still overrides the
recipe.
Consult and delegate ladders skip providers without mounted credentials. Every available rung's credential home is mounted in the lead box. Consult fallback replays its saved transcript; delegate fallback requires every file and Git history to remain unchanged.
The loop — work the queue while you sleep
Give the agent a checklist and let it work the list on its own — through the night, through rate limits, without your hand on the wheel.
Most real agent work isn't one big task — it's a queue of small, well-defined ones. Driving the agent through them by hand, one at a time, is the bottleneck. And a single marathon session quietly degrades: the context window fills with old work, the agent loses the plot, and quality slides. The loop sidesteps both.
You write each task as a folder under
.agent/tasks/ (its state is its directory).
coop loop then starts a
fresh agent for each one — so every
task begins with a clean head, no leftover context to
rot. The agent claims a task, does it, runs your gate,
commits the result, and moves to the next. It won't stop
while any task remains in 00_todo/ or
10_in_progress/. A monorepo? List the
members under subprojects: in a committed
.agent/project.yaml and one loop drains
every component's queue — no configuration beyond that.
coop init # scaffold AGENTS.md, the .agent/ folder, and the hooks coop tasks add "…" # a folder per task under .agent/tasks/ coop loop claude # disposable agents drain the queue, then review coop loop claude:claude-fable-5 --peer codex # pin its model; let it ask a peer
It reviews its own work. When the list
is empty, coop runs a review pass — a senior reviewer's
bar re-reads every task marked done, confirms the git
history backs it up, and reopens anything that falls
short. If a pass reopened work, the loop drains and
reviews again, repeating until a pass reopens nothing — so
"done" ends up meaning verified, not just
claimed. Tighten the bar with your own checks under
signoff.prompt in
.agent/loop.yaml — a task that fails one
(changelog updated, docs regenerated, no stray TODOs)
gets reopened.
It survives the daily cap. Long runs hit subscription rate limits. Rather than failing, the loop reads the reset time from the agent's own output and waits it out — or, if you've added a second account, switches to it and keeps going. An overnight run rides straight through the limit instead of dying on it.
It parks a decision instead of guessing.
On a one-way-door call it shouldn't make alone, the
agent moves the task to 50_blocked/ and
writes a decision.md (the question,
options, its recommendation) rather than picking blind.
When nothing else is actionable the loop stops and exits
3, so cron/CI can tell "stalled on a
decision" from "done." Answer them with
coop tasks decisions -i — it walks each
open decision, records your answer, and unblocks the
task — then re-run coop loop (or start it
with --preflight to unblock
already-answered ones first).
coop tasks watch shows the live board — the
queue plus any running forks, deduped — while it works.
For an at-a-glance status in your shell prompt or tmux,
coop prompt prints this repo's state on one
line (task counts and fork/loop activity, non-zero
segments only) — read-only and cheap, safe on every
redraw.
A backlog of small refactors. Migrating one pattern across dozens of files. Working down a test-coverage or lint list. A "Friday cleanup" queue you'd never get to by hand. Anything that's many small, checkable steps.
The .agent/ folder
coop init creates a small, tool-neutral
folder the agent reads back on every start (and after
each compaction). The work queue —
tasks/ and the backlog — is local,
git-ignored working state; the knowledge and config
beside it are committed with the repo, so they travel
with the project.
| Path | What it's for |
|---|---|
tasks/ |
the work queue — a folder per task under
00_todo/,
10_in_progress/,
50_blocked/, 99_done/;
its state is its directory (the numeric prefix
sorts ls in lifecycle order;
coop tasks shows the clean names).
Local working state
|
| the backlog |
unscheduled ideas — work, chores, ideas — as task
folders in the tasks/xx_backlog/ drawer
(coop backlog); outside the lifecycle, so
never auto-worked, and
coop backlog promote <id> moves one
into 00_todo/ when it's ready
|
rules/ |
the taste knowledge base (normative) — a correction becomes a "do X, not Y" rule here |
kb/ |
the descriptive knowledge base — subsystem maps, cross-cutting traps, and gotchas the code doesn't carry; a self-improving wiki the agents keep current as they work |
skills/ |
the workflow skills (spec,
work, sweep,
investigate,
review-board,
verify-api, release);
each agent's dir symlinks to them
|
presets/ |
orchestration recipes — a lead plus roles (thinker, critic, fast); see Presets |
project.yaml |
per-project config: a monorepo's members, the dev-server ports coop publishes, the box posture, and the fork-merge gate |
loop.yaml |
configures coop loop's stages —
preflight, work, between, signoff — each with its
own model ladder and prompt
|
fleet.yaml |
declares a fleet of fork loops for
coop fleet — one entry per fork
|
A fleet — many agents at once
One loop is one agent working one queue. A fleet is several — often different models — each on its own slice of the work, all running at the same time.
Split the backlog into separate task trees (coop
tasks split 3 slices the queue into copy-trees),
declare a fork per slice in .agent/fleet.yaml
(coop fleet init writes the template), then
coop fleet up starts them all in the
background; coop fleet watch is the live
board, showing each fork's progress, the task it's on,
who's finished, and what each has cost.
coop tasks split 3 # slice the todo queue 3 ways into copy-trees coop fleet init # write .agent/fleet.yaml, then declare a fork per slice coop fleet up # start every fork in .agent/fleet.yaml, detached coop fleet watch # the live dashboard coop fork merge --all # land the whole fleet through a revalidating rebase
Each fork in .agent/fleet.yaml takes two
keys: tasks: points at its slice, and
agent: is the who-runs — either a
target
(provider:model@account; give each fork a
different account so they don't contend) or a
preset name, whose lead ladder the
fork's loop rotates.
Once generating code is cheap, reviewing it becomes the bottleneck — so the move is to parallelize generation and batch the review. Add agents until your review queue, not the agents, is what's keeping you busy.
Editors
Prefer your editor to a terminal? coop serves the sandboxed agent over ACP, so any editor that speaks the protocol drives it while it runs in the box — your editor is the cockpit, the box stays the cage.
ACP
(the Agent Client Protocol) is an open, editor-agnostic
standard. coop acp [agent] speaks it over
stdio, so you register coop as a custom agent in any
editor that supports ACP and steer it from there. Zed
ships ACP today and others are adding it; the setup is the
same anywhere — point one entry at each agent you use. In
Zed's settings.json, for example:
{
"agent_servers": {
"coop": {
"type": "custom",
"command": "coop",
"args": ["acp", "claude"] // one agent; pin the target: "claude:opus/xhigh@work"
},
"coop · fusion": {
"type": "custom",
"command": "coop",
"args": ["acp", "fusion", "claude:opus/xhigh", "--peer", "codex"] // a council; governor's model/effort ride the target
}
}
}
Pin the model, reasoning effort, and account in coop's
target inside args —
provider[:model][/effort][@account] — not
the editor's per-option defaults; the toolbar dropdowns
come up reflecting it and stay switchable, and coop always
runs yolo whatever the editor's permission-mode setting.
One caveat: a codex governor takes its
model from codex's own config.toml (coop
can't set it over ACP), so pick a claude,
gemini, or grok governor when
you want coop to choose the model.
Because the repo mounts at its real path, sessions line
up across tools — a thread you started with
coop loop is right there to resume in your
editor.
coop's proxy owns the editor session. The toolbar grows
a coop dropdown to switch the credential
or preset mid-thread — the conversation survives the
switch. Every session runs yolo (the box is the
boundary, so there are no permission prompts to click).
A rate limit is handled for you: coop rotates to your
next signed-in account and re-sends your prompt — or,
with every account cooling, waits out the nearest reset
and sends then. And a box restart
(coop build / coop update, an
OOM) replays the handshake, so your editor never
disconnects.
Building a website? List the dev server's port under
serve: in a committed
.agent/project.yaml and the thread
announces the stable
http://localhost:<port> URL the
box publishes it at (bind the server to
0.0.0.0 inside the box).
PATH. If your editor can't find
coop, use the absolute path from
command -v coop as the
command.
Toolchain & services
Real projects need a language toolchain and a database. Declare them once, instead of having the agent reinstall them on every run.
If your repo pins versions in a
.tool-versions (asdf), the box provisions
that toolchain the first time and caches it — so a repo
with nothing but a .tool-versions just
works. For a fully reproducible image,
coop init --stack asdf bakes the same
versions into a Dockerfile.agent at build
time.
Need a Postgres or Redis alongside? They're opt-in —
coop init asks, or pass
--services postgres,redis — and run as
their own throwaway containers the box can reach by
name:
coop up # start the services, wait until healthy coop claude # the box reaches each service by its Compose name coop down -v # stop them and wipe the throwaway data
The final coop up status names the exact non-empty services
resolved by Compose, in Compose order. If resolution fails, Coop stops
before startup and tells you to fix the reported cause and retry
coop up.
To pull the latest agent CLIs and base image,
coop update rebuilds the box fresh;
coop build is the stable, pinned rebuild.
Configuration
Sensible defaults out of the box; a handful of knobs for when you need them.
Set these as environment variables or in
~/.config/coop/coop.conf. The ones you're
most likely to touch:
| Variable | What it does | |
|---|---|---|
COOP_GATE |
a command re-run in the box before a fork merge
lands (e.g. make check)
|
|
COOP_EGRESS |
none cuts the box off the network
entirely (loopback only). An agent can't reach
its model API this way, so it isn't a working
mode — it's for forensics: quarantine a box you
think is compromised, then exec in to see what it
did. The default is open.
|
|
COOP_RUNTIME |
force container /
docker /
podman instead of auto-detect
|
|
COOP_MEMORY ·
COOP_CPUS
|
cap the box's resources (e.g. 4g,
2)
|
|
COOP_<AGENT>_MODEL |
an agent's default model everywhere it runs
(e.g. COOP_CLAUDE_MODEL=opus)
|
|
COOP_LOOP_MODEL |
the model for loop iterations only — overnight runs on a cheaper model than interactive ones | |
COOP_CAFFEINATE |
on by default: while a loop runs, hold a sleep
inhibitor (macOS caffeinate) so the
machine doesn't idle-sleep mid-drain; set
0 to disable
|
|
COOP_SPINNER |
1 |
Animate Coop's live-view spinners: five-column Box Run beside progress bars and one-column Corner Run (◰ ◳ ◲ ◱) in dense task rows. Set to 0 or false to freeze them and suppress the loop's fast repaint ticker while debugging or recording. |
COOP_HOMES |
on by default: mount your per-agent home dirs
into the box; COOP_HOMES=0 keeps
them out so an agent can't read your host agent
configs
|
|
COOP_CONF |
relocate the coop.conf file coop
reads its COOP_* defaults from
|
|
NO_COLOR |
present at any value disables ANSI color everywhere (no-color.org) |
On Docker and Podman the box additionally runs with every Linux capability dropped, no-new-privileges, and a process cap. The complete list of variables lives in the README reference.
Troubleshooting
The handful of things that trip people up, and the quickest fix for each.
| Symptom | Fix |
|---|---|
| "no container runtime found" |
Install Apple container, Docker, or
Podman, then
coop build && coop doctor.
|
| "image isn't built" | Run coop build once. |
| Login hangs / "usage limit reached" |
Re-run coop login <agent>. A
subscription cap resets on a schedule — a loop
waits it out on its own.
|
| A detached loop won't quit |
coop fork logs <name> -f to
watch it;
coop fork stop <name> to stop
it.
|
| A secret is still visible |
Run coop doctor to see what's
shadowed, then add the path to
.coopignore.
|
The full troubleshooting guide and every command's flags
are in the
README
— or run coop help (and
coop <command> --help) for the live
reference.
Stuck on something not here? Open an issue.