diff --git a/packages/opencode/src/bus/index.ts b/packages/opencode/src/bus/index.ts index 87b08d6101..707c57c0c9 100644 --- a/packages/opencode/src/bus/index.ts +++ b/packages/opencode/src/bus/index.ts @@ -1,5 +1,6 @@ import z from "zod" import { Effect, Exit, Layer, PubSub, Scope, ServiceMap, Stream } from "effect" +import { EffectLogger } from "@/effect/logger" import { Log } from "../util/log" import { BusEvent } from "./bus-event" import { GlobalBus } from "./global" @@ -146,7 +147,7 @@ export namespace Bus { return () => { log.info("unsubscribing", { type }) - Effect.runFork(Scope.close(scope, Exit.void)) + Effect.runFork(Scope.close(scope, Exit.void).pipe(Effect.provide(EffectLogger.layer))) } }) } diff --git a/packages/opencode/src/command/index.ts b/packages/opencode/src/command/index.ts index 088d7c5659..4c08dbbb31 100644 --- a/packages/opencode/src/command/index.ts +++ b/packages/opencode/src/command/index.ts @@ -3,6 +3,7 @@ import { InstanceState } from "@/effect/instance-state" import { makeRuntime } from "@/effect/run-service" import { SessionID, MessageID } from "@/session/schema" import { Effect, Layer, ServiceMap } from "effect" +import { EffectLogger } from "@/effect/logger" import z from "zod" import { Config } from "../config/config" import { MCP } from "../mcp" @@ -140,6 +141,7 @@ export namespace Command { .map((message) => (message.content.type === "text" ? message.content.text : "")) .join("\n") || "", ), + Effect.provide(EffectLogger.layer), ), ) }, diff --git a/packages/opencode/src/effect/instance-state.ts b/packages/opencode/src/effect/instance-state.ts index 878648855e..86f84ddb1c 100644 --- a/packages/opencode/src/effect/instance-state.ts +++ b/packages/opencode/src/effect/instance-state.ts @@ -1,4 +1,5 @@ import { Effect, Fiber, ScopedCache, Scope, ServiceMap } from "effect" +import { EffectLogger } from "@/effect/logger" import { Instance, type InstanceContext } from "@/project/instance" import { Context } from "@/util/context" import { InstanceRef, WorkspaceRef } from "./instance-ref" @@ -47,7 +48,7 @@ export namespace InstanceState { }), }) - const off = registerDisposer((directory) => Effect.runPromise(ScopedCache.invalidate(cache, directory))) + const off = registerDisposer((directory) => Effect.runPromise(ScopedCache.invalidate(cache, directory).pipe(Effect.provide(EffectLogger.layer)))) yield* Effect.addFinalizer(() => Effect.sync(off)) return { diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index 2599a8dec9..c5d466e1f0 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -25,6 +25,7 @@ import { Bus } from "@/bus" import { TuiEvent } from "@/cli/cmd/tui/event" import open from "open" import { Effect, Exit, Layer, Option, ServiceMap, Stream } from "effect" +import { EffectLogger } from "@/effect/logger" import { InstanceState } from "@/effect/instance-state" import { makeRuntime } from "@/effect/run-service" import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process" @@ -469,12 +470,12 @@ export namespace MCP { log.info("tools list changed notification received", { server: name }) if (s.clients[name] !== client || s.status[name]?.status !== "connected") return - const listed = await Effect.runPromise(defs(name, client, timeout)) + const listed = await Effect.runPromise(defs(name, client, timeout).pipe(Effect.provide(EffectLogger.layer))) if (!listed) return if (s.clients[name] !== client || s.status[name]?.status !== "connected") return s.defs[name] = listed - await Effect.runPromise(bus.publish(ToolsChanged, { server: name }).pipe(Effect.ignore)) + await Effect.runPromise(bus.publish(ToolsChanged, { server: name }).pipe(Effect.ignore, Effect.provide(EffectLogger.layer))) }) } diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts index 814e7870a4..799b92f0b1 100644 --- a/packages/opencode/src/plugin/index.ts +++ b/packages/opencode/src/plugin/index.ts @@ -12,6 +12,7 @@ import { gitlabAuthPlugin as GitlabAuthPlugin } from "opencode-gitlab-auth" import { PoeAuthPlugin } from "opencode-poe-auth" import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cloudflare" import { Effect, Layer, ServiceMap, Stream } from "effect" +import { EffectLogger } from "@/effect/logger" import { InstanceState } from "@/effect/instance-state" import { makeRuntime } from "@/effect/run-service" import { errorMessage } from "@/util/error" @@ -83,7 +84,7 @@ export namespace Plugin { } function publishPluginError(bus: Bus.Interface, message: string) { - Effect.runFork(bus.publish(Session.Event.Error, { error: new NamedError.Unknown({ message }).toObject() })) + Effect.runFork(bus.publish(Session.Event.Error, { error: new NamedError.Unknown({ message }).toObject() }).pipe(Effect.provide(EffectLogger.layer))) } async function applyPlugin(load: PluginLoader.Loaded, input: PluginInput, hooks: Hooks[]) { diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index 004fb77f91..57d6e99a45 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -20,6 +20,7 @@ import { Global } from "../global" import path from "path" import { Filesystem } from "../util/filesystem" import { Effect, Layer, ServiceMap } from "effect" +import { EffectLogger } from "@/effect/logger" import { InstanceState } from "@/effect/instance-state" import { makeRuntime } from "@/effect/run-service" @@ -1215,7 +1216,7 @@ export namespace Provider { const options = yield* Effect.promise(() => plugin.auth!.loader!( - () => Effect.runPromise(auth.get(providerID).pipe(Effect.orDie)) as any, + () => Effect.runPromise(auth.get(providerID).pipe(Effect.orDie, Effect.provide(EffectLogger.layer))) as any, database[plugin.auth!.provider], ), ) diff --git a/packages/opencode/src/pty/index.ts b/packages/opencode/src/pty/index.ts index ff44de73b5..0358c72e85 100644 --- a/packages/opencode/src/pty/index.ts +++ b/packages/opencode/src/pty/index.ts @@ -11,6 +11,7 @@ import { Shell } from "@/shell/shell" import { Plugin } from "@/plugin" import { PtyID } from "./schema" import { Effect, Layer, ServiceMap } from "effect" +import { EffectLogger } from "@/effect/logger" export namespace Pty { const log = Log.create({ service: "pty" }) @@ -256,8 +257,8 @@ export namespace Pty { if (session.info.status === "exited") return log.info("session exited", { id, exitCode }) session.info.status = "exited" - Effect.runFork(bus.publish(Event.Exited, { id, exitCode })) - Effect.runFork(remove(id)) + Effect.runFork(bus.publish(Event.Exited, { id, exitCode }).pipe(Effect.provide(EffectLogger.layer))) + Effect.runFork(remove(id).pipe(Effect.provide(EffectLogger.layer))) }), ) yield* bus.publish(Event.Created, { info }) diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts index 61c159646d..aa42e1c1dc 100644 --- a/packages/opencode/src/session/message-v2.ts +++ b/packages/opencode/src/session/message-v2.ts @@ -15,6 +15,7 @@ import type { SystemError } from "bun" import type { Provider } from "@/provider/provider" import { ModelID, ProviderID } from "@/provider/schema" import { Effect } from "effect" +import { EffectLogger } from "@/effect/logger" /** Error shape thrown by Bun's fetch() when gzip/br decompression fails mid-stream */ interface FetchDecompressionError extends Error { @@ -839,7 +840,7 @@ export namespace MessageV2 { model: Provider.Model, options?: { stripMedia?: boolean }, ): Promise { - return Effect.runPromise(toModelMessagesEffect(input, model, options)) + return Effect.runPromise(toModelMessagesEffect(input, model, options).pipe(Effect.provide(EffectLogger.layer))) } export function page(input: { sessionID: SessionID; limit: number; before?: string }) { diff --git a/packages/opencode/src/tool/external-directory.ts b/packages/opencode/src/tool/external-directory.ts index ed9d2af2fb..ff8854649a 100644 --- a/packages/opencode/src/tool/external-directory.ts +++ b/packages/opencode/src/tool/external-directory.ts @@ -1,5 +1,6 @@ import path from "path" import { Effect } from "effect" +import { EffectLogger } from "@/effect/logger" import type { Tool } from "./tool" import { Instance } from "../project/instance" import { AppFileSystem } from "../filesystem" @@ -42,5 +43,5 @@ export const assertExternalDirectoryEffect = Effect.fn("Tool.assertExternalDirec }) export async function assertExternalDirectory(ctx: Tool.Context, target?: string, options?: Options) { - return Effect.runPromise(assertExternalDirectoryEffect(ctx, target, options)) + return Effect.runPromise(assertExternalDirectoryEffect(ctx, target, options).pipe(Effect.provide(EffectLogger.layer))) } diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index 7ba99c0c97..c2577a5054 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -30,6 +30,7 @@ import { Glob } from "../util/glob" import path from "path" import { pathToFileURL } from "url" import { Effect, Layer, ServiceMap } from "effect" +import { EffectLogger } from "@/effect/logger" import { FetchHttpClient, HttpClient } from "effect/unstable/http" import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner" import * as CrossSpawnSpawner from "@/effect/cross-spawn-spawner" @@ -136,7 +137,7 @@ export namespace ToolRegistry { Effect.gen(function* () { const pluginCtx: PluginToolContext = { ...toolCtx, - ask: (req) => Effect.runPromise(toolCtx.ask(req)), + ask: (req) => Effect.runPromise(toolCtx.ask(req).pipe(Effect.provide(EffectLogger.layer))), directory: ctx.directory, worktree: ctx.worktree, } diff --git a/packages/opencode/src/tool/skill.ts b/packages/opencode/src/tool/skill.ts index 22eac69cf8..f9f06b9cd9 100644 --- a/packages/opencode/src/tool/skill.ts +++ b/packages/opencode/src/tool/skill.ts @@ -2,6 +2,7 @@ import path from "path" import { pathToFileURL } from "url" import z from "zod" import { Effect } from "effect" +import { EffectLogger } from "@/effect/logger" import * as Stream from "effect/Stream" import { Tool } from "./tool" import { Skill } from "../skill" @@ -18,7 +19,7 @@ export const SkillTool = Tool.define( const rg = yield* Ripgrep.Service return async () => { - const list = await Effect.runPromise(skill.available()) + const list = await Effect.runPromise(skill.available().pipe(Effect.provide(EffectLogger.layer))) const description = list.length === 0