Stats
Actions
Tags
From great_cto
Preserves session context via automated handoff logs and blocks tool calls until subagent checks pass. Uses bash, Python, and Node scripts.
8 events · 16 hooks
Safety signals detected in this hook configuration
Where this hook configuration is defined
Defined inline in plugin.json manifest
Event handlers and matchers — expand Raw Configuration for the full JSON
bd prime 2>/dev/null; echo '---GREAT_CTO-CONTEXT---'; cat .great_cto/PROJECT.md 2>/dev/null | head -30; echo '---BEADS-READY---'; bd ready 2>/dev/null | head -10; BRANCH=$(git branch --show-current 2>/dev/null || echo 'unknown'); LAST_COMMIT=$(git log --oneline -1 2>/dev/null || echo 'none'); UNCOMMITTED=$(git status --short 2>/dev/null | wc -l | tr -d ' '); OPEN_GATES=$(bd list --label gate --status open 2>/dev/null | head -5 || grep '\[GATE:' .great_cto/tasks.md 2>/dev/null | head -5 || echo 'none'); OPEN_TASKS=$(bd list --status open 2>/dev/null | head -8 || echo 'none'); LAST_VERDICT=$(ls -t .great_cto/verdicts/*.log 2>/dev/null | head -1 | xargs tail -1 2>/dev/null || echo 'none'); LATEST_ARCH=$(ls docs/architecture/ARCH-*.md 2>/dev/null | sort | tail -1 || echo 'none'); LATEST_QA=$(ls docs/qa-reports/QA-*.md 2>/dev/null | sort | tail -1 || echo 'none'); LATEST_CSO=$(ls docs/security/CSO-*.md 2>/dev/null | sort | tail -1 || echo 'none'); printf '# Auto-Handoff — %s\n\n> Auto-saved by PreCompact hook. Next session: read this, then /inbox.\n\n## Git\n- Branch: `%s` | Last commit: `%s` | Uncommitted: %s files\n\n## Open Gates\n%s\n\n## Open Tasks\n%s\n\n## Last Agent Verdict\n%s\n\n## Latest Docs\n- Arch: %s\n- QA: %s\n- Security: %s\n\n## Resume\nRun `/inbox` to see pending gates, then continue pipeline.\n' "$(date '+%Y-%m-%d %H:%M')" "$BRANCH" "$LAST_COMMIT" "$UNCOMMITTED" "$OPEN_GATES" "$OPEN_TASKS" "$LAST_VERDICT" "$LATEST_ARCH" "$LATEST_QA" "$LATEST_CSO" > .great_cto/HANDOFF.md 2>/dev/null; echo '---HANDOFF-SAVED---'; mkdir -p .great_cto/logs; LOG_DATE=$(date +%Y-%m-%d); LOG_TIME=$(date +%H:%M); LOG_FILE=".great_cto/logs/session-${LOG_DATE}-autocompact.md"; printf '---\ndate: %s\ntime: %s\nduration: auto-saved (context compact)\n---\n\n# Session: context compact snapshot\n\n## Done\n%s\n\n## Pending\n%s\n\n## Commits\n%s\n' "$LOG_DATE" "$LOG_TIME" "$OPEN_TASKS" "$OPEN_TASKS" "$LAST_COMMIT" > "$LOG_FILE" 2>/dev/null; echo '---SESSIONLOG-SAVED---'15msBashPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/orchestrator-check.mjs" 2>/dev/null; EXIT=$?; if [ $EXIT -eq 2 ]; then exit 2; fi; exit 05msINPUT=$(cat 2>/dev/null); if [ -z "$INPUT" ]; then exit 0; fi; CMD=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('command',''))" 2>/dev/null); if [ -z "$CMD" ]; then exit 0; fi; if echo "$CMD" | grep -qiE '(^|[;&|[:space:]])rm[[:space:]]+(-[a-zA-Z]*r[a-zA-Z]*f|-[a-zA-Z]*f[a-zA-Z]*r|--recursive)|(^|[;&|[:space:]])git[[:space:]]+(push[[:space:]].*(--force(-with-lease)?|-f([[:space:]]|$))|reset[[:space:]]+--hard)|(DROP[[:space:]]+(TABLE|DATABASE|SCHEMA))|(^|[;&|[:space:]])truncate[[:space:]]+--all|(^|[;&|[:space:]])(mkfs|dd)[[:space:]]|(^|[;&|[:space:]])chmod[[:space:]]+[0-7]*0{3}[[:space:]]|curl[[:space:]]+.*[|][[:space:]]*(sudo|sh|bash|zsh|python[23]?|perl|ruby)'; then echo "BLOCKED: Dangerous command pattern detected."; exit 2; fi; exit 05msEdit|Write|MultiEditPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/secret-scan.mjs" 2>&1; EXIT=$?; if [ $EXIT -eq 2 ]; then exit 2; fi; exit 05msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/session-end.mjs" 2>/dev/null; true8msWrite|Edit|MultiEditINPUT=$(cat 2>/dev/null); FILE=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('file_path',''))" 2>/dev/null); TOOL=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_name',''))" 2>/dev/null); if [ -n "$FILE" ]; then mkdir -p .great_cto 2>/dev/null; printf '%s %s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$TOOL" "$FILE" >> .great_cto/agent-writes.log 2>/dev/null; fi; true3msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/format-check.mjs" 2>/dev/null; true12msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/summary-enforce.mjs" 2>/dev/null; true5msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/tool-failure.mjs" 2>/dev/null || true3msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); if [ -n "$PLUGIN_DIR" ] && [ -f "${PLUGIN_DIR}/shared/orchestrator.toml" ]; then mkdir -p shared; cp "${PLUGIN_DIR}/shared/orchestrator.toml" shared/orchestrator.toml 2>/dev/null || true; fi5msexport PATH="/opt/homebrew/bin:$HOME/.local/bin:/usr/local/bin:$PATH"; PLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); if [ -z "$PLUGIN_DIR" ]; then echo 'GREAT_CTO: plugin dir not found — run /update'; else mkdir -p ~/.claude/commands ~/.claude/agents ~/.great_cto .great_cto; for STALE in triage gates dora investigate threat-model sbom security-incident update status capture revisit board-report; do STALE_F=~/.claude/commands/${STALE}.md; [ -f "$STALE_F" ] && grep -q 'great_cto-managed' "$STALE_F" 2>/dev/null && rm -f "$STALE_F" 2>/dev/null; done; for CMD in start audit inbox board digest review recall ownership oncall rfc release doctor burn cost sec poc promote crystallize migrate resume save learn agent-review agent-retire help voice-compliance clinical-compliance samd-classify aedt-bias-audit api-contract-review fair-lending-audit part11-audit biodata-conformance hara em-fintech-review carbon-mrv dna-screen drug-ml-review glp-audit iq-oq-pq discover gen-evals prd prompt-evolve skillify spec ccr exception trace upl-check coding-audit procurement-review close-review msp-review tax-review prior-auth-review aml-review soc-review insurance-review mortgage-review title-review credentialing-review collections-review freight-review cro-review customs-review audit-review pharma-review immigration-review appraisal-review payroll-review workers-comp-review estate-review patent-review autopilot flow; do if cp "${PLUGIN_DIR}/commands/${CMD}.md" ~/.claude/commands/${CMD}.md 2>/dev/null; then grep -q 'great_cto-managed' ~/.claude/commands/${CMD}.md 2>/dev/null || echo '<!-- great_cto-managed -->' >> ~/.claude/commands/${CMD}.md; fi; done; for STALE_AGENT in tech-lead; do STALE_AF=~/.claude/agents/great_cto-${STALE_AGENT}.md; [ -f "$STALE_AF" ] && grep -q 'great_cto-managed' "$STALE_AF" 2>/dev/null && rm -f "$STALE_AF" 2>/dev/null; done; for AGENT in architect senior-dev qa-engineer security-officer devops l3-support project-auditor ai-prompt-architect ai-eval-engineer ai-security-reviewer web-store-reviewer pci-reviewer oracle-reviewer firmware-reviewer regulated-reviewer performance-engineer db-migration-reviewer pm mobile-store-reviewer library-reviewer infra-reviewer cli-reviewer game-reviewer data-platform-reviewer devtools-reviewer enterprise-saas-reviewer mlops-reviewer streaming-reviewer marketplace-reviewer cms-reviewer continuous-learner edtech-reviewer gov-reviewer insurance-reviewer voice-ai-reviewer ai-clinical-reviewer fda-reviewer hr-ai-reviewer api-platform-reviewer lending-credit-reviewer clinical-trials-reviewer bio-data-reviewer robotics-safety-reviewer emerging-markets-fintech-reviewer climate-mrv-reviewer biosecurity-reviewer drug-discovery-ml-reviewer glp-glab-reviewer lab-automation-reviewer gdpr-reviewer us-privacy-reviewer dpdpa-reviewer digital-health-reviewer sec-cyber-disclosure-reviewer adtech-privacy-reviewer cmmc-reviewer us-ai-reviewer legal-reviewer rcm-reviewer procurement-reviewer accounting-reviewer msp-reviewer tax-reviewer prior-auth-reviewer aml-bsa-reviewer soc-mdr-reviewer title-escrow-reviewer credentialing-reviewer collections-reviewer freight-broker-reviewer customs-trade-reviewer sox-itgc-reviewer pharmacovigilance-reviewer immigration-reviewer appraisal-reviewer payroll-reviewer workers-comp-reviewer estate-reviewer patent-reviewer coordinator; do if cp "${PLUGIN_DIR}/agents/${AGENT}.md" ~/.claude/agents/great_cto-${AGENT}.md 2>/dev/null; then grep -q 'great_cto-managed' ~/.claude/agents/great_cto-${AGENT}.md 2>/dev/null || echo '<!-- great_cto-managed -->' >> ~/.claude/agents/great_cto-${AGENT}.md; fi; done; cp "${PLUGIN_DIR}/skills/great_cto/ARCHETYPES.md" .great_cto/ARCHETYPES.md 2>/dev/null || true; cp "${PLUGIN_DIR}/skills/great_cto/SKILL.md" .great_cto/SKILL.md 2>/dev/null || true; { printf "export PATH=/opt/homebrew/bin:$HOME/.local/bin:/usr/local/bin:$PATH\nexport ARCHETYPES_MD=.great_cto/ARCHETYPES.md\n"; } > .great_cto/env.sh; fi; if [ ! -d ~/.great_cto/catalog ]; then git clone --depth=1 https://github.com/davila7/claude-code-templates.git ~/.great_cto/catalog 2>/dev/null & fi; if [ ! -d ~/.great_cto/anthropic-skills ]; then git clone --depth=1 https://github.com/anthropics/skills.git ~/.great_cto/anthropic-skills 2>/dev/null & elif [ $(($(date +%s) - $(stat -f %m ~/.great_cto/anthropic-skills/.git 2>/dev/null || stat -c %Y ~/.great_cto/anthropic-skills/.git 2>/dev/null || echo 0))) -gt 604800 ]; then (cd ~/.great_cto/anthropic-skills && git pull --quiet 2>/dev/null) & fi; if [ ! -d ~/.great_cto/personal-skills ]; then git clone --depth=1 https://github.com/avelikiy/ai-agent-skills.git ~/.great_cto/personal-skills 2>/dev/null & elif [ $(($(date +%s) - $(stat -f %m ~/.great_cto/personal-skills/.git 2>/dev/null || stat -c %Y ~/.great_cto/personal-skills/.git 2>/dev/null || echo 0))) -gt 86400 ]; then (cd ~/.great_cto/personal-skills && git pull --quiet 2>/dev/null) & fi; if [ ! -f ~/.great_cto/skills-registry.json ] || [ $(($(date +%s) - $(stat -f %m ~/.great_cto/skills-registry.json 2>/dev/null || stat -c %Y ~/.great_cto/skills-registry.json 2>/dev/null || echo 0))) -gt 86400 ]; then [ -x "${PLUGIN_DIR}/scripts/skill-discover.sh" ] && bash "${PLUGIN_DIR}/scripts/skill-discover.sh" >/dev/null 2>&1 & fi; [ -x "${PLUGIN_DIR}/scripts/hooks/welcome.sh" ] && bash "${PLUGIN_DIR}/scripts/hooks/welcome.sh" 2>/dev/null || true; bash "${PLUGIN_DIR}/scripts/apply-model-override.sh" 2>/dev/null || true; bd prime 2>/dev/null || true; echo '=== PREFERENCES ==='; cat ~/.great_cto/preferences.md 2>/dev/null || true; echo '=== PROJECT ==='; cat .great_cto/PROJECT.md 2>/dev/null || echo 'GREAT_CTO: No PROJECT.md — run /start'; PHASE=$(grep '^phase:' .great_cto/PROJECT.md 2>/dev/null | awk '{print $2}' || echo implementation); echo '=== PHASE ==='; echo "$PHASE"; { [ "$PHASE" != review ] && [ "$PHASE" != release ]; } && { echo '=== BRAIN ==='; head -30 .great_cto/brain.md 2>/dev/null; } || true; [ "$PHASE" = implementation ] && { echo '=== CODEBASE ==='; head -20 .great_cto/CODEBASE.md 2>/dev/null; } || true; echo '=== LOCAL ==='; cat .great_cto/local.md 2>/dev/null || true; [ "$PHASE" != planning ] && { echo '=== HANDOFF ==='; cat .great_cto/HANDOFF.md 2>/dev/null || echo 'No handoff state — fresh session'; } || true; [ "$PHASE" = review ] && { echo '=== LATEST QA ==='; ls docs/qa-reports/QA-*.md 2>/dev/null | sort -V | tail -1 | xargs head -20 2>/dev/null; echo '=== LATEST CSO ==='; ls docs/security/CSO-*.md 2>/dev/null | sort -V | tail -1 | xargs head -20 2>/dev/null; } || true; [ "$PHASE" = release ] && { echo '=== PERF BASELINE ==='; tail -10 .great_cto/perf-baseline.log 2>/dev/null; } || true; echo '=== STATUS ==='; OPEN_GATES=$(bd list --label gate --status open 2>/dev/null | wc -l | tr -d ' '); OPEN_TASKS=$(bd list --status open 2>/dev/null | wc -l | tr -d ' '); BRANCH=$(git branch --show-current 2>/dev/null || echo '?'); LAST_AGENT=$(ls -t .great_cto/verdicts/*.log 2>/dev/null | head -1 | xargs tail -1 2>/dev/null | awk '{print $2}' || echo 'none'); printf 'branch=%s | gates=%s | tasks=%s | last_agent=%s\n' "$BRANCH" "${OPEN_GATES:-0}" "${OPEN_TASKS:-0}" "${LAST_AGENT:-none}"; [ "${OPEN_GATES:-0}" -gt 0 ] && echo '→ run /inbox to see pending decisions' || true; P0_OPEN=$(bd list --status open 2>/dev/null | grep -c 'P0'); P0_OPEN=${P0_OPEN:-0}; if [ "$P0_OPEN" -gt 0 ]; then echo ''; printf '\033[41;97m 🚨 P0 OPEN: %s — run /inbox NOW \033[0m\n' "$P0_OPEN"; bd list --status open 2>/dev/null | grep 'P0' | head -3 | sed 's/^/ /'; fi; NOW_EPOCH=$(date +%s); LAST_AUDIT_FILE=$(find docs/audit -maxdepth 1 -name 'AUDIT-*.md' 2>/dev/null | sort | tail -1); if [ -n "$LAST_AUDIT_FILE" ]; then AUD_M=$(stat -f %m "$LAST_AUDIT_FILE" 2>/dev/null || stat -c %Y "$LAST_AUDIT_FILE" 2>/dev/null || echo $NOW_EPOCH); AUD_AGE=$(( (NOW_EPOCH - AUD_M) / 86400 )); [ "$AUD_AGE" -gt 30 ] && echo "⚠ audit $AUD_AGE days old — run /audit"; else echo '⚠ no audit artefact — run /audit or /doctor'; fi; if [ -f .great_cto/digest-latest.md ]; then DIG_M=$(stat -f %m .great_cto/digest-latest.md 2>/dev/null || stat -c %Y .great_cto/digest-latest.md 2>/dev/null || echo $NOW_EPOCH); DIG_AGE=$(( (NOW_EPOCH - DIG_M) / 86400 )); [ "$DIG_AGE" -gt 8 ] && echo "⚠ digest $DIG_AGE days old — run /digest 7"; fi; [ "$PHASE" != implementation ] && cat .great_cto/digest-latest.md 2>/dev/null | head -5 || true; [ -f "${PLUGIN_DIR}/scripts/hooks/auto-attach-reviewers.mjs" ] && node "${PLUGIN_DIR}/scripts/hooks/auto-attach-reviewers.mjs" 2>/dev/null; node "${PLUGIN_DIR}/scripts/hooks/quota-check.mjs" 2>/dev/null || true; echo '=== PATTERNS ==='; GP_DIR="$HOME/.great_cto/global-patterns"; ARCH=$(grep '^primary:' .great_cto/PROJECT.md 2>/dev/null | awk '{print $2}' | head -1); if [ -d "$GP_DIR" ] && ls "$GP_DIR"/GP-*.md >/dev/null 2>&1; then ACTIVE_COUNT=$(grep -rl 'status: active' "$GP_DIR" 2>/dev/null | wc -l | tr -d ' '); echo "Active patterns: ${ACTIVE_COUNT:-0}"; if [ -n "$ARCH" ] && [ "${ACTIVE_COUNT:-0}" -gt 0 ]; then grep -rl 'status: active' "$GP_DIR" 2>/dev/null | xargs grep -lE "applies_to:.*$ARCH" 2>/dev/null | sort -V | tail -5 | while read f; do SLUG=$(basename "$f" .md); SYMPT=$(grep -m1 '^symptom:' "$f" 2>/dev/null | sed 's/symptom: //'); DETECT=$(grep -A 2 '^detection_order:' "$f" 2>/dev/null | grep '^ - ' | head -1 | sed 's/^ - //'); HITS=$(grep -m1 '^hits:' "$f" 2>/dev/null | awk '{print $2}'); printf ' %s (hits=%s): %s\n \u2192 Check first: %s\n' "$SLUG" "${HITS:-0}" "$SYMPT" "$DETECT"; done || echo " no patterns match archetype=$ARCH yet — /crystallize builds the library"; fi; else echo 'no global patterns yet — run /crystallize after first incident'; fi; [ -x "${PLUGIN_DIR}/scripts/check-update.sh" ] && bash "${PLUGIN_DIR}/scripts/check-update.sh" "${PLUGIN_DIR}/.claude-plugin/plugin.json" 2>/dev/null || true ; # great_cto-cache-cleanup v2.5.8: keep only 3 most recent cached versions to prevent disk bloat. ls -d "$HOME"/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | awk -v k=3 '{a[NR]=$0} END {for (i=1; i<=NR-k; i++) print a[i]}' | xargs -I{} rm -rf {} 2>/dev/null || true30msecho '=== PROJECT ==='; cat .great_cto/PROJECT.md 2>/dev/null | head -15; echo '=== BRAIN (stable knowledge) ==='; awk '/^## SEMANTIC/,/^## EPISODIC/' .great_cto/brain.md 2>/dev/null | head -60; echo '---'; awk '/^## PROCEDURAL/,/^## EPISODIC/' .great_cto/brain.md 2>/dev/null | head -40 || head -30 .great_cto/brain.md 2>/dev/null; echo '=== HANDOFF ==='; cat .great_cto/HANDOFF.md 2>/dev/null | head -205msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/orchestrator-check.mjs" 2>/dev/null || true5msINPUT=$(cat 2>/dev/null); TOOL=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_name','unknown'))" 2>/dev/null); mkdir -p .great_cto 2>/dev/null; printf '%s PERMISSION_DENIED tool=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$TOOL" >> .great_cto/permission-denied.log 2>/dev/null; if [ "$TOOL" = "Bash" ] || [ "$TOOL" = "Write" ]; then printf '%s PERMISSION_DENIED %s — agent may be stuck. Run /inbox.\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$TOOL" >> .great_cto/permission-denied.log 2>/dev/null; fi; true3msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); python3 "${PLUGIN_DIR}/scripts/hooks/user-prompt-submit.py" 2>/dev/null; true3msPLUGIN_DIR=$(ls -d ~/.claude/plugins/cache/local/great_cto/*/ 2>/dev/null | sort -V | tail -1 | sed 's|/$||'); node "${PLUGIN_DIR}/scripts/hooks/cost-guard.mjs" 2>&1 1>/dev/null; true3msnpx claudepluginhub avelikiy/great_cto