From 50063849f9f64100baea946ba2e07b5205c30e2f Mon Sep 17 00:00:00 2001 From: Darren Hinde <107584450+darrenhinde@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:35:02 +0000 Subject: [PATCH] fix(plugin): fix hook JSON escaping and unconditional session firing (#241) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(shellcheck): declare and assign separately in router.sh (SC2155) * feat(plugin): enhance context management and skill invocation - Update .context-manifest.json to include profile and detailed source information. - Revise context-scout.md to clarify context root discovery and navigation. - Modify commands to replace deprecated skills with updated ones (brainstorming → approach, systematic-debugging → debugger). - Streamline install-context.md for clarity and remove interactive profile selection. - Improve oac-status.md to provide a more comprehensive status report. - Add OAC system paths to session-start.sh for better context management. - Remove obsolete skills and improve documentation for existing commands. * fix(plugin): fix hook JSON escaping and unconditional session firing - Fix double-escaped skill catalogue: use $'\n' real newlines instead of literal \n strings so escape_for_json encodes them correctly as \n in JSON - Fix OAC_SYSTEM_PATHS embedded raw into JSON string: build with real newlines and pass through escape_for_json before interpolation - Remove SessionStart matcher so hook fires on every session start unconditionally (startup, resume, clear, compact and any future types) - Remove redundant async:false field; add explicit timeout:30 --- plugins/claude-code/hooks/hooks.json | 4 +--- plugins/claude-code/hooks/session-start.sh | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/claude-code/hooks/hooks.json b/plugins/claude-code/hooks/hooks.json index 538a0b0..a31b1ed 100644 --- a/plugins/claude-code/hooks/hooks.json +++ b/plugins/claude-code/hooks/hooks.json @@ -2,13 +2,11 @@ "hooks": { "SessionStart": [ { - "matcher": "startup|resume|clear|compact", "hooks": [ { "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/session-start.sh", - "timeout": 30, - "async": false + "timeout": 30 } ] } diff --git a/plugins/claude-code/hooks/session-start.sh b/plugins/claude-code/hooks/session-start.sh index db0f2d6..f8218f2 100644 --- a/plugins/claude-code/hooks/session-start.sh +++ b/plugins/claude-code/hooks/session-start.sh @@ -30,6 +30,7 @@ escape_for_json() { using_oac_escaped=$(escape_for_json "$using_oac_content") # Build skill catalogue from skills directory +# Use real newlines (not literal \n) so escape_for_json encodes them correctly as \n in JSON skill_catalogue="" if [ -d "${PLUGIN_ROOT}/skills" ]; then for skill_dir in "${PLUGIN_ROOT}/skills"/*/; do @@ -39,9 +40,9 @@ if [ -d "${PLUGIN_ROOT}/skills" ]; then # Extract description from frontmatter description=$(grep -m1 '^description:' "$skill_file" 2>/dev/null | sed 's/^description: *//;s/^"//;s/"$//' || echo "") if [ -n "$description" ]; then - skill_catalogue="${skill_catalogue}\n- oac:${skill_name} — ${description}" + skill_catalogue="${skill_catalogue}"$'\n'"- oac:${skill_name} — ${description}" else - skill_catalogue="${skill_catalogue}\n- oac:${skill_name}" + skill_catalogue="${skill_catalogue}"$'\n'"- oac:${skill_name}" fi fi done