承接 adachsoft/composer-tool 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

adachsoft/composer-tool

最新稳定版本:v0.3.1

Composer 安装命令:

composer require adachsoft/composer-tool

包简介

AI tool-call adapter for running Composer operations via adachsoft/composer-lib.

README 文档

README

AI tool-call adapter for running Composer operations via adachsoft/composer-lib, implemented as a SPI tool for adachsoft/ai-tool-call.

This library exposes a primary AI tool named composer for Composer CLI operations, and additional tools for direct composer.json inspection and modification.

Requirements

  • PHP ^8.3
  • adachsoft/ai-tool-call
  • adachsoft/composer-lib
  • adachsoft/command-executor-lib
  • adachsoft/normalized-safe-path

Installation

Install via Composer:

composer require adachsoft/composer-tool

Quick Start

Registering the main composer tool in AiToolCall

use AdachSoft\AiToolCall\PublicApi\Builder\AiToolCallFacadeBuilder;
use AdachSoft\AiToolCall\SPI\Collection\ConfigMap;
use AdachSoft\AiToolCall\PublicApi\Dto\ToolCallRequestDto;
use AdachSoft\ComposerTool\Tool\ComposerToolFactory;

$facade = AiToolCallFacadeBuilder::new()
    ->withSpiFactories([
        new ComposerToolFactory(),
    ])
    ->withToolConfigs([
        'composer' => new ConfigMap([
            'working_directory' => __DIR__,
            // optional configuration, see below
            'hard_timeout_seconds' => 60,
            'activity_timeout_seconds' => 30,
            'non_interactive_enforced' => true,
            'output_capture_mode' => 'FULL',      // FULL|STDOUT_ONLY|STDERR_ONLY|DISCARD
            'config_patch_mode' => 'PERMANENT',   // PERMANENT|TEMPORARY|SKIP
            'backup_enabled' => true,
        ]),
    ])
    ->build();

Calling the composer tool

// Example: install with defaults
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'install',
    ],
));

$data = $result->result->all();

// $data contains (minimal, AI-friendly payload):
// - operation   (string)
// - status      (string enum from composer-lib, e.g. SUCCESS|FAILURE)
// - stdout      (string)
// - stderr      (string)

// Example: update specific packages in dry-run mode
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'update',
        'packages' => ['vendor/package-a', 'vendor/package-b'],
        'with_all_dependencies' => true,
        'dry_run' => true,
    ],
));

// Example: require packages with constraints as dev dependencies
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'require',
        'package_constraints' => [
            'vendor/package-a' => '^1.0',
            'vendor/package-b' => '~2.3',
        ],
        'dev' => true,
    ],
));

// Example: show package information with dependency tree
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'show',
        'package' => 'vendor/package',
        'tree' => true,
    ],
));

// Example: list licenses for all installed packages
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'licenses',
    ],
));

// Example: find why a package is installed
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'depends',
        'package' => 'vendor/package',
        'tree' => true,
    ],
));

// Example: check which packages prevent installing a given version
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'prohibits',
        'package' => 'vendor/package',
        'constraint' => '^1.0',
    ],
));

// Example: run a Composer script with additional arguments
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'run_script',
        'script' => 'my-script',
        'args' => ['--flag', 'value'],
    ],
));

// Example: clear Composer cache
$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer',
    parameters: [
        'operation' => 'clear_cache',
    ],
));

Available operations and parameters (composer tool)

The composer tool exposes the following operations (aligned with the adachsoft/composer-lib 0.3.x public API; see AdachSoft\\ComposerTool\\Tool\\ComposerTool::getDefinition() for machine-readable schema):

  • install

    • no_dev (bool, default: false) skip dev dependencies
    • prefer_dist (bool, default: true)
    • optimize_autoloader (bool, default: true)
    • dry_run (bool, default: false)
  • update

    • packages (string[] optional) list of package names to update
    • with_all_dependencies (bool, default: false)
    • no_dev (bool, default: false)
    • dry_run (bool, default: false)
  • require

    • package_constraints (map<string,string>, required) package => constraint
    • dev (bool, default: false) require as dev dependency
    • dry_run (bool, default: false)
  • remove

    • packages (string[] required) list of package names to remove
    • dry_run (bool, default: false)
  • dump_autoload

    • optimize (bool, default: true)
    • classmap_authoritative (bool, default: false)
  • validate

    • no_check_publish (bool, default: true)
  • outdated

    • direct (bool, default: true) only directly required packages
  • diagnose

    • no extra parameters
  • show

    • package (string, optional) package name to show (all if omitted)
    • tree (bool, default: false) show dependency tree
  • licenses

    • no extra parameters
  • depends

    • package (string, required) package name to inspect
    • tree (bool, default: false) show dependency tree
  • prohibits

    • package (string, required) package name
    • constraint (string, optional) version constraint
  • run_script

    • script (string, required) Composer script name from composer.json
    • args (string[] optional, default: []) additional arguments
  • clear_cache

    • no extra parameters

composer.json tools (for AI agents)

In addition to the composer CLI-like tool, this library provides three SPI tools dedicated to working with composer.json in a given working directory. These tools are intended to be called by AI agents, not by humans directly.

Tools overview

  • composer_json_file

    • Generic tool that can read and/or write composer.json depending on the operation parameter:
      • read
      • write
      • read_and_write
  • composer_json_read

    • Convenience wrapper for composer_json_file in read mode.
    • Always returns a read-only view of the current composer.json file.
  • composer_json_write

    • Convenience wrapper for composer_json_file in write mode.
    • Only performs write operations on composer.json.

