Skip to content

chat: deprecate the Local hook JSON format - #345634

Merged
Martin Aeschlimann (aeschli) merged 8 commits into
mainfrom
aeschli/hook-local-format-deprecation
Nov 3, 2026
Merged

Martin Aeschlimann (aeschli) merged 8 commits into
mainfrom
aeschli/hook-local-format-deprecation

Conversation

@aeschli

@aeschli Martin Aeschlimann (aeschli) commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to merged #343651, now based on main. This draft deprecates the Local hook format and updates Configure Hooks so newly generated Copilot files use the recommended format. The command-validation fix is already on main and is not part of this PR's diff.

Changes

  • Keep Local-format hook files valid, but add a deprecation warning recommending version: 1, CLI event names, and timeoutSec.
  • Change the default JSON schema snippet to the CLI format.
  • Update both new-file creation paths in Configure Hooks to write versioned camelCase Copilot files with a cross-platform command placeholder. Claude files retain their nested format, and existing Local files retain their naming convention.
  • Honor version when adding events to an empty CLI file.
  • Register the runtime-supported preCompact and subagentStart names so generated hooks remain discoverable and receive schema metadata.
  • Add thirteen tests covering generated files for all eleven hook types, parser round trips, and unchanged Claude structure.

Required Before Ready for Review

  • Define and test input/output compatibility during migration of existing files. The runtime normalizes PascalCase aliases and adds _vsCodeCompat, which affects payload mapping; changing only names/version/timeout is not necessarily behavior-preserving. This draft does not automatically migrate existing files.
  • Add behavioral JSON language-service validation tests for deprecation diagnostics and the default snippet.
  • Validate the Configure Hooks workflow in the running workbench, including editor selection and existing-file updates.

The native runtime was checked separately: both PascalCase and camelCase configurations for PreCompact/SubagentStart load successfully. Runtime support is not the blocker.

Validation

  • After chat: fix CLI hook command validation #343651 merged, merged main (3bc96745d641) in 4bcc64dc9ef and resolved the schema-test conflict, preserving both the upstream command-validation test and this draft's deprecation/default-snippet tests. The remaining diff contains only the follow-up changes.

  • node build/next/index.ts transpile — passed against the updated sources.

  • node test/unit/node/index.js --reporter dot --run src/vs/platform/agentPlugins/test/common/pluginParsers.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookSchema.test.ts — passed, 136 tests after the latest main merge.

  • git diff --cached --check and normal pre-commit hygiene checks — passed for both update merges.

  • The fast-build prerequisite check was blocked by an installed SDK/runtime version mismatch; dependency refresh was blocked by package-feed connectivity. The direct client transpile and targeted tests above succeeded; no new broad type-check was run.

  • Feedback follow-up: plugin parsing now also canonicalizes preCompact and subagentStart, preserving their original event names and commands.

  • node test/unit/node/index.js --run src/vs/platform/agentPlugins/test/common/pluginParsers.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookSchema.test.ts — passed, 131 tests after the feedback fix; client compilation also passed.

  • node build/eslint.ts src/vs/platform/agentPlugins/common/pluginParsers.ts src/vs/platform/agentPlugins/test/common/pluginParsers.test.ts and node build/hygiene.ts src/vs/platform/agentPlugins/common/pluginParsers.ts src/vs/platform/agentPlugins/test/common/pluginParsers.test.ts — both passed; the normal pre-commit hook also passed.

  • node build/next/build-fast.ts --client-only — passed.

  • node test/unit/node/index.js --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookSchema.test.ts — passed, 72 tests.

  • node build/eslint.ts src/vs/workbench/contrib/chat/browser/promptSyntax/hookActions.ts src/vs/workbench/contrib/chat/common/promptSyntax/hookCompatibility.ts src/vs/workbench/contrib/chat/common/promptSyntax/hookTypes.ts src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts — passed, four files.

  • node build/hygiene.ts src/vs/workbench/contrib/chat/browser/promptSyntax/hookActions.ts src/vs/workbench/contrib/chat/common/promptSyntax/hookCompatibility.ts src/vs/workbench/contrib/chat/common/promptSyntax/hookTypes.ts src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts — passed, four files; the normal pre-commit hook also passed.

  • git diff --check — passed before commit.

  • Standalone in-memory checks — all ten generated Copilot event configurations validate against the schema and remain discoverable. Earlier standalone Ajv validation also passed ten input cases on each split branch state and the baseline command-only regression check.

  • ./scripts/test.sh --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookSchema.test.ts --run src/vs/workbench/contrib/chat/test/browser/promptSyntax/hookActions.test.ts --run src/vs/workbench/contrib/chat/test/browser/promptSyntax/hookUtils.test.ts --reporter dot — Electron crashed before tests ran (exit 139).

  • node test/unit/browser/index.js --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookCompatibility.test.ts --run src/vs/workbench/contrib/chat/test/common/promptSyntax/hookSchema.test.ts --run src/vs/workbench/contrib/chat/test/browser/promptSyntax/hookActions.test.ts --run src/vs/workbench/contrib/chat/test/browser/promptSyntax/hookUtils.test.ts --browser chromium --reporter dot — blocked by sandbox policy on loopback listening (EPERM ::1); browser tests were not run.

  • Live UI, end-to-end migration, and broad type-checking were not run. No dependency manifests were changed.

