Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,43 @@

All notable changes to the "superdesign" extension will be documented in this file.

## [0.0.9] - 2025-07-25

### Added

- Google Gemini as a new AI provider
- Command to configure Google API Key (`superdesign.configureGoogleApiKey`)
- Model selection for Gemini in the chat interface

### Improved

- Extended provider support in the backend service
- Enhanced error handling for API key configuration across all providers

## [0.0.8] - 2025-07-01

### Added

- Settings icon in chat sidebar for easy access to extension configuration
- In-chat action buttons for API key configuration and settings access
- Enhanced error handling with user-friendly action options

### Improved

- Error messages now specifically mention "Anthropic API key" for clarity
- API key validation and authentication error detection
- User experience with cleaner error handling workflow
- Settings integration with direct commands for API key configuration

### Fixed

- Raw JSON error messages no longer display in chat interface
- Notification popups replaced with cleaner in-chat error messages
- Error message filtering to prevent duplicate or confusing displays
- Process exit errors now properly handled with action buttons

### Technical

- Enhanced `ClaudeCodeService` error detection patterns
- Improved `ChatMessageService` error filtering and handling
- Better error message routing between extension and webview
Expand All @@ -31,56 +47,66 @@ All notable changes to the "superdesign" extension will be documented in this fi
## [0.0.7] - 2025-07-01

### Added

- Default style sheet integration for enhanced design consistency
- Project initialization command (`superdesign.initializeProject`)
- CSS file loading support for custom styling
- Copy file path functionality in Design Frame component

### Improved

- Updated icon design and visual elements
- Enhanced Design Frame component with better user interactions
- Extended file handling capabilities

### Documentation

- Updated README with improved instructions and examples

## [0.0.6] - 2025-06-26

### Added

- Centralized logging system with configurable log levels
- Enhanced error handling and debugging capabilities
- Improved Claude Code service integration

### Fixed

- Performance optimizations and stability improvements
- Better error messages and user feedback

## [0.0.5] - 2025-06-26

### Added

- Enhanced chat interface functionality
- Improved AI provider integrations

## [0.0.4] - 2025-06-26

### Added

- Additional design tools and utilities
- Better canvas interaction features

## [0.0.3] - 2025-06-25

### Added

- Enhanced design frame capabilities
- Improved user experience features

## [0.0.2] - 2025-06-25

### Added

- Publish to Open VSX Registry

## [0.0.1] - 2025-06-24

### Added

- Initial release of Super Design VS Code extension
- Interactive chat interface with AI assistance
- Canvas view for visual design layout
Expand All @@ -95,6 +121,7 @@ All notable changes to the "superdesign" extension will be documented in this fi
- TypeScript support with comprehensive type definitions

### Features

- **Chat Interface**: Real-time conversation with AI assistants
- **Visual Canvas**: Drag-and-drop design environment
- **Design Frames**: Organized content containers
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,24 @@ Works seamlessly with Cursor, Windsurf, Claude Code, and plain VS Code.

---

## 🧠 Supported AI Providers

SuperDesign supports multiple AI providers. You can configure your preferred provider and model in the settings.

- **Anthropic:** Claude models
- **OpenAI:** GPT models
- **Google:** Gemini models
- **OpenRouter:** Access a wide range of models

To configure an API key, use the Command Palette (`Cmd+Shift+P`) and search for "Superdesign: Configure [Provider] API Key".

## Can I use my own Claude Code or Cursor subscription?

Yes, after you initialise superdesign extension, some cursor/claude code rules will be added, so you can prompt the agent to do design and preview in superdesign canva (cmd + shift + p -> superdesign: open canva)

If using Cursor - I will highly suggest copy the prompt in 'design.mdc' and create a custom mode in cursor with that same system prompt; This should give you much better performance

