#!/usr/bin/env bash # SessionStart hook for code-guide plugin. # Reads ALL skills/*/SKILL.md files and injects them as additionalContext # so every best-practice guide is always active from turn 1. # # Pattern: identical to explanatory-output-style's session-start hook # which injects educational-output instructions into context. # Instead of one static message, we dynamically iterate over all skills. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" # Build combined content from all SKILL.md files. combined="" while IFS= read -r -d '' skill_file; do skill_name=$(basename "$(dirname "$skill_file")") content=$(cat "$skill_file") # Append skill with header separator — uses $'...' for real newlines combined="${combined}"$'\n\n\n'"===== code-guide:${skill_name} ====="$'\n\n'"${content}" done < <(find "${PLUGIN_ROOT}/skills" -name 'SKILL.md' -print0 | sort -z) intro=$'You have the code-guide plugin loaded with all best-practice guides directly injected.\nThe following skills are ALWAYS active in context — no manual invocation needed.\nWhen the current task matches a skill\'s domain, apply its guidance automatically.\n' full_context=" ${intro} ${combined} " # JSON-escape the full context: \ → \\, " → \", newline → \n, etc. escape_for_json() { local s="$1" s="${s//\\/\\\\}" s="${s//\"/\\\"}" s="${s//$'\n'/\\n}" s="${s//$'\r'/\\r}" s="${s//$'\t'/\\t}" printf '%s' "$s" } escaped=$(escape_for_json "$full_context") if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"}}\n' "$escaped" else printf '{"additionalContext":"%s"}\n' "$escaped" fi exit 0