#!/usr/bin/env bash # Scribe SessionStart hook (dogfood / pre-plugin). # # Curls the running Scribe dev instance for the operator's always-on rules + # active-project context and emits it as SessionStart `additionalContext` — the # push channel that lets Scribe surface reflexively (plan #755, Phase 1). # # FAIL-OPEN by design: any missing tool, missing config, network error, or # unreachable instance results in injecting nothing and exiting 0. A session # must NEVER be blocked because Scribe is down. Reads URL+token from the # project's .mcp.json so no secret lives in this tracked script. # # Superseded in Phase 2 by the same hook bundled in the Scribe plugin, where # URL+token come from plugin userConfig instead of .mcp.json. set -uo pipefail MCP_JSON="${CLAUDE_PROJECT_DIR:-.}/.mcp.json" command -v jq >/dev/null 2>&1 || exit 0 command -v curl >/dev/null 2>&1 || exit 0 [ -f "$MCP_JSON" ] || exit 0 # scribe-dev is the locally-wired instance (prod id 2 / dev id 3 per binding). url=$(jq -r '.mcpServers["scribe-dev"].url // empty' "$MCP_JSON" 2>/dev/null) || exit 0 auth=$(jq -r '.mcpServers["scribe-dev"].headers.Authorization // empty' "$MCP_JSON" 2>/dev/null) || exit 0 token=${auth#Bearer } [ -n "$url" ] && [ -n "$token" ] || exit 0 base=${url%/mcp} body=$(curl -fsS --max-time 8 \ -H "Authorization: Bearer ${token}" \ "${base}/api/plugin/context?project_id=3" 2>/dev/null) || exit 0 text=$(printf '%s' "$body" | jq -r '.context // empty' 2>/dev/null) || exit 0 [ -n "$text" ] || exit 0 jq -n --arg c "$text" \ '{hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: $c}}' exit 0