From 71a3d2ff919ed56379a51116fd5204fe82f5fda8 Mon Sep 17 00:00:00 2001 From: Arjun <6592213+arkml@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:36:09 +0530 Subject: [PATCH] added session and always permissions --- apps/x/apps/renderer/src/App.tsx | 22 ++++-- .../ai-elements/permission-request.tsx | 56 ++++++++++++--- .../renderer/src/components/chat-sidebar.tsx | 10 ++- .../src/application/lib/command-executor.ts | 69 +++++++++++++++++-- apps/x/packages/core/src/config/security.ts | 49 +++++++++++-- apps/x/packages/core/src/runs/runs.ts | 18 ++++- apps/x/packages/shared/src/runs.ts | 3 + 7 files changed, 200 insertions(+), 27 deletions(-) diff --git a/apps/x/apps/renderer/src/App.tsx b/apps/x/apps/renderer/src/App.tsx index 9cc66879..016bd8c3 100644 --- a/apps/x/apps/renderer/src/App.tsx +++ b/apps/x/apps/renderer/src/App.tsx @@ -1527,9 +1527,15 @@ function App() { } }, [runId, isStopping, stopClickedAt]) - const handlePermissionResponse = useCallback(async (toolCallId: string, subflow: string[], response: 'approve' | 'deny') => { + const handlePermissionResponse = useCallback(async ( + toolCallId: string, + subflow: string[], + response: 'approve' | 'deny', + scope?: 'once' | 'session' | 'always', + command?: string, + ) => { if (!runId) return - + // Optimistically update the UI immediately setPermissionResponses(prev => { const next = new Map(prev) @@ -1541,11 +1547,11 @@ function App() { next.delete(toolCallId) return next }) - + try { await window.ipc.invoke('runs:authorizePermission', { runId, - authorization: { subflow, toolCallId, response } + authorization: { subflow, toolCallId, response, scope, command } }) } catch (error) { console.error('Failed to authorize permission:', error) @@ -2945,6 +2951,14 @@ function App() { handlePermissionResponse(permRequest.toolCall.toolCallId, permRequest.subflow, 'approve')} + onApproveSession={() => { + const cmd = permRequest.toolCall.toolName === 'executeCommand' && typeof permRequest.toolCall.arguments === 'object' && permRequest.toolCall.arguments !== null && 'command' in permRequest.toolCall.arguments ? String(permRequest.toolCall.arguments.command) : undefined + handlePermissionResponse(permRequest.toolCall.toolCallId, permRequest.subflow, 'approve', 'session', cmd) + }} + onApproveAlways={() => { + const cmd = permRequest.toolCall.toolName === 'executeCommand' && typeof permRequest.toolCall.arguments === 'object' && permRequest.toolCall.arguments !== null && 'command' in permRequest.toolCall.arguments ? String(permRequest.toolCall.arguments.command) : undefined + handlePermissionResponse(permRequest.toolCall.toolCallId, permRequest.subflow, 'approve', 'always', cmd) + }} onDeny={() => handlePermissionResponse(permRequest.toolCall.toolCallId, permRequest.subflow, 'deny')} isProcessing={isActive && isProcessing} response={response} diff --git a/apps/x/apps/renderer/src/components/ai-elements/permission-request.tsx b/apps/x/apps/renderer/src/components/ai-elements/permission-request.tsx index 91b16287..e9cef6dc 100644 --- a/apps/x/apps/renderer/src/components/ai-elements/permission-request.tsx +++ b/apps/x/apps/renderer/src/components/ai-elements/permission-request.tsx @@ -2,8 +2,14 @@ import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; import { cn } from "@/lib/utils"; -import { AlertTriangleIcon, CheckCircleIcon, CheckIcon, XCircleIcon, XIcon } from "lucide-react"; +import { AlertTriangleIcon, CheckCircleIcon, CheckIcon, ChevronDownIcon, XCircleIcon, XIcon } from "lucide-react"; import type { ComponentProps } from "react"; import { ToolCallPart } from "@x/shared/dist/message.js"; import z from "zod"; @@ -11,6 +17,8 @@ import z from "zod"; export type PermissionRequestProps = ComponentProps<"div"> & { toolCall: z.infer; onApprove?: () => void; + onApproveSession?: () => void; + onApproveAlways?: () => void; onDeny?: () => void; isProcessing?: boolean; response?: 'approve' | 'deny' | null; @@ -20,6 +28,8 @@ export const PermissionRequest = ({ className, toolCall, onApprove, + onApproveSession, + onApproveAlways, onDeny, isProcessing = false, response = null, @@ -117,16 +127,40 @@ export const PermissionRequest = ({ {!isResponded && (
- +
+ + {command && ( + + + + + + + Allow for Session + + + Always Allow + + + + )} +