Add question-reframing guidance to CLAUDE.md; commit accumulated project files
- CLAUDE.md: add "Question the question" and "One clarifying question" rules to Tone and Interaction — XY problem detection, false premise checks, and explicit reframe pattern before answering - Add claude/ detail-file directory (topic docs referenced from CLAUDE.md) - Add ABOUT.md, FUTURE.md - Update memory/, scripts/, settings.yaml with accumulated session changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,17 +5,13 @@
|
||||
# Outputs structured context to stdout, suitable for --append-system-prompt.
|
||||
#
|
||||
# What it loads:
|
||||
# - Every CLAUDE.md found walking up from cwd (top-down order)
|
||||
# - Directory tree (depth 3) from each CLAUDE.md location
|
||||
# - Paths to every CLAUDE.md found walking up from cwd (not contents — Claude Code loads those natively)
|
||||
# - Paths to every project CLAUDE.md found under each CLAUDE.md directory (for project discovery)
|
||||
# - Every CONTEXT.md found walking up from cwd (top-down order)
|
||||
# - Every MEMORY.md found walking up from cwd (top-down order)
|
||||
# - Every BESTPRACTICES.md found walking up from cwd (top-down order)
|
||||
# - All *.md files in cwd
|
||||
# - git-status-report from the highest-level CLAUDE.md dir
|
||||
set -uo pipefail
|
||||
|
||||
TREE_DEPTH=3
|
||||
|
||||
# --- Helpers ---
|
||||
|
||||
emit_header() {
|
||||
@@ -33,16 +29,15 @@ emit_file() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
emit_tree() {
|
||||
local dir="$1"
|
||||
emit_header "TREE: $dir (depth $TREE_DEPTH)"
|
||||
tree -L "$TREE_DEPTH" --charset utf-8 -I '.git|node_modules|__pycache__|.venv|venv|customers' "$dir" 2>/dev/null \
|
||||
|| find "$dir" -maxdepth "$TREE_DEPTH" -not -path '*/.git/*' -not -path '*/.git' -not -path '*/customers/*' -not -path '*/customers' | sort
|
||||
echo ""
|
||||
}
|
||||
|
||||
strip_ansi() {
|
||||
sed 's/\x1b\[[0-9;]*m//g'
|
||||
# Extract description from ABOUT.md in the same directory as a CLAUDE.md
|
||||
get_project_description() {
|
||||
local claude_path="$1"
|
||||
local dir
|
||||
dir="$(dirname "$claude_path")"
|
||||
local about="$dir/ABOUT.md"
|
||||
if [[ -f "$about" ]]; then
|
||||
sed -n 's/^description:[[:space:]]*//p' "$about" | head -1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Discovery: walk from cwd upward ---
|
||||
@@ -65,10 +60,8 @@ claude_dirs=()
|
||||
context_dirs=()
|
||||
memory_dirs=()
|
||||
bestpractices_dirs=()
|
||||
all_hierarchy_dirs=()
|
||||
|
||||
while IFS= read -r dir; do
|
||||
all_hierarchy_dirs+=("$dir")
|
||||
[[ -f "$dir/CLAUDE.md" ]] && claude_dirs+=("$dir")
|
||||
[[ -f "$dir/CONTEXT.md" ]] && context_dirs+=("$dir")
|
||||
[[ -f "$dir/MEMORY.md" ]] && memory_dirs+=("$dir")
|
||||
@@ -90,21 +83,53 @@ else
|
||||
emit_header "CLAUDE PROFILE: $profile_name ($profile_dir)"
|
||||
fi
|
||||
|
||||
# --- Output: CLAUDE.md files (top-down) + tree from each ---
|
||||
# --- Output: CLAUDE.md paths (not contents — Claude Code loads those natively) ---
|
||||
# Also discover project CLAUDE.md files under each directory for project listing
|
||||
|
||||
# Track files we've already emitted to avoid duplicates
|
||||
declare -A emitted_files
|
||||
|
||||
emit_header "CLAUDE.md FILES"
|
||||
for dir in "${claude_dirs[@]}"; do
|
||||
# Resolve symlinks for dedup — two paths might point to the same file
|
||||
real_path="$(readlink -f "$dir/CLAUDE.md")"
|
||||
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
||||
emit_file "$dir/CLAUDE.md"
|
||||
desc="$(get_project_description "$dir/CLAUDE.md")"
|
||||
if [[ -n "$desc" ]]; then
|
||||
echo "- $dir/CLAUDE.md — $desc"
|
||||
else
|
||||
echo "- $dir/CLAUDE.md"
|
||||
fi
|
||||
emitted_files["$real_path"]=1
|
||||
fi
|
||||
emit_tree "$dir"
|
||||
done
|
||||
|
||||
# Discover project CLAUDE.md files (depth 2-4 under each CLAUDE.md dir)
|
||||
# This replaces the old tree output — gives Claude a fresh project listing
|
||||
project_claudes=()
|
||||
for dir in "${claude_dirs[@]}"; do
|
||||
while IFS= read -r f; do
|
||||
real_path="$(readlink -f "$f")"
|
||||
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
||||
project_claudes+=("$f")
|
||||
emitted_files["$real_path"]=1
|
||||
fi
|
||||
done < <(find "$dir" -mindepth 2 -maxdepth 4 -name CLAUDE.md -not -path '*/.git/*' -not -path '*/node_modules/*' -not -path '*/__pycache__/*' 2>/dev/null | sort)
|
||||
done
|
||||
|
||||
if [[ ${#project_claudes[@]} -gt 0 ]]; then
|
||||
echo ""
|
||||
echo "Project CLAUDE.md files:"
|
||||
for f in "${project_claudes[@]}"; do
|
||||
desc="$(get_project_description "$f")"
|
||||
if [[ -n "$desc" ]]; then
|
||||
echo "- $f — $desc"
|
||||
else
|
||||
echo "- $f"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# --- Output: CONTEXT.md files (top-down) ---
|
||||
|
||||
for dir in "${context_dirs[@]}"; do
|
||||
@@ -134,27 +159,3 @@ for dir in "${bestpractices_dirs[@]}"; do
|
||||
emitted_files["$real_path"]=1
|
||||
fi
|
||||
done
|
||||
|
||||
# --- Output: all *.md files in cwd ---
|
||||
|
||||
if compgen -G "$PWD"/*.md > /dev/null 2>&1; then
|
||||
for md_file in "$PWD"/*.md; do
|
||||
[[ -f "$md_file" ]] || continue
|
||||
real_path="$(readlink -f "$md_file")"
|
||||
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
||||
emit_file "$md_file"
|
||||
emitted_files["$real_path"]=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# --- Output: git status report ---
|
||||
|
||||
if [[ ${#claude_dirs[@]} -gt 0 ]]; then
|
||||
highest_dir="${claude_dirs[0]}"
|
||||
git_status_report="$(command -v git-status-report 2>/dev/null || true)"
|
||||
if [[ -n "$git_status_report" ]]; then
|
||||
emit_header "GIT STATUS: $highest_dir"
|
||||
"$git_status_report" "$highest_dir" 2>/dev/null | strip_ansi || true
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -9,6 +9,26 @@ DATA=$(cat)
|
||||
SESSION_ID=$(echo "$DATA" | jq -r '.session_id // empty')
|
||||
MODEL=$(echo "$DATA" | jq -r '.model.display_name // "unknown"')
|
||||
CONTEXT_PCT=$(echo "$DATA" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
|
||||
FIVE_HR=$(echo "$DATA" | jq -r '.rate_limits.five_hour.used_percentage // empty' | cut -d. -f1)
|
||||
SEVEN_DAY=$(echo "$DATA" | jq -r '.rate_limits.seven_day.used_percentage // empty' | cut -d. -f1)
|
||||
|
||||
MODE_TAG=""
|
||||
MODEL_DISPLAY="$MODEL"
|
||||
if [[ -n "${CLAUDE_CONFIG_DIR:-}" && -f "$CLAUDE_CONFIG_DIR/active-mode.env" ]]; then
|
||||
env_file="$CLAUDE_CONFIG_DIR/active-mode.env"
|
||||
MODE_TAG=$(grep '^CLAUDE_MODE_TAG=' "$env_file" 2>/dev/null | cut -d= -f2- || true)
|
||||
raw_driver=$(grep '^CLAUDE_DRIVER=' "$env_file" 2>/dev/null | cut -d= -f2- || true)
|
||||
escalates_to=$(grep '^CLAUDE_ESCALATES_TO=' "$env_file" 2>/dev/null | cut -d= -f2- || true)
|
||||
if [[ -n "$raw_driver" ]]; then
|
||||
# Capitalize first letter of driver (sonnet→Sonnet, haiku→Haiku, opus→Opus)
|
||||
driver_cap="$(tr '[:lower:]' '[:upper:]' <<< "${raw_driver:0:1}")${raw_driver:1}"
|
||||
if [[ "$escalates_to" == "opus" ]]; then
|
||||
MODEL_DISPLAY="${driver_cap}→Opus"
|
||||
else
|
||||
MODEL_DISPLAY="$driver_cap"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
TOPIC=""
|
||||
if [[ -n "$SESSION_ID" ]]; then
|
||||
@@ -33,8 +53,23 @@ if [[ -n "$SESSION_ID" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$TOPIC" ]]; then
|
||||
echo "[$MODEL] $TOPIC | ${CONTEXT_PCT}% context"
|
||||
else
|
||||
echo "[$MODEL] ${CONTEXT_PCT}% context"
|
||||
USAGE=""
|
||||
if [[ -n "$FIVE_HR" ]]; then
|
||||
USAGE=" | 5h: ${FIVE_HR}%"
|
||||
if [[ -n "$SEVEN_DAY" ]]; then
|
||||
USAGE="$USAGE 7d: ${SEVEN_DAY}%"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prepend mode tag to topic if set
|
||||
if [[ -n "$MODE_TAG" && -n "$TOPIC" ]]; then
|
||||
TOPIC="${MODE_TAG} · ${TOPIC}"
|
||||
elif [[ -n "$MODE_TAG" ]]; then
|
||||
TOPIC="$MODE_TAG"
|
||||
fi
|
||||
|
||||
if [[ -n "$TOPIC" ]]; then
|
||||
echo "[$MODEL_DISPLAY] $TOPIC | ${CONTEXT_PCT}% context${USAGE}"
|
||||
else
|
||||
echo "[$MODEL_DISPLAY] ${CONTEXT_PCT}% context${USAGE}"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user