@xmanrui/dsh-im 4.16.0 → 4.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -571,7 +571,7 @@ var React28 = __toESM(require("react"), 1);
571
571
  // package.json
572
572
  var package_default = {
573
573
  name: "@xmanrui/dsh-im",
574
- version: "4.16.0",
574
+ version: "4.16.1",
575
575
  description: "\u628A\u5341\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect ten IM channels and a public AI Office to a local DeepSeek Harness.",
576
576
  keywords: [
577
577
  "deepseek-harness",
@@ -610,6 +610,10 @@ var package_default = {
610
610
  {
611
611
  name: "BuvkB",
612
612
  url: "https://github.com/BuvkB"
613
+ },
614
+ {
615
+ name: "masucc",
616
+ url: "https://github.com/masucc"
613
617
  }
614
618
  ],
615
619
  license: "MIT",
package/lib/index.js CHANGED
@@ -158,11 +158,11 @@ ${S("\u9519\u8BEF\u7801\uFF1A{code}\uFF1B\u53C2\u8003\u53F7\uFF1A{referenceId}",
158
158
  \u7528\u6CD5\uFF1A/workspace \u5DE5\u4F5C\u533A\u5E8F\u53F7\u6216\u7EDD\u5BF9\u8DEF\u5F84`,{message:s.message}));if(s?.code==="workspace-bot-not-found")return TA(S("\u673A\u5668\u4EBA\u6B63\u5728\u79FB\u9664\u6216\u5DF2\u91CD\u65B0\u63A5\u5165\uFF0C\u65E0\u6CD5\u5207\u6362\u539F\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\u3002"));throw s}}function d0(n){if(typeof n!="string")return!1;let A=n.trim();return nj.test(A)||oj.test(A)||aj.test(A)||ij.test(A)}var lj="9ca31362-e5b3-409c-a694-6993706a6004.schema",dj="/v1.0/card/instances/callback",gj=Object.freeze({new:"/new",history:"/history",stop:"/stop",compact:"/compact",status:"/status",help:"/help"});function Yy(n){return typeof n=="string"&&/^\/(?:m|menu)$/iu.test(n.trim())}var Ij=n=>`/preset ${/^\d+$/u.test(n)?"id:":""}${n}`;async function p0(n,A,o,a){let e=n.currentWorkspace?.(),i=A.sessionFor(o),t={signal:a},r=await Promise.allSettled([Lo(n,t),n.listWorkspaceSessions?.(e,t),(async()=>{let Q=i?n.workspaceSession?.(i):null;return typeof Q?.models=="function"?Q.models(t):n.listModels?.(t)})(),n.agentPresetSettings?.(t)]);if(a?.throwIfAborted(),n.currentWorkspace?.()!==e||A.sessionFor(o)!==i)throw new Error(S("\u4F1A\u8BDD\u6216\u5DE5\u4F5C\u533A\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001 /m\u3002"));let[s,c,g,I]=r.map(Q=>Q.status==="fulfilled"?Q.value:null),d={session:[[S("\u65B0\u4F1A\u8BDD"),"/new"],...(c?.sessions??[]).map(Q=>[Q.title||Q.sessionId,`/session ${Q.sessionId}`])],workspace:(s?.paths??(e?[e]:[])).map(Q=>[Q,`/workspace ${Q}`]),preset:[[S("\u8DDF\u968F Host \u9ED8\u8BA4"),"/preset --default"],...(I?.agentPresetCatalog?.items??[]).map(Q=>[Q.label||Q.id,Ij(Q.id)])],model:(g?.groups??[]).flatMap(Q=>Q.models.map(y=>[`${y.name} (${Q.id})`,`/model ${Q.id}/${y.id}`]))},B={session:i?`/session ${i}`:"/new",workspace:`/workspace ${e}`,preset:I?.agentPreset?Ij(I.agentPreset):"/preset --default",model:g?.current?`/model ${g.current.provider}/${g.current.model}`:null},f={revision:eCe(),notice:""};for(let[Q,y]of Object.entries(d))B[Q]&&!y.some(([,m])=>m===B[Q])&&y.unshift([Q==="session"?i:B[Q].replace(/^\/\w+\s+/u,""),B[Q]]),f[`${Q}_options`]=y.map(([m],b)=>({value:String(b),text:{zh_CN:m,en_US:m}})),f[`${Q}_index`]=y.findIndex(([,m])=>m===B[Q]);return{workspace:e,sessionId:i,selections:d,data:f}}function pj(n,A){let o;try{o=typeof A?.content=="string"?JSON.parse(A.content):A?.content}catch{return null}let{actionIds:a,params:e}=o?.cardPrivateData??{};if(!Array.isArray(a)||a.length!==1||e?.revision!==n.data.revision)return null;let i=a[0];if(Object.hasOwn(gj,i))return gj[i];let t=n.selections[i],r=e[i]?.index;return!Array.isArray(t)||!Number.isSafeInteger(r)||r<0?null:t[r]?.[1]??null}function h0(n){return{cardParamMap:Object.fromEntries(Object.entries(n).map(([A,o])=>[A,typeof o=="string"?o:JSON.stringify(o)]))}}var hj="https://oapi.dingtalk.com/",ACe="https://api.dingtalk.com/",rCe="DING_DWS_CLAW",iCe="02fcf2f4-5e02-4a85-b672-46d1f715543e.schema",fl="\u{1F914}\u601D\u8003\u4E2D",fj="\u2705\u5DF2\u5B8C\u6210",Qj="\u274C\u5904\u7406\u5931\u8D25",aCe=15e3,oCe=5e3,nCe="2659900",sCe="im_bg_1",cCe=new Set(["WAITING","SUCCESS","FAIL","EXPIRED"]),lA=class extends Error{constructor(A,o,a={}){super(o,a),this.name="DingtalkApiError",this.code=A,this.status=a.status,this.providerCode=a.providerCode}};function Vt(n){return typeof n=="string"&&n.trim()?n.trim():null}function HE(n){let A=n==null?null:String(n).trim();return A&&/^-?[A-Za-z0-9_.:-]{1,160}$/.test(A)?A:void 0}function yj(n,A){return Number.isInteger(A?.status)&&(n.status=A.status),A?.providerCode!==void 0&&(n.providerCode=A.providerCode),n}function LE(n,{fallback:A="artifact-provider-rejected"}={}){if(n?.code?.startsWith?.("artifact-"))return n;let o=Number(n?.status),a=HE(n?.providerCode),e=a??"",i=A,t="DingTalk could not prepare the file for delivery.";o===401||o===403||a==="401"||a==="403"||/(?:permission|forbidden|unauthor|access.?denied|\.auth(?:\.|$))/i.test(e)?(i="artifact-permission-required",t="DingTalk denied permission to send the file."):o===413||a==="413"||/(?:too.?large|size.?limit)/i.test(e)?(i="artifact-too-large",t="The file exceeds DingTalk's size limit."):o===429||a==="429"||/(?:rate.?limit|too.?many|throttl)/i.test(e)?(i="artifact-rate-limited",t="DingTalk rate-limited file delivery."):A==="artifact-provider-rejected"&&(t="DingTalk rejected the file message.");let r=new Error(t,{cause:n});return r.code=i,yj(r,n)}function gCe(n){let A=new Error("DingTalk file delivery result is uncertain",{cause:n});return A.code="artifact-delivery-uncertain",yj(A,n)}function jy(n){if(!n||typeof n!="object")return null;for(let A of["errcode","code"])if(n[A]!==void 0&&n[A]!==0&&n[A]!=="0")return HE(n[A])??"rejected";return null}function ICe(n,A){if(A?.aborted)throw Ns(A);let o=Number(n?.status);return n?.code==="network-error"||n?.code==="timeout"||n?.code==="invalid-response"||o>=500&&o<600?gCe(n):LE(n)}function lCe(n){let A;try{A=new URL(n)}catch(o){throw new lA("invalid-image-download","\u9489\u9489\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u56FE\u7247\u4E0B\u8F7D\u5730\u5740\u3002",{cause:o})}return A.protocol==="http:"&&(!A.port||A.port==="80")&&(A.protocol="https:",A.port=""),A}function uj(n){let A=n.toLowerCase().replace(/\.$/,"");return A==="dingtalk.com"||A.endsWith(".dingtalk.com")}function B0(n,{label:A,requireSubdomain:o=!0}={}){let a;try{a=new URL(n)}catch{throw new lA("invalid-url",`${A??"\u9489\u9489\u670D\u52A1"}\u8FD4\u56DE\u4E86\u65E0\u6548\u5730\u5740\u3002`)}let e=a.hostname.toLowerCase().replace(/\.$/,""),i=o?e!=="dingtalk.com"&&uj(e):uj(e);if(a.protocol!=="https:"||!i||a.port&&a.port!=="443")throw new lA("untrusted-url",`${A??"\u9489\u9489\u670D\u52A1"}\u5730\u5740\u4E0D\u53D7\u4FE1\u4EFB\u3002`);if(a.username||a.password)throw new lA("untrusted-url",`${A??"\u9489\u9489\u670D\u52A1"}\u5730\u5740\u4E0D\u53D7\u4FE1\u4EFB\u3002`);return a}function qg(n){let A=Vt(n);if(!A)throw new lA("invalid-session-webhook","\u9489\u9489\u6D88\u606F\u6CA1\u6709\u53EF\u7528\u7684\u56DE\u590D\u5730\u5740\u3002");let o=B0(A,{label:"\u9489\u9489\u56DE\u590D",requireSubdomain:!1});return o.hash="",o.toString()}function mj(n,A=4e3){let o=typeof n=="string"?n.trim():"";if(!o)return[];if(!Number.isInteger(A)||A<1)throw new TypeError("maxChars must be a positive integer");if(o.length<=A)return[o];let a=[],e=o;for(;e.length>A;){let i=e.lastIndexOf(`
159
159
  `,A);i<Math.floor(A*.6)&&(i=A),a.push(e.slice(0,i)),e=e.slice(i).replace(/^\n+/,"")}return e&&a.push(e),a}function Ns(n){return n?.reason instanceof Error?n.reason:new DOMException("The operation was aborted","AbortError")}function dCe(n,A){return n<=0?Promise.resolve():new Promise((o,a)=>{if(A?.aborted){a(Ns(A));return}let e=setTimeout(()=>{A?.removeEventListener("abort",i),o()},n),i=()=>{clearTimeout(e),a(Ns(A))};A?.addEventListener("abort",i,{once:!0})})}async function jn(n,A,{body:o,signal:a,timeoutMs:e=aCe,headers:i={},method:t="POST",action:r="request"}={}){let s=new AbortController,c=!1,g=()=>s.abort(a?.reason);if(a?.aborted)throw Ns(a);a?.addEventListener("abort",g,{once:!0});let I=e>0?setTimeout(()=>{c=!0,s.abort()},e):null;try{let d=await n(A,{method:t,redirect:"error",headers:{"content-type":"application/json",...i},body:JSON.stringify(o??{}),signal:s.signal});if(!d.ok){let B;try{let f=await d.json();B=HE(f?.code??f?.errcode)}catch{}throw new lA("http-error",`\u9489\u9489\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${d.status}\uFF09\u3002`,{status:d.status,providerCode:B})}try{return await d.json()}catch(B){throw new lA("invalid-response","\u9489\u9489\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:B})}}catch(d){throw a?.aborted?Ns(a):c?new lA("timeout","\u9489\u9489\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:d}):d instanceof lA?d:new lA("network-error",`\u6682\u65F6\u65E0\u6CD5\u5B8C\u6210\u9489\u9489${r}\u8BF7\u6C42\u3002`,{cause:d})}finally{I&&clearTimeout(I),a?.removeEventListener("abort",g)}}async function pCe(n,A,{body:o,signal:a,timeoutMs:e=6e4}={}){let i=new AbortController,t=!1,r=()=>i.abort(a?.reason);if(a?.aborted)throw Ns(a);a?.addEventListener("abort",r,{once:!0});let s=setTimeout(()=>{t=!0,i.abort()},e);try{let c=await n(A,{method:"POST",body:o,signal:i.signal,redirect:"error"}),g,I;try{g=await c.json()}catch(d){I=d}if(!c.ok)throw new lA("http-error",`\u9489\u9489\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${c.status}\uFF09\u3002`,{status:c.status,providerCode:HE(g?.code??g?.errcode)});if(I)throw new lA("invalid-response","\u9489\u9489\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002",{cause:I});return g}catch(c){throw a?.aborted?Ns(a):t?new lA("timeout","\u9489\u9489\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002",{cause:c}):c instanceof lA?c:new lA("network-error","\u6682\u65F6\u65E0\u6CD5\u5B8C\u6210\u9489\u9489\u6587\u4EF6\u4E0A\u4F20\u8BF7\u6C42\u3002",{cause:c})}finally{clearTimeout(s),a?.removeEventListener("abort",r)}}function Ej(n){let A=Vt(n?.robotCode);if(!A)throw new TypeError("DingTalk robotCode is required");if(n?.type==="group"){let o=Vt(n.openConversationId);if(o)return{type:"group",robotCode:A,openConversationId:o}}if(n?.type==="user"){let o=Vt(n.userId);if(o)return{type:"user",robotCode:A,userId:o}}throw new TypeError("DingTalk file target is invalid")}function hCe(n){return tCe(n).slice(1).toLowerCase()}function Cj(n){if(n?.type==="user"){let A=Vt(n.userId);if(A)return{type:"user",userId:A}}if(n?.type==="group"){let A=Vt(n.openConversationId);if(A)return{type:"group",openConversationId:A,atUserIds:n.atUserIds}}throw new TypeError("DingTalk AI Card target is invalid")}function UE(n,A){let o=e=>String(e).replace(/[&<>"']/g,i=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[i]),a=A?.type==="group"?Object.entries(A.atUserIds??{}).map(([e,i])=>`<a atId="${o(e)}">${o(i)}</a>`).join(" "):"";return uCe(a?`${a}
160
160
 
161
- ${n}`:n)}function u0(n,A,o){return{cardParamMap:{flowStatus:A,msgContent:UE(n,o),staticMsgContent:"",sys_full_json_obj:JSON.stringify({order:["msgContent"]}),config:JSON.stringify({autoLayout:!0})}}}function Bj(n,A,o){let a={outTrackId:n,userIdType:1};return A.type==="group"?{...a,openSpaceId:`dtv1.card//IM_GROUP.${A.openConversationId}`,imGroupOpenDeliverModel:{robotCode:o,atUserIds:A.atUserIds}}:{...a,openSpaceId:`dtv1.card//IM_ROBOT.${A.userId}`,imRobotOpenDeliverModel:{spaceType:"IM_ROBOT",robotCode:o,extension:{dynamicSummary:"true"}}}}function uCe(n){let o=(typeof n=="string"?n.replace(/\r\n?/g,`
161
+ ${n}`:n)}function u0(n,A,o){let a=UE(n,o);return{cardParamMap:{flowStatus:A,msgContent:a,staticMsgContent:"",sys_full_json_obj:JSON.stringify({order:["msgContent"]}),config:JSON.stringify({autoLayout:!0})}}}function Bj(n,A,o){let a={outTrackId:n,userIdType:1};return A.type==="group"?{...a,openSpaceId:`dtv1.card//IM_GROUP.${A.openConversationId}`,imGroupOpenDeliverModel:{robotCode:o,atUserIds:A.atUserIds}}:{...a,openSpaceId:`dtv1.card//IM_ROBOT.${A.userId}`,imRobotOpenDeliverModel:{spaceType:"IM_ROBOT",robotCode:o,extension:{dynamicSummary:"true"}}}}function uCe(n){let o=(typeof n=="string"?n.replace(/\r\n?/g,`
162
162
  `):"").split(`
163
163
  `),a=!1;return o.map((e,i)=>{let t=/^\s{0,3}```/.test(e),r=a;return t&&(a=!a),i===o.length-1?e:r||t||a||!e||!o[i+1]?`${e}
164
164
  `:/^\s{0,3}(?:[-*+] |\d+[.)] |#{1,6} |\||> )/.test(o[i+1])?`${e}
165
- `:`${e}<br>`}).join("")}function E0(n,A){if(!n||typeof n!="object"||n.errcode!==0)throw new lA("registration-rejected",`\u9489\u9489\u626B\u7801${A}\u5931\u8D25\u3002`);return n}function C0(n,A){let o=Number(n);return Number.isFinite(o)&&o>0?o:A}function Sj({fetchImpl:n=fetch,registrationBaseUrl:A=process.env.DINGTALK_REGISTRATION_BASE_URL||hj,registrationSource:o=process.env.DINGTALK_REGISTRATION_SOURCE||rCe,now:a=()=>Date.now(),cardMinIntervalMs:e=50,cardBackoffMs:i=1e3,delay:t=dCe}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");if(typeof a!="function")throw new TypeError("now must be a function");if(!Number.isFinite(e)||e<0)throw new TypeError("cardMinIntervalMs must be a non-negative number");if(!Number.isFinite(i)||i<0)throw new TypeError("cardBackoffMs must be a non-negative number");if(typeof t!="function")throw new TypeError("delay must be a function");let r=B0(A,{label:"\u9489\u9489\u6CE8\u518C\u670D\u52A1",requireSubdomain:!1}),s=new URL(ACe),c=Vt(o);if(!c)throw new TypeError("registrationSource is required");let g=new Map,I=new Map,d=new Map,B=Promise.resolve(),f=0,Q=(H,Y)=>new URL(Y.replace(/^\//,""),H);async function y({clientId:H,clientSecret:Y,signal:K,requestKind:k="normal"}){let v=Vt(H),z=Vt(Y);if(!v||!z)throw new TypeError("clientId and clientSecret are required");let F=g.get(v);if(F&&F.expiresAt>a())return F.token;let R=k==="reaction"?d:I;if(R.has(v))return R.get(v);let V=(async()=>{let $=await jn(n,Q(s,"v1.0/oauth2/accessToken"),{body:{appKey:v,appSecret:z},signal:K,action:"\u9274\u6743"}),Z=Vt($?.accessToken);if(!Z)throw new lA("invalid-access-token","\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u8BBF\u95EE\u4EE4\u724C\u3002");let ne=C0($?.expireIn??$?.expiresIn,7200),re=Math.max(1e3,(ne-60)*1e3);return g.set(v,{token:Z,expiresAt:a()+re}),Z})().finally(()=>R.delete(v));return R.set(v,V),V}async function m({clientId:H,clientSecret:Y,robotCode:K,messageId:k,conversationId:v,reactionName:z=fl,signal:F},R){let P=Vt(H),V=Vt(Y),$=Vt(K)??P,Z=Vt(k),ne=Vt(v),re=Vt(z);if(!P||!V)throw new TypeError("clientId and clientSecret are required");if(!$)throw new TypeError("robotCode is required");if(!Z||!ne)throw new TypeError("messageId and conversationId are required");if(!re)throw new TypeError("reactionName is required");let Se=await y({clientId:P,clientSecret:V,signal:F,requestKind:"reaction"}),De=await jn(n,Q(s,`v1.0/robot/emotion/${R}`),{body:{robotCode:$,openMsgId:Z,openConversationId:ne,emotionType:2,emotionName:re,textEmotion:{emotionId:nCe,emotionName:re,text:re,backgroundId:sCe}},headers:{"x-acs-dingtalk-access-token":Se},signal:F,timeoutMs:oCe,action:R==="reply"?"\u6D88\u606F\u72B6\u6001\u6DFB\u52A0":"\u6D88\u606F\u72B6\u6001\u64A4\u56DE"}),me=De?.success===!1?HE(De?.code??De?.errcode)??"rejected":jy(De);if(me)throw new lA("reaction-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6D88\u606F\u72B6\u6001\u8BF7\u6C42\u3002",{providerCode:me});return!0}async function b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:z}){let F=Vt(K),R=Vt(k);if(!F||!R)throw new TypeError("robotCode and downloadCode are required");let P=await y({clientId:H,clientSecret:Y,signal:v}),V;try{V=await jn(n,Q(s,"v1.0/robot/messageFiles/download"),{body:{downloadCode:R,robotCode:F},headers:{"x-acs-dingtalk-access-token":P},signal:v,action:`${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740`})}catch(Z){throw v?.aborted?Z:new lA(`${z}-download-address-failed`,`\u9489\u9489${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740\u83B7\u53D6\u5931\u8D25\u3002`,{cause:Z,status:Z?.status,providerCode:Z?.providerCode})}let $=Vt(V?.downloadUrl??V?.download_url);if(!$)throw new lA(`invalid-${z}-download`,`\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740\u3002`);return lCe($)}function M(H){let Y=async()=>{let k=Math.max(0,f-a());k>0&&await t(k,H),f=Math.max(f,a())+e},K=B.then(Y,Y);return B=K.catch(()=>{}),K}async function N(H,Y){await M(Y.signal);try{return await jn(n,Q(s,H),Y)}catch(K){if(!(K instanceof lA)||K.status!==403)throw K;return await t(i,Y.signal),await M(Y.signal),jn(n,Q(s,H),Y)}}async function U({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let V={"x-acs-dingtalk-access-token":await y({clientId:H,clientSecret:Y,signal:z})},$=[N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:UE(R,v),isFull:!0,isFinalize:!1,isError:!0},headers:V,signal:z,action:"AI Card \u5931\u8D25\u6536\u53E3"}),N("v1.0/card/instances",{method:"PUT",body:{outTrackId:F,cardData:u0(R,"5",v),cardUpdateOptions:{updateCardDataByKey:!0}},headers:V,signal:z,action:"AI Card \u5931\u8D25\u72B6\u6001"})],Z=await Promise.allSettled($);if(Z.every(({status:ne})=>ne==="rejected"))throw Z[0].reason;return!0}async function x({clientId:H,clientSecret:Y,target:K,file:k,signal:v},{uploadType:z,messageKey:F,createMessageParams:R}){if(!k||typeof k!="object"||typeof k.fileName!="string"||!k.fileName||!Buffer.isBuffer(k.bytes))throw new TypeError("A DingTalk file is required");let P=Ej(K),V;try{V=await y({clientId:H,clientSecret:Y,signal:v})}catch(Be){if(v?.aborted)throw Ns(v);let Pe=Number(Be?.status),pe=Be?.code==="http-error"&&Pe>=400&&Pe<500?"artifact-provider-rejected":"artifact-provider-failed";throw LE(Be,{fallback:pe})}let $=new URL("media/upload",hj);$.searchParams.set("access_token",V),$.searchParams.set("type",z);let Z=new FormData;Z.append("media",new Blob([k.bytes],{type:k.mediaType??"application/octet-stream"}),k.fileName);let ne;try{ne=await pCe(n,$,{body:Z,signal:v})}catch(Be){if(v?.aborted)throw Ns(v);let Pe=Number(Be?.status),pe=Be?.code==="http-error"&&Pe>=400&&Pe<500?"artifact-provider-rejected":"artifact-provider-failed";throw LE(Be,{fallback:pe})}let re=jy(ne),Se=Vt(ne?.media_id);if(re||!Se)throw LE(new lA("upload-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u4E0A\u4F20\u3002",{providerCode:re??"missing-media-id"}));v?.throwIfAborted();let De={robotCode:P.robotCode,msgKey:F,msgParam:JSON.stringify(R(Se,k)),...P.type==="group"?{openConversationId:P.openConversationId}:{userIds:[P.userId]}},me=P.type==="group"?"v1.0/robot/groupMessages/send":"v1.0/robot/oToMessages/batchSend",ve;try{ve=await jn(n,Q(s,me),{body:De,headers:{"x-acs-dingtalk-access-token":V},signal:v,action:"\u6587\u4EF6\u6D88\u606F\u53D1\u9001"})}catch(Be){throw ICe(Be,v)}let ge=jy(ve);if(ge)throw LE(new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u6D88\u606F\u3002",{providerCode:ge}));return ve}return Object.freeze({async beginRegistration({signal:H}={}){let Y=E0(await jn(n,Q(r,"app/registration/init"),{body:{source:c},signal:H,action:"\u521D\u59CB\u5316"}),"\u521D\u59CB\u5316"),K=Vt(Y.nonce);if(!K)throw new lA("invalid-registration","\u9489\u9489\u626B\u7801\u521D\u59CB\u5316\u7F3A\u5C11 nonce\u3002");let k=E0(await jn(n,Q(r,"app/registration/begin"),{body:{nonce:K},signal:H,action:"\u521B\u5EFA"}),"\u521B\u5EFA"),v=Vt(k.device_code),z=Vt(k.verification_uri_complete);if(!v||!z)throw new lA("invalid-registration","\u9489\u9489\u626B\u7801\u670D\u52A1\u8FD4\u56DE\u7684\u4FE1\u606F\u4E0D\u5B8C\u6574\u3002");let F=B0(z,{label:"\u9489\u9489\u626B\u7801",requireSubdomain:!1}).toString();return{deviceCode:v,userCode:Vt(k.user_code)??void 0,verificationUri:Vt(k.verification_uri)??void 0,verificationUriComplete:F,expiresInSeconds:C0(k.expires_in,7200),intervalSeconds:C0(k.interval,5)}},async pollRegistration({deviceCode:H,signal:Y}={}){let K=Vt(H);if(!K)throw new TypeError("deviceCode is required");let k=E0(await jn(n,Q(r,"app/registration/poll"),{body:{device_code:K},signal:Y,action:"\u72B6\u6001\u67E5\u8BE2"}),"\u72B6\u6001\u67E5\u8BE2"),v=Vt(k.status)?.toUpperCase();if(!v||!cCe.has(v))throw new lA("invalid-registration-status","\u9489\u9489\u626B\u7801\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u72B6\u6001\u3002");let z={status:v,failReason:Vt(k.fail_reason)??void 0};if(v==="SUCCESS"&&(z.clientId=Vt(k.client_id)??void 0,z.clientSecret=Vt(k.client_secret)??void 0,!z.clientId||!z.clientSecret))throw new lA("missing-credentials","\u9489\u9489\u626B\u7801\u5DF2\u786E\u8BA4\uFF0C\u4F46\u6CA1\u6709\u8FD4\u56DE\u673A\u5668\u4EBA\u51ED\u636E\u3002");return z},accessToken:y,async addReaction(H){return m(H,"reply")},async recallReaction(H){return m(H,"recall")},async addThinkingReaction(H){return m({...H,reactionName:fl},"reply")},async recallThinkingReaction(H){return m({...H,reactionName:fl},"recall")},async downloadImage({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,maxBytes:z}){let F=await b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:"image"});try{return await sn(F,{fetchImpl:n,signal:v,maxBytes:z})}catch(R){throw v?.aborted||R instanceof mA?R:new lA("image-content-download-failed","\u9489\u9489\u56FE\u7247\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\u3002",{cause:R})}},async downloadFile({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v}){let z=await b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:"file"});if(z.protocol!=="https:")throw new lA("invalid-file-download","\u9489\u9489\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u6587\u4EF6\u4E0B\u8F7D\u5730\u5740\u3002");try{let F=await n(z,{method:"GET",redirect:"follow",signal:v});if(!F?.ok)throw await F?.body?.cancel?.().catch?.(()=>{}),new lA("file-content-download-failed",`\u9489\u9489\u6587\u4EF6\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${F?.status??"unknown"}\uFF09\u3002`,{status:F?.status});return Buffer.from(await F.arrayBuffer())}catch(F){throw v?.aborted?Ns(v):F instanceof lA?F:new lA("file-content-download-failed","\u9489\u9489\u6587\u4EF6\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\u3002",{cause:F})}},async createMenuCard({clientId:H,clientSecret:Y,target:K,data:k,signal:v}){let z=Cj(K),F=await y({clientId:H,clientSecret:Y,signal:v}),R=`dsh_menu_${Bp()}`,P={"x-acs-dingtalk-access-token":F};return await N("v1.0/card/instances/createAndDeliver",{body:{...Bj(R,z,H),cardTemplateId:lj,outTrackId:R,cardData:h0(k),callbackType:"STREAM",imGroupOpenSpaceModel:{supportForward:!1},imRobotOpenSpaceModel:{supportForward:!1}},headers:P,signal:v,action:"\u83DC\u5355\u5361\u7247\u521B\u5EFA"}),{cardInstanceId:R}},async updateMenuCard({clientId:H,clientSecret:Y,cardInstanceId:K,data:k,signal:v}){if(!Vt(K))throw new TypeError("cardInstanceId is required");let z=await y({clientId:H,clientSecret:Y,signal:v});return await N("v1.0/card/instances",{method:"PUT",body:{outTrackId:K,cardData:h0(k),cardUpdateOptions:{updateCardDataByKey:!0}},headers:{"x-acs-dingtalk-access-token":z},signal:v,action:"\u83DC\u5355\u5361\u7247\u66F4\u65B0"}),!0},async createAiCard({clientId:H,clientSecret:Y,target:K,initialText:k,signal:v}){let z=Vt(H),F=Vt(Y),R=Vt(k);if(!z||!F)throw new TypeError("clientId and clientSecret are required");if(!R)throw new TypeError("initialText is required");let P=Cj(K),V=await y({clientId:z,clientSecret:F,signal:v}),$=`dsh_${Bp()}`,Z={"x-acs-dingtalk-access-token":V},ne=!1;try{await N("v1.0/card/instances",{body:{cardTemplateId:iCe,outTrackId:$,cardData:{cardParamMap:{config:JSON.stringify({autoLayout:!0})}},callbackType:"STREAM",cardAtUserIds:P.atUserIds?Object.keys(P.atUserIds):void 0,imGroupOpenSpaceModel:{supportForward:!0},imRobotOpenSpaceModel:{supportForward:!0}},headers:Z,signal:v,action:"AI Card \u521B\u5EFA"}),await N("v1.0/card/instances/deliver",{body:Bj($,P,z),headers:Z,signal:v,action:"AI Card \u6295\u653E"}),ne=!0,await N("v1.0/card/instances",{method:"PUT",body:{outTrackId:$,cardData:u0(R,"2",P)},headers:Z,signal:v,action:"AI Card \u542F\u52A8"}),await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:$,guid:Bp(),key:"msgContent",content:UE(R,P).replace(/\n+$/,""),isFull:!0,isFinalize:!1,isError:!1},headers:Z,signal:v,action:"AI Card \u542F\u52A8"})}catch(re){if(ne){let Se=AbortSignal.timeout(5e3);await U({clientId:z,clientSecret:F,cardInstanceId:$,text:S("\u5361\u7247\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u67E5\u770B\u540E\u7EED\u6D88\u606F\u3002"),target:P,signal:Se}).catch(()=>{})}throw re}return{cardInstanceId:$}},async updateAiCard({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let P=await y({clientId:H,clientSecret:Y,signal:z});return await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:UE(R,v).replace(/\n+$/,""),isFull:!0,isFinalize:!1,isError:!1},headers:{"x-acs-dingtalk-access-token":P},signal:z,action:"AI Card \u66F4\u65B0"}),!0},async finishAiCard({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let V={"x-acs-dingtalk-access-token":await y({clientId:H,clientSecret:Y,signal:z})},$=UE(R,v);await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:$,isFull:!0,isFinalize:!0,isError:!1},headers:V,signal:z,action:"AI Card \u5B8C\u6210"});let Z=!0,ne={method:"PUT",body:{outTrackId:F,cardData:u0(R,"3",v),cardUpdateOptions:{updateCardDataByKey:!0}},headers:V,signal:z,action:"AI Card \u6536\u53E3"};try{await N("v1.0/card/instances",ne)}catch{try{await N("v1.0/card/instances",ne)}catch{Z=!1}}return{delivered:!0,completed:Z}},failAiCard:U,async sendText({clientId:H,clientSecret:Y,sessionWebhook:K,text:k,at:v,signal:z}){let F=Vt(k);if(!F)throw new TypeError("text is required");let R=qg(K),P=await y({clientId:H,clientSecret:Y,signal:z}),V=v&&typeof v=="object"&&(Array.isArray(v.atUserIds)&&v.atUserIds.length>0||Array.isArray(v.atMobiles)&&v.atMobiles.length>0||v.isAtAll===!0)?{at:v}:{},$=await jn(n,R,{body:{msgtype:"text",text:{content:F},...V},headers:{"x-acs-dingtalk-access-token":P},signal:z,action:"\u6D88\u606F\u56DE\u590D"});if($?.errcode!==void 0&&$.errcode!==0||$?.code!==void 0&&$.code!==0)throw new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async sendRobotText({clientId:H,clientSecret:Y,target:K,text:k,signal:v}){if(typeof k!="string"||!k.trim())throw new TypeError("text is required");let z=k,F=Ej(K),R=await y({clientId:H,clientSecret:Y,signal:v}),P={robotCode:F.robotCode,msgKey:"sampleText",msgParam:JSON.stringify({content:z}),...F.type==="group"?{openConversationId:F.openConversationId}:{userIds:[F.userId]}},V=F.type==="group"?"v1.0/robot/groupMessages/send":"v1.0/robot/oToMessages/batchSend",$=await jn(n,Q(s,V),{body:P,headers:{"x-acs-dingtalk-access-token":R},signal:v,action:"\u4E3B\u52A8\u6587\u5B57\u6D88\u606F\u53D1\u9001"}),Z=jy($);if(Z)throw new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u4E3B\u52A8\u6587\u5B57\u6D88\u606F\u3002",{providerCode:Z});return $},async sendFile(H){return x(H,{uploadType:"file",messageKey:"sampleFile",createMessageParams:(Y,K)=>({mediaId:Y,fileName:K.fileName,fileType:hCe(K.fileName)})})},async sendImage(H){return x(H,{uploadType:"image",messageKey:"sampleImageMsg",createMessageParams:Y=>({photoURL:Y})})},clearAccessToken(H){let Y=Vt(H);Y&&g.delete(Y)}})}import{spawn as ABe}from"node:child_process";import{randomUUID as Vy}from"node:crypto";import{isAbsolute as rBe}from"node:path";import{isAbsolute as ECe}from"node:path";var CCe=256,BCe=/[\p{White_Space}\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u,fCe=/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;function xE(n,A){let o=new Error(A);return o.code=n,o}function QCe(n){if(typeof n!="string"||!n||n.length>CCe||BCe.test(n))throw xE("session-id-invalid","A non-empty, safe session id is required");return n}function yCe(n,A){if(!Array.isArray(A?.items)||!Array.isArray(A?.archivedSessionIds)||A.archivedSessionIds.some(a=>typeof a!="string"||!a))throw new Error("Harness returned an invalid response for workspace.list");let o=[];for(let a of A.items){if(typeof a?.workspaceId!="string"||!a.workspaceId||typeof a.path!="string"||!ECe(a.path)||!Array.isArray(a.sessionIds)||a.sessionIds.some(e=>typeof e!="string"||!e))throw new Error("Harness returned an invalid response for workspace.list");for(let e of a.sessionIds)e===n&&o.push(a)}if(o.length===0)throw xE("session-not-registered","The session is not registered to a Harness workspace");if(o.length!==1)throw xE("session-workspace-ambiguous","The session is registered to more than one Harness workspace");if(fCe.test(o[0].path))throw new Error("Harness returned an unsafe workspace path for the session");return{workspace:o[0],archived:A.archivedSessionIds.includes(n)}}function mCe(n,A){if(!Array.isArray(A?.items)||A.items.some(i=>typeof i?.sessionId!="string"||!i.sessionId))throw new Error("Harness returned an invalid response for session.list");let o=A.items.filter(i=>i.sessionId===n);if(o.length===0)throw xE("session-summary-unavailable","The session is no longer available from Harness");if(o.length!==1)throw new Error("Harness returned duplicate session summaries for session.list");let[a]=o;if(a.origin==="subagent")throw xE("session-subagent-unsupported","Subagent sessions cannot be adopted as a bot conversation");if(a.origin!==void 0)throw new Error("Harness returned an invalid session origin for session.list");let e=a.projections?.values?.title;if(e!=null&&typeof e!="string")throw new Error("Harness returned an invalid session title for session.list");return{title:typeof e=="string"?e:null}}async function wj(n,A,o={},a=3e4){let e=QCe(A);await n.ensureRunning(o);let i=await n.rpc("workspace.list",{},a,o),{workspace:t,archived:r}=yCe(e,i),s=mCe(e,await n.rpc("session.list",{},a,o)),c=await n.rpc("session.create",{workspaceId:t.workspaceId,sessionId:e},a,o);if(!c||c.sessionId!==e)throw new Error("Harness returned an invalid response for session.create");return{sessionId:e,workspace:t.path,title:s.title,archived:r}}import{createWriteStream as SCe}from"node:fs";import{mkdir as wCe,mkdtemp as DCe,readdir as bCe,realpath as Dj,rm as f0,writeFile as OCe}from"node:fs/promises";import{isAbsolute as Q0,join as YE,relative as bj,resolve as y0}from"node:path";import{pipeline as MCe}from"node:stream/promises";var Oj=YE(".dsh-im","inbound"),_Ce=new Set(["turn","persistent"]),TCe=/^(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})/;function KE(n){return String(n).padStart(2,"0")}function NCe(n=new Date){return`${n.getFullYear()}${KE(n.getMonth()+1)}${KE(n.getDate())}-${KE(n.getHours())}${KE(n.getMinutes())}${KE(n.getSeconds())}-`}function RCe(n){if(typeof n!="string")return null;let A=TCe.exec(n);if(!A)return null;let[o,a,e,i,t,r]=A.slice(1).map(Number),s=new Date(o,a-1,e,i,t,r);return s.getFullYear()!==o||s.getMonth()!==a-1||s.getDate()!==e||s.getHours()!==i||s.getMinutes()!==t||s.getSeconds()!==r?null:s}var co=class extends Error{constructor(A,o,a=S("\u6587\u4EF6\u63A5\u6536\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),e={}){super(o,e),this.name="InboundFileError",this.code=A,this.userMessage=a}};function m0(n){return Array.isArray(n?.files)?n.files.filter(Boolean):[]}function Mj(n,A){return typeof n!="string"?A:n.replaceAll("\\","/").split("/").at(-1)?.replace(/[\u0000-\u001f\u007f]/g,"").trim()||A}function kCe(n,A){let o=Mj(n,"file").replace(/[^\p{L}\p{N}._ -]/gu,"_").replace(/^\.+/,"").slice(0,160)||"file";return`${String(A+1).padStart(2,"0")}-${o}`}function vCe(n){if(Buffer.isBuffer(n)||n instanceof Uint8Array)return{data:Buffer.from(n)};let A=n?.data??n?.buffer;if(Buffer.isBuffer(A)||A instanceof Uint8Array)return{data:Buffer.from(A),name:n?.name??n?.filename,mediaType:n?.mediaType??n?.mimetype};let o=n?.stream??n;return o&&typeof o[Symbol.asyncIterator]=="function"?{stream:o,name:n?.name??n?.filename,mediaType:n?.mediaType??n?.mimetype}:null}function pA(n){return m0(n).length>0}function fp(n,{signal:A}={}){let o=m0(n);return o.length===0?n:{...n,files:o.map(a=>{if(a?.data!==void 0||typeof a?.load!="function")return a;let e;try{e=Promise.resolve(a.load({signal:A}))}catch(i){e=Promise.reject(i)}return e.catch(()=>{}),{...a,async load({signal:i}={}){i?.throwIfAborted();let t=await e;return i?.throwIfAborted(),t}}})}}async function _j(n,{workspace:A,signal:o,retention:a="turn",onStagedDirectory:e=null}={}){if(!_Ce.has(a))throw new co("inbound-file-retention-invalid",`Unknown inbound file retention: ${String(a)}`);if(e!==null&&typeof e!="function")throw new TypeError("onStagedDirectory must be a function");let i=m0(n);if(i.length===0)return null;if(typeof A!="string"||!Q0(A))throw new co("inbound-file-workspace-unavailable","The Harness Session workspace is unavailable for inbound files.");o?.throwIfAborted();let t=y0(A,Oj);await wCe(t,{recursive:!0,mode:448});let r=await DCe(YE(t,NCe()));e?.(r);let s=[];try{for(let[c,g]of i.entries()){o?.throwIfAborted();let I;try{I=g?.data===void 0?await g?.load?.({signal:o}):g.data}catch(y){throw o?.aborted?y:new co("inbound-file-download-failed",`Unable to download inbound file ${c+1}: ${y?.message??String(y)}`,S("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),{cause:y})}let d=vCe(I);if(!d)throw new co("inbound-file-data-invalid",`Inbound file ${c+1} returned no readable data.`);let B=Mj(d.name??g?.name,`file-${c+1}`),f=YE(r,kCe(B,c));if(d.data)await OCe(f,d.data,{mode:384,signal:o});else try{await MCe(d.stream,SCe(f,{flags:"wx",mode:384}),{signal:o})}catch(y){throw o?.aborted?y:new co("inbound-file-download-failed",`Unable to stream inbound file ${c+1}: ${y?.message??String(y)}`,S("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),{cause:y})}let Q=bj(y0(A),f);if(!Q||Q.startsWith("..")||Q0(Q))throw new co("inbound-file-path-invalid","The staged inbound file escaped the Harness Session workspace.");s.push(Object.freeze({name:B,path:Q,...typeof(d.mediaType??g?.mediaType)=="string"&&(d.mediaType??g.mediaType).trim()?{mediaType:(d.mediaType??g.mediaType).trim()}:{}}))}return Object.freeze({files:Object.freeze(s),directory:r,retention:a,async cleanup(){a==="turn"&&await f0(r,{recursive:!0,force:!0})}})}catch(c){throw await f0(r,{recursive:!0,force:!0}).catch(()=>{}),c}}async function Tj(n,A,{now:o=()=>new Date,isTracked:a}={}){if(typeof n!="string"||!n)throw new TypeError("sweepInboundAttachments requires a workspace");if(A!==0&&!(Number.isInteger(A)&&A>0))return{deleted:0};let e=y0(n,Oj),i,t;try{[i,t]=await Promise.all([Dj(n),Dj(e)])}catch(I){if(I?.code==="ENOENT")return{deleted:0};throw I}let r=bj(i,t);if(!r||r.startsWith("..")||Q0(r))throw new co("inbound-file-root-outside-workspace","The inbound attachment directory does not resolve inside the Harness Session workspace.");let s;try{s=await bCe(t,{withFileTypes:!0})}catch(I){if(I?.code==="ENOENT")return{deleted:0};throw I}let c=o(),g=0;for(let I of s){if(!I.isDirectory())continue;let d=RCe(I.name);if(d===null)continue;let B=YE(e,I.name),f=YE(t,I.name);if(typeof a=="function"&&(a(B)||B!==f&&a(f)))continue;let Q=(c-d)/36e5;if(A===0||Q>=A)try{await f0(f,{recursive:!0,force:!0}),g+=1}catch{}}return{deleted:g}}function S0(n,A){if(!A?.files?.length)return n;let o=["<dsh_im_files>",JSON.stringify({description:"Files uploaded with this user message. Paths are relative to the current Harness workspace.",files:A.files}),"</dsh_im_files>"].join(`
165
+ `:`${e}<br>`}).join("")}function E0(n,A){if(!n||typeof n!="object"||n.errcode!==0)throw new lA("registration-rejected",`\u9489\u9489\u626B\u7801${A}\u5931\u8D25\u3002`);return n}function C0(n,A){let o=Number(n);return Number.isFinite(o)&&o>0?o:A}function Sj({fetchImpl:n=fetch,registrationBaseUrl:A=process.env.DINGTALK_REGISTRATION_BASE_URL||hj,registrationSource:o=process.env.DINGTALK_REGISTRATION_SOURCE||rCe,now:a=()=>Date.now(),cardMinIntervalMs:e=50,cardBackoffMs:i=1e3,delay:t=dCe}={}){if(typeof n!="function")throw new TypeError("fetchImpl must be a function");if(typeof a!="function")throw new TypeError("now must be a function");if(!Number.isFinite(e)||e<0)throw new TypeError("cardMinIntervalMs must be a non-negative number");if(!Number.isFinite(i)||i<0)throw new TypeError("cardBackoffMs must be a non-negative number");if(typeof t!="function")throw new TypeError("delay must be a function");let r=B0(A,{label:"\u9489\u9489\u6CE8\u518C\u670D\u52A1",requireSubdomain:!1}),s=new URL(ACe),c=Vt(o);if(!c)throw new TypeError("registrationSource is required");let g=new Map,I=new Map,d=new Map,B=Promise.resolve(),f=0,Q=(H,Y)=>new URL(Y.replace(/^\//,""),H);async function y({clientId:H,clientSecret:Y,signal:K,requestKind:k="normal"}){let v=Vt(H),z=Vt(Y);if(!v||!z)throw new TypeError("clientId and clientSecret are required");let F=g.get(v);if(F&&F.expiresAt>a())return F.token;let R=k==="reaction"?d:I;if(R.has(v))return R.get(v);let V=(async()=>{let $=await jn(n,Q(s,"v1.0/oauth2/accessToken"),{body:{appKey:v,appSecret:z},signal:K,action:"\u9274\u6743"}),Z=Vt($?.accessToken);if(!Z)throw new lA("invalid-access-token","\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u8BBF\u95EE\u4EE4\u724C\u3002");let ne=C0($?.expireIn??$?.expiresIn,7200),re=Math.max(1e3,(ne-60)*1e3);return g.set(v,{token:Z,expiresAt:a()+re}),Z})().finally(()=>R.delete(v));return R.set(v,V),V}async function m({clientId:H,clientSecret:Y,robotCode:K,messageId:k,conversationId:v,reactionName:z=fl,signal:F},R){let P=Vt(H),V=Vt(Y),$=Vt(K)??P,Z=Vt(k),ne=Vt(v),re=Vt(z);if(!P||!V)throw new TypeError("clientId and clientSecret are required");if(!$)throw new TypeError("robotCode is required");if(!Z||!ne)throw new TypeError("messageId and conversationId are required");if(!re)throw new TypeError("reactionName is required");let Se=await y({clientId:P,clientSecret:V,signal:F,requestKind:"reaction"}),De=await jn(n,Q(s,`v1.0/robot/emotion/${R}`),{body:{robotCode:$,openMsgId:Z,openConversationId:ne,emotionType:2,emotionName:re,textEmotion:{emotionId:nCe,emotionName:re,text:re,backgroundId:sCe}},headers:{"x-acs-dingtalk-access-token":Se},signal:F,timeoutMs:oCe,action:R==="reply"?"\u6D88\u606F\u72B6\u6001\u6DFB\u52A0":"\u6D88\u606F\u72B6\u6001\u64A4\u56DE"}),me=De?.success===!1?HE(De?.code??De?.errcode)??"rejected":jy(De);if(me)throw new lA("reaction-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6D88\u606F\u72B6\u6001\u8BF7\u6C42\u3002",{providerCode:me});return!0}async function b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:z}){let F=Vt(K),R=Vt(k);if(!F||!R)throw new TypeError("robotCode and downloadCode are required");let P=await y({clientId:H,clientSecret:Y,signal:v}),V;try{V=await jn(n,Q(s,"v1.0/robot/messageFiles/download"),{body:{downloadCode:R,robotCode:F},headers:{"x-acs-dingtalk-access-token":P},signal:v,action:`${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740`})}catch(Z){throw v?.aborted?Z:new lA(`${z}-download-address-failed`,`\u9489\u9489${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740\u83B7\u53D6\u5931\u8D25\u3002`,{cause:Z,status:Z?.status,providerCode:Z?.providerCode})}let $=Vt(V?.downloadUrl??V?.download_url);if(!$)throw new lA(`invalid-${z}-download`,`\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE${z==="image"?"\u56FE\u7247":"\u6587\u4EF6"}\u4E0B\u8F7D\u5730\u5740\u3002`);return lCe($)}function M(H){let Y=async()=>{let k=Math.max(0,f-a());k>0&&await t(k,H),f=Math.max(f,a())+e},K=B.then(Y,Y);return B=K.catch(()=>{}),K}async function N(H,Y){await M(Y.signal);try{return await jn(n,Q(s,H),Y)}catch(K){if(!(K instanceof lA)||K.status!==403)throw K;return await t(i,Y.signal),await M(Y.signal),jn(n,Q(s,H),Y)}}async function U({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let V={"x-acs-dingtalk-access-token":await y({clientId:H,clientSecret:Y,signal:z})},$=[N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:UE(R,v),isFull:!0,isFinalize:!1,isError:!0},headers:V,signal:z,action:"AI Card \u5931\u8D25\u6536\u53E3"}),N("v1.0/card/instances",{method:"PUT",body:{outTrackId:F,cardData:u0(R,"5",v),cardUpdateOptions:{updateCardDataByKey:!0}},headers:V,signal:z,action:"AI Card \u5931\u8D25\u72B6\u6001"})],Z=await Promise.allSettled($);if(Z.every(({status:ne})=>ne==="rejected"))throw Z[0].reason;return!0}async function x({clientId:H,clientSecret:Y,target:K,file:k,signal:v},{uploadType:z,messageKey:F,createMessageParams:R}){if(!k||typeof k!="object"||typeof k.fileName!="string"||!k.fileName||!Buffer.isBuffer(k.bytes))throw new TypeError("A DingTalk file is required");let P=Ej(K),V;try{V=await y({clientId:H,clientSecret:Y,signal:v})}catch(Be){if(v?.aborted)throw Ns(v);let Pe=Number(Be?.status),pe=Be?.code==="http-error"&&Pe>=400&&Pe<500?"artifact-provider-rejected":"artifact-provider-failed";throw LE(Be,{fallback:pe})}let $=new URL("media/upload",hj);$.searchParams.set("access_token",V),$.searchParams.set("type",z);let Z=new FormData;Z.append("media",new Blob([k.bytes],{type:k.mediaType??"application/octet-stream"}),k.fileName);let ne;try{ne=await pCe(n,$,{body:Z,signal:v})}catch(Be){if(v?.aborted)throw Ns(v);let Pe=Number(Be?.status),pe=Be?.code==="http-error"&&Pe>=400&&Pe<500?"artifact-provider-rejected":"artifact-provider-failed";throw LE(Be,{fallback:pe})}let re=jy(ne),Se=Vt(ne?.media_id);if(re||!Se)throw LE(new lA("upload-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u4E0A\u4F20\u3002",{providerCode:re??"missing-media-id"}));v?.throwIfAborted();let De={robotCode:P.robotCode,msgKey:F,msgParam:JSON.stringify(R(Se,k)),...P.type==="group"?{openConversationId:P.openConversationId}:{userIds:[P.userId]}},me=P.type==="group"?"v1.0/robot/groupMessages/send":"v1.0/robot/oToMessages/batchSend",ve;try{ve=await jn(n,Q(s,me),{body:De,headers:{"x-acs-dingtalk-access-token":V},signal:v,action:"\u6587\u4EF6\u6D88\u606F\u53D1\u9001"})}catch(Be){throw ICe(Be,v)}let ge=jy(ve);if(ge)throw LE(new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u6587\u4EF6\u6D88\u606F\u3002",{providerCode:ge}));return ve}return Object.freeze({async beginRegistration({signal:H}={}){let Y=E0(await jn(n,Q(r,"app/registration/init"),{body:{source:c},signal:H,action:"\u521D\u59CB\u5316"}),"\u521D\u59CB\u5316"),K=Vt(Y.nonce);if(!K)throw new lA("invalid-registration","\u9489\u9489\u626B\u7801\u521D\u59CB\u5316\u7F3A\u5C11 nonce\u3002");let k=E0(await jn(n,Q(r,"app/registration/begin"),{body:{nonce:K},signal:H,action:"\u521B\u5EFA"}),"\u521B\u5EFA"),v=Vt(k.device_code),z=Vt(k.verification_uri_complete);if(!v||!z)throw new lA("invalid-registration","\u9489\u9489\u626B\u7801\u670D\u52A1\u8FD4\u56DE\u7684\u4FE1\u606F\u4E0D\u5B8C\u6574\u3002");let F=B0(z,{label:"\u9489\u9489\u626B\u7801",requireSubdomain:!1}).toString();return{deviceCode:v,userCode:Vt(k.user_code)??void 0,verificationUri:Vt(k.verification_uri)??void 0,verificationUriComplete:F,expiresInSeconds:C0(k.expires_in,7200),intervalSeconds:C0(k.interval,5)}},async pollRegistration({deviceCode:H,signal:Y}={}){let K=Vt(H);if(!K)throw new TypeError("deviceCode is required");let k=E0(await jn(n,Q(r,"app/registration/poll"),{body:{device_code:K},signal:Y,action:"\u72B6\u6001\u67E5\u8BE2"}),"\u72B6\u6001\u67E5\u8BE2"),v=Vt(k.status)?.toUpperCase();if(!v||!cCe.has(v))throw new lA("invalid-registration-status","\u9489\u9489\u626B\u7801\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u72B6\u6001\u3002");let z={status:v,failReason:Vt(k.fail_reason)??void 0};if(v==="SUCCESS"&&(z.clientId=Vt(k.client_id)??void 0,z.clientSecret=Vt(k.client_secret)??void 0,!z.clientId||!z.clientSecret))throw new lA("missing-credentials","\u9489\u9489\u626B\u7801\u5DF2\u786E\u8BA4\uFF0C\u4F46\u6CA1\u6709\u8FD4\u56DE\u673A\u5668\u4EBA\u51ED\u636E\u3002");return z},accessToken:y,async addReaction(H){return m(H,"reply")},async recallReaction(H){return m(H,"recall")},async addThinkingReaction(H){return m({...H,reactionName:fl},"reply")},async recallThinkingReaction(H){return m({...H,reactionName:fl},"recall")},async downloadImage({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,maxBytes:z}){let F=await b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:"image"});try{return await sn(F,{fetchImpl:n,signal:v,maxBytes:z})}catch(R){throw v?.aborted||R instanceof mA?R:new lA("image-content-download-failed","\u9489\u9489\u56FE\u7247\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\u3002",{cause:R})}},async downloadFile({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v}){let z=await b({clientId:H,clientSecret:Y,robotCode:K,downloadCode:k,signal:v,kind:"file"});if(z.protocol!=="https:")throw new lA("invalid-file-download","\u9489\u9489\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u6587\u4EF6\u4E0B\u8F7D\u5730\u5740\u3002");try{let F=await n(z,{method:"GET",redirect:"follow",signal:v});if(!F?.ok)throw await F?.body?.cancel?.().catch?.(()=>{}),new lA("file-content-download-failed",`\u9489\u9489\u6587\u4EF6\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\uFF08HTTP ${F?.status??"unknown"}\uFF09\u3002`,{status:F?.status});return Buffer.from(await F.arrayBuffer())}catch(F){throw v?.aborted?Ns(v):F instanceof lA?F:new lA("file-content-download-failed","\u9489\u9489\u6587\u4EF6\u5185\u5BB9\u4E0B\u8F7D\u5931\u8D25\u3002",{cause:F})}},async createMenuCard({clientId:H,clientSecret:Y,target:K,data:k,signal:v}){let z=Cj(K),F=await y({clientId:H,clientSecret:Y,signal:v}),R=`dsh_menu_${Bp()}`,P={"x-acs-dingtalk-access-token":F};return await N("v1.0/card/instances/createAndDeliver",{body:{...Bj(R,z,H),cardTemplateId:lj,outTrackId:R,cardData:h0(k),callbackType:"STREAM",imGroupOpenSpaceModel:{supportForward:!1},imRobotOpenSpaceModel:{supportForward:!1}},headers:P,signal:v,action:"\u83DC\u5355\u5361\u7247\u521B\u5EFA"}),{cardInstanceId:R}},async updateMenuCard({clientId:H,clientSecret:Y,cardInstanceId:K,data:k,signal:v}){if(!Vt(K))throw new TypeError("cardInstanceId is required");let z=await y({clientId:H,clientSecret:Y,signal:v});return await N("v1.0/card/instances",{method:"PUT",body:{outTrackId:K,cardData:h0(k),cardUpdateOptions:{updateCardDataByKey:!0}},headers:{"x-acs-dingtalk-access-token":z},signal:v,action:"\u83DC\u5355\u5361\u7247\u66F4\u65B0"}),!0},async createAiCard({clientId:H,clientSecret:Y,target:K,initialText:k,signal:v}){let z=Vt(H),F=Vt(Y),R=Vt(k);if(!z||!F)throw new TypeError("clientId and clientSecret are required");if(!R)throw new TypeError("initialText is required");let P=Cj(K),V=await y({clientId:z,clientSecret:F,signal:v}),$=`dsh_${Bp()}`,Z={"x-acs-dingtalk-access-token":V},ne=!1;try{await N("v1.0/card/instances/createAndDeliver",{body:{...Bj($,P,z),cardTemplateId:iCe,outTrackId:$,cardData:u0(R,"2",P),callbackType:"STREAM",cardAtUserIds:P.atUserIds?Object.keys(P.atUserIds):void 0,imGroupOpenSpaceModel:{supportForward:!0},imRobotOpenSpaceModel:{supportForward:!0}},headers:Z,signal:v,action:"AI Card \u521B\u5EFA\u5E76\u6295\u653E"}),ne=!0;try{await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:$,guid:Bp(),key:"msgContent",content:UE(R,P).replace(/\n+$/,""),isFull:!0,isFinalize:!1,isError:!1},headers:Z,signal:v,action:"AI Card \u542F\u52A8"})}catch(re){if(v?.aborted)throw re}}catch(re){if(ne){let Se=AbortSignal.timeout(5e3);await U({clientId:z,clientSecret:F,cardInstanceId:$,text:S("\u5361\u7247\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u67E5\u770B\u540E\u7EED\u6D88\u606F\u3002"),target:P,signal:Se}).catch(()=>{})}throw re}return{cardInstanceId:$}},async updateAiCard({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let P=await y({clientId:H,clientSecret:Y,signal:z});return await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:UE(R,v).replace(/\n+$/,""),isFull:!0,isFinalize:!1,isError:!1},headers:{"x-acs-dingtalk-access-token":P},signal:z,action:"AI Card \u66F4\u65B0"}),!0},async finishAiCard({clientId:H,clientSecret:Y,cardInstanceId:K,text:k,target:v,signal:z}){let F=Vt(K),R=Vt(k);if(!F)throw new TypeError("cardInstanceId is required");if(!R)throw new TypeError("text is required");let V={"x-acs-dingtalk-access-token":await y({clientId:H,clientSecret:Y,signal:z})},$=UE(R,v);return await N("v1.0/card/streaming",{method:"PUT",body:{outTrackId:F,guid:Bp(),key:"msgContent",content:$,isFull:!0,isFinalize:!0,isError:!1},headers:V,signal:z,action:"AI Card \u5B8C\u6210"}),await N("v1.0/card/instances",{method:"PUT",body:{outTrackId:F,cardData:u0(R,"3",v),cardUpdateOptions:{updateCardDataByKey:!0}},headers:V,signal:z,action:"AI Card \u5B8C\u6210\u72B6\u6001"}),{delivered:!0,completed:!0}},failAiCard:U,async sendText({clientId:H,clientSecret:Y,sessionWebhook:K,text:k,at:v,signal:z}){let F=Vt(k);if(!F)throw new TypeError("text is required");let R=qg(K),P=await y({clientId:H,clientSecret:Y,signal:z}),V=v&&typeof v=="object"&&(Array.isArray(v.atUserIds)&&v.atUserIds.length>0||Array.isArray(v.atMobiles)&&v.atMobiles.length>0||v.isAtAll===!0)?{at:v}:{},$=await jn(n,R,{body:{msgtype:"text",text:{content:F},...V},headers:{"x-acs-dingtalk-access-token":P},signal:z,action:"\u6D88\u606F\u56DE\u590D"});if($?.errcode!==void 0&&$.errcode!==0||$?.code!==void 0&&$.code!==0)throw new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u56DE\u590D\u6D88\u606F\u3002");return!0},async sendRobotText({clientId:H,clientSecret:Y,target:K,text:k,signal:v}){if(typeof k!="string"||!k.trim())throw new TypeError("text is required");let z=k,F=Ej(K),R=await y({clientId:H,clientSecret:Y,signal:v}),P={robotCode:F.robotCode,msgKey:"sampleText",msgParam:JSON.stringify({content:z}),...F.type==="group"?{openConversationId:F.openConversationId}:{userIds:[F.userId]}},V=F.type==="group"?"v1.0/robot/groupMessages/send":"v1.0/robot/oToMessages/batchSend",$=await jn(n,Q(s,V),{body:P,headers:{"x-acs-dingtalk-access-token":R},signal:v,action:"\u4E3B\u52A8\u6587\u5B57\u6D88\u606F\u53D1\u9001"}),Z=jy($);if(Z)throw new lA("send-rejected","\u9489\u9489\u670D\u52A1\u62D2\u7EDD\u4E86\u4E3B\u52A8\u6587\u5B57\u6D88\u606F\u3002",{providerCode:Z});return $},async sendFile(H){return x(H,{uploadType:"file",messageKey:"sampleFile",createMessageParams:(Y,K)=>({mediaId:Y,fileName:K.fileName,fileType:hCe(K.fileName)})})},async sendImage(H){return x(H,{uploadType:"image",messageKey:"sampleImageMsg",createMessageParams:Y=>({photoURL:Y})})},clearAccessToken(H){let Y=Vt(H);Y&&g.delete(Y)}})}import{spawn as ABe}from"node:child_process";import{randomUUID as Vy}from"node:crypto";import{isAbsolute as rBe}from"node:path";import{isAbsolute as ECe}from"node:path";var CCe=256,BCe=/[\p{White_Space}\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u,fCe=/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;function xE(n,A){let o=new Error(A);return o.code=n,o}function QCe(n){if(typeof n!="string"||!n||n.length>CCe||BCe.test(n))throw xE("session-id-invalid","A non-empty, safe session id is required");return n}function yCe(n,A){if(!Array.isArray(A?.items)||!Array.isArray(A?.archivedSessionIds)||A.archivedSessionIds.some(a=>typeof a!="string"||!a))throw new Error("Harness returned an invalid response for workspace.list");let o=[];for(let a of A.items){if(typeof a?.workspaceId!="string"||!a.workspaceId||typeof a.path!="string"||!ECe(a.path)||!Array.isArray(a.sessionIds)||a.sessionIds.some(e=>typeof e!="string"||!e))throw new Error("Harness returned an invalid response for workspace.list");for(let e of a.sessionIds)e===n&&o.push(a)}if(o.length===0)throw xE("session-not-registered","The session is not registered to a Harness workspace");if(o.length!==1)throw xE("session-workspace-ambiguous","The session is registered to more than one Harness workspace");if(fCe.test(o[0].path))throw new Error("Harness returned an unsafe workspace path for the session");return{workspace:o[0],archived:A.archivedSessionIds.includes(n)}}function mCe(n,A){if(!Array.isArray(A?.items)||A.items.some(i=>typeof i?.sessionId!="string"||!i.sessionId))throw new Error("Harness returned an invalid response for session.list");let o=A.items.filter(i=>i.sessionId===n);if(o.length===0)throw xE("session-summary-unavailable","The session is no longer available from Harness");if(o.length!==1)throw new Error("Harness returned duplicate session summaries for session.list");let[a]=o;if(a.origin==="subagent")throw xE("session-subagent-unsupported","Subagent sessions cannot be adopted as a bot conversation");if(a.origin!==void 0)throw new Error("Harness returned an invalid session origin for session.list");let e=a.projections?.values?.title;if(e!=null&&typeof e!="string")throw new Error("Harness returned an invalid session title for session.list");return{title:typeof e=="string"?e:null}}async function wj(n,A,o={},a=3e4){let e=QCe(A);await n.ensureRunning(o);let i=await n.rpc("workspace.list",{},a,o),{workspace:t,archived:r}=yCe(e,i),s=mCe(e,await n.rpc("session.list",{},a,o)),c=await n.rpc("session.create",{workspaceId:t.workspaceId,sessionId:e},a,o);if(!c||c.sessionId!==e)throw new Error("Harness returned an invalid response for session.create");return{sessionId:e,workspace:t.path,title:s.title,archived:r}}import{createWriteStream as SCe}from"node:fs";import{mkdir as wCe,mkdtemp as DCe,readdir as bCe,realpath as Dj,rm as f0,writeFile as OCe}from"node:fs/promises";import{isAbsolute as Q0,join as YE,relative as bj,resolve as y0}from"node:path";import{pipeline as MCe}from"node:stream/promises";var Oj=YE(".dsh-im","inbound"),_Ce=new Set(["turn","persistent"]),TCe=/^(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})/;function KE(n){return String(n).padStart(2,"0")}function NCe(n=new Date){return`${n.getFullYear()}${KE(n.getMonth()+1)}${KE(n.getDate())}-${KE(n.getHours())}${KE(n.getMinutes())}${KE(n.getSeconds())}-`}function RCe(n){if(typeof n!="string")return null;let A=TCe.exec(n);if(!A)return null;let[o,a,e,i,t,r]=A.slice(1).map(Number),s=new Date(o,a-1,e,i,t,r);return s.getFullYear()!==o||s.getMonth()!==a-1||s.getDate()!==e||s.getHours()!==i||s.getMinutes()!==t||s.getSeconds()!==r?null:s}var co=class extends Error{constructor(A,o,a=S("\u6587\u4EF6\u63A5\u6536\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),e={}){super(o,e),this.name="InboundFileError",this.code=A,this.userMessage=a}};function m0(n){return Array.isArray(n?.files)?n.files.filter(Boolean):[]}function Mj(n,A){return typeof n!="string"?A:n.replaceAll("\\","/").split("/").at(-1)?.replace(/[\u0000-\u001f\u007f]/g,"").trim()||A}function kCe(n,A){let o=Mj(n,"file").replace(/[^\p{L}\p{N}._ -]/gu,"_").replace(/^\.+/,"").slice(0,160)||"file";return`${String(A+1).padStart(2,"0")}-${o}`}function vCe(n){if(Buffer.isBuffer(n)||n instanceof Uint8Array)return{data:Buffer.from(n)};let A=n?.data??n?.buffer;if(Buffer.isBuffer(A)||A instanceof Uint8Array)return{data:Buffer.from(A),name:n?.name??n?.filename,mediaType:n?.mediaType??n?.mimetype};let o=n?.stream??n;return o&&typeof o[Symbol.asyncIterator]=="function"?{stream:o,name:n?.name??n?.filename,mediaType:n?.mediaType??n?.mimetype}:null}function pA(n){return m0(n).length>0}function fp(n,{signal:A}={}){let o=m0(n);return o.length===0?n:{...n,files:o.map(a=>{if(a?.data!==void 0||typeof a?.load!="function")return a;let e;try{e=Promise.resolve(a.load({signal:A}))}catch(i){e=Promise.reject(i)}return e.catch(()=>{}),{...a,async load({signal:i}={}){i?.throwIfAborted();let t=await e;return i?.throwIfAborted(),t}}})}}async function _j(n,{workspace:A,signal:o,retention:a="turn",onStagedDirectory:e=null}={}){if(!_Ce.has(a))throw new co("inbound-file-retention-invalid",`Unknown inbound file retention: ${String(a)}`);if(e!==null&&typeof e!="function")throw new TypeError("onStagedDirectory must be a function");let i=m0(n);if(i.length===0)return null;if(typeof A!="string"||!Q0(A))throw new co("inbound-file-workspace-unavailable","The Harness Session workspace is unavailable for inbound files.");o?.throwIfAborted();let t=y0(A,Oj);await wCe(t,{recursive:!0,mode:448});let r=await DCe(YE(t,NCe()));e?.(r);let s=[];try{for(let[c,g]of i.entries()){o?.throwIfAborted();let I;try{I=g?.data===void 0?await g?.load?.({signal:o}):g.data}catch(y){throw o?.aborted?y:new co("inbound-file-download-failed",`Unable to download inbound file ${c+1}: ${y?.message??String(y)}`,S("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),{cause:y})}let d=vCe(I);if(!d)throw new co("inbound-file-data-invalid",`Inbound file ${c+1} returned no readable data.`);let B=Mj(d.name??g?.name,`file-${c+1}`),f=YE(r,kCe(B,c));if(d.data)await OCe(f,d.data,{mode:384,signal:o});else try{await MCe(d.stream,SCe(f,{flags:"wx",mode:384}),{signal:o})}catch(y){throw o?.aborted?y:new co("inbound-file-download-failed",`Unable to stream inbound file ${c+1}: ${y?.message??String(y)}`,S("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002"),{cause:y})}let Q=bj(y0(A),f);if(!Q||Q.startsWith("..")||Q0(Q))throw new co("inbound-file-path-invalid","The staged inbound file escaped the Harness Session workspace.");s.push(Object.freeze({name:B,path:Q,...typeof(d.mediaType??g?.mediaType)=="string"&&(d.mediaType??g.mediaType).trim()?{mediaType:(d.mediaType??g.mediaType).trim()}:{}}))}return Object.freeze({files:Object.freeze(s),directory:r,retention:a,async cleanup(){a==="turn"&&await f0(r,{recursive:!0,force:!0})}})}catch(c){throw await f0(r,{recursive:!0,force:!0}).catch(()=>{}),c}}async function Tj(n,A,{now:o=()=>new Date,isTracked:a}={}){if(typeof n!="string"||!n)throw new TypeError("sweepInboundAttachments requires a workspace");if(A!==0&&!(Number.isInteger(A)&&A>0))return{deleted:0};let e=y0(n,Oj),i,t;try{[i,t]=await Promise.all([Dj(n),Dj(e)])}catch(I){if(I?.code==="ENOENT")return{deleted:0};throw I}let r=bj(i,t);if(!r||r.startsWith("..")||Q0(r))throw new co("inbound-file-root-outside-workspace","The inbound attachment directory does not resolve inside the Harness Session workspace.");let s;try{s=await bCe(t,{withFileTypes:!0})}catch(I){if(I?.code==="ENOENT")return{deleted:0};throw I}let c=o(),g=0;for(let I of s){if(!I.isDirectory())continue;let d=RCe(I.name);if(d===null)continue;let B=YE(e,I.name),f=YE(t,I.name);if(typeof a=="function"&&(a(B)||B!==f&&a(f)))continue;let Q=(c-d)/36e5;if(A===0||Q>=A)try{await f0(f,{recursive:!0,force:!0}),g+=1}catch{}}return{deleted:g}}function S0(n,A){if(!A?.files?.length)return n;let o=["<dsh_im_files>",JSON.stringify({description:"Files uploaded with this user message. Paths are relative to the current Harness workspace.",files:A.files}),"</dsh_im_files>"].join(`
166
166
  `);if(Array.isArray(n))return[...n,{type:"text",text:o}];let a=typeof n=="string"?n.trim():"";return a?`${a}
167
167
 
168
168
  ${o}`:o}function go(n){return n instanceof co?n.userMessage:null}import{createHash as Gj,randomUUID as Fj}from"node:crypto";import{constants as jE}from"node:fs";import{copyFile as PCe,lstat as Nj,mkdtemp as GCe,open as Lj,realpath as FCe,unlink as Uj}from"node:fs/promises";import{tmpdir as LCe}from"node:os";import{basename as UCe,extname as HCe,isAbsolute as xCe,join as Hj,resolve as KCe}from"node:path";var zy="dsh_im_return_file",qy="dsh-im-outbound-artifact",w0=64*1024,YCe=new Map([[".csv","text/csv"],[".doc","application/msword"],[".docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"],[".gif","image/gif"],[".html","text/html"],[".jpeg","image/jpeg"],[".jpg","image/jpeg"],[".json","application/json"],[".md","text/markdown"],[".pdf","application/pdf"],[".png","image/png"],[".rar","application/vnd.rar"],[".txt","text/plain"],[".webp","image/webp"],[".xls","application/vnd.ms-excel"],[".xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],[".xml","application/xml"],[".zip","application/zip"]]),xc=new WeakMap,xj=new WeakMap,JE=new WeakMap,Rj;function jCe(){return Rj??=GCe(Hj(LCe(),"dsh-im-outbound-")),Rj}function Hc(n,A){let o=new Error(A);return o.code=n,o}function kj(n){let A=typeof n?.session?.snapshotEvents=="function"?n.session.snapshotEvents():n?.session?.events;if(!Array.isArray(A))return null;let o=null;for(let a of A)a?.type==="turn/start"?o=Number.isInteger(a.data?.turn)?a.data.turn:null:a?.type==="turn/end"&&a.data?.turn===o&&(o=null);return Number.isInteger(o)&&o>=0?o:null}function vj(n){let A=n?.id??n?.header?.id;return typeof A=="string"&&A?A:null}function Uc(n,A){return`${n}\0${A}`}function Pj(n,A){return`${n}\0${A}`}function JCe(n){let A=String(n??"").replace(/[\u0000-\u001f\u007f]/g," ").replace(new RegExp("\\p{Cf}","gu"),"").replace(/\s+/g," ").trim();return A?[...A].slice(0,255).join(""):"result.bin"}function qCe(n){return YCe.get(HCe(n).toLowerCase())??"application/octet-stream"}function zCe(n){return Gj("sha256").update(n).digest("hex")}function VCe(n,A){return typeof n?.dev=="bigint"&&typeof n?.ino=="bigint"&&typeof n?.size=="bigint"&&typeof n?.mtimeNs=="bigint"&&typeof n?.ctimeNs=="bigint"&&n.dev===A?.dev&&n.ino===A?.ino&&n.size===A?.size&&n.mtimeNs===A?.mtimeNs&&n.ctimeNs===A?.ctimeNs}async function WCe(n,A){let o;try{o=await Lj(n,jE.O_RDONLY);let a=Gj("sha256"),e=o.createReadStream({autoClose:!1,highWaterMark:w0,...A?{signal:A}:{}});for await(let i of e)A?.throwIfAborted(),a.update(i);return a.digest("hex")}finally{await o?.close().catch(()=>{})}}async function ZCe(n,A,{signal:o,errorCode:a="artifact-changed",errorMessage:e="The result file changed while it was being read."}={}){let i=()=>Hc(a,e);if(!Number.isSafeInteger(A)||A<0)throw i();o?.throwIfAborted();let t;try{t=Buffer.allocUnsafe(A)}catch{throw i()}if(typeof n?.createReadStream=="function"){let c=n.createReadStream({autoClose:!1,start:0,end:A,highWaterMark:w0,...o?{signal:o}:{}}),g=0;for await(let I of c){o?.throwIfAborted();let d=Buffer.isBuffer(I)?I:Buffer.from(I);if(g+d.length>A)throw i();d.copy(t,g),g+=d.length}if(g!==A)throw i();return t}let r=0;for(;r<A;){o?.throwIfAborted();let c=Math.min(w0,A-r),g=await n.read(t,r,c,r),I=Number(g?.bytesRead??0);if(!Number.isInteger(I)||I<=0||I>c)throw i();r+=I}o?.throwIfAborted();let s=Buffer.allocUnsafe(1);if((await n.read(s,0,1,A))?.bytesRead!==0)throw i();return t}async function XCe(n,A,o){o?.throwIfAborted();let a;try{let e=xCe(A)?A:KCe(n,A),i=await FCe(e);if(!(await Nj(i,{bigint:!0})).isFile())throw Hc("artifact-not-file","The requested path is not a file.");let r=await jCe();a=Hj(r,`${Fj()}.artifact`),await PCe(i,a,jE.COPYFILE_EXCL),o?.throwIfAborted();let s=await Nj(a,{bigint:!0}),c=Number(s.size);if(!s.isFile()||!Number.isSafeInteger(c)||c<0)throw Hc("artifact-unavailable","The file could not be prepared for delivery.");let g=JCe(UCe(e));return Object.freeze({fileName:g,mediaType:qCe(g),size:c,digest:await WCe(a,o),storagePath:a})}catch(e){throw a&&await Uj(a).catch(()=>{}),e?.code?.startsWith?.("artifact-")?e:o?.aborted?o.reason??e:Hc("artifact-unavailable","The requested file is unavailable.")}}function Kj(n){return Object.freeze({artifactId:n.artifactId,fileName:n.fileName,size:n.size})}function Jy(n){return n.artifactId}function Rs(n){let A=xc.get(n);if(!A)return;if(A.releaseRequested=!0,A.materializing>0){A.cleanupRequested=!0;return}let o=[...JE.get(n)??[]];if(o.length>0){A.cleanupDeferred||(A.cleanupDeferred=!0,Promise.allSettled(o).finally(()=>{A.cleanupDeferred=!1,Rs(n)}));return}xc.delete(n),JE.delete(n),A.onCleanup?.(),Uj(A.path).catch(()=>{})}var D0=class{#t=new Map;#e=new Map;#A=new Map;#r=new Map;#o=new Map;#l=new Map;#n=new Map;#i=new Map;#a;constructor({uuid:A=Fj}={}){if(typeof A!="function")throw new TypeError("uuid must be a function");this.#a=A}openConsumer(A,o){if(typeof A!="string"||!A||typeof o!="string"||!o)throw new TypeError("sessionId and promptRpcId are required");let a=Pj(A,o),e={sessionId:A,promptRpcId:o,turn:null,released:!1};return this.#l.set(a,e),()=>{if(!e.released&&(e.released=!0,this.#l.get(a)===e&&this.#l.delete(a),e.turn!==null)){let i=Uc(A,e.turn);this.#n.get(i)===e&&this.#n.delete(i),this.discard(A,e.turn)}}}observeSessionEvent(A,o){let a=vj(A);if(!a||!o||typeof o!="object")return;if(o.type==="turn/start"){let t=o.data?.turn;Number.isInteger(t)&&t>=0&&this.#i.set(a,t);return}if(o.type==="user/message"){let t=o.data?.source?.rpcId,r=this.#i.get(a)??kj({session:A});if(typeof t!="string"||!t||!Number.isInteger(r))return;this.#i.set(a,r);let s=this.#l.get(Pj(a,t));if(!s||s.released)return;s.turn=r,this.#n.set(Uc(a,r),s);return}if(o.type!=="turn/end")return;let e=o.data?.turn;if(!Number.isInteger(e)||e<0)return;this.#i.get(a)===e&&this.#i.delete(a);let i=this.#n.get(Uc(a,e));(!i||i.released)&&this.discard(a,e)}disposeSession(A){let o=vj(A);if(!o)return;let a=`${o}\0`,e=new Set;for(let i of[this.#t,this.#e])for(let[t,r]of i)if(t.startsWith(a)){for(let s of r.values())e.add(s);i.delete(t)}for(let[i,t]of this.#l)i.startsWith(a)&&(t.released=!0,this.#l.delete(i));for(let i of this.#n.keys())i.startsWith(a)&&this.#n.delete(i);this.#i.delete(o);for(let i of e)Rs(i)}async stage(A,o){let a=A?.path;if(typeof a!="string"||!a.trim())throw new TypeError("A file path is required.");let e=o?.agent,i=e?.session?.header?.id,t=e?.session?.header?.cwd,r=kj(e);if(typeof i!="string"||!i||typeof t!="string"||!t||r===null)throw Hc("artifact-context-required","A live Harness Session is required to return a file.");let s=await XCe(t,a,o?.signal),{storagePath:c,...g}=s,I=Object.freeze({kind:qy,schemaVersion:1,artifactId:this.#a(),deliveryKey:this.#a(),...g,source:"managed-temp",registeredBy:Object.freeze({kind:"tool-result",eventId:typeof o?.callId=="string"?o.callId:"unknown",toolName:zy}),origin:Object.freeze({sessionId:i,turn:r,callId:typeof o?.callId=="string"?o.callId:null}),createdAt:Date.now()});xc.set(I,{path:c,materializing:0,materialized:!1,releaseRequested:!1,cleanupRequested:!1,cleanupDeferred:!1,onCleanup:()=>this.#g(I)});let d=Uc(i,r),B=this.#e.get(d);return B||(B=new Map,this.#e.set(d,B)),B.set(Jy(I),I),I}commit(A){if(A?.kind!==qy||!xc.has(A))return null;let o=Uc(A.origin.sessionId,A.origin.turn),a=Jy(A),e=this.#e.get(o);if(e?.get(a)!==A)return null;e.delete(a),e.size===0&&this.#e.delete(o);let i=this.#t.get(o);return i||(i=new Map,this.#t.set(o,i)),i.set(a,A),Kj(A)}release(A){if(A?.kind!==qy)return;let o=Uc(A.origin.sessionId,A.origin.turn),a=Jy(A),e=this.#e.get(o);e?.get(a)===A&&e.delete(a),e?.size===0&&this.#e.delete(o),Rs(A)}take(A,o,{signal:a}={}){let e=Uc(A,o),i=this.#t.get(e);if(this.#t.delete(e),!i)return[];if(a?.aborted){for(let s of i.values())Rs(s);return[]}let t=this.#A.get(e)??new Map;this.#A.set(e,t);let r=[];for(let[s,c]of i)xc.has(c)&&(t.set(s,c),r.push(c));if(t.size===0)this.#A.delete(e);else if(!this.#c(e,a))return[];return r}discard(A,o){if(typeof A!="string"||!Number.isInteger(o))return;let a=Uc(A,o),e=new Set([...this.#t.get(a)?.values()??[],...this.#e.get(a)?.values()??[]]);this.#t.delete(a),this.#e.delete(a);for(let i of e)Rs(i)}clear(){let A=new Set;for(let o of this.#t.values())for(let a of o.values())A.add(a);for(let o of this.#e.values())for(let a of o.values())A.add(a);for(let o of this.#A.values())for(let a of o.values())A.add(a);for(let o of A)Rs(o);this.#t.clear(),this.#e.clear(),this.#A.clear();for(let o of this.#r.keys())this.#s(o);for(let o of this.#l.values())o.released=!0;this.#l.clear(),this.#n.clear(),this.#i.clear()}#c(A,o){if(!o)return!0;this.#s(A);let a=this.#o.get(o);return a||(a={turnKeys:new Set,onAbort:null},a.onAbort=()=>{for(let e of[...a.turnKeys])for(let i of this.#A.get(e)?.values()??[])Rs(i)},this.#o.set(o,a),o.addEventListener("abort",a.onAbort,{once:!0})),a.turnKeys.add(A),this.#r.set(A,o),o.aborted?(a.onAbort(),!1):!0}#s(A){let o=this.#r.get(A);if(!o)return;this.#r.delete(A);let a=this.#o.get(o);a?.turnKeys.delete(A),a?.turnKeys.size===0&&(o.removeEventListener("abort",a.onAbort),this.#o.delete(o))}#g(A){let o=Uc(A.origin.sessionId,A.origin.turn),a=Jy(A),e=this.#t.get(o);e?.get(a)===A&&e.delete(a),e?.size===0&&this.#t.delete(o);let i=this.#e.get(o);i?.get(a)===A&&i.delete(a),i?.size===0&&this.#e.delete(o);let t=this.#A.get(o);t?.get(a)===A&&t.delete(a),t?.size===0&&(this.#A.delete(o),this.#s(o))}},Ql=new D0;function $Ce({registry:n=Ql}={}){let A=new WeakMap,o=new Map,a=(t,r)=>{let s=o.get(t);s||(s={artifacts:[]},o.set(t,s)),s.artifacts.push(r)},e=Object.freeze({name:zy,description:"Send a readable file or generated image to the user through the current conversation. Existing and newly created files are both valid.",parameters:{type:"object",additionalProperties:!1,properties:{path:{type:"string",description:"Absolute path, or a path relative to the current workspace."}},required:["path"]},output:{schema:{type:"object",additionalProperties:!1,properties:{artifactId:{type:"string"},fileName:{type:"string"},size:{type:"number"}},required:["artifactId","fileName","size"]},render:(t,r)=>[{type:"text",text:`Registered ${r.fileName} (${r.size} bytes) for IM delivery.`}]},async execute(t,r){let s=await n.stage(t,r);return A.set(r,s),Kj(s)}});return Object.freeze({definition:e,onResult:(t,r)=>{if(t?.name===zy){let c=A.get(t);if(!c)return;if(A.delete(t),r?.isError){n.release(c);return}t.parent===void 0?n.commit(c):a(t.parent,c);return}let s=o.get(t?.token);if(s){if(o.delete(t.token),r?.isError){for(let c of s.artifacts)n.release(c);return}if(t.parent!==void 0){for(let c of s.artifacts)a(t.parent,c);return}for(let c of s.artifacts)n.commit(c)}}})}function b0(n,{registry:A=Ql}={}){if(typeof n?.tools?.register!="function"||typeof n?.systemPrompt?.section!="function"||typeof n?.on!="function")return!1;let o=$Ce({registry:A});return n.tools.register(o.definition),n.on("tools/result",o.onResult),n.on("session/event",(a,e)=>A.observeSessionEvent(a,e)),n.on("session/disposed",a=>A.disposeSession(a)),n.systemPrompt.section({name:"dsh-im:return-file",order:115,text:`When the user asks to receive a file or generated image, call ${zy} with its path. Existing files can be sent directly; do not recreate or rename a file solely for delivery.`}),!0}async function Yj(n,{signal:A}={}){if(A?.aborted&&(Rs(n),A.throwIfAborted()),n?.kind!==qy||n.schemaVersion!==1||!xc.has(n)||typeof n.digest!="string"||!Number.isSafeInteger(n.size)||n.size<0)throw Hc("artifact-invalid","The file registration is invalid.");let o=xc.get(n);o.materializing+=1;let a,e=!1;try{let i=Number.isInteger(jE.O_NOFOLLOW)?jE.O_NOFOLLOW:0;a=await Lj(o.path,jE.O_RDONLY|i);let t=await a.stat({bigint:!0});if(!t.isFile()||t.size!==BigInt(n.size))throw Hc("artifact-invalid","The file registration is invalid.");let r=await ZCe(a,n.size,{signal:A,errorCode:"artifact-invalid",errorMessage:"The file registration is invalid."}),s=await a.stat({bigint:!0});if(!VCe(t,s)||r.byteLength!==n.size||zCe(r)!==n.digest)throw Hc("artifact-invalid","The file registration is invalid.");A?.throwIfAborted(),e=!0;let c=Object.freeze({artifactId:n.artifactId,deliveryKey:n.deliveryKey,fileName:n.fileName,mediaType:n.mediaType,size:n.size,bytes:r});return xj.set(c,n),o.materialized=!0,c}catch(i){throw i?.code?.startsWith?.("artifact-")?i:A?.aborted?A.reason??i:Hc("artifact-invalid","The file registration is invalid.")}finally{await a?.close().catch(()=>{}),o.materializing-=1,(!e||o.cleanupRequested)&&Rs(n)}}function Jn(n,A){let o=xj.get(n);if(!o||!xc.has(o)||!A||typeof A.then!="function")return A;let a=JE.get(o)??new Set,e=Promise.resolve(A).then(()=>{},()=>{});return a.add(e),JE.set(o,a),e.finally(()=>{a.delete(e),a.size===0&&JE.delete(o)}),A}function O0(n){let A=xc.get(n);A&&(A.releaseRequested=!0),Rs(n)}function qE(n,A,o){try{let a=n?.(A);a&&typeof a.then=="function"&&Promise.resolve(a).catch(o)}catch(a){o(a)}}async function eBe({apiProxy:n,rpcId:A,signal:o,onOpen:a,onEnvelope:e}){let i=new AbortController,t=()=>i.abort(o.reason),r,s,c,g=I=>{i.signal.aborted||(c=I,t())};o.addEventListener("abort",t,{once:!0});try{for(r=n.events.mux({rpcId:A,payload:{}},i.signal)[Symbol.asyncIterator](),s=Promise.resolve(r.next()),i.signal.aborted||qE(a,t,g);!i.signal.aborted;){let{value:I,done:d}=await s;if(d||i.signal.aborted)break;qE(e,{type:"server-request",rpcId:I?.rpcId,method:I?.payload?.type,payload:I?.payload},g),i.signal.aborted||(s=Promise.resolve(r.next()))}}catch(I){g(I)}finally{let I=i.signal.aborted;o.removeEventListener("abort",t),t(),await s?.catch(()=>{});try{await r?.return?.()}catch(d){I||(c??=d)}}if(c)throw c}function tBe({baseUrl:n,createWebSocket:A,signal:o,onOpen:a,onEnvelope:e,onMalformed:i}){let t=new URL("/api/events.mux",n);return t.protocol=t.protocol==="https:"?"wss:":"ws:",new Promise((r,s)=>{let c=A(t.toString()),g=!1,I=!1,d=M=>{if(!I){I=!0,c.removeEventListener("open",f),c.removeEventListener("message",Q),c.removeEventListener("close",y),c.removeEventListener("error",m),o.removeEventListener("abort",b);try{(c.readyState===0||c.readyState===1)&&c.close()}catch{}M&&!o.aborted?s(M):r()}},B=()=>d(),f=()=>{I||g||(g=!0,qE(a,B,d))},Q=M=>{if(I)return;let N;try{if(typeof M.data!="string")throw new Error("binary WebSocket frame");N=JSON.parse(M.data)}catch(U){qE(i,U,()=>{});return}qE(e,N,d)},y=()=>d(g?void 0:new Error("Harness event mux WebSocket closed before opening")),m=()=>d(new Error(g?"Harness event mux WebSocket failed":"Harness event mux WebSocket failed before opening")),b=()=>d();c.addEventListener("open",f),c.addEventListener("message",Q),c.addEventListener("close",y,{once:!0}),c.addEventListener("error",m,{once:!0}),o.addEventListener("abort",b,{once:!0}),o.aborted&&b()})}async function jj(n){if(!n.signal.aborted)return n.baseUrl!==void 0&&n.baseUrl!==null?tBe(n):eBe(n)}var iBe=new Map,aBe=new WeakMap,oBe=64,nBe=1800*1e3,sBe=4096;async function cBe(n){let A=n?.body;if(!A||typeof A.getReader!="function")return null;let o=A.getReader(),a=[],e=0;try{for(;;){let{done:r,value:s}=await o.read();if(r)break;if(!(s instanceof Uint8Array)||e+s.byteLength>oBe)return null;a.push(s),e+=s.byteLength}}catch{return null}finally{try{await o.cancel()}catch{}}let i=new Uint8Array(e),t=0;for(let r of a)i.set(r,t),t+=r.byteLength;return new TextDecoder().decode(i)}function gBe(n){if(n==="localhost"||n==="[::1]")return!0;let A=n.split(".");return A.length===4&&A[0]==="127"&&A.every(o=>/^\d{1,3}$/.test(o)&&Number(o)<=255)}async function IBe(n,A){return n.status===401?"harness-auth-required":n.status===407?"harness-proxy-auth-required":n.status===403?(await cBe(n))?.trim()!=="forbidden"?"harness-request-forbidden":gBe(A)?"harness-loopback-forbidden":"harness-host-untrusted":n.status===404?"harness-api-not-found":"harness-http-failed"}function N0(n){let A=typeof n=="string"?iBe:aBe,o=A.get(n);return o||(o={ownerships:new Map,claims:new Map,controls:new WeakMap,imInputOrigins:new Map,nextOrder:0},A.set(n,o)),o}function M0(n,A=Date.now()){for(let[o,a]of n)a>A||n.delete(o);for(;n.size>sBe;)n.delete(n.keys().next().value)}function Jj(n,A){let o=n.imInputOrigins;return M0(o),o.delete(A),o.set(A,Date.now()+nBe),M0(o),()=>o.delete(A)}function Xj(n,A){if(!n||!["object","function","string"].includes(typeof n)||typeof A!="string"||!A)return!1;let o=N0(n).imInputOrigins;return M0(o),o.delete(A)}function qj(n,A){return new Promise((o,a)=>{let e=()=>A.removeEventListener("abort",i),i=()=>{e(),a(A.reason)};if(A.aborted){i();return}A.addEventListener("abort",i,{once:!0}),Promise.resolve().then(()=>(A.throwIfAborted(),n())).then(t=>{e(),o(t)},t=>{e(),a(t)})})}function zj(n){let A=typeof n?.owner;return A!=="object"&&A!=="function"||n.owner===null||typeof n.key!="string"||!n.key?null:{owner:n.owner,key:n.key}}function _0(n){return n!==null&&typeof n=="object"&&typeof n.provider=="string"&&!!n.provider&&typeof n.model=="string"&&!!n.model&&(n.reasoningEffort===void 0||typeof n.reasoningEffort=="string"&&!!n.reasoningEffort)}function lBe(n){return n!==null&&typeof n=="object"&&Array.isArray(n.efforts)&&n.efforts.length>0&&n.efforts.every(A=>A!==null&&typeof A=="object"&&typeof A.id=="string"&&!!A.id&&typeof A.name=="string"&&!!A.name&&(A.description===void 0||typeof A.description=="string"))&&(n.defaultEffort===void 0||typeof n.defaultEffort=="string"&&!!n.defaultEffort)}function Vj(n,A,{session:o=!1}={}){if(!n||typeof n!="object"||!Array.isArray(n.groups)||!Array.isArray(n.failures))throw new Error(`Harness returned an invalid response for ${A}`);for(let a of n.groups){if(!a||typeof a!="object"||typeof a.id!="string"||!a.id||typeof a.name!="string"||!a.name||!Array.isArray(a.models))throw new Error(`Harness returned an invalid response for ${A}`);for(let e of a.models)if(!e||typeof e!="object"||typeof e.id!="string"||!e.id||typeof e.name!="string"||!e.name||e.description!==void 0&&typeof e.description!="string"||e.reasoning!==void 0&&!lBe(e.reasoning))throw new Error(`Harness returned an invalid response for ${A}`)}for(let a of n.failures)if(!a||typeof a!="object"||typeof a.id!="string"||!a.id||typeof a.name!="string"||!a.name||a.message!==void 0&&typeof a.message!="string")throw new Error(`Harness returned an invalid response for ${A}`);if(o&&(!_0(n.current)||typeof n.routable!="boolean"))throw new Error(`Harness returned an invalid response for ${A}`);return n}function Wj(){let n=new Error("Harness turn was stopped before producing a text reply");return n.code="turn-stopped",n}function dBe(n){return Array.isArray(n?.items)?n.items.flatMap(A=>typeof A?.path=="string"&&rBe(A.path)?[A.path]:[]):[]}function pBe(n,A){if(!Array.isArray(A?.items)||!Array.isArray(A?.archivedSessionIds))throw new Error("Harness returned an invalid response for workspace.list");let o=A.items.find(a=>a?.path===n);if(!o)return null;if(!Array.isArray(o.sessionIds)||o.sessionIds.some(a=>typeof a!="string"))throw new Error("Harness returned invalid session IDs for workspace.list");return o}function hBe(n){if(typeof n=="number"&&Number.isFinite(n))return n<1e12?n*1e3:n;if(typeof n=="string"&&n){let A=Date.parse(n);if(!Number.isNaN(A))return A}return null}function uBe(n){if(!n||typeof n!="object")return null;let A=[n?.header?.lastActivityAt,n?.header?.updatedAt,n?.header?.createdAt,n?.projections?.values?.lastActivityAt,n?.projections?.values?.updatedAt,n?.projections?.values?.createdAt,n?.lastActivityAt,n?.updatedAt,n?.createdAt];for(let o of A){let a=hBe(o);if(a!==null)return a}return null}function EBe(n,A,o){if(!Array.isArray(o?.items))throw new Error("Harness returned an invalid response for session.list");let a=new Set(A),e=new Map(o.items.flatMap(i=>typeof i?.sessionId=="string"?[[i.sessionId,i]]:[]));return{workspace:n.path,sessions:n.sessionIds.map(i=>{let t=e.get(i),r=t?.projections?.values?.title,s={sessionId:i,title:typeof r=="string"?r:null,archived:a.has(i),blank:t?.blank===!0,origin:t?.origin==="subagent"?"subagent":null,summaryAvailable:t!==void 0},c=t?.projections?.asOfSeq;Number.isSafeInteger(c)&&c>=-1&&(s.lastSeq=c);let g=uBe(t);return g!==null&&(s.time=g),s})}}function zE(n,A){return new Promise((o,a)=>{if(A?.aborted){a(A.reason??new DOMException("Aborted","AbortError"));return}let e=setTimeout(()=>{A?.removeEventListener("abort",i),o()},n),i=()=>{clearTimeout(e),a(A.reason??new DOMException("Aborted","AbortError"))};A?.addEventListener("abort",i,{once:!0})})}function Wy(n){return(Array.isArray(n)?n:[]).filter(A=>A?.type==="text"&&typeof A.text=="string").map(A=>A.text).join(`
@@ -177,7 +177,7 @@ ${o}`:o}function go(n){return n instanceof co?n.userMessage:null}import{createHa
177
177
  ${KBe(I.text,s)}`);c=zg([i,...g,t.join(`
178
178
  `)].join(`
179
179
 
180
- `)),s=Math.floor(s/2)}while(s>0&&(c.message.length>3e3||c.messages.length>3));return c}function jBe(n){let A=n?.code??n?.failure?.code;return A==="session-not-found"?S("\u5F53\u524D\u804A\u5929\u7ED1\u5B9A\u7684\u4F1A\u8BDD\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u4F1A\u8BDD\u3002"):A===ga||A==="workspace-bot-not-found"||A==="session-binding-changed"?S("\u4F1A\u8BDD\u3001\u5DE5\u4F5C\u533A\u6216\u673A\u5668\u4EBA\u72B6\u6001\u5DF2\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C /history\u3002"):A==="harness-api-not-found"?S("\u5F53\u524D Harness \u6682\u4E0D\u652F\u6301\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\u3002"):n?.name==="AbortError"?S("\u5386\u53F2\u8BFB\u53D6\u5DF2\u53D6\u6D88\u3002"):n?.name==="TimeoutError"||A==="harness-timeout"?S("\u8BFB\u53D6\u5386\u53F2\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"):S("\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}function Qi(n){return typeof n=="string"&&gJ.test(n.trim())}async function Ra(n,A,o,a,{signal:e,isDirect:i=!1,hasImages:t=!1,hasFiles:r=!1}={}){if(!Qi(n))return null;let s=gJ.exec(n.trim())[1].trim();if(s&&(!/^\d+$/u.test(s)||/^0+$/u.test(s)))return zg(S(FBe));let c=s?Math.min(Number(s),LBe):3;if(!i)return zg(S("\u8BF7\u5728\u4E0E\u673A\u5668\u4EBA\u7684\u79C1\u804A\u4E2D\u4F7F\u7528 /history\u3002"));if(t||r)return zg(S("/history \u4EC5\u652F\u6301\u6587\u5B57\u547D\u4EE4\uFF0C\u8BF7\u79FB\u9664\u56FE\u7247\u6216\u6587\u4EF6\u540E\u91CD\u8BD5\u3002"));let g=o?.sessionFor?.(a);if(typeof g!="string"||!g)return zg(S("\u5F53\u524D\u804A\u5929\u5C1A\u672A\u7ED1\u5B9A\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u53D1\u9001\u6D88\u606F\u6216\u4F7F\u7528 /session \u7ED1\u5B9A\u4F1A\u8BDD\u3002"));try{let I=A?.workspaceSession?.(g);if(typeof I?.readHistory!="function")return zg(S("\u5F53\u524D Harness \u6682\u4E0D\u652F\u6301\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\u3002"));let d=AbortSignal.timeout(cJ),B=e?AbortSignal.any([e,d]):d,f=Date.now()+cJ,Q=new Map,y,m,b=[],M=!1;for(let N=0;N<HBe;N+=1){if(B.throwIfAborted(),Date.now()>=f)throw new DOMException("History read timed out","TimeoutError");let U=await I.readHistory({maxMessages:UBe,...y===void 0?{}:{beforeSeq:y},timeoutMs:Math.max(1,f-Date.now()),signal:B});if(B.throwIfAborted(),Date.now()>=f)throw new DOMException("History read timed out","TimeoutError");if(o.sessionFor(a)!==g){let Y=new Error("Session binding changed during history read");throw Y.code="session-binding-changed",Y}if(!U||!Array.isArray(U.events)||typeof U.hasMore!="boolean")throw new TypeError("Invalid history page");let x=y??1/0;for(let Y of U.events){let K=Y?.event;if(!K||!Number.isSafeInteger(K.seq)||K.seq<0||typeof K.type!="string"||!K.type)throw new TypeError("Invalid history event");if(m!==void 0&&K.seq>m)continue;let k=Q.get(K.seq);if(k){if(!GBe(k,K))throw new TypeError("Conflicting history events")}else{if(y!==void 0&&K.seq>=y)throw new TypeError("Invalid history cursor");Q.set(K.seq,K)}x=Math.min(x,K.seq)}let H=[...Q.values()].sort((Y,K)=>Y.seq-K.seq);if(m??=H.at(-1)?.seq,M=U.hasMore,M&&(!Number.isFinite(x)||x===y))throw new TypeError("History cursor did not advance");if(b=xBe(H).slice(-c),b.length>=c||!M)break;y=x}return b.length===0?zg(M?S("\u672C\u6B21\u6709\u9650\u8BFB\u53D6\u4E2D\u672A\u627E\u5230\u53EF\u9884\u89C8\u7684\u5386\u53F2\u6D88\u606F\u3002"):S("\u5F53\u524D\u4F1A\u8BDD\u6682\u65E0\u53EF\u9884\u89C8\u7684\u5386\u53F2\u6D88\u606F\u3002")):YBe(g,b,c,M)}catch(I){return zg(jBe(I))}}var $y={name:"@xmanrui/dsh-im",version:"4.16.0",description:"\u628A\u5341\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect ten IM channels and a public AI Office to a local DeepSeek Harness.",keywords:["deepseek-harness","dsh","dsh-plugin","ai-agent","im","instant-messaging","chatbot","feishu","lark","wechat","wecom","dingtalk","qq","slack","telegram","discord","whatsapp","ai-office"],author:"xmanrui (https://github.com/xmanrui)",contributors:[{name:"C3H3-AI",url:"https://github.com/C3H3-AI"},{name:"divingleee",url:"https://github.com/divingleee"},{name:"Chan-0312",url:"https://github.com/Chan-0312"},{name:"BuvkB",url:"https://github.com/BuvkB"}],license:"MIT",type:"module",repository:{type:"git",url:"git+https://github.com/xmanrui/dsh-im.git"},homepage:"https://github.com/xmanrui/dsh-im#readme",bugs:{url:"https://github.com/xmanrui/dsh-im/issues"},publishConfig:{access:"public"},bin:{"dsh-im":"bin/dsh-im.mjs"},main:"./lib/index.js",exports:{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},files:["assets","bin","cordis.patch.yml","lib","plugin-src","scripts","src","PROACTIVE_DELIVERY.md","PROACTIVE_DELIVERY.en.md","LICENSE","README.md","README.en.md","THIRD_PARTY_NOTICES.md"],dsh:{bundle:{patch:"./cordis.patch.yml"},client:{inject:["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-locale"],platform:"web"},compatibility:{dsh:"0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1 || 0.1.3-alpha.1",dshReleases:{"0.1.2-alpha.4":"compatible","0.1.2-alpha.5":"compatible","0.1.2-rc.1":"compatible","0.1.3-alpha.1":"compatible"},profiles:["web"]}},scripts:{build:"node plugin-src/client/build.mjs && node plugin-src/host/build.mjs",test:"node --test test/*.test.mjs test/channels/*/*.test.mjs",check:"npm run build && npm test && node scripts/verify-package.mjs"},engines:{node:">=22.19"},dependencies:{"@tencent-connect/qqbot-connector":"1.2.0","@tencent-connect/qqbot-nodejs":"1.0.4","@wecom/aibot-node-sdk":"1.0.7","dingtalk-stream":"2.1.4",qrcode:"1.5.4",undici:"7.29.0"},devDependencies:{"@deepseek-ai/cordis":"4.0.1","@larksuiteoapi/node-sdk":"1.73.0","@whiskeysockets/baileys":"7.0.0-rc14",esbuild:"0.25.9","https-proxy-agent":"5.0.1",react:"18.3.1","react-dom":"18.3.1","react-test-renderer":"18.3.1",semver:"7.8.5"},directories:{doc:"docs",lib:"lib",test:"test"}};var qBe=/^\/(?:stop|steer|version)(?=$|\s)/iu,zBe=/^\/stop(?=$|\s)/iu,VBe=/^\/version(?=$|\s)/iu,WBe="\u7528\u6CD5\uFF1A/stop\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",ZBe="\u7528\u6CD5\uFF1A/version\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",XBe="\u7528\u6CD5\uFF1A/steer <\u8865\u5145\u6307\u4EE4>",$Be="\u63A7\u5236\u547D\u4EE4\u4EC5\u652F\u6301\u7EAF\u6587\u5B57\uFF0C\u8BF7\u79FB\u9664\u56FE\u7247\u540E\u91CD\u8BD5\u3002";function ho(n,A={}){return{message:n,...A}}function lJ(n){return n?{signal:n}:{}}function dJ(n,A,o){if(typeof A?.sessionFor!="function")return null;let a=A.sessionFor(o);if(typeof a!="string"||!a)return null;if(typeof n?.workspaceSession!="function")throw new TypeError("Harness does not support workspace sessions");let e=n.workspaceSession(a);if(!e||typeof e!="object")throw new TypeError("Harness returned an invalid workspace session");return e}function ri(n){return typeof n=="string"&&qBe.test(n.trim())}async function yi(n,A,o,a,{signal:e,hasImages:i=!1,pendingInteraction:t=!1,control:r,deferredDelivery:s}={}){if(!ri(n))return null;let c=n.trim(),g=zBe.test(c),I=VBe.test(c);if(i)return ho(S($Be));if(I)return/^\/version$/iu.test(c)?ho(`dsh-im v${$y.version}`):ho(S(ZBe));if(g){if(!/^\/stop$/iu.test(c))return ho(S(WBe));let y=dJ(A,o,a);if(!y)return ho(S("\u5F53\u524D\u804A\u5929\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u3002"));if(typeof y.stopActiveTurn!="function")throw new TypeError("Harness session does not support stopping active turns");let m=await y.stopActiveTurn(r,lJ(e));if(!m&&s){let b=await s.stop(a);if(b==="stopped")return ho(S("\u5DF2\u8BF7\u6C42\u505C\u6B62\u540E\u53F0\u4EFB\u52A1\u3002"),{stopped:!0});if(b==="unavailable")return ho(S("\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u540E\u53F0\u4EFB\u52A1\uFF0C\u8BF7\u5728 Harness \u4E2D\u67E5\u770B\u5E76\u505C\u6B62\u5BF9\u5E94\u4EFB\u52A1\u3002"))}return m?ho(S("\u5DF2\u8BF7\u6C42\u505C\u6B62\u5F53\u524D\u4EFB\u52A1\u3002"),{stopped:!0}):ho(S("\u5F53\u524D\u804A\u5929\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u3002"))}let B=/^\/steer(?:\s+([\s\S]*))?$/iu.exec(c)?.[1]?.trim()??"";if(!B)return ho(S(XBe));if(t)return ho([S("\u5F53\u524D\u4EFB\u52A1\u6B63\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54\u6216\u5BA1\u6279\u3002"),"",S("\u8BF7\u5148\u5904\u7406\u5F53\u524D\u8BF7\u6C42\uFF0C\u6216\u8005\u53D1\u9001 /stop \u505C\u6B62\u4EFB\u52A1\u3002")].join(`
180
+ `)),s=Math.floor(s/2)}while(s>0&&(c.message.length>3e3||c.messages.length>3));return c}function jBe(n){let A=n?.code??n?.failure?.code;return A==="session-not-found"?S("\u5F53\u524D\u804A\u5929\u7ED1\u5B9A\u7684\u4F1A\u8BDD\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u7ED1\u5B9A\u4F1A\u8BDD\u3002"):A===ga||A==="workspace-bot-not-found"||A==="session-binding-changed"?S("\u4F1A\u8BDD\u3001\u5DE5\u4F5C\u533A\u6216\u673A\u5668\u4EBA\u72B6\u6001\u5DF2\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C /history\u3002"):A==="harness-api-not-found"?S("\u5F53\u524D Harness \u6682\u4E0D\u652F\u6301\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\u3002"):n?.name==="AbortError"?S("\u5386\u53F2\u8BFB\u53D6\u5DF2\u53D6\u6D88\u3002"):n?.name==="TimeoutError"||A==="harness-timeout"?S("\u8BFB\u53D6\u5386\u53F2\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"):S("\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}function Qi(n){return typeof n=="string"&&gJ.test(n.trim())}async function Ra(n,A,o,a,{signal:e,isDirect:i=!1,hasImages:t=!1,hasFiles:r=!1}={}){if(!Qi(n))return null;let s=gJ.exec(n.trim())[1].trim();if(s&&(!/^\d+$/u.test(s)||/^0+$/u.test(s)))return zg(S(FBe));let c=s?Math.min(Number(s),LBe):3;if(!i)return zg(S("\u8BF7\u5728\u4E0E\u673A\u5668\u4EBA\u7684\u79C1\u804A\u4E2D\u4F7F\u7528 /history\u3002"));if(t||r)return zg(S("/history \u4EC5\u652F\u6301\u6587\u5B57\u547D\u4EE4\uFF0C\u8BF7\u79FB\u9664\u56FE\u7247\u6216\u6587\u4EF6\u540E\u91CD\u8BD5\u3002"));let g=o?.sessionFor?.(a);if(typeof g!="string"||!g)return zg(S("\u5F53\u524D\u804A\u5929\u5C1A\u672A\u7ED1\u5B9A\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u53D1\u9001\u6D88\u606F\u6216\u4F7F\u7528 /session \u7ED1\u5B9A\u4F1A\u8BDD\u3002"));try{let I=A?.workspaceSession?.(g);if(typeof I?.readHistory!="function")return zg(S("\u5F53\u524D Harness \u6682\u4E0D\u652F\u6301\u8BFB\u53D6\u4F1A\u8BDD\u5386\u53F2\u3002"));let d=AbortSignal.timeout(cJ),B=e?AbortSignal.any([e,d]):d,f=Date.now()+cJ,Q=new Map,y,m,b=[],M=!1;for(let N=0;N<HBe;N+=1){if(B.throwIfAborted(),Date.now()>=f)throw new DOMException("History read timed out","TimeoutError");let U=await I.readHistory({maxMessages:UBe,...y===void 0?{}:{beforeSeq:y},timeoutMs:Math.max(1,f-Date.now()),signal:B});if(B.throwIfAborted(),Date.now()>=f)throw new DOMException("History read timed out","TimeoutError");if(o.sessionFor(a)!==g){let Y=new Error("Session binding changed during history read");throw Y.code="session-binding-changed",Y}if(!U||!Array.isArray(U.events)||typeof U.hasMore!="boolean")throw new TypeError("Invalid history page");let x=y??1/0;for(let Y of U.events){let K=Y?.event;if(!K||!Number.isSafeInteger(K.seq)||K.seq<0||typeof K.type!="string"||!K.type)throw new TypeError("Invalid history event");if(m!==void 0&&K.seq>m)continue;let k=Q.get(K.seq);if(k){if(!GBe(k,K))throw new TypeError("Conflicting history events")}else{if(y!==void 0&&K.seq>=y)throw new TypeError("Invalid history cursor");Q.set(K.seq,K)}x=Math.min(x,K.seq)}let H=[...Q.values()].sort((Y,K)=>Y.seq-K.seq);if(m??=H.at(-1)?.seq,M=U.hasMore,M&&(!Number.isFinite(x)||x===y))throw new TypeError("History cursor did not advance");if(b=xBe(H).slice(-c),b.length>=c||!M)break;y=x}return b.length===0?zg(M?S("\u672C\u6B21\u6709\u9650\u8BFB\u53D6\u4E2D\u672A\u627E\u5230\u53EF\u9884\u89C8\u7684\u5386\u53F2\u6D88\u606F\u3002"):S("\u5F53\u524D\u4F1A\u8BDD\u6682\u65E0\u53EF\u9884\u89C8\u7684\u5386\u53F2\u6D88\u606F\u3002")):YBe(g,b,c,M)}catch(I){return zg(jBe(I))}}var $y={name:"@xmanrui/dsh-im",version:"4.16.1",description:"\u628A\u5341\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect ten IM channels and a public AI Office to a local DeepSeek Harness.",keywords:["deepseek-harness","dsh","dsh-plugin","ai-agent","im","instant-messaging","chatbot","feishu","lark","wechat","wecom","dingtalk","qq","slack","telegram","discord","whatsapp","ai-office"],author:"xmanrui (https://github.com/xmanrui)",contributors:[{name:"C3H3-AI",url:"https://github.com/C3H3-AI"},{name:"divingleee",url:"https://github.com/divingleee"},{name:"Chan-0312",url:"https://github.com/Chan-0312"},{name:"BuvkB",url:"https://github.com/BuvkB"},{name:"masucc",url:"https://github.com/masucc"}],license:"MIT",type:"module",repository:{type:"git",url:"git+https://github.com/xmanrui/dsh-im.git"},homepage:"https://github.com/xmanrui/dsh-im#readme",bugs:{url:"https://github.com/xmanrui/dsh-im/issues"},publishConfig:{access:"public"},bin:{"dsh-im":"bin/dsh-im.mjs"},main:"./lib/index.js",exports:{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},files:["assets","bin","cordis.patch.yml","lib","plugin-src","scripts","src","PROACTIVE_DELIVERY.md","PROACTIVE_DELIVERY.en.md","LICENSE","README.md","README.en.md","THIRD_PARTY_NOTICES.md"],dsh:{bundle:{patch:"./cordis.patch.yml"},client:{inject:["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-slots","@deepseek-ai/dsh-client-locale"],platform:"web"},compatibility:{dsh:"0.1.2-alpha.4 || 0.1.2-alpha.5 || 0.1.2-rc.1 || 0.1.3-alpha.1",dshReleases:{"0.1.2-alpha.4":"compatible","0.1.2-alpha.5":"compatible","0.1.2-rc.1":"compatible","0.1.3-alpha.1":"compatible"},profiles:["web"]}},scripts:{build:"node plugin-src/client/build.mjs && node plugin-src/host/build.mjs",test:"node --test test/*.test.mjs test/channels/*/*.test.mjs",check:"npm run build && npm test && node scripts/verify-package.mjs"},engines:{node:">=22.19"},dependencies:{"@tencent-connect/qqbot-connector":"1.2.0","@tencent-connect/qqbot-nodejs":"1.0.4","@wecom/aibot-node-sdk":"1.0.7","dingtalk-stream":"2.1.4",qrcode:"1.5.4",undici:"7.29.0"},devDependencies:{"@deepseek-ai/cordis":"4.0.1","@larksuiteoapi/node-sdk":"1.73.0","@whiskeysockets/baileys":"7.0.0-rc14",esbuild:"0.25.9","https-proxy-agent":"5.0.1",react:"18.3.1","react-dom":"18.3.1","react-test-renderer":"18.3.1",semver:"7.8.5"},directories:{doc:"docs",lib:"lib",test:"test"}};var qBe=/^\/(?:stop|steer|version)(?=$|\s)/iu,zBe=/^\/stop(?=$|\s)/iu,VBe=/^\/version(?=$|\s)/iu,WBe="\u7528\u6CD5\uFF1A/stop\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",ZBe="\u7528\u6CD5\uFF1A/version\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",XBe="\u7528\u6CD5\uFF1A/steer <\u8865\u5145\u6307\u4EE4>",$Be="\u63A7\u5236\u547D\u4EE4\u4EC5\u652F\u6301\u7EAF\u6587\u5B57\uFF0C\u8BF7\u79FB\u9664\u56FE\u7247\u540E\u91CD\u8BD5\u3002";function ho(n,A={}){return{message:n,...A}}function lJ(n){return n?{signal:n}:{}}function dJ(n,A,o){if(typeof A?.sessionFor!="function")return null;let a=A.sessionFor(o);if(typeof a!="string"||!a)return null;if(typeof n?.workspaceSession!="function")throw new TypeError("Harness does not support workspace sessions");let e=n.workspaceSession(a);if(!e||typeof e!="object")throw new TypeError("Harness returned an invalid workspace session");return e}function ri(n){return typeof n=="string"&&qBe.test(n.trim())}async function yi(n,A,o,a,{signal:e,hasImages:i=!1,pendingInteraction:t=!1,control:r,deferredDelivery:s}={}){if(!ri(n))return null;let c=n.trim(),g=zBe.test(c),I=VBe.test(c);if(i)return ho(S($Be));if(I)return/^\/version$/iu.test(c)?ho(`dsh-im v${$y.version}`):ho(S(ZBe));if(g){if(!/^\/stop$/iu.test(c))return ho(S(WBe));let y=dJ(A,o,a);if(!y)return ho(S("\u5F53\u524D\u804A\u5929\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u3002"));if(typeof y.stopActiveTurn!="function")throw new TypeError("Harness session does not support stopping active turns");let m=await y.stopActiveTurn(r,lJ(e));if(!m&&s){let b=await s.stop(a);if(b==="stopped")return ho(S("\u5DF2\u8BF7\u6C42\u505C\u6B62\u540E\u53F0\u4EFB\u52A1\u3002"),{stopped:!0});if(b==="unavailable")return ho(S("\u65E0\u6CD5\u5B89\u5168\u505C\u6B62\u540E\u53F0\u4EFB\u52A1\uFF0C\u8BF7\u5728 Harness \u4E2D\u67E5\u770B\u5E76\u505C\u6B62\u5BF9\u5E94\u4EFB\u52A1\u3002"))}return m?ho(S("\u5DF2\u8BF7\u6C42\u505C\u6B62\u5F53\u524D\u4EFB\u52A1\u3002"),{stopped:!0}):ho(S("\u5F53\u524D\u804A\u5929\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u3002"))}let B=/^\/steer(?:\s+([\s\S]*))?$/iu.exec(c)?.[1]?.trim()??"";if(!B)return ho(S(XBe));if(t)return ho([S("\u5F53\u524D\u4EFB\u52A1\u6B63\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54\u6216\u5BA1\u6279\u3002"),"",S("\u8BF7\u5148\u5904\u7406\u5F53\u524D\u8BF7\u6C42\uFF0C\u6216\u8005\u53D1\u9001 /stop \u505C\u6B62\u4EFB\u52A1\u3002")].join(`
181
181
  `));let f=dJ(A,o,a);if(!f)return ho(S("\u5F53\u524D\u804A\u5929\u6CA1\u6709\u7ED1\u5B9A\u4F1A\u8BDD\uFF0C\u65E0\u6CD5\u8865\u5145\u6307\u4EE4\u3002\u8BF7\u5148\u7ED1\u5B9A\u4F1A\u8BDD\u3002"));if(typeof f.steerActiveTurn!="function")throw new TypeError("Harness session does not support steering active turns");let Q=await f.steerActiveTurn(B,r,lJ(e));return ho(Q?S("\u5DF2\u63D0\u4EA4\u8865\u5145\u6307\u4EE4\uFF0CAgent \u4F1A\u5728\u4E0B\u4E00\u6B65\u8BFB\u53D6\u3002"):S("\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\uFF0C\u65E0\u6CD5\u8865\u5145\u6307\u4EE4\u3002\u8BF7\u76F4\u63A5\u53D1\u9001\u6D88\u606F\u5F00\u59CB\u65B0\u4EFB\u52A1\u3002"))}var efe=/^\/model(?=$|\s)/i,yJ=/^\/models(?=$|\s)/i,mJ=/^\/reasoning(?=$|\s)/i,SJ=/^\/reasonings(?=$|\s)/i,wJ=/^\/reasoninglist(?=$|\s)/i,pJ="\u7528\u6CD5\uFF1A/model <\u5E8F\u53F7\u6216 provider/model> [\u63A8\u7406\u7B49\u7EA7ID]",tfe="\u7528\u6CD5\uFF1A/models\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",Afe="\u7528\u6CD5\uFF1A/reasoning [\u5E8F\u53F7\u3001\u7B49\u7EA7ID\u6216 --default]",rfe="\u7528\u6CD5\uFF1A/reasoninglist \u6216 /reasonings\uFF08\u4E0D\u5E26\u53C2\u6570\uFF09",DJ="session-binding-changed",bJ="model-selection-mismatch",ife=/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]+/gu;function QA(n){return{handled:!0,message:n,messages:Lc(n)}}function mi(n){return typeof n!="string"?"":n.replace(ife," ").replace(/\s+/gu," ").trim()}function afe(n){return n?{signal:n}:{}}function ofe(n){if(n===void 0)return;if(!n||typeof n!="object"||!Array.isArray(n.efforts)||n.efforts.length===0)throw new TypeError("Harness returned invalid model reasoning metadata");let A=n.efforts.map(o=>{if(!o||typeof o!="object"||typeof o.id!="string"||!o.id||typeof o.name!="string"||!o.name||o.description!==void 0&&typeof o.description!="string")throw new TypeError("Harness returned an invalid reasoning effort");return{id:o.id,name:o.name,...o.description===void 0?{}:{description:o.description}}});if(n.defaultEffort!==void 0&&(typeof n.defaultEffort!="string"||!n.defaultEffort))throw new TypeError("Harness returned an invalid default reasoning effort");return{efforts:A,...n.defaultEffort===void 0?{}:{defaultEffort:n.defaultEffort}}}function OJ(n,{requireCurrent:A=!1}={}){if(!n||typeof n!="object"||!Array.isArray(n.groups)||!Array.isArray(n.failures))throw new TypeError("Harness returned an invalid model catalog");let o=n.groups.map(i=>{if(!i||typeof i!="object"||typeof i.id!="string"||!i.id||typeof i.name!="string"||!i.name||!Array.isArray(i.models))throw new TypeError("Harness returned an invalid model provider group");return{id:i.id,name:i.name,models:i.models.map(t=>{if(!t||typeof t!="object"||typeof t.id!="string"||!t.id||typeof t.name!="string"||!t.name||t.description!==void 0&&typeof t.description!="string")throw new TypeError("Harness returned an invalid model");return{id:t.id,name:t.name,...t.description===void 0?{}:{description:t.description},...t.reasoning===void 0?{}:{reasoning:ofe(t.reasoning)}}})}}),a=n.failures.map(i=>{if(!i||typeof i!="object"||typeof i.id!="string"||!i.id||typeof i.name!="string"||!i.name)throw new TypeError("Harness returned an invalid model provider failure");return{id:i.id,name:i.name}}),e=null;if(n.current!==void 0){if(!n.current||typeof n.current!="object"||typeof n.current.provider!="string"||!n.current.provider||typeof n.current.model!="string"||!n.current.model||n.current.reasoningEffort!==void 0&&(typeof n.current.reasoningEffort!="string"||!n.current.reasoningEffort))throw new TypeError("Harness returned an invalid current model");e={provider:n.current.provider,model:n.current.model,...n.current.reasoningEffort===void 0?{}:{reasoningEffort:n.current.reasoningEffort}}}else if(A)throw new TypeError("Harness returned no current model");return{groups:o,failures:a,current:e}}function Kc(n,A){return`${n}/${A}`}function MJ(n,A){return n?.provider===A?.provider&&n?.model===A?.model}function nfe(n,A){return MJ(n,A)&&n?.reasoningEffort===A?.reasoningEffort}function sfe(n,A){return MJ(n,A)&&(A.reasoningEffort===void 0||n?.reasoningEffort===A.reasoningEffort)}function x0(n){if(!n?.provider||!n?.model)return"";let A=Kc(n.provider,n.model);return n.reasoningEffort===void 0?A:`${A} \xB7 reasoningEffort=${mi(n.reasoningEffort)}`}function hJ(n,A,o){let a=new Error(`Harness ${o} did not confirm the selected model`);return a.code=bJ,a.expected=n,a.actual=A,a.source=o,a}function _J(){let n=new Error("Conversation binding changed during model selection");return n.code=DJ,n}function uJ(n,A,o){if((typeof n?.sessionFor=="function"?n.sessionFor(A):null)!==o)throw _J()}function cfe(n,A){for(let o of n.groups)for(let a of o.models)if(Kc(o.id,a.id)===A)return{provider:o.id,model:a.id};return null}function gfe(n,A){let o=0;for(let a of n.groups)for(let e of a.models)if(o+=1,o===A)return{provider:a.id,model:e.id};return null}function EJ(n){if(!/^\d+$/u.test(n))return null;let A=Number(n);return{index:Number.isSafeInteger(A)&&A>0?A:null}}function em(n,A){return A?n.groups.find(({id:a})=>a===A.provider)?.models.find(({id:a})=>a===A.model)??null:null}function Ife(n,A){return n?.reasoning?.efforts?.[A-1]??null}function K0(n,A){return n?.reasoning?.efforts?.find(({id:o})=>o===A)??null}function tm(n,A){return n?.reasoningEffort??A?.reasoning?.defaultEffort}function VE(n,A){if(A===void 0)return S("Default\uFF08\u7531\u6A21\u578B\u6216 Provider \u51B3\u5B9A\uFF09");let o=K0(n,A);if(!o)return mi(A);let a=mi(o.name),e=mi(o.id);return a===e?e:`${a} (${e})`}function TJ(n){let A=em(n,n.current);return VE(A,tm(n.current,A))}function lfe(n,A,o){return n===A&&n===o?S("\uFF08\u5F53\u524D\u3001\u9ED8\u8BA4\uFF09"):n===A?S("\uFF08\u5F53\u524D\uFF09"):n===o?S("\uFF08\u9ED8\u8BA4\uFF09"):""}function CJ(n){return[S("\u6A21\u578B\u5E8F\u53F7\u65E0\u6548\uFF1A{input}",{input:mi(n)}),"",S("\u8BF7\u53D1\u9001 /models \u67E5\u770B\u5E76\u8F93\u5165\u6709\u6548\u7684\u6B63\u6574\u6570\u5E8F\u53F7\u3002")].join(`
182
182
  `)}function BJ(n){return[S("\u63A8\u7406\u7B49\u7EA7\u5E8F\u53F7\u65E0\u6548\uFF1A{input}",{input:mi(n)}),"",S("\u8BF7\u53D1\u9001 /reasoninglist \u67E5\u770B\u5E76\u8F93\u5165\u6709\u6548\u7684\u6B63\u6574\u6570\u5E8F\u53F7\u3002")].join(`
183
183
  `)}function L0(n,A,o){let a=[S("\u6A21\u578B\u4E0D\u652F\u6301\u63A8\u7406\u7B49\u7EA7\uFF1A{effort}",{effort:mi(A)}),"",mi(x0(n))],e=o?.reasoning?.efforts?.map(({id:i})=>mi(i))??[];return e.length>0?a.push(S("\u53EF\u7528\u63A8\u7406\u7B49\u7EA7\uFF1A{efforts}",{efforts:e.join(", ")})):a.push(S("\u8BE5\u6A21\u578B\u4E0D\u63D0\u4F9B\u53EF\u5207\u6362\u7684\u63A8\u7406\u7B49\u7EA7\u3002")),a.join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmanrui/dsh-im",
3
- "version": "4.16.0",
3
+ "version": "4.16.1",
4
4
  "description": "把十种 IM 机器人和公网 AI Office 接入本机 DeepSeek Harness。 Connect ten IM channels and a public AI Office to a local DeepSeek Harness.",
5
5
  "keywords": [
6
6
  "deepseek-harness",
@@ -39,6 +39,10 @@
39
39
  {
40
40
  "name": "BuvkB",
41
41
  "url": "https://github.com/BuvkB"
42
+ },
43
+ {
44
+ "name": "masucc",
45
+ "url": "https://github.com/masucc"
42
46
  }
43
47
  ],
44
48
  "license": "MIT",
@@ -337,10 +337,13 @@ function cardMarkdown(text, target) {
337
337
  }
338
338
 
339
339
  function cardData(text, flowStatus, target) {
340
+ const markdown = cardMarkdown(text, target);
341
+ // The shared template uses msgContent for processing, finished, and
342
+ // failed cards. Switching its order to staticMsgContent hides the reply.
340
343
  return {
341
344
  cardParamMap: {
342
345
  flowStatus,
343
- msgContent: cardMarkdown(text, target),
346
+ msgContent: markdown,
344
347
  staticMsgContent: '',
345
348
  sys_full_json_obj: JSON.stringify({ order: ['msgContent'] }),
346
349
  config: JSON.stringify({ autoLayout: true }),
@@ -922,13 +925,17 @@ export function createDingtalkApi({
922
925
 
923
926
  let delivered = false;
924
927
  try {
925
- await cardRequest('v1.0/card/instances', {
928
+ // Deliver the thinking copy in the same request that first shows the
929
+ // card. Creating an empty instance and filling it after deliver (the
930
+ // previous three-request sequence) leaves a blank bubble visible in
931
+ // DingTalk for the time between deliver and the follow-up PUT, and
932
+ // leaves a permanently blank card if that PUT ever fails.
933
+ await cardRequest('v1.0/card/instances/createAndDeliver', {
926
934
  body: {
935
+ ...cardDeliverBody(cardInstanceId, normalizedTarget, appKey),
927
936
  cardTemplateId: DINGTALK_AI_CARD_TEMPLATE_ID,
928
937
  outTrackId: cardInstanceId,
929
- cardData: {
930
- cardParamMap: { config: JSON.stringify({ autoLayout: true }) },
931
- },
938
+ cardData: cardData(content, '2', normalizedTarget),
932
939
  callbackType: 'STREAM',
933
940
  cardAtUserIds: normalizedTarget.atUserIds
934
941
  ? Object.keys(normalizedTarget.atUserIds)
@@ -938,37 +945,31 @@ export function createDingtalkApi({
938
945
  },
939
946
  headers,
940
947
  signal,
941
- action: 'AI Card 创建',
942
- });
943
- await cardRequest('v1.0/card/instances/deliver', {
944
- body: cardDeliverBody(cardInstanceId, normalizedTarget, appKey),
945
- headers,
946
- signal,
947
- action: 'AI Card 投放',
948
+ action: 'AI Card 创建并投放',
948
949
  });
949
950
  delivered = true;
950
- await cardRequest('v1.0/card/instances', {
951
- method: 'PUT',
952
- body: { outTrackId: cardInstanceId, cardData: cardData(content, '2', normalizedTarget) },
953
- headers,
954
- signal,
955
- action: 'AI Card 启动',
956
- });
957
- await cardRequest('v1.0/card/streaming', {
958
- method: 'PUT',
959
- body: {
960
- outTrackId: cardInstanceId,
961
- guid: randomUUID(),
962
- key: 'msgContent',
963
- content: cardMarkdown(content, normalizedTarget).replace(/\n+$/, ''),
964
- isFull: true,
965
- isFinalize: false,
966
- isError: false,
967
- },
968
- headers,
969
- signal,
970
- action: 'AI Card 启动',
971
- });
951
+ try {
952
+ await cardRequest('v1.0/card/streaming', {
953
+ method: 'PUT',
954
+ body: {
955
+ outTrackId: cardInstanceId,
956
+ guid: randomUUID(),
957
+ key: 'msgContent',
958
+ content: cardMarkdown(content, normalizedTarget).replace(/\n+$/, ''),
959
+ isFull: true,
960
+ isFinalize: false,
961
+ isError: false,
962
+ },
963
+ headers,
964
+ signal,
965
+ action: 'AI Card 启动',
966
+ });
967
+ } catch (error) {
968
+ if (signal?.aborted) throw error;
969
+ // The card is already visible with the thinking copy from
970
+ // createAndDeliver above. Keep the instance so finishAiCard can
971
+ // still replace it in place instead of sending a second message.
972
+ }
972
973
  } catch (error) {
973
974
  if (delivered) {
974
975
  const cleanupSignal = AbortSignal.timeout(5_000);
@@ -1018,6 +1019,8 @@ export function createDingtalkApi({
1018
1019
  const token = await accessToken({ clientId, clientSecret, signal });
1019
1020
  const headers = { 'x-acs-dingtalk-access-token': token };
1020
1021
  const normalizedContent = cardMarkdown(content, target);
1022
+ // Close the streaming widget before persisting the template's
1023
+ // finished state and full answer in msgContent.
1021
1024
  await cardRequest('v1.0/card/streaming', {
1022
1025
  method: 'PUT',
1023
1026
  body: {
@@ -1033,8 +1036,7 @@ export function createDingtalkApi({
1033
1036
  signal,
1034
1037
  action: 'AI Card 完成',
1035
1038
  });
1036
- let completed = true;
1037
- const completionRequest = {
1039
+ await cardRequest('v1.0/card/instances', {
1038
1040
  method: 'PUT',
1039
1041
  body: {
1040
1042
  outTrackId: instanceId,
@@ -1043,18 +1045,9 @@ export function createDingtalkApi({
1043
1045
  },
1044
1046
  headers,
1045
1047
  signal,
1046
- action: 'AI Card 收口',
1047
- };
1048
- try {
1049
- await cardRequest('v1.0/card/instances', completionRequest);
1050
- } catch {
1051
- try {
1052
- await cardRequest('v1.0/card/instances', completionRequest);
1053
- } catch {
1054
- completed = false;
1055
- }
1056
- }
1057
- return { delivered: true, completed };
1048
+ action: 'AI Card 完成状态',
1049
+ });
1050
+ return { delivered: true, completed: true };
1058
1051
  },
1059
1052
 
1060
1053
  failAiCard: failCard,
@@ -1336,6 +1336,8 @@ export class DingtalkHarnessBridge {
1336
1336
  providerMessageIds: cardStream.providerMessageIds,
1337
1337
  });
1338
1338
  } else {
1339
+ // Failed streams close the card with a notice pointing to a
1340
+ // follow-up message. Deliver the answer through that fallback.
1339
1341
  textReceipt = createDeliveryReceipt({
1340
1342
  deliveryId: messageId,
1341
1343
  presentation: 'dingtalk-text',
@@ -1411,7 +1413,9 @@ export class DingtalkHarnessBridge {
1411
1413
  ? `${errorText}\n\n${batchFailureMessage}`
1412
1414
  : errorText;
1413
1415
  const streamed = cardStarted && await cardStream.finish(visibleError);
1414
- if (!streamed) await this.#send(sessionWebhook, visibleError, this.#atUsersFor(message));
1416
+ if (!streamed) {
1417
+ await this.#send(sessionWebhook, visibleError, this.#atUsersFor(message));
1418
+ }
1415
1419
  } catch {
1416
1420
  this.#logger.error?.('[dsh-dingtalk] failed to send the safe error reply');
1417
1421
  }