context-load walks from cwd upward, loading CLAUDE.md, CONTEXT.md, MEMORY.md, and BESTPRACTICES.md files with directory trees and git status. start-claude wraps the claude CLI with --append-system-prompt. CLAUDE.md: removed Ansible/Helm sections (in best-practices/), folded Validate Before Deploying into Process Principles, deduped secrets bullet, fixed best-practices path references. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
151 lines
4.3 KiB
Bash
Executable File
151 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# context-load — Gather project context for a Claude Code session
|
|
#
|
|
# Walks from cwd upward collecting key index files.
|
|
# 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
|
|
# - 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() {
|
|
echo ""
|
|
echo "================================================================"
|
|
echo "=== $1"
|
|
echo "================================================================"
|
|
echo ""
|
|
}
|
|
|
|
emit_file() {
|
|
local filepath="$1"
|
|
emit_header "FILE: $filepath"
|
|
cat "$filepath"
|
|
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' "$dir" 2>/dev/null \
|
|
|| find "$dir" -maxdepth "$TREE_DEPTH" -not -path '*/.git/*' -not -path '*/.git' | sort
|
|
echo ""
|
|
}
|
|
|
|
strip_ansi() {
|
|
sed 's/\x1b\[[0-9;]*m//g'
|
|
}
|
|
|
|
# --- Discovery: walk from cwd upward ---
|
|
|
|
discover_upward() {
|
|
local dir="$PWD"
|
|
local dirs=()
|
|
while [[ "$dir" != "/" ]]; do
|
|
dirs+=("$dir")
|
|
dir="$(dirname "$dir")"
|
|
done
|
|
# Return in top-down order (reverse — highest ancestor first)
|
|
for ((i=${#dirs[@]}-1; i>=0; i--)); do
|
|
echo "${dirs[$i]}"
|
|
done
|
|
}
|
|
|
|
# Collect dirs that have key index files
|
|
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")
|
|
[[ -f "$dir/BESTPRACTICES.md" ]] && bestpractices_dirs+=("$dir")
|
|
done < <(discover_upward)
|
|
|
|
if [[ ${#claude_dirs[@]} -eq 0 ]]; then
|
|
echo "# No CLAUDE.md found in directory hierarchy" >&2
|
|
echo "# Searched from: $PWD" >&2
|
|
fi
|
|
|
|
# --- Output: CLAUDE.md files (top-down) + tree from each ---
|
|
|
|
# Track files we've already emitted to avoid duplicates
|
|
declare -A emitted_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"
|
|
emitted_files["$real_path"]=1
|
|
fi
|
|
emit_tree "$dir"
|
|
done
|
|
|
|
# --- Output: CONTEXT.md files (top-down) ---
|
|
|
|
for dir in "${context_dirs[@]}"; do
|
|
real_path="$(readlink -f "$dir/CONTEXT.md")"
|
|
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
|
emit_file "$dir/CONTEXT.md"
|
|
emitted_files["$real_path"]=1
|
|
fi
|
|
done
|
|
|
|
# --- Output: MEMORY.md files (top-down) ---
|
|
|
|
for dir in "${memory_dirs[@]}"; do
|
|
real_path="$(readlink -f "$dir/MEMORY.md")"
|
|
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
|
emit_file "$dir/MEMORY.md"
|
|
emitted_files["$real_path"]=1
|
|
fi
|
|
done
|
|
|
|
# --- Output: BESTPRACTICES.md files (top-down) ---
|
|
|
|
for dir in "${bestpractices_dirs[@]}"; do
|
|
real_path="$(readlink -f "$dir/BESTPRACTICES.md")"
|
|
if [[ -z "${emitted_files[$real_path]:-}" ]]; then
|
|
emit_file "$dir/BESTPRACTICES.md"
|
|
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
|