The brain of the DDEV AI Workspace. A comprehensive set of AI agents, rules, skills, and configuration for Drupal 10/11 development. Designed for OpenCode and Claude Code, compatible with DDEV environments.
Part of DDEV AI Workspace — a modular ecosystem of DDEV add-ons for AI-powered Drupal development. Install the full stack with one command:
ddev add-on get trebormc/ddev-ai-workspaceCreated by Robert Menetray · Sponsored by DruScan
This repository is not a DDEV add-on. It is a configuration package that gets synced into OpenCode and Claude Code containers via ddev-agents-sync. It provides 10 specialized agents, 13 rules, and 24 skills tailored for Drupal development. The agents understand Drupal APIs, coding standards, caching, render arrays, the module/theme ecosystem, and quality tools like PHPStan, PHPCS, and PHPUnit.
The recommended way is to install the full DDEV AI Workspace, which installs all tools and syncs this repository automatically with a single command:
ddev add-on get trebormc/ddev-ai-workspace
ddev restart
ddev opencode # or: ddev claude-codeIf you only install ddev-opencode or ddev-claude-code, this repository is also automatically synced via ddev-agents-sync. No manual clone is needed.
ddev add-on get trebormc/ddev-opencode
ddev restart
ddev opencodeTo add private agent repos alongside the public ones, edit .ddev/.env.agents-sync:
AGENTS_REPOS=https://github.com/trebormc/drupal-ai-agents.git,https://github.com/your-org/private-agents.gitTo manually trigger an update: ddev agents-update
# Clone directly to the OpenCode config directory
git clone https://github.com/trebormc/drupal-ai-agents.git ~/.config/opencode
# Copy and customize the config
cd ~/.config/opencode
cp opencode.json.example opencode.json
vi opencode.json
# Authenticate
opencode auth login
# Run
opencodedrupal-ai-agents/
├── CLAUDE.md Main instructions (language, design, environment, agents)
├── opencode.json.example OpenCode config template (copy to opencode.json)
├── opencode-notifier.json Notification bridge config (used automatically)
├── .env.agents Model alias definitions (tokens → real model names)
├── install.sh Installation helper script (standalone mode)
├── .claude/
│ ├── settings.json Claude Code permissions and hooks
│ ├── agents/ 10 agent definitions (.md files with fat frontmatter)
│ │ ├── applier.md
│ │ ├── code-explorer.md
│ │ ├── code-review.md
│ │ ├── deep-research.md
│ │ ├── drupal-dev.md
│ │ ├── drupal-test-generator.md
│ │ ├── drupal-theme.md
│ │ ├── output-verifier.md
│ │ ├── ralph-planner.md
│ │ └── visual-test.md
│ ├── rules/ 13 rule sets loaded as instructions
│ │ ├── applier-protocol.md
│ │ ├── beads-workflow.md
│ │ ├── coding-behavior.md
│ │ ├── config-management.md
│ │ ├── ddev-environment.md
│ │ ├── drupal-coding-standards.md
│ │ ├── drupal-testing.md
│ │ ├── git-workflow.md
│ │ ├── lessons-learned.md
│ │ ├── quality-tools-setup.md
│ │ ├── security-rules.md
│ │ ├── services-conventions.md
│ │ └── twig-patterns.md
│ └── skills/ 24 reusable skills
│ ├── beads-task-tracking/SKILL.md
│ ├── commit-message/SKILL.md
│ ├── config-management/SKILL.md
│ ├── drupal-audit-setup/SKILL.md
│ ├── drupal-behat-test/SKILL.md
│ ├── drupal-code-patterns/SKILL.md
│ ├── drupal-debugging/SKILL.md
│ ├── drupal-functional-test/SKILL.md
│ ├── drupal-functionaljs-test/SKILL.md
│ ├── drupal-kernel-test/SKILL.md
│ ├── drupal-migration/SKILL.md
│ ├── drupal-playwright-test/SKILL.md
│ ├── drupal-testing/SKILL.md
│ ├── drupal-unit-test/SKILL.md
│ ├── drupal-update/SKILL.md
│ ├── drush-commands/SKILL.md
│ ├── module-scaffold/SKILL.md
│ ├── performance-audit/SKILL.md
│ ├── playwright-testing/SKILL.md
│ ├── quality-checks/SKILL.md
│ ├── skill-creator/SKILL.md
│ ├── tailwind-drupal/SKILL.md
│ ├── twig-audit/SKILL.md
│ └── xdebug-profiling/SKILL.md
└── docs/ Additional documentation
├── architecture.md
├── model-strategy.md
└── ralph-loop.md
Agent .md files use model tokens instead of hardcoded model names. This makes agents portable across OpenCode and Claude Code, and allows changing models globally from a single file.
| Token | Default | Use for |
|---|---|---|
${MODEL_SMART} |
Opus 4.6 | Quality gates, planning, research |
${MODEL_NORMAL} |
Sonnet 4.5 | General-purpose tasks |
${MODEL_CHEAP} |
Haiku 4.5 | Fast, cost-effective agents |
${MODEL_APPLIER} |
Haiku 4.5 | Mechanical code application |
Edit .env.agents to change which models all agents use:
# OpenCode models (provider/model-id format)
OC_MODEL_SMART=opencode/kimi-k2.5
OC_MODEL_NORMAL=opencode/minimax-m2.5
OC_MODEL_CHEAP=opencode/gpt-5-nano
OC_MODEL_APPLIER=opencode/gpt-5-nano
# Claude Code models (native aliases)
CC_MODEL_SMART=opus
CC_MODEL_NORMAL=sonnet
CC_MODEL_CHEAP=haiku
CC_MODEL_APPLIER=haikuWhen synced via ddev-agents-sync, envsubst replaces tokens with the correct values for each tool. To override without forking this repo, create a private repo with just .env.agents and add it as a second entry in AGENTS_REPOS.
Each agent .md uses a single frontmatter that works for both OpenCode and Claude Code:
---
description: Short description of the agent.
model: ${MODEL_CHEAP}
# OpenCode fields (Claude Code ignores these)
mode: subagent
tools:
read: true
glob: true
grep: true
bash: false
permission:
bash: deny
# Claude Code field (OpenCode ignores this)
allowed_tools: Read, Glob, Grep
---
Agent system prompt here...During sync, ddev-agents-sync generates separate copies:
- OpenCode (
/agents-opencode/): removesallowed_tools:, keeps everything else - Claude Code (
/agents-claude/): removesmode:,tools:(object),permission:, renamesallowed_tools:→tools:
| Agent | Token | Purpose |
|---|---|---|
drupal-dev |
MODEL_NORMAL |
Backend: modules, services, entities, plugins, APIs |
drupal-theme |
MODEL_NORMAL |
Frontend: Twig, CSS, JS, Tailwind, responsive |
drupal-test-generator |
MODEL_NORMAL |
Test generation: analyzes code, picks type, generates tests |
| Agent | Token | Purpose |
|---|---|---|
code-review |
MODEL_SMART |
Quality gate: correctness, security, Drupal quality, performance |
output-verifier |
MODEL_SMART |
Validate outputs with high confidence |
visual-test |
MODEL_NORMAL |
Playwright browser screenshots and UI checks |
| Agent | Token | Purpose |
|---|---|---|
code-explorer |
MODEL_CHEAP |
Codebase exploration and analysis |
applier |
MODEL_APPLIER |
Mechanical code application (SEARCH/REPLACE) |
ralph-planner |
MODEL_SMART |
Generate requirements.md for Ralph Loop |
deep-research |
MODEL_NORMAL |
Multi-source research and investigation |
All rules are always-on global instructions, loaded in both tools: Claude Code reads .claude/rules/ natively; OpenCode loads them via the instructions glob (~/.config/opencode/rules/*.md) in opencode.json. Adding a new rule requires no registration.
| File | Scope | Purpose |
|---|---|---|
coding-behavior.md |
Global | LLM behavioral guardrails: surface assumptions, simplicity first, surgical changes, verifiable goals |
drupal-coding-standards.md |
Global | Strict types, 2-space indent, type hints, DI, cache metadata, quality checklist |
twig-patterns.md |
Global | Presentation only, render full fields, cache bubbling, anti-patterns |
drupal-testing.md |
Global | Test type decision tree, D10 vs D11 differences, common rules |
beads-workflow.md |
Global | Beads task tracking: session start, during work, session end |
quality-tools-setup.md |
Global | PHPStan, PHPCS, Rector, GrumPHP, PHPUnit setup (Audit module priority) |
lessons-learned.md |
Global | Self-learning protocol: document problems and solutions |
services-conventions.md |
Global | Service definitions, DI, interfaces, event subscribers, tagging |
applier-protocol.md |
Global | SEARCH/REPLACE block format for code changes |
config-management.md |
Global | Config export/import, config_split, schema validation |
security-rules.md |
Global | Input sanitization, DB placeholders, route access, CSRF |
ddev-environment.md |
Global | Docker exec commands, environment variables, Audit module priority |
git-workflow.md |
Global | Agents must NOT commit/push; user controls git operations |
Reusable skill definitions that agents can invoke:
| Skill | Description |
|---|---|
drupal-testing |
Test orchestrator: analyzes code, determines type, delegates to specialized skills |
drupal-unit-test |
Unit tests with proper mocking patterns |
drupal-kernel-test |
Kernel tests: services, entities, DB, config, plugins, hooks |
drupal-functional-test |
Functional tests: forms, permissions, HTML output |
drupal-functionaljs-test |
FunctionalJavascript: AJAX, modals, autocompletes, WebDriverTestBase |
drupal-behat-test |
Behat: BDD, acceptance testing, Gherkin scenarios |
drupal-playwright-test |
Playwright: visual regression, cross-browser, E2E test files |
| Skill | Description |
|---|---|
module-scaffold |
Scaffold a new module with PSR-4 structure |
drupal-code-patterns |
Reference patterns: forms, blocks, routing, controllers, Batch/Queue API |
drupal-migration |
D7-to-D10/D11 upgrades, custom migrations (CSV, JSON, API, SQL) |
drupal-update |
Safe Composer update workflow: core, contrib, security patches |
config-management |
Configuration export/import, config_split, schema validation |
drupal-debugging |
Inspect services, entities, cache, watchdog logs, database queries |
drush-commands |
Cache clearing, database updates, module management, cron |
| Skill | Description |
|---|---|
quality-checks |
Full quality pipeline: Audit module primary, raw PHPCS/PHPStan fallback |
drupal-audit-setup |
Install and configure the Drupal Audit module |
performance-audit |
Caching, queries, lazy builders, bottlenecks, N+1 detection |
twig-audit |
Template anti-patterns, cache bubbling, raw filter misuse |
| Skill | Description |
|---|---|
playwright-testing |
Interactive browser testing with Playwright MCP (navigation, screenshots) |
tailwind-drupal |
TailwindCSS setup and usage in Drupal themes |
| Skill | Description |
|---|---|
beads-task-tracking |
Git-backed task tracking with Beads (bd) |
commit-message |
Generate commit messages from git diff (Conventional Commits format) |
xdebug-profiling |
Xdebug tracing and profiling for debugging and performance |
skill-creator |
Create and validate new OpenCode skills |
Create a .md file in .claude/agents/ with fat frontmatter and a system prompt:
---
description: My custom agent for code review.
model: ${MODEL_NORMAL}
mode: subagent
tools:
read: true
glob: true
grep: true
bash: false
write: false
edit: false
permission:
bash: deny
allowed_tools: Read, Glob, Grep
---
You are a code review specialist...The agent is auto-discovered from the .claude/agents/ directory. Use model tokens (${MODEL_SMART}, ${MODEL_NORMAL}, ${MODEL_CHEAP}, ${MODEL_APPLIER}) so the sync script resolves them correctly for each tool.
- Create a
.mdfile in the.claude/rules/directory. - For OpenCode: add its path to the
instructionsarray inopencode.json. - For Claude Code: rules in
.claude/rules/are auto-discovered.
- Create a
SKILL.mdfile in.claude/skills/{skill-name}/following the Agent Skills specification. - Skills are auto-discovered from the
.claude/skills/directory. No config changes needed.
To add custom agents without forking this repo:
- Create a git repository with the same structure (
.claude/agents/,.claude/rules/,.claude/skills/,.env.agents). - Add it to
AGENTS_REPOSin.ddev/.env.agents-sync:AGENTS_REPOS=https://github.com/trebormc/drupal-ai-agents.git,https://github.com/your-org/private-agents.git
- Files from your repo override the public ones (same filename = override).
This configuration package is part of DDEV AI Workspace, a modular ecosystem of DDEV add-ons for AI-powered Drupal development.
| Repository | Description | Relationship |
|---|---|---|
| ddev-ai-workspace | Meta add-on that installs the full AI development stack with one command. | Workspace |
| ddev-agents-sync | Auto-syncs this repo, resolves model tokens, generates tool-specific configs. | Syncs this package |
| ddev-opencode | OpenCode AI CLI container. Reads agents from /agents-opencode. |
Consumer |
| ddev-claude-code | Claude Code CLI container. Reads agents from /agents-claude. |
Consumer |
| ddev-ralph | Autonomous AI task orchestrator. Uses ralph-planner agent and Beads workflow. |
Consumer |
| ddev-beads | Beads git-backed task tracker. | Task tracking |
| ddev-ai-ssh | SSH access to the web container. Generates per-project keys, installs sshd. | SSH infrastructure |
| ddev-playwright-mcp | Headless Playwright browser for visual testing. | Browser automation |
This project is an independent initiative by Robert Menetray, sponsored by DruScan. It is not affiliated with Anthropic, OpenCode, Beads, Playwright, Microsoft, or DDEV. AI-generated code may contain errors. Always review changes before deploying to production.
Apache-2.0. See LICENSE.