* 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
82 lines
3.5 KiB
Bash
82 lines
3.5 KiB
Bash
#!/usr/bin/env bash
|
|
# SessionStart hook for OAC plugin
|
|
|
|
set -euo pipefail
|
|
|
|
# Determine plugin root directory
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
SKILL_FILE="${PLUGIN_ROOT}/skills/using-oac/SKILL.md"
|
|
|
|
# Read using-oac content
|
|
using_oac_content=$(cat "${SKILL_FILE}" 2>&1 || echo "Error reading using-oac skill")
|
|
|
|
|
|
# Escape string for JSON embedding
|
|
# SECURITY: Prevents command injection attacks from malicious SKILL.md files
|
|
escape_for_json() {
|
|
local s="$1"
|
|
# Escape backslashes FIRST - order matters!
|
|
s="${s//\\/\\\\}"
|
|
# Escape double quotes
|
|
s="${s//\"/\\\"}"
|
|
# Escape newlines, carriage returns, tabs
|
|
s="${s//$'\n'/\\n}"
|
|
s="${s//$'\r'/\\r}"
|
|
s="${s//$'\t'/\\t}"
|
|
printf '%s' "$s"
|
|
}
|
|
|
|
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
|
|
skill_name=$(basename "$skill_dir")
|
|
skill_file="${skill_dir}SKILL.md"
|
|
if [ -f "$skill_file" ]; 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}"
|
|
else
|
|
skill_catalogue="${skill_catalogue}"$'\n'"- oac:${skill_name}"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Build warning message for first-time users
|
|
warning_message=""
|
|
if [[ ! -f "${PLUGIN_ROOT}/.context-manifest.json" ]] && [[ ! -f "$(pwd)/.context-manifest.json" ]]; then
|
|
warning_message="\n\n<important-reminder>IN YOUR FIRST REPLY AFTER SEEING THIS MESSAGE YOU MUST TELL THE USER: **No context files found.** Invoke the install-context skill now to set up context for this project — it will check your project type and recommend the right profile. Say: \"I notice you don't have context files set up. Let me get that sorted for you.\" Then immediately run the install-context skill.</important-reminder>"
|
|
fi
|
|
|
|
warning_escaped=$(escape_for_json "$warning_message")
|
|
skill_catalogue_escaped=$(escape_for_json "$skill_catalogue")
|
|
|
|
# Build OAC system paths block
|
|
PROTOCOL_PATH="${PLUGIN_ROOT}/skills/context-discovery/context-discovery-protocol.md"
|
|
plugin_root_escaped=$(escape_for_json "$PLUGIN_ROOT")
|
|
protocol_path_escaped=$(escape_for_json "$PROTOCOL_PATH")
|
|
OAC_SYSTEM_PATHS="## OAC System Paths\n- Plugin Root: ${plugin_root_escaped}\n- Context Discovery Protocol: ${protocol_path_escaped}"
|
|
|
|
# Build context string
|
|
OAC_CONTEXT="<EXTREMELY_IMPORTANT>\nYou have OAC (OpenAgents Control).\n\n**Below is the full content of your 'oac:using-oac' skill — your introduction to using OAC skills. For all other skills, use the 'Skill' tool:**\n\n${using_oac_escaped}\n\n## Available OAC Skills (invoke with the Skill tool):\n${skill_catalogue_escaped}\n\n${OAC_SYSTEM_PATHS}\n\n${warning_escaped}\n</EXTREMELY_IMPORTANT>"
|
|
|
|
# Output dual-format JSON for cross-tool compatibility
|
|
# - additionalContext: Claude Code (hookSpecificOutput)
|
|
# - additional_context: Cursor / OpenCode / other tools
|
|
cat <<EOF
|
|
{
|
|
"additional_context": "${OAC_CONTEXT}",
|
|
"hookSpecificOutput": {
|
|
"hookEventName": "SessionStart",
|
|
"additionalContext": "${OAC_CONTEXT}"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
exit 0
|