authorize method
Future<ApprovalOutcome>
authorize({
- required String toolName,
- required ApprovalTier tier,
- required Map<
String, dynamic> arguments,
Resolves the policy for one tool call and, when it lands on ApprovalPolicy.prompt, awaits the user's decision via prompt.
Implementation
Future<ApprovalOutcome> authorize({
required String toolName,
required ApprovalTier tier,
required Map<String, dynamic> arguments,
}) async {
// 1. An explicit deny wins over everything, the interceptor included.
final denied = _denyOverrideOutcome(toolName);
if (denied != null) return denied;
// 1b. A skill's disallowed-tools (turn-scoped) blocks the call.
if (_turnDeny.contains(toolName)) {
return ApprovalOutcome.denied(
'Tool "$toolName" is disallowed by the active skill for this turn.',
);
}
// 2. Critical bash patterns force a prompt in interactive modes
// (always-ask/write/yolo). In `unattended` the mode wins: there is
// no user to answer, so the session must never block.
if (mode != ApprovalMode.unattended) {
final critical = await _criticalBashOutcome(
toolName: toolName,
tier: tier,
arguments: arguments,
);
if (critical != null) return critical;
}
// 3. Remaining per-tool overrides.
final overridden = await _overrideOutcome(
toolName: toolName,
tier: tier,
arguments: arguments,
);
if (overridden != null) return overridden;
// 4. A skill's allowed-tools (turn-scoped) auto-allows the call.
if (_turnAllow.contains(toolName)) {
return const ApprovalOutcome.allowed();
}
// 5. Session always-allow ("approve always" answers, `/allow`).
if (_alwaysAllow.contains(toolName)) {
return const ApprovalOutcome.allowed();
}
// 6. Session mode vs. tool tier.
return _modeOutcome(toolName: toolName, tier: tier, arguments: arguments);
}