Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a83336b
feat: add 12 public data source wiki entries with acquisition scripts…
ShinMegamiBoson Feb 22, 2026
c58a140
feat: add TUI progress display, input queuing, and ESC cancellation
ShinMegamiBoson Feb 22, 2026
be8bcac
feat: add read_image tool for vision-capable model analysis
ShinMegamiBoson Feb 22, 2026
61de9d7
feat: add reusable investigation scripts; fix TUI Live display flicker
ShinMegamiBoson Feb 22, 2026
4d267a3
feat: add session logs reference to system prompt
ShinMegamiBoson Feb 22, 2026
1279f00
fix: eliminate TUI flicker caused by patch_stdout corrupting Rich esc…
ShinMegamiBoson Feb 22, 2026
331dd8d
fix: eliminate TUI flicker, handle slash commands, auto-unblock prompt
ShinMegamiBoson Feb 22, 2026
92dbc07
feat: add per-turn session summaries for agent history awareness
ShinMegamiBoson Feb 23, 2026
9a60f65
feat: add live preview of tool call arguments during model streaming
ShinMegamiBoson Feb 23, 2026
7a227fa
fix: initialize _queued_input in RichREPL.__init__
ShinMegamiBoson Feb 23, 2026
50c4b9a
fix: define missing _queue_prompt_style() in tui.py
ShinMegamiBoson Feb 23, 2026
f24810e
test: add RichREPL test coverage for init, run loop, events, and slas…
ShinMegamiBoson Feb 23, 2026
c9c2baf
[Unplanned] Install meta-process governance framework
BrianMills2718 Feb 23, 2026
6bce3d5
[Trivial] Symlink AGENTS.md → CLAUDE.md for single source of truth
BrianMills2718 Feb 23, 2026
bbe2766
[Trivial] Slim meta-process.yaml to match project needs
BrianMills2718 Feb 23, 2026
f9b8864
[Unplanned] Enable worktree coordination for multi-agent isolation
BrianMills2718 Feb 23, 2026
c14b8ba
[Trivial] Refresh meta-process scaffolding (pr-auto + dead-code)
BrianMills2718 Feb 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
55 changes: 55 additions & 0 deletions .claude/hooks/check-hook-enabled.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/bash
# Check if a hook is enabled in meta-process.yaml
#
# Usage (source this in other hooks):
# source "$(dirname "$0")/check-hook-enabled.sh"
# if ! is_hook_enabled "protect_main"; then
# exit 0 # Hook disabled, skip
# fi
#
# Or check directly:
# ./check-hook-enabled.sh protect_main # exits 0 if enabled

# Get repo root
get_repo_root() {
git rev-parse --show-toplevel 2>/dev/null || dirname "$(dirname "$(dirname "$0")")"
}

# Check if a hook is enabled
# Returns 0 (true) if enabled, 1 (false) if disabled
is_hook_enabled() {
local hook_name="$1"
local repo_root
repo_root=$(get_repo_root)

# Use Python helper if available (more reliable YAML parsing)
if [[ -f "$repo_root/scripts/meta_config.py" ]]; then
python "$repo_root/scripts/meta_config.py" --hook "$hook_name" 2>/dev/null
return $?
fi

# Fallback: grep for the setting in meta-process.yaml
local config_file="$repo_root/meta-process.yaml"
if [[ ! -f "$config_file" ]]; then
# No config file = all hooks enabled by default
return 0
fi

# Simple grep-based check (not perfect but works for basic cases)
# Look for "hook_name: false" under hooks section
if grep -A 50 "^hooks:" "$config_file" 2>/dev/null | grep -q "^\s*${hook_name}:\s*false"; then
return 1 # Disabled
fi

return 0 # Enabled (default)
}

# If called directly (not sourced), check the hook
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
if [[ -z "$1" ]]; then
echo "Usage: $0 <hook_name>" >&2
exit 1
fi
is_hook_enabled "$1"
exit $?
fi
116 changes: 116 additions & 0 deletions .claude/hooks/check-references-reviewed.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/bash
# References Reviewed Enforcement Hook for Claude Code
# Warns (doesn't block) if the active plan lacks a References Reviewed section.
#
# Exit codes:
# 0 - Always (this hook warns but doesn't block)
#
# This hook encourages exploration before coding by checking that the plan
# documents what code/docs were reviewed before planning.

set -e

# Only warn once per session to avoid spam
# Use a temp file to track if we've warned
SESSION_MARKER="/tmp/.claude_refs_warned_$$"

# If we've already warned this session, skip
if [[ -f "$SESSION_MARKER" ]]; then
exit 0
fi

# Get the main repo root
MAIN_DIR=$(git rev-parse --git-common-dir 2>/dev/null | xargs dirname)
if [[ -z "$MAIN_DIR" ]]; then
exit 0
fi

# Read tool input to get file path
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ -z "$FILE_PATH" ]]; then
exit 0
fi

# Only check on source file edits (not docs, config, etc.)
# Handle both absolute paths (/path/to/src/...) and relative paths (src/...)
if [[ "$FILE_PATH" != *"/src/"* ]] && [[ "$FILE_PATH" != *"/tests/"* ]] && \
[[ "$FILE_PATH" != "src/"* ]] && [[ "$FILE_PATH" != "tests/"* ]]; then
exit 0
fi

# Get branch name
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")

# Skip for main branch
if [[ "$BRANCH" == "main" ]]; then
exit 0
fi

# Try to get plan number from branch name
PLAN_NUM=""
if [[ "$BRANCH" =~ ^plan-([0-9]+) ]]; then
PLAN_NUM="${BASH_REMATCH[1]}"
fi

# If no plan number, skip
if [[ -z "$PLAN_NUM" ]]; then
exit 0
fi

# Check references using parse_plan.py (check both script locations)
PARSE_PLAN=""
if [[ -f "$MAIN_DIR/scripts/meta/parse_plan.py" ]]; then
PARSE_PLAN="$MAIN_DIR/scripts/meta/parse_plan.py"
elif [[ -f "$MAIN_DIR/scripts/parse_plan.py" ]]; then
PARSE_PLAN="$MAIN_DIR/scripts/parse_plan.py"
else
exit 0
fi

# Get references reviewed
RESULT=$(python "$PARSE_PLAN" --plan "$PLAN_NUM" --references-reviewed --json 2>/dev/null || echo '{"error": "parse_failed"}')

# Parse result
REFS=$(echo "$RESULT" | jq -r '.references_reviewed // []')
REF_COUNT=$(echo "$REFS" | jq 'length')
ERROR=$(echo "$RESULT" | jq -r '.error // empty')

# Skip on errors
if [[ -n "$ERROR" ]]; then
exit 0
fi

# Check if references are sufficient (at least 2 entries)
MIN_REFS=2

if [[ "$REF_COUNT" -lt "$MIN_REFS" ]]; then
# Mark that we've warned
touch "$SESSION_MARKER"

echo "" >&2
echo "========================================" >&2
echo "⚠️ EXPLORATION WARNING" >&2
echo "========================================" >&2
echo "" >&2
echo "Plan #$PLAN_NUM has insufficient 'References Reviewed' ($REF_COUNT/$MIN_REFS minimum)" >&2
echo "" >&2
echo "Before implementing, you should:" >&2
echo " 1. Explore the existing codebase" >&2
echo " 2. Document what you reviewed in the plan" >&2
echo "" >&2
echo "Add to your plan file (docs/plans/${PLAN_NUM}_*.md):" >&2
echo "" >&2
echo " ## References Reviewed" >&2
echo " - src/relevant/file.py:10-50 - description of what you learned" >&2
echo " - docs/architecture/current/relevant.md - relevant design context" >&2
echo "" >&2
echo "This ensures you understand the codebase before changing it." >&2
echo "(This warning appears once per session)" >&2
echo "========================================" >&2
echo "" >&2
fi

# Always allow (warning only)
exit 0
92 changes: 92 additions & 0 deletions .claude/hooks/gate-edit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# Gate edits on required reading.
# PreToolUse/Edit hook — blocks edits to src/ files if coupled docs not read.
#
# Uses relationships.yaml couplings to determine what docs must be read
# and checks the session reads file (populated by track-reads.sh).
#
# Exit codes:
# 0 - Allow (all required docs read, or file not gated)
# 2 - Block (required docs not yet read)
#
# Bypass: SKIP_READ_GATE=1 in environment, or edit non-src files.

set -e

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || echo "")
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || echo "")

# Only gate Edit and Write
if [[ "$TOOL_NAME" != "Edit" && "$TOOL_NAME" != "Write" ]]; then
exit 0
fi

if [[ -z "$FILE_PATH" ]]; then
exit 0
fi

# Only gate src/ files
if [[ "$FILE_PATH" != *"/src/"* ]] && [[ "$FILE_PATH" != "src/"* ]]; then
exit 0
fi

# Bypass check
if [[ "${SKIP_READ_GATE:-}" == "1" ]]; then
exit 0
fi

