From c498905e6a75a8283955e9ffb80eb32bd8f01f89 Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Fri, 10 Jul 2026 20:19:44 +0200 Subject: [PATCH 1/3] fix(hooks): emit Copilot hook schema version Ensure generated Copilot hook JSON defaults the required top-level version to 1 and cover it with a regression test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/apm_cli/integration/hook_integrator.py | 2 ++ tests/unit/integration/test_hook_integrator.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/apm_cli/integration/hook_integrator.py b/src/apm_cli/integration/hook_integrator.py index 412a60f74..5b0d96657 100644 --- a/src/apm_cli/integration/hook_integrator.py +++ b/src/apm_cli/integration/hook_integrator.py @@ -1283,6 +1283,8 @@ def integrate_package_hooks( renamed_hooks[event_name] = entries rewritten["hooks"] = renamed_hooks + rewritten.setdefault("version", 1) + # Write rewritten JSON with open(target_path, "w", encoding="utf-8") as f: json.dump(rewritten, f, indent=2) diff --git a/tests/unit/integration/test_hook_integrator.py b/tests/unit/integration/test_hook_integrator.py index 558496358..044af9944 100644 --- a/tests/unit/integration/test_hook_integrator.py +++ b/tests/unit/integration/test_hook_integrator.py @@ -281,6 +281,17 @@ def test_integrate_hookify_vscode(self, temp_project): assert (scripts_dir / "stop.py").exists() assert (scripts_dir / "userpromptsubmit.py").exists() + def test_copilot_version_emitted_on_fresh_install(self, temp_project): + """Fresh Copilot hook JSON must contain top-level "version": 1.""" + pkg_info = self._setup_hookify_package(temp_project) + integrator = HookIntegrator() + + integrator.integrate_package_hooks(pkg_info, temp_project) + + hooks_path = temp_project / ".github" / "hooks" / "hookify-hooks.json" + config = json.loads(hooks_path.read_text()) + assert config["version"] == 1 + def test_integrate_learning_output_style_vscode(self, temp_project): """Test VSCode integration of learning-output-style plugin (different script dir).""" pkg_dir = temp_project / "apm_modules" / "anthropics" / "learning-output-style" From fbfc9f0d0ea62573d99be613239aa6b293d3c8ec Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Fri, 10 Jul 2026 20:59:13 +0200 Subject: [PATCH 2/3] test(hooks): preserve explicit Copilot version Protect the non-overwrite half of the schema-version fix with a regression test, addressing the review panel's test-coverage follow-up. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- tests/unit/integration/test_hook_integrator.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/unit/integration/test_hook_integrator.py b/tests/unit/integration/test_hook_integrator.py index 044af9944..023bdfb50 100644 --- a/tests/unit/integration/test_hook_integrator.py +++ b/tests/unit/integration/test_hook_integrator.py @@ -292,6 +292,21 @@ def test_copilot_version_emitted_on_fresh_install(self, temp_project): config = json.loads(hooks_path.read_text()) assert config["version"] == 1 + def test_copilot_existing_source_version_preserved(self, temp_project): + """An explicit source version must not be overwritten.""" + pkg_info = self._setup_hookify_package(temp_project) + source_path = pkg_info.install_path / "hooks" / "hooks.json" + source_config = json.loads(source_path.read_text()) + source_config["version"] = 3 + source_path.write_text(json.dumps(source_config)) + + integrator = HookIntegrator() + integrator.integrate_package_hooks(pkg_info, temp_project) + + hooks_path = temp_project / ".github" / "hooks" / "hookify-hooks.json" + config = json.loads(hooks_path.read_text()) + assert config["version"] == 3 + def test_integrate_learning_output_style_vscode(self, temp_project): """Test VSCode integration of learning-output-style plugin (different script dir).""" pkg_dir = temp_project / "apm_modules" / "anthropics" / "learning-output-style" From 42af7a69a0929c83d1e50a1210a3f18ef1756f24 Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Fri, 10 Jul 2026 21:13:27 +0200 Subject: [PATCH 3/3] test(hooks): verify version through install dispatch Assert the required Copilot hook schema version at the real install-service dispatch tier, addressing the final panel coverage follow-up. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- tests/integration/test_hook_integrator_copilot_casing_e2e.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_hook_integrator_copilot_casing_e2e.py b/tests/integration/test_hook_integrator_copilot_casing_e2e.py index 8fcf85fba..0f995f741 100644 --- a/tests/integration/test_hook_integrator_copilot_casing_e2e.py +++ b/tests/integration/test_hook_integrator_copilot_casing_e2e.py @@ -80,7 +80,9 @@ def _read_copilot_hooks_config(project_root: Path, package_name: str) -> dict[st """Read the actual Copilot hook JSON written under .github/hooks.""" config_path = project_root / ".github" / "hooks" / f"{package_name}-hooks.json" assert config_path.exists() - return json.loads(config_path.read_text(encoding="utf-8")) + config = json.loads(config_path.read_text(encoding="utf-8")) + assert config["version"] == 1 + return config def test_copilot_install_writes_only_camel_case_hook_events(tmp_path: Path) -> None: