feat: add Forgecode agent support#2034
Conversation
- Add 'forgecode' to AGENT_CONFIGS in agents.py with .forge/commands
directory, markdown format, and {{parameters}} argument placeholder
- Add 'forgecode' to AGENT_CONFIG in __init__.py with .forge/ folder,
install URL, and requires_cli=True
- Add forgecode binary check in check_tool() mapping agent key
'forgecode' to the actual 'forge' CLI binary
- Add forgecode case to build_variant() in create-release-packages.sh
generating commands into .forge/commands/ with {{parameters}}
- Add forgecode to ALL_AGENTS in create-release-packages.sh
The forgecode agent hangs when listing commands because the 'handoffs'
frontmatter field (a Claude Code-specific feature) contains 'send: true'
entries that forge tries to act on when indexing .forge/commands/ files.
Additionally, $ARGUMENTS in command bodies was never replaced with
{{parameters}}, so user input was not passed through to commands.
Python path (agents.py):
- Add strip_frontmatter_keys: [handoffs] to the forgecode AGENT_CONFIG
entry so register_commands drops the key before rendering
Bash path (create-release-packages.sh):
- Add extra_strip_key parameter to generate_commands; pass 'handoffs'
for the forgecode case in build_variant
- Use regex prefix match (~ "^"extra_key":") instead of exact
equality to handle trailing whitespace after the YAML key
- Add sed replacement of $ARGUMENTS -> $arg_format in the body
pipeline so {{parameters}} is substituted in forgecode command files
Forgecode requires both 'name' and 'description' fields in command frontmatter. This commit adds automatic injection of the 'name' field during command generation for forgecode. Changes: - Python (agents.py): Add inject_name: True to forgecode config and implement name injection logic in register_commands - Bash (create-release-packages.sh): Add post-processing step to inject name field into frontmatter after command generation This complements the existing handoffs stripping fix (d83be82) to fully support forgecode command requirements.
Forgecode uses {{parameters}} instead of the standard $ARGUMENTS
placeholder. Updated test to check for the correct placeholder format
for forgecode agent.
- Added special case handling for forgecode in test_argument_token_format
- Updated docstring to document forgecode's {{parameters}} format
- Test now passes for all 26 agents including forgecode
Added forgecode agent to all relevant sections: - Added to Supported AI Agents table - Added to --ai option description - Added to specify check command examples - Added initialization example - Added to CLI tools check list in detailed walkthrough Forgecode is now fully documented alongside other supported agents.
There was a problem hiding this comment.
Pull request overview
Adds first-class support for the Forgecode agent (forge CLI) across Spec Kit’s scaffold generation, agent configuration, docs, and tests so users can run the spec-driven workflow using --ai forgecode.
Changes:
- Added Forgecode agent configuration (dirs, args placeholder
{{parameters}}, frontmatter adjustments) and CLI tool detection mapping (forgecode→forge). - Updated release packaging script to generate
.forge/commands, strip problematic frontmatter keys, inject requiredname, and replace argument placeholders appropriately. - Updated tests and README to include Forgecode in supported agents and validate placeholder output.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/agents.py |
Adds Forgecode agent config and frontmatter/placeholder handling during command registration. |
src/specify_cli/__init__.py |
Adds Forgecode to AGENT_CONFIG and maps forgecode tool checks to the forge binary. |
.github/workflows/scripts/create-release-packages.sh |
Generates Forgecode release artifacts under .forge/commands, strips handoffs, injects name, and replaces placeholders. |
tests/test_core_pack_scaffold.py |
Extends scaffold assertions to handle Forgecode’s {{parameters}} placeholder. |
README.md |
Documents Forgecode support and updates CLI usage examples/lists. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
Addresses Copilot PR feedback: Users should see the actual executable name 'forge' in status and error messages, not the agent key 'forgecode'. Changes: - Added 'cli_binary' field to forgecode AGENT_CONFIG (set to 'forge') - Updated check_tool() to accept optional display_key parameter - Updated check_tool() to use cli_binary from AGENT_CONFIG when available - Updated check() command to display cli_binary in StepTracker - Updated init() error message to show cli_binary instead of agent key UX improvements: - 'specify check' now shows: '● forge (available/not found)' - 'specify init --ai forgecode' error shows: 'forge not found' (instead of confusing 'forgecode not found') This makes it clear to users that they need to install the 'forge' binary, even though they selected the 'forgecode' agent.
✅ Addressed: Binary Name in User-Facing MessagesCopilot's Feedback:
Solution Implemented (commit I've added a generic Changes Made:
User Experience After Fix:✅ or ✅ Design Benefits:This solution is generic and reusable - any future agent where the binary name differs from the agent key can simply add a Testing:
The confusion identified by Copilot has been completely eliminated. 🎉 |
|
@ericnoam As per AGENTS.md, we adhere to |
📌 Note: This Feedback Has Already Been AddressedHi Copilot! 👋 This feedback was fully resolved in commit Your Concern:
Our Fix:We implemented your suggested mapping approach by adding a Current State (Post-Fix):All user-facing output now shows # specify check output
├── ● forge (available) # ✅ Shows 'forge'
# or when not installed:
├── ● forge (not found) # ✅ Shows 'forge'
# specify init error message
forge not found # ✅ Shows 'forge'
Install from: https://forgecode.dev/docs/Code Changes in c69893c:
Verification:✅ StepTracker key = No user-facing output refers to 'forgecode' anymore! 🎉 See my earlier comment for full details of the implementation. |
Aligns with AGENTS.md design principle: "Use the actual CLI tool name as the key, not a shortened version" (AGENTS.md:61-83). The actual CLI executable is 'forge', so the AGENT_CONFIG key should be 'forge' (not 'forgecode'). This follows the same pattern as other agents like cursor-agent and kiro-cli. Changes: - Renamed AGENT_CONFIG key: "forgecode" → "forge" - Removed cli_binary field (no longer needed) - Simplified check_tool() - removed cli_binary lookup logic - Simplified init() and check() - removed display_key mapping - Updated all tests: test_forge_name_field_in_frontmatter - Updated documentation: README.md Code simplification: - Removed 6 lines of workaround code - Removed 1 function parameter (display_key) - Eliminated all special-case logic for forge Note: No backward compatibility needed - forge is a new agent being introduced in this PR.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
When inject_name is enabled (for forge), alias command files must have their own name field in frontmatter, not reuse the primary command's name. This is critical for Forge's command discovery and dispatch system. Changes: - For agents with inject_name, create a deepcopy of frontmatter for each alias and set the name to the alias name - Re-render the command content with the alias-specific frontmatter - Ensures each alias file has the correct name field matching its filename This fixes command discovery issues where forge would try to invoke aliases using the primary command's name.
Addressed |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/specify_cli/init.py:323
- The runtime agent key is "forge", but the PR description uses
--ai forgecode. There is currently no alias mapping for "forgecode" (AI_ASSISTANT_ALIASES only contains "kiro" -> "kiro-cli"), sospecify init --ai forgecodewill error. Consider either updating documentation/examples to consistently useforge, or adding aforgecode -> forgealias to match the branding/URL and avoid user confusion.
"forge": {
"name": "Forge",
"folder": ".forge/",
"commands_subdir": "commands",
"install_url": "https://forgecode.dev/docs/",
"requires_cli": True,
},
"generic": {
"name": "Generic (bring your own agent)",
"folder": None, # Set dynamically via --ai-commands-dir
"commands_subdir": "commands",
"install_url": None,
"requires_cli": False,
},
}
AI_ASSISTANT_ALIASES = {
"kiro": "kiro-cli",
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1. PowerShell script (create-release-packages.ps1):
- Added forge agent support for Windows users
- Enables `specify init --ai forge --offline` on Windows
- Enhanced Generate-Commands with ExtraStripKey parameter
- Added frontmatter stripping for handoffs key
- Added $ARGUMENTS replacement for {{parameters}}
- Implemented forge case with name field injection
- Complete parity with bash script
2. Test file (test_core_pack_scaffold.py):
- Removed trailing whitespace from blank lines
- Cleaner diffs and no linter warnings
Addresses Copilot PR feedback on both issues.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
I merge it earlier but only modified those files where there was conflict |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PowerShell release script:
- Add deduplication pass to Rewrite-Paths function
- Prevents .specify.specify/ double prefixes in generated commands
- Matches bash script behavior with regex '(?:\.specify/){2,}' -> '.specify/'
Bash update-agent-context script:
- Consolidate AGENTS.md updates to single call
- Remove redundant calls for $AMP_FILE, $KIRO_FILE, $BOB_FILE, $FORGE_FILE
- Update label to 'Codex/opencode/Amp/Kiro/Bob/Pi/Forge' to reflect all agents
- Prevents always-deduped $FORGE_FILE call that never executed
Both fixes improve efficiency and correctness while maintaining parity
between bash and PowerShell implementations.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Can you pull in the latest changes from upstream/main ? You'll notice that you now only should have to deal with the ingration file and its test file. I appreciate you working through this. The timing just was a bit tricky for all of this. Thanks a LOT! |
…ipts
- Remove unused _parse_rate_limit_headers() and _format_rate_limit_error()
from src/specify_cli/__init__.py (56 lines of dead code)
- Add GENRELEASES_DIR override support to PowerShell release script with
comprehensive safety checks (parity with bash script)
- Remove redundant shared-file update calls from PowerShell agent context
script (AMP_FILE, KIRO_FILE, BOB_FILE, FORGE_FILE all resolve to AGENTS.md)
- Update test docstring to accurately reflect Forge's {{parameters}} token
Changes align PowerShell scripts with bash equivalents and reduce maintenance
burden by removing dead code.
- Add 'forge' to usage message in Print-Summary (was missing from list) - Reorder ValidateSet to match bash script order (vibe before qodercli) This ensures PowerShell script documentation matches bash script and includes all supported agents consistently.
You mean but now I wonder whether it be easier to delete this PR and start one from the new code... |
|
Whichever way you decide I will work with you! |
Or...
|
Remove files that were deleted in b1832c9 (Stage 6 migration) but remained on this branch due to merge conflicts: - Remove .github/workflows/scripts/create-release-packages.{sh,ps1} (replaced by inline release.yml + uv tool install) - Remove tests/test_core_pack_scaffold.py (scaffold system removed, tests no longer relevant) These files existed on the feature branch because they were modified before b1832c9 landed. The merge kept our versions, but they should be deleted to align with the new integration-only architecture. This PR now focuses purely on adding NEW Forge integration support, not restoring old architecture.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/forge/init.py:42
registrar_configdeclaresstrip_frontmatter_keysandinject_name, butForgeIntegration.setup()/_apply_forge_transformations()currently hard-code strippinghandoffsand always perform name injection logic instead of deriving behavior from those config fields. This duplication can drift over time (e.g., adding another key to strip would updateregistrar_configbut not the transformation). Consider driving the transformations fromself.registrar_config(keys-to-strip + inject toggle) so config remains the single source of truth.
registrar_config = {
"dir": ".forge/commands",
"format": "markdown",
"args": "{{parameters}}",
"extension": ".md",
"strip_frontmatter_keys": ["handoffs"],
"inject_name": True,
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Please address Copilot feedback. If not applicable, please explain why |
Update docstrings to accurately explain that the 'handoffs' frontmatter key is from Claude Code (for multi-agent collaboration) and is stripped because it causes Forge to hang, not because it's a Forge-specific feature. Changes: - Module docstring: 'Forge-specific collaboration feature' → 'Claude Code feature that causes Forge to hang' - Class docstring: Add '(incompatible with Forge)' clarification - Method docstring: Add '(from Claude Code templates; incompatible with Forge)' context This avoids implying that handoffs belongs to Forge when it actually comes from spec-kit templates designed for Claude Code compatibility.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thank you! |
Description
This PR adds full support for the Forge agent (https://forgecode.dev/) to Spec Kit, enabling users to run the spec-driven development workflow using the
forgeCLI.What Changed
Core Implementation:
AGENT_CONFIGinsrc/specify_cli/__init__.pyandsrc/specify_cli/agents.pyforge(following AGENTS.md design principle)strip_frontmatter_keys: ["handoffs"]- Strips Claude Code-specific handoffs fieldinject_name: True- Automatically injects requirednamefieldargs: "{{parameters}}"- Uses Forge's parameter syntax instead of$ARGUMENTS.github/workflows/scripts/create-release-packages.sh).github/workflows/scripts/create-release-packages.ps1)Test Updates:
test_argument_token_formatto handle Forge's{{parameters}}syntaxtest_forge_name_field_in_frontmatterto validate frontmatter requirementsDocumentation:
--aioption descriptionsWhy This Is Needed
Forge is a popular AI coding assistant with a growing user base. Adding support allows Spec Kit users to leverage Forge's capabilities for spec-driven development workflows.
Technical Details
Forge-Specific Requirements:
nameanddescriptionfields in command frontmatter (unlike most agents that only needdescription)handoffsfield from Claude Code templates caused Forge to hang during command listing{{parameters}}instead of the standard$ARGUMENTSplaceholderforgeas the agent key (notforgecode) to match the actualforgeexecutable, following AGENTS.md design principleTesting
uv run specify --helpuv sync && uv run pytest(901/910 passing)specify init . --ai forge --offlinesuccessfullyforge cmd listshows all 9 speckit commands without hanging{{parameters}}placeholder is correctly replacedTest Results:
AI Disclosure
AI Assistance:
This PR was developed with the assistance of Forge agent (using the Claude Sonnet 4.5 model). The AI helped with:
All code was reviewed, tested, and validated by the human contributor before committing.
Related Issues
N/A - This is a new feature addition
Note: This PR demonstrates Spec Kit's extensibility in supporting diverse AI agents with varying requirements and formats.