Create a skill for generating Tool plugins (best practices, how-to, placement)
### Problem/Motivation
The Tool API lets modules expose well-defined, typed actions as `#[Tool]` plugins, and the `tool_ai_connector` submodule automatically surfaces those same tools to AI agents as `AiFunctionCall`s. Authoring a *correct* tool, though, means getting several moving parts right at once:
- the `#[Tool]` attribute — `id`, `label`, `description`, the `ToolOperation` enum (`Explain` / `Read` / `Transform` / `Trigger` / `Write`) and the `destructive` flag;
- typed `input_definitions` / `output_definitions` (`InputDefinition`, the list/map variants, `constraints`, `default_value`, `required`);
- extending `ToolBase` (or `ConditionToolBase`) and implementing `doExecute(): ExecutableResult` plus `checkAccess()`;
- the plugin location/namespace (`src/Plugin/tool/Tool/` → `Drupal\<module>\Plugin\tool\Tool\<Name>`), the plugin-ID gotcha (the id must equal the group or be prefixed `group:thing`), and a per-tool permission;
- and, critically, *which submodule a new tool belongs in* (`tool_content`, `tool_entity`, `tool_system`, `tool_user`, `tool_content_translation`, …).
There is no guided path for contributors — or for AI coding agents — to produce a consistent, correct tool, so tools drift in shape and quality.
### Proposed resolution
Create an agent skill (a Claude Code / agent skill, in the same spirit as the existing `create-ai-provider` and `new-document-loader-plugin` skills) that scaffolds a new Tool plugin and encodes the project's conventions. It should cover the three things requested:
**1. What should be a tool (best practices)**
- A tool is a single, atomic, well-defined action with typed inputs and outputs — not a grab-bag of behaviour.
- Choose the correct `ToolOperation` (`Explain` / `Read` / `Transform` / `Trigger` / `Write`) and set `destructive: TRUE` honestly for anything that deletes or irreversibly changes data (it encourages confirmation).
- Prefer typed inputs with `constraints` and sensible `default_value`s over free-form strings; mark inputs `required` correctly and declare `output_definitions` so callers (and LLMs) receive structured results.
- Always implement `checkAccess()` and ship a matching permission entry.
- Reuse existing tools and TypedData adapters instead of duplicating; don't model as a tool what is really static configuration.
**2. How to create one**
- Generate the plugin class under `src/Plugin/tool/Tool/`, namespace `Drupal\<module>\Plugin\tool\Tool\<Name>`, extending `ToolBase`.
- Emit the `#[Tool]` attribute with id/label/description/operation and the input/output definitions.
- Stub `doExecute(array $values): ExecutableResult` returning `ExecutableResult::success()` / `ExecutableResult::failure()`, plus `checkAccess()`.
- Add the permission to the module's `*.permissions.yml`.
- Point at `LogMessage` (`tool_system`) and the `tool_content` entity tools as reference implementations.
- Remind the author that, with `tool_ai_connector` enabled, the tool is **automatically exposed to AI agents** — so the label/description must read well to an LLM and every input needs a clear description.
**3. Where they belong**
- Route the new tool into the right domain submodule (content → `tool_content`, entity/field structure → `tool_entity`, system → `tool_system`, user → `tool_user`, translation → `tool_content_translation`), or scaffold a new submodule when no domain fits.
- The skill should ask which domain, default to the closest match, and place the files accordingly.
The skill should live in the module repo (e.g. under `.claude/skills/`) so it ships with the project and stays in sync with the API — the way other AI-initiative modules already carry their skills.
### Remaining tasks
- Write the skill (`SKILL.md` plus any scaffolding/templates).
- Capture the best-practices checklist above as the skill's guidance, with a concrete worked example.
- Add a reference/example tool the skill can mirror.
- Optional: a short docs page that links to the skill.
### User interface changes
None — contributor tooling.
### API changes
None.
issue