import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import test from "node:test"; import plugin from "../dist/index.js"; const packageJson = JSON.parse( await readFile(new URL("../package.json", import.meta.url), "utf8"), ); const manifest = JSON.parse( await readFile(new URL("../openclaw.plugin.json", import.meta.url), "utf8"), ); function registrations(config = {}) { const seen = []; plugin.register({ pluginConfig: config, on(name, handler, options) { seen.push({ name, handler, options }); }, }); return seen; } test("package, manifest, and executable test command are release compatible", () => { assert.equal(packageJson.version, "2.1.0-rc.1"); assert.equal(manifest.version, "2.1.0-rc.1"); assert.equal(packageJson.scripts.test, "node --test test/*.test.js"); }); test("schema declares every runtime-read property and exact B1 bounds", () => { const properties = manifest.configSchema.properties; const runtimeKeys = [ "approvalTimeoutMs", "blockUnknownAgentRuns", "blockedSenderIds", "readOnlyTools", "requireApprovalForHumanSideEffects", "requireExplicitTrustedSenders", "trustedSenderIds", ]; assert.deepEqual(Object.keys(properties).sort(), runtimeKeys); assert.deepEqual(properties.blockUnknownAgentRuns, { type: "boolean", default: false, }); assert.deepEqual(properties.approvalTimeoutMs, { type: "integer", minimum: 1000, maximum: 300000, default: 60000, }); }); test("all three hooks register exactly once at priority 100", () => { const seen = registrations(); assert.deepEqual( seen.map(({ name }) => name).sort(), ["agent_end", "before_agent_run", "before_tool_call"], ); for (const registration of seen) { assert.deepEqual(registration.options, { priority: 100 }); } });