Start in the package named by the task; search its src/ and tests/ before widening scope. Read only when relevant: packages/docs/content/architecture.md for repository-wide architecture, extensions.md for extension discovery, Page.php or Media.php for those entities, and...
php artisan boost:add-skill pushword/conversation
Save this content to: AGENTS.md
## Task routing
Start in the package named by the task; search its `src/` and `tests/` before widening scope. Read only when relevant: `packages/docs/content/architecture.md` for repository-wide architecture, `extensions.md` for extension discovery, `Page.php` or `Media.php` for those entities, and `packages/core/src/Event/PushwordEvents.php` for core and admin event names.
Keep search output bounded. For PHP, use `--glob '*.php'`. For frontend code, search `Resources/assets` (`src/assets` in admin-block-editor) first and inspect `Resources/public` only to verify built output. When generated files may appear, use `rg --max-columns 240 --max-columns-preview` so a minified line cannot consume the context.
## Working principles
- Nothing speculative: no unrequested features, abstractions, flexibility, or error handling for impossible cases.
- Remove orphans your change creates; flag (don't delete) pre-existing dead code.
- A zero or an "all good" must come from a measurement. Count per-item outcomes rather than deducing them (`total - errors`), don't trust an exit code a wrapper swallowed, and prove a guard test fails without its fix (on a copy, never in the shared tree).
## Stack
Pushword is a modular CMS: a monorepo of Symfony bundles (core + extensions).
- **DB**: SQLite by default; PostgreSQL and MariaDB via Doctrine — no migrations, use `bin/console doctrine:schema:update --force`
- No deprecated PHP/Symfony/Pushword features.
## Conventions
Match the surrounding code; php-cs-fixer and Rector settle the rest. Two things they don't:
- Group getter/setter for the same property together.
- Twig i18n: camelCase keys, alphabetical, in `packages/<package>/translations/messages.<locale>.yaml`.
## Commands
`composer` scripts run from the repo root; `bin/console` from `packages/dev-app/`.
```bash
composer console list pw # all commands (or bin/console from packages/dev-app/)
composer assets # build assets
composer dev # start server (symfony server:list to check)
composer reset-dev-app # reset demo
```
**Agent-optimized output**: some commands emit one compact JSON line when run by an AI agent (auto-detected) instead of progress/colors/timing. Add it to a command with `Pushword\Core\Command\AgentOutputTrait` + a `--format` option (auto|agent|text); gate every human write behind `if (! $this->agentMode)`. Tests asserting human output must pass `'--format' => 'text'`. `packages/docs/content/agent-output.md` lists which commands support it — update that list, not this file.
## Quality gates
- Lint and test, fixing all warnings/notices: `composer stan`, `composer rector`, `composer test` (or `composer test-filter ExampleTest`). Never use `vendor/bin/phpunit` directly. Never leave a broken build.
- Never skip tests (`markTestSkipped`, `@group skip`) — fix them.
- Clear cache after each change: `composer console cache:clear`. It does not reach the Markdown fragment pool (`var/cache/pushword-pools`, kept across deploys on purpose): a change to rendered output must bump `MarkdownParser::CACHE_VERSION` (TOC: `SplitContent::TOC_CACHE_VERSION`). That cache, and the static build's skip-unchanged, rely on renders being byte-deterministic: no `random()` in a render path, and a content-hash cache that never hits means entropy leaked into the output.
- Comments and docs in English only.
### Mandatory post-change review
For every task that creates, modifies, or deletes code, tests, configuration,
templates, styles, assets, or documentation:
1. After completing the implementation and before sending the final response, invoke
`$is-it-well-tested`.
2. Apply every no-brainer test it identifies. If it requires confirmation for a
non-obvious test, ask the user and do not present the task as complete.
3. Then invoke `$code-simplifier`, scoped strictly to files changed during the current
conversation.
4. If either skill modifies files, rerun the relevant tests and quality gates, including
`composer console cache:clear`.
5. Inspect the final diff and status, then commit only the files changed for the current
task. Add new files with a scoped `git add <path>` immediately before committing, and
use `git commit --only -m "type(scope): subject" -- <paths>`.
6. Verify that the commit exists and that no file belonging to the current task remains
uncommitted. Never include unrelated user or peer changes in the commit.
7. Do not send the final response until both skills, the relevant checks, and the scoped
commit have completed successfully.
8. End the final response with exactly the following status, replacing `<commit-sha>`
with the actual commit hash:
`Post-change review: is-it-well-tested complete; code-simplifier complete; committed <commit-sha>`
For a read-only analysis, explanation, or status request, do not run this review. Changes
made by these two skills do not recursively trigger another review; rerun only the
relevant verification commands. If `is-it-well-tested` requires user input, end the
response with exactly:
`Post-change review: awaiting user confirmation from is-it-well-tested`
### Deprecations
```bash
SYMFONY_DEPRECATIONS_HELPER='max[self]=0&max[direct]=0' composer test # runtime
php bin/console debug:container --deprecations # container
```
## Debugging UI
For admin UI or frontend changes, validate in the isolated test browser (`dev-browser --browser agent-dedicated`): discover elements with `page.snapshotForAI()`, then act on them by node id (or with plain Playwright selectors when they are known). The `ui-debug` skill (`.claude/skills/ui-debug/SKILL.md`) has the credentials, reset command and login script.
## Design
UI/templates/CSS: consult `packages/core/DesignGuidelines.md` (Tailwind, public templates). For admin (Bootstrap/EasyAdmin) apply only the underlying concepts — hierarchy, spacing, color roles, accessibility — not Tailwind classes.
## Git commits
- No AI footprint/signature (no "Generated by", "Co-Authored-By: Claude").
- Concise, focused on the change.
- The working tree AND its single git index are shared with parallel agents. Commit scoped:
`git commit --only -m "type(scope): subject" -- <paths>` — new files need a scoped `git add <path>` first.
- Never bare `git commit`, `commit -a`, or tree-wide `git add` (`-A`/`-u`/`.`): they sweep whatever a peer has staged.
- Staging is not a save point — never leave files staged; stage only right before your own `--only` commit.
- Never stash, hard-reset, `checkout`/`restore .`, or delete/unstage files you didn't create.
To compare with and without a change, use a `git worktree` or a copy.
- A peer's scoped commit takes whole files, so whatever sits in yours can be committed, even
released, at any instant: never leave a knowingly broken edit in the tree, even briefly.
A file you edited showing as unmodified was committed by someone else; check `git log`.
- `.claude/hooks/guard-git.sh` string-matches the whole Bash command: a commit message or
test command containing a blocked pattern must run from a script file.
- Whole-tree commits are a human-terminal operation — stop and ask Robin.
## Git branch cleanup
- Keep `origin/archive` as an intentional historical archive; do not ask to delete it during routine cleanup.
- Keep `origin/docs` and `origin/badges`; CI publishes to these branches.
## Docs
- `packages/docs/content/` — one `.md` per topic; `extension/` — per-bundle feature docs;
`blog/` — articles and comparisons. A page's slug is its path under `content/`, so
moving one needs a 301 row in `content/redirection.csv` and its inbound links updated.
- `packages/docs/AGENTS.md` names the few docs an agent should read: keep it an
allowlist, never a list of files to skip.
- `packages/core/DesignGuidelines.md` — UI/design principles.
- `packages/docs/content/upgrade/` — one note per release, indexed by `upgrade.md`.
Does your change ask something of a site that upgrades — a command to run, a config
key, a template to copy, a behaviour that changed under an unchanged call? Then write
it into `upgrade/next-release.md` in the same commit; the format is in that file.
`.scripts/release` renames it to `upgrade/<version>.md` and adds its index row at the
tag, so never create a versioned note or edit the table by hand.
## For AI agents on a downstream Pushword site
See `packages/docs/AGENTS.md` — the file that ships as `vendor/pushword/docs/AGENTS.md`.
Start in the package named by the task; search its src/ and tests/ before widening scope. Read only when relevant: packages/docs/content/architecture.md for repository-wide architecture, extensions.md for extension discovery, Page.php or Media.php for those entities, and packages/core/src/Event/PushwordEvents.php for core and admin event names.
Keep search output bounded. For PHP, use --glob '*.php'. For frontend code, search Resources/assets (src/assets in admin-block-editor) first and inspect Resources/public only to verify built output. When generated files may appear, use rg --max-columns 240 --max-columns-preview so a minified line cannot consume the context.
total - errors), don't trust an exit code a wrapper swallowed, and prove a guard test fails without its fix (on a copy, never in the shared tree).Pushword is a modular CMS: a monorepo of Symfony bundles (core + extensions).
bin/console doctrine:schema:update --forceMatch the surrounding code; php-cs-fixer and Rector settle the rest. Two things they don't:
packages/<package>/translations/messages.<locale>.yaml.composer scripts run from the repo root; bin/console from packages/dev-app/.
composer console list pw # all commands (or bin/console from packages/dev-app/)
composer assets # build assets
composer dev # start server (symfony server:list to check)
composer reset-dev-app # reset demo
Agent-optimized output: some commands emit one compact JSON line when run by an AI agent (auto-detected) instead of progress/colors/timing. Add it to a command with Pushword\Core\Command\AgentOutputTrait + a --format option (auto|agent|text); gate every human write behind if (! $this->agentMode). Tests asserting human output must pass '--format' => 'text'. packages/docs/content/agent-output.md lists which commands support it — update that list, not this file.
composer stan, composer rector, composer test (or composer test-filter ExampleTest). Never use vendor/bin/phpunit directly. Never leave a broken build.markTestSkipped, @group skip) — fix them.composer console cache:clear. It does not reach the Markdown fragment pool (var/cache/pushword-pools, kept across deploys on purpose): a change to rendered output must bump MarkdownParser::CACHE_VERSION (TOC: SplitContent::TOC_CACHE_VERSION). That cache, and the static build's skip-unchanged, rely on renders being byte-deterministic: no random() in a render path, and a content-hash cache that never hits means entropy leaked into the output.For every task that creates, modifies, or deletes code, tests, configuration, templates, styles, assets, or documentation:
$is-it-well-tested.$code-simplifier, scoped strictly to files changed during the current
conversation.composer console cache:clear.git add <path> immediately before committing, and
use git commit --only -m "type(scope): subject" -- <paths>.<commit-sha>
with the actual commit hash:
Post-change review: is-it-well-tested complete; code-simplifier complete; committed <commit-sha>For a read-only analysis, explanation, or status request, do not run this review. Changes
made by these two skills do not recursively trigger another review; rerun only the
relevant verification commands. If is-it-well-tested requires user input, end the
response with exactly:
Post-change review: awaiting user confirmation from is-it-well-tested
SYMFONY_DEPRECATIONS_HELPER='max[self]=0&max[direct]=0' composer test # runtime
php bin/console debug:container --deprecations # container
For admin UI or frontend changes, validate in the isolated test browser (dev-browser --browser agent-dedicated): discover elements with page.snapshotForAI(), then act on them by node id (or with plain Playwright selectors when they are known). The ui-debug skill (.claude/skills/ui-debug/SKILL.md) has the credentials, reset command and login script.
UI/templates/CSS: consult packages/core/DesignGuidelines.md (Tailwind, public templates). For admin (Bootstrap/EasyAdmin) apply only the underlying concepts — hierarchy, spacing, color roles, accessibility — not Tailwind classes.
git commit --only -m "type(scope): subject" -- <paths> — new files need a scoped git add <path> first.git commit, commit -a, or tree-wide git add (-A/-u/.): they sweep whatever a peer has staged.--only commit.checkout/restore ., or delete/unstage files you didn't create.
To compare with and without a change, use a git worktree or a copy.git log..claude/hooks/guard-git.sh string-matches the whole Bash command: a commit message or
test command containing a blocked pattern must run from a script file.origin/archive as an intentional historical archive; do not ask to delete it during routine cleanup.origin/docs and origin/badges; CI publishes to these branches.packages/docs/content/ — one .md per topic; extension/ — per-bundle feature docs;
blog/ — articles and comparisons. A page's slug is its path under content/, so
moving one needs a 301 row in content/redirection.csv and its inbound links updated.packages/docs/AGENTS.md names the few docs an agent should read: keep it an
allowlist, never a list of files to skip.packages/core/DesignGuidelines.md — UI/design principles.packages/docs/content/upgrade/ — one note per release, indexed by upgrade.md.
Does your change ask something of a site that upgrades — a command to run, a config
key, a template to copy, a behaviour that changed under an unchanged call? Then write
it into upgrade/next-release.md in the same commit; the format is in that file.
.scripts/release renames it to upgrade/<version>.md and adds its index row at the
tag, so never create a versioned note or edit the table by hand.See packages/docs/AGENTS.md — the file that ships as vendor/pushword/docs/AGENTS.md.
How can I help you explore Laravel packages today?