website-builde / fix-validation.sh
Daviddolor's picture
Single-process Chromium, fixed visual-polish prompt, Docker config for HF Space
ec675f2
Raw
History Blame Contribute Delete
5.4 kB
#!/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<ValidationResult> {
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<ValidationResult> {
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."