fix(cli): restore plugin list diagnostics (#37540)
Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com>
This commit is contained in:
parent
4bc8faa01c
commit
f2a4011371
5 changed files with 52 additions and 6 deletions
|
|
@ -114,6 +114,10 @@ export const Commands = Spec.make(typeof OPENCODE_CLI_NAME === "string" ? OPENCO
|
|||
}),
|
||||
],
|
||||
}),
|
||||
Spec.make("plugin", {
|
||||
description: "Manage plugins",
|
||||
commands: [Spec.make("list", { description: "List active plugins" })],
|
||||
}),
|
||||
Spec.make("migrate", { description: "Migrate v1 data to v2" }),
|
||||
Spec.make("mini", {
|
||||
description: "Start the minimal interactive interface",
|
||||
|
|
|
|||
24
packages/cli/src/commands/handlers/plugin/list.ts
Normal file
24
packages/cli/src/commands/handlers/plugin/list.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { EOL } from "node:os"
|
||||
import { Effect } from "effect"
|
||||
import { OpenCode } from "@opencode-ai/client"
|
||||
import { Service } from "@opencode-ai/client/effect/service"
|
||||
import { Commands } from "../../commands"
|
||||
import { Runtime } from "../../../framework/runtime"
|
||||
import { ServiceConfig } from "../../../services/service-config"
|
||||
|
||||
export default Runtime.handler(
|
||||
Commands.commands.plugin.commands.list,
|
||||
Effect.fn("cli.plugin.list")(function* () {
|
||||
const options = yield* ServiceConfig.options()
|
||||
const found = yield* Service.discover(options)
|
||||
const endpoint = found ?? (yield* Service.ensure(options))
|
||||
const client = OpenCode.make({ baseUrl: endpoint.url, headers: Service.headers(endpoint) })
|
||||
const response = yield* Effect.promise(() => client.plugin.list({ location: { directory: process.cwd() } }))
|
||||
const plugins = response.data.toSorted((a, b) => a.id.localeCompare(b.id))
|
||||
if (plugins.length === 0) {
|
||||
process.stdout.write("No plugins loaded" + EOL)
|
||||
return
|
||||
}
|
||||
process.stdout.write(plugins.map((plugin) => plugin.id).join(EOL) + EOL)
|
||||
}),
|
||||
)
|
||||
|
|
@ -32,6 +32,9 @@ const Handlers = Runtime.handlers(Commands, {
|
|||
auth: () => import("./commands/handlers/mcp/auth"),
|
||||
logout: () => import("./commands/handlers/mcp/logout"),
|
||||
},
|
||||
plugin: {
|
||||
list: () => import("./commands/handlers/plugin/list"),
|
||||
},
|
||||
migrate: () => import("./commands/handlers/migrate"),
|
||||
mini: () => import("./commands/handlers/mini"),
|
||||
run: () => import("./commands/handlers/run"),
|
||||
|
|
|
|||
|
|
@ -142,7 +142,11 @@ const resolve = Effect.fn("PluginSupervisor.resolve")(function* (
|
|||
continue
|
||||
}
|
||||
|
||||
const plugin = yield* load(operation).pipe(Effect.catchCause(() => Effect.succeed(undefined)))
|
||||
const plugin = yield* load(operation).pipe(
|
||||
Effect.catchCause((cause) =>
|
||||
Effect.logWarning("failed to load plugin", { target: operation.target, cause }).pipe(Effect.as(undefined)),
|
||||
),
|
||||
)
|
||||
if (!plugin) continue
|
||||
const previous = packages.get(operation.target)
|
||||
if (previous) enabled.delete(previous.id)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import { PluginSupervisor } from "@opencode-ai/core/plugin/supervisor"
|
|||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||
import { Effect } from "effect"
|
||||
import { Effect, Logger } from "effect"
|
||||
import { Database } from "../../src/database/database"
|
||||
import { tmpdir } from "../fixture/tmpdir"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
|
@ -111,8 +111,15 @@ describe("PluginSupervisor config", () => {
|
|||
),
|
||||
)
|
||||
|
||||
it.live("ignores invalid packages and continues loading", () =>
|
||||
withLocation(
|
||||
it.live("logs invalid packages and continues loading", () => {
|
||||
const output: string[] = []
|
||||
const logger = Logger.map(Logger.formatStructured, (entry) => {
|
||||
if (!Array.isArray(entry.message) || entry.message[0] !== "failed to load plugin") return
|
||||
const details = entry.message[1]
|
||||
if (typeof details !== "object" || details === null || !("target" in details)) return
|
||||
if (typeof details.target === "string") output.push(details.target)
|
||||
})
|
||||
return withLocation(
|
||||
{
|
||||
plugins: [
|
||||
"-*",
|
||||
|
|
@ -130,9 +137,13 @@ describe("PluginSupervisor config", () => {
|
|||
expect(yield* agents.get(AgentV2.ID.make("configured"))).toMatchObject({
|
||||
description: "Loaded after invalid plugins",
|
||||
})
|
||||
expect(output).toEqual([
|
||||
path.join(import.meta.dir, "../plugin/fixtures/missing-plugin.ts"),
|
||||
path.join(import.meta.dir, "../plugin/fixtures/invalid-plugin.ts"),
|
||||
])
|
||||
}),
|
||||
),
|
||||
)
|
||||
).pipe(Effect.provide(Logger.layer([logger])))
|
||||
})
|
||||
|
||||
it.live("loads auto-discovered plugin files", () =>
|
||||
withLocation(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue