fix(project): use directory param instead of process.cwd() for agents, commands, and slash commands

Extends the process.cwd() fix to cover all project-level loaders. In the desktop app, process.cwd() points to the app installation directory instead of the project directory, causing project-level agents, commands, and slash commands to not be discovered. Each function now accepts an optional directory parameter (defaulting to process.cwd() for backward compatibility) and callers pass ctx.directory from the plugin context.
This commit is contained in:
Willy
2026-02-13 11:09:35 +08:00
parent 6914f2fd04
commit f9ea9a4ee9
6 changed files with 18 additions and 18 deletions

View File

@@ -78,8 +78,8 @@ export function loadUserAgents(): Record<string, AgentConfig> {
return result
}
export function loadProjectAgents(): Record<string, AgentConfig> {
const projectAgentsDir = join(process.cwd(), ".claude", "agents")
export function loadProjectAgents(directory?: string): Record<string, AgentConfig> {
const projectAgentsDir = join(directory ?? process.cwd(), ".claude", "agents")
const agents = loadAgentsFromDir(projectAgentsDir, "project")
const result: Record<string, AgentConfig> = {}

View File

@@ -114,8 +114,8 @@ export async function loadUserCommands(): Promise<Record<string, CommandDefiniti
return commandsToRecord(commands)
}
export async function loadProjectCommands(): Promise<Record<string, CommandDefinition>> {
const projectCommandsDir = join(process.cwd(), ".claude", "commands")
export async function loadProjectCommands(directory?: string): Promise<Record<string, CommandDefinition>> {
const projectCommandsDir = join(directory ?? process.cwd(), ".claude", "commands")
const commands = await loadCommandsFromDir(projectCommandsDir, "project")
return commandsToRecord(commands)
}
@@ -127,18 +127,18 @@ export async function loadOpencodeGlobalCommands(): Promise<Record<string, Comma
return commandsToRecord(commands)
}
export async function loadOpencodeProjectCommands(): Promise<Record<string, CommandDefinition>> {
const opencodeProjectDir = join(process.cwd(), ".opencode", "command")
export async function loadOpencodeProjectCommands(directory?: string): Promise<Record<string, CommandDefinition>> {
const opencodeProjectDir = join(directory ?? process.cwd(), ".opencode", "command")
const commands = await loadCommandsFromDir(opencodeProjectDir, "opencode-project")
return commandsToRecord(commands)
}
export async function loadAllCommands(): Promise<Record<string, CommandDefinition>> {
export async function loadAllCommands(directory?: string): Promise<Record<string, CommandDefinition>> {
const [user, project, global, projectOpencode] = await Promise.all([
loadUserCommands(),
loadProjectCommands(),
loadProjectCommands(directory),
loadOpencodeGlobalCommands(),
loadOpencodeProjectCommands(),
loadOpencodeProjectCommands(directory),
])
return { ...projectOpencode, ...global, ...project, ...user }
}

View File

@@ -84,7 +84,7 @@ export async function applyAgentConfig(params: {
const includeClaudeAgents = params.pluginConfig.claude_code?.agents ?? true;
const userAgents = includeClaudeAgents ? loadUserAgents() : {};
const projectAgents = includeClaudeAgents ? loadProjectAgents() : {};
const projectAgents = includeClaudeAgents ? loadProjectAgents(params.ctx.directory) : {};
const rawPluginAgents = params.pluginComponents.agents;
const pluginAgents = Object.fromEntries(

View File

@@ -44,13 +44,13 @@ export async function applyCommandConfig(params: {
configDir: params.ctx.directory,
}),
includeClaudeCommands ? loadUserCommands() : Promise.resolve({}),
includeClaudeCommands ? loadProjectCommands() : Promise.resolve({}),
includeClaudeCommands ? loadProjectCommands(params.ctx.directory) : Promise.resolve({}),
loadOpencodeGlobalCommands(),
loadOpencodeProjectCommands(),
loadOpencodeProjectCommands(params.ctx.directory),
includeClaudeSkills ? loadUserSkills() : Promise.resolve({}),
includeClaudeSkills ? loadProjectSkills() : Promise.resolve({}),
includeClaudeSkills ? loadProjectSkills(params.ctx.directory) : Promise.resolve({}),
loadOpencodeGlobalSkills(),
loadOpencodeProjectSkills(),
loadOpencodeProjectSkills(params.ctx.directory),
]);
params.config.command = {

View File

@@ -101,7 +101,7 @@ export function createToolRegistry(args: {
getSessionID: getSessionIDForMcp,
})
const commands = discoverCommandsSync()
const commands = discoverCommandsSync(ctx.directory)
const slashcommandTool = createSlashcommandTool({
commands,
skills: skillContext.mergedSkills,

View File

@@ -48,12 +48,12 @@ function discoverCommandsFromDir(commandsDir: string, scope: CommandScope): Comm
return commands
}
export function discoverCommandsSync(): CommandInfo[] {
export function discoverCommandsSync(directory?: string): CommandInfo[] {
const configDir = getOpenCodeConfigDir({ binary: "opencode" })
const userCommandsDir = join(getClaudeConfigDir(), "commands")
const projectCommandsDir = join(process.cwd(), ".claude", "commands")
const projectCommandsDir = join(directory ?? process.cwd(), ".claude", "commands")
const opencodeGlobalDir = join(configDir, "command")
const opencodeProjectDir = join(process.cwd(), ".opencode", "command")
const opencodeProjectDir = join(directory ?? process.cwd(), ".opencode", "command")
const userCommands = discoverCommandsFromDir(userCommandsDir, "user")
const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode")