- Fix PS Resolve-Template fallback to skip dot-prefixed dirs (.cache)
- Rename _catalog to _catalog_name for consistency with extension system
- Enforce install_allowed policy in CLI preset add and download_pack()
- Fix shell injection: pass registry path via env var instead of string interpolation
- Fix init --preset error masking: distinguish "not found" from real errors
- Fix bash resolve_template: skip hidden dirs in extensions (match Python/PS)
- Fix temp dir leaks in tests: use temp_dir fixture instead of mkdtemp
- Fix self-test catalog entry: add note that it's local-only (no download_url)
- Fix Windows path issue in resolve_with_source: use Path.relative_to()
- Fix skill restore path: use project's .specify/templates/commands/ not source tree
- Add encoding="utf-8" to all file read/write in agents.py
- Update test to set up core command templates for skill restoration
- Move save_init_options() before preset install so skills propagation
works during 'specify init --preset --ai-skills'
- Clean up downloaded ZIP after successful preset install during init
- Validate --from URL scheme (require HTTPS, HTTP only for localhost)
- Expose unregister_commands() on extensions.py CommandRegistrar wrapper
instead of reaching into private _registrar field
- Use _get_merged_packs() for search() and get_pack_info() so all
active catalogs are searched, not just the highest-priority one
- Fix fetch_catalog() cache to verify cached URL matches current URL
- Fix PresetResolver: script resolution uses .sh extension, consistent
file extensions throughout resolve(), and resolve_with_source()
delegates to resolve() to honor template_type parameter
- Fix bash common.sh: fall through to directory scan when python3
returns empty preset list
- Fix PowerShell Resolve-Template: filter out dot-folders and sort
extensions deterministically