"use client"; import { useEffect, useState } from "react"; import { useUser } from "@/hooks/useUser"; import { useAi } from "@/hooks/useAi"; import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; import { toast } from "sonner"; import { NEW_STACKS, NewStackId } from "@/lib/new-stacks"; function buildInstruction(stack: NewStackId, lang: "js" | "ts", title?: string) { const jsOrTs = lang === 'ts' ? 'TypeScript' : 'JavaScript'; const reactEntry = lang === 'ts' ? "/frontend/src/main.tsx and /frontend/src/App.tsx" : "/frontend/src/main.jsx and /frontend/src/App.jsx"; switch (stack) { case 'express-react': return `Initialize a complete full-stack web project with the following structure and runnable code. Title: ${title || 'OmniDev Full-Stack App'} Requirements: - Frontend under /frontend using React + Vite (${jsOrTs}), TailwindCSS preconfigured. - Backend under /backend using Express (${jsOrTs}, ESM), with basic routes (GET /, GET /health) and CORS enabled. - Create a visually striking Hero section (animated) appropriate to the app, optimized and accessible. - Add a minimal README.md at root with start instructions. - Provide package.json in both /frontend and /backend with scripts to start dev/prod. - Provide /frontend/index.html and ${reactEntry}. - Provide /backend/server.${lang === 'ts' ? 'ts' : 'js'}. - Use ports 5173 for frontend and 3000 for backend. - Keep everything simple and runnable. - Return STRICT JSON ONLY as file updates (no markdown), paths rooted from repo (e.g., /frontend/..., /backend/...).`; case 'nextjs': return `Scaffold a full-stack Next.js 15 App Router project. Title: ${title || 'OmniDev Next App'} Requirements: - Next.js (${jsOrTs}), App Router, TailwindCSS. - Implement a landing page with an animated Hero section suitable for the domain. - Add /api/health route that returns { ok: true }. - Provide package.json with dev/build scripts. - Keep it simple and runnable with \'next dev\'. - Return STRICT JSON ONLY as file updates (no markdown), paths rooted from repo (e.g., /app/page.${lang === 'ts' ? 'tsx' : 'jsx'}, /app/api/health/route.${lang === 'ts' ? 'ts' : 'js'}).`; case 'nestjs-react': return `Initialize a NestJS backend and React (Vite) frontend. Title: ${title || 'OmniDev Nest + React'} Requirements: - Backend under /backend using NestJS (${jsOrTs}). Generate AppModule, AppController with GET / and GET /health. Enable CORS. - Frontend under /frontend using React + Vite (${jsOrTs}), TailwindCSS with a modern animated Hero section appropriate to the app. - Provide package.json in both apps with start/build scripts. - Return STRICT JSON ONLY as file updates (no markdown), paths rooted from repo.`; } } export default function ScaffoldNew() { const { user, openLoginWindow } = useUser(); const { model, provider } = useAi(); const router = useRouter(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [logs, setLogs] = useState([]); const [stack, setStack] = useState("express-react"); const [lang, setLang] = useState<"js" | "ts">("js"); const [title, setTitle] = useState(""); async function runScaffold() { if (!user) { await openLoginWindow(); return; } setLoading(true); setError(null); setLogs(["Starting scaffold via Augment..."]); try { // 1) Call augment to generate full-stack files const instruction = buildInstruction(stack, lang, title); const aug = await fetch('/api/augment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ context: '/ (empty project)', instruction, language: lang === 'ts' ? 'typescript' : 'javascript', framework: stack, response_type: 'file_updates', // Force Gemini for scaffold stage model: 'gemini-2.5-flash', provider: 'google', }), }).then(r => r.json()); if (!aug?.ok || !Array.isArray(aug.files) || aug.files.length === 0) { throw new Error(aug?.message || 'Augment did not return files'); } setLogs(prev => [...prev, `Augment produced ${aug.files.length} files`]); // 2) Create space with initial files const created = await fetch('/api/me/projects', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: title || 'OmniDev Project', initialFiles: aug.files.map((f: any) => ({ path: f.path, content: f.content })) }) }).then(r => r.json()); if (!created?.space?.project?.space_id) { throw new Error(created?.error || 'Failed to create project'); } setLogs(prev => [...prev, 'Project created, redirecting...']); router.push(`/${created.space.project.space_id}`); } catch (e: any) { setError(e?.message || 'Scaffold failed'); toast.error(e?.message || 'Scaffold failed'); } finally { setLoading(false); } } // Removed auto-run; wait for user selection return (

Create New Project

Choose your stack and hero style, then OmniDev will scaffold a complete project.

setTitle(e.target.value)} />

{NEW_STACKS.find(s => s.id === stack)?.description}

{/* Hero selection removed: AI decides the best hero automatically */}
{error &&

{error}

}
    {logs.map((l, i) => (
  • • {l}
  • ))}
); }