Skip to content

Stage 3: Standard markdown integrations — 19 agents migrated to plugin architecture#2038

Merged
mnriem merged 8 commits intogithub:mainfrom
mnriem:issue-1924-stage-3
Apr 1, 2026
Merged

Stage 3: Standard markdown integrations — 19 agents migrated to plugin architecture#2038
mnriem merged 8 commits intogithub:mainfrom
mnriem:issue-1924-stage-3

Conversation

@mnriem
Copy link
Copy Markdown
Collaborator

@mnriem mnriem commented Mar 31, 2026

Summary

Migrate all 19 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 (test_integration_base_markdown.py)
  • 1316 tests passing, 0 failures
  • Complete file inventory tests for both --script sh and --script ps variants
  • Byte-for-byte validated against v0.4.3 release packages (684 files compared — 342 sh + 342 ps — 0 command/template differences)

Wheel size

214 KB — contains all 20 integrations, templates, scripts, and the CLI. Compared to 3+ MB of release ZIPs (52 files), this is a ~93% reduction.


Part of #1924

…n 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)
Copilot AI review requested due to automatic review settings March 31, 2026 23:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates 19 “standard markdown” agents to the new plugin-based integrations/ architecture by introducing one subpackage per integration and registering them in INTEGRATION_REGISTRY, with corresponding tests validating registry completeness, registrar alignment, and per-integration file inventories.

Changes:

  • Added 19 new MarkdownIntegration subclasses under src/specify_cli/integrations/<key>/ and registered them in INTEGRATION_REGISTRY.
  • Refactored script installation into IntegrationBase.install_scripts() and updated MarkdownIntegration.setup() to process templates + install per-integration scripts.
  • Expanded/updated test suite with a reusable markdown integration test mixin and per-integration test modules; updated --ai auto-promote behavior tests.

Reviewed changes

