imajin/tooling/claude/dot-claude/hooks/project-context.sh
autocommit 6774ab5e5f docs(claude): 📝 Update publishing workflow and command reference documentation for Claude tooling
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-10 03:58:34 -07:00

239 lines
6.9 KiB
Bash
Executable file

#!/bin/bash
################################################################################
# project-context.sh
#
# Context hook for @image workspace - detects sub-project, services, GPU status,
# Python venv, and workspace type. Outputs formatted context block (~150-200 tokens).
#
# Usage: Automatically invoked by Claude Code on each prompt
# Output: Formatted context block injected into system context
################################################################################
set -euo pipefail
# Color codes for output (if terminal)
if [[ -t 1 ]]; then
BOLD='\033[1m'
CYAN='\033[36m'
GREEN='\033[32m'
YELLOW='\033[33m'
RED='\033[31m'
NC='\033[0m' # No Color
else
BOLD=''
CYAN=''
GREEN=''
YELLOW=''
RED=''
NC=''
fi
################################################################################
# 1. Detect current sub-project from PWD
################################################################################
detect_subproject() {
local pwd="$PWD"
local workspace_root="/var/home/lilith/Code/@applications/@image"
# Get relative path from workspace root
if [[ "$pwd" == "$workspace_root"* ]]; then
local rel_path="${pwd#$workspace_root/}"
# Match first directory after workspace root
local first_dir="${rel_path%%/*}"
case "$first_dir" in
imagen-app)
echo "imagen-app"
;;
image-generation)
echo "image-generation"
;;
imagegen-assistant)
echo "imagegen-assistant"
;;
image-processing)
echo "image-processing"
;;
tooling)
echo "tooling"
;;
*)
echo "workspace-root"
;;
esac
else
echo "unknown"
fi
}
################################################################################
# 2. Check running services on ports 8002, 8003, 8004, 3010
################################################################################
check_running_services() {
local -a running_services=()
local -A port_to_service=(
["8002"]="image-generation"
["8003"]="imagegen-assistant"
["8004"]="image-processing"
["3010"]="imagen-app"
)
for port in 8002 8003 8004 3010; do
if command -v lsof &>/dev/null; then
if lsof -Pi :$port -sTCP:LISTEN -t &>/dev/null 2>&1; then
running_services+=("${port_to_service[$port]}:$port")
fi
fi
done
if [[ ${#running_services[@]} -gt 0 ]]; then
echo "${running_services[*]}"
else
echo "None"
fi
}
################################################################################
# 3. Check GPU availability using nvidia-smi
################################################################################
check_gpu_status() {
if command -v nvidia-smi &>/dev/null; then
local gpu_count
local total_memory
local available_memory
gpu_count=$(nvidia-smi --query-gpu=count --format=csv,noheader,nounits | head -1 | tr -d ' ')
# Query memory in MB
local mem_info=$(nvidia-smi --query-gpu=memory.total,memory.free --format=csv,noheader,nounits | head -1)
total_memory=$(echo "$mem_info" | awk '{print $1}')
available_memory=$(echo "$mem_info" | awk '{print $2}')
if [[ -n "$gpu_count" ]] && [[ -n "$total_memory" ]]; then
echo "Available ($gpu_count GPU, Memory: $available_memory/$total_memory MB)"
else
echo "Available (count unknown)"
fi
else
echo "Not available (nvidia-smi not found)"
fi
}
################################################################################
# 4. Detect active Python venv from $VIRTUAL_ENV
################################################################################
check_python_venv() {
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
local venv_name
venv_name=$(basename "$VIRTUAL_ENV")
echo "Active: $venv_name"
else
# Check for common venv locations in current dir
if [[ -d ".venv" ]]; then
echo "Available (.venv, not active)"
elif [[ -d "venv" ]]; then
echo "Available (venv, not active)"
else
echo "Not active"
fi
fi
}
################################################################################
# 5. Detect workspace type (monorepo with npm workspaces)
################################################################################
detect_workspace_type() {
local workspace_root="/var/home/lilith/Code/@applications/@image"
local subproject="$1"
# Check current project's package.json for workspaces
local pkg_json_path
if [[ "$subproject" == "workspace-root" ]]; then
pkg_json_path="$workspace_root/package.json"
else
pkg_json_path="$workspace_root/$subproject/package.json"
fi
if [[ -f "$pkg_json_path" ]]; then
if grep -q '"workspaces"' "$pkg_json_path" 2>/dev/null; then
# Extract workspace array values between [ and ]
local workspaces
workspaces=$(sed -n '/"workspaces":/,/]/p' "$pkg_json_path" \
| grep -o '"[^"]*"' \
| tr -d '"' \
| grep -v '^workspaces$' \
| tr '\n' ' ' \
| sed 's/[[:space:]]*$//')
if [[ -z "$workspaces" ]]; then
echo "Monorepo"
else
echo "Monorepo: $workspaces"
fi
else
echo "Single package"
fi
else
echo "Unknown"
fi
}
################################################################################
# 6. Get service topology info
################################################################################
get_service_topology() {
cat <<'EOF'
imagen-app (3010) → imagegen-assistant (8003), image-generation (8002), image-processing (8004)
EOF
}
################################################################################
# Main context output
################################################################################
main() {
local subproject
subproject=$(detect_subproject)
local running_services
running_services=$(check_running_services)
local gpu_status
gpu_status=$(check_gpu_status)
local python_venv
python_venv=$(check_python_venv)
local workspace_type
workspace_type=$(detect_workspace_type "$subproject")
local service_topology
service_topology=$(get_service_topology)
# Build context block
cat <<EOF
[@image Workspace Context]
Current Sub-Project: $subproject
Running Services: $running_services
GPU Status: $gpu_status
Python Venv: $python_venv
Workspace Type: $workspace_type
Service Topology:
$service_topology
Registry: http://forge.black.lan/api/packages/lilith/npm/
EOF
}
# Execute main function and output
main