diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 8eafb92e815..8275a0c0c64 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -23,6 +23,9 @@ import { existsSync } from "fs" export namespace Config { const log = Log.create({ service: "config" }) + // Track install promises per directory so tools can wait for their dependencies + const installPromises = new Map>() + // Custom merge function that concatenates array fields instead of replacing them function mergeConfigConcatArrays(target: Info, source: Info): Info { const merged = mergeDeep(target, source) @@ -106,6 +109,7 @@ export namespace Config { const exists = existsSync(path.join(dir, "node_modules")) const installing = installDependencies(dir) + installPromises.set(dir, installing) if (!exists) await installing result.command = mergeDeep(result.command ?? {}, await loadCommand(dir)) @@ -162,6 +166,7 @@ export namespace Config { return { config: result, directories, + installPromises, } }) @@ -1118,4 +1123,9 @@ export namespace Config { export async function directories() { return state().then((x) => x.directories) } + + export async function getInstallPromise(dir: string): Promise { + const promises = await state().then((x) => x.installPromises) + return promises.get(dir) ?? Promise.resolve() + } } diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index db515284741..45e410c0e18 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -32,6 +32,9 @@ export namespace ToolRegistry { const glob = new Bun.Glob("tool/*.{js,ts}") for (const dir of await Config.directories()) { + // Wait for dependencies to be installed before loading tools from this directory + await Config.getInstallPromise(dir) + for await (const match of glob.scan({ cwd: dir, absolute: true,