feat: production readiness improvements
## Error Handling - Add GlobalErrorBoundary with error classification and recovery - Add custom error types (SecurityError, ConnectionError, TimeoutError) - Fix ErrorAlert component syntax errors ## Offline Mode - Add offlineStore for offline state management - Implement message queue with localStorage persistence - Add exponential backoff reconnection (1s→60s) - Add OfflineIndicator component with status display - Queue messages when offline, auto-retry on reconnect ## Security Hardening - Add AES-256-GCM encryption for chat history storage - Add secure API key storage with OS keychain integration - Add security audit logging system - Add XSS prevention and input validation utilities - Add rate limiting and token generation helpers ## CI/CD (Gitea Actions) - Add .gitea/workflows/ci.yml for continuous integration - Add .gitea/workflows/release.yml for release automation - Support Windows Tauri build and release ## UI Components - Add LoadingSpinner, LoadingOverlay, LoadingDots components - Add MessageSkeleton, ConversationListSkeleton skeletons - Add EmptyMessages, EmptyConversations empty states - Integrate loading states in ChatArea and ConversationList ## E2E Tests - Fix WebSocket mock for streaming response tests - Fix approval endpoint route matching - Add store state exposure for testing - All 19 core-features tests now passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -68,8 +68,23 @@ export const storeInspectors = {
|
||||
|
||||
/**
|
||||
* 获取持久化的 Chat Store 状态
|
||||
* 优先从运行时获取,如果不可用则从 localStorage 获取
|
||||
*/
|
||||
async getChatState<T = unknown>(page: Page): Promise<T | null> {
|
||||
// First try to get runtime state (more reliable for E2E tests)
|
||||
const runtimeState = await page.evaluate(() => {
|
||||
const stores = (window as any).__ZCLAW_STORES__;
|
||||
if (stores && stores.chat) {
|
||||
return stores.chat.getState() as T;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (runtimeState) {
|
||||
return runtimeState;
|
||||
}
|
||||
|
||||
// Fallback to localStorage
|
||||
return page.evaluate((key) => {
|
||||
const stored = localStorage.getItem(key);
|
||||
if (!stored) return null;
|
||||
|
||||
Reference in New Issue
Block a user