diff --git a/packages/core/src/plugin/boot.ts b/packages/core/src/plugin/boot.ts index 4e2454a933..d3ea5195cb 100644 --- a/packages/core/src/plugin/boot.ts +++ b/packages/core/src/plugin/boot.ts @@ -1,6 +1,6 @@ export * as PluginBoot from "./boot" -import { Effect, Layer } from "effect" +import { Context, Deferred, Effect, Layer } from "effect" import { AuthV2 } from "../auth" import { Catalog } from "../catalog" import { Npm } from "../npm" @@ -15,12 +15,20 @@ type Plugin = { effect: Effect.Effect } -export const layer = Layer.effectDiscard( +export interface Interface { + readonly wait: () => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/v2/PluginBoot") {} + +export const layer: Layer.Layer = Layer.effect( + Service, Effect.gen(function* () { const catalog = yield* Catalog.Service const plugin = yield* PluginV2.Service const auth = yield* AuthV2.Service const npm = yield* Npm.Service + const done = yield* Deferred.make() const add = Effect.fn("PluginBoot.add")(function* (input: Plugin) { yield* plugin.add({ @@ -33,12 +41,20 @@ export const layer = Layer.effectDiscard( }) }) - yield* add(EnvPlugin) - yield* add(AuthPlugin) - for (const item of ProviderPlugins) { - yield* add(item) - } - yield* add(ModelsDevPlugin) + const boot = Effect.gen(function* () { + yield* add(EnvPlugin) + yield* add(AuthPlugin) + for (const item of ProviderPlugins) { + yield* add(item) + } + yield* add(ModelsDevPlugin) + }).pipe(Effect.withSpan("PluginBoot.boot")) + + yield* boot.pipe(Effect.exit, Effect.flatMap((exit) => Deferred.done(done, exit)), Effect.forkScoped) + + return Service.of({ + wait: () => Deferred.await(done), + }) }), ) diff --git a/packages/opencode/src/cli/cmd/debug/v2.ts b/packages/opencode/src/cli/cmd/debug/v2.ts index 02766513e8..79f16cc26a 100644 --- a/packages/opencode/src/cli/cmd/debug/v2.ts +++ b/packages/opencode/src/cli/cmd/debug/v2.ts @@ -4,7 +4,7 @@ import { Catalog } from "@opencode-ai/core/catalog" import { effectCmd } from "../../effect-cmd" import { PluginBoot } from "@opencode-ai/core/plugin/boot" -const layer = Catalog.defaultLayer.pipe(Layer.provide(PluginBoot.defaultLayer)) +const layer = Layer.mergeAll(Catalog.defaultLayer, PluginBoot.defaultLayer) export const V2Command = effectCmd({ command: "v2", @@ -12,6 +12,7 @@ export const V2Command = effectCmd({ instance: false, handler: Effect.fn("Cli.debug.v2")(function* () { const result = yield* Effect.gen(function* () { + yield* PluginBoot.Service.use((s) => s.wait()) const catalog = yield* Catalog.Service const providers = (yield* catalog.provider.available()).sort((a, b) => a.id.localeCompare(b.id))