Add Zed integration#2780
Conversation
There was a problem hiding this comment.
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
ZedIntegrationclass registered in the integrations registry - Hook invocation rendering and init-flow handling for
zedskill 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.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
…am/main resolving conflicts
|
Side note, I have been using it last couple days and it works as expected |
|
Please address Copilot feedback and the test & lint errors |
- 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)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- 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
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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_modeandcursor_skill_modeare now unused after consolidating slash rendering intouse_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"
- 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
There was a problem hiding this comment.
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_mode
andcursor_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 computeuse_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.py
now 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 theALWAYS_SLASH_AGENTS/CONDITIONAL_SLASH_AGENTS` sets) so both init messaging and hook rendering stay consistent.
"""specify init command."""
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.
There was a problem hiding this comment.
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_modeandcursor_skill_modeare now computed but no longer used in_render_hook_invocation()after the switch toALWAYS_SLASH_AGENTS/CONDITIONAL_SLASH_AGENTS. Removing these locals (or reusing them in the newuse_slashlogic) 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"
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.
There was a problem hiding this comment.
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_modeandcursor_skill_modeare computed but no longer used after the refactor toALWAYS_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"
…_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.
|
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. |
mnriem
left a comment
There was a problem hiding this comment.
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 '/'.
|
Addressed the latest Copilot review comment (agy/trae invocation inconsistency) in 045afb9:
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)
- 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
|
Addressed all 4 new Copilot review comments in 3e750e8: 1-2. 3. Added parameterized 4. Centralized invocation-style logic — extracted |
| ALWAYS_SLASH_AGENTS: frozenset[str] = frozenset({"devin", "trae", "zed"}) | ||
| CONDITIONAL_SLASH_AGENTS: frozenset[str] = frozenset( | ||
| {"agy", "claude", "copilot", "cursor-agent"} | ||
| ) |
| 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 | ||
| ) |
| 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 | ||
| ) |
|
Please address Copilot feedback |
Summary
zedintegration that installs Spec Kit commands as Zed skills under.agents/skillsTesting
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 -qCloses #2779