Each of these tools expects a working_directory configuration passed via its corresponding factory:

  • ComposerJsonReadWriteToolFactory
  • ComposerJsonReadToolFactory
  • ComposerJsonWriteToolFactory

Registering composer.json tools in AiToolCall

use AdachSoft\AiToolCall\PublicApi\Builder\AiToolCallFacadeBuilder;
use AdachSoft\AiToolCall\SPI\Collection\ConfigMap;
use AdachSoft\ComposerTool\Tool\ComposerJsonReadToolFactory;
use AdachSoft\ComposerTool\Tool\ComposerJsonWriteToolFactory;
use AdachSoft\ComposerTool\Tool\ComposerJsonReadWriteToolFactory;

$facade = AiToolCallFacadeBuilder::new()
    ->withSpiFactories([
        new ComposerJsonReadToolFactory(),
        new ComposerJsonWriteToolFactory(),
        new ComposerJsonReadWriteToolFactory(),
    ])
    ->withToolConfigs([
        'composer_json_read' => new ConfigMap([
            'working_directory' => __DIR__,
        ]),
        'composer_json_write' => new ConfigMap([
            'working_directory' => __DIR__,
        ]),
        'composer_json_file' => new ConfigMap([
            'working_directory' => __DIR__,
        ]),
    ])
    ->build();

Parameters for write operations: json vs data

For tools that write composer.json (composer_json_write and composer_json_file in write / read_and_write modes), the desired file content can be provided in two alternative forms:

  • json (string)

    • Full composer.json contents as a raw JSON string.
    • Semantics for the agent: "I already know the exact textual content of the file. Take this JSON string, validate it, and write it."
  • data (object / map)

    • Structured representation of composer.json as a JSON object (associative array in PHP).
    • Semantics for the agent: "I have the semantic structure of the file. Take this object, encode it to JSON using project conventions, and write it."

At least one of json or data is required for write operations. If neither is provided, the call is rejected with an InvalidToolCallException.

The detailed rationale for this dual input model is described in docs/ADR-001-composer-json-write-parameters.md.

Example: read current composer.json

use AdachSoft\AiToolCall\PublicApi\Dto\ToolCallRequestDto;

$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer_json_read',
    parameters: [],
));

$payload = $result->result->all();
// payload contains, among others:
// - operation: "read"
// - path: absolute path to composer.json
// - data: decoded JSON as a map
// - raw: raw JSON string content

Example: overwrite composer.json with a JSON string

$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer_json_write',
    parameters: [
        'json' => "{\n  \"name\": \"vendor/package\"\n}\n",
        'backup' => true,
        'pretty' => true,
    ],
));

Example: update composer.json using structured data

$result = $facade->callTool(new ToolCallRequestDto(
    toolName: 'composer_json_write',
    parameters: [
        'data' => [
            'name' => 'vendor/package',
            'description' => 'Updated by AI agent',
        ],
        'backup' => true,
        'pretty' => true,
    ],
));

Configuration options (factory)

ComposerToolFactory reads configuration from ConfigMap with the following keys:

  • working_directory (string, required, non-empty)
  • hard_timeout_seconds (int, default: 60)
  • activity_timeout_seconds (int, default: 30)
  • non_interactive_enforced (bool, default: true)
  • output_capture_mode (string, default: FULL)
    • allowed values: FULL, STDOUT_ONLY, STDERR_ONLY, DISCARD
  • config_patch_mode (string, default: PERMANENT)
    • allowed values: PERMANENT, TEMPORARY, SKIP
  • backup_enabled (bool, default: true)

Invalid configuration results in ToolConfigurationException being thrown by the SPI layer (ComposerToolFactory).

Error handling

The tool is designed so that AI agents receive clear, structured feedback about what went wrong.

Invalid tool calls (schema / parameters)

The following cases result in AdachSoft\AiToolCall\SPI\Exception\InvalidToolCallException:

  • Missing required parameters, for example calling the tool without the operation field:
    • message: Composer tool call is missing required parameter "operation".
  • Parameters with wrong types, for example passing an integer where a string is expected:
    • message: Composer tool parameter "operation" must be a string, got int.
  • Unsupported operation value:
    • message: Unsupported Composer operation "foo". Allowed operations: install, update, require, remove, dump_autoload, validate, outdated, diagnose, show, licenses, depends, prohibits, run_script, clear_cache.

These messages are intended to be directly consumable by an AI agent and are also propagated to any higher-level wrapper (for example as "Tool call failed: <message>").

Composer-level validation failures

Certain domain-specific failures from adachsoft/composer-lib are reported as regular tool results instead of SPI exceptions:

  • InvalidComposerJsonException
  • NonInteractiveViolationException

In these cases the tool call succeeds from the SPI perspective, but the result payload indicates failure:

{
  "operation": "install",
  "status": "FAILURE",
  "stdout": "",
  "stderr": "Interactive mode is not allowed here."
}

This makes it easy for an AI agent to understand what Composer reported and decide how to proceed (e.g. adjust arguments and retry).

Unexpected runtime failures

Any other unexpected failure during Composer execution (bugs, environment issues, unhandled exceptions thrown by ComposerClientInterface or its collaborators) is wrapped in AdachSoft\AiToolCall\SPI\Exception\ToolExecutionException.

The exception message always includes the Composer operation name and the original error message, for example:

Composer operation "install" failed: <original-message>

Higher-level tooling (such as the AI integration layer) can then format this as a single error string (e.g. "Tool call failed: Composer operation \"install\" failed: ..."), while still retaining the original exception as the previous cause.

Versioning

This package follows Semantic Versioning and is versioned exclusively through Git tags. The composer.json file intentionally does not contain an explicit version field.

License

MIT

统计信息

  • 总下载量: 7
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-10