@gitlab/duo-cli 8.53.2 → 8.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1133,7 +1133,7 @@ ${jOQ(C)}`:""};if(typeof Q==="string"){let E=B?`
1133
1133
  ${D(B)}`:"";this.#E(`${Q}${E}${I(B)}`,A)}else{let E=EsA(Q);if(!E)return;this.#E(`${D(E)}${I(Q)}`,A)}}#E(A,Q){let B=`${CsA.default().format("YYYY-MM-DDTHH:mm:ss:SSS")} [${Q}]: `,D=(I)=>I.replace(/\n/g,`
1134
1134
  ${" ".repeat(TOQ)}`);this.#A.write(`${B}${D(A)}`)}setContext(A){this.#B=A}debug(A,Q){this.#D(hD.DEBUG,A,Q)}info(A,Q){this.#D(hD.INFO,A,Q)}warn(A,Q){this.#D(hD.WARNING,A,Q)}error(A,Q){this.#D(hD.ERROR,A,Q)}withContext(A){let Q=new WK(this.#A,this.#Q);return Q.setContext(A),Q}}WK=w1([FsA.Injectable(f1,[B_,tm])],WK);var s1A=dA(u1(),1);var a1A=dA(u1(),1);var YsA=dA(u1(),1),b4=YsA.createInterfaceId("GitLabApiService");var XsA=dA(TJ(),1);function GsA(A){return(A.split(`
1135
1135
  `).find((Q)=>Q.trim())??A.replace(`
