Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
bd0fc1e
6869: Add agents.md and Claude Code configuration
turegjorup Mar 19, 2026
1e7c04c
&869: Update Chnagelog
turegjorup Mar 19, 2026
30a9a53
6869: Update Changelog
turegjorup Mar 19, 2026
7b21a00
Merge branch 'feature/6869_agent_config' of github.com:itk-dev/devops…
turegjorup Mar 19, 2026
3d5ac2d
6869: Rename agents.md to claude.md and update settings
turegjorup Mar 25, 2026
864a7ca
Merge remote-tracking branch 'origin/develop' into feature/6869_agent…
turegjorup Mar 25, 2026
f07447d
Update .claude/settings.json
turegjorup Mar 25, 2026
8c33faf
6869: Add PHPStan job to PR workflow
turegjorup Mar 25, 2026
4b47640
6869: Improve Claude Code hooks and permissions
turegjorup Mar 25, 2026
560e5e5
6869: Clarify local-only dev credentials in docker-compose.override
turegjorup Mar 25, 2026
82b77ae
Merge branch 'feature/6869_agent_config' of github.com:itk-dev/devops…
turegjorup Mar 25, 2026
2ad001c
6869: Update claude.md for Symfony 8.0 and PHP 8.5
turegjorup Mar 25, 2026
9a88a00
6869: Fix typo in config reference (@var → @type)
turegjorup Mar 25, 2026
9344dca
6869: Fix FieldCollection::new() removed in EasyAdmin 5.x
turegjorup Mar 27, 2026
39144a6
6869: Update task file with "pr.actions" check
turegjorup Mar 27, 2026
84caedc
6869: Update defaults in claude.md
turegjorup Mar 27, 2026
506969b
6869: Add automation recommendations (agents, skills, hooks, MCP)
turegjorup Mar 27, 2026
5da6d06
6869: Fix hook file paths for Docker and update README
turegjorup Mar 27, 2026
bac1888
6869: Fix markdown lint errors in README.md
turegjorup Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .claude/agents/create-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: create-migration
description: Generate and validate a Doctrine migration after entity changes
model: sonnet
---

After entity changes, generate and validate a Doctrine migration:

1. Run `docker compose exec -T phpfpm bin/console doctrine:migrations:diff` to generate a migration
2. Read the generated migration file and verify the SQL looks correct
3. Run `docker compose exec -T phpfpm bin/console doctrine:migrations:migrate --no-interaction`
4. Run `docker compose exec -T phpfpm bin/console doctrine:schema:validate`

Report the migration file path, the SQL it contains, and whether schema validation passed.
If schema validation fails, investigate and report the discrepancies.
24 changes: 24 additions & 0 deletions .claude/agents/pr-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: pr-readiness
description: Run all CI-equivalent checks locally before creating a PR
model: haiku
---

Run the following checks in sequence inside Docker and report results for each.
Stop early if a critical check fails.

## Checks

1. **Composer validate**: `docker compose exec -T phpfpm composer validate --strict`
2. **Composer normalize**: `docker compose exec -T phpfpm composer normalize --dry-run`
3. **PHP coding standards**: `docker compose exec -T phpfpm composer coding-standards-check`
4. **PHPStan**: `docker compose exec -T phpfpm vendor/bin/phpstan analyse --no-progress`
5. **PHPUnit tests**: `docker compose exec -T phpfpm composer tests`
6. **Twig coding standards**: `docker compose exec -T phpfpm vendor/bin/twig-cs-fixer lint templates/`
7. **JS coding standards**: `docker compose run --rm -T node yarn coding-standards-check`
8. **API spec up to date**: Run `docker compose exec -T phpfpm composer update-api-spec`, then check `git diff --exit-code public/api-spec-v1.*`
9. **CHANGELOG updated**: Verify CHANGELOG.md has changes compared to the base branch (`git diff develop -- CHANGELOG.md`)

## Output

Report a summary table with columns: Check Name, Status (pass/fail), and error output for failures.
160 changes: 160 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"COMPOSE_USER": "deploy"
},
"permissions": {
"allow": [
"Bash(cat:*)",
"Bash(diff:*)",
"Bash(echo:*)",
"Bash(find:*)",
"Bash(gh:*)",
"Bash(git:*)",
"Bash(grep:*)",
"Bash(head:*)",
"Bash(ls:*)",
"Bash(pwd)",
"Bash(tail:*)",
"Bash(task:*)",
"Bash(tree:*)",
"Bash(wc:*)",
"Bash(which:*)",
"Bash(docker compose exec:*)",
"Bash(docker compose run:*)",
"Bash(docker compose up:*)",
"Bash(docker compose ps:*)",
"Bash(docker compose logs:*)",
"Bash(docker compose top:*)",
"Bash(docker compose config:*)",
"Bash(docker compose pull:*)",
"Bash(docker compose images:*)",
"Bash(docker network:*)"
],
"deny": [
"Bash(rm -rf:*)",
"Bash(gh issue delete:*)",
"Bash(gh release delete:*)",
"Bash(gh repo delete:*)",
"Bash(gh label delete:*)",
"Read(./.env.local)",
"Read(./.env.local.*)",
"Read(./config/secrets/*)"
],
"ask": [
"Bash(docker compose down:*)",
"Bash(docker compose stop:*)",
"Bash(docker compose rm:*)",
"Bash(docker compose restart:*)",
"Bash(gh issue create:*)",
"Bash(gh issue close:*)",
"Bash(gh issue edit:*)",
"Bash(gh issue comment:*)",
"Bash(gh pr create:*)",
"Bash(gh pr close:*)",
"Bash(gh pr merge:*)",
"Bash(gh pr edit:*)",
"Bash(gh pr comment:*)",
"Bash(gh pr review:*)",
"Bash(gh release create:*)",
"Bash(gh release edit:*)",
"Bash(gh repo create:*)",
"Bash(gh label create:*)",
"Bash(gh label edit:*)",
"Bash(git push:*)",
"Bash(git branch -d:*)",
"Bash(git branch -D:*)",
"Bash(git tag -d:*)",
"Bash(git tag -a:*)",
"Bash(git tag :*)",
"Bash(git reset:*)",
"Bash(git rebase:*)",
"Bash(git merge:*)",
"Bash(git stash drop:*)",
"Bash(git clean:*)",
"Bash(git checkout -- :*)",
"Bash(git restore:*)",
"Bash(git commit:*)"
]
},
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "docker compose up --detach --quiet-pull 2>/dev/null || true",
"timeout": 60,
"statusMessage": "Starting Docker services..."
}
]
}
],
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in */composer.lock|*/yarn.lock|*/.env.local|*/.env.local.*) echo 'BLOCKED: Do not edit lock files or .env.local directly' >&2; exit 1 ;; esac"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in *.php) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/php-cs-fixer fix --quiet \"$REL_PATH\" 2>/dev/null || true ;; esac",
"timeout": 30
},
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in *.php) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/phpstan analyse --no-progress --error-format=raw \"$REL_PATH\" 2>/dev/null || true ;; esac",
"timeout": 30
},
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in *.twig) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose exec -T phpfpm vendor/bin/twig-cs-fixer lint --fix \"$REL_PATH\" 2>/dev/null || true ;; esac",
"timeout": 15
},
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in */composer.json) docker compose exec -T phpfpm composer normalize --quiet 2>/dev/null || true ;; esac",
"timeout": 30
},
{
"type": "command",
"command": "case \"$CLAUDE_FILE_PATH\" in *.js|*.css|*.scss|*.yaml|*.yml|*.md) REL_PATH=\"${CLAUDE_FILE_PATH#$CLAUDE_PROJECT_DIR/}\"; docker compose run --rm -T node npx prettier --write \"$REL_PATH\" 2>/dev/null || true ;; esac",
"timeout": 15
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "docker compose exec -T phpfpm bin/console lint:container 2>/dev/null || true",
"timeout": 30,
"statusMessage": "Validating Symfony DI container..."
}
]
}
]
},
"enabledPlugins": {
"php-lsp@claude-plugins-official": true,
"code-simplifier@claude-plugins-official": true,
"context7@claude-plugins-official": true,
"code-review@claude-plugins-official": true,
"security-guidance@claude-plugins-official": true,
"playwright@claude-plugins-official": true,
"feature-dev@claude-plugins-official": true,
"itkdev-skills@itkdev-marketplace": true
}
}
12 changes: 12 additions & 0 deletions .claude/skills/update-api-spec/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
name: update-api-spec
description: Regenerate and stage API spec files after API resource changes
user-invocable: true
---

When API resources or operations change, regenerate the OpenAPI spec files:

1. Run `docker compose exec -T phpfpm composer update-api-spec`
2. Check `git diff public/api-spec-v1.*` for changes
3. If changed, stage the spec files with `git add public/api-spec-v1.yaml public/api-spec-v1.json`
4. Report what changed in the API spec
15 changes: 15 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ jobs:
docker compose exec phpfpm bin/console messenger:setup-transports failed
docker compose exec phpfpm bin/console doctrine:schema:validate

phpstan:
runs-on: ubuntu-latest
name: PHPStan
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Create docker network
run: docker network create frontend

- name: Run PHPStan
run: |
docker compose run --rm phpfpm composer install --no-interaction
docker compose run --rm phpfpm vendor/bin/phpstan analyse

