#!/bin/bash set -e # 1. Move to the builder root cd ~/website-builder echo "📁 Working in: $(pwd)" # 2. Create validator.ts if missing if [ ! -f "lib/validator.ts" ]; then echo "📝 Creating lib/validator.ts..." cat > lib/validator.ts << 'VALIDATOR_EOF' import { spawn } from "child_process"; import fs from "fs"; import path from "path"; export interface ValidationResult { success: boolean; installLog: string; buildLog: string; error?: string; duration: number; } function runCommand( cmd: string, args: string[], cwd: string, timeout: number = 300000 ): Promise<{ stdout: string; stderr: string; code: number | null }> { return new Promise((resolve) => { const child = spawn(cmd, args, { cwd, shell: true }); let stdout = "", stderr = ""; child.stdout.on("data", (d) => { stdout += d.toString(); }); child.stderr.on("data", (d) => { stderr += d.toString(); }); const timer = setTimeout(() => { child.kill("SIGTERM"); resolve({ stdout, stderr: stderr + "\n[ERROR] Timed out", code: null }); }, timeout); child.on("close", (code) => { clearTimeout(timer); resolve({ stdout, stderr, code }); }); child.on("error", (err) => { clearTimeout(timer); resolve({ stdout, stderr: stderr + "\n" + err.message, code: null }); }); }); } export async function validateProject( projectDir: string, options: { installTimeout?: number; buildTimeout?: number } = {} ): Promise { const start = Date.now(); const installTimeout = options.installTimeout || 300000; const buildTimeout = options.buildTimeout || 300000; if (!fs.existsSync(projectDir)) { return { success: false, installLog: "", buildLog: "", error: `Directory not found: ${projectDir}`, duration: 0 }; } const pkgPath = path.join(projectDir, "package.json"); if (!fs.existsSync(pkgPath)) { return { success: false, installLog: "", buildLog: "", error: "No package.json", duration: 0 }; } const installResult = await runCommand("npm", ["install", "--no-audit", "--no-fund", "--loglevel=error"], projectDir, installTimeout); const installLog = installResult.stdout + "\n" + installResult.stderr; if (installResult.code !== 0 && installResult.code !== null) { return { success: false, installLog, buildLog: "", error: `npm install failed with code ${installResult.code}`, duration: Date.now() - start }; } const buildResult = await runCommand("npm", ["run", "build"], projectDir, buildTimeout); const buildLog = buildResult.stdout + "\n" + buildResult.stderr; if (buildResult.code !== 0 && buildResult.code !== null) { return { success: false, installLog, buildLog, error: `npm run build failed with code ${buildResult.code}`, duration: Date.now() - start }; } return { success: true, installLog, buildLog, duration: Date.now() - start }; } export async function validateAndSave( projectDir: string, options?: { installTimeout?: number; buildTimeout?: number } ): Promise { const result = await validateProject(projectDir, options); const reportPath = path.join(projectDir, ".validation.json"); fs.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8"); return result; } VALIDATOR_EOF echo "✅ validator.ts created" else echo "✅ validator.ts already exists" fi # 3. Add import to server.ts if missing if ! grep -q 'import { validateAndSave } from "./lib/validator"' server.ts; then echo "📝 Adding import to server.ts..." # Insert after the last import line sed -i '/^import /a import { validateAndSave } from "./lib/validator";' server.ts echo "✅ Import added" else echo "✅ Import already present" fi # 4. Add validation block if missing if ! grep -q 'validateAndSave(projectDir)' server.ts; then echo "📝 Adding validation block after writeProject..." # Insert after writeProject(projectDir, files); line sed -i '/writeProject(projectDir, files);/a \ // Validate the project (install + build)\n\ const validation = await validateAndSave(projectDir);\n\ if (!validation.success) {\n\ console.error(`[build] Validation failed:\\n${validation.error}`);\n\ }' server.ts echo "✅ Validation block added" else echo "✅ Validation block already present" fi # 5. Restart the API echo "🔄 Restarting API..." pm2 restart crawl-api # 6. Wait a moment for the API to come up sleep 2 # 7. Test a new generation echo "🚀 Testing a new generation..." response=$(curl -s -X POST http://localhost:8092/build \ -H "Authorization: Bearer d3v-crawl-server-key-2026" \ -H "Content-Type: application/json" \ -d '{"prompt":"create a premium SaaS landing page for a cloud storage product with features and pricing pages","reference":"https://dropbox.com"}') echo "$response" | python3 -c "import sys,json; d=json.load(sys.stdin); print('✅ Project directory:', d['projectDir'])" 2>/dev/null || { echo "❌ API returned an error. Checking logs..." pm2 logs crawl-api --lines 20 } # 8. Show validation report for the latest project latest_project=$(ls -td ~/website-builder/generated_projects/*/ 2>/dev/null | head -1) if [ -n "$latest_project" ] && [ -f "$latest_project/.validation.json" ]; then echo "📊 Validation report for latest project:" cat "$latest_project/.validation.json" | python3 -m json.tool else echo "⚠️ No validation report found (maybe generation failed)." fi echo "✅ Done."