Copilot reviewed 84 out of 85 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_ai_skills.py Updates kiro alias test to assert --ai auto-promotes to --integration and files are created.
tests/integrations/test_registry.py Adds registry completeness checks and registrar key alignment assertions (cursor-agent/vibe).
tests/integrations/test_integration_windsurf.py Adds Windsurf integration test via shared markdown mixin.
tests/integrations/test_integration_vibe.py Adds Vibe integration test via shared markdown mixin.
tests/integrations/test_integration_trae.py Adds Trae integration test via shared markdown mixin.
tests/integrations/test_integration_shai.py Adds Shai integration test via shared markdown mixin.
tests/integrations/test_integration_roo.py Adds Roo integration test via shared markdown mixin.
tests/integrations/test_integration_qwen.py Adds Qwen integration test via shared markdown mixin.
tests/integrations/test_integration_qodercli.py Adds Qoder CLI integration test via shared markdown mixin.
tests/integrations/test_integration_pi.py Adds Pi integration test via shared markdown mixin.
tests/integrations/test_integration_opencode.py Adds Opencode integration test via shared markdown mixin.
tests/integrations/test_integration_kiro_cli.py Adds Kiro CLI integration test via shared markdown mixin.
tests/integrations/test_integration_kilocode.py Adds Kilocode integration test via shared markdown mixin.
tests/integrations/test_integration_junie.py Adds Junie integration test via shared markdown mixin.
tests/integrations/test_integration_iflow.py Adds iFlow integration test via shared markdown mixin.
tests/integrations/test_integration_cursor_agent.py Adds Cursor Agent integration test via shared markdown mixin.
tests/integrations/test_integration_copilot.py Adds comprehensive Copilot integration tests (setup, manifests, inventories, uninstall behavior).
tests/integrations/test_integration_codebuddy.py Adds CodeBuddy integration test via shared markdown mixin.
tests/integrations/test_integration_claude.py Adds Claude integration test via shared markdown mixin.
tests/integrations/test_integration_bob.py Adds Bob integration test via shared markdown mixin.
tests/integrations/test_integration_base_markdown.py Introduces shared markdown integration test mixin + inventory expectations.
tests/integrations/test_integration_auggie.py Adds Auggie integration test via shared markdown mixin.
tests/integrations/test_integration_amp.py Adds Amp integration test via shared markdown mixin.
src/specify_cli/integrations/windsurf/scripts/update-context.sh Adds Windsurf wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/windsurf/scripts/update-context.ps1 Adds Windsurf PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/windsurf/init.py Adds Windsurf integration config-only subclass.
src/specify_cli/integrations/vibe/scripts/update-context.sh Adds Vibe wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/vibe/scripts/update-context.ps1 Adds Vibe PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/vibe/init.py Adds Vibe integration config-only subclass.
src/specify_cli/integrations/trae/scripts/update-context.sh Adds Trae wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/trae/scripts/update-context.ps1 Adds Trae PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/trae/init.py Adds Trae integration config-only subclass.
src/specify_cli/integrations/shai/scripts/update-context.sh Adds Shai wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/shai/scripts/update-context.ps1 Adds Shai PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/shai/init.py Adds Shai integration config-only subclass.
src/specify_cli/integrations/roo/scripts/update-context.sh Adds Roo wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/roo/scripts/update-context.ps1 Adds Roo PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/roo/init.py Adds Roo integration config-only subclass.
src/specify_cli/integrations/qwen/scripts/update-context.sh Adds Qwen wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/qwen/scripts/update-context.ps1 Adds Qwen PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/qwen/init.py Adds Qwen integration config-only subclass.
src/specify_cli/integrations/qodercli/scripts/update-context.sh Adds Qoder CLI wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/qodercli/scripts/update-context.ps1 Adds Qoder CLI PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/qodercli/init.py Adds Qoder CLI integration config-only subclass.
src/specify_cli/integrations/pi/scripts/update-context.sh Adds Pi wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/pi/scripts/update-context.ps1 Adds Pi PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/pi/init.py Adds Pi integration config-only subclass.
src/specify_cli/integrations/opencode/scripts/update-context.sh Adds Opencode wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/opencode/scripts/update-context.ps1 Adds Opencode PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/opencode/init.py Adds Opencode integration config-only subclass.
src/specify_cli/integrations/kiro-cli/scripts/update-context.sh Adds Kiro CLI wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/kiro-cli/scripts/update-context.ps1 Adds Kiro CLI PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/kiro-cli/init.py Adds Kiro CLI integration config-only subclass.
src/specify_cli/integrations/kilocode/scripts/update-context.sh Adds Kilocode wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/kilocode/scripts/update-context.ps1 Adds Kilocode PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/kilocode/init.py Adds Kilocode integration config-only subclass.
src/specify_cli/integrations/junie/scripts/update-context.sh Adds Junie wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/junie/scripts/update-context.ps1 Adds Junie PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/junie/init.py Adds Junie integration config-only subclass.
src/specify_cli/integrations/iflow/scripts/update-context.sh Adds iFlow wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/iflow/scripts/update-context.ps1 Adds iFlow PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/iflow/init.py Adds iFlow integration config-only subclass.
src/specify_cli/integrations/cursor-agent/scripts/update-context.sh Adds Cursor Agent wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/cursor-agent/scripts/update-context.ps1 Adds Cursor Agent PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/cursor-agent/init.py Adds Cursor Agent integration config-only subclass.
src/specify_cli/integrations/copilot/init.py Refactors Copilot integration to use install_scripts() helper.
src/specify_cli/integrations/codebuddy/scripts/update-context.sh Adds CodeBuddy wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/codebuddy/scripts/update-context.ps1 Adds CodeBuddy PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/codebuddy/init.py Adds CodeBuddy integration config-only subclass.
src/specify_cli/integrations/claude/scripts/update-context.sh Adds Claude wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/claude/scripts/update-context.ps1 Adds Claude PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/claude/init.py Adds Claude integration config-only subclass.
src/specify_cli/integrations/bob/scripts/update-context.sh Adds Bob wrapper script delegating to shared update-agent-context.
src/specify_cli/integrations/bob/scripts/update-context.ps1 Adds Bob PowerShell wrapper delegating to shared update-agent-context.
src/specify_cli/integrations/bob/init.py Adds Bob integration config-only subclass.
src/specify_cli/integrations/base.py Adds install_scripts() and implements MarkdownIntegration.setup() template processing + script install.
src/specify_cli/integrations/init.py Registers all Stage 3 integrations in INTEGRATION_REGISTRY (including hyphenated keys via importlib).
src/specify_cli/agents.py Fixes cursor key mismatch (cursor-agent) and adds missing vibe registrar entry.
src/specify_cli/init.py Generalizes --ai auto-promote behavior to any registered integration (not just copilot).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- 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
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 86 out of 87 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 86 out of 87 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 86 out of 87 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 86 out of 87 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.
@mnriem mnriem requested a review from Copilot April 1, 2026 13:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 86 out of 87 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (3)

src/specify_cli/integrations/windsurf/scripts/update-context.ps1:1

  • The wrapper invokes the shared PowerShell script but doesn’t explicitly propagate its exit code, and it builds the path via string interpolation with /. For better Windows robustness and consistent failure signaling, build the path with Join-Path (or equivalent) and explicitly exit with the invoked script’s status so CI/automation can reliably detect failures.
    tests/integrations/test_integration_base_markdown.py:1
  • os.access(..., os.X_OK) is platform-dependent (notably on Windows, where executable bits may not behave like POSIX). If the test suite runs on Windows, this assertion is likely to fail even if the script was installed correctly. Consider making this assertion conditional on a POSIX platform, or assert a different invariant cross-platform (e.g., file exists + shebang present) and keep the executable-bit check only where it’s meaningful.
    tests/test_ai_skills.py:1
  • This test asserts on a specific CLI tip substring (--integration kiro-cli) which may change with formatting (Rich styling), wording, or localization, making it more brittle than necessary. Since the next assertion already validates the effective behavior (files created under .kiro/prompts), consider either removing the output assertion or relaxing it to a less presentation-dependent check.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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:
github#2038 (comment)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 87 out of 88 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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:
github#2038 (comment)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 87 out of 88 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.

@mnriem mnriem merged commit 255371d into github:main Apr 1, 2026
12 checks passed
@mnriem mnriem deleted the issue-1924-stage-3 branch April 1, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants