fix(chat): query expert skills via symlinks and use $ prefix for Codex

Expert skills in the chat session were derived by intersecting built-in
experts with ACP availableCommands, which caused Codex experts to never
appear since Codex does not advertise skills through ACP.

- Add `experts_list_for_agent` backend API that checks symlink status
  across all global skill dirs for the given agent type
- Replace availableCommands-based expert filtering with symlink-based
  query, making the settings page the single source of truth
- Use `$` prefix for Codex expert skills while keeping `/` for slash
  commands and other agents' experts
- Disable the expert button when no experts are linked for the agent
- Invalidate per-agent expert cache after link/unlink in settings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
xintaofei
2026-04-11 00:13:42 +08:00
parent e4eb7f67eb
commit ade59f474c
11 changed files with 187 additions and 29 deletions

View File

@@ -1,5 +1,6 @@
import type { ReactNode } from "react"
import type {
AgentType,
ConnectionStatus,
PromptCapabilitiesInfo,
PromptDraft,
@@ -38,6 +39,7 @@ interface ConversationShellProps {
selectedModeId?: string | null
onModeChange?: (modeId: string) => void
onConfigOptionChange?: (configId: string, valueId: string) => void
agentType?: AgentType | null
availableCommands?: AvailableCommandInfo[] | null
attachmentTabId?: string | null
draftStorageKey?: string | null
@@ -78,6 +80,7 @@ export function ConversationShell({
selectedModeId,
onModeChange,
onConfigOptionChange,
agentType,
availableCommands,
attachmentTabId,
draftStorageKey,
@@ -123,6 +126,7 @@ export function ConversationShell({
selectedModeId={selectedModeId}
onModeChange={onModeChange}
onConfigOptionChange={onConfigOptionChange}
agentType={agentType}
availableCommands={availableCommands}
attachmentTabId={attachmentTabId}
draftStorageKey={draftStorageKey}