mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-28 11:41:04 +00:00
feat: human-readable permission labels, deny rule feedback, and multi-dir search tests
- Add buildHumanReadableRuleLabel() to convert raw permission rules into natural-language descriptions for the 'Always Allow' UI options - Add PermissionManager.findMatchingDenyRule() to surface which deny rule caused a tool to be blocked, improving error messages in coreToolScheduler - Update ToolConfirmationMessage to use friendly labels with i18n support - Add comprehensive tests for new permission features and multi-directory search in glob, grep, and ripGrep tools - Fix integration test for tool-control allowedTools configuration
This commit is contained in:
parent
8c31775573
commit
a5a8ec5d67
14 changed files with 622 additions and 19 deletions
|
|
@ -17,7 +17,11 @@ import type {
|
|||
Config,
|
||||
EditorType,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import { IdeClient, ToolConfirmationOutcome } from '@qwen-code/qwen-code-core';
|
||||
import {
|
||||
IdeClient,
|
||||
ToolConfirmationOutcome,
|
||||
buildHumanReadableRuleLabel,
|
||||
} from '@qwen-code/qwen-code-core';
|
||||
import type { RadioSelectItem } from '../shared/RadioButtonSelect.js';
|
||||
import { RadioButtonSelect } from '../shared/RadioButtonSelect.js';
|
||||
import { MaxSizedBox } from '../shared/MaxSizedBox.js';
|
||||
|
|
@ -243,16 +247,24 @@ export const ToolConfirmationMessage: React.FC<
|
|||
key: 'Yes, allow once',
|
||||
});
|
||||
if (isTrustedFolder && !confirmationDetails.hideAlwaysAllow) {
|
||||
const rulesLabel = executionProps.permissionRules?.length
|
||||
? ` [${executionProps.permissionRules.join(', ')}]`
|
||||
const friendlyLabel = executionProps.permissionRules?.length
|
||||
? ` ${buildHumanReadableRuleLabel(executionProps.permissionRules)}`
|
||||
: '';
|
||||
options.push({
|
||||
label: t('Always allow in this project') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} in this project', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow in this project'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysProject,
|
||||
key: 'Always allow in this project',
|
||||
});
|
||||
options.push({
|
||||
label: t('Always allow for this user') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} for this user', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow for this user'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysUser,
|
||||
key: 'Always allow for this user',
|
||||
});
|
||||
|
|
@ -324,18 +336,26 @@ export const ToolConfirmationMessage: React.FC<
|
|||
key: 'Yes, allow once',
|
||||
});
|
||||
if (isTrustedFolder && !confirmationDetails.hideAlwaysAllow) {
|
||||
const rulesLabel =
|
||||
const friendlyLabel =
|
||||
'permissionRules' in infoProps &&
|
||||
(infoProps as { permissionRules?: string[] }).permissionRules?.length
|
||||
? ` [${(infoProps as { permissionRules?: string[] }).permissionRules!.join(', ')}]`
|
||||
? ` ${buildHumanReadableRuleLabel((infoProps as { permissionRules?: string[] }).permissionRules!)}`
|
||||
: '';
|
||||
options.push({
|
||||
label: t('Always allow in this project') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} in this project', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow in this project'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysProject,
|
||||
key: 'Always allow in this project',
|
||||
});
|
||||
options.push({
|
||||
label: t('Always allow for this user') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} for this user', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow for this user'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysUser,
|
||||
key: 'Always allow for this user',
|
||||
});
|
||||
|
|
@ -401,16 +421,24 @@ export const ToolConfirmationMessage: React.FC<
|
|||
key: 'Yes, allow once',
|
||||
});
|
||||
if (isTrustedFolder && !confirmationDetails.hideAlwaysAllow) {
|
||||
const rulesLabel = mcpProps.permissionRules?.length
|
||||
? ` [${mcpProps.permissionRules.join(', ')}]`
|
||||
const friendlyLabel = mcpProps.permissionRules?.length
|
||||
? ` ${buildHumanReadableRuleLabel(mcpProps.permissionRules)}`
|
||||
: '';
|
||||
options.push({
|
||||
label: t('Always allow in this project') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} in this project', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow in this project'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysProject,
|
||||
key: 'Always allow in this project',
|
||||
});
|
||||
options.push({
|
||||
label: t('Always allow for this user') + rulesLabel,
|
||||
label: friendlyLabel
|
||||
? t('Always allow {{action}} for this user', {
|
||||
action: friendlyLabel.trim(),
|
||||
})
|
||||
: t('Always allow for this user'),
|
||||
value: ToolConfirmationOutcome.ProceedAlwaysUser,
|
||||
key: 'Always allow for this user',
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue