feat: complete Phase 1-3 architecture optimization

Phase 1 - Security:
- Add AES-GCM encryption for localStorage fallback
- Enforce WSS protocol for non-localhost WebSocket connections
- Add URL sanitization to prevent XSS in markdown links

Phase 2 - Domain Reorganization:
- Create Intelligence Domain with Valtio store and caching
- Add unified intelligence-client for Rust backend integration
- Migrate from legacy agent-memory, heartbeat, reflection modules

Phase 3 - Core Optimization:
- Add virtual scrolling for ChatArea with react-window
- Implement LRU cache with TTL for intelligence operations
- Add message virtualization utilities

Additional:
- Add OpenFang compatibility test suite
- Update E2E test fixtures
- Add audit logging infrastructure
- Update project documentation and plans

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-21 22:11:50 +08:00
parent 815c56326b
commit ce562e8bfc
36 changed files with 5241 additions and 201 deletions

View File

@@ -151,6 +151,8 @@ export function Sidebar({
<div className="p-3 border-t border-gray-200 dark:border-gray-700">
<button
onClick={onOpenSettings}
aria-label="打开设置"
title="设置"
className="flex items-center gap-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 p-2 rounded-lg transition-colors"
>
<div className="w-8 h-8 bg-gray-600 rounded-full flex items-center justify-center text-white font-bold shadow-sm">

View File

@@ -9,7 +9,7 @@
import { useState, useEffect, useCallback } from 'react';
import { useHandStore, type Hand } from '../store/handStore';
import type { Workflow } from '../store/workflowStore';
import { useWorkflowStore, type Workflow } from '../store/workflowStore';
import {
X,
Plus,
@@ -202,6 +202,7 @@ function StepEditor({ step, hands, index, onUpdate, onRemove, onMoveUp, onMoveDo
export function WorkflowEditor({ workflow, isOpen, onClose, onSave, isSaving }: WorkflowEditorProps) {
const hands = useHandStore((s) => s.hands);
const loadHands = useHandStore((s) => s.loadHands);
const getWorkflowDetail = useWorkflowStore((s) => s.getWorkflowDetail);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [steps, setSteps] = useState<WorkflowStep[]>([]);
@@ -219,16 +220,31 @@ export function WorkflowEditor({ workflow, isOpen, onClose, onSave, isSaving }:
if (workflow) {
setName(workflow.name);
setDescription(workflow.description || '');
// For edit mode, we'd need to load full workflow details
// For now, initialize with empty steps
setSteps([]);
// Load full workflow details including steps
getWorkflowDetail(workflow.id)
.then((detail: { steps: Array<{ handName: string; name?: string; params?: Record<string, unknown>; condition?: string }> } | undefined) => {
if (detail && Array.isArray(detail.steps)) {
const editorSteps: WorkflowStep[] = detail.steps.map((step: { handName: string; name?: string; params?: Record<string, unknown>; condition?: string }, index: number) => ({
id: `step-${workflow.id}-${index}`,
handName: step.handName || '',
name: step.name,
params: step.params,
condition: step.condition,
}));
setSteps(editorSteps);
} else {
setSteps([]);
}
})
.catch(() => setSteps([]));
} else {
setName('');
setDescription('');
setSteps([]);
}
setError(null);
}, [workflow]);
}, [workflow, getWorkflowDetail]);
// Add new step
const handleAddStep = useCallback(() => {