# Get repo root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Normalize path
REL_PATH="$FILE_PATH"
if [[ "$FILE_PATH" == "$REPO_ROOT/"* ]]; then
REL_PATH="${FILE_PATH#$REPO_ROOT/}"
fi
if [[ "$REL_PATH" == worktrees/* ]]; then
REL_PATH=$(echo "$REL_PATH" | sed 's|^worktrees/[^/]*/||')
fi

# Find the check script
CHECK_SCRIPT="$REPO_ROOT/scripts/check_required_reading.py"
if [[ ! -f "$CHECK_SCRIPT" ]]; then
exit 0 # Script not available, allow
fi

READS_FILE="/tmp/.claude_session_reads"

# Run the check
set +e
RESULT=$(cd "$REPO_ROOT" && python "$CHECK_SCRIPT" "$REL_PATH" --reads-file "$READS_FILE" 2>/dev/null)
CHECK_EXIT=$?
set -e

if [[ $CHECK_EXIT -ne 0 ]]; then
# Escape for JSON output
RESULT_ESCAPED=$(echo "$RESULT" | jq -Rs .)

cat << EOF
{
"decision": "block",
"reason": $RESULT_ESCAPED
}
EOF
exit 2
fi

# All required reading done — output constraints as advisory context
if [[ -n "$RESULT" ]]; then
RESULT_ESCAPED=$(echo "$RESULT" | jq -Rs .)
cat << EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": $RESULT_ESCAPED
}
}
EOF
fi

exit 0
81 changes: 81 additions & 0 deletions .claude/hooks/post-edit-quiz.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash
# Post-edit quiz — surfaces understanding questions after editing src/ files.
# PostToolUse/Edit hook — shows constraint quiz after successful edits.
#
# This is advisory (exit 0) — it doesn't block, just prompts engagement.
#
# Only triggers for src/ files with governance entries.

set -e

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || echo "")
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || echo "")

# Only fire after Edit and Write
if [[ "$TOOL_NAME" != "Edit" && "$TOOL_NAME" != "Write" ]]; then
exit 0
fi

if [[ -z "$FILE_PATH" ]]; then
exit 0
fi

# Only for src/ files
if [[ "$FILE_PATH" != *"/src/"* ]] && [[ "$FILE_PATH" != "src/"* ]]; then
exit 0
fi

# Bypass
if [[ "${SKIP_QUIZ:-}" == "1" ]]; then
exit 0
fi

# Get repo root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Normalize path
REL_PATH="$FILE_PATH"
if [[ "$FILE_PATH" == "$REPO_ROOT/"* ]]; then
REL_PATH="${FILE_PATH#$REPO_ROOT/}"
fi
if [[ "$REL_PATH" == worktrees/* ]]; then
REL_PATH=$(echo "$REL_PATH" | sed 's|^worktrees/[^/]*/||')
fi

# Find quiz script
QUIZ_SCRIPT="$REPO_ROOT/scripts/generate_quiz.py"
if [[ ! -f "$QUIZ_SCRIPT" ]]; then
exit 0
fi

# Generate quiz (JSON mode for structured output)
set +e
RESULT=$(cd "$REPO_ROOT" && python "$QUIZ_SCRIPT" "$REL_PATH" --json 2>/dev/null)
QUIZ_EXIT=$?
set -e

if [[ $QUIZ_EXIT -ne 0 ]] || [[ -z "$RESULT" ]] || [[ "$RESULT" == "[]" ]]; then
exit 0
fi

# Extract just the questions as readable text
QUIZ_TEXT=$(cd "$REPO_ROOT" && python "$QUIZ_SCRIPT" "$REL_PATH" 2>/dev/null)

if [[ -z "$QUIZ_TEXT" ]]; then
exit 0
fi

QUIZ_ESCAPED=$(echo "$QUIZ_TEXT" | jq -Rs .)

cat << EOF
{
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": $QUIZ_ESCAPED
}
}
EOF

exit 0
48 changes: 48 additions & 0 deletions .claude/hooks/protect-main.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
# Branch Protection Hook for Claude Code
# Warns when editing files directly on the main/master branch.
# Encourages creating a feature branch first.
#
# This is the CORE version (branch-based workflow).
# For worktree enforcement, see worktree-coordination/protect-main.sh
#
# Exit codes:
# 0 - Allow the operation
# 2 - Block the operation

set -e

# Only applies to Edit/Write operations (file modifications)
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ -z "$FILE_PATH" ]]; then
exit 0 # No file_path, allow
fi

# Allow coordination files everywhere
BASENAME=$(basename "$FILE_PATH")
if [[ "$FILE_PATH" == *"/.claude/"* ]] || \
[[ "$BASENAME" == "CLAUDE.md" ]] || \
[[ "$FILE_PATH" == *"/.git/"* ]] || \
[[ "$FILE_PATH" == */meta/patterns/*.md ]] || \
[[ "$FILE_PATH" == */meta-process/*.md ]] || \
[[ "$BASENAME" == ".claude_session" ]]; then
exit 0 # Coordination/docs files allowed on any branch
fi

# Check current branch
BRANCH=$(git branch --show-current 2>/dev/null)

if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then
echo "WARNING: You're editing files directly on '$BRANCH'" >&2
echo "" >&2
echo "Consider creating a feature branch first:" >&2
echo " git checkout -b plan-N-description" >&2
echo "" >&2
echo "File: $FILE_PATH" >&2
# Allow but warn - the git hooks will catch direct commits to main
exit 0
fi

exit 0
Loading