Просмотр исходного кода

refactor(cli): convert debug wait, agent list, acp to effectCmd (#25518)

Kit Langton 3 месяцев назад
Родитель
Сommit
2829943ad1

+ 45 - 44
packages/opencode/src/cli/cmd/acp.ts

@@ -1,6 +1,6 @@
 import * as Log from "@opencode-ai/core/util/log"
-import { bootstrap } from "../bootstrap"
-import { cmd } from "./cmd"
+import { Effect } from "effect"
+import { effectCmd } from "../effect-cmd"
 import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
 import { ACP } from "@/acp/agent"
 import { Server } from "@/server/server"
@@ -9,7 +9,7 @@ import { withNetworkOptions, resolveNetworkOptions } from "../network"
 
 const log = Log.create({ service: "acp-command" })
 
-export const AcpCommand = cmd({
+export const AcpCommand = effectCmd({
   command: "acp",
   describe: "start ACP (Agent Client Protocol) server",
   builder: (yargs) => {
@@ -19,52 +19,53 @@ export const AcpCommand = cmd({
       default: process.cwd(),
     })
   },
-  handler: async (args) => {
+  handler: Effect.fn("Cli.acp")(function* (args) {
     process.env.OPENCODE_CLIENT = "acp"
-    await bootstrap(process.cwd(), async () => {
-      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))
 
-      const sdk = createOpencodeClient({
-        baseUrl: `http://${server.hostname}:${server.port}`,
-      })
+    const sdk = createOpencodeClient({
+      baseUrl: `http://${server.hostname}:${server.port}`,
+    })
 
-      const input = new WritableStream<Uint8Array>({
-        write(chunk) {
-          return new Promise<void>((resolve, reject) => {
-            process.stdout.write(chunk, (err) => {
-              if (err) {
-                reject(err)
-              } else {
-                resolve()
-              }
-            })
-          })
-        },
-      })
-      const output = new ReadableStream<Uint8Array>({
-        start(controller) {
-          process.stdin.on("data", (chunk: Buffer) => {
-            controller.enqueue(new Uint8Array(chunk))
+    const input = new WritableStream<Uint8Array>({
+      write(chunk) {
+        return new Promise<void>((resolve, reject) => {
+          process.stdout.write(chunk, (err) => {
+            if (err) {
+              reject(err)
+            } else {
+              resolve()
+            }
           })
-          process.stdin.on("end", () => controller.close())
-          process.stdin.on("error", (err) => controller.error(err))
-        },
-      })
+        })
+      },
+    })
+    const output = new ReadableStream<Uint8Array>({
+      start(controller) {
+        process.stdin.on("data", (chunk: Buffer) => {
+          controller.enqueue(new Uint8Array(chunk))
+        })
+        process.stdin.on("end", () => controller.close())
+        process.stdin.on("error", (err) => controller.error(err))
+      },
+    })
 
-      const stream = ndJsonStream(input, output)
-      const agent = await ACP.init({ sdk })
+    const stream = ndJsonStream(input, output)
+    const agent = yield* Effect.promise(() => ACP.init({ sdk }))
 
-      new AgentSideConnection((conn) => {
-        return agent.create(conn, { sdk })
-      }, stream)
+    new AgentSideConnection((conn) => {
+      return agent.create(conn, { sdk })
+    }, stream)
 
-      log.info("setup connection")
-      process.stdin.resume()
-      await new Promise((resolve, reject) => {
-        process.stdin.on("end", resolve)
-        process.stdin.on("error", reject)
-      })
-    })
-  },
+    log.info("setup connection")
+    process.stdin.resume()
+    yield* Effect.promise(
+      () =>
+        new Promise<void>((resolve, reject) => {
+          process.stdin.on("end", () => resolve())
+          process.stdin.on("error", reject)
+        }),
+    )
+  }),
 })

+ 16 - 19
packages/opencode/src/cli/cmd/agent.ts

@@ -13,6 +13,8 @@ import { Instance } from "../../project/instance"
 import { WithInstance } from "../../project/with-instance"
 import { EOL } from "os"
 import type { Argv } from "yargs"
+import { Effect } from "effect"
+import { effectCmd } from "../effect-cmd"
 
 type AgentMode = "all" | "primary" | "subagent"
 
@@ -233,28 +235,23 @@ const AgentCreateCommand = cmd({
   },
 })
 
-const AgentListCommand = cmd({
+const AgentListCommand = effectCmd({
   command: "list",
   describe: "list all available agents",
-  async handler() {
-    await WithInstance.provide({
-      directory: process.cwd(),
-      async fn() {
-        const agents = await AppRuntime.runPromise(Agent.Service.use((svc) => svc.list()))
-        const sortedAgents = agents.sort((a, b) => {
-          if (a.native !== b.native) {
-            return a.native ? -1 : 1
-          }
-          return a.name.localeCompare(b.name)
-        })
-
-        for (const agent of sortedAgents) {
-          process.stdout.write(`${agent.name} (${agent.mode})` + EOL)
-          process.stdout.write(`  ${JSON.stringify(agent.permission, null, 2)}` + EOL)
-        }
-      },
+  handler: Effect.fn("Cli.agent.list")(function* () {
+    const agents = yield* Agent.Service.use((svc) => svc.list())
+    const sortedAgents = agents.sort((a, b) => {
+      if (a.native !== b.native) {
+        return a.native ? -1 : 1
+      }
+      return a.name.localeCompare(b.name)
     })
-  },
+
+    for (const agent of sortedAgents) {
+      process.stdout.write(`${agent.name} (${agent.mode})` + EOL)
+      process.stdout.write(`  ${JSON.stringify(agent.permission, null, 2)}` + EOL)
+    }
+  }),
 })
 
 export const AgentCommand = cmd({

+ 11 - 10
packages/opencode/src/cli/cmd/debug/index.ts

@@ -1,5 +1,6 @@
 import { Global } from "@opencode-ai/core/global"
-import { bootstrap } from "../../bootstrap"
+import { Duration, Effect } from "effect"
+import { effectCmd } from "../../effect-cmd"
 import { cmd } from "../cmd"
 import { ConfigCommand } from "./config"
 import { FileCommand } from "./file"
@@ -26,19 +27,19 @@ export const DebugCommand = cmd({
       .command(StartupCommand)
       .command(AgentCommand)
       .command(PathsCommand)
-      .command({
-        command: "wait",
-        describe: "wait indefinitely (for debugging)",
-        async handler() {
-          await bootstrap(process.cwd(), async () => {
-            await new Promise((resolve) => setTimeout(resolve, 1_000 * 60 * 60 * 24))
-          })
-        },
-      })
+      .command(WaitCommand)
       .demandCommand(),
   async handler() {},
 })
 
+const WaitCommand = effectCmd({
+  command: "wait",
+  describe: "wait indefinitely (for debugging)",
+  handler: Effect.fn("Cli.debug.wait")(function* () {
+    yield* Effect.sleep(Duration.days(1))
+  }),
+})
+
 const PathsCommand = cmd({
   command: "paths",
   describe: "show global paths (data, config, cache, state)",