ContractSearchHandler
`contract:search` — finds class, interface, and enum NAMES across the app's plugins and its installed vendor code, so an installed capability exists for the agent BEFORE it guesses an API. The debt this pays (measured on a live cattle run): installed packages existed for execution but not epistemologically — `artifact:contract` reached only the app's own plugins, so the agent deduced vendor APIs, planned probes, and weighed static-analysis errors as an introspection API. Search answers the question that comes before the contract: what is the right name to ask for. Candidates come from the app's plugin trees, from `vendor/composer/autoload_psr4.php` (prefixes mapped to directories, PHP files enumerated), and from `autoload_classmap.php` when present — an optimized classmap is never required. Matching is on file and declaration names, and kinds come from the token scanner: no candidate file is ever required or executed by searching it.
ContractSearchHandler::__construct()
public function __construct(Milpa\DevTools\Support\RootResolver $roots = new RootResolver()):Parameters
| Name | Type | Description |
|---|---|---|
| $roots | Milpa\DevTools\Support\RootResolver |
ContractSearchHandler::handle()
public function handle(array $input): arraySearches declared type names and returns up to 25 matches, each with its FQCN, kind, and provenance (`app`, or `vendor` plus the owning package). No match is `ok:false` with a reason, never an exception.
Parameters
| Name | Type | Description |
|---|---|---|
| $input | array<string, mixed> |