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:
@@ -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">
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user