refactor(cli): convert web + account to effectCmd (instance: false) (#25512)

This commit is contained in:
Kit Langton
2026-05-02 21:59:35 -04:00
committed by GitHub
parent e98c291866
commit 1409a0715c
2 changed files with 37 additions and 29 deletions
+26 -21
View File
@@ -3,7 +3,7 @@ import { Duration, Effect, Match, Option } from "effect"
import { UI } from "../ui" import { UI } from "../ui"
import { Account } from "@/account/account" import { Account } from "@/account/account"
import { AccountID, OrgID, PollExpired, type PollResult, type AccountError } from "@/account/schema" import { AccountID, OrgID, PollExpired, type PollResult, type AccountError } from "@/account/schema"
import { AppRuntime } from "@/effect/app-runtime" import { effectCmd } from "../effect-cmd"
import * as Prompt from "../effect/prompt" import * as Prompt from "../effect/prompt"
import open from "open" import open from "open"
@@ -172,60 +172,65 @@ const openEffect = Effect.fn("open")(function* () {
yield* Prompt.outro("Opened " + url) yield* Prompt.outro("Opened " + url)
}) })
export const LoginCommand = cmd({ export const LoginCommand = effectCmd({
command: "login <url>", command: "login <url>",
describe: false, describe: false,
instance: false,
builder: (yargs) => builder: (yargs) =>
yargs.positional("url", { yargs.positional("url", {
describe: "server URL", describe: "server URL",
type: "string", type: "string",
demandOption: true, demandOption: true,
}), }),
async handler(args) { handler: Effect.fn("Cli.account.login")(function* (args) {
UI.empty() UI.empty()
await AppRuntime.runPromise(loginEffect(args.url)) yield* Effect.orDie(loginEffect(args.url))
}, }),
}) })
export const LogoutCommand = cmd({ export const LogoutCommand = effectCmd({
command: "logout [email]", command: "logout [email]",
describe: false, describe: false,
instance: false,
builder: (yargs) => builder: (yargs) =>
yargs.positional("email", { yargs.positional("email", {
describe: "account email to log out from", describe: "account email to log out from",
type: "string", type: "string",
}), }),
async handler(args) { handler: Effect.fn("Cli.account.logout")(function* (args) {
UI.empty() UI.empty()
await AppRuntime.runPromise(logoutEffect(args.email)) yield* Effect.orDie(logoutEffect(args.email))
}, }),
}) })
export const SwitchCommand = cmd({ export const SwitchCommand = effectCmd({
command: "switch", command: "switch",
describe: false, describe: false,
async handler() { instance: false,
handler: Effect.fn("Cli.account.switch")(function* () {
UI.empty() UI.empty()
await AppRuntime.runPromise(switchEffect()) yield* Effect.orDie(switchEffect())
}, }),
}) })
export const OrgsCommand = cmd({ export const OrgsCommand = effectCmd({
command: "orgs", command: "orgs",
describe: false, describe: false,
async handler() { instance: false,
handler: Effect.fn("Cli.account.orgs")(function* () {
UI.empty() UI.empty()
await AppRuntime.runPromise(orgsEffect()) yield* Effect.orDie(orgsEffect())
}, }),
}) })
export const OpenCommand = cmd({ export const OpenCommand = effectCmd({
command: "open", command: "open",
describe: false, describe: false,
async handler() { instance: false,
handler: Effect.fn("Cli.account.open")(function* () {
UI.empty() UI.empty()
await AppRuntime.runPromise(openEffect()) yield* Effect.orDie(openEffect())
}, }),
}) })
export const ConsoleCommand = cmd({ export const ConsoleCommand = cmd({
+11 -8
View File
@@ -1,6 +1,7 @@
import { Effect } from "effect"
import { Server } from "../../server/server" import { Server } from "../../server/server"
import { UI } from "../ui" import { UI } from "../ui"
import { cmd } from "./cmd" import { effectCmd } from "../effect-cmd"
import { withNetworkOptions, resolveNetworkOptions } from "../network" import { withNetworkOptions, resolveNetworkOptions } from "../network"
import { Flag } from "@opencode-ai/core/flag/flag" import { Flag } from "@opencode-ai/core/flag/flag"
import open from "open" import open from "open"
@@ -28,16 +29,19 @@ function getNetworkIPs() {
return results return results
} }
export const WebCommand = cmd({ export const WebCommand = effectCmd({
command: "web", command: "web",
builder: (yargs) => withNetworkOptions(yargs), builder: (yargs) => withNetworkOptions(yargs),
describe: "start opencode server and open web interface", describe: "start opencode server and open web interface",
handler: async (args) => { // Server loads instances per-request via x-opencode-directory header — no
// ambient project InstanceContext needed at startup.
instance: false,
handler: Effect.fn("Cli.web")(function* (args) {
if (!Flag.OPENCODE_SERVER_PASSWORD) { if (!Flag.OPENCODE_SERVER_PASSWORD) {
UI.println(UI.Style.TEXT_WARNING_BOLD + "! OPENCODE_SERVER_PASSWORD is not set; server is unsecured.") UI.println(UI.Style.TEXT_WARNING_BOLD + "! OPENCODE_SERVER_PASSWORD is not set; server is unsecured.")
} }
const opts = await resolveNetworkOptions(args) const opts = yield* Effect.promise(() => resolveNetworkOptions(args))
const server = await Server.listen(opts) const server = yield* Effect.promise(() => Server.listen(opts))
UI.empty() UI.empty()
UI.println(UI.logo(" ")) UI.println(UI.logo(" "))
UI.empty() UI.empty()
@@ -75,7 +79,6 @@ export const WebCommand = cmd({
open(displayUrl).catch(() => {}) open(displayUrl).catch(() => {})
} }
await new Promise(() => {}) yield* Effect.never
await server.stop() }),
},
}) })