From 090c5119dc22e33a3f693e5d13b6f60609f4c975 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 2 Jun 2025 11:05:07 +0000 Subject: [PATCH] feat: Add LLM planning display and new purple theme This commit introduces two new features: 1. LLM Planning Transparency: - I am now prompted to first generate a detailed, multi-step plan in Markdown format before providing code or artifacts. - Each plan step is prefixed with "g: " which allows the frontend to render it within a collapsible "ThoughtBox". - This enhances transparency by allowing you to see my intended approach before I proceed with implementation. 2. New 'Purple & White' Theme: - A new theme named 'purple' has been added to the application. - This theme uses a palette of purple shades for text and accents, with white and light lavender for backgrounds. - The theme switching logic has been updated to support three themes (light, dark, purple), and the theme switch UI component now cycles icons accordingly. - All necessary CSS variables have been defined for the new theme to ensure a consistent look and feel across the application. --- app/components/ui/ThemeSwitch.tsx | 11 ++- app/lib/common/prompts/prompts.ts | 36 +++------- app/lib/stores/theme.ts | 29 ++++---- app/styles/variables.scss | 107 ++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 41 deletions(-) diff --git a/app/components/ui/ThemeSwitch.tsx b/app/components/ui/ThemeSwitch.tsx index a46da2b2..5c4dffa8 100644 --- a/app/components/ui/ThemeSwitch.tsx +++ b/app/components/ui/ThemeSwitch.tsx @@ -15,11 +15,20 @@ export const ThemeSwitch = memo(({ className }: ThemeSwitchProps) => { setDomLoaded(true); }, []); + let iconClass = ''; + if (theme === 'dark') { + iconClass = 'i-ph-sun-dim-duotone'; + } else if (theme === 'light') { + iconClass = 'i-ph-moon-stars-duotone'; + } else { + // purple theme + iconClass = 'i-ph:palette-duotone'; + } return ( domLoaded && ( - Before providing a solution, BRIEFLY outline your implementation steps. This helps ensure systematic thinking and clear communication. Your planning should: - - List concrete steps you'll take - - Identify key components needed - - Note potential challenges - - Be concise (2-4 lines maximum) - - Example responses: - - User: "Create a todo list app with local storage" - Assistant: "Sure. I'll start by: - 1. Set up Vite + React - 2. Create TodoList and TodoItem components - 3. Implement localStorage for persistence - 4. Add CRUD operations + Before providing any code or executing any actions, you MUST first outline your implementation plan. This plan should be the very first part of your response. + The plan should be detailed, consisting of clear, actionable steps presented in Markdown format. + For each step in the plan, prefix the line with \`g: \` (e.g., \`g: 1. Initialize the project structure.\`). + The plan should cover: + - The main tasks you will perform. + - Any new files you will create and their purpose. + - Any existing files you will modify and what changes you intend to make. + - Any shell commands that will be run. + - Key components or functions you will develop. - Let's start now. - - [Rest of response...]" - - User: "Help debug why my API calls aren't working" - Assistant: "Great. My first steps will be: - 1. Check network requests - 2. Verify API endpoint format - 3. Examine error handling - - [Rest of response...]" - + After presenting the complete plan, and only then, proceed with generating the artifact containing the code and actions as per the . diff --git a/app/lib/stores/theme.ts b/app/lib/stores/theme.ts index 870adfd2..08a80ae6 100644 --- a/app/lib/stores/theme.ts +++ b/app/lib/stores/theme.ts @@ -1,7 +1,7 @@ import { atom } from 'nanostores'; import { logStore } from './logs'; -export type Theme = 'dark' | 'light'; +export type Theme = 'dark' | 'light' | 'purple'; export const kTheme = 'bolt_theme'; @@ -24,23 +24,12 @@ function initStore() { return DEFAULT_THEME; } -export function toggleTheme() { - const currentTheme = themeStore.get(); - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - - // Update the theme store +export function setTheme(newTheme: Theme) { themeStore.set(newTheme); - - // Update localStorage localStorage.setItem(kTheme, newTheme); - - // Update the HTML attribute document.querySelector('html')?.setAttribute('data-theme', newTheme); - - // Update user profile if it exists try { const userProfile = localStorage.getItem('bolt_user_profile'); - if (userProfile) { const profile = JSON.parse(userProfile); profile.theme = newTheme; @@ -49,6 +38,18 @@ export function toggleTheme() { } catch (error) { console.error('Error updating user profile theme:', error); } - logStore.logSystem(`Theme changed to ${newTheme} mode`); } + +export function toggleTheme() { + const currentTheme = themeStore.get(); + let newTheme: Theme; + if (currentTheme === 'light') { + newTheme = 'dark'; + } else if (currentTheme === 'dark') { + newTheme = 'purple'; + } else { + newTheme = 'light'; + } + setTheme(newTheme); // Call the new setTheme function +} diff --git a/app/styles/variables.scss b/app/styles/variables.scss index 099b3ed1..a9f26eb1 100644 --- a/app/styles/variables.scss +++ b/app/styles/variables.scss @@ -214,6 +214,113 @@ --modern-scrollbar-thumb-backgroundHover: rgba(10, 10, 10, 0.8); } +/* Color Tokens Purple Theme */ +:root[data-theme='purple'] { + --bolt-elements-borderColor: #B39DDB; /* Light purple for borders */ + --bolt-elements-borderColorActive: #673AB7; /* Primary purple for active borders */ + + --bolt-elements-bg-depth-1: #F8F7FC; /* Very light purple/off-white */ + --bolt-elements-bg-depth-2: #EDE7F6; /* Light lavender */ + --bolt-elements-bg-depth-3: #D1C4E9; /* Lavender */ + --bolt-elements-bg-depth-4: #F8F7FC; /* Very light purple/off-white */ + + --bolt-elements-textPrimary: #311B92; /* Deep purple */ + --bolt-elements-textSecondary: #5E35B1; /* Medium purple */ + --bolt-elements-textTertiary: #7E57C2; /* Lighter purple */ + + --bolt-elements-code-background: #EDE7F6; /* Light lavender */ + --bolt-elements-code-text: #311B92; /* Deep purple */ + + --bolt-elements-button-primary-background: #673AB7; /* Primary purple */ + --bolt-elements-button-primary-backgroundHover: #512DA8; /* Darker purple for hover */ + --bolt-elements-button-primary-text: #FFFFFF; /* White text */ + + --bolt-elements-button-secondary-background: #EDE7F6; /* Light lavender */ + --bolt-elements-button-secondary-backgroundHover: #D1C4E9; /* Lavender for hover */ + --bolt-elements-button-secondary-text: #4527A0; /* Dark purple text */ + + --bolt-elements-button-danger-background: #E91E63; /* Pink for danger */ + --bolt-elements-button-danger-backgroundHover: #C2185B; /* Darker pink for hover */ + --bolt-elements-button-danger-text: #FFFFFF; /* White text */ + + --bolt-elements-item-contentDefault: #5E35B1; /* Medium purple */ + --bolt-elements-item-contentActive: #311B92; /* Deep purple */ + --bolt-elements-item-contentAccent: #673AB7; /* Primary purple for accents */ + --bolt-elements-item-contentDanger: #E91E63; /* Pink for danger */ + --bolt-elements-item-backgroundDefault: rgba(0, 0, 0, 0); + --bolt-elements-item-backgroundActive: rgba(103, 58, 183, 0.05); /* Very light purple transparent */ + --bolt-elements-item-backgroundAccent: rgba(103, 58, 183, 0.1); /* Light purple transparent */ + --bolt-elements-item-backgroundDanger: rgba(233, 30, 99, 0.1); /* Light pink transparent */ + + --bolt-elements-loader-background: #D1C4E9; /* Lavender */ + --bolt-elements-loader-progress: #673AB7; /* Primary purple */ + + --bolt-elements-artifacts-background: #FFFFFF; /* White */ + --bolt-elements-artifacts-backgroundHover: #F8F7FC; /* Very light purple/off-white */ + --bolt-elements-artifacts-borderColor: var(--bolt-elements-borderColor); + --bolt-elements-artifacts-inlineCode-background: #EDE7F6; /* Light lavender */ + --bolt-elements-artifacts-inlineCode-text: var(--bolt-elements-textPrimary); + + --bolt-elements-actions-background: #FFFFFF; /* White */ + --bolt-elements-actions-code-background: #4A148C; /* Darker purple for code bg */ + + --bolt-elements-messages-background: #EDE7F6; /* Light lavender */ + --bolt-elements-messages-linkColor: #673AB7; /* Primary purple */ + --bolt-elements-messages-code-background: #4A148C; /* Darker purple for code bg */ + --bolt-elements-messages-inlineCode-background: #D1C4E9; /* Lavender */ + --bolt-elements-messages-inlineCode-text: #311B92; /* Deep purple */ + + --bolt-elements-icon-success: #4CAF50; /* Green for success */ + --bolt-elements-icon-error: #F44336; /* Red for error */ + --bolt-elements-icon-primary: #311B92; /* Deep purple */ + --bolt-elements-icon-secondary: #5E35B1; /* Medium purple */ + --bolt-elements-icon-tertiary: #7E57C2; /* Lighter purple */ + + --bolt-elements-dividerColor: #D1C4E9; /* Lavender */ + + --bolt-elements-prompt-background: rgba(248, 247, 252, 0.8); /* Translucent light bg */ + + --bolt-elements-sidebar-dropdownShadow: rgba(103, 58, 183, 0.2); /* Purple shadow */ + --bolt-elements-sidebar-buttonBackgroundDefault: rgba(103, 58, 183, 0.1); /* Light purple transparent */ + --bolt-elements-sidebar-buttonBackgroundHover: rgba(103, 58, 183, 0.2); /* Slightly darker purple transparent */ + --bolt-elements-sidebar-buttonText: #673AB7; /* Primary purple */ + + --bolt-elements-preview-addressBar-background: #EDE7F6; /* Light lavender */ + --bolt-elements-preview-addressBar-backgroundHover: #D1C4E9; /* Lavender */ + --bolt-elements-preview-addressBar-backgroundActive: #F8F7FC; /* Very light purple/off-white */ + --bolt-elements-preview-addressBar-text: var(--bolt-elements-textSecondary); + --bolt-elements-preview-addressBar-textActive: var(--bolt-elements-textPrimary); + + --bolt-elements-terminals-background: #F8F7FC; /* Very light purple/off-white */ + --bolt-elements-terminals-buttonBackground: #D1C4E9; /* Lavender */ + + --bolt-elements-cta-background: #EDE7F6; /* Light lavender */ + --bolt-elements-cta-text: #311B92; /* Deep purple */ + + /* Terminal Colors */ + --bolt-terminal-background: var(--bolt-elements-terminals-background); + --bolt-terminal-foreground: #311B92; /* Deep purple */ + --bolt-terminal-selection-background: rgba(103, 58, 183, 0.25); /* Purple selection */ + --bolt-terminal-black: #311B92; /* Deep purple (adjusted for readability) */ + --bolt-terminal-red: #C51162; /* Dark Pink */ + --bolt-terminal-green: #673AB7; /* Primary purple */ + --bolt-terminal-yellow: #7E57C2; /* Lighter purple */ + --bolt-terminal-blue: #5E35B1; /* Medium purple */ + --bolt-terminal-magenta: #9C27B0; /* Another shade of purple */ + --bolt-terminal-cyan: #7E57C2; /* Lighter purple */ + --bolt-terminal-white: #EDE7F6; /* Light lavender (for contrast) */ + --bolt-terminal-brightBlack: #5E35B1; /* Medium purple */ + --bolt-terminal-brightRed: #E91E63; /* Pink */ + --bolt-terminal-brightGreen: #7E57C2; /* Lighter purple */ + --bolt-terminal-brightYellow: #B39DDB; /* Light purple */ + --bolt-terminal-brightBlue: #673AB7; /* Primary purple */ + --bolt-terminal-brightMagenta: #AB47BC; /* Lighter Magenta */ + --bolt-terminal-brightCyan: #B39DDB; /* Light purple */ + --bolt-terminal-brightWhite: #F8F7FC; /* Very light purple/off-white */ + --modern-scrollbar-thumb-background: rgba(103, 58, 183, 0.3); + --modern-scrollbar-thumb-backgroundHover: rgba(103, 58, 183, 0.5); +} + /* * Element Tokens *