Nightfall Hooks for VS Code Copilot

Step-by-step instructions for deploying Nightfall's VS Code Copilot hooks to corporate-managed developer devices via your MDM. For the package overview and MDM mapping table, see README.md; this guide walks through the actual setup, end to end.

Heads up: VS Code Copilot hooks are Preview. Unlike Claude Code (one drop-in file) or Cursor (one merged file), VS Code needs two things per device: the hook file and an enterprise policy that tells Copilot to read it. Both steps are covered below.


1. What gets deployed

Nightfall ships a Copilot hook config (payloads/nightfall.json) that registers the nightfall-hook-relay binary against four VS Code Copilot events:

Event

When it fires

Purpose

UserPromptSubmit

When the developer submits a prompt

Inspect prompt content

PreToolUse

Before Copilot runs a tool (file write, terminal, etc.)

Inspect/intercept the action before it happens

PostToolUse

After a tool runs

Capture the result

Stop

When the agent finishes responding

Capture the completed turn

Every event runs the same command - nightfall-hook-relay --source vscode_copilot - with a 15-second timeout. The relay binary is resolved by name on the system PATH, so the one config file works unchanged on both macOS and Windows.

{
  "hooks": {
    "UserPromptSubmit": [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "PreToolUse":       [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "PostToolUse":      [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ],
    "Stop":             [ { "type": "command", "command": "nightfall-hook-relay --source vscode_copilot", "timeout": 15 } ]
  }
}

2. Before you start

  • Nightfall endpoint agent is installed on every target device. The agent auto-installs and keeps nightfall-hook-relay updated, and adds it to the system PATH. The hooks call the binary by name, so without the agent the hooks resolve to nothing.

  • MDM scope selected - the device group / Blueprint / Smart Group / assignment that will receive the deployment.

  • VS Code + Copilot extension are reasonably current on managed devices, and ideally pinned during the pilot (hooks are Preview).

  • You have the pieces from this package for your platform: the hook payload (payloads/nightfall.json), the matching policy source (payloads/nightfall-vscode-copilot.mobileconfig on macOS, payloads/hookFilesLocations.json on Windows), and the scripts in scripts/macos/ or scripts/windows/.


3. How the deployment works (two steps)

VS Code Copilot won't read the hook file unless chat.hookFilesLocations is set as an enterprise policy. So each device needs two things to happen:

  1. Drop the hook file - the install script copies nightfall.json to a fixed file path.

  2. Set the policy - the policy script registers that file path in chat.hookFilesLocations (a Configuration Profile on macOS, a registry policy on Windows).

Both the install scripts and the policy scripts are idempotent, so they're safe to wire to a recurring trigger.

File paths

Platform

Staging path

Hook file target (step 1)

macOS

/opt/nightfall/hooks/vscode/nightfall.json

/Library/Application Support/Copilot/hooks/nightfall.json

Windows

`C:\Nightfall\Hooks\vscode

ightfall.json`

`C:\ProgramData\Copilot\hooks

ightfall.json`

Policy values (step 2)

Platform

Policy mechanism

What it sets

macOS

Configuration Profile (com.microsoft.VSCode)

chat.hookFilesLocations/Library/Application Support/Copilot/hooks/nightfall.json: true

Windows

Registry under HKLM\Software\Policies\Microsoft\VSCode

chat.hookFilesLocations → `C:\ProgramData\Copilot\hooks

ightfall.json: `true

Both policy mechanisms are additive: macOS profile layering preserves other vendors' Configuration Profiles for the com.microsoft.VSCode domain, and the Windows policy script merges Nightfall's entry into any existing chat.hookFilesLocations. Nightfall never clobbers another vendor's hook-file registration.


4. macOS setup

Step 1 - Stage the hook file

Deliver payloads/nightfall.json to /opt/nightfall/hooks/vscode/nightfall.json using your MDM's file-distribution or app-deployment feature (e.g. wrap the JSON in a .pkg, or use Workspace ONE's Files feature).

Step 2 - Drop the file into place

Wire scripts/macos/install.sh into your MDM as a System-context script. It:

  1. Verifies it's running as root (exits early if not - deploy at System scope).

  2. Confirms the staged payload exists.

  3. Creates /Library/Application Support/Copilot/hooks/ if needed.

  4. Copies nightfall.json into place.

Step 3 - Install the policy

Wire scripts/macos/install-policy.sh into your MDM (also System-context). It installs payloads/nightfall-vscode-copilot.mobileconfig via sudo profiles install, which sets chat.hookFilesLocations so Copilot reads the file dropped in Step 2. The profile uses a stable PayloadIdentifier (ai.nightfall.hooks.vscode), so re-installs update in place. Alternatively, on profile-aware MDMs (Jamf, Kandji, Workspace ONE), upload the .mobileconfig directly as a Configuration / Custom Settings Profile instead of running the script.

scripts/macos/audit.sh compares the deployed hook file against the staged payload byte-for-byte (cmp -s):

  • Exit 0 > in sync, no action.

  • Exit 1 > drift detected, run install.sh to remediate.

(If the staging file is missing, audit exits 0 to avoid a remediation loop it can't fix.) The policy install is naturally idempotent and can simply be re-run on any trigger.


5. Windows setup

Step 1 - Stage the hook file

Deliver payloads/nightfall.json to C:\Nightfall\Hooks\vscode\nightfall.json using your MDM's file-distribution feature (e.g. an .msi or .intunewin).

Step 2 - Drop the file into place

Wire scripts/windows/install.ps1 into your MDM as a SYSTEM-context script. It:

  1. Verifies it's running as administrator (exits early if not).

  2. Confirms the staged payload exists.

  3. Creates C:\ProgramData\Copilot\hooks if needed.

  4. Copies nightfall.json into place.

Step 3 - Set the policy

Wire scripts/windows/install-policy.ps1 into your MDM (also SYSTEM-context). It merges Nightfall's entry into chat.hookFilesLocations under HKLM\Software\Policies\Microsoft\VSCode, preserving any entries other vendors have already registered. The merged value mirrors payloads/hookFilesLocations.json.

Alternatively, import VS Code's ADMX template and set the policy via the Intune UI, or push the same value via an OMA-URI Custom Configuration Profile.

Drift checking (Intune Win32 Remediation pattern)

scripts/windows/detect.ps1 compares the deployed hook file against the staged payload by SHA256:

  • Prints present, exit 0 > in sync.

  • Prints staging-missing, exit 0 > staging not deployed yet (no remediation loop).

  • Exit 1 → drift, run install.ps1 as the remediation.

The policy merge script is idempotent and can be re-run on any trigger.


6. Wiring into your MDM

The scripts are MDM-agnostic - the same scripts work regardless of vendor. Note that VS Code has two install scripts per platform (file drop + policy), so most rows below pair them:

MDM

Platform

Wire into

Script

Rippling

macOS

Custom Script — file drop

scripts/macos/install.sh

Rippling

macOS

Custom Script — policy install

scripts/macos/install-policy.sh

Rippling

Windows

PowerShell Script — file drop

scripts/windows/install.ps1

Rippling

Windows

PowerShell Script — policy merge

scripts/windows/install-policy.ps1

Jamf Pro

macOS

Script + Policy — file drop

scripts/macos/install.sh

Jamf Pro

macOS

Script + Policy — policy install

scripts/macos/install-policy.sh (or upload the .mobileconfig directly as a Configuration Profile)

Kandji

macOS

Custom Script — Audit (file)

scripts/macos/audit.sh

Kandji

macOS

Custom Script — Remediation (file)

scripts/macos/install.sh

Kandji

macOS

Custom Script — Policy install

scripts/macos/install-policy.sh (or upload the .mobileconfig as a Kandji Custom Profile)

Microsoft Intune

Windows

Win32 Remediation — Detection

scripts/windows/detect.ps1

Microsoft Intune

Windows

Win32 Remediation — Remediation

scripts/windows/install.ps1

Microsoft Intune

Windows

Custom Configuration Profile / ADMX — policy

scripts/windows/install-policy.ps1 (or import VS Code's ADMX and set the policy via UI)

Workspace ONE

macOS

Script — file drop

scripts/macos/install.sh

Workspace ONE

macOS

Script — policy install

scripts/macos/install-policy.sh (or upload the .mobileconfig as a Custom Settings Profile)

Workspace ONE

Windows

Script — file drop

scripts/windows/install.ps1

Workspace ONE

Windows

Script — policy merge

scripts/windows/install-policy.ps1 (or set OMA-URI under HKLM\Software\Policies\Microsoft\VSCode via a Profile)

Two drift strategies for the file drop:

  • Re-run on a schedule (Rippling / Jamf / Workspace ONE) - the install script is idempotent, so a periodic trigger simply re-copies the file. Simplest.

  • Audit/detect → remediate (Kandji / Intune) - pair the audit/detect script with the install script so a re-install only fires when drift is detected.

The policy scripts are idempotent regardless of strategy (profile install updates in place via the stable PayloadIdentifier; registry merge re-applies the same entry), so wire them to the same trigger as the file drop.


7. Validation

After deployment, open the Devices page in the Nightfall console. Each device shows a per-client hook status indicator. A healthy status for VS Code Copilot means the hooks are registered and the relay is responding - the deployment is working.

On a single device you can also confirm:

  • The hook file landed at the target path.

  • chat.hookFilesLocations includes that path - check the installed Configuration Profile (macOS) or the registry key under HKLM\Software\Policies\Microsoft\VSCode (Windows).

  • nightfall-hook-relay resolves on PATH (the endpoint agent provides it).

If the file is present but hooks don't fire, the policy is almost always the missing piece - Copilot silently ignores hook files at paths not listed in chat.hookFilesLocations.


8. Rollback

Remove both pieces; the relay binary stays installed (the Nightfall agent owns its lifecycle):

  1. Delete the hook file:

    1. macOS: /Library/Application Support/Copilot/hooks/nightfall.json

    2. Windows: C:\ProgramData\Copilot\hooks\nightfall.json

  2. Remove the policy entry for Nightfall's path from chat.hookFilesLocations:

    1. macOS: remove the ai.nightfall.hooks.vscode Configuration Profile.

    2. Windows: remove the Nightfall path entry under HKLM\Software\Policies\Microsoft\VSCode (leave other vendors' entries intact).

If you wired the install/policy scripts to a recurring trigger, remove those MDM assignments first — otherwise the next check-in will re-deploy.


9. Notes & known issues

  • VS Code Copilot hooks are Preview. The configuration format and behavior may change. Pin to specific VS Code and Copilot extension versions during pilot.

  • Two-step deployment is mandatory. Dropping the file without setting chat.hookFilesLocations does nothing — Copilot won't read an unregistered hook file. This is the most common cause of a "deployed but not working" report.

  • Multi-vendor coexistence. Both policy mechanisms are additive - macOS profile layering and the Windows registry merge preserve other vendors' hook-file registrations. Nightfall adds a single path entry and never overwrites others.

  • Copilot CLI and Copilot coding agent (cloud) are out of scope - hook coverage doesn't apply there.

  • Claude Code spillover into VS Code. By default VS Code Copilot may also read ~/.claude/settings.json. If you observe Claude's user-level hooks firing inside VS Code and want to suppress that, add "~/.claude/settings.json": false to the policy.

Last updated

Was this helpful?