@vectorchat/mcp-server
Version:
VectorChat MCP Server - Encrypted AI-to-AI communication with hardware security (YubiKey/TPM). 45+ MCP tools for Windsurf, Claude, and AI assistants. Model-based identity with EMDM encryption. Dynamic AI playbook system, communication zones, message relay
397 lines (333 loc) • 12.5 kB
Markdown
Enable UI transitions without refactoring the entire codebase.
```
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌───────────┐ │
│ │ UI Registry │ │ Theme Engine │ │ Router │ │
│ └────────────────┘ └────────────────┘ └───────────┘ │
│ │
├─────────────────────────────────────────────────────────┤
│ UI Abstraction Layer │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Component Factory Interface │ │
│ │ - buildChatScreen() │ │
│ │ - buildMessageBubble() │ │
│ │ - buildChannelList() │ │
│ │ - buildInputField() │ │
│ └────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────┤
│ Service Layer │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ ChatService │ │IdentityMgr │ │EncryptionSvc │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ WebSocketSvc │ │ HistorySvc │ │ SettingsSvc │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
```dart
// lib/interfaces/chat_service_interface.dart
abstract class IChatService {
Stream<ChatMessage> get messageStream;
Future<void> sendMessage(String content, String recipient);
Future<void> connect(String username);
Future<void> disconnect();
bool get isConnected;
}
// lib/interfaces/identity_service_interface.dart
abstract class IIdentityService {
Future<ModelIdentity> registerIdentity(String name, String modelPath);
ModelIdentity? getIdentity(String name);
List<ModelIdentity> getAllIdentities();
}
// lib/interfaces/encryption_service_interface.dart
abstract class IEncryptionService {
Future<Uint8List> encode(String data, ModelIdentity identity);
Future<String> decode(Uint8List data, ModelIdentity identity);
}
```
```dart
// lib/ui/component_factory.dart
abstract class ComponentFactory {
// Screen builders
Widget buildChatScreen(BuildContext context);
Widget buildSettingsScreen(BuildContext context);
Widget buildModelSelectionScreen(BuildContext context);
// Component builders
Widget buildMessageBubble(ChatMessage message);
Widget buildChannelList(List<Channel> channels);
Widget buildInputField(TextEditingController controller);
Widget buildStatusCard(String title, String status, Color color);
// Dialog builders
Future<void> showErrorDialog(BuildContext context, String message);
Future<void> showSuccessDialog(BuildContext context, String message);
}
// lib/ui/factories/classic_factory.dart
class ClassicComponentFactory implements ComponentFactory {
@override
Widget buildChatScreen(BuildContext context) {
return ChatScreen(); // Current implementation
}
@override
Widget buildMessageBubble(ChatMessage message) {
return MessageBubble(message: message); // Current implementation
}
// ... other implementations
}
// lib/ui/factories/modern_factory.dart
class ModernComponentFactory implements ComponentFactory {
@override
Widget buildChatScreen(BuildContext context) {
return ModernChatScreen(); // New Discord-style UI
}
@override
Widget buildMessageBubble(ChatMessage message) {
return ModernMessageBubble(message: message); // Rich formatting
}
// ... other implementations
}
```
```dart
// lib/ui/ui_registry.dart
class UIRegistry {
static final UIRegistry _instance = UIRegistry._internal();
factory UIRegistry() => _instance;
UIRegistry._internal();
final Map<String, ComponentFactory> _factories = {};
ComponentFactory? _activeFactory;
void registerFactory(String name, ComponentFactory factory) {
_factories[name] = factory;
}
void setActiveFactory(String name) {
if (_factories.containsKey(name)) {
_activeFactory = _factories[name];
}
}
ComponentFactory get factory {
if (_activeFactory == null) {
throw Exception('No active UI factory set');
}
return _activeFactory!;
}
}
```
```dart
// lib/ui/theme_engine.dart
enum UITheme {
classic, // Version 1.0
modern, // Version 2.0
compact, // Dense layout
custom, // User-defined
}
class ThemeEngine {
static final ThemeEngine _instance = ThemeEngine._internal();
factory ThemeEngine() => _instance;
ThemeEngine._internal();
UITheme _currentTheme = UITheme.classic;
UITheme get currentTheme => _currentTheme;
void setTheme(UITheme theme) {
_currentTheme = theme;
_updateFactory();
}
void _updateFactory() {
final registry = UIRegistry();
switch (_currentTheme) {
case UITheme.classic:
registry.setActiveFactory('classic');
break;
case UITheme.modern:
registry.setActiveFactory('modern');
break;
case UITheme.compact:
registry.setActiveFactory('compact');
break;
case UITheme.custom:
registry.setActiveFactory('custom');
break;
}
}
}
```
```dart
// lib/main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Register UI factories
final registry = UIRegistry();
registry.registerFactory('classic', ClassicComponentFactory());
registry.registerFactory('modern', ModernComponentFactory());
// Set default theme
final themeEngine = ThemeEngine();
themeEngine.setTheme(UITheme.classic);
runApp(VectorChatApp());
}
class VectorChatApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'VectorChat',
theme: ThemeData.dark(),
home: UIRegistry().factory.buildChatScreen(context),
);
}
}
```
```dart
// In any widget
class SomeWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final factory = UIRegistry().factory;
return Column(
children: [
factory.buildMessageBubble(message),
factory.buildInputField(controller),
],
);
}
}
// Switching themes
void switchToModernUI() {
ThemeEngine().setTheme(UITheme.modern);
// Trigger rebuild
setState(() {});
}
```
- Services stay exactly the same
- Business logic unchanged
- Only UI components swap out
```dart
// Test different UIs with same backend
if (userGroup == 'beta') {
ThemeEngine().setTheme(UITheme.modern);
} else {
ThemeEngine().setTheme(UITheme.classic);
}
```
```dart
// Let users choose their UI
Settings:
[ ] Classic UI (Version 1.0)
[x] Modern UI (Version 2.0)
[ ] Compact UI
```
### 4. **Gradual Migration**
```dart
// Migrate one component at a time
class HybridFactory implements ComponentFactory {
@override
Widget buildChatScreen(BuildContext context) {
return ModernChatScreen(); // New
}
@override
Widget buildSettingsScreen(BuildContext context) {
return SettingsScreen(); // Old (keep for now)
}
}
```
```
lib/
├── interfaces/
│ ├── chat_service_interface.dart
│ ├── identity_service_interface.dart
│ └── encryption_service_interface.dart
│
├── services/
│ ├── websocket_service.dart (implements IChatService)
│ ├── identity_manager.dart (implements IIdentityService)
│ └── emdm_encoder_v2.dart (implements IEncryptionService)
│
├── ui/
│ ├── component_factory.dart
│ ├── ui_registry.dart
│ ├── theme_engine.dart
│ │
│ ├── factories/
│ │ ├── classic_factory.dart (Version 1.0)
│ │ ├── modern_factory.dart (Version 2.0)
│ │ └── compact_factory.dart (Future)
│ │
│ ├── classic/ (Version 1.0 UI)
│ │ ├── chat_screen.dart
│ │ ├── message_bubble.dart
│ │ └── settings_screen.dart
│ │
│ └── modern/ (Version 2.0 UI)
│ ├── modern_chat_screen.dart
│ ├── modern_message_bubble.dart
│ ├── channel_sidebar.dart
│ └── details_panel.dart
│
├── models/
│ └── message.dart
│
└── main.dart
```
- Define service interfaces
- Implement in existing services
- Test compatibility
- Create ComponentFactory
- Build UIRegistry
- Implement ThemeEngine
- Create ClassicComponentFactory
- Wrap current screens
- Test switching mechanism
- Create ModernComponentFactory
- Build Discord-style components
- Implement feature parity
- Performance optimization
- Bug fixes
- User testing
- Documentation
```dart
// Test that both UIs work with same services
void testUICompatibility() {
final service = ChatService();
// Test with classic UI
ThemeEngine().setTheme(UITheme.classic);
testChatFunctionality(service);
// Test with modern UI
ThemeEngine().setTheme(UITheme.modern);
testChatFunctionality(service);
// Both should work identically
}
```
✅ **Modular** - Swap UIs without touching services
✅ **Flexible** - Multiple UI themes supported
✅ **Testable** - Easy A/B testing
✅ **Gradual** - Migrate one component at a time
✅ **User Choice** - Let users pick their UI
✅ **Future-Proof** - Easy to add new themes
**Result:** UI transitions without codebase refactoring! 🎨🔧