Install Claude Code as native skills and align preset/integration flows#2051
Install Claude Code as native skills and align preset/integration flows#2051mnriem merged 8 commits intogithub:mainfrom
Conversation
Done. I moved the Claude-specific tests into I also reran the affected test files after the move to make sure this was only organizational and didn’t change behavior. |
There was a problem hiding this comment.
Pull request overview
This PR migrates Claude Code support from legacy .claude/commands generated slash-command files to native Claude skills under .claude/skills/<skill>/SKILL.md, and updates init/preset/hook flows and documentation to match the new invocation model.
Changes:
- Added a dedicated Claude integration that generates skills at
.claude/skills/<speckit-*>/SKILL.mdand installs integration scripts. - Updated
specify init --ai claudebehavior and CLI messaging to default to Claude skill invocations like/speckit-plan. - Fixed preset skill propagation to create missing skill directories when presets introduce new commands, and added targeted Claude integration/init/preset/hook tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/claude/__init__.py |
Implements ClaudeIntegration writing native skill layout and frontmatter. |
src/specify_cli/__init__.py |
Adds Claude skill migration/autopromotion and updates init usage output for Claude skills. |
src/specify_cli/extensions.py |
Renders hook command invocations as /speckit-* when Claude skills are enabled. |
src/specify_cli/presets.py |
Ensures preset-provided commands propagate into skills, creating missing skill dirs when needed. |
tests/integrations/test_integration_claude.py |
Adds integration and init flow tests covering Claude skill generation and messaging. |
tests/test_ai_skills.py |
Updates/removes tests tied to legacy Claude commands and relaxes help-text assertion. |
README.md |
Updates docs/examples to describe Claude’s skills-first workflow and invocation syntax. |
💡 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
Keep Claude on the skills integration path and align preset-generated Claude skill frontmatter with the core integration.
Done |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
💡 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. If not applicable, please explain why
|
Addressed one suggestion directly and reviewed the other in detail. What I fixed:
What I did not change:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
💡 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 keeping in mind that the legacy path will very soon be removed
|
Addressed. I removed the test from the legacy-path suite and replaced it with a CLI-level test that covers the current Claude integration behavior instead. It now verifies that |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 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.
|
Thank you! |
- Fix circular import: move CommandRegistrar import in claude integration to inside method bodies (was at module level) - Lazy-populate AGENT_CONFIGS via _ensure_configs() to avoid circular import at class definition time - Set claude registrar_config to .claude/commands (extension/preset target) since the integration handles .claude/skills in setup() - Update tests from github#2051 to match: registrar_config assertions, remove --integration tip assertions, remove install_ai_skills mocks 1086 tests pass.
Restore ClaudeIntegration.registrar_config to .claude/skills (not .claude/commands) so extension/preset registrations write to the correct skills directory. Update tests that simulate claude setup to use .claude/skills and check for SKILL.md layout. Some tests still need updating for the full skills path — 10 remaining failures from the github#2051 test expectations around the extension/preset skill registration flow. WIP: 1076/1086 pass.
|
@afurm I noticed we have a mix of references to skills using both Is this intentional? ...is the project switching to dash? I noticed after taking this code i now see both:
Thank you! |
) * Stage 6: Complete migration — remove legacy scaffold path (#1924) Remove the legacy GitHub download and offline scaffold code paths. All 26 agents now use the integration system exclusively. Code removal (~1073 lines from __init__.py): - download_template_from_github(), download_and_extract_template() - scaffold_from_core_pack(), _locate_release_script() - install_ai_skills(), _get_skills_dir (restored slim version for presets) - _has_bundled_skills(), _migrate_legacy_kimi_dotted_skills() - AGENT_SKILLS_MIGRATIONS, _handle_agent_skills_migration() - _parse_rate_limit_headers(), _format_rate_limit_error() - Three-way branch in init() collapsed to integration-only Config derivation (single source of truth): - AGENT_CONFIG derived from INTEGRATION_REGISTRY (replaced 180-line dict) - CommandRegistrar.AGENT_CONFIGS derived from INTEGRATION_REGISTRY (replaced 160-line dict) - Backward-compat constants kept for presets/extensions: SKILL_DESCRIPTIONS, NATIVE_SKILLS_AGENTS, DEFAULT_SKILLS_DIR Release pipeline cleanup: - Deleted create-release-packages.sh/.ps1 (948 lines of ZIP packaging) - Deleted create-github-release.sh, generate-release-notes.sh - Deleted simulate-release.sh, get-next-version.sh, update-version.sh - Removed .github/workflows/scripts/ directory entirely - release.yml is now self-contained: check, notes, release all inlined - Install instructions use uv tool install with version tag Test cleanup: - Deleted test_ai_skills.py (tested removed functions) - Deleted test_core_pack_scaffold.py (tested removed scaffold) - Cleaned test_agent_config_consistency.py (removed 19 release-script tests) - Fixed test_branch_numbering.py (removed dead monkeypatches) - Updated auto-promote tests (verify files created, not tip messages) 1089 tests pass, 0 failures, ruff clean. * fix: resolve merge conflicts with #2051 (claude as skills) - Fix circular import: move CommandRegistrar import in claude integration to inside method bodies (was at module level) - Lazy-populate AGENT_CONFIGS via _ensure_configs() to avoid circular import at class definition time - Set claude registrar_config to .claude/commands (extension/preset target) since the integration handles .claude/skills in setup() - Update tests from #2051 to match: registrar_config assertions, remove --integration tip assertions, remove install_ai_skills mocks 1086 tests pass. * fix: properly preserve claude skills migration from #2051 Restore ClaudeIntegration.registrar_config to .claude/skills (not .claude/commands) so extension/preset registrations write to the correct skills directory. Update tests that simulate claude setup to use .claude/skills and check for SKILL.md layout. Some tests still need updating for the full skills path — 10 remaining failures from the #2051 test expectations around the extension/preset skill registration flow. WIP: 1076/1086 pass. * fix: properly handle SKILL.md paths in extension update rollback and tests Fix extension update rollback using _compute_output_name() for SKILL.md agents (converts dots to hyphens in skill directory names). Previously the backup and cleanup code constructed paths with raw command names (e.g. speckit.test-ext.hello/SKILL.md) instead of the correct computed names (speckit-test-ext-hello/SKILL.md). Test fixes for claude skills migration: - Update claude tests to use .claude/skills paths and SKILL.md layout - Use qwen (not claude) for skills-guard tests since claude's agent dir IS the skills dir — creating it triggers command registration - Fix test_extension_command_registered_when_extension_present to check skills path format 1086 tests pass, 0 failures, ruff clean. * fix: address PR review — lazy init, assertions, deprecated flags - _ensure_configs(): catch ImportError (not Exception), don't set _configs_loaded on failure so retries work - Move _ensure_configs() before unregister loop (not inside it) - Module-level try/except catches ImportError specifically - Remove tautology assertion (or True) in test_extensions.py - Strengthen preset provenance assertion to check source: field - Mark --offline, --skip-tls, --debug, --github-token as hidden deprecated no-ops in init() 1086 tests pass. * fix: remove deleted release scripts from pyproject.toml force-include Removes force-include entries for create-release-packages.sh/.ps1 which were deleted but still referenced in [tool.hatch.build].
For Claude, the dashed form is intentional. The PR switched Claude to skills in The dotted form still exists in the codebase as the canonical internal command ID ( What you are likely seeing locally is both legacy |
|
@afurm Is correct |
|
Got it! Thank you both. 💪 |


Fixes #2031.
This PR moves Claude Code support from generated slash-command files in
.claude/commandsto native skills in.claude/skills, and aligns the surrounding init, hook, and preset flows with that model.What changed:
.claude/skills/<skill>/SKILL.mdspecify init --ai claudeinstalls skills by default/speckit-plan/speckit-*invocation syntaxFollow-up fixes included in this branch:
--ai claudeWhy this is needed:
Reviewer guide:
src/specify_cli/integrations/claude/__init__.pysrc/specify_cli/__init__.pysrc/specify_cli/presets.pysrc/specify_cli/extensions.pytests/integrations/test_integration_claude.py,tests/test_presets.py,tests/test_extensions.pyTesting
uv run specify --helpuv sync && uv run pytestTargeted tests run:
uv run pytest tests/integrations/test_integration_claude.py tests/test_presets.py -quv run pytest tests/integrations/test_cli.py -quv run pytest tests/test_extensions.py -k HookInvocationRendering -qAI Disclosure
Used Codex to review the branch, identify regressions in Claude preset/init flows, implement the fixes, and add/update targeted tests.