# Cwcli

> Manage local Frappe/ERPNext Docker instances through the cwcli CLI - list instances, start/stop/restart them, check per-process health, back up and unlock sites, manage bench apps, and search cached apps and sites. Use whenever a task touches a local Frappe or ERPNext development instance, bench, or site: checking whether an instance is running, starting or restarting one, backing up or restoring a site, installing or updating bench apps, or finding which bench holds an app or site.

- Skill: `karotkriss/cwcli` (Agent Skill)
- Install (CLI): `npx skillmds@latest add karotkriss/cwcli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/karotkriss/cwcli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: karotkriss (https://skillmd.com/u/karotkriss)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/karotkriss/cwcli

---


# cwcli

Manage Frappe and ERPNext Docker instances - structured and non-interactive.

cwcli manages Frappe/ERPNext Docker instances for local development: instance lifecycle, bench and site operations, and backup/restore.

Use the `cwcli axi` surface, not the bare human commands.
It is the agent-facing half of the same tool: every verb prints one TOON document on stdout, never prompts, and takes every decision as a flag.

You do not need cwcli installed globally - invoke it with `uvx --from caffeinated-whale-cli cwcli axi ...`.
If cwcli output suggests a follow-up command starting with `cwcli`, run it as `uvx --from caffeinated-whale-cli cwcli ...` instead.

cwcli needs a running Docker daemon.
If a command reports `error: Could not connect to Docker`, ask the user to start Docker rather than retrying.

## When to use

Use cwcli whenever a task touches a local Frappe or ERPNext instance: checking what instances exist and whether they are running, starting/stopping/restarting one, reading per-process health, backing up or unlocking a site, listing or updating a bench's apps, or finding which bench holds a given app or site.

## Workflow

1. Run `uvx --from caffeinated-whale-cli cwcli axi` with no arguments for the home view: the live instance list plus suggested next commands.
   Start here - it answers "what exists and is it up?" in one call.
2. Drill in with the verb you need: `status <project>`, `benches <project>`, `apps list <project>`, `backup <project> --site <site>`.
3. A project with several benches needs `--bench <index|label>`.
   When a verb reports `multiple benches; pass --bench`, run `axi benches <project>` - it is the verb that answers every other verb's `--bench`, and it lists the valid values.
4. When a response includes a `help:` hint, follow it.

## Reading the output

Every verb prints one [TOON](https://toonformat.dev) document on stdout:

```
instances[2]{projectName,status,ports}:
  my-erp,running,8000 8001
  old-proj,exited,N/A
```

Errors are structured on stdout too, with an actionable `help:` line:

```
error: multiple benches; pass --bench <index|label>
options[2]:
  [0] /workspace/development/frappe-bench
  [1] /workspace/development/staging-bench
help: re-run with --bench <index|label>
```

Exit codes: **0** success (a completed operation, including one with warnings, and a successful read that reports bad news), **1** error, **2** usage error - a flag is missing or wrong, and the `help:` line names the fix.

## Verbs

```
  ls             List all Frappe/ERPNext instances; emit them as TOON.
  where          Search cached instances for apps/sites matching a string; emit matches as TOON.
  backup         Back up a site's database (and optionally files); emit the outcome as TOON.
  unlock         Remove a site's locks folder; emit the outcome as TOON.
  stop           Stop a project's containers, or one bench's dev processes; emit TOON.
  start          Start a project's containers + bench; emit the outcome as TOON (never prompts).
  status         Report every bench's per-process health; emit the report as TOON (`overall` first).
  logs           Read a bounded tail of a bench's per-process logs; emit them as ONE TOON document.
  url            Resolve a bench's host URL and probe it fresh; emit both as TOON.
  restart        Restart ONE supervised process; emit the outcome as TOON (never prompts, no --watch).
  scale          Widen the instance's published port range; emit the new port map as TOON.
  inspect        Inspect a project's benches, sites, and apps; emit the report as TOON.
  benches        List a project's benches with their indices, labels, and existence state; TOON.
  label          Set or clear a bench's durable user label; emit the outcome as TOON.
  migrate        Run 'bench migrate' against ONE site under maintenance mode; emit the report as TOON.
  run-tests      Run 'bench run-tests' for ONE app against ONE named site; emit the report as TOON.
  build          Run 'bench build' to compile the bench's assets; emit the report as TOON.
  config         Report the effective cwcli configuration; emit it as one TOON document; READ-ONLY.
  doctor         Run the system-wide, read-only environment preflight; emit it as one TOON document.
  init           Provision a new instance, bench, and site; emit the report as TOON (never prompts).
  rm             Permanently remove an instance; emit the outcome as TOON (never prompts).
  rm-site        Permanently drop ONE site; emit the outcome as TOON (never prompts).
  self-update    Report whether a newer cwcli is available; emit the check as TOON; READ-ONLY.
  setup          Install the SessionStart hook into every detected agent harness; emit TOON.
  apps list      List a bench's available apps, and (with --installed/--site) installed per site.
  apps update    Update app(s) and migrate affected sites; emit the report as TOON.
  apps checkout  Fetch and check out a ref into an app already in the bench; emit the report as TOON.
  apps install   Ensure and install ONE app on ONE named site; emit the report as TOON.
```

Run `uvx --from caffeinated-whale-cli cwcli axi <verb> --help` for a verb's flags.

## Rules

- **Never prompts.** A missing decision is a usage error naming the flag, never a hang. If a verb seems to want input, pass the flag its `help:` line names.
- **Read verbs exit 0 even when the news is bad, with one exception: `axi doctor`.** `axi status` on a fully stopped project, and `axi self-update --check` on an outdated install, both succeeded - the answer is in the document, not the exit code. `axi doctor` is a chainable preflight gate and exits non-zero when a check fails by design; read its `ok`/`failed` fields rather than treating the exit code as "doctor itself failed".
- **`axi` output is always TOON, never JSON.** JSON lives on the human commands' `--json` flag. Do not pass `--json` to an `axi` verb.
- **Destructive access is verb-specific.** Registered verbs such as `axi rm` and `axi rm-site` carry their own consent and data-safety gates; follow each verb's help exactly. There is no `axi apps uninstall` (uninstalling an app drops its tables) or `axi restore`. Ask the user to run the human command for those operations; do not work around their absence.

## Ambient context (optional)

`uvx --from caffeinated-whale-cli cwcli axi setup` installs a SessionStart hook into Claude Code, Codex, and OpenCode, so the home view lands in every session's opening context automatically.
It is the same information this skill describes, plus live state.
The user only needs one of the two.

