1+ import { LayerNode } from "@opencode-ai/core/effect/layer-node"
12import type {
23 Hooks ,
34 PluginInput ,
@@ -6,7 +7,6 @@ import type {
67 WorkspaceAdapter as PluginWorkspaceAdapter ,
78} from "@opencode-ai/plugin"
89import { Config } from "@/config/config"
9- import * as Log from "@opencode-ai/core/util/log"
1010import { createOpencodeClient } from "@opencode-ai/sdk"
1111import { ServerAuth } from "@/server/auth"
1212import { CodexAuthPlugin } from "./openai/codex"
@@ -19,6 +19,7 @@ import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cl
1919import { AzureAuthPlugin } from "./azure"
2020import { DigitalOceanAuthPlugin } from "./digitalocean"
2121import { XaiAuthPlugin } from "./xai"
22+ import { SnowflakeCortexAuthPlugin } from "./snowflake-cortex"
2223import { Effect , Layer , Context } from "effect"
2324import { EffectBridge } from "@/effect/bridge"
2425import { InstanceState } from "@/effect/instance-state"
@@ -31,8 +32,6 @@ import { RuntimeFlags } from "@/effect/runtime-flags"
3132import { EventV2Bridge } from "@/event-v2-bridge"
3233import { InstallationChannel } from "@opencode-ai/core/installation/version"
3334
34- const log = Log . create ( { service : "plugin" } )
35-
3635type State = {
3736 hooks : Hooks [ ]
3837}
@@ -77,6 +76,7 @@ function internalPlugins(flags: RuntimeFlags.Info): PluginInstance[] {
7776 CloudflareAIGatewayAuthPlugin ,
7877 AzureAuthPlugin ,
7978 DigitalOceanAuthPlugin ,
79+ SnowflakeCortexAuthPlugin ,
8080 XaiAuthPlugin ,
8181 ]
8282}
@@ -120,7 +120,7 @@ async function applyPlugin(load: PluginLoader.Loaded, input: PluginInput, hooks:
120120 }
121121}
122122
123- export const layer = Layer . effect (
123+ const layer = Layer . effect (
124124 Service ,
125125 Effect . gen ( function * ( ) {
126126 const events = yield * EventV2Bridge . Service
@@ -138,11 +138,12 @@ export const layer = Layer.effect(
138138
139139 const { Server } = yield * Effect . promise ( ( ) => import ( "../server/server" ) )
140140
141+ const serverUrl = Server . url
141142 const client = createOpencodeClient ( {
142- baseUrl : "http://localhost:4096" ,
143+ baseUrl : serverUrl ?. toString ( ) ?? "http://localhost:4096" ,
143144 directory : ctx . directory ,
144145 headers : ServerAuth . headers ( ) ,
145- fetch : async ( ...args ) => Server . Default ( ) . app . fetch ( ...args ) ,
146+ ... ( serverUrl ? { } : { fetch : async ( ...args ) => Server . Default ( ) . app . fetch ( ...args ) } ) ,
146147 } )
147148 const cfg = yield * config . get ( )
148149 const input : PluginInput = {
@@ -163,19 +164,18 @@ export const layer = Layer.effect(
163164 }
164165
165166 for ( const plugin of flags . disableDefaultPlugins ? [ ] : internalPlugins ( flags ) ) {
166- log . info ( "loading internal plugin" , { name : plugin . name } )
167167 const init = yield * Effect . tryPromise ( {
168168 try : ( ) => plugin ( input ) ,
169- catch : ( err ) => {
170- log . error ( "failed to load internal plugin" , { name : plugin . name , error : err } )
171- } ,
172- } ) . pipe ( Effect . option )
169+ catch : errorMessage ,
170+ } ) . pipe (
171+ Effect . tapError ( ( error ) => Effect . logError ( "failed to load internal plugin" , { name : plugin . name , error } ) ) ,
172+ Effect . option ,
173+ )
173174 if ( init . _tag === "Some" ) hooks . push ( init . value )
174175 }
175176
176177 const plugins = flags . pure ? [ ] : ( cfg . plugin_origins ?? [ ] )
177178 if ( flags . pure && cfg . plugin_origins ?. length ) {
178- log . info ( "skipping external plugins in pure mode" , { count : cfg . plugin_origins . length } )
179179 }
180180 if ( plugins . length ) yield * config . waitForDependencies ( )
181181
@@ -184,37 +184,29 @@ export const layer = Layer.effect(
184184 items : plugins ,
185185 kind : "server" ,
186186 report : {
187- start ( candidate ) {
188- log . info ( "loading plugin" , { path : candidate . plan . spec } )
189- } ,
190- missing ( candidate , _retry , message ) {
191- log . warn ( "plugin has no server entrypoint" , { path : candidate . plan . spec , message } )
192- } ,
187+ start ( candidate ) { } ,
188+ missing ( candidate , _retry , message ) { } ,
193189 error ( candidate , _retry , stage , error , resolved ) {
194190 const spec = candidate . plan . spec
195191 const cause = error instanceof Error ? ( error . cause ?? error ) : error
196192 const message = stage === "load" ? errorMessage ( error ) : errorMessage ( cause )
197193
198194 if ( stage === "install" ) {
199195 const parsed = parsePluginSpecifier ( spec )
200- log . error ( "failed to install plugin" , { pkg : parsed . pkg , version : parsed . version , error : message } )
201196 publishPluginError ( `Failed to install plugin ${ parsed . pkg } @${ parsed . version } : ${ message } ` )
202197 return
203198 }
204199
205200 if ( stage === "compatibility" ) {
206- log . warn ( "plugin incompatible" , { path : spec , error : message } )
207201 publishPluginError ( `Plugin ${ spec } skipped: ${ message } ` )
208202 return
209203 }
210204
211205 if ( stage === "entry" ) {
212- log . error ( "failed to resolve plugin server entry" , { path : spec , error : message } )
213206 publishPluginError ( `Failed to load plugin ${ spec } : ${ message } ` )
214207 return
215208 }
216209
217- log . error ( "failed to load plugin" , { path : spec , target : resolved ?. entry , error : message } )
218210 publishPluginError ( `Failed to load plugin ${ spec } : ${ message } ` )
219211 } ,
220212 } ,
@@ -229,10 +221,10 @@ export const layer = Layer.effect(
229221 try : ( ) => applyPlugin ( load , input , hooks ) ,
230222 catch : ( err ) => {
231223 const message = errorMessage ( err )
232- log . error ( "failed to load plugin" , { path : load . spec , error : message } )
233224 return message
234225 } ,
235226 } ) . pipe (
227+ Effect . tapError ( ( error ) => Effect . logError ( "failed to load plugin" , { path : load . spec , error } ) ) ,
236228 Effect . catch ( ( ) => {
237229 // TODO: make proper events for this
238230 // events.publish(Session.Event.Error, {
@@ -249,10 +241,11 @@ export const layer = Layer.effect(
249241 for ( const hook of hooks ) {
250242 yield * Effect . tryPromise ( {
251243 try : ( ) => Promise . resolve ( ( hook as any ) . config ?.( cfg ) ) ,
252- catch : ( err ) => {
253- log . error ( "plugin config hook failed" , { error : err } )
254- } ,
255- } ) . pipe ( Effect . ignore )
244+ catch : errorMessage ,
245+ } ) . pipe (
246+ Effect . tapError ( ( error ) => Effect . logError ( "plugin config hook failed" , { error } ) ) ,
247+ Effect . ignore ,
248+ )
256249 }
257250
258251 const unsubscribe = yield * events . listen ( ( event ) => {
@@ -271,10 +264,11 @@ export const layer = Layer.effect(
271264 ( hook ) =>
272265 Effect . tryPromise ( {
273266 try : ( ) => Promise . resolve ( hook . dispose ?.( ) ) ,
274- catch : ( error ) => {
275- log . error ( "plugin dispose hook failed" , { error } )
276- } ,
277- } ) . pipe ( Effect . ignore ) ,
267+ catch : errorMessage ,
268+ } ) . pipe (
269+ Effect . tapError ( ( error ) => Effect . logError ( "plugin dispose hook failed" , { error } ) ) ,
270+ Effect . ignore ,
271+ ) ,
278272 { discard : true } ,
279273 ) ,
280274 )
@@ -311,10 +305,10 @@ export const layer = Layer.effect(
311305 } ) ,
312306)
313307
314- export const defaultLayer = layer . pipe (
315- Layer . provide ( EventV2Bridge . defaultLayer ) ,
316- Layer . provide ( Config . defaultLayer ) ,
317- Layer . provide ( RuntimeFlags . defaultLayer ) ,
318- )
308+ export const node = LayerNode . make ( {
309+ service : Service ,
310+ layer : layer ,
311+ deps : [ EventV2Bridge . node , Config . node , RuntimeFlags . node ] ,
312+ } )
319313
320314export * as Plugin from "."
0 commit comments