diff --git a/__tests__/hooks/policy-evaluator.test.ts b/__tests__/hooks/policy-evaluator.test.ts index 390aee65..8da6c574 100644 --- a/__tests__/hooks/policy-evaluator.test.ts +++ b/__tests__/hooks/policy-evaluator.test.ts @@ -1218,5 +1218,23 @@ describe("hooks/policy-evaluator", () => { expect(result.decision).toBe("deny"); expect(result.reason).toBe("hard block. deny hint"); }); + + it("passes user-configured policyParams to custom policies without schema", async () => { + let capturedParams: unknown = null; + registerPolicy("custom/my-policy", "desc", (ctx) => { + capturedParams = ctx.params; + return { decision: "allow" }; + }, { events: ["PreToolUse"] }); + + const config = { + enabledPolicies: ["custom/my-policy"], + policyParams: { + "custom/my-policy": { maxCount: 10, threshold: 5 }, + }, + }; + + await evaluatePolicies("PreToolUse", { tool_name: "Bash" }, undefined, config); + expect(capturedParams).toEqual({ maxCount: 10, threshold: 5 }); + }); }); }); diff --git a/src/hooks/policy-evaluator.ts b/src/hooks/policy-evaluator.ts index 6e6a511b..da0f95ac 100644 --- a/src/hooks/policy-evaluator.ts +++ b/src/hooks/policy-evaluator.ts @@ -101,8 +101,9 @@ export async function evaluatePolicies( } ctx = { ...baseCtx, params: resolvedParams }; } else { - // Custom hooks and policies without schema get empty params - ctx = { ...baseCtx, params: {} }; + // Custom hooks and policies without schema get user-configured params if present + const userParams = getConfigParamsFor(config, policy.name) ?? {}; + ctx = { ...baseCtx, params: userParams }; } let result: Awaited>;