mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-02 09:20:42 -07:00
feat(policy): centralize plan mode tool visibility in policy engine (#20178)
Co-authored-by: Mahima Shanware <mshanware@google.com>
This commit is contained in:
@@ -9,7 +9,11 @@ import { policiesCommand } from './policiesCommand.js';
|
||||
import { CommandKind } from './types.js';
|
||||
import { MessageType } from '../types.js';
|
||||
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
|
||||
import { type Config, PolicyDecision } from '@google/gemini-cli-core';
|
||||
import {
|
||||
type Config,
|
||||
PolicyDecision,
|
||||
ApprovalMode,
|
||||
} from '@google/gemini-cli-core';
|
||||
|
||||
describe('policiesCommand', () => {
|
||||
let mockContext: ReturnType<typeof createMockCommandContext>;
|
||||
@@ -106,6 +110,7 @@ describe('policiesCommand', () => {
|
||||
expect(content).toContain(
|
||||
'### Yolo Mode Policies (combined with normal mode policies)',
|
||||
);
|
||||
expect(content).toContain('### Plan Mode Policies');
|
||||
expect(content).toContain(
|
||||
'**DENY** tool: `dangerousTool` [Priority: 10]',
|
||||
);
|
||||
@@ -114,5 +119,45 @@ describe('policiesCommand', () => {
|
||||
);
|
||||
expect(content).toContain('**ASK_USER** all tools');
|
||||
});
|
||||
|
||||
it('should show plan-only rules in plan mode section', async () => {
|
||||
const mockRules = [
|
||||
{
|
||||
decision: PolicyDecision.ALLOW,
|
||||
toolName: 'glob',
|
||||
priority: 70,
|
||||
modes: [ApprovalMode.PLAN],
|
||||
},
|
||||
{
|
||||
decision: PolicyDecision.DENY,
|
||||
priority: 60,
|
||||
modes: [ApprovalMode.PLAN],
|
||||
},
|
||||
{
|
||||
decision: PolicyDecision.ALLOW,
|
||||
toolName: 'shell',
|
||||
priority: 50,
|
||||
},
|
||||
];
|
||||
const mockPolicyEngine = {
|
||||
getRules: vi.fn().mockReturnValue(mockRules),
|
||||
};
|
||||
mockContext.services.config = {
|
||||
getPolicyEngine: vi.fn().mockReturnValue(mockPolicyEngine),
|
||||
} as unknown as Config;
|
||||
|
||||
const listCommand = policiesCommand.subCommands![0];
|
||||
await listCommand.action!(mockContext, '');
|
||||
|
||||
const call = vi.mocked(mockContext.ui.addItem).mock.calls[0];
|
||||
const content = (call[0] as { text: string }).text;
|
||||
|
||||
// Plan-only rules appear under Plan Mode section
|
||||
expect(content).toContain('### Plan Mode Policies');
|
||||
// glob ALLOW is plan-only, should appear in plan section
|
||||
expect(content).toContain('**ALLOW** tool: `glob` [Priority: 70]');
|
||||
// shell ALLOW has no modes (applies to all), appears in normal section
|
||||
expect(content).toContain('**ALLOW** tool: `shell` [Priority: 50]');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ interface CategorizedRules {
|
||||
normal: PolicyRule[];
|
||||
autoEdit: PolicyRule[];
|
||||
yolo: PolicyRule[];
|
||||
plan: PolicyRule[];
|
||||
}
|
||||
|
||||
const categorizeRulesByMode = (
|
||||
@@ -21,6 +22,7 @@ const categorizeRulesByMode = (
|
||||
normal: [],
|
||||
autoEdit: [],
|
||||
yolo: [],
|
||||
plan: [],
|
||||
};
|
||||
const ALL_MODES = Object.values(ApprovalMode);
|
||||
rules.forEach((rule) => {
|
||||
@@ -29,6 +31,7 @@ const categorizeRulesByMode = (
|
||||
if (modeSet.has(ApprovalMode.DEFAULT)) result.normal.push(rule);
|
||||
if (modeSet.has(ApprovalMode.AUTO_EDIT)) result.autoEdit.push(rule);
|
||||
if (modeSet.has(ApprovalMode.YOLO)) result.yolo.push(rule);
|
||||
if (modeSet.has(ApprovalMode.PLAN)) result.plan.push(rule);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
@@ -82,6 +85,9 @@ const listPoliciesCommand: SlashCommand = {
|
||||
const uniqueYolo = categorized.yolo.filter(
|
||||
(rule) => !normalRulesSet.has(rule),
|
||||
);
|
||||
const uniquePlan = categorized.plan.filter(
|
||||
(rule) => !normalRulesSet.has(rule),
|
||||
);
|
||||
|
||||
let content = '**Active Policies**\n\n';
|
||||
content += formatSection('Normal Mode Policies', categorized.normal);
|
||||
@@ -93,6 +99,7 @@ const listPoliciesCommand: SlashCommand = {
|
||||
'Yolo Mode Policies (combined with normal mode policies)',
|
||||
uniqueYolo,
|
||||
);
|
||||
content += formatSection('Plan Mode Policies', uniquePlan);
|
||||
|
||||
context.ui.addItem(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user