feat: add 'Always approve' button for tool-call approvals

When a tool-call approval banner appears, users can now click 'Always
approve' to both approve the current call AND add the tool to the
session's autoApprovedToolNames. Future calls to that tool are then
auto-approved without showing the banner.

- Add alwaysApprove?: boolean to ResolveSessionApprovalInput
- In resolveSessionApproval, atomically append tool to session
  approvalSettings when alwaysApprove is true (avoids running guard)
- Add 'Always approve' button in ApprovalBanner (tool-call kind only)
- Wire through ChatPane and App.tsx with updated callback signatures

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-27 19:34:50 +01:00
co-authored by Copilot
parent 4f1ae86021
commit 1868a79d9a
6 changed files with 32 additions and 9 deletions
+8
View File
@@ -699,6 +699,7 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
sessionId: string,
approvalId: string,
decision: ApprovalDecision,
alwaysApprove?: boolean,
): Promise<WorkspaceState> {
const workspace = await this.loadWorkspace();
const session = this.requireSession(workspace, sessionId);
@@ -726,6 +727,13 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
this.setSessionPendingApprovalState(session, dequeuePendingApprovalState(session, approvalId));
session.updatedAt = resolvedAt;
if (decision === 'approved' && alwaysApprove && approval.toolName) {
const existing = session.approvalSettings?.autoApprovedToolNames ?? [];
if (!existing.includes(approval.toolName)) {
session.approvalSettings = { autoApprovedToolNames: [...existing, approval.toolName] };
}
}
const updatedRun = this.updateSessionRun(session, handle.requestId, (run) =>
upsertRunApprovalEvent(run, resolvedApproval));
+1 -1
View File
@@ -113,7 +113,7 @@ export function registerIpcHandlers(window: BrowserWindow, service: AryxAppServi
service.cancelSessionTurn(input.sessionId),
);
ipcMain.handle(ipcChannels.resolveSessionApproval, (_event, input: ResolveSessionApprovalInput) =>
service.resolveSessionApproval(input.sessionId, input.approvalId, input.decision),
service.resolveSessionApproval(input.sessionId, input.approvalId, input.decision, input.alwaysApprove),
);
ipcMain.handle(ipcChannels.resolveSessionUserInput, (_event, input: ResolveSessionUserInputInput) =>
service.resolveSessionUserInput(input.sessionId, input.userInputId, input.answer, input.wasFreeform),