Skip to content

feat: add argument-hint frontmatter to Claude Code commands (#1951)#2059

Open
Quratulain-bilal wants to merge 9 commits intogithub:mainfrom
Quratulain-bilal:feat/argument-hint-claude-commands
Open

feat: add argument-hint frontmatter to Claude Code commands (#1951)#2059
Quratulain-bilal wants to merge 9 commits intogithub:mainfrom
Quratulain-bilal:feat/argument-hint-claude-commands

Conversation

@Quratulain-bilal
Copy link
Copy Markdown
Contributor

@Quratulain-bilal Quratulain-bilal commented Apr 2, 2026

Summary

  • Add argument-hint frontmatter injection to Claude Code skills (SkillsIntegration)
  • ClaudeIntegration.setup() delegates to super().setup() then post-processes each
    SKILL.md to inject hints
  • No duplication of base class logic — clean post-processing approach (addresses previous
    Copilot feedback)
  • Proper \r\n / \n EOL preservation in inject_argument_hint()
Command argument-hint
specify Describe the feature you want to specify
plan Optional guidance for the planning phase
tasks Optional task generation constraints
implement Optional implementation guidance or task filter
analyze Optional focus areas for analysis
clarify Optional areas to clarify in the spec
constitution Principles or values for the project constitution
checklist Domain or focus area for the checklist
taskstoissues Optional filter or label for GitHub issues

What changed after #2051 merge

  • Rebased on SkillsIntegration base class (replaces old MarkdownIntegration)
  • Skills now live at .claude/skills/speckit-*/SKILL.md
  • Removed release script changes (scripts deleted in Stage 6 migration)
  • All previous Copilot review feedback addressed

Closes #1951

Test plan

  • 6 argument-hint tests in tests/integrations/test_integration_claude.py
  • All existing Claude integration tests pass
  • uv run pytest tests/integrations/test_integration_claude.py -q

)

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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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-hint into generated Claude command frontmatter based on command name.
  • Keep templates agent-agnostic by performing injection inside generate_commands() only when agent == 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.

Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

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

Quratulain-bilal and others added 2 commits April 2, 2026 18:46
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>
@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Done added argument-hint injection to src/specify_cli/integrations/claude/init.py with
inject_argument_hint() scoped to frontmatter only, and added 5 tests in
tests/integrations/test_integration_claude.py covering hint presence, correct values,
frontmatter scoping, ordering, and body-safety. See commit ffa6946.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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 mnriem self-requested a review April 2, 2026 14:03
Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

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>
@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Quratulain-bilal commented Apr 2, 2026

All 4 Copilot comments addressed in commit 6e5ba27:

  1. Removed unused import re
  2. inject_argument_hint() now pre-scans frontmatter and skips injection if argument-hint:
    already exists prevents duplicates
  3. Regarding scope: argument-hint is intentionally injected in both the release scripts and
    integration setup the maintainer requested coverage in integrations/claude/init.py as
    well, so both specify init --ai claude and release ZIPs get hints. Updated PR description
    would be: hints are injected wherever Claude commands are generated.
  4. test_hint_appears_after_description now asserts found_description flag so it fails
    explicitly if no description: line is found. Also added
    test_inject_argument_hint_skips_if_already_present for the duplicate-guard.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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.

@mnriem mnriem self-requested a review April 2, 2026 14:19
- 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>
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 2, 2026

Can you hold of until PR #2051 gets merged and see if yours is still needed?

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Sure, will hold off. Watching #2051 if it covers argument-hint injection for Claude
commands across all paths (release scripts + integration system), I'll close this PR.
Otherwise I'll rebase and fill any gaps.

@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Quratulain-bilal commented Apr 2, 2026

#2051 is now merged. I've rebased/merged main into this branch and updated the
implementation to work with the new SkillsIntegration base class and .claude/skills/
layout. The argument-hint feature is still needed #2051 doesn't include it. Ready for
review.

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.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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 the yaml dependency) 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.
@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Quratulain-bilal commented Apr 2, 2026

Not applicable. super().setup() delegates to SkillsIntegration.setup() which calls
_build_skill_fm() → CommandRegistrar.build_skill_frontmatter(). That method already adds
disable-model-invocation: true for Claude (see agents.py line 398-400). The post-processing
step only injects argument-hint it does not touch or remove any existing frontmatter keys.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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.

Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

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
@Quratulain-bilal
Copy link
Copy Markdown
Contributor Author

Addressed all Copilot feedback in fa2fa9c:

  1. Re-record manifest hash after argument-hint injection via record_file_in_manifest() so
    check_modified()/uninstall stays in sync
  2. Double-quote argument-hint values to match existing SKILL.md frontmatter style
  3. read_bytes()/write_bytes() already applied in previous commit for platform-stable EOL

Regarding disable-model-invocation: not applicable super().setup() delegates to
SkillsIntegration.setup() which uses CommandRegistrar.build_skill_frontmatter(), and that already adds
disable-model-invocation: true for Claude (agents.py line 398-400).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 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 mnriem self-requested a review April 2, 2026 20:36
Copy link
Copy Markdown
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

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

Almost there. Looks like there is a test failure

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.

[Feature]: Argument hints for /speckit.* Claude Code commands

3 participants