1136
- `,"")).trim()}function POQ(A){return GsA(A).match(/^(query|mutation|subscription)\s+/)?.[1]}function SOQ(A){return GsA(A).match(/(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function ve(A){let Q=POQ(A),B=SOQ(A);if(Q)return`${Q}: ${B??"anonymous"}`;return}var yOQ=(A)=>{if(A.method==="GET"||A.method==="HEAD")return;if(!A.body)return;return y8("Body",JSON.stringify(A.body))},vOQ=(A)=>{if(A.method==="POST"||A.method==="PATCH"||A.method==="PUT")return;if(!A.searchParams)return;return y8("Search Params",JSON.stringify(A.searchParams))},kOQ=(A)=>{if(!A.headers)return;return y8("Headers",JSON.stringify(A.headers))},em=(A)=>{switch(A.type){case"graphql":return iE("GraphQL Request",y8("Query",A.query.replace(/[\s\n]+/g," ").trim()),y8("Variables",JSON.stringify(A.variables)));case"rest":return iE("REST Request",y8("Method",A.method),y8("Path",A.path),kOQ(A),vOQ(A),yOQ(A));default:return y8("Unknown request type",A.type)}};var zsA=(A)=>{try{return JSON.parse(A)?.error}catch{return}},gOQ=(A)=>{if(!A)return"";try{return JSON.parse(A)?.error_description??""}catch{return""}},TGA=(A,Q)=>Boolean(A.status===401&&Q&&zsA(Q)==="invalid_token"),jGA=(A,Q)=>Boolean(A.status===400&&Q&&zsA(Q)==="invalid_grant");class ke extends Error{request;cause;constructor(A,Q,B){super(A);this.request=Q,this.cause=B?.cause}get sanitizedMessage(){return"API request failed"}}class PGA extends ke{status;constructor(A,Q,B,D){super(A,Q,D);this.status=B}}class Au extends PGA{type="rest";response;#A;constructor(A,Q,B,D){let I=`Fetching ${B} from ${Q.url} failed. ${gOQ(D)}`;if(TGA(Q,D))I=`Request for ${B} failed because the token is expired or revoked.`;if(jGA(Q,D))I="Request to refresh token failed, because it's revoked or already refreshed.";super(I,A,Q.status);this.response=Q,this.#A=D}isInvalidTokenOrInvalidRefresh(){return TGA(this.response,this.#A)||jGA(this.response,this.#A)}get ctx(){return iE("Error details",em(this.request),this.#Q())}get sanitizedMessage(){if(TGA(this.response,this.#A))return"Request failed because the token is expired or revoked.";if(jGA(this.response,this.#A))return"Request to refresh token failed, because it's revoked or already refreshed.";return`Request failed with error code: ${this.response.status}`}#Q(){let A=Object.fromEntries(this.response.headers.entries());return iE("Response",y8("Status",String(this.status)),!XsA.default.isEmpty(A)?y8("Headers",JSON.stringify(A)):void 0,this.#A?y8("Response body",this.#A):void 0)}get body(){return this.#A}}var UsA=(A)=>A.errors?.map((Q)=>Q.message).join(",")||"";class SGA extends PGA{type="graphql";graphQlResponse;#A;constructor(A,Q){let B=ve(A.query),D=`GraphQL request "${B}" failed with ${UsA(Q)}`;super(D,A,Q.status);this.graphQlResponse=Q,this.#A=B}get sanitizedMessage(){return`GraphQL request "${this.#A}" failed with status ${this.graphQlResponse.status}`}get ctx(){return iE("Error details",em(this.request),this.#Q())}#Q(){return iE("Response",y8("Status",String(this.graphQlResponse.status)),y8("Errors",UsA(this.graphQlResponse)))}}class ge extends ke{type="network";cause;constructor(A,Q){let B=Q instanceof Error?Q.message:`Network error occurred: ${Q}`;super(B,A);this.cause=Q}get ctx(){return iE("Error details",em(this.request),this.#A())}get sanitizedMessage(){let A=this.cause,Q=A?.code||A?.errno,B=this.#Q(Q);return`Network error occurred${B?`: ${B}`:""}`}#A(){if(!this.cause||!(this.cause instanceof Error))return;let A=this.cause;if(A.code||A.errno){let Q=A.code||A.errno,B=this.#Q(Q),D=B?`${B} (${Q})`:`Error code: ${Q}`;return y8("Network issue",D)}return}#Q(A){return{ENOTFOUND:"DNS lookup failed - hostname could not be resolved",ECONNREFUSED:"Connection refused - server is not accepting connections",ECONNRESET:"Connection reset by peer - server closed the connection unexpectedly",ETIMEDOUT:"Connection timed out - server did not respond in time",EHOSTUNREACH:"Host unreachable - network route to server not available",ENETUNREACH:"Network unreachable - no network connectivity",ECONNABORTED:"Connection aborted - request was cancelled",EBADF:"Bad file descriptor - network connection issue",EPIPE:"Broken pipe - connection closed while writing data",EAI_AGAIN:"DNS lookup failed temporarily - try again later"}[A]}}class bOQ extends ke{type="timeout";#A;constructor(A,Q){let B=`Request timed out${Q?` after ${Q}ms`:""}`;super(B,A);this.#A=B}get ctx(){return iE("Error details",em(this.request))}get sanitizedMessage(){return this.#A}}var wsA=Au;function be(A){return A instanceof Au}var Qu={type:"rest",method:"GET",path:"/api/v4/version"};var ZsA=(A)=>be(A)&&(A.status<400||A.status>=500);var fe=JSON;var KsA=(A)=>A.toUpperCase(),HsA=(A)=>{let Q={};return A.forEach((B,D)=>{Q[D]=B}),Q};var VsA=(A,Q,B)=>{return A.document?A:{document:A,variables:Q,requestHeaders:B,signal:void 0}},$sA=(A,Q,B)=>{return A.query?A:{query:A,variables:Q,requestHeaders:B,signal:void 0}},WsA=(A,Q)=>{return A.documents?A:{documents:A,requestHeaders:Q,signal:void 0}};var gAA=dA(z61(),1),w61=(A)=>{let Q=void 0,B=A.definitions.filter((D)=>D.kind==="OperationDefinition");if(B.length===1)Q=B[0]?.name?.value;return Q},W_=(A)=>{if(typeof A==="string"){let B=void 0;try{let D=gAA.parse(A);B=w61(D)}catch(D){}return{query:A,operationName:B}}let Q=w61(A);return{query:gAA.print(A),operationName:Q}};class ZF extends Error{constructor(A,Q){let B=`${ZF.extractMessage(A)}: ${JSON.stringify({response:A,request:Q})}`;super(B);if(Object.setPrototypeOf(this,ZF.prototype),this.response=A,this.request=Q,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,ZF)}static extractMessage(A){return A.errors?.[0]?.message??`GraphQL Error (Code: ${A.status})`}}var wW=dA(D41(),1);var wmQ="connection_init",ZmQ="connection_ack",E41="ping",C41="pong",KmQ="subscribe",HmQ="next",VmQ="error",F41="complete";class zW{get type(){return this._type}get id(){return this._id}get payload(){return this._payload}constructor(A,Q,B){this._type=A,this._payload=Q,this._id=B}get text(){let A={type:this.type};if(this.id!=null&&this.id!=null)A.id=this.id;if(this.payload!=null&&this.payload!=null)A.payload=this.payload;return JSON.stringify(A)}static parse(A,Q){let{type:B,payload:D,id:I}=JSON.parse(A);return new zW(B,Q(D),I)}}class KzA{constructor(A,{onInit:Q,onAcknowledged:B,onPing:D,onPong:I}){this.socketState={acknowledged:!1,lastRequestId:0,subscriptions:{}},this.socket=A,A.addEventListener("open",async(E)=>{this.socketState.acknowledged=!1,this.socketState.subscriptions={},A.send(WmQ(Q?await Q():null).text)}),A.addEventListener("close",(E)=>{this.socketState.acknowledged=!1,this.socketState.subscriptions={}}),A.addEventListener("error",(E)=>{console.error(E)}),A.addEventListener("message",(E)=>{try{let C=$mQ(E.data);switch(C.type){case ZmQ:{if(this.socketState.acknowledged)console.warn("Duplicate CONNECTION_ACK message ignored");else if(this.socketState.acknowledged=!0,B)B(C.payload);return}case E41:{if(D)D(C.payload).then((G)=>A.send(I41(G).text));else A.send(I41(null).text);return}case C41:{if(I)I(C.payload);return}}if(!this.socketState.acknowledged)return;if(C.id===void 0||C.id===null||!this.socketState.subscriptions[C.id])return;let{query:F,variables:J,subscriber:Y}=this.socketState.subscriptions[C.id];switch(C.type){case HmQ:{if(!C.payload.errors&&C.payload.data)Y.next&&Y.next(C.payload.data);if(C.payload.errors)Y.error&&Y.error(new ZF({...C.payload,status:200},{query:F,variables:J}));return}case VmQ:{Y.error&&Y.error(new ZF({errors:C.payload,status:200},{query:F,variables:J}));return}case F41:{Y.complete&&Y.complete(),delete this.socketState.subscriptions[C.id];return}}}catch(C){console.error(C),A.close(1006)}A.close(4400,"Unknown graphql-ws message.")})}makeSubscribe(A,Q,B,D){let I=(this.socketState.lastRequestId++).toString();return this.socketState.subscriptions[I]={query:A,variables:D,subscriber:B},this.socket.send(MmQ(I,{query:A,operationName:Q,variables:D}).text),()=>{this.socket.send(qmQ(I).text),delete this.socketState.subscriptions[I]}}rawRequest(A,Q){return new Promise((B,D)=>{let I;this.rawSubscribe(A,{next:(E,C)=>I={data:E,extensions:C},error:D,complete:()=>B(I)},Q)})}request(A,Q){return new Promise((B,D)=>{let I;this.subscribe(A,{next:(E)=>I=E,error:D,complete:()=>B(I)},Q)})}subscribe(A,Q,B){let{query:D,operationName:I}=W_(A);return this.makeSubscribe(D,I,Q,B)}rawSubscribe(A,Q,B){return this.makeSubscribe(A,void 0,Q,B)}ping(A){this.socket.send(NmQ(A).text)}close(){this.socket.close(1000)}}KzA.PROTOCOL="graphql-transport-ws";function $mQ(A,Q=(B)=>B){return zW.parse(A,Q)}function WmQ(A){return new zW(wmQ,A)}function NmQ(A){return new zW(E41,A,void 0)}function I41(A){return new zW(C41,A,void 0)}function MmQ(A,Q){return new zW(KmQ,Q,A)}function qmQ(A){return new zW(F41,void 0,A)}var sS=(A)=>{let Q={};if(A)if(typeof Headers!=="undefined"&&A instanceof Headers||wW&&wW.Headers&&A instanceof wW.Headers)Q=HsA(A);else if(Array.isArray(A))A.forEach(([B,D])=>{if(B&&D!==void 0)Q[B]=D});else Q=A;return Q},J41=(A)=>A.replace(/([\s,]|#[^\n\r]+)+/g," ").trim(),OmQ=(A)=>{if(!Array.isArray(A.query)){let D=A,I=[`query=${encodeURIComponent(J41(D.query))}`];if(A.variables)I.push(`variables=${encodeURIComponent(D.jsonSerializer.stringify(D.variables))}`);if(D.operationName)I.push(`operationName=${encodeURIComponent(D.operationName)}`);return I.join("&")}if(typeof A.variables!=="undefined"&&!Array.isArray(A.variables))throw new Error("Cannot create query with given variable type, array expected");let Q=A,B=A.query.reduce((D,I,E)=>{return D.push({query:J41(I),variables:Q.variables?Q.jsonSerializer.stringify(Q.variables[E]):void 0}),D},[]);return`query=${encodeURIComponent(Q.jsonSerializer.stringify(B))}`},_mQ=(A)=>async(Q)=>{let{url:B,query:D,variables:I,operationName:E,fetch:C,fetchOptions:F,middleware:J}=Q,Y={...Q.headers},G="",X=void 0;if(A==="POST"){if(X=LmQ(D,I,E,F.jsonSerializer),typeof X==="string")Y["Content-Type"]="application/json"}else G=OmQ({query:D,variables:I,operationName:E,jsonSerializer:F.jsonSerializer??fe});let z={method:A,headers:Y,body:X,...F},U=B,w=z;if(J){let Z=await Promise.resolve(J({...z,url:B,operationName:E,variables:I})),{url:H,...W}=Z;U=H,w=W}if(G)U=`${U}?${G}`;return await C(U,w)};class $zA{constructor(A,Q={}){this.url=A,this.requestConfig=Q,this.rawRequest=async(...B)=>{let[D,I,E]=B,C=$sA(D,I,E),{headers:F,fetch:J=wW.default,method:Y="POST",requestMiddleware:G,responseMiddleware:X,...z}=this.requestConfig,{url:U}=this;if(C.signal!==void 0)z.signal=C.signal;let{operationName:w}=W_(C.query);return HzA({url:U,query:C.query,variables:C.variables,headers:{...sS(VzA(F)),...sS(C.requestHeaders)},operationName:w,fetch:J,method:Y,fetchOptions:z,middleware:G}).then((Z)=>{if(X)X(Z);return Z}).catch((Z)=>{if(X)X(Z);throw Z})}}async request(A,...Q){let[B,D]=Q,I=VsA(A,B,D),{headers:E,fetch:C=wW.default,method:F="POST",requestMiddleware:J,responseMiddleware:Y,...G}=this.requestConfig,{url:X}=this;if(I.signal!==void 0)G.signal=I.signal;let{query:z,operationName:U}=W_(I.document);return HzA({url:X,query:z,variables:I.variables,headers:{...sS(VzA(E)),...sS(I.requestHeaders)},operationName:U,fetch:C,method:F,fetchOptions:G,middleware:J}).then((w)=>{if(Y)Y(w);return w.data}).catch((w)=>{if(Y)Y(w);throw w})}batchRequests(A,Q){let B=WsA(A,Q),{headers:D,...I}=this.requestConfig;if(B.signal!==void 0)I.signal=B.signal;let E=B.documents.map(({document:F})=>W_(F).query),C=B.documents.map(({variables:F})=>F);return HzA({url:this.url,query:E,variables:C,headers:{...sS(VzA(D)),...sS(B.requestHeaders)},operationName:void 0,fetch:this.requestConfig.fetch??wW.default,method:this.requestConfig.method||"POST",fetchOptions:I,middleware:this.requestConfig.requestMiddleware}).then((F)=>{if(this.requestConfig.responseMiddleware)this.requestConfig.responseMiddleware(F);return F.data}).catch((F)=>{if(this.requestConfig.responseMiddleware)this.requestConfig.responseMiddleware(F);throw F})}setHeaders(A){return this.requestConfig.headers=A,this}setHeader(A,Q){let{headers:B}=this.requestConfig;if(B)B[A]=Q;else this.requestConfig.headers={[A]:Q};return this}setEndpoint(A){return this.url=A,this}}var HzA=async(A)=>{let{query:Q,variables:B,fetchOptions:D}=A,I=_mQ(KsA(A.method??"post")),E=Array.isArray(A.query),C=await I(A),F=await RmQ(C,D.jsonSerializer??fe),J=Array.isArray(F)?!F.some(({data:G})=>!G):Boolean(F.data),Y=Array.isArray(F)||!F.errors||Array.isArray(F.errors)&&!F.errors.length||D.errorPolicy==="all"||D.errorPolicy==="ignore";if(C.ok&&Y&&J){let{errors:G,...X}=Array.isArray(F)?F:F,z=D.errorPolicy==="ignore"?X:F;return{...E?{data:z}:z,headers:C.headers,status:C.status}}else throw new ZF({...typeof F==="string"?{error:F}:F,status:C.status,headers:C.headers},{query:Q,variables:B})};var LmQ=(A,Q,B,D)=>{let I=D??fe;if(!Array.isArray(A))return I.stringify({query:A,variables:Q,operationName:B});if(typeof Q!=="undefined"&&!Array.isArray(Q))throw new Error("Cannot create request body with given variable type, array expected");let E=A.reduce((C,F,J)=>{return C.push({query:F,variables:Q?Q[J]:void 0}),C},[]);return I.stringify(E)},RmQ=async(A,Q)=>{let B;if(A.headers.forEach((D,I)=>{if(I.toLowerCase()==="content-type")B=D}),B&&(B.toLowerCase().startsWith("application/json")||B.toLowerCase().startsWith("application/graphql+json")||B.toLowerCase().startsWith("application/graphql-response+json")))return Q.parse(await A.text());else return A.text()},VzA=(A)=>{return typeof A==="function"?A():A},Lz=(A,...Q)=>{return A.reduce((B,D,I)=>`${B}${D}${I in Q?String(Q[I]):""}`,"")};var Y41=async(A,Q,B)=>{if(!Q.ok){let D=await Q.text().catch(()=>{return});throw new wsA(A,Q,B,D)}};function A9(){return"8.53.2"}var G41=(A)=>{let Q=A?`${A?.name}:${A?.version}`:"missing client info";return`gitlab-language-server:${A9()} (${Q})`};function U41(A){return A!==null&&A!==void 0}var WzA=(A,Q)=>{return Object.entries(Q).forEach(([B,D])=>{if(U41(D))A.searchParams.append(B,String(D))}),A},dAA=(A)=>A.toString().replace(/\/?$/,"/"),tS=(A)=>A.replace(/^\.?\/?/,"./"),X41=(A)=>{if(A.startsWith("git@")){let Q=A.match(/git@([^:]+):(.+)/);if(Q){let[,B,D]=Q;return`https://${B}/${D}`}}if(A.startsWith("git://"))return A.replace("git://","https://");if(A.startsWith("ssh://"))return A.replace("ssh://","https://").replace(/git@([^/]+)/,"$1");return A};var TmQ=(A)=>A.split("/").pop()||"unknown resource";class NzA{#A;#Q;#B;#D;#I;constructor(A,Q,B,D,I){this.#A=A,this.#Q=Q,this.#B=new URL(dAA(D)),this.#D=I,this.#I=B}getDefaultHeaders(){return{Authorization:`Bearer ${this.#D}`,"User-Agent":G41(this.#I),"X-Gitlab-Language-Server-Version":A9()}}async fetchFromApiRaw(A){try{let Q=`Unknown request method "${A.method}", request type "${A.type}"`;switch(A.method){case"GET":return await this.#C(A);case"POST":return await this.#F(A);case"PATCH":return await this.#J(A);case"PUT":return await this.#Y(A);case"HEAD":return await this.#G(A);default:throw new Error(Q)}}catch(Q){throw new ge(A,Q)}}async fetchFromApi(A){if(A.type==="graphql")return this.#E(A);let Q=await this.fetchFromApiRaw(A);return await Y41(A,Q,TmQ(A.path)),Q.json()}fetchOperation=(A)=>(Q)=>this.fetchFromApi({...A,signal:Q});async#E(A){let Q=new URL("./api/graphql",this.#B),B=ve(A.query);if(B)this.#A.debug(`[SimpleApiClient] Making GraphQL request: ${B}`);let D=async(E,C)=>{let F=E instanceof URL?E.toString():E;return this.#Q.post(F,{...C,headers:{...C?.headers},signal:A.signal})},I=new $zA(Q.href,{fetch:D,headers:{...this.getDefaultHeaders()}});try{return await I.request(A.query,A.variables)}catch(E){if(E instanceof ZF)throw new SGA(A,E.response);throw new ge(A,E)}}async#C(A){let Q=tS(A.path),B=new URL(Q,this.#B);return WzA(B,A.searchParams??{}),this.#Q.get(B,{headers:{...this.getDefaultHeaders(),...A.headers},signal:A.signal})}async#F(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.post(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#J(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.patch(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#Y(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.put(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#G(A){let Q=tS(A.path),B=new URL(Q,this.#B);return WzA(B,A.searchParams??{}),this.#Q.head(B,{headers:{...this.getDefaultHeaders(),...A.headers},signal:A.signal})}}var z41="api",w41=(A)=>{if(!(A instanceof Au)||!A.isInvalidTokenOrInvalidRefresh())return{valid:!1,reason:"unknown",message:`Token validation failed: ${A}`};return{valid:!1,reason:"invalid_token",message:"Token is invalid or expired."}},Z41=(A)=>{if(A.includes(z41))return;return{valid:!1,reason:"invalid_scopes",message:`Token has scope(s) ${A.map((B)=>`'${B}'`).join(", ")} (needs ${z41}).`}};async function jmQ(A,Q){let B={type:"rest",method:"GET",path:"/api/v4/personal_access_tokens/self"},{scopes:D}=await A.fetchFromApi(B),I=Z41(D);if(I)return I;return{valid:!0,tokenInfo:{scopes:D,type:"pat",token:Q}}}async function PmQ(A,Q){let B={type:"rest",method:"GET",path:"/oauth/token/info"},{scope:D}=await A.fetchFromApi(B),I=Z41(D);if(I)return I;return{valid:!0,tokenInfo:{scopes:D,type:"oauth",token:Q}}}async function K41(A,Q){if(!Q)return{valid:!1,message:"No token provided",reason:"invalid_token"};let B=await Promise.all([jmQ(A,Q).catch(w41),PmQ(A,Q).catch(w41)]),D=B.find((F)=>F.valid);if(D)return D;let I=B.filter((F)=>!F.valid),E=I.find((F)=>F.reason==="invalid_scopes");if(E)return E;let C=I.find((F)=>F.reason==="invalid_token");if(C)return C;return B[0]}var cAA=dA(u1(),1);var MzA=cAA.createInterfaceId("ProjectService");class ou{#A;#Q;constructor(A,Q){this.#A=Q,this.#Q=d1(A,"[ProjectService]")}async getProjectFromPathWithNamespace(A){return this.#Q.debug(`Fetching details for project: ${A}`),this.#A.fetchFromApi({type:"rest",method:"GET",path:`/api/v4/projects/${encodeURIComponent(A)}`})}async getProjectIdsFromPaths(A){return(await this.#A.fetchFromApi({type:"graphql",query:Lz`
1136
+ `,"")).trim()}function POQ(A){return GsA(A).match(/^(query|mutation|subscription)\s+/)?.[1]}function SOQ(A){return GsA(A).match(/(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function ve(A){let Q=POQ(A),B=SOQ(A);if(Q)return`${Q}: ${B??"anonymous"}`;return}var yOQ=(A)=>{if(A.method==="GET"||A.method==="HEAD")return;if(!A.body)return;return y8("Body",JSON.stringify(A.body))},vOQ=(A)=>{if(A.method==="POST"||A.method==="PATCH"||A.method==="PUT")return;if(!A.searchParams)return;return y8("Search Params",JSON.stringify(A.searchParams))},kOQ=(A)=>{if(!A.headers)return;return y8("Headers",JSON.stringify(A.headers))},em=(A)=>{switch(A.type){case"graphql":return iE("GraphQL Request",y8("Query",A.query.replace(/[\s\n]+/g," ").trim()),y8("Variables",JSON.stringify(A.variables)));case"rest":return iE("REST Request",y8("Method",A.method),y8("Path",A.path),kOQ(A),vOQ(A),yOQ(A));default:return y8("Unknown request type",A.type)}};var zsA=(A)=>{try{return JSON.parse(A)?.error}catch{return}},gOQ=(A)=>{if(!A)return"";try{return JSON.parse(A)?.error_description??""}catch{return""}},TGA=(A,Q)=>Boolean(A.status===401&&Q&&zsA(Q)==="invalid_token"),jGA=(A,Q)=>Boolean(A.status===400&&Q&&zsA(Q)==="invalid_grant");class ke extends Error{request;cause;constructor(A,Q,B){super(A);this.request=Q,this.cause=B?.cause}get sanitizedMessage(){return"API request failed"}}class PGA extends ke{status;constructor(A,Q,B,D){super(A,Q,D);this.status=B}}class Au extends PGA{type="rest";response;#A;constructor(A,Q,B,D){let I=`Fetching ${B} from ${Q.url} failed. ${gOQ(D)}`;if(TGA(Q,D))I=`Request for ${B} failed because the token is expired or revoked.`;if(jGA(Q,D))I="Request to refresh token failed, because it's revoked or already refreshed.";super(I,A,Q.status);this.response=Q,this.#A=D}isInvalidTokenOrInvalidRefresh(){return TGA(this.response,this.#A)||jGA(this.response,this.#A)}get ctx(){return iE("Error details",em(this.request),this.#Q())}get sanitizedMessage(){if(TGA(this.response,this.#A))return"Request failed because the token is expired or revoked.";if(jGA(this.response,this.#A))return"Request to refresh token failed, because it's revoked or already refreshed.";return`Request failed with error code: ${this.response.status}`}#Q(){let A=Object.fromEntries(this.response.headers.entries());return iE("Response",y8("Status",String(this.status)),!XsA.default.isEmpty(A)?y8("Headers",JSON.stringify(A)):void 0,this.#A?y8("Response body",this.#A):void 0)}get body(){return this.#A}}var UsA=(A)=>A.errors?.map((Q)=>Q.message).join(",")||"";class SGA extends PGA{type="graphql";graphQlResponse;#A;constructor(A,Q){let B=ve(A.query),D=`GraphQL request "${B}" failed with ${UsA(Q)}`;super(D,A,Q.status);this.graphQlResponse=Q,this.#A=B}get sanitizedMessage(){return`GraphQL request "${this.#A}" failed with status ${this.graphQlResponse.status}`}get ctx(){return iE("Error details",em(this.request),this.#Q())}#Q(){return iE("Response",y8("Status",String(this.graphQlResponse.status)),y8("Errors",UsA(this.graphQlResponse)))}}class ge extends ke{type="network";cause;constructor(A,Q){let B=Q instanceof Error?Q.message:`Network error occurred: ${Q}`;super(B,A);this.cause=Q}get ctx(){return iE("Error details",em(this.request),this.#A())}get sanitizedMessage(){let A=this.cause,Q=A?.code||A?.errno,B=this.#Q(Q);return`Network error occurred${B?`: ${B}`:""}`}#A(){if(!this.cause||!(this.cause instanceof Error))return;let A=this.cause;if(A.code||A.errno){let Q=A.code||A.errno,B=this.#Q(Q),D=B?`${B} (${Q})`:`Error code: ${Q}`;return y8("Network issue",D)}return}#Q(A){return{ENOTFOUND:"DNS lookup failed - hostname could not be resolved",ECONNREFUSED:"Connection refused - server is not accepting connections",ECONNRESET:"Connection reset by peer - server closed the connection unexpectedly",ETIMEDOUT:"Connection timed out - server did not respond in time",EHOSTUNREACH:"Host unreachable - network route to server not available",ENETUNREACH:"Network unreachable - no network connectivity",ECONNABORTED:"Connection aborted - request was cancelled",EBADF:"Bad file descriptor - network connection issue",EPIPE:"Broken pipe - connection closed while writing data",EAI_AGAIN:"DNS lookup failed temporarily - try again later"}[A]}}class bOQ extends ke{type="timeout";#A;constructor(A,Q){let B=`Request timed out${Q?` after ${Q}ms`:""}`;super(B,A);this.#A=B}get ctx(){return iE("Error details",em(this.request))}get sanitizedMessage(){return this.#A}}var wsA=Au;function be(A){return A instanceof Au}var Qu={type:"rest",method:"GET",path:"/api/v4/version"};var ZsA=(A)=>be(A)&&(A.status<400||A.status>=500);var fe=JSON;var KsA=(A)=>A.toUpperCase(),HsA=(A)=>{let Q={};return A.forEach((B,D)=>{Q[D]=B}),Q};var VsA=(A,Q,B)=>{return A.document?A:{document:A,variables:Q,requestHeaders:B,signal:void 0}},$sA=(A,Q,B)=>{return A.query?A:{query:A,variables:Q,requestHeaders:B,signal:void 0}},WsA=(A,Q)=>{return A.documents?A:{documents:A,requestHeaders:Q,signal:void 0}};var gAA=dA(z61(),1),w61=(A)=>{let Q=void 0,B=A.definitions.filter((D)=>D.kind==="OperationDefinition");if(B.length===1)Q=B[0]?.name?.value;return Q},W_=(A)=>{if(typeof A==="string"){let B=void 0;try{let D=gAA.parse(A);B=w61(D)}catch(D){}return{query:A,operationName:B}}let Q=w61(A);return{query:gAA.print(A),operationName:Q}};class ZF extends Error{constructor(A,Q){let B=`${ZF.extractMessage(A)}: ${JSON.stringify({response:A,request:Q})}`;super(B);if(Object.setPrototypeOf(this,ZF.prototype),this.response=A,this.request=Q,typeof Error.captureStackTrace==="function")Error.captureStackTrace(this,ZF)}static extractMessage(A){return A.errors?.[0]?.message??`GraphQL Error (Code: ${A.status})`}}var wW=dA(D41(),1);var wmQ="connection_init",ZmQ="connection_ack",E41="ping",C41="pong",KmQ="subscribe",HmQ="next",VmQ="error",F41="complete";class zW{get type(){return this._type}get id(){return this._id}get payload(){return this._payload}constructor(A,Q,B){this._type=A,this._payload=Q,this._id=B}get text(){let A={type:this.type};if(this.id!=null&&this.id!=null)A.id=this.id;if(this.payload!=null&&this.payload!=null)A.payload=this.payload;return JSON.stringify(A)}static parse(A,Q){let{type:B,payload:D,id:I}=JSON.parse(A);return new zW(B,Q(D),I)}}class KzA{constructor(A,{onInit:Q,onAcknowledged:B,onPing:D,onPong:I}){this.socketState={acknowledged:!1,lastRequestId:0,subscriptions:{}},this.socket=A,A.addEventListener("open",async(E)=>{this.socketState.acknowledged=!1,this.socketState.subscriptions={},A.send(WmQ(Q?await Q():null).text)}),A.addEventListener("close",(E)=>{this.socketState.acknowledged=!1,this.socketState.subscriptions={}}),A.addEventListener("error",(E)=>{console.error(E)}),A.addEventListener("message",(E)=>{try{let C=$mQ(E.data);switch(C.type){case ZmQ:{if(this.socketState.acknowledged)console.warn("Duplicate CONNECTION_ACK message ignored");else if(this.socketState.acknowledged=!0,B)B(C.payload);return}case E41:{if(D)D(C.payload).then((G)=>A.send(I41(G).text));else A.send(I41(null).text);return}case C41:{if(I)I(C.payload);return}}if(!this.socketState.acknowledged)return;if(C.id===void 0||C.id===null||!this.socketState.subscriptions[C.id])return;let{query:F,variables:J,subscriber:Y}=this.socketState.subscriptions[C.id];switch(C.type){case HmQ:{if(!C.payload.errors&&C.payload.data)Y.next&&Y.next(C.payload.data);if(C.payload.errors)Y.error&&Y.error(new ZF({...C.payload,status:200},{query:F,variables:J}));return}case VmQ:{Y.error&&Y.error(new ZF({errors:C.payload,status:200},{query:F,variables:J}));return}case F41:{Y.complete&&Y.complete(),delete this.socketState.subscriptions[C.id];return}}}catch(C){console.error(C),A.close(1006)}A.close(4400,"Unknown graphql-ws message.")})}makeSubscribe(A,Q,B,D){let I=(this.socketState.lastRequestId++).toString();return this.socketState.subscriptions[I]={query:A,variables:D,subscriber:B},this.socket.send(MmQ(I,{query:A,operationName:Q,variables:D}).text),()=>{this.socket.send(qmQ(I).text),delete this.socketState.subscriptions[I]}}rawRequest(A,Q){return new Promise((B,D)=>{let I;this.rawSubscribe(A,{next:(E,C)=>I={data:E,extensions:C},error:D,complete:()=>B(I)},Q)})}request(A,Q){return new Promise((B,D)=>{let I;this.subscribe(A,{next:(E)=>I=E,error:D,complete:()=>B(I)},Q)})}subscribe(A,Q,B){let{query:D,operationName:I}=W_(A);return this.makeSubscribe(D,I,Q,B)}rawSubscribe(A,Q,B){return this.makeSubscribe(A,void 0,Q,B)}ping(A){this.socket.send(NmQ(A).text)}close(){this.socket.close(1000)}}KzA.PROTOCOL="graphql-transport-ws";function $mQ(A,Q=(B)=>B){return zW.parse(A,Q)}function WmQ(A){return new zW(wmQ,A)}function NmQ(A){return new zW(E41,A,void 0)}function I41(A){return new zW(C41,A,void 0)}function MmQ(A,Q){return new zW(KmQ,Q,A)}function qmQ(A){return new zW(F41,void 0,A)}var sS=(A)=>{let Q={};if(A)if(typeof Headers!=="undefined"&&A instanceof Headers||wW&&wW.Headers&&A instanceof wW.Headers)Q=HsA(A);else if(Array.isArray(A))A.forEach(([B,D])=>{if(B&&D!==void 0)Q[B]=D});else Q=A;return Q},J41=(A)=>A.replace(/([\s,]|#[^\n\r]+)+/g," ").trim(),OmQ=(A)=>{if(!Array.isArray(A.query)){let D=A,I=[`query=${encodeURIComponent(J41(D.query))}`];if(A.variables)I.push(`variables=${encodeURIComponent(D.jsonSerializer.stringify(D.variables))}`);if(D.operationName)I.push(`operationName=${encodeURIComponent(D.operationName)}`);return I.join("&")}if(typeof A.variables!=="undefined"&&!Array.isArray(A.variables))throw new Error("Cannot create query with given variable type, array expected");let Q=A,B=A.query.reduce((D,I,E)=>{return D.push({query:J41(I),variables:Q.variables?Q.jsonSerializer.stringify(Q.variables[E]):void 0}),D},[]);return`query=${encodeURIComponent(Q.jsonSerializer.stringify(B))}`},_mQ=(A)=>async(Q)=>{let{url:B,query:D,variables:I,operationName:E,fetch:C,fetchOptions:F,middleware:J}=Q,Y={...Q.headers},G="",X=void 0;if(A==="POST"){if(X=LmQ(D,I,E,F.jsonSerializer),typeof X==="string")Y["Content-Type"]="application/json"}else G=OmQ({query:D,variables:I,operationName:E,jsonSerializer:F.jsonSerializer??fe});let z={method:A,headers:Y,body:X,...F},U=B,w=z;if(J){let Z=await Promise.resolve(J({...z,url:B,operationName:E,variables:I})),{url:H,...W}=Z;U=H,w=W}if(G)U=`${U}?${G}`;return await C(U,w)};class $zA{constructor(A,Q={}){this.url=A,this.requestConfig=Q,this.rawRequest=async(...B)=>{let[D,I,E]=B,C=$sA(D,I,E),{headers:F,fetch:J=wW.default,method:Y="POST",requestMiddleware:G,responseMiddleware:X,...z}=this.requestConfig,{url:U}=this;if(C.signal!==void 0)z.signal=C.signal;let{operationName:w}=W_(C.query);return HzA({url:U,query:C.query,variables:C.variables,headers:{...sS(VzA(F)),...sS(C.requestHeaders)},operationName:w,fetch:J,method:Y,fetchOptions:z,middleware:G}).then((Z)=>{if(X)X(Z);return Z}).catch((Z)=>{if(X)X(Z);throw Z})}}async request(A,...Q){let[B,D]=Q,I=VsA(A,B,D),{headers:E,fetch:C=wW.default,method:F="POST",requestMiddleware:J,responseMiddleware:Y,...G}=this.requestConfig,{url:X}=this;if(I.signal!==void 0)G.signal=I.signal;let{query:z,operationName:U}=W_(I.document);return HzA({url:X,query:z,variables:I.variables,headers:{...sS(VzA(E)),...sS(I.requestHeaders)},operationName:U,fetch:C,method:F,fetchOptions:G,middleware:J}).then((w)=>{if(Y)Y(w);return w.data}).catch((w)=>{if(Y)Y(w);throw w})}batchRequests(A,Q){let B=WsA(A,Q),{headers:D,...I}=this.requestConfig;if(B.signal!==void 0)I.signal=B.signal;let E=B.documents.map(({document:F})=>W_(F).query),C=B.documents.map(({variables:F})=>F);return HzA({url:this.url,query:E,variables:C,headers:{...sS(VzA(D)),...sS(B.requestHeaders)},operationName:void 0,fetch:this.requestConfig.fetch??wW.default,method:this.requestConfig.method||"POST",fetchOptions:I,middleware:this.requestConfig.requestMiddleware}).then((F)=>{if(this.requestConfig.responseMiddleware)this.requestConfig.responseMiddleware(F);return F.data}).catch((F)=>{if(this.requestConfig.responseMiddleware)this.requestConfig.responseMiddleware(F);throw F})}setHeaders(A){return this.requestConfig.headers=A,this}setHeader(A,Q){let{headers:B}=this.requestConfig;if(B)B[A]=Q;else this.requestConfig.headers={[A]:Q};return this}setEndpoint(A){return this.url=A,this}}var HzA=async(A)=>{let{query:Q,variables:B,fetchOptions:D}=A,I=_mQ(KsA(A.method??"post")),E=Array.isArray(A.query),C=await I(A),F=await RmQ(C,D.jsonSerializer??fe),J=Array.isArray(F)?!F.some(({data:G})=>!G):Boolean(F.data),Y=Array.isArray(F)||!F.errors||Array.isArray(F.errors)&&!F.errors.length||D.errorPolicy==="all"||D.errorPolicy==="ignore";if(C.ok&&Y&&J){let{errors:G,...X}=Array.isArray(F)?F:F,z=D.errorPolicy==="ignore"?X:F;return{...E?{data:z}:z,headers:C.headers,status:C.status}}else throw new ZF({...typeof F==="string"?{error:F}:F,status:C.status,headers:C.headers},{query:Q,variables:B})};var LmQ=(A,Q,B,D)=>{let I=D??fe;if(!Array.isArray(A))return I.stringify({query:A,variables:Q,operationName:B});if(typeof Q!=="undefined"&&!Array.isArray(Q))throw new Error("Cannot create request body with given variable type, array expected");let E=A.reduce((C,F,J)=>{return C.push({query:F,variables:Q?Q[J]:void 0}),C},[]);return I.stringify(E)},RmQ=async(A,Q)=>{let B;if(A.headers.forEach((D,I)=>{if(I.toLowerCase()==="content-type")B=D}),B&&(B.toLowerCase().startsWith("application/json")||B.toLowerCase().startsWith("application/graphql+json")||B.toLowerCase().startsWith("application/graphql-response+json")))return Q.parse(await A.text());else return A.text()},VzA=(A)=>{return typeof A==="function"?A():A},Lz=(A,...Q)=>{return A.reduce((B,D,I)=>`${B}${D}${I in Q?String(Q[I]):""}`,"")};var Y41=async(A,Q,B)=>{if(!Q.ok){let D=await Q.text().catch(()=>{return});throw new wsA(A,Q,B,D)}};function A9(){return"8.54.0"}var G41=(A)=>{let Q=A?`${A?.name}:${A?.version}`:"missing client info";return`gitlab-language-server:${A9()} (${Q})`};function U41(A){return A!==null&&A!==void 0}var WzA=(A,Q)=>{return Object.entries(Q).forEach(([B,D])=>{if(U41(D))A.searchParams.append(B,String(D))}),A},dAA=(A)=>A.toString().replace(/\/?$/,"/"),tS=(A)=>A.replace(/^\.?\/?/,"./"),X41=(A)=>{if(A.startsWith("git@")){let Q=A.match(/git@([^:]+):(.+)/);if(Q){let[,B,D]=Q;return`https://${B}/${D}`}}if(A.startsWith("git://"))return A.replace("git://","https://");if(A.startsWith("ssh://"))return A.replace("ssh://","https://").replace(/git@([^/]+)/,"$1");return A};var TmQ=(A)=>A.split("/").pop()||"unknown resource";class NzA{#A;#Q;#B;#D;#I;constructor(A,Q,B,D,I){this.#A=A,this.#Q=Q,this.#B=new URL(dAA(D)),this.#D=I,this.#I=B}getDefaultHeaders(){return{Authorization:`Bearer ${this.#D}`,"User-Agent":G41(this.#I),"X-Gitlab-Language-Server-Version":A9()}}async fetchFromApiRaw(A){try{let Q=`Unknown request method "${A.method}", request type "${A.type}"`;switch(A.method){case"GET":return await this.#C(A);case"POST":return await this.#F(A);case"PATCH":return await this.#J(A);case"PUT":return await this.#Y(A);case"HEAD":return await this.#G(A);default:throw new Error(Q)}}catch(Q){throw new ge(A,Q)}}async fetchFromApi(A){if(A.type==="graphql")return this.#E(A);let Q=await this.fetchFromApiRaw(A);return await Y41(A,Q,TmQ(A.path)),Q.json()}fetchOperation=(A)=>(Q)=>this.fetchFromApi({...A,signal:Q});async#E(A){let Q=new URL("./api/graphql",this.#B),B=ve(A.query);if(B)this.#A.debug(`[SimpleApiClient] Making GraphQL request: ${B}`);let D=async(E,C)=>{let F=E instanceof URL?E.toString():E;return this.#Q.post(F,{...C,headers:{...C?.headers},signal:A.signal})},I=new $zA(Q.href,{fetch:D,headers:{...this.getDefaultHeaders()}});try{return await I.request(A.query,A.variables)}catch(E){if(E instanceof ZF)throw new SGA(A,E.response);throw new ge(A,E)}}async#C(A){let Q=tS(A.path),B=new URL(Q,this.#B);return WzA(B,A.searchParams??{}),this.#Q.get(B,{headers:{...this.getDefaultHeaders(),...A.headers},signal:A.signal})}async#F(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.post(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#J(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.patch(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#Y(A){let Q=tS(A.path),B=new URL(Q,this.#B);return this.#Q.put(B,{headers:{"Content-Type":"application/json",...this.getDefaultHeaders(),...A.headers},body:JSON.stringify(A.body),signal:A.signal})}async#G(A){let Q=tS(A.path),B=new URL(Q,this.#B);return WzA(B,A.searchParams??{}),this.#Q.head(B,{headers:{...this.getDefaultHeaders(),...A.headers},signal:A.signal})}}var z41="api",w41=(A)=>{if(!(A instanceof Au)||!A.isInvalidTokenOrInvalidRefresh())return{valid:!1,reason:"unknown",message:`Token validation failed: ${A}`};return{valid:!1,reason:"invalid_token",message:"Token is invalid or expired."}},Z41=(A)=>{if(A.includes(z41))return;return{valid:!1,reason:"invalid_scopes",message:`Token has scope(s) ${A.map((B)=>`'${B}'`).join(", ")} (needs ${z41}).`}};async function jmQ(A,Q){let B={type:"rest",method:"GET",path:"/api/v4/personal_access_tokens/self"},{scopes:D}=await A.fetchFromApi(B),I=Z41(D);if(I)return I;return{valid:!0,tokenInfo:{scopes:D,type:"pat",token:Q}}}async function PmQ(A,Q){let B={type:"rest",method:"GET",path:"/oauth/token/info"},{scope:D}=await A.fetchFromApi(B),I=Z41(D);if(I)return I;return{valid:!0,tokenInfo:{scopes:D,type:"oauth",token:Q}}}async function K41(A,Q){if(!Q)return{valid:!1,message:"No token provided",reason:"invalid_token"};let B=await Promise.all([jmQ(A,Q).catch(w41),PmQ(A,Q).catch(w41)]),D=B.find((F)=>F.valid);if(D)return D;let I=B.filter((F)=>!F.valid),E=I.find((F)=>F.reason==="invalid_scopes");if(E)return E;let C=I.find((F)=>F.reason==="invalid_token");if(C)return C;return B[0]}var cAA=dA(u1(),1);var MzA=cAA.createInterfaceId("ProjectService");class ou{#A;#Q;constructor(A,Q){this.#A=Q,this.#Q=d1(A,"[ProjectService]")}async getProjectFromPathWithNamespace(A){return this.#Q.debug(`Fetching details for project: ${A}`),this.#A.fetchFromApi({type:"rest",method:"GET",path:`/api/v4/projects/${encodeURIComponent(A)}`})}async getProjectIdsFromPaths(A){return(await this.#A.fetchFromApi({type:"graphql",query:Lz`
1137
1137
  query getProjectIds($fullPaths: [String!]!) {
1138
1138
  projects(fullPaths: $fullPaths) {
1139
1139
  nodes {
@@ -1617,7 +1617,7 @@ ${E}`)}return B.join(`
1617
1617
  `),error:""}}catch(I){let E=`Failed to read directory "${B}": ${I}`;return this.#A.error(E,I),{error:E,response:""}}}}rf=w1([GZ0.Injectable(oB,[f1,V8])],rf);var eIA=dA(u1(),1);import{mkdir as VT4}from"node:fs/promises";import{join as $T4}from"node:path";class sf{#A;#Q;#B;constructor(A,Q,B){this.#A=d1(A,"[MakeDirectoryActionHandler]"),this.#Q=H3(this.#A,B),this.#B=Q}name="mkdir";canHandle(A){return Boolean(A.mkdir)}async execute(A,{workspaceFolderPath:Q,abortSignal:B}){let{directory_path:D}=A.mkdir,I=$T4(Q,D);try{return await nY(D,Q,this.#Q,this.#B,this.#A),this.#A.debug(`Creating directory "${D}"`),B.throwIfAborted(),await VT4(I,{recursive:!0}),{response:`Directory created successfully: "${D}"`,error:""}}catch(E){let C=E instanceof Error?E.message:String(E);return this.#A.error(`Unable to create directory "${I}"`,E),{error:C,response:""}}}}sf=w1([eIA.Injectable(oB,[f1,V8,eIA.collection(j7)])],sf);var AEA=dA(u1(),1);import{join as WT4}from"node:path";class po{logger;constructor(A){this.logger=A}updateFileState(A,Q,B,D){try{Q.recordFileRead(B,A)}catch(I){this.logger.warn(`Failed to update version cache after reading for "${D}"`,I)}}}class tf extends po{#A;#Q;#B;constructor(A,Q,B,D){super(d1(A,"[ReadFileActionHandler]"));this.#A=Q,this.#Q=H3(this.logger,B),this.#B=D}name="read_file";formatInput(A){return{tool:"read_file",filepath:A.file_path}}canHandle(A){return Boolean(A.runReadFile)}async execute({runReadFile:A},{workspaceFolderPath:Q,fileStateTracker:B}){let D=A.filepath,I=WT4(Q,D);this.logger.debug(`Reading file "${A.filepath}"`);try{if(await nY(D,Q,this.#Q,this.#A,this.logger),await dIA(aT(I),this.#B))return this.logger.debug(`File "${D}" detected as binary, skipping read`),{response:"",error:`Cannot read file: "${D}" is a binary file`};let E=await this.#Q.getText(I);return this.updateFileState(E,B,I,D),{response:E,error:""}}catch(E){let C=E instanceof Error?E.message:String(E);return this.logger.error(`Error reading file "${I}"`,E),{response:"",error:`Error reading file: ${C}`}}}}tf=w1([AEA.Injectable(oB,[f1,V8,AEA.collection(j7),EZ])],tf);var QEA=dA(u1(),1);import{join as NT4}from"node:path";class ef extends po{#A;#Q;#B;constructor(A,Q,B,D){super(d1(A,"[ReadFilesActionHandler]"));this.#A=Q,this.#Q=H3(this.logger,B),this.#B=D}name="read_files";canHandle(A){return Boolean(A.runReadFiles)}async execute({runReadFiles:A},{workspaceFolderPath:Q,fileStateTracker:B}){let D=A.filepaths,I={};return await Promise.allSettled(D.map(async(C)=>{let F=NT4(Q,C);try{if(await nY(C,Q,this.#Q,this.#A,this.logger),await dIA(aT(F),this.#B)){this.logger.debug(`File "${C}" detected as binary, skipping read`),I[C]={error:`Cannot read file: "${C}" is a binary file`};return}let J=await this.#Q.getText(F);I[C]={content:J},this.updateFileState(J,B,F,C),this.logger.debug(`Successfully read file "${C}"`)}catch(J){let Y=J instanceof Error?J.message:String(J);I[C]={error:`Error reading file: ${Y}`},this.logger.error(`Error reading file "${F}"`,J)}})),{response:JSON.stringify(I),error:""}}}ef=w1([QEA.Injectable(oB,[f1,V8,QEA.collection(j7),EZ])],ef);var DEA=dA(u1(),1);var UZ0=dA(u1(),1),BEA=(A)=>{return Object.hasOwn(A,"error")},rT=UZ0.createInterfaceId("WorkflowCommandService");class Ax{#A;#Q;constructor(A,Q){this.#A=d1(A,"[RunCommandActionHandler]"),this.#Q=H3(this.#A,Q)}name="run_command";formatInput(A){let{program:Q,args:B}=A;return{tool:"run_command",command:B?`${Q} ${B}`:Q}}canHandle(A){return Boolean(A.runCommand)}async execute({runCommand:A},{workspaceFolderPath:Q,workflowId:B,abortSignal:D}){let{program:I,flags:E,arguments:C}=A;this.#A.debug(`Running command: "${I} ${[...E,...C].join(" ")}"`);let F=await this.#Q.runCommand(B,Q,I,!1,[...E,...C],D);if(BEA(F))return{...F,response:""};if(F.exitCode===0)return this.#A.debug(`Command completed successfully with output: ${F.output}`),{response:F.output,error:""};let{output:J,exitCode:Y}=F,G=`Process exited with code ${Y}`;return this.#A.error(`${G}. Output: ${J}`),{error:G,response:J}}}Ax=w1([DEA.Injectable(oB,[f1,DEA.collection(rT)])],Ax);var SW0=dA(u1(),1);var CW0=dA(u1(),1);var FW0=dA(EW0(),1);import{spawn as Ig4}from"node:child_process";import{rm as Eg4,writeFile as Cg4}from"node:fs/promises";import{tmpdir as Fg4}from"node:os";import{join as Jg4}from"node:path";class Lx{logger;#A;#Q;constructor(A,Q,B){this.logger=A,this.#A=Q,this.#Q=B}async buildGitArgs(A,Q,B,D){return[...await this.defaultGitArgs(B,D),A,...Q]}async defaultGitArgs(A,Q){let B=[],D="auth",E=this.#A.get("gitHttpUser")||"auth",C=!0,F=this.#A.get("gitUserEmail")||"",J=this.#A.get("gitUserName")||"",Y;try{Y=this.extractBaseURL(A)}catch(G){throw this.logger.error(`Failed to get baseURL for git repo from repositoryUrl "${A}"`,G),G}if(Y.length){if(E)B.push("-c",`credential.${Y}.username=${E}`);let G=this.#B();if(G)B.push("-c",`url.${Y}/.insteadOf=${G}`);else{let X=Y.replace(/^https?:\/\//,"");B.push("-c",`url.${Y}/.insteadOf=git@${X}:`)}}if(B.push("-c",`safe.directory=${Q}`),B.push("-c",`user.email=${F}`),J)B.push("-c",`user.name=${J}`);return B}extractBaseURL(A){if(A==="")return"";try{let Q=X41(A),B=new URL(Q);if(B.protocol!=="http:"&&B.protocol!=="https:")throw new Error(`unsupported protocol: ${B.protocol}`);if(!B.origin)throw new Error(`invalid URL format: ${A}`);return B.origin}catch(Q){throw new Error(`invalid URL: ${A}, ${Q instanceof Error?Q.message:"parsing failed"}`)}}#B(){let A=process.env.CI_REPOSITORY_URL;if(!A)return null;try{let Q=new URL(A),B=`${Q.protocol}//${Q.host}`;if(Q.username||Q.password){let D=Q.password?`${Q.username}:${Q.password}`:Q.username;B=`${Q.protocol}//${D}@${Q.host}`}return B}catch(Q){throw new Error(`Failed to parse CI_REPOSITORY_URL, does it contain the expected structure? ${Q instanceof Error?Q.message:"parsing failed"}`)}}async createGitAskPass(){let A=Jg4(Fg4(),`git-askpass-${RM()}`),Q=`#!/bin/sh
1618
1618
  echo $GIT_PASSWORD`;return await Cg4(A,`#!/bin/sh
1619
1619
  echo $GIT_PASSWORD`,{mode:448}),A}async removeGitAskPass(A){if(!A)return;try{await Eg4(A,{force:!0})}catch(Q){this.logger.warn(`Failed to clean up temporary git askpass file: "${A}"`,Q)}}runGitCommand(A,Q,B,D,I){let E=this.#Q.redactSecrets(JSON.stringify(A),"git-command-args");return this.logger.debug(`Running git command with the following argument: ${E}`),new Promise((C,F)=>{let J=Ig4("git",A,{shell:!1,cwd:B,env:{PATH:process.env.PATH,HOME:process.env.HOME||process.env.USERPROFILE,GIT_EXEC_PATH:process.env.GIT_EXEC_PATH,GIT_PASSWORD:this.#A.get("gitHttpPassword")||D,GIT_ASKPASS:Q,GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_NOGLOBAL:"1",GIT_CONFIG_GLOBAL:"/dev/null",http_proxy:process.env.http_proxy||process.env.HTTP_PROXY,https_proxy:process.env.https_proxy||process.env.HTTPS_PROXY,all_proxy:process.env.all_proxy||process.env.ALL_PROXY,no_proxy:process.env.no_proxy||process.env.NO_PROXY},signal:I}),Y="";J.stdout.on("data",(G)=>{Y+=G}),J.stderr.on("data",(G)=>{Y+=G}),J.on("error",(G)=>{this.logger.debug("Git command error spawning process",{error:G.message}),F(G)}),J.on("close",(G)=>{if(G!==0)this.logger.debug(`Git command failed with exit code ${G}`,{error:Y}),F(new Error(`git command failed with exit code ${G}: ${Y}`));else C(Y)})})}}class xEA extends Lx{#A;constructor(A,Q,B,D){super(d1(A,"[NodeGitLsFiles]"),Q,D);this.#A=B}async execute(A,Q="",B=""){let D="";try{return await FW0.listFiles({dir:A,fs:this.#A})}catch(I){if(hM1(I))this.logger.debug(`Repository "${A}" has an unsupported dircache version configured. "isomorphic-git" cannot work with anything other than dircache "2". Falling back to direct system git call`)}try{let E=[],C=await this.buildGitArgs("ls-files",E,Q,A);D=await this.createGitAskPass();let F=await this.runGitCommand(C,D,A,B);return this.logger.debug("Command executed successfully"),F.split(`
1620
- `).filter((J)=>J.trim()!=="")}catch(I){throw this.logger.error("Command execution error",I),I}finally{await this.removeGitAskPass(D)}}}xEA=w1([CW0.Injectable(xM1,[f1,A8,EZ,QI])],xEA);var VW0=dA(HW0(),1),$W0=dA(u1(),1);import{readFileSync as Ng4}from"fs";import{homedir as Mg4}from"os";import{join as qg4}from"path";class mEA{#A;constructor(A){this.#A=d1(A,"[NodeGitConfigCommand]")}async getRemoteUrl(A,Q,B){try{let D=this.#Q(B);if(!D)return B;let I=this.#B(D);if(I!==D){if(this.#A.debug(`Resolved SSH hostname: '${D}' -> '${I}'`),B.startsWith("git@"))return B.replace(`git@${D}:`,`git@${I}:`);try{let E=new URL(B);return E.hostname=I,E.toString()}catch{return B.replace(D,I)}}return B}catch{return B}}#Q(A){try{let Q=A.match(/^git@([^:]+):/);if(Q)return Q[1]??null;return new URL(A).hostname}catch{return null}}#B(A){try{let Q=qg4(Mg4(),".ssh","config"),B=Ng4(Q,"utf8"),I=VW0.default.parse(B).compute(A);if(I.HostName)return I.HostName;return A}catch{return A}}}mEA=w1([$W0.Injectable(uM1,[f1])],mEA);var yg4=NW0(),wdA=TW0();var vg4=1000,jW0=process.platform==="win32"?30000:1e6;function kg4(A){return wdA(A).map((B)=>{if(typeof B==="string")return B;if(typeof B==="object"&&B!==null){if("pattern"in B)return B.pattern;if("op"in B)return B.op}return String(B)})}function gg4(A){return A.length<=vg4}function bg4(A,Q){let B=Buffer.from(A).length,D=Buffer.from(Q).length;return B+D<jW0}function PW0(A,Q=""){if(!bg4(A,Q))return{isValid:!1,error:`Command is too long: bytes exceed ${jW0} byte limit on ${process.platform}`};let B;try{B=kg4(Q)}catch(D){return{isValid:!1,error:D instanceof Error?D.message:"Failed to parse arguments"}}for(let D of B)if(!gg4(D))return{isValid:!1,error:`Argument too long: ${D.substring(0,50)}...`};return{isValid:!0,args:B}}class Tx extends Lx{constructor(A,Q,B){super(d1(A,"[RunGitCommandActionHandler]"),Q,B)}name="run_git_command";canHandle(A){return Boolean(A.runGitCommand)}async execute({runGitCommand:A},{workspaceFolderPath:Q,workflowToken:B,abortSignal:D}){try{let I=PW0(A.command,A.arguments);if(!I.isValid)throw new Error(I.error);let E=await this.buildGitArgs(A.command,I.args??[],A.repository_url,Q),C=await this.createGitAskPass();try{let F=await this.runGitCommand(E,C,Q,B.gitlab_rails.token,D);return this.logger.debug(`Ran git command with result: ${F.substring(0,200)}${F.length>200?"...":""}`),{response:F,error:""}}finally{await this.removeGitAskPass(C)}}catch(I){return this.logger.error("Git command execution error",I),{response:"",error:`${I instanceof Error?I.message:I}`}}}}Tx=w1([SW0.Injectable(oB,[f1,A8,QI])],Tx);var dEA=dA(u1(),1);class jx{#A;#Q;constructor(A,Q){this.#A=d1(A,"[RunShellCommandActionHandler]"),this.#Q=H3(this.#A,Q)}name="run_shell_command";formatInput(A){return{tool:"run_shell_command",command:A.command}}canHandle(A){return Boolean(A.runShellCommand)}async execute({runShellCommand:A},{workspaceFolderPath:Q,workflowId:B,abortSignal:D}){let{command:I}=A;this.#A.debug(`Running shell command: "${I}"`);let E=await this.#Q.runShellCommand(B,Q,I,!1,D);if(BEA(E))return{...E,response:""};if(E.exitCode===0)return this.#A.debug(`Shell command completed successfully with output: ${E.output}`),{response:E.output,error:""};let{output:C,exitCode:F}=E,J=`Process exited with code ${F}`;return this.#A.error(`${J}. Output: ${C}`),{error:J,response:C}}}jx=w1([dEA.Injectable(oB,[f1,dEA.collection(rT)])],jx);var Sx=dA(u1(),1);class Px{#A;#Q;constructor(A,Q){this.#A=d1(A,"[RunMcpToolActionHandler]"),this.#Q=Q}name="run_mcp_tool";canHandle(A){return Boolean(A.runMCPTool)}async execute({runMCPTool:A},{abortSignal:Q}){try{let{name:B,args:D}=A;return this.#A.debug(`Running MCP tool: "${B}" with args: "${D}"`),Q.throwIfAborted(),{response:await this.#Q.execute(B,D),error:""}}catch(B){return{error:`${B instanceof Error?B.message:B}`,response:""}}}}Px=w1([Sx.Service({dependencies:[f1,wY],lifetime:Sx.ServiceLifetime.Singleton}),Sx.Implements(oB)],Px);var cEA=dA(u1(),1);import{join as fg4}from"node:path";class yx{#A;#Q;#B;constructor(A,Q,B){this.#A=d1(A,"[WriteFileActionHandler]"),this.#Q=Q,this.#B=H3(this.#A,B)}name="create_file_with_contents";formatInput(A){return{tool:"create_file_with_contents",filepath:A.file_path,content:A.contents}}canHandle(A){return Boolean(A.runWriteFile)}async execute({runWriteFile:A},{workspaceFolderPath:Q,fileStateTracker:B,abortSignal:D}){let I=A.filepath,E=fg4(Q,I);try{let C=await this.#B.getText(E);B.assertFileNotModifiedSinceLastRead(Q,I,C)}catch(C){if(C instanceof Qf||C instanceof Bf)return this.#A.debug(`Can't write file: "${C.message}"`),{error:C.message,response:""};if(C instanceof BV);else this.#A.error(`Failed to verify if Duo has already read file before writing for: "${I}"`,C)}try{return await nY(I,Q,this.#B,this.#Q,this.#A),this.#A.debug(`Writing file "${I}"`),D.throwIfAborted(),await this.#B.writeFile(E,A.contents),await this.#D(B,E,I),{response:"File written successfully",error:""}}catch(C){let F=C instanceof Error?C.message:String(C);return this.#A.error(`Error writing file "${E}"`,C),{error:F,response:""}}}async#D(A,Q,B){try{let D=await this.#B.getText(Q);A.recordFileRead(Q,D)}catch(D){this.#A.warn(`Failed to update version cache after edit for "${B}"`,D)}}}yx=w1([cEA.Injectable(oB,[f1,V8,cEA.collection(j7)])],yx);import{fileURLToPath as xg4}from"url";var yW0=dA(u1(),1);class vx{#A;#Q;#B;#D;#I;#E;#C;#F;#J;#Y="websocket";constructor(A,Q,B,D,I){this.#D=A.get("telemetry.enabled")??!0,this.#C=Q,this.#E=d1(Q,"[Duo Workflow Runner]"),this.#F=B,this.#J=D,this.#I=I;let E=A.get();this.#G(E),A.onConfigChange((C)=>this.#G(C))}#G(A){this.#A=A.workspaceFolders||[],this.#Q=A.projectPath||void 0,this.#B=this.#Q?void 0:A.duo?.agentPlatform?.defaultNamespace;let Q=A.telemetry?.enabled;if(typeof Q!=="undefined"&&this.#D!==Q)this.#D=Q;this.#Y=this.#U(A)}#U(A){let B=A.duo?.agentPlatform?.connectionType?.toLowerCase();if(B&&xPA.includes(B))return B;return"websocket"}getProjectPath(){return this.#Q||""}getNamespacePath(){return this.#B||""}async preCreateWorkflow(A,Q,B,D,I,E){if(!this.#A||this.#A.length===0)throw new Error("No workspace folders");this.#C.debug("Optimistically pre-creating workflow...");let C=await this.#z(A,Q,B,D,I,E);return this.#C.debug(`Workflow "${C}" + auth token pre-created, ready for the user to submit their prompt.`),C}async createWorkflow(A,Q,B,D,I,E){let C=I?.projectPath||this.#Q,F=I?.namespaceId||this.#B;return this.#F.createWorkflow(A,{project_id:C,namespace_id:F},Q,B,D?su(D):void 0,E)}async*runWorkflow(A){let Q=this.#A?.[0];if(!Q)throw new Error("No workspace folders");let B=xg4(Q.uri);if(this.#A&&this.#A.length>1)this.#E.info(`More than one workspace folder detected. Using workspace folder ${B}`);let{goal:D,existingWorkflowId:I,preCreatedWorkflowId:E,type:C="software_development",workflowDefinition:F,aiCatalogItemVersionId:J,metadata:Y,additionalOptions:G}=A,X=I||E;if(!X)X=await this.#z(D,C,F,J,Y,G);let z=this.#I.getExecutorForWorkflow(X),U={...A,workspaceFolderPath:B,workflowId:X,connectionType:this.#Y};try{this.#I.clearExecutorDisposal(X),yield*z.runWorkflow(U)}finally{this.#I.setupExecutorDisposal(X)}}stopWorkflow(A){let Q=this.#I.getExecutorForWorkflow(A);if(Q)Q.stopWorkflow()}async getGraphqlData(A){return this.#F.getGraphqlData(A)}async updateStatus(A){return this.#F.updateStatus(A)}async sendEvent(A,Q,B){return this.#F.sendEvent(A,Q,B)}async#z(A,Q,B,D,I,E){let C=I?.projectPath||this.#Q,F=I?.namespaceId||this.#B,J=this.#J.getTokenFromCache({workflowType:Q}),Y=[this.#F.createWorkflow(A,{project_id:C,namespace_id:F},Q,B,D?su(D):void 0,E)];if(!J)Y.push(this.#F.getWorkflowToken(Q));let[G,X]=await Promise.all(Y);if(X)this.#J.cacheToken(G,Q,X);return G}}vx=w1([yW0.Injectable(yN,[A8,f1,EM,FM,fo])],vx);var vW0=dA(u1(),1);import{spawn as hg4}from"node:child_process";class kx{#A;constructor(A){this.#A=d1(A,"[RunCommandAsProcess]")}priority=1;#Q(A=process.env){let Q=["CI_JOB_TOKEN","GITLAB_OAUTH_TOKEN","DUO_WORKFLOW_SERVICE_TOKEN"],B={};for(let[D,I]of Object.entries(A))if(!Q.includes(D))B[D]=I;return B}async runCommand(A,Q,B,D,I,E=new AbortController().signal){return this.#A.debug(`Running command: ${B} ${I.join(" ")} in ${Q} for workflowId: ${A}`),this.#B(B,I,{cwd:Q,signal:E,shell:!1})}async runShellCommand(A,Q,B,D,I=new AbortController().signal){return this.#A.debug(`Running shell command: ${B} in ${Q} for workflowId: ${A}`),this.#B(B,[],{cwd:Q,signal:I,shell:!0})}#B(A,Q,B){let{signal:D}=B;return new Promise((I)=>{let E=hg4(A,Q,{...B,env:this.#Q()}),C="";E.stdout?.on("data",(F)=>{C+=F}),E.stderr?.on("data",(F)=>{C+=F}),E.on("error",(F)=>{this.#A.error(`Command execution error: ${F.message}`),I({error:F.message})}),E.on("close",(F)=>{this.#A.debug(`Command exited with code ${F}. Output: ${C}`),I({output:C,exitCode:F})}),D?.addEventListener("abort",()=>{if(Ng(D.reason))this.#A.info("Command aborted due to signal"),I({error:"Operation was aborted because the workflow was cancelled or stopped"})})})}}kx=w1([vW0.Injectable(rT,[f1])],kx);var kW0=dA(u1(),1);class Pr{#A;#Q;#B;#D=new tu;constructor(A,Q,B){this.#A=A,this.#Q=Q,this.#B=d1(B,"[DuoWorkflowInstanceTracker]")}trackEvent(A,Q){if(!this.isEnabled())return;this.#I(A,Q).catch((B)=>this.#B.error("Could not track duo workflow telemetry event",B))}async#I(A,Q){try{this.#B.debug(`Tracking workflow event: ${A} for workflow ${Q.workflow_id}`),await this.#A.fetchFromApi({type:"rest",method:"POST",path:"/api/v4/usage_data/track_event",body:{event:A,additional_properties:{...Q},send_to_snowplow:!0}}),this.#D.success()}catch(B){this.#B.error(`Telemetry request for "${A}" failed`,B),this.#D.error()}}isEnabled(){if(this.#D.isOpen())return!1;let A=this.#Q.get("telemetry.enabled");return Boolean(A)}}Pr=w1([kW0.Injectable(rb,[b4,A8,f1])],Pr);var gW0=dA(u1(),1);class Sr{logger;constructor(A,Q){this.logger=d1(A,Q)}detectOSInfo(){try{let{platform:A,arch:Q}=process;if(!A||!Q)return this.logger.debug("Platform or architecture not available"),null;return{platform:A,architecture:Q}}catch(A){return this.logger.warn("Error detecting OS information",A),null}}buildOSInfoContent(A){let Q=[];return Q.push(`Platform: ${this.formatPlatform(A.platform)}`),Q.push(`Architecture: ${A.architecture}`),Q.join(" • ")}formatPlatform(A){return{win32:"Windows",darwin:"macOS",linux:"Linux",freebsd:"FreeBSD",openbsd:"OpenBSD",netbsd:"NetBSD",aix:"AIX",sunos:"SunOS",android:"Android"}[A]||A}}class wj extends Sr{constructor(A){super(A,"[OSContextProvider]")}async getItems(){try{let A=this.detectOSInfo();if(!A)return this.logger.info("No OS information detected"),[];return[{category:"agent_user_environment",content:JSON.stringify(A),id:"agent_user_environment_os_info",metadata:{title:"Operating System",enabled:!0,subType:"os",icon:"monitor",secondaryText:this.buildOSInfoContent(A),subTypeLabel:"System Information"}}]}catch(A){return this.logger.warn("Could not detect OS information",A),[]}}}wj=w1([gW0.Injectable(iF,[f1])],wj);var lEA=dA(u1(),1);import{join as fW0}from"path";var bx=dA(u1(),1);import{join as pEA,relative as bW0,resolve as ZdA,dirname as mg4}from"node:path";var KdA=bx.createInterfaceId("AgentsMdResolver");class gx{#A;#Q;#B;#D;constructor(A,Q,B,D){this.#A=d1(A,"[AgentsMdResolver]"),this.#Q=Q,this.#B=H3(new TS,B),this.#D=D}async resolveAgentsMdContextItem(){let A=this.#D.get(),{cwd:Q}=A,B=A.workspaceFolders||[],D=process.env.GLAB_CONFIG_DIR||ez(),I=await this.#Y(B),E=[];if(D){let J=await this.#F(D,I);if(J)E.push(J)}let C=await this.#C(Q,B,I);E.push(...C);let F=I.map((J)=>({uriPath:J.uriPath,displayPath:J.workspaceRelativePath})).filter((J)=>!E.some((Y)=>Y.uriPath===J.uriPath));return this.#J(E,F)}async#I(A,Q){try{let B=await this.#B.getText(A);this.#A.info(`AGENTS.md loaded from "${A}"`);let D=aT(A).toString(),E=Q.find((C)=>C.uriPath===D)?.workspaceRelativePath||A;return{uriPath:D,displayPath:E,content:B}}catch(B){if(B instanceof BV)this.#A.debug(`AGENTS.md file not found at "${A}".`);else this.#A.warn(`Could not read AGENTS.md rule file from "${A}"`,B);return null}}async#E(A,Q,B){let D=ZdA(A),I=ZdA(Q),E=B.map((F)=>({...F,resolvedPath:ZdA(F.absolutePath)})).filter(({resolvedPath:F})=>{let J=mg4(F);if(bW0(I,J).startsWith(".."))return!1;let X=bW0(J,D);if(X.startsWith("..")&&X!=="")return!1;return!0}).sort((F,J)=>{let Y=F.resolvedPath.split("/").length;return J.resolvedPath.split("/").length-Y});if(E.length===0)return null;let C=E[0];return this.#I(C.absolutePath,B)}async#C(A,Q,B){if(!A){let F=Q.map((Y)=>{let G=pEA(PM(Y.uri).fsPath,"AGENTS.md");return this.#I(G,B)});return(await Promise.all(F)).filter((Y)=>Y!==null)}let D=Q.find((F)=>F.uri===A);if(D){let F=pEA(PM(D.uri).fsPath,"AGENTS.md"),J=await this.#I(F,B);return J?[J]:[]}let I=fw0(A,Q);if(!I||!I.length)return this.#A.error(`"cwd" appears to not be within a workspaceFolder. This should not happen! ${JSON.stringify({cwd:A,workspaceFolders:Q})}`),[];let E=Q.map(async(F)=>{return this.#E(PM(A).fsPath,PM(F.uri).fsPath,B)});return(await Promise.all(E)).filter((F)=>F!==null)}async#F(A,Q){let B=pEA(A,"AGENTS.md");return this.#I(B,Q)}#J(A,Q){if(A.length===0&&Q.length===0)return null;let B="",D=A.filter((I)=>I.content.trim().length).map((I)=>{return`<instructions from="${I.displayPath}">${I.content}</instructions>`}).join(`
1620
+ `).filter((J)=>J.trim()!=="")}catch(I){throw this.logger.error("Command execution error",I),I}finally{await this.removeGitAskPass(D)}}}xEA=w1([CW0.Injectable(xM1,[f1,A8,EZ,QI])],xEA);var VW0=dA(HW0(),1),$W0=dA(u1(),1);import{readFileSync as Ng4}from"fs";import{homedir as Mg4}from"os";import{join as qg4}from"path";class mEA{#A;constructor(A){this.#A=d1(A,"[NodeGitConfigCommand]")}async getRemoteUrl(A,Q,B){try{let D=this.#Q(B);if(!D)return B;let I=this.#B(D);if(I!==D){if(this.#A.debug(`Resolved SSH hostname: '${D}' -> '${I}'`),B.startsWith("git@"))return B.replace(`git@${D}:`,`git@${I}:`);try{let E=new URL(B);return E.hostname=I,E.toString()}catch{return B.replace(D,I)}}return B}catch{return B}}#Q(A){try{let Q=A.match(/^git@([^:]+):/);if(Q)return Q[1]??null;return new URL(A).hostname}catch{return null}}#B(A){try{let Q=qg4(Mg4(),".ssh","config"),B=Ng4(Q,"utf8"),I=VW0.default.parse(B).compute(A);if(I.HostName)return I.HostName;return A}catch{return A}}}mEA=w1([$W0.Injectable(uM1,[f1])],mEA);var yg4=NW0(),wdA=TW0();var vg4=1000,jW0=process.platform==="win32"?30000:1e6;function kg4(A){return wdA(A).map((B)=>{if(typeof B==="string")return B;if(typeof B==="object"&&B!==null){if("pattern"in B)return B.pattern;if("op"in B)return B.op}return String(B)})}function gg4(A){return A.length<=vg4}function bg4(A,Q){let B=Buffer.from(A).length,D=Buffer.from(Q).length;return B+D<jW0}function PW0(A,Q=""){if(!bg4(A,Q))return{isValid:!1,error:`Command is too long: bytes exceed ${jW0} byte limit on ${process.platform}`};let B;try{B=kg4(Q)}catch(D){return{isValid:!1,error:D instanceof Error?D.message:"Failed to parse arguments"}}for(let D of B)if(!gg4(D))return{isValid:!1,error:`Argument too long: ${D.substring(0,50)}...`};return{isValid:!0,args:B}}class Tx extends Lx{constructor(A,Q,B){super(d1(A,"[RunGitCommandActionHandler]"),Q,B)}name="run_git_command";canHandle(A){return Boolean(A.runGitCommand)}async execute({runGitCommand:A},{workspaceFolderPath:Q,workflowToken:B,abortSignal:D}){try{let I=PW0(A.command,A.arguments);if(!I.isValid)throw new Error(I.error);let E=await this.buildGitArgs(A.command,I.args??[],A.repository_url,Q),C=await this.createGitAskPass();try{let F=await this.runGitCommand(E,C,Q,B.gitlab_rails.token,D);return this.logger.debug(`Ran git command with result: ${F.substring(0,200)}${F.length>200?"...":""}`),{response:F,error:""}}finally{await this.removeGitAskPass(C)}}catch(I){return this.logger.error("Git command execution error",I),{response:"",error:`${I instanceof Error?I.message:I}`}}}}Tx=w1([SW0.Injectable(oB,[f1,A8,QI])],Tx);var dEA=dA(u1(),1);class jx{#A;#Q;constructor(A,Q){this.#A=d1(A,"[RunShellCommandActionHandler]"),this.#Q=H3(this.#A,Q)}name="run_shell_command";formatInput(A){return{tool:"run_shell_command",command:A.command}}canHandle(A){return Boolean(A.runShellCommand)}async execute({runShellCommand:A},{workspaceFolderPath:Q,workflowId:B,abortSignal:D}){let{command:I}=A;this.#A.debug(`Running shell command: "${I}"`);let E=await this.#Q.runShellCommand(B,Q,I,!1,D);if(BEA(E))return{...E,response:""};if(E.exitCode===0)return this.#A.debug(`Shell command completed successfully with output: ${E.output}`),{response:E.output,error:""};let{output:C,exitCode:F}=E,J=`Process exited with code ${F}`;return this.#A.error(`${J}. Output: ${C}`),{error:J,response:C}}}jx=w1([dEA.Injectable(oB,[f1,dEA.collection(rT)])],jx);var Sx=dA(u1(),1);class Px{#A;#Q;constructor(A,Q){this.#A=d1(A,"[RunMcpToolActionHandler]"),this.#Q=Q}name="run_mcp_tool";canHandle(A){return Boolean(A.runMCPTool)}async execute({runMCPTool:A},{abortSignal:Q}){try{let{name:B,args:D}=A;return this.#A.debug(`Running MCP tool: "${B}" with args: "${D}"`),Q.throwIfAborted(),{response:await this.#Q.execute(B,D),error:""}}catch(B){return{error:`${B instanceof Error?B.message:B}`,response:""}}}}Px=w1([Sx.Service({dependencies:[f1,wY],lifetime:Sx.ServiceLifetime.Singleton}),Sx.Implements(oB)],Px);var cEA=dA(u1(),1);import{join as fg4}from"node:path";class yx{#A;#Q;#B;constructor(A,Q,B){this.#A=d1(A,"[WriteFileActionHandler]"),this.#Q=Q,this.#B=H3(this.#A,B)}name="create_file_with_contents";formatInput(A){return{tool:"create_file_with_contents",filepath:A.file_path,content:A.contents}}canHandle(A){return Boolean(A.runWriteFile)}async execute({runWriteFile:A},{workspaceFolderPath:Q,fileStateTracker:B,abortSignal:D}){let I=A.filepath,E=fg4(Q,I);try{let C=await this.#B.getText(E);B.assertFileNotModifiedSinceLastRead(Q,I,C)}catch(C){if(C instanceof Qf||C instanceof Bf)return this.#A.debug(`Can't write file: "${C.message}"`),{error:C.message,response:""};if(C instanceof BV);else this.#A.error(`Failed to verify if Duo has already read file before writing for: "${I}"`,C)}try{return await nY(I,Q,this.#B,this.#Q,this.#A),this.#A.debug(`Writing file "${I}"`),D.throwIfAborted(),await this.#B.writeFile(E,A.contents),await this.#D(B,E,I),{response:"File written successfully",error:""}}catch(C){let F=C instanceof Error?C.message:String(C);return this.#A.error(`Error writing file "${E}"`,C),{error:F,response:""}}}async#D(A,Q,B){try{let D=await this.#B.getText(Q);A.recordFileRead(Q,D)}catch(D){this.#A.warn(`Failed to update version cache after edit for "${B}"`,D)}}}yx=w1([cEA.Injectable(oB,[f1,V8,cEA.collection(j7)])],yx);import{fileURLToPath as xg4}from"url";var yW0=dA(u1(),1);class vx{#A;#Q;#B;#D;#I;#E;#C;#F;#J;#Y="websocket";constructor(A,Q,B,D,I){this.#D=A.get("telemetry.enabled")??!0,this.#C=Q,this.#E=d1(Q,"[Duo Workflow Runner]"),this.#F=B,this.#J=D,this.#I=I;let E=A.get();this.#G(E),A.onConfigChange((C)=>this.#G(C))}#G(A){this.#A=A.workspaceFolders||[],this.#Q=A.projectPath||void 0,this.#B=A.duo?.agentPlatform?.defaultNamespace;let Q=A.telemetry?.enabled;if(typeof Q!=="undefined"&&this.#D!==Q)this.#D=Q;this.#Y=this.#U(A)}#U(A){let B=A.duo?.agentPlatform?.connectionType?.toLowerCase();if(B&&xPA.includes(B))return B;return"websocket"}getProjectPath(){return this.#Q||""}getNamespacePath(){return this.#B||""}async preCreateWorkflow(A,Q,B,D,I,E){if(!this.#A||this.#A.length===0)throw new Error("No workspace folders");this.#C.debug("Optimistically pre-creating workflow...");let C=await this.#z(A,Q,B,D,I,E);return this.#C.debug(`Workflow "${C}" + auth token pre-created, ready for the user to submit their prompt.`),C}async createWorkflow(A,Q,B,D,I,E){let C=I?.projectPath||this.#Q,F=C?void 0:this.#B;return this.#F.createWorkflow(A,{project_id:C,namespace_id:F},Q,B,D?su(D):void 0,E)}async*runWorkflow(A){let Q=this.#A?.[0];if(!Q)throw new Error("No workspace folders");let B=xg4(Q.uri);if(this.#A&&this.#A.length>1)this.#E.info(`More than one workspace folder detected. Using workspace folder ${B}`);let{goal:D,existingWorkflowId:I,preCreatedWorkflowId:E,type:C="software_development",workflowDefinition:F,aiCatalogItemVersionId:J,metadata:Y,additionalOptions:G}=A,X=I||E;if(!X)X=await this.#z(D,C,F,J,Y,G);let z=this.#I.getExecutorForWorkflow(X),U={...A,workspaceFolderPath:B,workflowId:X,connectionType:this.#Y};try{this.#I.clearExecutorDisposal(X),yield*z.runWorkflow(U)}finally{this.#I.setupExecutorDisposal(X)}}stopWorkflow(A){let Q=this.#I.getExecutorForWorkflow(A);if(Q)Q.stopWorkflow()}async getGraphqlData(A){return this.#F.getGraphqlData(A)}async updateStatus(A){return this.#F.updateStatus(A)}async sendEvent(A,Q,B){return this.#F.sendEvent(A,Q,B)}async#z(A,Q,B,D,I,E){let C=this.#J.getTokenFromCache({workflowType:Q}),F=I?.projectPath||this.#Q,J=F?void 0:this.#B,Y=[this.#F.createWorkflow(A,{project_id:F,namespace_id:J},Q,B,D?su(D):void 0,E)];if(!C)Y.push(this.#F.getWorkflowToken(Q));let[G,X]=await Promise.all(Y);if(X)this.#J.cacheToken(G,Q,X);return G}}vx=w1([yW0.Injectable(yN,[A8,f1,EM,FM,fo])],vx);var vW0=dA(u1(),1);import{spawn as hg4}from"node:child_process";class kx{#A;constructor(A){this.#A=d1(A,"[RunCommandAsProcess]")}priority=1;#Q(A=process.env){let Q=["CI_JOB_TOKEN","GITLAB_OAUTH_TOKEN","DUO_WORKFLOW_SERVICE_TOKEN"],B={};for(let[D,I]of Object.entries(A))if(!Q.includes(D))B[D]=I;return B}async runCommand(A,Q,B,D,I,E=new AbortController().signal){return this.#A.debug(`Running command: ${B} ${I.join(" ")} in ${Q} for workflowId: ${A}`),this.#B(B,I,{cwd:Q,signal:E,shell:!1})}async runShellCommand(A,Q,B,D,I=new AbortController().signal){return this.#A.debug(`Running shell command: ${B} in ${Q} for workflowId: ${A}`),this.#B(B,[],{cwd:Q,signal:I,shell:!0})}#B(A,Q,B){let{signal:D}=B;return new Promise((I)=>{let E=hg4(A,Q,{...B,env:this.#Q()}),C="";E.stdout?.on("data",(F)=>{C+=F}),E.stderr?.on("data",(F)=>{C+=F}),E.on("error",(F)=>{this.#A.error(`Command execution error: ${F.message}`),I({error:F.message})}),E.on("close",(F)=>{this.#A.debug(`Command exited with code ${F}. Output: ${C}`),I({output:C,exitCode:F})}),D?.addEventListener("abort",()=>{if(Ng(D.reason))this.#A.info("Command aborted due to signal"),I({error:"Operation was aborted because the workflow was cancelled or stopped"})})})}}kx=w1([vW0.Injectable(rT,[f1])],kx);var kW0=dA(u1(),1);class Pr{#A;#Q;#B;#D=new tu;constructor(A,Q,B){this.#A=A,this.#Q=Q,this.#B=d1(B,"[DuoWorkflowInstanceTracker]")}trackEvent(A,Q){if(!this.isEnabled())return;this.#I(A,Q).catch((B)=>this.#B.error("Could not track duo workflow telemetry event",B))}async#I(A,Q){try{this.#B.debug(`Tracking workflow event: ${A} for workflow ${Q.workflow_id}`),await this.#A.fetchFromApi({type:"rest",method:"POST",path:"/api/v4/usage_data/track_event",body:{event:A,additional_properties:{...Q},send_to_snowplow:!0}}),this.#D.success()}catch(B){this.#B.error(`Telemetry request for "${A}" failed`,B),this.#D.error()}}isEnabled(){if(this.#D.isOpen())return!1;let A=this.#Q.get("telemetry.enabled");return Boolean(A)}}Pr=w1([kW0.Injectable(rb,[b4,A8,f1])],Pr);var gW0=dA(u1(),1);class Sr{logger;constructor(A,Q){this.logger=d1(A,Q)}detectOSInfo(){try{let{platform:A,arch:Q}=process;if(!A||!Q)return this.logger.debug("Platform or architecture not available"),null;return{platform:A,architecture:Q}}catch(A){return this.logger.warn("Error detecting OS information",A),null}}buildOSInfoContent(A){let Q=[];return Q.push(`Platform: ${this.formatPlatform(A.platform)}`),Q.push(`Architecture: ${A.architecture}`),Q.join(" • ")}formatPlatform(A){return{win32:"Windows",darwin:"macOS",linux:"Linux",freebsd:"FreeBSD",openbsd:"OpenBSD",netbsd:"NetBSD",aix:"AIX",sunos:"SunOS",android:"Android"}[A]||A}}class wj extends Sr{constructor(A){super(A,"[OSContextProvider]")}async getItems(){try{let A=this.detectOSInfo();if(!A)return this.logger.info("No OS information detected"),[];return[{category:"agent_user_environment",content:JSON.stringify(A),id:"agent_user_environment_os_info",metadata:{title:"Operating System",enabled:!0,subType:"os",icon:"monitor",secondaryText:this.buildOSInfoContent(A),subTypeLabel:"System Information"}}]}catch(A){return this.logger.warn("Could not detect OS information",A),[]}}}wj=w1([gW0.Injectable(iF,[f1])],wj);var lEA=dA(u1(),1);import{join as fW0}from"path";var bx=dA(u1(),1);import{join as pEA,relative as bW0,resolve as ZdA,dirname as mg4}from"node:path";var KdA=bx.createInterfaceId("AgentsMdResolver");class gx{#A;#Q;#B;#D;constructor(A,Q,B,D){this.#A=d1(A,"[AgentsMdResolver]"),this.#Q=Q,this.#B=H3(new TS,B),this.#D=D}async resolveAgentsMdContextItem(){let A=this.#D.get(),{cwd:Q}=A,B=A.workspaceFolders||[],D=process.env.GLAB_CONFIG_DIR||ez(),I=await this.#Y(B),E=[];if(D){let J=await this.#F(D,I);if(J)E.push(J)}let C=await this.#C(Q,B,I);E.push(...C);let F=I.map((J)=>({uriPath:J.uriPath,displayPath:J.workspaceRelativePath})).filter((J)=>!E.some((Y)=>Y.uriPath===J.uriPath));return this.#J(E,F)}async#I(A,Q){try{let B=await this.#B.getText(A);this.#A.info(`AGENTS.md loaded from "${A}"`);let D=aT(A).toString(),E=Q.find((C)=>C.uriPath===D)?.workspaceRelativePath||A;return{uriPath:D,displayPath:E,content:B}}catch(B){if(B instanceof BV)this.#A.debug(`AGENTS.md file not found at "${A}".`);else this.#A.warn(`Could not read AGENTS.md rule file from "${A}"`,B);return null}}async#E(A,Q,B){let D=ZdA(A),I=ZdA(Q),E=B.map((F)=>({...F,resolvedPath:ZdA(F.absolutePath)})).filter(({resolvedPath:F})=>{let J=mg4(F);if(bW0(I,J).startsWith(".."))return!1;let X=bW0(J,D);if(X.startsWith("..")&&X!=="")return!1;return!0}).sort((F,J)=>{let Y=F.resolvedPath.split("/").length;return J.resolvedPath.split("/").length-Y});if(E.length===0)return null;let C=E[0];return this.#I(C.absolutePath,B)}async#C(A,Q,B){if(!A){let F=Q.map((Y)=>{let G=pEA(PM(Y.uri).fsPath,"AGENTS.md");return this.#I(G,B)});return(await Promise.all(F)).filter((Y)=>Y!==null)}let D=Q.find((F)=>F.uri===A);if(D){let F=pEA(PM(D.uri).fsPath,"AGENTS.md"),J=await this.#I(F,B);return J?[J]:[]}let I=fw0(A,Q);if(!I||!I.length)return this.#A.error(`"cwd" appears to not be within a workspaceFolder. This should not happen! ${JSON.stringify({cwd:A,workspaceFolders:Q})}`),[];let E=Q.map(async(F)=>{return this.#E(PM(A).fsPath,PM(F.uri).fsPath,B)});return(await Promise.all(E)).filter((F)=>F!==null)}async#F(A,Q){let B=pEA(A,"AGENTS.md");return this.#I(B,Q)}#J(A,Q){if(A.length===0&&Q.length===0)return null;let B="",D=A.filter((I)=>I.content.trim().length).map((I)=>{return`<instructions from="${I.displayPath}">${I.content}</instructions>`}).join(`
1621
1621
  `).trim();if(D.length)B+=`The user wants you to adhere to these AGENTS.md rules:
1622
1622
  ${D}`;if(Q.length){let I=Q.map((E)=>`<file>${E.displayPath}</file>`).join(`
1623
1623
  `).trim();B+=`CRITICAL INSTRUCTION: Before editing any file, you MUST follow these steps:
@@ -2003,5 +2003,5 @@ Get help with code, planning, security, project management, and more. Duo CLI ca
2003
2003
  ${NYA(this.#I,I)}`),this.#D=d1(Q,"[TUIController]");try{let{backend:E,workspaceFolder:C,username:F,gitlabRemote:J}=await B.initialize();if(this.#Q=E,J)this.#B.setState({...this.#B.getState(),gitlabRemoteInfo:{status:"connected",gitlabPath:J.namespaceWithPath,gitlabHost:J.host}});else this.#B.setState({...this.#B.getState(),gitlabRemoteInfo:{status:"error",errorMessage:`Could not find GitLab remote info in workspace ${C}. Some features might not be available.`}});rE(this.#K(A.getRequiredService(zw))),this.#R(F),await Promise.all([this.#V(C,D),this.#$(Q)])}catch(E){this.#E?.handleError("Duo CLI initialization failed",E),this.#B.setState({...this.#B.getState(),criticalErrorMessage:E instanceof Error?E.message:"Unknown initialization error"}),await iq(1)}}async#K(A){try{await A.reloadAllServers(this.#I.cwd),await A.waitForAllServersSettled(30000)}catch(Q){this.#D?.warn(`Failed to preload MCP servers during controller initialization: ${Q}`)}}async#V(A,Q){this.#Z=await Q.getRepositoriesForWorkspace(A)}async#$(A){let Q=process.env.GLAB_CONFIG_DIR||ez();if(!Q){this.#D?.warn("Unable to determine baseDir for prompt history storage, this will be skipped!");return}let B=cMQ(Q,"duo-cli-prompt-history.json"),D=new aW(A,B);try{this.#w=new FrA(A),await this.#w?.load(D,this.#I.cwd),this.#D?.debug("Loaded prompt history")}catch(I){this.#D?.error("Failed to load prompt history",I)}}getCallbacks(){return{onKeyPress:(A,Q)=>{if(Q.escape&&this.#B.getState().isLoading&&this.#z){this.#D?.info("Cancelling stream due to ESC key press"),this.#z.abort();return}let B=this.#B.getState().input.inputType;if(B===Z7.TEXT)this.#Y.handleKeyPress(A,Q);else if(B===Z7.CHOICE)this.#G.handleKeyPress(A,Q);else if(B===Z7.PROMPT_HISTORY_SEARCH)this.#U.handleKeyPress(A,Q)},onSubmit:(A)=>{this.#Y.onSubmit(A)},onExit:()=>this.#P(),toggleExpanded:()=>{let A=this.#B.getState();this.#B.setState({...A,expanded:!A.expanded})},onFileSearch:async(A)=>{this.#D?.info(`onFileSearch callback triggered: ${A}`);let Q=UM1(A);return this.#D?.info(`Translated search pattern to glob pattern: ${Q}`),(await Promise.all(this.#Z.map(async(D)=>{let I=await D.getFiles(Q),E=ZoB(this.#I.cwd,D.fsPath);return I.map((C)=>cMQ(E,C))}))).flat()},onHistoryPrevious:()=>{if(!this.#w)return;let A=this.#B.getState(),Q=this.#w?.handlePrevious(A.input);if(Q)this.#B.setState({...A,input:Q})},onHistoryNext:()=>{if(!this.#w)return;let A=this.#B.getState(),Q=this.#w?.handleNext(A.input);if(Q)this.#B.setState({...A,input:Q})},onOpenHistorySearch:()=>this.#v(),onCancelHistorySearch:()=>this.#M(),onHistorySearchQueryChange:(A)=>this.#y(A),onSelectHistoryItem:(A)=>this.#L(A),onDeleteHistoryItem:(A)=>this.#k(A)}}#H(){let A={type:"message",id:"welcome",role:"assistant",content:DrA(),timestamp:Date.now()};this.#B.setState({elements:[A],isLoading:!1,input:pW,expanded:!1,cwd:this.#I.cwd,gitlabRemoteInfo:{status:"not-checked"}})}#R(A){let Q=DrA(),B=this.#B.getState();this.#B.setState({...B,username:A,elements:B.elements.map((D)=>{return D.id==="welcome"?{...D,content:Q}:D})})}async#T(A){let Q=this.#B.getState();if(Q.isLoading)return;this.#B.setState({...Q,input:pW}),await this.#j(A)}async#q(A){if(this.#B.getState().isLoading||!A.prompt.trim())return;await this.#w?.add(A.prompt),this.#Y.clear();let B={id:Date.now().toString(),type:"message",role:"user",content:A.prompt,timestamp:Date.now()};this.#N(B),await this.#j(A)}async#j(A){if(this.#B.setState({...this.#B.getState(),input:pW,isLoading:!0}),await this.#X,!this.#Q)throw new Error("Backend not initialized");this.#z=new AbortController;let Q=await this.#S(A);try{let B;for await(let D of this.#Q.sendMessageStream(Q,this.#z.signal))B=D,this.#O(D);if(B?.type==="TOOL_AWAITING_APPROVAL"){let D={type:"SEND_TOOL_APPROVAL",scope:"session",toolId:B.toolId,toolName:B.toolName};this.#G.setChoice([{label:"Approve",value:{...D,approved:!0}},{label:"Reject",value:{...D,approved:!1}}])}}catch(B){this.#E?.handleError("Error in message streaming",B),this.#O({type:"ERROR",message:"Sorry, there was an error processing your message. Please try again.",timestamp:Date.now()})}finally{this.#F=void 0,this.#J.clear(),this.#z=void 0,this.#B.setState({...this.#B.getState(),isLoading:!1})}}async#S(A){if(A.type!=="SEND_PROMPT")return A;let Q=A;try{let B=await this.#C?.retrieveContextItemsWithContent({mode:"agentic"});Q.aiContextItems=[...Q.aiContextItems||[],...B||[]],await this.#C?.clearSelectedContextItems()}catch(B){this.#D?.error("Failed to get AIContextItems for message. Context items will be omitted.",B)}return Q}#N(A){let Q=this.#B.getState();this.#B.setState({...Q,elements:[...Q.elements,A]})}#O(A){if(!this.#B)throw new Error("Store not initialized");let Q=this.#B.getState();switch(A.type){case"TEXT_CHUNK":{if(!this.#F||this.#F.id!==A.messageId)this.#F={id:A.messageId,type:"message",role:"assistant",content:A.content,timestamp:A.timestamp},this.#N(this.#F);else{this.#F.content+=A.content;let B=Q.elements.map((D)=>D.type==="message"&&D.id===A.messageId&&this.#F?this.#F:D);this.#B.setState({...Q,elements:B})}break}case"TOOL_START":{let B={id:A.toolId,type:"tool",name:A.name,input:A.input,state:{type:"loading"},timestamp:A.timestamp};this.#J.set(A.toolId,B),this.#_(B);break}case"TOOL_AWAITING_APPROVAL":{let B={id:A.toolId,type:"tool",name:A.toolName,input:A.input,state:{type:"approval_request",content:""},timestamp:A.timestamp};this.#J.set(A.toolId,B),this.#_(B);break}case"TOOL_COMPLETE":{let B=this.#J.get(A.toolId);if(B){let D={...B,state:A.error?{type:"error",error:A.error}:{type:"success",output:A.result}};this.#_(D),this.#J.delete(A.toolId)}break}case"ERROR":{this.#D?.error("Agent error:",A.message);let B={id:`error-${Date.now()}`,type:"error",error:`${A.message}`,timestamp:A.timestamp};this.#N(B);break}default:this.#D?.warn("Unknown agent event type:",A);break}}#_(A){let Q=this.#B.getState(),B=Q.elements.findIndex((I)=>I.type==="tool"&&I.id===A.id);if(B<0){this.#N(A);return}let D=[...Q.elements];D[B]=A,this.#B.setState({...Q,elements:D})}#P(){rE(iq(0))}#v(){if(!this.#w)return;let A=this.#w.handleOpenSearch();this.#U.setState(A)}#M(){if(!this.#w)return;let A=this.#B.getState(),Q=this.#w.handleCancelSearch();this.#B.setState({...A,input:Q})}#y(A){if(!this.#w)return;let Q=this.#w.search(A,10);this.#U.updateSearchResults(A,Q)}#L(A){if(!this.#w)return;let Q=this.#B.getState(),B=this.#w.handleSelectItem(A);this.#B.setState({...Q,input:B})}async#k(A){if(!this.#w)return;let Q=this.#B.getState();if(await this.#w.remove(A)===-1)return;if(Q.input.inputType===Z7.PROMPT_HISTORY_SEARCH){let D=this.#w.search(Q.input.searchQuery,10);this.#U.updateAfterDelete(D)}}}var KoB=({runConfig:A})=>{let[Q,B]=tt.useState(void 0),[D]=tt.useState(()=>new JrA(B,A));if(tt.useEffect(()=>{rE(D.initialize())},[D]),!Q)return U1(E0,{children:"Initializing..."});return U1(A$A,{state:Q,callbacks:D.getCallbacks()})},pMQ=(A,Q)=>{tc(U1(KoB,{runConfig:A}),Q)};class YrA{#A;#Q;#B;#D=null;constructor(A){this.#B=A}async initialize(){let A=await WYA({logDestination:"stdout"},this.#B),Q=A.getRequiredService(f1),B=A.getRequiredService(VU),D=A.getRequiredService(QI);Q.debug(`CLI run config:
2004
2004
  ${NYA(this.#B,D)}`),this.#Q=d1(Q,"[RunController]");try{let I=A.getRequiredService(dV),{backend:E}=await I.initialize();this.#A=E}catch(I){B.handleError("Duo CLI initialization failed",I),await iq(1)}}async execute(){if(!this.#A||this.#B.command?.name!=="run")throw new Error("Controller not initialized. Call initialize() first.");let{goal:A}=this.#B.command;this.#Q?.info(`Executing workflow: ${JSON.stringify({goal:A},null,4)}`);let Q={id:Date.now().toString(),type:"message",role:"user",content:A,timestamp:Date.now()};try{let B;for await(let D of this.#A.sendMessageStream({type:"SEND_PROMPT",prompt:Q.content}))this.#I(D),B=D;if(this.#D)this.#Q?.info(JSON.stringify(this.#D,null,2));await iq(B?.type==="ERROR"?1:0)}catch(B){throw this.#Q?.error("Workflow failed:",B instanceof Error?B.message:String(B)),B}}#I(A){switch(A.type){case"TEXT_CHUNK":{if(!this.#D||this.#D.id!==A.messageId){if(this.#D)this.#Q?.info(JSON.stringify(this.#D,null,4));this.#D={id:A.messageId,type:"message",role:"assistant",content:A.content,timestamp:A.timestamp}}else this.#D.content+=A.content;break}case"TOOL_START":{this.#Q?.info(`Tool started: ${A.name}`);break}case"TOOL_COMPLETE":{if(this.#Q?.info(`Tool completed: ${A.toolId}`),A.error)this.#Q?.error(`Tool error: ${A.error}`);break}case"TOOL_AWAITING_APPROVAL":break;case"ERROR":{this.#Q?.error(`Error: ${A.message}`);break}default:{let Q=A;this.#Q?.warn(`Unexpected event received: ${JSON.stringify(Q)}`);break}}}}var HoB=()=>{return"production"},GrA,MYA=async()=>{if(!GrA){let A=gM1(),Q=await bM1(),B=A9(),D=HoB();GrA={terminalName:A,isKittyProtocolSupported:Q,duoCliVersion:B,environment:D}}return GrA};import{statSync as VoB}from"node:fs";import{isAbsolute as $oB,normalize as WoB,resolve as NoB}from"node:path";function lMQ(A,Q=process.cwd()){let B;if($oB(A))B=WoB(A);else B=NoB(Q,A);return MoB(B),B}function MoB(A){try{if(!VoB(A).isDirectory())throw new e$(`Path "${A}" exists but is not a directory`)}catch(Q){if(Q instanceof Error&&Q.code==="ENOENT")throw new e$(`Directory "${A}" does not exist`);throw Q}}function iMQ(A){try{let Q=JSON.parse(A);return Array.isArray(Q)?Q.map((D)=>({category:D.Category||D.category,content:D.Content||D.content,metadata:D.metadata||{}})):[]}catch(Q){if(Q instanceof SyntaxError)throw new e$(`Invalid JSON format: ${Q.message}`);throw new e$(`AI Context Item schema error: ${Q}`)}}var qoB=p.object({gitlabBaseUrl:p.string().optional(),gitlabAuthToken:p.string().optional()}),aMQ="duo-cli-config";class nMQ{#A;#Q;#B;constructor(A,Q,B){this.#A=A,this.#B=B,this.#Q=Q}async saveConfig(A){try{let{configurationEntries:Q}=A,B={gitlabAuthToken:"",gitlabBaseUrl:""};for(let D of Q){let I=D.key;if(I in B)B[I]=D.value}return this.#A=B,await this.#Q.set(aMQ,B),q2()}catch(Q){return this.#B.error("Failed to save configuration:",Q),l4(Q)}}exit(){process.exit(0)}getDuoConfiguration(){return{gitlabBaseUrl:this.#A.gitlabBaseUrl||"https://gitlab.com",gitlabAuthToken:this.#A.gitlabAuthToken||""}}async initialize(){let A=await this.#Q.get(aMQ),Q=qoB.safeParse(A);if(!Q.success)return;let B=this.#D(this.#A);this.#A={...Q.data,...B}}isMissingConfiguration(){let{gitlabAuthToken:A,gitlabBaseUrl:Q}=this.#A;return!A||!Q}getConfigurationModel(){return{configurationEntries:[{key:"gitlabBaseUrl",value:this.#A.gitlabBaseUrl??"",displayName:"\uD83D\uDD17 GitLab Instance URL",description:"The URL of the GitLab instance to connect to.",defaultValue:"https://gitlab.com",isSensitive:!1},{key:"gitlabAuthToken",value:this.#A.gitlabAuthToken??"",displayName:"\uD83D\uDD16 GitLab Token",description:"GitLab access token with API permissions. Create one here: https://gitlab.com/-/user_settings/personal_access_tokens",defaultValue:"",isSensitive:!0}]}}#D(A){return Object.fromEntries(Object.entries(A).filter(([,Q])=>Q!=null&&Q!==""))}}var qYA=async(A={})=>{let Q=new GP,B=new mJA("info"),D=new WK(Q,B),I=new aW(D),E=new nMQ(A,I,D);return await E.initialize(),E};var UrA=(A,Q)=>{tc(U1(vM1,{initialState:A.getConfigurationModel(),controller:A}),Q)};var OoB=process.platform==="win32",OYA=pNQ(),aq=new yrA,XrA=async(A)=>{let Q=global.__errorHandler;if(Q){let B=new fK("Duo CLI uncaught exception",A);Q.handleError(B.message,B)}else console.error("Duo CLI uncaught exception",A);await iq(1)};process.on("unhandledRejection",XrA);process.on("uncaughtException",XrA);var zrA=A9();aq.name("duo").description("GitLab Duo for your command line").version(zrA,"-v, --version","Display version number").option("-C, --cwd <path>","change working directory",(A)=>lMQ(A),process.cwd()).addOption(new D2("--gitlab-base-url <url>","Base URL of GitLab instance").env("GITLAB_URL").default(process.env.GITLAB_BASE_URL)).addOption(new D2("--gitlab-auth-token <token>","Authentication token for GitLab instance").env("GITLAB_TOKEN").default(process.env.GITLAB_OAUTH_TOKEN)).addOption(new D2("--log-level <level>","Set logging level").choices(Object.values(hD)).env("LOG_LEVEL").default(hD.DEBUG)).addOption(new D2("--git-http-user <user>","Username for git HTTP authentication credentials").env("DUO_WORKFLOW_GIT_HTTP_USER")).addOption(new D2("--git-http-password <password>","Password for git HTTP authentication credentials").env("DUO_WORKFLOW_GIT_HTTP_PASSWORD")).addOption(new D2("--git-user-email <email>","Email for git commit attribution").env("DUO_WORKFLOW_GIT_USER_EMAIL")).addOption(new D2("--git-user-name <name>","Name for git commit attribution").env("DUO_WORKFLOW_GIT_USER_NAME")).addOption(new D2("--telemetry-enabled","Enable collection of telemetry and error events").env("DUO_WORKFLOW_TELEMETRY_ENABLED").default(!0));OYA.registerOptions(aq.addOption(new D2("--existing-session-id <sessionId>","ID of existing session to resume").default(process.env.DUO_WORKFLOW_WORKFLOW_ID)).action(async(A)=>{let Q=aq.opts(),{cwd:B,logLevel:D,gitHttpUser:I,gitHttpPassword:E,gitUserEmail:C,gitUserName:F,telemetryEnabled:J}=Q,{existingSessionId:Y}=A,G=await qYA(Q),X=await MYA();if(G.isMissingConfiguration()){UrA(G,X);return}let U=G.getDuoConfiguration(),w=OYA.mapConfig({cliVersion:zrA,cwd:B,envInfo:X,gitHttpPassword:E,gitHttpUser:I,gitUserEmail:C,gitUserName:F,gitlabAuthToken:U.gitlabAuthToken,gitlabBaseUrl:U.gitlabBaseUrl,logLevel:D,telemetryEnabled:J,command:{name:"tui",existingSessionId:Y}},{programConfig:Q,commandConfig:A});pMQ(w,X)}));var _oB=aq.command("config").description("configuration management commands");_oB.command("edit").description("edit duo CLI configuration").action(async()=>{let A=await qYA(),Q=await MYA();UrA(A,Q)});var _YA=aq.command("log").description("log management commands");_YA.command("last").description("open the last log file").action(()=>{yE1()});_YA.command("list").description("list all log files").action(()=>{vE1()});_YA.command("tail [args...]").description(`tail the last log file. "args" can be any standard ${OoB?'PowerShell "Get-Content"':'"tail"'} arguments`).allowUnknownOption().action((A)=>kE1(A||[]));_YA.command("clear").description("remove all existing log files").action(()=>{gE1()});OYA.registerOptions(aq.command("run").description("Run a workflow in non-interactive / headless mode").addOption(new D2("-g, --goal <goal>","Goal/prompt for the session").default(process.env.DUO_WORKFLOW_GOAL).makeOptionMandatory()).addOption(new D2("--ai-context-items <contextItems>","JSON encoded array of additional context items").env("DUO_WORKFLOW_ADDITIONAL_CONTEXT_CONTENT").argParser((A)=>iMQ(A))).action(async(A)=>{let Q=aq.opts(),{cwd:B,existingSessionId:D,gitHttpPassword:I,gitHttpUser:E,gitUserEmail:C,gitUserName:F,logLevel:J,telemetryEnabled:Y}=Q,{goal:G,aiContextItems:X}=A,U=(await qYA(Q)).getDuoConfiguration(),w=await MYA();if(!U.gitlabAuthToken)throw new e$("--gitlab-auth-token / GITLAB_AUTH_TOKEN option is required.");let Z=OYA.mapConfig({cliVersion:zrA,cwd:B,gitlabBaseUrl:U.gitlabBaseUrl,gitlabAuthToken:U.gitlabAuthToken,logLevel:J,envInfo:w,gitHttpUser:E,gitHttpPassword:I,gitUserEmail:C,gitUserName:F,telemetryEnabled:Y,command:{name:"run",goal:G,aiContextItems:X,existingSessionId:D}},{programConfig:Q,commandConfig:A}),H=new YrA(Z);await H.initialize(),await H.execute()}));try{await aq.parseAsync(process.argv)}catch(A){await XrA(A)}
2005
2005
 
2006
- //# debugId=3603AB4DDE9235A464756E2164756E21
2006
+ //# debugId=336278BD48AE3CCE64756E2164756E21
2007
2007
  //# sourceMappingURL=index.js.map