Skip to content

fix: load Copilot hook plugins again#155

Merged
st0nefish-ci[bot] merged 1 commit into
masterfrom
fix/copilot-hook-schema
Jun 17, 2026
Merged

fix: load Copilot hook plugins again#155
st0nefish-ci[bot] merged 1 commit into
masterfrom
fix/copilot-hook-schema

Conversation

@St0nefish

Copy link
Copy Markdown
Owner

Summary

Copilot was rejecting hook-enabled plugins because the repo still wrote hooks.json in the old flat-array shape. This prevented git-tools from loading its /ship command and left installed Copilot plugin metadata stale.

Test plan

  • bash .github/scripts/validate-plugins.sh
  • `copilot plugin update git-tools@agent-toolkit

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>
Copilot AI review requested due to automatic review settings June 17, 2026 20:04
@st0nefish-ci st0nefish-ci Bot enabled auto-merge June 17, 2026 20:05
@st0nefish-ci st0nefish-ci Bot merged commit a6cedd6 into master Jun 17, 2026
7 checks passed
@st0nefish-ci st0nefish-ci Bot deleted the fix/copilot-hook-schema branch June 17, 2026 20:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ 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.json files to { "hooks": { "<event>": [ ... ] } } shape and remove per-entry event fields.
  • Update documentation and the plugin validation script to reflect/enforce the new Copilot hook format.
  • Bump plugin.json versions 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"
}
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.

2 participants