feat(opencode): cut plugin system and remote behavior feeds; add SessionContext assembly and Runner
- delete plugin machinery (loader, install, meta, hooks) and all trigger sites - fold first-party provider auth into static registry (provider/hooks.ts) - remove remote instruction URL fetch, skills remote puller, TUI plugin host - add session/context.ts: single provenance-tagged context assembly point - add session/runner.ts: admit/context/stream/tools loop with compaction policy - relocate audit artifacts to audit/ (FORK-AUDIT, instruction docs as evidence)
This commit is contained in:
@@ -10,7 +10,6 @@ import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { TestConfig } from "../fixture/config"
|
||||
import { Config } from "@/config/config"
|
||||
import { Plugin } from "@/plugin"
|
||||
import { Agent } from "@/agent/agent"
|
||||
import { InstanceState } from "@/effect/instance-state"
|
||||
|
||||
@@ -26,30 +25,6 @@ const configLayer = TestConfig.layer({
|
||||
directories: () => InstanceState.directory.pipe(Effect.map((dir) => [path.join(dir, ".opencode")])),
|
||||
})
|
||||
|
||||
// Fake Plugin.Service that returns a single plugin whose `tool` map contains
|
||||
// one definition with `args: undefined`. Used to exercise the plugin entry
|
||||
// point of `fromPlugin` for the #27451 / #27630 regression.
|
||||
const brokenPluginLayer = Layer.succeed(
|
||||
Plugin.Service,
|
||||
Plugin.Service.of({
|
||||
init: () => Effect.void,
|
||||
trigger: ((_name: unknown, _input: unknown, output: unknown) =>
|
||||
Effect.succeed(output)) as Plugin.Interface["trigger"],
|
||||
list: () =>
|
||||
Effect.succeed([
|
||||
{
|
||||
tool: {
|
||||
broken_plugin_tool: {
|
||||
description: "plugin tool with missing args",
|
||||
args: undefined as unknown as Record<string, never>,
|
||||
execute: async () => "ok",
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
}),
|
||||
)
|
||||
|
||||
const root = LayerNode.group([ToolRegistry.node, Agent.node])
|
||||
const replacements = [
|
||||
[Config.node, configLayer],
|
||||
@@ -93,8 +68,6 @@ const withEmptyCodeMode = testEffect(
|
||||
],
|
||||
]),
|
||||
)
|
||||
const withBrokenPlugin = testEffect(LayerNode.compile(root, [...replacements, [Plugin.node, brokenPluginLayer]]))
|
||||
|
||||
afterEach(async () => {
|
||||
await disposeAllInstances()
|
||||
})
|
||||
@@ -257,21 +230,6 @@ describe("tool.registry", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
// Same regression, plugin entry point. The original reports (#27451, #27630)
|
||||
// came in through `plugin.list()` — `oh-my-opencode` was registering a tool
|
||||
// with `args: undefined` and crashing every message submit. The file-scan
|
||||
// and plugin-list loops both funnel through `fromPlugin`, but covering both
|
||||
// entry points means a future refactor that splits them won't silently lose
|
||||
// protection.
|
||||
withBrokenPlugin.instance("tolerates a plugin tool registered with null/undefined args", () =>
|
||||
Effect.gen(function* () {
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const ids = yield* registry.ids()
|
||||
expect(ids).toContain("read")
|
||||
expect(ids).toContain("broken_plugin_tool")
|
||||
}),
|
||||
)
|
||||
|
||||
it.instance("loads tools from .opencode/tools (plural)", () =>
|
||||
Effect.gen(function* () {
|
||||
const test = yield* TestInstance
|
||||
|
||||
Reference in New Issue
Block a user