refactor(cli): convert debug wait, agent list, acp to effectCmd (#25518)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import * as Log from "@opencode-ai/core/util/log"
|
import * as Log from "@opencode-ai/core/util/log"
|
||||||
import { bootstrap } from "../bootstrap"
|
import { Effect } from "effect"
|
||||||
import { cmd } from "./cmd"
|
import { effectCmd } from "../effect-cmd"
|
||||||
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
|
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
|
||||||
import { ACP } from "@/acp/agent"
|
import { ACP } from "@/acp/agent"
|
||||||
import { Server } from "@/server/server"
|
import { Server } from "@/server/server"
|
||||||
@@ -9,7 +9,7 @@ import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
|||||||
|
|
||||||
const log = Log.create({ service: "acp-command" })
|
const log = Log.create({ service: "acp-command" })
|
||||||
|
|
||||||
export const AcpCommand = cmd({
|
export const AcpCommand = effectCmd({
|
||||||
command: "acp",
|
command: "acp",
|
||||||
describe: "start ACP (Agent Client Protocol) server",
|
describe: "start ACP (Agent Client Protocol) server",
|
||||||
builder: (yargs) => {
|
builder: (yargs) => {
|
||||||
@@ -19,52 +19,53 @@ export const AcpCommand = cmd({
|
|||||||
default: process.cwd(),
|
default: process.cwd(),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handler: async (args) => {
|
handler: Effect.fn("Cli.acp")(function* (args) {
|
||||||
process.env.OPENCODE_CLIENT = "acp"
|
process.env.OPENCODE_CLIENT = "acp"
|
||||||
await bootstrap(process.cwd(), async () => {
|
const opts = yield* Effect.promise(() => resolveNetworkOptions(args))
|
||||||
const opts = await resolveNetworkOptions(args)
|
const server = yield* Effect.promise(() => Server.listen(opts))
|
||||||
const server = await Server.listen(opts)
|
|
||||||
|
|
||||||
const sdk = createOpencodeClient({
|
const sdk = createOpencodeClient({
|
||||||
baseUrl: `http://${server.hostname}:${server.port}`,
|
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))
|
|
||||||
})
|
|
||||||
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 })
|
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
process.stdin.on("end", () => controller.close())
|
||||||
|
process.stdin.on("error", (err) => controller.error(err))
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const stream = ndJsonStream(input, output)
|
||||||
|
const agent = yield* Effect.promise(() => ACP.init({ sdk }))
|
||||||
|
|
||||||
|
new AgentSideConnection((conn) => {
|
||||||
|
return agent.create(conn, { sdk })
|
||||||
|
}, stream)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import { Instance } from "../../project/instance"
|
|||||||
import { WithInstance } from "../../project/with-instance"
|
import { WithInstance } from "../../project/with-instance"
|
||||||
import { EOL } from "os"
|
import { EOL } from "os"
|
||||||
import type { Argv } from "yargs"
|
import type { Argv } from "yargs"
|
||||||
|
import { Effect } from "effect"
|
||||||
|
import { effectCmd } from "../effect-cmd"
|
||||||
|
|
||||||
type AgentMode = "all" | "primary" | "subagent"
|
type AgentMode = "all" | "primary" | "subagent"
|
||||||
|
|
||||||
@@ -233,28 +235,23 @@ const AgentCreateCommand = cmd({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const AgentListCommand = cmd({
|
const AgentListCommand = effectCmd({
|
||||||
command: "list",
|
command: "list",
|
||||||
describe: "list all available agents",
|
describe: "list all available agents",
|
||||||
async handler() {
|
handler: Effect.fn("Cli.agent.list")(function* () {
|
||||||
await WithInstance.provide({
|
const agents = yield* Agent.Service.use((svc) => svc.list())
|
||||||
directory: process.cwd(),
|
const sortedAgents = agents.sort((a, b) => {
|
||||||
async fn() {
|
if (a.native !== b.native) {
|
||||||
const agents = await AppRuntime.runPromise(Agent.Service.use((svc) => svc.list()))
|
return a.native ? -1 : 1
|
||||||
const sortedAgents = agents.sort((a, b) => {
|
}
|
||||||
if (a.native !== b.native) {
|
return a.name.localeCompare(b.name)
|
||||||
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)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
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({
|
export const AgentCommand = cmd({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Global } from "@opencode-ai/core/global"
|
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 { cmd } from "../cmd"
|
||||||
import { ConfigCommand } from "./config"
|
import { ConfigCommand } from "./config"
|
||||||
import { FileCommand } from "./file"
|
import { FileCommand } from "./file"
|
||||||
@@ -26,19 +27,19 @@ export const DebugCommand = cmd({
|
|||||||
.command(StartupCommand)
|
.command(StartupCommand)
|
||||||
.command(AgentCommand)
|
.command(AgentCommand)
|
||||||
.command(PathsCommand)
|
.command(PathsCommand)
|
||||||
.command({
|
.command(WaitCommand)
|
||||||
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))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.demandCommand(),
|
.demandCommand(),
|
||||||
async handler() {},
|
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({
|
const PathsCommand = cmd({
|
||||||
command: "paths",
|
command: "paths",
|
||||||
describe: "show global paths (data, config, cache, state)",
|
describe: "show global paths (data, config, cache, state)",
|
||||||
|
|||||||
Reference in New Issue
Block a user