cc-haha/desktop/src/stores/agentStore.ts
程序员阿江(Relakkes) de736c49f7 Unify plugin capabilities with the desktop management views
Desktop plugin details now route into the shared Skills, Agents, and MCP management surfaces instead of maintaining separate read-only drilldowns. This also extends the desktop/server skill aggregation so plugin-provided skills appear in the shared list, groups MCP entries by source, and preserves detail-view back navigation based on where the user entered the page.

The implementation keeps plugin detail as the high-level capability hub while pushing real inspection into the existing management pages. Disabled plugins no longer expose false navigation paths into shared views, and the agent-browser regression script was expanded to exercise the new end-to-end flows.

Constraint: Shared Agents data only includes enabled plugin agents, so disabled plugins cannot deep-link into agent detail
Rejected: Keep duplicating full Skills/Agents/MCP detail inside Plugin detail | creates divergent UI flows and stale data paths
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: If a detail view can be opened from multiple entry points, keep the return target in store state rather than hardcoding a single back destination
Tested: desktop vitest for plugins/skills/agents/mcp; desktop tsc --noEmit; desktop vite build; server skills API test; agent-browser web regression on plugin->skill/mcp and plugin->agent back navigation
Not-tested: packaged desktop app regression after rebuilding the Tauri bundle
2026-04-22 12:31:57 +08:00

46 lines
1.2 KiB
TypeScript

import { create } from 'zustand'
import { agentsApi, type AgentDefinition } from '../api/agents'
export type AgentDetailReturnTab = 'agents' | 'plugins'
type AgentStore = {
activeAgents: AgentDefinition[]
allAgents: AgentDefinition[]
isLoading: boolean
error: string | null
selectedAgent: AgentDefinition | null
selectedAgentReturnTab: AgentDetailReturnTab
fetchAgents: (cwd?: string) => Promise<void>
selectAgent: (
agent: AgentDefinition | null,
returnTab?: AgentDetailReturnTab,
) => void
}
export const useAgentStore = create<AgentStore>((set) => ({
activeAgents: [],
allAgents: [],
isLoading: false,
error: null,
selectedAgent: null,
selectedAgentReturnTab: 'agents',
fetchAgents: async (cwd) => {
set({ isLoading: true, error: null })
try {
const { activeAgents, allAgents } = await agentsApi.list(cwd)
set({ activeAgents, allAgents, isLoading: false })
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to load agents'
set({ isLoading: false, error: message })
}
},
selectAgent: (agent, returnTab = 'agents') =>
set({
selectedAgent: agent,
selectedAgentReturnTab: agent ? returnTab : 'agents',
}),
}))