Loading...
Claude Code workspace depth tracker showing monorepo navigation level, project root detection, and directory depth visualization for context awareness.
#!/usr/bin/env bash
# Workspace Project Depth Indicator for Claude Code
# Tracks directory depth and project context
# Read JSON from stdin
read -r input
# Extract workspace info
current_dir=$(echo "$input" | jq -r '.workspace.current_dir // ""')
# Handle empty workspace
if [ -z "$current_dir" ] || [ "$current_dir" = "null" ]; then
echo "📂 No workspace"
exit 0
fi
# Calculate directory depth (count of slashes)
# Remove leading slash to avoid off-by-one
dir_path="${current_dir#/}"
depth=$(echo "$dir_path" | tr -cd '/' | wc -c | tr -d ' ')
# Detect project root indicators
project_indicators=(
".git"
"package.json"
"Cargo.toml"
"go.mod"
"pom.xml"
"build.gradle"
"pyproject.toml"
"composer.json"
)
# Check if current directory is project root
IS_PROJECT_ROOT=false
PROJECT_TYPE=""
for indicator in "${project_indicators[@]}"; do
if [ -f "${current_dir}/${indicator}" ] || [ -d "${current_dir}/${indicator}" ]; then
IS_PROJECT_ROOT=true
case "$indicator" in
".git") PROJECT_TYPE="git" ;;
"package.json") PROJECT_TYPE="node" ;;
"Cargo.toml") PROJECT_TYPE="rust" ;;
"go.mod") PROJECT_TYPE="go" ;;
"pom.xml"|"build.gradle") PROJECT_TYPE="java" ;;
"pyproject.toml") PROJECT_TYPE="python" ;;
"composer.json") PROJECT_TYPE="php" ;;
esac
break
fi
done
# Find project root by walking up directory tree
PROJECT_ROOT="$current_dir"
check_dir="$current_dir"
while [ "$check_dir" != "/" ]; do
for indicator in "${project_indicators[@]}"; do
if [ -f "${check_dir}/${indicator}" ] || [ -d "${check_dir}/${indicator}" ]; then
PROJECT_ROOT="$check_dir"
break 2
fi
done
check_dir=$(dirname "$check_dir")
done
# Calculate depth relative to project root (0 = at root)
if [ "$PROJECT_ROOT" != "$current_dir" ]; then
relative_path="${current_dir#$PROJECT_ROOT/}"
relative_depth=$(echo "$relative_path" | tr -cd '/' | wc -c | tr -d ' ')
relative_depth=$((relative_depth + 1)) # +1 because we're in a subdirectory
else
relative_depth=0
fi
# Color coding based on depth
if [ $relative_depth -eq 0 ]; then
DEPTH_COLOR="\033[38;5;46m" # Green: At project root
DEPTH_ICON="📁"
DEPTH_STATUS="ROOT"
elif [ $relative_depth -le 2 ]; then
DEPTH_COLOR="\033[38;5;75m" # Blue: 1-2 levels deep (normal)
DEPTH_ICON="📂"
DEPTH_STATUS="L${relative_depth}"
elif [ $relative_depth -le 4 ]; then
DEPTH_COLOR="\033[38;5;226m" # Yellow: 3-4 levels deep (moderate)
DEPTH_ICON="📂"
DEPTH_STATUS="L${relative_depth}"
else
DEPTH_COLOR="\033[38;5;208m" # Orange: 5+ levels deep (deep nesting)
DEPTH_ICON="📂"
DEPTH_STATUS="L${relative_depth}+"
fi
# Project type indicator
if [ "$IS_PROJECT_ROOT" = true ] && [ -n "$PROJECT_TYPE" ]; then
TYPE_DISPLAY="${PROJECT_TYPE}"
else
TYPE_DISPLAY=""
fi
# Extract directory name for display
dir_name=$(basename "$current_dir")
# Monorepo detection (apps/, packages/, libs/ directories)
if echo "$current_dir" | grep -qE '/(apps|packages|libs|services|modules)/'; then
MONOREPO_INDICATOR="[monorepo]"
else
MONOREPO_INDICATOR=""
fi
# Build breadcrumb visualization (last 3 directories)
if [ $relative_depth -gt 0 ]; then
breadcrumb=$(echo "$current_dir" | awk -F'/' '{for(i=NF-2;i<=NF;i++) if($i) printf "%s/", $i}' | sed 's|/$||')
else
breadcrumb="$dir_name"
fi
RESET="\033[0m"
# Output statusline
if [ -n "$TYPE_DISPLAY" ]; then
echo -e "${DEPTH_ICON} ${DEPTH_COLOR}${DEPTH_STATUS}${RESET} ${TYPE_DISPLAY} | ${breadcrumb} ${MONOREPO_INDICATOR}"
else
echo -e "${DEPTH_ICON} ${DEPTH_COLOR}${DEPTH_STATUS}${RESET} | ${breadcrumb} ${MONOREPO_INDICATOR}"
fi
{
"format": "bash",
"position": "left",
"refreshInterval": 2000
}Workspace showing 'No workspace' despite active Claude Code session
Verify workspace.current_dir field exists: echo '$input' | jq .workspace.current_dir. If field missing or null, Claude Code may not be tracking workspace. Check that session was started in a directory (not attached to running process without cwd).
Project root not being detected correctly
Script checks for common project indicators: .git, package.json, Cargo.toml, go.mod, pom.xml, build.gradle, pyproject.toml, composer.json. If your project uses different marker (e.g., .project), add to project_indicators array. Verify indicator exists: ls -la $current_dir.
Relative depth showing incorrect level count
Depth calculation: relative_depth = (number of slashes in path after project root) + 1. Example: project root /foo/bar, current /foo/bar/src/lib = 2 levels deep. Check PROJECT_ROOT detection: echo $PROJECT_ROOT. Verify current_dir: echo $current_dir. Path stripping: ${current_dir#$PROJECT_ROOT/}.
Monorepo indicator not appearing for monorepo projects
Monorepo detection matches directories containing /apps/, /packages/, /libs/, /services/, or /modules/. Check path: echo '$current_dir' | grep -E '/(apps|packages|libs|services|modules)/'. Add custom monorepo patterns to grep: |(workspaces|projects)/.
Breadcrumb showing only current directory not last 3 levels
Breadcrumb uses awk to extract last 3 path components: awk -F'/' '{for(i=NF-2;i<=NF;i++) if($i) printf "%s/", $i}'. Test: echo '/foo/bar/baz/qux' | awk -F'/' '{for(i=NF-2;i<=NF;i++) if($i) printf "%s/", $i}' (should show bar/baz/qux). Adjust NF-2 to NF-N for more/fewer levels.
Project type not displaying despite being at project root
IS_PROJECT_ROOT flag set to true when indicator found in current_dir. Check file exists: ls $current_dir/package.json (for node). Verify case statement assigns PROJECT_TYPE correctly. Add debug: echo IS_PROJECT_ROOT=$IS_PROJECT_ROOT PROJECT_TYPE=$PROJECT_TYPE to output.
Loading reviews...