@@ -1047,6 +1047,8 @@ async function removeCometHooksForPlatform(
10471047 return await removeGeminiHooks ( platformBase , scriptRelPaths ) ;
10481048 case 'windsurf' :
10491049 return await removeWindsurfHooks ( platformBase , scriptRelPaths ) ;
1050+ case 'trae' :
1051+ return await removeTraeHooks ( platformBase , scriptRelPaths ) ;
10501052 case 'copilot' :
10511053 return await removeCopilotHooks ( platformBase , scriptRelPaths ) ;
10521054 case 'kiro' :
@@ -1065,7 +1067,6 @@ async function removeQwenStyleHooks(
10651067) : Promise < RemovalResult > {
10661068 const settingsPath = path . join ( platformBase , 'settings.json' ) ;
10671069 if ( ! ( await fileExists ( settingsPath ) ) ) return { removed : 0 , failed : 0 } ;
1068- let removed = 0 ;
10691070 const readResult = await readJsonObjectFile ( settingsPath ) ;
10701071 if ( readResult . status === 'missing' ) return { removed : 0 , failed : 0 } ;
10711072 if ( readResult . status === 'error' ) return { removed : 0 , failed : 1 } ;
@@ -1081,6 +1082,7 @@ async function removeQwenStyleHooks(
10811082 return { removed : 0 , failed : 0 } ;
10821083 }
10831084
1085+ let removed = 0 ;
10841086 const filtered = existingPreToolUse . flatMap ( ( group ) => {
10851087 if ( ! Array . isArray ( group . hooks ) ) return [ group ] ;
10861088
@@ -1117,7 +1119,6 @@ async function removeGeminiHooks(
11171119) : Promise < RemovalResult > {
11181120 const settingsPath = path . join ( platformBase , 'settings.json' ) ;
11191121 if ( ! ( await fileExists ( settingsPath ) ) ) return { removed : 0 , failed : 0 } ;
1120- let removed = 0 ;
11211122 const readResult = await readJsonObjectFile ( settingsPath ) ;
11221123 if ( readResult . status === 'missing' ) return { removed : 0 , failed : 0 } ;
11231124 if ( readResult . status === 'error' ) return { removed : 0 , failed : 1 } ;
@@ -1133,7 +1134,30 @@ async function removeGeminiHooks(
11331134 return { removed : 0 , failed : 0 } ;
11341135 }
11351136
1136- const filtered = existingBeforeTool . flatMap ( ( group ) => {
1137+ const result = removeManagedGroupedHooks ( existingBeforeTool , scriptRelPaths ) ;
1138+ const removed = result . removed ;
1139+ const filtered = result . groups ;
1140+
1141+ if ( filtered . length === 0 ) {
1142+ delete existingHooks . BeforeTool ;
1143+ } else {
1144+ existingHooks . BeforeTool = filtered ;
1145+ }
1146+
1147+ if ( Object . keys ( existingHooks ) . length === 0 ) {
1148+ delete settings . hooks ;
1149+ }
1150+
1151+ await writeFile ( settingsPath , JSON . stringify ( settings , null , 2 ) + '\n' , 'utf-8' ) ;
1152+ return { removed, failed : 0 } ;
1153+ }
1154+
1155+ function removeManagedGroupedHooks (
1156+ groups : Array < Record < string , unknown > > ,
1157+ scriptRelPaths : string [ ] ,
1158+ ) : { groups : Array < Record < string , unknown > > ; removed : number } {
1159+ let removed = 0 ;
1160+ const filtered = groups . flatMap ( ( group ) => {
11371161 if ( ! Array . isArray ( group . hooks ) ) return [ group ] ;
11381162
11391163 const hooksBefore = ( group . hooks as Array < Record < string , unknown > > ) . length ;
@@ -1149,18 +1173,7 @@ async function removeGeminiHooks(
11491173 return [ { ...group , hooks } ] ;
11501174 } ) ;
11511175
1152- if ( filtered . length === 0 ) {
1153- delete existingHooks . BeforeTool ;
1154- } else {
1155- existingHooks . BeforeTool = filtered ;
1156- }
1157-
1158- if ( Object . keys ( existingHooks ) . length === 0 ) {
1159- delete settings . hooks ;
1160- }
1161-
1162- await writeFile ( settingsPath , JSON . stringify ( settings , null , 2 ) + '\n' , 'utf-8' ) ;
1163- return { removed, failed : 0 } ;
1176+ return { groups : filtered , removed } ;
11641177}
11651178
11661179async function removeWindsurfHooks (
@@ -1169,7 +1182,6 @@ async function removeWindsurfHooks(
11691182) : Promise < RemovalResult > {
11701183 const hooksPath = path . join ( platformBase , 'hooks.json' ) ;
11711184 if ( ! ( await fileExists ( hooksPath ) ) ) return { removed : 0 , failed : 0 } ;
1172- let removed = 0 ;
11731185 const readResult = await readJsonObjectFile ( hooksPath ) ;
11741186 if ( readResult . status === 'missing' ) return { removed : 0 , failed : 0 } ;
11751187 if ( readResult . status === 'error' ) return { removed : 0 , failed : 1 } ;
@@ -1187,6 +1199,7 @@ async function removeWindsurfHooks(
11871199 return { removed : 0 , failed : 0 } ;
11881200 }
11891201
1202+ let removed = 0 ;
11901203 const filtered = existingPreWrite . filter ( ( entry ) => {
11911204 if ( isManagedHookCommand ( entry . command , scriptRelPaths ) ) {
11921205 removed ++ ;
@@ -1209,6 +1222,45 @@ async function removeWindsurfHooks(
12091222 return { removed, failed : 0 } ;
12101223}
12111224
1225+ async function removeTraeHooks (
1226+ platformBase : string ,
1227+ scriptRelPaths : string [ ] ,
1228+ ) : Promise < RemovalResult > {
1229+ const hooksPath = path . join ( platformBase , 'hooks.json' ) ;
1230+ if ( ! ( await fileExists ( hooksPath ) ) ) return { removed : 0 , failed : 0 } ;
1231+ const readResult = await readJsonObjectFile ( hooksPath ) ;
1232+ if ( readResult . status === 'missing' ) return { removed : 0 , failed : 0 } ;
1233+ if ( readResult . status === 'error' ) return { removed : 0 , failed : 1 } ;
1234+ const hooksFile = readResult . value ;
1235+
1236+ const existingHooks = hooksFile . hooks as Record < string , unknown > | undefined ;
1237+ if ( ! existingHooks ) {
1238+ return { removed : 0 , failed : 0 } ;
1239+ }
1240+
1241+ const existingPreToolUse = existingHooks . PreToolUse as Array < Record < string , unknown > > | undefined ;
1242+ if ( ! existingPreToolUse || ! Array . isArray ( existingPreToolUse ) ) {
1243+ return { removed : 0 , failed : 0 } ;
1244+ }
1245+
1246+ const result = removeManagedGroupedHooks ( existingPreToolUse , scriptRelPaths ) ;
1247+ const removed = result . removed ;
1248+ const filtered = result . groups ;
1249+
1250+ if ( filtered . length === 0 ) {
1251+ delete existingHooks . PreToolUse ;
1252+ } else {
1253+ existingHooks . PreToolUse = filtered ;
1254+ }
1255+
1256+ if ( Object . keys ( existingHooks ) . length === 0 ) {
1257+ delete hooksFile . hooks ;
1258+ }
1259+
1260+ await writeFile ( hooksPath , JSON . stringify ( hooksFile , null , 2 ) + '\n' , 'utf-8' ) ;
1261+ return { removed, failed : 0 } ;
1262+ }
1263+
12121264async function removeCopilotHooks (
12131265 platformBase : string ,
12141266 scriptRelPaths : string [ ] ,
0 commit comments