Skip to content

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,codex on the command line;
  • "agents": ["claude"] in a config;
  • --yolo installs 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-skills takes the defaults without prompting.
  • --add-skills 'owner/repo|skill-a skill-b,owner/other' installs the defaults plus the listed specs. A bare owner/repo means all skills in that repo. Quote the value; it contains | and often *.
  • A config's skills key expresses an exact list (there is deliberately no replace-flag on the CLI). --add-skills on 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.