* Stage 3: Standard markdown integrations — 19 agents migrated to plugin architecture
Migrate all standard markdown integrations to self-contained subpackages
under integrations/. Each subclasses MarkdownIntegration with config-only
overrides (~10 lines per __init__.py).
Integrations migrated (19):
claude, qwen, opencode, junie, kilocode, auggie, roo, codebuddy,
qodercli, amp, shai, bob, trae, pi, iflow, kiro-cli, windsurf,
vibe, cursor-agent
Changes:
- Create integrations/<key>/ subpackage with __init__.py and scripts/
(update-context.sh, update-context.ps1) for each integration
- Register all 19 in INTEGRATION_REGISTRY (20 total with copilot)
- MarkdownIntegration.setup() processes templates (replaces {SCRIPT},
{ARGS}, __AGENT__; strips frontmatter blocks; rewrites paths)
- Extract install_scripts() to IntegrationBase; refactor copilot to use it
- Generalize --ai auto-promote from copilot-only to registry-driven:
any integration registered in INTEGRATION_REGISTRY auto-promotes.
Unregistered agents (gemini, tabnine, codex, kimi, agy, generic)
continue through the legacy --ai path unchanged.
- Fix cursor/cursor-agent key mismatch in CommandRegistrar.AGENT_CONFIGS
- Add missing vibe entry to CommandRegistrar.AGENT_CONFIGS
- Update kiro alias test to reflect auto-promote behavior
Testing:
- Per-agent test files (test_integration_<agent>.py) with shared mixin
- 1316 tests passing, 0 failures
- Complete file inventory tests for both sh and ps variants
- Byte-for-byte validated against v0.4.3 release packages (684 files)
* Address PR review: fix repo root detection and no-op test
- Fix repo root fallback in all 20 update-context.sh scripts: walk up
from script location to find .specify/ instead of falling back to pwd
- Fix repo root fallback in all 20 update-context.ps1 scripts: walk up
from script location to find .specify/ instead of falling back to $PWD
- Add assertions to test_setup_writes_to_correct_directory: verify
expected_dir exists and all command files reside under it
* Fix REPO_ROOT priority: prefer .specify walk-up over git root
In monorepos the git toplevel may differ from the project root that
contains .specify/. The previous fix still preferred git rev-parse
over the walk-up result.
Bash scripts (20): prefer the discovered _root when it contains
.specify/; only accept git root if it also contains .specify/.
PowerShell scripts (20): validate git root contains .specify/ before
using it; fall back to walking up from script directory otherwise.
* Guard git call with try/catch in PowerShell scripts
With $ErrorActionPreference = 'Stop', an unguarded git rev-parse
throws a terminating CommandNotFoundException when git is not
installed, preventing the .specify walk-up fallback from running.
Wrap the git call in try/catch across all 20 update-context.ps1
scripts so the fallback works reliably without git.
* Rename hyphenated package dirs to valid Python identifiers
Rename kiro-cli → kiro_cli and cursor-agent → cursor_agent so the
packages can be imported with normal Python syntax instead of
importlib. The user-facing integration key (IntegrationBase.key)
stays hyphenated to match the actual CLI tool / binary name.
Also reorganize _register_builtins(): imports and registrations
are now grouped alphabetically with clear section comments.
* Reuse CommandRegistrar path rewriting in process_template()
Replace the duplicated regex-based path rewriting in
MarkdownIntegration.process_template() with a call to the shared
CommandRegistrar._rewrite_project_relative_paths() implementation.
This ensures extension-local paths are preserved and boundary rules
stay consistent across the codebase.
* Promote _rewrite_project_relative_paths to public API
Rename CommandRegistrar._rewrite_project_relative_paths() to
rewrite_project_relative_paths() (drop leading underscore) so
integrations can call it without reaching into a private method
across subsystem boundaries.
Addresses PR review feedback:
https://github.com/github/spec-kit/pull/2038#discussion_r3022105627
* Broaden TestRegistrarKeyAlignment to cover all integration keys
Parametrize across ALL_INTEGRATION_KEYS instead of only checking
cursor-agent and vibe. Keeps a separate negative test for the
stale 'cursor' shorthand.
Addresses PR review feedback:
https://github.com/github/spec-kit/pull/2038#discussion_r3022269032
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.
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.
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.
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
- 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
None of the yaml.dump() calls specify allow_unicode=True, causing
non-ASCII characters in extension descriptions to be escaped to
\uXXXX sequences in generated .agent.md frontmatter and config files.
Add allow_unicode=True to all 6 yaml.dump() call sites, and
encoding="utf-8" to all corresponding write_text() and read_text()
calls to ensure consistent UTF-8 handling across platforms.
Add `iflow` as a supported AI agent (the key users pass to --ai) across
all relevant configuration files, release scripts, agent context
scripts, and README. Includes consistency tests following the same
pattern as kimi/tabnine additions.
- README: describe `check` generically (git + all AGENT_CONFIG CLI agents)
- README: describe `--ai` with reference to AGENT_CONFIG for full list
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(ai): add native support for Pi coding agent by pi+gpt 5.4
* docs(pi): document MCP limitations for Pi agent
* fix: unitended kimi agent mention added to update-agent-context.ps1
* fix: address reviewer feedback
* Apply suggestions from code review
Changes in AGENTS.md weren't part of my PR, but the Copilot feedback seems to be correct is correct. I've doublechecked it with contents of test_agent_config_consistency.py and create-release-packages scripts
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat: add Trae IDE support as a new agent
Add Trae (https://www.trae.ai/) as a supported AI agent in spec-kit.
Trae is an IDE-based agent that uses .trae/rules/ directory for
project-level rules in Markdown format.
Changes across 9 files:
- src/specify_cli/__init__.py: Add trae to AGENT_CONFIG (IDE-based,
.trae/ folder, rules subdir, no CLI required)
- src/specify_cli/extensions.py: Add trae to CommandRegistrar.AGENT_CONFIGS
(.trae/rules, markdown format, .md extension)
- README.md: Add Trae to supported agents table, CLI examples, and
--ai option description
- .github/workflows/scripts/create-release-packages.sh: Add trae to
ALL_AGENTS array and build case statement
- .github/workflows/scripts/create-release-packages.ps1: Add trae to
AllAgents array and switch statement
- .github/workflows/scripts/create-github-release.sh: Add trae template
zip files to release assets
- scripts/bash/update-agent-context.sh: Add TRAE_FILE, trae case in
update function, and auto-detect block
- scripts/powershell/update-agent-context.ps1: Add TRAE_FILE, ValidateSet
entry, switch case, and auto-detect block
- tests/test_agent_config_consistency.py: Add 8 consistency tests for
trae following established kimi/tabnine patterns
* fix: correct Generate-Commands parameter names for trae in PowerShell release script
Fix incorrect parameter names in the trae case of Build-Variant:
- -Format -> -Extension
- -ArgsToken -> -ArgFormat
- -OutDir -> -OutputDir
These now match the Generate-Commands function signature and all other
agent entries in the script.
Co-authored-by: Copilot <copilot@github.com>
* Update release packaging scripts and agent docs
* Update Agent.md
* Restore format
* Adjust order
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Unused
* fix: add TRAE_FILE to update_all_existing_agents() for auto-detect support
Add missing update_if_new call for TRAE_FILE in the bash
update-agent-context.sh script's update_all_existing_agents()
function, matching the PowerShell implementation.
This ensures running the script without arguments will correctly
auto-detect and update existing Trae agent files.
* Add configuration for 'trae' in agents.py
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Refactor trae configuration test for clarity
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Update update-agent-context.sh
* Fix formatting in update-agent-context.sh
---------
Co-authored-by: root <root@g340-cd52-700-60f9-5561-211-6c32.byted.org>
Co-authored-by: root <root@g340-cd52-700-c3d1-c735-796-4b9e.byted.org>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>