Per https://code.claude.com/docs/en/plugins.md "Convert existing
configurations": the hooks config file goes at
`<plugin-root>/hooks/hooks.json` — sibling to the script files
under hooks/, NOT inside `.claude-plugin/`. v1.0.2 had it at
`.claude-plugin/hooks/hooks.json` (still 0 hooks loaded). v1.0.3
puts it at the actually-documented path.
Final layout:
.claude-plugin/plugin.json
hooks/hooks.json ← event → command map
hooks/hyprpanel-state.sh ← the script
`${CLAUDE_PLUGIN_ROOT}` in `command` strings is case-sensitive and
correct.
Per Claude Code's plugin spec at https://code.claude.com/docs/en/plugins.md,
hooks must live at `.claude-plugin/hooks/hooks.json` — a `hooks/`
subdirectory inside `.claude-plugin/`. v1.0.0 had `hooks.json`
directly under `.claude-plugin/` (loaded 0 hooks); v1.0.1 inlined
into `plugin.json` (also not supported). v1.0.2 puts the file at
the documented path.
Schema is unchanged — three-level nesting (event → matcher list →
handler list), same as user settings.json. `${CLAUDE_PLUGIN_ROOT}`
substitution is supported here.
The standalone .claude-plugin/hooks.json file wasn't being read by
Claude Code on /reload-plugins ("0 hooks" loaded). Inline the hook
block into plugin.json's `hooks` key per the manifest spec —
delete hooks.json so the plugin has a single source of truth.
Bump to 1.0.1 so the installed cache picks up the change on next
auto-update / `claude plugin update`.
Hooks-only Claude Code plugin that surfaces per-window claude state
in the patched HyprPanel workspaces bar. Wires UserPromptSubmit /
PreToolUse / PostToolUse / Notification / Stop / SessionEnd to a
shell script that walks the parent-PID chain to find the kitty
client whose claude this script lives in, then writes a state token
to /tmp/hyprpanel-claude/<address>.
Bar visuals are owned separately by the workspaces patch in
projects/hyprpanel-dev. The contract between the two is the
/tmp/hyprpanel-claude/ directory layout (state file, .tools
counter, .ping sidecar for blink-decay animations).