Agentic tool toggles
The agentic image installs many AI CLIs, but only a curated set is exposed by default. Devilbox lets you add or remove tool symlinks at runtime with the same environment-file pattern used elsewhere in the stack.
Overview
Each agent tool declares its default-enabled status in its own options.yml
file under ../docker-agentic/agentic_tools/<slug>/options.yml. The effective
default-on set is the union of every tool with default_enabled: true.
Default-on agent tools:
claude-codecodexcopilotdroidgeminikilo-codekimikiroopencodepi-coding-agentqwen-codereasonix
Default-on extra tools (built into the :work image):
openspecspeckit
The runtime variables in env-example are:
AGENTIC_TOOLS_ENABLE=AGENTIC_TOOLS_DISABLE=AGENTIC_TOOLS_ENABLE adds slugs to the default list. AGENTIC_TOOLS_DISABLE
removes slugs from the final set.
The implementation is
../docker-agentic/Dockerfiles/base/data/startup.1.d/20-agentic-toggle.sh.
Why this mirrors the PHP-FPM pattern
Devilbox already relies on .env values to decide which runtime pieces are
active. For example, env-example defines:
CONTAINERS_CONFIG_DEFAULT="bind httpd php mysql"CONTAINERS_CONFIG_OPTIONAL="php74 php81 php82 php83 php84 redis opensearch buggregator"Agentic tools follow the same principle:
- Defaults are documented in one source-of-truth file.
- Optional items can be added without rebuilding the image.
- Unwanted defaults can be removed without deleting installed files.
- The final active set is computed at container startup.
This makes team onboarding predictable while still allowing per-project lean images or extra tools.
How the synchronizer works
At container startup, 20-agentic-toggle.sh:
- Reads each
/opt/agentic-tools/<slug>/options.ymlto discover default-enabled slugs. - Parses
AGENTIC_TOOLS_ENABLEas comma-separated slugs. - Parses
AGENTIC_TOOLS_DISABLEas comma-separated slugs. - Normalizes values to lowercase and trims whitespace.
- Unions defaults with enabled slugs.
- Removes disabled slugs.
- Scans each
/opt/agentic-tools/<slug>/bindirectory. - Creates or removes symlinks under
/usr/local/bin.
It is idempotent. It does not delete non-symlink files. It only removes symlinks
that point back into /opt/agentic-tools.
Default tool list (agent tools — per-agent images)
| Slug | Image tag | Binary | Install method |
|---|---|---|---|
claude-code | :claude-code | claude | custom via https://claude.ai/install.sh |
codex | :codex | codex | custom via https://chatgpt.com/codex/install.sh |
copilot | :copilot | copilot | custom using gh copilot extension |
droid | :droid | droid | custom via Factory.ai installer |
gemini | :gemini | gemini | npm package @google/gemini-cli |
kilo-code | :kilo-code | kilo | npm package @kilocode/cli |
kimi | :kimi | kimi | custom via Kimi Code installer |
kiro | :kiro | kiro-cli | custom via .deb package |
opencode | :opencode | opencode | custom via https://opencode.ai/install |
pi-coding-agent | :pi-coding-agent | pi | custom via https://pi.dev/install.sh |
qwen-code | :qwen-code | qwen | npm package @qwen-code/qwen-code |
reasonix | :reasonix | reasonix | npm package reasonix |
Default tool list (extra tools — built into :work image)
| Slug | Binary | Install method |
|---|---|---|
openspec | openspec | npm install -g @fission-ai/openspec |
speckit | specify | pipx install specify-cli |
How to enable tools
Add comma-separated slugs to .env:
AGENTIC_TOOLS_ENABLE=aider,gooseThen restart the stack:
./dvl.sh agent restart agenticor recreate it:
./dvl.sh agent down./dvl.sh agent upThe startup synchronizer will create symlinks for enabled slugs that have a
binary under /opt/agentic-tools/<slug>/bin.
How to disable tools
Add comma-separated slugs to .env:
AGENTIC_TOOLS_DISABLE=pi-coding-agent,reasonixRestart the stack. The synchronizer removes matching /usr/local/bin symlinks
when they point into /opt/agentic-tools.
Disable does not uninstall packages from the image. It only removes command entrypoints from the active tool set.
Precedence rules
The implementation order in 20-agentic-toggle.sh is:
- Start with default-enabled slugs from each tool’s
options.yml. - Add
AGENTIC_TOOLS_ENABLE. - Sort and deduplicate.
- Remove
AGENTIC_TOOLS_DISABLE.
Therefore, disable wins when a slug appears in both lists.
The script prints a warning when the same slug appears in both variables:
[agentic-toggle] WARN: slug 'aider' appears in both ENABLE and DISABLE; DISABLE winsAdditional parsing rules:
- Values are comma-separated.
- Whitespace is trimmed.
- Slugs are lowercased.
- There is no
allwildcard support. - Unknown slugs do not create commands because no matching tool directory/bin is found.
Worked examples
Example 1: Add Aider and Goose
AGENTIC_TOOLS_ENABLE=aider,gooseAGENTIC_TOOLS_DISABLE=Result:
- All defaults remain active.
aiderandgoosebecome active if their installed binaries exist (these are host-side or separately installed tools — they reference config mounts undercfg/agentic/but are not shipped in the Docker image).
Example 2: Keep a smaller default set
AGENTIC_TOOLS_DISABLE=pi-coding-agent,reasonixResult:
- Default tools are still the base.
pi-coding-agentandreasonixare removed from the final active set.- Their files remain in
/opt/agentic-tools.
Example 3: Enable Multica CLI with the Multica stack
AGENTIC_TOOLS_ENABLE=multicaMULTICA_API_URL=http://multica-api:8080Then enable both stack layers:
./dvl.sh agent enable agentic multica./dvl.sh agent upUse the container-to-container API URL, not the host-side MULTICA_API_PORT.
Example 4: Collision proves disable precedence
AGENTIC_TOOLS_ENABLE=aiderAGENTIC_TOOLS_DISABLE=aiderResult: aider is disabled, and the startup script emits a warning.
Example 5: Case and spaces are normalized
AGENTIC_TOOLS_ENABLE=" AIDER , GOOSE "Result: the script treats this as aider and goose.
Inspecting the final state
Use dvl agent tools to list tool directories known to the sibling
docker-agentic/agentic_tools source tree:
./dvl.sh agent toolsUse the container shell to check active commands:
./dvl.sh agent shellcommand -v claudecommand -v aidercommand -v multicaIf command -v returns nothing, the symlink is not active in /usr/local/bin.
Troubleshooting tool not found
The slug is installed but disabled
Check whether it has default_enabled: true in its options.yml. If not, add it:
AGENTIC_TOOLS_ENABLE=slug-nameRestart the container after editing .env.
The slug is both enabled and disabled
Remove it from AGENTIC_TOOLS_DISABLE. Disable wins on collision.
The slug spelling is wrong
Use exact slugs. Examples include claude-code, copilot,
pi-coding-agent, and opencode.
There is no wildcard support and no automatic fuzzy matching.
The installer did not create a binary
The toggle script only links binaries found under:
/opt/agentic-tools/<slug>/binIf the upstream installer skipped a tool because a release probe failed, there may be no binary to link. Inspect container startup logs for warnings.
A command exists but points somewhere else
The script refuses to remove symlinks that point outside /opt/agentic-tools.
This protects custom host or image commands. Inspect the link manually inside
the container:
ls -l /usr/local/bin/<command>Changes did not apply
The toggle runs at startup from /opt/agentic-tools/_entrypoint.d/ before the
user-mounted /startup.1.d. Restart the agentic container after changing
.env so the synchronizer runs again.