#!/usr/bin/env bash # Collect project structure for /explore analysis. # Usage: Run from project root, or pass project path as argument. # Output: Structured text with directory tree, file counts, language distribution. set -euo pipefail PROJECT_DIR="${1:-.}" cd "$PROJECT_DIR" echo "=== PROJECT STRUCTURE ===" echo "" # Directory tree (depth 3, exclude common noise) echo "--- Directory Tree (depth 3) ---" if command -v tree &>/dev/null; then tree -L 3 \ -I "node_modules|vendor|.git|dist|build|out|.venv|__pycache__|*.egg-info|coverage|.nyc_output" \ --dirsfirst elif command -v find &>/dev/null; then find . -maxdepth 3 \ -not -path "./.git/*" \ -not -path "./node_modules/*" \ -not -path "./vendor/*" \ -not -path "./dist/*" \ -not -path "./build/*" \ -not -path "./out/*" \ -not -path "./.venv/*" \ -not -path "*/__pycache__/*" \ -not -path "*/.egg-info/*" \ -not -path "*/coverage/*" \ -not -path "./.nyc_output/*" \ -print | head -100 | sort fi echo "" echo "=== FILE COUNTS ===" echo "" # Count files by extension (top 10) echo "--- Top 10 File Types ---" find . -type f \ -not -path "./.git/*" \ -not -path "./node_modules/*" \ -not -path "./vendor/*" \ -not -path "./dist/*" \ -not -path "./build/*" \ -not -path "./out/*" \ -not -path "./.venv/*" \ -not -path "*/__pycache__/*" \ -printf '%f\n' | \ sed 's/.*\.//' | \ grep -v '^\.[^/]*$' | \ sort | uniq -c | sort -rn | head -10 echo "" echo "=== TOTAL FILE COUNT ===" echo "" # Total files (excluding noise) total=$(find . -type f \ -not -path "./.git/*" \ -not -path "./node_modules/*" \ -not -path "./vendor/*" \ -not -path "./dist/*" \ -not -path "./build/*" \ -not -path "./out/*" \ -not -path "./.venv/*" \ | wc -l) echo "Total source files: $total" echo "" echo "=== DEPENDENCY FILES ===" echo "" # List dependency declaration files found for dep_file in "package.json" "requirements.txt" "pyproject.toml" "setup.py" "go.mod" "go.sum" "Cargo.toml" "Cargo.lock" "pom.xml" "build.gradle" "Gemfile" "Gemfile.lock" "composer.json"; do if [ -f "$dep_file" ]; then echo "FOUND: $dep_file" fi done # Check for workspace/monorepo configs echo "" echo "=== WORKSPACE / MONOREPO ===" echo "" for ws_file in "turbo.json" "nx.json" "lerna.json" "pnpm-workspace.yaml" "go.work"; do if [ -f "$ws_file" ]; then echo "FOUND: $ws_file" fi done # Check Cargo.toml for workspace if [ -f "Cargo.toml" ] && grep -q '\[workspace\]' Cargo.toml 2>/dev/null; then echo "FOUND: Cargo.toml [workspace]" fi echo "" echo "=== ENTRY POINTS ===" echo "" # Try to identify entry points if [ -f "package.json" ]; then main=$(node -e "try{const p=require('./package.json');console.log(p.main||'');}catch(e){}" 2>/dev/null || echo "") bin=$(node -e "try{const p=require('./package.json');console.log(typeof p.bin==='string'?p.bin:JSON.stringify(p.bin));}catch(e){}" 2>/dev/null || echo "") dev=$(node -e "try{const p=require('./package.json');console.log(p.scripts?.dev||p.scripts?.start||'');}catch(e){}" 2>/dev/null || echo "") [ -n "$main" ] && echo "package.json main: $main" [ -n "$bin" ] && echo "package.json bin: $bin" [ -n "$dev" ] && echo "package.json dev/start: $dev" fi for entry in "src/main.ts" "src/main.tsx" "src/main.js" "src/main.jsx" "src/index.ts" "src/index.js" "src/main.py" "app/main.py" "main.go" "src/main.rs" "app.py" "index.js" "index.ts"; do if [ -f "$entry" ]; then echo "FOUND: $entry" fi done echo "" echo "=== COLLECTED ==="