Codeman Worker
The Worker is the machine-local execution side of Cloud Agent Fleet. It does not open an inbound listener. It enrolls with the Hub, consumes assignments over an outbound Server-Sent Events stream, and posts lifecycle events back over HTTP.
Prerequisites#
By default the Worker manages Codeman under the hood:
CLOUDAGENTFLEET_MANAGE_CODEMANdefaults totrue— install (if missing) and start Codeman when/api/v1/statusis down; stop it on Worker shutdown only if this Worker process started it.CLOUDAGENTFLEET_CODEMAN_INSTALLdefaults totruewhen manage is on — run the official installer once whencodemanis not on PATH.- Set either flag to
falseto attach to an existing Codeman only (no install/start/stop).
Manual install (optional when manage/install are on):
curl -fsSL https://getcodeman.com/install | bash
codeman web
On Windows, install and manage run inside WSL (same as setup). Native Windows without WSL remains unsupported for Codeman. Keep Codeman's authentication and provider login local to that machine. Cloud Agent Fleet does not copy those credentials to the Hub.
Configure and start with the CLI#
Install the Worker (npm install --global @cloudagentfleet/worker, or the
worker release archive), then run the guided setup, which installs Codeman
when you pick it and runs the Worker as a service:
cloudagentfleet init
cloudagentfleet setup --run is the step-by-step alternative that runs the
Worker in the terminal.
The guided flow detects WSL/Codeman, asks before installing Codeman on first
setup, lets you choose approved folders or whole-system access, discovers
workspaces beneath those roots, selects the Codeman mode, and writes
~/.cloudagentfleet/worker.json (including manageCodeman / installCodeman,
default true). On cloudagentfleet run (or setup --run), those flags become
CLOUDAGENTFLEET_MANAGE_CODEMAN and CLOUDAGENTFLEET_CODEMAN_INSTALL so the Worker
can install/start Codeman without a separate codeman web -d on each host.
To configure without launching, omit --run; later use cloudagentfleet run.
Once a Worker is online, run this Hub-side selection flow:
cloudagentfleet start
It selects an online Worker, then a ready workspace, then a ready agent, asks for the prompt, and creates the job with an idempotency key.
To expose the Worker-backed Codeman as a Hub instance, enroll it explicitly:
cloudagentfleet enroll connector \
--controller-url http://127.0.0.1:8787 \
--instance-id codeman-worker-linux \
--name "Codeman on Linux" \
--node-id worker-linux-1 \
--workspace-mode folders \
--workspace-root "$HOME/workspaces"
The command checks /api/instances/:id/health after registration. For a
Codeman endpoint already reachable over Tailscale, use
enroll tailscale-url --url https://<name>.<tailnet>.ts.net instead. This is
the preferred path for the native Codeman UI: the Hub proxies the
selected host's Codeman REST, SSE, and WebSocket traffic over the tailnet, so
terminal input does not pass through the request-per-keystroke Worker path.
The connector remains available for machines that cannot accept Hub
connections. To serve the single private Hub, use the hub serve command
described in TAILSCALE-SERVE.md.
CLOUDAGENTFLEET_AUTH_TOKEN is read from the environment when the Hub
requires authentication.
Start the Worker manually#
The current runtime accepts configuration through environment variables:
export CLOUDAGENTFLEET_NODE_ID=worker-linux-1
export CLOUDAGENTFLEET_NODE_NAME="Linux build machine"
export CLOUDAGENTFLEET_CONTROLLER_URL=https://controller.example.test
export CLOUDAGENTFLEET_AUTH_TOKEN="controller-worker-token"
export CLOUDAGENTFLEET_WORKSPACE_MODE=folders
export CLOUDAGENTFLEET_WORKSPACE_ROOTS="$HOME/workspaces"
export CLOUDAGENTFLEET_WORKSPACES='[
{
"id": "payments",
"name": "payments",
"canonicalPath": "/home/me/workspaces/payments",
"health": "ready",
"providers": { "codeman": "ready" }
}
]'
export CLOUDAGENTFLEET_CODEMAN_URL=http://127.0.0.1:3000
# Optional opt-outs (both default true):
# export CLOUDAGENTFLEET_MANAGE_CODEMAN=false
# export CLOUDAGENTFLEET_CODEMAN_INSTALL=false
node --experimental-strip-types apps/node-agent/src/main.ts
CLOUDAGENTFLEET_CODEMAN_USERNAME and CLOUDAGENTFLEET_CODEMAN_PASSWORD may be set when Codeman Basic
authentication is enabled. They are used only for direct Worker-to-Codeman
requests.
Assignment flow#
- The Worker posts its registration to
POST /api/workers. - It opens
GET /api/workers/:id/connectand waits forjob.assignevents. - A Codeman job creates a session with the selected workspace path.
- The Worker starts Codeman's interactive session and submits the prompt with the required carriage return.
- Completion is synchronized using Codeman's stop/exit wait signal, then the
clean
last-responseis posted as ajob.event. The Hub keeps it on the job asresult(or the reason aserrorwhen the job fails), soGET /api/jobs/:idreturns the agent's answer. - Hub cancellation deletes the corresponding Codeman session.
Choosing the agent#
A job may name the agent Codeman starts for it with agent (one of Codeman's
modes: claude, codex, opencode, gemini, …). Without it the Worker's
configured mode is used. The agent must be installed and signed in on that
Worker. Follow-ups continue the session's existing agent.
Continuing a conversation#
A finished job keeps its Codeman session, and the job records it as
sessionId. To continue the same conversation, create the next job with that
sessionId:
POST /api/jobs
{ "provider": "codeman", "nodeId": "worker-1", "workspaceId": "workspace-app",
"prompt": "Make it shorter", "idempotencyKey": "thread-7-msg-2", "sessionId": "<sessionId from the earlier job>" }
The Worker types the prompt into that session instead of starting a new one.
It only accepts sessions it created for jobs (named hosted-<nodeId>-…), so a
job can't type into a session someone started from the dashboard.
Agent permissions for jobs come from the workspace: Codeman starts the agent
with its own command, so give a job a workspace whose .claude/settings.json
(or the provider's equivalent) allows only the tools that job should use.
The Hub normally sends a workspace ID. The dashboard can also send an explicit workspace path for a newly discovered location. The Worker checks health, Codeman readiness, and the approved-folder/system policy again before creating a session; paths outside the policy are rejected.
The dashboard's path picker requests suggestions from
GET /api/instances/:id/workspaces/suggestions?path=.... Connector Workers
enumerate local directories, skip symlinks, verify canonical paths against the
policy, and return at most 50 entries. Direct Tailscale instances can only
complete against their registered workspace metadata because Codeman does not
provide a documented remote filesystem listing endpoint.
Current limits#
- Provider login remains owned by Codeman and is not automated by the Worker.
- Cursor Agent availability depends on the official
agentCLI (or the legacycursor-agentcommand) being installed and authenticated on each machine. Claude Code remains owned by Codeman. - Codeman is auto-installed only when missing (not upgraded on every start).
Setup may still ask before the first interactive install; the Worker remains
the long-term supervisor on every
run. Install the Worker service explicitly withcloudagentfleet worker install.