Runners
Runtime profiles
How a runner launches Claude Code and Codex with the right account and config.
A runtime profile tells a runner how to launch an agent CLI: which runtime, which binary, which environment and which extra arguments. Profiles let one machine run agents under different Claude Code accounts or configurations, and they decide whose subscription a session uses.
Profiles live in the runner's config file on each machine, not on the server. The runner reports them to AgentDock, and you pick one per project in the UI.
The shape of a profile
Profiles are the profiles array in ~/.config/agentdock/runner.json:
{
"profiles": [
{ "id": "claude-default", "runtime": "claude", "env": {}, "args": [] },
{
"id": "claude-work",
"runtime": "claude",
"env": { "CLAUDE_CONFIG_DIR": "/home/you/.claude-profiles/work" },
"args": []
},
{ "id": "codex-default", "runtime": "codex", "env": {}, "args": [] }
]
}| Field | Required | Meaning |
|---|---|---|
id | yes | Unique name on this runner. Letters, digits, ., _ and -, starting with a letter or digit. It is what the UI shows. |
runtime | yes | claude or codex. |
binary | no | The executable to launch. Defaults to the runtime's name (claude or codex) on the runner's PATH. Use an absolute path for a CLI outside PATH or a wrapper script. |
env | yes | Environment variables set for every session launched with this profile. Names must look like [A-Za-z_][A-Za-z0-9_]*. Use it for CLAUDE_CONFIG_DIR or CODEX_HOME. |
args | yes | Extra arguments placed right after the binary, before AgentDock's own arguments. |
The runner also reports whether each profile is authenticated. That is checked, never stored: a Claude profile counts as authenticated when its config directory holds a non-empty .credentials.json, a Codex profile when its CODEX_HOME holds an auth.json. The runner only looks at file metadata, never reads the credential.
The config directory of a profile is CLAUDE_CONFIG_DIR from env, or ~/.claude when it is not set. For Codex it is CODEX_HOME, or ~/.codex.
Auto-detection
agentdock-runner pair proposes profiles when the config has none. It finds:
| Profile | Detected from | env |
|---|---|---|
claude-default | always proposed | none, so Claude Code uses ~/.claude |
claude-<name> | each directory in ~/.claude-profiles/ | CLAUDE_CONFIG_DIR set to that directory's absolute path |
codex-default | always proposed | CODEX_HOME if it is set in the runner's environment, else none (~/.codex) |
Directory names are turned into ids by replacing unsupported characters with -. If two names collide, the second gets a -2 suffix. Detection never runs shell functions or aliases, so a profile you only defined as a shell alias is not found; add it by hand.
To run detection again:
agentdock-runner profiles # what is configured now
agentdock-runner profiles --detect # what detection would propose
agentdock-runner profiles --detect --write # store the proposalprofiles --detect --write replaces the whole profiles array with the proposal, so hand-made profiles and edits are lost. pair is safer: it only fills an empty list and never overwrites existing profiles.
Edit profiles by hand
Edit runner.json directly to add a binary, arguments or variables, then restart the runner. It reads profiles when it starts and reports them to AgentDock when it connects.
{
"id": "claude-sandboxed",
"runtime": "claude",
"binary": "/usr/local/bin/claude-sandbox",
"env": {
"CLAUDE_CONFIG_DIR": "/home/you/.claude-profiles/ci",
"MAX_THINKING_TOKENS": "16000"
},
"args": ["--verbose"]
}Use absolute paths in env. Keep the file at mode 0600: the runner's token is in it too.
How AgentDock picks a profile
Profiles are chosen per project, in the web app:
- Settings → General → Default runtime profile is the project's default.
- Settings → Orchestrator can set a different profile just for the orchestrator, along with its model and permission mode.
When you click Start… on the Fleet page, the dialog shows the effective profile read-only. The API resolves it in this order: a profile in the start request, then the Orchestrator setting, then the project's default. If none is set, Start is refused with No runtime profile is set.
The chosen profile must belong to the project's runner, must still be reported by it, and must be a claude profile. The runner then starts a tmux session with the profile's env and this command:
<binary> <args...> --remote-control <session> -n <session> \
--model <model> --permission-mode <mode> "/code-sentinel:orchestrator start"So the Code Sentinel plugin must be installed in that profile's Claude Code config.
Skill runs also take a profile, chosen when you start the run, and also need a claude profile. Installing a skill to a profile (admin only) writes it into the profile's config directory, under skills/<name>/.
AgentDock reads session transcripts from the config directory of every configured profile, so cost and tokens are recorded no matter which profile a session ran under.
The orchestrator dispatches workers itself, through Code Sentinel's dispatch.sh. Passing the profile's CLAUDE_CONFIG_DIR and binary on to workers is a Code Sentinel change (plugin issue #6) that is merged on the plugin's develop branch but not yet released. With an older plugin, workers start with the tmux server's environment.
Codex limits
Codex profiles are detected, reported and usable for some things, but Codex is not a full citizen yet.
- Works: detection and reporting, installing skills to a Codex profile, and project skill installs for Codex (under
.agents/skills/). - Listed, not parsed: Codex sessions appear in Sessions, but their transcript format is not parsed, so they carry no tokens or cost. The runner option
otlp.codexExperimentalmaps Codex telemetry records, whose attribute names are not verified yet. It is off by default. - Not built (milestone M4): Codex as the orchestrator, Codex workers in orchestrator slots, and Codex skill runs. Starting the orchestrator or a skill run with a Codex profile is refused with
unsupported_runtime.