- Add AppUpdater module with update lifecycle management - Create UpdateSettings UI component with progress display - Add Progress UI component based on Radix UI - Create update Zustand store for state management - Register update IPC handlers in main process - Auto-check for updates on production startup - Add commit documentation for commits 2-6
128 lines
4.3 KiB
Markdown
128 lines
4.3 KiB
Markdown
# Commit 4: Provider Configuration
|
|
|
|
## Summary
|
|
Implement secure API key storage using Electron's safeStorage API and create a comprehensive provider management UI for configuring AI model providers.
|
|
|
|
## Changes
|
|
|
|
### Electron Main Process
|
|
|
|
#### `electron/utils/secure-storage.ts` (New)
|
|
Secure storage utility using Electron's safeStorage:
|
|
- `isEncryptionAvailable()` - Check if system keychain is available
|
|
- `storeApiKey(providerId, apiKey)` - Encrypt and store API key
|
|
- `getApiKey(providerId)` - Decrypt and retrieve API key
|
|
- `deleteApiKey(providerId)` - Remove stored API key
|
|
- `hasApiKey(providerId)` - Check if key exists
|
|
- `listStoredKeyIds()` - List all stored provider IDs
|
|
|
|
Provider configuration management:
|
|
- `saveProvider(config)` - Save provider configuration
|
|
- `getProvider(providerId)` - Get single provider
|
|
- `getAllProviders()` - Get all providers
|
|
- `deleteProvider(providerId)` - Delete provider and key
|
|
- `setDefaultProvider(providerId)` - Set default provider
|
|
- `getDefaultProvider()` - Get default provider ID
|
|
- `getProviderWithKeyInfo(providerId)` - Get provider with masked key
|
|
- `getAllProvidersWithKeyInfo()` - Get all providers with key info
|
|
|
|
Note: Uses dynamic `import('electron-store')` for ESM compatibility.
|
|
|
|
#### `electron/main/ipc-handlers.ts`
|
|
New `registerProviderHandlers()` function with IPC handlers:
|
|
- `provider:encryptionAvailable`
|
|
- `provider:list` / `provider:get` / `provider:save` / `provider:delete`
|
|
- `provider:setApiKey` / `provider:deleteApiKey` / `provider:hasApiKey` / `provider:getApiKey`
|
|
- `provider:setDefault` / `provider:getDefault`
|
|
- `provider:validateKey` - Basic format validation
|
|
|
|
#### `electron/preload/index.ts`
|
|
Added all provider IPC channels to valid channels list.
|
|
|
|
### React Renderer
|
|
|
|
#### `src/stores/providers.ts` (New)
|
|
Zustand store for provider management:
|
|
- State: `providers`, `defaultProviderId`, `loading`, `error`
|
|
- Actions: `fetchProviders`, `addProvider`, `updateProvider`, `deleteProvider`
|
|
- Actions: `setApiKey`, `deleteApiKey`, `setDefaultProvider`, `validateApiKey`, `getApiKey`
|
|
|
|
#### `src/components/settings/ProvidersSettings.tsx` (New)
|
|
Provider management UI component:
|
|
- `ProvidersSettings` - Main component orchestrating provider list
|
|
- `ProviderCard` - Individual provider display with actions
|
|
- `AddProviderDialog` - Modal for adding new providers
|
|
|
|
Features:
|
|
- Provider type icons (Anthropic, OpenAI, Google, Ollama, Custom)
|
|
- Masked API key display (first 4 + last 4 characters)
|
|
- Set default provider
|
|
- Enable/disable providers
|
|
- Edit/delete functionality
|
|
- API key validation on add
|
|
|
|
#### `src/pages/Settings/index.tsx`
|
|
- Added AI Providers section with `ProvidersSettings` component
|
|
- Added `Key` icon import
|
|
|
|
## Technical Details
|
|
|
|
### Security Architecture
|
|
```
|
|
Renderer Process Main Process
|
|
| |
|
|
| provider:setApiKey |
|
|
|--------------------------------->|
|
|
| | safeStorage.encryptString()
|
|
| | |
|
|
| | v
|
|
| | System Keychain
|
|
| | |
|
|
| | electron-store
|
|
| | (encrypted base64)
|
|
| |
|
|
| provider:getApiKey |
|
|
|--------------------------------->|
|
|
| | safeStorage.decryptString()
|
|
|<---------------------------------|
|
|
| (plaintext) |
|
|
```
|
|
|
|
### Provider Configuration Schema
|
|
```typescript
|
|
interface ProviderConfig {
|
|
id: string;
|
|
name: string;
|
|
type: 'anthropic' | 'openai' | 'google' | 'ollama' | 'custom';
|
|
baseUrl?: string;
|
|
model?: string;
|
|
enabled: boolean;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
}
|
|
```
|
|
|
|
### Key Validation Rules
|
|
- Anthropic: Must start with `sk-ant-`
|
|
- OpenAI: Must start with `sk-`
|
|
- Google: Minimum 20 characters
|
|
- Ollama: No key required
|
|
- Custom: No validation
|
|
|
|
### ESM Compatibility
|
|
electron-store v10+ is ESM-only. Solution: dynamic imports in main process.
|
|
|
|
```typescript
|
|
let store: any = null;
|
|
async function getStore() {
|
|
if (!store) {
|
|
const Store = (await import('electron-store')).default;
|
|
store = new Store({ /* config */ });
|
|
}
|
|
return store;
|
|
}
|
|
```
|
|
|
|
## Version
|
|
v0.1.0-alpha (incremental)
|