@@ -8,37 +8,71 @@ import * as Vcs from "./vcs"
88import { Bus } from "../bus"
99import { Command } from "../command"
1010import { InstanceState } from "@/effect/instance-state"
11- import * as Log from "@opencode-ai/core/util/log"
1211import { FileWatcher } from "@/file/watcher"
1312import { ShareNext } from "@/share/share-next"
14- import * as Effect from "effect/Effect "
13+ import { Context , Effect , Layer } from "effect"
1514import { Config } from "@/config/config"
1615
17- export const InstanceBootstrap = Effect . gen ( function * ( ) {
18- const ctx = yield * InstanceState . context
19- Log . Default . info ( "bootstrapping" , { directory : ctx . directory } )
20- // everything depends on config so eager load it for nice traces
21- yield * Config . Service . use ( ( svc ) => svc . get ( ) )
22- // Plugin can mutate config so it has to be initialized before anything else.
23- yield * Plugin . Service . use ( ( svc ) => svc . init ( ) )
24- yield * Effect . all (
25- [
26- LSP . Service ,
27- ShareNext . Service ,
28- Format . Service ,
29- File . Service ,
30- FileWatcher . Service ,
31- Vcs . Service ,
32- Snapshot . Service ,
33- ] . map ( ( s ) => Effect . forkDetach ( s . use ( ( i ) => i . init ( ) ) ) ) ,
34- ) . pipe ( Effect . withSpan ( "InstanceBootstrap.init" ) )
35-
36- const projectID = ctx . project . id
37- yield * Bus . Service . use ( ( svc ) =>
38- svc . subscribeCallback ( Command . Event . Executed , async ( payload ) => {
39- if ( payload . properties . name === Command . Default . INIT ) {
40- Project . setInitialized ( projectID )
41- }
42- } ) ,
43- )
44- } ) . pipe ( Effect . withSpan ( "InstanceBootstrap" ) )
16+ export interface Interface {
17+ readonly run : Effect . Effect < void >
18+ }
19+
20+ export class Service extends Context . Service < Service , Interface > ( ) ( "@opencode/InstanceBootstrap" ) { }
21+
22+ export const layer = Layer . effect (
23+ Service ,
24+ Effect . gen ( function * ( ) {
25+ // Yield each bootstrap dep at layer init so `run` itself has R = never.
26+ // This breaks the circular declaration loop through Config → Instance → InstanceStore
27+ // (instance-store.ts only yields this Service tag, never the impl-side services).
28+ const bus = yield * Bus . Service
29+ const config = yield * Config . Service
30+ const file = yield * File . Service
31+ const fileWatcher = yield * FileWatcher . Service
32+ const format = yield * Format . Service
33+ const lsp = yield * LSP . Service
34+ const plugin = yield * Plugin . Service
35+ const shareNext = yield * ShareNext . Service
36+ const snapshot = yield * Snapshot . Service
37+ const vcs = yield * Vcs . Service
38+
39+ const run = Effect . gen ( function * ( ) {
40+ const ctx = yield * InstanceState . context
41+ yield * Effect . logInfo ( "bootstrapping" , { directory : ctx . directory } )
42+ // everything depends on config so eager load it for nice traces
43+ yield * config . get ( )
44+ // Plugin can mutate config so it has to be initialized before anything else.
45+ yield * plugin . init ( )
46+ yield * Effect . all (
47+ [ lsp , shareNext , format , file , fileWatcher , vcs , snapshot ] . map ( ( s ) => Effect . forkDetach ( s . init ( ) ) ) ,
48+ ) . pipe ( Effect . withSpan ( "InstanceBootstrap.init" ) )
49+
50+ const projectID = ctx . project . id
51+ yield * bus . subscribeCallback ( Command . Event . Executed , async ( payload ) => {
52+ if ( payload . properties . name === Command . Default . INIT ) {
53+ Project . setInitialized ( projectID )
54+ }
55+ } )
56+ } ) . pipe ( Effect . withSpan ( "InstanceBootstrap" ) )
57+
58+ return Service . of ( { run } )
59+ } ) ,
60+ )
61+
62+ export const defaultLayer : Layer . Layer < Service > = layer . pipe (
63+ Layer . provide ( [
64+ Bus . layer ,
65+ Config . defaultLayer ,
66+ File . defaultLayer ,
67+ FileWatcher . defaultLayer ,
68+ Format . defaultLayer ,
69+ LSP . defaultLayer ,
70+ Plugin . defaultLayer ,
71+ Project . defaultLayer ,
72+ ShareNext . defaultLayer ,
73+ Snapshot . defaultLayer ,
74+ Vcs . defaultLayer ,
75+ ] ) ,
76+ )
77+
78+ export * as InstanceBootstrap from "./bootstrap"
0 commit comments