fix: load Copilot hook plugins again#155
Merged
Merged
Conversation
Copilot was rejecting every hook-enabled plugin because the repo still wrote hooks.json in the old flat-array shape. That prevented git-tools from surfacing its ship command and left the local registry stuck on stale plugin metadata. * convert Copilot hooks.json files to the object-based schema Copilot currently loads * refresh validator/docs to match the accepted hook shape * bump plugin versions and keep Claude/Copilot manifests in sync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
⚠️ Not ready to approve
The Copilot hook validation is currently too permissive for non-array per-event values, and plugins-copilot/java-toolkit/hooks/hooks.json is missing the consistently-documented type: "command" field.
Pull request overview
Fixes Copilot CLI hook-enabled plugin loading by migrating hooks/hooks.json from the legacy flat-array format to the object hooks map format (still version: 1), and updates repo docs + validation to match while bumping plugin versions to refresh installed metadata.
Changes:
- Convert Copilot plugin
hooks.jsonfiles to{ "hooks": { "<event>": [ ... ] } }shape and remove per-entryeventfields. - Update documentation and the plugin validation script to reflect/enforce the new Copilot hook format.
- Bump
plugin.jsonversions across Claude + Copilot plugin variants to keep them in sync and force metadata refresh.
File summaries
| File | Description |
|---|---|
| README.md | Updates Copilot hook format documentation (object map). |
| CLAUDE.md | Updates Copilot hook format documentation (object map). |
| .github/scripts/validate-plugins.sh | Updates Copilot hook validation logic for object-map shape. |
| .claude/agents/plugin-validator.md | Updates validator agent guidance for Copilot hook format. |
| plugins-copilot/stl-game-config/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/session/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/session-history-analyzer/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/permission-manager/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape (multi-hook). |
| plugins-copilot/notify-on-stop/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape (multi-event). |
| plugins-copilot/markdown/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/kb-capture/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/java-toolkit/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/image/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/git-tools/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/format-on-save/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape (multi-event). |
| plugins-copilot/elevated-edit/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/convert-doc/hooks/hooks.json | Migrates Copilot hooks.json to object-map shape. |
| plugins-copilot/stl-game-config/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/session/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/session-history-analyzer/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/permission-manager/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/notify-on-stop/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/markdown/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/kb-capture/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/java-toolkit/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/image/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/git-tools/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/format-on-save/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/elevated-edit/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-copilot/convert-doc/.claude-plugin/plugin.json | Bumps Copilot plugin version for metadata refresh. |
| plugins-claude/stl-game-config/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/session/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/session-history-analyzer/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/permission-manager/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/notify-on-stop/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/markdown/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/kb-capture/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/java-toolkit/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/image/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/git-tools/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/format-on-save/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/elevated-edit/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
| plugins-claude/convert-doc/.claude-plugin/plugin.json | Bumps canonical plugin version to keep Copilot/Claude in sync. |
Copilot's findings
- Files reviewed: 43/43 changed files
- Comments generated: 2
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+161
to
+173
| # Copilot hooks must use the object shape: | ||
| # {"hooks": {"preToolUse": [{"bash": "..."}]}} | ||
| local shape | ||
| shape=$(jq -r '.hooks | type' "$f" 2>/dev/null) | ||
| if [[ "$shape" != "array" ]]; then | ||
| fail "$f — Copilot hooks.json must use flat array .hooks entries" | ||
| if [[ "$shape" != "object" ]]; then | ||
| fail "$f — Copilot hooks.json must use object .hooks entries" | ||
| return | ||
| fi | ||
|
|
||
| local bad_events has_command missing_bash | ||
| bad_events=$(jq -r '.hooks[].event | select(test("^[A-Z]"))' "$f" 2>/dev/null) | ||
| has_command=$(jq -r '[.hooks[] | objects | select(has("command"))] | length' "$f" 2>/dev/null) | ||
| missing_bash=$(jq -r '[.hooks[] | objects | select(((.bash // "") | length) == 0)] | length' "$f" 2>/dev/null) | ||
| bad_events=$(jq -r '.hooks | keys[] | select(test("^[A-Z]"))' "$f" 2>/dev/null) | ||
| has_command=$(jq -r '[.hooks[]?[]? | objects | select(has("command"))] | length' "$f" 2>/dev/null) | ||
| missing_bash=$(jq -r '[.hooks[]?[]? | objects | select(((.bash // "") | length) == 0)] | length' "$f" 2>/dev/null) |
Comment on lines
+5
to
+7
| { | ||
| "bash": "bash ${COPILOT_PLUGIN_ROOT}/scripts/approve-own-scripts.sh" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Copilot was rejecting hook-enabled plugins because the repo still wrote
hooks.jsonin the old flat-array shape. This preventedgit-toolsfrom loading its/shipcommand and left installed Copilot plugin metadata stale.Test plan
bash .github/scripts/validate-plugins.sh