phpunit:
runs-on: ubuntu-latest
name: PHP Unit tests
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ yarn-error.log
phpstan.neon
###< phpstan/phpstan ###
.phpunit.cache
.claude
.twig-cs-fixer.cache
8 changes: 8 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstreamapi/context7-mcp@latest"]
}
}
}
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- [#58](https://github.com/itk-dev/devops_itksites/pull/58)
5002: Added export to everything
- [#62](https://github.com/itk-dev/devops_itksites/pull/62)
6869: Add agents.md and Claude Code configuration for AI coding agents

## [1.8.10] - 2025-07-02

Expand Down
94 changes: 83 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
[![Codecov](https://img.shields.io/codecov/c/github/itk-dev/devops_itksites?style=flat-square&logo=codecov)](https://codecov.io/gh/itk-dev/devops_itksites)
[![GitHub last commit](https://img.shields.io/github/last-commit/itk-dev/devops_itksites?style=flat-square)](https://github.com/itk-dev/devops_itksites/commits/develop/)
[![GitHub License](https://img.shields.io/github/license/itk-dev/devops_itksites?style=flat-square)](https://github.com/itk-dev/devops_itksites/blob/develop/LICENSE)
[![agents.md](https://img.shields.io/badge/%F0%9F%A4%96_agents.md-AI%20ready-8A2BE2?style=flat-square)](https://github.com/itk-dev/devops_itksites/blob/develop/agents.md)

This is our internal server and site registration tool. It works in tandem with our
[ITK sites server harvester](https://github.com/itk-dev/devops_itkServerHarvest).
Expand All @@ -15,17 +16,17 @@ information about sites and installations running on the server. These are sent

This allows us to monitor

* What is installed and running
* Which sites/domains we are hosting
* What docker images we are running
* What packages and modules we are running
* If there are known CVE's for the packages/modules
* What git repositories we are hosting
- What is installed and running
- Which sites/domains we are hosting
- What docker images we are running
- What packages and modules we are running
- If there are known CVE's for the packages/modules
- What git repositories we are hosting

Additionally we can register and document

* All OpenID Connect setups
* All Services Certificates
- All OpenID Connect setups
- All Services Certificates

Servers, OpenID Connect setups, Services Certificates must be created and maintained manually.
All other information is kept up to date by analysing the DetectionResults.
Expand Down Expand Up @@ -73,9 +74,9 @@ AZURE_AZ_OIDC_REDIRECT_URI=https://itksites.local.itkdev.dk/openid-connect/gener

There are not implemented on

* sites
* installations
* domains
- sites
- installations
- domains

This is due to automated processes and scripts that listen from sites and data
is therefore not relevant to have. The architecture makes it possible to delete
Expand Down Expand Up @@ -130,3 +131,74 @@ during development to automatically rebuild assets when source files change.
```sh
docker compose run --rm node yarn coding-standards-check
```

### 🤖 AI coding agents

This project includes an [`agents.md`](agents.md) file that provides project
context for AI coding agents. The file describes the project architecture,
technology stack, development commands, CI/CD setup, and coding conventions.

`agents.md` is a vendor-neutral standard supported by tools such as
[Claude Code](https://claude.ai/claude-code),
[OpenCode](https://opencode.ai/), and others.

Tool-specific configuration (permissions, hooks, plugins) lives in `.claude/`
and is not portable across tools.

#### Claude Code plugins

The following plugins are enabled in `.claude/settings.json`:

| Plugin | Purpose | Source |
| ------------------- | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `php-lsp` | PHP language server for type-aware code intelligence | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `context7` | Up-to-date documentation lookup for Symfony, Doctrine, API Platform, etc. | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `code-review` | Pull request code review | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `code-simplifier` | Suggests clarity and maintainability improvements | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `security-guidance` | Flags potential security issues (OWASP, injection, etc.) | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `playwright` | Browser automation for debugging and testing the EasyAdmin UI | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
| `feature-dev` | Guided feature development with codebase exploration and architecture focus | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |

> **Note:** The `php-lsp` plugin requires [Intelephense](https://intelephense.com/)
> installed globally: `npm install -g intelephense`. All other plugins work
> without additional dependencies.

#### Claude Code agents

Custom agents in `.claude/agents/` automate multi-step workflows:

| Agent | Purpose |
| ------------------ | ----------------------------------------------------------------- |
| `pr-readiness` | Runs all CI-equivalent checks locally before creating a PR |
| `create-migration` | Generates and validates a Doctrine migration after entity changes |

#### Claude Code skills

Custom skills in `.claude/skills/` provide repeatable task shortcuts:

| Skill | Invocation | Purpose |
| ----------------- | ------------------ | ----------------------------------------------------- |
| `update-api-spec` | `/update-api-spec` | Regenerate and stage OpenAPI spec files after changes |

#### Claude Code hooks

Hooks in `.claude/settings.json` run automatically on tool events:

| Hook | Trigger | Purpose |
| -------------- | -------------- | ------------------------------------------------------ |
| Docker start | `SessionStart` | Starts Docker services on session start |
| PHP-CS-Fixer | `PostToolUse` | Auto-formats PHP files on edit |
| PHPStan | `PostToolUse` | Runs static analysis on edited PHP files |
| Twig-CS-Fixer | `PostToolUse` | Auto-formats Twig templates on edit |
| Composer norm | `PostToolUse` | Normalizes `composer.json` on edit |
| Prettier | `PostToolUse` | Auto-formats JS, CSS, YAML, and Markdown files on edit |
| Lock guard | `PreToolUse` | Blocks edits to lock files and `.env.local` |
| Container lint | `Stop` | Validates Symfony DI container before stopping |

#### MCP servers

A shared `.mcp.json` provides team-wide MCP server configuration:

| Server | Purpose |
| ---------- | ------------------------------------------------------------------------- |
| `context7` | Live documentation lookup for Symfony, Doctrine, API Platform, and others |
Loading
Loading