@@ -777,19 +777,9 @@ def _register_for_non_skill_agents(
777777 Used during reconciliation to avoid overwriting properly formatted
778778 SKILL.md files that were written by _register_skills().
779779 """
780- registrar ._ensure_configs ()
781- for agent_name , agent_config in registrar .AGENT_CONFIGS .items ():
782- if agent_config .get ("extension" ) == "/SKILL.md" :
783- continue
784- agent_dir = self .project_root / agent_config ["dir" ]
785- if agent_dir .exists ():
786- try :
787- registrar .register_commands (
788- agent_name , commands , source_id ,
789- source_dir , self .project_root ,
790- )
791- except ValueError :
792- continue
780+ registrar .register_commands_for_non_skill_agents (
781+ commands , source_id , source_dir , self .project_root
782+ )
793783
794784 def _reconcile_skills (self , command_names : List [str ]) -> None :
795785 """Re-register skills for commands whose winning layer changed.
@@ -2018,6 +2008,21 @@ def __init__(self, project_root: Path):
20182008 self .presets_dir = project_root / ".specify" / "presets"
20192009 self .overrides_dir = self .templates_dir / "overrides"
20202010 self .extensions_dir = project_root / ".specify" / "extensions"
2011+ self ._manifest_cache : Dict [str , Optional ["PresetManifest" ]] = {}
2012+
2013+ def _get_manifest (self , pack_dir : Path ) -> Optional ["PresetManifest" ]:
2014+ """Get a cached preset manifest, parsing it on first access."""
2015+ key = str (pack_dir )
2016+ if key not in self ._manifest_cache :
2017+ manifest_path = pack_dir / "preset.yml"
2018+ if manifest_path .exists ():
2019+ try :
2020+ self ._manifest_cache [key ] = PresetManifest (manifest_path )
2021+ except PresetValidationError :
2022+ self ._manifest_cache [key ] = None
2023+ else :
2024+ self ._manifest_cache [key ] = None
2025+ return self ._manifest_cache [key ]
20212026
20222027 def _get_all_extensions_by_priority (self ) -> list [tuple [int , str , dict | None ]]:
20232028 """Build unified list of registered and unregistered extensions sorted by priority.
@@ -2285,20 +2290,14 @@ def _find_in_subdirs(base_dir: Path) -> Optional[Path]:
22852290 # Read strategy and manifest file path from preset manifest
22862291 strategy = "replace"
22872292 manifest_file_path = None
2288- manifest_path = pack_dir / "preset.yml"
2289- if manifest_path .exists ():
2290- try :
2291- manifest = PresetManifest (manifest_path )
2292- for tmpl in manifest .templates :
2293- if (tmpl .get ("name" ) == template_name
2294- and tmpl .get ("type" ) == template_type ):
2295- strategy = tmpl .get ("strategy" , "replace" )
2296- manifest_file_path = tmpl .get ("file" )
2297- break
2298- except PresetValidationError :
2299- # Invalid manifest — fall back to default "replace"
2300- # strategy so layer resolution still works.
2301- pass
2293+ manifest = self ._get_manifest (pack_dir )
2294+ if manifest :
2295+ for tmpl in manifest .templates :
2296+ if (tmpl .get ("name" ) == template_name
2297+ and tmpl .get ("type" ) == template_type ):
2298+ strategy = tmpl .get ("strategy" , "replace" )
2299+ manifest_file_path = tmpl .get ("file" )
2300+ break
23022301 # Use manifest file path if specified, otherwise convention-based lookup
23032302 candidate = None
23042303 if manifest_file_path :
@@ -2444,15 +2443,20 @@ def resolve_content(
24442443 top_frontmatter_text = None
24452444
24462445 def _split_frontmatter (text : str ) -> tuple :
2447- """Return (frontmatter_block_with_fences, body) or (None, text)."""
2448- from .agents import CommandRegistrar
2449- fm_dict , body = CommandRegistrar .parse_frontmatter (text )
2450- if fm_dict :
2451- # Re-extract the raw frontmatter block (text before body)
2452- end = text .find ("---" , 3 )
2453- fm_block = text [:end + 3 ]
2454- return fm_block , body
2455- return None , text
2446+ """Return (frontmatter_block_with_fences, body) or (None, text).
2447+
2448+ Detects frontmatter by the presence of ``---`` fences rather than
2449+ whether the parsed YAML has keys, so empty frontmatter blocks
2450+ (``---\\ n---``) are also stripped.
2451+ """
2452+ if not text .startswith ("---" ):
2453+ return None , text
2454+ end = text .find ("---" , 3 )
2455+ if end == - 1 :
2456+ return None , text
2457+ fm_block = text [:end + 3 ]
2458+ body = text [end + 3 :].strip ()
2459+ return fm_block , body
24562460
24572461 if is_command :
24582462 fm , body = _split_frontmatter (content )
0 commit comments