diff --git a/lib/client.js b/lib/client.js index 67ba271..5e2f877 100644 --- a/lib/client.js +++ b/lib/client.js @@ -8330,7 +8330,7 @@ function safeVerificationUrl(value) { try { const url = new URL(value); const host = url.hostname.toLowerCase(); - return url.protocol === "https:" && (host === "weixin.qq.com" || host.endsWith(".weixin.qq.com")) ? url.toString() : void 0; + return url.protocol === "https:" && (host === "weixin.qq.com" || host.endsWith(".weixin.qq.com") || host === "wechat.com" || host.endsWith(".wechat.com")) ? url.toString() : void 0; } catch { return void 0; } diff --git a/lib/index.js b/lib/index.js index 3491b04..8fe3319 100644 --- a/lib/index.js +++ b/lib/index.js @@ -385,7 +385,7 @@ ${_}`:Y),await g()}catch(Y){this.#i.error?.("[dsh-im:qq] failed to send the safe `).trim()),t.chattype==="group"?o.replace(/^\s*@\S+(?:\s+|$)/u,"").trim():o}function Tke(n){let t=rg(n);return t.msgtype==="image"?[t.image]:t.msgtype!=="mixed"||!Array.isArray(t.mixed?.msg_item)?[]:t.mixed.msg_item.filter(o=>o?.msgtype==="image").map(o=>o.image)}function Nke(n){let t=rg(n);return t.msgtype==="file"&&t.file&&typeof t.file=="object"?[t.file]:[]}function Rke(n,t){let o=pa(t?.url);if(!o)return null;let i=pa(t?.aeskey)??void 0;return{async load({signal:e,maxBytes:a}){if(e?.throwIfAborted(),typeof n?.downloadFile!="function")throw new Error("Enterprise WeChat image download is unavailable");let A=await n.downloadFile(o,i);e?.throwIfAborted();let r=A?.buffer;if(!Buffer.isBuffer(r)&&!(r instanceof Uint8Array))throw new Error("Enterprise WeChat image download returned no data");let s=Buffer.from(r);if(Number.isFinite(a)&&s.length>a)throw new ut("image-too-large",`Enterprise WeChat image exceeds ${a} bytes`,D("\u56FE\u7247\u8D85\u8FC7 5 MB\uFF0C\u8BF7\u538B\u7F29\u540E\u91CD\u8BD5\u3002"));return{data:s,name:A?.filename}}}}function kke(n,t){let o=pa(t?.url);if(!o)return null;let i=pa(t?.aeskey)??void 0;return{name:pa(t?.filename??t?.file_name??t?.name)??"file",async load({signal:e}={}){if(e?.throwIfAborted(),typeof n?.downloadFile!="function")throw new Error("Enterprise WeChat file download is unavailable");let a=await n.downloadFile(o,i);e?.throwIfAborted();let A=a?.buffer??a?.data;if(!Buffer.isBuffer(A)&&!(A instanceof Uint8Array))throw new Error("Enterprise WeChat file download returned no data");return{data:Buffer.from(A),...pa(a?.filename)?{name:a.filename.trim()}:{}}}}}function Wv(n,t){return{content:tP(n),images:Tke(n).map(o=>Rke(t,o)).filter(Boolean),files:Nke(n).map(o=>kke(t,o)).filter(Boolean)}}function vke(n,t){return!Array.isArray(n?.files)||n.files.length===0?n:{...n,files:n.files.map(o=>{let i=o.load({signal:t});return i.catch(()=>{}),{...o,async load({signal:e}={}){e?.throwIfAborted();let a=await i;return e?.throwIfAborted(),a}}})}}function Pke(n,t){return qt(n)?{...n,images:n.images.map(o=>{let i=o.load({signal:t,maxBytes:ZW});return i.catch(()=>{}),{...o,async load({signal:e,maxBytes:a=ZW}={}){e?.throwIfAborted();let A=await i;e?.throwIfAborted();let r=A?.data??A?.buffer??A;if((Buffer.isBuffer(r)||r instanceof Uint8Array?r.length:0)>a)throw new ut("image-too-large",`Enterprise WeChat image exceeds ${a} bytes`,D("\u56FE\u7247\u8D85\u8FC7 5 MB\uFF0C\u8BF7\u538B\u7F29\u540E\u91CD\u8BD5\u3002"));return A}}})}:n}function Gke(n){return{...n,images:n.images.map(t=>({...t,async load(){throw new ut("image-queue-full",`Enterprise WeChat already has ${e6} prefetched images`,D("\u5F53\u524D\u5F85\u5904\u7406\u56FE\u7247\u8F83\u591A\uFF0C\u8BF7\u7A0D\u540E\u91CD\u65B0\u53D1\u9001\u3002"))}}))}}function eP(n){return rg(n).msgtype==="text"?tP(n):""}function Fke(n){return rg(n).msgtype==="text"&&!!pa(tP(n))}function rS(n,t=_ke){let o=String(n??"").trim();if(!o)return[];let i=[],e="",a=0;for(let A of o){let r=Buffer.byteLength(A);e&&a+r>t?(i.push(e),e=A,a=r):(e+=A,a+=r)}return e&&i.push(e),i}function Lke(n){return n?.type==="tool"?D("\u6B63\u5728\u4F7F\u7528{name}\u2026",{name:n.name}):n?.text}function iu(n,t="",{finish:o=!1}={}){let i=String(n??"").replace(/<\/?think>/gi,"").trim(),e=String(t??"").trim();if(!i)return e;let a=o||e?`${i}`:`${i}`;return e?`${a} ${e}`:a}function Uke(n,t){let o=String(n??D("\u7ED3\u679C\u6587\u4EF6")).replace(/[\r\n]+/g," ").trim()||D("\u7ED3\u679C\u6587\u4EF6");switch(t?.code){case"artifact-delivery-uncertain":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u7684\u53D1\u9001\u7ED3\u679C\u672A\u80FD\u786E\u8BA4\uFF0C\u8BF7\u5148\u68C0\u67E5\u804A\u5929\u5185\u662F\u5426\u5DF2\u6536\u5230\uFF0C\u4E0D\u8981\u7ACB\u5373\u91CD\u8BD5\u3002",{name:o});case"artifact-permission-required":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u5DF2\u751F\u6210\uFF0C\u4F46\u4F01\u4E1A\u5FAE\u4FE1\u667A\u80FD\u673A\u5668\u4EBA\u7F3A\u5C11\u7D20\u6750\u4E0A\u4F20\u6216\u6587\u4EF6\u6D88\u606F\u80FD\u529B\uFF0C\u8BF7\u68C0\u67E5\u673A\u5668\u4EBA\u6743\u9650\u3002",{name:o});case"artifact-too-large":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u8D85\u8FC7\u5F53\u524D\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u53EF\u53D1\u9001\u7684\u6587\u4EF6\u5927\u5C0F\uFF0C\u672A\u53D1\u9001\u3002",{name:o});case"artifact-empty":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u4E3A\u7A7A\uFF0C\u4F01\u4E1A\u5FAE\u4FE1\u4E0D\u5141\u8BB8\u53D1\u9001\u7A7A\u6587\u4EF6\u3002",{name:o});case"artifact-changed":case"artifact-invalid":case"artifact-unavailable":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u6216\u51C6\u5907\u53D1\u9001\uFF0C\u8BF7\u786E\u8BA4\u6587\u4EF6\u4ECD\u53EF\u8BBF\u95EE\u540E\u91CD\u8BD5\u3002",{name:o});case"artifact-rate-limited":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u6682\u65F6\u88AB\u4F01\u4E1A\u5FAE\u4FE1\u9650\u6D41\uFF0C\u672A\u80FD\u53D1\u9001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",{name:o});case"artifact-provider-rejected":return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u5DF2\u751F\u6210\uFF0C\u4F46\u4F01\u4E1A\u5FAE\u4FE1\u62D2\u7EDD\u4E86\u8BE5\u6587\u4EF6\u6216\u6587\u4EF6\u6D88\u606F\u3002",{name:o});default:return D("\u7ED3\u679C\u6587\u4EF6\u300C{name}\u300D\u5DF2\u751F\u6210\uFF0C\u4F46\u6682\u65F6\u672A\u80FD\u901A\u8FC7\u4F01\u4E1A\u5FAE\u4FE1\u53D1\u9001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",{name:o})}}function AP(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}function $W(n,t){return t?(t.throwIfAborted(),new Promise((o,i)=>{let e=!1,a=(r,s)=>{e||(e=!0,t.removeEventListener("abort",A),r(s))},A=()=>a(i,AP(t));t.addEventListener("abort",A,{once:!0}),Promise.resolve(n).then(r=>a(o,r),r=>a(i,r)),t.aborted&&A()})):n}function Zv(n,{dispatched:t=!1}={}){if(n?.code?.startsWith?.("artifact-"))return n;let o=Number(n?.httpStatus??n?.status??n?.response?.status),i=Number(n?.providerCode??n?.errcode??n?.body?.errcode),e=new Error("Enterprise WeChat file delivery failed",{cause:n});return o===401||o===403||i===48002?e.code="artifact-permission-required":o===413?e.code="artifact-too-large":o===429||i===45009?e.code="artifact-rate-limited":Number.isFinite(i)&&i!==0?e.code="artifact-provider-rejected":e.code=t?"artifact-delivery-uncertain":"artifact-provider-failed",Number.isFinite(o)&&(e.status=o),Number.isFinite(i)&&(e.providerCode=i),e}async function A6(n,t,o,i,{signal:e,timeoutMs:a=$v}={}){if(e?.throwIfAborted(),typeof n?.uploadMedia!="function"||typeof n?.sendMediaMessage!="function"){let d=new Error(`Enterprise WeChat ${i} delivery is unavailable`);throw d.code="artifact-provider-unavailable",d}let A=AbortSignal.timeout(a),r=e?AbortSignal.any([e,A]):A,s;try{let d=n.uploadMedia(o.bytes,{type:i,filename:o.fileName});Zo(o,d),s=await $W(d,r)}catch(d){throw e?.aborted?AP(e):Zv(d)}e?.throwIfAborted();let g=pa(s?.media_id);if(!g){let d=new Error(`Enterprise WeChat ${i} upload returned no media id`);throw d.code="artifact-provider-rejected",d}let c;try{let d=n.sendMediaMessage(t,i,g);Zo(o,d),c=await $W(d,r)}catch(d){throw e?.aborted?AP(e):Zv(d,{dispatched:!0})}e?.throwIfAborted();let I=Number(c?.body?.errcode??c?.errcode);if(Number.isFinite(I)&&I!==0)throw Zv({providerCode:I});return c}function Hke(n,t,o,i){return A6(n,t,o,"image",i)}function Kke(n,t,o,i){return A6(n,t,o,"file",i)}function xke(n,t){return typeof n=="string"&&n.trim()?n:t.length>0?D("\u7ED3\u679C\u6587\u4EF6\u5DF2\u751F\u6210\u3002"):D("\u4EFB\u52A1\u5DF2\u5B8C\u6210\uFF0C\u4F46\u6CA1\u6709\u751F\u6210\u53EF\u663E\u793A\u7684\u6587\u672C\u3002")}function Xv(n){return pa(n?.body?.msgid)??pa(n?.body?.message_id)}function Yke(n,t){return t.questions[t.index]&&pa(rg(n).from?.userid)===t.actor&&pa(eP(n))}function rP(){return{messagesReceived:0,messagesReplied:0,messagesRejected:0,artifactsSent:0,artifactSendErrors:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastError:null,lastMessageError:null}}var aS=class{#e;#A;#t;#r;#a;#i;#c;#s;#I;#o=new Map;#n=new Map;#g=new Map;#l=new Set;#p=new Set;#d=new Set;#h;#E=new Ii;#u=0;constructor({client:t,harness:o,state:i,status:e=rP(),logger:a=console,replyTimeoutMs:A=6e5,generateStreamId:r=bke,fileUploadTimeoutMs:s=$v,signal:g}){if(!t||typeof t.replyStream!="function"||typeof t.sendMessage!="function")throw new TypeError("Enterprise WeChat client is required");if(!o||!i)throw new TypeError("Harness client and state store are required");if(!Number.isInteger(s)||s<1)throw new TypeError("fileUploadTimeoutMs must be a positive integer");this.#e=t,this.#A=o,this.#t=i,this.#r=e,this.#a=a,this.#i=A,this.#c=r,this.#I=Math.min(s,$v),this.#s=g,this.#h=new ii({label:"wecom",logger:a})}get status(){return structuredClone(this.#r)}accept(t){if(this.#s?.aborted)return Promise.resolve();let o=rg(t),i=pa(o.msgid),e=pa(o.from?.userid),a=o.chattype==="group"?pa(o.chatid):e;if(!i||!e||!a||!["single","group"].includes(o.chattype)||this.#t.hasSeen(i)||this.#l.has(i))return Promise.resolve();let A=XW(t);this.#l.add(i),o.chattype==="single"&&io(this.#t,{chatId:a});let r=this.#n.get(A),s=Wv(t,this.#e),g=pa(s.content)??"",c=lo(g),I=this.#E.status(A);if(c&&o.chattype==="group")return this.#f(t,i,a,{message:Tn()});if(o.chattype==="single"&&(c||I.phase==="collecting")){let Q=/^\/batch$/iu.test(g)&&I.phase==="idle"&&(this.#o.has(A)||r||this.#h.hasPending(A))?{handled:!0,kind:"busy",message:po()}:this.#E.handle(A,g,{plainText:Fke(t)});if(Q.handled)return Q.kind==="submit"?this.#B({...t,body:{...o,msgtype:"text",text:{content:Q.prompt}}},i,A,{batchSubmission:Q}):this.#f(t,i,a,Q)}let d=Gt(s)?null:Pi(g)?gi:Gi(g)?Fi:Li(g)?ci:null;if(d){let f;return f=this.#m(t,i,a,A,s,d).catch(Q=>{if(Q?.code==="turn-stopped"||this.#s?.aborted)return;this.#r.lastError=Q?.message??String(Q);let y=At(this.#r,Q);return this.#a.error?.(`[dsh-im:wecom] failed to process a command [${y.referenceId}]`),this.#Q(t,a,dt(y)).catch(()=>{})}).finally(()=>{this.#l.delete(i),this.#d.delete(f)}),this.#d.add(f),f}let B=this.#h.claimReply({key:A,actor:e,messageId:i,text:eP(t),addressed:!0,hasPendingQuestion:!!r,questionCompletion:r?.submitting||r?.claimedReplyMessageId?r.queue:null,isQuestionPending:()=>this.#n.has(A),send:f=>this.#Q(t,a,f)});if(B){let f;return f=B.process(async()=>this.#t.hasSeen(i)?!1:(await this.#t.markSeen(i),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString(),!0)).finally(()=>{this.#l.delete(i),this.#p.delete(f)}),this.#p.add(f),f}if(r&&r.actor!==e)return this.#B(t,i,A);if(r?.submitting||r?.claimedReplyMessageId)return this.#B(t,i,A);if(r){Yke(t,r)&&(r.claimedReplyMessageId=i);let Q=(r.queue??Promise.resolve()).catch(()=>{}).then(()=>this.#M(t,i,e,a,A,r)).finally(()=>{this.#l.delete(i),r.claimedReplyMessageId===i&&(r.claimedReplyMessageId=null),r.queue===Q&&(r.queue=null)});return r.queue=Q,Q}return this.#B(t,i,A)}#B(t,o,i,{releaseMessageId:e=!0,alreadyRecorded:a=!1,batchSubmission:A=null}={}){let r=Wv(t,this.#e),s=r.images.length,g=0,c=r;s>0&&(this.#u+s<=e6?(g=s,this.#u+=g,c=Pke(r,this.#s)):c=Gke(r)),c=vke(c,this.#s);let d=(this.#o.get(i)??Promise.resolve()).catch(()=>{}).then(()=>this.#b(t,{alreadyRecorded:a,preparedMessage:c,batchSubmission:A})).finally(()=>{this.#u-=g,e&&this.#l.delete(o),this.#o.get(i)===d&&this.#o.delete(i)});return this.#o.set(i,d),d}#f(t,o,i,e){let a;return a=Promise.resolve().then(async()=>{this.#t.hasSeen(o)||(await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString(),e.message&&await this.#Q(t,i,e.message),this.#r.lastError=null)}).catch(async A=>{if(this.#s?.aborted)return;this.#r.lastError=A?.message??String(A);let r=At(this.#r,A);this.#a.error?.(`[dsh-im:wecom] failed to process a batch input message [${r.referenceId}]`),await this.#Q(t,i,dt(r)).catch(()=>{})}).finally(()=>{this.#l.delete(o),this.#d.delete(a)}),this.#d.add(a),a}async waitForIdle(){await Promise.allSettled([...this.#o.values(),...[...this.#n.values()].flatMap(t=>t.queue?[t.queue]:[]),...this.#p,...this.#d])}async#m(t,o,i,e,a,A){if(this.#s?.throwIfAborted(),this.#t.hasSeen(o))return;await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString();let r=await A(a.content,this.#A,this.#t,e,{signal:this.#s,hasImages:qt(a),hasFiles:Gt(a),pendingInteraction:this.#n.has(e)||this.#h.hasPending(e),control:{owner:this,key:e}});r?.stopped&&await Promise.allSettled([this.#v(e),this.#h.closeRoute(e)]);for(let s of r?.messages??[r?.message])s&&await this.#Q(t,i,s);this.#r.lastError=null}async#y(t,o){let i=[];for(let e of rS(o)){this.#s?.throwIfAborted();let a=await this.#e.sendMessage(t,{msgtype:"markdown",markdown:{content:e}}),A=Xv(a);A&&i.push(A)}return i}async#Q(t,o,i){this.#s?.throwIfAborted();let e=rS(i);if(e.length!==0)try{await this.#e.replyStream(t,this.#c("stream"),e[0],!0);for(let a of e.slice(1))await this.#e.sendMessage(o,{msgtype:"markdown",markdown:{content:a}})}catch{await this.#y(o,i)}}async#C(t,o,i=[],e=null){if(i.length===0)return{receipt:e,failureNoticeVisible:!1,artifactSendErrors:0};let a=await Co({artifacts:i,baseReceipt:e,deliveryId:o,aggregatePresentation:e?"wecom-text-and-files":"wecom-files",alwaysMerge:!0,channelKey:"wecom",signal:this.#s,sendImage:A=>Hke(this.#e,t,A,{signal:this.#s,timeoutMs:this.#I}),sendFile:A=>Kke(this.#e,t,A,{signal:this.#s,timeoutMs:this.#I}),onFailure:(A,r)=>At(this.#r,r,{userMessage:Uke(A?.fileName,r),reason:r?.code}),sendFailureNotice:(A,r,s)=>this.#y(t,dt(s)),logger:this.#a});return this.#r.artifactsSent=(this.#r.artifactsSent??0)+a.artifactsSent,this.#r.artifactSendErrors=(this.#r.artifactSendErrors??0)+a.artifactSendErrors,{receipt:a.receipt,failureNoticeVisible:a.failureNoticeVisible,artifactSendErrors:a.artifactSendErrors}}async#b(t,{alreadyRecorded:o=!1,preparedMessage:i,batchSubmission:e=null}={}){if(this.#s?.aborted)return;let a=rg(t),A=typeof a.msgid=="string"?a.msgid:"",r=typeof a.from?.userid=="string"?a.from.userid:"",s=a.chattype==="group"?a.chatid:r;if(!A||!r||!s||!["single","group"].includes(a.chattype))return;if(!o){if(this.#t.hasSeen(A))return;this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString()}let g=i??Wv(t,this.#e),c=g.content,I=qt(g),d=Gt(g),B=XW(t),f=null,Q=!1,y=D("\u6B63\u5728\u601D\u8003\u4E2D\u2026"),m="",_=e===null,N=!1;try{if(!c&&!I&&!d){await this.#Q(t,s,D("\u76EE\u524D\u652F\u6301\u6587\u5B57\u3001\u56FE\u7247\u3001\u6587\u4EF6\u548C\u8BED\u97F3\u8F6C\u5199\u6D88\u606F\u3002")),await this.#t.markSeen(A);return}let G=c.toLowerCase();if(!I&&!d&&G==="/help"){await this.#Q(t,s,Mke()),await this.#t.markSeen(A);return}if(!I&&!d&&G==="/status"){await this.#A.ensureRunning({signal:this.#s}),await this.#Q(t,s,D("\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u4E0E DeepSeek Harness \u8FDE\u63A5\u6B63\u5E38\u3002")),await this.#t.markSeen(A);return}if(!I&&!d&&G==="/new"){await this.#t.clearSession(B),await this.#Q(t,s,D("\u5DF2\u5F00\u542F\u65B0\u4F1A\u8BDD\u3002\u8BF7\u53D1\u9001\u4F60\u7684\u95EE\u9898\u3002")),await this.#t.markSeen(A);return}let Y=I||d?null:await Io(c,this.#A,B);if(Y){for(let ae of Y.messages??[Y.message])await this.#Q(t,s,ae);await this.#t.markSeen(A);return}let J=I||d?null:await si(c,this.#A,this.#t,B,{signal:this.#s});if(J){await this.#Q(t,s,J.message),await this.#t.markSeen(A);return}f=this.#c("stream");try{await this.#e.replyStream(t,f,iu(y),!1),Q=!0}catch(ae){this.#a.warn?.("[dsh-im:wecom] unable to start a stream; using an active reply:",ae)}let H=I?await so(g,{signal:this.#s}):void 0;await this.#t.markSeen(A),N=!0;let{answer:j,artifacts:q=[]}=await ni({harness:this.#A,state:this.#t,key:B,text:c,content:H,createOptions:{signal:this.#s},existsOptions:{signal:this.#s},askOptions:{timeoutMs:this.#i,signal:this.#s,control:{owner:this,key:B},onUpdate:Q&&typeof this.#e.replyStreamNonBlocking=="function"?async ae=>{ae?.type==="text"?m=ae.text:y=Lke(ae)||y;let ge=rS(iu(y,m))[0];ge&&await this.#e.replyStreamNonBlocking(t,f,ge,!1)}:void 0,onInteraction:ae=>this.#w(ae,{key:B,actor:r,chatId:s,requiresMention:a.chattype==="group"}),onInteractionResolved:ae=>this.#S(ae),files:g.files}});e&&(this.#E.complete(B,e.token),_=!0),this.#s?.throwIfAborted();let U=xke(j,q),R=rS(iu(y,U,{finish:!0})),V=!1,L=null,T=null;try{if(Q&&R.length>0)try{let ae=[],ge=await this.#e.replyStream(t,f,R[0],!0),Se=Xv(ge);Se&&ae.push(Se);for(let de of R.slice(1)){let De=await this.#e.sendMessage(s,{msgtype:"markdown",markdown:{content:de}}),Be=Xv(De);Be&&ae.push(Be)}V=!0,L=zt({deliveryId:A,presentation:"wecom-text",providerMessageIds:ae})}catch(ae){this.#a.warn?.("[dsh-im:wecom] stream finalization failed; using an active reply:",ae)}if(!V){let ae=await this.#y(s,U);L=zt({deliveryId:A,presentation:"wecom-text",providerMessageIds:ae})}}catch(ae){T=Sa(ae),this.#a.warn?.("[dsh-im:wecom] final text delivery failed; continuing with result files:",ae)}let P=await this.#C(s,A,q,L),W=P.receipt?.artifacts?.some(({outcome:ae})=>ae==="sent"||ae==="unknown");if(T&&!W&&!P.failureNoticeVisible)throw T;return T&&P.artifactSendErrors===0&&At(this.#r,T),N||await this.#t.markSeen(A),this.#r.messagesReplied+=1,this.#r.lastReplyAt=new Date().toISOString(),this.#r.lastError=null,!T&&P.artifactSendErrors===0&&oo(this.#r),P.receipt}catch(G){let Y=null;if(!_&&e&&(G?.code==="turn-stopped"?this.#E.complete(B,e.token):Y=this.#E.fail(B,e.token).message??null,_=!0),G?.code==="turn-stopped"){Q&&f&&await this.#e.replyStream(t,f,iu(y,D("\u5DF2\u505C\u6B62\u3002"),{finish:!0}),!0).catch(()=>{}),N||await this.#t.markSeen(A);return}if(this.#s?.aborted)return;this.#r.lastError=G?.message??String(G);let J=Eo(G)??go(G),H=At(this.#r,G,{userMessage:J,reason:vi(G)?.reason});this.#a.error?.(`[dsh-im:wecom] failed to process an inbound message [${H.referenceId}]`);let j=dt(H),q=Y?`${j} -${Y}`:j;try{Q&&f?await this.#e.replyStream(t,f,iu(y,q,{finish:!0}),!0):await this.#Q(t,s,q),N||await this.#t.markSeen(A)}catch{this.#a.error?.("[dsh-im:wecom] failed to send the safe error reply")}}finally{await Promise.allSettled([this.#v(B),this.#h.closeRoute(B)])}}async#M(t,o,i,e,a,A){if(this.#s?.aborted)return;let r=this.#n.get(a),s=A.claimedReplyMessageId===o;if(!r||r!==A||r.submitting)return s&&(!r||r!==A)?this.#R(t,o,e):this.#B(t,o,a,{releaseMessageId:!1});if(this.#t.hasSeen(o))return;await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString();let g=pa(eP(t));if(!g){await this.#Q(t,e,D("\u8BF7\u7528\u6587\u5B57\u56DE\u7B54\u5F53\u524D\u95EE\u9898\u3002")).catch(()=>{});return}let c=this.#n.get(a);if(!c||c!==A||c.submitting){if(s&&(!c||c!==A)){await this.#Q(t,e,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{});return}return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0})}if(c.actor!==i)return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0});if(c.chatId=e,c.needsPresentation){try{await this.#_(c)}catch{this.#r.lastError=D("\u4F01\u4E1A\u5FAE\u4FE1\u4EA4\u4E92\u95EE\u9898\u53D1\u9001\u5931\u8D25\u3002"),this.#a.error?.("[dsh-im:wecom] failed to retry an interaction question"),c.interaction.reconnect?.();return}let d=this.#n.get(a);if(!d||d!==A||d.submitting){if(s&&(!d||d!==A)){await this.#Q(t,e,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{});return}return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0})}}let I=c.questions[c.index];if(I){if(c.answers.push(ai(I,g)),c.index+=1,c.index{});return}if(this.#n.get(a)!==c)return;c.submitting=!1,c.answers.pop(),c.index-=1,this.#r.lastError=D("\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\u3002"),this.#a.error?.("[dsh-im:wecom] failed to answer a Harness interaction"),await this.#Q(t,e,D("\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u5F53\u524D\u95EE\u9898\u7684\u7B54\u6848\u3002")).catch(()=>{})}}}async#w(t,{key:o,actor:i,chatId:e,requiresMention:a}){if(t?.kind==="approval")return this.#h.handleRequested(t,{key:o,actor:i,requiresMention:a,send:c=>this.#y(e,c)});if(t?.kind!=="question")return;let A=t?.payload?.questions,r=typeof t?.interactionId=="string"?t.interactionId:t?.rpcId;if(typeof t?.rpcId!="string"||typeof r!="string"||typeof t.sessionId!="string"||!Array.isArray(A)||A.length===0||A.some(c=>!ti(c))){this.#a.warn?.("[dsh-im:wecom] ignored an invalid Harness question interaction");return}if(t.recovered===!0){await t.respond({ok:!1,error:{code:"cancelled",message:"Enterprise WeChat safely cancelled an interaction left by an earlier client.",details:{}}}),await this.#y(e,D("\u68C0\u6D4B\u5230\u8FD9\u4E2A Session \u4E2D\u9057\u7559\u7684\u5F85\u56DE\u7B54\u95EE\u9898\uFF0C\u5DF2\u5B89\u5168\u53D6\u6D88\u5E76\u7EE7\u7EED\u5904\u7406\u4F60\u521A\u624D\u7684\u6D88\u606F\u3002")).catch(()=>{});return}let s=this.#n.get(o);if(s?.interactionId===r){s.interaction=t,s.needsPresentation&&await this.#_(s);return}if(this.#g.has(r))return;if(s){this.#a.warn?.("[dsh-im:wecom] cancelled a second pending Harness question"),await t.respond({ok:!1,error:{code:"cancelled",message:"Enterprise WeChat is already handling another user interaction.",details:{}}});return}let g={kind:"question",interactionId:r,sessionId:t.sessionId,interaction:t,actor:i,requiresMention:a,questions:A,answers:[],index:0,chatId:e,queue:null,claimedReplyMessageId:null,submitting:!1,needsPresentation:!0,presentationPromise:null};this.#n.set(o,g),this.#g.set(g.interactionId,o),await this.#_(g)}async#S(t){if(t?.kind==="approval"){await this.#h.handleResolved(t);return}let o=t?.interactionId;if(t?.kind!=="question"||typeof o!="string")return;let i=this.#g.get(o);i&&this.#N(i,o)}#_(t){if(!t.needsPresentation)return Promise.resolve();if(t.presentationPromise)return t.presentationPromise;let o=t.questions[t.index];if(!o)return Promise.resolve();let i=this.#y(t.chatId,ri(o,t.index,t.questions.length,{requiresMention:t.requiresMention})).then(()=>{t.needsPresentation=!1}).finally(()=>{t.presentationPromise===i&&(t.presentationPromise=null)});return t.presentationPromise=i,i}async#R(t,o,i){this.#t.hasSeen(o)||(await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString(),await this.#Q(t,i,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{}))}#k(t,o){let i=this.#n.get(t);return!i||o!==void 0&&i.interactionId!==o?null:(this.#n.delete(t),this.#g.delete(i.interactionId),i)}#N(t,o){return this.#k(t,o)!==null}async#v(t){let o=this.#k(t);if(!(!o||o.kind!=="question"))try{await o.interaction.respond({ok:!1,error:{code:"cancelled",message:"The Enterprise WeChat interaction ended before the user answered.",details:{}}},{signal:AbortSignal.timeout(5e3)})}catch(i){i?.code!=="interaction-not-pending"&&this.#a.warn?.("[dsh-im:wecom] failed to cancel a pending Harness interaction")}}};function zke(){let n=new Error("Enterprise WeChat WebSocket authentication timed out");return n.code="connect-timeout",n}function Vke(){return{startedAt:null,ready:!1,wecomConnectionState:"idle",harnessReachable:!1,lastCheckedAt:null,lastConnectedAt:null,lastError:null,...rP()}}var ou=class{#e;#A;#t;#r;#a;#i;#c;#s;#I;#o=Vke();#n=null;#g=null;#l=null;#p=null;#d=null;constructor({config:t,secret:o,harness:i,state:e,logger:a=console,replyTimeoutMs:A=6e5,connectTimeoutMs:r=2e4,maxReconnectAttempts:s=10,createClient:g=c=>new Jke(c)}){if(!t||!o||!i||!e)throw new TypeError("WecomRuntime requires config, secret, Harness, and state");this.#e=t,this.#A=o,this.#t=i,this.#r=e,this.#a=a,this.#i=A,this.#c=r,this.#s=s,this.#I=g}get status(){return structuredClone(this.#o)}async start(){if(this.#o.ready&&this.#n)return this.status;if(this.#l)return this.#l;this.#d?.abort(new DOMException("Enterprise WeChat runtime replaced","AbortError"));let t=new AbortController;return this.#p=t,this.#d=t,this.#l=this.#h(t.signal).finally(()=>{this.#p===t&&(this.#p=null),this.#l=null}),this.#l}async#h(t){await this.#E(),t.throwIfAborted(),this.#o.startedAt=new Date().toISOString(),this.#o.wecomConnectionState="connecting",this.#o.lastError=null,await this.#t.ensureRunning(),this.#o.harnessReachable=!0;let o={debug(){},info(){},warn(){},error(){}},i=this.#I({botId:this.#e.remoteBotId,secret:this.#A,logger:o,maxReconnectAttempts:this.#s});if(!i||typeof i.connect!="function"||typeof i.disconnect!="function")throw new TypeError("Enterprise WeChat client factory returned an invalid client");this.#n=i,this.#g=new aS({client:i,harness:this.#t,state:this.#r,status:this.#o,logger:this.#a,replyTimeoutMs:this.#i,signal:t});let e,a,A=!1,r=new Promise((f,Q)=>{e=f,a=Q}),s=()=>{if(this.#n!==i||t.aborted)return;A=!0;let f=Date.now();this.#o.ready=!0,this.#o.wecomConnectionState="connected",this.#o.lastCheckedAt=f,this.#o.lastConnectedAt=f,this.#o.lastError=null,e()},g=()=>{this.#n===i&&(this.#o.ready=!1,this.#o.wecomConnectionState="connecting",this.#o.lastCheckedAt=Date.now())},c=()=>{this.#n===i&&(this.#o.ready=!1,this.#o.wecomConnectionState="connecting",this.#o.lastCheckedAt=Date.now())},I=f=>{if(this.#n!==i)return;let Q=f instanceof jke||f instanceof qke;!A&&Q&&a(f),Q&&(this.#o.ready=!1,this.#o.wecomConnectionState="failed"),this.#o.lastError=Q?f.name:"connection-error",this.#a.warn?.(`[dsh-im:wecom] bot ${this.#e.botId} connection error`)},d=f=>this.#g?.accept(f);i.on("authenticated",s),i.on("disconnected",g),i.on("reconnecting",c),i.on("error",I),i.on("message",d);let B;try{return i.connect(),await Promise.race([r,new Promise((f,Q)=>{t.addEventListener("abort",()=>Q(t.reason),{once:!0})}),new Promise((f,Q)=>{B=setTimeout(()=>Q(zke()),this.#c)})]),this.status}catch(f){throw t.aborted?(await this.#E(),f):(this.#o.ready=!1,this.#o.wecomConnectionState="failed",this.#o.lastError=f?.message??String(f),await this.#E(),f)}finally{clearTimeout(B)}}async stop(){let t=this.#l;return this.#p?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),this.#d?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),this.#d=null,await this.#E(),await t?.catch(()=>{}),this.status}async sendConnectionTest(t){return Tg({state:this.#r,text:t,channelLabel:D("\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"),send:async({chatId:o},i)=>{if(!this.#o.ready||!this.#n)throw new Error("Enterprise WeChat runtime is not connected");await this.#n.sendMessage(o,{msgtype:"markdown",markdown:{content:i}})}})}async#E(){let t=this.#n,o=this.#g;this.#n=null,this.#g=null;try{t?.disconnect(),t?.removeAllListeners?.()}catch{this.#a.warn?.(`[dsh-im:wecom] bot ${this.#e.botId} failed to stop cleanly`)}await o?.waitForIdle(),this.#o.ready=!1,this.#o.wecomConnectionState="idle"}};var t6=Object.freeze([250,1e3,3e3,5e3,1e4,3e4]);function Wke(n){if(!Array.isArray(n)||n.length===0)return[...t6];let t=n.filter(o=>Number.isFinite(o)&&o>=0);return t.length>0?t:[...t6]}var iS=class{#e;#A;#t;#r;#a;#i;#c;#s=null;#I=null;#o=0;#n=!1;#g=!1;#l;#p;constructor({controller:t,harness:o,logger:i=console,retryDelaysMs:e,healthyIntervalMs:a=15e3,setTimeoutImpl:A=setTimeout,clearTimeoutImpl:r=clearTimeout}){if(!t||typeof t.initialize!="function"||typeof t.status!="function")throw new TypeError("ConnectionSupervisor requires a controller");if(!o||typeof o.ensureRunning!="function")throw new TypeError("ConnectionSupervisor requires a Harness client");this.#e=t,this.#A=o,this.#t=i,this.#r=Wke(e),this.#a=Number.isFinite(a)&&a>=0?a:15e3,this.#i=A,this.#c=r,this.#l=new Promise(s=>{this.#p=s})}get ready(){return this.#l}start(){return this.#g||this.#n?this:(this.#g=!0,this.#d(0),this)}async close(){this.#n||(this.#n=!0,this.#s!==null&&this.#c(this.#s),this.#s=null,await this.#I?.catch(()=>{}),this.#p?.(null),this.#p=null)}#d(t){this.#n||(this.#s=this.#i(()=>{this.#s=null,this.#h()},t),this.#s?.unref?.())}async#h(){if(this.#n||this.#I)return;let t=this.#E();this.#I=t;try{await t}finally{this.#I===t&&(this.#I=null)}}async#E(){try{if(await this.#A.ensureRunning(),this.#n)return;let t=await this.#e.initialize();if(this.#n)return;this.#p?.(t),this.#p=null;let{configured:o,connected:i}=t.totals;if(i65535)throw new Error("dsh-im Enterprise WeChat requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function eve(n){let t=xI(n.dshHome??process.env.DSH_HOME??nu(Xke(),".dsh")),o=xI(n.dataDir??nu(t,"integrations","dsh-wecom"));return{config:xI(n.configPath??nu(o,"config.json")),bots:xI(n.botsDir??nu(o,"bots")),workspaces:xI(n.workspacesPath??nu(o,"workspaces.json"))}}async function iP(n,t={},o={}){if(!n?.credentials)throw new TypeError("dsh-im Enterprise WeChat requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-im Enterprise WeChat requires ctx.webServer");let i=o.ConfigStore??Zm,e=o.StateStore??tS,a=o.HarnessClient??$m,A=o.Controller??au,r=o.Runtime??ou,s=o.QrAuth??eS,g=o.createConnectionSupervisor??aP,c=typeof n.logger=="function"?n.logger("dsh-im:wecom"):n.logger??console,I=()=>Oa(n),d=eve(t),B=await new i(d.config).load(),f=xI(t.workspace??process.cwd()),Q=o.WorkspaceStore??Zr,y=o.workspaces??await new Q(d.workspaces,{defaultWorkspace:f}).load(),m=B.list();await y.reconcile(m.map(P=>P.botId)),await Promise.all(m.map(P=>y.ensure(P.botId,{defaultAgentPreset:t.agentPreset})));let _=typeof B.remove=="function"?Ma(B,{workspaces:y}):B,N=o.qrAuth??new s({source:t.qrSource??"deepseek-harness",platform:t.qrPlatform}),G=new Map,Y=P=>xI(d.bots,P,"state.json"),J=async P=>{let W=G.get(P);return W||(W=await new e(Y(P)).load(),G.set(P,W)),W},H=Na(n,o.commandExecutor),{controlExecutor:j,sessionMaintenanceExecutor:q,fileIngressExecutor:U}=Ra(n,{controlExecutor:o.controlExecutor,sessionMaintenanceExecutor:o.sessionMaintenanceExecutor,fileIngressExecutor:o.fileIngressExecutor}),R=new a({baseUrl:$ke(n.webServer,t.harnessBaseUrl),workspace:f,autostart:!1,dshBin:t.dshBin??"dsh",...H?{commandExecutor:H}:{},...j?{controlExecutor:j}:{},...q?{sessionMaintenanceExecutor:q}:{},...U?{fileIngressExecutor:U}:{}}),V=new A({qrAuth:N,credentials:n.credentials,configStore:_,logger:c,createRuntime:async({botId:P,config:W,secret:ae})=>{let ge=await J(P);await y.ensure(P,{defaultAgentPreset:t.agentPreset});let Se=_a(R,{botId:P,workspaces:y,state:ge,agentPresetCatalog:I});return new r({config:W,secret:ae,harness:Se.harness,state:Se.state,replyTimeoutMs:t.replyTimeoutMs??6e5,connectTimeoutMs:t.connectTimeoutMs??2e4,maxReconnectAttempts:t.maxReconnectAttempts??10,logger:{error:(...de)=>c.error?.(`[${P}]`,...de),warn:(...de)=>c.warn?.(`[${P}]`,...de),info:(...de)=>c.info?.(`[${P}]`,...de),debug:(...de)=>c.debug?.(`[${P}]`,...de)}})},deleteState:async({botId:P})=>{let W=G.get(P);if(G.delete(P),W&&typeof W.remove=="function")await W.remove();else try{await Zke(Y(P))}catch(ae){if(ae?.code!=="ENOENT")throw ae}}}),L=Ta(V,{workspaces:y,stateFor:J,agentPresetCatalog:I}),T=g({controller:L,harness:R,logger:c,retryDelaysMs:t.retryDelaysMs,healthyIntervalMs:t.healthyIntervalMs}).start();return{controller:L,ready:T.ready,async close(){await T.close(),await L.close(),R.stopManagedProcess()}}}import Ave from"qrcode";var a6="/wecom",Rr=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",deleteBot:"bot.delete",setWorkspace:hi,setAgentPreset:Ei}),i6=Object.freeze(Object.values(Rr)),tve=new Set(["secret","secretRef","scode","remoteBotId","verificationUrl","bot_info","botid"]);function sP(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function id(n,t){return sP(n)&&Object.keys(n).every(o=>t.includes(o))}function oP(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{1,128}$/.test(n)}function r6(n,t){return typeof n=="string"&&n.trim().length>0&&n.length<=t}function rve(n,t){return sP(t)?n===Rr.status?id(t,[])?null:"connection.status does not accept fields.":n===Rr.beginProvisioning?id(t,["locale"])&&(t.locale===void 0||t.locale==="zh-CN")?null:"provision.begin received unsupported fields.":[Rr.pollProvisioning,Rr.cancelProvisioning].includes(n)?id(t,["attemptId"])&&oP(t.attemptId)?null:`${n} requires an attemptId.`:n===Rr.bindCredentials?id(t,["botId","secret"])&&r6(t.botId,512)&&r6(t.secret,1024)?null:"bot.bind-credentials requires Bot ID and Secret.":n===Rr.reconnectBot?id(t,["botId","sendTest"])&&oP(t.botId)&&(t.sendTest===void 0||t.sendTest===!0)?null:"bot.reconnect requires a botId and optional sendTest=true.":n===Rr.deleteBot?id(t,["botId","confirm"])&&oP(t.botId)&&t.confirm===!0?null:"bot.delete requires a botId and confirm=true.":n===Rr.setWorkspace?ka(t)?null:"\u8BF7\u8F93\u5165\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84\u3002":n===Rr.setAgentPreset?Pa(t)?null:"\u8BF7\u9009\u62E9 Agent Preset\u3002":"Unknown Enterprise WeChat endpoint.":"Payload must be an object."}function nd(n){if(Array.isArray(n))return n.map(nd);if(!sP(n))return n;let t={};for(let[o,i]of Object.entries(n))tve.has(o)||(t[o]=nd(i));return t}async function ave(n){return Ave.toDataURL(n,{type:"image/png",errorCorrectionLevel:"M",margin:2,width:320})}async function nP(n,t){return!n||typeof n.verificationUrl!="string"?nd(n):nd({...n,qrCodeDataUrl:await t(n.verificationUrl)})}async function od(n,t){let o=structuredClone(n);return o?.provisioning&&(o.provisioning=await nP(o.provisioning,t)),nd(o)}function o6(n,{encodeQr:t=ave}={}){for(let e of["status","startProvisioning","registrationStatus","cancelProvisioning","bindCredentials","reconnectBot","deleteBot"])if(typeof n?.[e]!="function")throw new TypeError(`A complete Enterprise WeChat controller is required (${e})`);let o=new Map,i=e=>{let a=o.get(e);return a||(o.size>=16&&o.delete(o.keys().next().value),a=Promise.resolve().then(()=>t(e)),o.set(e,a)),a};return async(e,a,A)=>{if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};if(!i6.includes(e))return{ok:!1,error:{code:"bad-request",message:"Unknown Enterprise WeChat endpoint."}};let r=rve(e,a);if(r)return{ok:!1,error:{code:"bad-request",message:r}};try{let s;if(e===Rr.status)s=await od(await n.status(),i);else if(e===Rr.beginProvisioning)s=await nP(await n.startProvisioning(),i);else if(e===Rr.pollProvisioning){let g=await n.registrationStatus(a.attemptId);if(!g)return{ok:!1,error:{code:"bad-request",message:"The provisioning attempt no longer exists."}};s=await nP(g,i)}else if(e===Rr.cancelProvisioning)s=nd(await n.cancelProvisioning(a.attemptId));else if(e===Rr.bindCredentials)s=await od(await n.bindCredentials(a),i);else if(e===Rr.reconnectBot){let g=await n.reconnectBot(a.botId);if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};let c;if(a.sendTest===!0)if(!g?.bots?.some(d=>d?.botId===a.botId&&d?.connected===!0)||typeof n.sendConnectionTest!="function")c=rr(Ir("\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"));else try{await n.sendConnectionTest(a.botId),c=rr()}catch(d){c=rr(d)}s=await od({...g,...c?{testMessage:c}:{}},i)}else if(e===Rr.setWorkspace){if(typeof n.updateWorkspace!="function")throw new Error("Workspace update is unavailable");s=await od(await n.updateWorkspace(a.botId,a.workspace),i)}else if(e===Rr.setAgentPreset){if(typeof n.updateAgentPreset!="function")throw new Error("Agent preset update is unavailable");s=await od(await n.updateAgentPreset(a.botId,a.agentPreset),i)}else s=await od(await n.deleteBot(a.botId),i);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!0,value:s}}catch(s){let g=va(s);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!1,error:g??{code:"wecom-operation-failed",message:"\u4F01\u4E1A\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}}}}function oS(n,t,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(a6,o6(t,o),{authority:yr(i)})}async function n6(n,t={}){if(t?.controller)return oS(n,t.controller,t.rpcOptions,t.rpcAuthority);let o=await iP(n,t,t.internals),i=oS(n,o.controller,t.rpcOptions,t.rpcAuthority);return n.effect(()=>async()=>o.close(),"dsh-im: close Enterprise WeChat bot connections"),i}import{unlink as iPe}from"node:fs/promises";import{homedir as oPe}from"node:os";import{join as pu,resolve as JI}from"node:path";import{createHash as Dve}from"node:crypto";import{mkdir as wve,readFile as Ove,rename as bve,unlink as Mve,writeFile as _ve}from"node:fs/promises";import{dirname as Tve}from"node:path";import{createCipheriv as ive,createDecipheriv as ove,createHash as s6,randomBytes as gP,randomUUID as g6}from"node:crypto";var nS="https://ilinkai.weixin.qq.com/",nve="2.4.6",sve="3",p6="https://novac2c.cdn.weixin.qq.com/c2c",YI=1800,cP="novac2c.cdn.weixin.qq.com",gve="bot",cve=2<<16|1024|6,Ive=15e3,c6=35e3,lve=3,pve=new Set(["wait","scaned","confirmed","expired","scaned_but_redirect","need_verifycode","verify_code_blocked","binded_redirect"]),NA=class extends Error{constructor(t,o,i={}){super(o,i),this.name="WeixinApiError",this.code=t,this.status=i.status,this.providerCode=i.providerCode}};function wt(n){return typeof n=="string"&&n.trim()?n.trim():null}function d6(n){let t=n==null?null:String(n).trim();return t&&/^-?[A-Za-z0-9_.:-]{1,160}$/.test(t)?t:void 0}function h6(n,t){return Number.isInteger(t?.status)&&(n.status=t.status),t?.providerCode!==void 0&&(n.providerCode=t.providerCode),n}function su(n,{fallback:t="artifact-provider-rejected"}={}){if(n?.code?.startsWith?.("artifact-"))return n;let o=Number(n?.status),i=d6(n?.providerCode),e=i??"",a=t,A="Weixin could not prepare the file for delivery.";o===401||o===403||i==="401"||i==="403"||/(?:permission|forbidden|unauthor|access.?denied)/i.test(e)?(a="artifact-permission-required",A="Weixin denied permission to send the file."):o===413||i==="413"||/(?:too.?large|size.?limit)/i.test(e)?(a="artifact-too-large",A="The file exceeds Weixin's size limit."):o===429||i==="429"||/(?:rate.?limit|too.?many)/i.test(e)?(a="artifact-rate-limited",A="Weixin rate-limited file delivery."):t==="artifact-provider-rejected"&&(A="Weixin rejected the file message.");let r=new Error(A,{cause:n});return r.code=a,h6(r,n)}function dve(n){let t=new Error("Weixin file delivery result is uncertain",{cause:n});return t.code="artifact-delivery-uncertain",h6(t,n)}function I6(n){if(!n||typeof n!="object")return null;for(let t of["ret","errcode"])if(n[t]!==void 0&&n[t]!==0&&n[t]!=="0")return d6(n[t])??"rejected";return null}function hve(n,t){if(t?.aborted)throw sd(t);let o=Number(n?.status);return n?.code==="network-error"||n?.code==="timeout"||n?.code==="invalid-response"||o>=500&&o<600?dve(n):su(n)}function Eve(n){let t=wt(n);return!t||t.length%4!==0||!/^[A-Za-z0-9+/]+={0,2}$/.test(t)?null:Buffer.from(t,"base64")}function E6(n){let t=wt(n?.aeskey);if(t){if(!/^[0-9a-fA-F]{32}$/.test(t))throw new NA("invalid-image-key","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u5BC6\u94A5\u65E0\u6548\u3002");return Buffer.from(t,"hex")}let o=Eve(n?.media?.aes_key);if(o?.length===16)return o;if(o?.length===32&&/^[0-9a-fA-F]{32}$/.test(o.toString("ascii")))return Buffer.from(o.toString("ascii"),"hex");throw new NA("invalid-image-key","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u5BC6\u94A5\u65E0\u6548\u3002")}function C6(n,t){let o=Buffer.from(n),i=Buffer.from(t);if(i.length!==16||o.length===0||o.length%16!==0)throw new NA("invalid-image-ciphertext","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u6570\u636E\u65E0\u6548\u3002");try{let e=ove("aes-128-ecb",i,null);return Buffer.concat([e.update(o),e.final()])}catch(e){throw new NA("image-decryption-failed","\u5FAE\u4FE1\u56FE\u7247\u89E3\u5BC6\u5931\u8D25\u3002",{cause:e})}}function u6(n){let t=wt(n?.encrypt_query_param);if(t)return`${p6}/download?encrypted_query_param=${encodeURIComponent(t)}`;let o=wt(n?.full_url);if(!o)throw new NA("missing-image-url","\u5FAE\u4FE1\u56FE\u7247\u6CA1\u6709\u53EF\u7528\u7684\u4E0B\u8F7D\u5730\u5740\u3002");let i;try{i=new URL(o)}catch{throw new NA("invalid-image-url","\u5FAE\u4FE1\u56FE\u7247\u7684\u4E0B\u8F7D\u5730\u5740\u65E0\u6548\u3002")}if(i.protocol!=="https:"||i.hostname!==cP||i.port&&i.port!=="443"||!i.pathname.startsWith("/c2c/"))throw new NA("untrusted-image-url","\u5FAE\u4FE1\u56FE\u7247\u7684\u4E0B\u8F7D\u5730\u5740\u4E0D\u53D7\u4FE1\u4EFB\u3002");return i.username="",i.password="",i.hash="",i.toString()}function IP(n,{fetchImpl:t=fetch}={}){if(typeof t!="function")throw new TypeError("fetchImpl must be a function");let o=[];for(let i of n?.item_list??[]){let e=i?.image_item;!e||typeof e!="object"||o.push({name:o.length===0?"image":`image-${o.length+1}`,load:async({signal:a,maxBytes:A})=>{let r=E6(e),s=u6(e.media),g=await no(s,{fetchImpl:t,signal:a,maxBytes:A+16,allowedHosts:[cP]});return C6(g,r)}})}return o}async function Cve(n,{fetchImpl:t,signal:o}){let i=await t(new URL(n),{method:"GET",signal:o,redirect:"manual"});if(!i?.ok)throw await i?.body?.cancel?.().catch?.(()=>{}),new NA("file-download-failed",`\u5FAE\u4FE1\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${i?.status??"unknown"}\uFF09\u3002`,{status:i?.status});return Buffer.from(await i.arrayBuffer())}function lP(n,{fetchImpl:t=fetch}={}){if(typeof t!="function")throw new TypeError("fetchImpl must be a function");let o=[];for(let i of n?.item_list??[]){let e=i?.file_item;if(!e||typeof e!="object")continue;let a=Number(e.len);o.push({name:wt(e.file_name)??(o.length===0?"file":`file-${o.length+1}`),...Number.isFinite(a)&&a>=0?{size:a}:{},load:async({signal:A}={})=>{A?.throwIfAborted();let r=E6(e),s=u6(e.media),g=await Cve(s,{fetchImpl:t,signal:A});return A?.throwIfAborted(),C6(g,r)}})}return o}function pP(n){let t=n.toLowerCase().replace(/\.$/,"");return t==="weixin.qq.com"||t.endsWith(".weixin.qq.com")}function gd(n){let t;try{t=new URL(n)}catch{throw new NA("invalid-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u8FDE\u63A5\u5730\u5740\u3002")}if(t.protocol!=="https:"||!pP(t.hostname)||t.port!==""&&t.port!=="443")throw new NA("untrusted-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u8FDE\u63A5\u5730\u5740\u3002");return t.username="",t.password="",t.search="",t.hash="",t.pathname.endsWith("/")||(t.pathname+="/"),t.toString()}function uve(n){let t=wt(n);if(!t)throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u5730\u5740\u3002");let o;try{o=new URL(t)}catch{throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u626B\u7801\u5730\u5740\u3002")}if(o.protocol!=="https:"||!pP(o.hostname))throw new NA("untrusted-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u626B\u7801\u5730\u5740\u3002");return o.toString()}function B6(){return{"iLink-App-Id":gve,"iLink-App-ClientVersion":String(cve)}}function Bve(n){let t={...B6(),"content-type":"application/json",AuthorizationType:"ilink_bot_token","X-WECHAT-UIN":Buffer.from(String(gP(4).readUInt32BE(0)),"utf8").toString("base64")};return wt(n)&&(t.Authorization=`Bearer ${n.trim()}`),t}function ac(){return{channel_version:nve,bot_agent:"DeepSeekHarness/1.1.0"}}function fve(n){return Math.ceil((n+1)/16)*16}function l6(n){let t;try{t=new URL(n)}catch{throw new NA("invalid-upload-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002")}if(t.protocol!=="https:"||t.hostname!==cP||t.port&&t.port!=="443"||t.pathname!=="/c2c/upload"||t.username||t.password)throw new NA("untrusted-upload-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002");return t.hash="",t}function Qve(n,t){let o=wt(n?.upload_full_url);if(o)return l6(o);let i=wt(n?.upload_param);if(!i)throw new NA("missing-upload-url","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002");let e=new URL(`${p6}/upload`);return e.searchParams.set("encrypted_query_param",i),e.searchParams.set("filekey",t),l6(e)}function yve(n,t){let o=ive("aes-128-ecb",t,null);return Buffer.concat([o.update(n),o.final()])}async function mve(n,t,o,{signal:i}={}){let e;for(let a=1;a<=lve;a+=1){i?.throwIfAborted();try{let A=await n(t,{method:"POST",headers:{"content-type":"application/octet-stream"},body:o,signal:i?AbortSignal.any([i,AbortSignal.timeout(6e4)]):AbortSignal.timeout(6e4),redirect:"error"});if(A.status>=400&&A.status<500)throw new NA("upload-rejected",`\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u88AB\u62D2\u7EDD\uFF08HTTP ${A.status}\uFF09\u3002`,{status:A.status});if(A.status!==200)throw new NA("upload-failed",`\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\uFF08HTTP ${A.status}\uFF09\u3002`,{status:A.status});let r=wt(A.headers.get("x-encrypted-param"));if(await A.body?.cancel?.().catch(()=>{}),!r)throw new NA("invalid-upload-response","\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u7F3A\u5C11\u4E0B\u8F7D\u53C2\u6570\u3002");return r}catch(A){if(i?.aborted)throw sd(i);if(A instanceof NA&&(A.code==="upload-rejected"||A.status<500))throw A;e=A}}throw e instanceof NA?e:new NA("upload-failed","\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\u3002",{cause:e})}function sd(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}async function es(n,{method:t,baseUrl:o,endpoint:i,body:e,token:a,timeoutMs:A=Ive,signal:r,authenticated:s=!0}){let g=gd(o),c=new URL(i,g);if(!pP(c.hostname))throw new NA("untrusted-endpoint","\u62D2\u7EDD\u8BBF\u95EE\u4E0D\u53D7\u4FE1\u4EFB\u7684\u5FAE\u4FE1\u670D\u52A1\u5730\u5740\u3002");let I=new AbortController,d=!1,B=()=>I.abort(r?.reason);if(r?.aborted)throw sd(r);r?.addEventListener("abort",B,{once:!0});let f=A>0?setTimeout(()=>{d=!0,I.abort()},A):null;try{let Q=await n(c,{method:t,headers:s?Bve(a):B6(),...e===void 0?{}:{body:JSON.stringify(e)},signal:I.signal});if(!Q.ok)throw new NA("http-error",`\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${Q.status}\uFF09\u3002`,{status:Q.status});try{return await Q.json()}catch(y){throw new NA("invalid-response","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:y})}}catch(Q){throw r?.aborted?sd(r):d?new NA("timeout","\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:Q}):Q instanceof NA?Q:new NA("network-error","\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\u3002",{cause:Q})}finally{f&&clearTimeout(f),r?.removeEventListener("abort",B)}}function Sve(n){if(!n||typeof n!="object"||!pve.has(n.status))throw new NA("invalid-login-status","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u626B\u7801\u72B6\u6001\u3002");return n}function f6({fetchImpl:n=fetch}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");async function t({baseUrl:o,token:i,toUserId:e,file:a,contextToken:A,runId:r,signal:s},{mediaType:g,createItem:c}){let I=wt(e);if(!I||!a||typeof a!="object"||typeof a.fileName!="string"||!a.fileName||!Buffer.isBuffer(a.bytes))throw new TypeError("toUserId and a file are required");s?.throwIfAborted();let d=gP(16).toString("hex"),B=gP(16),f=s6("md5").update(a.bytes).digest("hex"),Q;try{Q=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getuploadurl",token:i,signal:s,body:{filekey:d,media_type:g,to_user_id:I,rawsize:a.bytes.byteLength,rawfilemd5:f,filesize:fve(a.bytes.byteLength),no_need_thumb:!0,aeskey:B.toString("hex"),base_info:ac()}})}catch(U){if(s?.aborted)throw sd(s);let R=Number(U?.status),V=U?.code==="http-error"&&R>=400&&R<500?"artifact-provider-rejected":"artifact-provider-failed";throw su(U,{fallback:V})}let y=I6(Q);if(y)throw su(new NA("upload-url-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u4E0A\u4F20\u8BF7\u6C42\u3002",{providerCode:y}));let m=Qve(Q,d),_=yve(a.bytes,B),N;try{N=await mve(n,m,_,{signal:s})}catch(U){if(s?.aborted)throw sd(s);let R=Number(U?.status),V=U?.code==="upload-rejected"||R>=400&&R<500?"artifact-provider-rejected":"artifact-provider-failed";throw su(U,{fallback:V})}s?.throwIfAborted();let G=wt(a.deliveryKey)??wt(a.artifactId)??g6(),Y=g===3?G:`${G}\0${g}`,J=`dsh-weixin-${s6("sha256").update(Y).digest("hex").slice(0,32)}`,H={encrypt_query_param:N,aes_key:Buffer.from(B.toString("hex")).toString("base64"),encrypt_type:1},j;try{j=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendmessage",token:i,signal:s,body:{msg:{from_user_id:"",to_user_id:I,client_id:J,message_type:2,message_state:2,item_list:[c({file:a,media:H,ciphertextSize:_.byteLength})],...wt(A)?{context_token:A.trim()}:{},...wt(r)?{run_id:r.trim()}:{}},base_info:ac()}})}catch(U){throw hve(U,s)}let q=I6(j);if(q)throw su(new NA("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u6D88\u606F\u3002",{providerCode:q}));return{messageId:J}}return Object.freeze({inboundImages(o){return IP(o,{fetchImpl:n})},inboundFiles(o){return lP(o,{fetchImpl:n})},async beginLogin({localTokens:o=[],botType:i=sve,signal:e}={}){let a=[...new Set(o.map(wt).filter(Boolean))].slice(-10),A=await es(n,{method:"POST",baseUrl:nS,endpoint:`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(i)}`,body:{local_token_list:a},timeoutMs:1e4,signal:e}),r=wt(A?.qrcode);if(!r)throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u4E8C\u7EF4\u7801\u4EE4\u724C\u3002");return{qrcode:r,qrcodeUrl:uve(A.qrcode_img_content)}},async pollLogin({qrcode:o,baseUrl:i=nS,verifyCode:e,signal:a}){let A=wt(o);if(!A)throw new TypeError("qrcode is required");let r=`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(A)}`;wt(e)&&(r+=`&verify_code=${encodeURIComponent(e.trim())}`);let s=await es(n,{method:"GET",baseUrl:i,endpoint:r,timeoutMs:c6,signal:a,authenticated:!1});return Sve(s)},async getUpdates({baseUrl:o,token:i,getUpdatesBuf:e="",timeoutMs:a,signal:A}){try{return await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getupdates",body:{get_updates_buf:e,base_info:ac()},token:i,timeoutMs:a??c6,signal:A})}catch(r){if(r instanceof NA&&r.code==="timeout")return{ret:0,msgs:[],get_updates_buf:e};throw r}},async getConfig({baseUrl:o,token:i,toUserId:e,contextToken:a,signal:A}){let r=wt(e);if(!r)throw new TypeError("toUserId is required");let s=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getconfig",token:i,signal:A,timeoutMs:1e4,body:{ilink_user_id:r,...wt(a)?{context_token:a.trim()}:{},base_info:ac()}});if(s?.ret!==void 0&&s.ret!==0)throw new NA("config-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u673A\u5668\u4EBA\u914D\u7F6E\u8BF7\u6C42\u3002");return{typingTicket:wt(s?.typing_ticket)}},async sendTyping({baseUrl:o,token:i,toUserId:e,typingTicket:a,status:A,signal:r}){let s=wt(e),g=wt(a);if(!s||!g)throw new TypeError("toUserId and typingTicket are required");if(A!==1&&A!==2)throw new TypeError("typing status must be 1 or 2");let c=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendtyping",token:i,signal:r,timeoutMs:1e4,body:{ilink_user_id:s,typing_ticket:g,status:A,base_info:ac()}});if(c?.ret!==void 0&&c.ret!==0)throw new NA("typing-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u8F93\u5165\u72B6\u6001\u8BF7\u6C42\u3002");return!0},async sendText({baseUrl:o,token:i,toUserId:e,text:a,contextToken:A,runId:r,signal:s}){let g=wt(e),c=wt(a);if(!g||!c)throw new TypeError("toUserId and text are required");let I=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendmessage",token:i,signal:s,body:{msg:{from_user_id:"",to_user_id:g,client_id:`dsh-weixin-${g6()}`,message_type:2,message_state:2,item_list:[{type:1,text_item:{text:c}}],...wt(A)?{context_token:A.trim()}:{},...wt(r)?{run_id:r.trim()}:{}},base_info:ac()}});if(I?.ret!==void 0&&I.ret!==0)throw new NA("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async sendFile(o){return t(o,{mediaType:3,createItem:({file:i,media:e})=>({type:4,file_item:{media:e,file_name:i.fileName,len:String(i.bytes.byteLength)}})})},async sendImage(o){return t(o,{mediaType:1,createItem:({media:i,ciphertextSize:e})=>({type:2,image_item:{media:i,mid_size:e}})})},async notifyStart({baseUrl:o,token:i,signal:e}){let a=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/msg/notifystart",token:i,signal:e,timeoutMs:1e4,body:{base_info:ac()}});if(a?.ret!==void 0&&a.ret!==0)throw new NA("start-rejected","\u5FAE\u4FE1\u8D26\u53F7\u8FDE\u63A5\u542F\u52A8\u5931\u8D25\u3002");return a},async notifyStop({baseUrl:o,token:i,signal:e}){return es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/msg/notifystop",token:i,signal:e,timeoutMs:1e4,body:{base_info:ac()}})}})}function jI(n){for(let t of n?.item_list??[]){if(t?.type===1&&typeof t.text_item?.text=="string"){let o=t.text_item.text.trim();if(o)return o}if(t?.type===3&&typeof t.voice_item?.text=="string"){let o=t.voice_item.text.trim();if(o)return o}}return null}function dP(n){return n?.message_id!==void 0&&n.message_id!==null?String(n.message_id):wt(n?.client_id)}function Q6(n,t=YI){if(n.length<=t)return[n];let o=[],i=n;for(;i.length>t;){let e=i.lastIndexOf(` +${Y}`:j;try{Q&&f?await this.#e.replyStream(t,f,iu(y,q,{finish:!0}),!0):await this.#Q(t,s,q),N||await this.#t.markSeen(A)}catch{this.#a.error?.("[dsh-im:wecom] failed to send the safe error reply")}}finally{await Promise.allSettled([this.#v(B),this.#h.closeRoute(B)])}}async#M(t,o,i,e,a,A){if(this.#s?.aborted)return;let r=this.#n.get(a),s=A.claimedReplyMessageId===o;if(!r||r!==A||r.submitting)return s&&(!r||r!==A)?this.#R(t,o,e):this.#B(t,o,a,{releaseMessageId:!1});if(this.#t.hasSeen(o))return;await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString();let g=pa(eP(t));if(!g){await this.#Q(t,e,D("\u8BF7\u7528\u6587\u5B57\u56DE\u7B54\u5F53\u524D\u95EE\u9898\u3002")).catch(()=>{});return}let c=this.#n.get(a);if(!c||c!==A||c.submitting){if(s&&(!c||c!==A)){await this.#Q(t,e,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{});return}return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0})}if(c.actor!==i)return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0});if(c.chatId=e,c.needsPresentation){try{await this.#_(c)}catch{this.#r.lastError=D("\u4F01\u4E1A\u5FAE\u4FE1\u4EA4\u4E92\u95EE\u9898\u53D1\u9001\u5931\u8D25\u3002"),this.#a.error?.("[dsh-im:wecom] failed to retry an interaction question"),c.interaction.reconnect?.();return}let d=this.#n.get(a);if(!d||d!==A||d.submitting){if(s&&(!d||d!==A)){await this.#Q(t,e,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{});return}return this.#B(t,o,a,{releaseMessageId:!1,alreadyRecorded:!0})}}let I=c.questions[c.index];if(I){if(c.answers.push(ai(I,g)),c.index+=1,c.index{});return}if(this.#n.get(a)!==c)return;c.submitting=!1,c.answers.pop(),c.index-=1,this.#r.lastError=D("\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\u3002"),this.#a.error?.("[dsh-im:wecom] failed to answer a Harness interaction"),await this.#Q(t,e,D("\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u5F53\u524D\u95EE\u9898\u7684\u7B54\u6848\u3002")).catch(()=>{})}}}async#w(t,{key:o,actor:i,chatId:e,requiresMention:a}){if(t?.kind==="approval")return this.#h.handleRequested(t,{key:o,actor:i,requiresMention:a,send:c=>this.#y(e,c)});if(t?.kind!=="question")return;let A=t?.payload?.questions,r=typeof t?.interactionId=="string"?t.interactionId:t?.rpcId;if(typeof t?.rpcId!="string"||typeof r!="string"||typeof t.sessionId!="string"||!Array.isArray(A)||A.length===0||A.some(c=>!ti(c))){this.#a.warn?.("[dsh-im:wecom] ignored an invalid Harness question interaction");return}if(t.recovered===!0){await t.respond({ok:!1,error:{code:"cancelled",message:"Enterprise WeChat safely cancelled an interaction left by an earlier client.",details:{}}}),await this.#y(e,D("\u68C0\u6D4B\u5230\u8FD9\u4E2A Session \u4E2D\u9057\u7559\u7684\u5F85\u56DE\u7B54\u95EE\u9898\uFF0C\u5DF2\u5B89\u5168\u53D6\u6D88\u5E76\u7EE7\u7EED\u5904\u7406\u4F60\u521A\u624D\u7684\u6D88\u606F\u3002")).catch(()=>{});return}let s=this.#n.get(o);if(s?.interactionId===r){s.interaction=t,s.needsPresentation&&await this.#_(s);return}if(this.#g.has(r))return;if(s){this.#a.warn?.("[dsh-im:wecom] cancelled a second pending Harness question"),await t.respond({ok:!1,error:{code:"cancelled",message:"Enterprise WeChat is already handling another user interaction.",details:{}}});return}let g={kind:"question",interactionId:r,sessionId:t.sessionId,interaction:t,actor:i,requiresMention:a,questions:A,answers:[],index:0,chatId:e,queue:null,claimedReplyMessageId:null,submitting:!1,needsPresentation:!0,presentationPromise:null};this.#n.set(o,g),this.#g.set(g.interactionId,o),await this.#_(g)}async#S(t){if(t?.kind==="approval"){await this.#h.handleResolved(t);return}let o=t?.interactionId;if(t?.kind!=="question"||typeof o!="string")return;let i=this.#g.get(o);i&&this.#N(i,o)}#_(t){if(!t.needsPresentation)return Promise.resolve();if(t.presentationPromise)return t.presentationPromise;let o=t.questions[t.index];if(!o)return Promise.resolve();let i=this.#y(t.chatId,ri(o,t.index,t.questions.length,{requiresMention:t.requiresMention})).then(()=>{t.needsPresentation=!1}).finally(()=>{t.presentationPromise===i&&(t.presentationPromise=null)});return t.presentationPromise=i,i}async#R(t,o,i){this.#t.hasSeen(o)||(await this.#t.markSeen(o),this.#r.messagesReceived+=1,this.#r.lastMessageAt=new Date().toISOString(),await this.#Q(t,i,D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002")).catch(()=>{}))}#k(t,o){let i=this.#n.get(t);return!i||o!==void 0&&i.interactionId!==o?null:(this.#n.delete(t),this.#g.delete(i.interactionId),i)}#N(t,o){return this.#k(t,o)!==null}async#v(t){let o=this.#k(t);if(!(!o||o.kind!=="question"))try{await o.interaction.respond({ok:!1,error:{code:"cancelled",message:"The Enterprise WeChat interaction ended before the user answered.",details:{}}},{signal:AbortSignal.timeout(5e3)})}catch(i){i?.code!=="interaction-not-pending"&&this.#a.warn?.("[dsh-im:wecom] failed to cancel a pending Harness interaction")}}};function zke(){let n=new Error("Enterprise WeChat WebSocket authentication timed out");return n.code="connect-timeout",n}function Vke(){return{startedAt:null,ready:!1,wecomConnectionState:"idle",harnessReachable:!1,lastCheckedAt:null,lastConnectedAt:null,lastError:null,...rP()}}var ou=class{#e;#A;#t;#r;#a;#i;#c;#s;#I;#o=Vke();#n=null;#g=null;#l=null;#p=null;#d=null;constructor({config:t,secret:o,harness:i,state:e,logger:a=console,replyTimeoutMs:A=6e5,connectTimeoutMs:r=2e4,maxReconnectAttempts:s=10,createClient:g=c=>new Jke(c)}){if(!t||!o||!i||!e)throw new TypeError("WecomRuntime requires config, secret, Harness, and state");this.#e=t,this.#A=o,this.#t=i,this.#r=e,this.#a=a,this.#i=A,this.#c=r,this.#s=s,this.#I=g}get status(){return structuredClone(this.#o)}async start(){if(this.#o.ready&&this.#n)return this.status;if(this.#l)return this.#l;this.#d?.abort(new DOMException("Enterprise WeChat runtime replaced","AbortError"));let t=new AbortController;return this.#p=t,this.#d=t,this.#l=this.#h(t.signal).finally(()=>{this.#p===t&&(this.#p=null),this.#l=null}),this.#l}async#h(t){await this.#E(),t.throwIfAborted(),this.#o.startedAt=new Date().toISOString(),this.#o.wecomConnectionState="connecting",this.#o.lastError=null,await this.#t.ensureRunning(),this.#o.harnessReachable=!0;let o={debug(){},info(){},warn(){},error(){}},i=this.#I({botId:this.#e.remoteBotId,secret:this.#A,logger:o,maxReconnectAttempts:this.#s});if(!i||typeof i.connect!="function"||typeof i.disconnect!="function")throw new TypeError("Enterprise WeChat client factory returned an invalid client");this.#n=i,this.#g=new aS({client:i,harness:this.#t,state:this.#r,status:this.#o,logger:this.#a,replyTimeoutMs:this.#i,signal:t});let e,a,A=!1,r=new Promise((f,Q)=>{e=f,a=Q}),s=()=>{if(this.#n!==i||t.aborted)return;A=!0;let f=Date.now();this.#o.ready=!0,this.#o.wecomConnectionState="connected",this.#o.lastCheckedAt=f,this.#o.lastConnectedAt=f,this.#o.lastError=null,e()},g=()=>{this.#n===i&&(this.#o.ready=!1,this.#o.wecomConnectionState="connecting",this.#o.lastCheckedAt=Date.now())},c=()=>{this.#n===i&&(this.#o.ready=!1,this.#o.wecomConnectionState="connecting",this.#o.lastCheckedAt=Date.now())},I=f=>{if(this.#n!==i)return;let Q=f instanceof jke||f instanceof qke;!A&&Q&&a(f),Q&&(this.#o.ready=!1,this.#o.wecomConnectionState="failed"),this.#o.lastError=Q?f.name:"connection-error",this.#a.warn?.(`[dsh-im:wecom] bot ${this.#e.botId} connection error`)},d=f=>this.#g?.accept(f);i.on("authenticated",s),i.on("disconnected",g),i.on("reconnecting",c),i.on("error",I),i.on("message",d);let B;try{return i.connect(),await Promise.race([r,new Promise((f,Q)=>{t.addEventListener("abort",()=>Q(t.reason),{once:!0})}),new Promise((f,Q)=>{B=setTimeout(()=>Q(zke()),this.#c)})]),this.status}catch(f){throw t.aborted?(await this.#E(),f):(this.#o.ready=!1,this.#o.wecomConnectionState="failed",this.#o.lastError=f?.message??String(f),await this.#E(),f)}finally{clearTimeout(B)}}async stop(){let t=this.#l;return this.#p?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),this.#d?.abort(new DOMException("Enterprise WeChat runtime stopped","AbortError")),this.#d=null,await this.#E(),await t?.catch(()=>{}),this.status}async sendConnectionTest(t){return Tg({state:this.#r,text:t,channelLabel:D("\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"),send:async({chatId:o},i)=>{if(!this.#o.ready||!this.#n)throw new Error("Enterprise WeChat runtime is not connected");await this.#n.sendMessage(o,{msgtype:"markdown",markdown:{content:i}})}})}async#E(){let t=this.#n,o=this.#g;this.#n=null,this.#g=null;try{t?.disconnect(),t?.removeAllListeners?.()}catch{this.#a.warn?.(`[dsh-im:wecom] bot ${this.#e.botId} failed to stop cleanly`)}await o?.waitForIdle(),this.#o.ready=!1,this.#o.wecomConnectionState="idle"}};var t6=Object.freeze([250,1e3,3e3,5e3,1e4,3e4]);function Wke(n){if(!Array.isArray(n)||n.length===0)return[...t6];let t=n.filter(o=>Number.isFinite(o)&&o>=0);return t.length>0?t:[...t6]}var iS=class{#e;#A;#t;#r;#a;#i;#c;#s=null;#I=null;#o=0;#n=!1;#g=!1;#l;#p;constructor({controller:t,harness:o,logger:i=console,retryDelaysMs:e,healthyIntervalMs:a=15e3,setTimeoutImpl:A=setTimeout,clearTimeoutImpl:r=clearTimeout}){if(!t||typeof t.initialize!="function"||typeof t.status!="function")throw new TypeError("ConnectionSupervisor requires a controller");if(!o||typeof o.ensureRunning!="function")throw new TypeError("ConnectionSupervisor requires a Harness client");this.#e=t,this.#A=o,this.#t=i,this.#r=Wke(e),this.#a=Number.isFinite(a)&&a>=0?a:15e3,this.#i=A,this.#c=r,this.#l=new Promise(s=>{this.#p=s})}get ready(){return this.#l}start(){return this.#g||this.#n?this:(this.#g=!0,this.#d(0),this)}async close(){this.#n||(this.#n=!0,this.#s!==null&&this.#c(this.#s),this.#s=null,await this.#I?.catch(()=>{}),this.#p?.(null),this.#p=null)}#d(t){this.#n||(this.#s=this.#i(()=>{this.#s=null,this.#h()},t),this.#s?.unref?.())}async#h(){if(this.#n||this.#I)return;let t=this.#E();this.#I=t;try{await t}finally{this.#I===t&&(this.#I=null)}}async#E(){try{if(await this.#A.ensureRunning(),this.#n)return;let t=await this.#e.initialize();if(this.#n)return;this.#p?.(t),this.#p=null;let{configured:o,connected:i}=t.totals;if(i65535)throw new Error("dsh-im Enterprise WeChat requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function eve(n){let t=xI(n.dshHome??process.env.DSH_HOME??nu(Xke(),".dsh")),o=xI(n.dataDir??nu(t,"integrations","dsh-wecom"));return{config:xI(n.configPath??nu(o,"config.json")),bots:xI(n.botsDir??nu(o,"bots")),workspaces:xI(n.workspacesPath??nu(o,"workspaces.json"))}}async function iP(n,t={},o={}){if(!n?.credentials)throw new TypeError("dsh-im Enterprise WeChat requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-im Enterprise WeChat requires ctx.webServer");let i=o.ConfigStore??Zm,e=o.StateStore??tS,a=o.HarnessClient??$m,A=o.Controller??au,r=o.Runtime??ou,s=o.QrAuth??eS,g=o.createConnectionSupervisor??aP,c=typeof n.logger=="function"?n.logger("dsh-im:wecom"):n.logger??console,I=()=>Oa(n),d=eve(t),B=await new i(d.config).load(),f=xI(t.workspace??process.cwd()),Q=o.WorkspaceStore??Zr,y=o.workspaces??await new Q(d.workspaces,{defaultWorkspace:f}).load(),m=B.list();await y.reconcile(m.map(P=>P.botId)),await Promise.all(m.map(P=>y.ensure(P.botId,{defaultAgentPreset:t.agentPreset})));let _=typeof B.remove=="function"?Ma(B,{workspaces:y}):B,N=o.qrAuth??new s({source:t.qrSource??"deepseek-harness",platform:t.qrPlatform}),G=new Map,Y=P=>xI(d.bots,P,"state.json"),J=async P=>{let W=G.get(P);return W||(W=await new e(Y(P)).load(),G.set(P,W)),W},H=Na(n,o.commandExecutor),{controlExecutor:j,sessionMaintenanceExecutor:q,fileIngressExecutor:U}=Ra(n,{controlExecutor:o.controlExecutor,sessionMaintenanceExecutor:o.sessionMaintenanceExecutor,fileIngressExecutor:o.fileIngressExecutor}),R=new a({baseUrl:$ke(n.webServer,t.harnessBaseUrl),workspace:f,autostart:!1,dshBin:t.dshBin??"dsh",...H?{commandExecutor:H}:{},...j?{controlExecutor:j}:{},...q?{sessionMaintenanceExecutor:q}:{},...U?{fileIngressExecutor:U}:{}}),V=new A({qrAuth:N,credentials:n.credentials,configStore:_,logger:c,createRuntime:async({botId:P,config:W,secret:ae})=>{let ge=await J(P);await y.ensure(P,{defaultAgentPreset:t.agentPreset});let Se=_a(R,{botId:P,workspaces:y,state:ge,agentPresetCatalog:I});return new r({config:W,secret:ae,harness:Se.harness,state:Se.state,replyTimeoutMs:t.replyTimeoutMs??6e5,connectTimeoutMs:t.connectTimeoutMs??2e4,maxReconnectAttempts:t.maxReconnectAttempts??10,logger:{error:(...de)=>c.error?.(`[${P}]`,...de),warn:(...de)=>c.warn?.(`[${P}]`,...de),info:(...de)=>c.info?.(`[${P}]`,...de),debug:(...de)=>c.debug?.(`[${P}]`,...de)}})},deleteState:async({botId:P})=>{let W=G.get(P);if(G.delete(P),W&&typeof W.remove=="function")await W.remove();else try{await Zke(Y(P))}catch(ae){if(ae?.code!=="ENOENT")throw ae}}}),L=Ta(V,{workspaces:y,stateFor:J,agentPresetCatalog:I}),T=g({controller:L,harness:R,logger:c,retryDelaysMs:t.retryDelaysMs,healthyIntervalMs:t.healthyIntervalMs}).start();return{controller:L,ready:T.ready,async close(){await T.close(),await L.close(),R.stopManagedProcess()}}}import Ave from"qrcode";var a6="/wecom",Rr=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",deleteBot:"bot.delete",setWorkspace:hi,setAgentPreset:Ei}),i6=Object.freeze(Object.values(Rr)),tve=new Set(["secret","secretRef","scode","remoteBotId","verificationUrl","bot_info","botid"]);function sP(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function id(n,t){return sP(n)&&Object.keys(n).every(o=>t.includes(o))}function oP(n){return typeof n=="string"&&/^[A-Za-z0-9_-]{1,128}$/.test(n)}function r6(n,t){return typeof n=="string"&&n.trim().length>0&&n.length<=t}function rve(n,t){return sP(t)?n===Rr.status?id(t,[])?null:"connection.status does not accept fields.":n===Rr.beginProvisioning?id(t,["locale"])&&(t.locale===void 0||t.locale==="zh-CN")?null:"provision.begin received unsupported fields.":[Rr.pollProvisioning,Rr.cancelProvisioning].includes(n)?id(t,["attemptId"])&&oP(t.attemptId)?null:`${n} requires an attemptId.`:n===Rr.bindCredentials?id(t,["botId","secret"])&&r6(t.botId,512)&&r6(t.secret,1024)?null:"bot.bind-credentials requires Bot ID and Secret.":n===Rr.reconnectBot?id(t,["botId","sendTest"])&&oP(t.botId)&&(t.sendTest===void 0||t.sendTest===!0)?null:"bot.reconnect requires a botId and optional sendTest=true.":n===Rr.deleteBot?id(t,["botId","confirm"])&&oP(t.botId)&&t.confirm===!0?null:"bot.delete requires a botId and confirm=true.":n===Rr.setWorkspace?ka(t)?null:"\u8BF7\u8F93\u5165\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84\u3002":n===Rr.setAgentPreset?Pa(t)?null:"\u8BF7\u9009\u62E9 Agent Preset\u3002":"Unknown Enterprise WeChat endpoint.":"Payload must be an object."}function nd(n){if(Array.isArray(n))return n.map(nd);if(!sP(n))return n;let t={};for(let[o,i]of Object.entries(n))tve.has(o)||(t[o]=nd(i));return t}async function ave(n){return Ave.toDataURL(n,{type:"image/png",errorCorrectionLevel:"M",margin:2,width:320})}async function nP(n,t){return!n||typeof n.verificationUrl!="string"?nd(n):nd({...n,qrCodeDataUrl:await t(n.verificationUrl)})}async function od(n,t){let o=structuredClone(n);return o?.provisioning&&(o.provisioning=await nP(o.provisioning,t)),nd(o)}function o6(n,{encodeQr:t=ave}={}){for(let e of["status","startProvisioning","registrationStatus","cancelProvisioning","bindCredentials","reconnectBot","deleteBot"])if(typeof n?.[e]!="function")throw new TypeError(`A complete Enterprise WeChat controller is required (${e})`);let o=new Map,i=e=>{let a=o.get(e);return a||(o.size>=16&&o.delete(o.keys().next().value),a=Promise.resolve().then(()=>t(e)),o.set(e,a)),a};return async(e,a,A)=>{if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};if(!i6.includes(e))return{ok:!1,error:{code:"bad-request",message:"Unknown Enterprise WeChat endpoint."}};let r=rve(e,a);if(r)return{ok:!1,error:{code:"bad-request",message:r}};try{let s;if(e===Rr.status)s=await od(await n.status(),i);else if(e===Rr.beginProvisioning)s=await nP(await n.startProvisioning(),i);else if(e===Rr.pollProvisioning){let g=await n.registrationStatus(a.attemptId);if(!g)return{ok:!1,error:{code:"bad-request",message:"The provisioning attempt no longer exists."}};s=await nP(g,i)}else if(e===Rr.cancelProvisioning)s=nd(await n.cancelProvisioning(a.attemptId));else if(e===Rr.bindCredentials)s=await od(await n.bindCredentials(a),i);else if(e===Rr.reconnectBot){let g=await n.reconnectBot(a.botId);if(A?.aborted)return{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}};let c;if(a.sendTest===!0)if(!g?.bots?.some(d=>d?.botId===a.botId&&d?.connected===!0)||typeof n.sendConnectionTest!="function")c=rr(Ir("\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"));else try{await n.sendConnectionTest(a.botId),c=rr()}catch(d){c=rr(d)}s=await od({...g,...c?{testMessage:c}:{}},i)}else if(e===Rr.setWorkspace){if(typeof n.updateWorkspace!="function")throw new Error("Workspace update is unavailable");s=await od(await n.updateWorkspace(a.botId,a.workspace),i)}else if(e===Rr.setAgentPreset){if(typeof n.updateAgentPreset!="function")throw new Error("Agent preset update is unavailable");s=await od(await n.updateAgentPreset(a.botId,a.agentPreset),i)}else s=await od(await n.deleteBot(a.botId),i);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!0,value:s}}catch(s){let g=va(s);return A?.aborted?{ok:!1,error:{code:"cancelled",message:"The request was cancelled."}}:{ok:!1,error:g??{code:"wecom-operation-failed",message:"\u4F01\u4E1A\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}}}}function oS(n,t,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(a6,o6(t,o),{authority:yr(i)})}async function n6(n,t={}){if(t?.controller)return oS(n,t.controller,t.rpcOptions,t.rpcAuthority);let o=await iP(n,t,t.internals),i=oS(n,o.controller,t.rpcOptions,t.rpcAuthority);return n.effect(()=>async()=>o.close(),"dsh-im: close Enterprise WeChat bot connections"),i}import{unlink as iPe}from"node:fs/promises";import{homedir as oPe}from"node:os";import{join as pu,resolve as JI}from"node:path";import{createHash as Dve}from"node:crypto";import{mkdir as wve,readFile as Ove,rename as bve,unlink as Mve,writeFile as _ve}from"node:fs/promises";import{dirname as Tve}from"node:path";import{createCipheriv as ive,createDecipheriv as ove,createHash as s6,randomBytes as gP,randomUUID as g6}from"node:crypto";var nS="https://ilinkai.weixin.qq.com/",nve="2.4.6",sve="3",p6="https://novac2c.cdn.weixin.qq.com/c2c",YI=1800,cP="novac2c.cdn.weixin.qq.com",gve="bot",cve=2<<16|1024|6,Ive=15e3,c6=35e3,lve=3,pve=new Set(["wait","scaned","confirmed","expired","scaned_but_redirect","need_verifycode","verify_code_blocked","binded_redirect"]),NA=class extends Error{constructor(t,o,i={}){super(o,i),this.name="WeixinApiError",this.code=t,this.status=i.status,this.providerCode=i.providerCode}};function wt(n){return typeof n=="string"&&n.trim()?n.trim():null}function d6(n){let t=n==null?null:String(n).trim();return t&&/^-?[A-Za-z0-9_.:-]{1,160}$/.test(t)?t:void 0}function h6(n,t){return Number.isInteger(t?.status)&&(n.status=t.status),t?.providerCode!==void 0&&(n.providerCode=t.providerCode),n}function su(n,{fallback:t="artifact-provider-rejected"}={}){if(n?.code?.startsWith?.("artifact-"))return n;let o=Number(n?.status),i=d6(n?.providerCode),e=i??"",a=t,A="Weixin could not prepare the file for delivery.";o===401||o===403||i==="401"||i==="403"||/(?:permission|forbidden|unauthor|access.?denied)/i.test(e)?(a="artifact-permission-required",A="Weixin denied permission to send the file."):o===413||i==="413"||/(?:too.?large|size.?limit)/i.test(e)?(a="artifact-too-large",A="The file exceeds Weixin's size limit."):o===429||i==="429"||/(?:rate.?limit|too.?many)/i.test(e)?(a="artifact-rate-limited",A="Weixin rate-limited file delivery."):t==="artifact-provider-rejected"&&(A="Weixin rejected the file message.");let r=new Error(A,{cause:n});return r.code=a,h6(r,n)}function dve(n){let t=new Error("Weixin file delivery result is uncertain",{cause:n});return t.code="artifact-delivery-uncertain",h6(t,n)}function I6(n){if(!n||typeof n!="object")return null;for(let t of["ret","errcode"])if(n[t]!==void 0&&n[t]!==0&&n[t]!=="0")return d6(n[t])??"rejected";return null}function hve(n,t){if(t?.aborted)throw sd(t);let o=Number(n?.status);return n?.code==="network-error"||n?.code==="timeout"||n?.code==="invalid-response"||o>=500&&o<600?dve(n):su(n)}function Eve(n){let t=wt(n);return!t||t.length%4!==0||!/^[A-Za-z0-9+/]+={0,2}$/.test(t)?null:Buffer.from(t,"base64")}function E6(n){let t=wt(n?.aeskey);if(t){if(!/^[0-9a-fA-F]{32}$/.test(t))throw new NA("invalid-image-key","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u5BC6\u94A5\u65E0\u6548\u3002");return Buffer.from(t,"hex")}let o=Eve(n?.media?.aes_key);if(o?.length===16)return o;if(o?.length===32&&/^[0-9a-fA-F]{32}$/.test(o.toString("ascii")))return Buffer.from(o.toString("ascii"),"hex");throw new NA("invalid-image-key","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u5BC6\u94A5\u65E0\u6548\u3002")}function C6(n,t){let o=Buffer.from(n),i=Buffer.from(t);if(i.length!==16||o.length===0||o.length%16!==0)throw new NA("invalid-image-ciphertext","\u5FAE\u4FE1\u56FE\u7247\u7684\u52A0\u5BC6\u6570\u636E\u65E0\u6548\u3002");try{let e=ove("aes-128-ecb",i,null);return Buffer.concat([e.update(o),e.final()])}catch(e){throw new NA("image-decryption-failed","\u5FAE\u4FE1\u56FE\u7247\u89E3\u5BC6\u5931\u8D25\u3002",{cause:e})}}function u6(n){let t=wt(n?.encrypt_query_param);if(t)return`${p6}/download?encrypted_query_param=${encodeURIComponent(t)}`;let o=wt(n?.full_url);if(!o)throw new NA("missing-image-url","\u5FAE\u4FE1\u56FE\u7247\u6CA1\u6709\u53EF\u7528\u7684\u4E0B\u8F7D\u5730\u5740\u3002");let i;try{i=new URL(o)}catch{throw new NA("invalid-image-url","\u5FAE\u4FE1\u56FE\u7247\u7684\u4E0B\u8F7D\u5730\u5740\u65E0\u6548\u3002")}if(i.protocol!=="https:"||i.hostname!==cP||i.port&&i.port!=="443"||!i.pathname.startsWith("/c2c/"))throw new NA("untrusted-image-url","\u5FAE\u4FE1\u56FE\u7247\u7684\u4E0B\u8F7D\u5730\u5740\u4E0D\u53D7\u4FE1\u4EFB\u3002");return i.username="",i.password="",i.hash="",i.toString()}function IP(n,{fetchImpl:t=fetch}={}){if(typeof t!="function")throw new TypeError("fetchImpl must be a function");let o=[];for(let i of n?.item_list??[]){let e=i?.image_item;!e||typeof e!="object"||o.push({name:o.length===0?"image":`image-${o.length+1}`,load:async({signal:a,maxBytes:A})=>{let r=E6(e),s=u6(e.media),g=await no(s,{fetchImpl:t,signal:a,maxBytes:A+16,allowedHosts:[cP]});return C6(g,r)}})}return o}async function Cve(n,{fetchImpl:t,signal:o}){let i=await t(new URL(n),{method:"GET",signal:o,redirect:"manual"});if(!i?.ok)throw await i?.body?.cancel?.().catch?.(()=>{}),new NA("file-download-failed",`\u5FAE\u4FE1\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${i?.status??"unknown"}\uFF09\u3002`,{status:i?.status});return Buffer.from(await i.arrayBuffer())}function lP(n,{fetchImpl:t=fetch}={}){if(typeof t!="function")throw new TypeError("fetchImpl must be a function");let o=[];for(let i of n?.item_list??[]){let e=i?.file_item;if(!e||typeof e!="object")continue;let a=Number(e.len);o.push({name:wt(e.file_name)??(o.length===0?"file":`file-${o.length+1}`),...Number.isFinite(a)&&a>=0?{size:a}:{},load:async({signal:A}={})=>{A?.throwIfAborted();let r=E6(e),s=u6(e.media),g=await Cve(s,{fetchImpl:t,signal:A});return A?.throwIfAborted(),C6(g,r)}})}return o}function pP(n){let t=n.toLowerCase().replace(/\.$/,"");return t==="weixin.qq.com"||t.endsWith(".weixin.qq.com")||t==="wechat.com"||t.endsWith(".wechat.com")}function gd(n){let t;try{t=new URL(n)}catch{throw new NA("invalid-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u8FDE\u63A5\u5730\u5740\u3002")}if(t.protocol!=="https:"||!pP(t.hostname)||t.port!==""&&t.port!=="443")throw new NA("untrusted-base-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u8FDE\u63A5\u5730\u5740\u3002");return t.username="",t.password="",t.search="",t.hash="",t.pathname.endsWith("/")||(t.pathname+="/"),t.toString()}function uve(n){let t=wt(n);if(!t)throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u5730\u5740\u3002");let o;try{o=new URL(t)}catch{throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u626B\u7801\u5730\u5740\u3002")}if(o.protocol!=="https:"||!pP(o.hostname))throw new NA("untrusted-qr","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u626B\u7801\u5730\u5740\u3002");return o.toString()}function B6(){return{"iLink-App-Id":gve,"iLink-App-ClientVersion":String(cve)}}function Bve(n){let t={...B6(),"content-type":"application/json",AuthorizationType:"ilink_bot_token","X-WECHAT-UIN":Buffer.from(String(gP(4).readUInt32BE(0)),"utf8").toString("base64")};return wt(n)&&(t.Authorization=`Bearer ${n.trim()}`),t}function ac(){return{channel_version:nve,bot_agent:"DeepSeekHarness/1.1.0"}}function fve(n){return Math.ceil((n+1)/16)*16}function l6(n){let t;try{t=new URL(n)}catch{throw new NA("invalid-upload-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002")}if(t.protocol!=="https:"||t.hostname!==cP||t.port&&t.port!=="443"||t.pathname!=="/c2c/upload"||t.username||t.password)throw new NA("untrusted-upload-url","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002");return t.hash="",t}function Qve(n,t){let o=wt(n?.upload_full_url);if(o)return l6(o);let i=wt(n?.upload_param);if(!i)throw new NA("missing-upload-url","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6587\u4EF6\u4E0A\u4F20\u5730\u5740\u3002");let e=new URL(`${p6}/upload`);return e.searchParams.set("encrypted_query_param",i),e.searchParams.set("filekey",t),l6(e)}function yve(n,t){let o=ive("aes-128-ecb",t,null);return Buffer.concat([o.update(n),o.final()])}async function mve(n,t,o,{signal:i}={}){let e;for(let a=1;a<=lve;a+=1){i?.throwIfAborted();try{let A=await n(t,{method:"POST",headers:{"content-type":"application/octet-stream"},body:o,signal:i?AbortSignal.any([i,AbortSignal.timeout(6e4)]):AbortSignal.timeout(6e4),redirect:"error"});if(A.status>=400&&A.status<500)throw new NA("upload-rejected",`\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u88AB\u62D2\u7EDD\uFF08HTTP ${A.status}\uFF09\u3002`,{status:A.status});if(A.status!==200)throw new NA("upload-failed",`\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\uFF08HTTP ${A.status}\uFF09\u3002`,{status:A.status});let r=wt(A.headers.get("x-encrypted-param"));if(await A.body?.cancel?.().catch(()=>{}),!r)throw new NA("invalid-upload-response","\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u54CD\u5E94\u7F3A\u5C11\u4E0B\u8F7D\u53C2\u6570\u3002");return r}catch(A){if(i?.aborted)throw sd(i);if(A instanceof NA&&(A.code==="upload-rejected"||A.status<500))throw A;e=A}}throw e instanceof NA?e:new NA("upload-failed","\u5FAE\u4FE1\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\u3002",{cause:e})}function sd(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}async function es(n,{method:t,baseUrl:o,endpoint:i,body:e,token:a,timeoutMs:A=Ive,signal:r,authenticated:s=!0}){let g=gd(o),c=new URL(i,g);if(!pP(c.hostname))throw new NA("untrusted-endpoint","\u62D2\u7EDD\u8BBF\u95EE\u4E0D\u53D7\u4FE1\u4EFB\u7684\u5FAE\u4FE1\u670D\u52A1\u5730\u5740\u3002");let I=new AbortController,d=!1,B=()=>I.abort(r?.reason);if(r?.aborted)throw sd(r);r?.addEventListener("abort",B,{once:!0});let f=A>0?setTimeout(()=>{d=!0,I.abort()},A):null;try{let Q=await n(c,{method:t,headers:s?Bve(a):B6(),...e===void 0?{}:{body:JSON.stringify(e)},signal:I.signal});if(!Q.ok)throw new NA("http-error",`\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${Q.status}\uFF09\u3002`,{status:Q.status});try{return await Q.json()}catch(y){throw new NA("invalid-response","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:y})}}catch(Q){throw r?.aborted?sd(r):d?new NA("timeout","\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:Q}):Q instanceof NA?Q:new NA("network-error","\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\u3002",{cause:Q})}finally{f&&clearTimeout(f),r?.removeEventListener("abort",B)}}function Sve(n){if(!n||typeof n!="object"||!pve.has(n.status))throw new NA("invalid-login-status","\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u626B\u7801\u72B6\u6001\u3002");return n}function f6({fetchImpl:n=fetch}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");async function t({baseUrl:o,token:i,toUserId:e,file:a,contextToken:A,runId:r,signal:s},{mediaType:g,createItem:c}){let I=wt(e);if(!I||!a||typeof a!="object"||typeof a.fileName!="string"||!a.fileName||!Buffer.isBuffer(a.bytes))throw new TypeError("toUserId and a file are required");s?.throwIfAborted();let d=gP(16).toString("hex"),B=gP(16),f=s6("md5").update(a.bytes).digest("hex"),Q;try{Q=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getuploadurl",token:i,signal:s,body:{filekey:d,media_type:g,to_user_id:I,rawsize:a.bytes.byteLength,rawfilemd5:f,filesize:fve(a.bytes.byteLength),no_need_thumb:!0,aeskey:B.toString("hex"),base_info:ac()}})}catch(U){if(s?.aborted)throw sd(s);let R=Number(U?.status),V=U?.code==="http-error"&&R>=400&&R<500?"artifact-provider-rejected":"artifact-provider-failed";throw su(U,{fallback:V})}let y=I6(Q);if(y)throw su(new NA("upload-url-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u4E0A\u4F20\u8BF7\u6C42\u3002",{providerCode:y}));let m=Qve(Q,d),_=yve(a.bytes,B),N;try{N=await mve(n,m,_,{signal:s})}catch(U){if(s?.aborted)throw sd(s);let R=Number(U?.status),V=U?.code==="upload-rejected"||R>=400&&R<500?"artifact-provider-rejected":"artifact-provider-failed";throw su(U,{fallback:V})}s?.throwIfAborted();let G=wt(a.deliveryKey)??wt(a.artifactId)??g6(),Y=g===3?G:`${G}\0${g}`,J=`dsh-weixin-${s6("sha256").update(Y).digest("hex").slice(0,32)}`,H={encrypt_query_param:N,aes_key:Buffer.from(B.toString("hex")).toString("base64"),encrypt_type:1},j;try{j=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendmessage",token:i,signal:s,body:{msg:{from_user_id:"",to_user_id:I,client_id:J,message_type:2,message_state:2,item_list:[c({file:a,media:H,ciphertextSize:_.byteLength})],...wt(A)?{context_token:A.trim()}:{},...wt(r)?{run_id:r.trim()}:{}},base_info:ac()}})}catch(U){throw hve(U,s)}let q=I6(j);if(q)throw su(new NA("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u6D88\u606F\u3002",{providerCode:q}));return{messageId:J}}return Object.freeze({inboundImages(o){return IP(o,{fetchImpl:n})},inboundFiles(o){return lP(o,{fetchImpl:n})},async beginLogin({localTokens:o=[],botType:i=sve,signal:e}={}){let a=[...new Set(o.map(wt).filter(Boolean))].slice(-10),A=await es(n,{method:"POST",baseUrl:nS,endpoint:`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(i)}`,body:{local_token_list:a},timeoutMs:1e4,signal:e}),r=wt(A?.qrcode);if(!r)throw new NA("invalid-qr","\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u4E8C\u7EF4\u7801\u4EE4\u724C\u3002");return{qrcode:r,qrcodeUrl:uve(A.qrcode_img_content)}},async pollLogin({qrcode:o,baseUrl:i=nS,verifyCode:e,signal:a}){let A=wt(o);if(!A)throw new TypeError("qrcode is required");let r=`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(A)}`;wt(e)&&(r+=`&verify_code=${encodeURIComponent(e.trim())}`);let s=await es(n,{method:"GET",baseUrl:i,endpoint:r,timeoutMs:c6,signal:a,authenticated:!1});return Sve(s)},async getUpdates({baseUrl:o,token:i,getUpdatesBuf:e="",timeoutMs:a,signal:A}){try{return await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getupdates",body:{get_updates_buf:e,base_info:ac()},token:i,timeoutMs:a??c6,signal:A})}catch(r){if(r instanceof NA&&r.code==="timeout")return{ret:0,msgs:[],get_updates_buf:e};throw r}},async getConfig({baseUrl:o,token:i,toUserId:e,contextToken:a,signal:A}){let r=wt(e);if(!r)throw new TypeError("toUserId is required");let s=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/getconfig",token:i,signal:A,timeoutMs:1e4,body:{ilink_user_id:r,...wt(a)?{context_token:a.trim()}:{},base_info:ac()}});if(s?.ret!==void 0&&s.ret!==0)throw new NA("config-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u673A\u5668\u4EBA\u914D\u7F6E\u8BF7\u6C42\u3002");return{typingTicket:wt(s?.typing_ticket)}},async sendTyping({baseUrl:o,token:i,toUserId:e,typingTicket:a,status:A,signal:r}){let s=wt(e),g=wt(a);if(!s||!g)throw new TypeError("toUserId and typingTicket are required");if(A!==1&&A!==2)throw new TypeError("typing status must be 1 or 2");let c=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendtyping",token:i,signal:r,timeoutMs:1e4,body:{ilink_user_id:s,typing_ticket:g,status:A,base_info:ac()}});if(c?.ret!==void 0&&c.ret!==0)throw new NA("typing-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u8F93\u5165\u72B6\u6001\u8BF7\u6C42\u3002");return!0},async sendText({baseUrl:o,token:i,toUserId:e,text:a,contextToken:A,runId:r,signal:s}){let g=wt(e),c=wt(a);if(!g||!c)throw new TypeError("toUserId and text are required");let I=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/sendmessage",token:i,signal:s,body:{msg:{from_user_id:"",to_user_id:g,client_id:`dsh-weixin-${g6()}`,message_type:2,message_state:2,item_list:[{type:1,text_item:{text:c}}],...wt(A)?{context_token:A.trim()}:{},...wt(r)?{run_id:r.trim()}:{}},base_info:ac()}});if(I?.ret!==void 0&&I.ret!==0)throw new NA("send-rejected","\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async sendFile(o){return t(o,{mediaType:3,createItem:({file:i,media:e})=>({type:4,file_item:{media:e,file_name:i.fileName,len:String(i.bytes.byteLength)}})})},async sendImage(o){return t(o,{mediaType:1,createItem:({media:i,ciphertextSize:e})=>({type:2,image_item:{media:i,mid_size:e}})})},async notifyStart({baseUrl:o,token:i,signal:e}){let a=await es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/msg/notifystart",token:i,signal:e,timeoutMs:1e4,body:{base_info:ac()}});if(a?.ret!==void 0&&a.ret!==0)throw new NA("start-rejected","\u5FAE\u4FE1\u8D26\u53F7\u8FDE\u63A5\u542F\u52A8\u5931\u8D25\u3002");return a},async notifyStop({baseUrl:o,token:i,signal:e}){return es(n,{method:"POST",baseUrl:o,endpoint:"ilink/bot/msg/notifystop",token:i,signal:e,timeoutMs:1e4,body:{base_info:ac()}})}})}function jI(n){for(let t of n?.item_list??[]){if(t?.type===1&&typeof t.text_item?.text=="string"){let o=t.text_item.text.trim();if(o)return o}if(t?.type===3&&typeof t.voice_item?.text=="string"){let o=t.voice_item.text.trim();if(o)return o}}return null}function dP(n){return n?.message_id!==void 0&&n.message_id!==null?String(n.message_id):wt(n?.client_id)}function Q6(n,t=YI){if(n.length<=t)return[n];let o=[],i=n;for(;i.length>t;){let e=i.lastIndexOf(` `,t);ea===null))return null;let o=new Set,i=new Set,e=new Set;for(let a of t){if(o.has(a.botId)||i.has(a.accountId)||e.has(a.tokenRef))return null;o.add(a.botId),i.add(a.accountId),e.add(a.tokenRef)}return Object.freeze({version:1,accounts:Object.freeze(t)})}var sS=class{#e;#A=hP;#t=Promise.resolve();constructor(t){this.#e=t}async load(){try{let t=Rve(JSON.parse(await Ove(this.#e,"utf8")));if(!t)throw new Error("dsh-weixin config contains invalid account data");this.#A=t}catch(t){if(t?.code!=="ENOENT")throw t;this.#A=hP}return this}list(){return structuredClone(this.#A.accounts)}get(t){let o=this.#A.accounts.find(i=>i.botId===t);return o?structuredClone(o):null}getByAccountId(t){let o=this.#A.accounts.find(i=>i.accountId===t);return o?structuredClone(o):null}async save(t){let o=m6(t);if(!o)throw new Error("Refusing to persist incomplete dsh-weixin account data");return this.#r(i=>{let e=i.find(r=>r.accountId===o.accountId&&r.botId!==o.botId),a=i.find(r=>r.tokenRef===o.tokenRef&&r.botId!==o.botId);if(e||a)throw new Error("Duplicate Weixin account identity");let A=i.findIndex(r=>r.botId===o.botId);return A===-1?i.push(o):i[A]=o,structuredClone(o)})}async remove(t){if(!y6(t))throw new TypeError("Invalid Weixin bot id");return this.#r(o=>{let i=o.findIndex(a=>a.botId===t);if(i===-1)return null;let[e]=o.splice(i,1);return structuredClone(e)})}async clear(){let t=this.#t.then(async()=>{try{await Mve(this.#e)}catch(o){if(o?.code!=="ENOENT")throw o}this.#A=hP});this.#t=t.then(()=>{},()=>{}),await t}async#r(t){let o,i=this.#t.then(async()=>{let e=[...this.#A.accounts];o=t(e);let a=Object.freeze({version:1,accounts:Object.freeze(e)});await this.#a(a),this.#A=a});return this.#t=i.then(()=>{},()=>{}),await i,o}async#a(t){await wve(Tve(this.#e),{recursive:!0,mode:448});let o=`${this.#e}.tmp`;await _ve(o,`${JSON.stringify(t,null,2)} `,{encoding:"utf8",mode:384}),await bve(o,this.#e)}};var gS=class extends lr{constructor(t){super({...t,rpcIdPrefix:"weixin",logPrefix:"dsh-weixin"})}};import{mkdir as kve,readFile as vve,rename as Pve,unlink as Gve,writeFile as Fve}from"node:fs/promises";import{dirname as Lve}from"node:path";var cS=Object.freeze({version:1,sessions:{},seenMessageIds:[],getUpdatesBuf:""});function Uve(n){if(!n||typeof n!="object")return structuredClone(cS);let t={};if(n.sessions&&typeof n.sessions=="object"&&!Array.isArray(n.sessions))for(let[o,i]of Object.entries(n.sessions))typeof o=="string"&&typeof i=="string"&&i&&(t[o]=i);return{version:1,sessions:t,seenMessageIds:Array.isArray(n.seenMessageIds)?n.seenMessageIds.filter(o=>typeof o=="string").slice(-1e3):[],getUpdatesBuf:typeof n.getUpdatesBuf=="string"?n.getUpdatesBuf:""}}var IS=class{#e;#A=structuredClone(cS);#t=Promise.resolve();constructor(t){this.#e=t}async load(){try{this.#A=Uve(JSON.parse(await vve(this.#e,"utf8")))}catch(t){if(t?.code!=="ENOENT")throw t;this.#A=structuredClone(cS),await this.#r()}return this}sessionFor(t){return this.#A.sessions[t]??null}async setSession(t,o){this.#A.sessions[t]=o,await this.#r()}async clearSession(t){delete this.#A.sessions[t],await this.#r()}async clearSessions(){this.#A.sessions={},await this.#r()}hasSeen(t){return this.#A.seenMessageIds.includes(t)}async markSeen(t){this.hasSeen(t)||(this.#A.seenMessageIds.push(t),this.#A.seenMessageIds.length>1e3&&this.#A.seenMessageIds.splice(0,this.#A.seenMessageIds.length-1e3),await this.#r())}getUpdatesBuf(){return this.#A.getUpdatesBuf}async setGetUpdatesBuf(t){typeof t!="string"||t===this.#A.getUpdatesBuf||(this.#A.getUpdatesBuf=t,await this.#r())}snapshot(){return structuredClone(this.#A)}async remove(){try{await Gve(this.#e)}catch(t){if(t?.code!=="ENOENT")throw t}this.#A=structuredClone(cS)}async#r(){let t=`${JSON.stringify(this.#A,null,2)} `,o=this.#t.then(async()=>{await kve(Lve(this.#e),{recursive:!0,mode:448});let i=`${this.#e}.tmp`;await Fve(i,t,{encoding:"utf8",mode:384}),await Pve(i,this.#e)});this.#t=o.then(()=>{},()=>{}),await o}};import{randomUUID as Hve}from"node:crypto";var S6=new Set(["starting","pending","scanned","needs_verification","connecting"]),lS=new Set(["connected","expired","failed","cancelled"]),D6=5*6e4,b6=Object.freeze({"credential-read-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u8BFB\u53D6\u73B0\u6709\u767B\u5F55\u51ED\u636E\u3002\u8BF7\u68C0\u67E5 DSH \u51ED\u636E\u5B58\u50A8\u3002","credential-save-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u767B\u5F55\u51ED\u636E\u65E0\u6CD5\u5199\u5165 DSH \u51ED\u636E\u5B58\u50A8\u3002\u8BF7\u68C0\u67E5\u51ED\u636E\u5B58\u50A8\u662F\u5426\u53EF\u5199\u3002","account-config-save-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u8D26\u53F7\u914D\u7F6E\u65E0\u6CD5\u5199\u5165\u672C\u673A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u76EE\u5F55\u6743\u9650\u3002","runtime-prepare-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u521D\u59CB\u5316\u8D26\u53F7\u72B6\u6001\u6216\u5DE5\u4F5C\u533A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u548C\u5DE5\u4F5C\u533A\u76EE\u5F55\u3002","harness-connect-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u63D2\u4EF6\u65E0\u6CD5\u8FDE\u63A5\u672C\u673A Harness\u3002\u8BF7\u68C0\u67E5 dsh web \u5730\u5740\u548C\u7AEF\u53E3\u3002","harness-timeout":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u8D85\u65F6\u3002\u8BF7\u786E\u8BA4 dsh web \u672A\u963B\u585E\u3002","harness-auth-required":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u9700\u8981\u8EAB\u4EFD\u8BA4\u8BC1\u3002\u8BF7\u68C0\u67E5\u4EE3\u7406\u3001\u7F51\u5173\u6216\u81EA\u5B9A\u4E49\u9274\u6743\u914D\u7F6E\u3002","harness-proxy-auth-required":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u672C\u673A Harness \u8BF7\u6C42\u88AB\u4EE3\u7406\u8981\u6C42\u8BA4\u8BC1\u3002\u8BF7\u8BA9\u56DE\u73AF\u5730\u5740\u7ED5\u8FC7\u4EE3\u7406\uFF0C\u5E76\u68C0\u67E5 NO_PROXY \u914D\u7F6E\u3002","harness-loopback-forbidden":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5F02\u5E38\u62D2\u7EDD\u4E86\u56DE\u73AF\u5730\u5740\u7684\u5065\u5EB7\u68C0\u67E5\u3002\u8BF7\u68C0\u67E5 HTTP \u4EE3\u7406\u3001Harness \u6E90\u7801\u7248\u672C\u548C\u6784\u5EFA\u4EA7\u7269\u3002","harness-host-untrusted":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u7684 Host \u4FE1\u4EFB\u68C0\u67E5\u62D2\u7EDD\u4E86\u975E\u56DE\u73AF\u5730\u5740\u8BF7\u6C42\u3002\u8BF7\u68C0\u67E5 harnessBaseUrl \u4E0E trustedHosts \u914D\u7F6E\u3002","harness-request-forbidden":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u5065\u5EB7\u68C0\u67E5\u6536\u5230\u4E86\u975E Harness \u6807\u51C6\u7684 403 \u62D2\u7EDD\u54CD\u5E94\u3002\u8BF7\u68C0\u67E5\u4EE3\u7406\u6216\u7F51\u5173\u914D\u7F6E\u3002","harness-api-not-found":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u627E\u4E0D\u5230 Harness \u5065\u5EB7\u68C0\u67E5\u63A5\u53E3\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002","harness-http-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u8FD4\u56DE\u670D\u52A1\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002","harness-response-invalid":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002","harness-rpc-rejected":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u62D2\u7EDD\u4E86\u5065\u5EB7\u68C0\u67E5\u8BF7\u6C42\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002","harness-check-unknown-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002","connection-start-failed":"\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u6D88\u606F\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u540E\u91CD\u8BD5\u3002"});function cd(n){return typeof n=="string"&&n.trim()?n.trim():null}function Kve(){return new DOMException("Provisioning was cancelled","AbortError")}function w6(n,t){let o=cd(n);return o?gd(o.includes("://")?o:`https://${o}`):gd(t)}function gu(n){return n?{attemptId:n.id,status:n.state,...n.verificationUrl?{verificationUrl:n.verificationUrl}:{},...n.expiresAt?{expiresAt:n.expiresAt}:{},pollIntervalMs:1e3,...n.state==="needs_verification"?{verificationRequired:!0}:{},...n.botId?{botId:n.botId}:{},...n.alreadyConnected?{alreadyConnected:!0}:{},...n.error?{error:structuredClone(n.error)}:{}}:null}function qa(n,t){return Object.freeze({code:n,message:t})}function cu(n,t){let o=new Error(`Weixin activation failed during ${n}`,{cause:t});return o.name="WeixinActivationStageError",o.code=n,o}function xve(n){if(n instanceof NA)return qa(n.code,n.message);let t=b6[n?.code];return t?qa(n.code,D(t)):qa("activation-unknown-failed",D("\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u6FC0\u6D3B\u8FC7\u7A0B\u4E2D\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002"))}function O6(n,t){return n instanceof NA||b6[n?.code]?n:cu(t,n)}var Iu=class{#e;#A;#t;#r;#a;#i;#c=new Map;#s=new Map;#I=new Map;#o=null;#n=new Map;#g=0;#l=!1;constructor({api:t,credentials:o,configStore:i,createRuntime:e,deleteState:a=async()=>{},logger:A=console}){if(!t||typeof t.beginLogin!="function"||typeof t.pollLogin!="function")throw new TypeError("WeixinController requires a Weixin API client");if(!o||typeof o.resolve!="function"||typeof o.set!="function"||typeof o.unset!="function")throw new TypeError("WeixinController requires the DSH credential provider");if(!i||typeof i.list!="function"||typeof i.save!="function"||typeof i.remove!="function")throw new TypeError("WeixinController requires a config store");if(typeof e!="function")throw new TypeError("createRuntime is required");this.#e=t,this.#A=o,this.#t=i,this.#r=e,this.#a=a,this.#i=A}async initialize(){if(this.#l)return this.status();for(let t of this.#t.list())this.#c.get(t.botId)?.status?.ready!==!0&&await this.#m(t.botId,async()=>{let i=this.#t.get(t.botId);if(!(!i||this.#l))try{let e=await this.#u(i.tokenRef);if(!e){this.#s.set(i.botId,qa("missing-token",D("\u767B\u5F55\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u8D26\u53F7\u540E\u91CD\u65B0\u626B\u7801\u3002")));return}await this.#h(i,e),this.#s.delete(i.botId)}catch(e){this.#s.set(i.botId,qa("connection-failed",D("\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002"))),this.#i.warn?.(`[dsh-weixin] account ${i.botId} failed to initialize:`,e)}finally{this.#Q()}});return this.status()}async startProvisioning(){if(this.#l)throw new Error("dsh-weixin controller is closed");this.#o&&await this.cancelProvisioning(this.#o);let t={id:Hve(),state:"starting",createdAt:Date.now(),expiresAt:Date.now()+D6,controller:new AbortController,pendingVerifyCode:null,verifyResolve:null,currentBaseUrl:nS,error:null,botId:null,task:null};this.#I.set(t.id,t),this.#o=t.id,this.#Q();try{let o=(await Promise.all(this.#t.list().slice(-10).map(async e=>this.#u(e.tokenRef)))).filter(Boolean),i=await this.#e.beginLogin({localTokens:o,signal:t.controller.signal});return this.#f(t),t.qrcode=i.qrcode,t.verificationUrl=i.qrcodeUrl,t.state="pending",t.expiresAt=Date.now()+D6,this.#Q(),t.task=this.#p(t),gu(t)}catch(o){throw t.controller.signal.aborted?(t.state="cancelled",t.error=qa("cancelled",D("\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002"))):(t.state="failed",t.error=qa(o instanceof NA?o.code:"qr-start-failed",o instanceof NA?o.message:D("\u65E0\u6CD5\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"))),this.#o===t.id&&(this.#o=null),this.#Q(),o}}registrationStatus(t){return gu(this.#I.get(t))}async submitVerification(t,o){let i=this.#I.get(t);if(!i||i.state!=="needs_verification")throw new Error("The provisioning attempt is not waiting for a verification code");let e=cd(o);if(!e||!/^\d{4,8}$/.test(e))throw new TypeError("Verification code must contain 4 to 8 digits");return i.pendingVerifyCode=e,i.state="scanned",i.verifyResolve?.(),i.verifyResolve=null,this.#Q(),gu(i)}async cancelProvisioning(t){let o=this.#I.get(t);return o?(lS.has(o.state)||(o.controller.abort(),o.verifyResolve?.(),o.verifyResolve=null,await o.task?.catch(()=>{}),lS.has(o.state)||(o.state="cancelled"),o.error??=qa("cancelled",D("\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002"))),this.#o===o.id&&(this.#o=null),this.#Q(),gu(o)):null}async reconnectBot(t){let o=this.#t.get(t);if(!o)throw new Error("Unknown Weixin account");return await this.#m(t,async()=>{let i=await this.#u(o.tokenRef);if(!i)throw new Error("The Weixin token is missing");try{await this.#h(o,i),this.#s.delete(t)}catch(e){throw this.#s.set(t,qa("connection-failed",D("\u5FAE\u4FE1\u8FDE\u63A5\u4ECD\u672A\u5C31\u7EEA\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"))),e}finally{this.#Q()}}),this.status()}async sendConnectionTest(t){let o=this.#t.get(t);if(!o)throw new Error("Unknown Weixin account");return this.#m(t,async()=>{let i=this.#c.get(t);if(!i?.status?.ready||typeof i.sendConnectionTest!="function")throw Ir(D("\u5FAE\u4FE1\u673A\u5668\u4EBA"));return i.sendConnectionTest(ma(D("\u5FAE\u4FE1\u673A\u5668\u4EBA\uFF08{name}\uFF09",{name:CP(o.accountId)})))})}async deleteBot(t){let o=this.#t.get(t);if(!o)throw new Error("Unknown Weixin account");return await this.#m(t,async()=>{let i=await this.#A.resolve(o.tokenRef).catch(()=>{});await this.#E(t);try{await this.#A.unset(o.tokenRef),await this.#t.remove(t)}catch(e){throw i?.value&&(await this.#A.set(o.tokenRef,i.value).catch(()=>{}),await this.#h(o,i.value).catch(()=>{})),new Error("Unable to remove the Weixin account safely.",{cause:e})}try{await this.#a({botId:t,config:o})}catch(e){this.#i.warn?.(`[dsh-weixin] account ${t} state cleanup failed:`,e)}this.#s.delete(t),this.#Q()}),this.status()}status(){let t=this.#t.list().map(e=>{let a=this.#c.get(e.botId)?.status??null,A=a?.ready===!0&&a.weixinConnectionState==="connected"&&a.harnessReachable===!0,r=A?"connected":a?.weixinConnectionState==="connecting"?"connecting":this.#s.has(e.botId)||a?.weixinConnectionState==="failed"?"error":"offline",s=this.#s.get(e.botId)??(r==="error"?qa("connection-failed",D("\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002")):null);return{botId:e.botId,state:r,connected:A,configured:!0,bot:{name:D("\u5FAE\u4FE1\u673A\u5668\u4EBA"),accountIdMasked:CP(e.accountId)},health:{status:A?"healthy":r==="error"?"error":"offline",summary:A?D("\u5FAE\u4FE1\u6D88\u606F\u957F\u8F6E\u8BE2\u8FD0\u884C\u6B63\u5E38"):r==="error"?D("\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u63D2\u4EF6\u4F1A\u81EA\u52A8\u91CD\u8BD5"):D("\u5FAE\u4FE1\u8FDE\u63A5\u5F53\u524D\u79BB\u7EBF"),lastCheckedAt:a?.lastCheckedAt??null},stats:{messagesReceived:a?.messagesReceived??0,messagesReplied:a?.messagesReplied??0},lastMessageError:qr(a?.lastMessageError),error:s?structuredClone(s):null}}),o=t.filter(e=>e.connected).length,i=this.#o?this.#I.get(this.#o):null;return{schemaVersion:1,revision:this.#g,state:i&&S6.has(i.state)?"provisioning":t.length===0?"disconnected":o===t.length?"connected":o>0?"degraded":"offline",bots:t,totals:{configured:t.length,connected:o},...i&&S6.has(i.state)?{provisioning:gu(i)}:{}}}async close(){this.#l||(this.#l=!0,this.#o&&await this.cancelProvisioning(this.#o),await Promise.allSettled([...this.#c.keys()].map(t=>this.#E(t))))}async#p(t){try{for(;!t.controller.signal.aborted&&Date.now(){t.verifyResolve=i,t.controller.signal.aborted&&i()}),t.verifyResolve=null,this.#f(t));let o=await this.#e.pollLogin({qrcode:t.qrcode,baseUrl:t.currentBaseUrl,verifyCode:t.pendingVerifyCode,signal:t.controller.signal});if(this.#f(t),o.status==="wait")t.state="pending";else if(o.status==="scaned")t.pendingVerifyCode=null,t.state="scanned";else if(o.status==="need_verifycode")t.pendingVerifyCode=null,t.state="needs_verification";else if(o.status==="verify_code_blocked"){t.state="failed",t.error=qa("verification-blocked",D("\u914D\u5BF9\u7801\u591A\u6B21\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801\u3002"));break}else if(o.status==="expired"){t.state="expired",t.error=qa("expired",D("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002"));break}else if(o.status==="scaned_but_redirect")t.currentBaseUrl=w6(o.redirect_host,t.currentBaseUrl),t.state="scanned";else if(o.status==="binded_redirect"){let i=this.#t.list().find(e=>this.#c.get(e.botId)?.status?.ready===!0)??this.#t.list()[0];i?(t.state="connected",t.botId=i.botId,t.alreadyConnected=!0):(t.state="failed",t.error=qa("already-bound",D("\u8BE5\u5FAE\u4FE1\u8D26\u53F7\u5DF2\u7ED1\u5B9A\uFF0C\u4F46\u672C\u673A\u6CA1\u6709\u53EF\u6062\u590D\u7684\u51ED\u636E\u3002")));break}else if(o.status==="confirmed"){let i=cd(o.bot_token),e=cd(o.ilink_bot_id),a=cd(o.ilink_user_id);if(!i||!e||!a)throw new NA("incomplete-login",D("\u5FAE\u4FE1\u6388\u6743\u6210\u529F\uFF0C\u4F46\u8FD4\u56DE\u7684\u8D26\u53F7\u51ED\u636E\u4E0D\u5B8C\u6574\u3002"));t.state="connecting",this.#Q();let A=w6(o.baseurl,t.currentBaseUrl);t.botId=await this.#d(t,{token:i,accountId:e,ownerUserId:a,baseUrl:A}),t.state="connected",t.error=null;break}this.#Q()}!t.controller.signal.aborted&&Date.now()>=t.expiresAt&&!lS.has(t.state)&&(t.state="expired",t.error=qa("expired",D("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002")))}catch(o){t.controller.signal.aborted||o?.name==="AbortError"?(t.state="cancelled",t.error=qa("cancelled",D("\u626B\u7801\u7ED1\u5B9A\u5DF2\u53D6\u6D88\u3002"))):(t.state="failed",t.error=xve(o),this.#i.error?.("[dsh-weixin] provisioning failed:",o))}finally{t.pendingVerifyCode=null,t.verifyResolve?.(),t.verifyResolve=null,this.#o===t.id&&(this.#o=null),this.#Q(),this.#y()}}async#d(t,{token:o,accountId:i,ownerUserId:e,baseUrl:a}){let A=EP(i),r=this.#t.getByAccountId(i),s={botId:A.botId,accountId:i,tokenRef:A.tokenRef,ownerUserId:e,baseUrl:a,createdAt:r?.createdAt??new Date().toISOString(),connectedAt:new Date().toISOString()},g;try{g=await this.#A.resolve(A.tokenRef)}catch(c){throw cu("credential-read-failed",c)}return this.#m(A.botId,async()=>{try{try{await this.#A.set(A.tokenRef,o)}catch(c){throw cu("credential-save-failed",c)}this.#f(t);try{await this.#t.save(s)}catch(c){throw cu("account-config-save-failed",c)}return this.#f(t),await this.#h(s,o),this.#f(t),this.#s.delete(A.botId),this.#Q(),A.botId}catch(c){throw await this.#E(A.botId),r?await this.#t.save(r).catch(()=>{}):this.#t.get(A.botId)&&await this.#t.remove(A.botId).catch(()=>null)&&await this.#a({botId:A.botId,config:s}).catch(d=>{this.#i.warn?.("[dsh-weixin] failed to clean up cancelled bot state:",d)}),await this.#B(A.tokenRef,g),r&&g?.value&&await this.#h(r,g.value).catch(()=>{}),c}})}async#h(t,o){await this.#E(t.botId);let i;try{i=await this.#r({botId:t.botId,config:t,token:o})}catch(e){throw O6(e,"runtime-prepare-failed")}if(!i||typeof i.start!="function"||typeof i.stop!="function")throw cu("runtime-prepare-failed",new TypeError("createRuntime returned an invalid Weixin runtime"));try{await i.start(),this.#c.set(t.botId,i)}catch(e){throw await i.stop().catch(()=>{}),O6(e,"connection-start-failed")}}async#E(t){let o=this.#c.get(t);this.#c.delete(t),await o?.stop().catch(i=>{this.#i.warn?.(`[dsh-weixin] account ${t} failed to stop cleanly:`,i)})}async#u(t){let o=await this.#A.resolve(t).catch(()=>{});return cd(o?.value)}async#B(t,o){try{o?.value?await this.#A.set(t,o.value):await this.#A.unset(t)}catch(i){this.#i.error?.(`[dsh-weixin] failed to restore credential ${t}:`,i)}}#f(t){if(t.controller.signal.aborted||this.#o!==t.id)throw Kve()}#m(t,o){let a=(this.#n.get(t)??Promise.resolve()).catch(()=>{}).then(o).finally(()=>{this.#n.get(t)===a&&this.#n.delete(t)});return this.#n.set(t,a),a}#y(){for(let[t,o]of this.#I)t!==this.#o&&lS.has(o.state)&&this.#I.size>16&&this.#I.delete(t)}#Q(){this.#g+=1}};var pS=()=>D("\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002"),Yve=5e3,uP=6e4,jve=()=>[D("\u5FAE\u4FE1\u5DF2\u8FDE\u63A5 DeepSeek Harness\u3002"),"",D("\u76F4\u63A5\u53D1\u9001\u6587\u5B57\u3001\u56FE\u7247\u3001\u6587\u4EF6\u6216\u5E26\u6587\u5B57\u8BC6\u522B\u7ED3\u679C\u7684\u8BED\u97F3\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002"),D("/new \u5F00\u542F\u4E00\u4E2A\u5168\u65B0\u4F1A\u8BDD"),D("/compact \u538B\u7F29\u5F53\u524D\u4F1A\u8BDD\u7684\u8F83\u65E9\u4E0A\u4E0B\u6587"),D("/workspace \u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84 \u5207\u6362\u5DE5\u4F5C\u533A"),D("/workspacelist \u5217\u51FA\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84"),D("/sessionlist [\u5DE5\u4F5C\u533A\u5E8F\u53F7\u6216\u7EDD\u5BF9\u8DEF\u5F84] \u5217\u51FA\u4F1A\u8BDD ID \u548C\u6807\u9898"),D("/session Session ID \u6216\u5F53\u524D\u5DE5\u4F5C\u533A\u5E8F\u53F7 \u5C06\u5F53\u524D\u804A\u5929\u7ED1\u5B9A\u5230\u6307\u5B9A\u4F1A\u8BDD"),D("/models \u6309\u5E8F\u53F7\u5217\u51FA\u6240\u6709\u53EF\u7528\u6A21\u578B"),D("/reasoninglist \u6216 /reasonings \u6309\u5E8F\u53F7\u5217\u51FA\u5F53\u524D\u6A21\u578B\u53EF\u7528\u63A8\u7406\u7B49\u7EA7"),D("/reasoning [\u5E8F\u53F7\u3001\u7B49\u7EA7ID\u6216 --default] \u67E5\u770B\u6216\u5207\u6362\u5F53\u524D\u63A8\u7406\u7B49\u7EA7"),D("/model [\u5E8F\u53F7\u6216\u5B8C\u6574\u6A21\u578BID] [\u63A8\u7406\u7B49\u7EA7ID] \u67E5\u770B\u6216\u5207\u6362\u5F53\u524D\u4F1A\u8BDD\u6A21\u578B"),D("\u793A\u4F8B\uFF1A\u5148\u53D1 /models\uFF0C\u518D\u53D1 /model 2 [\u63A8\u7406\u7B49\u7EA7ID]"),D("/presetlist \u6309\u5E8F\u53F7\u5217\u51FA\u53EF\u7528 Agent Preset"),D("/preset [\u5E8F\u53F7\u6216\u5B8C\u6574ID] \u67E5\u770B\u6216\u8BBE\u7F6E\u5F53\u524D\u673A\u5668\u4EBA Agent Preset"),D("\u7EAF\u6570\u5B57 ID\uFF1A/preset id:"),D("/preset --default \u8DDF\u968F Host \u9ED8\u8BA4"),D("/stop \u505C\u6B62\u5F53\u524D\u4EFB\u52A1"),D("/steer \u8865\u5145\u6307\u4EE4 \u7EA0\u504F\u5F53\u524D\u4EFB\u52A1"),D("/batch \u5F00\u59CB\u6279\u91CF\u8F93\u5165\uFF08\u4EC5\u79C1\u804A\uFF0C\u6700\u591A 10 \u6761\u6587\u5B57\uFF09"),D("/send \u63D0\u4EA4\u5F53\u524D\u6279\u6B21"),D("/cancel \u53D6\u6D88\u5F53\u524D\u6279\u6B21"),D("/status \u68C0\u67E5\u8FDE\u63A5\u72B6\u6001"),D("/version \u67E5\u770B\u63D2\u4EF6\u7248\u672C"),D("/help \u663E\u793A\u672C\u5E2E\u52A9")].join(` diff --git a/plugin-src/client/channels/weixin/api.js b/plugin-src/client/channels/weixin/api.js index 9cbcaa2..06596bd 100644 --- a/plugin-src/client/channels/weixin/api.js +++ b/plugin-src/client/channels/weixin/api.js @@ -74,7 +74,8 @@ export function safeVerificationUrl(value) { const url = new URL(value); const host = url.hostname.toLowerCase(); return url.protocol === 'https:' - && (host === 'weixin.qq.com' || host.endsWith('.weixin.qq.com')) + && (host === 'weixin.qq.com' || host.endsWith('.weixin.qq.com') + || host === 'wechat.com' || host.endsWith('.wechat.com')) ? url.toString() : undefined; } catch { diff --git a/src/channels/weixin/weixin-api.mjs b/src/channels/weixin/weixin-api.mjs index 655bd14..a96a838 100644 --- a/src/channels/weixin/weixin-api.mjs +++ b/src/channels/weixin/weixin-api.mjs @@ -240,7 +240,8 @@ export function extractWeixinFiles(message, { fetchImpl = fetch } = {}) { function isWeixinHost(hostname) { const normalized = hostname.toLowerCase().replace(/\.$/, ''); - return normalized === 'weixin.qq.com' || normalized.endsWith('.weixin.qq.com'); + return normalized === 'weixin.qq.com' || normalized.endsWith('.weixin.qq.com') + || normalized === 'wechat.com' || normalized.endsWith('.wechat.com'); } export function normalizeWeixinApiBaseUrl(value) { diff --git a/test/channels/weixin/weixin-api.test.mjs b/test/channels/weixin/weixin-api.test.mjs index d25c27b..369a8c2 100644 --- a/test/channels/weixin/weixin-api.test.mjs +++ b/test/channels/weixin/weixin-api.test.mjs @@ -652,7 +652,12 @@ test('Weixin URL, inbound text, and reply chunk helpers enforce their narrow for normalizeWeixinApiBaseUrl('https://ilinkai.weixin.qq.com/path'), 'https://ilinkai.weixin.qq.com/path/', ); + assert.equal( + normalizeWeixinApiBaseUrl('https://ilinkai.wechat.com/path'), + 'https://ilinkai.wechat.com/path/', + ); assert.throws(() => normalizeWeixinApiBaseUrl('https://ilinkai.weixin.qq.com:444/')); + assert.throws(() => normalizeWeixinApiBaseUrl('https://ilinkai.wechat.com.attacker.test/')); assert.equal(extractWeixinText({ item_list: [{ type: 1, text_item: { text: ' 你好 ' } }] }), '你好'); assert.equal(extractWeixinText({ item_list: [{ type: 3, voice_item: { text: '语音转写' } }] }), '语音转写'); assert.deepEqual(splitWeixinText('abcdefgh', 5), ['abcde', 'fgh']); diff --git a/test/weixin-client-api.test.mjs b/test/weixin-client-api.test.mjs index 00420cf..e758958 100644 --- a/test/weixin-client-api.test.mjs +++ b/test/weixin-client-api.test.mjs @@ -28,11 +28,13 @@ test('client normalizes the exact redacted Host account view', () => { assert.doesNotMatch(JSON.stringify(snapshot), /host-secret|token/); }); -test('client accepts only image data URLs and Tencent Weixin HTTPS links', () => { +test('client accepts only image data URLs and Tencent Weixin or WeChat HTTPS links', () => { assert.match(safeQrSource('data:image/png;base64,AAAA'), /^data:image/); assert.equal(safeQrSource('javascript:alert(1)'), undefined); assert.equal(safeVerificationUrl('https://liteapp.weixin.qq.com/q/test'), 'https://liteapp.weixin.qq.com/q/test'); + assert.equal(safeVerificationUrl('https://liteapp.wechat.com/q/test'), 'https://liteapp.wechat.com/q/test'); assert.equal(safeVerificationUrl('https://attacker.test/q/test'), undefined); + assert.equal(safeVerificationUrl('https://liteapp.wechat.com.attacker.test/q/test'), undefined); }); test('client preserves verification-required provisioning without accepting unknown states', () => {