Files
DeskClaw/build_process/commit_4_provider_configuration.md
Haze e02cf05baf feat(update): implement auto-update functionality with electron-updater
- 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
2026-02-05 23:36:12 +08:00

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)