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

0.2.1 2026-01-27 08:21 UTC

This package is not auto-updated.

Last update: 2026-01-27 07:22:28 UTC


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 ConfigMap in the SPI factory,
  • execution is delegated to RectorRunner, which uses rector-wrapper-lib.

Requirements

  • PHP ^8.3
  • adachsoft/ai-tool-call ^2.0.1
  • adachsoft/rector-wrapper-lib ^0.2.0
  • adachsoft/collection ^3.0.0
  • adachsoft/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 to rector-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, digits 0-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.
  • 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 in path causes an InvalidArgumentException inside RectorRunner.
  • paths resolved outside of base_path are 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).
  • ToolExecutionException
    • thrown when Rector execution fails, wraps the original exception from rector-wrapper-lib.
    • message is prefixed with: "Rector execution failed: ...".

From the Public API side (AiToolCallFacade), these are further mapped to PublicApi\Exception\ToolCallFailedException.

Safety & Limitations

  • Paths are always resolved relative to base_path and validated so they cannot escape the project directory (no .., no absolute paths outside base).
  • max_errors from RectorToolConfig is passed to rector-wrapper-lib as LimitsDto::maxErrors to prevent flooding the AI context with excessive errors.
  • Actual Rector rules, sets and configuration are defined in your rector.php and 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, ConfigMap key 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.