Instructions here (Click to play):
Instructions here (Click to play):
[![Instruction video](v0.0.11.png)](https://youtu.be/KChmJMCDOB0?si=pvU0kNRO4GRWjsec&t=122)

## 📂 Where Are My Designs Stored?
Expand Down Expand Up @@ -86,4 +98,3 @@ Pull requests are welcome. Star the repo and join us on [Discord](https://discor
- 📦 GitHub: [https://github.com/superdesigndev/superdesign](https://github.com/superdesigndev/superdesign)
- 💬 Discord: [Join the Community](https://discord.gg/XYZ)
- 🐦 Twitter / X: [@SuperDesignDev](https://x.com/SuperDesignDev)

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
"title": "Configure OpenRouter API Key",
"category": "Superdesign"
},
{
"command": "superdesign.configureGoogleApiKey",
"title": "Configure Google API Key",
"category": "Superdesign"
},
{
"command": "superdesign.showChatSidebar",
"title": "Show Chat Sidebar",
Expand Down Expand Up @@ -153,15 +158,21 @@
"description": "OpenRouter API key for custom agent",
"scope": "application"
},
"superdesign.googleApiKey": {
"type": "string",
"description": "Google API key for Gemini models.",
"scope": "application"
},
"superdesign.aiModelProvider": {
"type": "string",
"enum": [
"openai",
"anthropic",
"openrouter"
"openrouter",
"google"
],
"default": "anthropic",
"description": "AI model provider for custom agent (OpenAI, Anthropic, or OpenRouter)",
"description": "AI model provider for custom agent (OpenAI, Anthropic, OpenRouter, Google)",
"scope": "application"
},
"superdesign.aiModel": {
Expand Down
42 changes: 42 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,48 @@ async function configureOpenRouterApiKey() {
}
}

async function configureGoogleApiKey() {
const config = vscode.workspace.getConfiguration('superdesign');
const currentKey = config.get<string>('googleApiKey');

const input = await vscode.window.showInputBox({
title: 'Configure Google API Key',
prompt: 'Enter your Google API key',
value: currentKey ? '••••••••••••••••' : '',
password: true,
placeHolder: 'Enter your Google API Key',
validateInput: (value) => {
if (!value || value.trim().length === 0) {
return 'API key cannot be empty';
}
if (value === '••••••••••••••••') {
return null; // User didn't change the masked value, that's OK
}
return null;
}
});

if (input !== undefined) {
// Only update if user didn't just keep the masked value
if (input !== '••••••••••••••••') {
try {
await vscode.workspace.getConfiguration('superdesign').update(
'googleApiKey',
input.trim(),
vscode.ConfigurationTarget.Global
);
vscode.window.showInformationMessage('✅ Google API key configured successfully!');
} catch (error) {
vscode.window.showErrorMessage(`Failed to save API key: ${error}`);
}
} else if (currentKey) {
vscode.window.showInformationMessage('API key unchanged (already configured)');
} else {
vscode.window.showWarningMessage('No API key was set');
}
}
}

class SuperdesignCanvasPanel {
public static currentPanel: SuperdesignCanvasPanel | undefined;
public static readonly viewType = 'superdesignCanvasPanel';
Expand Down
12 changes: 12 additions & 0 deletions src/providers/chatSidebarProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ export class ChatSidebarProvider implements vscode.WebviewViewProvider {
case 'openrouter':
defaultModel = 'anthropic/claude-3-7-sonnet-20250219';
break;
case 'google':
defaultModel = 'gemini-2.5-pro';
break;
case 'anthropic':
default:
defaultModel = 'claude-3-5-sonnet-20241022';
Expand Down Expand Up @@ -143,6 +146,11 @@ export class ChatSidebarProvider implements vscode.WebviewViewProvider {
apiKeyKey = 'anthropicApiKey';
configureCommand = 'superdesign.configureApiKey';
displayName = `Anthropic (${this.getModelDisplayName(model)})`;
} else if (model.startsWith('gemini-')) {
provider = 'google';
apiKeyKey = 'googleApiKey';
configureCommand = 'superdesign.configureGoogleApiKey';
displayName = `Google (${this.getModelDisplayName(model)})`;
} else {
provider = 'openai';
apiKeyKey = 'openaiApiKey';
Expand Down Expand Up @@ -197,6 +205,10 @@ export class ChatSidebarProvider implements vscode.WebviewViewProvider {
'claude-3-opus-20240229': 'Claude 3 Opus',
'claude-3-sonnet-20240229': 'Claude 3 Sonnet',
'claude-3-haiku-20240307': 'Claude 3 Haiku',
// Google models
'gemini-2.5-pro': 'Gemini 2.5 Pro',
'gemini-2.5-flash': 'Gemini 2.5 Flash',
'gemini-2.5-flash-lite': 'Gemini 2.5 Flash Lite',
// OpenRouter - Google models
'google/gemini-2.5-pro': 'Gemini 2.5 Pro',
'google/gemini-2.5-flash': 'Gemini 2.5 Flash',
Expand Down
6 changes: 6 additions & 0 deletions src/services/chatMessageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ export class ChatMessageService {
effectiveProvider = 'openrouter';
} else if (specificModel.startsWith('claude-')) {
effectiveProvider = 'anthropic';
} else if (specificModel.startsWith('gemini-')) {
effectiveProvider = 'google';
} else {
effectiveProvider = 'openai';
}
Expand All @@ -156,6 +158,10 @@ export class ChatMessageService {
providerName = 'Anthropic';
configureCommand = 'superdesign.configureApiKey';
break;
case 'google':
providerName = 'Google';
configureCommand = 'superdesign.configureGoogleApiKey';
break;
case 'openai':
providerName = 'OpenAI';
configureCommand = 'superdesign.configureOpenAIApiKey';
Expand Down
30 changes: 27 additions & 3 deletions src/services/customAgentService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { streamText, CoreMessage } from 'ai';
import { createOpenAI } from '@ai-sdk/openai';
import { createAnthropic } from '@ai-sdk/anthropic';
import { createGoogleGenerativeAI } from '@ai-sdk/google';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import * as vscode from 'vscode';
import * as path from 'path';
Expand Down Expand Up @@ -94,12 +95,30 @@ export class CustomAgentService implements AgentService {
effectiveProvider = 'openrouter';
} else if (specificModel.startsWith('claude-')) {
effectiveProvider = 'anthropic';
} else if (specificModel.startsWith('gemini-')) {
effectiveProvider = 'google';
} else {
effectiveProvider = 'openai';
}
}
effectiveProvider = 'openai';
}
}

switch (effectiveProvider) {
case 'google':
const googleKey = config.get<string>('googleApiKey');
if (!googleKey) {
throw new Error('Google API key not configured. Please run "Configure Google API Key" command.');
}

this.outputChannel.appendLine(`Google API key found.`);

const google = createGoogleGenerativeAI({
apiKey: googleKey,
});

const googleModel = specificModel || 'gemini-2.5-pro';
this.outputChannel.appendLine(`Using Google model: ${googleModel}`);
return google(googleModel);

case 'openrouter':
const openrouterKey = config.get<string>('openrouterApiKey');
if (!openrouterKey) {
Expand Down Expand Up @@ -180,6 +199,9 @@ export class CustomAgentService implements AgentService {
case 'openrouter':
modelName = 'anthropic/claude-3-7-sonnet-20250219';
break;
case 'google':
modelName = 'gemini-2.5-pro';
break;
case 'anthropic':
default:
modelName = 'claude-3-5-sonnet-20241022';
Expand Down Expand Up @@ -905,6 +927,8 @@ I've created the html design, please reveiw and let me know if you need any chan
return !!config.get<string>('openrouterApiKey');
case 'anthropic':
return !!config.get<string>('anthropicApiKey');
case 'google':
return !!config.get<string>('googleApiKey');
case 'openai':
default:
return !!config.get<string>('openaiApiKey');
Expand Down
4 changes: 4 additions & 0 deletions src/webview/components/Chat/ModelSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const ModelSelector: React.FC<ModelSelectorProps> = ({ selectedModel, onModelCha
{ id: 'claude-4-sonnet-20250514', name: 'Claude 4 Sonnet', provider: 'Anthropic', category: 'Balanced' },
{ id: 'claude-3-7-sonnet-20250219', name: 'Claude 3.7 Sonnet', provider: 'Anthropic', category: 'Balanced' },
{ id: 'claude-3-5-sonnet-20241022', name: 'Claude 3.5 Sonnet', provider: 'Anthropic', category: 'Balanced' },
// Google (Direct)
{ id: 'gemini-2.5-pro', name: 'Gemini 2.5 Pro', provider: 'Google', category: 'Balanced' },
{ id: 'gemini-2.5-flash', name: 'Gemini 2.5 Flash', provider: 'Google', category: 'Fast' },
{ id: 'gemini-2.5-flash-lite', name: 'Gemini 2.5 Flash Lite', provider: 'Google', category: 'Fast' },
// Google (OpenRouter)
{ id: 'google/gemini-2.5-pro', name: 'Gemini 2.5 Pro', provider: 'OpenRouter (Google)', category: 'Balanced' },
// Meta (OpenRouter)
Expand Down