Files
Claude-Code-Workflow/ccw/frontend/src/hooks/useNativeSessions.ts
catlog22 75173312c1 feat(queue): implement queue scheduler service and API routes
- Added QueueSchedulerService to manage task queue lifecycle, including state machine, dependency resolution, and session management.
- Implemented HTTP API endpoints for queue scheduling:
  - POST /api/queue/execute: Submit items to the scheduler.
  - GET /api/queue/scheduler/state: Retrieve full scheduler state.
  - POST /api/queue/scheduler/start: Start scheduling loop with items.
  - POST /api/queue/scheduler/pause: Pause scheduling.
  - POST /api/queue/scheduler/stop: Graceful stop of the scheduler.
  - POST /api/queue/scheduler/config: Update scheduler configuration.
- Introduced types for queue items, scheduler state, and WebSocket messages to ensure type safety and compatibility with the backend.
- Added static model lists for LiteLLM as a fallback for available models.
2026-02-27 20:53:46 +08:00

128 lines
3.2 KiB
TypeScript

// ========================================
// useNativeSessions Hook
// ========================================
// TanStack Query hook for native CLI sessions list
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import {
fetchNativeSessions,
type NativeSessionListItem,
type NativeSessionsListResponse,
} from '../lib/api';
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
import { workspaceQueryKeys } from '@/lib/queryKeys';
// ========== Constants ==========
const STALE_TIME = 30 * 1000;
const GC_TIME = 5 * 60 * 1000;
// ========== Types ==========
export type NativeTool = 'gemini' | 'qwen' | 'codex' | 'claude' | 'opencode';
export interface UseNativeSessionsOptions {
/** Filter by tool type */
tool?: NativeTool;
/** Override default stale time (ms) */
staleTime?: number;
/** Override default gc time (ms) */
gcTime?: number;
/** Enable/disable the query */
enabled?: boolean;
}
export interface ByToolRecord {
[tool: string]: NativeSessionListItem[];
}
export interface UseNativeSessionsReturn {
/** All sessions data */
sessions: NativeSessionListItem[];
/** Sessions grouped by tool */
byTool: ByToolRecord;
/** Total count from API */
count: number;
/** Loading state for initial fetch */
isLoading: boolean;
/** Fetching state (initial or refetch) */
isFetching: boolean;
/** Error object if query failed */
error: Error | null;
/** Manually refetch data */
refetch: () => Promise<void>;
}
// ========== Helper Functions ==========
/**
* Group sessions by tool type
*/
function groupByTool(sessions: NativeSessionListItem[]): ByToolRecord {
return sessions.reduce<ByToolRecord>((acc, session) => {
const tool = session.tool;
if (!acc[tool]) {
acc[tool] = [];
}
acc[tool].push(session);
return acc;
}, {});
}
// ========== Hook ==========
/**
* Hook for fetching native CLI sessions list
*
* @example
* ```tsx
* const { sessions, byTool, isLoading } = useNativeSessions();
* const geminiSessions = byTool['gemini'] ?? [];
* ```
*
* @example
* ```tsx
* // Filter by tool
* const { sessions } = useNativeSessions({ tool: 'gemini' });
* ```
*/
export function useNativeSessions(
options: UseNativeSessionsOptions = {}
): UseNativeSessionsReturn {
const { tool, staleTime = STALE_TIME, gcTime = GC_TIME, enabled = true } = options;
const projectPath = useWorkflowStore(selectProjectPath);
const query = useQuery<NativeSessionsListResponse>({
queryKey: workspaceQueryKeys.nativeSessionsList(projectPath, tool),
queryFn: () => fetchNativeSessions(tool, projectPath),
staleTime,
gcTime,
enabled,
refetchOnWindowFocus: false,
retry: 2,
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000),
});
// Memoize sessions and byTool calculations
const { sessions, byTool } = React.useMemo(() => {
const sessions = query.data?.sessions ?? [];
const byTool = groupByTool(sessions);
return { sessions, byTool };
}, [query.data]);
const refetch = async () => {
await query.refetch();
};
return {
sessions,
byTool,
count: query.data?.count ?? 0,
isLoading: query.isLoading,
isFetching: query.isFetching,
error: query.error,
refetch,
};
}