Skip to content

Commit bd0fc1e

Browse files
turegjorupclaude
andcommitted
6869: Add agents.md and Claude Code configuration
Add vendor-neutral agents.md with project context for AI coding agents, and Claude Code settings with permissions, hooks, and plugins. Update README with AI coding agents section describing the setup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 072186c commit bd0fc1e

3 files changed

Lines changed: 281 additions & 0 deletions

File tree

.claude/settings.json

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
3+
"env": {
4+
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
5+
},
6+
"permissions": {
7+
"allow": [
8+
"Bash(cat:*)",
9+
"Bash(diff:*)",
10+
"Bash(echo:*)",
11+
"Bash(find:*)",
12+
"Bash(gh:*)",
13+
"Bash(git:*)",
14+
"Bash(grep:*)",
15+
"Bash(head:*)",
16+
"Bash(ls:*)",
17+
"Bash(pwd)",
18+
"Bash(tail:*)",
19+
"Bash(tree:*)",
20+
"Bash(wc:*)",
21+
"Bash(which:*)",
22+
"Bash(docker compose:*)",
23+
"Bash(docker network:*)"
24+
],
25+
"deny": [
26+
"Bash(rm -rf:*)",
27+
"Read(./.env.local)",
28+
"Read(./.env.local.*)",
29+
"Read(./config/secrets/*)"
30+
],
31+
"ask": [
32+
"Bash(gh issue create:*)",
33+
"Bash(gh issue close:*)",
34+
"Bash(gh issue delete:*)",
35+
"Bash(gh issue edit:*)",
36+
"Bash(gh issue comment:*)",
37+
"Bash(gh pr create:*)",
38+
"Bash(gh pr close:*)",
39+
"Bash(gh pr merge:*)",
40+
"Bash(gh pr edit:*)",
41+
"Bash(gh pr comment:*)",
42+
"Bash(gh pr review:*)",
43+
"Bash(gh release create:*)",
44+
"Bash(gh release delete:*)",
45+
"Bash(gh release edit:*)",
46+
"Bash(gh repo create:*)",
47+
"Bash(gh repo delete:*)",
48+
"Bash(gh label create:*)",
49+
"Bash(gh label delete:*)",
50+
"Bash(gh label edit:*)",
51+
"Bash(git push:*)",
52+
"Bash(git branch -d:*)",
53+
"Bash(git branch -D:*)",
54+
"Bash(git tag -d:*)",
55+
"Bash(git tag -a:*)",
56+
"Bash(git tag :*)",
57+
"Bash(git reset:*)",
58+
"Bash(git rebase:*)",
59+
"Bash(git merge:*)",
60+
"Bash(git stash drop:*)",
61+
"Bash(git clean:*)",
62+
"Bash(git checkout -- :*)",
63+
"Bash(git restore:*)",
64+
"Bash(git commit:*)"
65+
]
66+
},
67+
"hooks": {
68+
"PostToolUse": [
69+
{
70+
"matcher": "Write|Edit",
71+
"hooks": [
72+
{
73+
"type": "command",
74+
"command": "case \"$CLAUDE_FILE_PATH\" in *.php) docker compose exec -T phpfpm vendor/bin/php-cs-fixer fix --quiet \"$CLAUDE_FILE_PATH\" 2>/dev/null || true ;; esac",
75+
"timeout": 30
76+
},
77+
{
78+
"type": "command",
79+
"command": "case \"$CLAUDE_FILE_PATH\" in *.yaml|*.yml) docker compose exec -T phpfpm bin/console lint:yaml \"$CLAUDE_FILE_PATH\" 2>/dev/null || true ;; esac",
80+
"timeout": 15
81+
},
82+
{
83+
"type": "command",
84+
"command": "case \"$CLAUDE_FILE_PATH\" in *.twig) docker compose exec -T phpfpm bin/console lint:twig \"$CLAUDE_FILE_PATH\" 2>/dev/null || true ;; esac",
85+
"timeout": 15
86+
},
87+
{
88+
"type": "command",
89+
"command": "case \"$CLAUDE_FILE_PATH\" in *.json) python3 -m json.tool \"$CLAUDE_FILE_PATH\" > /dev/null 2>&1 || true ;; esac",
90+
"timeout": 10
91+
}
92+
]
93+
}
94+
]
95+
},
96+
"enabledPlugins": {
97+
"php-lsp@claude-plugins-official": true,
98+
"code-simplifier@claude-plugins-official": true,
99+
"context7@claude-plugins-official": true,
100+
"code-review@claude-plugins-official": true,
101+
"security-guidance@claude-plugins-official": true,
102+
"playwright@claude-plugins-official": true,
103+
"feature-dev@claude-plugins-official": true
104+
},
105+
"alwaysThinkingEnabled": true,
106+
"defaultMode": "acceptEdits"
107+
}

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
[![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)
77
[![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/)
88
[![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)
9+
[![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)
910

1011

1112
This is our internal server and site registration tool. It works in tandem with our
@@ -125,3 +126,34 @@ during development to automatically rebuild assets when source files change.
125126
```sh
126127
docker compose run --rm node yarn coding-standards-check
127128
```
129+
130+
### 🤖 AI coding agents
131+
132+
This project includes an [`agents.md`](agents.md) file that provides project
133+
context for AI coding agents. The file describes the project architecture,
134+
technology stack, development commands, CI/CD setup, and coding conventions.
135+
136+
`agents.md` is a vendor-neutral standard supported by tools such as
137+
[Claude Code](https://claude.ai/claude-code),
138+
[OpenCode](https://opencode.ai/), and others.
139+
140+
Tool-specific configuration (permissions, hooks, plugins) lives in `.claude/`
141+
and is not portable across tools.
142+
143+
#### Claude Code plugins
144+
145+
The following plugins are enabled in `.claude/settings.json`:
146+
147+
| Plugin | Purpose | Source |
148+
|---|---|---|
149+
| `php-lsp` | PHP language server for type-aware code intelligence | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
150+
| `context7` | Up-to-date documentation lookup for Symfony, Doctrine, API Platform, etc. | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
151+
| `code-review` | Pull request code review | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
152+
| `code-simplifier` | Suggests clarity and maintainability improvements | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
153+
| `security-guidance` | Flags potential security issues (OWASP, injection, etc.) | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
154+
| `playwright` | Browser automation for debugging and testing the EasyAdmin UI | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
155+
| `feature-dev` | Guided feature development with codebase exploration and architecture focus | [claude-plugins-official](https://github.com/anthropics/claude-code-plugins) |
156+
157+
> **Note:** The `php-lsp` plugin requires [Intelephense](https://intelephense.com/)
158+
> installed globally: `npm install -g intelephense`. All other plugins work
159+
> without additional dependencies.

agents.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# 🤖 Code Agents - DevOps ITKsites
2+
3+
## Project Overview
4+
5+
**DevOps ITKsites** is an internal Symfony application for server and site
6+
registration/monitoring at ITK Dev. It receives `DetectionResults` from the
7+
[ITK sites server harvester](https://github.com/itk-dev/devops_itkServerHarvest)
8+
and processes them asynchronously to track servers, sites, domains, Docker
9+
images, packages, modules, CVEs, and git repositories.
10+
11+
## Technology Stack
12+
13+
- **Language**: PHP 8.4+ (Symfony 7.3)
14+
- **API**: API Platform 4.0 (REST)
15+
- **Admin UI**: EasyAdmin 4.x
16+
- **Database**: Doctrine ORM 3.x / DBAL 4.x with MariaDB
17+
- **Messaging**: Symfony Messenger (AMQP/RabbitMQ)
18+
- **Auth**: OpenID Connect (`itk-dev/openid-connect-bundle`)
19+
- **Frontend**: Webpack Encore, Stimulus.js
20+
- **Testing**: PHPUnit 11+
21+
- **Code Quality**: PHP-CS-Fixer, PHPStan, Rector
22+
23+
## Architecture
24+
25+
```mermaid
26+
graph TD
27+
A[Harvester] -->|POST DetectionResult| B[API Platform REST endpoint]
28+
B --> C[Symfony Messenger]
29+
C --> D[Async Message Handlers]
30+
D --> D1[DirectoryHandler]
31+
D --> D2[DockerImageHandler]
32+
D --> D3[DrupalHandler]
33+
D --> D4[GitHandler]
34+
D --> D5[NginxHandler]
35+
D --> D6[SymfonyHandler]
36+
D1 & D2 & D3 & D4 & D5 & D6 --> E[Doctrine ORM]
37+
E --> F[MariaDB]
38+
F --> G[EasyAdmin UI]
39+
```
40+
41+
### Key Directories
42+
43+
| Directory | Purpose |
44+
|---|---|
45+
| `src/Entity/` | ~20 Doctrine entities (Server, Site, Domain, Installation, Package, DockerImage, Advisory, etc.) |
46+
| `src/Handler/` | DetectionResult handlers (Directory, Docker, Drupal, Git, Nginx, Symfony) |
47+
| `src/MessageHandler/` | Async message processing (PersistDetectionResult, ProcessDetectionResult) |
48+
| `src/Admin/` | EasyAdmin CRUD controllers |
49+
| `src/ApiResource/` | API Platform resource definitions |
50+
| `src/Service/` | Factories (PackageVersion, ModuleVersion, Advisory) and export services |
51+
| `src/Repository/` | Doctrine repositories |
52+
| `config/packages/` | Bundle configurations |
53+
| `migrations/` | Doctrine migrations |
54+
| `fixtures/` | Hautelook/Alice test fixtures |
55+
| `tests/` | PHPUnit tests (Api, Controller, MessageHandler) |
56+
57+
### Data Flow
58+
59+
All analyzed data (sites, installations, domains, packages, etc.) can be
60+
truncated and rebuilt by replaying DetectionResults. Manually maintained data
61+
(Servers, OIDC setups, Service Certificates) is separate and must be preserved.
62+
63+
## Development Environment
64+
65+
```sh
66+
# Start services (MariaDB, PHP-FPM 8.4, Nginx, Mailpit)
67+
docker compose pull && docker compose up --detach
68+
69+
# Install dependencies
70+
docker compose exec phpfpm composer install
71+
72+
# Run migrations
73+
docker compose exec phpfpm bin/console doctrine:migrations:migrate --no-interaction
74+
75+
# Load fixtures
76+
docker compose exec phpfpm composer fixtures
77+
78+
# Login as admin (after fixtures)
79+
docker compose exec phpfpm bin/console itk-dev:openid-connect:login admin@example.com
80+
81+
# Process message queues
82+
docker compose exec phpfpm composer queues
83+
84+
# Build frontend assets
85+
docker compose run --rm node yarn install && docker compose run --rm node yarn build
86+
```
87+
88+
## Quality Checks
89+
90+
All commands run inside Docker containers:
91+
92+
```sh
93+
# PHP coding standards (PHP-CS-Fixer)
94+
docker compose exec phpfpm composer coding-standards-check
95+
docker compose exec phpfpm composer coding-standards-apply
96+
97+
# PHPUnit tests (creates test DB, runs migrations, executes tests)
98+
docker compose exec phpfpm composer tests
99+
100+
# Frontend coding standards
101+
docker compose run --rm node yarn coding-standards-check
102+
103+
# API spec export (must be committed)
104+
docker compose exec phpfpm composer update-api-spec
105+
```
106+
107+
## CI/CD
108+
109+
### GitHub Actions (`pr.yaml`)
110+
111+
Pull requests run these checks:
112+
113+
1. **Composer validation** - validates and installs (prod + dev)
114+
2. **Doctrine schema validation** - migrations + schema check against MariaDB
115+
3. **PHP-CS-Fixer** - coding standards
116+
4. **PHPUnit** - unit/integration tests with MariaDB
117+
5. **API spec validation** - ensures exported OpenAPI spec is up to date
118+
6. **Fixtures** - verifies fixtures load successfully
119+
7. **Asset build** - verifies frontend assets compile
120+
8. **Changelog** - ensures CHANGELOG.md is updated
121+
122+
### Woodpecker CI (deployment)
123+
124+
- `stg.yml` - Deploys to staging on push to develop
125+
- `prod.yml` - Deploys to production on release (Ansible playbook, runs migrations + transport setup)
126+
127+
## PR Guidelines
128+
129+
- PRs must link to a ticket
130+
- Code must pass all CI checks (tests, coding standards, static analysis)
131+
- CHANGELOG.md must be updated
132+
- UI changes require screenshots
133+
- Base branch: `develop`
134+
135+
## Important Conventions
136+
137+
- Entity classes extend `AbstractBaseEntity` (provides `id`, `createdAt`, `updatedAt`)
138+
- Detection handlers implement `DetectionResultHandlerInterface`
139+
- Handlers are auto-tagged and injected via tagged iterator in `services.yaml`
140+
- Async processing uses Symfony Messenger with AMQP transport
141+
- Environment-specific config goes in `.env.local` (not committed)
142+
- API specs (`public/api-spec-v1.yaml` and `.json`) must be regenerated and committed when API changes

0 commit comments

Comments
 (0)