Overview
5dive is a single Bash entry point installed at /usr/local/bin/5diveon any Linux+systemd host. It is the canonical way to create, inspect, and tear down agents — and it's the same binary that runs every agent on the managed 5dive.com VMs (no open-core split). The CLI is intentionally narrow and emits structured JSON whenever --json is passed, so it is safe to script against from a dashboard, a webhook, or another agent.
Each agent is one Linux user (agent-<name>) in the claude group, one systemd unit (5dive-agent@<name>.service), and one tmux session (agent-<name>). The unit runs the chosen CLI binary inside a tmux restart loop with the agent type's shared credentials injected via EnvironmentFile.
This page is the reference manual. It is written so an LLM can use the CLI without trial-and-error: every flag, every exit code, and every state path is listed below.
Quickstart
Install on any Linux host with systemd (requires sudo):
curl -fsSL https://install.5dive.com | sudo bashThen run the interactive first-run wizard — it walks you through picking an agent type, signing in, optionally pairing a Telegram bot, and creating your first agent:
5dive initIf you'd rather script the agent create step (CI, reproducible setup), here's the explicit path to a running Claude agent paired to Telegram:
# 1. Authenticate the Claude CLI once (covers every claude-typed agent)
sudo 5dive agent auth login claude
# 2. Spawn an agent named "scout" wired to Telegram
sudo 5dive agent create scout \
--type=claude \
--channels=telegram \
--telegram-token=123456:ABC...
# 3. Pair the bot to your chat (DM the bot, then paste the code it replies)
sudo 5dive agent pair scout --code=AB12CD
# 4. Inspect — should print state=running
sudo 5dive agent stats scoutAll commands exit non-zero on failure with an exit code drawn from the table at the bottom of this page. Add --json to any of them to get a parseable envelope on stdout. For declarative many-agent setups, see Compose.
Concepts
Agents
An agent is a long-running tmux session running one of the supported coding CLIs (Claude Code, Codex, Antigravity, Grok, openclaw, hermes, opencode). It owns its own Linux user, its own home directory, and — when paired — its own bot/app token. Two agents of the same type can coexist on one host.
Accounts (named auth profiles)
By default every agent of a given type shares one set of credentials, stored under /etc/5dive/connectors/<type>.env. To run two agents of the same type against different accounts, create a named account once and bind agents to it: 5dive account add personal, 5dive account login personal --type=claude, then --auth-profile=personal on agent create (or 5dive agent set-account <agent> personal after the fact). See Accounts for the full surface. The lower-level auth set --auth-profile=<name> and auth login --auth-profile=<name>verbs still work and back the dashboard's device-code flow.
Channels
A channel is the inbound message surface the agent listens on. Today: telegram, discord, or none. Every agent type supports Telegram — natively where the CLI ships an MCP plugin contract (claude, openclaw, hermes), and via a bundled 5dive bridge for the rest (codex, grok, antigravity, opencode). Discord is currently claude / openclaw / hermes only.
Workdir
The tmux session starts in the agent's workdir. Default is /home/claude/projects. Override at create time with --workdir=..., or change later with 5dive agent config <name> set workdir=....
JSON output
Pass --json as a global flag (anywhere on the command line) to switch stdout to a stable envelope. Progress lines (==>) keep going to stderr so the JSON on stdout is always parseable. The exit code matches error.code on failure.
{
"ok": true,
"data": {
"name": "scout",
"type": "claude",
"channels": "telegram",
"workdir": "/home/claude/projects",
"created": true
}
}{
"ok": false,
"error": {
"code": 6,
"class": "auth_required",
"message": "claude is not authenticated (missing) — run: sudo 5dive agent auth login claude"
}
}Branch on error.class for stable program flow — the human-readable message changes, the class does not.
Agent types
5dive agent types lists every supported CLI on the host along with auth state and an installed boolean. Types missing from disk are installed on demand the first time you agent create them.
| Type | Channels | Auth flow | Notes |
|---|---|---|---|
| claude | telegram, discord | setup-token / API key | Anthropic Claude Code. Default for new agents. |
| codex | telegram | OpenAI device flow / API key | OpenAI Codex CLI. |
| antigravity | telegram | Google OAuth | Google Antigravity CLI. |
| grok | telegram | xAI device-auth / API key | xAI Grok CLI. |
| hermes | telegram, discord | OpenAI device flow / API key | Nous Research hermes harness. |
| openclaw | telegram, discord | OpenAI device flow / API key | Third-party Claude harness, OpenAI-backed. |
| opencode | telegram | none / optional API key | opencode.ai. Free models, no signup required. |
Isolation tiers
Every agent runs as its own Linux user, but the blast radius of that user is configurable. Pick a tier at create time with --isolation=<tier> — default is admin.
| Tier | Access |
|---|---|
| admin | Full host. In the claude + sudoers groups; can install software, spawn subagents, and read shared project state. Default. |
| standard | Shared read, limited write. In the claude group (so cross-agent reads work) but no sudo. |
| sandboxed | Own home only. No claude group, no sudo, systemd resource limits. Use for untrusted prompts or work that must not see your other agents. |
sudo 5dive agent create scout --type=claude --isolation=sandboxedAuthentication
Auth is decoupled from agents. You authenticate a typeonce (optionally under a named profile) and every agent of that type inherits the credentials via systemd's EnvironmentFile.
Interactive login (TTY)
sudo 5dive agent auth login claudeHands this process off to the upstream CLI's interactive flow. Don't use this from a dashboard; use the device-code variant below instead.
API key
# Direct
sudo 5dive agent auth set claude --api-key=sk-ant-...
# From stdin (recommended — keeps the key out of shell history)
echo "$KEY" | sudo 5dive agent auth set claude --api-key=-Anthropic sk-ant-oat01-* tokens are routed to CLAUDE_CODE_OAUTH_TOKEN; everything else becomes ANTHROPIC_API_KEY.
Non-TTY device-code flow
The dashboard uses this flow because it runs without a PTY. Each call is async — start, poll until you get a URL, show the URL to the user, then submit the callback code the upstream login redirects to.
# 1. Start a session — returns a session id
sudo 5dive agent auth start claude --json
# -> {"ok":true,"data":{"session":"01HXX..","state":"awaiting_url"}}
# 2. Poll until state=awaiting_code; data.url is what the user opens
sudo 5dive agent auth poll 01HXX.. --json
# 3. User pastes the callback code from the redirect URL back to you
sudo 5dive agent auth submit 01HXX.. --code=anthropic#abc123
# 4. (optional) cancel a pending session
sudo 5dive agent auth cancel 01HXX..Status
# Sentinel-only (fast)
sudo 5dive agent auth status
# Live probe — actually calls the API
sudo 5dive agent auth status --probe
# One type only
sudo 5dive agent auth status --type=claude --probeAccounts
An account is a named bundle of credentials that one or more agents can share. Accounts are the user-facing surface over the lower-level auth profile primitive: the same on-disk storage, friendlier verbs.
Use accounts when you want two agents of the same type to authenticate against different sign-ins (e.g. personal + work Anthropic accounts), or when you want a single sign-in to feed many agents — re-authing the account heals every agent bound to it in one shot.
Create and sign in
# 1. Create an empty account
sudo 5dive account add personal
# 2. Sign in interactively (TTY hand-off)
sudo 5dive account login personal --type=claude
# Or, set an API key non-interactively
echo "$KEY" | sudo 5dive agent auth set claude \
--api-key=- --auth-profile=personalNames: lowercase letters, digits, _, and -; must start with a letter; max 32 characters. The literal name defaultis reserved (it's the magic value agent set-account <agent> default uses to clear a binding).
Inspect
sudo 5dive account list # name, types signed in, # agents bound
sudo 5dive account show personal # detail incl. env keys present
sudo 5dive account usage # per-account 5h/7d rate-limit usage{
"ok": true,
"data": [
{ "name": "personal", "types": ["claude"], "agents": ["scout","builder"] },
{ "name": "work", "types": ["claude","codex"], "agents": ["work-bot"] }
]
}Bind agents
# At create time
sudo 5dive agent create scout --type=claude --auth-profile=personal
# After the fact (rebinds + restarts the agent to pick up the new env)
sudo 5dive agent set-account scout work
# Clear the binding (agent falls back to the shared default credentials)
sudo 5dive agent set-account scout defaultRename and remove
# Rename — repoints every bound agent's symlink and restarts the units
sudo 5dive account rename personal primary
# Remove — refuses if any agents still bind to it
sudo 5dive account remove primaryaccount remove is a safety net: if any agent has its authProfile set to the account, the command fails with class conflict (exit 5) and prints the agent names. Rebind or delete those agents first.
Account vs `agent auth` (lower-level)
The legacy agent auth set/login/start/poll/submit/cancel verbs still work — they take an --auth-profile=<name>flag and back the dashboard's device-code flow. Prefer account for human-driven flows; reach for agent auth start|poll|submit when you need the non-TTY device-code lifecycle from a programmatic caller.
Agent lifecycle
Create
sudo 5dive agent create <name> --type=<type> \
[--channels=none|telegram|discord] \
[--telegram-token=<bot-token>] \
[--discord-token=<token>] \
[--workdir=<absolute-path>] \
[--auth-profile=<name>] \
[--isolation=admin|standard|sandboxed] \
[--provider=<id> --api-key=<key|->] \
[--with-skills=<spec>[,<spec>...]] \
[--yolo | --autonomy=standard|yolo] \
[--no-skills] [--no-team-bot] [--defer-auth]Names: lowercase letters / digits / hyphens, must start with a letter, max 16 characters. The CLI installs the type binary on demand if it's missing, then refuses to create the agent unless the type is authenticated.
--with-skills preinstalls one or more skills on the new agent. Spec is either a bare id (defaults to 5dive-ai/skills) or <owner/repo>:<id>. Multiple specs are comma-separated. When the create call is made by another agent on a claude-typed agent, the flag defaults to --with-skills=5dive-cli so spawned children inherit inter-agent comms knowledge automatically. Use --no-skills to opt out. A failed skill install warns but does not roll back the agent — rerun 5dive agent skill <name> add ... to retry.
--defer-authskips the auth gate so the agent can be created before credentials exist (useful when the agent's own first-run UI handles sign-in). --provider=<id> --api-key=<key|-> is for hermes/openclaw only — BYO key for one of openrouter, google, minimax, moonshot, huggingface, anthropic, deepseek, qwen, nous, openai, zai (mutually exclusive with --defer-auth). When the host has a shared team bot configured, new no-bot agents auto-attach to it (own forum topic, send-only on the shared token) — --no-team-bot opts out.
--yolo (alias --autonomy=yolo) sets the agent's autonomy mode. claude-only: it appends a standing “act on your own recommendations, still honor hard gates” directive to the system prompt (via --append-system-prompt, so it survives a /clear) — the agent stops asking for permission on reversible work but still parks secrets/approvals on a human. Default is standard; change it later with agent config <name> set autonomy=....
List & inspect
sudo 5dive agent list # text or --json
sudo 5dive agent stats <name> # state, restart count, last exit
sudo 5dive agent logs <name> --lines=200 [--follow] [--tmux]--tmux dumps the tmux scrollback (what the user sees in the TUI). Without it, logs come from systemd / journalctl.
Start, stop, restart, remove
sudo 5dive agent start <name>
sudo 5dive agent stop <name>
sudo 5dive agent restart <name>
sudo 5dive agent rm <name> # removes user, unit, tmux session, envReconfigure
sudo 5dive agent config <name> set channels=<none|telegram|discord>
sudo 5dive agent config <name> set workdir=<path> # "default" clears
sudo 5dive agent config <name> set auth-profile=<name> # "default" clears
sudo 5dive agent config <name> set telegram.token=<token>
sudo 5dive agent config <name> set discord.token=<token>
sudo 5dive agent config <name> set model=<id> # claude/codex/grok/antigravity;
# claude: opus|sonnet|haiku|fable
sudo 5dive agent config <name> set effort=<low|medium|high|xhigh|max>
# claude only — reasoning effort;
# xhigh/max are Opus-tier
sudo 5dive agent config <name> set autonomy=<standard|yolo>
# claude only — yolo appends the "act on
# your recs, still honor hard gates" directive
# Shorter alias for the auth-profile case
sudo 5dive agent set-account <agent> <account|default>Send input / attach
# Inject a message into the running tmux session (sends keys + Enter)
sudo 5dive agent send <name> "implement the dashboard skeleton"
# Hand off a chat request: tells the receiver to answer in that
# Telegram/Discord chat via its OWN bot instead of relaying back
sudo 5dive agent send <name> "user asks ..." --reply-to-chat=<id> [--reply-to-msg=<id>]
# Attach your terminal to the session — Ctrl-b d to detach
sudo 5dive agent <name> tuiWhen called from another agent, send auto-wraps the payload with a [5dive-msg from=<sender> id=<id>] envelope so the receiver knows who pinged it. Use --from=<label> to override and --raw to skip wrapping. See Inter-agent comms for the full protocol and the synchronous agent ask wrapper.
Clone
sudo 5dive agent clone <src> <dst> [--channels=...] \
[--telegram-token=...] [--discord-token=...] [--workdir=...]Clones type, workdir, and auth profile from <src>. Channel + tokens must be passed fresh — two agents cannot share a Telegram bot.
Compose (declarative)
Standing up many agents at once? Declare them in 5dive.yaml and bring the whole stack up in one command. Re-running 5dive up is idempotent — agents that already exist are left alone; only missing ones are created.
agents:
coder:
type: claude
workdir: ./repo
channels: telegram
telegram_token: ${TELEGRAM_TOKEN_CODER}
isolation: standard
skills: [5dive-cli]
reviewer:
type: codex
workdir: ./repo
isolation: sandboxed
pm:
type: claude
channels: telegram
telegram_token: ${TELEGRAM_TOKEN_PM}sudo 5dive up # bring everything up (idempotent)
sudo 5dive ps # status of each agent in the file
sudo 5dive down # stop + remove everything declared
sudo 5dive export # dump the LIVE fleet to a 5dive.yaml (reverse direction)
# Default file: 5dive.yaml or 5dive.yml in cwd; override with -f <file>${VAR} placeholders are strictly expanded from the environment — unset references fail loudly (exit 3) rather than silently inserting an empty string. Relative workdir paths resolve against the directory holding the spec file (Docker-Compose convention). Spec keys per agent: type, channels, telegram_token, discord_token, workdir, skills, no_skills, defer_auth, isolation, auth_profile, provider, api_key, and pack — set pack: <slug> to build the agent from a published character pack instead of a bare type (the pack supplies the persona; the spec supplies the name + token).
Team templates
Bundled multi-agent company structures — provision a whole team in one call. team import wraps up, so it is idempotent too.
sudo 5dive team ls # list bundled templates
sudo 5dive team import <slug|path> [--auth-profile=<name>]Packs & marketplace
An agent pack is a portable .tar.gzof an agent's identity — instructions, skill refs, and a sanitized subset of its settings. Packs carry no secrets: tokens, API keys, sessions, and transcripts are hard-excluded. Use a pack to share an agent across users or hosts; agent clone remains the same-host, full-fidelity duplicate path.
Export
# Config-only pack (default — safe to share)
sudo 5dive agent export <name> --out=./mybot.tar.gz
# With persona memory — a two-phase, deny-by-default review gate
sudo 5dive agent export <name> --with-memory # 1. writes a redacted DRAFT to review/edit
sudo 5dive agent export <name> --approve-memory=<dir> # 2. seals the reviewed memory into the pack--with-memory never ships memory blind: phase one distills only reference/project knowledge facts (private user/feedback facts are excluded) into a draft directory for you to read and edit; nothing is packed until you re-run with --approve-memory=<draft dir>.
Marketplace & import
The character-pack registry (<org>/character-packs on GitHub) is a public catalogue of ready-made agent personas. Browse it, then import any entry by its bare slug into a fresh agent name:
# Browse the registry
sudo 5dive agent marketplace ls
# Import a published persona under a new name + your own bot
sudo 5dive agent import lilbro --as=scout \
--channels=telegram --telegram-token=123456:ABC...
# Import from a local .tar.gz you were handed
sudo 5dive agent import ./mybot.tar.gz --as=scoutimport takes either a registry slug or a local pack file and recreates the agent under --as=<name>. Because packs carry no secrets, you supply the new agent's own token / auth-profile / workdir at import time. Skills are re-added from their recorded refs (any skill not in a published repo is skipped and reported). The dashboard's Marketplace modal drives this same path.
Channels & pairing
A new agent created with --channels=telegram writes the bot token under /etc/5dive/connectors/telegram-<name>.env and starts an MCP plugin process inside the agent. The plugin is locked down by default — it ignores every chat until you pair one.
Pairing
# Option A — give the user a 6-character code, they DM the bot, paste it back
sudo 5dive agent pair <name> # prints/returns code
# Option B — paste the bot's reply directly (dashboard flow)
sudo 5dive agent pair <name> --code=AB12CD
# Option C — seed access.json directly with a known Telegram user id
# (pairs with agent telegram-discover, which long-polls getUpdates and
# returns {userId, chatId, username} on the first inbound DM)
sudo 5dive agent pair <name> --user-id=<id> [--chat-id=<id>]Allow-list
The plugin's allow-list lives at ~/.claude/channels/<channel>/access.json inside the agent's home. Pairing appends to allowFrom; rotate the bot token via 5dive agent config <name> set telegram.token=....
Skills
Skills are the skills.sh prompt-bundle format. A skill is a directory with a SKILL.mdat its root. Installing a skill on an agent drops it into the agent type's skills dir (~/.claude/skills/ for claude, ~/.hermes/skills/ for hermes, ~/.agents/skills/ for codex / opencode, ~/skills/ for openclaw) and makes it loadable on next prompt.
# Install a skill on an agent
sudo 5dive agent skill <name> add \
--source=<owner/repo> \
--skill=<skill-id>
# List installed skills
sudo 5dive agent skill <name> list
# Remove a skill
sudo 5dive agent skill <name> rm <skill-id>Tip: install the 5dive-cli skill from github.com/5dive-ai/skills on any agent to teach it the 5dive command surface — agent lifecycle, JSON envelope, recovery on exit codes, and the --json orchestration loop:
sudo 5dive agent skill <name> add \
--source=5dive-ai/skills \
--skill=5dive-cliWith it installed, an agent can spawn its own subagents on the same host — see Spawning subagents.
Spawning subagents
Any agent on a 5dive VM can call 5diveto spawn more agents on the same host — that's how recursion works. The agent user (agent-<name>) is in the claude group and has sudo 5dive ... in its sudoers, so:
# From inside one agent's tmux session — spawn a worker for a side task
sudo 5dive agent create worker-1 \
--type=claude \
--workdir=/home/claude/projects/myrepo \
--json
# Send it a task
sudo 5dive agent send worker-1 "audit auth middleware for OWASP A01"
# Watch its output
sudo 5dive agent logs worker-1 --tmux --lines=50
# Tear it down when done
sudo 5dive agent rm worker-1For LLM-driven orchestration, prefer --jsonon every call and branch on error.class rather than parsing the human stderr. The 5dive-cli skill packages this loop as a reusable prompt — install it on the parent agent and ask for “a worker that does X”.
Inter-agent comms
agent send and agent askform a tiny message bus between agents on the same host. There is no separate channel — messages land in the receiver's running CLI as if a human had typed them, but with an envelope that lets the receiver tell who is pinging it.
Auto-attributed sends
When the caller is an agent-* Linux user (i.e. one agent shelling out to talk to another), the CLI auto-detects the sender from $SUDO_USER and wraps the payload as:
[5dive-msg from=<you> id=<8-hex>] <your text>Humans calling sudo 5dive agent send directly are unaffected — only sends from agent users get the envelope. Override with --from=<label> or skip wrapping entirely with --raw.
Replying
A receiver that sees a wrapped message replies the same way it would talk to anything else — by name. The [re=<id>] prefix is convention, not enforced; it lets the sender match replies when juggling several outstanding asks.
# Inside the receiver's session, after seeing
# [5dive-msg from=scout id=ab12cd34] please summarise the audit
sudo 5dive agent send scout "[re=ab12cd34] auth middleware looks clean except ..."Synchronous request/response: agent ask
sudo 5dive agent ask <name> "<prompt>" \
[--from=<sender>] \
[--timeout=120] \
[--idle-secs=5] \
[--poll-secs=2] \
[--json]Sends the wrapped envelope, then watches tmux capture-pane after the marker line until the slice has been quiet for --idle-secs (default 5s) — at which point it returns the reply body. Times out with class timeout (exit 11) if the receiver never goes idle within --timeout.
{
"ok": true,
"data": {
"name": "scout",
"from": "coordinator",
"msg_id": "ab12cd34",
"reply": "auth middleware looks clean except for ..."
}
}Caveats
Idle-by-stability is heuristic. A receiver that streams progress continuously will keep ask awake until --timeout fires. For long agentic work, prompt the receiver for a terse final summary, or use plain send + logs and poll on your own schedule.
The reply is whatever was on screen. It includes any chrome the receiver CLI prints (cursor lines, status hints) — don't expect a clean JSON body unless the prompt explicitly asks for one.
No retries, no delivery confirmation. If the receiver crashed mid-reply you'll get a partial slice or a timeout, nothing in between.
When to use what
Fire-and-forget delegation: agent send, then poll agent logs --tmux at your own convenience. Need an answer before continuing: agent ask. Fan-out across N workers: loop agent send, or run several agent ask calls in parallel via & + wait.
Task queue
A host-shared work queue (sqlite at /var/lib/5dive/tasks/tasks.db) that any agent in the claude group can use without sudo. Tasks have priorities, assignees, parent/subtask links, and blocking edges — the substrate for delegating work across a fleet.
5dive task add <title...> [--body=<text>] [--priority=low|medium|high|urgent] \
[--assignee=<agent>] [--parent=<id>] [--project=<key>] [--recurring="<cron>"]
5dive task ls [--mine] [--status=<s>] [--all] [--project=<key>] [--recurring]
5dive task show <id|PREFIX-N> # full detail + subtasks + blockers
5dive task start <id|PREFIX-N> # -> in_progress
5dive task done <id|PREFIX-N> [--result=<text>]
5dive task cancel <id|PREFIX-N> [--result=<text>]
5dive task assign <id|PREFIX-N> <agent>
5dive task escalate <id|PREFIX-N> # flag for attention: bump priority a tier + ping owner & human
5dive task block <id|PREFIX-N> --by=<id|PREFIX-N> # + unblock to clear
5dive task rm <id|PREFIX-N> # delete (cascades subtasks + edges)Statuses: todo → in_progress → done / cancelled, plus blocked while a blocking edge or human gate is open. --recurring="<cron>" (5-field cron) makes a template that re-instantiates on schedule. Task ids are PREFIX-N — the default dive project numbers DIVE-1, DIVE-2…; see Projects to carve out your own namespace.
Verify loops (maker → verifier)
A task can carry a declarative acceptance loop so “done” is proven, not just claimed. Attach acceptance criteria, a verify command, and (optionally) a separate verifier agent at create time:
5dive task add "ship the export endpoint" \
--accept="returns 200 + a .tar.gz" \
--verify="curl -fsS localhost:3000/export -o /tmp/o && file /tmp/o | grep gzip" \
--verifier=reviewer --max-iters=35dive task verify <id|PREFIX-N> [--cmd="<command>"] [--no-done]
# run the check; exit 0 => proven-done (flips to done)
5dive task reject <id|PREFIX-N> [--feedback="<what to fix>"]
# verifier's FAIL verdict — bounce back to the maker
5dive task loops [--stuck] [--all] [--escalate-stuck]
# board of active loops: iteration/cap + ⚠ stuck flagWith a --verifier(which must differ from the assignee), the maker's task done does not close the task — it hands off to the verifier, who grades against the criteria / runs task verify, then closes it on PASS or task reject --feedback= on FAIL (bounce back to the maker, or escalate to a human at --max-iters). The writer never grades itself. task loops is the observability view — --escalate-stuck pings the owning agent + the human on loops that have stalled.
Human task inbox
When an agent needs a decision, approval, secret, or a manual step only a person can do, it parks the task on a human instead of guessing:
5dive task need <id> --type=decision|secret|approval|manual \
--ask="<one crisp question>" [--options=A|B] [--recommend="A"]
5dive task inbox # list ONLY human-gated tasks
5dive task answer <id> --value="..." # record answer, unblock, ping the agentThe gate pings the owner (Telegram inline buttons when paired); answer clears it and wakes the owning agent to resume.
approval and secret gates are human-only: an agent-* caller is refused, and once gate-proof enforcement is on they require a --proof=<token>that only a real human tap mints — so a sudo-capable agent can't silently clear its own approval gate. Trusted UI paths (dashboard, the Telegram approve button) attach the proof automatically.
Projects
A project carves the shared task queue into its own identifier namespace. Every host starts with the built-in dive project (prefix DIVE-, so tasks number DIVE-1, DIVE-2…). Add your own so unrelated streams of work get their own readable ids (FROG-1, POST-1) instead of sharing one counter.
sudo 5dive project add frogs --prefix=FROG \
[--name="Frog app"] [--goal="<one-liner>"] \
[--folder=/home/claude/projects/frogs] [--lead-agent=<agent>]
5dive project ls # key, prefix, task count, lead, status
5dive project show <key> # detail
# Then file work into it — ids auto-number per project:
5dive task add "build the pond view" --project=frogs # -> FROG-1
5dive task ls --project=frogsA prefix is UPPERCASE letters only. Tasks filed with --project=<key> number independently within that project; everything else in the task queue (assignees, blockers, gates, loops) works identically across projects.
Usage & budgets
5dive usagereports per-agent and per-task token burn — the subscription tokens an agent consumed, not dollars. Use it to see which agents and which tasks are eating the shared account's budget.
5dive usage [--7d] # board: top agents + top tasks by tokens (24h default)
5dive usage <agent> [--7d] # one agent: per-model + per-task breakdown
# Soft daily budgets — a board warning, not a throttle
sudo 5dive usage budget set <agent> --daily=<tokens>
5dive usage budget ls
sudo 5dive usage budget clear <agent>A budget is advisory: crossing it flags the agent with ⚠ on the usage board — nothing is throttled or stopped. Pair it with account usage (Accounts) for the 5h/7d rate-limit picture per sign-in.
Org chart & heartbeat
Org chart
A lightweight reporting structure over the agents on a host — who manages whom, and what each agent's role is. Dashboards and coordinator agents read it to route work.
5dive org set <agent> --manager=<agent> [--role=<text>] [--title=<text>]
5dive org tree # render the hierarchy
5dive org show <agent> | ls | rm <agent>Heartbeat (wake-on-work)
Enrolled agents are woken only when they have queued tasks — one task per tick — instead of idling in a hot loop. The root cron driver is heartbeat tick.
sudo 5dive heartbeat on <name> [--every=<dur>] [--no-fresh] # default 30m;
# /clear before each task unless --no-fresh
sudo 5dive heartbeat off <name>
sudo 5dive heartbeat ls # enrolled agents + next wake + queued count
sudo 5dive heartbeat tick # cron driver (root); wakes due agents with workDoctor & health
5dive doctor walks every dependency (tmux/jq/bun/python3/nvm/node/npm), every type binary, every live auth probe, the creds heal (renames a stale ~/.claude/.credentials.json that would shadow an env-injected token), registry integrity, channel-plugin wiring, and shelld reachability.
# Read-only check
sudo 5dive doctor --json
# Fix what's fixable (apt installs, type installer recipes, registry reseed)
sudo 5dive doctor --repair
# Narrow the scope
sudo 5dive doctor --category=deps # or types | auth | creds | registry | shelld | channelsEnvelope is always {ok: true, data: {summary, checks}} with exit 0 — branch on data.summary.errors > 0 in CI.
Updating & uninstall
5dive --version # what's installed
5dive update --check # read-only: is the CLI behind/stale? (no root)
sudo 5dive self-update # update CLI + plugins, then restart agents
# (alias: sudo 5dive update)
sudo 5dive watch [--interval=N] # htop-style live view of every agent;
# ↑↓ select, ↵ attach, r refresh, q quit
sudo 5dive uninstall [--purge] [--yes] # remove 5dive; --purge also wipes
# state + agent usersManaged 5dive.com boxes update nightly on their own; self-update is the on-demand path for self-hosted installs.
Exit codes
Both shell exit code and error.code in the JSON envelope. Branch on error.class for human-stable matching.
| Code | Class | Meaning |
|---|---|---|
| 0 | ok | Success |
| 1 | generic | Catch-all / internal error |
| 2 | usage | Unknown flag, missing arg, bad subcommand |
| 3 | validation | Format check failed (name, workdir, token, lines) |
| 4 | not_found | Agent/type/session doesn't exist |
| 5 | conflict | Already exists (name collision) |
| 6 | auth_required | Type not authenticated, bot token missing |
| 7 | not_installed | CLI binary missing, no installer recipe |
| 8 | not_running | tmux session / systemd unit not active |
| 9 | pairing | Pair code not pending or invalid |
| 10 | permission | Must run as root |
| 11 | timeout | Plugin didn't materialize within waitloop |
State & paths
Useful only when debugging — every path below is managed by the CLI. Don't edit by hand.
| /var/lib/5dive/agents.json | Agent registry (versioned). Source of truth for `agent list`. |
| /var/lib/5dive/agents.d/<name>.env | Per-agent systemd EnvironmentFile. |
| /var/lib/5dive/auth-profiles/<name>/ | Named auth profile env files + captured CLI config. |
| /var/lib/5dive/auth-sessions/<id>/ | Live device-code session state. |
| /etc/5dive/connectors/<type>.env | Shared auth env (default profile). |
| /etc/5dive/connectors/telegram-<name>.env | Per-agent bot token. |
| /etc/systemd/system/5dive-agent@.service | Templated systemd unit. One instance per agent. |
| /var/lib/5dive/tasks/tasks.db | Shared task queue (sqlite). Group-writable — agents use it without sudo. |
| /var/log/5dive/agent-audit.log | NDJSON audit trail of every mutating command. |