goaop/framework | NS: Go\ | PHP: ^8.4.0 AOP via source transformation at load time (stream filter, no PECL, no eval).
php artisan boost:add-skill lisachenko/go-aop-php
Save this content to: AGENTS.md
# Go! AOP Framework
goaop/framework | NS: Go\ | PHP: ^8.4.0
AOP via source transformation at load time (stream filter, no PECL, no eval).
## Agent gate
- PHP 8.4+ required. If PHP 8.3 or less → STOP, report can't run tests/phpstan.
- Gate: `composer analyze` before commit (phpstan level 10).
- Remote session (Claude Code on the web): `composer install` is source-only/slow and dies on phpstan/phpstan → packagist-mirror recipe in `tests/AGENTS.md` § Remote sessions.
## Commands
| Action | Command |
|-----------|-----------------------------------------------------------------------|
| install | `composer install` |
| test:all | `composer test` (= `./vendor/bin/phpunit`) |
| test:file | `./vendor/bin/phpunit tests/Core/ContainerTest.php` |
| test:one | `./vendor/bin/phpunit --filter testName tests/Core/ContainerTest.php` |
| test:perf:transform | `composer test:performance:transformation` (opt-in group, JIT disabled) |
| analyze | `composer analyze` (= `./vendor/bin/phpstan analyze --memory-limit=512M`) |
| cs | `composer cs` (= `./vendor/bin/php-cs-fixer check --diff`, PER-CS) |
| cs:fix | `composer cs:fix` (= `./vendor/bin/php-cs-fixer fix`) |
| check | `composer check` (cs + analyze + test) |
## Architecture overview
Intercepts PHP class loading pipeline: source stream filter transforms source → injects interception hooks → caches result.
- Init: AspectKernel::init() → stream filter → transformers → configureAop()
- Main transformer: WeavingTransformer (class→trait, proxy class re-inherits parent+interfaces)
- Proxy dispatch: per-method static $__joinPoint → InterceptorInjector → interceptor chain of first-class advice callables (The::aspect(X::class)->m(...), The::advice('id') for closure advices)
## Directory → AGENTS.md map
| Directory | Sub-AGENTS.md | Covers |
|-------------------|----------------------------|---------------------------------------------------------------|
| `src/Instrument/` | `src/Instrument/AGENTS.md` | Init flow, transformers, trait engine overview, aspects skip |
| `src/Instrument/Transformer/Weaving/` | `src/Instrument/Transformer/Weaving/AGENTS.md` | WeavingTransformer steps, TokenStreamEditor, TraitConverter, ProxyCache, line numbers, Override |
| `src/Proxy/` | `src/Proxy/AGENTS.md` | Proxy generators, code-gen, readonly, hooks, enums |
| `src/Aop/` | `src/Aop/AGENTS.md` | Interfaces, generics, implementations, pointcuts, attributes |
| `src/Aop/Exception/` | `src/Aop/Exception/AGENTS.md` | Exception groups, static constructors |
| `src/Core/` | `src/Core/AGENTS.md` | Container, aspect loading, advice matching, bridge |
| `src/Core/Cache/` | `src/Core/Cache/AGENTS.md` | Compiled advisor cache: compiler, printer, writer, loader |
| `tests/` | `tests/AGENTS.md` | Test conventions, fixtures, PHPUnit, PHPStan |
## Rules
- Skip explanations unless asked. Show changes, not commentary.
- Use targeted edits (Edit tool) over full-file rewrites.
- No filler words ("let me", "carefully", "I'll now").
- Before commit: phpunit and phpstan must pass. Fix errors before offering to commit.
- Touching a SourceTransformer/NodeRewriter or the transformer wiring (AspectKernel, FrameworkServices, SourceTransformingLoader) → run `composer test:performance:transformation` before and after; the numbers must not get worse (CI compares head with base on such PRs).
- New classes are `final` unless they are meant to be extended.
- Constructor arguments stored as-is are promoted properties, one per line (multiline signature, trailing comma).
Their phpstan type and description go into an inline `/** @var list<Foo> Description */` (or a plain `/** Description */`)
above the promoted parameter, not into a constructor `@param` tag.
- Framework-internal contracts expose stored values as interface properties (`public int $kind { get; }`), implemented
by promoted/readonly properties or `get` hooks, not as getter methods. `@api` contracts (`Advice`, `Advisor`,
`Aop\Intercept\*`) keep their getter methods.
- Throwing or adding an exception → read `src/Aop/Exception/AGENTS.md` first.
- No anonymous classes in `src/`: extract a named `final` class (`@internal` for machinery); anonymous classes are for tests and mocks.
- Commit messages and PR titles must follow Conventional Commits (`type(scope): summary`, e.g. `fix(proxy): ...`).
- Generated code (proxies, woven traits, advisor caches) must stay clean and readable: reference classes through short `use` aliases, never replace them with fully-qualified names. Name collisions are detected and resolved by adjusting the imports automatically (`Go\Proxy\Generator\ProxyImports`, see `src/Proxy/AGENTS.md`).
goaop/framework | NS: Go\ | PHP: ^8.4.0 AOP via source transformation at load time (stream filter, no PECL, no eval).
composer analyze before commit (phpstan level 10).composer install is source-only/slow and dies on phpstan/phpstan → packagist-mirror recipe in tests/AGENTS.md § Remote sessions.| Action | Command |
|---|---|
| install | composer install |
| test:all | composer test (= ./vendor/bin/phpunit) |
| test:file | ./vendor/bin/phpunit tests/Core/ContainerTest.php |
| test:one | ./vendor/bin/phpunit --filter testName tests/Core/ContainerTest.php |
| test:perf:transform | composer test:performance:transformation (opt-in group, JIT disabled) |
| analyze | composer analyze (= ./vendor/bin/phpstan analyze --memory-limit=512M) |
| cs | composer cs (= ./vendor/bin/php-cs-fixer check --diff, PER-CS) |
| cs:fix | composer cs:fix (= ./vendor/bin/php-cs-fixer fix) |
| check | composer check (cs + analyze + test) |
Intercepts PHP class loading pipeline: source stream filter transforms source → injects interception hooks → caches result.
| Directory | Sub-AGENTS.md | Covers |
|---|---|---|
src/Instrument/ |
src/Instrument/AGENTS.md |
Init flow, transformers, trait engine overview, aspects skip |
src/Instrument/Transformer/Weaving/ |
src/Instrument/Transformer/Weaving/AGENTS.md |
WeavingTransformer steps, TokenStreamEditor, TraitConverter, ProxyCache, line numbers, Override |
src/Proxy/ |
src/Proxy/AGENTS.md |
Proxy generators, code-gen, readonly, hooks, enums |
src/Aop/ |
src/Aop/AGENTS.md |
Interfaces, generics, implementations, pointcuts, attributes |
src/Aop/Exception/ |
src/Aop/Exception/AGENTS.md |
Exception groups, static constructors |
src/Core/ |
src/Core/AGENTS.md |
Container, aspect loading, advice matching, bridge |
src/Core/Cache/ |
src/Core/Cache/AGENTS.md |
Compiled advisor cache: compiler, printer, writer, loader |
tests/ |
tests/AGENTS.md |
Test conventions, fixtures, PHPUnit, PHPStan |
composer test:performance:transformation before and after; the numbers must not get worse (CI compares head with base on such PRs).final unless they are meant to be extended./** @var list<Foo> Description */ (or a plain /** Description */)
above the promoted parameter, not into a constructor @param tag.public int $kind { get; }), implemented
by promoted/readonly properties or get hooks, not as getter methods. @api contracts (Advice, Advisor,
Aop\Intercept\*) keep their getter methods.src/Aop/Exception/AGENTS.md first.src/: extract a named final class (@internal for machinery); anonymous classes are for tests and mocks.type(scope): summary, e.g. fix(proxy): ...).use aliases, never replace them with fully-qualified names. Name collisions are detected and resolved by adjusting the imports automatically (Go\Proxy\Generator\ProxyImports, see src/Proxy/AGENTS.md).How can I help you explore Laravel packages today?