2020from pathlib import Path
2121from typing import TYPE_CHECKING , Any
2222
23+ import yaml
24+
2325if TYPE_CHECKING :
2426 from .manifest import IntegrationManifest
2527
@@ -606,6 +608,7 @@ def remove_context_section(self, project_root: Path) -> bool:
606608 # For .mdc files, treat Speckit-generated frontmatter-only content as empty
607609 if ctx_path .suffix == ".mdc" :
608610 import re
611+
609612 # Delete the file if only YAML frontmatter remains (no body content)
610613 frontmatter_only = re .match (
611614 r"^---\n.*?\n---\s*$" , normalized , re .DOTALL
@@ -953,7 +956,6 @@ def _extract_description(content: str) -> str:
953956 and ``>``) keep their YAML semantics instead of being treated as
954957 raw text.
955958 """
956- import yaml
957959
958960 frontmatter_text , _ = TomlIntegration ._split_frontmatter (content )
959961 if not frontmatter_text :
@@ -1140,7 +1142,6 @@ def command_filename(self, template_name: str) -> str:
11401142 @staticmethod
11411143 def _extract_frontmatter (content : str ) -> dict [str , Any ]:
11421144 """Extract frontmatter as a dict from YAML frontmatter block."""
1143- import yaml
11441145
11451146 if not content .startswith ("---" ):
11461147 return {}
@@ -1201,24 +1202,33 @@ def _human_title(identifier: str) -> str:
12011202 text = text [len ("speckit." ) :]
12021203 return text .replace ("." , " " ).replace ("-" , " " ).replace ("_" , " " ).title ()
12031204
1204- @staticmethod
1205- def _render_yaml (title : str , description : str , body : str , source_id : str ) -> str :
1206- """Render a YAML recipe file from title, description, and body.
1207-
1208- Produces a Goose-compatible recipe with a literal block scalar
1209- for the prompt content. Uses ``yaml.safe_dump()`` for the
1210- header fields to ensure proper escaping.
1211- """
1212- import yaml
12131205
1206+ @staticmethod
1207+ def _build_yaml_header (title : str , description : str ) -> dict :
1208+ """Build the base YAML header."""
12141209 header = {
12151210 "version" : "1.0.0" ,
12161211 "title" : title ,
12171212 "description" : description ,
12181213 "author" : {"contact" : "spec-kit" },
1214+ "parameters" : [
1215+ {
1216+ "key" : "args" ,
1217+ "input_type" : "string" ,
1218+ "requirement" : "optional" ,
1219+ "default" : "" ,
1220+ "description" : "User input passed to the command." ,
1221+ }
1222+ ],
12191223 "extensions" : [{"type" : "builtin" , "name" : "developer" }],
12201224 "activities" : ["Spec-Driven Development" ],
12211225 }
1226+ return header
1227+
1228+ @classmethod
1229+ def _render_yaml (cls , title : str , description : str , body : str , source_id : str ) -> str :
1230+
1231+ header = cls ._build_yaml_header (title , description )
12221232
12231233 header_yaml = yaml .safe_dump (
12241234 header ,
@@ -1227,12 +1237,20 @@ def _render_yaml(title: str, description: str, body: str, source_id: str) -> str
12271237 default_flow_style = False ,
12281238 ).strip ()
12291239
1230- # Indent each line for YAML block scalar
1240+ # Indent the body for YAML block scalar
12311241 indented = "\n " .join (f" { line } " for line in body .split ("\n " ))
12321242
1233- lines = [header_yaml , "prompt: |" , indented , "" , f"# Source: { source_id } " ]
1243+ lines = [
1244+ header_yaml ,
1245+ "prompt: |" ,
1246+ indented ,
1247+ "" ,
1248+ f"# Source: { source_id } " ,
1249+ ]
1250+
12341251 return "\n " .join (lines ) + "\n "
12351252
1253+
12361254 def setup (
12371255 self ,
12381256 project_root : Path ,
@@ -1391,7 +1409,6 @@ def setup(
13911409 template. Each SKILL.md has normalised frontmatter containing
13921410 ``name``, ``description``, ``compatibility``, and ``metadata``.
13931411 """
1394- import yaml
13951412
13961413 templates = self .list_command_templates ()
13971414 if not templates :
0 commit comments