SYMBOL INDEX (714 symbols across 10 files) FILE: src/specify_cli/__init__.py function _github_token (line 62) | def _github_token(cli_token: str | None = None) -> str | None: function _github_auth_headers (line 66) | def _github_auth_headers(cli_token: str | None = None) -> dict: function _parse_rate_limit_headers (line 71) | def _parse_rate_limit_headers(headers: httpx.Headers) -> dict: function _format_rate_limit_error (line 99) | def _format_rate_limit_error(status_code: int, headers: httpx.Headers, u... function _build_ai_assistant_help (line 318) | def _build_ai_assistant_help() -> str: class StepTracker (line 356) | class StepTracker: method __init__ (line 360) | def __init__(self, title: str): method attach_refresh (line 366) | def attach_refresh(self, cb): method add (line 369) | def add(self, key: str, label: str): method start (line 374) | def start(self, key: str, detail: str = ""): method complete (line 377) | def complete(self, key: str, detail: str = ""): method error (line 380) | def error(self, key: str, detail: str = ""): method skip (line 383) | def skip(self, key: str, detail: str = ""): method _update (line 386) | def _update(self, key: str, status: str, detail: str): method _maybe_refresh (line 398) | def _maybe_refresh(self): method render (line 405) | def render(self): function get_key (line 441) | def get_key(): function select_with_arrows (line 461) | def select_with_arrows(options: dict, prompt_text: str = "Select an opti... class BannerGroup (line 538) | class BannerGroup(TyperGroup): method format_help (line 541) | def format_help(self, ctx, formatter): function show_banner (line 555) | def show_banner(): function callback (line 570) | def callback(ctx: typer.Context): function run_command (line 577) | def run_command(cmd: list[str], check_return: bool = True, capture: bool... function check_tool (line 595) | def check_tool(tool: str, tracker: StepTracker = None) -> bool: function is_git_repo (line 631) | def is_git_repo(path: Path = None) -> bool: function init_git_repo (line 651) | def init_git_repo(project_path: Path, quiet: bool = False) -> Tuple[bool... function handle_vscode_settings (line 686) | def handle_vscode_settings(sub_item, dest_file, rel_path, verbose=False,... function merge_json_files (line 755) | def merge_json_files(existing_path: Path, new_content: Any, verbose: boo... function download_template_from_github (line 834) | def download_template_from_github(ai_assistant: str, download_dir: Path,... function download_and_extract_template (line 948) | def download_and_extract_template(project_path: Path, ai_assistant: str,... function ensure_executable_scripts (line 1098) | def ensure_executable_scripts(project_path: Path, tracker: StepTracker |... function ensure_constitution_from_template (line 1146) | def ensure_constitution_from_template(project_path: Path, tracker: StepT... function save_init_options (line 1185) | def save_init_options(project_path: Path, options: dict[str, Any]) -> None: function load_init_options (line 1197) | def load_init_options(project_path: Path) -> dict[str, Any]: function _get_skills_dir (line 1237) | def _get_skills_dir(project_path: Path, selected_ai: str) -> Path: function install_ai_skills (line 1255) | def install_ai_skills(project_path: Path, selected_ai: str, tracker: Ste... function _has_bundled_skills (line 1426) | def _has_bundled_skills(project_path: Path, selected_ai: str) -> bool: function _handle_agent_skills_migration (line 1459) | def _handle_agent_skills_migration(console: Console, agent_key: str) -> ... function init (line 1468) | def init( function check (line 1929) | def check(): function version (line 1973) | def version(): function get_speckit_version (line 2083) | def get_speckit_version() -> str: function preset_list (line 2108) | def preset_list(): function preset_add (line 2143) | def preset_add( function preset_remove (line 2251) | def preset_remove( function preset_search (line 2279) | def preset_search( function preset_resolve (line 2318) | def preset_resolve( function preset_info (line 2344) | def preset_info( function preset_set_priority (line 2418) | def preset_set_priority( function preset_enable (line 2470) | def preset_enable( function preset_disable (line 2511) | def preset_disable( function preset_catalog_list (line 2556) | def preset_catalog_list(): function preset_catalog_add (line 2616) | def preset_catalog_add( function preset_catalog_remove (line 2688) | def preset_catalog_remove( function _resolve_installed_extension (line 2733) | def _resolve_installed_extension( function _resolve_catalog_extension (line 2790) | def _resolve_catalog_extension( function extension_list (line 2854) | def extension_list( function catalog_list (line 2898) | def catalog_list(): function catalog_add (line 2958) | def catalog_add( function catalog_remove (line 3030) | def catalog_remove( function extension_add (line 3073) | def extension_add( function extension_remove (line 3217) | def extension_remove( function extension_search (line 3274) | def extension_search( function extension_info (line 3361) | def extension_info( function _print_extension_info (line 3453) | def _print_extension_info(ext_info: dict, manager): function extension_update (line 3553) | def extension_update( function extension_enable (line 3956) | def extension_enable( function extension_disable (line 4003) | def extension_disable( function extension_set_priority (line 4052) | def extension_set_priority( function main (line 4102) | def main(): FILE: src/specify_cli/agents.py class CommandRegistrar (line 16) | class CommandRegistrar: method parse_frontmatter (line 167) | def parse_frontmatter(content: str) -> tuple[dict, str]: method render_frontmatter (line 198) | def render_frontmatter(fm: dict) -> str: method _adjust_script_paths (line 213) | def _adjust_script_paths(self, frontmatter: dict) -> dict: method render_markdown_command (line 232) | def render_markdown_command( method render_toml_command (line 254) | def render_toml_command( method render_skill_command (line 286) | def render_skill_command( method _resolve_codex_skill_placeholders (line 321) | def _resolve_codex_skill_placeholders(frontmatter: dict, body: str, pr... method _convert_argument_placeholder (line 375) | def _convert_argument_placeholder(self, content: str, from_placeholder... method _compute_output_name (line 389) | def _compute_output_name(agent_name: str, cmd_name: str, agent_config:... method register_commands (line 400) | def register_commands( method write_copilot_prompt (line 490) | def write_copilot_prompt(project_root: Path, cmd_name: str) -> None: method register_commands_for_all_agents (line 502) | def register_commands_for_all_agents( method unregister_commands (line 540) | def unregister_commands( FILE: src/specify_cli/extensions.py class ExtensionError (line 29) | class ExtensionError(Exception): class ValidationError (line 34) | class ValidationError(ExtensionError): class CompatibilityError (line 39) | class CompatibilityError(ExtensionError): function normalize_priority (line 44) | def normalize_priority(value: Any, default: int = 10) -> int: class CatalogEntry (line 65) | class CatalogEntry: class ExtensionManifest (line 74) | class ExtensionManifest: method __init__ (line 80) | def __init__(self, manifest_path: Path): method _load_yaml (line 93) | def _load_yaml(self, path: Path) -> dict: method _validate (line 103) | def _validate(self): method id (line 159) | def id(self) -> str: method name (line 164) | def name(self) -> str: method version (line 169) | def version(self) -> str: method description (line 174) | def description(self) -> str: method requires_speckit_version (line 179) | def requires_speckit_version(self) -> str: method commands (line 184) | def commands(self) -> List[Dict[str, Any]]: method hooks (line 189) | def hooks(self) -> Dict[str, Any]: method get_hash (line 193) | def get_hash(self) -> str: class ExtensionRegistry (line 199) | class ExtensionRegistry: method __init__ (line 205) | def __init__(self, extensions_dir: Path): method _load (line 215) | def _load(self) -> dict: method _save (line 243) | def _save(self): method add (line 249) | def add(self, extension_id: str, metadata: dict): method update (line 262) | def update(self, extension_id: str, metadata: dict): method restore (line 300) | def restore(self, extension_id: str, metadata: dict): method remove (line 322) | def remove(self, extension_id: str): method get (line 335) | def get(self, extension_id: str) -> Optional[dict]: method list (line 356) | def list(self) -> Dict[str, dict]: method keys (line 375) | def keys(self) -> set: method is_installed (line 389) | def is_installed(self, extension_id: str) -> bool: method list_by_priority (line 403) | def list_by_priority(self, include_disabled: bool = False) -> List[tup... class ExtensionManager (line 436) | class ExtensionManager: method __init__ (line 439) | def __init__(self, project_root: Path): method _load_extensionignore (line 450) | def _load_extensionignore(source_dir: Path) -> Optional[Callable[[str,... method check_compatibility (line 513) | def check_compatibility( method install_from_directory (line 547) | def install_from_directory( method install_from_zip (line 620) | def install_from_zip( method remove (line 680) | def remove(self, extension_id: str, keep_config: bool = False) -> bool: method list_installed (line 747) | def list_installed(self) -> List[Dict[str, Any]]: method get_extension (line 791) | def get_extension(self, extension_id: str) -> Optional[ExtensionManife... function version_satisfies (line 812) | def version_satisfies(current: str, required: str) -> bool: class CommandRegistrar (line 830) | class CommandRegistrar: method __init__ (line 842) | def __init__(self): method parse_frontmatter (line 848) | def parse_frontmatter(content: str) -> tuple[dict, str]: method render_frontmatter (line 853) | def render_frontmatter(fm: dict) -> str: method _write_copilot_prompt (line 858) | def _write_copilot_prompt(project_root, cmd_name: str) -> None: method _render_markdown_command (line 862) | def _render_markdown_command(self, frontmatter, body, ext_id): method _render_toml_command (line 867) | def _render_toml_command(self, frontmatter, body, ext_id): method register_commands_for_agent (line 873) | def register_commands_for_agent( method register_commands_for_all_agents (line 889) | def register_commands_for_all_agents( method unregister_commands (line 902) | def unregister_commands( method register_commands_for_claude (line 910) | def register_commands_for_claude( class ExtensionCatalog (line 920) | class ExtensionCatalog: method __init__ (line 927) | def __init__(self, project_root: Path): method _validate_catalog_url (line 939) | def _validate_catalog_url(self, url: str) -> None: method _load_catalog_config (line 960) | def _load_catalog_config(self, config_path: Path) -> Optional[List[Cat... method get_active_catalogs (line 1035) | def get_active_catalogs(self) -> List[CatalogEntry]: method get_catalog_url (line 1084) | def get_catalog_url(self) -> str: method _fetch_single_catalog (line 1099) | def _fetch_single_catalog(self, entry: CatalogEntry, force_refresh: bo... method _get_merged_extensions (line 1171) | def _get_merged_extensions(self, force_refresh: bool = False) -> List[... method is_cache_valid (line 1222) | def is_cache_valid(self) -> bool: method fetch_catalog (line 1241) | def fetch_catalog(self, force_refresh: bool = False) -> Dict[str, Any]: method search (line 1292) | def search( method get_extension_info (line 1347) | def get_extension_info(self, extension_id: str) -> Optional[Dict[str, ... method download_extension (line 1365) | def download_extension(self, extension_id: str, target_dir: Optional[P... method clear_cache (line 1421) | def clear_cache(self): class ConfigManager (line 1436) | class ConfigManager: method __init__ (line 1446) | def __init__(self, project_root: Path, extension_id: str): method _load_yaml_config (line 1457) | def _load_yaml_config(self, file_path: Path) -> Dict[str, Any]: method _get_extension_defaults (line 1474) | def _get_extension_defaults(self) -> Dict[str, Any]: method _get_project_config (line 1487) | def _get_project_config(self) -> Dict[str, Any]: method _get_local_config (line 1496) | def _get_local_config(self) -> Dict[str, Any]: method _get_env_config (line 1505) | def _get_env_config(self) -> Dict[str, Any]: method _merge_configs (line 1543) | def _merge_configs(self, base: Dict[str, Any], override: Dict[str, Any... method get_config (line 1565) | def get_config(self) -> Dict[str, Any]: method get_value (line 1588) | def get_value(self, key_path: str, default: Any = None) -> Any: method has_value (line 1614) | def has_value(self, key_path: str) -> bool: class HookExecutor (line 1635) | class HookExecutor: method __init__ (line 1638) | def __init__(self, project_root: Path): method get_project_config (line 1648) | def get_project_config(self) -> Dict[str, Any]: method save_project_config (line 1670) | def save_project_config(self, config: Dict[str, Any]): method register_hooks (line 1681) | def register_hooks(self, manifest: ExtensionManifest): method unregister_hooks (line 1731) | def unregister_hooks(self, extension_id: str): method get_hooks_for_event (line 1757) | def get_hooks_for_event(self, event_name: str) -> List[Dict[str, Any]]: method should_execute_hook (line 1772) | def should_execute_hook(self, hook: Dict[str, Any]) -> bool: method _evaluate_condition (line 1793) | def _evaluate_condition(self, condition: str, extension_id: Optional[s... method format_hook_message (line 1868) | def format_hook_message( method check_hooks_for_event (line 1907) | def check_hooks_for_event(self, event_name: str) -> Dict[str, Any]: method execute_hook (line 1949) | def execute_hook(self, hook: Dict[str, Any]) -> Dict[str, Any]: method enable_hooks (line 1973) | def enable_hooks(self, extension_id: str): method disable_hooks (line 1992) | def disable_hooks(self, extension_id: str): FILE: src/specify_cli/presets.py class PresetCatalogEntry (line 31) | class PresetCatalogEntry: class PresetError (line 40) | class PresetError(Exception): class PresetValidationError (line 45) | class PresetValidationError(PresetError): class PresetCompatibilityError (line 50) | class PresetCompatibilityError(PresetError): class PresetManifest (line 58) | class PresetManifest: method __init__ (line 64) | def __init__(self, manifest_path: Path): method _load_yaml (line 77) | def _load_yaml(self, path: Path) -> dict: method _validate (line 87) | def _validate(self): method id (line 170) | def id(self) -> str: method name (line 175) | def name(self) -> str: method version (line 180) | def version(self) -> str: method description (line 185) | def description(self) -> str: method author (line 190) | def author(self) -> str: method requires_speckit_version (line 195) | def requires_speckit_version(self) -> str: method templates (line 200) | def templates(self) -> List[Dict[str, Any]]: method tags (line 205) | def tags(self) -> List[str]: method get_hash (line 209) | def get_hash(self) -> str: class PresetRegistry (line 215) | class PresetRegistry: method __init__ (line 221) | def __init__(self, packs_dir: Path): method _load (line 231) | def _load(self) -> dict: method _save (line 258) | def _save(self): method add (line 264) | def add(self, pack_id: str, metadata: dict): method remove (line 277) | def remove(self, pack_id: str): method update (line 290) | def update(self, pack_id: str, updates: dict): method restore (line 323) | def restore(self, pack_id: str, metadata: dict): method get (line 345) | def get(self, pack_id: str) -> Optional[dict]: method list (line 366) | def list(self) -> Dict[str, dict]: method keys (line 385) | def keys(self) -> set: method list_by_priority (line 399) | def list_by_priority(self, include_disabled: bool = False) -> List[tup... method is_installed (line 431) | def is_installed(self, pack_id: str) -> bool: class PresetManager (line 446) | class PresetManager: method __init__ (line 449) | def __init__(self, project_root: Path): method check_compatibility (line 459) | def check_compatibility( method _register_commands (line 494) | def _register_commands( method _unregister_commands (line 544) | def _unregister_commands(self, registered_commands: Dict[str, List[str... method _get_skills_dir (line 558) | def _get_skills_dir(self) -> Optional[Path]: method _register_skills (line 585) | def _register_skills( method _unregister_skills (line 705) | def _unregister_skills(self, skill_names: List[str], preset_dir: Path)... method install_from_directory (line 791) | def install_from_directory( method install_from_zip (line 850) | def install_from_zip( method remove (line 906) | def remove(self, pack_id: str) -> bool: method list_installed (line 936) | def list_installed(self) -> List[Dict[str, Any]]: method get_pack (line 979) | def get_pack(self, pack_id: str) -> Optional[PresetManifest]: class PresetCatalog (line 1000) | class PresetCatalog: method __init__ (line 1011) | def __init__(self, project_root: Path): method _validate_catalog_url (line 1023) | def _validate_catalog_url(self, url: str) -> None: method _load_catalog_config (line 1048) | def _load_catalog_config(self, config_path: Path) -> Optional[List[Pre... method get_active_catalogs (line 1113) | def get_active_catalogs(self) -> List[PresetCatalogEntry]: method get_catalog_url (line 1162) | def get_catalog_url(self) -> str: method _get_cache_paths (line 1174) | def _get_cache_paths(self, url: str): method _is_url_cache_valid (line 1191) | def _is_url_cache_valid(self, url: str) -> bool: method _fetch_single_catalog (line 1208) | def _fetch_single_catalog(self, entry: PresetCatalogEntry, force_refre... method _get_merged_packs (line 1259) | def _get_merged_packs(self, force_refresh: bool = False) -> Dict[str, ... method is_cache_valid (line 1281) | def is_cache_valid(self) -> bool: method fetch_catalog (line 1302) | def fetch_catalog(self, force_refresh: bool = False) -> Dict[str, Any]: method search (line 1358) | def search( method get_pack_info (line 1411) | def get_pack_info( method download_pack (line 1433) | def download_pack( method clear_cache (line 1503) | def clear_cache(self): class PresetResolver (line 1511) | class PresetResolver: method __init__ (line 1521) | def __init__(self, project_root: Path): method _get_all_extensions_by_priority (line 1533) | def _get_all_extensions_by_priority(self) -> list[tuple[int, str, dict... method resolve (line 1575) | def resolve( method resolve_with_source (line 1656) | def resolve_with_source( FILE: tests/test_agent_config_consistency.py class TestAgentConfigConsistency (line 13) | class TestAgentConfigConsistency: method test_runtime_config_uses_kiro_cli_and_removes_q (line 16) | def test_runtime_config_uses_kiro_cli_and_removes_q(self): method test_extension_registrar_uses_kiro_cli_and_removes_q (line 23) | def test_extension_registrar_uses_kiro_cli_and_removes_q(self): method test_extension_registrar_includes_codex (line 31) | def test_extension_registrar_includes_codex(self): method test_runtime_codex_uses_native_skills (line 39) | def test_runtime_codex_uses_native_skills(self): method test_release_agent_lists_include_kiro_cli_and_exclude_q (line 44) | def test_release_agent_lists_include_kiro_cli_and_exclude_q(self): method test_release_ps_switch_has_shai_and_agy_generation (line 66) | def test_release_ps_switch_has_shai_and_agy_generation(self): method test_release_sh_switch_has_shai_and_agy_generation (line 73) | def test_release_sh_switch_has_shai_and_agy_generation(self): method test_release_scripts_generate_codex_skills (line 80) | def test_release_scripts_generate_codex_skills(self): method test_init_ai_help_includes_roo_and_kiro_alias (line 90) | def test_init_ai_help_includes_roo_and_kiro_alias(self): method test_devcontainer_kiro_installer_uses_pinned_checksum (line 97) | def test_devcontainer_kiro_installer_uses_pinned_checksum(self): method test_release_output_targets_kiro_prompt_dir (line 105) | def test_release_output_targets_kiro_prompt_dir(self): method test_agent_context_scripts_use_kiro_cli (line 121) | def test_agent_context_scripts_use_kiro_cli(self): method test_runtime_config_includes_tabnine (line 133) | def test_runtime_config_includes_tabnine(self): method test_extension_registrar_includes_tabnine (line 141) | def test_extension_registrar_includes_tabnine(self): method test_release_agent_lists_include_tabnine (line 152) | def test_release_agent_lists_include_tabnine(self): method test_release_scripts_generate_tabnine_toml_commands (line 168) | def test_release_scripts_generate_tabnine_toml_commands(self): method test_github_release_includes_tabnine_packages (line 177) | def test_github_release_includes_tabnine_packages(self): method test_agent_context_scripts_include_tabnine (line 184) | def test_agent_context_scripts_include_tabnine(self): method test_ai_help_includes_tabnine (line 194) | def test_ai_help_includes_tabnine(self): method test_kimi_in_agent_config (line 200) | def test_kimi_in_agent_config(self): method test_kimi_in_extension_registrar (line 207) | def test_kimi_in_extension_registrar(self): method test_kimi_in_release_agent_lists (line 216) | def test_kimi_in_release_agent_lists(self): method test_kimi_in_powershell_validate_set (line 232) | def test_kimi_in_powershell_validate_set(self): method test_kimi_in_github_release_output (line 242) | def test_kimi_in_github_release_output(self): method test_ai_help_includes_kimi (line 249) | def test_ai_help_includes_kimi(self): method test_trae_in_agent_config (line 255) | def test_trae_in_agent_config(self): method test_trae_in_extension_registrar (line 263) | def test_trae_in_extension_registrar(self): method test_trae_in_release_agent_lists (line 273) | def test_trae_in_release_agent_lists(self): method test_trae_in_release_scripts_generate_commands (line 289) | def test_trae_in_release_scripts_generate_commands(self): method test_trae_in_github_release_output (line 298) | def test_trae_in_github_release_output(self): method test_trae_in_agent_context_scripts (line 305) | def test_trae_in_agent_context_scripts(self): method test_trae_in_powershell_validate_set (line 315) | def test_trae_in_powershell_validate_set(self): method test_ai_help_includes_trae (line 325) | def test_ai_help_includes_trae(self): method test_pi_in_agent_config (line 331) | def test_pi_in_agent_config(self): method test_pi_in_extension_registrar (line 339) | def test_pi_in_extension_registrar(self): method test_pi_in_release_agent_lists (line 350) | def test_pi_in_release_agent_lists(self): method test_release_scripts_generate_pi_prompt_templates (line 366) | def test_release_scripts_generate_pi_prompt_templates(self): method test_pi_in_powershell_validate_set (line 376) | def test_pi_in_powershell_validate_set(self): method test_pi_in_github_release_output (line 386) | def test_pi_in_github_release_output(self): method test_agent_context_scripts_include_pi (line 393) | def test_agent_context_scripts_include_pi(self): method test_ai_help_includes_pi (line 403) | def test_ai_help_includes_pi(self): method test_iflow_in_agent_config (line 409) | def test_iflow_in_agent_config(self): method test_iflow_in_extension_registrar (line 416) | def test_iflow_in_extension_registrar(self): method test_iflow_in_release_agent_lists (line 425) | def test_iflow_in_release_agent_lists(self): method test_iflow_in_release_scripts_build_variant (line 441) | def test_iflow_in_release_scripts_build_variant(self): method test_iflow_in_github_release_output (line 450) | def test_iflow_in_github_release_output(self): method test_iflow_in_agent_context_scripts (line 457) | def test_iflow_in_agent_context_scripts(self): method test_ai_help_includes_iflow (line 467) | def test_ai_help_includes_iflow(self): FILE: tests/test_ai_skills.py function temp_dir (line 37) | def temp_dir(): function project_dir (line 45) | def project_dir(temp_dir): function templates_dir (line 53) | def templates_dir(project_dir): function commands_dir_claude (line 116) | def commands_dir_claude(project_dir): function commands_dir_gemini (line 126) | def commands_dir_gemini(project_dir): function commands_dir_qwen (line 136) | def commands_dir_qwen(project_dir): class TestGetSkillsDir (line 147) | class TestGetSkillsDir: method test_claude_skills_dir (line 150) | def test_claude_skills_dir(self, project_dir): method test_gemini_skills_dir (line 155) | def test_gemini_skills_dir(self, project_dir): method test_tabnine_skills_dir (line 160) | def test_tabnine_skills_dir(self, project_dir): method test_copilot_skills_dir (line 165) | def test_copilot_skills_dir(self, project_dir): method test_codex_uses_override (line 170) | def test_codex_uses_override(self, project_dir): method test_cursor_agent_skills_dir (line 175) | def test_cursor_agent_skills_dir(self, project_dir): method test_kiro_cli_skills_dir (line 180) | def test_kiro_cli_skills_dir(self, project_dir): method test_pi_skills_dir (line 185) | def test_pi_skills_dir(self, project_dir): method test_unknown_agent_uses_default (line 190) | def test_unknown_agent_uses_default(self, project_dir): method test_all_configured_agents_resolve (line 195) | def test_all_configured_agents_resolve(self, project_dir): method test_override_takes_precedence_over_config (line 204) | def test_override_takes_precedence_over_config(self, project_dir): class TestInstallAiSkills (line 214) | class TestInstallAiSkills: method test_skills_installed_with_correct_structure (line 217) | def test_skills_installed_with_correct_structure(self, project_dir, te... method test_generated_skill_has_parseable_yaml (line 251) | def test_generated_skill_has_parseable_yaml(self, project_dir, templat... method test_empty_yaml_frontmatter (line 268) | def test_empty_yaml_frontmatter(self, project_dir, templates_dir): method test_enhanced_descriptions_used_when_available (line 280) | def test_enhanced_descriptions_used_when_available(self, project_dir, ... method test_template_without_frontmatter (line 295) | def test_template_without_frontmatter(self, project_dir, templates_dir): method test_missing_templates_directory (line 307) | def test_missing_templates_directory(self, project_dir): method test_empty_templates_directory (line 323) | def test_empty_templates_directory(self, project_dir): method test_malformed_yaml_frontmatter (line 339) | def test_malformed_yaml_frontmatter(self, project_dir): method test_additive_does_not_overwrite_other_files (line 361) | def test_additive_does_not_overwrite_other_files(self, project_dir, te... method test_return_value (line 375) | def test_return_value(self, project_dir, templates_dir): method test_return_false_when_no_templates (line 379) | def test_return_false_when_no_templates(self, project_dir): method test_non_md_commands_dir_falls_back (line 388) | def test_non_md_commands_dir_falls_back(self, project_dir): method test_qwen_md_commands_dir_installs_skills (line 408) | def test_qwen_md_commands_dir_installs_skills(self, project_dir): method test_pi_prompt_dir_installs_skills (line 430) | def test_pi_prompt_dir_installs_skills(self, project_dir): method test_skills_install_for_all_agents (line 452) | def test_skills_install_for_all_agents(self, temp_dir, agent_key): method test_copilot_ignores_non_speckit_agents (line 479) | def test_copilot_ignores_non_speckit_agents(self, project_dir): method test_non_speckit_commands_ignored_for_all_agents (line 505) | def test_non_speckit_commands_ignored_for_all_agents(self, temp_dir, a... method test_copilot_fallback_when_only_non_speckit_agents (line 530) | def test_copilot_fallback_when_only_non_speckit_agents(self, project_d... method test_fallback_when_only_non_speckit_commands (line 551) | def test_fallback_when_only_non_speckit_commands(self, temp_dir, agent... class TestCommandCoexistence (line 574) | class TestCommandCoexistence: method test_existing_commands_preserved_claude (line 582) | def test_existing_commands_preserved_claude(self, project_dir, templat... method test_existing_commands_preserved_gemini (line 595) | def test_existing_commands_preserved_gemini(self, project_dir, templat... method test_existing_commands_preserved_qwen (line 604) | def test_existing_commands_preserved_qwen(self, project_dir, templates... method test_commands_dir_not_removed (line 613) | def test_commands_dir_not_removed(self, project_dir, templates_dir, co... method test_no_commands_dir_no_error (line 619) | def test_no_commands_dir_no_error(self, project_dir, templates_dir): class TestNewProjectCommandSkip (line 629) | class TestNewProjectCommandSkip: method _fake_extract (line 636) | def _fake_extract(self, agent, project_path, **_kwargs): method test_new_project_commands_removed_after_skills_succeed (line 646) | def test_new_project_commands_removed_after_skills_succeed(self, tmp_p... method test_new_project_nonstandard_commands_subdir_removed_after_skills_succeed (line 672) | def test_new_project_nonstandard_commands_subdir_removed_after_skills_... method test_codex_native_skills_preserved_without_conversion (line 696) | def test_codex_native_skills_preserved_without_conversion(self, tmp_pa... method test_codex_native_skills_missing_fails_clearly (line 723) | def test_codex_native_skills_missing_fails_clearly(self, tmp_path): method test_codex_native_skills_ignores_non_speckit_skill_dirs (line 745) | def test_codex_native_skills_ignores_non_speckit_skill_dirs(self, tmp_... method test_commands_preserved_when_skills_fail (line 772) | def test_commands_preserved_when_skills_fail(self, tmp_path): method test_here_mode_commands_preserved (line 796) | def test_here_mode_commands_preserved(self, tmp_path, monkeypatch): class TestSkipIfExists (line 831) | class TestSkipIfExists: method test_existing_skill_not_overwritten (line 834) | def test_existing_skill_not_overwritten(self, project_dir, templates_d... method test_fresh_install_writes_all_skills (line 852) | def test_fresh_install_writes_all_skills(self, project_dir, templates_... class TestSkillDescriptions (line 865) | class TestSkillDescriptions: method test_all_known_commands_have_descriptions (line 868) | def test_all_known_commands_have_descriptions(self): class TestCliValidation (line 881) | class TestCliValidation: method test_ai_skills_without_ai_fails (line 884) | def test_ai_skills_without_ai_fails(self): method test_ai_skills_without_ai_shows_usage (line 894) | def test_ai_skills_without_ai_shows_usage(self): method test_agy_without_ai_skills_fails (line 904) | def test_agy_without_ai_skills_fails(self): method test_codex_without_ai_skills_fails (line 915) | def test_codex_without_ai_skills_fails(self): method test_interactive_agy_without_ai_skills_prompts_skills (line 926) | def test_interactive_agy_without_ai_skills_prompts_skills(self, monkey... method test_interactive_codex_without_ai_skills_enables_skills (line 968) | def test_interactive_codex_without_ai_skills_enables_skills(self, monk... method test_kimi_next_steps_show_skill_invocation (line 1010) | def test_kimi_next_steps_show_skill_invocation(self, monkeypatch): method test_ai_skills_flag_appears_in_help (line 1034) | def test_ai_skills_flag_appears_in_help(self): method test_kiro_alias_normalized_to_kiro_cli (line 1045) | def test_kiro_alias_normalized_to_kiro_cli(self, tmp_path): method test_q_removed_from_agent_config (line 1076) | def test_q_removed_from_agent_config(self): class TestParameterOrderingIssue (line 1082) | class TestParameterOrderingIssue: method test_ai_flag_consuming_here_flag (line 1085) | def test_ai_flag_consuming_here_flag(self): method test_ai_flag_consuming_ai_skills_flag (line 1097) | def test_ai_flag_consuming_ai_skills_flag(self): method test_error_message_provides_hint (line 1109) | def test_error_message_provides_hint(self): method test_error_message_lists_available_agents (line 1120) | def test_error_message_lists_available_agents(self): method test_ai_commands_dir_consuming_flag (line 1132) | def test_ai_commands_dir_consuming_flag(self): FILE: tests/test_cursor_frontmatter.py class TestScriptFrontmatterPattern (line 37) | class TestScriptFrontmatterPattern: method test_create_new_has_mdc_frontmatter_logic (line 40) | def test_create_new_has_mdc_frontmatter_logic(self): method test_update_existing_has_mdc_frontmatter_logic (line 47) | def test_update_existing_has_mdc_frontmatter_logic(self): method test_powershell_script_has_mdc_frontmatter_logic (line 57) | def test_powershell_script_has_mdc_frontmatter_logic(self): class TestCursorFrontmatterIntegration (line 76) | class TestCursorFrontmatterIntegration: method git_repo (line 80) | def git_repo(self, tmp_path): method _run_update (line 163) | def _run_update(self, repo, agent_type="cursor-agent"): method test_new_mdc_file_has_frontmatter (line 175) | def test_new_mdc_file_has_frontmatter(self, git_repo): method test_existing_mdc_without_frontmatter_gets_it_added (line 196) | def test_existing_mdc_without_frontmatter_gets_it_added(self, git_repo): method test_existing_mdc_with_frontmatter_not_duplicated (line 221) | def test_existing_mdc_with_frontmatter_not_duplicated(self, git_repo): method test_non_mdc_file_has_no_frontmatter (line 253) | def test_non_mdc_file_has_no_frontmatter(self, git_repo): FILE: tests/test_extensions.py function temp_dir (line 37) | def temp_dir(): function valid_manifest_data (line 45) | def valid_manifest_data(): function extension_dir (line 83) | def extension_dir(temp_dir, valid_manifest_data): function project_dir (line 113) | def project_dir(temp_dir): class TestNormalizePriority (line 127) | class TestNormalizePriority: method test_valid_integer (line 130) | def test_valid_integer(self): method test_valid_string_number (line 136) | def test_valid_string_number(self): method test_zero_returns_default (line 141) | def test_zero_returns_default(self): method test_negative_returns_default (line 146) | def test_negative_returns_default(self): method test_none_returns_default (line 151) | def test_none_returns_default(self): method test_invalid_string_returns_default (line 156) | def test_invalid_string_returns_default(self): method test_float_truncates (line 161) | def test_float_truncates(self): method test_empty_string_returns_default (line 166) | def test_empty_string_returns_default(self): method test_custom_default (line 170) | def test_custom_default(self): class TestExtensionManifest (line 178) | class TestExtensionManifest: method test_valid_manifest (line 181) | def test_valid_manifest(self, extension_dir): method test_missing_required_field (line 193) | def test_missing_required_field(self, temp_dir): method test_invalid_extension_id (line 204) | def test_invalid_extension_id(self, temp_dir, valid_manifest_data): method test_invalid_version (line 217) | def test_invalid_version(self, temp_dir, valid_manifest_data): method test_invalid_command_name (line 230) | def test_invalid_command_name(self, temp_dir, valid_manifest_data): method test_no_commands (line 243) | def test_no_commands(self, temp_dir, valid_manifest_data): method test_manifest_hash (line 256) | def test_manifest_hash(self, extension_dir): class TestExtensionRegistry (line 268) | class TestExtensionRegistry: method test_empty_registry (line 271) | def test_empty_registry(self, temp_dir): method test_add_extension (line 282) | def test_add_extension(self, temp_dir): method test_remove_extension (line 301) | def test_remove_extension(self, temp_dir): method test_registry_persistence (line 316) | def test_registry_persistence(self, temp_dir): method test_update_preserves_installed_at (line 332) | def test_update_preserves_installed_at(self, temp_dir): method test_update_merges_with_existing (line 353) | def test_update_merges_with_existing(self, temp_dir): method test_update_raises_for_missing_extension (line 374) | def test_update_raises_for_missing_extension(self, temp_dir): method test_restore_overwrites_completely (line 384) | def test_restore_overwrites_completely(self, temp_dir): method test_restore_can_recreate_removed_entry (line 405) | def test_restore_can_recreate_removed_entry(self, temp_dir): method test_restore_rejects_none_metadata (line 423) | def test_restore_rejects_none_metadata(self, temp_dir): method test_restore_rejects_non_dict_metadata (line 432) | def test_restore_rejects_non_dict_metadata(self, temp_dir): method test_restore_uses_deep_copy (line 444) | def test_restore_uses_deep_copy(self, temp_dir): method test_get_returns_deep_copy (line 465) | def test_get_returns_deep_copy(self, temp_dir): method test_get_returns_none_for_corrupted_entry (line 484) | def test_get_returns_none_for_corrupted_entry(self, temp_dir): method test_list_returns_deep_copy (line 504) | def test_list_returns_deep_copy(self, temp_dir): method test_list_returns_empty_dict_for_corrupted_registry (line 523) | def test_list_returns_empty_dict_for_corrupted_registry(self, temp_dir): class TestExtensionManager (line 540) | class TestExtensionManager: method test_check_compatibility_valid (line 543) | def test_check_compatibility_valid(self, extension_dir, project_dir): method test_check_compatibility_invalid (line 552) | def test_check_compatibility_invalid(self, extension_dir, project_dir): method test_install_from_directory (line 561) | def test_install_from_directory(self, extension_dir, project_dir): method test_install_duplicate (line 580) | def test_install_duplicate(self, extension_dir, project_dir): method test_remove_extension (line 591) | def test_remove_extension(self, extension_dir, project_dir): method test_remove_nonexistent (line 608) | def test_remove_nonexistent(self, project_dir): method test_list_installed (line 615) | def test_list_installed(self, extension_dir, project_dir): method test_config_backup_on_remove (line 634) | def test_config_backup_on_remove(self, extension_dir, project_dir): class TestCommandRegistrar (line 658) | class TestCommandRegistrar: method test_kiro_cli_agent_config_present (line 661) | def test_kiro_cli_agent_config_present(self): method test_codex_agent_config_present (line 667) | def test_codex_agent_config_present(self): method test_pi_agent_config_present (line 673) | def test_pi_agent_config_present(self): method test_qwen_agent_config_is_markdown (line 682) | def test_qwen_agent_config_is_markdown(self): method test_parse_frontmatter_valid (line 691) | def test_parse_frontmatter_valid(self): method test_parse_frontmatter_no_frontmatter (line 711) | def test_parse_frontmatter_no_frontmatter(self): method test_parse_frontmatter_non_mapping_returns_empty_dict (line 721) | def test_parse_frontmatter_non_mapping_returns_empty_dict(self): method test_render_frontmatter (line 736) | def test_render_frontmatter(self): method test_register_commands_for_claude (line 750) | def test_register_commands_for_claude(self, extension_dir, project_dir): method test_command_with_aliases (line 778) | def test_command_with_aliases(self, project_dir, temp_dir): method test_unregister_commands_for_codex_skills_uses_mapped_names (line 827) | def test_unregister_commands_for_codex_skills_uses_mapped_names(self, ... method test_register_commands_for_all_agents_distinguishes_codex_from_amp (line 844) | def test_register_commands_for_all_agents_distinguishes_codex_from_amp... method test_codex_skill_registration_writes_skill_frontmatter (line 857) | def test_codex_skill_registration_writes_skill_frontmatter(self, exten... method test_codex_skill_registration_resolves_script_placeholders (line 877) | def test_codex_skill_registration_resolves_script_placeholders(self, p... method test_codex_skill_alias_frontmatter_matches_alias_name (line 946) | def test_codex_skill_alias_frontmatter_matches_alias_name(self, projec... method test_codex_skill_registration_uses_fallback_script_variant_without_init_options (line 993) | def test_codex_skill_registration_uses_fallback_script_variant_without... method test_codex_skill_registration_fallback_prefers_powershell_on_windows (line 1056) | def test_codex_skill_registration_fallback_prefers_powershell_on_windows( method test_register_commands_for_copilot (line 1120) | def test_register_commands_for_copilot(self, extension_dir, project_dir): method test_copilot_companion_prompt_created (line 1148) | def test_copilot_companion_prompt_created(self, extension_dir, project... method test_copilot_aliases_get_companion_prompts (line 1168) | def test_copilot_aliases_get_companion_prompts(self, project_dir, temp... method test_non_copilot_agent_no_companion_file (line 1219) | def test_non_copilot_agent_no_companion_file(self, extension_dir, proj... class TestVersionSatisfies (line 1238) | class TestVersionSatisfies: method test_version_satisfies_simple (line 1241) | def test_version_satisfies_simple(self): method test_version_satisfies_range (line 1247) | def test_version_satisfies_range(self): method test_version_satisfies_complex (line 1253) | def test_version_satisfies_complex(self): method test_version_satisfies_invalid (line 1258) | def test_version_satisfies_invalid(self): class TestIntegration (line 1266) | class TestIntegration: method test_full_install_and_remove_workflow (line 1269) | def test_full_install_and_remove_workflow(self, extension_dir, project... method test_copilot_cleanup_removes_prompt_files (line 1311) | def test_copilot_cleanup_removes_prompt_files(self, extension_dir, pro... method test_multiple_extensions (line 1336) | def test_multiple_extensions(self, temp_dir, project_dir): class TestExtensionCatalog (line 1393) | class TestExtensionCatalog: method test_catalog_initialization (line 1396) | def test_catalog_initialization(self, temp_dir): method test_cache_directory_creation (line 1407) | def test_cache_directory_creation(self, temp_dir): method test_cache_expiration (line 1444) | def test_cache_expiration(self, temp_dir): method test_search_all_extensions (line 1472) | def test_search_all_extensions(self, temp_dir): method test_search_by_query (line 1540) | def test_search_by_query(self, temp_dir): method test_search_by_tag (line 1604) | def test_search_by_tag(self, temp_dir): method test_search_verified_only (line 1675) | def test_search_verified_only(self, temp_dir): method test_get_extension_info (line 1739) | def test_get_extension_info(self, temp_dir): method test_clear_cache (line 1801) | def test_clear_cache(self, temp_dir): class TestCatalogEntry (line 1826) | class TestCatalogEntry: method test_catalog_entry_creation (line 1829) | def test_catalog_entry_creation(self): class TestCatalogStack (line 1845) | class TestCatalogStack: method _make_project (line 1848) | def _make_project(self, temp_dir: Path) -> Path: method _write_catalog_config (line 1855) | def _write_catalog_config(self, project_dir: Path, catalogs: list) -> ... method _write_valid_cache (line 1863) | def _write_valid_cache( method test_default_stack (line 1881) | def test_default_stack(self, temp_dir): method test_env_var_overrides_default_stack (line 1898) | def test_env_var_overrides_default_stack(self, temp_dir, monkeypatch): method test_env_var_invalid_url_raises (line 1911) | def test_env_var_invalid_url_raises(self, temp_dir, monkeypatch): method test_project_config_overrides_defaults (line 1920) | def test_project_config_overrides_defaults(self, temp_dir): method test_project_config_sorted_by_priority (line 1942) | def test_project_config_sorted_by_priority(self, temp_dir): method test_project_config_invalid_url_raises (line 1970) | def test_project_config_invalid_url_raises(self, temp_dir): method test_empty_project_config_raises_error (line 1989) | def test_empty_project_config_raises_error(self, temp_dir): method test_catalog_entries_without_urls_raises_error (line 2005) | def test_catalog_entries_without_urls_raises_error(self, temp_dir): method test_load_catalog_config_missing_file (line 2028) | def test_load_catalog_config_missing_file(self, temp_dir): method test_load_catalog_config_localhost_allowed (line 2036) | def test_load_catalog_config_localhost_allowed(self, temp_dir): method test_merge_conflict_higher_priority_wins (line 2059) | def test_merge_conflict_higher_priority_wins(self, temp_dir): method test_install_allowed_false_from_get_extension_info (line 2144) | def test_install_allowed_false_from_get_extension_info(self, temp_dir): method test_search_results_include_catalog_metadata (line 2179) | def test_search_results_include_catalog_metadata(self, temp_dir): class TestExtensionIgnore (line 2213) | class TestExtensionIgnore: method _make_extension (line 2216) | def _make_extension(self, temp_dir, valid_manifest_data, extra_files=N... method test_no_extensionignore (line 2251) | def test_no_extensionignore(self, temp_dir, valid_manifest_data): method test_extensionignore_excludes_files (line 2270) | def test_extensionignore_excludes_files(self, temp_dir, valid_manifest... method test_extensionignore_glob_patterns (line 2300) | def test_extensionignore_glob_patterns(self, temp_dir, valid_manifest_... method test_extensionignore_comments_and_blanks (line 2325) | def test_extensionignore_comments_and_blanks(self, temp_dir, valid_man... method test_extensionignore_itself_excluded (line 2345) | def test_extensionignore_itself_excluded(self, temp_dir, valid_manifes... method test_extensionignore_relative_path_match (line 2364) | def test_extensionignore_relative_path_match(self, temp_dir, valid_man... method test_extensionignore_dotdot_pattern_is_noop (line 2388) | def test_extensionignore_dotdot_pattern_is_noop(self, temp_dir, valid_... method test_extensionignore_absolute_path_pattern_is_noop (line 2410) | def test_extensionignore_absolute_path_pattern_is_noop(self, temp_dir,... method test_extensionignore_empty_file (line 2431) | def test_extensionignore_empty_file(self, temp_dir, valid_manifest_data): method test_extensionignore_windows_backslash_patterns (line 2454) | def test_extensionignore_windows_backslash_patterns(self, temp_dir, va... method test_extensionignore_star_does_not_cross_directories (line 2477) | def test_extensionignore_star_does_not_cross_directories(self, temp_di... method test_extensionignore_doublestar_crosses_directories (line 2501) | def test_extensionignore_doublestar_crosses_directories(self, temp_dir... method test_extensionignore_negation_pattern (line 2526) | def test_extensionignore_negation_pattern(self, temp_dir, valid_manife... class TestExtensionAddCLI (line 2553) | class TestExtensionAddCLI: method test_add_by_display_name_uses_resolved_id_for_download (line 2556) | def test_add_by_display_name_uses_resolved_id_for_download(self, tmp_p... class TestExtensionUpdateCLI (line 2612) | class TestExtensionUpdateCLI: method _create_extension_source (line 2616) | def _create_extension_source(base_dir: Path, version: str, include_con... method _create_catalog_zip (line 2658) | def _create_catalog_zip(zip_path: Path, version: str): method test_update_success_preserves_installed_at (line 2678) | def test_update_success_preserves_installed_at(self, tmp_path): method test_update_failure_rolls_back_registry_hooks_and_commands (line 2726) | def test_update_failure_rolls_back_registry_hooks_and_commands(self, t... class TestExtensionListCLI (line 2788) | class TestExtensionListCLI: method test_list_shows_extension_id (line 2791) | def test_list_shows_extension_id(self, extension_dir, project_dir): class TestExtensionPriority (line 2814) | class TestExtensionPriority: method test_list_by_priority_empty (line 2817) | def test_list_by_priority_empty(self, temp_dir): method test_list_by_priority_single (line 2827) | def test_list_by_priority_single(self, temp_dir): method test_list_by_priority_ordering (line 2841) | def test_list_by_priority_ordering(self, temp_dir): method test_list_by_priority_default (line 2860) | def test_list_by_priority_default(self, temp_dir): method test_list_by_priority_invalid_priority_defaults (line 2879) | def test_list_by_priority_invalid_priority_defaults(self, temp_dir): method test_list_by_priority_excludes_disabled (line 2897) | def test_list_by_priority_excludes_disabled(self, temp_dir): method test_list_by_priority_includes_disabled_when_requested (line 2914) | def test_list_by_priority_includes_disabled_when_requested(self, temp_... method test_install_with_priority (line 2931) | def test_install_with_priority(self, extension_dir, project_dir): method test_install_default_priority (line 2939) | def test_install_default_priority(self, extension_dir, project_dir): method test_list_installed_includes_priority (line 2947) | def test_list_installed_includes_priority(self, extension_dir, project... method test_priority_preserved_on_update (line 2957) | def test_priority_preserved_on_update(self, temp_dir): method test_corrupted_extension_entry_not_picked_up_as_unregistered (line 2972) | def test_corrupted_extension_entry_not_picked_up_as_unregistered(self,... class TestExtensionPriorityCLI (line 3003) | class TestExtensionPriorityCLI: method test_add_with_priority_option (line 3006) | def test_add_with_priority_option(self, extension_dir, project_dir): method test_list_shows_priority (line 3025) | def test_list_shows_priority(self, extension_dir, project_dir): method test_set_priority_changes_priority (line 3043) | def test_set_priority_changes_priority(self, extension_dir, project_dir): method test_set_priority_same_value_no_change (line 3068) | def test_set_priority_same_value_no_change(self, extension_dir, projec... method test_set_priority_invalid_value (line 3086) | def test_set_priority_invalid_value(self, extension_dir, project_dir): method test_set_priority_not_installed (line 3104) | def test_set_priority_not_installed(self, project_dir): method test_set_priority_by_display_name (line 3121) | def test_set_priority_by_display_name(self, extension_dir, project_dir): class TestExtensionPriorityBackwardsCompatibility (line 3145) | class TestExtensionPriorityBackwardsCompatibility: method test_legacy_extension_without_priority_field (line 3148) | def test_legacy_extension_without_priority_field(self, temp_dir): method test_legacy_extension_in_list_installed (line 3174) | def test_legacy_extension_in_list_installed(self, extension_dir, proje... method test_mixed_legacy_and_new_extensions_ordering (line 3191) | def test_mixed_legacy_and_new_extensions_ordering(self, temp_dir): FILE: tests/test_merge.py function test_merge_json_files_type_mismatch_preservation (line 8) | def test_merge_json_files_type_mismatch_preservation(tmp_path): function test_merge_json_files_deep_nesting (line 23) | def test_merge_json_files_deep_nesting(tmp_path): function test_merge_json_files_empty_existing (line 50) | def test_merge_json_files_empty_existing(tmp_path): function test_merge_vscode_realistic_scenario (line 61) | def test_merge_vscode_realistic_scenario(tmp_path): function test_merge_json_files_with_bom (line 101) | def test_merge_json_files_with_bom(tmp_path): function test_merge_json_files_not_a_dictionary_template (line 112) | def test_merge_json_files_not_a_dictionary_template(tmp_path): function test_merge_json_files_unparseable_existing (line 120) | def test_merge_json_files_unparseable_existing(tmp_path): function test_merge_json_files_list_preservation (line 128) | def test_merge_json_files_list_preservation(tmp_path): function test_merge_json_files_no_changes (line 142) | def test_merge_json_files_no_changes(tmp_path): function test_merge_json_files_type_mismatch_no_op (line 155) | def test_merge_json_files_type_mismatch_no_op(tmp_path): function test_handle_vscode_settings_preserves_mode_on_atomic_write (line 168) | def test_handle_vscode_settings_preserves_mode_on_atomic_write(tmp_path): FILE: tests/test_presets.py function temp_dir (line 42) | def temp_dir(): function valid_pack_data (line 50) | def valid_pack_data(): function pack_dir (line 82) | def pack_dir(temp_dir, valid_pack_data): function project_dir (line 104) | def project_dir(temp_dir): class TestPresetManifest (line 135) | class TestPresetManifest: method test_valid_manifest (line 138) | def test_valid_manifest(self, pack_dir): method test_missing_manifest (line 150) | def test_missing_manifest(self, temp_dir): method test_invalid_yaml (line 155) | def test_invalid_yaml(self, temp_dir): method test_missing_schema_version (line 162) | def test_missing_schema_version(self, temp_dir, valid_pack_data): method test_wrong_schema_version (line 171) | def test_wrong_schema_version(self, temp_dir, valid_pack_data): method test_missing_pack_id (line 180) | def test_missing_pack_id(self, temp_dir, valid_pack_data): method test_invalid_pack_id_format (line 189) | def test_invalid_pack_id_format(self, temp_dir, valid_pack_data): method test_invalid_version (line 198) | def test_invalid_version(self, temp_dir, valid_pack_data): method test_missing_speckit_version (line 207) | def test_missing_speckit_version(self, temp_dir, valid_pack_data): method test_no_templates_provided (line 216) | def test_no_templates_provided(self, temp_dir, valid_pack_data): method test_invalid_template_type (line 225) | def test_invalid_template_type(self, temp_dir, valid_pack_data): method test_valid_template_types (line 234) | def test_valid_template_types(self): method test_template_missing_required_fields (line 240) | def test_template_missing_required_fields(self, temp_dir, valid_pack_d... method test_invalid_template_name_format (line 249) | def test_invalid_template_name_format(self, temp_dir, valid_pack_data): method test_get_hash (line 258) | def test_get_hash(self, pack_dir): method test_multiple_templates (line 265) | def test_multiple_templates(self, temp_dir, valid_pack_data): class TestPresetRegistry (line 283) | class TestPresetRegistry: method test_empty_registry (line 286) | def test_empty_registry(self, temp_dir): method test_add_and_get (line 294) | def test_add_and_get(self, temp_dir): method test_remove (line 308) | def test_remove(self, temp_dir): method test_remove_nonexistent (line 320) | def test_remove_nonexistent(self, temp_dir): method test_list (line 327) | def test_list(self, temp_dir): method test_persistence (line 341) | def test_persistence(self, temp_dir): method test_corrupted_registry (line 354) | def test_corrupted_registry(self, temp_dir): method test_get_nonexistent (line 365) | def test_get_nonexistent(self, temp_dir): method test_restore (line 372) | def test_restore(self, temp_dir): method test_restore_rejects_none_metadata (line 393) | def test_restore_rejects_none_metadata(self, temp_dir): method test_restore_rejects_non_dict_metadata (line 402) | def test_restore_rejects_non_dict_metadata(self, temp_dir): method test_restore_uses_deep_copy (line 414) | def test_restore_uses_deep_copy(self, temp_dir): method test_get_returns_deep_copy (line 435) | def test_get_returns_deep_copy(self, temp_dir): method test_get_returns_none_for_corrupted_entry (line 453) | def test_get_returns_none_for_corrupted_entry(self, temp_dir): method test_list_returns_deep_copy (line 472) | def test_list_returns_deep_copy(self, temp_dir): method test_list_returns_empty_dict_for_corrupted_registry (line 490) | def test_list_returns_empty_dict_for_corrupted_registry(self, temp_dir): method test_list_by_priority_excludes_disabled (line 504) | def test_list_by_priority_excludes_disabled(self, temp_dir): method test_list_by_priority_includes_disabled_when_requested (line 521) | def test_list_by_priority_includes_disabled_when_requested(self, temp_... class TestPresetManager (line 542) | class TestPresetManager: method test_install_from_directory (line 545) | def test_install_from_directory(self, project_dir, pack_dir): method test_install_already_installed (line 559) | def test_install_already_installed(self, project_dir, pack_dir): method test_install_incompatible (line 567) | def test_install_incompatible(self, project_dir, temp_dir, valid_pack_... method test_install_from_zip (line 582) | def test_install_from_zip(self, project_dir, pack_dir, temp_dir): method test_install_from_zip_nested (line 596) | def test_install_from_zip_nested(self, project_dir, pack_dir, temp_dir): method test_install_from_zip_no_manifest (line 609) | def test_install_from_zip_no_manifest(self, project_dir, temp_dir): method test_remove (line 619) | def test_remove(self, project_dir, pack_dir): method test_remove_nonexistent (line 632) | def test_remove_nonexistent(self, project_dir): method test_list_installed (line 638) | def test_list_installed(self, project_dir, pack_dir): method test_list_installed_empty (line 650) | def test_list_installed_empty(self, project_dir): method test_get_pack (line 655) | def test_get_pack(self, project_dir, pack_dir): method test_get_pack_not_installed (line 664) | def test_get_pack_not_installed(self, project_dir): method test_check_compatibility_valid (line 669) | def test_check_compatibility_valid(self, pack_dir, temp_dir): method test_check_compatibility_invalid (line 675) | def test_check_compatibility_invalid(self, pack_dir, temp_dir): method test_install_with_priority (line 683) | def test_install_with_priority(self, project_dir, pack_dir): method test_install_default_priority (line 692) | def test_install_default_priority(self, project_dir, pack_dir): method test_list_installed_includes_priority (line 701) | def test_list_installed_includes_priority(self, project_dir, pack_dir): class TestRegistryPriority (line 711) | class TestRegistryPriority: method test_list_by_priority (line 714) | def test_list_by_priority(self, temp_dir): method test_list_by_priority_default (line 730) | def test_list_by_priority_default(self, temp_dir): method test_list_by_priority_invalid_priority_defaults (line 743) | def test_list_by_priority_invalid_priority_defaults(self, temp_dir): class TestPresetResolver (line 765) | class TestPresetResolver: method test_resolve_core_template (line 768) | def test_resolve_core_template(self, project_dir): method test_resolve_nonexistent (line 776) | def test_resolve_nonexistent(self, project_dir): method test_resolve_higher_priority_pack_wins (line 782) | def test_resolve_higher_priority_pack_wins(self, project_dir, temp_dir... method test_resolve_override_takes_priority (line 816) | def test_resolve_override_takes_priority(self, project_dir): method test_resolve_pack_takes_priority_over_core (line 829) | def test_resolve_pack_takes_priority_over_core(self, project_dir, pack... method test_resolve_override_takes_priority_over_pack (line 840) | def test_resolve_override_takes_priority_over_pack(self, project_dir, ... method test_resolve_extension_provided_templates (line 857) | def test_resolve_extension_provided_templates(self, project_dir): method test_resolve_disabled_extension_templates_skipped (line 876) | def test_resolve_disabled_extension_templates_skipped(self, project_dir): method test_resolve_disabled_extension_not_picked_up_as_unregistered (line 895) | def test_resolve_disabled_extension_not_picked_up_as_unregistered(self... method test_resolve_pack_over_extension (line 914) | def test_resolve_pack_over_extension(self, project_dir, pack_dir, temp... method test_resolve_with_source_core (line 933) | def test_resolve_with_source_core(self, project_dir): method test_resolve_with_source_override (line 941) | def test_resolve_with_source_override(self, project_dir): method test_resolve_with_source_pack (line 953) | def test_resolve_with_source_pack(self, project_dir, pack_dir): method test_resolve_with_source_extension (line 964) | def test_resolve_with_source_extension(self, project_dir): method test_resolve_with_source_not_found (line 982) | def test_resolve_with_source_not_found(self, project_dir): method test_resolve_skips_hidden_extension_dirs (line 988) | def test_resolve_skips_hidden_extension_dirs(self, project_dir): class TestExtensionPriorityResolution (line 1001) | class TestExtensionPriorityResolution: method test_unregistered_beats_registered_with_lower_precedence (line 1004) | def test_unregistered_beats_registered_with_lower_precedence(self, pro... method test_registered_with_higher_precedence_beats_unregistered (line 1028) | def test_registered_with_higher_precedence_beats_unregistered(self, pr... method test_unregistered_attribution_with_priority_ordering (line 1052) | def test_unregistered_attribution_with_priority_ordering(self, project... method test_same_priority_sorted_alphabetically (line 1077) | def test_same_priority_sorted_alphabetically(self, project_dir): class TestPresetCatalog (line 1102) | class TestPresetCatalog: method test_default_catalog_url (line 1105) | def test_default_catalog_url(self, project_dir): method test_community_catalog_url (line 1111) | def test_community_catalog_url(self, project_dir): method test_cache_validation_no_cache (line 1116) | def test_cache_validation_no_cache(self, project_dir): method test_cache_validation_valid (line 1121) | def test_cache_validation_valid(self, project_dir): method test_cache_validation_expired (line 1136) | def test_cache_validation_expired(self, project_dir): method test_cache_validation_corrupted (line 1151) | def test_cache_validation_corrupted(self, project_dir): method test_clear_cache (line 1161) | def test_clear_cache(self, project_dir): method test_search_with_cached_data (line 1173) | def test_search_with_cached_data(self, project_dir): method test_get_pack_info (line 1221) | def test_get_pack_info(self, project_dir): method test_validate_catalog_url_https (line 1248) | def test_validate_catalog_url_https(self, project_dir): method test_validate_catalog_url_http_rejected (line 1253) | def test_validate_catalog_url_http_rejected(self, project_dir): method test_validate_catalog_url_localhost_http_allowed (line 1259) | def test_validate_catalog_url_localhost_http_allowed(self, project_dir): method test_env_var_catalog_url (line 1265) | def test_env_var_catalog_url(self, project_dir, monkeypatch): class TestIntegration (line 1275) | class TestIntegration: method test_full_install_resolve_remove_cycle (line 1278) | def test_full_install_resolve_remove_cycle(self, project_dir, pack_dir): method test_override_beats_pack_beats_extension_beats_core (line 1299) | def test_override_beats_pack_beats_extension_beats_core(self, project_... method test_install_from_zip_then_resolve (line 1336) | def test_install_from_zip_then_resolve(self, project_dir, pack_dir, te... class TestPresetCatalogEntry (line 1360) | class TestPresetCatalogEntry: method test_create_entry (line 1363) | def test_create_entry(self): method test_default_description (line 1378) | def test_default_description(self): class TestPresetCatalogMultiCatalog (line 1392) | class TestPresetCatalogMultiCatalog: method test_default_active_catalogs (line 1395) | def test_default_active_catalogs(self, project_dir): method test_env_var_overrides_catalogs (line 1407) | def test_env_var_overrides_catalogs(self, project_dir, monkeypatch): method test_project_config_overrides_defaults (line 1420) | def test_project_config_overrides_defaults(self, project_dir): method test_load_catalog_config_nonexistent (line 1440) | def test_load_catalog_config_nonexistent(self, project_dir): method test_load_catalog_config_empty (line 1448) | def test_load_catalog_config_empty(self, project_dir): method test_load_catalog_config_invalid_yaml (line 1457) | def test_load_catalog_config_invalid_yaml(self, project_dir): method test_load_catalog_config_not_a_list (line 1466) | def test_load_catalog_config_not_a_list(self, project_dir): method test_load_catalog_config_invalid_entry (line 1475) | def test_load_catalog_config_invalid_entry(self, project_dir): method test_load_catalog_config_http_url_rejected (line 1484) | def test_load_catalog_config_http_url_rejected(self, project_dir): method test_load_catalog_config_priority_sorting (line 1501) | def test_load_catalog_config_priority_sorting(self, project_dir): method test_load_catalog_config_invalid_priority (line 1528) | def test_load_catalog_config_invalid_priority(self, project_dir): method test_load_catalog_config_install_allowed_string (line 1545) | def test_load_catalog_config_install_allowed_string(self, project_dir): method test_get_catalog_url_uses_highest_priority (line 1564) | def test_get_catalog_url_uses_highest_priority(self, project_dir): method test_cache_paths_default_url (line 1585) | def test_cache_paths_default_url(self, project_dir): method test_cache_paths_custom_url (line 1594) | def test_cache_paths_custom_url(self, project_dir): method test_url_cache_valid (line 1604) | def test_url_cache_valid(self, project_dir): method test_url_cache_expired (line 1618) | def test_url_cache_expired(self, project_dir): class TestSelfTestPreset (line 1648) | class TestSelfTestPreset: method test_self_test_preset_exists (line 1651) | def test_self_test_preset_exists(self): method test_self_test_manifest_valid (line 1656) | def test_self_test_manifest_valid(self): method test_self_test_provides_all_core_templates (line 1664) | def test_self_test_provides_all_core_templates(self): method test_self_test_template_files_exist (line 1671) | def test_self_test_template_files_exist(self): method test_self_test_templates_have_marker (line 1678) | def test_self_test_templates_have_marker(self): method test_install_self_test_preset (line 1685) | def test_install_self_test_preset(self, project_dir): method test_self_test_overrides_all_core_templates (line 1692) | def test_self_test_overrides_all_core_templates(self, project_dir): method test_self_test_resolve_with_source (line 1713) | def test_self_test_resolve_with_source(self, project_dir): method test_self_test_removal_restores_core (line 1730) | def test_self_test_removal_restores_core(self, project_dir): method test_self_test_not_in_catalog (line 1746) | def test_self_test_not_in_catalog(self): method test_self_test_has_command (line 1752) | def test_self_test_has_command(self): method test_self_test_command_file_exists (line 1759) | def test_self_test_command_file_exists(self): method test_self_test_registers_commands_for_claude (line 1766) | def test_self_test_registers_commands_for_claude(self, project_dir): method test_self_test_registers_commands_for_gemini (line 1781) | def test_self_test_registers_commands_for_gemini(self, project_dir): method test_self_test_unregisters_commands_on_remove (line 1797) | def test_self_test_unregisters_commands_on_remove(self, project_dir): method test_self_test_no_commands_without_agent_dirs (line 1811) | def test_self_test_no_commands_without_agent_dirs(self, project_dir): method test_extension_command_skipped_when_extension_missing (line 1819) | def test_extension_command_skipped_when_extension_missing(self, projec... method test_extension_command_registered_when_extension_present (line 1862) | def test_extension_command_registered_when_extension_present(self, pro... class TestInitOptions (line 1907) | class TestInitOptions: method test_save_and_load_round_trip (line 1910) | def test_save_and_load_round_trip(self, project_dir): method test_load_returns_empty_when_missing (line 1920) | def test_load_returns_empty_when_missing(self, project_dir): method test_load_returns_empty_on_invalid_json (line 1925) | def test_load_returns_empty_on_invalid_json(self, project_dir): class TestPresetSkills (line 1935) | class TestPresetSkills: method _write_init_options (line 1938) | def _write_init_options(self, project_dir, ai="claude", ai_skills=True): method _create_skill (line 1943) | def _create_skill(self, skills_dir, skill_name, body="original body"): method test_skill_overridden_on_preset_install (line 1951) | def test_skill_overridden_on_preset_install(self, project_dir, temp_dir): method test_skill_not_updated_when_ai_skills_disabled (line 1975) | def test_skill_not_updated_when_ai_skills_disabled(self, project_dir, ... method test_skill_not_updated_without_init_options (line 1991) | def test_skill_not_updated_without_init_options(self, project_dir, tem... method test_skill_restored_on_preset_remove (line 2006) | def test_skill_restored_on_preset_remove(self, project_dir, temp_dir): method test_no_skills_registered_when_no_skill_dir_exists (line 2036) | def test_no_skills_registered_when_no_skill_dir_exists(self, project_d... class TestPresetSetPriority (line 2051) | class TestPresetSetPriority: method test_set_priority_changes_priority (line 2054) | def test_set_priority_changes_priority(self, project_dir, pack_dir): method test_set_priority_same_value_no_change (line 2079) | def test_set_priority_same_value_no_change(self, project_dir, pack_dir): method test_set_priority_invalid_value (line 2097) | def test_set_priority_invalid_value(self, project_dir, pack_dir): method test_set_priority_not_installed (line 2115) | def test_set_priority_not_installed(self, project_dir): class TestPresetPriorityBackwardsCompatibility (line 2130) | class TestPresetPriorityBackwardsCompatibility: method test_legacy_preset_without_priority_field (line 2133) | def test_legacy_preset_without_priority_field(self, temp_dir): method test_legacy_preset_in_list_installed (line 2159) | def test_legacy_preset_in_list_installed(self, project_dir, pack_dir): method test_mixed_legacy_and_new_presets_ordering (line 2176) | def test_mixed_legacy_and_new_presets_ordering(self, temp_dir): class TestPresetEnableDisable (line 2210) | class TestPresetEnableDisable: method test_disable_preset (line 2213) | def test_disable_preset(self, project_dir, pack_dir): method test_enable_preset (line 2238) | def test_enable_preset(self, project_dir, pack_dir): method test_disable_already_disabled (line 2264) | def test_disable_already_disabled(self, project_dir, pack_dir): method test_enable_already_enabled (line 2283) | def test_enable_already_enabled(self, project_dir, pack_dir): method test_disable_not_installed (line 2301) | def test_disable_not_installed(self, project_dir): method test_enable_not_installed (line 2315) | def test_enable_not_installed(self, project_dir): method test_disabled_preset_excluded_from_resolution (line 2329) | def test_disabled_preset_excluded_from_resolution(self, project_dir, p... method test_enable_corrupted_registry_entry (line 2355) | def test_enable_corrupted_registry_entry(self, project_dir, pack_dir): method test_disable_corrupted_registry_entry (line 2375) | def test_disable_corrupted_registry_entry(self, project_dir, pack_dir):