refactor(cli): convert agent / providers / mcp to effectCmd (#25525)

This commit is contained in:
Kit Langton
2026-05-02 23:22:44 -04:00
committed by GitHub
parent 5f03d892c0
commit 0e13279545
3 changed files with 44 additions and 44 deletions

View File

@@ -9,8 +9,7 @@ import path from "path"
import fs from "fs/promises"
import { Filesystem } from "@/util/filesystem"
import matter from "gray-matter"
import { Instance } from "../../project/instance"
import { WithInstance } from "../../project/with-instance"
import { InstanceRef } from "@/effect/instance-ref"
import { EOL } from "os"
import type { Argv } from "yargs"
import { Effect } from "effect"
@@ -35,7 +34,7 @@ const AVAILABLE_PERMISSIONS = [
"skill",
]
const AgentCreateCommand = cmd({
const AgentCreateCommand = effectCmd({
command: "create",
describe: "create a new agent",
builder: (yargs: Argv) =>
@@ -63,10 +62,11 @@ const AgentCreateCommand = cmd({
alias: ["m"],
describe: "model to use in the format of provider/model",
}),
async handler(args) {
await WithInstance.provide({
directory: process.cwd(),
async fn() {
handler: Effect.fn("Cli.agent.create")(function* (args) {
const maybeCtx = yield* InstanceRef
if (!maybeCtx) return yield* Effect.die("InstanceRef not provided")
const ctx = maybeCtx
yield* Effect.promise(async () => {
const cliPath = args.path
const cliDescription = args.description
const cliMode = args.mode as AgentMode | undefined
@@ -79,7 +79,7 @@ const AgentCreateCommand = cmd({
prompts.intro("Create agent")
}
const project = Instance.project
const project = ctx.project
// Determine scope/path
let targetPath: string
@@ -94,7 +94,7 @@ const AgentCreateCommand = cmd({
{
label: "Current project",
value: "project" as const,
hint: Instance.worktree,
hint: ctx.worktree,
},
{
label: "Global",
@@ -107,7 +107,7 @@ const AgentCreateCommand = cmd({
scope = scopeResult
}
targetPath = path.join(
scope === "global" ? Global.Path.config : path.join(Instance.worktree, ".opencode"),
scope === "global" ? Global.Path.config : path.join(ctx.worktree, ".opencode"),
"agent",
)
}
@@ -230,9 +230,8 @@ const AgentCreateCommand = cmd({
prompts.log.success(`Agent created: ${filePath}`)
prompts.outro("Done")
}
},
})
},
}),
})
const AgentListCommand = effectCmd({

View File

@@ -11,8 +11,7 @@ import { McpAuth } from "../../mcp/auth"
import { McpOAuthProvider } from "../../mcp/oauth-provider"
import { Config } from "@/config/config"
import { ConfigMCP } from "../../config/mcp"
import { Instance } from "../../project/instance"
import { WithInstance } from "../../project/with-instance"
import { InstanceRef } from "@/effect/instance-ref"
import { Installation } from "../../installation"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import path from "path"
@@ -433,21 +432,22 @@ async function addMcpToConfig(name: string, mcpConfig: ConfigMCP.Info, configPat
return configPath
}
export const McpAddCommand = cmd({
export const McpAddCommand = effectCmd({
command: "add",
describe: "add an MCP server",
async handler() {
await WithInstance.provide({
directory: process.cwd(),
async fn() {
handler: Effect.fn("Cli.mcp.add")(function* () {
const maybeCtx = yield* InstanceRef
if (!maybeCtx) return yield* Effect.die("InstanceRef not provided")
const ctx = maybeCtx
yield* Effect.promise(async () => {
UI.empty()
prompts.intro("Add MCP server")
const project = Instance.project
const project = ctx.project
// Resolve config paths eagerly for hints
const [projectConfigPath, globalConfigPath] = await Promise.all([
resolveConfigPath(Instance.worktree),
resolveConfigPath(ctx.worktree),
resolveConfigPath(Global.Path.config, true),
])
@@ -592,12 +592,11 @@ export const McpAddCommand = cmd({
}
prompts.outro("MCP server added successfully")
},
})
},
}),
})
export const McpDebugCommand = cmd({
export const McpDebugCommand = effectCmd({
command: "debug <name>",
describe: "debug OAuth connection for an MCP server",
builder: (yargs) =>
@@ -606,10 +605,8 @@ export const McpDebugCommand = cmd({
type: "string",
demandOption: true,
}),
async handler(args) {
await WithInstance.provide({
directory: process.cwd(),
async fn() {
handler: Effect.fn("Cli.mcp.debug")(function* (args) {
yield* Effect.promise(async () => {
UI.empty()
prompts.intro("MCP OAuth Debug")
@@ -781,7 +778,6 @@ export const McpDebugCommand = cmd({
}
prompts.outro("Debug complete")
},
})
},
}),
})

View File

@@ -1,6 +1,7 @@
import { Auth } from "../../auth"
import { AppRuntime } from "../../effect/app-runtime"
import { cmd } from "./cmd"
import { effectCmd } from "../effect-cmd"
import * as prompts from "@clack/prompts"
import { UI } from "../ui"
import { ModelsDev } from "@/provider/models"
@@ -13,7 +14,6 @@ import os from "os"
import { Config } from "@/config/config"
import { Global } from "@opencode-ai/core/global"
import { Plugin } from "../../plugin"
import { WithInstance } from "../../project/with-instance"
import type { Hooks } from "@opencode-ai/plugin"
import { Process } from "@/util/process"
import { text } from "node:stream/consumers"
@@ -232,11 +232,14 @@ export const ProvidersCommand = cmd({
async handler() {},
})
export const ProvidersListCommand = cmd({
export const ProvidersListCommand = effectCmd({
command: "list",
aliases: ["ls"],
describe: "list providers and credentials",
async handler(_args) {
// Lists global credentials + provider env vars; no project instance needed.
instance: false,
handler: Effect.fn("Cli.providers.list")(function* (_args) {
yield* Effect.promise(async () => {
UI.empty()
const authPath = path.join(Global.Path.data, "auth.json")
const homedir = os.homedir()
@@ -280,10 +283,11 @@ export const ProvidersListCommand = cmd({
prompts.outro(`${activeEnvVars.length} environment variable` + (activeEnvVars.length === 1 ? "" : "s"))
}
},
})
}),
})
export const ProvidersLoginCommand = cmd({
export const ProvidersLoginCommand = effectCmd({
command: "login [url]",
describe: "log in to a provider",
builder: (yargs) =>
@@ -302,10 +306,8 @@ export const ProvidersLoginCommand = cmd({
describe: "login method label (skips method selection)",
type: "string",
}),
async handler(args) {
await WithInstance.provide({
directory: process.cwd(),
async fn() {
handler: Effect.fn("Cli.providers.login")(function* (args) {
yield* Effect.promise(async () => {
UI.empty()
prompts.intro("Add credential")
if (args.url) {
@@ -487,15 +489,17 @@ export const ProvidersLoginCommand = cmd({
})
prompts.outro("Done")
},
})
},
}),
})
export const ProvidersLogoutCommand = cmd({
export const ProvidersLogoutCommand = effectCmd({
command: "logout",
describe: "log out from a configured provider",
async handler(_args) {
// Removes a global auth credential; no project instance needed.
instance: false,
handler: Effect.fn("Cli.providers.logout")(function* (_args) {
yield* Effect.promise(async () => {
UI.empty()
const credentials: Array<[string, Auth.Info]> = await AppRuntime.runPromise(
Effect.gen(function* () {
@@ -525,5 +529,6 @@ export const ProvidersLogoutCommand = cmd({
}),
)
prompts.outro("Logout successful")
},
})
}),
})