|
| 1 | +# Extension Behavior & Deployment — RFC Addendum |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Extension commands can declare two new frontmatter sections: |
| 6 | + |
| 7 | +1. **`behavior:`** — agent-neutral intent vocabulary |
| 8 | +2. **`agents:`** — per-agent escape hatch for fields with no neutral equivalent |
| 9 | + |
| 10 | +Deployment target is fully derived from `behavior.execution` — no separate manifest field is needed. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## `behavior:` Vocabulary |
| 15 | + |
| 16 | +```yaml |
| 17 | +behavior: |
| 18 | + execution: command | isolated | agent |
| 19 | + capability: fast | balanced | strong |
| 20 | + effort: low | medium | high | max |
| 21 | + tools: none | read-only | write | full | <custom> |
| 22 | + invocation: explicit | automatic |
| 23 | + visibility: user | model | both |
| 24 | + color: red | blue | green | yellow | purple | orange | pink | cyan |
| 25 | +``` |
| 26 | +
|
| 27 | +### Per-agent translation |
| 28 | +
|
| 29 | +| behavior field | value | Claude | Copilot | Codex | Others | |
| 30 | +|---|---|---|---|---|---| |
| 31 | +| `execution` | `isolated` | `context: fork` | — | — | — | |
| 32 | +| `execution` | `agent` | routing only (see Deployment section) | — | — | — | |
| 33 | +| `capability` | `fast` | `model: claude-haiku-4-5-20251001` | `model: Claude Haiku 4.5` | — | — | |
| 34 | +| `capability` | `balanced` | `model: claude-sonnet-4-6` | `model: Claude Sonnet 4.5` | — | — | |
| 35 | +| `capability` | `strong` | `model: claude-opus-4-6` | `model: Claude Opus 4.5` | — | — | |
| 36 | +| `effort` | any | `effort: {value}` | — | `effort: {value}` | — | |
| 37 | +| `tools` | `read-only` | `allowed-tools: Read Grep Glob` | `tools: [read_file, list_directory, search_files]` | — | — | |
| 38 | +| `tools` | `write` | `allowed-tools: Read Write Edit Grep Glob` | `tools: ["*"]` | — | — | |
| 39 | +| `tools` | `none` | `allowed-tools: ""` | `tools: []` | — | — | |
| 40 | +| `tools` | `full` | — (no restriction, all tools available) | `tools: ["*"]` | — | — | |
| 41 | +| `tools` | `<custom string>` | `allowed-tools: <value>` (literal passthrough) | — | — | — | |
| 42 | +| `tools` | `<yaml list>` | `allowed-tools: <space-joined items>` | — | — | — | |
| 43 | +| `invocation` | `explicit` | `disable-model-invocation: true` | `disable-model-invocation: true` | — | — | |
| 44 | +| `invocation` | `automatic` | `disable-model-invocation: false` | `disable-model-invocation: false` | — | — | |
| 45 | +| `visibility` | `user` | `user-invocable: true` | `user-invocable: true` | — | — | |
| 46 | +| `visibility` | `model` | `user-invocable: false` | `user-invocable: false` | — | — | |
| 47 | +| `visibility` | `both` | — | — | — | — | |
| 48 | +| `color` | any valid value | `color: {value}` | — | — | — | |
| 49 | + |
| 50 | +Cells marked `—` mean "no concept, field omitted silently." |
| 51 | + |
| 52 | +> **Note:** For Claude agent definitions (`execution: agent`), the `allowed-tools` key is automatically remapped to `tools` by spec-kit during deployment. The table above shows the `allowed-tools` form used in skill files (SKILL.md); the agent definition example below shows the resulting `tools` key after remapping. |
| 53 | + |
| 54 | +### `tools` presets and custom values (Claude) |
| 55 | + |
| 56 | +The `tools` field accepts four named presets or a custom value: |
| 57 | + |
| 58 | +| value | `allowed-tools` written | use case | |
| 59 | +|---|---|---| |
| 60 | +| `none` | `""` (empty — no tools) | pure reasoning, no file access | |
| 61 | +| `read-only` | `Read Grep Glob` | read/search, no writes | |
| 62 | +| `write` | `Read Write Edit Grep Glob` | file reads + writes, no shell | |
| 63 | +| `full` | _(key omitted)_ | all tools including Bash | |
| 64 | + |
| 65 | +For anything outside these presets, pass a **custom string** or **YAML list** — it is written verbatim as `allowed-tools`: |
| 66 | + |
| 67 | +```yaml |
| 68 | +# Custom string (space-separated) |
| 69 | +behavior: |
| 70 | + tools: "Read Write Bash" |
| 71 | +
|
| 72 | +# YAML list (joined with spaces) |
| 73 | +behavior: |
| 74 | + tools: |
| 75 | + - Read |
| 76 | + - Write |
| 77 | + - Bash |
| 78 | +``` |
| 79 | + |
| 80 | +> Custom values bypass preset lookup entirely and are not validated. Use named presets whenever possible. |
| 81 | + |
| 82 | +### `color` (Claude Code only) |
| 83 | + |
| 84 | +Controls the UI color of the agent entry in the Claude Code task list and transcript. Accepted values: `red`, `blue`, `green`, `yellow`, `purple`, `orange`, `pink`, `cyan`. The value is passed through verbatim to the agent definition frontmatter — no translation occurs. Other agents ignore this field. |
| 85 | + |
| 86 | +--- |
| 87 | + |
| 88 | +## `agents:` Escape Hatch |
| 89 | + |
| 90 | +For fields with no neutral equivalent, declare them per-agent: |
| 91 | + |
| 92 | +```yaml |
| 93 | +agents: |
| 94 | + claude: |
| 95 | + paths: "src/**" |
| 96 | + argument-hint: "Path to the codebase" |
| 97 | + copilot: |
| 98 | + someCustomKey: someValue |
| 99 | +``` |
| 100 | + |
| 101 | +Agent-specific overrides win over `behavior:` translations. |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## Deployment Routing from `behavior.execution` |
| 106 | + |
| 107 | +Deployment target is fully derived from `behavior.execution` in the command file — no separate manifest field needed. |
| 108 | + |
| 109 | +| `behavior.execution` | Claude | Copilot | Codex | Others | |
| 110 | +|---|---|---|---|---| |
| 111 | +| `command` (default) | `.claude/skills/{name}/SKILL.md` | `.github/agents/{name}.agent.md` | `.agents/skills/{name}/SKILL.md` | per-agent format | |
| 112 | +| `isolated` | `.claude/skills/{name}/SKILL.md` + `context: fork` | `.github/agents/{name}.agent.md` + `mode: agent` | per-agent format | per-agent format | |
| 113 | +| `agent` | `.claude/agents/{name}.md` | `.github/agents/{name}.agent.md` + `mode: agent` + `tools:` | not supported | not supported | |
| 114 | + |
| 115 | +### Agent definition format (Claude, `execution: agent`) |
| 116 | + |
| 117 | +Spec-kit writes a Claude agent definition file at `.claude/agents/{name}.md`. |
| 118 | +The body becomes the **system prompt**. Frontmatter is minimal — no |
| 119 | +`user-invocable`, `disable-model-invocation`, `context`, or `metadata` keys. |
| 120 | + |
| 121 | +```markdown |
| 122 | +--- |
| 123 | +name: speckit-revenge-analyzer |
| 124 | +description: Codebase analyzer subagent |
| 125 | +model: claude-opus-4-6 |
| 126 | +tools: Read Grep Glob |
| 127 | +--- |
| 128 | +You are a codebase analysis specialist... |
| 129 | +``` |
| 130 | + |
| 131 | +### Deferred: `execution: isolated` as agent definition |
| 132 | + |
| 133 | +It is theoretically possible to want a command that runs in an isolated |
| 134 | +context (`context: fork`) AND is deployed as a named agent definition |
| 135 | +(`.claude/agents/`). These two concerns are orthogonal — isolation is a |
| 136 | +runtime concern, agent definition is a deployment concern. |
| 137 | + |
| 138 | +This combination is **not supported** in this implementation. `execution: |
| 139 | +isolated` always deploys as a skill file. Decoupling runtime context from |
| 140 | +deployment target is deferred until a concrete use case requires it. |
| 141 | + |
| 142 | +--- |
| 143 | + |
| 144 | +## Full Example: Orchestrator + Reusable Subagent |
| 145 | + |
| 146 | +**`extension.yml`** (no manifest `type` field — deployment derived from command frontmatter): |
| 147 | +```yaml |
| 148 | +provides: |
| 149 | + commands: |
| 150 | + - name: speckit.revenge.extract |
| 151 | + file: commands/extract.md |
| 152 | +
|
| 153 | + - name: speckit.revenge.analyzer |
| 154 | + file: commands/analyzer.md |
| 155 | +``` |
| 156 | + |
| 157 | +**`commands/extract.md`** (orchestrator skill — no `execution:` → deploys to skills): |
| 158 | +```markdown |
| 159 | +--- |
| 160 | +description: Run the extraction pipeline |
| 161 | +behavior: |
| 162 | + invocation: automatic |
| 163 | +agents: |
| 164 | + claude: |
| 165 | + argument-hint: "Path to codebase (optional)" |
| 166 | +--- |
| 167 | +Orchestrate extraction for $ARGUMENTS... |
| 168 | +``` |
| 169 | + |
| 170 | +**`commands/analyzer.md`** (reusable subagent — `execution: agent` → deploys to `.claude/agents/`): |
| 171 | +```markdown |
| 172 | +--- |
| 173 | +description: Analyze codebase structure and extract domain information |
| 174 | +behavior: |
| 175 | + execution: agent |
| 176 | + capability: strong |
| 177 | + tools: read-only |
| 178 | + color: green |
| 179 | +agents: |
| 180 | + claude: |
| 181 | + paths: "src/**" |
| 182 | +--- |
| 183 | +You are a codebase analysis specialist. |
| 184 | +Analyze $ARGUMENTS and return structured domain findings. |
| 185 | +``` |
| 186 | + |
| 187 | +The deployed `.claude/agents/speckit-revenge-analyzer.md` will contain: |
| 188 | + |
| 189 | +```markdown |
| 190 | +--- |
| 191 | +name: speckit-revenge-analyzer |
| 192 | +description: Analyze codebase structure and extract domain information |
| 193 | +model: claude-opus-4-6 |
| 194 | +tools: Read Grep Glob |
| 195 | +color: green |
| 196 | +--- |
| 197 | +You are a codebase analysis specialist. |
| 198 | +... |
| 199 | +``` |
| 200 | + |
| 201 | +### `tools: write` example |
| 202 | + |
| 203 | +Use `write` when an agent needs to create or modify files but does not need shell access (Bash): |
| 204 | + |
| 205 | +```yaml |
| 206 | +behavior: |
| 207 | + execution: agent |
| 208 | + capability: strong |
| 209 | + tools: write # Read Write Edit Grep Glob — no Bash |
| 210 | + color: yellow |
| 211 | +``` |
| 212 | + |
| 213 | +### `tools: full` example |
| 214 | + |
| 215 | +Use `full` when an agent needs unrestricted access including Bash (running tests, git commands, CLI tools): |
| 216 | + |
| 217 | +```yaml |
| 218 | +behavior: |
| 219 | + execution: agent |
| 220 | + capability: strong |
| 221 | + tools: full # all tools; no allowed-tools key injected |
| 222 | + color: red |
| 223 | +``` |
0 commit comments