From 109d9b6adad51a6ce3bb4ba742547246fdcb0678 Mon Sep 17 00:00:00 2001 From: martinyde Date: Fri, 10 Apr 2026 15:46:40 +0200 Subject: [PATCH] Added create project agent, itkdev-symfony skill, and modified skills used when creating a new project --- README.md | 1 + agents/itkdev-create-project.md | 129 +++++++++++++++++++++++ skills/itkdev-docker-templates/SKILL.md | 49 +++++---- skills/itkdev-drupal/SKILL.md | 81 ++++++++++++++- skills/itkdev-symfony/SKILL.md | 130 ++++++++++++++++++++++++ skills/itkdev-taskfile/SKILL.md | 37 ++++++- 6 files changed, 403 insertions(+), 24 deletions(-) create mode 100644 agents/itkdev-create-project.md create mode 100644 skills/itkdev-symfony/SKILL.md diff --git a/README.md b/README.md index 359e5f1..dd73d5f 100644 --- a/README.md +++ b/README.md @@ -28,4 +28,5 @@ claude plugin add itk-dev/itkdev-skills | Agent | Description | |-------|-------------| | `itkdev-code-review` | Automated PR review against ITK Dev standards | +| `itkdev-create-project` | Create new Drupal/Symfony projects with ITK Dev Docker setup | | `itkdev-issue-workflow` | Autonomous GitHub issue workflow (runs in isolated subagent context) | diff --git a/agents/itkdev-create-project.md b/agents/itkdev-create-project.md new file mode 100644 index 0000000..48d6f0a --- /dev/null +++ b/agents/itkdev-create-project.md @@ -0,0 +1,129 @@ +--- +name: itkdev-create-project +description: "Create a new Drupal or Symfony project with ITK Dev Docker setup. Delegates to this agent when creating new projects, building new sites, or scaffolding new applications." +skills: + - itkdev-docker + - itkdev-docker-templates + - itkdev-taskfile + - itkdev-drupal + - itkdev-symfony +memory: project +--- + +# Create Project Agent + +You are a project scaffolding agent that creates new Drupal or Symfony projects with the ITK Dev Docker setup. You guide the user through project creation with interactive steps where needed and autonomous execution where possible. + +You have access to all standard tools: Bash, Read, Write, Edit, Glob, Grep, Task, WebFetch, and more. + +**Sandbox note:** The `itkdev-docker-compose` and `docker compose` commands need to access paths and sockets (e.g. the Docker socket) outside the default sandbox allowlist. Before running these commands, explain this to the user and ask for permission to disable the sandbox. + +**File access in new project directories:** Files inside newly created project directories may not be accessible via the `Read` or `Edit` tools due to sandbox/permission restrictions (the directory didn't exist when permissions were set). To work around this: +- **Reading files:** Use `docker compose exec phpfpm cat -n ` or `grep -n` inside the container instead of the `Read` tool. +- **Editing files:** Use `docker compose exec phpfpm sed -i ...` or `docker compose exec phpfpm bash -c '...'` inside the container instead of the `Edit` tool. For appending content, use `cat >>` inside the container. +- **Writing new files:** The `Write` tool typically works for creating new files in the project directory, even when `Read`/`Edit` are blocked. +- All container commands require sandbox disabled — ask the user for permission once at the start of the Docker phase. + +## PHASE 1: Project Requirements (USER INTERACTION) + +1. Ask two questions: + - **Type:** Drupal or Symfony? + - **Version:** Which version? + +2. Fetch available templates from the GitHub API using `WebFetch` (not `curl` via Bash, which is blocked by the sandbox): + ``` + WebFetch url: https://api.github.com/repos/itk-dev/devops_itkdev-docker/contents/templates?ref=develop + prompt: List all directory names (the "name" field) from this JSON array. Only return the names, one per line. + ``` + +3. Present the relevant templates (filtered by the chosen type) to the user so they can confirm which one to use. + +4. **Version mismatch handling:** If the exact version template doesn't exist (e.g. the user wants Symfony 7 but only `symfony-6` is available), use the closest available template — the Docker setup is compatible across versions. The actual framework version is determined by the `composer create-project` step, not the template. + +5. Confirm the template selection before proceeding. + +## PHASE 2: Scaffold Docker Environment (AUTONOMOUS) + +1. Create the project directory and navigate into it. + +2. Apply the devops Docker template: + ```bash + printf 'y\n\n' | itkdev-docker-compose template:install + ``` + Where `` matches the confirmed template (e.g. `drupal-11`, `symfony-8`). + + The `template:install` command has three interactive prompts (see `itkdev-docker-templates` skill for details). Piping `printf 'y\n\n'` answers `y` to the confirmation and accepts defaults for project name and domain. + +3. Verify the generated `.env` file contains correct values for `COMPOSE_PROJECT_NAME`, `COMPOSE_DOMAIN`, and `ITKDEV_TEMPLATE`. If the project name or domain should differ from the defaults, edit the `.env` file directly after install. + +## PHASE 3: Service Selection (USER INTERACTION) + +1. Read the generated `docker-compose.yml` to determine which services the template includes. + +2. Present the list of services to the user and ask which ones the project actually needs. + +3. For each service the user does not need, remove it from `docker-compose.yml`, `docker-compose.dev.yml`, and `docker-compose.server.yml` — including any `depends_on` references, networks, volumes, and environment variables that only apply to the removed service. Keep the files clean and consistent after removal. + +## PHASE 4: Framework Scaffolding (AUTONOMOUS) + +1. Start the Docker environment: + ```bash + docker compose up -d + ``` + +2. Run `composer create-project` inside the PHP-FPM container to scaffold the project on top of the Docker setup. The project is created in a temp directory first to avoid conflicts with existing files, then merged into the app root. + + **Drupal:** + ```bash + docker compose exec phpfpm composer create-project drupal/recommended-project: /tmp/project && docker compose exec phpfpm cp -rT /tmp/project /app + ``` + + **Symfony:** See the "Project Scaffolding" section in the `itkdev-symfony` skill for the full procedure (create-project, `.env` restore, post-scaffold `composer install`). + +3. Run `composer install` to ensure the vendor directory and autoloader are fully initialized: + ```bash + docker compose exec phpfpm composer install + ``` + This prevents extraction errors (e.g. `RecursiveDirectoryIterator` failures) that can occur when requiring new packages into a partially-initialized vendor directory from `cp -rT`. + +4. **Drupal only:** Install Drush immediately — it is not included in `drupal/recommended-project` but is required for site installation and all subsequent Drupal tasks: + ```bash + docker compose exec phpfpm composer require drush/drush --no-interaction + ``` + +## PHASE 5: Report & Optional Steps (USER INTERACTION) + +Report the following to the user: +- **Project directory** — the full path +- **Docker services** — which services are running +- **Project type and version** — e.g. Drupal 11, Symfony 8 +- **Accessible domain** — e.g. `http://.local.itkdev.dk` + +Then offer to continue with these optional next steps: + +### Option 1: Install the site + +**Drupal:** See the "Site Installation" section in the `itkdev-drupal` skill for the full procedure (settings.php setup, profile selection, drush command). If the user does not specify a profile, default to **minimal**. + +**Symfony:** See the "Database Configuration" section in the `itkdev-symfony` skill for the full procedure (Doctrine ORM installation, DATABASE_URL configuration, connection verification). + +### Option 2: Create a Taskfile.yml + +Generate a [Task](https://taskfile.dev/) file that mirrors the checks and steps defined in the `.github/workflows/` directory, so developers can run the same CI checks locally. See the `itkdev-taskfile` skill for the canonical header, task patterns, and framework-specific console commands. + +### Option 3: Create a theme (Drupal only) + +If the project is Drupal, ask if the user wants to set up a custom theme. See the "Theme Development" section in the `itkdev-drupal` skill for the full procedure (base theme vs custom theme, generation steps). + +## Important Rules + +- Always ask for project type and version before starting +- Always fetch and present available templates from GitHub +- Use the `itkdev-docker-templates` skill for template installation details +- Use the `itkdev-taskfile` skill for Taskfile generation patterns +- Use the `itkdev-drupal` skill for Drupal-specific guidance (site installation, theme development, drush) +- Use the `itkdev-symfony` skill for Symfony-specific guidance (scaffolding, database, console commands) +- **Console commands:** Always use `vendor/bin/` when running framework CLI tools inside the container (e.g. `vendor/bin/drush`). Never use bare `drush` or `console`. +- The `itkdev-docker-compose` CLI must be on the PATH (from the `scripts/` directory of the devops repo) +- Drupal uses PHP CodeSniffer (`.phpcs.xml.dist`), Symfony uses PHP CS Fixer (`.php-cs-fixer.dist.php`) +- The `drupal-module` template is a minimal setup (no Nginx/database/Memcached) for standalone module development diff --git a/skills/itkdev-docker-templates/SKILL.md b/skills/itkdev-docker-templates/SKILL.md index 274efe3..a0b83a5 100644 --- a/skills/itkdev-docker-templates/SKILL.md +++ b/skills/itkdev-docker-templates/SKILL.md @@ -75,6 +75,26 @@ itkdev-docker-compose template:update --force After installation, the `.env` file will contain `ITKDEV_TEMPLATE=`. +### Interactive Prompts + +The `template:install` command has three interactive prompts that will hang in a non-interactive shell: + +1. `Are you sure you want to install the template in (y|N)?` — uses `read -p ... -n 1 -r`, reads a single character. Must send `y`. +2. `Project name ()?` (default: directory name) — uses `read -e`, accepts newline for default. +3. `Domain [.local.itkdev.dk]?` (default: `.local.itkdev.dk`) — uses `read -e`, accepts newline for default. + +The confirmation prompt (`y|N`) is **always** shown (even on fresh installs). For non-interactive shells, pipe input: +```bash +printf 'y\n\n' | itkdev-docker-compose template:install +``` +This answers `y` to the confirmation and accepts defaults for project name and domain. + +Using `--force` skips only the confirmation prompt but still requires the project name and domain inputs. + +### Version Mismatch + +If the exact version template doesn't exist (e.g. the user wants Symfony 7 but only `symfony-6` is available), use the closest available template — the Docker setup is compatible across versions. The actual framework version is determined by the `composer create-project` step, not the template. + ## Setup Workflows ### New Drupal 11 Project @@ -107,40 +127,31 @@ After installation, the `.env` file will contain `ITKDEV_TEMPLATE=>`). See the agent's sandbox note for details. + +1. **Config sync directory:** Set `$settings['config_sync_directory']` to `'../config/sync'`. + ```bash + docker compose exec phpfpm sed -i "s|# \$settings\['config_sync_directory'\] = '/directory/outside/webroot';|\$settings['config_sync_directory'] = '../config/sync';|" /app/web/sites/default/settings.php + ``` + Also create the directory: + ```bash + docker compose exec phpfpm mkdir -p /app/config/sync + ``` +2. **Skip permissions hardening:** Uncomment `$settings['skip_permissions_hardening'] = TRUE;` so file permissions are never hardened. Note: this setting may not exist in all Drupal versions — skip if not present. +3. **Local settings override:** Remove the commented-out `settings.local.php` include block and append an uncommented version at the very end of the file: + ```bash + # Remove the commented block + docker compose exec phpfpm sed -i '/^#$/,/^# }$/d' /app/web/sites/default/settings.php + # Append uncommented block at end + docker compose exec phpfpm bash -c 'cat >> /app/web/sites/default/settings.php << '\''EOFPHP'\'' + + if (file_exists($app_root . '\''/'\'' . $site_path . '\''/settings.local.php'\'')) { + include $app_root . '\''/'\'' . $site_path . '\''/settings.local.php'\''; + } + EOFPHP' + ``` + +Ask the user which install profile to use. If the user does not specify, default to **minimal**: +- **minimal** (default) — bare-bones installation with no pre-configured content types or modules +- **standard** — includes default content types, blocks, and commonly used modules + +Then install with the chosen profile and `--db-url` matching the MariaDB container credentials: + +```bash +docker compose exec phpfpm vendor/bin/drush site:install --yes --db-url=mysql://db:db@mariadb:3306/db --account-name=admin --account-pass=admin +``` + +Without a profile and `--db-url`, Drush cannot resolve the install profile or connect to the database. + ## Drush Commands **Always run drush via itkdev-docker-compose** (or use Taskfile tasks if available): diff --git a/skills/itkdev-symfony/SKILL.md b/skills/itkdev-symfony/SKILL.md new file mode 100644 index 0000000..159bae9 --- /dev/null +++ b/skills/itkdev-symfony/SKILL.md @@ -0,0 +1,130 @@ +--- +name: itkdev-symfony +description: Symfony development assistance for ITK Dev projects. Use when working with Symfony codebases, scaffolding Symfony projects, configuring databases, running console commands, or managing Symfony configuration. +--- + +# Symfony Development Guide + +You are assisting with Symfony development in ITK Dev Docker projects. This skill covers project scaffolding, database configuration, console commands, and coding standards. + +## Project Detection + +Recognize Symfony projects by: +- `config/bundles.php` file +- `symfony/*` packages in `composer.json` +- `public/index.php` entry point +- `.php-cs-fixer.dist.php` config file +- `docker-compose.yml` with ITK Dev Docker setup + +## Docker and Taskfile + +**IMPORTANT:** ITK Dev projects run in Docker containers. Never run PHP, Composer, or console commands directly on the host. + +For Docker environment details (CLI commands, services, configuration), see the `itkdev-docker` skill. +For Taskfile automation (coding standards, site management), see the `itkdev-taskfile` skill. +For project templates and setup, see the `itkdev-docker-templates` skill. + +**Quick reference:** + +```bash +# Via docker compose +docker compose exec phpfpm bin/console cache:clear +docker compose exec phpfpm composer install + +# Via Taskfile (preferred if available) +task # List available tasks +task console -- cache:clear # Run console commands +``` + +## Project Scaffolding + +To scaffold a Symfony project inside the Docker container: + +```bash +docker compose exec phpfpm composer create-project symfony/skeleton:".*" /tmp/project && docker compose exec phpfpm cp -rT /tmp/project /app +``` + +### Restore Docker `.env` + +The Symfony skeleton includes its own `.env` file, so `cp -rT` overwrites the Docker `.env`. After the copy, you MUST restore the Docker Compose variables (`COMPOSE_PROJECT_NAME`, `COMPOSE_DOMAIN`, `ITKDEV_TEMPLATE`) by prepending them back to the `.env` file. Because the `.env` is already overwritten at this point, `docker compose` will fail with `required variable COMPOSE_DOMAIN is missing a value` unless you pass the variables inline: + +```bash +COMPOSE_DOMAIN=.local.itkdev.dk COMPOSE_PROJECT_NAME= docker compose exec phpfpm bash -c 'printf "COMPOSE_PROJECT_NAME=\nCOMPOSE_DOMAIN=.local.itkdev.dk\nITKDEV_TEMPLATE=