diff --git a/components/AIAssist.tsx b/components/AIAssist.tsx index e572250..402cb21 100644 --- a/components/AIAssist.tsx +++ b/components/AIAssist.tsx @@ -55,23 +55,75 @@ const LiveCanvas = memo(({ data, type, isStreaming }: { data: string, type: stri const trimmed = normalized.trim(); const isFullDocument = /^]/i.test(normalized); + const isReactLike = normalized.includes("import React") || normalized.includes("useState") || normalized.includes("useEffect") || /<[A-Z][\s\S]*>/.test(normalized); let doc: string; if (isFullDocument) { - // If it's a full document, inject Tailwind CSS but keep the structure + // ... same as before but add React support if needed ... + const reactScripts = isReactLike ? ` + + + + ` : ""; + if (hasHeadTag) { doc = normalized.replace(//i, ` + ${reactScripts} `); } else { doc = normalized.replace(/]*>/i, (match) => `${match} + ${reactScripts} `); } + } else if (isReactLike) { + // Specialized React Runner for fragments/components + const cleanedCode = normalized + .replace(/import\s+(?:React\s*,\s*)?{?([\s\S]*?)}?\s+from\s+['"]react['"];?/g, "const { $1 } = React;") + .replace(/import\s+React\s+from\s+['"]react['"];?/g, "/* React already global */") + .replace(/import\s+[\s\S]*?from\s+['"]lucide-react['"];?/g, "const { ...lucide } = window.lucide || {};") + .replace(/export\s+default\s+/g, "const MainComponent = "); + + // Try to find the component name to render + const componentMatch = cleanedCode.match(/const\s+([A-Z]\w+)\s*=\s*\(\)\s*=>/); + const mainComponent = componentMatch ? componentMatch[1] : (cleanedCode.includes("MainComponent") ? "MainComponent" : null); + + doc = ` + + + + + + + + + + + + + +
+ + + + `; } else { // Wrap fragments in a styled container doc = ` @@ -206,13 +258,16 @@ function parseStreamingContent(text: string, currentAgent: string) { .trim(); if (!preview) { - const fenced = text.match(/```(html|css|javascript|tsx|jsx|md|markdown)\s*([\s\S]*?)```/i); + const fenced = text.match(/```(html|css|javascript|typescript|tsx|jsx|md|markdown)\s*([\s\S]*?)```/i); if (fenced) { const language = fenced[1].toLowerCase(); + const data = fenced[2].trim(); + const isReactLike = data.includes("import React") || data.includes("useState") || /<[A-Z][\s\S]*>/.test(data); + preview = { - type: language === "html" ? "web" : "code", + type: (language === "html" || isReactLike) ? "app" : "code", language, - data: fenced[2].trim(), + data, isStreaming: false }; } @@ -391,6 +446,7 @@ export default function AIAssist() { setPreviewData(preview); lastParsedPreview = preview; setShowCanvas(true); + if (isPreviewRenderable(preview)) setViewMode("preview"); } if (agent !== currentAgent) setCurrentAgent(agent); diff --git a/lib/services/ollama-cloud.ts b/lib/services/ollama-cloud.ts index 400706d..fdf53f4 100644 --- a/lib/services/ollama-cloud.ts +++ b/lib/services/ollama-cloud.ts @@ -751,8 +751,8 @@ AGENTS & CAPABILITIES: - pm: Project Manager. Create PRDs, timelines, and action plans. - code: Software Architect. Provide logic, algorithms, and backend snippets. - design: UI/UX Designer. Create high-fidelity mockups and components. -- web: Frontend Developer. Build responsive sites using HTML/Tailwind. -- app: Mobile App Developer. Create mobile-first interfaces and dashboards. +- web: Frontend Developer. Build responsive sites using HTML/Tailwind or React. Use [PREVIEW:web:html] or [PREVIEW:web:javascript]. +- app: Mobile App Developer. Create mobile-first interfaces and dashboards. React components are supported and rendered live. Use [PREVIEW:app:javascript]. ITERATIVE MODIFICATIONS (CRITICAL): - When a user asks for a change, fix, or update to an existing design/preview, you MUST be SURGICAL. diff --git a/lib/services/qwen-oauth.ts b/lib/services/qwen-oauth.ts index dcc4c68..03eb4af 100644 --- a/lib/services/qwen-oauth.ts +++ b/lib/services/qwen-oauth.ts @@ -1025,8 +1025,8 @@ AGENTS & CAPABILITIES: - pm: Project Manager. Create PRDs, timelines, and action plans. - code: Software Architect. Provide logic, algorithms, and backend snippets. - design: UI/UX Designer. Create high-fidelity mockups and components. -- web: Frontend Developer. Build responsive sites using HTML/Tailwind. -- app: Mobile App Developer. Create mobile-first interfaces and dashboards. +- web: Frontend Developer. Build responsive sites using HTML/Tailwind or React. Use [PREVIEW:web:html] or [PREVIEW:web:javascript]. +- app: Mobile App Developer. Create mobile-first interfaces and dashboards. React components are supported and rendered live. Use [PREVIEW:app:javascript]. ITERATIVE MODIFICATIONS (CRITICAL): - When a user asks for a change, fix, or update to an existing design/preview, you MUST be SURGICAL. diff --git a/lib/services/zai-plan.ts b/lib/services/zai-plan.ts index 4ab664c..a351112 100644 --- a/lib/services/zai-plan.ts +++ b/lib/services/zai-plan.ts @@ -824,8 +824,8 @@ AGENTS & CAPABILITIES: - pm: Project Manager. Create PRDs, timelines, and action plans. - code: Software Architect. Provide logic, algorithms, and backend snippets. - design: UI/UX Designer. Create high-fidelity mockups and components. -- web: Frontend Developer. Build responsive sites using HTML/Tailwind. -- app: Mobile App Developer. Create mobile-first interfaces and dashboards. +- web: Frontend Developer. Build responsive sites using HTML/Tailwind or React. Use [PREVIEW:web:html] or [PREVIEW:web:javascript]. +- app: Mobile App Developer. Create mobile-first interfaces and dashboards. React components are supported and rendered live. Use [PREVIEW:app:javascript]. ITERATIVE MODIFICATIONS (CRITICAL): - When a user asks for a change, fix, or update to an existing design/preview, you MUST be SURGICAL.