mirror of
https://github.com/davidkaya/aryx.git
synced 2026-08-06 19:58:43 +02:00
feat: category-based approval for runtime tools
Replace 20+ individual runtime tool toggles with 5 permission categories (read, write, shell, web_fetch, store_memory) matching how Copilot CLI, Cline, and other coding agents handle approvals. - Add resolveApprovalToolKey() to map permission kinds to category IDs - Simplify fallbackRuntimeApprovalTools to 5 categories - Thread alwaysApprove through PendingApprovalHandle → sidecar resolve - Update ApprovalBanner to use category labels for Always Approve button - Update ResolveApprovalCommand contract with alwaysApprove field - Update tests for category-based model Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -193,6 +193,28 @@ export function approvalPolicyRequiresCheckpoint(
|
||||
return rule.agentIds.includes(normalizedAgentId);
|
||||
}
|
||||
|
||||
const runtimePermissionKinds: ReadonlySet<string> = new Set(['read', 'write', 'shell', 'memory', 'url']);
|
||||
|
||||
/**
|
||||
* Resolves the canonical approval key for a pending approval.
|
||||
*
|
||||
* Runtime tools always use their permission-kind category (`read`, `write`, `shell`)
|
||||
* mapped to the corresponding approval-tool id. MCP/custom/hook tools use their
|
||||
* specific tool name.
|
||||
*/
|
||||
export function resolveApprovalToolKey(
|
||||
toolName: string | undefined,
|
||||
permissionKind: string | undefined,
|
||||
): string | undefined {
|
||||
if (permissionKind && runtimePermissionKinds.has(permissionKind)) {
|
||||
if (permissionKind === 'memory') return 'store_memory';
|
||||
if (permissionKind === 'url') return 'web_fetch';
|
||||
return permissionKind;
|
||||
}
|
||||
|
||||
return toolName;
|
||||
}
|
||||
|
||||
export function approvalPolicyAutoApprovesTool(
|
||||
policy: ApprovalPolicy | undefined,
|
||||
toolName?: string,
|
||||
|
||||
@@ -137,42 +137,16 @@ export function resolveToolLabel(toolId: string): string {
|
||||
return builtinToolLabels.get(toolId) ?? toolId;
|
||||
}
|
||||
|
||||
// Fallback runtime tools used before sidecar capabilities are loaded or when the
|
||||
// CLI cannot report its built-in tool catalog dynamically.
|
||||
// Fallback approval tool categories for runtime tools. The approval UI groups
|
||||
// built-in tools by permission category (read, write, shell, web, memory) rather
|
||||
// than listing 20+ individual tools, matching other coding agents (Copilot CLI,
|
||||
// Cline, Roo Code, etc.).
|
||||
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' },
|
||||
{ id: 'write_bash', label: 'Write shell input' },
|
||||
{ id: 'stop_bash', label: 'Stop shell session' },
|
||||
{ id: 'list_bash', label: 'List shell sessions' },
|
||||
// File tools
|
||||
{ id: 'view', label: 'View files' },
|
||||
{ id: 'create', label: 'Create files' },
|
||||
{ id: 'edit', label: 'Edit files' },
|
||||
{ id: 'apply_patch', label: 'Apply patch' },
|
||||
// Search tools
|
||||
{ id: 'grep', label: 'Search file contents' },
|
||||
{ id: 'glob', label: 'Find files by pattern' },
|
||||
// Agent tools
|
||||
{ id: 'task', label: 'Run sub-agent' },
|
||||
{ id: 'read_agent', label: 'Read agent results' },
|
||||
{ id: 'list_agents', label: 'List agents' },
|
||||
// Web tools
|
||||
{ id: 'web_fetch', label: 'Fetch web content' },
|
||||
{ id: 'web_search', label: 'Search the web' },
|
||||
// Other tools
|
||||
{ id: 'skill', label: 'Invoke skill' },
|
||||
{ id: 'show_file', label: 'Show file' },
|
||||
{ id: 'fetch_copilot_cli_documentation', label: 'Fetch CLI docs' },
|
||||
{ id: 'update_todo', label: 'Update checklist' },
|
||||
{ id: 'shell', label: 'Shell commands' },
|
||||
{ id: 'web_fetch', label: 'Web access' },
|
||||
{ id: 'store_memory', label: 'Store memory' },
|
||||
{ id: 'sql', label: 'Query session data' },
|
||||
{ id: 'lsp', label: 'Language server' },
|
||||
];
|
||||
|
||||
export function createWorkspaceSettings(): WorkspaceSettings {
|
||||
@@ -238,12 +212,13 @@ export function normalizeSessionToolingSelection(
|
||||
|
||||
export function listApprovalToolDefinitions(
|
||||
tooling: WorkspaceToolingSettings,
|
||||
runtimeTools: ReadonlyArray<RuntimeToolDefinition> = fallbackRuntimeApprovalTools,
|
||||
_runtimeTools: ReadonlyArray<RuntimeToolDefinition> = fallbackRuntimeApprovalTools,
|
||||
): ApprovalToolDefinition[] {
|
||||
const toolsById = new Map<string, ApprovalToolDefinition>();
|
||||
const runtimeApprovalTools = runtimeTools.length > 0 ? runtimeTools : fallbackRuntimeApprovalTools;
|
||||
|
||||
for (const tool of runtimeApprovalTools) {
|
||||
// Always use category-level approval for built-in runtime tools regardless of
|
||||
// what the sidecar reports as individual tools.
|
||||
for (const tool of fallbackRuntimeApprovalTools) {
|
||||
registerApprovalTool(toolsById, {
|
||||
id: tool.id,
|
||||
label: resolveToolLabel(tool.id),
|
||||
|
||||
Reference in New Issue
Block a user