fix(claude-code-command-loader): skip EXCLUDED_DIRS and memoize per directory
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import { promises as fs } from "fs"
|
||||
import { resolve } from "path"
|
||||
|
||||
import type { CommandDefinition } from "./types"
|
||||
|
||||
const commandLoaderCache = new Map<string, Promise<Record<string, CommandDefinition>>>()
|
||||
|
||||
export async function getCommandLoaderCacheKey(directory?: string): Promise<string> {
|
||||
const resolvedDirectory = resolve(directory ?? process.cwd())
|
||||
|
||||
try {
|
||||
return await fs.realpath(resolvedDirectory)
|
||||
} catch {
|
||||
return resolvedDirectory
|
||||
}
|
||||
}
|
||||
|
||||
export function getCachedCommands(
|
||||
cacheKey: string,
|
||||
): Promise<Record<string, CommandDefinition>> | undefined {
|
||||
return commandLoaderCache.get(cacheKey)
|
||||
}
|
||||
|
||||
export function setCachedCommands(
|
||||
cacheKey: string,
|
||||
commands: Promise<Record<string, CommandDefinition>>,
|
||||
): void {
|
||||
commandLoaderCache.set(cacheKey, commands)
|
||||
}
|
||||
|
||||
export function deleteCachedCommands(cacheKey: string): void {
|
||||
commandLoaderCache.delete(cacheKey)
|
||||
}
|
||||
|
||||
export function clearCommandLoaderCache(): void {
|
||||
commandLoaderCache.clear()
|
||||
}
|
||||
@@ -4,13 +4,23 @@ import { parseFrontmatter } from "../../shared/frontmatter"
|
||||
import { sanitizeModelField } from "../../shared/model-sanitizer"
|
||||
import { isMarkdownFile } from "../../shared/file-utils"
|
||||
import {
|
||||
EXCLUDED_DIRS,
|
||||
findProjectOpencodeCommandDirs,
|
||||
getClaudeConfigDir,
|
||||
getOpenCodeCommandDirs,
|
||||
} from "../../shared"
|
||||
import { log } from "../../shared/logger"
|
||||
import {
|
||||
clearCommandLoaderCache,
|
||||
deleteCachedCommands,
|
||||
getCachedCommands,
|
||||
getCommandLoaderCacheKey,
|
||||
setCachedCommands,
|
||||
} from "./loader-cache"
|
||||
import type { CommandScope, CommandDefinition, CommandFrontmatter, LoadedCommand } from "./types"
|
||||
|
||||
export { clearCommandLoaderCache }
|
||||
|
||||
async function loadCommandsFromDir(
|
||||
commandsDir: string,
|
||||
scope: CommandScope,
|
||||
@@ -48,6 +58,7 @@ async function loadCommandsFromDir(
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
if (EXCLUDED_DIRS.has(entry.name)) continue
|
||||
if (entry.name.startsWith(".")) continue
|
||||
const subDirPath = join(commandsDir, entry.name)
|
||||
const subPrefix = prefix ? `${prefix}/${entry.name}` : entry.name
|
||||
@@ -159,11 +170,26 @@ export async function loadOpencodeProjectCommands(directory?: string): Promise<R
|
||||
}
|
||||
|
||||
export async function loadAllCommands(directory?: string): Promise<Record<string, CommandDefinition>> {
|
||||
const [user, project, global, projectOpencode] = await Promise.all([
|
||||
const cacheKey = await getCommandLoaderCacheKey(directory)
|
||||
const cachedCommands = getCachedCommands(cacheKey)
|
||||
if (cachedCommands) {
|
||||
return cachedCommands
|
||||
}
|
||||
|
||||
const loadCommandsPromise = Promise.all([
|
||||
loadUserCommands(),
|
||||
loadProjectCommands(directory),
|
||||
loadOpencodeGlobalCommands(),
|
||||
loadOpencodeProjectCommands(directory),
|
||||
])
|
||||
return { ...projectOpencode, ...global, ...project, ...user }
|
||||
.then(([user, project, global, projectOpencode]) => {
|
||||
return { ...projectOpencode, ...global, ...project, ...user }
|
||||
})
|
||||
.catch((error) => {
|
||||
deleteCachedCommands(cacheKey)
|
||||
throw error
|
||||
})
|
||||
|
||||
setCachedCommands(cacheKey, loadCommandsPromise)
|
||||
return loadCommandsPromise
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user