diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd2d1a00e..e8dd27229 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Fixed
+
+- Hook integrator now processes the `windows` property in hook JSON files, copying referenced scripts and rewriting paths during install/compile (#311)
+
 ### Added
 
 - `apm install` now deploys `.instructions.md` files to `.claude/rules/*.md` for Claude Code, converting `applyTo:` frontmatter to Claude's `paths:` format (#516)
diff --git a/src/apm_cli/integration/hook_integrator.py b/src/apm_cli/integration/hook_integrator.py
index 9ff9e55eb..d73540459 100644
--- a/src/apm_cli/integration/hook_integrator.py
+++ b/src/apm_cli/integration/hook_integrator.py
@@ -43,6 +43,7 @@
 """
 
 import json
+import logging
 import re
 import shutil
 from pathlib import Path
@@ -52,6 +53,8 @@
 from apm_cli.integration.base_integrator import BaseIntegrator
 from apm_cli.utils.paths import portable_relpath
 
+_log = logging.getLogger(__name__)
+
 
 @dataclass
 class HookIntegrationResult:
@@ -71,6 +74,23 @@ class HookIntegrator(BaseIntegrator):
     - Cursor: Merged into .cursor/hooks.json hooks key + .cursor/hooks/<pkg>/
     """
 
+    # Superset of all known script-path keys across supported hook specs.
+    # Every call site in _rewrite_hooks_data() iterates over this tuple,
+    # so a single addition here propagates everywhere.
+    #
+    #   "command":    Claude Code (primary), VS Code (default/cross-platform), Cursor
+    #   "bash":       GitHub Copilot Agent cloud/CLI
+    #   "powershell": GitHub Copilot Agent cloud/CLI
+    #   "windows":    VS Code (OS-specific override)
+    #   "linux":      VS Code (OS-specific override)
+    #   "osx":        VS Code (OS-specific override)
+    #
+    # Refs:
+    #   GH Copilot Agent: https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-hooks
+    #   VS Code:          https://code.visualstudio.com/docs/copilot/customization/hooks
+    #   Claude Code:      https://code.claude.com/docs/en/hooks
+    HOOK_COMMAND_KEYS: Tuple[str, ...] = ("command", "bash", "powershell", "windows", "linux", "osx")
+
     def find_hook_files(self, package_path: Path) -> List[Path]:
         """Find all hook JSON files in a package.
 
@@ -230,13 +250,18 @@ def _rewrite_hooks_data(
                 if not isinstance(matcher, dict):
                     continue
                 # Rewrite script paths in the matcher dict itself
-                # (GitHub Copilot flat format: bash/powershell keys at this level)
-                for key in ("command", "bash", "powershell"):
+                # (GitHub Copilot flat format: bash/powershell/windows keys at this level)
+                for key in self.HOOK_COMMAND_KEYS:
                     if key in matcher:
                         new_cmd, scripts = self._rewrite_command_for_target(
                             matcher[key], package_path, package_name, target,
                             hook_file_dir=hook_file_dir,
                         )
+                        if scripts:
+                            _log.debug(
+                                "Hook %s/%s: rewrote '%s' key (%d script(s))",
+                                package_name, event_name, key, len(scripts),
+                            )
                         matcher[key] = new_cmd
                         all_scripts.extend(scripts)
 
@@ -245,16 +270,29 @@ def _rewrite_hooks_data(
                 for hook in matcher.get("hooks", []):
                     if not isinstance(hook, dict):
                         continue
-                    for key in ("command", "bash", "powershell"):
+                    for key in self.HOOK_COMMAND_KEYS:
                         if key in hook:
                             new_cmd, scripts = self._rewrite_command_for_target(
                                 hook[key], package_path, package_name, target,
                                 hook_file_dir=hook_file_dir,
                             )
+                            if scripts:
+                                _log.debug(
+                                    "Hook %s/%s: rewrote '%s' key (%d script(s))",
+                                    package_name, event_name, key, len(scripts),
+                                )
                             hook[key] = new_cmd
                             all_scripts.extend(scripts)
 
-        return rewritten, all_scripts
+        # De-duplicate by target path to avoid redundant copies when
+        # multiple keys (e.g. command + bash) reference the same script.
+        seen_targets: dict[str, Path] = {}
+        for source, target_rel in all_scripts:
+            if target_rel not in seen_targets:
+                seen_targets[target_rel] = source
+        unique_scripts = [(src, tgt) for tgt, src in seen_targets.items()]
+
+        return rewritten, unique_scripts
 
     def _get_package_name(self, package_info) -> str:
         """Get a short package name for use in file/directory naming.
diff --git a/tests/unit/integration/test_hook_integrator.py b/tests/unit/integration/test_hook_integrator.py
index 744e59202..47aa9175c 100644
--- a/tests/unit/integration/test_hook_integrator.py
+++ b/tests/unit/integration/test_hook_integrator.py
@@ -1218,6 +1218,299 @@ def test_rewrite_powershell_key(self, temp_project):
         assert ".github/hooks/scripts/my-pkg/scripts/check.ps1" in cmd
         assert len(scripts) == 1
 
+    def test_rewrite_windows_key(self, temp_project):
+        """Test rewriting the windows key (GitHub Copilot format)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "scan-secrets.ps1").write_text("Write-Host 'scanning'")
+
+        integrator = HookIntegrator()
+        cmd, scripts = integrator._rewrite_command_for_target(
+            "./scripts/scan-secrets.ps1",
+            pkg_dir,
+            "my-pkg",
+            "vscode",
+        )
+
+        assert "./" not in cmd
+        assert ".github/hooks/scripts/my-pkg/scripts/scan-secrets.ps1" in cmd
+        assert len(scripts) == 1
+
+    def test_rewrite_linux_key(self, temp_project):
+        """Test rewriting the linux key (VS Code OS-specific override)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "validate.sh").write_text("#!/bin/bash")
+
+        integrator = HookIntegrator()
+        cmd, scripts = integrator._rewrite_command_for_target(
+            "./scripts/validate.sh",
+            pkg_dir,
+            "my-pkg",
+            "vscode",
+        )
+
+        assert "./" not in cmd
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.sh" in cmd
+        assert len(scripts) == 1
+
+    def test_rewrite_osx_key(self, temp_project):
+        """Test rewriting the osx key (VS Code OS-specific override)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "format-mac.sh").write_text("#!/bin/bash")
+
+        integrator = HookIntegrator()
+        cmd, scripts = integrator._rewrite_command_for_target(
+            "./scripts/format-mac.sh",
+            pkg_dir,
+            "my-pkg",
+            "vscode",
+        )
+
+        assert "./" not in cmd
+        assert ".github/hooks/scripts/my-pkg/scripts/format-mac.sh" in cmd
+        assert len(scripts) == 1
+
+    def test_rewrite_hooks_data_windows_flat_format(self, temp_project):
+        """Test _rewrite_hooks_data handles windows key in flat format (GitHub Copilot)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "validate.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "validate.ps1").write_text("Write-Host 'ok'")
+
+        data = {
+            "version": 1,
+            "hooks": {
+                "preToolUse": [
+                    {
+                        "type": "command",
+                        "bash": "./scripts/validate.sh",
+                        "windows": "./scripts/validate.ps1",
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["preToolUse"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.sh" in hook["bash"]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.ps1" in hook["windows"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_windows_nested_format(self, temp_project):
+        """Test _rewrite_hooks_data handles windows key in nested format (Claude-style)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "validate.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "validate.ps1").write_text("Write-Host 'ok'")
+
+        data = {
+            "hooks": {
+                "PreToolUse": [
+                    {
+                        "matcher": "Bash",
+                        "hooks": [
+                            {
+                                "type": "command",
+                                "command": "./scripts/validate.sh",
+                                "windows": "./scripts/validate.ps1",
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["PreToolUse"][0]["hooks"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.ps1" in hook["windows"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_linux_flat_format(self, temp_project):
+        """Test _rewrite_hooks_data handles linux key in flat format (VS Code)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "format.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "format-linux.sh").write_text("#!/bin/bash")
+
+        data = {
+            "hooks": {
+                "PostToolUse": [
+                    {
+                        "type": "command",
+                        "command": "./scripts/format.sh",
+                        "linux": "./scripts/format-linux.sh",
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["PostToolUse"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/format.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/format-linux.sh" in hook["linux"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_linux_nested_format(self, temp_project):
+        """Test _rewrite_hooks_data handles linux key in nested format (Claude-style)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "validate.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "validate-linux.sh").write_text("#!/bin/bash")
+
+        data = {
+            "hooks": {
+                "PreToolUse": [
+                    {
+                        "matcher": "Bash",
+                        "hooks": [
+                            {
+                                "type": "command",
+                                "command": "./scripts/validate.sh",
+                                "linux": "./scripts/validate-linux.sh",
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["PreToolUse"][0]["hooks"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate-linux.sh" in hook["linux"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_osx_flat_format(self, temp_project):
+        """Test _rewrite_hooks_data handles osx key in flat format (VS Code)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "format.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "format-mac.sh").write_text("#!/bin/bash")
+
+        data = {
+            "hooks": {
+                "PostToolUse": [
+                    {
+                        "type": "command",
+                        "command": "./scripts/format.sh",
+                        "osx": "./scripts/format-mac.sh",
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["PostToolUse"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/format.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/format-mac.sh" in hook["osx"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_osx_nested_format(self, temp_project):
+        """Test _rewrite_hooks_data handles osx key in nested format (Claude-style)."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "validate.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "validate-mac.sh").write_text("#!/bin/bash")
+
+        data = {
+            "hooks": {
+                "PreToolUse": [
+                    {
+                        "matcher": "Bash",
+                        "hooks": [
+                            {
+                                "type": "command",
+                                "command": "./scripts/validate.sh",
+                                "osx": "./scripts/validate-mac.sh",
+                            }
+                        ]
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["PreToolUse"][0]["hooks"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/validate-mac.sh" in hook["osx"]
+        assert len(scripts) == 2
+
+    def test_rewrite_hooks_data_all_platform_keys(self, temp_project):
+        """Test _rewrite_hooks_data handles all 6 platform keys together."""
+        pkg_dir = temp_project / "pkg"
+        (pkg_dir / "scripts").mkdir(parents=True)
+        (pkg_dir / "scripts" / "run.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "run.ps1").write_text("Write-Host 'ok'")
+        (pkg_dir / "scripts" / "run-win.ps1").write_text("Write-Host 'win'")
+        (pkg_dir / "scripts" / "run-linux.sh").write_text("#!/bin/bash")
+        (pkg_dir / "scripts" / "run-mac.sh").write_text("#!/bin/bash")
+
+        data = {
+            "version": 1,
+            "hooks": {
+                "preToolUse": [
+                    {
+                        "type": "command",
+                        "command": "./scripts/run.sh",
+                        "bash": "./scripts/run.sh",
+                        "powershell": "./scripts/run.ps1",
+                        "windows": "./scripts/run-win.ps1",
+                        "linux": "./scripts/run-linux.sh",
+                        "osx": "./scripts/run-mac.sh",
+                    }
+                ]
+            }
+        }
+
+        integrator = HookIntegrator()
+        rewritten, scripts = integrator._rewrite_hooks_data(
+            data, pkg_dir, "my-pkg", "vscode",
+        )
+
+        hook = rewritten["hooks"]["preToolUse"][0]
+        assert ".github/hooks/scripts/my-pkg/scripts/run.sh" in hook["command"]
+        assert ".github/hooks/scripts/my-pkg/scripts/run.sh" in hook["bash"]
+        assert ".github/hooks/scripts/my-pkg/scripts/run.ps1" in hook["powershell"]
+        assert ".github/hooks/scripts/my-pkg/scripts/run-win.ps1" in hook["windows"]
+        assert ".github/hooks/scripts/my-pkg/scripts/run-linux.sh" in hook["linux"]
+        assert ".github/hooks/scripts/my-pkg/scripts/run-mac.sh" in hook["osx"]
+        # Scripts are de-duplicated by target path. command and bash both
+        # reference run.sh with the same target, so only 5 unique entries.
+        assert len(scripts) == 5
+        script_targets = [t for _, t in scripts]
+        assert script_targets.count(".github/hooks/scripts/my-pkg/scripts/run.sh") == 1
+        assert script_targets.count(".github/hooks/scripts/my-pkg/scripts/run.ps1") == 1
+        assert script_targets.count(".github/hooks/scripts/my-pkg/scripts/run-win.ps1") == 1
+        assert script_targets.count(".github/hooks/scripts/my-pkg/scripts/run-linux.sh") == 1
+        assert script_targets.count(".github/hooks/scripts/my-pkg/scripts/run-mac.sh") == 1
+
     def test_rewrite_hooks_data_github_copilot_flat_format(self, temp_project):
         """Test _rewrite_hooks_data handles GitHub Copilot flat format (bash/powershell at top level)."""
         pkg_dir = temp_project / "pkg"
