From 3f12b2dfa84c5ff31b8bcafb9fa8c4fd47349677 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Tue, 25 Aug 2026 03:24:08 +0000 Subject: [PATCH] fix: expose package classes through Composer --- README.md | 2 ++ composer.json | 6 ++++++ tests/composer-autoload-smoke.php | 15 +++++++++++++-- tests/fixtures/phpstan-consumer.neon | 6 ++++++ tests/fixtures/phpstan-consumer.php | 23 +++++++++++++++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/phpstan-consumer.neon create mode 100644 tests/fixtures/phpstan-consumer.php diff --git a/README.md b/README.md index ea793f8..d81850b 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ composer require wordpress/agents-api:^0.1 Composer autoloads `agents-api.php` through the package `files` autoload entry. The consuming project must load Composer's generated `vendor/autoload.php` during WordPress bootstrap. After that, the same public API is available as in the plugin activation path. +Public agent package definitions are classmapped, so Composer-aware IDEs and static analyzers discover their concrete types without executing the WordPress runtime bootstrap. + Pin released tags (`^0.1`, `0.1.x`, or an exact `0.1.0` tag) for reproducible production installs. Track `main` only for active substrate development. ## Consumer Integration diff --git a/composer.json b/composer.json index ee11ede..5f6d394 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,10 @@ "autoload": { "files": [ "agents-api.php" + ], + "classmap": [ + "src/Registry/class-wp-agent.php", + "src/Packages/" ] }, "suggest": { @@ -24,8 +28,10 @@ }, "scripts": { "phpstan": "phpstan analyse --no-progress --memory-limit=2G", + "phpstan-consumer": "phpstan analyse --no-progress --memory-limit=1G -c tests/fixtures/phpstan-consumer.neon", "smoke": [ "php tests/composer-autoload-smoke.php", + "@phpstan-consumer", "php tests/bootstrap-version-skew-smoke.php", "php tests/bootstrap-smoke.php", "php tests/message-envelope-smoke.php", diff --git a/tests/composer-autoload-smoke.php b/tests/composer-autoload-smoke.php index d99bb11..7b9e1a2 100644 --- a/tests/composer-autoload-smoke.php +++ b/tests/composer-autoload-smoke.php @@ -9,11 +9,22 @@ echo "agents-api-composer-autoload-smoke\n"; -require dirname( __DIR__ ) . '/vendor/autoload.php'; +$loader = require dirname( __DIR__ ) . '/vendor/autoload.php'; if ( defined( 'AGENTS_API_LOADED' ) ) { fwrite( STDERR, "FAIL: Composer autoload initialized Agents API outside WordPress.\n" ); exit( 1 ); } -echo "PASS: Composer autoload returns without WordPress.\n"; +$package_file = $loader->findFile( 'WP_Agent_Package' ); +if ( ! is_string( $package_file ) || ! str_ends_with( str_replace( '\\', '/', $package_file ), '/src/Packages/class-wp-agent-package.php' ) ) { + fwrite( STDERR, "FAIL: Composer classmap does not expose WP_Agent_Package.\n" ); + exit( 1 ); +} + +if ( class_exists( 'WP_Agent_Package', false ) ) { + fwrite( STDERR, "FAIL: Composer autoload eagerly loaded WP_Agent_Package outside WordPress.\n" ); + exit( 1 ); +} + +echo "PASS: Composer autoload returns without WordPress and exposes package classmaps lazily.\n"; diff --git a/tests/fixtures/phpstan-consumer.neon b/tests/fixtures/phpstan-consumer.neon new file mode 100644 index 0000000..3fa37d0 --- /dev/null +++ b/tests/fixtures/phpstan-consumer.neon @@ -0,0 +1,6 @@ +parameters: + level: 7 + paths: + - phpstan-consumer.php + bootstrapFiles: + - ../../vendor/autoload.php diff --git a/tests/fixtures/phpstan-consumer.php b/tests/fixtures/phpstan-consumer.php new file mode 100644 index 0000000..8356f39 --- /dev/null +++ b/tests/fixtures/phpstan-consumer.php @@ -0,0 +1,23 @@ + + */ +function agents_api_phpstan_consume_package( WP_Agent_Package $package ): array { + $report = WP_Agent_Package_Capability_Checker::check( $package, array() ); + + return array( + $package->get_slug(), + $report->to_array(), + WP_Agent_Package_Artifact_Status::classify( 'installed', 'current' ), + WP_Agent_Package_Artifact_Hasher::hash( array() ), + ); +}