Agents and the CLI
How to create, configure, and deploy an agent — and how agents act in sandboxes and sessions, how cost is tracked, and how to install and use the ch CLI.
Agents are configurations, not processes
In CodeHerder an agent is a durable workspace member: a display name, a role, capability labels used to rank it during auto-staffing, and optional device requirements. It carries one or more launch configs — the reusable “kind of worker” configuration: a command to run, arguments, environment variables, a persona description, and required capabilities (such as which AI model tier to use). An agent is not a long-lived process, and it does not accumulate state across tasks.
When the engine assigns a task to an agent, it:
- Creates a sandbox for the task — an isolated git worktree on a device, cut from the task’s base branch (the repository’s default branch unless the task names another).
- Spawns a fresh, clean-context process (a session) inside that sandbox, feeding it the task brief, the codebase, the workspace wiki, the agent persona, and the skills that apply at that stage. This list is not exhaustive. The coding-agent CLI also loads the repository’s own instructions (
CLAUDE.mdorAGENTS.md), its.claude/settings and hooks, and its.mcp.json, because CodeHerder pre-accepts project trust for the worktree. In process mode and--dockermode, the device user’s own harness configuration is reachable too. See Isolating agents on a device. - Lets the session run to completion for that stage.
- If the task advances to the next stage, it spawns a new session — again with no shared transcript from the previous session.
This model keeps per-session context windows small and costs predictable. Each session is billed independently.
Sandboxes and sessions
A sandbox is the durable per-task execution context, with its own branch and a lifecycle. A task-bound sandbox’s branch starts with task/, followed by the last 12 characters of the task’s ID (e.g. task/8f3a1c9e2b04). A task-free sandbox’s branch starts with session/ instead, followed by the last 12 characters of the sandbox’s own ID. The lifecycle:
provision → ready → active → completing → done (or abandoned)
A task-free sandbox, such as a session you start on a device, can also rest in stopped. A task sandbox never enters that state. stopped is not finished: the sandbox keeps its branch and can start again.
A session is one activation within a sandbox — one clean-context process doing one stage of the work. Several sessions may happen inside a single sandbox over the task’s lifetime (one per stage).
You can list a task’s sandboxes and their state with:
ch sandbox list <taskId>
ch sandbox list <taskId> --limit N --cursor <token>
ch sandbox show <sandboxId>
That task scope shows every sandbox regardless of state. It defaults to 50 rows, up to 200 with --limit.
Point it at a workspace instead to see every sandbox across the whole workspace — including a group’s, which rolls up sandboxes from every workspace nested beneath it:
ch sandbox list workspace [<ref>] # your current workspace if <ref> is omitted
ch sandbox list workspace --all # include done and abandoned sandboxes too
Unlike the task scope, the workspace scope hides done and abandoned sandboxes until you pass --all. A stopped sandbox still shows. This scope also pages at a larger size: 200 rows by default, up to 500 with --limit. See Choosing whose data a list shows for the scope keyword every list feed like this one shares, and Paging through long lists for how --cursor works.
Cost per session
Cost is tracked per session and reported in USD. For a full breakdown — including CLI commands, time windows, per-agent and per-model splits, and the web cost view — see Understanding costs.
Installing the CLI
The ch binary is the primary interface for agents and human operators alike. Install it with one command — it needs no sign-in:
curl -fsSL {{app_base}}/cli/install.sh | sh
The script detects your platform, verifies the published checksum and signature, and installs ch to ~/.local/bin/ch. To download and verify a binary by hand instead, see the Install CLI page in a workspace’s sidebar (under Set up).
Once installed, configure it with your API key:
export CH_TOKEN=<your-key>
export CH_WORKSPACE_ID=<your-workspace-id>
Verify with:
ch whoami
To keep the binary current, see Updating the CLI. For the full credential reference — including named profiles and credential precedence — see Credentials and profiles. For the conventions every command shares — discoverable help, short-form aliases, JSON output, and how to supply text — see Using the ch CLI.
The agents your workspace starts with
Every account starts with three agents. They live at the top of the account, and every workspace under it inherits them:
- Planner — plans, triages, and discovers work, on the opus tier.
- Builder — writes and lands code, on the sonnet tier.
- Reviewer — reviews and verifies finished work, on the opus tier.
Together they cover the built-in story workflow end to end. It runs plan, review, and verify on the opus tier, and code and merge on the sonnet tier. ch agent list shows all three.
They’re ordinary agents. Rename, disable, or archive any of them the same way you would one you created yourself. CodeHerder adds the roster once, to the account. A new workspace gets no copy of its own. If the account already has an agent, CodeHerder adds nothing.
Creating an agent
An agent is a workspace member of kind “agent”. You can create one from the CLI, from the web app, or by copying an existing agent from another workspace.
Creating or copying an agent needs workspace owner or admin — a member without that role doesn’t see the New agent or Copy agent button on the web app’s Agents page, and ch agent create is refused with a permission error from the CLI. See Why a control is missing.
Creating a runnable agent in one call
Add launch-config flags to ch agent create, and the agent gets its first launch config in the same call. It can run a task right away:
ch agent create --display-name "Builder" --cap model:opus --cap model:sonnet \
--harness claude --config-cap model:opus --config-cap model:sonnet
The command prints an agent ID. Keep it: you need it to add more launch configs (see Running more than one launch config).
This call carries two different capability flags. Mixing them up sets the wrong one without an error:
--capis the agent’s own skill labels. CodeHerder uses them to rank agents when it staffs a task. They are a soft preference, never a block.--config-capis the launch config’s capabilities. This is the hard gate: a stage runs on the config only if the config covers what the stage requires.ch agent config editspells this same idea--cap.
See Capabilities for the full soft-versus-hard rule. Pass either flag several times to declare several values.
--harness claude alone is enough. CodeHerder derives the launch command from the harness (see Choosing a harness). Pass --command instead to point at a specific binary.
Two more flags are useful at creation:
--rolesets a free-form label, such asicorleader. It defaults toic.--mint-keyprints an API key for the agent. CodeHerder does not store the key, so copy it at once. You use it to authenticate as this agent on a device.
ch agent create --display-name "Team lead" --role leader --cap model:opus \
--harness claude --config-cap model:opus --mint-key
Any launch-config flag starts the one-call flow: --harness, --command, --arg, --env, --config-cap, --persona, --system-prompt, --credential-ref, or --allowed-model. When you give one, you must also give --harness or --command. If CodeHerder rejects the launch config, for example an invalid harness or a malformed credential ref, it does not create the agent either. A failed call is safe to retry.
Give no launch-config flag, and CodeHerder creates an agent with no launch config. That agent cannot run a task. The CLI prints a hint to run ch agent config create <agent-id> --harness <h>. See Configuring the agent.
From the web app
On the Set up → Agents page, click New agent:
| Field | Notes |
|---|---|
| Display name | Required. |
| Role | Free-form, such as ic or leader. Defaults to ic if left blank — same default as the CLI’s --role. |
| Capabilities | The same skill labels as --cap on the CLI. Enter them separated by commas or spaces, e.g. model:sonnet, go. |
| Mint a one-time API key for this agent | A checkbox, on by default. Leave it checked to get a key immediately — the key is shown exactly once right after creation and CodeHerder never stores it, so copy it before dismissing the panel. Uncheck it if you don’t need a key yet; you can mint one later (see Minting API keys). |
| Harness | The coding-agent CLI to launch — see Choosing a harness below. Same field as --harness on the CLI. |
| Command | Derived from the harness automatically; edit only for an advanced override. Same field as --command on the CLI. |
| Launch config capabilities | The launch config’s hard gate — same field as --config-cap on the CLI, and distinct from the Capabilities field above. |
The web app’s New agent form always sets a launch config, so an agent created there can run a task right away. To add a second config, or change one later, see Configuring the agent.
Copying an existing agent
If a workspace you’re already a member of has an agent set up the way you want, you can copy it instead of starting from scratch. On the Set up → Agents page, click Copy agent.
The panel lists agents from your other workspaces. These are workspaces where you’re a direct member, not ones you only see through group inheritance. Pick one, optionally give the copy its own display name, and submit.
Copying carries over:
- role and capabilities,
- the source agent’s first enabled launch config (or its first config, if none is enabled): harness, command and args, capabilities, persona, system prompt, allowed models, and device requirements,
- environment variable keys, and any secret references (an env var bound to a workspace secret keeps pointing at that same secret).
Copying takes one launch config, even if the source agent has several. A credential ref carries over only if the target workspace can use that secret. Plain (non-secret) environment variable values are left blank on the copy, so you re-enter them afterward. Copying does not mint an API key. Add one later like any agent created without one (see Minting API keys).
If the source config’s args hold a value that looks like a credential — an API key, a token, a JWT, a connection string with a password in it — the copy is refused outright. See Keeping credentials out of a launch config below for what counts and how to fix it.
After the copy completes, you land on the new agent’s detail page, where you can fill in its launch config and any environment values the copy left blank.
Editing an agent
Update an agent’s own fields — as opposed to its launch config, covered below — with:
ch agent edit <agent> --display-name "Builder v2" --role leader --cap model:opus --cap go
--cap replaces the agent’s whole capability set — include every capability you want to keep. --clear-caps empties it instead; the two flags are mutually exclusive. A launch config’s own --cap follows the same rule: pass it, and it replaces the config’s whole capability list (see Flag reference below).
An agent can rename itself — --display-name is the one field a session running as that agent may change on its own agent record. Changing its role, capabilities, or device requirements needs workspace owner or admin, the same as creating or copying an agent.
--device-requirement and --clear-device-requirements set which devices the agent is allowed to run on — see Capabilities for what a device requirement is and how it’s enforced. Like --cap, --device-requirement replaces the full set on each call.
Pausing an agent — stopping it from picking up new work without touching its configuration — is its own pair of commands, not part of edit; see Monitoring your agents.
Archiving an agent
ch agent archive <agentRef>
ch agent restore <agentRef>
Archiving is a reversible retire: it revokes the agent’s API keys and its claude.ai/ChatGPT connector grants in the same step, and the agent stops picking up new work. Its history — sessions, costs, messages, wiki pages — is kept, and so are its launch configs. Restoring clears the archived state, but it does not re-issue the revoked API keys or connector grants — mint a fresh key afterward (see Minting API keys).
There is no ch agent delete. Typing it prints Did you mean: ch agent archive ? and runs nothing.
Web app: the Set up → Agents page has an Archive/Restore control on each agent’s row, and the same control appears again on the agent’s own detail page.
Archiving needs workspace owner or admin. The call must come from a human’s own credential, not from inside a running session. An agent’s session credential is refused.
ch agent archive refuses while any session of that agent is still live. Run ch session list agent <agentRef> --active to see which sessions are still running, and stop those first.
Finding an archived agent: ch agent list hides archived agents by default. Pass --archived to see only the archived ones, or --all for every agent, active and archived together — its STATE column reads active, disabled (since <when>), or archived (since <when>). See Listing archived records for how this flag works across CodeHerder. ch agent list also takes --enabled/--disabled, narrowing on that same STATE column instead — see Listing enabled and disabled records. In the web app, the Agents page carries both as pickers — Enabled / Disabled / All, and Live / Archived / All; archived rows appear dimmed with an Archived badge.
Configuring the agent
Every agent needs a launch config — the settings the device uses to start the coding-agent CLI for each stage — before it can run tasks. The web app’s New agent form always sets one at creation time; ch agent create sets one too when you pass the launch-config flags (see Creating an agent above), but makes a config-free agent if you omit them. Use the commands below to inspect the current config, change it later, or add one to an agent that doesn’t have one yet. Inspect the current config with:
ch agent config show <agent-id>
Set or update the config with any combination of these flags — pass only the ones you want to change:
ch agent config edit <agent-id> \
[--harness claude] \
[--cap model:opus --cap model:sonnet] \
[--arg <argument>] \
[--env KEY=VALUE] \
[--credential-ref ENV_VAR=<secretId>] \
[--persona "A senior Go engineer focused on correctness"] \
[--system-prompt "Always write tests first."]
--harness or --command is required only when the agent doesn’t have a launch config yet — an edit to an existing one can name any single flag on its own. See What each edit actually changes below for the full rule.
Choosing a harness
The harness selects which coding-agent CLI CodeHerder launches on the device. Use --harness with one of:
| Harness | CLI launched |
|---|---|
claude |
claude (default) |
codex |
codex |
cursor |
cursor-agent |
opencode |
opencode |
pi |
pi |
When you set --harness, CodeHerder derives the launch command automatically — you do not need to provide --command. The selected CLI must be installed on the device that runs the agent.
The five harnesses aren’t interchangeable in every respect — see Choosing the coding-agent CLI your agents run for what actually changes (placement, cost tracking, conversation continuity on rework, and device readiness checks) when you switch.
Flag reference
Each flag accepted by config edit (config set also works for edit):
| Flag | Purpose |
|---|---|
--harness |
Coding-agent CLI to launch (claude, codex, cursor, opencode, pi) — derives --command; required only when the agent has no launch config yet |
--command |
Advanced override: absolute path or binary name the device runs; only needed if you’re not passing --harness |
--cap |
Stage-gate capability label — the engine only runs a stage on this config if its caps fully cover what the stage requires; repeat for multiple |
--arg |
Extra argument passed to the command — repeat for multiple |
--env KEY=VALUE |
Environment variable set on each launch — repeat for multiple. A variable set at group, workspace, device, or agent scope also reaches the session; a config’s own --env value wins if the same key is set both ways. |
--credential-ref ENV_VAR=<secretId> |
Bind a workspace secret to an env var name — repeat for multiple; the value is resolved and injected only when a session spawns, never passed through the CLI. See Secrets |
--persona |
Short description of this agent’s role, included in each task brief |
--system-prompt |
Instruction prepended to every session; inline text, or --system-prompt-file <path> (or - for stdin) to read it from a file |
--allowed-model |
Model this config is allowed to run — repeat for multiple; see Which model your agents run |
What each edit actually changes
config edit is a partial update: it changes only the fields whose flag you actually pass, and leaves every other field exactly as it was stored. Run config edit --persona "..." on its own and only the persona changes — the command, args, environment, and capabilities all stay put.
The one thing to watch is that five of these flags are repeatable lists — --arg, --env, --cap, --credential-ref, and --allowed-model. Pass any of them on a call and it replaces that field’s whole list. For example, if a config currently has two --arg values and you run config edit --arg --model --arg claude-sonnet-4-6, the config ends up with exactly those two arguments — the old ones are gone. So whenever you touch a list flag, include every value in that list you want to keep, not just the new one.
To clear a list field entirely without touching anything else, pass the flag once with an empty value, for example --arg "" or --env "". The field still changes — it ends up empty rather than untouched.
--harness on its own switches the coding-agent CLI and re-derives --command for it, while leaving args, environment, capabilities, persona, and system prompt untouched. --command, --persona, --system-prompt are plain single-value fields: pass one and it’s set; omit it and the stored value stays.
Running config edit with no flags at all is refused — pass at least one launch-config flag. --harness or --command is required only when the write creates the agent’s first launch config (a fresh agent, or ch agent create with any launch-config flag); editing a config that already exists needs neither.
For guidance on what to put in each field and how they affect sessions, see Agent personas and system prompts.
Adding or editing a launch config needs workspace owner or admin — see Who can manage a launch config below for the full split.
For an API key or other credential you don’t want to hard-code in --env, create a workspace secret and bind it to an env var with --credential-ref instead — see Secrets for creating a secret and adding a Credential ref. See Keeping credentials out of a launch config below for what happens if you try to put one in --arg or --env directly.
Keeping credentials out of a launch config
CodeHerder refuses to save a launch config whose --arg or --env carries a value that looks like a live credential — an API key or token under a name like *_TOKEN, *_KEY, *_API_KEY, *_SECRET, *_PASSWORD, or *_DSN (including well-known ones like GITHUB_TOKEN or DATABASE_URL), a connection string with a password embedded in it (user:password@host), or a value shaped like a JWT. This applies to ch agent config create, ch agent config edit, inline config flags on ch agent create, and copying an existing agent (see Copying an existing agent above) — any write that would leave a literal credential sitting in a launch config is refused.
An @secret: reference (see Secrets on a device) and an empty value both pass through fine — only a literal secret-shaped value is refused.
Instead, keep the credential out of the config text entirely:
--credential-ref ENV_VAR=<secretId>binds a workspace-held secret to an environment variable — see Secrets.@secret:<key>in an--envvalue defers to a value stored only on the device itself — see Secrets on a device.- A secret variable set at group, workspace, device, or agent scope reaches the session without ever being typed into the config — see Variables.
If a config already holds a literal credential, an edit that leaves it in place is refused, even an edit to an unrelated field like the persona. Replace the offending --arg or --env value in the same call, using one of the options above, and the edit goes through.
Running more than one launch config
An agent can carry an ordered list of launch configs — each with its own harness, capabilities, environment, and credentials. This lets one agent run different coding-agent CLIs for different stages, or hold a primary config and a fallback.
config show and config edit always target the top config (position 1, the first one in the list). To manage multiple configs, use the dedicated subcommands from the ch CLI:
ch agent config list <agent-id> # show all configs in order
ch agent config create <agent-id> --harness codex --cap model:sonnet # add a new config at the next position
ch agent config reorder <agent-id> <configId> <configId> ... # reorder by listing IDs
ch agent config enable <agent-id> <configId> # make a config selectable again
ch agent config disable <agent-id> <configId> # skip a config without deleting it
ch agent config delete <agent-id> <configId> # delete a config (alias: rm)
You can also manage the full list of configs from the web app: the Launch configs panel on the agent detail page lists every config in order and lets you add, edit, reorder (drag or move up/down), enable/disable, and remove configs — the same set of operations available through the CLI above.
How selection works: when CodeHerder places a task stage, it picks each agent’s first enabled config whose capabilities cover what the stage requires. It skips a config whose harness no linked device can run. Ordering and enabling controls which config — and which harness and credentials — actually runs. To switch an agent between configurations, reorder or enable/disable; to take a config temporarily out of rotation, disable it rather than deleting it.
Reordering or disabling configs never overrides a device-wide pause from an exhausted Claude usage window or spend cap — selection doesn’t look at live usage, so switching configs on the same paused device won’t get work moving there again. See AI usage limits.
Who can manage a launch config
Every launch-config write needs workspace owner or admin: adding one (config create, or config edit on an agent with none yet), editing one, enabling or disabling one, reordering with config reorder, and removing one with config delete. Being the human who created the agent doesn’t grant any of this on its own. In the web app, the Launch configs panel shows a member without that role a read-only list, with no add, edit, reorder, enable/disable, or remove controls.
Reading is looser than writing, but not fully open: a member below owner or admin can still run config show and config list, but sees every argument and every environment variable value replaced with [redacted]. The count of arguments and the set of environment variable names are unchanged. One exception: an @secret: reference in an environment value, under a name that doesn’t look like a credential, stays visible. It names only a device-side key, not a value.
Capabilities and routing
Capabilities owns the full picture across agents, launch configs, stages, and tasks. In short, there are two rules:
- Agent skills (
ch agent create --cap) are a soft preference. They rank agents when CodeHerder places an unassigned task. They never block placement. - Launch config capabilities (
--caponch agent config edit,--config-caponch agent create) are a hard gate. A stage runs only on a config that covers what the stage requires. If no enabled launch config covers a stage, the stage is unstaffable, and tasks that reach it queue and never start.
By default, the built-in feature, story, and bug workflows need both model tiers. Their plan, review, and verify stages require model:opus, and their code and merge stages require model:sonnet. For bug, triage is the plan step. See How work flows for what each stage does. A launch config with only one tier can staff part of the pipeline, so a task can stall partway through. Give one config both tiers, or run two configs, one per tier (see Running more than one launch config).
To close a gap, add the missing capability to a config. Name every capability you want to keep, because --cap replaces the whole list:
ch agent config edit <agentId> --harness claude --cap <existing-cap> --cap <missing-cap>
The Capability gap callout on the Set up → Agents page lists each stage that no enabled launch config covers (see Monitoring your agents). A task can still stall when its own required capabilities, or its device placement, rule out every config. See Why isn’t my task moving?.
Where an agent runs
Agents run on devices — machines running ch device-server. There’s no separate step to put an agent on a device: any device linked to the agent’s workspace (or an ancestor group) is a candidate, and the engine picks the best eligible one — online, enabled, and covering the config’s required capabilities — each time it places work.
Throughout this section, <agent-id> also accepts the agent’s display name, and <device-id> also accepts the device’s name — its hostname, unless you’ve set one — see Referring to things on the command line for the full rule.
To check which devices an agent could actually run on right now, and why any others are excluded:
ch agent placement <agent-id>
This lists every device linked to the agent’s workspace, whether it’s eligible, and — for an ineligible one — the reason. It checks the agent’s devices, not any one task, so it leaves out checks that depend on a task, such as the git-host sign-in a task needs. It also doesn’t read live device health. See The Placement report for how to read it in full, including every reason and what to do about each.
Authenticating a device’s own sessions runs through the device’s own device token, minted once per device — there’s no separate per-(agent, device) credential to mint or rotate. For the first-time setup flow — registering a device end to end — see the Quickstart. For ongoing device management, see Managing your devices.
Core CLI verbs
Tasks
ch task create --title "My task" --type story --parent <epicId>
ch task list [--status code] [--created-by me]
ch task show <taskId>
ch task status <taskId> <stage> # move to a named pipeline stage
ch task comment <taskId> --from-file notes.md
ch task edit <taskId> --acceptance-file criteria.md # set any field, native or per-task
ch task field <taskId> acceptance # read one field back
ch task fields <taskId> # list every field and whether it's writable now
For the full ch task list filter set — status, priority, type, limit, and more — see Finding and tracking your work.
Dependencies and blockers
ch task depends-on <taskId> <upstreamId>
ch task block <taskId> "Waiting on upstream API"
ch task unblock <blockerId>
Sessions and agents
ch sandbox list <taskId> # a task's sandboxes, or `workspace [<ref>]` scope instead
ch session list <taskId> # a task's sessions, or `agent`/`device`/`workspace` scope instead
ch session show <sessionId>
ch agent create --display-name "Builder" --harness claude # flags: see above
ch agent edit <agent-id> --display-name "Builder v2"
ch agent config show <agent-id>
ch agent config edit <agent-id> --persona "..."
ch agent config list <agent-id>
ch agent placement <agent-id>
The other ch agent config verbs (create, reorder, enable, disable, delete) are in Running more than one launch config.
For the full ch session surface — tail, stop, input, attach, all four list scopes, and who can use each one — see Sessions from the command line. For how to read ch agent placement’s output — and its task-scoped sibling ch task placement — see The Placement report.
Workspace wiki
ch wiki list
ch wiki show <slug|id>
ch wiki write --slug <slug> --title "<title>" --body-file learning.md
Messages
ch msg send <name-or-workspace> --from-file message.md
ch msg send session:<sessionId> --from-file message.md # addresses one live session
ch msg inbox --unread
See Messages and your inbox for the full rundown on addressing one session instead of an agent as a whole.
The current-task default (CH_TASK_ID)
Most of the commands above take a task ID as their first argument — and copying a 36-character UUID around gets old fast. CH_TASK_ID is the task-level equivalent of CH_WORKSPACE_ID (see Credentials and profiles): set it once, and task-scoped commands pick it up automatically.
Set it for the rest of your shell session:
export CH_TASK_ID=<taskId>
Or set it for a single command inline:
CH_TASK_ID=<taskId> ch task show
With CH_TASK_ID exported, you can drive a task’s whole lifecycle without naming it again:
export CH_TASK_ID=<taskId>
ch task show
ch task comment --from-file handoff.md
ch task status code
Task-scoped ch task verbs (show, status, comment, field, watch, blockers, deps, and most others), ch sandbox list, and the bare/task-ID form of ch session list all default their task argument from CH_TASK_ID when you omit it. An explicit task ID on the command line always overrides CH_TASK_ID.
Two commands carry a free-text body. Each defaults its task ID only when you supply that body as a flag:
ch task blockdefaults fromCH_TASK_IDwhen you pass the reason with--reasonor--from-file, and pass nothing else — as inch task block --reason "Waiting on upstream API".ch task commentdefaults fromCH_TASK_IDwhen you pass the body with--from-file, and pass nothing else.
The first plain argument is always read as the task ID. So name the task ID yourself whenever you write the reason or body as a plain argument instead.
Auto-staffing
Every built-in type is eligible for auto-staffing: initiative, epic, feature, bug, story, task, and auto. When you create an unassigned task of one of these types, CodeHerder moves it from To do to its first working stage and staffs it with a suitable idle agent. You can create a story, set its acceptance criteria, and it reaches an agent with no further action from you. See Assigning work for how the choice works.
task is the lightweight to-do type. Use it for yourself, or direct it to a specific person with the Assignee dropdown. An unassigned task starts on its own, like every other type.
Monitoring your fleet
Once your agents are set up and running, you’ll want to know whether they’re healthy and picking up work. Monitoring your agents covers the web Agents page (the agent list and its columns, the capability-gap warning), pausing an agent with Disable/Enable, and the CLI commands for workload snapshots (ch agent workload) and per-agent event feeds (ch activity agent <agentId>).
Last updated