feat(agents): add Goose AI agent support#2015
feat(agents): add Goose AI agent support#2015furkankoykiran wants to merge 9 commits intogithub:mainfrom
Conversation
Add Goose agent configuration with .goose/recipes directory structure. Goose is an open source AI agent (20.5k+ GitHub stars) that uses YAML recipe format with slash command support (PR block/goose#5718).
Add Goose configuration with YAML format and .goose/recipes directory.
Uses {{args}} placeholder for YAML recipe arguments.
Add goose to ALL_AGENTS array and implement YAML recipe generation. Generate Goose recipes in .goose/recipes/ directory using YAML format.
Add goose to AllAgents array and implement YAML recipe generation. Generate Goose recipes in .goose/recipes/ directory using YAML format.
Add GOOSE_FILE variable and goose case statement for updating agent context files in .goose/recipes/AGENTS.md.
Add GOOSE_FILE variable and goose case statement for updating agent context files in .goose/recipes/AGENTS.md.
Add Goose entry with link to official documentation and note about YAML recipe format with slash command support.
Add Goose to current supported agents table and CLI-Based Agents section. Document YAML recipe format in .goose/recipes/ directory.
Add comprehensive consistency tests for Goose agent configuration: - AGENT_CONFIG validation - CommandRegistrar.AGENT_CONFIGS validation - Release script agent lists validation - Release script YAML recipe generation validation - Agent context script support validation
There was a problem hiding this comment.
Pull request overview
Adds initial support for Block’s Goose AI agent to spec-kit by wiring Goose into agent configuration, scaffolding/release packaging, and documentation, plus adding consistency tests.
Changes:
- Add
gooseto CLI agent configuration (AGENT_CONFIG) and extension/preset command registrar config (CommandRegistrar.AGENT_CONFIGS). - Extend release packaging scripts to generate Goose-oriented YAML recipe files under
.goose/recipes/. - Update agent-context update scripts and docs, and add consistency tests for the new agent.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Adds Goose to AGENT_CONFIG so CLI can target .goose/recipes. |
src/specify_cli/agents.py |
Adds Goose to CommandRegistrar.AGENT_CONFIGS with format: yaml. |
.github/workflows/scripts/create-release-packages.sh |
Adds Goose to ALL_AGENTS and attempts YAML recipe generation. |
.github/workflows/scripts/create-release-packages.ps1 |
Adds Goose to $AllAgents and attempts YAML recipe generation. |
scripts/bash/update-agent-context.sh |
Adds goose handling and .goose/recipes/AGENTS.md target. |
scripts/powershell/update-agent-context.ps1 |
Adds goose handling and .goose/recipes/AGENTS.md target. |
README.md |
Lists Goose in supported agents table. |
AGENTS.md |
Documents Goose as a supported agent and CLI-based requirement. |
tests/test_agent_config_consistency.py |
Adds consistency checks ensuring Goose is wired into configs/scripts/releases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """GitHub release script should include goose template packages.""" | ||
| gh_release_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-github-release.sh").read_text(encoding="utf-8") | ||
|
|
||
| assert "spec-kit-template-goose-sh-" in gh_release_text | ||
| assert "spec-kit-template-goose-ps-" in gh_release_text | ||
|
|
There was a problem hiding this comment.
This test currently fails against the repo state in this PR: .github/workflows/scripts/create-github-release.sh does not include any spec-kit-template-goose-... artifacts yet, so the asserted strings aren’t present. Either update create-github-release.sh to upload the Goose template zips (recommended, since the release packaging scripts now build them) or remove/adjust this assertion until the release script is updated.
| """GitHub release script should include goose template packages.""" | |
| gh_release_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-github-release.sh").read_text(encoding="utf-8") | |
| assert "spec-kit-template-goose-sh-" in gh_release_text | |
| assert "spec-kit-template-goose-ps-" in gh_release_text | |
| """GitHub release script should include goose template packages. | |
| NOTE: The create-github-release.sh script does not yet upload the | |
| spec-kit-template-goose-* artifacts. Once it does, reintroduce | |
| explicit assertions for those artifact names here. | |
| """ | |
| gh_release_text = (REPO_ROOT / ".github" / "workflows" / "scripts" / "create-github-release.sh").read_text(encoding="utf-8") | |
| # Intentionally no assertions on specific goose template artifact names | |
| # until create-github-release.sh is updated to publish them. |
| prompt: | | ||
| $body | ||
| YAML_EOF |
There was a problem hiding this comment.
The YAML recipe generation here produces invalid YAML for the prompt: | block because only the first line of $body is indented (subsequent lines from $body start at column 0). YAML block scalars require every content line to be indented at least one level, so these files won’t parse. Consider indenting every line of $body (e.g., prefix each line with two spaces) before writing it under prompt: |.
| title=$(echo "$name" | sed 's/\b\(.\)/\u/g/g') # Convert to title case | ||
| instructions=$(printf '%s\n' "$body" | sed 's/"/\\"/g' | tr '\n' '\\n') | ||
| cat > "$output_dir/speckit.$name.$ext" <<YAML_EOF | ||
| version: 1.0.0 | ||
| title: "$title" | ||
| description: "$description" | ||
| instructions: "$description" |
There was a problem hiding this comment.
title=$(echo "$name" | sed 's/\b\(.\)/\u/g/g') looks broken: the replacement string is \u without \1, so the matched character is dropped and title will likely become empty. Also, instructions=... is computed but never used, while the YAML instructions: field is set to $description instead. Please fix title casing (and keep the captured character) and either use/remove the instructions variable so the YAML fields reflect the intended recipe schema.
| title=$(echo "$name" | sed 's/\b\(.\)/\u/g/g') # Convert to title case | |
| instructions=$(printf '%s\n' "$body" | sed 's/"/\\"/g' | tr '\n' '\\n') | |
| cat > "$output_dir/speckit.$name.$ext" <<YAML_EOF | |
| version: 1.0.0 | |
| title: "$title" | |
| description: "$description" | |
| instructions: "$description" | |
| title=$(echo "$name" | sed 's/\b\(.\)/\u\1/g') # Convert to title case | |
| instructions=$(printf '%s\n' "$body" | sed 's/"/\\"/g' | tr '\n' '\\n') | |
| cat > "$output_dir/speckit.$name.$ext" <<YAML_EOF | |
| version: 1.0.0 | |
| title: "$title" | |
| description: "$description" | |
| instructions: "$instructions" |
| $title = (Get-Culture).TextInfo.ToTitleCase($name) | ||
| $escapedBody = $body -replace '"', '`"' | ||
| $escapedBody = $escapedBody -replace "`n", '\n' | ||
| $output = @" | ||
| version: 1.0.0 | ||
| title: "$title" | ||
| description: "$description" | ||
| instructions: "$description" | ||
| author: | ||
| contact: "spec-kit" | ||
| extensions: | ||
| - type: builtin | ||
| name: developer | ||
| activities: | ||
| - "Spec-Driven Development" | ||
| prompt: | | ||
| $body | ||
| "@ | ||
| Set-Content -Path $outputFile -Value $output -NoNewline | ||
| } |
There was a problem hiding this comment.
The generated YAML recipe will be invalid for prompt: | because $body is inserted without indenting each line (only the first line is prefixed by the single space in the here-string). YAML block scalars require consistent indentation for all lines in the scalar. Also, $escapedBody is computed but unused, and instructions: is set to $description despite having separate variables—please either map these fields correctly or remove the unused variables.
| "format": "yaml", | ||
| "args": "{{args}}", | ||
| "extension": ".yaml" |
There was a problem hiding this comment.
CommandRegistrar.register_commands() only supports format values markdown and toml (and the special SKILL.md case). Adding Goose with format: "yaml" means command registration for Goose will raise ValueError("Unsupported format: yaml") and be skipped by register_commands_for_all_agents(), so extensions/presets won’t actually install Goose recipes. To make Goose support functional, add a YAML renderer + a elif agent_config["format"] == "yaml" branch (mapping frontmatter/body into the Goose recipe schema), or change the config to a supported format if YAML generation isn’t implemented yet.
| "format": "yaml", | |
| "args": "{{args}}", | |
| "extension": ".yaml" | |
| "format": "markdown", | |
| "args": "{{args}}", | |
| "extension": ".md" |
Description
This PR adds support for Block's Goose AI Agent to the spec-kit project. Goose is an open source AI agent (20.5k+ GitHub stars) that uses a "recipe" system with slash command support (merged in PR block/goose#5718, November 2025).
Key Features of Goose:
.goose/recipes/directory/implement)goose --instructions <recipe.yaml>or slash commandsChanges
src/specify_cli/__init__.pysrc/specify_cli/agents.py.github/workflows/scripts/create-release-packages.sh.github/workflows/scripts/create-release-packages.ps1scripts/bash/update-agent-context.shscripts/powershell/update-agent-context.ps1README.mdAGENTS.mdtests/test_agent_config_consistency.pyTesting
uv run specify --helpuv sync && uv run pytestNote: Test execution encountered a
json5import issue that appears to be a pre-existing environment problem, not related to the Goose integration changes themselves. The consistency tests for Goose follow the exact same pattern as other agents (e.g., iflow, pi).AI Disclosure