@@ -273,6 +273,249 @@ describe("isToolAllowedForMode", () => {
273273 } ) ,
274274 ) . toThrow ( / M a r k d o w n f i l e s o n l y / )
275275 } )
276+
277+ it ( "applies restrictions to apply_patch (custom tool)" , ( ) => {
278+ // Test that apply_patch respects file restrictions when included
279+ // Note: apply_patch only accepts { patch: string } - file paths are embedded in patch content
280+ const patchResult = isToolAllowedForMode (
281+ "apply_patch" ,
282+ "markdown-editor" ,
283+ customModes ,
284+ undefined ,
285+ {
286+ patch : "*** Begin Patch\n*** Update File: test.md\n@@ \n-old\n+new\n*** End Patch" ,
287+ } ,
288+ undefined ,
289+ [ "apply_patch" ] , // Include custom tool
290+ )
291+ expect ( patchResult ) . toBe ( true )
292+
293+ // Test apply_patch with non-matching file (file path embedded in patch content)
294+ expect ( ( ) =>
295+ isToolAllowedForMode (
296+ "apply_patch" ,
297+ "markdown-editor" ,
298+ customModes ,
299+ undefined ,
300+ {
301+ patch : "*** Begin Patch\n*** Update File: test.js\n@@ \n-old\n+new\n*** End Patch" ,
302+ } ,
303+ undefined ,
304+ [ "apply_patch" ] , // Include custom tool
305+ ) ,
306+ ) . toThrow ( FileRestrictionError )
307+ expect ( ( ) =>
308+ isToolAllowedForMode (
309+ "apply_patch" ,
310+ "markdown-editor" ,
311+ customModes ,
312+ undefined ,
313+ {
314+ patch : "*** Begin Patch\n*** Update File: test.js\n@@ \n-old\n+new\n*** End Patch" ,
315+ } ,
316+ undefined ,
317+ [ "apply_patch" ] , // Include custom tool
318+ ) ,
319+ ) . toThrow ( / \\ .m d \$ / )
320+ } )
321+
322+ it ( "applies restrictions to search_replace (custom tool)" , ( ) => {
323+ // Test that search_replace respects file restrictions when included
324+ const searchReplaceResult = isToolAllowedForMode (
325+ "search_replace" ,
326+ "markdown-editor" ,
327+ customModes ,
328+ undefined ,
329+ {
330+ file_path : "test.md" ,
331+ old_string : "old text" ,
332+ new_string : "new text" ,
333+ } ,
334+ undefined ,
335+ [ "search_replace" ] , // Include custom tool
336+ )
337+ expect ( searchReplaceResult ) . toBe ( true )
338+
339+ // Test search_replace with non-matching file
340+ expect ( ( ) =>
341+ isToolAllowedForMode (
342+ "search_replace" ,
343+ "markdown-editor" ,
344+ customModes ,
345+ undefined ,
346+ {
347+ file_path : "test.js" ,
348+ old_string : "old text" ,
349+ new_string : "new text" ,
350+ } ,
351+ undefined ,
352+ [ "search_replace" ] , // Include custom tool
353+ ) ,
354+ ) . toThrow ( FileRestrictionError )
355+ expect ( ( ) =>
356+ isToolAllowedForMode (
357+ "search_replace" ,
358+ "markdown-editor" ,
359+ customModes ,
360+ undefined ,
361+ {
362+ file_path : "test.js" ,
363+ old_string : "old text" ,
364+ new_string : "new text" ,
365+ } ,
366+ undefined ,
367+ [ "search_replace" ] , // Include custom tool
368+ ) ,
369+ ) . toThrow ( / \\ .m d \$ / )
370+ } )
371+
372+ it ( "applies restrictions to edit_file (custom tool)" , ( ) => {
373+ // Test that edit_file respects file restrictions when included
374+ const editFileResult = isToolAllowedForMode (
375+ "edit_file" ,
376+ "markdown-editor" ,
377+ customModes ,
378+ undefined ,
379+ {
380+ file_path : "test.md" ,
381+ old_string : "old text" ,
382+ new_string : "new text" ,
383+ } ,
384+ undefined ,
385+ [ "edit_file" ] , // Include custom tool
386+ )
387+ expect ( editFileResult ) . toBe ( true )
388+
389+ // Test edit_file with non-matching file
390+ expect ( ( ) =>
391+ isToolAllowedForMode (
392+ "edit_file" ,
393+ "markdown-editor" ,
394+ customModes ,
395+ undefined ,
396+ {
397+ file_path : "test.js" ,
398+ old_string : "old text" ,
399+ new_string : "new text" ,
400+ } ,
401+ undefined ,
402+ [ "edit_file" ] , // Include custom tool
403+ ) ,
404+ ) . toThrow ( FileRestrictionError )
405+ expect ( ( ) =>
406+ isToolAllowedForMode (
407+ "edit_file" ,
408+ "markdown-editor" ,
409+ customModes ,
410+ undefined ,
411+ {
412+ file_path : "test.js" ,
413+ old_string : "old text" ,
414+ new_string : "new text" ,
415+ } ,
416+ undefined ,
417+ [ "edit_file" ] , // Include custom tool
418+ ) ,
419+ ) . toThrow ( / \\ .m d \$ / )
420+ } )
421+
422+ it ( "applies restrictions to all editing tools in architect mode (custom tools)" , ( ) => {
423+ // Test apply_patch in architect mode
424+ // Note: apply_patch only accepts { patch: string } - file paths are embedded in patch content
425+ expect (
426+ isToolAllowedForMode (
427+ "apply_patch" ,
428+ "architect" ,
429+ [ ] ,
430+ undefined ,
431+ {
432+ patch : "*** Begin Patch\n*** Update File: test.md\n@@ \n-old\n+new\n*** End Patch" ,
433+ } ,
434+ undefined ,
435+ [ "apply_patch" ] , // Include custom tool
436+ ) ,
437+ ) . toBe ( true )
438+
439+ expect ( ( ) =>
440+ isToolAllowedForMode (
441+ "apply_patch" ,
442+ "architect" ,
443+ [ ] ,
444+ undefined ,
445+ {
446+ patch : "*** Begin Patch\n*** Update File: test.js\n@@ \n-old\n+new\n*** End Patch" ,
447+ } ,
448+ undefined ,
449+ [ "apply_patch" ] , // Include custom tool
450+ ) ,
451+ ) . toThrow ( FileRestrictionError )
452+
453+ // Test search_replace in architect mode
454+ expect (
455+ isToolAllowedForMode (
456+ "search_replace" ,
457+ "architect" ,
458+ [ ] ,
459+ undefined ,
460+ {
461+ file_path : "test.md" ,
462+ old_string : "old text" ,
463+ new_string : "new text" ,
464+ } ,
465+ undefined ,
466+ [ "search_replace" ] , // Include custom tool
467+ ) ,
468+ ) . toBe ( true )
469+
470+ expect ( ( ) =>
471+ isToolAllowedForMode (
472+ "search_replace" ,
473+ "architect" ,
474+ [ ] ,
475+ undefined ,
476+ {
477+ file_path : "test.js" ,
478+ old_string : "old text" ,
479+ new_string : "new text" ,
480+ } ,
481+ undefined ,
482+ [ "search_replace" ] , // Include custom tool
483+ ) ,
484+ ) . toThrow ( FileRestrictionError )
485+
486+ // Test edit_file in architect mode
487+ expect (
488+ isToolAllowedForMode (
489+ "edit_file" ,
490+ "architect" ,
491+ [ ] ,
492+ undefined ,
493+ {
494+ file_path : "test.md" ,
495+ old_string : "old text" ,
496+ new_string : "new text" ,
497+ } ,
498+ undefined ,
499+ [ "edit_file" ] , // Include custom tool
500+ ) ,
501+ ) . toBe ( true )
502+
503+ expect ( ( ) =>
504+ isToolAllowedForMode (
505+ "edit_file" ,
506+ "architect" ,
507+ [ ] ,
508+ undefined ,
509+ {
510+ file_path : "test.js" ,
511+ old_string : "old text" ,
512+ new_string : "new text" ,
513+ } ,
514+ undefined ,
515+ [ "edit_file" ] , // Include custom tool
516+ ) ,
517+ ) . toThrow ( FileRestrictionError )
518+ } )
276519 } )
277520
278521 it ( "handles non-existent modes" , ( ) => {
0 commit comments