field-inventory.md's apm-agent-allowlist and validate.sh's runtime check already included source_keys as a 4th allowed field, and the apm-agent.md template already instructed authors to add it for provenance tracking — but SKILL.md (x2), README.md, ADR-0016, and deployment-modes.md still described the allowlist as name/description/ model, "nothing else". The template itself even contradicted its own source_keys guidance with a header claiming "ONLY the three fields below — full stop" directly above it. Updates all six locations to document source_keys as the intentional 4th field, resolving the contradiction.
264 lines
18 KiB
Markdown
264 lines
18 KiB
Markdown
---
|
|
name: agent-author
|
|
description: >
|
|
Use when the user wants to create a new agent definition file from scratch
|
|
("write an agent for X", "build a subagent that does Y", "create an agent
|
|
definition for Z"), or improve an existing one. Handles agent definitions at
|
|
plugin/APM, project, and user scope. Project and user scope always generate
|
|
a Claude Code (`.md`) + Copilot CLI (`.agent.md`) file pair in one pass;
|
|
plugin/APM scope generates a single vendor-neutral `.apm/agents/<name>.agent.md`
|
|
file instead (no per-target Claude Code / Copilot split). Also use when the
|
|
user provides inline feedback about an agent's behavior and wants it applied,
|
|
or when a grill session has produced findings the user wants acted on — even
|
|
if they don't say "improve" explicitly. Do not use for read-only review —
|
|
examine agent files manually or run a grill session to generate improvement
|
|
signals. Do not use to author skills — use /skill-author instead.
|
|
allowed-tools: Bash Read Write Edit
|
|
metadata:
|
|
category: factory
|
|
source_keys:
|
|
- context7-websites-code-claude
|
|
- claude-code-plugins-docs
|
|
- claude-code-subagents-docs
|
|
- context7-github-en-copilot
|
|
- github-custom-agents-configuration
|
|
- github-cli-plugin-reference
|
|
- github-plugins-creating
|
|
---
|
|
|
|
## Gotchas
|
|
|
|
- At plugin/APM scope, bump the resolved package's `apm.yml` `version` after every change — minor for a new agent, patch for a fix. Consumers compare this version to detect updates; skipping it hides the change.
|
|
- At plugin/APM scope, `tools` and all Claude-only fields (`isolation`, `maxTurns`, `effort`, `memory`, `permissionMode`, `disallowedTools`, `skills`, `color`, `initialPrompt`, `background`, `hooks`, `mcpServers`) are omitted entirely, not merely restricted (ADR-0016: `apm compile` copies frontmatter verbatim to both harnesses with no per-target integrator, so a harness-specific value is wrong on at least one). Only project/user scope supports these fields.
|
|
- An `apm.yml` with no top-level `type:` field is a marketplace-only manifest, not a package root — the walk-up skips it and keeps going.
|
|
- `AskUserQuestion`, `EnterPlanMode`, `ExitPlanMode`, `ScheduleWakeup`, and `WaitForMcpServers` are never available to any subagent regardless of the `tools` field. Exception: `ExitPlanMode` is available when the parent session runs in `permissionMode: plan`.
|
|
- Duplicate `name` values in the same scope: Claude Code silently discards one without warning. Always verify uniqueness before shipping.
|
|
- Plugin agents in subdirectories get scoped identifiers (`plugin:folder:name`) — keep agents flat in `agents/` to avoid this. Applies to project/user-scope Claude Code agents only.
|
|
- Copilot CLI agent files **must** use the `.agent.md` extension — a plain `.md` file isn't picked up. The plugin/APM-scope single file also ends in `.agent.md` by convention, but it's vendor-neutral, not Copilot-only — it compiles to Claude Code too.
|
|
- Copilot has no `permissionMode`, `maxTurns`, `isolation`, or `memory` fields — do not include them in project/user-scope Copilot files.
|
|
- `model` resolution order for Claude Code: `CLAUDE_CODE_SUBAGENT_MODEL` env var → per-invocation parameter → frontmatter `model` → main session model. The frontmatter value is a low-priority default, not a guarantee.
|
|
|
|
## Route
|
|
|
|
If the destination resolves to plugin/APM scope (scope detection in Step 1 finds a `type:`-bearing `apm.yml` at or above the root), read `references/deployment-modes.md`.
|
|
|
|
Determine which flow before touching the filesystem:
|
|
|
|
- **Neither `<name>.md` nor `<name>.agent.md` exist at the target paths** → follow **Creating a new agent**
|
|
- **At least one file exists + improvement signals present** → follow **Improving an existing agent**
|
|
- **At least one file exists + no signals** → ask: "No improvement signals found. Did you mean to create a new agent, or do you have feedback to apply?"
|
|
|
|
Signals: grill session output, inline user feedback, session context describing what went wrong.
|
|
|
|
## Creating a new agent
|
|
|
|
### Prerequisites
|
|
|
|
Before touching the filesystem, confirm you have:
|
|
- [ ] Agent name (kebab-case, e.g. `code-reviewer`)
|
|
- [ ] Root directory (a path inside a package for plugin/APM scope, project root, or `~` for user scope)
|
|
- [ ] Agent purpose — one sentence describing the task this agent handles
|
|
- [ ] Trigger condition — when should the runtime delegate to this agent?
|
|
|
|
If any are missing, stop and ask before proceeding. Then capture `git log --oneline -1` before touching the filesystem — Step 5 needs it to verify a real commit landed.
|
|
|
|
Verify `kyberforge:agent-audit` is available — it ships with the kyberforge plugin and is co-installed with this skill. If unavailable, stop and tell the user to install the kyberforge plugin before continuing.
|
|
|
|
### Step 1 — Scaffold
|
|
|
|
Run the scaffold script with the agent name and root directory:
|
|
|
|
```bash
|
|
bash scripts/new-agent.sh <name> <root>
|
|
```
|
|
|
|
Examples:
|
|
```bash
|
|
bash scripts/new-agent.sh code-reviewer packages/my-package/ # plugin/APM scope if packages/my-package/apm.yml has a type: field
|
|
bash scripts/new-agent.sh deploy-assistant .
|
|
bash scripts/new-agent.sh security-reviewer ~
|
|
```
|
|
|
|
**Scope detection (script handles this automatically).** The script walks up from `<root>` for a package boundary — same shape `agent-audit`'s `validate.sh` uses:
|
|
- Nearest ancestor `apm.yml` with a top-level `type:` field (`instructions`/`skill`/`hybrid`/`prompts`) → **plugin/APM scope** → `<package-root>/.apm/agents/<name>.agent.md` (single vendor-neutral file). A `type:`-less `apm.yml` is marketplace-only — skipped, walk continues upward.
|
|
- No such `apm.yml`, `<root>` is a project directory → **project scope** (unchanged) → `<root>/.claude/agents/<name>.md` + `<root>/.github/agents/<name>.agent.md`
|
|
- `<root>` is exactly `~` (checked directly, no walk-up) → **user scope** (unchanged) → `~/.claude/agents/<name>.md` + `~/.copilot/agents/<name>.agent.md`
|
|
|
|
A bare `plugin.json` with no `apm.yml` no longer signals plugin scope — that path is fully replaced, not dual-mode; it falls through to project scope.
|
|
|
|
The script is file-by-file no-op — it skips any file that already exists.
|
|
|
|
### Step 2 — Fill in the agent file(s)
|
|
|
|
**At plugin/APM scope**, there is exactly one file: `<package-root>/.apm/agents/<name>.agent.md`. Frontmatter carries ONLY `name`, `description`, optionally `model`, and optionally `source_keys` (provenance metadata, not a runtime field — see the template) — never `tools` or the other Claude-only fields listed in Gotchas (ADR-0016). Fill in `name`, `description`, `model`, and the system prompt body per the guidance below; the rest of this step's field-by-field guidance (tools, maxTurns, effort, memory, isolation, disallowedTools, skills, color, initialPrompt, background) is project/user scope only. Skip Step 3 and go to Step 4.
|
|
|
|
**At project/user scope**, continue below to fill in both provider files — this step covers the Claude Code file (`<name>.md`); Step 3 covers the Copilot file.
|
|
|
|
Open the scaffolded Claude Code file. Replace every `FILL IN:` placeholder. **Remove all template documentation comments from the YAML frontmatter after filling in required fields** — these are marked with `<!--` and `-->` and must be deleted before shipping.
|
|
|
|
**`name`** — lowercase letters and hyphens only. Must be unique within the scope.
|
|
|
|
**`description`** — the most important field for autonomous delegation:
|
|
- Start with an action verb: "Reviews...", "Analyzes...", "Generates..."
|
|
- If this agent should trigger without explicit user direction, include "Use proactively" in the description
|
|
- Specific about the triggering condition and expertise domain
|
|
- Under 300 characters preferred
|
|
|
|
**`tools`** (project/user scope only — never at plugin/APM scope) — restrict to what the agent actually needs. Omit to inherit all tools. Use `Agent(type1,type2)` to limit which subagent types this agent can spawn; omit `Agent` entirely to prevent spawning.
|
|
|
|
**Optional fields worth considering (project/user scope only — never at plugin/APM scope):**
|
|
- `model`: set when this agent needs a different capability tier (`haiku` for fast tasks, `opus` for deep reasoning)
|
|
- `maxTurns`: set a cap to prevent runaway agents on bounded tasks
|
|
- `effort`: set to `low` for single-lookup tasks, `high` or above for deep reasoning or multi-file analysis — overrides session effort level; omit to inherit
|
|
- `memory`: `user`, `project`, or `local` — only when cross-session state is genuinely needed
|
|
- `isolation: worktree` — only when the agent modifies files and needs an isolated copy
|
|
- `disallowedTools`: space-separated denylist applied before `tools`; supports `mcp__*` glob patterns (e.g. `disallowedTools: mcp__filesystem__*`)
|
|
- `skills`: list of skill names preloaded at agent startup — different from the `source_keys` metadata field
|
|
- `color`: UI color for the agent tile (`red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, `cyan`)
|
|
- `initialPrompt`: auto-submitted as the first turn when this agent activates as the main session thread; only set when this agent is intended for main-thread activation
|
|
- `background`: set `true` to force background execution
|
|
|
|
**`source_keys`** — top-level list of research source slugs that informed this agent. Add only when research sources were used (i.e. entries with `` `extracted` `` status are in context from a prior `/research` session). Each slug must match an H2 heading in `sources.md` — see Step 4 for where that file lives (plugin/APM scope only). Omit entirely when no research was used.
|
|
|
|
```yaml
|
|
source_keys:
|
|
- my-source-slug
|
|
```
|
|
|
|
**System prompt body** — write as a direct role instruction:
|
|
- Open with: "You are a [role]. When invoked, [primary action]."
|
|
- Cover: inputs expected, process steps, output format, error handling
|
|
- One job per agent
|
|
|
|
### Step 3 — Fill in the Copilot agent file (project/user scope only)
|
|
|
|
Skip this step entirely at plugin/APM scope — there is no separate Copilot file there. The single `.apm/agents/<name>.agent.md` file from Step 2 already compiles to both Claude Code and Copilot CLI via `apm compile`.
|
|
|
|
**Two distinct Copilot agent formats** exist, with different paths and field sets. Choose one based on the deployment target:
|
|
|
|
**CLI format** (default — what the scaffold creates):
|
|
- Path: `.github/agents/<name>.agent.md` (project) or `~/.copilot/agents/<name>.agent.md` (user)
|
|
- Extension: **must be `.agent.md`**
|
|
- Supported fields: `name` (required), `description` (required), `tools` (optional)
|
|
- `tools` uses Copilot aliases: `execute` (shell), `read`, `edit`, `search`, `agent`, `web`
|
|
- Body length limit: **30,000 characters** — content beyond this is silently truncated
|
|
|
|
**Cloud/IDE format** (use when targeting Copilot Chat in VS Code or GitHub.com):
|
|
- Path: `.github/copilot/agents/<name>.md` (note: plain `.md`, different directory)
|
|
- Additional fields available: `target` (`vscode`, `github-copilot`, or omit for both), `user-invocable` (set `false` to hide from manual invocation), `disable-model-invocation` (set `true` to require explicit user invocation), `mcp-servers` (MCP server config — processed by cloud runtime, ignored in VS Code)
|
|
- Body length limit: **30,000 characters** — silently truncated
|
|
|
|
**Do not include Claude Code-only fields in either format**: `maxTurns`, `isolation`, `memory`, `permissionMode`, `effort`, `hooks`, `mcpServers`.
|
|
|
|
**`source_keys`** — add the same top-level list as the CC file when research sources were used. Omit when no research was used.
|
|
|
|
**Remove all template documentation comments from the YAML frontmatter after filling in required fields** — these are marked with `<!--` and `-->` and must be deleted before shipping.
|
|
|
|
The system prompt body should match the Claude Code version — the agent's task definition is the same across providers.
|
|
|
|
### Step 4 — Populate or delete `sources.md` (plugin/APM scope only)
|
|
|
|
Skip at project/user scope. The file lives at the package root (alongside `apm.yml`), not inside `.apm/agents/` — otherwise tooling that scans that directory for agent definitions would treat it as an agent needing frontmatter (ADR-0010).
|
|
|
|
If a research `sources.md` is present in the conversation context:
|
|
1. Filter to entries with `` `extracted` `` status only.
|
|
2. For each entry, identify which agent file it contributed to.
|
|
3. Write `sources.md` at the package root using the format below. Paths in `Contributing files:` are relative to the package root.
|
|
|
|
```markdown
|
|
# Sources
|
|
|
|
## slug-name
|
|
|
|
- **URL:** <source URL>
|
|
- **Research doc:** <path/to/research/sources.md relative to repo root>
|
|
- **Description:** <what this source covers>
|
|
- **Contributing files:** .apm/agents/<name>.agent.md
|
|
- **Status:** `extracted`
|
|
```
|
|
|
|
Each slug must match an H2 heading, and each slug must also appear in the `source_keys` list of the file listed under `Contributing files:`.
|
|
|
|
If no research sources are in context, delete `sources.md`.
|
|
|
|
### Step 5 — Validate and close
|
|
|
|
Run this checklist before invoking the audit:
|
|
|
|
**Plugin/APM scope — single file (`<name>.agent.md`):**
|
|
- [ ] `name` field present, kebab-case, unique in scope
|
|
- [ ] `description` field present and action-first
|
|
- [ ] Frontmatter contains ONLY `name`, `description`, and optionally `model` (plus `source_keys` if research-sourced) — no `tools`, `isolation`, `maxTurns`, `effort`, `memory`, `permissionMode`, `disallowedTools`, `skills`, `color`, `initialPrompt`, `background`, `hooks`, or `mcpServers`
|
|
- [ ] System prompt body present and non-empty
|
|
- [ ] No `FILL IN:` placeholders remain
|
|
- [ ] No `<!-- -->` template comments remain in frontmatter
|
|
|
|
**Project/user scope — Claude Code file (`<name>.md`):**
|
|
- [ ] `name` field present, kebab-case, unique in scope
|
|
- [ ] `description` field present and action-first
|
|
- [ ] System prompt body present and non-empty
|
|
- [ ] No `FILL IN:` placeholders remain
|
|
- [ ] No `<!-- -->` template comments remain in frontmatter
|
|
|
|
**Project/user scope — Copilot CLI file (`<name>.agent.md`):**
|
|
- [ ] File extension is `.agent.md` (not `.md`)
|
|
- [ ] `name` field matches the filename stem (e.g. `name: my-agent` in `my-agent.agent.md`)
|
|
- [ ] `description` field present
|
|
- [ ] No Claude Code-only fields (`maxTurns`, `isolation`, `memory`, `permissionMode`, `effort`, `hooks`, `mcpServers`)
|
|
- [ ] System prompt body present and non-empty
|
|
- [ ] Body does not exceed 30,000 characters
|
|
- [ ] No `<!-- -->` template comments remain in frontmatter
|
|
|
|
At plugin/APM scope, apply a **minor bump** to the resolved package's `apm.yml` `version` (single manifest, e.g. `1.0.4` → `1.1.0`).
|
|
|
|
Invoke `kyberforge:agent-audit` on the created file(s) before closing — validates the pair at project/user scope, the single file at plugin/APM scope.
|
|
|
|
**Commit verification.** Capture `git log --oneline -1` before Step 1 and keep it. Once the audit is clean, run `git add` and `git commit` for the new agent files — do not stop at staging. Then run `git log --oneline -1` again and confirm the hash changed from the one you captured at the start. A non-empty `git diff --stat` is not sufficient proof of completion: staged-but-uncommitted work isn't part of any commit and can be silently lost if the working tree is cleaned up before a commit lands. Only report the agent as done once the hash has actually changed.
|
|
|
|
## Improving an existing agent
|
|
|
|
### Step 1 — Verify inputs
|
|
|
|
Confirm the agent files exist and at least one improvement signal is present in the conversation or a referenced file.
|
|
|
|
If no signals: "This skill applies existing signals to an agent. For a blind review, examine the files manually or run a grill session first."
|
|
|
|
Verify `kyberforge:agent-audit` is available — it ships with the kyberforge plugin and is co-installed with this skill. If unavailable, stop and tell the user to install the kyberforge plugin before continuing.
|
|
|
|
Capture `git log --oneline -1` now, before making any edits — Step 5 needs it to verify a real commit landed.
|
|
|
|
**Partial state (project/user scope only)** — if one provider file exists but not the other, scaffold the missing one (`bash scripts/new-agent.sh <name> <root>`, file-by-file no-op) then continue. Doesn't apply at plugin/APM scope — single file, no partial-pair state.
|
|
|
|
### Step 2 — Gather and group signals
|
|
|
|
Read the current agent file(s). Collect all signals from the conversation.
|
|
|
|
Group by **root cause**, not symptom. One root cause → one fix.
|
|
|
|
```text
|
|
Example:
|
|
- User feedback: agent keeps trying to push to remote
|
|
- Session context: no scope boundary in system prompt
|
|
→ Root cause: system prompt lacks git scope constraint → fix: add explicit boundary
|
|
```
|
|
|
|
### Step 3 — Announce planned changes
|
|
|
|
Before editing, state which root causes were identified, what evidence supports each, and which files will change. Then proceed — edits are reversible via git.
|
|
|
|
### Step 4 — Apply changes
|
|
|
|
Edit any file the signals point to. Generalize the fix — find the underlying gap, not the specific example that failed. For every sentence you add, ask: "Would the agent get this wrong without it?" A shorter, focused definition consistently outperforms an exhaustive one. For Copilot files, verify no Claude Code-only fields are introduced. For a plugin/APM-scope single file, verify no field beyond `name`, `description`, `model`, and `source_keys` is introduced.
|
|
|
|
If the edit adds or removes research-sourced content, update `source_keys` in the edited file(s) and the corresponding entry in `sources.md` per Create flow's Step 4.
|
|
|
|
### Step 5 — Validate and close
|
|
|
|
Re-run the validation checklist from the create flow's Step 5 on any edited file.
|
|
|
|
At plugin/APM scope, apply a **patch bump** to the resolved package's `apm.yml` `version` (e.g. `1.0.4` → `1.0.5`).
|
|
|
|
Invoke `kyberforge:agent-audit` on the edited file(s) to confirm no regressions — the pair at project/user scope, the single file at plugin/APM scope.
|
|
|
|
**Commit verification.** Capture `git log --oneline -1` at the start of Step 1 and keep it. Once the audit is clean, run `git add` and `git commit` for the changed files — do not stop at staging. Then run `git log --oneline -1` again and confirm the hash changed from the one you captured at the start. A non-empty `git diff --stat` is not sufficient proof of completion: staged-but-uncommitted work isn't part of any commit and can be silently lost if the working tree is cleaned up before a commit lands. Only report the improvement as done once the hash has actually changed.
|