fix(presets): tolerate non-UTF-8 legacy commands (#3896)

Assisted-by: GitHub Copilot (model: GPT-5.6 Sol, autonomous)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Marsel Safin
2026-08-03 12:33:39 -05:00
committed by GitHub
co-authored by Copilot
parent e9ffc9d8e7
commit 14fab0a1af
2 changed files with 19 additions and 1 deletions
+1 -1
View File
@@ -5297,7 +5297,7 @@ class PresetResolver:
fm_strategy = fm_data.get("strategy")
if isinstance(fm_strategy, str) and fm_strategy.lower() in VALID_PRESET_STRATEGIES:
strategy = fm_strategy.lower()
except (yaml.YAMLError, OSError):
except (UnicodeDecodeError, yaml.YAMLError, OSError):
# Best-effort legacy frontmatter parsing: keep default
# strategy ("replace") when content is unreadable/invalid.
pass
+18
View File
@@ -11626,6 +11626,24 @@ class TestResolveContent:
class TestCollectAllLayers:
"""Test PresetResolver.collect_all_layers() method."""
def test_non_utf8_legacy_command_keeps_replace_strategy(self, project_dir):
presets_dir = project_dir / ".specify" / "presets"
command_path = (
presets_dir / "legacy-pack" / "commands" / "speckit.legacy.md"
)
command_path.parent.mkdir(parents=True)
command_path.write_bytes(b"\xff\xfe")
PresetRegistry(presets_dir).add(
"legacy-pack", {"version": "1.0.0", "priority": 10}
)
layers = PresetResolver(project_dir).collect_all_layers(
"speckit.legacy", "command"
)
assert layers[0]["path"] == command_path
assert layers[0]["strategy"] == "replace"
def test_single_core_layer(self, project_dir):
"""Test collecting layers with only core template."""
resolver = PresetResolver(project_dir)