fix(presets): preserve argument-hint in preset SKILL.md generation (#2978)

* fix(presets): preserve argument-hint in preset SKILL.md generation

Preset-provided and extension-override commands that declare
`argument-hint:` in their frontmatter had it dropped from the generated
Claude SKILL.md, and it was re-dropped when a preset was removed and its
overridden skill restored. This is the preset-side analog of the
extension fix in #2903 / #2916.

Factor the argument-hint carry-over into a shared
CommandRegistrar.apply_argument_hint() helper and apply it at the four
preset skill-generation sites (register, reconcile override-restore, and
the core/extension unregister-restore paths). The extension path from

The helper writes argument-hint into the frontmatter dict before
serialization (so a folded multi-line description cannot be split into
invalid YAML) and only for integrations that support it (those exposing
inject_argument_hint -- currently Claude), leaving build_skill_frontmatter's
shared shape unchanged for every other agent. Core templates carry no
argument-hint, so the core-restore path is a no-op. No behavior change for
non-Claude agents or the core path.

Add regression tests covering a folding description (Claude) and the
non-Claude gate (codex).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(presets): address review - guard skill_frontmatter type and tighten apply_argument_hint annotations

Add a symmetric isinstance(skill_frontmatter, dict) guard so the helper stays a safe no-op if a caller passes a non-dict, and annotate the parameters as Dict[str, Any] with an optional integration to match real call-site usage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ali jawwad
2026-06-22 19:52:13 +05:00
committed by GitHub
parent f5f76160a3
commit f9c6cf83e5
4 changed files with 115 additions and 16 deletions

View File

@@ -356,6 +356,33 @@ class CommandRegistrar:
}
return skill_frontmatter
@staticmethod
def apply_argument_hint(
source_frontmatter: Dict[str, Any],
skill_frontmatter: Dict[str, Any],
integration: Optional[object] = None,
) -> None:
"""Carry a command's ``argument-hint`` into its generated skill frontmatter.
Copies ``argument-hint`` from the parsed source command frontmatter into
*skill_frontmatter* (mutated in place) before serialization, so that a
folded multi-line ``description`` cannot be split into invalid YAML. Only
integrations that support the field — those exposing
``inject_argument_hint`` (currently Claude) — receive the key, leaving
:meth:`build_skill_frontmatter`'s shared shape unchanged for every other
agent. Built-in templates carry no ``argument-hint``, so this is a no-op
for the core path.
"""
if not isinstance(source_frontmatter, dict) or not isinstance(skill_frontmatter, dict):
return
argument_hint = source_frontmatter.get("argument-hint")
if (
argument_hint
and integration is not None
and hasattr(integration, "inject_argument_hint")
):
skill_frontmatter["argument-hint"] = str(argument_hint)
@staticmethod
def resolve_skill_placeholders(
agent_name: str, frontmatter: dict, body: str, project_root: Path