feat(FN-3724): add coordination tools and permanent-agent action gating

This merge adds a direct-mode review tab to the task detail modal (FN-3278), improves mobile mailbox keyboard handling and fixes request hangs during wake dispatch (FN-3750/FN-3751), and reclassifies coordination tools with lock exemptions in the agent gating system (FN-3724), alongside GitHub route

Fusion-Task-Id: FN-3724
This commit is contained in:
Fusion
2026-05-08 11:39:07 -07:00
committed by gsxdsm
parent 04ff9d9403
commit fbc47ec49c
5 changed files with 98 additions and 32 deletions

View File

@@ -445,8 +445,8 @@ describe("wrapToolsWithPermanentAgentGating", () => {
expect(tool.execute).not.toHaveBeenCalled();
});
it("requires approval for mutating fn_* tools and never executes mutation", async () => {
const tool = { name: "fn_task_create", label: "Task Create", description: "", parameters: {}, execute: vi.fn() };
it("allows exempt internal coordination fn_* tools without approval", async () => {
const tool = { name: "fn_task_create", label: "Task Create", description: "", parameters: {}, execute: vi.fn().mockResolvedValue({ ok: true }) };
const createApprovalRequest = vi.fn().mockResolvedValue({ id: "apr-fn-1" });
const { wrapToolsWithPermanentAgentGating } = await import("../pi.js");
const wrapped = wrapToolsWithPermanentAgentGating([tool as any], {
@@ -467,15 +467,9 @@ describe("wrapToolsWithPermanentAgentGating", () => {
});
const result = await (wrapped[0] as any).execute("t1", { description: "create" });
expect((result as any).isError).toBe(true);
expect((result as any).details).toEqual(expect.objectContaining({
disposition: "require-approval",
category: "task_agent_mutation",
toolName: "fn_task_create",
approvalRequestId: "apr-fn-1",
}));
expect(createApprovalRequest).toHaveBeenCalledTimes(1);
expect(tool.execute).not.toHaveBeenCalled();
expect(result).toEqual({ ok: true });
expect(createApprovalRequest).not.toHaveBeenCalled();
expect(tool.execute).toHaveBeenCalledTimes(1);
});
it("keeps read-only tools allowed without approval-request creation", async () => {