import { describe, expect, it } from "vitest"; import { applyShellDecisionFloor, SHELL_TOOL_DECISION_FLOOR_PATTERN, } from "#src/handlers/gates/shell-decision-floor"; import type { PermissionCheckResult, PermissionState } from "#src/types"; function check(state: PermissionState, source: PermissionCheckResult["source"] = "bash") { return { state, toolName: "bash", source, origin: source === "session" ? ("session" as const) : ("global" as const), command: "pwd", matchedPattern: source === "session" ? "pwd" : "*", } satisfies PermissionCheckResult; } describe("applyShellDecisionFloor", () => { it("raises allow to ask", () => { expect(applyShellDecisionFloor(check("allow"), "ask")).toEqual({ ...check("allow"), state: "ask", source: "bash", matchedPattern: SHELL_TOOL_DECISION_FLOOR_PATTERN, reason: undefined, }); }); it("raises a session allow to ask without retaining the session fast path", () => { const result = applyShellDecisionFloor(check("allow", "session"), "ask"); expect(result.state).toBe("ask"); expect(result.source).toBe("bash"); expect(result.matchedPattern).toBe(SHELL_TOOL_DECISION_FLOOR_PATTERN); }); it.each(["ask", "deny"] as const)("preserves an existing %s", (state) => { const original = check(state); expect(applyShellDecisionFloor(original, "ask")).toBe(original); }); it("does nothing when no floor is configured", () => { const original = check("allow"); expect(applyShellDecisionFloor(original, undefined)).toBe(original); }); });