refactor(core): remove domain layer exports (#34625)

This commit is contained in:
James Long
2026-06-30 13:05:15 -04:00
committed by GitHub
parent e78726854a
commit 5a23bdcb69
38 changed files with 81 additions and 153 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ export interface Interface extends State.Transformable<Draft> {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Agent") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Agent") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const state = State.create<Data, Draft>({ const state = State.create<Data, Draft>({
-2
View File
@@ -233,5 +233,3 @@ export const locationLayer = Layer.effect(
) )
export const node = makeLocationNode({ service: Service, layer: locationLayer, deps: [] }) export const node = makeLocationNode({ service: Service, layer: locationLayer, deps: [] })
export const defaultLayer = locationLayer
+1 -1
View File
@@ -61,7 +61,7 @@ export interface Interface extends State.Transformable<Draft> {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Catalog") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Catalog") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const events = yield* EventV2.Service const events = yield* EventV2.Service
+1 -1
View File
@@ -26,7 +26,7 @@ export interface Interface extends State.Transformable<Draft> {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Command") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Command") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.sync(() => { Effect.sync(() => {
const state = State.create<Data, Draft>({ const state = State.create<Data, Draft>({
+1 -1
View File
@@ -132,7 +132,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Config") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Config") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const fs = yield* FSUtil.Service const fs = yield* FSUtil.Service
+1 -1
View File
@@ -71,7 +71,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/v2
* write under the same process-local lock so cooperating OpenCode mutations do * write under the same process-local lock so cooperating OpenCode mutations do
* not overwrite changes made from the same stale content. * not overwrite changes made from the same stale content.
*/ */
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const fs = yield* FSUtil.Service const fs = yield* FSUtil.Service
+1 -1
View File
@@ -44,7 +44,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/Image") {} export class Service extends Context.Service<Service, Interface>()("@opencode/Image") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const config = yield* Config.Service const config = yield* Config.Service
+1 -1
View File
@@ -19,7 +19,7 @@ class File extends Schema.Class<File>("InstructionContext.File")({
const Files = Schema.Array(File) const Files = Schema.Array(File)
const key = SystemContext.Key.make("core/instructions") const key = SystemContext.Key.make("core/instructions")
export const layer = Layer.effectDiscard( const layer = Layer.effectDiscard(
Effect.gen(function* () { Effect.gen(function* () {
const fs = yield* FSUtil.Service const fs = yield* FSUtil.Service
const global = yield* Global.Service const global = yield* Global.Service
+1 -1
View File
@@ -76,7 +76,7 @@ interface ResolvedPath {
const slash = (value: string) => value.replaceAll("\\", "/") const slash = (value: string) => value.replaceAll("\\", "/")
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const fs = yield* FSUtil.Service const fs = yield* FSUtil.Service
+1 -1
View File
@@ -16,7 +16,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/Lo
export const node = LayerNode.unbound(Service, tags.values.location) export const node = LayerNode.unbound(Service, tags.values.location)
export const layer = (ref: Ref) => const layer = (ref: Ref) =>
Layer.effect( Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
+1 -1
View File
@@ -106,7 +106,7 @@ interface Pending {
readonly deferred: Deferred.Deferred<void, RejectedError | CorrectedError> readonly deferred: Deferred.Deferred<void, RejectedError | CorrectedError>
} }
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
EffectRuntime.gen(function* () { EffectRuntime.gen(function* () {
const events = yield* EventV2.Service const events = yield* EventV2.Service
+1 -1
View File
@@ -28,7 +28,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Plugin") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Plugin") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const events = yield* EventV2.Service const events = yield* EventV2.Service
+1 -1
View File
@@ -22,7 +22,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Policy") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Policy") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
EffectRuntime.gen(function* () { EffectRuntime.gen(function* () {
let statements: Info[] = [] let statements: Info[] = []
+1 -1
View File
@@ -125,7 +125,7 @@ export const refreshAfterBoot = Effect.gen(function* () {
) )
}) })
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const fs = yield* FSUtil.Service const fs = yield* FSUtil.Service
+1 -1
View File
@@ -89,7 +89,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Pty") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Pty") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const events = yield* EventV2.Service const events = yield* EventV2.Service
+1 -2
View File
@@ -51,7 +51,6 @@ export const make = (ttl: Duration.Input = DEFAULT_TTL) =>
}) })
}) })
export const layer = Layer.effect(Service, make()) const layer = Layer.effect(Service, make())
export const defaultLayer = layer
export const node = makeGlobalNode({ service: Service, layer: layer, deps: [] }) export const node = makeGlobalNode({ service: Service, layer: layer, deps: [] })
+1 -1
View File
@@ -72,7 +72,7 @@ interface Pending {
* layer once per embedded Location so replies cannot settle another Location's * layer once per embedded Location so replies cannot settle another Location's
* deferred request. * deferred request.
*/ */
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const events = yield* EventV2.Service const events = yield* EventV2.Service
+1 -1
View File
@@ -40,7 +40,7 @@ export interface Interface extends State.Transformable<Draft> {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Reference") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Reference") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const global = yield* Global.Service const global = yield* Global.Service
+1 -1
View File
@@ -31,7 +31,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/ReferenceGuidance") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/ReferenceGuidance") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const references = yield* Reference.Service const references = yield* Reference.Service
+1 -1
View File
@@ -53,7 +53,7 @@ export interface Interface extends State.Transformable<Draft> {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Skill") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Skill") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const discovery = yield* SkillDiscovery.Service const discovery = yield* SkillDiscovery.Service
+1 -1
View File
@@ -37,7 +37,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/SkillGuidance") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/SkillGuidance") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const skills = yield* SkillV2.Service const skills = yield* SkillV2.Service
+1 -1
View File
@@ -83,7 +83,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Snapshot") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Snapshot") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const config = yield* Config.Service const config = yield* Config.Service
+1 -7
View File
@@ -43,14 +43,8 @@ const builtIns = Layer.effectDiscard(
}), }),
) )
export const layer = Layer.mergeAll(builtIns, InstructionContext.layer).pipe(
Layer.provideMerge(SystemContextRegistry.layer),
)
export const locationLayer = layer
export const node = makeLocationNode({ export const node = makeLocationNode({
name: "system-context-builtins", name: "system-context-builtins",
layer, layer: builtIns,
deps: [Location.node, SystemContextRegistry.node, InstructionContext.node, FSUtil.node, Global.node], deps: [Location.node, SystemContextRegistry.node, InstructionContext.node, FSUtil.node, Global.node],
}) })
+1 -1
View File
@@ -16,7 +16,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/SystemContextRegistry") {} export class Service extends Context.Service<Service, Interface>()("@opencode/v2/SystemContextRegistry") {}
export const layer = Layer.effect( const layer = Layer.effect(
Service, Service,
Effect.gen(function* () { Effect.gen(function* () {
const entries = yield* Ref.make<ReadonlyArray<Entry>>([]) const entries = yield* Ref.make<ReadonlyArray<Entry>>([])
@@ -31,8 +31,8 @@ import { waitEvent } from "./util"
import { WorkspaceRef } from "@/effect/instance-ref" import { WorkspaceRef } from "@/effect/instance-ref"
import { Vcs } from "@/project/vcs" import { Vcs } from "@/project/vcs"
import { InstanceStore } from "@/project/instance-store" import { InstanceStore } from "@/project/instance-store"
import { InstanceBootstrap } from "@/project/bootstrap"
import { WorkspaceAdapterRuntime } from "./workspace-adapter-runtime" import { WorkspaceAdapterRuntime } from "./workspace-adapter-runtime"
import { AppNodeBuilderV1 } from "@/effect/app-node-builder-v1"
import { WorkspaceEvent } from "@opencode-ai/schema/workspace-event" import { WorkspaceEvent } from "@opencode-ai/schema/workspace-event"
export const Info = Schema.Struct({ export const Info = Schema.Struct({
@@ -602,9 +602,7 @@ const layer = Layer.effect(
fallback: "", fallback: "",
response: "text", response: "text",
}).pipe( }).pipe(
Effect.provide( Effect.provide(AppNodeBuilderV1.build(InstanceStore.node)),
LayerNode.compile(InstanceStore.node, [[InstanceStore.bootstrapNode, InstanceBootstrap.node]]),
),
) )
: "" : ""
@@ -622,9 +620,7 @@ const layer = Layer.effect(
}), }),
fallback: { applied: false }, fallback: { applied: false },
}).pipe( }).pipe(
Effect.provide( Effect.provide(AppNodeBuilderV1.build(InstanceStore.node)),
LayerNode.compile(InstanceStore.node, [[InstanceStore.bootstrapNode, InstanceBootstrap.node]]),
),
) )
} }
@@ -0,0 +1,12 @@
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
import { InstanceBootstrap } from "@/project/bootstrap"
import { InstanceStore } from "@/project/instance-store"
const bootstrapReplacement = [InstanceStore.bootstrapNode, InstanceBootstrap.node] as const
export function build<A, E>(root: LayerNode.Node<A, E, any>, replacements: LayerNode.Replacements = []) {
return AppNodeBuilder.build(root, replacements.concat([bootstrapReplacement]))
}
export * as AppNodeBuilderV1 from "./app-node-builder-v1"
+3 -5
View File
@@ -38,7 +38,6 @@ import { Command } from "@/command"
import { Truncate } from "@/tool/truncate" import { Truncate } from "@/tool/truncate"
import { ToolRegistry } from "@/tool/registry" import { ToolRegistry } from "@/tool/registry"
import { Format } from "@/format" import { Format } from "@/format"
import { InstanceBootstrap } from "@/project/bootstrap"
import { InstanceStore } from "@/project/instance-store" import { InstanceStore } from "@/project/instance-store"
import { Project } from "@/project/project" import { Project } from "@/project/project"
import { Vcs } from "@/project/vcs" import { Vcs } from "@/project/vcs"
@@ -53,10 +52,10 @@ import { BackgroundJob } from "@/background/job"
import { RuntimeFlags } from "@/effect/runtime-flags" import { RuntimeFlags } from "@/effect/runtime-flags"
import { EventV2Bridge } from "@/event-v2-bridge" import { EventV2Bridge } from "@/event-v2-bridge"
import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { LayerNode } from "@opencode-ai/core/effect/layer-node"
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" import { AppNodeBuilderV1 } from "./app-node-builder-v1"
import { SessionProjector } from "@opencode-ai/core/session/projector" import { SessionProjector } from "@opencode-ai/core/session/projector"
export const AppLayer = AppNodeBuilder.build( export const AppLayer = AppNodeBuilderV1.build(
LayerNode.group([ LayerNode.group([
Npm.node, Npm.node,
FSUtil.node, FSUtil.node,
@@ -107,8 +106,7 @@ export const AppLayer = AppNodeBuilder.build(
ShareNext.node, ShareNext.node,
SessionShare.node, SessionShare.node,
]), ]),
[[InstanceStore.bootstrapNode, InstanceBootstrap.node]], ).pipe(Layer.provideMerge(AppNodeBuilderV1.build(Ripgrep.node)), Layer.provideMerge(Observability.layer))
).pipe(Layer.provideMerge(AppNodeBuilder.build(Ripgrep.node)), Layer.provideMerge(Observability.layer))
const rt = ManagedRuntime.make(AppLayer, { memoMap }) const rt = ManagedRuntime.make(AppLayer, { memoMap })
type Runtime = Pick<typeof rt, "runSync" | "runPromise" | "runPromiseExit" | "runFork" | "runCallback" | "dispose"> type Runtime = Pick<typeof rt, "runSync" | "runPromise" | "runPromiseExit" | "runFork" | "runCallback" | "dispose">
@@ -14,9 +14,9 @@ export type Shape<Fields extends ConfigMap> = {
*/ */
export type ServiceClass<Self, Id extends string, Service> = Context.ServiceClass<Self, Id, Service> & { export type ServiceClass<Self, Id extends string, Service> = Context.ServiceClass<Self, Id, Service> & {
/** Provide already-parsed config, useful in tests. */ /** Provide already-parsed config, useful in tests. */
readonly layer: (input: Service) => Layer.Layer<Self> readonly configLayer: (input: Service) => Layer.Layer<Self>
/** Parse config once from the active Effect ConfigProvider and provide the service. */ /** Parse config once from the active Effect ConfigProvider and provide the service. */
readonly defaultLayer: Layer.Layer<Self, Config.ConfigError> readonly layer: Layer.Layer<Self, Config.ConfigError>
} }
/** /**
@@ -35,19 +35,19 @@ export type ServiceClass<Self, Id extends string, Service> = Context.ServiceClas
* }, * },
* ) {} * ) {}
* *
* const live = ServerAuthConfig.defaultLayer * const live = ServerAuthConfig.layer
* const test = ServerAuthConfig.layer({ password: Option.some("secret"), username: "kit" }) * const test = ServerAuthConfig.configLayer({ password: Option.some("secret"), username: "kit" })
* ``` * ```
*/ */
export const Service = export const Service =
<Self>() => <Self>() =>
<const Id extends string, const Fields extends ConfigMap>(id: Id, fields: Fields) => { <const Id extends string, const Fields extends ConfigMap>(id: Id, fields: Fields) => {
class ConfigTag extends Context.Service<Self, Shape<Fields>>()(id) { class ConfigTag extends Context.Service<Self, Shape<Fields>>()(id) {
static layer(input: Shape<Fields>) { static configLayer(input: Shape<Fields>) {
return Layer.succeed(this, this.of(input)) return Layer.succeed(this, this.of(input))
} }
static get defaultLayer() { static get layer() {
const tag = this const tag = this
return Layer.effect( return Layer.effect(
tag, tag,
@@ -57,7 +57,7 @@ export class Service extends ConfigService.Service<Service>()("@opencode/Runtime
export type Info = Context.Service.Shape<typeof Service> export type Info = Context.Service.Shape<typeof Service>
const emptyConfigLayer = Service.defaultLayer.pipe( const emptyConfigLayer = Service.layer.pipe(
Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown({}))), Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown({}))),
Layer.orDie, Layer.orDie,
) )
@@ -71,7 +71,7 @@ export const layer = (overrides: Partial<Info> = {}) =>
}), }),
).pipe(Layer.provide(emptyConfigLayer)) ).pipe(Layer.provide(emptyConfigLayer))
export const node = LayerNode.make({ service: Service, layer: Service.defaultLayer.pipe(Layer.orDie), deps: [] }) export const node = LayerNode.make({ service: Service, layer: Service.layer.pipe(Layer.orDie), deps: [] })
export * as RuntimeFlags from "./runtime-flags" export * as RuntimeFlags from "./runtime-flags"
import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { LayerNode } from "@opencode-ai/core/effect/layer-node"
@@ -22,7 +22,6 @@ import { McpAuth } from "@/mcp/auth"
import { Permission } from "@/permission" import { Permission } from "@/permission"
import { Plugin } from "@/plugin" import { Plugin } from "@/plugin"
import { PluginPtyEnvironment } from "@/plugin/pty-environment" import { PluginPtyEnvironment } from "@/plugin/pty-environment"
import { InstanceBootstrap } from "@/project/bootstrap"
import { InstanceStore } from "@/project/instance-store" import { InstanceStore } from "@/project/instance-store"
import { Project } from "@/project/project" import { Project } from "@/project/project"
import { Vcs } from "@/project/vcs" import { Vcs } from "@/project/vcs"
@@ -52,7 +51,7 @@ import { Worktree } from "@/worktree"
import { RuntimeFlags } from "@/effect/runtime-flags" import { RuntimeFlags } from "@/effect/runtime-flags"
import { MoveSession } from "@opencode-ai/core/control-plane/move-session" import { MoveSession } from "@opencode-ai/core/control-plane/move-session"
import { Database } from "@opencode-ai/core/database/database" import { Database } from "@opencode-ai/core/database/database"
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" import { AppNodeBuilderV1 } from "@/effect/app-node-builder-v1"
import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { LayerNode } from "@opencode-ai/core/effect/layer-node"
import { httpClient } from "@opencode-ai/core/effect/app-node-platform" import { httpClient } from "@opencode-ai/core/effect/app-node-platform"
import { EventV2 } from "@opencode-ai/core/event" import { EventV2 } from "@opencode-ai/core/event"
@@ -101,7 +100,7 @@ import { sessionHandlers } from "./handlers/session"
import { syncHandlers } from "./handlers/sync" import { syncHandlers } from "./handlers/sync"
import { tuiHandlers } from "./handlers/tui" import { tuiHandlers } from "./handlers/tui"
import { handlers } from "@opencode-ai/server/handlers" import { handlers } from "@opencode-ai/server/handlers"
import { locationServiceMapLayer } from "@opencode-ai/core/location-services" import { buildLocationServiceMap, LocationServiceMap } from "@opencode-ai/core/location-services"
import { layer as locationLayer } from "@opencode-ai/server/location" import { layer as locationLayer } from "@opencode-ai/server/location"
import { sessionLocationLayer } from "@opencode-ai/server/middleware/session-location" import { sessionLocationLayer } from "@opencode-ai/server/middleware/session-location"
import { PtyEnvironment } from "@opencode-ai/server/pty-environment" import { PtyEnvironment } from "@opencode-ai/server/pty-environment"
@@ -134,10 +133,10 @@ const cors = (corsOptions?: CorsOptions) =>
// - ptyConnectApiRoutes: typed WebSocket upgrade route with ticket-aware auth. // - ptyConnectApiRoutes: typed WebSocket upgrade route with ticket-aware auth.
// - instanceApiRoutes: remaining typed instance routes. // - instanceApiRoutes: remaining typed instance routes.
// - uiRoute: raw catch-all fallback; auth is router middleware so public static assets can bypass it. // - uiRoute: raw catch-all fallback; auth is router middleware so public static assets can bypass it.
const authOnlyRouterLayer = authorizationRouterMiddleware.layer.pipe(Layer.provide(ServerAuth.Config.defaultLayer)) const authOnlyRouterLayer = authorizationRouterMiddleware.layer.pipe(Layer.provide(ServerAuth.Config.layer))
const httpApiAuthLayer = authorizationLayer.pipe(Layer.provide(ServerAuth.Config.defaultLayer)) const httpApiAuthLayer = authorizationLayer.pipe(Layer.provide(ServerAuth.Config.layer))
const ptyConnectHttpApiAuthLayer = ptyConnectAuthorizationLayer.pipe(Layer.provide(ServerAuth.Config.defaultLayer)) const ptyConnectHttpApiAuthLayer = ptyConnectAuthorizationLayer.pipe(Layer.provide(ServerAuth.Config.layer))
const serverHttpApiAuthLayer = serverAuthorizationLayer.pipe(Layer.provide(ServerAuth.Config.defaultLayer)) const serverHttpApiAuthLayer = serverAuthorizationLayer.pipe(Layer.provide(ServerAuth.Config.layer))
const workspaceRoutingLive = workspaceRoutingLayer.pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal)) const workspaceRoutingLive = workspaceRoutingLayer.pipe(Layer.provide(Socket.layerWebSocketConstructorGlobal))
const rootApiRoutes = HttpApiBuilder.layer(RootHttpApi).pipe( const rootApiRoutes = HttpApiBuilder.layer(RootHttpApi).pipe(
Layer.provide([controlHandlers, controlPlaneHandlers, globalHandlers]), Layer.provide([controlHandlers, controlPlaneHandlers, globalHandlers]),
@@ -272,6 +271,8 @@ const app = LayerNode.group([
export function createRoutes( export function createRoutes(
corsOptions?: CorsOptions, corsOptions?: CorsOptions,
): Layer.Layer<never, EffectConfig.ConfigError, RouteRequirements> { ): Layer.Layer<never, EffectConfig.ConfigError, RouteRequirements> {
const locationServiceMapV2 = buildLocationServiceMap()
return Layer.mergeAll( return Layer.mergeAll(
rootApiRoutes, rootApiRoutes,
eventApiRoutes, eventApiRoutes,
@@ -287,7 +288,7 @@ export function createRoutes(
corsVaryFix, corsVaryFix,
fenceLayer, fenceLayer,
cors(corsOptions), cors(corsOptions),
AppNodeBuilder.build(MoveSession.node), AppNodeBuilderV1.build(MoveSession.node, [[LocationServiceMap.node, locationServiceMapV2]]),
HttpServer.layerServices, HttpServer.layerServices,
]), ]),
Layer.provide(Layer.succeed(CorsConfig)(corsOptions)), Layer.provide(Layer.succeed(CorsConfig)(corsOptions)),
@@ -297,13 +298,14 @@ export function createRoutes(
Layer.provide(locationLayer), Layer.provide(locationLayer),
Layer.provide(PtyEnvironment.layer), Layer.provide(PtyEnvironment.layer),
Layer.provide( Layer.provide(
AppNodeBuilder.build(SessionV2.node, [[SessionExecution.node, SessionExecutionLocal.node]]).pipe( AppNodeBuilderV1.build(SessionV2.node, [
Layer.provide(locationServiceMapLayer), [LocationServiceMap.node, locationServiceMapV2],
), [SessionExecution.node, SessionExecutionLocal.node],
]),
), ),
Layer.provide(locationServiceMapLayer), Layer.provide(locationServiceMapV2),
Layer.provide(LayerNode.compile(app, [[InstanceStore.bootstrapNode, InstanceBootstrap.node]])), Layer.provide(AppNodeBuilderV1.build(app)),
) )
} }
-74
View File
@@ -1,5 +1,4 @@
import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { LayerNode } from "@opencode-ai/core/effect/layer-node"
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
import { PermissionV1 } from "@opencode-ai/core/v1/permission" import { PermissionV1 } from "@opencode-ai/core/v1/permission"
import { Slug } from "@opencode-ai/core/util/slug" import { Slug } from "@opencode-ai/core/util/slug"
import { SessionV1 } from "@opencode-ai/core/v1/session" import { SessionV1 } from "@opencode-ai/core/v1/session"
@@ -10,7 +9,6 @@ import { Decimal } from "decimal.js"
import type { ProviderMetadata, Usage } from "@opencode-ai/llm" import type { ProviderMetadata, Usage } from "@opencode-ai/llm"
import { InstallationVersion } from "@opencode-ai/core/installation/version" import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { Database } from "@opencode-ai/core/database/database" import { Database } from "@opencode-ai/core/database/database"
import { makeRuntime } from "@opencode-ai/core/effect/runtime"
import { EventV2Bridge } from "@/event-v2-bridge" import { EventV2Bridge } from "@/event-v2-bridge"
import { SessionV2 } from "@opencode-ai/core/session" import { SessionV2 } from "@opencode-ai/core/session"
import * as SessionExecutionLocal from "@opencode-ai/core/session/execution/local" import * as SessionExecutionLocal from "@opencode-ai/core/session/execution/local"
@@ -47,8 +45,6 @@ import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model" import { ModelV2 } from "@opencode-ai/core/model"
import { SessionMessage } from "@opencode-ai/schema/session-message" import { SessionMessage } from "@opencode-ai/schema/session-message"
const runtime = makeRuntime(Database.Service, AppNodeBuilder.build(Database.node))
const parentTitlePrefix = "New session - " const parentTitlePrefix = "New session - "
const childTitlePrefix = "Child session - " const childTitlePrefix = "Child session - "
@@ -1013,76 +1009,6 @@ function listByProject(
) )
} }
export function* listGlobal(input?: {
directory?: string
roots?: boolean
start?: number
cursor?: number
search?: string
limit?: number
archived?: boolean
}) {
const conditions: SQL[] = []
if (input?.directory) {
conditions.push(eq(SessionTable.directory, input.directory))
}
if (input?.roots) {
conditions.push(isNull(SessionTable.parent_id))
}
if (input?.start) {
conditions.push(gte(SessionTable.time_updated, input.start))
}
if (input?.cursor) {
conditions.push(lt(SessionTable.time_updated, input.cursor))
}
if (input?.search) {
conditions.push(like(SessionTable.title, `%${input.search}%`))
}
if (!input?.archived) {
conditions.push(isNull(SessionTable.time_archived))
}
const limit = input?.limit ?? 100
const rows = runtime.runSync(({ db }) => {
const query =
conditions.length > 0
? db
.select()
.from(SessionTable)
.where(and(...conditions))
: db.select().from(SessionTable)
return query.orderBy(desc(SessionTable.time_updated), desc(SessionTable.id)).limit(limit).all().pipe(Effect.orDie)
})
const ids = [...new Set(rows.map((row) => row.project_id))]
const projects = new Map<string, ProjectInfo>()
if (ids.length > 0) {
const items = runtime.runSync(({ db }) =>
db
.select({ id: ProjectTable.id, name: ProjectTable.name, worktree: ProjectTable.worktree })
.from(ProjectTable)
.where(inArray(ProjectTable.id, ids))
.all()
.pipe(Effect.orDie),
)
for (const item of items) {
projects.set(item.id, {
id: item.id,
name: item.name ?? undefined,
worktree: item.worktree,
})
}
}
for (const row of rows) {
const project = projects.get(row.project_id) ?? null
yield { ...fromRow(row), project }
}
}
export const node = LayerNode.make({ export const node = LayerNode.make({
service: Service, service: Service,
layer: layer, layer: layer,
@@ -10,12 +10,12 @@ class TestConfig extends ConfigService.Service<TestConfig>()("@test/ConfigServic
}) {} }) {}
const fromConfig = (input: Record<string, unknown>) => const fromConfig = (input: Record<string, unknown>) =>
TestConfig.defaultLayer.pipe(Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown(input)))) TestConfig.layer.pipe(Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown(input))))
const readConfig = TestConfig.useSync((config) => config) const readConfig = TestConfig.useSync((config) => config)
describe("ConfigService", () => { describe("ConfigService", () => {
it.effect("defaultLayer parses values from the active ConfigProvider", () => it.effect("layer parses values from the active ConfigProvider", () =>
Effect.gen(function* () { Effect.gen(function* () {
const config = yield* readConfig.pipe( const config = yield* readConfig.pipe(
Effect.provide( Effect.provide(
@@ -33,7 +33,7 @@ describe("ConfigService", () => {
}), }),
) )
it.effect("defaultLayer applies Effect Config defaults", () => it.effect("layer applies Effect Config defaults", () =>
Effect.gen(function* () { Effect.gen(function* () {
const config = yield* readConfig.pipe(Effect.provide(fromConfig({ NAME: "kit" }))) const config = yield* readConfig.pipe(Effect.provide(fromConfig({ NAME: "kit" })))
@@ -47,7 +47,7 @@ describe("ConfigService", () => {
Effect.gen(function* () { Effect.gen(function* () {
const config = yield* readConfig.pipe( const config = yield* readConfig.pipe(
Effect.provide( Effect.provide(
TestConfig.layer({ TestConfig.configLayer({
name: "direct", name: "direct",
token: Option.some("parsed"), token: Option.some("parsed"),
port: 9000, port: 9000,
@@ -10,7 +10,7 @@ const fromConfig = (input: Record<string, unknown>) =>
const readFlags = RuntimeFlags.Service.useSync((flags) => flags) const readFlags = RuntimeFlags.Service.useSync((flags) => flags)
describe("RuntimeFlags", () => { describe("RuntimeFlags", () => {
it.effect("defaultLayer defaults autoShare to false", () => it.effect("layer defaults autoShare to false", () =>
Effect.gen(function* () { Effect.gen(function* () {
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({}))) const flags = yield* readFlags.pipe(Effect.provide(fromConfig({})))
@@ -18,7 +18,7 @@ describe("RuntimeFlags", () => {
}), }),
) )
it.effect("defaultLayer parses plugin flags from the active ConfigProvider", () => it.effect("layer parses plugin flags from the active ConfigProvider", () =>
Effect.gen(function* () { Effect.gen(function* () {
const flags = yield* readFlags.pipe( const flags = yield* readFlags.pipe(
Effect.provide( Effect.provide(
@@ -65,7 +65,7 @@ describe("RuntimeFlags", () => {
}), }),
) )
it.effect("defaultLayer parses OPENCODE_EXPERIMENTAL_LSP_TY", () => it.effect("layer parses OPENCODE_EXPERIMENTAL_LSP_TY", () =>
Effect.gen(function* () { Effect.gen(function* () {
const flags = yield* readFlags.pipe( const flags = yield* readFlags.pipe(
Effect.provide( Effect.provide(
@@ -56,9 +56,9 @@ const v2ApiLayer = HttpRouter.serve(
{ disableListenLog: true, disableLogger: true }, { disableListenLog: true, disableLogger: true },
).pipe(Layer.provideMerge(NodeHttpServer.layerTest)) ).pipe(Layer.provideMerge(NodeHttpServer.layerTest))
const noAuthLayer = ServerAuth.Config.layer({ password: Option.none(), username: "opencode" }) const noAuthLayer = ServerAuth.Config.configLayer({ password: Option.none(), username: "opencode" })
const secretLayer = ServerAuth.Config.layer({ password: Option.some("secret"), username: "opencode" }) const secretLayer = ServerAuth.Config.configLayer({ password: Option.some("secret"), username: "opencode" })
const kitSecretLayer = ServerAuth.Config.layer({ password: Option.some("secret"), username: "kit" }) const kitSecretLayer = ServerAuth.Config.configLayer({ password: Option.some("secret"), username: "kit" })
const it = testEffect(apiLayer.pipe(Layer.provide(noAuthLayer))) const it = testEffect(apiLayer.pipe(Layer.provide(noAuthLayer)))
const itSecret = testEffect(apiLayer.pipe(Layer.provide(secretLayer))) const itSecret = testEffect(apiLayer.pipe(Layer.provide(secretLayer)))
@@ -44,7 +44,7 @@ const apiLayer = HttpRouter.serve(
moveSession: (value) => Ref.set(called, value), moveSession: (value) => Ref.set(called, value),
}), }),
), ),
Layer.provide(ServerAuth.Config.layer({ password: Option.none(), username: "opencode" })), Layer.provide(ServerAuth.Config.configLayer({ password: Option.none(), username: "opencode" })),
) )
const it = testEffect(apiLayer) const it = testEffect(apiLayer)
@@ -38,7 +38,7 @@ const apiLayer = HttpRouter.serve(
upgrade: () => Effect.void, upgrade: () => Effect.void,
}), }),
), ),
Layer.provide(ServerAuth.Config.layer({ password: Option.none(), username: "opencode" })), Layer.provide(ServerAuth.Config.configLayer({ password: Option.none(), username: "opencode" })),
) )
const it = testEffect(apiLayer) const it = testEffect(apiLayer)
@@ -44,7 +44,7 @@ const fsUtilLayer = AppNodeBuilder.build(FSUtil.node)
const it = testEffect(Layer.mergeAll(testStateLayer, fsUtilLayer, RuntimeFlags.layer())) const it = testEffect(Layer.mergeAll(testStateLayer, fsUtilLayer, RuntimeFlags.layer()))
function authConfigLayer(input?: { password?: string; username?: string }) { function authConfigLayer(input?: { password?: string; username?: string }) {
return ServerAuth.Config.layer({ return ServerAuth.Config.configLayer({
password: input?.password === undefined ? Option.none() : Option.some(input.password), password: input?.password === undefined ? Option.none() : Option.some(input.password),
username: input?.username ?? "opencode", username: input?.username ?? "opencode",
}) })
@@ -3,6 +3,7 @@ import { LLMEvent, ToolFailure } from "@opencode-ai/llm"
import { LLMClient, RequestExecutor, WebSocketExecutor, type LLMClientShape } from "@opencode-ai/llm/route" import { LLMClient, RequestExecutor, WebSocketExecutor, type LLMClientShape } from "@opencode-ai/llm/route"
import { jsonSchema, tool, type ModelMessage, type Tool } from "ai" import { jsonSchema, tool, type ModelMessage, type Tool } from "ai"
import { Effect, Fiber, Layer, Stream } from "effect" import { Effect, Fiber, Layer, Stream } from "effect"
import { FetchHttpClient } from "effect/unstable/http"
import { LLMNative } from "@/session/llm/native-request" import { LLMNative } from "@/session/llm/native-request"
import { LLMNativeRuntime } from "@/session/llm/native-runtime" import { LLMNativeRuntime } from "@/session/llm/native-runtime"
import type { Provider } from "@/provider/provider" import type { Provider } from "@/provider/provider"
@@ -73,7 +74,9 @@ const providerInfo: Provider.Info = {
} }
const it = testEffect( const it = testEffect(
LLMClient.layer.pipe(Layer.provide(Layer.mergeAll(RequestExecutor.defaultLayer, WebSocketExecutor.layer))), LLMClient.layer.pipe(
Layer.provide(Layer.mergeAll(RequestExecutor.layer.pipe(Layer.provide(FetchHttpClient.layer)), WebSocketExecutor.layer)),
),
) )
function responsesStream(chunks: unknown[]) { function responsesStream(chunks: unknown[]) {