feat: enable 'always approve for session' for runtime tools

Runtime tool permission requests (read, write, shell, store_memory) now
resolve stable approval names via fallback in the sidecar approval
coordinator, enabling the 'Always approve' button and session-level
auto-approval for built-in tools.

Backend:
- Add fallback tool names for PermissionRequestRead (read),
  PermissionRequestWrite (write), PermissionRequestShell (shell),
  and PermissionRequestMemory (store_memory)
- Add autoApprovedToolName parameter to RequiresToolCallApproval
  for permission-kind-based session approval matching
- Track tool.execution_start events in ToolNamesByCallId for
  supplementary exact-name resolution

Frontend:
- Use approval.toolName ?? approval.permissionKind as fallback key
  in resolveSessionApproval and ApprovalBanner
- Add shell, read, write permission-kind entries to builtin approval
  tool definitions so pruning preserves session overrides

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-27 21:20:14 +01:00
co-authored by Copilot
parent 154787c336
commit 3ec69d990b
9 changed files with 199 additions and 15 deletions
+4 -3
View File
@@ -729,10 +729,11 @@ export class AryxAppService extends EventEmitter<AppServiceEvents> {
this.setSessionPendingApprovalState(session, dequeuePendingApprovalState(session, approvalId));
session.updatedAt = resolvedAt;
if (decision === 'approved' && alwaysApprove && approval.toolName) {
const approvalKey = approval.toolName ?? approval.permissionKind;
if (decision === 'approved' && alwaysApprove && approvalKey) {
const existing = session.approvalSettings?.autoApprovedToolNames ?? [];
if (!existing.includes(approval.toolName)) {
session.approvalSettings = { autoApprovedToolNames: [...existing, approval.toolName] };
if (!existing.includes(approvalKey)) {
session.approvalSettings = { autoApprovedToolNames: [...existing, approvalKey] };
}
}
@@ -23,7 +23,8 @@ export function ApprovalBanner({
const kindLabel = approval.kind === 'final-response' ? 'Final response review' : 'Tool call approval';
const hasMessages = approval.messages && approval.messages.length > 0;
const showPosition = position !== undefined && total !== undefined && total > 1;
const canAlwaysApprove = approval.kind === 'tool-call' && !!approval.toolName;
const approvalToolKey = approval.toolName ?? approval.permissionKind;
const canAlwaysApprove = approval.kind === 'tool-call' && !!approvalToolKey;
return (
<div className="rounded-xl border border-amber-500/30 bg-amber-500/5 px-4 py-3" role="alert">
@@ -90,11 +91,11 @@ export function ApprovalBanner({
</button>
{canAlwaysApprove && (
<button
aria-label={`Always approve ${approval.toolName}`}
aria-label={`Always approve ${approvalToolKey}`}
className="inline-flex items-center gap-1.5 rounded-lg bg-emerald-600/20 px-3.5 py-1.5 text-[12px] font-medium text-emerald-300 transition hover:bg-emerald-600/30 disabled:cursor-not-allowed disabled:opacity-50"
disabled={isResolving}
onClick={() => onResolve('approved', true)}
title={`Auto-approve "${approval.toolName}" for the rest of this session`}
title={`Auto-approve "${approvalToolKey}" for the rest of this session`}
type="button"
>
<ShieldBan className="size-3" />
+8
View File
@@ -92,6 +92,10 @@ const lspApprovalOperations = [
// Human-readable labels for built-in runtime tools.
// Both bash and powershell variants are included for forward compatibility.
const builtinToolLabels: ReadonlyMap<string, string> = new Map([
// Permission-kind approval categories (used by sidecar for runtime tool session approval)
['shell', 'Shell commands'],
['read', 'Read files'],
['write', 'Write files'],
// Shell tools
['bash', 'Execute shell commands'],
['powershell', 'Execute shell commands'],
@@ -136,6 +140,10 @@ export function resolveToolLabel(toolId: string): string {
// Fallback runtime tools used before sidecar capabilities are loaded or when the
// CLI cannot report its built-in tool catalog dynamically.
const fallbackRuntimeApprovalTools: ReadonlyArray<RuntimeToolDefinition> = [
// Permission-kind approval categories (used by sidecar for runtime tool session approval)
{ id: 'shell', label: 'Shell commands' },
{ id: 'read', label: 'Read files' },
{ id: 'write', label: 'Write files' },
// Shell tools (bash variants — SDK reports these on all platforms)
{ id: 'bash', label: 'Execute shell commands' },
{ id: 'read_bash', label: 'Read shell output' },