refactor(opencode): pass server endpoint to TUI

This commit is contained in:
starptech 2026-07-10 00:09:25 +01:00
parent 9307833c5c
commit 00fb739ad6
4 changed files with 25 additions and 12 deletions

View file

@ -3,8 +3,6 @@ import { UI } from "@/cli/ui"
import { errorMessage } from "@opencode-ai/tui/util/error"
import { validateSession } from "../tui/validate-session"
import { ServerAuth } from "@/server/auth"
import { OpenCode } from "@opencode-ai/client/promise"
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
export const AttachCommand = cmd({
command: "attach <url>",
@ -63,7 +61,9 @@ export const AttachCommand = cmd({
return
}
const headers = ServerAuth.headers({ password: args.password, username: args.username })
const credentials = { password: args.password, username: args.username }
const headers = ServerAuth.headers(credentials)
const endpoint = ServerAuth.endpoint(args.url, credentials)
const config = await TuiConfig.get()
try {
@ -84,9 +84,7 @@ export const AttachCommand = cmd({
const { createLegacyTuiPluginHost } = await import("@/plugin/tui/runtime")
await Effect.runPromise(
run({
// @ts-expect-error V1 does not consume the V2-only server input.
client: createOpencodeClient({ baseUrl: args.url, headers, directory }),
api: OpenCode.make({ baseUrl: args.url, headers }),
server: { endpoint },
config,
pluginHost: createLegacyTuiPluginHost(),
args: {

View file

@ -8,8 +8,6 @@ import { errorMessage } from "@opencode-ai/tui/util/error"
import { withTimeout } from "@/util/timeout"
import { withNetworkOptions, resolveNetworkOptionsNoConfig, hasArg } from "@/cli/network"
import { Filesystem } from "@/util/filesystem"
import { OpenCode } from "@opencode-ai/client/promise"
import { createOpencodeClient } from "@opencode-ai/sdk/v2"
import { writeHeapSnapshot } from "v8"
import { ServerAuth } from "@/server/auth"
import { validateSession } from "../tui/validate-session"
@ -135,6 +133,7 @@ export const TuiThreadCommand = cmd({
const external = hasArg("--port") || hasArg("--hostname") || network.mdns === true
const headers = external ? ServerAuth.headers() : undefined
const url = (await client.call("server", network)).url
const endpoint = external ? ServerAuth.endpoint(url) : { url }
try {
await validateSession({
@ -157,11 +156,9 @@ export const TuiThreadCommand = cmd({
const { Effect } = await import("effect")
const { run } = await import("../tui/layer")
const { createLegacyTuiPluginHost } = await import("@/plugin/tui/runtime")
await Effect.runPromise(
await Effect.runPromise(
run({
// @ts-expect-error V1 does not consume the V2-only server input.
client: createOpencodeClient({ baseUrl: url, headers, directory: cwd }),
api: OpenCode.make({ baseUrl: url, headers }),
server: { endpoint },
async onSnapshot() {
const tui = writeHeapSnapshot("tui.heapsnapshot")
const server = await client.call("snapshot", undefined)

View file

@ -1,6 +1,7 @@
export * as ServerAuth from "./auth"
import { ConfigService } from "@/effect/config-service"
import { Service } from "@opencode-ai/client/effect"
import { Flag } from "@opencode-ai/core/flag/flag"
import { Config as EffectConfig, Context, Option, Redacted } from "effect"
@ -46,3 +47,12 @@ export function headers(credentials?: Credentials) {
if (!authorization) return undefined
return { Authorization: authorization }
}
export function endpoint(url: string, credentials?: Credentials): Service.Endpoint {
const password = credentials?.password ?? Flag.OPENCODE_SERVER_PASSWORD
const username = credentials?.username ?? Flag.OPENCODE_SERVER_USERNAME ?? "opencode"
return {
url,
auth: password ? { type: "basic", username, password } : undefined,
}
}

View file

@ -20,6 +20,10 @@ describe("ServerAuth", () => {
expect(ServerAuth.header()).toBeUndefined()
expect(ServerAuth.headers()).toBeUndefined()
expect(ServerAuth.endpoint("http://localhost:4096")).toEqual({
url: "http://localhost:4096",
auth: undefined,
})
})
test("defaults to the opencode username", () => {
@ -47,6 +51,10 @@ describe("ServerAuth", () => {
expect(ServerAuth.headers({ password: "cli-secret", username: "bob" })).toEqual({
Authorization: `Basic ${Buffer.from("bob:cli-secret").toString("base64")}`,
})
expect(ServerAuth.endpoint("https://example.test", { password: "cli-secret", username: "bob" })).toEqual({
url: "https://example.test",
auth: { type: "basic", username: "bob", password: "cli-secret" },
})
})
test("validates decoded credentials against effect config", () => {