// Opt-in native plugin discovery in an isolated database. No inference requests. import assert from "node:assert/strict"; import { randomBytes } from "node:crypto"; import { mkdir, mkdtemp, readFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { serviceOpencodeConfig } from "../../src/runtime/opencode2-config.js"; import { startOpencode2 } from "../../src/runtime/opencode2-server.js"; const root = await mkdtemp(join(tmpdir(), "tjwater-answer-ui-smoke-")); const directory = join(root, "workspace"); await mkdir(directory); let native: Awaited> | undefined; let sessionID: string | undefined; try { native = await startOpencode2({ command: process.env.OPENCODE_COMMAND ?? "opencode2", hostname: "127.0.0.1", port: 0, timeout: 30_000, config: serviceOpencodeConfig(JSON.parse(await readFile("opencode.json", "utf8")), undefined, root), env: { AGENT_INTERNAL_TOKEN: randomBytes(32).toString("hex"), TJWATER_AGENT_WORKSPACE_ROOT: root, WATERNETWORK_API_KEY: "DISCOVERY_TEST_ONLY", XDG_DATA_HOME: join(root, "native-data"), OPENCODE_DB: join(root, "native-data", "opencode", "opencode.db"), XDG_CONFIG_HOME: join(root, "native-config"), XDG_CACHE_HOME: join(root, "native-cache"), XDG_STATE_HOME: join(root, "native-state") }, }); sessionID = (await native.client.session.create({ agent: "instruction", location: { directory } })).id; const response = await native.client.rpc.call({ rpcID: "tjwater.tools", method: "list", input: {}, location: { directory } }); const result = response.output as Array<{ id: string; direct: boolean }>; assert.ok(result.some((tool) => tool.id === "present_answer" && tool.direct), "present_answer must be registered as a direct native tool"); assert.ok(result.some((tool) => tool.id === "publish_task_report" && tool.direct), "publish_task_report must remain registered with rich report support"); assert.equal((await native.client.permission.create({ sessionID, action: "present_answer", resources: ["*"], save: [] })).effect, "allow"); console.log("Native answer and report tool discovery, plus answer permission, passed. No inference requests."); } finally { if (native && sessionID) await native.client.session.remove({ sessionID }).catch(() => {}); native?.close(); if (native) await native.exited; await rm(root, { recursive: true, force: true }); }