From e9d2ff34bf9ac85e70f72f0996cd55cde6a98ecb Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sat, 17 Jan 2026 14:54:08 +0000 Subject: [PATCH] Generated by Spark: AI button for errors. --- PRD.md | 12 +- spark.meta.json | 7 +- src/ErrorFallback.tsx | 23 ++-- src/components/AIErrorHelper.tsx | 189 +++++++++++++++++++++++++++++++ src/components/ReactPreview.tsx | 7 +- 5 files changed, 223 insertions(+), 15 deletions(-) create mode 100644 src/components/AIErrorHelper.tsx diff --git a/PRD.md b/PRD.md index 9793fb1..c0f8b4e 100644 --- a/PRD.md +++ b/PRD.md @@ -54,6 +54,13 @@ This is a CRUD application with search, filtering, and organization features but - **Progression**: Click copy button → Visual feedback (toast notification) → Paste code elsewhere - **Success criteria**: Code copies exactly as stored, toast confirms action, works across browsers +### AI Error Helper +- **Functionality**: Intelligent error analysis button that appears when errors occur, uses AI to explain errors in plain language and suggest fixes +- **Purpose**: Help developers quickly understand and resolve errors without leaving the app +- **Trigger**: Automatically appears when runtime errors, preview rendering errors, or validation errors occur +- **Progression**: Error occurs → AI helper button appears with pulsing animation → Click button → AI analyzes error context → Display explanation and suggested fixes in dialog +- **Success criteria**: Button appears within 100ms of error, AI provides helpful context-aware explanations, suggestions are actionable and specific to the error type + ## Edge Case Handling - **Empty State**: Show welcoming illustration and "Create your first snippet" CTA when no snippets exist - **Long Code Blocks**: Truncate preview with "Show more" expansion, scroll within card for full view @@ -61,8 +68,9 @@ This is a CRUD application with search, filtering, and organization features but - **Invalid Input**: Require title and code content minimum, show inline validation errors - **Search No Results**: Display "No snippets found" message with suggestion to adjust filters - **Network/Storage Errors**: Graceful error messages with retry options (though KV storage is local) -- **Preview Rendering Errors**: Display detailed error messages when React code fails to compile or render, show warnings for non-React language previews +- **Preview Rendering Errors**: Display detailed error messages when React code fails to compile or render, show warnings for non-React language previews, AI helper button available for error analysis - **Preview Not Available**: Show informative message for snippets without preview enabled or non-React languages +- **AI Error Analysis Failure**: If AI service is unavailable, show graceful fallback message with standard error details ## Design Direction The design should evoke a premium developer tool - clean, focused, and sophisticated with subtle tech-forward aesthetics. Think VS Code meets Notion: professional minimalism with purposeful color accents and smooth micro-interactions that make frequent use satisfying. @@ -106,6 +114,7 @@ Animations should feel responsive and technical - quick, purposeful movements th - AlertDialog for delete confirmations - Checkbox for enabling split-screen preview mode - Alert for displaying preview rendering errors + - Custom AI helper button with sparkle/magic wand icon for error analysis - **Customizations**: - Custom syntax language badges with predefined color mapping (JavaScript=yellow, Python=blue, JSX/TSX=cyan/sky, etc.) @@ -130,6 +139,7 @@ Animations should feel responsive and technical - quick, purposeful movements th - Check (confirmation feedback) - SplitVertical (preview mode indicator and toggle) - WarningCircle (preview errors) + - Sparkles/MagicWand (AI helper for error analysis) - **Spacing**: - Container padding: p-6 (desktop) / p-4 (mobile) diff --git a/spark.meta.json b/spark.meta.json index 27581a1..fd74d91 100644 --- a/spark.meta.json +++ b/spark.meta.json @@ -1,3 +1,4 @@ -{ - "templateVersion": 0, -} +{ + "templateVersion": 0, + "dbType": null +} \ No newline at end of file diff --git a/src/ErrorFallback.tsx b/src/ErrorFallback.tsx index d628fcd..271fd3c 100644 --- a/src/ErrorFallback.tsx +++ b/src/ErrorFallback.tsx @@ -1,11 +1,10 @@ import { Alert, AlertTitle, AlertDescription } from "./components/ui/alert"; import { Button } from "./components/ui/button"; +import { AIErrorHelper } from "./components/AIErrorHelper"; import { AlertTriangleIcon, RefreshCwIcon } from "lucide-react"; export const ErrorFallback = ({ error, resetErrorBoundary }) => { - // When encountering an error in the development mode, rethrow it and don't display the boundary. - // The parent UI will take care of showing a more helpful dialog. if (import.meta.env.DEV) throw error; return ( @@ -26,14 +25,18 @@ export const ErrorFallback = ({ error, resetErrorBoundary }) => { - +
+ + + +
); diff --git a/src/components/AIErrorHelper.tsx b/src/components/AIErrorHelper.tsx new file mode 100644 index 0000000..a1f3c75 --- /dev/null +++ b/src/components/AIErrorHelper.tsx @@ -0,0 +1,189 @@ +import { useState } from 'react' +import { Button } from '@/components/ui/button' +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog' +import { Alert, AlertDescription } from '@/components/ui/alert' +import { Sparkle } from '@phosphor-icons/react' +import { motion, AnimatePresence } from 'framer-motion' + +interface AIErrorHelperProps { + error: Error | string + context?: string + className?: string +} + +export function AIErrorHelper({ error, context, className }: AIErrorHelperProps) { + const [open, setOpen] = useState(false) + const [analysis, setAnalysis] = useState('') + const [isAnalyzing, setIsAnalyzing] = useState(false) + const [analysisError, setAnalysisError] = useState('') + + const errorMessage = typeof error === 'string' ? error : error.message + const errorStack = typeof error === 'string' ? '' : error.stack + + const analyzeError = async () => { + setOpen(true) + setIsAnalyzing(true) + setAnalysisError('') + setAnalysis('') + + try { + const contextInfo = context ? `\n\nContext: ${context}` : '' + const stackInfo = errorStack ? `\n\nStack trace: ${errorStack}` : '' + + const promptText = `You are a helpful debugging assistant for a code snippet manager app. Analyze this error and provide: + +1. A clear explanation of what went wrong (in plain language) +2. Why this error likely occurred +3. 2-3 specific actionable steps to fix it + +Error message: ${errorMessage}${contextInfo}${stackInfo} + +Keep your response concise, friendly, and focused on practical solutions. Format your response with clear sections using markdown.` + + const result = await window.spark.llm(promptText, 'gpt-4o-mini') + setAnalysis(result) + } catch (err) { + setAnalysisError('Unable to analyze error. The AI service may be temporarily unavailable.') + } finally { + setIsAnalyzing(false) + } + } + + return ( + <> + + + + + + + + + + AI Error Analysis + + + Let me help you understand and fix this error + + + +
+ + + {errorMessage} + + + + {isAnalyzing && ( +
+
+ + + + Analyzing error... +
+
+ {[1, 2, 3].map((i) => ( + + ))} +
+
+ )} + + {analysisError && ( + + {analysisError} + + )} + + + {analysis && ( + +
+ {analysis.split('\n').map((line, idx) => { + if (line.startsWith('###')) { + return ( +

+ {line.replace('###', '').trim()} +

+ ) + } + if (line.startsWith('##')) { + return ( +

+ {line.replace('##', '').trim()} +

+ ) + } + if (line.match(/^\d+\./)) { + return ( +
+ {line} +
+ ) + } + if (line.startsWith('-')) { + return ( +
+ {line} +
+ ) + } + if (line.trim()) { + return ( +

+ {line} +

+ ) + } + return null + })} +
+
+ )} +
+
+
+
+ + ) +} + diff --git a/src/components/ReactPreview.tsx b/src/components/ReactPreview.tsx index 2c4d1cd..97985a1 100644 --- a/src/components/ReactPreview.tsx +++ b/src/components/ReactPreview.tsx @@ -2,6 +2,7 @@ import { useEffect, useState, useRef } from 'react' import * as React from 'react' import * as ReactDOM from 'react-dom' import { Alert, AlertDescription } from '@/components/ui/alert' +import { AIErrorHelper } from '@/components/AIErrorHelper' import { WarningCircle } from '@phosphor-icons/react' interface ReactPreviewProps { @@ -77,12 +78,16 @@ export function ReactPreview({ code, language }: ReactPreviewProps) { if (error) { return (
- + {error} +
) }