-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·346 lines (303 loc) · 11.6 KB
/
setup.sh
File metadata and controls
executable file
·346 lines (303 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#!/bin/bash
# setup.sh
set -e
# Get script directory for reliable path handling
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "=== Vibe Coding Iterator Setup ==="
echo
# Function to sanitize project name for conda environment
sanitize_project_name() {
local name="$1"
# Convert to lowercase, replace spaces and special chars with hyphens, remove leading/trailing hyphens
echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/^-\+//' | sed 's/-\+$//'
}
# Function to check if conda environment exists
conda_env_exists() {
local env_name="$1"
conda env list | grep -q "^$env_name "
}
# Function to check if conda environment has all required packages
check_env_packages() {
local env_name="$1"
local requirements_file="$2"
# Activate environment temporarily to check packages
eval "$(conda shell.bash hook)"
conda activate "$env_name" 2>/dev/null || return 1
# Use importlib.metadata to check by distribution name (handles hyphens)
while IFS= read -r line; do
[[ "$line" =~ ^[[:space:]]*# ]] && continue
[[ -z "${line// }" ]] && continue
local dist_name=$(echo "$line" | sed 's/[<>=!].*//' | tr -d ' ')
if [[ -n "$dist_name" ]]; then
python - "$dist_name" <<'PY' 2>/dev/null
import sys
from importlib.metadata import version
dist = sys.argv[1]
try:
version(dist)
except Exception:
raise SystemExit(1)
PY
if [[ $? -ne 0 ]]; then
conda deactivate 2>/dev/null || true
return 1
fi
fi
done < "$requirements_file"
conda deactivate 2>/dev/null || true
return 0
}
# Function to create and setup conda environment
setup_conda_env() {
local env_name="$1"
local requirements_file="$2"
echo "Creating conda environment: $env_name"
conda create -n "$env_name" python=3.11 -y
echo "Installing Python packages..."
eval "$(conda shell.bash hook)"
conda activate "$env_name"
pip install -r "$requirements_file"
# Install Playwright browsers if playwright is present
if python -c "import importlib.util, sys; sys.exit(0 if importlib.util.find_spec('playwright') else 1)"; then
echo "Installing Playwright browsers..."
python -m playwright install || true
fi
# Ensure runtime storage directory exists
mkdir -p "$SCRIPT_DIR/storage"
conda deactivate
echo "✓ Conda environment setup completed"
}
# Get project name from user
echo "=== Project Configuration ==="
read -p "Enter your vibe project name: " project_name
if [[ -z "$project_name" ]]; then
echo "✗ Project name cannot be empty"
exit 1
fi
# Sanitize project name
sanitized_name=$(sanitize_project_name "$project_name")
if [[ "$sanitized_name" != "$project_name" ]]; then
echo "Project name sanitized: '$project_name' → '$sanitized_name'"
fi
# Check if conda is available
if ! command -v conda >/dev/null 2>&1; then
echo "✗ conda is not installed or not in PATH"
echo "Please install Anaconda or Miniconda first:"
echo " https://docs.conda.io/en/latest/miniconda.html"
exit 1
fi
# Check if conda environment exists and has required packages
if conda_env_exists "$sanitized_name"; then
echo "✓ Conda environment '$sanitized_name' already exists"
if check_env_packages "$sanitized_name" "$SCRIPT_DIR/requirements.txt"; then
echo "✓ Environment has all required packages"
echo "✓ Conda environment is ready to use"
else
echo "⚠ Environment is missing some required packages"
read -p "Recreate the environment? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Removing existing environment..."
conda env remove -n "$sanitized_name" -y
setup_conda_env "$sanitized_name" "$SCRIPT_DIR/requirements.txt"
else
echo "Please manually install missing packages or recreate the environment"
exit 1
fi
fi
else
echo "Creating new conda environment: $sanitized_name"
setup_conda_env "$sanitized_name" "$SCRIPT_DIR/requirements.txt"
fi
# Activate the conda environment
echo
echo "=== Activating Conda Environment ==="
eval "$(conda shell.bash hook)"
if [[ -n "$CONDA_DEFAULT_ENV" && "$CONDA_DEFAULT_ENV" != "$sanitized_name" ]]; then
conda deactivate || true
fi
conda activate "$sanitized_name"
echo "✓ Conda environment '$sanitized_name' is now active"
# Setup OpenRouter configuration
echo
echo "=== OpenRouter Configuration ==="
echo "This project uses OpenRouter API for AI model access."
echo
# Check if .env file exists and validate required variables
ENV_FILE="$SCRIPT_DIR/.env"
CONFIGURE_OPENROUTER=false
if [[ -f "$ENV_FILE" ]]; then
echo "✓ Found existing .env file"
# Ask whether to reuse or create new
while true; do
read -p "Reuse existing .env? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
REUSE_ENV=true
break
elif [[ $REPLY =~ ^[Nn]$ || -z "$REPLY" ]]; then
REUSE_ENV=false
break
else
echo "Please answer y or n."
fi
done
if [[ "$REUSE_ENV" == true ]]; then
# Check if all required environment variables are defined
MISSING_VARS=()
if ! grep -q "^VIBES_API_KEY=" "$ENV_FILE"; then
MISSING_VARS+=("VIBES_API_KEY")
fi
if ! grep -q "^VIBES_VISION_MODEL=" "$ENV_FILE"; then
MISSING_VARS+=("VIBES_VISION_MODEL")
fi
if ! grep -q "^VIBES_CODE_MODEL=" "$ENV_FILE"; then
MISSING_VARS+=("VIBES_CODE_MODEL")
fi
if [[ ${#MISSING_VARS[@]} -eq 0 ]]; then
echo "✓ All required environment variables are configured"
echo "Current OpenRouter configuration:"
echo " API Key: $(grep "^VIBES_API_KEY=" "$ENV_FILE" | cut -d'=' -f2 | sed 's/.*/***/g')"
echo " Vision Model: $(grep "^VIBES_VISION_MODEL=" "$ENV_FILE" | cut -d'=' -f2)"
echo " Code Model: $(grep "^VIBES_CODE_MODEL=" "$ENV_FILE" | cut -d'=' -f2)"
echo "Configuration looks complete."
# Ensure VIBES_APP_NAME is present and up to date with sanitized project name
if grep -q "^VIBES_APP_NAME=" "$ENV_FILE"; then
tmpfile=$(mktemp)
sed "s/^VIBES_APP_NAME=.*/VIBES_APP_NAME=$sanitized_name/" "$ENV_FILE" > "$tmpfile" && mv "$tmpfile" "$ENV_FILE"
else
echo "VIBES_APP_NAME=$sanitized_name" >> "$ENV_FILE"
fi
else
echo "⚠ Missing required environment variables: ${MISSING_VARS[*]}"
echo "The .env file needs to be recreated to include all required variables."
read -p "Recreate .env file? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
CONFIGURE_OPENROUTER=true
else
echo "✗ Cannot continue without complete OpenRouter configuration"
exit 1
fi
fi
else
echo "Will create a new .env"
CONFIGURE_OPENROUTER=true
fi
else
echo "No .env found yet — let's configure OpenRouter now."
CONFIGURE_OPENROUTER=true
fi
if [[ "$CONFIGURE_OPENROUTER" == true ]]; then
# Suggested default models (open source, low cost, solid capabilities)
DEFAULT_VISION_MODEL="meta-llama/llama-3.2-90b-vision-instruct"
DEFAULT_CODE_MODEL="z-ai/glm-4.5-air"
echo "Enter your OpenRouter API key:"
echo "(Get one from: https://openrouter.ai/settings/keys)"
echo "Note: input is hidden for security; type and press Enter."
# Validate API key immediately; re-prompt until it passes
BASE_URL_VALIDATE="https://openrouter.ai/api/v1"
while true; do
read -p "API Key: " -s api_key
echo
if [[ -z "$api_key" ]]; then
echo "✗ API key cannot be empty"
continue
fi
code=$(curl -sS -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $api_key" "$BASE_URL_VALIDATE/models")
if [[ "$code" == "200" ]]; then
echo "✓ API key accepted"
break
else
echo "✗ API key was not accepted (HTTP $code). Please try again."
fi
done
echo "Enter the OpenRouter model slug for vision tasks:"
echo "(Default: $DEFAULT_VISION_MODEL)"
read -p "Vision Model [$DEFAULT_VISION_MODEL]: " vision_model
vision_model=${vision_model:-$DEFAULT_VISION_MODEL}
echo "Enter the OpenRouter model slug for code generation:"
echo "(Default: $DEFAULT_CODE_MODEL)"
read -p "Code Model [$DEFAULT_CODE_MODEL]: " code_model
code_model=${code_model:-$DEFAULT_CODE_MODEL}
# Create or update .env file
{
echo "# Vibe Coding Iterator - OpenRouter Configuration"
echo "# Generated on $(date)"
echo ""
echo "# OpenRouter base URL"
echo "OPENROUTER_BASE_URL=https://openrouter.ai/api/v1"
echo ""
echo "# OpenRouter API key - get from https://openrouter.ai/settings/keys"
echo "VIBES_API_KEY=$api_key"
echo ""
echo "# Vision model for screenshot analysis"
echo "VIBES_VISION_MODEL=$vision_model"
echo ""
echo "# Code generation model"
echo "VIBES_CODE_MODEL=$code_model"
echo ""
echo "# App name used for attribution headers (required)"
echo "VIBES_APP_NAME=$sanitized_name"
} > "$ENV_FILE"
echo "✓ OpenRouter configuration saved to .env"
fi
echo
echo "=== Setup Complete ==="
echo "✓ Conda environment '$sanitized_name' is active"
echo "✓ Python dependencies are installed"
echo "✓ OpenRouter API configuration is ready"
echo
echo "Your environment variables:"
echo "- VIBES_API_KEY: Configured"
if [[ -f "$ENV_FILE" ]]; then
echo "- VIBES_VISION_MODEL: $(grep "VIBES_VISION_MODEL=" "$ENV_FILE" | cut -d'=' -f2)"
echo "- VIBES_CODE_MODEL: $(grep "VIBES_CODE_MODEL=" "$ENV_FILE" | cut -d'=' -f2)"
echo "- VIBES_APP_NAME: $(grep "^VIBES_APP_NAME=" "$ENV_FILE" | cut -d'=' -f2)"
else
echo "- VIBES_VISION_MODEL: (not configured)"
echo "- VIBES_CODE_MODEL: (not configured)"
echo "- VIBES_APP_NAME: $sanitized_name"
fi
echo
echo "=== Integration Test ==="
# Validate OpenRouter API access without consuming credits by listing models
OR_BASE_URL="${OPENROUTER_BASE_URL:-https://openrouter.ai/api/v1}"
OR_API_KEY="$(grep '^VIBES_API_KEY=' "$ENV_FILE" | cut -d'=' -f2)"
if curl -sSf -H "Authorization: Bearer $OR_API_KEY" "$OR_BASE_URL/models" >/dev/null; then
echo "✓ OpenRouter API reachable and API key accepted"
else
echo "✗ Integration test failed: models endpoint unreachable or API key rejected"
echo " - Verify internet connectivity"
echo " - Check VIBES_API_KEY in .env and optional OPENROUTER_BASE_URL"
exit 1
fi
# Query API key details
KEY_URL="$OR_BASE_URL/key"
tmp_json=$(mktemp)
http_code=$(curl -sS -o "$tmp_json" -w "%{http_code}" -H "Authorization: Bearer $OR_API_KEY" "$KEY_URL")
if [[ "$http_code" == "200" ]]; then
echo "✓ API key details (HTTP 200):"
python - "$tmp_json" <<'PY'
import json, sys
path = sys.argv[1]
data = json.load(open(path))
info = data.get("data", {})
label = info.get("label")
limit = info.get("limit")
usage = info.get("usage")
remain = info.get("limit_remaining")
free = info.get("is_free_tier")
prov = info.get("is_provisioning_key")
print(f" - label: {label}")
print(f" - limit: {limit}")
print(f" - usage: {usage}")
print(f" - limit_remaining: {remain}")
print(f" - is_free_tier: {free}")
print(f" - is_provisioning_key: {prov}")
PY
else
echo "✗ API key check failed (HTTP $http_code). Response body:"
cat "$tmp_json"
fi
rm -f "$tmp_json"