perf(startup): parallelize command and skill loading in config-handler

- Add async versions of skill loader functions (loadUserSkillsAsync, loadProjectSkillsAsync, loadOpencodeGlobalSkillsAsync, loadOpencodeProjectSkillsAsync)
- Use Promise.all to load 8 loaders concurrently instead of sequentially
- Improves startup performance by eliminating serial I/O bottlenecks

Generated with assistance of OhMyOpenCode
This commit is contained in:
YeonGyu-Kim
2026-01-05 14:03:17 +09:00
parent 6b5a8263f9
commit fe11ba294c
2 changed files with 67 additions and 24 deletions

View File

@@ -340,6 +340,42 @@ export function loadOpencodeProjectSkills(): Record<string, CommandDefinition> {
return skillsToRecord(skills)
}
/**
* Async version of loadUserSkills
*/
export async function loadUserSkillsAsync(): Promise<Record<string, CommandDefinition>> {
const userSkillsDir = join(getClaudeConfigDir(), "skills")
const skills = await loadSkillsFromDirAsync(userSkillsDir, "user")
return skillsToRecord(skills)
}
/**
* Async version of loadProjectSkills
*/
export async function loadProjectSkillsAsync(): Promise<Record<string, CommandDefinition>> {
const projectSkillsDir = join(process.cwd(), ".claude", "skills")
const skills = await loadSkillsFromDirAsync(projectSkillsDir, "project")
return skillsToRecord(skills)
}
/**
* Async version of loadOpencodeGlobalSkills
*/
export async function loadOpencodeGlobalSkillsAsync(): Promise<Record<string, CommandDefinition>> {
const opencodeSkillsDir = join(homedir(), ".config", "opencode", "skill")
const skills = await loadSkillsFromDirAsync(opencodeSkillsDir, "opencode")
return skillsToRecord(skills)
}
/**
* Async version of loadOpencodeProjectSkills
*/
export async function loadOpencodeProjectSkillsAsync(): Promise<Record<string, CommandDefinition>> {
const opencodeProjectDir = join(process.cwd(), ".opencode", "skill")
const skills = await loadSkillsFromDirAsync(opencodeProjectDir, "opencode-project")
return skillsToRecord(skills)
}
/**
* Discover all skills from all sources with priority ordering.
* Priority order: opencode-project > project > opencode > user

View File

@@ -1,16 +1,16 @@
import { createBuiltinAgents } from "../agents";
import {
loadUserCommands,
loadProjectCommands,
loadOpencodeGlobalCommands,
loadOpencodeProjectCommands,
loadUserCommandsAsync,
loadProjectCommandsAsync,
loadOpencodeGlobalCommandsAsync,
loadOpencodeProjectCommandsAsync,
} from "../features/claude-code-command-loader";
import { loadBuiltinCommands } from "../features/builtin-commands";
import {
loadUserSkills,
loadProjectSkills,
loadOpencodeGlobalSkills,
loadOpencodeProjectSkills,
loadUserSkillsAsync,
loadProjectSkillsAsync,
loadOpencodeGlobalSkillsAsync,
loadOpencodeProjectSkillsAsync,
} from "../features/opencode-skill-loader";
import {
loadUserAgents,
@@ -282,24 +282,31 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
};
const builtinCommands = loadBuiltinCommands(pluginConfig.disabled_commands);
const userCommands = (pluginConfig.claude_code?.commands ?? true)
? loadUserCommands()
: {};
const opencodeGlobalCommands = loadOpencodeGlobalCommands();
const systemCommands = (config.command as Record<string, unknown>) ?? {};
const projectCommands = (pluginConfig.claude_code?.commands ?? true)
? loadProjectCommands()
: {};
const opencodeProjectCommands = loadOpencodeProjectCommands();
const userSkills = (pluginConfig.claude_code?.skills ?? true)
? loadUserSkills()
: {};
const projectSkills = (pluginConfig.claude_code?.skills ?? true)
? loadProjectSkills()
: {};
const opencodeGlobalSkills = loadOpencodeGlobalSkills();
const opencodeProjectSkills = loadOpencodeProjectSkills();
// Parallel loading of all commands and skills for faster startup
const includeClaudeCommands = pluginConfig.claude_code?.commands ?? true;
const includeClaudeSkills = pluginConfig.claude_code?.skills ?? true;
const [
userCommands,
projectCommands,
opencodeGlobalCommands,
opencodeProjectCommands,
userSkills,
projectSkills,
opencodeGlobalSkills,
opencodeProjectSkills,
] = await Promise.all([
includeClaudeCommands ? loadUserCommandsAsync() : Promise.resolve({}),
includeClaudeCommands ? loadProjectCommandsAsync() : Promise.resolve({}),
loadOpencodeGlobalCommandsAsync(),
loadOpencodeProjectCommandsAsync(),
includeClaudeSkills ? loadUserSkillsAsync() : Promise.resolve({}),
includeClaudeSkills ? loadProjectSkillsAsync() : Promise.resolve({}),
loadOpencodeGlobalSkillsAsync(),
loadOpencodeProjectSkillsAsync(),
]);
config.command = {
...builtinCommands,