Resolve a template name to its file path. Walks the priority stack and returns the first match. Args: template_name: Template name (e.g., "spec-template") template_type: Template type ("template", "command", or "script") skip_presets: When True,
(
self,
template_name: str,
template_type: str = "template",
skip_presets: bool = False,
)
| 2630 | return None |
| 2631 | |
| 2632 | def resolve( |
| 2633 | self, |
| 2634 | template_name: str, |
| 2635 | template_type: str = "template", |
| 2636 | skip_presets: bool = False, |
| 2637 | ) -> Optional[Path]: |
| 2638 | """Resolve a template name to its file path. |
| 2639 | |
| 2640 | Walks the priority stack and returns the first match. |
| 2641 | |
| 2642 | Args: |
| 2643 | template_name: Template name (e.g., "spec-template") |
| 2644 | template_type: Template type ("template", "command", or "script") |
| 2645 | skip_presets: When True, skip tier 2 (installed presets). Use |
| 2646 | resolve_core() as the preferred caller-facing API for this. |
| 2647 | |
| 2648 | Returns: |
| 2649 | Path to the resolved template file, or None if not found |
| 2650 | """ |
| 2651 | # Determine subdirectory based on template type |
| 2652 | if template_type == "template": |
| 2653 | subdirs = ["templates", ""] |
| 2654 | elif template_type == "command": |
| 2655 | subdirs = ["commands"] |
| 2656 | elif template_type == "script": |
| 2657 | subdirs = ["scripts"] |
| 2658 | else: |
| 2659 | subdirs = [""] |
| 2660 | |
| 2661 | # Determine file extension based on template type |
| 2662 | ext = ".md" |
| 2663 | if template_type == "script": |
| 2664 | ext = ".sh" # scripts use .sh; callers can also check .ps1 |
| 2665 | |
| 2666 | # Priority 1: Project-local overrides |
| 2667 | if template_type == "script": |
| 2668 | override = self.overrides_dir / "scripts" / f"{template_name}{ext}" |
| 2669 | else: |
| 2670 | override = self.overrides_dir / f"{template_name}{ext}" |
| 2671 | if override.exists(): |
| 2672 | return override |
| 2673 | |
| 2674 | # Priority 2: Installed presets (sorted by priority — lower number wins) |
| 2675 | if not skip_presets and self.presets_dir.exists(): |
| 2676 | registry = PresetRegistry(self.presets_dir) |
| 2677 | for pack_id, _metadata in registry.list_by_priority(): |
| 2678 | pack_dir = self.presets_dir / pack_id |
| 2679 | for subdir in subdirs: |
| 2680 | if subdir: |
| 2681 | candidate = pack_dir / subdir / f"{template_name}{ext}" |
| 2682 | else: |
| 2683 | candidate = pack_dir / f"{template_name}{ext}" |
| 2684 | if candidate.exists(): |
| 2685 | return candidate |
| 2686 | |
| 2687 | # Priority 3: Extension-provided templates (sorted by priority — lower number wins) |
| 2688 | for _priority, ext_id, _metadata in self._get_all_extensions_by_priority(): |
| 2689 | ext_dir = self.extensions_dir / ext_id |