@@ -1094,6 +1094,19 @@ Return ONLY the commit message - no explanations, no extra text.`,
10941094 value : EXPIRES_AT_OPS ,
10951095 } ,
10961096 } ,
1097+ // Explicit expiration clear (update member / update invitation). A blank
1098+ // Expires At field means "leave unchanged", so clearing needs its own toggle.
1099+ {
1100+ id : 'clearExpiresAt' ,
1101+ title : 'Clear Expiration' ,
1102+ type : 'switch' ,
1103+ mode : 'advanced' ,
1104+ description : 'Remove the existing access expiration date (overrides Expires At)' ,
1105+ condition : {
1106+ field : 'operation' ,
1107+ value : [ 'gitlab_update_member' , 'gitlab_update_invitation' ] ,
1108+ } ,
1109+ } ,
10971110 // Custom member role ID (GitLab Ultimate)
10981111 {
10991112 id : 'memberRoleId' ,
@@ -1853,7 +1866,7 @@ Return ONLY the commit message - no explanations, no extra text.`,
18531866 resourceId : params . resourceId . trim ( ) ,
18541867 userId : Number ( params . userId ) ,
18551868 accessLevel : Number ( params . memberAccessLevel ) ,
1856- expiresAt : params . expiresAt ?. trim ( ) || undefined ,
1869+ expiresAt : params . clearExpiresAt ? '' : params . expiresAt ?. trim ( ) || undefined ,
18571870 memberRoleId : params . memberRoleId ? Number ( params . memberRoleId ) : undefined ,
18581871 }
18591872
@@ -1899,8 +1912,14 @@ Return ONLY the commit message - no explanations, no extra text.`,
18991912 if ( ! params . resourceId ?. trim ( ) || ! params . email ?. trim ( ) ) {
19001913 throw new Error ( 'Project / Group ID and Email are required.' )
19011914 }
1902- if ( ! params . invitationAccessLevel && ! params . expiresAt ?. trim ( ) ) {
1903- throw new Error ( 'At least one of Access Level or Expires At is required.' )
1915+ if (
1916+ ! params . invitationAccessLevel &&
1917+ ! params . expiresAt ?. trim ( ) &&
1918+ ! params . clearExpiresAt
1919+ ) {
1920+ throw new Error (
1921+ 'At least one of Access Level, Expires At, or Clear Expiration is required.'
1922+ )
19041923 }
19051924 return {
19061925 ...baseParams ,
@@ -1912,7 +1931,7 @@ Return ONLY the commit message - no explanations, no extra text.`,
19121931 accessLevel : params . invitationAccessLevel
19131932 ? Number ( params . invitationAccessLevel )
19141933 : undefined ,
1915- expiresAt : params . expiresAt ?. trim ( ) || undefined ,
1934+ expiresAt : params . clearExpiresAt ? '' : params . expiresAt ?. trim ( ) || undefined ,
19161935 }
19171936
19181937 case 'gitlab_revoke_invitation' :
@@ -2165,6 +2184,10 @@ Return ONLY the commit message - no explanations, no extra text.`,
21652184 description : 'Optional new access level for an invitation ("" leaves it unchanged)' ,
21662185 } ,
21672186 expiresAt : { type : 'string' , description : 'Access expiration date (YYYY-MM-DD)' } ,
2187+ clearExpiresAt : {
2188+ type : 'boolean' ,
2189+ description : 'Remove the existing access expiration date (update member/invitation)' ,
2190+ } ,
21682191 memberRoleId : { type : 'number' , description : 'Custom member role ID (Ultimate)' } ,
21692192 email : { type : 'string' , description : 'Email address for invitations' } ,
21702193 directMembersOnly : { type : 'boolean' , description : 'Exclude inherited members' } ,
0 commit comments