@zerowidth/cli
v0.1.0
Published
Command-line interface for ZeroWidth — your workspace's flows, docs and tools from the terminal
Maintainers
Readme
ZeroWidth CLI
Command-line interface for ZeroWidth — your workspace's flows, docs and tools from the terminal.
A thin client over ZeroWidth's MCP endpoint. List, run, and chat with flows, search docs, manage profiles, and call any ZeroWidth tool from a terminal or shell script.
Install
npm install -g @zerowidth/cliInstalls two commands: zerowidth and the short alias 0w (interchangeable). Requires Node.js 22 or later.
Or run it without installing:
npx @zerowidth/cli flow lsQuick start
zerowidth login # browser-callback auth (or `--paste` for headless)
zerowidth doctor # confirm everything's wired
zerowidth flow ls
zerowidth flow run flw_2nQs # run a flow in your workspace
zerowidth flow run --local ./my-flow.zwf # or run one on your machine, no API callA real session
$ zerowidth flow ls --tag triage --limit 3
┌──────────────────┬───────────────────┬────────────┬─────────────────────┐
│ id │ name │ visibility │ updatedAt │
├──────────────────┼───────────────────┼────────────┼─────────────────────┤
│ flw_2nQs… │ Inbox triage │ workspace │ 2026-04-21T10:14:02 │
│ flw_3pX1… │ Lead summarizer │ workspace │ 2026-04-19T16:08:55 │
│ flw_5tA9… │ Doc Q&A │ private │ 2026-04-12T09:33:11 │
└──────────────────┴───────────────────┴────────────┴─────────────────────┘
$ zerowidth flow run flw_5tA9 --session docs-qa
✓ Inputs collected (1)
chat ▸ How do PATs scope to workspaces?
A personal access token (PAT) inherits the scopes you pick at login time…
[markdown rendered to the terminal]
▸ $0.0024 · 1.4s · exec a13c0f72…
chat ▸ /save
✓ saved as docs-qa
chat ▸ /exitResume the conversation later with zerowidth flow run flw_5tA9 --session docs-qa — the last few messages reprint, and you continue where you left off.
For scripts, drop --non-interactive and pipe the JSON output anywhere:
zerowidth flow run flw_5tA9 --non-interactive --input question="..." --json | jq .outputCommands
Auth and diagnostics
| Command | |
|---|---|
| zerowidth login [--paste] | Authenticate via browser callback (or paste a PAT manually). |
| zerowidth logout | Forget the stored token. |
| zerowidth whoami | Verify the stored token; show API URL, kind, visible tools. |
| zerowidth doctor | Run health checks — node version, API reachable, token valid, etc. |
| zerowidth upgrade [--dry-run] | Upgrade the CLI to the latest version on npm (--dry-run only checks). |
Flows
| Command | |
|---|---|
| zerowidth flow ls [--tag] [--limit] | List flows. |
| zerowidth flow get <id> | Read flow nodes, links, metadata. |
| zerowidth flow run <id> [--input k=v ...] [--input-json '{...}'] [--session name] [--trace mode] [--output file] [--non-interactive] | Execute. Interactive in a TTY (data wizard, then chat REPL if the flow has an input-chat node). One-shot otherwise. --non-interactive forces one-shot mode even in a TTY (useful for scripts that allocate a TTY). |
Inside the chat REPL: /help, /retry, /edit (opens $EDITOR), /clear, /show, /save, /branch <name>, /export <file>, /trace summary|full|none, /cancel (abort the in-flight turn), /exit. Multi-line input via """ on its own line.
Browse
| Command | |
|---|---|
| zerowidth docs search <query> | Full-text doc search. |
| zerowidth docs get <slug> | Read a docs page. |
| zerowidth docs ls [--product <slug>] | List docs pages, optionally filtered by product. |
Open in browser
| Command | |
|---|---|
| zerowidth open | Workspace dashboard. |
| zerowidth open flow <id> | Flow editor. |
| zerowidth open docs [slug] | Docs site. |
Profiles, config, sessions
| Command | |
|---|---|
| zerowidth profile ls / current / use <name> / rm <name> | Manage credential profiles (local, staging, prod, …). |
| zerowidth config show / set <k> <v> / unset <k> | Persistent CLI config (api_url, accounts_url). |
| zerowidth session ls / show <name> / rm <name> | Manage saved chat transcripts. |
Room agent
| Command | |
|---|---|
| zerowidth room-agent connect <token> | Save the token a room gave you when you brought the agent in. |
| zerowidth room-agent [--cwd <dir>] | Answer in rooms with the Claude Code on this machine. |
| zerowidth room-agent disconnect | Forget this profile's agent token. |
Bring an agent into a ZeroWidth room from its People menu, save the token it shows you once, and run it in the folder you want it to read:
zerowidth room-agent connect zwa_…
zerowidth room-agent --cwd ~/code/my-repoIt answers whenever someone in that room @mentions it. Nothing connects
in — the command asks ZeroWidth for work, runs Claude Code headless with
that room's context, and posts the answer back.
Claude Code is read-only here: it reads and searches files, never
edits them or runs commands, and .env, .pem and .key files are
denied outright. Each room keeps its own session, so follow-up questions
carry on from earlier ones.
The token is stored per profile, so a client's workspace and your own can
each keep their own agent. ZW_AGENT_TOKEN overrides it for containers
and CI. Requires Claude Code on your
PATH (--claude points at it elsewhere).
Generic MCP access
| Command | |
|---|---|
| zerowidth mcp inspect | List every catalog tool your current token can see. |
| zerowidth mcp call <tool> [--arg k=v ...] | Call any tool by name — escape hatch for tools not yet wrapped as a curated command. |
Shell completion
Auto-detect your shell and wire it up in one step:
zerowidth completion --installOr print the script and place it yourself:
zerowidth completion bash >> ~/.bashrc
zerowidth completion zsh >> ~/.zshrc
zerowidth completion fish > ~/.config/fish/completions/zerowidth.fishInputs and arguments
--input and --arg flags accept repeatable key=value pairs. Values are parsed as JSON when they look like JSON literals, and fall back to strings otherwise:
zerowidth flow run my_flow \
--input prompt="Summarize this" \
--input limit=5 \
--input verbose=true \
--input tags='["a","b"]'For complex inputs, pass a JSON object directly:
zerowidth flow run my_flow --input-json '{"prompt":"Hello","options":{"limit":5}}'In a TTY, flow run walks each input interactively with names + types + defaults, pre-filling values you passed via --input.
Run flows locally
Design a flow on zerowidth.ai, export it as .zwf (or copy it as JSON), and run it on your laptop with no API call:
export OPENROUTER_API_KEY=sk-or-...
zerowidth flow run --local ./my-flow.zwf \
--input prompt="Summarize this" \
--jsonThe CLI hands the flow to the Workbench SDK (the same engine ZeroWidth runs), which executes it in-process with your BYOK provider keys. No tokens, no API round-trip, no connection to ZeroWidth. The SDK is an optional dependency, so it installs with the CLI by default. Both .zwf and plain .json flow files are supported.
Key resolution — later wins, so flags override env which overrides file:
| Source | Form |
|---|---|
| ~/.config/zerowidth/profiles/<profile>/keys.json | { "openrouter": "...", "openai": "..." } |
| Environment | OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY, MISTRAL_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY |
| Flag | --key openrouter=sk-or-... (repeatable) |
zerowidth doctor reports whether the SDK is installed and ready. If it was skipped (for example with --omit=optional), --local prints a reinstall hint (npm install -g @zerowidth/cli --include=optional) and exits without trying.
Current limitations: local execution is one-shot only — flows with input-chat nodes need their messages provided via --input chat='[...]' or --input-json '{...}'. The streaming chat REPL still runs through your ZeroWidth workspace. This will likely change in a future release.
Profiles
Each profile has its own credentials and URLs. Switch between local / staging / prod without re-logging-in:
zerowidth --profile local login
zerowidth --profile prod login
zerowidth profile use prod # set the default for future shells
zerowidth --profile staging flow ls # one-off overrideProfiles live at ~/.config/zerowidth/profiles/<name>/.
The active profile is resolved in this order, first match wins:
--profile <name>flag on the current commandZEROWIDTH_PROFILEenvironment variable~/.config/zerowidth/active_profile(set byzerowidth profile use <name>)default
Output format
Pretty tables in a terminal, raw JSON when piped or with --json:
zerowidth flow ls # tabular
zerowidth flow ls --json # JSON
zerowidth flow ls | jq '.[].id' # JSON (auto-detected from the pipe)--quiet (or -q) suppresses status messages on stderr while keeping data on stdout. Useful in scripts.
Configuration
Credentials and config live under ~/.config/zerowidth/ on macOS/Linux (or %APPDATA%/zerowidth/ on Windows). Credentials are written with mode 0600.
| Env var | Effect |
|---|---|
| ZEROWIDTH_HOME | Override the config directory location. |
| ZEROWIDTH_PROFILE | Active profile name (overrides ~/.config/zerowidth/active_profile). |
| ZEROWIDTH_TOKEN | Personal Access Token to use for this invocation, bypassing stored credentials. Takes precedence over the saved token — handy for CI/agents that don't want to run login or persist a token to disk. |
| ZEROWIDTH_API_URL | API base URL (overrides saved config). Default: https://api.zerowidth.ai |
| ZEROWIDTH_ACCOUNTS_URL | Accounts hub base URL (used by browser login at /cli/auth). Default: https://accounts.zerowidth.ai |
| ZEROWIDTH_DEBUG=1 | Print every SSE event during chat REPL turns, and full stack traces on error (same as --debug). |
| ZEROWIDTH_NO_UPDATE_NOTIFIER=1 | Silence the once-a-day "newer version available" banner. |
| NO_COLOR | Disable colored output (any value). See no-color.org. |
| FORCE_COLOR | Force colored output even when not a TTY (e.g. CI logs). 0 forces it off. |
| HTTPS_PROXY / HTTP_PROXY | Route requests through an HTTP(S) proxy. Honors NO_PROXY for host bypass. |
Troubleshooting
When a command fails, the CLI prints a one-line hint underneath the error when it can recognize the failure mode — auth issues, rate limits, network errors, missing-tool 404s. Add --debug (or ZEROWIDTH_DEBUG=1) to any command to print the full stack trace, and --json to get the error as a machine-readable { "error", "hint" } object on stdout. If you're stuck, the first thing to run is:
zerowidth doctor # human-readable
zerowidth doctor --json # machine-readable, paste this into bug reportsDoctor probes node version, profile + URL config, API reachability, MCP endpoint availability, token presence, and token validity. It exits non-zero if any check fails.
The CLI checks for newer versions on npm at most once per day and prints a banner only in fully interactive terminals (never in pipes or scripts). Set ZEROWIDTH_NO_UPDATE_NOTIFIER=1 to silence it.
How it works
Catalog commands are a thin wrapper around ZeroWidth's unified MCP endpoint — POST {api_url}/mcp, spoken over the official Model Context Protocol Streamable HTTP transport with your PAT as a Bearer token. The CLI uses the standard @modelcontextprotocol/sdk client, so the server enforces the same scopes, audit, and quota that any other MCP client would see.
That means anything the CLI can do, your AI assistant in Claude Desktop or Cursor can do too — same catalog, same identity model, same audit rows.
Note:
flow run <id>executes a flow in your workspace over the ZeroWidth API, streaming the chat REPL live in an interactive terminal. Catalog commands (flow ls/get,docs,mcp inspect/call) run over the unified/mcpendpoint.flow run --local <file>runs a flow on your machine without any API call.
Contributing
Issues and PRs welcome. The unified MCP catalog at https://api.zerowidth.ai/mcp is the source of truth — any new tool that ships server-side is reachable via zerowidth mcp call <name> immediately. Curated commands (zerowidth flow ls, etc.) live in src/commands/.
License
Apache-2.0 — see LICENSE.
