Files
superwork/vscode/webview-ui/src/hooks/useManagedSessions.ts
T

95 lines
3.4 KiB
TypeScript

/**
* 项目 Claude 会话管理器的订阅 hook。
*
* - mount 时 postMessage `managed-sessions/get` 拉取一次
* - 监听 `managed-sessions/show` 同步主进程状态(全量列表)
* - `createManagedSession(profilePath, prompt?)` 让主进程开 cc 终端并捕获会话
* - `renameManagedSession(id, name)` / `resumeManagedSession(id)` / `deleteManagedSession(id)`
* 都把动作委托给主进程,列表由后续 `managed-sessions/show` 更新
*/
import type { ManagedSessionsData } from '../types'
import { useCallback, useEffect, useState } from 'react'
import { onMessage, postMessage } from '../lib/vscode'
export interface ImportableNamedSession {
id: string
name: string
mtimeMs: number
}
export interface UseManagedSessionsResult {
managedSessions: ManagedSessionsData
createManagedSession: (profilePath: string, name?: string, prompt?: string) => void
renameManagedSession: (id: string, name: string) => void
resumeManagedSession: (id: string, profilePath?: string) => void
deleteManagedSession: (id: string) => void
closeManagedSessionTab: (id: string) => void
listImportableNamedSessions: () => void
importNamedSession: (sessionId: string, name: string) => void
importableSessions: ImportableNamedSession[]
importableLoading: boolean
}
export function useManagedSessions(): UseManagedSessionsResult {
const [managedSessions, setManagedSessions] = useState<ManagedSessionsData>({ sessions: [] })
const [importableSessions, setImportableSessions] = useState<ImportableNamedSession[]>([])
const [importableLoading, setImportableLoading] = useState(false)
useEffect(() => {
const cleanup = onMessage((msg) => {
if (msg.type === 'managed-sessions/show')
setManagedSessions(msg.data)
if (msg.type === 'managed-sessions/importable') {
setImportableSessions(msg.sessions)
setImportableLoading(false)
}
})
postMessage({ type: 'managed-sessions/get' })
return cleanup
}, [])
const createManagedSession = useCallback((profilePath: string, name?: string, prompt?: string): void => {
postMessage({ type: 'managed-sessions/create', profilePath, name, prompt })
}, [])
const renameManagedSession = useCallback((id: string, name: string): void => {
postMessage({ type: 'managed-sessions/rename', sessionId: id, name })
}, [])
const resumeManagedSession = useCallback((id: string, profilePath?: string): void => {
postMessage({ type: 'managed-sessions/resume', sessionId: id, profilePath })
}, [])
const deleteManagedSession = useCallback((id: string): void => {
postMessage({ type: 'managed-sessions/delete', sessionId: id })
}, [])
const closeManagedSessionTab = useCallback((id: string): void => {
postMessage({ type: 'managed-sessions/close-tab', sessionId: id })
}, [])
const listImportableNamedSessions = useCallback((): void => {
setImportableLoading(true)
setImportableSessions([])
postMessage({ type: 'managed-sessions/list-importable' })
}, [])
const importNamedSession = useCallback((sessionId: string, name: string): void => {
postMessage({ type: 'managed-sessions/import', sessionId, name })
}, [])
return {
managedSessions,
createManagedSession,
renameManagedSession,
resumeManagedSession,
deleteManagedSession,
closeManagedSessionTab,
listImportableNamedSessions,
importNamedSession,
importableSessions,
importableLoading,
}
}