@@ -20,7 +20,9 @@ import {
2020 isHeadlessMode ,
2121 FatalAuthenticationError ,
2222 PolicyDecision ,
23+ ApprovalMode ,
2324 PRIORITY_YOLO_ALLOW_ALL ,
25+ createPolicyEngineConfig ,
2426} from '@google/gemini-cli-core' ;
2527
2628// Mock dependencies
@@ -60,6 +62,32 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
6062 FileDiscoveryService : vi . fn ( ) ,
6163 getCodeAssistServer : vi . fn ( ) ,
6264 fetchAdminControlsOnce : vi . fn ( ) ,
65+ createPolicyEngineConfig : vi
66+ . fn ( )
67+ . mockImplementation (
68+ ( _settings , mode , _defaultPoliciesDir , _interactive ) => ( {
69+ rules :
70+ mode === actual . ApprovalMode . YOLO
71+ ? [
72+ {
73+ toolName : '*' ,
74+ decision : actual . PolicyDecision . ALLOW ,
75+ priority : actual . PRIORITY_YOLO_ALLOW_ALL ,
76+ modes : [ actual . ApprovalMode . YOLO ] ,
77+ allowRedirection : true ,
78+ } ,
79+ ]
80+ : [
81+ {
82+ toolName : 'read_file' ,
83+ decision : actual . PolicyDecision . ALLOW ,
84+ priority : 1.05 ,
85+ source : 'Default: read-only.toml' ,
86+ } ,
87+ ] ,
88+ checkers : [ ] ,
89+ } ) ,
90+ ) ,
6391 coreEvents : {
6492 emitAdminSettingsChanged : vi . fn ( ) ,
6593 } ,
@@ -286,6 +314,85 @@ describe('loadConfig', () => {
286314 } ) ;
287315 } ) ;
288316
317+ describe ( 'policy engine configuration' , ( ) => {
318+ it ( 'should merge V1 and V2 tool settings into policySettings' , async ( ) => {
319+ const settings : Settings = {
320+ allowedTools : [ 'v1-allowed' ] ,
321+ tools : {
322+ allowed : [ 'v2-allowed' ] ,
323+ exclude : [ 'v2-exclude' ] ,
324+ core : [ 'v2-core' ] ,
325+ } ,
326+ mcpServers : {
327+ test : { command : 'test' , args : [ ] } ,
328+ } ,
329+ policyPaths : [ '/path/to/policy' ] ,
330+ adminPolicyPaths : [ '/path/to/admin/policy' ] ,
331+ } ;
332+
333+ await loadConfig ( settings , mockExtensionLoader , taskId ) ;
334+
335+ expect ( createPolicyEngineConfig ) . toHaveBeenCalledWith (
336+ expect . objectContaining ( {
337+ tools : {
338+ core : [ 'v2-core' ] ,
339+ exclude : [ 'v2-exclude' ] ,
340+ allowed : [ 'v1-allowed' ] ,
341+ } ,
342+ mcpServers : settings . mcpServers ,
343+ policyPaths : settings . policyPaths ,
344+ adminPolicyPaths : settings . adminPolicyPaths ,
345+ } ) ,
346+ ApprovalMode . DEFAULT ,
347+ undefined ,
348+ true ,
349+ ) ;
350+ } ) ;
351+
352+ it ( 'should use V2 tool settings when V1 is missing' , async ( ) => {
353+ const settings : Settings = {
354+ tools : {
355+ allowed : [ 'v2-allowed' ] ,
356+ } ,
357+ } ;
358+
359+ await loadConfig ( settings , mockExtensionLoader , taskId ) ;
360+
361+ expect ( createPolicyEngineConfig ) . toHaveBeenCalledWith (
362+ expect . objectContaining ( {
363+ tools : expect . objectContaining ( {
364+ allowed : [ 'v2-allowed' ] ,
365+ } ) ,
366+ } ) ,
367+ ApprovalMode . DEFAULT ,
368+ undefined ,
369+ true ,
370+ ) ;
371+ } ) ;
372+
373+ it ( 'should use V1 tool settings when V2 is also present' , async ( ) => {
374+ const settings : Settings = {
375+ allowedTools : [ 'v1-allowed' ] ,
376+ tools : {
377+ allowed : [ 'v2-allowed' ] ,
378+ } ,
379+ } ;
380+
381+ await loadConfig ( settings , mockExtensionLoader , taskId ) ;
382+
383+ expect ( createPolicyEngineConfig ) . toHaveBeenCalledWith (
384+ expect . objectContaining ( {
385+ tools : expect . objectContaining ( {
386+ allowed : [ 'v1-allowed' ] ,
387+ } ) ,
388+ } ) ,
389+ ApprovalMode . DEFAULT ,
390+ undefined ,
391+ true ,
392+ ) ;
393+ } ) ;
394+ } ) ;
395+
289396 describe ( 'tool configuration' , ( ) => {
290397 it ( 'should pass V1 allowedTools to Config properly' , async ( ) => {
291398 const settings : Settings = {
@@ -410,14 +517,19 @@ describe('loadConfig', () => {
410517 ) ;
411518 } ) ;
412519
413- it ( 'should use default approval mode and empty rules when GEMINI_YOLO_MODE is not true' , async ( ) => {
520+ it ( 'should use default approval mode and load default rules when GEMINI_YOLO_MODE is not true' , async ( ) => {
414521 vi . stubEnv ( 'GEMINI_YOLO_MODE' , 'false' ) ;
415522 await loadConfig ( mockSettings , mockExtensionLoader , taskId ) ;
416523 expect ( Config ) . toHaveBeenCalledWith (
417524 expect . objectContaining ( {
418525 approvalMode : 'default' ,
419526 policyEngineConfig : expect . objectContaining ( {
420- rules : [ ] ,
527+ rules : expect . arrayContaining ( [
528+ expect . objectContaining ( {
529+ toolName : 'read_file' ,
530+ decision : PolicyDecision . ALLOW ,
531+ } ) ,
532+ ] ) ,
421533 } ) ,
422534 } ) ,
423535 ) ;
0 commit comments