feat(a2ui): Implement A2UI backend with question handling and WebSocket support

- Added A2UITypes for defining question structures and answers.
- Created A2UIWebSocketHandler for managing WebSocket connections and message handling.
- Developed ask-question tool for interactive user questions via A2UI.
- Introduced platformUtils for platform detection and shell command handling.
- Centralized TypeScript types in index.ts for better organization.
- Implemented compatibility checks for hook templates based on platform requirements.
This commit is contained in:
catlog22
2026-01-31 15:27:12 +08:00
parent 4e009bb03a
commit 715ef12c92
163 changed files with 19495 additions and 715 deletions

View File

@@ -14,6 +14,7 @@ import type {
WorkflowFilters,
WorkflowSorting,
} from '../types/store';
import { switchWorkspace as apiSwitchWorkspace, fetchRecentPaths, removeRecentPath as apiRemoveRecentPath } from '../lib/api';
// Helper to generate session key from ID
const sessionKey = (sessionId: string): string => {
@@ -365,6 +366,53 @@ export const useWorkflowStore = create<WorkflowStore>()(
set({ serverPlatform: platform }, false, 'setServerPlatform');
},
// ========== Workspace Actions ==========
switchWorkspace: async (path: string) => {
const response = await apiSwitchWorkspace(path);
const sessionDataStore: Record<string, SessionMetadata> = {};
// Build sessionDataStore from both arrays
[...response.activeSessions, ...response.archivedSessions].forEach((session) => {
const key = sessionKey(session.session_id);
sessionDataStore[key] = session;
});
set(
{
projectPath: response.projectPath,
recentPaths: response.recentPaths,
workflowData: {
activeSessions: response.activeSessions,
archivedSessions: response.archivedSessions,
},
sessionDataStore,
},
false,
'switchWorkspace'
);
// Trigger query invalidation callback
const callback = get()._invalidateQueriesCallback;
if (callback) {
callback();
}
},
removeRecentPath: async (path: string) => {
const updatedPaths = await apiRemoveRecentPath(path);
set({ recentPaths: updatedPaths }, false, 'removeRecentPath');
},
refreshRecentPaths: async () => {
const paths = await fetchRecentPaths();
set({ recentPaths: paths }, false, 'refreshRecentPaths');
},
registerQueryInvalidator: (callback: () => void) => {
set({ _invalidateQueriesCallback: callback }, false, 'registerQueryInvalidator');
},
// ========== Filters and Sorting ==========
setFilters: (filters: Partial<WorkflowFilters>) => {