Agents, skills, and the denylist
The installer wires coding agents into the DDEV web container, installs agent skills for them, and writes a command denylist so an agent cannot run the commands you ruled out. All three are asked up front and can be set non-interactively with flags or a config.
Coding agents
Three agents are supported: Claude Code (claude), Codex (codex),
and OpenCode (opencode). Each is installed through its
e0ipso/ddev-assistant-<agent> DDEV add-on, which bakes the agent CLI into
the web image and mirrors your host agent configuration into the container.
The installer also writes a DDEV command per agent, so you start them with:
ddev claude
ddev codex
ddev opencode
Choose agents in the prompt, or:
--agents claude,codexon the command line;"agents": ["claude"]in a config;--yoloinstalls Claude Code.
Choosing no agent ("bring your own") still installs skills, into all three agents' directories, so whichever agent you run later finds them.
A config can also set "agent_auto_mode": true (config only, no flag or
prompt). That bakes each agent's own auto-approval flag into its ddev
<agent> wrapper: --permission-mode auto for Claude,
--dangerously-bypass-approvals-and-sandbox for Codex, --auto for
OpenCode. Use it for unattended demo builds, not for day-to-day work.
Agent skills
Skills are installed inside the container with npx skills add, per agent,
into each agent's own directory (.claude/skills/, .codex/skills/,
.opencode/skills/). The defaults, which --yolo installs:
- Drupal Module Finder: search contrib before writing custom code.
- Superpowers: a set of general engineering process skills.
- Find Skills: lets the agent discover further skills itself.
- Agent Browser: drive a browser for verification and screenshots.
Control the list:
--default-skillstakes the defaults without prompting.--add-skills 'owner/repo|skill-a skill-b,owner/other'installs the defaults plus the listed specs. A bareowner/repomeans all skills in that repo. Quote the value; it contains|and often*.- A config's
skillskey expresses an exact list (there is deliberately no replace-flag on the CLI).--add-skillson top of a config extends the config's list instead of the defaults.
Drupal builds also get the drupal/ai_best_practices module, whose
skills-sync populates .agents/skills/; the installer links those into
.claude/skills/ so Claude Code sees them too.
The command denylist
The denylist stops the chosen agents from running commands you ruled out.
The defaults are git push and ssh: an agent should neither
publish work on its own nor leave the machine. The prompt lets you deselect
these or add your own entries; --default-denylist takes the defaults
without prompting, and a config sets "deny_commands": [...].
Each agent enforces rules differently, so the installer writes each agent's native format:
| Agent | Where the rules land |
|---|---|
| Claude Code | .claude/settings.json, permissions.deny (e.g. Bash(git push:*) plus Bash(git * push:*) to catch flag-first variants) |
| OpenCode | opencode.json, permission.bash glob map with an "*": "allow" baseline prepended only if you have none |
| Codex | .codex/rules/one-line-installer.rules (execpolicy prefix rules; experimental, applies only when the project is trusted) |
The writers merge; they never overwrite. A sidecar manifest records exactly which rules the installer owns, so re-running adds newly selected rules, withdraws deselected ones, and leaves your own hand-added rules and settings alone. An empty selection removes everything the installer wrote.
The denylist is best effort, not a sandbox: aliases, environment tricks, and self-written scripts can still get around it. Treat it as a guardrail.
Changing things later
Run the installer inside the project (management mode) to add or remove agents, change the denylist, or install more skills on an existing site. See Getting started.