Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions packages/opencode/src/server/instance/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,13 @@ export function createGlobalRoutes(options: GlobalRoutesOptions = {}) {
},
}),
async (c) => {
return c.json(await Config.getGlobal())
const config = await AppRuntime.runPromise(
Effect.gen(function* () {
const service = yield* Config.Service
return yield* service.getGlobal()
}),
)
Comment thread
Astro-Han marked this conversation as resolved.
return c.json(config)
},
)
.patch(
Expand All @@ -416,7 +422,12 @@ export function createGlobalRoutes(options: GlobalRoutesOptions = {}) {
validator("json", Config.Info.zod),
async (c) => {
const config = c.req.valid("json")
const next = await Config.updateGlobal(config)
const next = await AppRuntime.runPromise(
Effect.gen(function* () {
const service = yield* Config.Service
return yield* service.updateGlobal(config)
}),
)
Comment thread
Astro-Han marked this conversation as resolved.
return c.json(next)
},
)
Expand Down
70 changes: 70 additions & 0 deletions packages/opencode/test/server/global-config-routes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { afterEach, describe, expect, test } from "bun:test"
import fs from "fs/promises"
import path from "path"
import { Hono } from "hono"
import { Config } from "../../src/config"
import { AppRuntime } from "../../src/effect/app-runtime"
import { Global } from "../../src/global"
import { Instance } from "../../src/project/instance"
import { GlobalRoutes } from "../../src/server/instance/global"
import { tmpdir } from "../fixture/fixture"
import { withConfigDepsLock } from "../shared/config-deps-lock"

afterEach(async () => {
await Instance.disposeAll()
})

async function invalidateConfig() {
await AppRuntime.runPromise(Config.Service.use((svc) => svc.invalidate(true)))
}

async function withIsolatedGlobalConfig<T>(fn: (globalDir: string) => Promise<T>) {
await using global = await tmpdir()
const previousRuntime = process.env.PAWWORK_RUNTIME_NAMESPACE
const previousHome = process.env.PAWWORK_HOME
const previousConfigDir = process.env.PAWWORK_CONFIG_DIR
const previousConfig = Global.Path.config

process.env.PAWWORK_RUNTIME_NAMESPACE = "pawwork"
process.env.PAWWORK_HOME = global.path
delete process.env.PAWWORK_CONFIG_DIR
;(Global.Path as { config: string }).config = global.path
await invalidateConfig()

try {
return await fn(global.path)
} finally {
;(Global.Path as { config: string }).config = previousConfig
if (previousRuntime === undefined) delete process.env.PAWWORK_RUNTIME_NAMESPACE
else process.env.PAWWORK_RUNTIME_NAMESPACE = previousRuntime
if (previousHome === undefined) delete process.env.PAWWORK_HOME
else process.env.PAWWORK_HOME = previousHome
if (previousConfigDir === undefined) delete process.env.PAWWORK_CONFIG_DIR
else process.env.PAWWORK_CONFIG_DIR = previousConfigDir
await invalidateConfig()
}
}

describe("global config routes", () => {
test("gets and patches global config through the route runtime", async () => {
await withConfigDepsLock(async () => {
await withIsolatedGlobalConfig(async (globalDir) => {
const app = new Hono().route("/global", GlobalRoutes())

const before = await app.request("/global/config")
expect(before.status).toBe(200)

const response = await app.request("/global/config", {
method: "PATCH",
headers: { "content-type": "application/json" },
body: JSON.stringify({ model: "test/model" }),
})
const body = await response.json()

expect(response.status).toBe(200)
expect(body.model).toBe("test/model")
expect(JSON.parse(await fs.readFile(path.join(globalDir, "pawwork.json"), "utf8")).model).toBe("test/model")
})
})
})
})
Loading