refactor: isolate legacy flags
This commit is contained in:
parent
407ac2d8aa
commit
43c08387f1
65 changed files with 282 additions and 147 deletions
|
|
@ -1,11 +1,9 @@
|
|||
export * as ServerAuth from "./auth"
|
||||
|
||||
import { Context, Effect, Layer, Option, Redacted } from "effect"
|
||||
import { all, option, string, withDefault } from "effect/Config"
|
||||
import { Context, Layer, Option, Redacted } from "effect"
|
||||
|
||||
export type Credentials = {
|
||||
password?: string
|
||||
username?: string
|
||||
}
|
||||
|
||||
export type DecodedCredentials = {
|
||||
|
|
@ -15,7 +13,6 @@ export type DecodedCredentials = {
|
|||
|
||||
export type Info = {
|
||||
readonly password: Option.Option<string>
|
||||
readonly username: string
|
||||
}
|
||||
|
||||
export class Config extends Context.Service<Config, Info>()("@opencode/ServerAuthConfig") {
|
||||
|
|
@ -24,17 +21,7 @@ export class Config extends Context.Service<Config, Info>()("@opencode/ServerAut
|
|||
}
|
||||
|
||||
static get layer() {
|
||||
return Layer.effect(
|
||||
this,
|
||||
Effect.gen(function* () {
|
||||
return Config.of(
|
||||
yield* all({
|
||||
password: string("OPENCODE_SERVER_PASSWORD").pipe(option),
|
||||
username: string("OPENCODE_SERVER_USERNAME").pipe(withDefault("opencode")),
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
return this.configLayer({ password: Option.none() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,16 +32,16 @@ export function required(config: Info) {
|
|||
export function authorized(credentials: DecodedCredentials, config: Info) {
|
||||
return (
|
||||
Option.isSome(config.password) &&
|
||||
credentials.username === config.username &&
|
||||
credentials.username === "opencode" &&
|
||||
Redacted.value(credentials.password) === config.password.value
|
||||
)
|
||||
}
|
||||
|
||||
export function header(credentials?: Credentials) {
|
||||
const password = credentials?.password ?? process.env.OPENCODE_SERVER_PASSWORD
|
||||
const password = credentials?.password
|
||||
if (!password) return undefined
|
||||
|
||||
return `Basic ${Buffer.from(`${credentials?.username ?? process.env.OPENCODE_SERVER_USERNAME ?? "opencode"}:${password}`).toString("base64")}`
|
||||
return `Basic ${Buffer.from(`opencode:${password}`).toString("base64")}`
|
||||
}
|
||||
|
||||
export function headers(credentials?: Credentials) {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,13 @@ import { Observability } from "@opencode-ai/core/observability"
|
|||
import { Schema } from "effect"
|
||||
|
||||
export const ServerOptions = Schema.Struct({
|
||||
client: Schema.optional(Schema.String),
|
||||
hostname: Schema.optional(Schema.String),
|
||||
port: Schema.optional(
|
||||
Schema.Int.check(Schema.isGreaterThanOrEqualTo(1), Schema.isLessThanOrEqualTo(65_535)),
|
||||
),
|
||||
password: Schema.optional(Schema.String),
|
||||
simulation: Schema.optional(Schema.Boolean),
|
||||
database: Schema.optional(Database.Options),
|
||||
models: Schema.optional(ModelsDev.Options),
|
||||
observability: Schema.optional(Observability.Options),
|
||||
|
|
@ -16,6 +18,8 @@ export const ServerOptions = Schema.Struct({
|
|||
Schema.Struct({
|
||||
directory: Schema.optional(Schema.String),
|
||||
project: Schema.optional(Schema.Boolean),
|
||||
file: Schema.optional(Schema.String),
|
||||
content: Schema.optional(Schema.String),
|
||||
}),
|
||||
),
|
||||
windows: Schema.optional(
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ function dispatch(
|
|||
application: Ref.Ref<Option.Option<App>>,
|
||||
shutdown: Deferred.Deferred<void>,
|
||||
): App {
|
||||
const auth = ServerAuth.Config.of({ username: "opencode", password: Option.some(password) })
|
||||
const auth = ServerAuth.Config.of({ password: Option.some(password) })
|
||||
return Effect.gen(function* () {
|
||||
const request = yield* HttpServerRequest.HttpServerRequest
|
||||
const url = new URL(request.url, "http://localhost")
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ import { PtyTicket } from "@opencode-ai/core/pty/ticket"
|
|||
import { Pty } from "@opencode-ai/core/pty"
|
||||
import { Project } from "@opencode-ai/core/project"
|
||||
import { SessionV2 } from "@opencode-ai/core/session"
|
||||
import { SessionCompaction } from "@opencode-ai/core/session/compaction"
|
||||
import { SessionGenerateNode } from "@opencode-ai/core/session/generate-node"
|
||||
import { SessionModelRequest } from "@opencode-ai/core/session/model-request"
|
||||
import { SessionTitle } from "@opencode-ai/core/session/title"
|
||||
import { Shell } from "@opencode-ai/core/shell"
|
||||
import { Job } from "@opencode-ai/core/job"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
|
|
@ -64,7 +68,7 @@ const applicationServices = LayerNode.group([
|
|||
export function createRoutes(options: ServerOptions = {}, serviceURLs: () => ReadonlyArray<string> = () => []) {
|
||||
return makeRoutes(
|
||||
options.password
|
||||
? ServerAuth.Config.configLayer({ username: "opencode", password: Option.some(options.password) })
|
||||
? ServerAuth.Config.configLayer({ password: Option.some(options.password) })
|
||||
: ServerAuth.Config.layer,
|
||||
options,
|
||||
serviceURLs,
|
||||
|
|
@ -72,7 +76,7 @@ export function createRoutes(options: ServerOptions = {}, serviceURLs: () => Rea
|
|||
}
|
||||
|
||||
export function createEmbeddedRoutes(options: ServerOptions = {}) {
|
||||
return makeRoutes(ServerAuth.Config.configLayer({ username: "opencode", password: Option.none() }), options, () => [])
|
||||
return makeRoutes(ServerAuth.Config.configLayer({ password: Option.none() }), options, () => [])
|
||||
}
|
||||
|
||||
function makeRoutes<AuthError, AuthServices>(
|
||||
|
|
@ -83,19 +87,30 @@ function makeRoutes<AuthError, AuthServices>(
|
|||
const pluginRuntimeCell = PluginRuntime.makeCell()
|
||||
const replacements: LayerNode.Replacements = [
|
||||
[Database.node, Database.configured(options.database)],
|
||||
[ModelsDev.node, ModelsDev.configured(options.models)],
|
||||
[ModelsDev.node, ModelsDev.configured({ ...options.models, client: options.client })],
|
||||
[Watcher.node, Watcher.configured({ enabled: options.fs?.filewatcher })],
|
||||
[FileSystemSearch.node, FileSystemSearch.configured({ fff: options.fs?.fff })],
|
||||
[Global.node, Global.layerWith(options.config?.directory ? { config: options.config.directory } : {})],
|
||||
[Config.node, Config.configured({ project: options.config?.project })],
|
||||
[
|
||||
Config.node,
|
||||
Config.configured({
|
||||
project: options.config?.project,
|
||||
file: options.config?.file,
|
||||
content: options.config?.content,
|
||||
}),
|
||||
],
|
||||
[InstructionDiscovery.node, InstructionDiscovery.configured({ project: options.config?.project })],
|
||||
[CommandV2.node, CommandV2.configured({ gitbash: options.windows?.gitbash })],
|
||||
[Pty.node, Pty.configured({ gitbash: options.windows?.gitbash })],
|
||||
[Shell.node, Shell.configured({ gitbash: options.windows?.gitbash })],
|
||||
[SessionCompaction.node, SessionCompaction.configured({ client: options.client })],
|
||||
[SessionGenerateNode.node, SessionGenerateNode.configured({ client: options.client })],
|
||||
[SessionModelRequest.node, SessionModelRequest.configured({ client: options.client })],
|
||||
[SessionTitle.node, SessionTitle.configured({ client: options.client })],
|
||||
[PluginRuntime.node, PluginRuntime.layerWithCell(pluginRuntimeCell)],
|
||||
[PluginRuntime.providerNode, PluginRuntime.providerNodeWithCell(pluginRuntimeCell)],
|
||||
]
|
||||
const serviceLayer = simulateEnabled()
|
||||
const serviceLayer = options.simulation
|
||||
? Layer.unwrap(
|
||||
Effect.gen(function* () {
|
||||
const { simulationReplacements } = yield* Effect.promise(() => import("@opencode-ai/simulation/backend"))
|
||||
|
|
@ -120,7 +135,7 @@ function makeRoutes<AuthError, AuthServices>(
|
|||
Layer.provide(authorizationLayer),
|
||||
Layer.provide(schemaErrorLayer),
|
||||
Layer.provide(auth),
|
||||
Layer.provide(Observability.layer(options.observability)),
|
||||
Layer.provide(Observability.layer({ ...options.observability, client: options.client })),
|
||||
HttpRouter.provideRequest(requestServices),
|
||||
Layer.provideMerge(services),
|
||||
Layer.provideMerge(HttpRouter.layer),
|
||||
|
|
@ -129,8 +144,4 @@ function makeRoutes<AuthError, AuthServices>(
|
|||
)
|
||||
}
|
||||
|
||||
function simulateEnabled() {
|
||||
return !!process.env.OPENCODE_SIMULATE
|
||||
}
|
||||
|
||||
export const webHandler = () => HttpRouter.toWebHandler(createRoutes().pipe(Layer.provide(HttpServer.layerServices)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue