From 28fd16e663512c7c88a5c18cb19deeda099bfe48 Mon Sep 17 00:00:00 2001 From: Faqeha Noor Date: Sun, 19 Jul 2026 22:18:00 +0500 Subject: [PATCH] fix(copilot): honor preset command template overrides --- .../integrations/copilot/__init__.py | 10 ++++- .../integrations/test_integration_copilot.py | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/specify_cli/integrations/copilot/__init__.py b/src/specify_cli/integrations/copilot/__init__.py index 44bd47f353..01828b48d5 100644 --- a/src/specify_cli/integrations/copilot/__init__.py +++ b/src/specify_cli/integrations/copilot/__init__.py @@ -350,6 +350,10 @@ def _setup_default( if not templates: return [] + from ...presets import PresetResolver + + preset_resolver = PresetResolver(project_root_resolved) + dest = self.commands_dest(project_root) dest_resolved = dest.resolve() try: @@ -367,7 +371,11 @@ def _setup_default( # 1. Process and write command files as .agent.md for src_file in templates: - raw = src_file.read_text(encoding="utf-8") + resolved_template = preset_resolver.resolve( + src_file.stem, template_type="command" + ) + source_path = resolved_template or src_file + raw = source_path.read_text(encoding="utf-8") processed = self.process_template( raw, self.key, script_type, arg_placeholder, project_root=project_root, diff --git a/tests/integrations/test_integration_copilot.py b/tests/integrations/test_integration_copilot.py index 5b3a5712ad..0ee2533cc6 100644 --- a/tests/integrations/test_integration_copilot.py +++ b/tests/integrations/test_integration_copilot.py @@ -188,6 +188,43 @@ def test_specify_agent_resolves_active_spec_template(self, tmp_path): assert "Copy `.specify/templates/spec-template.md`" not in content assert "Load `.specify/templates/spec-template.md`" not in content + def test_setup_falls_back_to_bundled_command_template_without_preset_override(self, tmp_path): + """Copilot should keep using the bundled specify command template when no preset override exists.""" + from specify_cli.integrations.copilot import CopilotIntegration + copilot = CopilotIntegration() + m = IntegrationManifest("copilot", tmp_path) + + copilot.setup(tmp_path, m) + + specify_file = tmp_path / ".github" / "agents" / "speckit.specify.agent.md" + content = specify_file.read_text(encoding="utf-8") + assert "Create or update the feature specification" in content + assert "preset override content" not in content + + def test_setup_uses_preset_command_override_when_present(self, tmp_path): + """Copilot should prefer a preset-provided command template over the bundled one.""" + from specify_cli.integrations.copilot import CopilotIntegration + copilot = CopilotIntegration() + m = IntegrationManifest("copilot", tmp_path) + + preset_dir = tmp_path / ".specify" / "presets" / "demo" + (preset_dir / "commands").mkdir(parents=True, exist_ok=True) + (preset_dir / "commands" / "specify.md").write_text( + "preset override content\n", + encoding="utf-8", + ) + (tmp_path / ".specify" / "presets" / ".registry").write_text( + '{"schema_version": "1.0", "presets": {"demo": {"version": "1.0.0", "source": "local", "enabled": true, "priority": 10}}}', + encoding="utf-8", + ) + + copilot.setup(tmp_path, m) + + specify_file = tmp_path / ".github" / "agents" / "speckit.specify.agent.md" + content = specify_file.read_text(encoding="utf-8") + assert "preset override content" in content + assert "Create or update the feature specification" not in content + def test_plan_command_has_no_context_placeholder(self, tmp_path): """The core plan command must not carry a context-file placeholder — agent context files are owned by the opt-in agent-context extension."""