Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
This commit is contained in:
153
demo/tools/discovery/discover-env.sh
Executable file
153
demo/tools/discovery/discover-env.sh
Executable file
@@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# DSS - Environment Variable Analysis
|
||||
# Checks environment configuration (names only, no values)
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_PATH="${1:-.}"
|
||||
|
||||
# Common env vars that should be set
|
||||
REQUIRED_VARS=(
|
||||
"NODE_ENV"
|
||||
"PORT"
|
||||
)
|
||||
|
||||
# Optional but recommended
|
||||
RECOMMENDED_VARS=(
|
||||
"LOG_LEVEL"
|
||||
"DATABASE_URL"
|
||||
"API_URL"
|
||||
)
|
||||
|
||||
# Sensitive vars that should NOT be in code
|
||||
SENSITIVE_PATTERNS=(
|
||||
"API_KEY"
|
||||
"SECRET"
|
||||
"PASSWORD"
|
||||
"TOKEN"
|
||||
"PRIVATE"
|
||||
"AWS_"
|
||||
"FIGMA_TOKEN"
|
||||
)
|
||||
|
||||
# Find env files
|
||||
find_env_files() {
|
||||
local files=()
|
||||
|
||||
for pattern in ".env" ".env.local" ".env.development" ".env.production" ".env.example"; do
|
||||
if [[ -f "$PROJECT_PATH/$pattern" ]]; then
|
||||
local var_count=$(grep -cE "^[A-Z_]+=" "$PROJECT_PATH/$pattern" 2>/dev/null || echo 0)
|
||||
local has_values="false"
|
||||
|
||||
# Check if file has actual values (not just placeholders)
|
||||
if grep -qE "^[A-Z_]+=.+" "$PROJECT_PATH/$pattern" 2>/dev/null; then
|
||||
if ! grep -qE "^[A-Z_]+=(your_|<|placeholder)" "$PROJECT_PATH/$pattern" 2>/dev/null; then
|
||||
has_values="true"
|
||||
fi
|
||||
fi
|
||||
|
||||
files+=("{\"file\":\"$pattern\",\"variables\":$var_count,\"has_real_values\":$has_values}")
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${files[@]}"
|
||||
}
|
||||
|
||||
# Get var names from env files (not values)
|
||||
get_env_var_names() {
|
||||
local vars=()
|
||||
|
||||
for file in "$PROJECT_PATH/.env"* 2>/dev/null; do
|
||||
if [[ -f "$file" ]]; then
|
||||
while IFS= read -r varname; do
|
||||
if [[ -n "$varname" && ! " ${vars[*]} " =~ " $varname " ]]; then
|
||||
vars+=("\"$varname\"")
|
||||
fi
|
||||
done < <(grep -oE "^[A-Z_][A-Z0-9_]*" "$file" 2>/dev/null)
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${vars[@]}"
|
||||
}
|
||||
|
||||
# Check for hardcoded sensitive vars in code
|
||||
check_hardcoded_secrets() {
|
||||
local findings=()
|
||||
|
||||
for pattern in "${SENSITIVE_PATTERNS[@]}"; do
|
||||
local found=$(grep -rEl "${pattern}.*=.*['\"][^'\"]+['\"]" "$PROJECT_PATH" \
|
||||
--include="*.js" --include="*.ts" --include="*.py" \
|
||||
! -path "*/node_modules/*" ! -path "*/.git/*" \
|
||||
2>/dev/null | head -5)
|
||||
|
||||
if [[ -n "$found" ]]; then
|
||||
while IFS= read -r file; do
|
||||
if [[ -n "$file" ]]; then
|
||||
findings+=("{\"file\":\"${file#$PROJECT_PATH/}\",\"pattern\":\"$pattern\"}")
|
||||
fi
|
||||
done <<< "$found"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${findings[@]}"
|
||||
}
|
||||
|
||||
# Check current environment
|
||||
check_current_env() {
|
||||
local status=()
|
||||
|
||||
for var in "${REQUIRED_VARS[@]}"; do
|
||||
if [[ -n "${!var}" ]]; then
|
||||
status+=("{\"var\":\"$var\",\"status\":\"set\"}")
|
||||
else
|
||||
status+=("{\"var\":\"$var\",\"status\":\"missing\"}")
|
||||
fi
|
||||
done
|
||||
|
||||
for var in "${RECOMMENDED_VARS[@]}"; do
|
||||
if [[ -n "${!var}" ]]; then
|
||||
status+=("{\"var\":\"$var\",\"status\":\"set\",\"required\":false}")
|
||||
fi
|
||||
done
|
||||
|
||||
echo "${status[@]}"
|
||||
}
|
||||
|
||||
# Build output
|
||||
env_files=$(find_env_files)
|
||||
var_names=$(get_env_var_names)
|
||||
hardcoded=$(check_hardcoded_secrets)
|
||||
current_env=$(check_current_env)
|
||||
|
||||
files_json=$(IFS=,; echo "${env_files[*]}")
|
||||
names_json=$(IFS=,; echo "${var_names[*]}")
|
||||
hardcoded_json=$(IFS=,; echo "${hardcoded[*]}")
|
||||
current_json=$(IFS=,; echo "${current_env[*]}")
|
||||
|
||||
# Calculate readiness score
|
||||
total_files=${#env_files[@]}
|
||||
hardcoded_count=${#hardcoded[@]}
|
||||
readiness="ready"
|
||||
[[ $total_files -eq 0 ]] && readiness="missing_config"
|
||||
[[ $hardcoded_count -gt 0 ]] && readiness="has_hardcoded_secrets"
|
||||
|
||||
cat <<EOF
|
||||
{
|
||||
"scan_type": "environment",
|
||||
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"project_path": "$PROJECT_PATH",
|
||||
"readiness": "$readiness",
|
||||
"env_files": [${files_json:-}],
|
||||
"variables_defined": [${names_json:-}],
|
||||
"current_environment": [${current_json:-}],
|
||||
"hardcoded_secrets": [${hardcoded_json:-}],
|
||||
"recommendations": [
|
||||
"Use .env.example for template (no real values)",
|
||||
"Add .env* to .gitignore",
|
||||
"Use environment variables for all secrets",
|
||||
"Consider using a secrets manager for production"
|
||||
]
|
||||
}
|
||||
EOF
|
||||
Reference in New Issue
Block a user