فهرست منبع

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

Kit Langton 4 ماه پیش
والد
کامیت
1409a0715c
2فایلهای تغییر یافته به همراه37 افزوده شده و 29 حذف شده
  1. 26 21
      packages/opencode/src/cli/cmd/account.ts
  2. 11 8
      packages/opencode/src/cli/cmd/web.ts

+ 26 - 21
packages/opencode/src/cli/cmd/account.ts

@@ -3,7 +3,7 @@ import { Duration, Effect, Match, Option } from "effect"
 import { UI } from "../ui"
 import { Account } from "@/account/account"
 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 open from "open"
 
@@ -172,60 +172,65 @@ const openEffect = Effect.fn("open")(function* () {
   yield* Prompt.outro("Opened " + url)
 })
 
-export const LoginCommand = cmd({
+export const LoginCommand = effectCmd({
   command: "login <url>",
   describe: false,
+  instance: false,
   builder: (yargs) =>
     yargs.positional("url", {
       describe: "server URL",
       type: "string",
       demandOption: true,
     }),
-  async handler(args) {
+  handler: Effect.fn("Cli.account.login")(function* (args) {
     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]",
   describe: false,
+  instance: false,
   builder: (yargs) =>
     yargs.positional("email", {
       describe: "account email to log out from",
       type: "string",
     }),
-  async handler(args) {
+  handler: Effect.fn("Cli.account.logout")(function* (args) {
     UI.empty()
-    await AppRuntime.runPromise(logoutEffect(args.email))
-  },
+    yield* Effect.orDie(logoutEffect(args.email))
+  }),
 })
 
-export const SwitchCommand = cmd({
+export const SwitchCommand = effectCmd({
   command: "switch",
   describe: false,
-  async handler() {
+  instance: false,
+  handler: Effect.fn("Cli.account.switch")(function* () {
     UI.empty()
-    await AppRuntime.runPromise(switchEffect())
-  },
+    yield* Effect.orDie(switchEffect())
+  }),
 })
 
-export const OrgsCommand = cmd({
+export const OrgsCommand = effectCmd({
   command: "orgs",
   describe: false,
-  async handler() {
+  instance: false,
+  handler: Effect.fn("Cli.account.orgs")(function* () {
     UI.empty()
-    await AppRuntime.runPromise(orgsEffect())
-  },
+    yield* Effect.orDie(orgsEffect())
+  }),
 })
 
-export const OpenCommand = cmd({
+export const OpenCommand = effectCmd({
   command: "open",
   describe: false,
-  async handler() {
+  instance: false,
+  handler: Effect.fn("Cli.account.open")(function* () {
     UI.empty()
-    await AppRuntime.runPromise(openEffect())
-  },
+    yield* Effect.orDie(openEffect())
+  }),
 })
 
 export const ConsoleCommand = cmd({

+ 11 - 8
packages/opencode/src/cli/cmd/web.ts

@@ -1,6 +1,7 @@
+import { Effect } from "effect"
 import { Server } from "../../server/server"
 import { UI } from "../ui"
-import { cmd } from "./cmd"
+import { effectCmd } from "../effect-cmd"
 import { withNetworkOptions, resolveNetworkOptions } from "../network"
 import { Flag } from "@opencode-ai/core/flag/flag"
 import open from "open"
@@ -28,16 +29,19 @@ function getNetworkIPs() {
   return results
 }
 
-export const WebCommand = cmd({
+export const WebCommand = effectCmd({
   command: "web",
   builder: (yargs) => withNetworkOptions(yargs),
   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) {
       UI.println(UI.Style.TEXT_WARNING_BOLD + "!  OPENCODE_SERVER_PASSWORD is not set; server is unsecured.")
     }
-    const opts = await resolveNetworkOptions(args)
-    const server = await Server.listen(opts)
+    const opts = yield* Effect.promise(() => resolveNetworkOptions(args))
+    const server = yield* Effect.promise(() => Server.listen(opts))
     UI.empty()
     UI.println(UI.logo("  "))
     UI.empty()
@@ -75,7 +79,6 @@ export const WebCommand = cmd({
       open(displayUrl).catch(() => {})
     }
 
-    await new Promise(() => {})
-    await server.stop()
-  },
+    yield* Effect.never
+  }),
 })