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>
- Add agy_skill_mode and devin_skill_mode variables to fix F841 lint error - Use all skill mode variables in the slash-skill conditional check - Update --ai-skills help text to reflect it works with --integration too
05b7fac to
04d3eb3
Compare
|
Please address Copilot feedback and resolve conflicts by rebasing on upstream/main |
Trae is a SkillsIntegration like Zed/Agy/Devin, so it should also be treated as always-skills-based in hook invocation rendering.
AgyIntegration is a SkillsIntegration subclass with no --skills option, so it should be treated as always skills-based (like Zed, Devin, Trae). This aligns init.py skill mode detection with extensions.py hook rendering.
…sets Addressed Copilot review comments: - Restored _is_skills_integration guard on agy_skill_mode in init.py to be defensive about runtime integration type. - Refactored _render_hook_invocation() in extensions.py to use always_slash/conditional_slash frozensets instead of individual per-agent booleans, eliminating unused variables (F841) and making it harder for conditions to drift between integrations. - Centralized slash-skill determination so adding a new unconditional slash-skill integration is a one-key addition.
Resolved conflicts in extensions.py: - Adopted upstream/main's is_ai_skills_enabled(init_options) helper - Combined with always_slash/conditional_slash frozenset approach - Moved agy to conditional_slash (gated on ai_skills_enabled) - Kept existing reformatted code style for frozenset and imports
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
src/specify_cli/extensions.py:2652
claude_skill_modeandcursor_skill_modeare computed but no longer used after the refactor to thealways_slash/conditional_slashlogic. Removing these unused locals (or using them inuse_slash) will reduce dead code and keep the invocation selection easier to audit.
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"
- Added copilot to CONDITIONAL_SLASH_AGENTS for consistent hook invocation rendering with init.py - Moved always_slash/conditional_slash frozensets to module scope to avoid per-call reallocation - Replaced manual os.chdir() with monkeypatch.chdir() in test - Overrode test_options_include_skills_flag for Zed (no --skills)
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"
| assert "Executing: `/speckit-plan`" in message | ||
| assert "EXECUTE_COMMAND: speckit.plan" in message | ||
| assert "EXECUTE_COMMAND_INVOCATION: /speckit-plan" in message |
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