adachsoft / symfony-console-tool
Requires
Requires (Dev)
- adachsoft/php-code-style: ^0.4.3
- friendsofphp/php-cs-fixer: ^3.89
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^12.4
- rector/rector: ^2.3
- symfony/console: ^8.0
README
Library providing an AI SPI tool for running Symfony Console commands (run) and listing available commands (list) in external Symfony projects.
Installation
composer require adachsoft/symfony-console-tool
Usage with adachsoft/ai-tool-call (SPI)
Register SymfonyConsoleToolFactory in the AiToolCallFacadeBuilder and configure the tool using ConfigMap:
use AdachSoft\AiToolCall\PublicApi\Builder\AiToolCallFacadeBuilder;
use AdachSoft\AiToolCall\SPI\Collection\ConfigMap;
use AdachSoft\SymfonyConsoleTool\Tool\SymfonyConsoleToolFactory;
$builder = AiToolCallFacadeBuilder::new()
->withSpiFactories([
new SymfonyConsoleToolFactory(),
])
->withToolConfigs([
'symfony_console' => new ConfigMap([
'base_path' => '/path/to/your/symfony/project',
'console_path' => 'bin/console',
'php_binary' => 'php',
'timeout' => 30.0,
]),
]);
$facade = $builder->build();
Then you can call the symfony_console tool via the public API:
use AdachSoft\AiToolCall\PublicApi\Dto\ToolCallRequestDto;
// List commands
$listResult = $facade->callTool(new ToolCallRequestDto(
toolName: 'symfony_console',
parameters: [
'action' => 'list',
],
));
// Run a specific command
$runResult = $facade->callTool(new ToolCallRequestDto(
toolName: 'symfony_console',
parameters: [
'action' => 'run',
'command' => 'cache:clear --env=prod',
],
));
The result payload is an array with the following keys:
exit_code(int) — command exit codeoutput(string) — STDOUT contents
Compatibility checks
Before executing any action (run, list, or describe), the tool performs a lightweight compatibility check.
By default, it uses an internal checker that verifies if the configured console_path (normalized relative to base_path) exists as a regular file and is readable by the PHP process. Note that this check does not verify if the project is a valid Symfony application or if the file is a genuine Symfony Console entry point; it only confirms file existence and readability.
If the check fails, the tool throws an exception with a message formatted as:
Symfony Console is unavailable for this project: <reason> This project may legitimately not support Symfony Console. Do not retry this tool unless the project configuration changes.
The absence of the "Symfony Console execution failed" prefix in the error message indicates that this is a normal unavailability scenario, not a command execution failure.
Custom compatibility policies
You can implement custom compatibility logic by creating a class that implements SymfonyConsoleCompatibilityCheckerInterface.
Example:
use AdachSoft\SymfonyConsoleTool\Compatibility\SymfonyConsoleCompatibilityCheckerInterface;
use AdachSoft\SymfonyConsoleTool\Dto\SymfonyConsoleCompatibilityResultDto;
class MyCustomChecker implements SymfonyConsoleCompatibilityCheckerInterface
{
public function check(string $resolvedConsolePath): SymfonyConsoleCompatibilityResultDto
{
// Your custom logic here
if (some_condition) {
return new SymfonyConsoleCompatibilityResultDto(true, null);
}
return new SymfonyConsoleCompatibilityResultDto(false, 'Custom reason');
}
}
To use your custom checker, inject it into the SymfonyConsoleToolFactory:
use AdachSoft\SymfonyConsoleTool\Tool\SymfonyConsoleToolFactory;
$factory = new SymfonyConsoleToolFactory(new MyCustomChecker());
$builder = AiToolCallFacadeBuilder::new()
->withSpiFactories([
$factory,
])
// ...
Security
console_path is resolved relative to base_path using adachsoft/normalized-safe-path. Any attempt to escape base_path (path traversal) will result in an error and the tool call will fail.