Skip to content

Commit 16085ac

Browse files
committed
Also load agents from ~/.agents
1 parent 9b31949 commit 16085ac

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

cli/src/utils/local-agent-registry.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import fs from 'fs'
2+
import os from 'os'
23
import path from 'path'
34

45
import { pluralize } from '@codebuff/common/util/string'
@@ -35,28 +36,45 @@ let userAgentFilePaths: Map<string, string> = new Map()
3536
/**
3637
* Initialize the agent registry by loading user agents via the SDK.
3738
* This must be called at CLI startup before any sync agent loading functions.
39+
*
40+
* Agents are loaded from:
41+
* - {cwd}/.agents (project)
42+
* - {cwd}/../.agents (parent, e.g. monorepo root)
43+
* - ~/.agents (global, user's home directory)
44+
*
45+
* Later directories take precedence, so project agents override global ones.
3846
*/
3947
export async function initializeAgentRegistry(): Promise<void> {
40-
const agentsDir = findAgentsDirectory()
41-
if (agentsDir) {
42-
try {
43-
userAgentsCache = await sdkLoadLocalAgents({ agentsPath: agentsDir })
44-
// Build ID-to-filepath map by scanning agent files
45-
userAgentFilePaths = buildAgentFilePathMap(agentsDir)
46-
} catch (error) {
47-
// Fall back to empty cache if SDK loading fails, but log a warning
48-
logger.warn({ error, agentsDir }, 'Failed to load user agents from .agents directory')
49-
userAgentsCache = {}
50-
userAgentFilePaths = new Map()
51-
}
48+
try {
49+
// Let SDK load from all default directories (cwd, parent, home)
50+
userAgentsCache = await sdkLoadLocalAgents({ verbose: false })
51+
// Build ID-to-filepath map by scanning all agent directories
52+
userAgentFilePaths = buildAgentFilePathMap(getDefaultAgentDirs())
53+
} catch (error) {
54+
// Fall back to empty cache if SDK loading fails, but log a warning
55+
logger.warn({ error }, 'Failed to load user agents from .agents directories')
56+
userAgentsCache = {}
57+
userAgentFilePaths = new Map()
5258
}
5359
}
5460

5561
/**
56-
* Scan agent directory and build a map from agent ID to source file path.
62+
* Get default agent directories to scan.
63+
* Matches the SDK's getDefaultAgentDirs() to ensure consistency.
64+
*/
65+
const getDefaultAgentDirs = (): string[] => {
66+
const cwdAgents = path.join(process.cwd(), AGENTS_DIR_NAME)
67+
const parentAgents = path.join(process.cwd(), '..', AGENTS_DIR_NAME)
68+
const homeAgents = path.join(os.homedir(), AGENTS_DIR_NAME)
69+
return [cwdAgents, parentAgents, homeAgents]
70+
}
71+
72+
/**
73+
* Scan agent directories and build a map from agent ID to source file path.
5774
* Uses regex to extract IDs from files without requiring module loading.
75+
* Later directories in the list take precedence (can override earlier ones).
5876
*/
59-
const buildAgentFilePathMap = (agentsDir: string): Map<string, string> => {
77+
const buildAgentFilePathMap = (agentsDirs: string[]): Map<string, string> => {
6078
const idToPath = new Map<string, string>()
6179
const idRegex = /id\s*:\s*['"`]([^'"`]+)['"`]/i
6280

@@ -87,7 +105,10 @@ const buildAgentFilePathMap = (agentsDir: string): Map<string, string> => {
87105
}
88106
}
89107

90-
scanDirectory(agentsDir)
108+
// Scan all directories - later directories override earlier ones
109+
for (const agentsDir of agentsDirs) {
110+
scanDirectory(agentsDir)
111+
}
91112
return idToPath
92113
}
93114

0 commit comments

Comments
 (0)