adachsoft / rector-tool
AI tool wrapper for running Rector (analyze/fix) via adachsoft/rector-wrapper-lib.
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Forks: 0
pkg:composer/adachsoft/rector-tool
Requires
- adachsoft/ai-tool-call: ^2.0.1
- adachsoft/collection: ^3.0
- adachsoft/command-executor-lib: ^2.0
- adachsoft/rector-wrapper-lib: ^0.2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.89
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.4
- rector/rector: 2.3.3
README
Thin SPI adapter tool for running Rector through
adachsoft/rector-wrapper-lib
inside the adachsoft/ai-tool-call ecosystem.
The package exposes a single SPI tool:
- Tool name:
rector_analyze - Purpose: analyze or fix PHP code using Rector (dry-run or apply diffs)
It is designed to be a thin, testable adapter:
- configuration is provided via
ConfigMapin the SPI factory, - execution is delegated to
RectorRunner, which usesrector-wrapper-lib.
Requirements
- PHP ^8.3
adachsoft/ai-tool-call^2.0.1adachsoft/rector-wrapper-lib^0.2.0adachsoft/collection^3.0.0adachsoft/command-executor-lib^2.0
These constraints are enforced transitively via Composer when you require this package.
Installation
composer require adachsoft/rector-tool
This will pull all required dependencies, including ai-tool-call and rector-wrapper-lib.
For development, you may also want to install Rector directly:
composer require --dev rector/rector
SPI Integration Overview
adachsoft/ai-tool-call 2.x uses a factory-based SPI model:
- You implement tools via
AdachSoft\AiToolCall\SPI\ToolInterface. - You register them via
AdachSoft\AiToolCall\SPI\Factory\ToolFactoryInterface. - Configuration is provided as
AdachSoft\AiToolCall\SPI\Collection\ConfigMap.
This library provides:
AdachSoft\RectorTool\RectorTool– the SPI tool implementation.AdachSoft\RectorTool\RectorToolFactory– the SPI factory that wires:RectorToolConfig(base path, error limits, rector config path),RectorRunner(delegates torector-wrapper-lib),- Rector facade created by
RectorWrapperFactory::createDefault().
You typically never instantiate RectorTool directly – the AI Tool Call builder
uses the factory and a ConfigMap to create a fully configured tool.
Registering the Tool in AiToolCallFacadeBuilder
use AdachSoft\AiToolCall\PublicApi\Builder\AiToolCallFacadeBuilder;
use AdachSoft\AiToolCall\PublicApi\Dto\ToolCallRequestDto;
use AdachSoft\AiToolCall\SPI\Collection\ConfigMap;
use AdachSoft\RectorTool\RectorToolFactory;
$rectorFactory = new RectorToolFactory();
$rectorConfig = new ConfigMap([
// Required: base path of the project where Rector should operate
'base_path' => __DIR__,
// Optional: maximum number of errors to collect before stopping
'max_errors' => 50,
// Optional: explicit path to rector.php (relative or absolute)
'default_rector_config_path' => __DIR__ . '/rector.php',
]);
$facade = AiToolCallFacadeBuilder::new()
->withSpiFactories([$rectorFactory])
->withToolConfigs([
// Tool name must match RectorTool::getDefinition()->name
'rector_analyze' => $rectorConfig,
])
->build();
// Example: dry-run analysis
$result = $facade->callTool(new ToolCallRequestDto(
toolName: 'rector_analyze',
parameters: [
'path' => 'src', // relative to base_path
'fix' => false, // dry-run (check only)
],
));
// Example: apply fixes
$fixResult = $facade->callTool(new ToolCallRequestDto(
toolName: 'rector_analyze',
parameters: [
'path' => 'src',
'fix' => true, // execute Rector in fix mode
],
));
ConfigMap key rules
ConfigMap in ai-tool-call 2.x strictly validates keys:
- non-empty string,
- at most 32 characters,
- lowercase
a-z, digits0-9, underscore_, - optional dot-separated segments (e.g.
http_client.timeout).
This library uses the following keys (all valid under these rules):
base_path– required,max_errors– optional,default_rector_config_path– optional.
Tool Definition
RectorTool::getDefinition() returns:
- name:
rector_analyze - description:
Analyzes or fixes PHP code using Rector. Use this tool to upgrade code, fix architectural issues, or improve code quality.
parametersSchema (JSON Schema-like array):
{ "type": "object", "properties": { "path": { "type": "string", "description": "Relative path to the file or directory to analyze (e.g., 'src/Service')." }, "fix": { "type": "boolean", "description": "Whether to apply fixes automatically. Defaults to false (dry-run)." } }, "required": ["path"] }
Parameters
path(string, required)- Relative path (file or directory) inside
base_path. - Examples:
src,src/Service,app/Controller/UserController.php.
- Relative path (file or directory) inside
fix(bool, optional, default:false)false– Rector runs in check / dry-run mode (no files are modified).true– Rector runs in fix mode and writes changes to disk.
Path traversal is blocked:
- any
..segment inpathcauses anInvalidArgumentExceptioninsideRectorRunner. - paths resolved outside of
base_pathare rejected.
Tool Result Structure
RectorTool::callTool() returns a ToolCallResultDto with result
wrapped in a KeyValueMap built from a PHP array with the following shape:
[
'status' => 'OK' | 'LIMIT_EXCEEDED' | 'RUNTIME_ERROR',
'meta' => [
'duration_ms' => int, // total runtime in milliseconds
'total_files' => int, // total files inspected by Rector
'changed_files' => int, // files with diffs
],
'errors' => [
// list of runtime error strings reported by Rector
'Some runtime error message',
'Another error message'
],
'diffs' => [
[
'file' => 'path/to/file.php',
'diff' => "--- Original\n+++ New\n...", // unified diff
'applied_rectors' => [
'Rector\\Rule\\SomeRule',
'Rector\\Rule\\OtherRule'
],
],
// more file diffs...
],
];
You can access this structure from the ToolCallResultDto via:
/** @var ToolCallResultDto $result */
$payload = $result->result->all();
$status = $payload['status'];
$meta = $payload['meta'];
$errors = $payload['errors'];
$diffs = $payload['diffs'];
Error Handling
The tool uses the standard SPI exception model from ai-tool-call:
InvalidToolCallException- thrown when required parameters are missing or invalid (e.g. missing/empty
path).
- thrown when required parameters are missing or invalid (e.g. missing/empty
ToolExecutionException- thrown when Rector execution fails, wraps the original exception from
rector-wrapper-lib. - message is prefixed with:
"Rector execution failed: ...".
- thrown when Rector execution fails, wraps the original exception from
From the Public API side (AiToolCallFacade), these are further mapped to
PublicApi\Exception\ToolCallFailedException.
Safety & Limitations
- Paths are always resolved relative to
base_pathand validated so they cannot escape the project directory (no.., no absolute paths outside base). max_errorsfromRectorToolConfigis passed torector-wrapper-libasLimitsDto::maxErrorsto prevent flooding the AI context with excessive errors.- Actual Rector rules, sets and configuration are defined in your
rector.phpand are not controlled by this library.
Versioning
This library follows Semantic Versioning. The effective behavior is also constrained by the versions of:
adachsoft/ai-tool-call(factory-based SPI,ConfigMapkey validation),adachsoft/rector-wrapper-lib(DTO shapes, status enums, limits),adachsoft/collection(immutable map/list semantics).
Always consult their respective CHANGELOGs when upgrading major versions.
Development
For development, install Rector as a dev dependency:
composer require --dev rector/rector
This allows you to run Rector on the project codebase itself.