Problem
Hook commands in extensions.yml use dotted IDs (e.g., speckit.git.commit) but skills use hyphenated names (speckit-git-commit). Without an explicit note in the generated SKILL.md, agents emit /speckit.git.commit which doesn't resolve.
Claude (#2346) and Codex (#2503) both solve this by independently overriding setup() and post_process_skill_content() with identical _HOOK_COMMAND_NOTE constants and _inject_hook_command_note regex logic. Copilot (skills mode) and Vibe have the same latent bug — they don't inject the note.
Prerequisites
This should land after #2503 is merged, since it will deduplicate and lift the hook note logic that #2503 adds for Codex.
Proposed changes
-
Move the post-processing loop into SkillsIntegration.setup() so it calls self.post_process_skill_content() after writing each SKILL.md. This eliminates the duplicated loop in Claude, Codex, Copilot, and Vibe.
-
Move _inject_hook_command_note into SkillsIntegration and call it from the base post_process_skill_content(). The dot-to-hyphen translation is inherent to how skills map hook IDs — it's not agent-specific.
-
Remove the duplicated logic from ClaudeIntegration and CodexIntegration. Claude's post_process_skill_content() would still override for its agent-specific flags (user-invocable, disable-model-invocation) but call super() to get the hook note.
Affected integrations
| Integration |
Has post-process loop |
Has hook note |
After refactor |
Base (SkillsIntegration) |
No |
No |
Both |
| Claude |
Yes (duplicated) |
Yes |
Simplified |
| Codex |
Yes (duplicated, #2503) |
Yes |
Simplified |
| Copilot (skills) |
Yes (duplicated) |
No — bug |
Fixed |
| Vibe |
Yes (duplicated) |
No — bug |
Fixed |
| Agy |
No |
No |
Fixed |
| Devin |
No |
No |
Fixed |
Problem
Hook commands in
extensions.ymluse dotted IDs (e.g.,speckit.git.commit) but skills use hyphenated names (speckit-git-commit). Without an explicit note in the generated SKILL.md, agents emit/speckit.git.commitwhich doesn't resolve.Claude (#2346) and Codex (#2503) both solve this by independently overriding
setup()andpost_process_skill_content()with identical_HOOK_COMMAND_NOTEconstants and_inject_hook_command_noteregex logic. Copilot (skills mode) and Vibe have the same latent bug — they don't inject the note.Prerequisites
This should land after #2503 is merged, since it will deduplicate and lift the hook note logic that #2503 adds for Codex.
Proposed changes
Move the post-processing loop into
SkillsIntegration.setup()so it callsself.post_process_skill_content()after writing each SKILL.md. This eliminates the duplicated loop in Claude, Codex, Copilot, and Vibe.Move
_inject_hook_command_noteintoSkillsIntegrationand call it from the basepost_process_skill_content(). The dot-to-hyphen translation is inherent to how skills map hook IDs — it's not agent-specific.Remove the duplicated logic from
ClaudeIntegrationandCodexIntegration. Claude'spost_process_skill_content()would still override for its agent-specific flags (user-invocable,disable-model-invocation) but callsuper()to get the hook note.Affected integrations
SkillsIntegration)