From f3f873e3c4ef3341ae7942e54898263ff78ce37b Mon Sep 17 00:00:00 2001 From: Huarch Date: Tue, 14 Jul 2026 18:17:55 +0800 Subject: [PATCH] fix(agent): load frontend action plugin --- opencode.json | 3 +++ tests/frontendAction/callIdPlugin.test.ts | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/opencode.json b/opencode.json index 26899b3..d1aea3d 100644 --- a/opencode.json +++ b/opencode.json @@ -28,5 +28,8 @@ }, "edit": "ask" }, + "plugin": [ + "./.opencode/plugins/frontend-action-call-id.ts" + ], "default_agent": "instruction" } diff --git a/tests/frontendAction/callIdPlugin.test.ts b/tests/frontendAction/callIdPlugin.test.ts index 8659c50..23d9b2e 100644 --- a/tests/frontendAction/callIdPlugin.test.ts +++ b/tests/frontendAction/callIdPlugin.test.ts @@ -1,8 +1,22 @@ import { describe, expect, it } from "bun:test"; +import { readdirSync, readFileSync } from "node:fs"; +import { join } from "node:path"; -import { frontendActionCallIdPlugin } from "../../.opencode/plugins/frontend-action-call-id.js"; +import { FRONTEND_ACTION_TOOLS, frontendActionCallIdPlugin } from "../../.opencode/plugins/frontend-action-call-id.js"; +import { frontendActionRegistry } from "../../src/frontendAction/registry.js"; + +const frontendActionToolNames = () => readdirSync(".opencode/tools") + .filter((file) => file.endsWith(".ts")) + .filter((file) => readFileSync(join(".opencode/tools", file), "utf8").includes("executeFrontendAction(")) + .map((file) => file.replace(/\.ts$/, "")) + .sort(); describe("frontend action call ID plugin", () => { + it("is registered in the OpenCode project config", () => { + const config = JSON.parse(readFileSync("opencode.json", "utf8")) as { plugin?: unknown[] }; + expect(config.plugin).toContain("./.opencode/plugins/frontend-action-call-id.ts"); + }); + it("overwrites forged IDs only for allowlisted tools", async () => { const hooks = await frontendActionCallIdPlugin({} as never); const before = hooks["tool.execute.before"]; @@ -15,4 +29,10 @@ describe("frontend action call ID plugin", () => { await before({ tool: "web_search", sessionID: "session", callID: "ignored" }, ordinaryOutput); expect(ordinaryOutput.args).toEqual({ query: "water" }); }); + + it("covers every tool that uses the frontend action bridge", () => { + const bridgeTools = frontendActionToolNames(); + expect([...FRONTEND_ACTION_TOOLS].sort()).toEqual(bridgeTools); + expect(frontendActionRegistry.map((action) => action.id).sort()).toEqual(bridgeTools); + }); });