feat: add argument-hint frontmatter to Claude Code commands (#1951)#2059
feat: add argument-hint frontmatter to Claude Code commands (#1951)#2059Quratulain-bilal wants to merge 9 commits intogithub:mainfrom
Conversation
) Inject argument-hint into YAML frontmatter for Claude agent only during release package generation. Templates remain agent-agnostic; hints are added on the fly in generate_commands() when agent is "claude". Closes github#1951 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds Claude Code–specific argument-hint frontmatter to generated /speckit.* command files at release-package generation time, improving the Claude slash-command UX without making the shared templates agent-specific.
Changes:
- Inject
argument-hintinto generated Claude command frontmatter based on command name. - Keep templates agent-agnostic by performing injection inside
generate_commands()only whenagent == claude. - Mirror the same behavior in both Bash and PowerShell release packaging scripts for parity.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| .github/workflows/scripts/create-release-packages.sh | Adds Claude-only argument-hint injection during command generation in release packaging. |
| .github/workflows/scripts/create-release-packages.ps1 | Implements the same Claude-only argument-hint injection for PowerShell-based packaging parity. |
💡 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. Note that until we have fully migrated you will also have to addresss this in src/specify_cli/integrations/claude/init.py
Please add tests for this in tests/integrations/test_integration_claude.py
Addresses Copilot review: the awk/regex matched description: anywhere in the file. Now both bash and PowerShell track frontmatter boundaries (--- delimiters) and only inject argument-hint after the first description: inside the frontmatter block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Override setup() in ClaudeIntegration to inject argument-hint into YAML frontmatter after description: line, scoped to frontmatter only - Add ARGUMENT_HINTS mapping for all 9 commands - Add tests: hint presence, correct values, frontmatter scoping, ordering after description, and body-safety check Addresses maintainer feedback to cover the new integrations system in src/specify_cli/integrations/claude/__init__.py with tests in tests/integrations/test_integration_claude.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Done added argument-hint injection to src/specify_cli/integrations/claude/init.py with |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 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
- Remove unused `import re` - Skip injection if argument-hint already exists in frontmatter - Add found_description assertion to test_hint_appears_after_description - Add test_inject_argument_hint_skips_if_already_present test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
All 4 Copilot comments addressed in commit 6e5ba27:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Eliminates setup() duplication by calling super().setup() then post-processing command files to inject argument-hint - Fixes EOL preservation to correctly detect \r\n vs \n - No drift risk if MarkdownIntegration.setup() changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Can you hold of until PR #2051 gets merged and see if yours is still needed? |
|
Sure, will hold off. Watching #2051 if it covers argument-hint injection for Claude |
Resolve conflicts with Stage 6 migration (github#2063) and release 0.4.5 (github#2064). Keep inject_argument_hint alongside new _render_skill and _build_skill_fm methods. Accept deletion of legacy release packaging scripts.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (2)
src/specify_cli/integrations/claude/init.py:149
- The post-processing rewrites SKILL.md after
super().setup()has already recorded file hashes in the integration manifest. Because the file content changes, the manifest will contain stale hashes and uninstall/modified-file detection may treat these files as user-modified. After writing updated content, re-record the file in the manifest (e.g.,manifest.record_existing(rel_path)or the existing helper used elsewhere).
content = path.read_text(encoding="utf-8")
updated = self.inject_argument_hint(content, hint)
if updated != content:
path.write_text(updated, encoding="utf-8")
src/specify_cli/integrations/claude/init.py:112
- After switching to
super().setup(), the_render_skill()/_build_skill_fm()helpers appear unused (no call sites in the repo). Keeping them (and theyamldependency) increases maintenance burden and can confuse future readers about which codepath is active. Consider removing them if they’re no longer part of the integration’s intended behavior.
def _render_skill(self, template_name: str, frontmatter: dict[str, Any], body: str) -> str:
"""Render a processed command template as a Claude skill."""
skill_name = f"speckit-{template_name.replace('.', '-')}"
description = frontmatter.get(
"description",
f"Spec-kit workflow command: {template_name}",
)
skill_frontmatter = self._build_skill_fm(
skill_name, description, f"templates/commands/{template_name}.md"
)
frontmatter_text = yaml.safe_dump(skill_frontmatter, sort_keys=False).strip()
return f"---\n{frontmatter_text}\n---\n\n{body.strip()}\n"
def _build_skill_fm(self, name: str, description: str, source: str) -> dict:
from specify_cli.agents import CommandRegistrar
return CommandRegistrar.build_skill_frontmatter(
self.key, name, description, source
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address Copilot review: avoid platform newline translation by using read_bytes()/write_bytes() instead of read_text()/write_text() when post-processing SKILL.md files for argument-hint injection.
|
Not applicable. super().setup() delegates to SkillsIntegration.setup() which calls |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 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. Make sure the hashes are recorded at the right time as that will make uninstall possible
- Re-record file hash in manifest after writing argument-hint so check_modified()/uninstall stays in sync - Double-quote argument-hint values to match SKILL.md frontmatter style - Update tests to expect quoted hint values
|
Addressed all Copilot feedback in fa2fa9c:
Regarding disable-model-invocation: not applicable super().setup() delegates to |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 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
left a comment
There was a problem hiding this comment.
Almost there. Looks like there is a test failure
Summary
argument-hintfrontmatter injection to Claude Code skills (SkillsIntegration)ClaudeIntegration.setup()delegates tosuper().setup()then post-processes eachSKILL.mdto inject hintsCopilot feedback)
\r\n/\nEOL preservation ininject_argument_hint()What changed after #2051 merge
SkillsIntegrationbase class (replaces oldMarkdownIntegration).claude/skills/speckit-*/SKILL.mdCloses #1951
Test plan
tests/integrations/test_integration_claude.pyuv run pytest tests/integrations/test_integration_claude.py -q