Manual Checks

  1. Configure a new hook and verify the generated JSON has version: 1, the correct CLI event name, and no Local-format deprecation warning; the command placeholder should be selected.
  2. Repeat for PreCompact, SubagentStart, UserPromptSubmit, and Stop; verify generated events remain visible in Configure Hooks.
  3. Add a hook to an empty versioned CLI file and verify its event uses CLI naming.
  4. Verify existing Local files and Claude files retain their structure when adding hooks.
  5. Verify the default CLI snippet has no schema diagnostics.

This draft targets main; the former stacked parent #343651 has merged.

Fixes #343595

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep legacy hooks valid while recommending the Copilot CLI format and updating the default snippet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use versioned camelCase hook files for new Copilot configurations while preserving Claude and existing Local formats. Register the runtime-supported preCompact and subagentStart names so generated hooks remain discoverable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The platform hook mapping omits preCompact and subagentStart aliases, causing plugin parsing to silently drop those events from generated configurations.

1 open issue
What changed in this PR

Deprecates the Local hook JSON format while keeping it valid, and makes Configure Hooks generate the recommended Copilot CLI format. This builds on the stacked command-validation fix without automatically migrating existing files.

Changes:

  • Add a Local-format deprecation warning and switch the default snippet to versioned CLI JSON.
  • Centralize new-file generation, preserve Claude structure, and honor versioned empty files when adding events.
  • Register two additional CLI event names and add generation, parser round-trip, and schema-structure tests.
File Description
src/​vs/​workbench/​contrib/​chat/​test/​common/​promptSyntax/​hookSchema.test.ts Check deprecation placement and default snippet structure.
src/​vs/​workbench/​contrib/​chat/​test/​common/​promptSyntax/​hookCompatibility.test.ts Cover all ten generated Copilot events, discovery, and Claude structure.
src/​vs/​workbench/​contrib/​chat/​common/​promptSyntax/​hookTypes.ts Register preCompact and subagentStart CLI names.
src/​vs/​workbench/​contrib/​chat/​common/​promptSyntax/​hookSchema.ts Deprecate Local format and update the default snippet.
src/​vs/​workbench/​contrib/​chat/​common/​promptSyntax/​hookCompatibility.ts Add a shared format-aware hook-file builder.
src/​vs/​workbench/​contrib/​chat/​browser/​promptSyntax/​hookActions.ts Use the builder in both creation paths and honor existing file versions.

Review effort: Balanced

Copilot AI commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

One or more custom setup steps configured for this repository failed during this Copilot code review run:

Setup pnpm

Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.

Note

You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.

Recognize preCompact and subagentStart when parsing plugin hook files, retaining their canonical type, original event name, and commands. Extend the existing canonicalization regression test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Explain in the Local-format deprecation message that CLI hooks use different JSON input/output shapes and that renaming configuration fields alone can change behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve both hook compatibility test additions and cover the upstream userPromptTransformed event in generated files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Base automatically changed from digitarald/agents/hook-validation-local-schema-fix to main November 3, 2026 09:36
Preserve the deprecation and default-snippet regression tests alongside the merged command-validation test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aeschli
Martin Aeschlimann (aeschli) marked this pull request as ready for review November 3, 2026 10:25
@aeschli
Martin Aeschlimann (aeschli) merged commit e021961 into main Nov 3, 2026
55 checks passed
@aeschli
Martin Aeschlimann (aeschli) deleted the aeschli/hook-local-format-deprecation branch November 3, 2026 11:01
@vs-code-engineering vs-code-engineering Bot added this to the 1.146.0 milestone Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants