diff --git a/packages/ui/src/components/sections/agents/AgentsSidebar.tsx b/packages/ui/src/components/sections/agents/AgentsSidebar.tsx index d5e11faf..e83b0ca7 100644 --- a/packages/ui/src/components/sections/agents/AgentsSidebar.tsx +++ b/packages/ui/src/components/sections/agents/AgentsSidebar.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Button } from '@/components/ui/button'; import { ButtonLarge } from '@/components/ui/button-large'; import { Input } from '@/components/ui/input'; @@ -25,6 +25,7 @@ import { isVSCodeRuntime } from '@/lib/desktop'; import { cn } from '@/lib/utils'; import type { Agent } from '@opencode-ai/sdk/v2'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; +import { SidebarGroup } from '@/components/sections/shared/SidebarGroup'; interface AgentsSidebarProps { onItemSelect?: () => void; @@ -307,6 +308,25 @@ export const AgentsSidebar: React.FC = ({ onItemSelect }) => const builtInAgents = visibleAgents.filter(isAgentBuiltIn); const customAgents = visibleAgents.filter((agent) => !isAgentBuiltIn(agent)); + // Group custom agents by subfolder + const { groupedCustomAgents, ungroupedCustomAgents } = useMemo(() => { + const groups: Record = {}; + const ungrouped: typeof customAgents = []; + for (const agent of customAgents) { + const ext = agent as { group?: string }; + if (ext.group) { + if (!groups[ext.group]) groups[ext.group] = []; + groups[ext.group].push(agent); + } else { + ungrouped.push(agent); + } + } + const sortedGroups = Object.keys(groups) + .sort((a, b) => a.localeCompare(b)) + .map((name) => ({ name, agents: groups[name] })); + return { groupedCustomAgents: sortedGroups, ungroupedCustomAgents: ungrouped }; + }, [customAgents]); + return (
@@ -363,7 +383,38 @@ export const AgentsSidebar: React.FC = ({ onItemSelect }) =>
Custom Agents
- {customAgents.map((agent) => ( + + {/* Grouped agents by subfolder */} + {groupedCustomAgents.map(({ name: groupName, agents: groupAgents }) => ( + + {groupAgents.map((agent) => ( + { + setSelectedAgent(agent.name); + onItemSelect?.(); + if (isMobile) { + setSidebarOpen(false); + } + }} + onRename={() => handleOpenRenameDialog(agent)} + onDelete={() => handleDeleteAgent(agent)} + onDuplicate={() => handleDuplicateAgent(agent)} + getAgentModeIcon={getAgentModeIcon} + /> + ))} + + ))} + + {/* Ungrouped agents (flat in root agents dir) */} + {ungroupedCustomAgents.map((agent) => ( = ({ + label, + count, + storageKey, + defaultExpanded = true, + children, +}) => { + const key = getStorageKey(storageKey, label); + + const [expanded, setExpanded] = useState(() => { + try { + const stored = localStorage.getItem(key); + if (stored !== null) return stored === 'true'; + } catch { + // ignore storage errors + } + return defaultExpanded; + }); + + useEffect(() => { + try { + localStorage.setItem(key, String(expanded)); + } catch { + // ignore storage errors + } + }, [key, expanded]); + + return ( +
+ + + {expanded && ( +
+ {children} +
+ )} +
+ ); +}; diff --git a/packages/ui/src/components/sections/shared/index.ts b/packages/ui/src/components/sections/shared/index.ts index b6b36f44..787a5414 100644 --- a/packages/ui/src/components/sections/shared/index.ts +++ b/packages/ui/src/components/sections/shared/index.ts @@ -54,3 +54,4 @@ export { SettingsSidebarHeader } from './SettingsSidebarHeader'; export { SettingsSidebarItem, type SettingsSidebarItemAction } from './SettingsSidebarItem'; export { SettingsPageLayout } from './SettingsPageLayout'; export { SettingsSection } from './SettingsSection'; +export { SidebarGroup } from './SidebarGroup'; diff --git a/packages/ui/src/components/sections/skills/SkillsSidebar.tsx b/packages/ui/src/components/sections/skills/SkillsSidebar.tsx index 1ac9bb58..5316b48a 100644 --- a/packages/ui/src/components/sections/skills/SkillsSidebar.tsx +++ b/packages/ui/src/components/sections/skills/SkillsSidebar.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { Button } from '@/components/ui/button'; import { ButtonLarge } from '@/components/ui/button-large'; import { Input } from '@/components/ui/input'; @@ -24,6 +24,7 @@ import { useDeviceInfo } from '@/lib/device'; import { isVSCodeRuntime } from '@/lib/desktop'; import { cn } from '@/lib/utils'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; +import { SidebarGroup } from '@/components/sections/shared/SidebarGroup'; interface SkillsSidebarProps { onItemSelect?: () => void; @@ -190,6 +191,27 @@ export const SkillsSidebar: React.FC = ({ onItemSelect }) => const projectSkills = skills.filter((s) => s.scope === 'project'); const userSkills = skills.filter((s) => s.scope === 'user'); + // Helper: group a list of skills by their domain folder + function groupSkillsByFolder(list: DiscoveredSkill[]) { + const groups: Record = {}; + const ungrouped: DiscoveredSkill[] = []; + for (const skill of list) { + if (skill.group) { + if (!groups[skill.group]) groups[skill.group] = []; + groups[skill.group].push(skill); + } else { + ungrouped.push(skill); + } + } + const sortedGroups = Object.keys(groups) + .sort((a, b) => a.localeCompare(b)) + .map((name) => ({ name, skills: groups[name] })); + return { sortedGroups, ungrouped }; + } + + const groupedProjectSkills = useMemo(() => groupSkillsByFolder(projectSkills), [projectSkills]); + const groupedUserSkills = useMemo(() => groupSkillsByFolder(userSkills), [userSkills]); + return (
@@ -221,7 +243,33 @@ export const SkillsSidebar: React.FC = ({ onItemSelect }) =>
Project Skills
- {projectSkills.map((skill) => ( + {groupedProjectSkills.sortedGroups.map(({ name: groupName, skills: groupSkills }) => ( + + {groupSkills.map((skill) => ( + { + setSelectedSkill(skill.name); + onItemSelect?.(); + if (isMobile) { + setSidebarOpen(false); + } + }} + onRename={() => handleOpenRenameDialog(skill)} + onDelete={() => handleDeleteSkill(skill)} + onDuplicate={() => handleDuplicateSkill(skill)} + /> + ))} + + ))} + {groupedProjectSkills.ungrouped.map((skill) => ( = ({ onItemSelect }) =>
User Skills
- {userSkills.map((skill) => ( + {groupedUserSkills.sortedGroups.map(({ name: groupName, skills: groupSkills }) => ( + + {groupSkills.map((skill) => ( + { + setSelectedSkill(skill.name); + onItemSelect?.(); + if (isMobile) { + setSidebarOpen(false); + } + }} + onRename={() => handleOpenRenameDialog(skill)} + onDelete={() => handleDeleteSkill(skill)} + onDuplicate={() => handleDuplicateSkill(skill)} + /> + ))} + + ))} + {groupedUserSkills.ungrouped.map((skill) => ( 1 ? parts[0] : undefined; +} + // Helper to check if agent is built-in (handles both SDK 'builtIn' and API 'native') export const isAgentBuiltIn = (agent: Agent): boolean => { const extended = agent as AgentWithExtras & { builtIn?: boolean }; @@ -202,12 +220,16 @@ export const useAgentsStore = create()( ?? sources.json?.scope; } + // Parse subfolder group from file path + const mdPath: string | null | undefined = data.sources?.md?.path; + const group = parseAgentGroup(mdPath); + if (scope === 'project' || scope === 'user') { - return { ...agent, scope: scope as AgentScope }; + return { ...agent, scope: scope as AgentScope, group }; } // Explicitly set null scope if not found, to clear stale state - return { ...agent, scope: undefined }; + return { ...agent, scope: undefined, group }; } } catch (err) { console.warn(`[AgentsStore] Failed to fetch config for agent ${agent.name}:`, err); diff --git a/packages/ui/src/stores/useSkillsStore.ts b/packages/ui/src/stores/useSkillsStore.ts index c4229c42..c3bcfd14 100644 --- a/packages/ui/src/stores/useSkillsStore.ts +++ b/packages/ui/src/stores/useSkillsStore.ts @@ -64,6 +64,23 @@ export interface DiscoveredSkill { scope: SkillScope; source: SkillSource; description?: string; + /** Domain folder parsed from file path, e.g. "automation-ai", "lark-ecosystem" */ + group?: string; +} + +/** Parse the domain group folder from a skill file path. + * e.g. "~/.config/opencode/skills/automation-ai/ai-production/SKILL.md" → "automation-ai" + * e.g. "~/.config/opencode/skills/theme-system/SKILL.md" → undefined (flat) + */ +function parseSkillGroup(path: string): string | undefined { + const normalizedPath = path.replace(/\\/g, '/'); + const idx = normalizedPath.lastIndexOf('/skills/'); + if (idx === -1) return undefined; + const relative = normalizedPath.substring(idx + '/skills/'.length); + const parts = relative.split('/'); + // Grouped layout: //SKILL.md → parts.length >= 3 + // Flat layout: /SKILL.md → parts.length == 2 + return parts.length >= 3 ? parts[0] : undefined; } // Raw skill response from API before transformation @@ -185,6 +202,7 @@ export const useSkillsStore = create()( scope: s.scope ?? 'user', source: s.source ?? 'opencode', description: s.sources?.md?.description || '', + group: parseSkillGroup(s.path), })); set({ skills, isLoading: false }); diff --git a/packages/vscode/src/opencodeConfig.ts b/packages/vscode/src/opencodeConfig.ts index 88f319e2..d91f9bb8 100644 --- a/packages/vscode/src/opencodeConfig.ts +++ b/packages/vscode/src/opencodeConfig.ts @@ -61,14 +61,104 @@ const getProjectAgentPath = (workingDirectory: string, agentName: string): strin return pluralPath; }; -const getUserAgentPath = (agentName: string): string => { +type AgentLookupCache = { + userAgentIndexByName: Map; + userAgentLookupByName: Map; + userAgentIndexReady: boolean; + userAgentIndexBuiltAt: number; +}; + +const AGENT_LOOKUP_CACHE_TTL_MS = 1000; + +const createAgentLookupCache = (): AgentLookupCache => ({ + userAgentIndexByName: new Map(), + userAgentLookupByName: new Map(), + userAgentIndexReady: false, + userAgentIndexBuiltAt: 0, +}); + +const globalAgentLookupCache = createAgentLookupCache(); + +const resetAgentLookupCache = (cache: AgentLookupCache): void => { + cache.userAgentIndexByName.clear(); + cache.userAgentLookupByName.clear(); + cache.userAgentIndexReady = false; + cache.userAgentIndexBuiltAt = 0; +}; + +const buildUserAgentIndex = (cache: AgentLookupCache): void => { + if (cache.userAgentIndexReady && Date.now() - cache.userAgentIndexBuiltAt < AGENT_LOOKUP_CACHE_TTL_MS) { + return; + } + + cache.userAgentIndexByName.clear(); + cache.userAgentLookupByName.clear(); + cache.userAgentIndexReady = true; + cache.userAgentIndexBuiltAt = Date.now(); + + if (!fs.existsSync(AGENT_DIR)) return; + + const dirsToVisit: string[] = [AGENT_DIR]; + while (dirsToVisit.length > 0) { + const dir = dirsToVisit.pop(); + if (!dir) continue; + + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch { + continue; + } + + entries.sort((a, b) => a.name.localeCompare(b.name)); + + for (const entry of entries) { + if (!entry.isFile() || !entry.name.endsWith('.md')) continue; + const discoveredAgentName = entry.name.slice(0, -3); + if (!cache.userAgentIndexByName.has(discoveredAgentName)) { + cache.userAgentIndexByName.set(discoveredAgentName, path.join(dir, entry.name)); + } + } + + for (let i = entries.length - 1; i >= 0; i -= 1) { + const entry = entries[i]; + if (entry?.isDirectory()) { + dirsToVisit.push(path.join(dir, entry.name)); + } + } + } +}; + +const getIndexedUserAgentPath = (agentName: string, cache: AgentLookupCache): string | null => { + if (cache.userAgentLookupByName.has(agentName)) { + return cache.userAgentLookupByName.get(agentName) || null; + } + + buildUserAgentIndex(cache); + const found = cache.userAgentIndexByName.get(agentName) || null; + cache.userAgentLookupByName.set(agentName, found); + return found; +}; + +const getUserAgentPath = (agentName: string, lookupCache: AgentLookupCache = globalAgentLookupCache): string => { const pluralPath = path.join(AGENT_DIR, `${agentName}.md`); + + if (fs.existsSync(pluralPath)) return pluralPath; + const legacyPath = path.join(OPENCODE_CONFIG_DIR, 'agent', `${agentName}.md`); - if (fs.existsSync(legacyPath) && !fs.existsSync(pluralPath)) return legacyPath; + if (fs.existsSync(legacyPath)) return legacyPath; + + const found = getIndexedUserAgentPath(agentName, lookupCache); + if (found) return found; + return pluralPath; }; -export const getAgentScope = (agentName: string, workingDirectory?: string): { scope: AgentScope | null; path: string | null } => { +export const getAgentScope = ( + agentName: string, + workingDirectory?: string, + lookupCache: AgentLookupCache = globalAgentLookupCache +): { scope: AgentScope | null; path: string | null } => { if (workingDirectory) { const projectPath = getProjectAgentPath(workingDirectory, agentName); if (fs.existsSync(projectPath)) { @@ -76,7 +166,7 @@ export const getAgentScope = (agentName: string, workingDirectory?: string): { s } } - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); if (fs.existsSync(userPath)) { return { scope: AGENT_SCOPE.USER, path: userPath }; } @@ -84,8 +174,13 @@ export const getAgentScope = (agentName: string, workingDirectory?: string): { s return { scope: null, path: null }; }; -const getAgentWritePath = (agentName: string, workingDirectory?: string, requestedScope?: AgentScope): { scope: AgentScope; path: string } => { - const existing = getAgentScope(agentName, workingDirectory); +const getAgentWritePath = ( + agentName: string, + workingDirectory?: string, + requestedScope?: AgentScope, + lookupCache: AgentLookupCache = globalAgentLookupCache +): { scope: AgentScope; path: string } => { + const existing = getAgentScope(agentName, workingDirectory, lookupCache); if (existing.path) { return { scope: existing.scope!, path: existing.path }; } @@ -100,7 +195,7 @@ const getAgentWritePath = (agentName: string, workingDirectory?: string, request return { scope: AGENT_SCOPE.USER, - path: getUserAgentPath(agentName) + path: getUserAgentPath(agentName, lookupCache) }; }; @@ -703,6 +798,7 @@ export const createAgent = (agentName: string, config: Record, const { prompt, scope: _ignored, ...frontmatter } = config as Record & { prompt?: unknown; scope?: unknown }; void _ignored; // Scope is only used for path determination writeMdFile(targetPath, frontmatter, typeof prompt === 'string' ? prompt : ''); + resetAgentLookupCache(globalAgentLookupCache); }; export const updateAgent = (agentName: string, updates: Record, workingDirectory?: string) => { @@ -807,6 +903,10 @@ export const updateAgent = (agentName: string, updates: Record, if (jsonModified) { writeConfig(config, jsonTarget.path || CONFIG_FILE); } + + if (mdModified || isBuiltinOverride) { + resetAgentLookupCache(globalAgentLookupCache); + } }; export const deleteAgent = (agentName: string, workingDirectory?: string) => { @@ -849,6 +949,8 @@ export const deleteAgent = (agentName: string, workingDirectory?: string) => { targetConfig.agent = agentMap; writeConfig(targetConfig, jsonTarget.path || CONFIG_FILE); } + + resetAgentLookupCache(globalAgentLookupCache); }; export const getCommandSources = (commandName: string, workingDirectory?: string): ConfigSources => { diff --git a/packages/web/server/lib/opencode/agents.js b/packages/web/server/lib/opencode/agents.js index 3ce16021..2db6995d 100644 --- a/packages/web/server/lib/opencode/agents.js +++ b/packages/web/server/lib/opencode/agents.js @@ -45,12 +45,80 @@ function getProjectAgentPath(workingDirectory, agentName) { } /** - * Get user-level agent path + * Create a per-request lookup cache for user-level agent path resolution. */ -function getUserAgentPath(agentName) { +function createAgentLookupCache() { + return { + userAgentIndexByName: new Map(), + userAgentLookupByName: new Map(), + userAgentIndexReady: false, + }; +} + +function buildUserAgentIndex(cache) { + if (cache.userAgentIndexReady) return; + cache.userAgentIndexReady = true; + + if (!fs.existsSync(AGENT_DIR)) return; + + const dirsToVisit = [AGENT_DIR]; + while (dirsToVisit.length > 0) { + const dir = dirsToVisit.pop(); + let entries; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch { + continue; + } + + entries.sort((a, b) => a.name.localeCompare(b.name)); + + for (const entry of entries) { + if (!entry.isFile() || !entry.name.endsWith('.md')) continue; + const agentName = entry.name.slice(0, -3); + if (!cache.userAgentIndexByName.has(agentName)) { + cache.userAgentIndexByName.set(agentName, path.join(dir, entry.name)); + } + } + + for (let i = entries.length - 1; i >= 0; i -= 1) { + const entry = entries[i]; + if (entry.isDirectory()) { + dirsToVisit.push(path.join(dir, entry.name)); + } + } + } +} + +function getIndexedUserAgentPath(agentName, cache) { + if (cache.userAgentLookupByName.has(agentName)) { + return cache.userAgentLookupByName.get(agentName); + } + + buildUserAgentIndex(cache); + const found = cache.userAgentIndexByName.get(agentName) || null; + cache.userAgentLookupByName.set(agentName, found); + return found; +} + +/** + * Get user-level agent path — walks subfolders to support grouped layouts. + * e.g. ~/.config/opencode/agents/business/ceo-diginno.md + */ +function getUserAgentPath(agentName, lookupCache = null) { + // 1. Check flat path first (legacy / newly created agents) const pluralPath = path.join(AGENT_DIR, `${agentName}.md`); + if (fs.existsSync(pluralPath)) return pluralPath; + const legacyPath = path.join(AGENT_DIR, '..', 'agent', `${agentName}.md`); - if (fs.existsSync(legacyPath) && !fs.existsSync(pluralPath)) return legacyPath; + if (fs.existsSync(legacyPath)) return legacyPath; + + // 2. Lookup subfolders for grouped layout + const cache = lookupCache || createAgentLookupCache(); + const found = getIndexedUserAgentPath(agentName, cache); + if (found) return found; + + // 3. Return expected flat path as default (for new agent creation) return pluralPath; } @@ -58,7 +126,7 @@ function getUserAgentPath(agentName) { * Determine agent scope based on where the .md file exists * Priority: project level > user level > null (built-in only) */ -function getAgentScope(agentName, workingDirectory) { +function getAgentScope(agentName, workingDirectory, lookupCache = null) { if (workingDirectory) { const projectPath = getProjectAgentPath(workingDirectory, agentName); if (fs.existsSync(projectPath)) { @@ -66,7 +134,7 @@ function getAgentScope(agentName, workingDirectory) { } } - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); if (fs.existsSync(userPath)) { return { scope: AGENT_SCOPE.USER, path: userPath }; } @@ -77,9 +145,9 @@ function getAgentScope(agentName, workingDirectory) { /** * Get the path where an agent should be written based on scope */ -function getAgentWritePath(agentName, workingDirectory, requestedScope) { +function getAgentWritePath(agentName, workingDirectory, requestedScope, lookupCache = null) { // For updates: check existing location first (project takes precedence) - const existing = getAgentScope(agentName, workingDirectory); + const existing = getAgentScope(agentName, workingDirectory, lookupCache); if (existing.path) { return existing; } @@ -95,7 +163,7 @@ function getAgentWritePath(agentName, workingDirectory, requestedScope) { return { scope: AGENT_SCOPE.USER, - path: getUserAgentPath(agentName) + path: getUserAgentPath(agentName, lookupCache) }; } @@ -104,7 +172,7 @@ function getAgentWritePath(agentName, workingDirectory, requestedScope) { * Priority: project .md > user .md > project JSON > user JSON * Returns: { source: 'md'|'json'|null, scope: 'project'|'user'|null, path: string|null } */ -function getAgentPermissionSource(agentName, workingDirectory) { +function getAgentPermissionSource(agentName, workingDirectory, lookupCache = null) { // Check project-level .md first if (workingDirectory) { const projectMdPath = getProjectAgentPath(workingDirectory, agentName); @@ -117,7 +185,7 @@ function getAgentPermissionSource(agentName, workingDirectory) { } // Check user-level .md - const userMdPath = getUserAgentPath(agentName); + const userMdPath = getUserAgentPath(agentName, lookupCache); if (fs.existsSync(userMdPath)) { const { frontmatter } = parseMdFile(userMdPath); if (frontmatter.permission !== undefined) { @@ -215,11 +283,11 @@ function mergePermissionWithNonWildcards(newPermission, permissionSource, agentN return merged; } -function getAgentSources(agentName, workingDirectory) { +function getAgentSources(agentName, workingDirectory, lookupCache = createAgentLookupCache()) { const projectPath = workingDirectory ? getProjectAgentPath(workingDirectory, agentName) : null; const projectExists = projectPath && fs.existsSync(projectPath); - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); const userExists = fs.existsSync(userPath); const mdPath = projectExists ? projectPath : (userExists ? userPath : null); @@ -270,11 +338,11 @@ function getAgentSources(agentName, workingDirectory) { return sources; } -function getAgentConfig(agentName, workingDirectory) { +function getAgentConfig(agentName, workingDirectory, lookupCache = createAgentLookupCache()) { const projectPath = workingDirectory ? getProjectAgentPath(workingDirectory, agentName) : null; const projectExists = projectPath && fs.existsSync(projectPath); - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); const userExists = fs.existsSync(userPath); if (projectExists || userExists) { @@ -312,9 +380,10 @@ function getAgentConfig(agentName, workingDirectory) { function createAgent(agentName, config, workingDirectory, scope) { ensureDirs(); + const lookupCache = createAgentLookupCache(); const projectPath = workingDirectory ? getProjectAgentPath(workingDirectory, agentName) : null; - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); if (projectPath && fs.existsSync(projectPath)) { throw new Error(`Agent ${agentName} already exists as project-level .md file`); @@ -350,8 +419,9 @@ function createAgent(agentName, config, workingDirectory, scope) { function updateAgent(agentName, updates, workingDirectory) { ensureDirs(); + const lookupCache = createAgentLookupCache(); - const { scope, path: mdPath } = getAgentWritePath(agentName, workingDirectory); + const { scope, path: mdPath } = getAgentWritePath(agentName, workingDirectory, undefined, lookupCache); const mdExists = mdPath && fs.existsSync(mdPath); const layers = readConfigLayers(workingDirectory); @@ -369,7 +439,7 @@ function updateAgent(agentName, updates, workingDirectory) { let targetScope = scope; if (!mdExists && isBuiltinOverride) { - targetPath = getUserAgentPath(agentName); + targetPath = getUserAgentPath(agentName, lookupCache); targetScope = AGENT_SCOPE.USER; } @@ -412,7 +482,7 @@ function updateAgent(agentName, updates, workingDirectory) { } if (field === 'permission') { - const permissionSource = getAgentPermissionSource(agentName, workingDirectory); + const permissionSource = getAgentPermissionSource(agentName, workingDirectory, lookupCache); const newPermission = mergePermissionWithNonWildcards(value, permissionSource, agentName); if (permissionSource.source === 'md') { @@ -510,6 +580,7 @@ function updateAgent(agentName, updates, workingDirectory) { } function deleteAgent(agentName, workingDirectory) { + const lookupCache = createAgentLookupCache(); let deleted = false; if (workingDirectory) { @@ -521,7 +592,7 @@ function deleteAgent(agentName, workingDirectory) { } } - const userPath = getUserAgentPath(agentName); + const userPath = getUserAgentPath(agentName, lookupCache); if (fs.existsSync(userPath)) { fs.unlinkSync(userPath); console.log(`Deleted user-level agent .md file: ${userPath}`);