/** * OpenCode permission config builder helpers. * * Extracted from opencode.ts to reduce cyclomatic complexity. */ import type { CanonicalTool, PermissionRule } from "../types.js"; /** OpenCode permission values */ export type OpenCodePermission = "allow" | "deny" | "ask"; /** OpenCode permission config type */ export type OpenCodePermissionConfig = Record>; /** * Base permissions that override OpenCode's interactive defaults. * * OpenCode v1.1.1 sets these defaults that differ from other agents: * - doom_loop: "ask" (interactive prompt when agent repeats same tool 3x) * - external_directory: "ask" (interactive prompt for external paths) * * For axrun, we need consistent behavior across all agents, so we * explicitly override these. The interactive "ask" actions are replaced * with "allow" since axrun is headless. * * Trade-off for doom_loop: Setting "allow" means the agent won't be stopped * when it appears stuck in a loop. In CI/CD, this relies on job timeouts to * prevent runaway execution. The alternative ("deny") would abort the agent, * and ("ask") would hang waiting for input. "allow" is the least disruptive * for headless operation. * * Note: OpenCode's default "read" protection (denying .env files) is * overridden dynamically by the permission builder logic, not here. */ export declare const BASE_PERMISSION_OVERRIDES: Record; /** * Collect path patterns from permission rules, grouped by OpenCode permission name. * * Note: Only read/write rules can have path patterns per the PathPatternRule type. * The TOOL_TO_OPENCODE mapping includes glob/grep for tool-level permissions, but these * will never appear here since PathRestrictedTool is limited to read/write. */ export declare function collectPathPatterns(rules: PermissionRule[]): Map; /** * Collect tool names from permission rules. */ export declare function collectTools(rules: PermissionRule[]): Set; /** * Collect bash patterns from permission rules. */ export declare function collectBashPatterns(rules: PermissionRule[]): string[]; /** * Build bash permission config from patterns and tool permissions. * * IMPORTANT: The wildcard "*" rule must be added FIRST in the config object. * OpenCode's `disabled()` function uses `findLast()` to find any rule matching * the permission name, then checks if that rule has `pattern === "*"` and * `action === "deny"`. If the "*" rule is last, bash gets disabled entirely * even when specific patterns are allowed. By adding "*" first, `findLast()` * returns a specific pattern rule instead, keeping bash available to the model. * * At execution time, `evaluate()` correctly handles rule precedence because it * uses `findLast()` with BOTH permission AND pattern matching - so specific * patterns still take priority over the wildcard when the command matches. */ export declare function buildBashPermission(allowPatterns: string[], denyPatterns: string[], bashAllowed: boolean, bashDenied: boolean): OpenCodePermission | Record; /** * Build tool permission config with optional path patterns. * * IMPORTANT: Like buildBashPermission, the wildcard "*" rule must be added * FIRST to prevent OpenCode's disabled() from hiding the tool entirely. * See buildBashPermission comment for detailed explanation. */ export declare function buildToolPermission(canonicalName: CanonicalTool, opencodeName: string, allowedTools: Set, deniedTools: Set, allowPathPatterns: Map, denyPathPatterns: Map): OpenCodePermission | Record; /** * Build default deny-all permission config for headless security. */ export declare function buildDenyAllConfig(): OpenCodePermissionConfig;