adachsoft / phpstan-tool
AI Tool-Call SPI tool for running PHPStan static analysis with normalized base_path semantics.
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Forks: 0
pkg:composer/adachsoft/phpstan-tool
Requires
- adachsoft/ai-tool-call: ^2.0.1
- adachsoft/command-executor-lib: 2.0.0
- adachsoft/normalized-safe-path: ^0.1.0
Requires (Dev)
- adachsoft/php-code-style: ^0.2
- friendsofphp/php-cs-fixer: ^3.89
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.4
- rector/rector: ^2.3
This package is not auto-updated.
Last update: 2026-01-31 20:32:52 UTC
README
AI Tool-Call SPI tool for running PHPStan static analysis with normalized base_path semantics.
This library exposes a single SPI tool, phpstan, that can be discovered and called through
adachsoft/ai-tool-call. It runs PHPStan via
adachsoft/command-executor-lib and resolves
all user-provided paths relative to a configured base_path using
adachsoft/normalized-safe-path.
Installation
Install via Composer:
composer require adachsoft/phpstan-tool
The exact version constraints for dependencies are defined in this package's composer.json.
High-level architecture
The package follows the AI Tool-Call architecture described in
.docs/AI_TOOL_CALL_BASE_PATH_SEMANTICS_AND_TOOL_ARCHITECTURE_PL.md:
Tool (SPI)
AdachSoft\PhpstanTool\Tool\PhpStanTool- Implements
AdachSoft\AiToolCall\SPI\ToolInterface. - Validates input parameters (
KeyValueMap), applies configuration defaults, delegates work to the runner, and maps the result toToolCallResultDto.
Factory (SPI)
AdachSoft\PhpstanTool\Tool\PhpStanToolFactory- Implements
AdachSoft\AiToolCall\SPI\Factory\ToolFactoryInterface. - Reads configuration from
ConfigMap(snake_case keys), applies sensible defaults and assembles dependencies:PhpStanToolConfig→PhpStanRunner→PhpStanTool.
Runner (service layer)
AdachSoft\PhpstanTool\Runner\PhpStanRunnerInterfaceAdachSoft\PhpstanTool\Runner\PhpStanRunner- Responsible for:
- resolving user paths against
base_pathusingSafePathHelper::normalize(), - building the
phpstan analysecommand, - executing the command via
CommandExecutorInterface::executeWithResult()withcwd = base_path, - mapping low-level failures to
PhpStanExecutionException.
- resolving user paths against
Output processing
AdachSoft\PhpstanTool\Runner\OutputProcessor- Post-processes raw
stdout/stderrfrom PHPStan:- trims output to a fixed maximum size (10 000 characters total),
- limits the number of reported errors (configured
max_errors), - optionally filters errors by a simple substring (
error_type), - sanitizes absolute occurrences of
base_pathfrom output for portability.
Configuration value object
AdachSoft\PhpstanTool\Config\PhpStanToolConfig- Immutable object storing resolved configuration for a single tool instance.
Factory configuration (ConfigMap)
PhpStanToolFactory reads configuration from AdachSoft\AiToolCall\SPI\Collection\ConfigMap.
All keys are in snake_case and validated by ConfigMap:
base_path(string, optional)- Absolute path that acts as the root for resolving user paths.
- Also used as the working directory (
cwd) for command execution. - Default:
getcwd() ?: '.'.
phpstan_path(string, optional)- Path to the PHPStan executable, relative to
base_pathor absolute. - Default:
vendor/bin/phpstan.
- Path to the PHPStan executable, relative to
default_timeout(int|null, optional)- Default timeout (seconds) for PHPStan execution when no per-call override is provided.
nullmeans "no explicit timeout".
max_errors(int, optional)- Default maximum number of errors to include in the processed output.
0means "no limit" (only trimming by total output size applies).- Default:
30.
Invalid types or empty strings for required config values cause ToolConfigurationException.
Tool contract: phpstan
Tool name
phpstan
Parameters (per call)
All parameters are provided as entries in KeyValueMap (snake_case keys) and validated by
PhpStanTool. When validation fails, InvalidToolCallException is thrown.
path(string, required)- Path to file or directory to analyse.
- If relative, it is resolved against
base_pathusingSafePathHelper::normalize().
error_type(string|null, optional)- Simple substring filter applied to error sections.
- When set, only errors whose text contains this substring are kept.
timeout(int|null, optional)- Per-call timeout in seconds.
null→ falls back todefault_timeoutfrom configuration.
Result shape
The tool always returns a ToolCallResultDto with a KeyValueMap result containing exactly
these keys:
stdout(string)stderr(string)exit_code(int)success(bool)
The stdout/stderr values may be trimmed and/or filtered by OutputProcessor according to the
rules described above, but the structural shape of the result is stable.
If the runner fails (invalid path, execution error, timeout, etc.), PhpStanExecutionException is
thrown in the runner layer and mapped to SpiToolExecutionException in the SPI tool layer.
base_path semantics
base_path follows the common semantics for AI tools built with adachsoft/ai-tool-call:
- All relative user paths are resolved against
base_pathusingSafePathHelper::normalize(). - All CLI processes are executed with
cwd = base_path. - Where appropriate, absolute occurrences of
base_pathinstdout/stderrare removed to keep outputs portable and avoid leaking environment details. - Unsafe paths (e.g. attempts to traverse outside
base_path) result in a domain exception rather than direct command execution.
For full details, see .docs/AI_TOOL_CALL_BASE_PATH_SEMANTICS_AND_TOOL_ARCHITECTURE_PL.md.
Example usage (pseudo-code)
Below is a high-level example of how this tool can be wired with adachsoft/ai-tool-call. Exact
wiring depends on your application and how you register tool factories.
use AdachSoft\AiToolCall\SPI\Collection\ConfigMap;
use AdachSoft\AiToolCall\SPI\Collection\KeyValueMap;
use AdachSoft\AiToolCall\SPI\Dto\ToolCallRequestDto;
use AdachSoft\PhpstanTool\Tool\PhpStanToolFactory;
// 1) Configure the tool instance via ConfigMap
$configMap = new ConfigMap([
'base_path' => '/app/project',
'phpstan_path' => 'vendor/bin/phpstan',
'default_timeout' => 60,
'max_errors' => 30,
]);
$factory = new PhpStanToolFactory();
$tool = $factory->create($configMap);
// 2) Build a per-call request
$request = new ToolCallRequestDto(
toolName: 'phpstan',
parameters: new KeyValueMap([
'path' => 'src', // resolved as /app/project/src
]),
);
// 3) Execute tool
$result = $tool->callTool($request);
// 4) Consume structured result
$stdout = $result->result->get('stdout');
$stderr = $result->result->get('stderr');
$exitCode = $result->result->get('exit_code');
$success = $result->result->get('success');
In a real application, the PhpStanToolFactory is typically registered in your AI tool registry
so that agents can discover and invoke phpstan dynamically.
License
This package is open-sourced software licensed under the MIT license.