Conversation
🎨 Major UI/UX Enhancements: - Create completely new EnhancedChatInterface with glass morphism design - Add sophisticated animations using Framer Motion throughout - Implement two-phase layout: hero welcome → split chat interface - Add dynamic gradient backgrounds with animated color-shifting orbs - Enhance all UI components (Button, Input, Textarea) with multiple variants 🤖 AI System Improvements: - Fix missing refetchCustomer function causing runtime errors - Add comprehensive error handling with graceful failure recovery - Implement secure API key management with validation - Add multiple AI provider support (Groq + OpenRouter failsafe) - Include rate limiting and performance optimizations ⚡ E2B Code Execution Integration: - Add full E2B sandbox integration for Python and JavaScript - Implement secure code execution in isolated sandboxes - Add proper error handling for execution failures - Include performance optimizations with sandbox management - Provide clear user feedback during code execution 🛡️ Production-Ready Features: - Add React Error Boundaries with multiple severity levels - Implement global error handler for uncaught errors - Create comprehensive notification system with categorization - Add sophisticated loading states with multiple variants - Include Sentry integration for error reporting 🔧 Technical Improvements: - Establish comprehensive design system with CSS custom properties - Add modular component architecture with clear separation - Implement type-safe code throughout with proper TypeScript - Optimize performance with efficient rendering patterns - Follow modern React patterns with hooks and context This transforms the previously broken chat system into a world-class AI development tool with enterprise-level architecture and UX. - Scout jam: [0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a](https://scout.new/jam/0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a) Co-authored-by: Scout <scout@scout.new>
🛡️ Security Fixes: - Fix SafeText component API usage: change from text prop to children - Remove all API key logging to prevent accidental exposure - Ensure proper sanitization by using correct component API ⚡ Functionality Fixes: - Fix async/await inconsistency in getUserApiKey() calls - Implement proper real-time streaming with updateMessage mutation - Fix import path for sandbox utilities (remove .ts extension) 🧹 Code Cleanup: - Remove unused state variables: showShowcase, showcaseExecutions, previewCode, etc. - Remove unused imports: E2BCodeExecution, ShowcaseExecutionResult type - Clean up dead code and improve maintainability ✅ Technical Improvements: - Add proper error handling for streaming updates - Implement real-time message updates during AI responses - Fix mutation imports and usage patterns - Ensure all promises are properly awaited These fixes address all critical issues identified in the code review, making the application secure and production-ready. - Scout jam: [0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a](https://scout.new/jam/0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a) Co-authored-by: Scout <scout@scout.new>
🛡️ Authentication Fixes: - Add graceful handling for missing Clerk publishable key - Add graceful handling for missing Convex URL - Replace throwing errors with helpful setup instructions - Add beautiful setup screen when authentication is not configured 🎨 User Experience Improvements: - Show helpful setup instructions instead of error screens - Provide step-by-step guide for getting API keys - Add refresh button to retry after configuration - Remove duplicate ConvexProviderWithClerk wrapper ✅ Technical Improvements: - Remove authentication provider duplication in App.tsx - Add mock Convex client for development when URL missing - Add proper console warnings with setup instructions - Ensure app starts without crashing when keys are missing This resolves the authentication errors shown in the browser and provides a much better developer experience for initial setup. - Scout jam: [0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a](https://scout.new/jam/0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a) Co-authored-by: Scout <scout@scout.new>
WalkthroughRefactors app provider hierarchy and protected route wrapping in App.tsx. Adds conditional bootstrap in main.tsx to render a setup UI when Clerk key is missing. Updates Convex client initialization to warn and use a mock URL when VITE_CONVEX_URL is absent. Public routes and outer providers remain intact. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant Main as main.tsx
participant Clerk as ClerkProvider
participant Convex as ConvexProviderWithClerk
participant App as App
Browser->>Main: Start
Main->>Main: Check VITE_CLERK_PUBLISHABLE_KEY
alt Key present
Main->>Clerk: Initialize
Clerk->>Convex: Wrap with Clerk
Convex->>App: Render application
else Key missing
Main->>Browser: Render UnauthenticatedApp (setup UI)
end
sequenceDiagram
participant App
participant AuthWrap as AuthWrapper + UserSync
participant Data as TRPC/Query Providers
participant Router as Router/Routes
participant Guard as AuthGuard
participant Protected as Protected Pages
App->>AuthWrap: Wrap
AuthWrap->>Data: Wrap
Data->>Router: Render routes
Router->>Guard: For /chat, /settings, /success
Guard->>Protected: Render component
sequenceDiagram
participant ConvexCfg as convex.ts
participant Env as process.env
participant Convex as ConvexReactClient
ConvexCfg->>Env: Read VITE_CONVEX_URL
alt URL present
ConvexCfg->>Convex: new ConvexReactClient(real URL)
else URL missing
ConvexCfg->>Convex: new ConvexReactClient(mock URL)
ConvexCfg->>ConvexCfg: console.warn guidance
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…xProvider - Scout jam: [0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a](https://scout.new/jam/0fa5888b-ec59-4025-8e7c-5ae1d6bfb07a) Co-authored-by: Scout <scout@scout.new>
|
Claude finished @otdoges's task —— View job PR Code Review - Enhanced AI Chat GUII've completed a thorough review of the changes in this PR. Here are my findings and recommendations: 🎯 Overall AssessmentThis PR significantly enhances the development experience by providing better error handling, authentication recovery, and a helpful setup UI for new developers. The changes align well with the project's architecture and security requirements. 📋 Code Quality & Best Practices✅ Strengths
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
src/lib/convex.ts (1)
6-10: Gate setup logs to development onlyThese logs are great for DX but can be noisy in production if misconfigured. Wrap them with a DEV check.
Apply this diff:
if (!convexUrl) { - console.warn("⚠️ Missing Convex URL - Database will be disabled"); - console.log("💡 To enable database:"); - console.log(" 1. Get a Convex deployment URL from: https://dashboard.convex.dev"); - console.log(" 2. Add VITE_CONVEX_URL=https://your-app.convex.cloud to .env.local"); - console.log(" 3. Restart the development server"); + if (import.meta.env.DEV) { + console.warn("⚠️ Missing Convex URL - Database will be disabled"); + console.log("💡 To enable database:"); + console.log(" 1. Get a Convex deployment URL from: https://dashboard.convex.dev"); + console.log(" 2. Add VITE_CONVEX_URL=https://your-app.convex.cloud to .env.local"); + console.log(" 3. Restart the development server"); + } }src/main.tsx (2)
83-136: Move UnauthenticatedApp to its own file to fix Fast Refresh warningESLint warns: “Fast refresh only works when a file has exports.” Defining a component inside main.tsx without exporting it triggers this. Extract it to a component file and import it here.
Apply this diff to remove the inline component:
-// Fallback component when authentication is not configured -const UnauthenticatedApp = () => ( - <div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 flex items-center justify-center p-4"> - <div className="max-w-md w-full space-y-6 text-center"> - <div className="space-y-4"> - <div className="w-16 h-16 mx-auto bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center"> - <svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /> - </svg> - </div> - <h1 className="text-3xl font-bold text-white">ZapDev AI Platform</h1> - <p className="text-slate-300 text-lg">Authentication Setup Required</p> - </div> - - <div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-lg p-6 space-y-4 text-left"> - <h2 className="text-xl font-semibold text-white">Quick Setup:</h2> - <div className="space-y-3 text-sm text-slate-300"> - <div className="flex items-start gap-3"> - <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">1</span> - <div> - <p className="text-white font-medium">Get Clerk API Key</p> - <p>Visit <code className="bg-slate-700 px-1 rounded">dashboard.clerk.com</code></p> - </div> - </div> - <div className="flex items-start gap-3"> - <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">2</span> - <div> - <p className="text-white font-medium">Get Convex URL</p> - <p>Visit <code className="bg-slate-700 px-1 rounded">dashboard.convex.dev</code></p> - </div> - </div> - <div className="flex items-start gap-3"> - <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">3</span> - <div> - <p className="text-white font-medium">Update .env.local</p> - <code className="block bg-slate-700 p-2 rounded mt-1 text-xs"> -VITE_CLERK_PUBLISHABLE_KEY=pk_test_...<br/> -VITE_CONVEX_URL=https://your-app.convex.cloud - </code> - </div> - </div> - </div> - </div> - - <button - onClick={() => window.location.reload()} - className="w-full bg-gradient-to-r from-blue-500 to-purple-600 text-white font-semibold py-3 px-6 rounded-lg hover:from-blue-600 hover:to-purple-700 transition-all duration-200 shadow-lg hover:shadow-xl" - > - Refresh After Setup - </button> - </div> - </div> -);Then add a new file src/pages/UnauthenticatedApp.tsx:
import React from "react"; const UnauthenticatedApp: React.FC = () => ( <div className="min-h-screen bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 flex items-center justify-center p-4"> <div className="max-w-md w-full space-y-6 text-center"> <div className="space-y-4"> <div className="w-16 h-16 mx-auto bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center"> <svg className="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /> </svg> </div> <h1 className="text-3xl font-bold text-white">ZapDev AI Platform</h1> <p className="text-slate-300 text-lg">Authentication Setup Required</p> </div> <div className="bg-slate-800/50 backdrop-blur-sm border border-slate-700 rounded-lg p-6 space-y-4 text-left"> <h2 className="text-xl font-semibold text-white">Quick Setup:</h2> <div className="space-y-3 text-sm text-slate-300"> <div className="flex items-start gap-3"> <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">1</span> <div> <p className="text-white font-medium">Get Clerk API Key</p> <p>Visit <code className="bg-slate-700 px-1 rounded">dashboard.clerk.com</code></p> </div> </div> <div className="flex items-start gap-3"> <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">2</span> <div> <p className="text-white font-medium">Get Convex URL</p> <p>Visit <code className="bg-slate-700 px-1 rounded">dashboard.convex.dev</code></p> </div> </div> <div className="flex items-start gap-3"> <span className="flex-shrink-0 w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-bold">3</span> <div> <p className="text-white font-medium">Update .env.local</p> <code className="block bg-slate-700 p-2 rounded mt-1 text-xs"> VITE_CLERK_PUBLISHABLE_KEY=pk_test_...<br /> VITE_CONVEX_URL=https://your-app.convex.cloud </code> </div> </div> </div> </div> <button onClick={() => window.location.reload()} className="w-full bg-gradient-to-r from-blue-500 to-purple-600 text-white font-semibold py-3 px-6 rounded-lg hover:from-blue-600 hover:to-purple-700 transition-all duration-200 shadow-lg hover:shadow-xl" > Refresh After Setup </button> </div> </div> ); export default UnauthenticatedApp;Finally, import it in main.tsx:
import UnauthenticatedApp from './pages/UnauthenticatedApp';
1-12: Prefer path alias for internal imports and add UnauthenticatedApp importMinor consistency tweak: use the @/ path alias and import the extracted component.
Apply this diff:
-import { convex } from './lib/convex' +import { convex } from '@/lib/convex' +import UnauthenticatedApp from './pages/UnauthenticatedApp'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
src/App.tsx(1 hunks)src/lib/convex.ts(1 hunks)src/main.tsx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/convex-security.mdc)
**/*.{ts,tsx}: All Convex queries and mutations MUST use proper authentication. Never accept user IDs from client parameters.
Always verify user owns the data before allowing access.
Use the authenticated user's identity.subject for user references.
Implement proper error messages that don't leak information.
Authentication verification in every function.
Authorization checks for data ownership.
Input validation and sanitization.
Error handling without information leakage.
**/*.{ts,tsx}: Use Sonner for toast notifications to provide consistent user feedback, including success, error, and loading states.
Always handle errors gracefully using try-catch blocks in asynchronous functions, providing user feedback and logging errors.
Provide specific, actionable error messages for form validation errors using toast notifications.
Handle common network error scenarios in catch blocks, providing appropriate toast messages for network errors, authentication errors, and unexpected errors.If using TypeScript, use an enum to store flag names.
Strict TypeScript must be used with no 'any' types allowed
**/*.{ts,tsx}: NEVER useanytype - use proper TypeScript types
Useunknownfor truly unknown data types
Implement proper interface definitions
Do not use empty interfaces; use a type alias instead (e.g.,type InputProps = ...instead ofinterface InputProps {})
All function parameters must be typed
All return types should be explicit for public APIs
Use proper generic constraints
Implement discriminated unions for state management
Use proper interface definitions for error handling types (e.g.,interface ValidationResult { isValid: boolean; error?: string; })
**/*.{ts,tsx}: Always sanitize user input before storing or displaying using a sanitization function likesanitizeText.
Implement comprehensive input validation, including length checks and detection of malicious patterns, as shown in thevalidateInputfunction.
Define and use security constants suc...
Files:
src/lib/convex.tssrc/main.tsxsrc/App.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/posthog-integration.mdc)
**/*.{js,jsx,ts,tsx}: Use a consistent naming convention for this storage. enum/const object members should be written UPPERCASE_WITH_UNDERSCORE.
If a custom property for a person or event is at any point referenced in two or more files or two or more callsites in the same file, use an enum or const object, as above in feature flags.
Files:
src/lib/convex.tssrc/main.tsxsrc/App.tsx
**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/error-handling.mdc)
**/*.tsx: Always provide loading feedback to users during asynchronous operations.
Use proper error boundaries to handle component crashes and display user-friendly error UI.Use proper React component typing (e.g.,
const MyComponent: React.FC<Props> = ...)
**/*.tsx: Use theSafeTextReact component for all user-generated content to ensure safe text display.
NEVER usedangerouslySetInnerHTMLwith user content.
NEVER use direct string interpolation in HTML with user content.
Files:
src/main.tsxsrc/App.tsx
src/**/*.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
src/**/*.tsx: Use React Hook Form with Zod validation for client-side forms
Prevent XSS by sanitizing any user-generated content before rendering (avoid unsafe HTML, or sanitize it)
Implement proper error handling with typed error boundaries in React
Files:
src/main.tsxsrc/App.tsx
{src/main.tsx,src/App.tsx}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Keep application entry points at src/main.tsx (providers setup) and src/App.tsx (routing)
Files:
src/main.tsxsrc/App.tsx
src/App.tsx
📄 CodeRabbit Inference Engine (CLAUDE.md)
Maintain routing protection: protect /chat and /settings with AuthGuard; keep public routes unprotected as specified
Files:
src/App.tsx
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: otdoges/zapdev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-12T03:04:41.047Z
Learning: Applies to {src/main.tsx,src/App.tsx} : Keep application entry points at src/main.tsx (providers setup) and src/App.tsx (routing)
Learnt from: CR
PR: otdoges/zapdev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-12T03:04:41.047Z
Learning: Applies to src/App.tsx : Maintain routing protection: protect /chat and /settings with AuthGuard; keep public routes unprotected as specified
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/authentication-patterns.mdc:0-0
Timestamp: 2025-08-09T23:02:50.250Z
Learning: Applies to **/useAuth.@(ts|tsx) : Use the provided `useAuth` hook pattern for integrating Clerk and Convex authentication, including syncing Clerk user data to Convex and returning the correct authentication state.
📚 Learning: 2025-08-09T23:03:33.416Z
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-08-09T23:03:33.416Z
Learning: Applies to convex/**/*.ts : All Convex functions must use proper authentication verification
Applied to files:
src/lib/convex.ts
📚 Learning: 2025-08-12T03:04:41.047Z
Learnt from: CR
PR: otdoges/zapdev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-12T03:04:41.047Z
Learning: Applies to convex/**/*.ts : All Convex functions must verify authentication
Applied to files:
src/lib/convex.ts
📚 Learning: 2025-08-09T23:02:50.250Z
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/authentication-patterns.mdc:0-0
Timestamp: 2025-08-09T23:02:50.250Z
Learning: Applies to **/{pages,components}/**/*.tsx : Handle all authentication states in components by showing a loading spinner when loading, a sign-in prompt when unauthenticated, and protected content when authenticated.
Applied to files:
src/main.tsxsrc/App.tsx
📚 Learning: 2025-08-09T23:02:50.250Z
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/authentication-patterns.mdc:0-0
Timestamp: 2025-08-09T23:02:50.250Z
Learning: Applies to **/{auth,authentication}/**/*.tsx : Redirect authenticated users to `/chat` using the `SignInButton` with `forceRedirectUrl` set to `/chat` in Clerk configuration.
Applied to files:
src/main.tsxsrc/App.tsx
📚 Learning: 2025-08-09T23:02:50.250Z
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/authentication-patterns.mdc:0-0
Timestamp: 2025-08-09T23:02:50.250Z
Learning: Applies to **/useAuth.@(ts|tsx) : Use the provided `useAuth` hook pattern for integrating Clerk and Convex authentication, including syncing Clerk user data to Convex and returning the correct authentication state.
Applied to files:
src/main.tsxsrc/App.tsx
📚 Learning: 2025-08-12T03:04:41.047Z
Learnt from: CR
PR: otdoges/zapdev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-12T03:04:41.047Z
Learning: Applies to src/App.tsx : Maintain routing protection: protect /chat and /settings with AuthGuard; keep public routes unprotected as specified
Applied to files:
src/App.tsx
📚 Learning: 2025-08-12T03:04:41.047Z
Learnt from: CR
PR: otdoges/zapdev#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-12T03:04:41.047Z
Learning: Applies to {src/main.tsx,src/App.tsx} : Keep application entry points at src/main.tsx (providers setup) and src/App.tsx (routing)
Applied to files:
src/App.tsx
📚 Learning: 2025-08-09T23:02:50.250Z
Learnt from: CR
PR: otdoges/zapdev#0
File: .cursor/rules/authentication-patterns.mdc:0-0
Timestamp: 2025-08-09T23:02:50.250Z
Learning: Applies to **/{routes,router}.tsx : Use `AuthGuard` to wrap protected routes in your React Router configuration.
Applied to files:
src/App.tsx
🧬 Code Graph Analysis (2)
src/main.tsx (2)
src/lib/convex.ts (1)
convex(14-16)src/hooks/useAuth.ts (1)
useAuth(16-46)
src/App.tsx (6)
src/components/UserSync.tsx (1)
UserSync(7-39)src/components/AuthWrapper.tsx (1)
AuthWrapper(10-47)src/lib/trpc.ts (2)
trpc(6-6)trpcClient(8-18)src/components/ui/tooltip.tsx (1)
TooltipProvider(28-28)src/pages/Checkout.tsx (1)
CheckoutPage(3-8)src/pages/Success.tsx (1)
Success(20-217)
🪛 GitHub Check: ESLint
src/main.tsx
[warning] 84-84:
Fast refresh only works when a file has exports. Move your component(s) to a separate file.
🔇 Additional comments (5)
src/App.tsx (3)
47-57: Auth protection for /chat and /settings is preserved — goodThis aligns with our routing protection requirement.
58-62: Confirm intent to require auth for /successPrevious guidance only mandated protecting /chat and /settings. Putting /success behind auth could block users returning from checkout if they aren’t signed in yet (or cause redirect loops). If the server requires auth to finalize, this is fine; otherwise, consider making it public and handling 401s in-page (as the component already toasts on 401).
31-33: tRPC base URL uses VITE_CONVEX_URL; add a safe fallback to avoid "undefined/trpc"Given convex.ts now dev-falls back when VITE_CONVEX_URL is missing, ensure trpcClient doesn’t produce an invalid URL (undefined/trpc). Recommend dev-only fallback and production hard-fail in src/lib/trpc.ts.
Proposed update for src/lib/trpc.ts (for your follow-up commit):
const baseUrl = import.meta.env.VITE_CONVEX_URL; if (!baseUrl) { if (import.meta.env.DEV) { console.warn("Missing VITE_CONVEX_URL for tRPC; using mock Convex URL"); } else { throw new Error("VITE_CONVEX_URL must be configured for tRPC in production"); } } export const trpcClient = createTRPCClient<AppRouter>({ links: [ httpBatchLink({ url: `${baseUrl || "https://mock-convex-url.convex.cloud"}/trpc`, headers: () => { const token = authTokenManager.getToken(); return token ? { authorization: `Bearer ${token}` } : {}; }, }), ], });src/main.tsx (2)
54-58: DX logs for missing Clerk key look goodClear, actionable steps without crashing the app. Nice.
139-160: Conditional bootstrap is solidGating the full provider stack behind PUBLISHABLE_KEY and rendering a friendly setup UI otherwise is a clean UX.
Summary by CodeRabbit
New Features
Bug Fixes
Refactor