effect: add RuntimeFlags service (#27181)

This commit is contained in:
Kit Langton
2026-05-12 20:59:02 -04:00
committed by GitHub
parent d0b8ff0f22
commit b7c6fa611f
9 changed files with 124 additions and 41 deletions

View File

@@ -0,0 +1,27 @@
import { Config, ConfigProvider, Context, Effect, Layer } from "effect"
import { ConfigService } from "@/effect/config-service"
export class Service extends ConfigService.Service<Service>()("@opencode/RuntimeFlags", {
pure: Config.boolean("OPENCODE_PURE").pipe(Config.withDefault(false)),
disableDefaultPlugins: Config.boolean("OPENCODE_DISABLE_DEFAULT_PLUGINS").pipe(Config.withDefault(false)),
}) {}
export type Info = Context.Service.Shape<typeof Service>
const emptyConfigLayer = Service.defaultLayer.pipe(
Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown({}))),
Layer.orDie,
)
export const layer = (overrides: Partial<Info> = {}) =>
Layer.effect(
Service,
Effect.gen(function* () {
const flags = yield* Service
return Service.of({ ...flags, ...overrides })
}),
).pipe(Layer.provide(emptyConfigLayer))
export const defaultLayer = Service.defaultLayer.pipe(Layer.orDie)
export * as RuntimeFlags from "./runtime-flags"

View File

@@ -9,7 +9,6 @@ import { Config } from "@/config/config"
import { Bus } from "../bus"
import * as Log from "@opencode-ai/core/util/log"
import { createOpencodeClient } from "@opencode-ai/sdk"
import { Flag } from "@opencode-ai/core/flag/flag"
import { ServerAuth } from "@/server/auth"
import { CodexAuthPlugin } from "./codex"
import { Session } from "@/session/session"
@@ -28,6 +27,7 @@ import { PluginLoader } from "./loader"
import { parsePluginSpecifier, readPluginId, readV1Plugin, resolvePluginId } from "./shared"
import { registerAdapter } from "@/control-plane/adapters"
import type { WorkspaceAdapter } from "@/control-plane/types"
import { RuntimeFlags } from "@/effect/runtime-flags"
const log = Log.create({ service: "plugin" })
@@ -112,6 +112,7 @@ export const layer = Layer.effect(
Effect.gen(function* () {
const bus = yield* Bus.Service
const config = yield* Config.Service
const flags = yield* RuntimeFlags.Service
const state = yield* InstanceState.make<State>(
Effect.fn("Plugin.state")(function* (ctx) {
@@ -148,7 +149,7 @@ export const layer = Layer.effect(
$: typeof Bun === "undefined" ? undefined : Bun.$,
}
for (const plugin of INTERNAL_PLUGINS) {
for (const plugin of flags.disableDefaultPlugins ? [] : INTERNAL_PLUGINS) {
log.info("loading internal plugin", { name: plugin.name })
const init = yield* Effect.tryPromise({
try: () => plugin(input),
@@ -159,8 +160,8 @@ export const layer = Layer.effect(
if (init._tag === "Some") hooks.push(init.value)
}
const plugins = Flag.OPENCODE_PURE ? [] : (cfg.plugin_origins ?? [])
if (Flag.OPENCODE_PURE && cfg.plugin_origins?.length) {
const plugins = flags.pure ? [] : (cfg.plugin_origins ?? [])
if (flags.pure && cfg.plugin_origins?.length) {
log.info("skipping external plugins in pure mode", { count: cfg.plugin_origins.length })
}
if (plugins.length) yield* config.waitForDependencies()
@@ -285,6 +286,10 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = layer.pipe(Layer.provide(Bus.layer), Layer.provide(Config.defaultLayer))
export const defaultLayer = layer.pipe(
Layer.provide(Bus.layer),
Layer.provide(Config.defaultLayer),
Layer.provide(RuntimeFlags.defaultLayer),
)
export * as Plugin from "."