RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/AGENTS.md/github/spec-kit

AGENTS.md

AGENTS.md
AGENTS.mdroot

Quality

79/100

Scores the file, not the repository.

Length

3,955 words

54 headings · 22 code blocks

Repository

125k

— · pushed 0 days ago

Last changed

3 days ago

First indexed 3 days ago.
github/spec-kit/AGENTS.mdRawGitHub
1# AGENTS.md
2 
3## About Spec Kit and Specify
4 
5**GitHub Spec Kit** is a comprehensive toolkit for implementing Spec-Driven Development (SDD) - a methodology that emphasizes creating clear specifications before implementation. The toolkit includes templates, scripts, and workflows that guide development teams through a structured approach to building software.
6 
7**Specify CLI** is the command-line interface that bootstraps projects with the Spec Kit framework. It sets up the necessary directory structures, templates, and AI agent integrations to support the Spec-Driven Development workflow.
8 
9The toolkit supports multiple AI coding assistants, allowing teams to use their preferred tools while maintaining consistent project structure and development practices.
10 
11---
12 
13## Quickstart — Add a New Integration in 5 Steps
14 
15If you are new to the codebase and want to add support for a new AI agent, here is the shortest path from zero to a working integration:
16 
171. **Choose a base class** — most agents only need `MarkdownIntegration`. See [Choose a base class](#1-choose-a-base-class).
182. **Create a subpackage** — add `src/specify_cli/integrations/<package_dir>/__init__.py` with the required `key`, `config`, and `registrar_config` fields.
193. **Register it** — add one import and one `_register()` call in `src/specify_cli/integrations/__init__.py` (both alphabetical).
204. **Write a test file** — create `tests/integrations/test_integration_<key>.py` (hyphens in the key become underscores in the filename).
215. **Run and verify** — use `specify init --integration <key>` to exercise the full install/uninstall cycle.
22 
23Each step is expanded under [Adding a New Integration](#adding-a-new-integration). Note that agent **context files** (`CLAUDE.md`, `AGENTS.md`, …) are **not** handled by the integration — that is owned by the opt-in `agent-context` extension; see [Context file behavior](#4-context-file-behavior).
24 
25---
26 
27## Integration Architecture
28 
29Each AI agent is a self-contained **integration subpackage** under `src/specify_cli/integrations/<key>/`. The subpackage exposes a single class that declares all metadata and inherits setup/teardown logic from a base class. Built-in integrations are then instantiated and added to the global `INTEGRATION_REGISTRY` by `src/specify_cli/integrations/__init__.py` via `_register_builtins()`.
30 
31```text
32src/specify_cli/integrations/
33├── __init__.py # INTEGRATION_REGISTRY + _register_builtins()
34├── base.py # IntegrationBase, MarkdownIntegration, TomlIntegration, YamlIntegration, SkillsIntegration
35├── manifest.py # IntegrationManifest (file tracking)
36├── claude/ # Example: SkillsIntegration subclass
37│ └── __init__.py # ClaudeIntegration class
38├── gemini/ # Example: TomlIntegration subclass
39│ └── __init__.py
40├── kilocode/ # Example: MarkdownIntegration subclass
41│ └── __init__.py
42├── copilot/ # Example: IntegrationBase subclass (custom setup)
43│ └── __init__.py
44└── ... # One subpackage per supported agent
45```
46 
47The registry is the **single source of truth for Python integration metadata**. Supported agents, their directories, formats, capabilities, and context files are derived from the integration classes for the Python integration layer.
48 
49---
50 
51## IntegrationManifest — File Tracking
52 
53`manifest.py` provides the `IntegrationManifest` class, which records every file an integration installs. This record is what makes uninstall reliable and safe.
54 
55### How it works
56 
57`setup()` receives an `IntegrationManifest` and writes files through it rather than touching the filesystem directly:
58 
59```python
60# Produce a new file and record its hash for later verification.
61manifest.record_file("commands/speckit.plan.md", processed_content)
62 
63# Adopt a pre-existing file the integration is now responsible for.
64manifest.record_existing(".vscode/settings.json")
65```
66 
67The manifest is persisted at `.specify/integrations/<key>.manifest.json` (one per integration, keyed by `key`) and stores a SHA-256 hash per file. When the user runs `specify integration uninstall <key>`, `teardown()` delegates to `manifest.uninstall()`, which removes only files whose current hash still matches the recorded value — so files the user later edited by hand are skipped, not clobbered (use `specify integration uninstall <key> --force` to remove modified tracked files anyway).
68 
69### Why this matters
70 
71Without hash-tracked manifests, uninstall would either remove files it should not (destructive) or leave orphans behind (messy). If you write a custom `setup()`, route **every** file you create through `manifest.record_file(...)` (or `record_existing(...)` for files you adopt) so uninstall can reason about them.
72 
73---
74 
75## Adding a New Integration
76 
77### 1. Choose a base class
78 
79| Your agent needs… | Subclass |
80|---|---|
81| Standard markdown commands (`.md`) | `MarkdownIntegration` |
82| TOML-format commands (`.toml`) | `TomlIntegration` |
83| YAML recipe files (`.yaml`) | `YamlIntegration` |
84| Skill directories (`speckit-<name>/SKILL.md`) | `SkillsIntegration` |
85| Fully custom output (companion files, settings merge, etc.) | `IntegrationBase` directly |
86 
87Most agents only need `MarkdownIntegration` — a minimal subclass with zero method overrides.
88 
89### 2. Create the subpackage
90 
91Create `src/specify_cli/integrations/<package_dir>/__init__.py`, where `<package_dir>` is the Python-safe directory name derived from `<key>`: use the key as-is when it contains no hyphens (e.g., key `"gemini"` → `gemini/`), or replace hyphens with underscores when it does (e.g., key `"kiro-cli"` → `kiro_cli/`). The `IntegrationBase.key` class attribute always retains the original hyphenated value, since that is what the CLI and registry use. For CLI-based integrations (`requires_cli: True`), the `key` should match the actual CLI tool name (the executable users install and run) so CLI checks can resolve it correctly. For IDE-based integrations (`requires_cli: False`), use the canonical integration identifier instead.
92 
93**Minimal example — Markdown agent (Kilo Code):**
94 
95```python
96"""Kilo Code IDE integration."""
97 
98from ..base import MarkdownIntegration
99 
100 
101class KilocodeIntegration(MarkdownIntegration):
102 key = "kilocode"
103 config = {
104 "name": "Kilo Code",
105 "folder": ".kilo/",
106 "commands_subdir": "commands",
107 "install_url": None,
108 "requires_cli": False,
109 }
110 registrar_config = {
111 "dir": ".kilo/commands",
112 "legacy_dir": ".kilocode/workflows",
113 "format": "markdown",
114 "args": "$ARGUMENTS",
115 "extension": ".md",
116 }
117```
118 
119**TOML agent (Gemini):**
120 
121```python
122"""Gemini CLI integration."""
123 
124from ..base import TomlIntegration
125 
126 
127class GeminiIntegration(TomlIntegration):
128 key = "gemini"
129 config = {
130 "name": "Gemini CLI",
131 "folder": ".gemini/",
132 "commands_subdir": "commands",
133 "install_url": "https://github.com/google-gemini/gemini-cli",
134 "requires_cli": True,
135 }
136 registrar_config = {
137 "dir": ".gemini/commands",
138 "format": "toml",
139 "args": "{{args}}",
140 "extension": ".toml",
141 }
142```
143 
144**Skills agent (Codex):**
145 
146```python
147"""Codex CLI integration — skills-based agent."""
148 
149from __future__ import annotations
150 
151from ..base import IntegrationOption, SkillsIntegration
152 
153 
154class CodexIntegration(SkillsIntegration):
155 key = "codex"
156 config = {
157 "name": "Codex CLI",
158 "folder": ".agents/",
159 "commands_subdir": "skills",
160 "install_url": "https://github.com/openai/codex",
161 "requires_cli": True,
162 }
163 registrar_config = {
164 "dir": ".agents/skills",
165 "format": "markdown",
166 "args": "$ARGUMENTS",
167 "extension": "/SKILL.md",
168 }
169 
170 @classmethod
171 def options(cls) -> list[IntegrationOption]:
172 return [
173 IntegrationOption(
174 "--skills",
175 is_flag=True,
176 default=True,
177 help="Install as agent skills (default for Codex)",
178 ),
179 ]
180```
181 
182#### Required fields
183 
184| Field | Location | Purpose |
185|---|---|---|
186| `key` | Class attribute | Unique identifier; for CLI-based integrations (`requires_cli: True`), must match the CLI executable name |
187| `config` | Class attribute (dict) | Agent metadata: `name`, `folder`, `commands_subdir`, `install_url`, `requires_cli` |
188| `registrar_config` | Class attribute (dict) | Command output config: `dir`, `format`, `args` placeholder, file `extension` |
189 
190**Key design rule:** For CLI-based integrations (`requires_cli: True`), `key` must be the actual executable name (e.g., `"cursor-agent"` not `"cursor"`). This ensures `shutil.which(key)` works for CLI-tool checks without special-case mappings. IDE-based integrations (`requires_cli: False`) should use their canonical identifier (e.g., `"kilocode"`, `"copilot"`).
191 
192### 3. Register it
193 
194In `src/specify_cli/integrations/__init__.py`, add one import and one `_register()` call inside `_register_builtins()`. Both lists are alphabetical:
195 
196```python
197def _register_builtins() -> None:
198 # -- Imports (alphabetical) -------------------------------------------
199 from .claude import ClaudeIntegration
200 # ...
201 from .newagent import NewAgentIntegration # ← add import
202 # ...
203 
204 # -- Registration (alphabetical) --------------------------------------
205 _register(ClaudeIntegration())
206 # ...
207 _register(NewAgentIntegration()) # ← add registration
208 # ...
209```
210 
211### 4. Context file behavior
212 
213The Specify CLI carries **no agent-context state whatsoever**. Integration classes do **not** declare a `context_file`, and the CLI never creates, updates, removes, resolves, or migrates a context/instruction file (`CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`, …). New integrations add nothing for context handling.
214 
215Managing the "Spec Kit" section in the context file is fully owned by the bundled `agent-context` extension (`extensions/agent-context/`), which is a **full opt-in**: `specify init` does not install it. A user adds/enables it through the standard extension verbs, after which the extension's own bundled scripts maintain the context section. When the extension is absent or disabled, nothing in Spec Kit touches the context file.
216 
217The extension reads its own config file at `.specify/extensions/agent-context/agent-context-config.yml`:
218 
219```yaml
220# Path to the coding agent context file managed by this extension
221context_file: CLAUDE.md
222 
223# Delimiters for the managed Spec Kit section
224context_markers:
225 start: "<!-- SPECKIT START -->"
226 end: "<!-- SPECKIT END -->"
227```
228 
229- The Specify CLI does **not** write this config. When `context_file` is empty, the extension's bundled scripts self-seed it by looking up the active integration's key in the extension's own `agent-context-defaults.json` map (`extensions/agent-context/scripts/bash/update-agent-context.sh`, `.ps1`, and `extensions/agent-context/scripts/python/update_agent_context.py`). The CLI registry is never consulted — all agent→context-file knowledge lives inside the extension.
230- `context_markers.{start,end}` are read solely by the extension's scripts; they default to the Spec Kit markers shown above and can be customized by editing `agent-context-config.yml` directly.
231 
232Existing projects created by older Spec Kit versions keep working: any previously written managed section or extension config is left intact and is only ever updated by the extension when run.
233 
234Only add custom setup logic when the agent needs non-standard behavior. Integrations no longer require per-agent thin wrapper scripts or shared context-update dispatcher scripts — the `agent-context` extension is fully generic.
235 
236### 5. Test it
237 
238```bash
239# Install into a test project
240specify init my-project --integration &lt;key&gt;
241 
242# Verify files were created in the commands directory configured by
243# config["folder"] + config["commands_subdir"] (for example, .kilo/commands/)
244ls -R my-project/.kilo/commands/
245 
246# Uninstall cleanly
247cd my-project && specify integration uninstall &lt;key&gt;
248```
249 
250Each integration also has a dedicated test file at `tests/integrations/test_integration_<key>.py`. Note that hyphens in the key are replaced with underscores in the filename (e.g., key `cursor-agent` → `test_integration_cursor_agent.py`, key `kiro-cli` → `test_integration_kiro_cli.py`). Run it with:
251 
252```bash
253pytest tests/integrations/test_integration_&lt;key_with_underscores&gt;.py -v
254```
255 
256### 6. Optional overrides
257 
258The base classes handle most work automatically. Override only when the agent deviates from standard patterns:
259 
260| Override | When to use | Example |
261|---|---|---|
262| `command_filename(template_name)` | Custom file naming or extension | Copilot → `speckit.{name}.agent.md` |
263| `options()` | Integration-specific CLI flags via `--integration-options` | Codex → `--skills` flag, Copilot → `--skills` flag |
264| `setup()` | Custom install logic (companion files, settings merge) | Copilot → `.agent.md` + `.prompt.md` + `.vscode/settings.json` (default) or `speckit-<name>/SKILL.md` (skills mode) |
265| `teardown()` | Custom uninstall logic | Rarely needed; base handles manifest-tracked files |
266 
267**Example — Copilot (fully custom `setup`):**
268 
269Copilot extends `IntegrationBase` directly because it creates `.agent.md` commands, companion `.prompt.md` files, and merges `.vscode/settings.json`. It also supports a `--skills` mode that scaffolds `speckit-<name>/SKILL.md` under `.github/skills/` using composition with an internal `_CopilotSkillsHelper`. See `src/specify_cli/integrations/copilot/__init__.py` for the full implementation.
270 
271### 7. Update Devcontainer files (Optional)
272 
273For agents that have VS Code extensions or require CLI installation, update the devcontainer configuration files:
274 
275#### VS Code Extension-based Agents
276 
277For agents available as VS Code extensions, add them to `.devcontainer/devcontainer.json`:
278 
279```jsonc
280{
281 "customizations": {
282 "vscode": {
283 "extensions": [
284 // ... existing extensions ...
285 "[New Agent Extension ID]"
286 ]
287 }
288 }
289}
290```
291 
292#### CLI-based Agents
293 
294For agents that require CLI tools, add installation commands to `.devcontainer/post-create.sh`:
295 
296```bash
297#!/bin/bash
298 
299# Existing installations...
300
301echo -e &quot;\n🤖 Installing [New Agent Name] CLI...&quot;
302# run_command "npm install -g [agent-cli-package]@latest"
303echo &quot;✅ Done&quot;
304```
305 
306---
307 
308## Command File Formats
309 
310### Script References (`scripts:` frontmatter)
311 
312Core command templates (`templates/commands/*.md`) that invoke a helper script declare it in a `scripts:` frontmatter block with one line per supported script type. The `{SCRIPT}` placeholder in the command body is replaced at install time with the entry matching the project's selected script type (`--script sh|ps|py`):
313 
314```yaml
315scripts:
316 sh: scripts/bash/setup-plan.sh --json
317 ps: scripts/powershell/setup-plan.ps1 -Json
318 py: scripts/python/setup_plan.py --json
319```
320 
321| Key | Script type | Location |
322| ---- | ---------------------- | -------------------------- |
323| `sh` | POSIX shell (bash/zsh) | `scripts/bash/*.sh` |
324| `ps` | PowerShell | `scripts/powershell/*.ps1` |
325| `py` | Python | `scripts/python/*.py` |
326 
327All three entries must be present and behaviorally equivalent — agents parse the same stdout contract (`FEATURE_DIR:…`, `AVAILABLE_DOCS:…`, `--json` shapes) regardless of which one runs. (The bundled `agent-context` and `git` extension command templates also invoke helpers but do not yet use `scripts:` frontmatter — see [Script Types and Migration](#script-types-and-migration).)
328 
329### Markdown Format
330 
331**Standard format:**
332 
333```markdown
334---
335description: "Command description"
336---
337 
338Command content with {SCRIPT} and $ARGUMENTS placeholders.
339```
340 
341**GitHub Copilot Chat Mode format:**
342 
343```markdown
344---
345description: "Command description"
346mode: speckit.command-name
347---
348 
349Command content with {SCRIPT} and $ARGUMENTS placeholders.
350```
351 
352### TOML Format
353 
354```toml
355description = "Command description"
356
357prompt = """
358Command content with {SCRIPT} and {{args}} placeholders.
359"""
360```
361 
362### YAML Format
363 
364Used by: Goose
365 
366```yaml
367version: 1.0.0
368title: "Command Title"
369description: "Command description"
370author:
371 contact: spec-kit
372extensions:
373 - type: builtin
374 name: developer
375activities:
376 - Spec-Driven Development
377prompt: |
378 Command content with {SCRIPT} and {{args}} placeholders.
379```
380 
381## Argument Patterns
382 
383Different agents use different argument placeholders. The placeholder used in command files is always taken from `registrar_config["args"]` for each integration — check there first when in doubt:
384 
385- **Markdown/prompt-based**: `$ARGUMENTS` (default for most markdown agents)
386- **TOML-based**: `{{args}}` (e.g., Gemini)
387- **YAML-based**: `{{args}}` (e.g., Goose)
388- **Custom**: some agents override the default (e.g., Forge uses `{{parameters}}`)
389- **Script placeholders**: `{SCRIPT}` (replaced with the resolved command from the template's `scripts:` frontmatter, per the project's `--script sh|ps|py` selection)
390- **Agent placeholders**: `__AGENT__` (replaced with agent name)
391 
392## Script Types and Migration
393 
394Spec Kit ships every core workflow script in three interchangeable variants — POSIX shell (`sh`), PowerShell (`ps`), and Python (`py`) — selected per project with `specify init --script sh|ps|py`. Each core command template that invokes a helper script carries all three in its `scripts:` frontmatter (templates that don't call a script, e.g. `constitution`/`specify`, have no `scripts:` block); see [Script References](#script-references-scripts-frontmatter).
395 
396### Why Python is recommended
397 
398- **No extra runtime.** The `specify` CLI is already Python, so the interpreter is guaranteed present — `py` adds no new dependency.
399- **Path toward a single source of truth.** The shell variants require paired `.sh` + `.ps1` maintenance and diverge on JSON handling (`jq` vs manual parsing). The Python variant avoids `jq` and is intended to eventually replace that dual-maintenance — but that consolidation has not happened yet: all three variants are still maintained in parallel (see the parity rule below).
400- **Parity-tested.** The Python ports are covered by tests — output-parity tests against the shell scripts where the contract is stdout-based, and direct unit tests elsewhere — so the stdout contract agents rely on stays stable.
401 
402### Defaults and availability
403 
404- `py` is available today for the core command templates (via their `scripts:` frontmatter). The bundled extensions (`agent-context`, `git`) ship Python script variants on disk, but their command templates still hard-code the Bash/PowerShell invocations, so `--script py` does not yet route those extension commands to Python — wiring `py` into the extension command templates is tracked separately.
405- Selection is per project: interactive `specify init` prompts for the script type, while non-interactive runs default to a shell variant by OS (`sh` on Linux/macOS, `ps` on Windows). `py` is chosen at the prompt or via `--script py`.
406- `sh` and `ps` remain fully supported. Nothing is removed, and `py` is not yet the default.
407 
408### Parity rule for contributors
409 
410All three script types are first-class: any change to a workflow script must update `sh`, `ps`, and `py` together and keep their tests (parity and unit) green. Making `py` the default and eventually retiring `sh`/`ps` is future work gated on adoption, tracked under the script-unification epic ([#3277](https://github.com/github/spec-kit/issues/3277)) — not something to act on from this doc.
411 
412## Special Processing Requirements
413 
414Some agents require custom processing beyond the standard template transformations:
415 
416### Copilot Integration
417 
418GitHub Copilot has unique requirements:
419 
420- Commands use `.agent.md` extension (not `.md`)
421- Each command gets a companion `.prompt.md` file in `.github/prompts/`
422- Installs `.vscode/settings.json` with prompt file recommendations
423- Context file lives at `.github/copilot-instructions.md`
424 
425Implementation: Extends `IntegrationBase` with custom `setup()` method that:
426 
4271. Processes templates with `process_template()`
4282. Generates companion `.prompt.md` files
4293. Merges VS Code settings
430 
431**Skills mode (`--skills`):** Copilot also supports an alternative skills-based layout
432via `--integration-options="--skills"`. When enabled:
433 
434- Commands are scaffolded as `speckit-<name>/SKILL.md` under `.github/skills/`
435- No companion `.prompt.md` files are generated
436- No `.vscode/settings.json` merge
437- `post_process_skill_content()` injects a `mode: speckit.<stem>` frontmatter field
438- `build_command_invocation()` returns `/speckit-<stem>` instead of bare args
439 
440The two modes are mutually exclusive — a project uses one or the other:
441 
442```bash
443# Default mode: .agent.md agents + .prompt.md companions + settings merge
444specify init my-project --integration copilot
445 
446# Skills mode: speckit-<name>/SKILL.md under .github/skills/
447specify init my-project --integration copilot --integration-options=&quot;--skills&quot;
448```
449 
450### Forge Integration
451 
452Forge has special frontmatter and argument requirements:
453 
454- Uses `{{parameters}}` instead of `$ARGUMENTS`
455- Strips `handoffs` frontmatter key (Forge-specific collaboration feature)
456- Injects `name` field into frontmatter when missing
457 
458Implementation: Extends `MarkdownIntegration` with custom `setup()` method that:
459 
4601. Inherits standard template processing from `MarkdownIntegration`
4612. Adds extra `$ARGUMENTS` → `{{parameters}}` replacement after template processing
4623. Applies Forge-specific transformations via `_apply_forge_transformations()`
4634. Strips `handoffs` frontmatter key
4645. Injects missing `name` fields
465 
466### Goose Integration
467 
468Goose is a YAML-format agent using Block's recipe system:
469 
470- Uses `.goose/recipes/` directory for YAML recipe files
471- Uses `{{args}}` argument placeholder
472- Produces YAML with `prompt: |` block scalar for command content
473 
474Implementation: Extends `YamlIntegration` (parallel to `TomlIntegration`):
475 
4761. Processes templates through the standard placeholder pipeline
4772. Extracts title and description from frontmatter
4783. Renders output as Goose recipe YAML (version, title, description, author, extensions, activities, prompt)
4794. Uses `yaml.safe_dump()` for header fields to ensure proper escaping
480 
481## Branch Naming Convention
482 
483Branches follow one of two patterns depending on whether an issue exists:
484 
485```text
486<type>/<number>-<short-slug> # when an issue is created first
487<type>/<short-slug> # when no issue exists (PR-only changes)
488```
489 
490When an issue exists, include its number immediately after the prefix — this is what makes branches traceable. For small or self-contained changes that go straight to a PR without a tracking issue, omit the number.
491 
492| Prefix | When to use | Example |
493|---|---|---|
494| `feat/` | New features | `feat/2342-workflow-cli-alignment` |
495| `fix/` | Bug fixes | `fix/2653-paths-only-validation` |
496| `docs/` | Documentation changes | `docs/2677-branch-naming-convention`, `docs/update-landing-stats` |
497| `community/` | Community catalog additions | `community/2492-add-mde-extension` |
498| `chore/` | Maintenance, tooling, CI | `chore/2366-editorconfig` |
499 
500**Rules:**
501 
5021. Include the issue number when one exists — this is what makes branches traceable
5032. Use kebab-case for the slug
5043. Keep the slug short — enough to identify the work without looking up the issue
505 
506---
507 
508## Agent Disclosure for PRs, Comments, and Commits
509 
510Disclosure is **continuous**, not a one-time event. A single AI-disclosure paragraph in the PR body does **not** cover the commits and replies you add during review rounds. Each of the following must independently attest to agent authorship.
511 
512### Commits
513 
514- **Every commit you author must carry an `Assisted-by:` trailer** identifying the agent and whether it acted autonomously or under direct human supervision, for example:
515 
516```
517 Assisted-by: GitHub Copilot (model: <name-if-known>, autonomous)
518```
519 
520 Use `supervised` instead of `autonomous` only when a human actually authored or line-by-line reviewed the change before it was committed.
521- **Never push solo-authored commits that hide agent authorship behind the operator's git identity.** If an agent generated the change, the trailer must say so even when the commit is attributed to a human account.
522- Preserve any tool-generated `Co-authored-by:` trailers (e.g. Copilot Autofix) — do not strip them to make a commit look hand-written.
523 
524### Comments
525 
526- If you are an agent working on behalf of a human, **disclose your identity in your PR comment** — name the agent (and model, if applicable) and the human you are acting for (e.g., "Posted on behalf of @user by GitHub Copilot (model: &lt;name-if-known&gt;)").
527- **Re-state agent identity in each review-round summary comment.** A prior PR-body disclosure does not cover later comments or commits.
528- Post **one** top-level summary comment per review round listing what changed and the commit SHA. Do not reply on every individual comment.
529- Reply inline only when context is needed (disagreement, deferral, non-obvious fix). Keep it to a sentence or two.
530- **Never click "Resolve conversation"** — that belongs to the reviewer or PR author.
531- No emoji, no celebratory framing, no checklist mirroring the reviewer's items, no restating what the reviewer wrote.
532- Re-request review once per round (when all feedback is addressed), not after every intermediate push.
533 
534### Anti-patterns (do not do these)
535 
536- **Do not** reply "Done" or push a "fix" within seconds/minutes of a review event without disclosing that the response or commit was agent-generated. Speed of turnaround is not a substitute for attestation — a near-instant tested code change is itself a signal of automation and must be disclosed as such.
537- **Do not** claim "reviewed, tested, and understood by me" for commits that were authored and pushed automatically in response to a review trigger. If the loop is automated, disclose it as automated.
538 
539---
540 
541## Common Pitfalls
542 
5431. **Using shorthand keys for CLI-based integrations**: For CLI-based integrations (`requires_cli: True`), the `key` must match the executable name (e.g., `"cursor-agent"` not `"cursor"`). `shutil.which(key)` is used for CLI tool checks — mismatches require special-case mappings. IDE-based integrations (`requires_cli: False`) are not subject to this constraint.
5442. **Reintroducing context handling into the CLI**: The opt-in `agent-context` extension owns everything about context files — including the per-agent default mapping in `agent-context-defaults.json`. Integration classes must **not** declare a `context_file`, and no CLI code should read, write, resolve, or migrate context files. All context-file logic lives in `.specify/extensions/agent-context/` and its bundled scripts.
5453. **Incorrect `requires_cli` value**: Set to `True` only for agents that have a CLI tool; set to `False` for IDE-based agents.
5464. **Wrong argument format**: Use `$ARGUMENTS` for Markdown agents, `{{args}}` for TOML agents.
5475. **Skipping registration**: The import and `_register()` call in `_register_builtins()` must both be added.
5486. **Running tests against the wrong environment**: Always run the suite inside this working tree's own virtualenv (`uv sync --extra test` then `.venv/bin/python -m pytest`, or activate the venv first). A bare `uv run pytest` can resolve to an ambient/global interpreter whose editable `.pth` points at a *different* worktree. The failure is sneaky: test collection still imports `specify_cli` successfully, but newly-added subpackages (e.g. a fresh `specify_cli/bundler/`) resolve as a stale namespace package and raise `ModuleNotFoundError`. If a brand-new subpackage imports under `python -c` but not under pytest, suspect environment contamination, not your code.
549 
550---
551 
552## Error Handling and Debugging
553 
554### Common Errors and Fixes
555 
556| Symptom | Likely Cause | Fix |
557|---|---|---|
558| `Integration '<key>' not found` | Missing `_register()` call | Add `_register(<Name>Integration())` inside `_register_builtins()` |
559| `NameError: name '<Name>Integration' is not defined` at startup | Missing import | Add `from .<package_dir> import <Name>Integration` inside `_register_builtins()` |
560| CLI check fails for a `requires_cli: True` agent | `key` does not match the executable name | Set `key` to the exact name `shutil.which(key)` must resolve (e.g. `"cursor-agent"`, not `"cursor"`) |
561| Command files have the wrong argument syntax | Wrong `args` value in `registrar_config` | Use `$ARGUMENTS` for Markdown agents, `{{args}}` for TOML/YAML agents, or the agent's custom placeholder |
562| `ModuleNotFoundError` on a brand-new subpackage under pytest only | Ambient interpreter with a stale editable `.pth` | Run inside this tree's own venv (see Common Pitfall 6) |
563| Uninstall leaves files behind, or skips files you expected removed | Files not recorded via the manifest, or their hash changed after install | Route every created file through `manifest.record_file(...)`; user-edited files are intentionally skipped unless `force=True` |
564| Context file (`CLAUDE.md`, etc.) not updated | Expecting the CLI to manage it | Context files are owned by the opt-in `agent-context` extension, not the integration — see [Context file behavior](#4-context-file-behavior) |
565 
566### Debugging Tips
567 
568**Inspect the manifest** to see what an installed integration tracks:
569 
570```bash
571cat .specify/integrations/&lt;key&gt;.manifest.json
572```
573 
574**Verify a CLI tool is detected** before debugging a `requires_cli` agent:
575 
576```bash
577which &lt;key&gt; # Should print the executable path if installed
578```
579 
580**Verify the installed output structure** after `specify init`:
581 
582```bash
583find my-project/&lt;folder&gt; -type f
584```
585 
586---
587 
588## Contribution Checklist
589 
590Before opening or merging an integration PR, confirm the following:
591 
592- [ ] Added the integration subpackage under `src/specify_cli/integrations/<package_dir>/`.
593- [ ] Registered it (import **and** `_register()`) in `src/specify_cli/integrations/__init__.py`, both alphabetical.
594- [ ] Added or updated tests in `tests/integrations/test_integration_<key>.py`.
595- [ ] Verified the install/uninstall flow with `specify init --integration <key>`.
596- [ ] Did **not** add `context_file` handling to the CLI (that belongs to the `agent-context` extension).
597- [ ] Updated devcontainer files if the agent needs a VS Code extension or CLI install step.
598- [ ] Updated this guide or other relevant docs if the integration has special setup or limitations.
599 
600---
601 
602*This documentation should be updated whenever new integrations are added to maintain accuracy and completeness.*
603 

Commands it names

  • pytest tests/integrations/test_integration_<key_with_underscores>.py -v
  • git
  • uv sync --extra test
  • uv run pytest
  • python -c

Sections

  • AGENTS.md
  • About Spec Kit and Specify
  • Quickstart — Add a New Integration in 5 Steps
  • Integration Architecture
  • IntegrationManifest — File Tracking
  • How it works
  • Produce a new file and record its hash for later verification.
  • Adopt a pre-existing file the integration is now responsible for.
  • Why this matters
  • Adding a New Integration
  • 1. Choose a base class
  • 2. Create the subpackage
  • 3. Register it
  • 4. Context file behavior
  • Path to the coding agent context file managed by this extension
  • Delimiters for the managed Spec Kit section
  • 5. Test it
  • Install into a test project
  • Verify files were created in the commands directory configured by
  • config["folder"] + config["commands_subdir"] (for example, .kilo/commands/)
  • Uninstall cleanly
  • 6. Optional overrides
  • 7. Update Devcontainer files (Optional)
  • Existing installations...
  • run_command "npm install -g [agent-cli-package]@latest"
  • Command File Formats
  • Script References (`scripts:` frontmatter)
  • Markdown Format
  • TOML Format
  • YAML Format
  • Argument Patterns
  • Script Types and Migration
  • Why Python is recommended
  • Defaults and availability
  • Parity rule for contributors
  • Special Processing Requirements
  • Copilot Integration
  • Default mode: .agent.md agents + .prompt.md companions + settings merge
  • Skills mode: speckit-<name>/SKILL.md under .github/skills/
  • Forge Integration
  • Goose Integration
  • Branch Naming Convention
  • Agent Disclosure for PRs, Comments, and Commits
  • Commits
  • Comments
  • Anti-patterns (do not do these)
  • Common Pitfalls
  • Error Handling and Debugging
  • Common Errors and Fixes
  • Debugging Tips
  • Contribution Checklist

What it covers

setuptestlint-formatcode-stylearchitecturetypesgit-prdatabasedo-notagent-behaviourdocs

Stack — with the evidence

python

(1.00)

pytest

(0.95)

github-actions

(0.60)

Format

AGENTS.md

A plain-markdown README for coding agents, deliberately unopinionated: no frontmatter, no globs, no vendor keys. That minimalism is why it became the one file a dozen different agents will read, and why it carries the least per-file targeting power of any format here.

What the corpus says about it

Repository

Owner
github
Language
—
License
—
Archived
no

All configs in this repo

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
trick77/agents-md-syncAGENTS.md · 2AGENTS.mdtypescriptnode+4setupbuildteststyle+5100/1003 days ago
SkeneTechnologies/skene-cookbookAGENTS.md · 51AGENTS.mdpythoneslint+4setupbuildtestlint-format+7100/1002 days ago
duckduckgo/content-scope-scriptsspecial-pages/AGENTS.md · 70AGENTS.mdtypescriptjavascript+5buildteststylearch+3100/1003 days ago
wpscanteam/wpscanAGENTS.md · 9.7kAGENTS.mdrubyvue+3setupbuildteststyle+6100/1002 days ago
OnlyTerp/prompt-cache-skillsAGENTS.md · 112AGENTS.mdpythongithub-actionssetupbuildtestlint-format+5100/1003 days ago
mui/material-uiAGENTS.md · 99kAGENTS.mdtypescriptjavascript+13setupbuildtestlint-format+9100/1003 days ago
n8n-io/n8npackages/@n8n/agents/AGENTS.md · 199kAGENTS.mdtypescriptlangchain+16buildteststylearch+3100/1003 days ago
aaif-goose/gooseAGENTS.md · 52kAGENTS.mdrusttypescript+2setupbuildtestlint-format+6100/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack