Skip to content

Add Zed integration#2780

Open
arrrrny wants to merge 25 commits into
github:mainfrom
arrrrny:feat/2779-zed-integration
Open

Add Zed integration#2780
arrrrny wants to merge 25 commits into
github:mainfrom
arrrrny:feat/2779-zed-integration

Conversation

@arrrrny

@arrrrny arrrrny commented May 31, 2026

Copy link
Copy Markdown

Summary

  • add a built-in zed integration that installs Spec Kit commands as Zed skills under .agents/skills
  • render Zed skill invocations correctly in init next-steps output and hook messages
  • add integration coverage for Zed plus registry/list assertions and docs updates

Testing

  • uv run --extra test python3 -m pytest tests/integrations/test_registry.py tests/integrations/test_integration_subcommand.py::TestIntegrationList::test_list_shows_available_integrations tests/integrations/test_integration_zed.py -q

Closes #2779

@arrrrny arrrrny requested a review from mnriem as a code owner May 31, 2026 08:39
Copilot AI review requested due to automatic review settings May 31, 2026 08:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds Zed editor as a new skills-based integration that installs Spec Kit commands as .agents/skills/speckit-<name>/SKILL.md files invokable via Zed's slash-command menu.

Changes:

  • New ZedIntegration class registered in the integrations registry
  • Hook invocation rendering and init-flow handling for zed skill mode
  • Documentation, registry, and integration-test updates including a new test_integration_zed.py

Reviewed changes

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

Show a summary per file
File Description
src/specify_cli/integrations/zed/init.py New ZedIntegration (skills-based, .agents/skills, AGENTS.md)
src/specify_cli/integrations/init.py Imports and registers ZedIntegration
src/specify_cli/extensions.py Adds zed_skill_mode branch rendering /skill-name invocations
src/specify_cli/commands/init.py Adds Zed to skill-mode flags, post-init step, and display command logic
docs/reference/integrations.md Adds Zed row to integrations table
docs/index.md Bumps integration count from 30 to 31 and lists Zed
tests/integrations/test_registry.py Adds zed to expected-keys list
tests/integrations/test_integration_subcommand.py Asserts zed appears in list output
tests/integrations/test_integration_zed.py New tests for Zed integration and hook invocation rendering

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

Comment thread src/specify_cli/integrations/zed/__init__.py Outdated

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address Copilot feedback

@arrrrny

arrrrny commented Jun 1, 2026

Copy link
Copy Markdown
Author

Side note, I have been using it last couple days and it works as expected

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 1

Comment thread docs/index.md Outdated
@mnriem

mnriem commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Please address Copilot feedback and the test & lint errors

Copilot AI review requested due to automatic review settings June 2, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 6 comments.

Comment thread src/specify_cli/commands/init.py Outdated
Comment thread src/specify_cli/commands/init.py
Comment thread src/specify_cli/commands/init.py Outdated
Comment thread src/specify_cli/extensions.py Outdated
Comment thread src/specify_cli/extensions.py Outdated
Comment thread src/specify_cli/integrations/zed/__init__.py Outdated
- Remove non-actionable --skills flag from ZedIntegration (Zed is always
  skills-based, like Agy)
- Align zed_skill_mode predicate with ai_skills for consistency across
  init output and hook rendering
- Consolidate claude/cursor/zed slash-skill return blocks in
  _render_hook_invocation to reduce duplication
- Override test_options_include_skills_flag for Zed (no --skills flag)
@arrrrny arrrrny requested a review from mnriem June 2, 2026 23:22
@mnriem mnriem requested a review from Copilot June 3, 2026 13:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 1

Comment thread src/specify_cli/integrations/zed/__init__.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 3, 2026 14:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 2 comments.

Comment thread src/specify_cli/extensions.py Outdated
Comment thread tests/integrations/test_integration_zed.py Outdated
- Make zed_skill_mode unconditional in hook rendering (Zed is always
  skills-based, no --skills option)
- Add test_init_persists_ai_skills_for_zed that exercises the actual
  CLI init path and verifies HookExecutor renders /speckit-plan
  without manual init-options manipulation

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 2

Comment thread docs/index.md Outdated
Comment thread docs/index.md Outdated

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address Copilot feedback

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 4, 2026 03:52
@arrrrny arrrrny requested review from Copilot and mnriem June 5, 2026 17:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

src/specify_cli/extensions.py:2660

  • claude_skill_mode and cursor_skill_mode are now unused after consolidating slash rendering into use_slash. Please remove these locals (or incorporate them into the new logic) to avoid dead code and potential lint failures.
        codex_skill_mode = selected_ai == "codex" and ai_skills_enabled
        claude_skill_mode = selected_ai == "claude" and ai_skills_enabled
        kimi_skill_mode = selected_ai == "kimi"
        cursor_skill_mode = selected_ai == "cursor-agent" and ai_skills_enabled
        cline_mode = selected_ai == "cline"

Comment thread src/specify_cli/extensions.py Outdated
Comment thread src/specify_cli/commands/init.py Outdated
Comment thread docs/index.md Outdated
Comment thread docs/index.md Outdated
arrrrny and others added 2 commits June 5, 2026 23:09
- Removed redundant local import yaml in _register_extension_skills
  (yaml is already imported at module scope)
- Split --ai-skills usage hint into two separate print statements
  for better readability
- Changed integrations count from '33' to '30+' to avoid future drift
Copilot AI review requested due to automatic review settings June 5, 2026 20:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/specify_cli/extensions.py:2632

  • claude_skill_modeandcursor_skill_modeare computed but no longer used after the refactor toCONDITIONAL_SLASH_AGENTS. This adds dead code and can confuse future changes. Recommended: remove these unused locals, or use them directly to compute use_slash` (single-source-of-truth).
        codex_skill_mode = selected_ai == "codex" and ai_skills_enabled
        claude_skill_mode = selected_ai == "claude" and ai_skills_enabled
        kimi_skill_mode = selected_ai == "kimi"
        cursor_skill_mode = selected_ai == "cursor-agent" and ai_skills_enabled
        cline_mode = selected_ai == "cline"

src/specify_cli/commands/init.py:1

  • init.pynow hard-codes a growing matrix of “skill mode” flags and repeats invocation-style logic that also exists inHookExecutor(e.g., which agents use/speckit-). This increases drift risk as more integrations are added. Suggested approach: centralize “invocation style” in a shared helper (or reuse the ALWAYS_SLASH_AGENTS/CONDITIONAL_SLASH_AGENTS` sets) so both init messaging and hook rendering stay consistent.
"""specify init command."""

Comment thread src/specify_cli/commands/init.py
The _is_skills_integration variable was accidentally dropped during the
web UI merge resolution of upstream/main's removal of legacy --ai flags.
Re-added the definition via isinstance(resolved_integration, SkillsIntegration)
check so that skill-mode booleans work correctly.
@arrrrny arrrrny requested a review from Copilot June 5, 2026 20:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/specify_cli/extensions.py:2632

  • claude_skill_mode and cursor_skill_mode are now computed but no longer used in _render_hook_invocation() after the switch to ALWAYS_SLASH_AGENTS / CONDITIONAL_SLASH_AGENTS. Removing these locals (or reusing them in the new use_slash logic) will reduce dead code and prevent future confusion about which branch controls Claude/Cursor behavior.
        codex_skill_mode = selected_ai == "codex" and ai_skills_enabled
        claude_skill_mode = selected_ai == "claude" and ai_skills_enabled
        kimi_skill_mode = selected_ai == "kimi"
        cursor_skill_mode = selected_ai == "cursor-agent" and ai_skills_enabled
        cline_mode = selected_ai == "cline"

Comment thread src/specify_cli/commands/init.py Outdated
Aligns zed_skill_mode with the other skills-based agents (codex, claude,
cursor-agent, copilot) which all use _is_skills_integration gating.
Since ZedIntegration extends SkillsIntegration, behavior is unchanged.
@arrrrny arrrrny requested a review from Copilot June 5, 2026 20:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/specify_cli/extensions.py:2632

  • claude_skill_mode and cursor_skill_mode are computed but no longer used after the refactor to ALWAYS_SLASH_AGENTS / CONDITIONAL_SLASH_AGENTS. Please remove these locals (preferred), or update the subsequent logic to use them, to avoid dead code and reduce confusion during future edits.
        codex_skill_mode = selected_ai == "codex" and ai_skills_enabled
        claude_skill_mode = selected_ai == "claude" and ai_skills_enabled
        kimi_skill_mode = selected_ai == "kimi"
        cursor_skill_mode = selected_ai == "cursor-agent" and ai_skills_enabled
        cline_mode = selected_ai == "cline"

Comment thread tests/integrations/test_integration_zed.py Outdated
…_render_hook_invocation

These variables became unused after the refactor to ALWAYS_SLASH_AGENTS /
CONDITIONAL_SLASH_AGENTS sets. Claude and Cursor-Agent are now handled by the
CONDITIONAL_SLASH_AGENTS path, so the separate boolean locals are dead code.

Fixes ruff F841 and addresses Copilot review feedback that was repeated across
multiple review rounds.
@arrrrny

arrrrny commented Jun 6, 2026

Copy link
Copy Markdown
Author

Hi @mnriem My ZED editor did some unncessary formatting, I did ruff but still same. Can you still merge and if do the formatting later? I did all copilots requested changes, behavioral changes are solid.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 1

Comment thread src/specify_cli/extensions.py

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please address Copilot feedback

…ndering and build_command_invocation

- Moved agy and trae from '-<name>' (dollar/Codex format) to
  '/speckit-<name>' (slash format) in _display_cmd() to match:
  - HookExecutor._render_hook_invocation() (ALWAYS_SLASH_AGENTS for trae,
    CONDITIONAL_SLASH_AGENTS for agy)
  - SkillsIntegration.build_command_invocation() (default: /speckit-<name>)
- The '$' prefix is specific to Codex; all other skills agents use '/'.
@arrrrny

arrrrny commented Jun 9, 2026

Copy link
Copy Markdown
Author

Addressed the latest Copilot review comment (agy/trae invocation inconsistency) in 045afb9:

  • Moved agy_skill_mode and trae_skill_mode from the $speckit-{name} (Codex-specific) branch to the /speckit-{name} (standard slash format) branch in _display_cmd() in init.py
  • Now consistent with:
    • HookExecutor._render_hook_invocation() (trae in ALWAYS_SLASH_AGENTS, agy in CONDITIONAL_SLASH_AGENTS)
    • SkillsIntegration.build_command_invocation() (default: returns /speckit-<name>)

Also addressed the earlier F841 unused-variable comments (claude_skill_mode, cursor_skill_mode) in 5f3cdb4.

Resolved conflicts:
- src/specify_cli/commands/init.py: function param formatting + removed
  git init / branch_numbering code from upstream/main (Zed-specific
  additions preserved)
- src/specify_cli/extensions.py: cache write encoding (accepted
  upstream/main's utf-8 + OSError handling)
- tests/integrations/test_integration_zed.py: removed --no-git flag
  (no longer accepted by the CLI)
Copilot AI review requested due to automatic review settings June 9, 2026 18:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 9 out of 9 changed files in this pull request and generated 4 comments.

Comment thread tests/integrations/test_integration_zed.py Outdated
Comment thread tests/integrations/test_integration_zed.py Outdated
Comment thread src/specify_cli/extensions.py
Comment thread src/specify_cli/commands/init.py
- Add is_slash_skills_agent() helper to extensions.py to centralize the
  agent-to-invocation-format mapping, reducing drift risk between
  HookExecutor._render_hook_invocation() and init.py _display_cmd()
- Use the shared helper in both locations; init.py now imports and
  delegates to is_slash_skills_agent() instead of maintaining its own
  per-agent boolean matrix
- Fix test_hooks_render_skill_invocation to use ai_skills=False,
  proving Zed renders /speckit-<name> unconditionally
- Add parameterized TestSlashSkillsSets covering all agents in
  ALWAYS_SLASH_AGENTS and CONDITIONAL_SLASH_AGENTS with ai_skills
  both true and false
@arrrrny

arrrrny commented Jun 9, 2026

Copy link
Copy Markdown
Author

Addressed all 4 new Copilot review comments in 3e750e8:

1-2. test_hooks_render_skill_invocation now uses ai_skills: False — proves Zed unconditionally renders /speckit-plan even when ai_skills is disabled.

3. Added parameterized TestSlashSkillsSets — 14 test cases covering every agent in ALWAYS_SLASH_AGENTS (devin, trae, zed) and CONDITIONAL_SLASH_AGENTS (agy, claude, copilot, cursor-agent), each with ai_skills both True and False, asserting the expected invocation format. This locks in the semantic contract of the shared constant sets.

4. Centralized invocation-style logic — extracted is_slash_skills_agent(selected_ai, ai_skills_enabled) as a module-level helper in extensions.py. Both HookExecutor._render_hook_invocation() and init.py's _display_cmd() now delegate to this single function instead of maintaining duplicate per-agent boolean matrices. Adding a new agent to ALWAYS_SLASH_AGENTS / CONDITIONAL_SLASH_AGENTS now automatically updates both hook rendering and init messaging.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment on lines +48 to +51
ALWAYS_SLASH_AGENTS: frozenset[str] = frozenset({"devin", "trae", "zed"})
CONDITIONAL_SLASH_AGENTS: frozenset[str] = frozenset(
{"agy", "claude", "copilot", "cursor-agent"}
)
Comment on lines +55 to +67
def is_slash_skills_agent(selected_ai: str, ai_skills_enabled: bool) -> bool:
"""Return True if *selected_ai* uses ``/speckit-<name>`` hook invocations.

The decision is based on the agent sets defined above:

* Agents in `ALWAYS_SLASH_AGENTS` always use slash invocations.
* Agents in `CONDITIONAL_SLASH_AGENTS` only use them when
*ai_skills_enabled* is ``True``.
* All other agents return ``False``.
"""
return selected_ai in ALWAYS_SLASH_AGENTS or (
selected_ai in CONDITIONAL_SLASH_AGENTS and ai_skills_enabled
)
Comment on lines +702 to +712
native_skill_mode = (
codex_skill_mode
or claude_skill_mode
or kimi_skill_mode
or agy_skill_mode
or trae_skill_mode
or cursor_agent_skill_mode
or copilot_skill_mode
or devin_skill_mode
or zed_skill_mode
)
@mnriem

mnriem commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Please address Copilot feedback

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.

[Agent]: Add support for Zed

3 participants