From caa9e5eec2d85ab73fce2a1de62ffac0e3f036f9 Mon Sep 17 00:00:00 2001 From: C3H3-AI <256468226+C3H3-AI@users.noreply.github.com> Date: Sun, 23 Aug 2026 11:13:03 +0800 Subject: [PATCH] fix(feishu): ensure /m sends a new card while other actions keep in-place updates --- lib/index.js | 4 ++-- src/channels/feishu/bridge.mjs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/index.js b/lib/index.js index 42bf50a..94a91df 100644 --- a/lib/index.js +++ b/lib/index.js @@ -249,11 +249,11 @@ ${s.join(` **4**\u72B6\u6001 \xB7 **5**\u4FEE\u590D \xB7 **6**\u66F4\u591A\u8BBE\u7F6E \xB7 **7**\u5E2E\u52A9`)},{tag:"hr"},Kc()];return bi("\u{1F4D6} \u5E2E\u52A9",o)}function bq(n){if(typeof n!="string"||!/^[A-Za-z0-9_-]{16,128}$/.test(n))throw new TypeError("A safe card-action probe nonce is required");return bi("\u{1F9EA} \u9A8C\u8BC1\u5361\u7247\u6309\u94AE",[{tag:"div",text:tt("\u6388\u6743\u5DF2\u63D0\u4EA4\u3002\u8BF7\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\uFF1B\u673A\u5668\u4EBA\u771F\u5B9E\u6536\u5230\u56DE\u8C03\u540E\u624D\u4F1A\u5224\u5B9A\u4FEE\u590D\u6210\u529F\u3002")},{tag:"column_set",flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:bQ("\u5B8C\u6210\u9A8C\u8BC1"),type:"primary",width:"fill",behaviors:[{type:"callback",value:{action:"repair_verify",nonce:n}}]}]}]}])}function Mq(n,r,o,i,e=new Set){let a=o*10,A=r.slice(a,a+10),t=Math.max(1,Math.ceil(i/10)),s=I=>typeof e?.has=="function"&&e.has(I),g=(I,E)=>({tag:"column_set",flex_mode:"none",horizontal_spacing:"default",columns:[{tag:"column",width:"90px",vertical_align:"center",elements:[I]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[E]}]}),c=[{tag:"div",text:tt(`**\u5DE5\u4F5C\u533A**\uFF1A\`${n}\` \u5171 **${i}** \u4E2A\u4F1A\u8BDD${i>10?`\uFF08\u7B2C ${o+1}/${t} \u9875\uFF09`:""}`)},...A.map((I,E)=>{let B=`${E+1}. ${ep(I.title)}${I.archived===!0?"\uFF08\u5DF2\u5F52\u6863\uFF09":""}`,f=s(I.sessionId);return g(OQ(f?"\u2B50 \u53D6\u6D88\u5173\u6CE8":"\u2606 \u5173\u6CE8",f?`unwatch:${I.sessionId}`:`watch:${I.sessionId}`),OQ(B,`use:${I.sessionId}`))})];return o>0&&c.push(Ao("\u25C0 \u4E0A\u4E00\u9875",`sessions:${o-1}`)),o+1Ao(`${e+1}. ${i}${i===r?"\uFF08\u5F53\u524D\uFF09":""}`,`workspace:${i}`)),{tag:"hr"},Kc()];return bi("\u{1F5C2} \u5DE5\u4F5C\u533A",o)}function FSe(n,r){let o=new Set(n.map(e=>e.sessionId)),i=(Array.isArray(r)?r:[]).filter(e=>e?.sessionId&&!o.has(e.sessionId)).slice(0,30).map(e=>({text:{tag:"plain_text",content:ep(e.title??e.sessionId)},value:e.sessionId}));return i.length===0?null:{tag:"multi_select_static",name:"watch_add",placeholder:{tag:"plain_text",content:"\u52FE\u9009\u8981\u5173\u6CE8\u7684\u4F1A\u8BDD"},options:i,behaviors:[{type:"callback",value:{action:"watch_add",kind:"multi"}}]}}function LSe(n){let r=n.slice(0,30).map(o=>({text:{tag:"plain_text",content:ep(o.title)},value:o.sessionId}));return r.length===0?null:{tag:"multi_select_static",name:"watch_remove",placeholder:{tag:"plain_text",content:"\u52FE\u9009\u8981\u53D6\u6D88\u5173\u6CE8\u7684\u4F1A\u8BDD"},options:r,behaviors:[{type:"callback",value:{action:"watch_remove",kind:"multi"}}]}}function Nq(n,r){let o=Array.isArray(n)?n:[],i=FSe(o,r),e=LSe(o),a=[];return o.length===0?a.push({tag:"div",text:tt("\u5F53\u524D\u6CA1\u6709\u5173\u6CE8\u7684\u4F1A\u8BDD\u3002\u4EFB\u52A1\u5B8C\u6210\u4F1A\u81EA\u52A8\u63A8\u9001\u7ED3\u679C\u3002")}):a.push({tag:"div",text:tt(`\u5F53\u524D\u5173\u6CE8 **${o.length}** \u4E2A\u4F1A\u8BDD\uFF1A`)}),i&&a.push({tag:"hr"},{tag:"div",text:tt("**\u2795 \u6DFB\u52A0\u5173\u6CE8**\uFF08\u591A\u9009\u4E0B\u62C9\u52FE\u9009\uFF09")},i),e&&a.push({tag:"hr"},{tag:"div",text:tt("**\u2796 \u53D6\u6D88\u5173\u6CE8**\uFF08\u591A\u9009\u4E0B\u62C9\u52FE\u9009\uFF09")},e),a.push({tag:"hr"},lg("\u{1F4CB} \u4F1A\u8BDD\u5217\u8868","sessions","\u{1F519} \u8FD4\u56DE\u83DC\u5355","back_to_menu")),bi("\u{1F441} \u5173\u6CE8\u5217\u8868",a)}function Tq(n,r,o){let i=o==="completed"?"\u5DF2\u5B8C\u6210":o==="stopped"?"\u5DF2\u505C\u6B62":o==="aborted"?"\u5DF2\u4E2D\u6B62":o==="cancelled"?"\u5DF2\u53D6\u6D88":"\u5DF2\u7ED3\u675F";return bi("\u2705 \u4EFB\u52A1\u5B8C\u6210",[{tag:"div",text:tt(`**${ep(r)}** \`${n}\``)},{tag:"div",text:tt(`**\u72B6\u6001**\uFF1A${i}`)},{tag:"hr"},lg("\u{1F4CB} \u4F1A\u8BDD\u5217\u8868","sessions","\u{1F519} \u8FD4\u56DE\u83DC\u5355","back_to_menu"),{tag:"div",text:tt("\u7ED1\u5B9A\u8BE5\u4F1A\u8BDD\u540E\u53EF\u7EE7\u7EED\u8FFD\u95EE\uFF0C\u8F93\u5165\u6587\u5B57\u5373\u53EF\u3002")}])}var Rq=["\u7EE7\u7EED","\u52A0\u901F\u8FD0\u884C","\u603B\u7ED3\u5F53\u524D\u8FDB\u5C55","\u66F4\u7B80\u6D01\u4E9B","\u66F4\u8BE6\u7EC6\u4E9B"],nR="__steer_custom__";function kq({hasSession:n}){let r=n?"\u4ECE\u4E0B\u65B9\u4E0B\u62C9\u9009\u62E9\u8865\u5145\u6307\u4EE4\uFF1B\u6700\u540E\u4E00\u9879\u53EF\u81EA\u5B9A\u4E49\u8F93\u5165\u3002":"\u5F53\u524D\u6CA1\u6709\u7ED1\u5B9A\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u4F1A\u8BDD\u518D\u8865\u5145\u6307\u4EE4\u3002",o=Rq.map(e=>({text:{tag:"plain_text",content:e},value:e}));o.push({text:{tag:"plain_text",content:"\u270F\uFE0F \u66F4\u591A / \u81EA\u5B9A\u4E49\u2026"},value:nR});let i=[{tag:"div",text:tt(r)},{tag:"hr"},{tag:"select_static",name:"steer_quick",placeholder:{tag:"plain_text",content:"\u9009\u62E9\u8865\u5145\u6307\u4EE4"},initial_index:1,options:o,behaviors:[{type:"callback",value:{action:"steer",source:"quick"}}]},{tag:"hr"},Ao("\u{1F519} \u8FD4\u56DE\u83DC\u5355","back_to_menu")];return bi("\u2795 \u8865\u5145\u6307\u4EE4",i)}function sR(){let n=[{tag:"div",text:tt("\u8F93\u5165\u8865\u5145\u6307\u4EE4\u540E\u70B9\u300C\u63D0\u4EA4\u300D\uFF0C\u53D1\u9001\u7ED9\u5F53\u524D\u8FD0\u884C\u7684\u4EFB\u52A1\u3002")},{tag:"hr"},{tag:"form",name:"steer_form",elements:[{tag:"input",name:"steer_text",placeholder:{tag:"plain_text",content:"\u8F93\u5165\u4F60\u7684\u8865\u5145\u6307\u4EE4"}},{tag:"button",text:{tag:"plain_text",content:"\u63D0\u4EA4"},type:"primary",width:"fill",form_action_type:"submit",behaviors:[{type:"callback",value:{action:"steer",source:"form"}}]}]},{tag:"hr"},Ao("\u{1F519} \u8FD4\u56DE\u83DC\u5355","back_to_menu")];return bi("\u2795 \u81EA\u5B9A\u4E49\u6307\u4EE4",n)}import{mkdir as USe,readFile as HSe,rename as KSe,writeFile as YSe}from"node:fs/promises";import{dirname as xSe}from"node:path";var jSe=Object.freeze({version:1,sessions:{},seenMessageIds:[],watches:{},includeArchivedSessions:!1}),_Q=20;function gR(n){return n&&typeof n=="object"&&typeof n.sessionId=="string"&&n.sessionId.length>0&&typeof n.chatId=="string"&&n.chatId.length>0}var MQ=class{#e;#A=structuredClone(jSe);#t=Promise.resolve();constructor(r){this.#e=r}async load(){try{let r=JSON.parse(await HSe(this.#e,"utf8"));this.#A={version:1,sessions:r.sessions&&typeof r.sessions=="object"?r.sessions:{},seenMessageIds:Array.isArray(r.seenMessageIds)?r.seenMessageIds.slice(-1e3):[],watches:r.watches&&typeof r.watches=="object"?r.watches:{},includeArchivedSessions:typeof r.includeArchivedSessions=="boolean"?r.includeArchivedSessions:!1}}catch(r){if(r?.code!=="ENOENT")throw r;await this.#r()}return this}sessionFor(r){return this.#A.sessions[r]??null}async setSession(r,o){this.#A.sessions[r]=o,await this.#r()}async clearSession(r){delete this.#A.sessions[r],await this.#r()}async clearSessions(){this.#A.sessions={},await this.#r()}hasSeen(r){return this.#A.seenMessageIds.includes(r)}async markSeen(r){this.hasSeen(r)||(this.#A.seenMessageIds.push(r),this.#A.seenMessageIds.length>1e3&&this.#A.seenMessageIds.splice(0,this.#A.seenMessageIds.length-1e3),await this.#r())}snapshot(){return structuredClone(this.#A)}watchEntries(r){let o=this.#A.watches[r];return Array.isArray(o)?o.filter(gR):[]}watchEntry(r,o){return this.watchEntries(r).find(i=>i.sessionId===o)??null}async setWatch(r,o){let i=this.#A.watches[r]??[],e=i.findIndex(a=>a.sessionId===o.sessionId);e===-1?(i.length>=_Q&&i.shift(),i.push(o)):i[e]=o,this.#A.watches[r]=i,await this.#r()}async removeWatch(r,o){let i=this.#A.watches[r]??[];this.#A.watches[r]=i.filter(e=>e.sessionId!==o),await this.#r()}async clearWatches(r){delete this.#A.watches[r],await this.#r()}keysWatching(r){return Object.entries(this.#A.watches).filter(([,o])=>Array.isArray(o)&&o.some(i=>gR(i)&&i.sessionId===r)).map(([o])=>o)}watchedSessionIds(){let r=new Set;for(let o of Object.values(this.#A.watches))if(Array.isArray(o))for(let i of o)gR(i)&&r.add(i.sessionId);return[...r]}includesArchivedSessions(){return this.#A.includeArchivedSessions===!0}async setIncludeArchivedSessions(r){this.#A.includeArchivedSessions=r===!0,await this.#r()}async#r(){let r=JSON.stringify(this.#A,null,2)+` -`;this.#t=this.#t.then(async()=>{await USe(xSe(this.#e),{recursive:!0,mode:448});let o=`${this.#e}.tmp`;await YSe(o,r,{encoding:"utf8",mode:384}),await KSe(o,this.#e)}),await this.#t}};var pg=Object.freeze({MENTION:"mention",ALL:"all"});function Mi(n){return n===pg.ALL?pg.ALL:pg.MENTION}function NQ(n){return n===pg.MENTION||n===pg.ALL}var TQ="\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002",qSe=30*6e4,VSe=/^\/m(?:enu)?$/i,zSe=/^\/repair(?:\s|$)/i,WSe=/^\/repair(?:\s+(qr|status|cancel|verify))?\s*$/i,vq=/^\/watch(?:\s+([^\s]+))?$/i,Pq=/^\/unwatch(?:\s+([^\s]+))?$/i,ZSe=/^\/watchlist$/i,XSe=/^\/sessionlist(?:\s|$)/i,$Se=/^\/workspacelist$/i,eDe=/^\d{1,2}$/,ADe=10*6e4,tDe=50,rDe=15e3,aDe=1e3,RQ=new Set(["starting","qr_ready","polling","slow_down","domain_switched","saving"]),Gq=new Set(["succeeded","expired","cancelled","error"]),iDe=new Set(["accounts.feishu.cn","open.feishu.cn","accounts.larksuite.com","open.larksuite.com"]),Fq=/^\/archived(?:\s+(on|off))?$/i,oDe=/^\/(?:m(?:enu)?|help|new|status|compact|sessionlist(?:\s|$)|workspacelist|watchlist|archived(?:\s+(on|off))?)$/i,nDe=["/session Session ID \u6216\u5F53\u524D\u5DE5\u4F5C\u533A\u5E8F\u53F7 \u5C06\u5F53\u524D\u804A\u5929\u7ED1\u5B9A\u5230\u6307\u5B9A\u4F1A\u8BDD","/workspacelist \u5217\u51FA\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84","/sessionlist [\u5DE5\u4F5C\u533A\u5E8F\u53F7\u6216\u7EDD\u5BF9\u8DEF\u5F84] \u5217\u51FA\u4F1A\u8BDD ID \u548C\u6807\u9898"];function Mh(n){switch(n?.code){case"workspace-not-absolute":return"\u5DE5\u4F5C\u533A\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002";case"workspace-not-found":return"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u4E0D\u5B58\u5728\u3002";case"workspace-not-directory":return"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u76EE\u5F55\u3002";case"workspace-bot-not-found":return"\u673A\u5668\u4EBA\u6B63\u5728\u79FB\u9664\u6216\u5DF2\u91CD\u65B0\u63A5\u5165\uFF0C\u65E0\u6CD5\u64CD\u4F5C\u539F\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\u3002";default:return"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}function XA(n){return typeof n=="string"&&n.trim()?n.trim():null}function Lq(n){return(Array.isArray(n?.events)?n.events:[]).map(r=>r?.event??r).filter(r=>r&&typeof r=="object"&&Number.isFinite(r.seq)).sort((r,o)=>r.seq-o.seq)}function vQ(n){return XA(n?.sender?.sender_id?.open_id)??XA(n?.sender?.sender_id?.user_id)}function sDe(n){return XA(n?.sender?.sender_id?.open_id)}function Uq(n,r){return new Promise((o,i)=>{if(r?.aborted){i(r.reason??new DOMException("Aborted","AbortError"));return}let e=setTimeout(a,n);e.unref?.();function a(){r?.removeEventListener("abort",A),o()}function A(){clearTimeout(e),i(r.reason??new DOMException("Aborted","AbortError"))}r?.addEventListener("abort",A,{once:!0})})}function kQ(n,{botId:r}={}){let o=n&&typeof n=="object"?n:{},i=o.registration&&typeof o.registration=="object"?o.registration:o,e=XA(i.operation)??XA(o.operation);if(e&&e!=="callback_repair")throw new Error("The active Feishu operation is not a callback repair");let a=XA(i.botId)??XA(o.botId);if(r&&a&&a!==r)throw new Error("The Feishu repair belongs to another bot");let A=XA(i.state),t=i.attemptId??i.attempt,s=typeof t=="string"||Number.isFinite(t)?String(t):null;if(!A||!s)throw new Error("Feishu returned an invalid repair status");let g=XA(i.verificationUrl)??XA(i.qrCodeUrl),c=Number(i.expiresAt),I=Number(i.remainingSeconds),E=Number(i.pollIntervalMs)||Number(i.pollIntervalSeconds)*1e3;return{state:A,attemptId:s,botId:a,verificationUrl:g,expiresAt:Number.isFinite(c)?c:null,remainingSeconds:Number.isFinite(I)?I:null,pollIntervalMs:Number.isFinite(E)&&E>0?E:null,error:i.error&&typeof i.error=="object"?{code:XA(i.error.code),message:XA(i.error.message)}:null}}function Hq(n,r){let o=new URL(n);if(o.protocol!=="https:"||!iDe.has(o.hostname))throw new Error("Feishu returned an untrusted repair URL");if(o.searchParams.get("tp")!=="sdk"||o.searchParams.get("clientID")!==r||o.searchParams.has("createOnly"))throw new Error("Feishu returned an invalid existing-app repair URL");if(o.toString().includes("{{client_id}}")||o.toString().includes("%7B%7Bclient_id%7D%7D"))throw new Error("Feishu returned an unresolved client id placeholder");return o.toString()}function gDe(n,r){return r.needsPresentation!==!0&&r.questions[r.index]&&vQ(n)===r.actor&&n?.message?.message_type==="text"&&XA(bh(n))}function cDe(n){for(let r of["messagesReceived","messagesReplied","messagesRejected"])n[r]??=0;n.lastMessageAt??=null,n.lastReplyAt??=null,n.lastRejectedAt??=null,n.lastError??=null}var PQ=class{#e;#A;#t;#r;#n=new Map;#o=new Map;#l=new Map;#s=new Map;#c=new Set;#a=new Set;#i=new Set;#I;#g;#p;#h;#C;#E;#d;#B;#u;#y;#S;#f;#m=null;#D=0;#w;#k;#M=new Map;#T=new Map;#O=new Map;#b=null;#_=Promise.resolve();#P=new Map;#N=[];constructor({client:r,channel:o,harness:i,state:e,status:a,allowedSenderOpenIds:A=new Set,botId:t,appId:s,botOpenId:g,groupResponseMode:c=pg.ALL,repair:I,repairOwnerOpenIds:E,repairPollIntervalMs:B=aDe,repairLinkWaitMs:f=rDe,replyTimeoutMs:Q=6e5,logger:y=console,signal:m}){if(!r||!i||!e||!a)throw new TypeError("Feishu bridge dependencies are required");if(I!=null){if(!I||typeof I.start!="function"||typeof I.status!="function"||typeof I.cancel!="function")throw new TypeError("Feishu repair capability requires start/status/cancel");if(!XA(t)||!XA(s))throw new TypeError("Feishu repair capability requires botId and appId")}if(!Number.isFinite(B)||B<=0||!Number.isFinite(f)||f<=0)throw new TypeError("Feishu repair timing values must be positive numbers");this.#e=r,this.#A=o,this.#t=i,this.#r=e,this.#g=a,this.#p=A,this.#d=XA(t),this.#B=XA(s),this.#u=XA(g),this.#y=Mi(c),this.#S=I??null;let T=E??A;this.#f=new Set([...T??[]].filter(_=>typeof _=="string"&&_&&_!=="*")),this.#w=B,this.#k=f,this.#h=Q,this.#C=y,this.#I=new Ja({label:"Feishu",logger:y}),this.#E=m,cDe(this.#g),typeof this.#t?.watchHarnessEvents=="function"&&queueMicrotask(()=>this.#fe())}setGroupResponseMode(r){this.#y=Mi(r)}#H(r){if(r?.message?.chat_type==="p2p")return!0;let o=Array.isArray(r?.message?.mentions)?r.message.mentions:[];return this.#u?o.some(i=>i?.id?.open_id===this.#u||i?.open_id===this.#u):o.length>0}accept(r){if(this.#E?.aborted)return Promise.resolve();let o=XA(r?.message?.message_id);if(!o||Bq(r))return Promise.resolve();if(!fq(r,this.#p))return this.#g.messagesRejected+=1,this.#g.lastRejectedAt=new Date().toISOString(),this.#C.warn?.("[dsh-feishu] ignored a message from a sender outside the allowlist"),Promise.resolve();let i=this.#H(r);if(r?.message?.chat_type!=="p2p"&&this.#y===pg.MENTION&&!i||this.#r.hasSeen(o)||this.#c.has(o))return Promise.resolve();let e;try{e=uq(r)}catch{return this.#g.messagesRejected+=1,this.#g.lastRejectedAt=new Date().toISOString(),Promise.resolve()}if(r.message.chat_type==="p2p"){let I=XA(r.message.chat_id);I&&Hi(this.#r,{chatId:I})}this.#c.add(o);let a=this.#Se(o,"OnIt"),A=oR(r,this.#e),t=XA(A.content)??"";if(oDe.test(t))return Promise.resolve().then(()=>this.#J(r,e,{alreadyRecorded:!1})).then(()=>this.#z(o,a,"DONE")).catch(E=>this.#G(r,o,a,E)).finally(()=>this.#c.delete(o));let s=hi(t)?Wa:di(t)?ui:Bi(t)?Ji:null;if(s&&i){let I=this.#F(r,o,e,A,s),E;return E=I.then(()=>this.#z(o,a,"DONE")).catch(B=>this.#G(r,o,a,B)).finally(()=>{this.#c.delete(o),this.#i.delete(E)}),this.#i.add(E),E}if(this.#pe(r,e))return Promise.resolve().then(()=>this.#Ee(r,o)).then(()=>this.#z(o,a,"DONE")).catch(E=>this.#G(r,o,a,E)).finally(()=>this.#c.delete(o));let g=this.#o.get(e),c=this.#I.claimReply({key:e,actor:vQ(r),messageId:o,text:bh(r)??"",addressed:i,hasPendingQuestion:!!g,questionCompletion:g?.submitting||g?.claimedReplyMessageId?g.queue:null,isQuestionPending:()=>this.#o.has(e),send:I=>this.#Q(r.message.chat_id,I)});if(c){let I=c.process(async()=>this.#r.hasSeen(o)?!1:(await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1,!0)),E;return E=I.then(()=>this.#z(o,a,"DONE")).catch(B=>this.#G(r,o,a,B)).finally(()=>{this.#c.delete(o),this.#a.delete(E)}),this.#a.add(E),E}if(g&&vQ(r)!==g.actor)return this.#R(r,o,e,a);if(g?.submitting||g?.claimedReplyMessageId)return this.#R(r,o,e,a);if(g){gDe(r,g)&&(g.claimedReplyMessageId=o);let E=(g.queue??Promise.resolve()).catch(()=>{}).then(()=>this.#Ye(r,o,e,g,a));g.queue=E;let B=()=>{g.claimedReplyMessageId===o&&(g.claimedReplyMessageId=null),g.queue===E&&(g.queue=null)},f;return f=E.then(()=>(B(),this.#z(o,a,"DONE")),Q=>(B(),this.#G(r,o,a,Q))).finally(()=>{B(),this.#c.delete(o),this.#a.delete(f)}),this.#a.add(f),f}return this.#R(r,o,e,a)}#R(r,o,i,e,{releaseMessageId:a=!0,alreadyRecorded:A=!1,finalize:t=!0}={}){let g=(this.#n.get(i)??Promise.resolve()).catch(()=>{}).then(()=>this.#J(r,i,{alreadyRecorded:A})),c=t?g.then(()=>this.#z(o,e,"DONE")).catch(E=>this.#G(r,o,e,E)):g,I;return I=c.finally(()=>{a&&this.#c.delete(o),this.#n.get(i)===I&&this.#n.delete(i)}),this.#n.set(i,I),I}async#G(r,o,i,e){if(e?.code==="turn-stopped"){await this.#he(o,i);return}if(this.#E?.aborted){await this.#he(o,i);return}this.#C.error?.("[dsh-feishu] message handling failed:",e?.message??String(e)),this.#g.lastError=e?.message??String(e),await this.#z(o,i,"ERROR"),await this.#Q(r.message.chat_id,xi(e)??"\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002\u5982\u679C\u95EE\u9898\u6301\u7EED\uFF0C\u8BF7\u5728 DeepSeek Harness \u7684\u98DE\u4E66\u63D2\u4EF6\u9875\u9762\u68C0\u67E5\u8FDE\u63A5\u72B6\u6001\u3002").catch(()=>{})}async waitForIdle(){await Promise.allSettled([...this.#n.values(),...[...this.#o.values()].flatMap(r=>r.queue?[r.queue]:[]),...this.#a,...this.#i,this.#_])}async#F(r,o,i,e,a){if(this.#E?.throwIfAborted(),this.#r.hasSeen(o))return;await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1;let A=await a(XA(e.content)??"",this.#t,this.#r,i,{signal:this.#E,hasImages:lr(e),pendingInteraction:this.#o.has(i)||this.#I.hasPending(i),control:{owner:this,key:i}});A?.stopped&&await Promise.allSettled([this.#me(i),this.#I.closeRoute(i)]);for(let t of A?.messages??[A?.message])t&&await this.#Q(r.message.chat_id,t);this.#g.lastError=null}async#J(r,o,{alreadyRecorded:i=!1}={}){this.#E?.throwIfAborted();let e=r.message.message_id;if(!i){if(this.#r.hasSeen(e))return;await this.#r.markSeen(e),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1}let a=oR(r,this.#e),A=a.content,t=lr(a),s=r.message.message_type==="text"&&!t?A:null;if(!A&&!t){await this.#Q(r.message.chat_id,"\u76EE\u524D\u652F\u6301\u6587\u5B57\u548C\u56FE\u7247\u6D88\u606F\u3002");return}if(s!==null&&zSe.test(s)){await this.#L(r,s);return}if(s==="/help"){await this.#Q(r.message.chat_id,wq());return}if(VSe.test(s)){await this.#X(o,r.message.chat_id);return}if(s==="/new"){await this.#r.clearSession(o),await this.#Q(r.message.chat_id,"\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002"),await this.#X(o,r.message.chat_id);return}if(s==="/status"){await this.#_e(o,r.message.chat_id);return}if(s==="/compact"){let I=await za(s,this.#t,this.#r,o,{signal:this.#E});I&&await this.#Q(r.message.chat_id,I.message);return}if(XSe.test(s)){let I=s.slice(12).trim()||null;await this.#de({chatId:r.message.chat_id,key:o},I,0);return}if($Se.test(s)){await this.#ue({chatId:r.message.chat_id,key:o});return}if(vq.test(s)){let I=(vq.exec(s)?.[1]??"").trim()||null;await this.#se(o,r.message.chat_id,I);return}if(Pq.test(s)){let I=(Pq.exec(s)?.[1]??"").trim()||null;await this.#ge(o,r.message.chat_id,I);return}if(ZSe.test(s)){await this.#ce(o,r.message.chat_id);return}if(Fq.test(s)){let E=Fq.exec(s)[1]?.toLowerCase();if(E!=="on"&&E!=="off"){await this.#Q(r.message.chat_id,"\u7528\u6CD5\uFF1A/archived on\uFF08\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\uFF09\u6216 /archived off\uFF08\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\uFF09");return}typeof this.#r?.setIncludeArchivedSessions=="function"&&await this.#r.setIncludeArchivedSessions(E==="on"),await this.#Q(r.message.chat_id,E==="on"?"\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002":"\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002");return}if(eDe.test(s)){let I=this.#Z(o);if(I){await this.#x(I,Number(s),{chatId:r.message.chat_id,key:o,event:r});return}}let g=s===null?null:await ji(A,this.#t,o);if(g){for(let I of g.messages??[g.message])await this.#Q(r.message.chat_id,I);return}let c=s===null?null:await za(s,this.#t,this.#r,o,{signal:this.#E});if(c){await this.#Q(r.message.chat_id,c.message);return}this.#C.info?.(`[dsh-feishu] processing ${r.message.chat_type} message ${e}`);try{await this.#Ke(r,o,a),this.#g.messagesReplied+=1,this.#g.lastReplyAt=new Date().toISOString(),this.#g.lastError=null}finally{await this.#me(o),await this.#I.closeRoute(o)}}async#L(r,o){if(r?.message?.chat_type!=="p2p"){await this.#Q(r.message.chat_id,"\u4E3A\u907F\u514D\u6388\u6743\u94FE\u63A5\u66B4\u9732\uFF0C\u8BF7\u79C1\u804A\u673A\u5668\u4EBA\u53D1\u9001 /repair\u3002");return}let i=sDe(r);if(!i||!this.#f.has(i)){await this.#Q(r.message.chat_id,this.#f.size===0?"\u5F53\u524D\u673A\u5668\u4EBA\u6CA1\u6709\u53EF\u9A8C\u8BC1\u7684\u63A5\u5165\u8005\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u4ECE\u804A\u5929\u53D1\u8D77\u4FEE\u590D\uFF1B\u8BF7\u5148\u5728\u63D2\u4EF6\u9875\u8BBE\u7F6E\u7BA1\u7406\u5458\u3002":"\u6B64\u64CD\u4F5C\u53EA\u80FD\u7531\u673A\u5668\u4EBA\u63A5\u5165\u8005\u5728\u79C1\u804A\u4E2D\u53D1\u8D77\uFF0C\u672A\u8FDB\u884C\u4EFB\u4F55\u4FEE\u6539\u3002");return}if(!this.#S){await this.#Q(r.message.chat_id,"\u5F53\u524D Host \u7248\u672C\u6682\u4E0D\u652F\u6301\u804A\u5929\u5185\u4FEE\u590D\uFF0C\u8BF7\u5148\u66F4\u65B0\u63D2\u4EF6\u3002");return}let e=WSe.exec(o);if(!e){await this.#Q(r.message.chat_id,"\u7528\u6CD5\uFF1A/repair\u3001/repair qr\u3001/repair status\u3001/repair cancel \u6216 /repair verify");return}let a=e[1]?.toLowerCase()??"start",A=r.message.chat_id;if(a==="start"){await this.#W({actorOpenId:i,chatId:A});return}let t=this.#m;if(!t){await this.#Q(A,"\u5F53\u524D Runtime \u6CA1\u6709\u53EF\u6062\u590D\u7684\u4FEE\u590D\u4EFB\u52A1\u8BB0\u5F55\uFF08\u673A\u5668\u4EBA\u53EF\u80FD\u521A\u5B8C\u6210\u5BC6\u94A5\u66F4\u65B0\u5E76\u91CD\u542F\uFF09\u3002\u672C\u547D\u4EE4\u4E0D\u4F1A\u542F\u52A8\u65B0\u7684\u6388\u6743\uFF1B\u8BF7\u67E5\u770B\u673A\u5668\u4EBA\u53D1\u9001\u7684\u9A8C\u8BC1\u7ED3\u679C\uFF0C\u786E\u8BA4\u4E0A\u4E00\u6B21\u4EFB\u52A1\u5DF2\u7ED3\u675F\u540E\u518D\u53D1\u9001 /repair\u3002");return}if(t.actorOpenId!==i){await this.#Q(A,"\u53E6\u4E00\u4F4D\u7BA1\u7406\u5458\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002");return}if(a==="cancel"){let g;try{let c=await this.#S.cancel(this.#Y(t));g=kQ(c,{botId:this.#d}),t.snapshot=g}catch{await this.#Q(A,"\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u4FEE\u590D\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}g.state==="cancelled"&&(t.stopped=!0,this.#D+=1),await this.#Q(A,this.#V(g));return}let s;try{s=await this.#q(t)}catch{await this.#Q(A,"\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}if(a==="qr"){if(!RQ.has(s.state)||!t.verificationUrl){await this.#Q(A,this.#V(s,{verificationFocused:!0}));return}await this.#ie(A,t.verificationUrl,s);return}await this.#Q(A,this.#V(s,{verificationFocused:a==="verify"}))}#Y(r){return{botId:this.#d,attemptId:r.attemptId,actorOpenId:r.actorOpenId,chatId:r.chatId}}async#W({actorOpenId:r,chatId:o}){let i=this.#m;if(i&&RQ.has(i.snapshot.state)){if(i.actorOpenId!==r){await this.#Q(o,"\u53E6\u4E00\u4F4D\u7BA1\u7406\u5458\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002");return}try{let A=await this.#q(i);if(RQ.has(A.state)&&i.verificationUrl){await this.#$(o,i.verificationUrl,A,{existing:!0});return}}catch{await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}}let e;try{e=kQ(await this.#S.start({botId:this.#d,actorOpenId:r,chatId:o}),{botId:this.#d}),e=await this.#ae(e,{actorOpenId:r,chatId:o})}catch{await this.#Q(o,"\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u8BF7\u7A0D\u540E\u53D1\u9001 /repair \u91CD\u8BD5\u3002");return}let a={attemptId:e.attemptId,actorOpenId:r,chatId:o,snapshot:e,verificationUrl:null,stopped:!1,announcedSaving:!1,announcedTerminal:!1};if(this.#m=a,e.verificationUrl)try{a.verificationUrl=Hq(e.verificationUrl,this.#B)}catch{a.stopped=!0,await this.#S.cancel(this.#Y(a)).catch(()=>{}),await this.#Q(o,"\u98DE\u4E66\u8FD4\u56DE\u4E86\u65E0\u6CD5\u5B89\u5168\u9A8C\u8BC1\u7684\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002");return}if(Gq.has(e.state)){a.announcedTerminal=!0,e.state!=="succeeded"&&await this.#Q(o,this.#V(e));return}if(!a.verificationUrl){a.stopped=!0,await this.#Q(o,"\u98DE\u4E66\u672A\u8FD4\u56DE\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002");return}await this.#$(o,a.verificationUrl,e),this.#v(a)}async#ae(r,o){let i=r,e=Date.now()+this.#k;for(;!i.verificationUrl&&RQ.has(i.state);){if(Date.now()>=e)throw new Error("Feishu repair link timed out");await Uq(Math.min(100,this.#w),this.#E),i=kQ(await this.#S.status({botId:this.#d,attemptId:i.attemptId,actorOpenId:o.actorOpenId,chatId:o.chatId}),{botId:this.#d})}return i}async#q(r){let o=kQ(await this.#S.status(this.#Y(r)),{botId:this.#d});if(o.attemptId!==r.attemptId)throw new Error("Feishu repair attempt changed unexpectedly");return r.snapshot=o,o.verificationUrl&&(r.verificationUrl=Hq(o.verificationUrl,this.#B)),o}#v(r){let o=++this.#D;(async()=>{for(;!r.stopped&&this.#m===r&&this.#D===o&&!this.#E?.aborted;){let i=Math.max(250,Math.min(1e4,r.snapshot.pollIntervalMs??this.#w));if(await Uq(i,this.#E),r.stopped||this.#m!==r||this.#D!==o)return;let e=await this.#q(r);if(e.state==="saving"&&!r.announcedSaving&&(r.announcedSaving=!0,await this.#Q(r.chatId,"\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u53D1\u9001\u5E76\u7B49\u5F85\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\uFF1B\u6536\u5230\u771F\u5B9E\u56DE\u8C03\u540E\u624D\u4F1A\u5B8C\u6210\u3002")),Gq.has(e.state)){r.stopped=!0,e.state!=="succeeded"&&!r.announcedTerminal&&(r.announcedTerminal=!0,await this.#Q(r.chatId,this.#V(e)));return}}})().catch(async()=>{this.#E?.aborted||r.stopped||this.#m!==r||(r.stopped=!0,this.#C.warn?.("[dsh-feishu] callback repair status monitoring failed"),await this.#Q(r.chatId,"\u4FEE\u590D\u72B6\u6001\u67E5\u8BE2\u4E2D\u65AD\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair status \u91CD\u8BD5\u67E5\u8BE2\u3002").catch(()=>{}))})}async#$(r,o,i,{existing:e=!1}={}){let a=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null),A=a===null?"\u94FE\u63A5\u4E3A\u77ED\u671F\u6709\u6548":`\u94FE\u63A5\u7EA6 ${Math.max(1,Math.ceil(a/60))} \u5206\u949F\u540E\u8FC7\u671F`;await this.#Q(r,[e?"\u5DF2\u6709\u4E00\u4E2A\u4FEE\u590D\u4EFB\u52A1\u5728\u7B49\u5F85\u6388\u6743\u3002":"\u{1F527} \u51C6\u5907\u4FEE\u590D\u5361\u7247\u6309\u94AE\u3002","\u672C\u6B21\u53EA\u4F1A\u589E\u91CF\u6DFB\u52A0 card.action.trigger\u3002\u8BF7\u6838\u5BF9\u786E\u8BA4\u9875\u53EA\u663E\u793A\u8FD9\u4E00\u9879\uFF1B\u82E5\u51FA\u73B0\u5176\u4ED6\u6743\u9650\u6216\u4E8B\u4EF6\uFF0C\u8BF7\u53D6\u6D88\u3002","","\u5F53\u524D\u8BBE\u5907\u76F4\u63A5\u6253\u5F00\uFF1A",o,"",`\u82E5\u8981\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF0C\u53D1\u9001 /repair qr\u3002${A}\u3002`].join(` +`;this.#t=this.#t.then(async()=>{await USe(xSe(this.#e),{recursive:!0,mode:448});let o=`${this.#e}.tmp`;await YSe(o,r,{encoding:"utf8",mode:384}),await KSe(o,this.#e)}),await this.#t}};var pg=Object.freeze({MENTION:"mention",ALL:"all"});function Mi(n){return n===pg.ALL?pg.ALL:pg.MENTION}function NQ(n){return n===pg.MENTION||n===pg.ALL}var TQ="\u8FD9\u4E2A\u95EE\u9898\u5DF2\u5728\u5176\u4ED6\u5BA2\u6237\u7AEF\u5904\u7406\uFF0C\u65E0\u9700\u518D\u6B21\u56DE\u7B54\u3002",qSe=30*6e4,VSe=/^\/m(?:enu)?$/i,zSe=/^\/repair(?:\s|$)/i,WSe=/^\/repair(?:\s+(qr|status|cancel|verify))?\s*$/i,vq=/^\/watch(?:\s+([^\s]+))?$/i,Pq=/^\/unwatch(?:\s+([^\s]+))?$/i,ZSe=/^\/watchlist$/i,XSe=/^\/sessionlist(?:\s|$)/i,$Se=/^\/workspacelist$/i,eDe=/^\d{1,2}$/,ADe=10*6e4,tDe=50,rDe=15e3,aDe=1e3,RQ=new Set(["starting","qr_ready","polling","slow_down","domain_switched","saving"]),Gq=new Set(["succeeded","expired","cancelled","error"]),iDe=new Set(["accounts.feishu.cn","open.feishu.cn","accounts.larksuite.com","open.larksuite.com"]),Fq=/^\/archived(?:\s+(on|off))?$/i,oDe=/^\/(?:m(?:enu)?|help|new|status|compact|sessionlist(?:\s|$)|workspacelist|watchlist|archived(?:\s+(on|off))?)$/i,nDe=["/session Session ID \u6216\u5F53\u524D\u5DE5\u4F5C\u533A\u5E8F\u53F7 \u5C06\u5F53\u524D\u804A\u5929\u7ED1\u5B9A\u5230\u6307\u5B9A\u4F1A\u8BDD","/workspacelist \u5217\u51FA\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84","/sessionlist [\u5DE5\u4F5C\u533A\u5E8F\u53F7\u6216\u7EDD\u5BF9\u8DEF\u5F84] \u5217\u51FA\u4F1A\u8BDD ID \u548C\u6807\u9898"];function Mh(n){switch(n?.code){case"workspace-not-absolute":return"\u5DE5\u4F5C\u533A\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002";case"workspace-not-found":return"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u4E0D\u5B58\u5728\u3002";case"workspace-not-directory":return"\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u76EE\u5F55\u3002";case"workspace-bot-not-found":return"\u673A\u5668\u4EBA\u6B63\u5728\u79FB\u9664\u6216\u5DF2\u91CD\u65B0\u63A5\u5165\uFF0C\u65E0\u6CD5\u64CD\u4F5C\u539F\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\u3002";default:return"\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}}function XA(n){return typeof n=="string"&&n.trim()?n.trim():null}function Lq(n){return(Array.isArray(n?.events)?n.events:[]).map(r=>r?.event??r).filter(r=>r&&typeof r=="object"&&Number.isFinite(r.seq)).sort((r,o)=>r.seq-o.seq)}function vQ(n){return XA(n?.sender?.sender_id?.open_id)??XA(n?.sender?.sender_id?.user_id)}function sDe(n){return XA(n?.sender?.sender_id?.open_id)}function Uq(n,r){return new Promise((o,i)=>{if(r?.aborted){i(r.reason??new DOMException("Aborted","AbortError"));return}let e=setTimeout(a,n);e.unref?.();function a(){r?.removeEventListener("abort",A),o()}function A(){clearTimeout(e),i(r.reason??new DOMException("Aborted","AbortError"))}r?.addEventListener("abort",A,{once:!0})})}function kQ(n,{botId:r}={}){let o=n&&typeof n=="object"?n:{},i=o.registration&&typeof o.registration=="object"?o.registration:o,e=XA(i.operation)??XA(o.operation);if(e&&e!=="callback_repair")throw new Error("The active Feishu operation is not a callback repair");let a=XA(i.botId)??XA(o.botId);if(r&&a&&a!==r)throw new Error("The Feishu repair belongs to another bot");let A=XA(i.state),t=i.attemptId??i.attempt,s=typeof t=="string"||Number.isFinite(t)?String(t):null;if(!A||!s)throw new Error("Feishu returned an invalid repair status");let g=XA(i.verificationUrl)??XA(i.qrCodeUrl),c=Number(i.expiresAt),I=Number(i.remainingSeconds),E=Number(i.pollIntervalMs)||Number(i.pollIntervalSeconds)*1e3;return{state:A,attemptId:s,botId:a,verificationUrl:g,expiresAt:Number.isFinite(c)?c:null,remainingSeconds:Number.isFinite(I)?I:null,pollIntervalMs:Number.isFinite(E)&&E>0?E:null,error:i.error&&typeof i.error=="object"?{code:XA(i.error.code),message:XA(i.error.message)}:null}}function Hq(n,r){let o=new URL(n);if(o.protocol!=="https:"||!iDe.has(o.hostname))throw new Error("Feishu returned an untrusted repair URL");if(o.searchParams.get("tp")!=="sdk"||o.searchParams.get("clientID")!==r||o.searchParams.has("createOnly"))throw new Error("Feishu returned an invalid existing-app repair URL");if(o.toString().includes("{{client_id}}")||o.toString().includes("%7B%7Bclient_id%7D%7D"))throw new Error("Feishu returned an unresolved client id placeholder");return o.toString()}function gDe(n,r){return r.needsPresentation!==!0&&r.questions[r.index]&&vQ(n)===r.actor&&n?.message?.message_type==="text"&&XA(bh(n))}function cDe(n){for(let r of["messagesReceived","messagesReplied","messagesRejected"])n[r]??=0;n.lastMessageAt??=null,n.lastReplyAt??=null,n.lastRejectedAt??=null,n.lastError??=null}var PQ=class{#e;#A;#t;#r;#n=new Map;#o=new Map;#l=new Map;#s=new Map;#c=new Set;#a=new Set;#i=new Set;#I;#g;#p;#h;#C;#E;#d;#B;#u;#y;#S;#f;#m=null;#D=0;#w;#k;#M=new Map;#T=new Map;#O=new Map;#b=null;#_=Promise.resolve();#P=new Map;#N=[];constructor({client:r,channel:o,harness:i,state:e,status:a,allowedSenderOpenIds:A=new Set,botId:t,appId:s,botOpenId:g,groupResponseMode:c=pg.ALL,repair:I,repairOwnerOpenIds:E,repairPollIntervalMs:B=aDe,repairLinkWaitMs:f=rDe,replyTimeoutMs:Q=6e5,logger:y=console,signal:m}){if(!r||!i||!e||!a)throw new TypeError("Feishu bridge dependencies are required");if(I!=null){if(!I||typeof I.start!="function"||typeof I.status!="function"||typeof I.cancel!="function")throw new TypeError("Feishu repair capability requires start/status/cancel");if(!XA(t)||!XA(s))throw new TypeError("Feishu repair capability requires botId and appId")}if(!Number.isFinite(B)||B<=0||!Number.isFinite(f)||f<=0)throw new TypeError("Feishu repair timing values must be positive numbers");this.#e=r,this.#A=o,this.#t=i,this.#r=e,this.#g=a,this.#p=A,this.#d=XA(t),this.#B=XA(s),this.#u=XA(g),this.#y=Mi(c),this.#S=I??null;let T=E??A;this.#f=new Set([...T??[]].filter(_=>typeof _=="string"&&_&&_!=="*")),this.#w=B,this.#k=f,this.#h=Q,this.#C=y,this.#I=new Ja({label:"Feishu",logger:y}),this.#E=m,cDe(this.#g),typeof this.#t?.watchHarnessEvents=="function"&&queueMicrotask(()=>this.#fe())}setGroupResponseMode(r){this.#y=Mi(r)}#H(r){if(r?.message?.chat_type==="p2p")return!0;let o=Array.isArray(r?.message?.mentions)?r.message.mentions:[];return this.#u?o.some(i=>i?.id?.open_id===this.#u||i?.open_id===this.#u):o.length>0}accept(r){if(this.#E?.aborted)return Promise.resolve();let o=XA(r?.message?.message_id);if(!o||Bq(r))return Promise.resolve();if(!fq(r,this.#p))return this.#g.messagesRejected+=1,this.#g.lastRejectedAt=new Date().toISOString(),this.#C.warn?.("[dsh-feishu] ignored a message from a sender outside the allowlist"),Promise.resolve();let i=this.#H(r);if(r?.message?.chat_type!=="p2p"&&this.#y===pg.MENTION&&!i||this.#r.hasSeen(o)||this.#c.has(o))return Promise.resolve();let e;try{e=uq(r)}catch{return this.#g.messagesRejected+=1,this.#g.lastRejectedAt=new Date().toISOString(),Promise.resolve()}if(r.message.chat_type==="p2p"){let I=XA(r.message.chat_id);I&&Hi(this.#r,{chatId:I})}this.#c.add(o);let a=this.#Se(o,"OnIt"),A=oR(r,this.#e),t=XA(A.content)??"";if(oDe.test(t))return Promise.resolve().then(()=>this.#J(r,e,{alreadyRecorded:!1})).then(()=>this.#z(o,a,"DONE")).catch(E=>this.#G(r,o,a,E)).finally(()=>this.#c.delete(o));let s=hi(t)?Wa:di(t)?ui:Bi(t)?Ji:null;if(s&&i){let I=this.#F(r,o,e,A,s),E;return E=I.then(()=>this.#z(o,a,"DONE")).catch(B=>this.#G(r,o,a,B)).finally(()=>{this.#c.delete(o),this.#i.delete(E)}),this.#i.add(E),E}if(this.#pe(r,e))return Promise.resolve().then(()=>this.#Ee(r,o)).then(()=>this.#z(o,a,"DONE")).catch(E=>this.#G(r,o,a,E)).finally(()=>this.#c.delete(o));let g=this.#o.get(e),c=this.#I.claimReply({key:e,actor:vQ(r),messageId:o,text:bh(r)??"",addressed:i,hasPendingQuestion:!!g,questionCompletion:g?.submitting||g?.claimedReplyMessageId?g.queue:null,isQuestionPending:()=>this.#o.has(e),send:I=>this.#Q(r.message.chat_id,I)});if(c){let I=c.process(async()=>this.#r.hasSeen(o)?!1:(await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1,!0)),E;return E=I.then(()=>this.#z(o,a,"DONE")).catch(B=>this.#G(r,o,a,B)).finally(()=>{this.#c.delete(o),this.#a.delete(E)}),this.#a.add(E),E}if(g&&vQ(r)!==g.actor)return this.#R(r,o,e,a);if(g?.submitting||g?.claimedReplyMessageId)return this.#R(r,o,e,a);if(g){gDe(r,g)&&(g.claimedReplyMessageId=o);let E=(g.queue??Promise.resolve()).catch(()=>{}).then(()=>this.#Ye(r,o,e,g,a));g.queue=E;let B=()=>{g.claimedReplyMessageId===o&&(g.claimedReplyMessageId=null),g.queue===E&&(g.queue=null)},f;return f=E.then(()=>(B(),this.#z(o,a,"DONE")),Q=>(B(),this.#G(r,o,a,Q))).finally(()=>{B(),this.#c.delete(o),this.#a.delete(f)}),this.#a.add(f),f}return this.#R(r,o,e,a)}#R(r,o,i,e,{releaseMessageId:a=!0,alreadyRecorded:A=!1,finalize:t=!0}={}){let g=(this.#n.get(i)??Promise.resolve()).catch(()=>{}).then(()=>this.#J(r,i,{alreadyRecorded:A})),c=t?g.then(()=>this.#z(o,e,"DONE")).catch(E=>this.#G(r,o,e,E)):g,I;return I=c.finally(()=>{a&&this.#c.delete(o),this.#n.get(i)===I&&this.#n.delete(i)}),this.#n.set(i,I),I}async#G(r,o,i,e){if(e?.code==="turn-stopped"){await this.#he(o,i);return}if(this.#E?.aborted){await this.#he(o,i);return}this.#C.error?.("[dsh-feishu] message handling failed:",e?.message??String(e)),this.#g.lastError=e?.message??String(e),await this.#z(o,i,"ERROR"),await this.#Q(r.message.chat_id,xi(e)??"\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002\u5982\u679C\u95EE\u9898\u6301\u7EED\uFF0C\u8BF7\u5728 DeepSeek Harness \u7684\u98DE\u4E66\u63D2\u4EF6\u9875\u9762\u68C0\u67E5\u8FDE\u63A5\u72B6\u6001\u3002").catch(()=>{})}async waitForIdle(){await Promise.allSettled([...this.#n.values(),...[...this.#o.values()].flatMap(r=>r.queue?[r.queue]:[]),...this.#a,...this.#i,this.#_])}async#F(r,o,i,e,a){if(this.#E?.throwIfAborted(),this.#r.hasSeen(o))return;await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1;let A=await a(XA(e.content)??"",this.#t,this.#r,i,{signal:this.#E,hasImages:lr(e),pendingInteraction:this.#o.has(i)||this.#I.hasPending(i),control:{owner:this,key:i}});A?.stopped&&await Promise.allSettled([this.#me(i),this.#I.closeRoute(i)]);for(let t of A?.messages??[A?.message])t&&await this.#Q(r.message.chat_id,t);this.#g.lastError=null}async#J(r,o,{alreadyRecorded:i=!1}={}){this.#E?.throwIfAborted();let e=r.message.message_id;if(!i){if(this.#r.hasSeen(e))return;await this.#r.markSeen(e),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1}let a=oR(r,this.#e),A=a.content,t=lr(a),s=r.message.message_type==="text"&&!t?A:null;if(!A&&!t){await this.#Q(r.message.chat_id,"\u76EE\u524D\u652F\u6301\u6587\u5B57\u548C\u56FE\u7247\u6D88\u606F\u3002");return}if(s!==null&&zSe.test(s)){await this.#L(r,s);return}if(s==="/help"){await this.#Q(r.message.chat_id,wq());return}if(VSe.test(s)){await this.#X(o,r.message.chat_id,{newCard:!0});return}if(s==="/new"){await this.#r.clearSession(o),await this.#Q(r.message.chat_id,"\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002"),await this.#X(o,r.message.chat_id);return}if(s==="/status"){await this.#_e(o,r.message.chat_id);return}if(s==="/compact"){let I=await za(s,this.#t,this.#r,o,{signal:this.#E});I&&await this.#Q(r.message.chat_id,I.message);return}if(XSe.test(s)){let I=s.slice(12).trim()||null;await this.#de({chatId:r.message.chat_id,key:o},I,0);return}if($Se.test(s)){await this.#ue({chatId:r.message.chat_id,key:o});return}if(vq.test(s)){let I=(vq.exec(s)?.[1]??"").trim()||null;await this.#se(o,r.message.chat_id,I);return}if(Pq.test(s)){let I=(Pq.exec(s)?.[1]??"").trim()||null;await this.#ge(o,r.message.chat_id,I);return}if(ZSe.test(s)){await this.#ce(o,r.message.chat_id);return}if(Fq.test(s)){let E=Fq.exec(s)[1]?.toLowerCase();if(E!=="on"&&E!=="off"){await this.#Q(r.message.chat_id,"\u7528\u6CD5\uFF1A/archived on\uFF08\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\uFF09\u6216 /archived off\uFF08\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\uFF09");return}typeof this.#r?.setIncludeArchivedSessions=="function"&&await this.#r.setIncludeArchivedSessions(E==="on"),await this.#Q(r.message.chat_id,E==="on"?"\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002":"\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002");return}if(eDe.test(s)){let I=this.#Z(o);if(I){await this.#x(I,Number(s),{chatId:r.message.chat_id,key:o,event:r});return}}let g=s===null?null:await ji(A,this.#t,o);if(g){for(let I of g.messages??[g.message])await this.#Q(r.message.chat_id,I);return}let c=s===null?null:await za(s,this.#t,this.#r,o,{signal:this.#E});if(c){await this.#Q(r.message.chat_id,c.message);return}this.#C.info?.(`[dsh-feishu] processing ${r.message.chat_type} message ${e}`);try{await this.#Ke(r,o,a),this.#g.messagesReplied+=1,this.#g.lastReplyAt=new Date().toISOString(),this.#g.lastError=null}finally{await this.#me(o),await this.#I.closeRoute(o)}}async#L(r,o){if(r?.message?.chat_type!=="p2p"){await this.#Q(r.message.chat_id,"\u4E3A\u907F\u514D\u6388\u6743\u94FE\u63A5\u66B4\u9732\uFF0C\u8BF7\u79C1\u804A\u673A\u5668\u4EBA\u53D1\u9001 /repair\u3002");return}let i=sDe(r);if(!i||!this.#f.has(i)){await this.#Q(r.message.chat_id,this.#f.size===0?"\u5F53\u524D\u673A\u5668\u4EBA\u6CA1\u6709\u53EF\u9A8C\u8BC1\u7684\u63A5\u5165\u8005\u8EAB\u4EFD\uFF0C\u4E0D\u80FD\u4ECE\u804A\u5929\u53D1\u8D77\u4FEE\u590D\uFF1B\u8BF7\u5148\u5728\u63D2\u4EF6\u9875\u8BBE\u7F6E\u7BA1\u7406\u5458\u3002":"\u6B64\u64CD\u4F5C\u53EA\u80FD\u7531\u673A\u5668\u4EBA\u63A5\u5165\u8005\u5728\u79C1\u804A\u4E2D\u53D1\u8D77\uFF0C\u672A\u8FDB\u884C\u4EFB\u4F55\u4FEE\u6539\u3002");return}if(!this.#S){await this.#Q(r.message.chat_id,"\u5F53\u524D Host \u7248\u672C\u6682\u4E0D\u652F\u6301\u804A\u5929\u5185\u4FEE\u590D\uFF0C\u8BF7\u5148\u66F4\u65B0\u63D2\u4EF6\u3002");return}let e=WSe.exec(o);if(!e){await this.#Q(r.message.chat_id,"\u7528\u6CD5\uFF1A/repair\u3001/repair qr\u3001/repair status\u3001/repair cancel \u6216 /repair verify");return}let a=e[1]?.toLowerCase()??"start",A=r.message.chat_id;if(a==="start"){await this.#W({actorOpenId:i,chatId:A});return}let t=this.#m;if(!t){await this.#Q(A,"\u5F53\u524D Runtime \u6CA1\u6709\u53EF\u6062\u590D\u7684\u4FEE\u590D\u4EFB\u52A1\u8BB0\u5F55\uFF08\u673A\u5668\u4EBA\u53EF\u80FD\u521A\u5B8C\u6210\u5BC6\u94A5\u66F4\u65B0\u5E76\u91CD\u542F\uFF09\u3002\u672C\u547D\u4EE4\u4E0D\u4F1A\u542F\u52A8\u65B0\u7684\u6388\u6743\uFF1B\u8BF7\u67E5\u770B\u673A\u5668\u4EBA\u53D1\u9001\u7684\u9A8C\u8BC1\u7ED3\u679C\uFF0C\u786E\u8BA4\u4E0A\u4E00\u6B21\u4EFB\u52A1\u5DF2\u7ED3\u675F\u540E\u518D\u53D1\u9001 /repair\u3002");return}if(t.actorOpenId!==i){await this.#Q(A,"\u53E6\u4E00\u4F4D\u7BA1\u7406\u5458\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002");return}if(a==="cancel"){let g;try{let c=await this.#S.cancel(this.#Y(t));g=kQ(c,{botId:this.#d}),t.snapshot=g}catch{await this.#Q(A,"\u6682\u65F6\u65E0\u6CD5\u53D6\u6D88\u4FEE\u590D\u4EFB\u52A1\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}g.state==="cancelled"&&(t.stopped=!0,this.#D+=1),await this.#Q(A,this.#V(g));return}let s;try{s=await this.#q(t)}catch{await this.#Q(A,"\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}if(a==="qr"){if(!RQ.has(s.state)||!t.verificationUrl){await this.#Q(A,this.#V(s,{verificationFocused:!0}));return}await this.#ie(A,t.verificationUrl,s);return}await this.#Q(A,this.#V(s,{verificationFocused:a==="verify"}))}#Y(r){return{botId:this.#d,attemptId:r.attemptId,actorOpenId:r.actorOpenId,chatId:r.chatId}}async#W({actorOpenId:r,chatId:o}){let i=this.#m;if(i&&RQ.has(i.snapshot.state)){if(i.actorOpenId!==r){await this.#Q(o,"\u53E6\u4E00\u4F4D\u7BA1\u7406\u5458\u6B63\u5728\u4FEE\u590D\u8BE5\u673A\u5668\u4EBA\uFF0C\u672C\u6B21\u4E0D\u4F1A\u663E\u793A\u5176\u6388\u6743\u4FE1\u606F\u3002");return}try{let A=await this.#q(i);if(RQ.has(A.state)&&i.verificationUrl){await this.#$(o,i.verificationUrl,A,{existing:!0});return}}catch{await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u67E5\u8BE2\u4FEE\u590D\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");return}}let e;try{e=kQ(await this.#S.start({botId:this.#d,actorOpenId:r,chatId:o}),{botId:this.#d}),e=await this.#ae(e,{actorOpenId:r,chatId:o})}catch{await this.#Q(o,"\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u8BF7\u7A0D\u540E\u53D1\u9001 /repair \u91CD\u8BD5\u3002");return}let a={attemptId:e.attemptId,actorOpenId:r,chatId:o,snapshot:e,verificationUrl:null,stopped:!1,announcedSaving:!1,announcedTerminal:!1};if(this.#m=a,e.verificationUrl)try{a.verificationUrl=Hq(e.verificationUrl,this.#B)}catch{a.stopped=!0,await this.#S.cancel(this.#Y(a)).catch(()=>{}),await this.#Q(o,"\u98DE\u4E66\u8FD4\u56DE\u4E86\u65E0\u6CD5\u5B89\u5168\u9A8C\u8BC1\u7684\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002");return}if(Gq.has(e.state)){a.announcedTerminal=!0,e.state!=="succeeded"&&await this.#Q(o,this.#V(e));return}if(!a.verificationUrl){a.stopped=!0,await this.#Q(o,"\u98DE\u4E66\u672A\u8FD4\u56DE\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u4E2D\u6B62\u672C\u6B21\u4FEE\u590D\u3002");return}await this.#$(o,a.verificationUrl,e),this.#v(a)}async#ae(r,o){let i=r,e=Date.now()+this.#k;for(;!i.verificationUrl&&RQ.has(i.state);){if(Date.now()>=e)throw new Error("Feishu repair link timed out");await Uq(Math.min(100,this.#w),this.#E),i=kQ(await this.#S.status({botId:this.#d,attemptId:i.attemptId,actorOpenId:o.actorOpenId,chatId:o.chatId}),{botId:this.#d})}return i}async#q(r){let o=kQ(await this.#S.status(this.#Y(r)),{botId:this.#d});if(o.attemptId!==r.attemptId)throw new Error("Feishu repair attempt changed unexpectedly");return r.snapshot=o,o.verificationUrl&&(r.verificationUrl=Hq(o.verificationUrl,this.#B)),o}#v(r){let o=++this.#D;(async()=>{for(;!r.stopped&&this.#m===r&&this.#D===o&&!this.#E?.aborted;){let i=Math.max(250,Math.min(1e4,r.snapshot.pollIntervalMs??this.#w));if(await Uq(i,this.#E),r.stopped||this.#m!==r||this.#D!==o)return;let e=await this.#q(r);if(e.state==="saving"&&!r.announcedSaving&&(r.announcedSaving=!0,await this.#Q(r.chatId,"\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u53D1\u9001\u5E76\u7B49\u5F85\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\uFF1B\u6536\u5230\u771F\u5B9E\u56DE\u8C03\u540E\u624D\u4F1A\u5B8C\u6210\u3002")),Gq.has(e.state)){r.stopped=!0,e.state!=="succeeded"&&!r.announcedTerminal&&(r.announcedTerminal=!0,await this.#Q(r.chatId,this.#V(e)));return}}})().catch(async()=>{this.#E?.aborted||r.stopped||this.#m!==r||(r.stopped=!0,this.#C.warn?.("[dsh-feishu] callback repair status monitoring failed"),await this.#Q(r.chatId,"\u4FEE\u590D\u72B6\u6001\u67E5\u8BE2\u4E2D\u65AD\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair status \u91CD\u8BD5\u67E5\u8BE2\u3002").catch(()=>{}))})}async#$(r,o,i,{existing:e=!1}={}){let a=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null),A=a===null?"\u94FE\u63A5\u4E3A\u77ED\u671F\u6709\u6548":`\u94FE\u63A5\u7EA6 ${Math.max(1,Math.ceil(a/60))} \u5206\u949F\u540E\u8FC7\u671F`;await this.#Q(r,[e?"\u5DF2\u6709\u4E00\u4E2A\u4FEE\u590D\u4EFB\u52A1\u5728\u7B49\u5F85\u6388\u6743\u3002":"\u{1F527} \u51C6\u5907\u4FEE\u590D\u5361\u7247\u6309\u94AE\u3002","\u672C\u6B21\u53EA\u4F1A\u589E\u91CF\u6DFB\u52A0 card.action.trigger\u3002\u8BF7\u6838\u5BF9\u786E\u8BA4\u9875\u53EA\u663E\u793A\u8FD9\u4E00\u9879\uFF1B\u82E5\u51FA\u73B0\u5176\u4ED6\u6743\u9650\u6216\u4E8B\u4EF6\uFF0C\u8BF7\u53D6\u6D88\u3002","","\u5F53\u524D\u8BBE\u5907\u76F4\u63A5\u6253\u5F00\uFF1A",o,"",`\u82E5\u8981\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\uFF0C\u53D1\u9001 /repair qr\u3002${A}\u3002`].join(` `))}async#ie(r,o,i){try{let e=await JSe.toBuffer(o,{errorCorrectionLevel:"M",margin:1,width:480,type:"png"}),a=await this.#e.im.v1.image.create({data:{image_type:"message",image:e}}),A=XA(a?.image_key)??XA(a?.data?.image_key);if(!A)throw new Error("Feishu QR upload returned no image key");let t=i.remainingSeconds??(i.expiresAt?Math.max(0,Math.ceil((i.expiresAt-Date.now())/1e3)):null);await this.#Q(r,`\u8BF7\u7528\u53E6\u4E00\u53F0\u8BBE\u5907\u626B\u7801\u5B8C\u6210\u6388\u6743${t===null?"":`\uFF08\u5269\u4F59\u7EA6 ${Math.max(1,Math.ceil(t/60))} \u5206\u949F\uFF09`}\u3002`);let s=await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:r,msg_type:"image",content:JSON.stringify({image_key:A})}});if(s?.code&&s.code!==0)throw new Error("Feishu QR message send failed")}catch{await this.#Q(r,`\u4E8C\u7EF4\u7801\u6682\u65F6\u65E0\u6CD5\u53D1\u9001\uFF0C\u8BF7\u76F4\u63A5\u6253\u5F00\u6388\u6743\u94FE\u63A5\uFF1A ${o}`)}}#V(r,{verificationFocused:o=!1}={}){return r.state==="succeeded"?"\u2705 \u4FEE\u590D\u5B8C\u6210\uFF1A\u5DF2\u5B9E\u6D4B\u6536\u5230 card.action.trigger\uFF0C\u83DC\u5355\u6309\u94AE\u73B0\u5728\u53EF\u7528\u3002":r.state==="expired"||r.error?.code==="expired_token"?"\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF1B\u5E73\u53F0\u672A\u8FD4\u56DE\u6210\u529F\u7ED3\u679C\uFF0C\u65E0\u6CD5\u786E\u8BA4\u5DF2\u4FEE\u590D\u3002\u53D1\u9001 /repair \u751F\u6210\u65B0\u94FE\u63A5\u3002":r.state==="cancelled"||r.error?.code==="abort"?"\u5DF2\u53D6\u6D88\u672C\u6B21\u4FEE\u590D\u6388\u6743\uFF0C\u672A\u786E\u8BA4\u5B8C\u6210\u4FEE\u590D\u3002":r.error?.code==="access_denied"?"\u4F60\u5DF2\u53D6\u6D88\u6216\u62D2\u7EDD\u6388\u6743\uFF0C\u6CA1\u6709\u786E\u8BA4\u4FEE\u590D\uFF1B\u53D1\u9001 /repair \u53EF\u91CD\u8BD5\u3002":r.error?.code==="card_action_probe_timeout"||r.error?.code==="card-action-probe-timeout"?"\u6388\u6743\u5DF2\u63D0\u4EA4\uFF0C\u4F46\u672A\u6536\u5230\u6D4B\u8BD5\u6309\u94AE\u56DE\u8C03\u3002\u53EF\u80FD\u5C1A\u672A\u70B9\u51FB\u6216\u914D\u7F6E\u4ECD\u5728\u4F20\u64AD\uFF1B\u7A0D\u540E\u53D1\u9001 /repair verify \u67E5\u8BE2\uFF0C\u4E0D\u8981\u76F2\u76EE\u91CD\u590D\u6388\u6743\u3002":r.state==="error"?"\u4FEE\u590D\u6D41\u7A0B\u6682\u65F6\u5931\u8D25\uFF0C\u73B0\u6709\u673A\u5668\u4EBA\u8FDE\u63A5\u4E0D\u53D7\u5F71\u54CD\uFF1B\u53D1\u9001 /repair \u53EF\u91CD\u8BD5\u3002":r.state==="saving"?"\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u7B49\u5F85\u4E13\u7528\u6D4B\u8BD5\u6309\u94AE\u7684\u771F\u5B9E\u56DE\u8C03\uFF1B\u56DE\u8C03\u5230\u8FBE\u524D\u4E0D\u4F1A\u5BA3\u544A\u6210\u529F\u3002":o?"\u6388\u6743\u5C1A\u672A\u5B8C\u6210\uFF0C\u6682\u65F6\u4E0D\u80FD\u9A8C\u8BC1\u5361\u7247\u6309\u94AE\u3002\u8BF7\u5148\u6253\u5F00\u6388\u6743\u94FE\u63A5\u5E76\u786E\u8BA4\u3002":`\u4FEE\u590D\u4EFB\u52A1\u6B63\u5728\u7B49\u5F85\u6388\u6743${r.remainingSeconds===null?"":`\uFF0C\u5269\u4F59\u7EA6 ${Math.max(1,Math.ceil(r.remainingSeconds/60))} \u5206\u949F`}\u3002\u53D1\u9001 /repair qr \u53EF\u83B7\u53D6\u4E8C\u7EF4\u7801\uFF0C/repair cancel \u53EF\u53D6\u6D88\u3002`}onCardAction(r){let o=XA(r?.operator?.open_id)??XA(r?.operator?.user_id)??XA(r?.operator?.operator_id?.open_id)??XA(r?.operator?.operator_id?.user_id);if(!(o!==null&&(this.#p.has("*")||this.#p.has(o))))return this.#C.warn?.("[dsh-feishu] ignoring card action from an unallowed sender"),Promise.resolve();let e=typeof r?.action?.value?.action=="string"?r.action.value.action:null;if(!e)return Promise.resolve();let a=r?.action?.option,A=Array.isArray(r?.action?.value?.options)?r.action.value.options.map(c=>c?.value??c).filter(c=>typeof c=="string"):Array.isArray(r?.action?.options)?r.action.options.map(c=>c?.value??c).filter(c=>typeof c=="string"):[];(e==="watch_add"||e==="watch_remove")&&(this.#N=A);let t=e==="workspace_pick"&&typeof a=="string"?`workspace:${a}`:e==="session_pick"&&typeof a=="string"?`use:${a}`:e==="preset_pick"&&typeof a=="string"?`preset:select:${a}`:e==="model_pick"&&typeof a=="string"?`model:select:${a}`:e==="archive_pick"&&typeof a=="string"?`archive:${a}`:e==="steer_pick"&&typeof a=="string"?`steer:${a}`:e,s=XA(r?.context?.open_message_id),g=s?this.#T.get(s):null;if(!g){let c=XA(r?.context?.open_chat_id);return c&&this.#Q(c,"\u8FD9\u4E2A\u83DC\u5355\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u56DE\u590D /m \u91CD\u65B0\u6253\u5F00\u3002").catch(()=>{}),Promise.resolve()}if(e==="steer"){let c=r?.action?.value?.source;if(c==="quick"&&typeof a=="string")return a===nR?this.#U(g.chatId,sR(),g).catch(I=>{this.#C.warn?.("[dsh-feishu] steer custom card failed:",I.message)}):this.#oe(g,a).catch(I=>{this.#C.warn?.("[dsh-feishu] steer (quick) failed:",I.message)});if(c==="form"){let I=XA(r?.action?.form_value?.steer_text);return I?this.#oe(g,I).catch(E=>{this.#C.warn?.("[dsh-feishu] steer (form) failed:",E.message)}):(this.#Q(g.chatId,"\u8BF7\u8F93\u5165\u8865\u5145\u6307\u4EE4\u540E\u518D\u63D0\u4EA4\u3002").catch(()=>{}),Promise.resolve())}}return this.#K(t,g).catch(c=>{this.#C.warn?.("[dsh-feishu] card action failed:",c.message)})}async#K(r,{chatId:o,key:i,sessionWorkspace:e=null}){if(r==="sessions"||/^sessions:\d+$/.test(r)){let a=r==="sessions"?0:Number(r.slice(9));await this.#de({chatId:o,key:i},e,a);return}if(r==="workspaces"){await this.#ue({chatId:o,key:i});return}if(r==="watchlist"){await this.#ce(i,o);return}if(r==="watch_add"||r==="watch_remove"){let a=this.#N??[];if(this.#N=null,r==="watch_add"){let A=0,t=0;for(let s of a)try{await this.#se(i,o,s),A+=1}catch{t+=1}await this.#Q(o,A>0?`\u5DF2\u6279\u91CF\u5173\u6CE8 ${A} \u4E2A\u4F1A\u8BDD\u3002`:"\u5DF2\u5173\u6CE8\uFF08\u6216\u5DF2\u8FBE\u5173\u6CE8\u4E0A\u9650\uFF09\u3002")}else{let A=0;for(let t of a)try{await this.#ge(i,o,t),A+=1}catch{}await this.#Q(o,A>0?`\u5DF2\u53D6\u6D88\u5173\u6CE8 ${A} \u4E2A\u4F1A\u8BDD\u3002`:"\u672A\u53D6\u6D88\u4EFB\u4F55\u5173\u6CE8\u3002")}await this.#ce(i,o);return}if(r==="new"){await this.#r.clearSession(i),await this.#Q(o,"\u5DF2\u5F00\u542F\u5168\u65B0 Harness \u4F1A\u8BDD\u3002");return}if(r==="use:current"){let a=this.#r.sessionFor(i);if(typeof a!="string"||!a){await this.#Q(o,"\u5F53\u524D\u6CA1\u6709\u7ED1\u5B9A\u7684\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u4ECE\u4F1A\u8BDD\u5217\u8868\u9009\u62E9\u3002");return}await this.#Q(o,"\u5DF2\u5C31\u7EEA\uFF0C\u76F4\u63A5\u53D1\u6D88\u606F\u5373\u53EF\u7EE7\u7EED\u5F53\u524D\u4F1A\u8BDD\u3002");return}if(r==="archive_toggle"||r==="archive:on"||r==="archive:off"){let a=r==="archive:on"?!0:r==="archive:off"?!1:!(this.#r?.includesArchivedSessions?.()??!1);await this.#r?.setIncludeArchivedSessions?.(a),await this.#Q(o,a?"\u5DF2\u5F00\u542F\uFF1A\u4F1A\u8BDD\u5217\u8868\u5305\u542B\u5F52\u6863\u4F1A\u8BDD\u3002":"\u5DF2\u5173\u95ED\uFF1A\u4F1A\u8BDD\u5217\u8868\u9690\u85CF\u5F52\u6863\u4F1A\u8BDD\u3002"),await this.#X(i,o);return}if(r==="repair"){await this.#Q(o,"\u4FEE\u590D\u9700\u5728\u79C1\u804A\u4E2D\u9A8C\u8BC1\u63A5\u5165\u8005\u8EAB\u4EFD\uFF0C\u8BF7\u76F4\u63A5\u53D1\u9001 /repair \u5F00\u59CB\u3002");return}if(r==="compact"){await this.#Re(i,o);return}if(r==="stop"){await this.#ke(i,o);return}if(r==="steer"){await this.#ve(i,o);return}if(r.startsWith("steer:")){let a=r.slice(6);if(a==="custom"){await this.#U(o,sR(),{key:i});return}await this.#oe({key:i,chatId:o},a);return}if(r==="presets"){await this.#be(i,o);return}if(r==="settings"){await this.#te(i,o);return}if(r==="models"){await this.#Me(i,o);return}if(r==="status"){await this.#Ne(i,o);return}if(r==="help"){await this.#Te(i,o);return}if(r==="back_to_menu"){await this.#X(i,o);return}if(r==="preset_default"){await this.#Be(i,o);return}if(r.startsWith("preset:select:")){let a=r.slice(14);if(a===wQ){await this.#Be(i,o);return}await this.#Pe(i,o,a);return}if(r.startsWith("model:select:")){let a=r.slice(13);await this.#Ge(i,o,a);return}if(r.startsWith("use:")){await this.#De(i,o,r.slice(4));return}if(r.startsWith("workspace:")){await this.#we(i,o,r.slice(10));return}if(r.startsWith("unwatch:")){await this.#ge(i,o,r.slice(8));return}r.startsWith("watch:")&&await this.#se(i,o,r.slice(6))}#j(r,o){if(this.#M.size>=tDe){let i=this.#M.keys().next().value;i!==void 0&&this.#M.delete(i)}this.#M.delete(r),this.#M.set(r,{...o,expiresAt:Date.now()+ADe})}#Z(r){let o=this.#M.get(r);return o?o.expiresAto.archived!==!0):r}async#de({chatId:r,key:o},i,e=0){try{let a=await SO(i??"",this.#t);if(a.error){await this.#Q(r,a.error);return}let A=await this.#t.listWorkspaceSessions(a.workspace),t=this.#ee(Array.isArray(A?.sessions)?A.sessions:[]),s=A?.workspace??a.workspace;if(t.length===0){await this.#Q(r,`\u5DE5\u4F5C\u533A\uFF1A${s} \u8BE5\u5DE5\u4F5C\u533A\u6682\u65E0\u4F1A\u8BDD\u3002`);return}let g=Math.ceil(t.length/10),c=Number.isSafeInteger(e)&&e>0?Math.min(e,g-1):0,I=new Set((this.#r.watchEntries?.(o)??[]).map(B=>B.sessionId)),E=t.slice(c*10,(c+1)*10);this.#j(o,{kind:"sessions",sessions:E.map(B=>({...B,watched:I.has(B.sessionId)}))}),await this.#U(r,Mq(s,t,c,t.length,I),{key:o,sessionWorkspace:a.workspace})}catch(a){this.#C.warn?.("[dsh-feishu] session list failed:",a.message),await this.#Q(r,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u4F1A\u8BDD\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#ue({chatId:r,key:o}){try{let{current:i,paths:e}=await WI(this.#t);this.#j(o,{kind:"workspaces",paths:e}),await this.#U(r,_q(e,i),{key:o})}catch(i){this.#C.warn?.("[dsh-feishu] workspace list failed:",i.message),await this.#Q(r,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u5DE5\u4F5C\u533A\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#De(r,o,i){try{let e=await this.#t.bindWorkspaceSession(r,i),a=String(e?.title??"").replace(/\s+/gu," ").trim()||"\u6682\u65E0\u6807\u9898";await this.#Q(o,`\u5DF2\u7ED1\u5B9A\u4F1A\u8BDD\u300C${a}\u300D -ID\uFF1A${e?.sessionId??i}`),await this.#X(r,o)}catch(e){await this.#Q(o,`\u7ED1\u5B9A\u5931\u8D25\uFF1A${Mh(e)}`)}}async#we(r,o,i){try{let e=await this.#t.switchWorkspace(i);await this.#Q(o,`\u5DE5\u4F5C\u533A\u5DF2\u5207\u6362\u4E3A\uFF1A${e}`),await this.#X(r,o)}catch(e){await this.#Q(o,`\u5207\u6362\u5931\u8D25\uFF1A${Mh(e)}`)}}async#U(r,o,i={}){let{update:e=!1}=i;if(e){let t=this.#O.get(r);if(t)try{return await this.#e.request({method:"PATCH",url:`/open-apis/im/v1/messages/${t}`,data:{content:o}}),t}catch(s){this.#C.warn?.("[dsh-feishu] card update failed:",s?.code??s?.message??s,"sending new")}}let a=await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:r,msg_type:"interactive",content:o}});if(a?.code&&a.code!==0)throw new Error(`Feishu card send failed: ${a.msg||a.code}`);let A=XA(a?.data?.message_id);if(i.key&&A&&(this.#T.set(A,{key:i.key,chatId:r,sessionWorkspace:typeof i.sessionWorkspace=="string"&&i.sessionWorkspace?i.sessionWorkspace:null}),this.#T.size>200)){let t=this.#T.keys().next().value;t!==void 0&&this.#T.delete(t)}return A&&this.#O.set(r,A),A}async#X(r,o){let i=[],e=null;try{let g=await WI(this.#t);i=g.paths,e=g.current??null}catch{}let a=null,A=null;try{let g=this.#r.sessionFor(r);typeof g=="string"&&g&&(A=g,a=await this.#Oe(r,g)||g)}catch{A=this.#r.sessionFor(r),a=A}let t=[];try{let g=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(g&&typeof this.#t.listWorkspaceSessions=="function"){let c=await this.#t.listWorkspaceSessions(g);t=(Array.isArray(c?.sessions)?c.sessions:[]).map(I=>({id:I.sessionId,title:I.title??I.name??I.sessionId})).slice(0,20)}}catch{}A&&(t=t.filter(g=>g.id!==A),t.unshift({id:A,title:a??A}),t=t.slice(0,20)),!A&&t.length>0&&(A=t[0].id,a=t[0].title??t[0].id);let s=this.#r?.includesArchivedSessions?.()??!1;this.#j(r,{kind:"menu",chatId:o}),await this.#U(o,Qq({workspaces:i,currentWorkspace:e,currentSession:A?{id:A,title:a}:null,sessions:t,archiveVisible:s}),{key:r,update:!0})}async#Oe(r,o){try{if(typeof this.#t.workspaceSession=="function"){let e=this.#t.workspaceSession(o);if(e&&typeof e=="object"){let a=XA(e.title)??XA(e.name)??XA(e.displayName);if(a)return a}}let i=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(i&&typeof this.#t.listWorkspaceSessions=="function"){let e=await this.#t.listWorkspaceSessions(i),a=(Array.isArray(e?.sessions)?e.sessions:[]).find(A=>A.sessionId===o);if(a){let A=XA(a.title)??XA(a.name);if(A)return A}}}catch{}return null}async#te(r,o){let i=this.#r?.includesArchivedSessions?.()??!1,e=null,a=null,A=[],t=null;try{let s=await WI(this.#t);A=s.paths,t=s.current??null}catch{}try{let s=await this.#t.agentPresetSettings({signal:this.#E});e=s.agentPresetCatalog,e._currentId=s.agentPreset}catch{}try{await this.#t.ensureRunning({signal:this.#E});let s=this.#r?.sessionFor?.(r),g;if(typeof s=="string"&&s){let c=this.#t.workspaceSession(s);c?.models&&(g=await c.models({signal:this.#E}))}g||(g=await this.#t.listModels({signal:this.#E})),a=g}catch{}await this.#U(o,yq({archiveVisible:i,presetCatalog:e,modelCatalog:a,workspaces:A,currentWorkspace:t}),{key:r})}async#be(r,o){try{let i=await this.#t.agentPresetSettings({signal:this.#E}),e=i.agentPresetCatalog;e._currentId=i.agentPreset,await this.#U(o,mq(e),{key:r})}catch(i){this.#C.warn?.("[dsh-feishu] preset card failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u9884\u8BBE\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#Me(r,o){try{await this.#t.ensureRunning({signal:this.#E});let i=this.#r?.sessionFor?.(r),e;if(typeof i=="string"&&i){let a=this.#t.workspaceSession(i);a?.models&&(e=await a.models({signal:this.#E}))}e||(e=await this.#t.listModels({signal:this.#E})),await this.#U(o,Sq(e),{key:r})}catch(i){this.#C.warn?.("[dsh-feishu] model card failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u6A21\u578B\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#_e(r,o){try{await this.#t.ensureRunning({signal:this.#E});let i=["\u8FDE\u63A5\u6B63\u5E38"],e=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;e&&i.push(`\u5DE5\u4F5C\u533A\uFF1A${e}`);let a=typeof this.#t.agentPresetSettings=="function"?await this.#t.agentPresetSettings({signal:this.#E}).catch(()=>null):null;if(a){let A=a.agentPresetCatalog?.items?.find(t=>t.id===a.agentPreset);i.push(`\u9884\u8BBE\uFF1A${A?`${A.label}\uFF08${A.id}\uFF09`:a.agentPreset||"\u8DDF\u968F\u9ED8\u8BA4"}`)}await this.#Q(o,i.join(` +ID\uFF1A${e?.sessionId??i}`),await this.#X(r,o)}catch(e){await this.#Q(o,`\u7ED1\u5B9A\u5931\u8D25\uFF1A${Mh(e)}`)}}async#we(r,o,i){try{let e=await this.#t.switchWorkspace(i);await this.#Q(o,`\u5DE5\u4F5C\u533A\u5DF2\u5207\u6362\u4E3A\uFF1A${e}`),await this.#X(r,o)}catch(e){await this.#Q(o,`\u5207\u6362\u5931\u8D25\uFF1A${Mh(e)}`)}}async#U(r,o,i={}){let{update:e=!1}=i;if(e){let t=this.#O.get(r);if(t)try{return await this.#e.request({method:"PATCH",url:`/open-apis/im/v1/messages/${t}`,data:{content:o}}),t}catch(s){this.#C.warn?.("[dsh-feishu] card update failed:",s?.code??s?.message??s,"sending new")}}let a=await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:r,msg_type:"interactive",content:o}});if(a?.code&&a.code!==0)throw new Error(`Feishu card send failed: ${a.msg||a.code}`);let A=XA(a?.data?.message_id);if(i.key&&A&&(this.#T.set(A,{key:i.key,chatId:r,sessionWorkspace:typeof i.sessionWorkspace=="string"&&i.sessionWorkspace?i.sessionWorkspace:null}),this.#T.size>200)){let t=this.#T.keys().next().value;t!==void 0&&this.#T.delete(t)}return A&&this.#O.set(r,A),A}async#X(r,o,{newCard:i=!1}={}){let e=[],a=null;try{let c=await WI(this.#t);e=c.paths,a=c.current??null}catch{}let A=null,t=null;try{let c=this.#r.sessionFor(r);typeof c=="string"&&c&&(t=c,A=await this.#Oe(r,c)||c)}catch{t=this.#r.sessionFor(r),A=t}let s=[];try{let c=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(c&&typeof this.#t.listWorkspaceSessions=="function"){let I=await this.#t.listWorkspaceSessions(c);s=(Array.isArray(I?.sessions)?I.sessions:[]).map(E=>({id:E.sessionId,title:E.title??E.name??E.sessionId})).slice(0,20)}}catch{}t&&(s=s.filter(c=>c.id!==t),s.unshift({id:t,title:A??t}),s=s.slice(0,20)),!t&&s.length>0&&(t=s[0].id,A=s[0].title??s[0].id);let g=this.#r?.includesArchivedSessions?.()??!1;this.#j(r,{kind:"menu",chatId:o}),await this.#U(o,Qq({workspaces:e,currentWorkspace:a,currentSession:t?{id:t,title:A}:null,sessions:s,archiveVisible:g}),{key:r,update:!i})}async#Oe(r,o){try{if(typeof this.#t.workspaceSession=="function"){let e=this.#t.workspaceSession(o);if(e&&typeof e=="object"){let a=XA(e.title)??XA(e.name)??XA(e.displayName);if(a)return a}}let i=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(i&&typeof this.#t.listWorkspaceSessions=="function"){let e=await this.#t.listWorkspaceSessions(i),a=(Array.isArray(e?.sessions)?e.sessions:[]).find(A=>A.sessionId===o);if(a){let A=XA(a.title)??XA(a.name);if(A)return A}}}catch{}return null}async#te(r,o){let i=this.#r?.includesArchivedSessions?.()??!1,e=null,a=null,A=[],t=null;try{let s=await WI(this.#t);A=s.paths,t=s.current??null}catch{}try{let s=await this.#t.agentPresetSettings({signal:this.#E});e=s.agentPresetCatalog,e._currentId=s.agentPreset}catch{}try{await this.#t.ensureRunning({signal:this.#E});let s=this.#r?.sessionFor?.(r),g;if(typeof s=="string"&&s){let c=this.#t.workspaceSession(s);c?.models&&(g=await c.models({signal:this.#E}))}g||(g=await this.#t.listModels({signal:this.#E})),a=g}catch{}await this.#U(o,yq({archiveVisible:i,presetCatalog:e,modelCatalog:a,workspaces:A,currentWorkspace:t}),{key:r})}async#be(r,o){try{let i=await this.#t.agentPresetSettings({signal:this.#E}),e=i.agentPresetCatalog;e._currentId=i.agentPreset,await this.#U(o,mq(e),{key:r})}catch(i){this.#C.warn?.("[dsh-feishu] preset card failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u9884\u8BBE\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#Me(r,o){try{await this.#t.ensureRunning({signal:this.#E});let i=this.#r?.sessionFor?.(r),e;if(typeof i=="string"&&i){let a=this.#t.workspaceSession(i);a?.models&&(e=await a.models({signal:this.#E}))}e||(e=await this.#t.listModels({signal:this.#E})),await this.#U(o,Sq(e),{key:r})}catch(i){this.#C.warn?.("[dsh-feishu] model card failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u6A21\u578B\u5217\u8868\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#_e(r,o){try{await this.#t.ensureRunning({signal:this.#E});let i=["\u8FDE\u63A5\u6B63\u5E38"],e=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;e&&i.push(`\u5DE5\u4F5C\u533A\uFF1A${e}`);let a=typeof this.#t.agentPresetSettings=="function"?await this.#t.agentPresetSettings({signal:this.#E}).catch(()=>null):null;if(a){let A=a.agentPresetCatalog?.items?.find(t=>t.id===a.agentPreset);i.push(`\u9884\u8BBE\uFF1A${A?`${A.label}\uFF08${A.id}\uFF09`:a.agentPreset||"\u8DDF\u968F\u9ED8\u8BA4"}`)}await this.#Q(o,i.join(` `))}catch(i){this.#C.warn?.("[dsh-feishu] status text failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u7CFB\u7EDF\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#Ne(r,o){try{await this.#t.ensureRunning({signal:this.#E});let i={connected:!0,workspace:null,preset:null,model:null,sessionCount:0};try{let e=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;i.workspace=e||"\u672A\u77E5"}catch{}try{let e=await this.#t.agentPresetSettings({signal:this.#E}),a=e.agentPresetCatalog.items.find(A=>A.id===e.agentPreset);i.preset=a?`${a.label}\uFF08${a.id}\uFF09`:e.agentPreset||"\u8DDF\u968F\u9ED8\u8BA4"}catch{}try{let e=this.#r?.sessionFor?.(r);if(typeof e=="string"&&e){let a=this.#t.workspaceSession(e);if(a?.models){let A=await a.models({signal:this.#E});A.current&&(i.model=`${A.current.provider}/${A.current.model}`)}}}catch{}try{let e=typeof this.#t.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(e){let a=await this.#t.listWorkspaceSessions(e);Array.isArray(a?.sessions)&&(i.sessionCount=a.sessions.length)}}catch{}await this.#U(o,Dq(i),{key:r})}catch(i){this.#C.warn?.("[dsh-feishu] status card failed:",i.message),await this.#Q(o,"\u6682\u65F6\u65E0\u6CD5\u83B7\u53D6\u7CFB\u7EDF\u72B6\u6001\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#Te(r,o){await this.#U(o,Oq(nDe),{key:r})}async#Re(r,o){try{let e=(await za("/compact",this.#t,this.#r,r,{signal:this.#E}))?.message||"\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25\u3002";await this.#Q(o,e)}catch(i){this.#C.warn?.("[dsh-feishu] compact failed:",i.message,i.code),await this.#Q(o,compactCommand?.message||"\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#ke(r,o){try{let i=await Wa("/stop",this.#t,this.#r,r,{signal:this.#E,control:{owner:this,key:r}});await this.#Q(o,i?.message||"/stop \u6267\u884C\u5B8C\u6210\u3002")}catch(i){this.#C.warn?.("[dsh-feishu] stop failed:",i.message),await this.#Q(o,"\u505C\u6B62\u4EFB\u52A1\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#ve(r,o){let i=!!this.#r.sessionFor?.(r);this.#j(r,{kind:"steer"}),await this.#U(o,kq({hasSession:i}),{key:r})}async#oe(r,o){let{key:i,chatId:e}=r,A=(await Wa(`/steer ${o}`,this.#t,this.#r,i,{signal:this.#E,control:{owner:this,key:i}}))?.message||"\u5DF2\u63D0\u4EA4\u8865\u5145\u6307\u4EE4\u3002";this.#Q(e,A).catch(()=>{})}async#Be(r,o){try{if(typeof this.#t?.updateAgentPreset!="function"){await this.#Q(o,"\u5F53\u524D Host \u6682\u4E0D\u652F\u6301\u4FEE\u6539 Agent Preset\u3002");return}await this.#t.updateAgentPreset(null,{signal:this.#E}),await this.#Q(o,"\u5DF2\u6062\u590D\u8DDF\u968F Host \u9ED8\u8BA4\u9884\u8BBE\u3002"),await this.#te(r,o)}catch(i){this.#C.warn?.("[dsh-feishu] preset default failed:",i.message),await this.#Q(o,"\u9884\u8BBE\u91CD\u7F6E\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002")}}async#Pe(r,o,i){try{if(typeof this.#t?.updateAgentPreset!="function"){await this.#Q(o,"\u5F53\u524D Host \u6682\u4E0D\u652F\u6301\u4FEE\u6539 Agent Preset\u3002");return}await this.#t.updateAgentPreset(i,{signal:this.#E}),await this.#Q(o,`\u9884\u8BBE\u5DF2\u5207\u6362\u4E3A\uFF1A${i}`),await this.#te(r,o)}catch(e){this.#C.warn?.("[dsh-feishu] preset select failed:",e.message),await this.#Q(o,`\u9884\u8BBE\u5207\u6362\u5931\u8D25\uFF1A${e.message}`)}}async#Ge(r,o,i){try{let a=(await ui(`/model ${i}`,this.#t,this.#r,r,{signal:this.#E,control:{owner:this,key:r}}))?.message||"\u6A21\u578B\u5207\u6362\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";await this.#Q(o,a),await this.#te(r,o)}catch(e){this.#C.warn?.("[dsh-feishu] model select failed:",e.message),await this.#Q(o,`\u6A21\u578B\u5207\u6362\u5931\u8D25\uFF1A${e.message}`)}}#fe(){if(this.#b||typeof this.#t?.watchHarnessEvents!="function"||this.#E?.aborted)return;let r=this.#E??new AbortController().signal;try{this.#b=this.#t.watchHarnessEvents({signal:r,onSessionEvent:o=>this.#Ue(o),onReconnect:()=>{this.#ne(()=>this.#He())}}),Promise.resolve(this.#b).catch(o=>{r.aborted||this.#C.warn?.("[dsh-feishu] event watcher stopped:",o.message)})}catch(o){this.#b=null,this.#C.warn?.("[dsh-feishu] event watcher failed to start:",o.message)}}#ne(r){let o=this.#_.then(r,r).catch(i=>{this.#E?.aborted||this.#C.warn?.("[dsh-feishu] completion event failed:",i.message)});return this.#_=o,o}async#Fe(r){if(typeof r!="string"||r==="")return{error:"\u7528\u6CD5\uFF1A/watch "};let o=/^\d{1,4}$/.test(r)?Number(r):null,i=typeof this.#t?.currentWorkspace=="function"?this.#t.currentWorkspace():null,e=async t=>{let s=await this.#t.listWorkspaceSessions(t);return Array.isArray(s?.sessions)?s.sessions:[]};if(o!==null){if(!i)return{error:"\u5F53\u524D\u673A\u5668\u4EBA\u6CA1\u6709\u53EF\u7528\u7684\u5DE5\u4F5C\u533A\uFF0C\u65E0\u6CD5\u6309\u5E8F\u53F7\u89E3\u6790\u4F1A\u8BDD\u3002"};let t=this.#ee(await e(i)),s=t[o-1];return s?.sessionId?{sessionId:s.sessionId,title:s.title??"\u6682\u65E0\u6807\u9898"}:{error:`\u5F53\u524D\u5DE5\u4F5C\u533A\u53EA\u6709 ${t.length} \u4E2A\u4F1A\u8BDD\u3002`}}let a=typeof this.#t?.listWorkspaces=="function"?(await this.#t.listWorkspaces()).filter(t=>t!==i):[],A=[i,...a].filter(Boolean);for(let t of A){let g=(await e(t)).find(c=>c.sessionId===r);if(g)return{sessionId:r,title:g.title??"\u6682\u65E0\u6807\u9898"}}return{error:"\u6CA1\u6709\u627E\u5230\u8FD9\u4E2A\u4F1A\u8BDD\uFF0C\u8BF7\u7528 /sessionlist \u67E5\u770B\u53EF\u7528\u4F1A\u8BDD\u3002"}}async#Le(r){if(typeof this.#t?.rpc!="function")return null;let o=await this.#t.rpc("session.history",{sessionId:r,maxMessages:20},3e4,{signal:this.#E});return Lq(o).at(-1)?.seq??-1}async#se(r,o,i){if(this.#fe(),typeof this.#r?.setWatch!="function"){await this.#Q(o,"\u5F53\u524D\u72B6\u6001\u5B58\u50A8\u4E0D\u652F\u6301\u5173\u6CE8\u3002");return}let e;try{e=await this.#Fe(i)}catch(t){await this.#Q(o,`\u65E0\u6CD5\u89E3\u6790\u4F1A\u8BDD\uFF1A${Mh(t)}`);return}if(e.error){await this.#Q(o,e.error);return}let a=this.#r.watchEntries?.(r)??[],A=a.find(t=>t.sessionId===e.sessionId);if(!A&&a.length>=_Q){await this.#Q(o,`\u6BCF\u4E2A\u804A\u5929\u6700\u591A\u5173\u6CE8 ${_Q} \u4E2A\u4F1A\u8BDD\u3002`);return}try{let t=typeof A?.lastSeq=="number"?A.lastSeq:await this.#Le(e.sessionId);await this.#r.setWatch(r,{sessionId:e.sessionId,title:e.title,chatId:o,lastSeq:t}),await this.#Q(o,`\u5DF2\u5173\u6CE8\u4F1A\u8BDD\u300C${String(e.title).replace(/\s+/gu," ")}\u300D\uFF0C\u4EFB\u52A1\u5B8C\u6210\u4F1A\u63A8\u9001\u7ED3\u679C\u3002`),await this.#ne(()=>this.#Ie(e.sessionId))}catch(t){await this.#Q(o,`\u5173\u6CE8\u5931\u8D25\uFF1A${Mh(t)}`)}}async#ge(r,o,i){if(typeof this.#r?.removeWatch!="function")return;let e=this.#r.watchEntries?.(r)??[],a=typeof i=="string"&&/^\d{1,4}$/.test(i)?e[Number(i)-1]:e.find(A=>A.sessionId===i);if(!a){await this.#Q(o,"\u5173\u6CE8\u5217\u8868\u91CC\u6CA1\u6709\u8FD9\u4E2A\u4F1A\u8BDD\uFF0C\u56DE\u590D /watchlist \u67E5\u770B\u3002");return}try{await this.#r.removeWatch(r,a.sessionId),this.#P.delete(`${r}\0${a.sessionId}`),await this.#Q(o,`\u5DF2\u53D6\u6D88\u5173\u6CE8\u300C${String(a.title??"").replace(/\s+/gu," ")}\u300D\u3002`)}catch(A){await this.#Q(o,`\u53D6\u6D88\u5931\u8D25\uFF1A${Mh(A)}`)}}async#ce(r,o){let i=this.#r.watchEntries?.(r)??[],e=[];try{let a=typeof this.#t?.currentWorkspace=="function"?this.#t.currentWorkspace():null;if(a&&typeof this.#t?.listWorkspaceSessions=="function"){let A=await this.#t.listWorkspaceSessions(a);e=(Array.isArray(A?.sessions)?A.sessions:[]).map(t=>({sessionId:t.sessionId,title:t.title??t.name??t.sessionId}))}}catch{}this.#j(r,{kind:"watches",entries:i}),await this.#U(o,Nq(i,e),{key:r})}#Ue({sessionId:r,event:o}){this.#E?.aborted||!r||!o||typeof o!="object"||o.type!=="turn/end"||!Number.isFinite(o.seq)||this.#ne(async()=>{(this.#r.keysWatching?.(r)??[]).some(e=>this.#P.has(`${e}\0${r}`))&&await this.#Ie(r),await this.#Qe(r,o)})}async#Qe(r,o){if(this.#E?.aborted||typeof this.#r?.keysWatching!="function")return;let i=o?.data?.reason?.kind??o?.data?.reason??null;for(let e of this.#r.keysWatching(r)){if(this.#E?.aborted)return;let a=this.#r.watchEntry?.(e,r),A=`${e}\0${r}`,t=this.#P.get(A);if(typeof t=="number"&&typeof a?.lastSeq=="number"&&a.lastSeq>=t&&(this.#P.delete(A),t=void 0),!(!a?.chatId||typeof a.lastSeq=="number"&&a.lastSeq>=o.seq||typeof t=="number"&&o.seq>t))try{await this.#U(a.chatId,Tq(r,a.title,i),{key:e});let s=this.#r.watchEntry?.(e,r);if(!s||s.chatId!==a.chatId||typeof s.lastSeq=="number"&&s.lastSeq>=o.seq)continue;await this.#r.setWatch(e,{...s,lastSeq:o.seq}),t===o.seq&&this.#P.delete(A)}catch(s){this.#P.set(A,typeof t=="number"?Math.min(t,o.seq):o.seq),this.#C.warn?.("[dsh-feishu] completion push failed:",s.message)}}}async#Ie(r){if(!(this.#E?.aborted||typeof this.#t?.rpc!="function"))try{let o=await this.#t.rpc("session.history",{sessionId:r,maxMessages:20},3e4,{signal:this.#E}),i=Lq(o),e=i.at(-1)?.seq??-1,a=typeof this.#r?.keysWatching=="function"?this.#r.keysWatching(r):[];for(let A of a){let t=this.#r.watchEntry?.(A,r);t&&typeof t.lastSeq!="number"&&await this.#r.setWatch(A,{...t,lastSeq:e})}for(let A of i)A.type==="turn/end"&&await this.#Qe(r,A)}catch(o){this.#E?.aborted||this.#C.warn?.(`[dsh-feishu] watch compensation failed for ${r}:`,o.message)}}async#He(){let r=typeof this.#r?.watchedSessionIds=="function"?this.#r.watchedSessionIds():[];for(let o of r){if(this.#E?.aborted)return;await this.#Ie(o)}}#le(r,o){return{timeoutMs:this.#h,signal:this.#E,control:{owner:this,key:o},onInteraction:i=>this.#xe(i,{key:o,actor:vQ(r),chatId:r.message.chat_id,requiresMention:r.message.chat_type!=="p2p"}),onInteractionResolved:i=>this.#je(i)}}async#Ke(r,o,i){let e=r.message.chat_id,a=r.message.message_id,A=i.content,t=lr(i)?await Yi(i,{signal:this.#E}):void 0;if(!this.#A?.stream){let{answer:c}=await Va({harness:this.#t,state:this.#r,key:o,text:A,content:t,createOptions:{signal:this.#E},existsOptions:{signal:this.#E},askOptions:this.#le(r,o)});for(let I of DQ(c))await this.#Q(e,I);this.#g.streamFallbacks=(this.#g.streamFallbacks??0)+1;return}let s=!1,g="";try{await this.#A.stream(e,{markdown:async c=>{s=!0;let I={...this.#le(r,o),onUpdate:async E=>{await c.setContent(this.#Je(E)),this.#g.streamUpdates=(this.#g.streamUpdates??0)+1}};({answer:g}=await Va({harness:this.#t,state:this.#r,key:o,text:A,content:t,createOptions:{signal:this.#E},existsOptions:{signal:this.#E},askOptions:I})),await c.setContent(g)}},{replyTo:a}),this.#g.streamResponses=(this.#g.streamResponses??0)+1}catch(c){if(this.#g.streamErrors=(this.#g.streamErrors??0)+1,g){this.#C.warn?.("[dsh-feishu] native stream failed after generation; sending final text:",c.message);for(let E of DQ(g))await this.#Q(e,E);this.#g.streamFallbacks=(this.#g.streamFallbacks??0)+1;return}if(s)throw c;this.#C.warn?.("[dsh-feishu] native stream unavailable; using text fallback:",c.message);let{answer:I}=await Va({harness:this.#t,state:this.#r,key:o,text:A,content:t,createOptions:{signal:this.#E},existsOptions:{signal:this.#E},askOptions:this.#le(r,o)});for(let E of DQ(I))await this.#Q(e,E);this.#g.streamFallbacks=(this.#g.streamFallbacks??0)+1}}async#Ye(r,o,i,e,a){this.#E?.throwIfAborted();let A=this.#o.get(i),t=e.claimedReplyMessageId===o;if(!A||A!==e||A.submitting)return this.#pe(r,i)?this.#Ee(r,o):t&&(!A||A!==e)?this.#Ee(r,o):this.#R(r,o,i,a,{releaseMessageId:!1,finalize:!1});if(this.#r.hasSeen(o))return;await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1;let s=bh(r);if(!s){await this.#Q(r.message.chat_id,"\u8BF7\u7528\u6587\u5B57\u56DE\u7B54\u5F53\u524D\u95EE\u9898\u3002");return}let g=this.#o.get(i);if(!g||g!==e||g.submitting){if(this.#pe(r,i)){await this.#Q(r.message.chat_id,TQ).catch(()=>{});return}if(t&&(!g||g!==e)){await this.#Q(r.message.chat_id,TQ);return}return this.#R(r,o,i,a,{releaseMessageId:!1,alreadyRecorded:!0,finalize:!1})}if(g.chatId=r.message.chat_id,g.needsPresentation){try{await this.#re(g)}catch{this.#g.lastError="\u98DE\u4E66\u4EA4\u4E92\u95EE\u9898\u53D1\u9001\u5931\u8D25\u3002",this.#C.error?.("[dsh-feishu] failed to retry an interaction question"),g.interaction.reconnect?.()}return}let c=g.questions[g.index];if(c){if(g.answers.push(ja(c,s)),g.index+=1,g.index{});return}g.submitting=!1,g.answers.pop(),g.index-=1,this.#g.lastError="\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\u3002",this.#C.error?.("[dsh-feishu] failed to answer a Harness interaction"),await this.#Q(r.message.chat_id,"\u56DE\u7B54\u63D0\u4EA4\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u5F53\u524D\u95EE\u9898\u7684\u7B54\u6848\u3002").catch(()=>{})}}}async#xe(r,{key:o,actor:i,chatId:e,requiresMention:a}){if(await this.#I.handleRequested(r,{key:o,actor:i,requiresMention:a,send:c=>this.#Q(e,c)})||r?.kind!=="question")return;let A=r?.payload?.questions,t=typeof r?.interactionId=="string"?r.interactionId:r?.rpcId;if(typeof r.rpcId!="string"||typeof t!="string"||typeof r.sessionId!="string"||!Array.isArray(A)||A.length===0||A.some(c=>!Ya(c))){this.#C.warn?.("[dsh-feishu] ignored an invalid Harness question interaction");return}if(r.recovered===!0){await r.respond({ok:!1,error:{code:"cancelled",message:"Feishu safely cancelled an interaction left by an earlier client.",details:{}}}),await this.#Q(e,"\u68C0\u6D4B\u5230\u8FD9\u4E2A Session \u4E2D\u9057\u7559\u7684\u5F85\u56DE\u7B54\u95EE\u9898\uFF0C\u5DF2\u5B89\u5168\u53D6\u6D88\u5E76\u7EE7\u7EED\u5904\u7406\u4F60\u521A\u624D\u7684\u6D88\u606F\u3002").catch(()=>{});return}let s=this.#o.get(o);if(s?.interactionId===t){s.interaction=r,s.needsPresentation&&await this.#re(s);return}if(this.#l.has(t))return;if(s){await r.respond({ok:!1,error:{code:"cancelled",message:"Feishu is already handling another user interaction.",details:{}}});return}let g={kind:"question",interactionId:t,sessionId:r.sessionId,interaction:r,key:o,actor:i,requiresMention:a,questions:A,answers:[],index:0,chatId:e,queue:null,claimedReplyMessageId:null,submitting:!1,needsPresentation:!0,questionMessageIds:new Set,inactive:!1};this.#o.set(o,g),this.#l.set(g.interactionId,o),await this.#re(g)}async#je(r){if(await this.#I.handleResolved(r))return;let o=r?.interactionId;if(r?.kind!=="question"||typeof o!="string")return;let i=this.#l.get(o);if(!i)return;let e=this.#o.get(i);e&&this.#Ae(i,e),this.#Ce(i,o)}async#re(r){let o=r.questions[r.index];if(!o)return;let i=await this.#Q(r.chatId,xa(o,r.index,r.questions.length,{requiresMention:r.requiresMention}));i&&(r.questionMessageIds.add(i),r.inactive&&this.#Ae(r.key,r)),r.needsPresentation=!1}#Ae(r,o){let i=Date.now()+qSe;for(let e of o.questionMessageIds??[])this.#s.set(e,{key:r,expiresAt:i})}#pe(r,o){let i=Date.now();for(let[e,a]of this.#s)a.expiresAt<=i&&this.#s.delete(e);for(let e of[r?.message?.parent_id,r?.message?.root_id]){let a=this.#s.get(e);if(a?.key===o&&a.expiresAt>i)return!0}return!1}async#Ee(r,o){this.#r.hasSeen(o)||(await this.#r.markSeen(o),this.#g.lastMessageAt=new Date().toISOString(),this.#g.messagesReceived+=1,await this.#Q(r.message.chat_id,TQ).catch(()=>{}))}#ye(r,o){let i=this.#o.get(r);return!i||o!==void 0&&i.interactionId!==o?null:(this.#o.delete(r),this.#l.delete(i.interactionId),i.inactive=!0,i)}#Ce(r,o){return this.#ye(r,o)!==null}async#me(r){let o=this.#ye(r);if(!(!o||o.kind!=="question")){this.#Ae(r,o);try{await o.interaction.respond({ok:!1,error:{code:"cancelled",message:"The Feishu interaction ended before the user answered.",details:{}}},{signal:AbortSignal.timeout(5e3)})}catch(i){i?.code!=="interaction-not-pending"&&this.#C.warn?.("[dsh-feishu] failed to cancel a pending Harness interaction")}}}#Je(r){return r.type==="text"&&r.text?r.text:r.type==="tool"?r.name==="web_search"?"_\u6B63\u5728\u641C\u7D22\u7F51\u7EDC\u5E76\u6574\u7406\u4FE1\u606F\u2026_":`_\u6B63\u5728\u4F7F\u7528 ${r.name||"\u5DE5\u5177"}\u2026_`:`_${r.text||"\u6B63\u5728\u5904\u7406\u2026"}_`}async#Se(r,o){if(!this.#A?.addReaction)return null;try{let i=await this.#A.addReaction(r,o);return this.#g.reactionsAdded=(this.#g.reactionsAdded??0)+1,i}catch(i){return this.#g.reactionErrors=(this.#g.reactionErrors??0)+1,this.#C.warn?.(`[dsh-feishu] unable to add ${o} reaction:`,i.message),null}}async#he(r,o){let i=await o;if(i&&this.#A?.removeReaction)try{await this.#A.removeReaction(r,i),this.#g.reactionsRemoved=(this.#g.reactionsRemoved??0)+1}catch(e){this.#g.reactionErrors=(this.#g.reactionErrors??0)+1,this.#C.warn?.("[dsh-feishu] unable to remove processing reaction:",e.message)}}async#z(r,o,i){await this.#he(r,o),await this.#Se(r,i)}async#Q(r,o){let i=await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:r,msg_type:"text",content:JSON.stringify({text:o})}});if(i?.code&&i.code!==0)throw new Error(`Feishu send failed: ${i.msg||i.code}`);return XA(i?.data?.message_id)}};var Kq="stream_md",IDe="\u5DF2\u8FDE\u63A5 DeepSeek Harness\uFF0C\u6B63\u5728\u601D\u8003\u2026";function Yc(n,r){if(r?.code&&r.code!==0)throw new Error(`${n} failed: ${r.msg||r.code}`);return r}function lDe(n){let r=String(n??"").replace(/\s+/g," ").trim();return r.length<=50?r:`${r.slice(0,49)}\u2026`}function pDe(n){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"\u6B63\u5728\u751F\u6210\u2026"},streaming_config:{print_frequency_ms:{default:70},print_step:{default:1},print_strategy:"fast"}},body:{elements:[{tag:"markdown",element_id:Kq,content:n}]}}}var GQ=class{#e;#A;constructor({client:r,initialText:o=IDe}){this.#e=r,this.#A=o}async stream(r,o,i={}){if(typeof o?.markdown!="function")throw new Error("Feishu stream requires a markdown producer");let e=null,A=Yc("Feishu card.create",await this.#e.cardkit.v1.card.create({data:{type:"card_json",data:JSON.stringify(pDe(this.#A))}}))?.data?.card_id;if(!A)throw new Error("Feishu card.create returned no card_id");try{e=await this.#t(r,A,i.replyTo);let t=0,s=this.#A,g={messageId:e,setContent:async I=>{let E=String(I??"")||"\u2026";if(E===s)return;if(E.length>28e3)throw new Error("Feishu stream content exceeds 28000 characters");let B=await this.#e.cardkit.v1.cardElement.content({path:{card_id:A,element_id:Kq},data:{content:E,sequence:++t,uuid:`content_${A}_${t}`}});Yc("Feishu cardElement.content",B),s=E}};await o.markdown(g);let c=await this.#e.cardkit.v1.card.settings({path:{card_id:A},data:{settings:JSON.stringify({config:{streaming_mode:!1,summary:{content:lDe(s)||"\u56DE\u7B54\u5B8C\u6210"}}}),sequence:++t,uuid:`settings_${A}_${t}`}});return Yc("Feishu card.settings",c),{messageId:e}}catch(t){throw e&&await this.#r(e),t}}async#t(r,o,i){let e=JSON.stringify({type:"card",data:{card_id:o}}),a=i?await this.#e.im.v1.message.reply({path:{message_id:i},data:{msg_type:"interactive",content:e}}):await this.#e.im.v1.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:r,msg_type:"interactive",content:e}});Yc("Feishu message send",a);let A=a?.data?.message_id;if(!A)throw new Error("Feishu message send returned no message_id");return A}async#r(r){try{let o=await this.#e.im.v1.message.delete({path:{message_id:r}});Yc("Feishu message delete",o)}catch(o){console.warn("[bridge] unable to recall a failed streaming card:",o.message)}}async addReaction(r,o){let e=Yc("Feishu reaction.create",await this.#e.im.v1.messageReaction.create({path:{message_id:r},data:{reaction_type:{emoji_type:o}}}))?.data?.reaction_id;if(!e)throw new Error("Feishu reaction.create returned no reaction_id");return e}async removeReaction(r,o){Yc("Feishu reaction.delete",await this.#e.im.v1.messageReaction.delete({path:{message_id:r,reaction_id:o}}))}};var CDe=15e3,hDe="\u2705 \u4FEE\u590D\u5B8C\u6210\uFF1A\u5DF2\u5B9E\u6D4B\u6536\u5230 card.action.trigger\uFF0C\u83DC\u5355\u6309\u94AE\u73B0\u5728\u53EF\u7528\u3002",dDe="\u26A0\uFE0F \u4FEE\u590D\u9A8C\u8BC1\u8D85\u65F6\uFF1A\u672A\u6536\u5230\u6D4B\u8BD5\u5361\u6309\u94AE\u7684 card.action.trigger\uFF0C\u4E0D\u80FD\u786E\u8BA4\u6309\u94AE\u5DF2\u4FEE\u590D\u3002\u8BF7\u4E0D\u8981\u91CD\u590D\u6388\u6743\uFF1B\u5148\u68C0\u67E5\u98DE\u4E66\u5F00\u653E\u5E73\u53F0\u7684\u5361\u7247\u56DE\u8C03\u914D\u7F6E\uFF0C\u786E\u8BA4\u540E\u518D\u53D1\u9001 /repair\u3002",IR="\u26A0\uFE0F \u4FEE\u590D\u9A8C\u8BC1\u5931\u8D25\uFF1A\u65E0\u6CD5\u53D1\u9001\u4E13\u7528\u6D4B\u8BD5\u5361\uFF0C\u4E0D\u80FD\u786E\u8BA4 card.action.trigger \u5DF2\u6062\u590D\u3002\u8BF7\u4E0D\u8981\u91CD\u590D\u6388\u6743\uFF1B\u5148\u68C0\u67E5\u673A\u5668\u4EBA\u6D88\u606F\u6743\u9650\u548C\u8FDE\u63A5\u72B6\u6001\u3002",uDe="\u26A0\uFE0F \u4FEE\u590D\u9A8C\u8BC1\u4E2D\u65AD\uFF1ARuntime \u5DF2\u505C\u6B62\uFF0C\u672A\u5B8C\u6210 card.action.trigger \u5B9E\u6D4B\uFF0C\u4E0D\u80FD\u786E\u8BA4\u4FEE\u590D\u6210\u529F\u3002\u8BF7\u4E0D\u8981\u91CD\u590D\u6388\u6743\uFF1B\u5148\u7B49\u5F85\u673A\u5668\u4EBA\u6062\u590D\u8FDE\u63A5\u3002";function ps(n){return typeof n=="string"&&n.trim()?n.trim():null}function BDe(n){return ps(n?.operator?.open_id)??ps(n?.operator?.operator_id?.open_id)}function Ap(n,r){let o=new Error(r);return o.code=n,o}function fDe(n,r){if(!n||typeof n.request!="function")return;let o=i=>({...i??{},timeout:i?.timeout??r});return{request:i=>n.request(o(i)),get:(i,e)=>n.get(i,o(e)),delete:(i,e)=>n.delete(i,o(e)),head:(i,e)=>n.head(i,o(e)),options:(i,e)=>n.options(i,o(e)),post:(i,e,a)=>n.post(i,e,o(a)),put:(i,e,a)=>n.put(i,e,o(a)),patch:(i,e,a)=>n.patch(i,e,o(a))}}function QDe({allowedSenderCount:n=1}={}){return{startedAt:null,ready:!1,feishuLongConnectionState:"idle",harnessReachable:!1,messagesReceived:0,messagesReplied:0,messagesRejected:0,reactionsAdded:0,reactionsRemoved:0,reactionErrors:0,streamResponses:0,streamUpdates:0,streamFallbacks:0,streamErrors:0,cardActionsReceived:0,cardActionProbesVerified:0,lastMessageAt:null,lastReplyAt:null,lastRejectedAt:null,lastCardActionAt:null,lastError:null,agentPreset:"standard",authorizationMode:"sender-open-id-allowlist",allowedSenderCount:n}}var FQ=class{#e;#A;#t;#r;#n;#o;#l;#s;#c;#a;#i;#I;#g;#p;#h;#C;#E=null;#d=null;#B=null;#u=null;#y=null;#S=new Map;#f;constructor({lark:r,botId:o,appId:i,appSecret:e,domain:a="feishu",botOpenId:A,groupResponseMode:t,ownerOpenId:s,ownerOpenIds:g,harness:c,state:I,repair:E,replyTimeoutMs:B=6e5,connectTimeoutMs:f=15e3,requestTimeoutMs:Q=CDe,wsAgent:y,logger:m=console}){if(!r)throw new Error("FeishuRuntime requires the Feishu SDK");if(!i||!e)throw new Error("FeishuRuntime requires app credentials");let T=Array.isArray(g)?g:[s],_=[...new Set(T.filter(P=>typeof P=="string"&&P))];if(_.length===0)throw new Error("FeishuRuntime requires at least one owner open_id");if(!c)throw new Error("FeishuRuntime requires a Harness client");if(!I)throw new Error("FeishuRuntime requires a state store");if(E!=null&&!ps(o))throw new TypeError("FeishuRuntime repair capability requires a botId");if(!Number.isFinite(Q)||Q<=0)throw new TypeError("FeishuRuntime requestTimeoutMs must be a positive number");this.#e=r,this.#A=ps(o),this.#t=i,this.#r=e,this.#n=a,this.#o=ps(A),this.#l=Mi(t),this.#s=_,this.#c=c,this.#a=I,this.#C=E??null,this.#i=B,this.#I=f,this.#g=Q,this.#p=y,this.#h=m,this.#f=QDe({allowedSenderCount:_.length})}get status(){return structuredClone(this.#f)}setGroupResponseMode(r){this.#l=Mi(r),this.#d?.setGroupResponseMode(this.#l)}async start(){return this.#B&&this.#f.ready?this.status:this.#u?this.#u:(this.#u=this.#m().finally(()=>{this.#u=null}),this.#u)}async#m(){let r=new AbortController;this.#y=r;let{signal:o}=r;this.#f.startedAt=new Date().toISOString(),this.#f.feishuLongConnectionState="connecting",this.#f.lastError=null;try{await this.#c.ensureRunning({signal:o}),this.#f.harnessReachable=!0;let i=this.#n==="lark"?this.#e.Domain.Lark:this.#e.Domain.Feishu,e={appId:this.#t,appSecret:this.#r,domain:i},a=fDe(this.#e.defaultHttpInstance,this.#g);a&&(e.httpInstance=a),this.#E=new this.#e.Client(e);let A=new GQ({client:this.#E,initialText:"\u5DF2\u8FDE\u63A5 DeepSeek Harness\uFF0C\u6B63\u5728\u601D\u8003\u2026"});this.#d=new PQ({client:this.#E,channel:A,harness:this.#c,state:this.#a,status:this.#f,allowedSenderOpenIds:new Set(this.#s),botId:this.#A,appId:this.#t,botOpenId:this.#o,groupResponseMode:this.#l,repair:this.#C,repairOwnerOpenIds:new Set(this.#s.filter(I=>I!=="*")),replyTimeoutMs:this.#i,signal:o,logger:this.#h});let t=new this.#e.EventDispatcher({}).register({"im.message.receive_v1":I=>(this.#d.accept(I),{}),"im.message.reaction.created_v1":()=>({}),"im.message.reaction.deleted_v1":()=>({}),"card.action.trigger":I=>(this.#f.cardActionsReceived+=1,this.#f.lastCardActionAt=new Date().toISOString(),this.#D(I)||this.#d.onCardAction(I),{})}),s,g,c=new Promise((I,E)=>{let B=!1,f=setTimeout(()=>{B||(B=!0,E(new Error(`Feishu WebSocket handshake timed out after ${this.#I}ms`)))},this.#I);s=()=>{B||(B=!0,clearTimeout(f),I())},g=Q=>{B||(B=!0,clearTimeout(f),E(Q))}});return this.#B=new this.#e.WSClient({...e,...this.#p?{agent:this.#p}:{},loggerLevel:this.#e.LoggerLevel.info,handshakeTimeoutMs:15e3,onReady:()=>{this.#f.feishuLongConnectionState="connected",this.#f.ready=!0,this.#f.lastError=null,s()},onError:I=>{this.#f.feishuLongConnectionState="failed",this.#f.ready=!1,this.#f.lastError=I?.message??String(I),this.#h.error("[dsh-feishu] Feishu long connection failed:",this.#f.lastError),g(I)},onReconnecting:()=>{this.#f.feishuLongConnectionState="reconnecting",this.#f.ready=!1},onReconnected:()=>{this.#f.feishuLongConnectionState="connected",this.#f.ready=!0,this.#f.lastError=null}}),await this.#B.start({eventDispatcher:t}).catch(I=>{g(I)}),await c,this.status}catch(i){throw this.#f.ready=!1,this.#f.feishuLongConnectionState="failed",this.#f.lastError=i?.message??String(i),await this.stop({preserveError:!0}),i}}async beginCardActionProbe({expectedOperatorOpenId:r,timeoutMs:o=9e4}={}){if(!this.#f.ready||!this.#E)throw Ap("card_action_probe_unavailable","\u98DE\u4E66\u673A\u5668\u4EBA\u5C1A\u672A\u8FDE\u63A5");let i=ps(r);if(!i||i==="*")throw new TypeError("A precise Feishu operator open_id is required");if(!Number.isFinite(o)||o<=0||o>10*6e4)throw new TypeError("Card-action probe timeout must be between 1 and 600000ms");let e=EDe().replaceAll("-",""),a;try{a=await this.#E.im.v1.message.create({params:{receive_id_type:"open_id"},data:{receive_id:i,msg_type:"interactive",content:bq(e)}})}catch{throw this.#w(i,IR,"failure"),Ap("card_action_probe_send_failed","\u65E0\u6CD5\u53D1\u9001\u98DE\u4E66\u5361\u7247\u56DE\u8C03\u6D4B\u8BD5")}if(a?.code&&a.code!==0)throw this.#w(i,IR,"failure"),Ap("card_action_probe_send_failed","\u65E0\u6CD5\u53D1\u9001\u98DE\u4E66\u5361\u7247\u56DE\u8C03\u6D4B\u8BD5");let A=ps(a?.data?.message_id)??ps(a?.message_id);if(!A)throw this.#w(i,IR,"failure"),Ap("card_action_probe_send_failed","\u98DE\u4E66\u672A\u8FD4\u56DE\u6D4B\u8BD5\u5361\u7247\u7684\u6D88\u606F ID");return new Promise((t,s)=>{let g=setTimeout(()=>{let c=this.#S.get(A);!c||c.nonce!==e||(this.#S.delete(A),this.#w(i,dDe,"timeout"),s(Ap("card_action_probe_timeout","\u5728\u89C4\u5B9A\u65F6\u95F4\u5185\u672A\u6536\u5230\u98DE\u4E66\u5361\u7247\u6309\u94AE\u56DE\u8C03")))},o);g.unref?.(),this.#S.set(A,{messageId:A,nonce:e,expectedOperatorOpenId:i,timeout:g,resolve:t,reject:s})})}#D(r){let o=ps(r?.context?.open_message_id);if(!o)return!1;let i=this.#S.get(o);if(!i)return!1;let e=r?.action?.value,a=BDe(r);return e?.action!=="repair_verify"||e?.nonce!==i.nonce||a!==i.expectedOperatorOpenId?!1:(clearTimeout(i.timeout),this.#S.delete(o),this.#f.cardActionProbesVerified+=1,this.#w(a,hDe,"success").finally(()=>{i.resolve({verified:!0,messageId:o,operatorOpenId:a})}),!0)}#w(r,o,i){let e=this.#E;return e?Promise.resolve().then(async()=>{let a=await e.im.v1.message.create({params:{receive_id_type:"open_id"},data:{receive_id:r,msg_type:"text",content:JSON.stringify({text:o})}});if(a?.code&&a.code!==0)throw new Error("Feishu callback repair notice failed");return!0}).catch(()=>(this.#h.warn?.(`[dsh-feishu] unable to send the callback repair ${i} notice`),!1)):(this.#h.warn?.(`[dsh-feishu] unable to send the callback repair ${i} notice`),Promise.resolve(!1))}async sendConnectionTest(r){if(!this.#f.ready||!this.#E){let e=new Error("\u98DE\u4E66\u673A\u5668\u4EBA\u5C1A\u672A\u8FDE\u63A5");throw e.code="test-target-unavailable",e}if(typeof r!="string"||!r.trim())throw new TypeError("Feishu connection test text is required");let o=async(e,a,A)=>{let t=await this.#E.im.v1.message.create({params:{receive_id_type:e},data:{receive_id:a,msg_type:"text",content:JSON.stringify({text:A})}});if(t?.code&&t.code!==0)throw new Error(`Feishu connection test failed: ${t.msg||t.code}`)},i=this.#s.find(e=>e!=="*");return i?(await o("open_id",i,r),{sent:!0}):xs({state:this.#a,text:r,channelLabel:"\u98DE\u4E66\u673A\u5668\u4EBA",send:async(e,a)=>{let A=typeof e?.chatId=="string"?e.chatId.trim():"";if(!A)throw rr("\u98DE\u4E66\u673A\u5668\u4EBA");await o("chat_id",A,a)}})}async stop({preserveError:r=!1}={}){let o=r?this.#f.lastError:null,i=this.#y;this.#y=null,i?.abort(new DOMException("Feishu runtime stopped","AbortError"));for(let e of this.#S.values())clearTimeout(e.timeout),this.#w(e.expectedOperatorOpenId,uDe,"abort"),e.reject(Ap("abort","\u98DE\u4E66\u8FD0\u884C\u65F6\u5DF2\u505C\u6B62"));return this.#S.clear(),this.#f.ready=!1,this.#B&&(this.#B.close({force:!0}),this.#B=null),this.#d&&(await this.#d.waitForIdle(),this.#d=null),this.#E=null,this.#f.feishuLongConnectionState=r?"failed":"idle",this.#f.lastError=o,this.status}};var LQ=class extends ar{constructor(r){super({...r,rpcIdPrefix:"feishu",logPrefix:"dsh-feishu"})}};import{createHash as yDe}from"node:crypto";import{mkdir as mDe,readFile as SDe,rename as DDe,unlink as wDe,writeFile as ODe}from"node:fs/promises";import{dirname as bDe}from"node:path";var KQ="DSH_FEISHU_APP_SECRET";function dn(n){return typeof n=="string"&&n.trim()?n.trim():null}function Yq(n){let r=dn(n);return r&&/^[A-Za-z0-9_-]{1,128}$/.test(r)?r:null}function xq(n){return`bot_${yDe("sha256").update(n).digest("hex").slice(0,24)}`}function MDe(n){let r=Array.isArray(n.ownerOpenIds)?n.ownerOpenIds:[n.ownerOpenId];return[...new Set(r.map(dn).filter(Boolean))]}function UQ(n,{legacy:r=!1}={}){if(!n||typeof n!="object")return null;let o=dn(n.appId),i=MDe(n);if(!o||i.length===0)return null;let e=Yq(n.id)??(r?xq(o):null),a=dn(n.secretRef)??(r?KQ:null);if(!e||!a||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(a))return null;let A=n.domain==="lark"?"lark":"feishu";return Object.freeze({id:e,appId:o,secretRef:a,ownerOpenIds:Object.freeze(i),domain:A,botName:dn(n.botName),botOpenId:dn(n.botOpenId),activated:n.activated??null,groupResponseMode:Mi(n.groupResponseMode),groupMessagePermissionGranted:n.groupMessagePermissionGranted===!0,deletionPending:n.deletionPending===!0,connectedAt:dn(n.connectedAt),createdAt:dn(n.createdAt)??dn(n.connectedAt)})}function _De(n){if(!n||typeof n!="object")return null;if(n.version===2&&Array.isArray(n.bots)){let o=n.bots.map(A=>UQ(A));if(o.some(A=>A===null))throw new Error("dsh-feishu config contains an invalid bot entry");let i=new Set,e=new Set,a=new Set;for(let A of o){if(i.has(A.id)||e.has(A.secretRef)||a.has(A.appId))throw new Error("dsh-feishu config contains duplicate bot identities");i.add(A.id),e.add(A.secretRef),a.add(A.appId)}return{value:Object.freeze({version:2,bots:Object.freeze(o)}),migrated:!1}}let r=UQ(n,{legacy:!0});return r?{value:Object.freeze({version:2,bots:Object.freeze([r])}),migrated:!0}:null}var HQ=class{#e;#A=Object.freeze({version:2,bots:Object.freeze([])});#t=Promise.resolve();constructor(r){this.#e=r}async load(){try{let r=JSON.parse(await SDe(this.#e,"utf8")),o=_De(r);if(!o)throw new Error("dsh-feishu config is incomplete or invalid");this.#A=o.value,o.migrated&&await this.#o(this.#A)}catch(r){if(r?.code!=="ENOENT")throw r;this.#A=Object.freeze({version:2,bots:Object.freeze([])})}return this}get(){let r=this.#A.bots[0];if(!r)return null;let o=structuredClone(r);return o.ownerOpenId=o.ownerOpenIds[0],o}list(){return structuredClone(this.#A.bots)}getBot(r){let o=this.#A.bots.find(i=>i.id===r);return o?structuredClone(o):null}async save(r){let o={...r};o.id||(o.id=xq(dn(o.appId)??"invalid")),o.secretRef||(o.secretRef=KQ);let i=UQ(o);if(!i)throw new Error("Refusing to persist incomplete dsh-feishu configuration");return await this.#r([i]),this.get()}async saveBot(r){let o=UQ(r);if(!o)throw new Error("Refusing to persist incomplete dsh-feishu bot configuration");return this.#n(i=>{if(i.find(t=>t.secretRef===o.secretRef&&t.id!==o.id))throw new Error("Refusing to share a credential reference between Feishu bots");if(i.find(t=>t.appId===o.appId&&t.id!==o.id))throw new Error("Refusing to persist the same Feishu app twice");let A=i.findIndex(t=>t.id===o.id);return A===-1?i.push(o):i[A]=o,structuredClone(o)})}async removeBot(r){if(!Yq(r))throw new TypeError("Invalid Feishu bot id");return this.#n(o=>{let i=o.findIndex(a=>a.id===r);if(i===-1)return null;let[e]=o.splice(i,1);return structuredClone(e)})}async clear(){let r=this.#t.then(async()=>{try{await wDe(this.#e)}catch(o){if(o?.code!=="ENOENT")throw o}this.#A=Object.freeze({version:2,bots:Object.freeze([])})});this.#t=r.then(()=>{},()=>{}),await r}async#r(r){let o=Object.freeze({version:2,bots:Object.freeze([...r])}),i=this.#t.then(async()=>{await this.#o(o),this.#A=o});this.#t=i.then(()=>{},()=>{}),await i}async#n(r){let o,i=this.#t.then(async()=>{let e=[...this.#A.bots];o=r(e);let a=Object.freeze({version:2,bots:Object.freeze(e)});await this.#o(a),this.#A=a});return this.#t=i.then(()=>{},()=>{}),await i,o}async#o(r){await mDe(bDe(this.#e),{recursive:!0,mode:448});let o=`${this.#e}.tmp`;await ODe(o,`${JSON.stringify(r,null,2)} `,{encoding:"utf8",mode:384}),await DDe(o,this.#e)}};import{randomUUID as zq}from"node:crypto";var lR=new Set(["starting","qr_ready","polling","slow_down","domain_switched","saving"]),NDe=new Set(["polling","slow_down","domain_switched"]),ii=Object.freeze({IDLE:"idle",STARTING:"starting",QR_READY:"qr_ready",POLLING:"polling",SLOW_DOWN:"slow_down",DOMAIN_SWITCHED:"domain_switched",SAVING:"saving",SUCCEEDED:"succeeded",EXPIRED:"expired",CANCELLED:"cancelled",ERROR:"error"});function jq(n){return["access_denied","expired_token","abort"].includes(n?.code)?n.code:"registration_failed"}function pR(n){let r=jq(n);return{code:r,message:{access_denied:"Registration was denied.",abort:"Registration was cancelled.",expired_token:"The registration QR code expired."}[r]??"Unable to register the Feishu app."}}function TDe(n){let r=Number(n);if(!Number.isFinite(r)||r<=0)throw new TypeError("registerApp onQRCodeReady returned an invalid expireIn");return r}function RDe(n){if(n!==void 0){if(n===null||typeof n!="object"||Array.isArray(n))throw new TypeError("registerApp returned invalid user_info");return{...n}}}var Es=class{#e;#A;#t;#r;#n;#o=0;#l=null;#s;constructor({registerApp:r,onCredentials:o,now:i=Date.now,setTimeout:e=globalThis.setTimeout,clearTimeout:a=globalThis.clearTimeout}={}){if(typeof r!="function")throw new TypeError("RegistrationManager requires a registerApp function");if(typeof o!="function")throw new TypeError("RegistrationManager requires an onCredentials function");if(typeof i!="function"||typeof e!="function"||typeof a!="function")throw new TypeError("RegistrationManager clock dependencies must be functions");this.#e=r,this.#A=o,this.#t=i,this.#r=e,this.#n=a,this.#s=this.#a(null,ii.IDLE)}start(r={}){if(r===null||typeof r!="object"||Array.isArray(r))throw new TypeError("Registration options must be an object");this.#u();let o={id:++this.#o,controller:new AbortController,qrCodeUrl:null,expiresAt:null,pollIntervalSeconds:null,expiryTimer:null};this.#l=o,this.#s=this.#a(o,ii.STARTING);let i={...r,signal:o.controller.signal,onQRCodeReady:a=>this.#I(o,a),onStatusChange:a=>this.#g(o,a)};return Promise.resolve().then(()=>this.#e(i)).then(a=>this.#p(o,a),a=>this.#h(o,a)),this.status()}status(){this.#C();let r={...this.#s};r.error&&(r.error={...r.error});let o=this.#l;return o&&o.expiresAt!==null&&lR.has(r.state)&&(r.remainingSeconds=Math.max(0,Math.ceil((o.expiresAt-this.#t())/1e3))),r}cancel(){let r=this.#l;return r?(this.#d(r,ii.CANCELLED,{error:{code:"abort",message:"Registration was cancelled."}}),r.controller.abort(),this.status()):this.status()}#c(r){return this.#l===r}#a(r,o,i={}){let e={state:o,attempt:r?.id??this.#o,updatedAt:this.#t(),...i};return r?.qrCodeUrl&&lR.has(o)&&(e.qrCodeUrl=r.qrCodeUrl,e.expiresAt=r.expiresAt),r?.pollIntervalSeconds!==null&&lR.has(o)&&(e.pollIntervalSeconds=r.pollIntervalSeconds),e}#i(r,o,i={}){this.#c(r)&&(this.#s=this.#a(r,o,i))}#I(r,o){if(!this.#c(r))return;if(typeof o?.url!="string"||!o.url)throw new TypeError("registerApp onQRCodeReady returned an invalid URL");let i=TDe(o.expireIn);r.qrCodeUrl=o.url,r.expiresAt=this.#t()+i*1e3,this.#B(r),r.expiryTimer=this.#r(()=>this.#E(r),i*1e3),r.expiryTimer?.unref?.(),this.#i(r,ii.QR_READY)}#g(r,o){!this.#c(r)||!NDe.has(o?.status)||(o.status===ii.SLOW_DOWN&&Number.isFinite(Number(o.interval))&&(r.pollIntervalSeconds=Number(o.interval)),this.#i(r,o.status))}async#p(r,o){if(!this.#c(r))return;let i=o?.client_id,e=o?.client_secret;if(typeof i!="string"||!i||typeof e!="string"||!e){this.#d(r,ii.ERROR,{error:{code:"invalid_credentials",message:"Feishu registration returned invalid credentials."}});return}let a;try{a=RDe(o.user_info)}catch{this.#d(r,ii.ERROR,{error:{code:"invalid_credentials",message:"Feishu registration returned invalid credentials."}});return}this.#B(r),r.qrCodeUrl=null,r.expiresAt=null,r.pollIntervalSeconds=null,this.#i(r,ii.SAVING);try{await this.#A({client_id:i,client_secret:e,user_info:a})}catch{this.#c(r)&&this.#d(r,ii.ERROR,{error:{code:"credentials_callback_failed",message:"Unable to store the Feishu credentials."}});return}this.#c(r)&&this.#d(r,ii.SUCCEEDED)}#h(r,o){if(!this.#c(r))return;let i=jq(o);if(i==="expired_token"){this.#d(r,ii.EXPIRED,{error:pR(o)});return}if(i==="abort"){this.#d(r,ii.CANCELLED,{error:pR(o)});return}this.#d(r,ii.ERROR,{error:pR(o)})}#C(){let r=this.#l;r&&r.expiresAt!==null&&this.#t()>=r.expiresAt&&this.#E(r)}#E(r){this.#c(r)&&(this.#d(r,ii.EXPIRED,{error:{code:"expired_token",message:"The registration QR code expired."}}),r.controller.abort())}#d(r,o,i={}){this.#c(r)&&(this.#B(r),this.#s=this.#a(r,o,i),this.#l=null)}#B(r){r.expiryTimer!==null&&(this.#n(r.expiryTimer),r.expiryTimer=null)}#u(){let r=this.#l;r&&(this.#B(r),this.#l=null,r.controller.abort())}};var kDe="card.action.trigger",_h="callback_repair";function vDe(n){return n==="lark"?"accounts.larksuite.com":"accounts.feishu.cn"}function PDe(n){return n==="lark"?"open.larksuite.com":"open.feishu.cn"}function ER(n,r,o="feishu",i="Feishu app update"){let e;try{e=new URL(n)}catch{throw new Error(`${i} returned an invalid verification URL`)}let a=o==="feishu"||o==="lark",A=e.searchParams.getAll("clientID"),t=e.searchParams.getAll("tp"),s=e.searchParams.getAll("addons"),g=String(r).includes("{{")||String(r).includes("}}")||[...e.searchParams.values()].some(c=>c.includes("{{")||c.includes("}}"));if(!a||e.protocol!=="https:"||e.hostname!==PDe(o)||e.port!==""||e.username!==""||e.password!==""||t.length!==1||t[0]!=="sdk"||A.length!==1||A[0]!==r||e.searchParams.has("createOnly")||s.length!==1||!s[0]?.trim()||g)throw new Error(`${i} returned an unsafe verification URL`);return e.toString()}function GDe(n,r,o="feishu"){return ER(n,r,o,"Feishu callback repair")}var YQ=class{#e;#A;#t;constructor({registerApp:r,onCredentials:o,appId:i,domain:e="feishu"}={}){if(typeof r!="function")throw new TypeError("registerApp is required");if(typeof o!="function")throw new TypeError("onCredentials is required");if(typeof i!="string"||!i.trim())throw new TypeError("appId is required");if(e!=="feishu"&&e!=="lark")throw new TypeError("domain is invalid");this.#A=i.trim(),this.#t=e,this.#e=new Es({registerApp:a=>r({...a,onQRCodeReady:A=>{GDe(A?.url,this.#A,this.#t),a.onQRCodeReady(A)}}),onCredentials:o})}start(){return this.#e.start({source:"deepseek-harness-card-action-repair",domain:vDe(this.#t),appId:this.#A,addons:{preset:!1,callbacks:{items:[kDe]}}})}status(){return this.#e.status()}cancel(){return this.#e.cancel()}};var FDe="im:message.group_msg",jQ="group_message_permission";function LDe(n){return n==="lark"?"accounts.larksuite.com":"accounts.feishu.cn"}function UDe(n,r,o="feishu"){return ER(n,r,o,"Feishu group message permission update")}var xQ=class{#e;#A;#t;constructor({registerApp:r,onCredentials:o,appId:i,domain:e="feishu"}={}){if(typeof r!="function")throw new TypeError("registerApp is required");if(typeof o!="function")throw new TypeError("onCredentials is required");if(typeof i!="string"||!i.trim())throw new TypeError("appId is required");if(e!=="feishu"&&e!=="lark")throw new TypeError("domain is invalid");this.#A=i.trim(),this.#t=e,this.#e=new Es({registerApp:a=>r({...a,onQRCodeReady:A=>{UDe(A?.url,this.#A,this.#t),a.onQRCodeReady(A)}}),onCredentials:o})}start(){return this.#e.start({source:"deepseek-harness-group-message-permission",domain:LDe(this.#t),appId:this.#A,addons:{preset:!1,scopes:{tenant:[FDe]}}})}status(){return this.#e.status()}cancel(){return this.#e.cancel()}};var Jq=Object.freeze(["im:message.p2p_msg:readonly","im:message.group_at_msg:readonly","im:message:readonly","im:message:send_as_bot","im:message.reactions:write_only","im:message:recall","cardkit:card:write"]);var hR=new Set(["starting","qr_ready","polling","slow_down","domain_switched"]),JQ=new Set([...hR,"saving"]),qq=new Set([_h,jQ]),CR="*",HDe=12e4,KDe=6e5;function Wq(){return{ready:!1,feishuLongConnectionState:"idle",harnessReachable:!1}}function qQ(n){return n?n.status:Wq()}function VQ(n){return n.ready===!0&&n.feishuLongConnectionState==="connected"&&n.harnessReachable===!0}function Zq(n){return n.length>12?`${n.slice(0,8)}\u2022\u2022\u2022\u2022${n.slice(-4)}`:"cli_\u2022\u2022\u2022\u2022"}function YDe(n){return{name:n.botName,appIdMasked:Zq(n.appId),activated:n.activated,domain:n.domain}}function xDe({connected:n,error:r,connection:o}){return n?"connected":r||o.feishuLongConnectionState==="failed"?"error":"disconnected"}function jDe(){return`bot_${zq().replaceAll("-","")}`}function JDe(){return`reg_${zq().replaceAll("-","")}`}function Vq(n){return`DSH_FEISHU_APP_SECRET_${n.slice(4).toUpperCase()}`}function zQ(n){return JSON.stringify({id:n.id,appId:n.appId,secretRef:n.secretRef,ownerOpenIds:n.ownerOpenIds,domain:n.domain,botName:n.botName,botOpenId:n.botOpenId,activated:n.activated,groupResponseMode:Mi(n.groupResponseMode),groupMessagePermissionGranted:n.groupMessagePermissionGranted===!0,deletionPending:n.deletionPending===!0,connectedAt:n.connectedAt??null,createdAt:n.createdAt??null})}function WQ(n){return typeof n=="string"&&n.trim()?n.trim():null}var Nh=class{#e;#A;#t;#r;#n;#o;#l;#s;#c=new Map;#a=new Map;#i=new Map;#I=new Map;#g=new Map;#p=null;#h=Promise.resolve();#C=new Map;#E=1;#d;#B=!1;constructor({registerApp:r,verifyApp:o,credentials:i,configStore:e,createRuntime:a,deleteState:A=async()=>{},createBotId:t=jDe,createRegistrationId:s=JDe,callbackProbeTimeoutMs:g=HDe}){if(typeof r!="function")throw new Error("registerApp is required");if(typeof o!="function")throw new Error("verifyApp is required");if(!i)throw new Error("credentials service is required");if(!e||typeof e.list!="function")throw new Error("multi-bot config store is required");if(typeof a!="function")throw new Error("createRuntime is required");if(typeof A!="function")throw new Error("deleteState must be a function");if(!Number.isFinite(g)||g<=0||g>KDe)throw new TypeError("callbackProbeTimeoutMs must be between 1 and 600000ms");this.#e=r,this.#A=o,this.#t=i,this.#r=e,this.#n=a,this.#o=A,this.#l=t,this.#s=s,this.#d=g}async initialize(){if(this.#B)return this.status();let r=this.#r.list(),o=!1;return await Promise.allSettled(r.map(i=>this.#N(i.id,async()=>{let e=qQ(this.#c.get(i.id));if(VQ(e)||e.feishuLongConnectionState==="connecting"||e.feishuLongConnectionState==="reconnecting")return;if(o=!0,i.deletionPending){this.#a.set(i.id,{code:"deletion_pending",message:"\u673A\u5668\u4EBA\u6B63\u5728\u7B49\u5F85\u5B8C\u6210\u672C\u5730\u5220\u9664\uFF0C\u8BF7\u91CD\u8BD5\u79FB\u9664\u3002"});return}let a;try{a=await this.#t.resolve(i.secretRef)}catch{this.#a.set(i.id,{code:"missing_credentials",message:"\u65E0\u6CD5\u8BFB\u53D6\u673A\u5668\u4EBA\u51ED\u636E\uFF0C\u8BF7\u68C0\u67E5\u51ED\u636E\u5B58\u50A8\u3002"});return}if(!a?.value){this.#a.set(i.id,{code:"missing_credentials",message:"\u673A\u5668\u4EBA\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u5220\u9664\u540E\u91CD\u65B0\u626B\u7801\u63A5\u5165\u3002"});return}try{await this.#w(i,a.value),this.#a.delete(i.id)}catch{this.#a.set(i.id,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u98DE\u4E66\uFF0C\u8BF7\u91CD\u8BD5\u3002"})}}))),o&&this.#R(),this.status()}startRegistration(){this.#_();let r=this.#s();if(typeof r!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(r)||this.#i.has(r))throw new Error("Registration id generator returned an invalid or duplicate id");let o={id:r,manager:null,botId:null,createdNew:!1,cancelled:!1};return o.manager=new Es({registerApp:this.#e,onCredentials:i=>this.#P(()=>this.#D(o,i))}),this.#i.set(r,o),this.#p=r,this.#H(),o.manager.start({source:"deepseek-harness",createOnly:!0,appPreset:{name:"{user} \u7684\u5317\u6C47\u661F\u6CB3 AI \u52A9\u624B",desc:"\u8FDE\u63A5\u98DE\u4E66\u4E0E DeepSeek Harness\uFF0C\u5728\u804A\u5929\u4E2D\u4F7F\u7528\u4F01\u4E1A AI \u52A9\u624B\u3002"},addons:{preset:!1,scopes:{tenant:[...Jq]},events:{items:{tenant:["im.message.receive_v1"]}},callbacks:{items:["card.action.trigger"]}}}),this.#R(),this.registrationStatus(r)}startCallbackRepair(r,{actorOpenId:o,chatId:i}={}){this.#_();let e=this.#b(r);if(e.deletionPending)throw new Error("Cannot repair a Feishu bot pending deletion");let a=this.#I.get(r),A=a?this.#i.get(a):null;if(A&&JQ.has(A.manager.status().state)){if(A.operation!==_h)throw new Error("Another Feishu app update is already active for this bot");return this.registrationStatus(A.id)}this.#I.delete(r);let t=this.#s();if(typeof t!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(t)||this.#i.has(t))throw new Error("Registration id generator returned an invalid or duplicate id");let s={id:t,operation:_h,manager:null,botId:r,createdNew:!1,cancelled:!1,remoteCommitted:!1,processing:null,publicError:null,stage:"authorizing",target:structuredClone(e),targetFingerprint:zQ(e),initiator:{actorOpenId:WQ(o),chatId:WQ(i)}};return s.manager=new YQ({registerApp:this.#e,appId:e.appId,domain:e.domain,onCredentials:g=>{s.remoteCommitted=!0;let I=this.#f(s,g).finally(()=>{s.processing===I&&(s.processing=null)});return s.processing=I,I}}),this.#i.set(t,s),this.#I.set(r,t),this.#p=t,this.#H(),s.manager.start(),this.#R(),this.registrationStatus(t)}startGroupMessagePermission(r){this.#_();let o=this.#b(r);if(o.deletionPending)throw new Error("Cannot update permissions for a Feishu bot pending deletion");let i=this.#I.get(r),e=i?this.#i.get(i):null;if(e&&JQ.has(e.manager.status().state)){if(e.operation!==jQ)throw new Error("Another Feishu app update is already active for this bot");return this.registrationStatus(e.id)}this.#I.delete(r);let a=this.#s();if(typeof a!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(a)||this.#i.has(a))throw new Error("Registration id generator returned an invalid or duplicate id");let A={id:a,operation:jQ,manager:null,botId:r,createdNew:!1,cancelled:!1,remoteCommitted:!1,processing:null,publicError:null,stage:"authorizing",target:structuredClone(o),targetFingerprint:zQ(o),initiator:{actorOpenId:null,chatId:null}};return A.manager=new xQ({registerApp:this.#e,appId:o.appId,domain:o.domain,onCredentials:t=>{A.remoteCommitted=!0;let g=this.#S(A,t).finally(()=>{A.processing===g&&(A.processing=null)});return A.processing=g,g}}),this.#i.set(a,A),this.#I.set(r,a),this.#p=a,this.#H(),A.manager.start(),this.#R(),this.registrationStatus(a)}hasRegistration(r){return this.#i.has(r)}registrationStatus(r){let o=this.#i.get(r);return o?this.#u({registration:o,selectedBotId:o.botId}):null}async cancelRegistration(r=this.#p){let o=this.#i.get(r);if(!o)return this.status();let i=o.manager.status().state;return qq.has(o.operation)&&i==="saving"?this.registrationStatus(r):JQ.has(i)?(o.cancelled=!0,o.manager.cancel(),await this.#P(async()=>{o.createdNew&&o.botId&&this.#g.get(o.botId)===o.id&&this.#r.getBot(o.botId)&&await this.#N(o.botId,()=>this.#T(o.botId))}),this.#R(),this.registrationStatus(r)??this.status()):this.registrationStatus(r)}status(r){return this.#u({registration:this.#i.get(this.#p)??null,selectedBotId:r})}async bindCredentials({appId:r,appSecret:o,domain:i="feishu"}={}){this.#_();let e=typeof r=="string"?r.trim():"",a=typeof o=="string"?o.trim():"",A=i==="lark"?"lark":"feishu";if(!e||!a)throw new TypeError("Feishu App ID and App Secret are required");return this.#P(async()=>{this.#_();let t=await this.#A({appId:e,appSecret:a,domain:A});this.#_();let s=this.#r.list().find(f=>f.appId===e),g=s?.id??this.#l();if(typeof g!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(g)||!s&&this.#r.getBot(g))throw new Error("Bot id generator returned an invalid or duplicate id");let c=s?.secretRef??Vq(g),I=await this.#t.resolve(c).catch(()=>{}),E={...s,id:g,appId:e,secretRef:c,ownerOpenIds:s?.ownerOpenIds?.length?s.ownerOpenIds:[CR],domain:A,botName:t.name,botOpenId:t.openId,activated:t.activated,deletionPending:!1,connectedAt:new Date().toISOString(),createdAt:s?.createdAt??new Date().toISOString()};await this.#t.set(c,a);let B;try{B=await this.#r.saveBot(E)}catch(f){throw await this.#O(c,I),f}return await this.#N(g,async()=>{try{await this.#w(B,a),this.#a.delete(g)}catch{this.#a.set(g,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u5DF2\u7ECF\u7ED1\u5B9A\uFF0C\u4F46\u957F\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u8BF7\u70B9\u51FB\u91CD\u8BD5\u3002"})}}),this.#R(),this.status(g)})}async reconnectBot(r){return this.#_(),this.#N(r,async()=>{let o=this.#b(r);if(o.deletionPending)return this.#a.set(r,{code:"deletion_pending",message:"\u673A\u5668\u4EBA\u6B63\u5728\u7B49\u5F85\u5B8C\u6210\u672C\u5730\u5220\u9664\uFF0C\u8BF7\u91CD\u8BD5\u79FB\u9664\u3002"}),this.status(r);if(VQ(qQ(this.#c.get(r))))return this.status(r);let i;try{i=await this.#t.resolve(o.secretRef)}catch{i=null}if(!i?.value)return this.#a.set(r,{code:"missing_credentials",message:"\u673A\u5668\u4EBA\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u5220\u9664\u540E\u91CD\u65B0\u626B\u7801\u63A5\u5165\u3002"}),this.#R(),this.status(r);try{await this.#w(o,i.value),this.#a.delete(r)}catch{this.#a.set(r,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u98DE\u4E66\uFF0C\u8BF7\u91CD\u8BD5\u3002"})}return this.#R(),this.status(r)})}async sendConnectionTest(r){return this.#_(),this.#N(r,async()=>{let o=this.#b(r),i=this.#c.get(r);if(!VQ(qQ(i))||typeof i.sendConnectionTest!="function"){let e=new Error("\u98DE\u4E66\u673A\u5668\u4EBA\u5C1A\u672A\u8FDE\u63A5");throw e.code="test-target-unavailable",e}return i.sendConnectionTest(ca(`${o.botName}\uFF08${Zq(o.appId)}\uFF09`,"\u98DE\u4E66\u673A\u5668\u4EBA"))})}async disconnectBot(r){return this.#_(),this.#N(r,async()=>(this.#b(r),await this.#M(r),this.#a.delete(r),this.#R(),this.status(r)))}async updateGroupResponseMode(r,o){if(this.#_(),!NQ(o))throw new TypeError("Invalid Feishu group response mode");return this.#P(()=>this.#N(r,async()=>{let i=this.#b(r);if(o==="all"&&i.groupMessagePermissionGranted!==!0){let a=new Error("Authorize im:message.group_msg before enabling all group messages");throw a.code="group_message_permission_required",a}let e=await this.#r.saveBot({...i,groupResponseMode:o});return this.#c.get(r)?.setGroupResponseMode?.(e.groupResponseMode),this.#R(),this.status(r)}))}async deleteBot(r){return this.#_(),this.#P(()=>this.#N(r,async()=>(this.#b(r),await this.#T(r),this.#R(),this.status())))}async reconnect(){let r=this.#r.list()[0];return r?this.reconnectBot(r.id):this.status()}async disconnect(){let r=this.#r.list()[0];return r?this.deleteBot(r.id):this.status()}async close(){if(this.#B)return;this.#B=!0;let r=[];for(let o of this.#i.values()){let i=o.manager.status().state;qq.has(o.operation)&&i==="saving"?(o.manager.cancel(),o.processing&&r.push(o.processing)):JQ.has(i)&&(o.cancelled=!0,o.manager.cancel())}await this.#h,await Promise.allSettled([...this.#C.values()]),await Promise.allSettled([...this.#c.keys()].map(o=>this.#M(o))),await Promise.allSettled(r),await this.#h,await Promise.allSettled([...this.#C.values()]),await Promise.allSettled([...this.#c.keys()].map(o=>this.#M(o)))}#u({registration:r,selectedBotId:o}={}){let i=this.#r.list().map(I=>{let E=qQ(this.#c.get(I.id)),B=VQ(E),f=this.#a.get(I.id)??null;return{botId:I.id,phase:xDe({connected:B,error:f,connection:E}),connected:B,configured:!0,groupResponseMode:Mi(I.groupResponseMode),groupMessagePermissionGranted:I.groupMessagePermissionGranted===!0,bot:YDe(I),connection:E,error:f}}),e=r?this.#y(r):{state:"idle",attempt:0,updatedAt:Date.now()},a=hR.has(e.state),A=e.state==="saving",t=!!r&&(a||A),s=i.find(I=>I.botId===o)??(t?null:i[0]??null),g=i.some(I=>I.connected),c=s?.phase??"unconfigured";return a?c="registering":A?c="connecting":e.state==="error"&&!s&&(c="error"),{schemaVersion:2,revision:this.#E,phase:c,connected:s?.connected??!1,configured:i.length>0,bot:s?.bot??null,connection:s?.connection??Wq(),error:s?.error??e.error??null,registration:e,bots:i,totals:{configured:i.length,connected:i.filter(I=>I.connected).length},anyConnected:g}}#y(r){let o=r.manager.status();return{...o,attempt:r.id,...r.botId?{botId:r.botId}:{},...r.operation?{operation:r.operation}:{},...r.stage?{stage:r.stage}:{},...o.state==="error"&&r.publicError?{error:{...r.publicError}}:{}}}async#S(r,o){let i=o.client_id,e=o.client_secret,a=WQ(o.user_info?.open_id),A=o.user_info?.tenant_brand,t=r.target;if(r.cancelled)throw this.#m(r,"abort","Group message permission update was cancelled before local activation.");if(i!==t.appId)throw this.#m(r,"repair_app_mismatch","Feishu returned credentials for a different app.");if(!a)throw this.#m(r,"repair_owner_missing","Feishu returned no permission operator identity.");if(A!==void 0&&A!==t.domain)throw this.#m(r,"repair_domain_mismatch","Feishu returned credentials for a different account domain.");if(!t.ownerOpenIds.includes(CR)&&!t.ownerOpenIds.includes(a))throw this.#m(r,"repair_owner_mismatch","The Feishu permission operator is not an owner of this configured bot.");r.stage="verifying_identity";let s;try{s=await this.#A({appId:i,appSecret:e,domain:t.domain})}catch(g){throw this.#m(r,"repair_credentials_invalid","Feishu could not verify the updated app credentials.",g)}if(t.botOpenId&&s?.openId!==t.botOpenId)throw this.#m(r,"repair_bot_mismatch","The updated Feishu app belongs to a different bot identity.");await this.#P(()=>this.#N(r.botId,async()=>{let g=this.#r.getBot(r.botId);if(!g||g.deletionPending||zQ(g)!==r.targetFingerprint)throw this.#m(r,"repair_target_changed","The Feishu bot changed while its permission update was in progress.");let c;try{c=await this.#t.resolve(g.secretRef)}catch(E){throw this.#m(r,"credential_update_failed","Unable to read the current Feishu credential.",E)}if(c?.value!==e){r.stage="persisting_secret";try{await this.#t.set(g.secretRef,e)}catch(B){if((await this.#t.resolve(g.secretRef).catch(()=>null))?.value!==e)throw this.#m(r,"credential_update_failed","Unable to store the updated Feishu credential.",B)}if((await this.#t.resolve(g.secretRef).catch(()=>null))?.value!==e)throw this.#m(r,"credential_state_unknown","The updated Feishu credential could not be confirmed after writing.")}r.stage="enabling_all_messages";let I;try{I=await this.#r.saveBot({...g,groupMessagePermissionGranted:!0,groupResponseMode:"all"})}catch(E){throw this.#m(r,"group_message_permission_save_failed","The permission was accepted, but all-message mode could not be saved.",E)}r.stage="restarting";try{await this.#w(I,e)}catch(E){throw this.#a.set(r.botId,{code:"connection_failed",message:"\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u4F46\u673A\u5668\u4EBA\u957F\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u8BF7\u70B9\u51FB\u91CD\u8BD5\u3002"}),this.#R(),this.#m(r,"group_message_permission_connection_failed","The permission was accepted, but the Feishu runtime could not restart.",E)}this.#a.delete(r.botId),r.stage="verified",r.publicError=null,this.#R()}))}async#f(r,o){let i=o.client_id,e=o.client_secret,a=WQ(o.user_info?.open_id),A=o.user_info?.tenant_brand,t=r.target;if(r.cancelled)throw this.#m(r,"abort","Callback repair was cancelled before local activation.");if(i!==t.appId)throw this.#m(r,"repair_app_mismatch","Feishu returned credentials for a different app.");if(!a)throw this.#m(r,"repair_owner_missing","Feishu returned no repair operator identity.");if(A!==void 0&&A!==t.domain)throw this.#m(r,"repair_domain_mismatch","Feishu returned credentials for a different account domain.");if(r.initiator.actorOpenId&&r.initiator.actorOpenId!==a)throw this.#m(r,"repair_owner_mismatch","The Feishu repair was confirmed by a different operator.");if(!t.ownerOpenIds.includes(CR)&&!t.ownerOpenIds.includes(a))throw this.#m(r,"repair_owner_mismatch","The Feishu repair operator is not an owner of this configured bot.");r.stage="verifying_identity";let s;try{s=await this.#A({appId:i,appSecret:e,domain:t.domain})}catch(c){throw this.#m(r,"repair_credentials_invalid","Feishu could not verify the repaired app credentials.",c)}if(t.botOpenId&&s?.openId!==t.botOpenId)throw this.#m(r,"repair_bot_mismatch","The repaired Feishu app belongs to a different bot identity.");let g=await this.#P(()=>this.#N(r.botId,async()=>{let c=this.#r.getBot(r.botId);if(!c||c.deletionPending||zQ(c)!==r.targetFingerprint)throw this.#m(r,"repair_target_changed","The Feishu bot changed while its callback repair was in progress.");let I;try{I=await this.#t.resolve(c.secretRef)}catch(f){throw this.#m(r,"credential_update_failed","Unable to read the current Feishu credential.",f)}if(I?.value!==e){r.stage="persisting_secret";try{await this.#t.set(c.secretRef,e)}catch(Q){if((await this.#t.resolve(c.secretRef).catch(()=>null))?.value!==e)throw this.#m(r,"credential_update_failed","Unable to store the repaired Feishu credential.",Q)}if((await this.#t.resolve(c.secretRef).catch(()=>null))?.value!==e)throw this.#m(r,"credential_state_unknown","The repaired Feishu credential could not be confirmed after writing.")}let B;r.stage="restarting";try{await this.#w(c,e),B=this.#c.get(r.botId)}catch(f){throw this.#a.set(r.botId,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u56DE\u8C03\u4FEE\u590D\u5DF2\u4FDD\u5B58\uFF0C\u4F46\u957F\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u8BF7\u70B9\u51FB\u91CD\u8BD5\u3002"}),this.#R(),this.#m(r,"repair_connection_failed","The repaired Feishu runtime could not be started.",f)}if(!B)throw this.#m(r,"repair_connection_failed","The repaired Feishu runtime is unavailable.");return this.#a.delete(r.botId),this.#R(),B}));if(typeof g.beginCardActionProbe!="function")throw this.#m(r,"card_action_probe_unavailable","The Feishu runtime cannot verify card callbacks.");r.stage="awaiting_callback";try{if((await g.beginCardActionProbe({expectedOperatorOpenId:a,timeoutMs:this.#d,...r.initiator.chatId?{chatId:r.initiator.chatId}:{}}))?.verified!==!0){let I=new Error("Feishu runtime returned no callback proof");throw I.code="card_action_probe_failed",I}}catch(c){let I=c?.code==="card_action_probe_timeout"?"card_action_probe_timeout":c?.code==="card_action_probe_unavailable"?"card_action_probe_unavailable":c?.code==="card_action_probe_send_failed"?"card_action_probe_send_failed":"card_action_probe_failed";throw this.#m(r,I,I==="card_action_probe_timeout"?"Timed out waiting for the Feishu callback verification button.":"The Feishu card callback probe failed.",c)}r.stage="verified",r.publicError=null,this.#R()}#m(r,o,i,e){r.publicError={code:o,message:i};let a=new Error(i,e?{cause:e}:void 0);return a.code=o,a}async#D(r,o){if(r.cancelled)throw new Error("Registration was cancelled");let i=o.client_id,e=o.client_secret,a=o.user_info?.open_id,A=o.user_info?.tenant_brand==="lark"?"lark":"feishu";if(!a)throw new Error("Feishu registration returned no owner open_id");let t=await this.#A({appId:i,appSecret:e,domain:A});if(r.cancelled)throw new Error("Registration was cancelled");let s=this.#r.list().find(Q=>Q.appId===i),g=s?.id??this.#l();if(typeof g!="string"||!/^[A-Za-z0-9_-]{1,128}$/.test(g)||!s&&this.#r.getBot(g))throw new Error("Bot id generator returned an invalid or duplicate id");let c=s?.secretRef??Vq(g),I=this.#g.get(g),E=await this.#t.resolve(c).catch(()=>{});await this.#t.set(c,e);let B;try{B=await this.#r.saveBot({...s,id:g,appId:i,secretRef:c,ownerOpenIds:[...new Set([...s?.ownerOpenIds??[],a])],domain:A,botName:t.name,botOpenId:t.openId,activated:t.activated,deletionPending:!1,connectedAt:new Date().toISOString(),createdAt:s?.createdAt??new Date().toISOString()}),r.botId=g,r.createdNew=!s,this.#g.set(g,r.id)}catch(Q){try{await this.#O(c,E)}catch(y){throw new Error("Unable to restore the Feishu credential after a config failure.",{cause:y})}throw Q}if(r.cancelled)throw r.createdNew?await this.#N(g,()=>this.#T(g)):(await this.#r.saveBot(s),await this.#O(c,E),I?this.#g.set(g,I):this.#g.delete(g)),new Error("Registration was cancelled");let f=!1;try{if(await this.#N(g,()=>this.#w(B,e)),r.cancelled)throw r.createdNew?await this.#N(g,()=>this.#T(g)):(await this.#r.saveBot(s),await this.#O(c,E),I?this.#g.set(g,I):this.#g.delete(g),E?.value&&!s.deletionPending?await this.#N(g,()=>this.#w(s,E.value)):await this.#N(g,()=>this.#M(g))),f=!0,new Error("Registration was cancelled");this.#a.delete(g),this.#R()}catch(Q){if(r.cancelled)throw!f&&r.createdNew&&this.#r.getBot(g)?await this.#N(g,()=>this.#T(g)):!f&&s&&(await this.#r.saveBot(s),await this.#O(c,E),I?this.#g.set(g,I):this.#g.delete(g),!this.#B&&E?.value&&!s.deletionPending?await this.#N(g,()=>this.#w(s,E.value)):await this.#N(g,()=>this.#M(g))),this.#R(),Q;if(s&&E?.value)try{throw await this.#r.saveBot(s),await this.#O(c,E),I?this.#g.set(g,I):this.#g.delete(g),s.deletionPending?(await this.#N(g,()=>this.#M(g)),this.#a.set(g,{code:"deletion_pending",message:"\u673A\u5668\u4EBA\u6B63\u5728\u7B49\u5F85\u5B8C\u6210\u672C\u5730\u5220\u9664\uFF0C\u8BF7\u91CD\u8BD5\u79FB\u9664\u3002"})):(await this.#N(g,()=>this.#w(s,E.value)),this.#a.delete(g)),this.#R(),Q}catch(y){throw y===Q?Q:(this.#a.set(g,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u8FDE\u63A5\u66F4\u65B0\u5931\u8D25\uFF0C\u4E14\u539F\u8FDE\u63A5\u65E0\u6CD5\u6062\u590D\uFF0C\u8BF7\u91CD\u8BD5\u3002"}),this.#R(),new Error("Unable to restore the previous Feishu bot connection.",{cause:y}))}throw this.#a.set(g,{code:"connection_failed",message:"\u673A\u5668\u4EBA\u5DF2\u7ECF\u521B\u5EFA\uFF0C\u4F46\u957F\u8FDE\u63A5\u672A\u5C31\u7EEA\uFF0C\u8BF7\u70B9\u51FB\u91CD\u8BD5\u3002"}),this.#R(),Q}}async#w(r,o){await this.#M(r.id);let i=await this.#n({botId:r.id,config:r,appSecret:o,repair:this.#k(r.id)});this.#c.set(r.id,i);try{await i.start()}catch(e){throw this.#c.get(r.id)===i&&this.#c.delete(r.id),await i.stop({preserveError:!0}).catch(()=>{}),e}}#k(r){let o=i=>{let e=this.#i.get(i);return e?.operation===_h&&e.botId===r?e:null};return Object.freeze({start:({actorOpenId:i,chatId:e}={})=>this.startCallbackRepair(r,{actorOpenId:i,chatId:e}),status:({attemptId:i}={})=>o(i)?this.registrationStatus(i):null,cancel:async({attemptId:i}={})=>o(i)?this.cancelRegistration(i):this.status(r)})}async#M(r){let o=this.#c.get(r);this.#c.delete(r),o&&await o.stop()}async#T(r){let o=this.#r.getBot(r);if(o){o.deletionPending||(o=await this.#r.saveBot({...o,deletionPending:!0})),await this.#M(r);try{await this.#t.unset(o.secretRef)}catch(i){throw this.#a.set(r,{code:"credential_removal_failed",message:"\u65E0\u6CD5\u5220\u9664\u673A\u5668\u4EBA\u51ED\u636E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}),new Error("Unable to remove the Feishu credential.",{cause:i})}try{await this.#o({botId:r,config:o})}catch(i){throw this.#a.set(r,{code:"state_cleanup_failed",message:"\u65E0\u6CD5\u5220\u9664\u673A\u5668\u4EBA\u7684\u672C\u5730\u4F1A\u8BDD\u6570\u636E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"}),new Error("Unable to remove the Feishu bot session state.",{cause:i})}await this.#r.removeBot(r),this.#a.delete(r),this.#g.delete(r)}}async#O(r,o){o?.value?await this.#t.set(r,o.value):await this.#t.unset(r)}#b(r){let o=this.#r.getBot(r);if(!o)throw new Error("Unknown Feishu bot");return o}#_(){if(this.#B)throw new Error("The Feishu controller is closed")}#P(r){let o=this.#h.then(r,r);return this.#h=o.then(()=>{},()=>{}),o}#N(r,o){let e=(this.#C.get(r)??Promise.resolve()).then(o,o),a=e.then(()=>{},()=>{});return this.#C.set(r,a),a.finally(()=>{this.#C.get(r)===a&&this.#C.delete(r)}),e}#H(){if(!(this.#i.size<=32))for(let[r,o]of this.#i){if(r===this.#p)continue;let i=o.manager.status().state;if(!hR.has(i)&&i!=="saving"&&this.#i.delete(r),this.#i.size<=32)break}}#R(){this.#E+=1}};function zDe(n){for(let r of["https_proxy","HTTPS_PROXY","http_proxy","HTTP_PROXY"]){let o=n?.[r];if(typeof o=="string"&&o.trim())return o.trim()}}function WDe(n,r=o=>new Xq.default(o)){let o=zDe(n);return o?r(o):void 0}function ZDe(n,r){if(r!==void 0)return new URL(r);let o=n?.port;if(!Number.isInteger(o)||o<1||o>65535)throw new Error("dsh-feishu requires an initialized DSH webServer port");return new URL(`http://127.0.0.1:${o}`)}function XDe(n){let r=Eg(n.dshHome??process.env.DSH_HOME??tp(qDe(),".dsh")),o=Eg(n.dataDir??tp(r,"integrations","dsh-feishu"));return{root:o,config:Eg(n.configPath??tp(o,"config.json")),legacyState:Eg(n.statePath??tp(o,"state.json")),bots:Eg(n.botsDir??tp(o,"bots")),workspaces:Eg(n.workspacesPath??tp(o,"workspaces.json"))}}async function dR(n,r={},o={}){if(!n?.credentials)throw new TypeError("dsh-feishu requires ctx.credentials");if(!n?.webServer)throw new TypeError("dsh-feishu requires ctx.webServer");let i=o.lark??AR,e=o.Controller??Nh,a=o.ConfigStore??HQ,A=o.StateStore??MQ,t=o.HarnessClient??LQ,s=o.FeishuRuntime??FQ,g=o.verifyFeishuApp??dq,c=Ee=>g({...Ee,httpInstance:i.defaultHttpInstance}),I=o.createConnectionSupervisor??tR,E=typeof n.logger=="function"?n.logger("dsh-feishu"):n.logger??console,B=()=>Ea(n),f=XDe(r),Q=await new a(f.config).load(),y=Eg(r.workspace??process.cwd()),m=o.WorkspaceStore??Lr,T=o.workspaces??await new m(f.workspaces,{defaultWorkspace:y}).load(),_=typeof Q.list=="function",P=()=>_?Q.list():[],Y=P();_&&await T.reconcile(Y.map(Ee=>Ee.id)),await Promise.all(Y.map(Ee=>T.ensure(Ee.id,{defaultAgentPreset:r.agentPreset})));let j=typeof Q.removeBot=="function"?Ca(Q,{workspaces:T,method:"removeBot",botIdFromRemoved:Ee=>Ee.id}):Q,K=new Map,q=Ee=>!Ee.id||!Ee.secretRef||Ee.secretRef===KQ?f.legacyState:Eg(f.bots,Ee.id,"state.json"),V=async Ee=>{let me=Ee.id??"__legacy__",_e=K.get(me);return _e||(_e=await new A(q(Ee)).load(),K.set(me,_e)),_e},H=async Ee=>{let me=P().find(_e=>_e.id===Ee);if(!me)throw new Error("Unknown Feishu bot");return V(me)},v=ua(n,o.commandExecutor),{controlExecutor:Z,sessionMaintenanceExecutor:U}=Ba(n,{controlExecutor:o.controlExecutor,sessionMaintenanceExecutor:o.sessionMaintenanceExecutor}),M=new t({baseUrl:ZDe(n.webServer,r.harnessBaseUrl),workspace:y,autostart:!1,dshBin:r.dshBin??"dsh",...v?{commandExecutor:v}:{},...Z?{controlExecutor:Z}:{},...U?{sessionMaintenanceExecutor:U}:{}}),G=o.proxyEnv??process.env,te=WDe(G,o.createProxyAgent),Be=new e({registerApp:Ee=>i.registerApp(Ee),verifyApp:c,credentials:n.credentials,configStore:j,createRuntime:async({botId:Ee,config:me,appSecret:_e,repair:Ve})=>{let oA=await V(me),tA=Ee??me.id??me.appId;await T.ensure(tA,{defaultAgentPreset:r.agentPreset});let Pe=ha(M,{botId:tA,workspaces:T,state:oA,agentPresetCatalog:B});return new s({lark:i,botId:tA,repair:Ve,appId:me.appId,appSecret:_e,domain:me.domain,botOpenId:me.botOpenId,groupResponseMode:me.groupResponseMode,ownerOpenIds:me.ownerOpenIds??[me.ownerOpenId],harness:Pe.harness,state:Pe.state,replyTimeoutMs:r.replyTimeoutMs??6e5,...te?{wsAgent:te}:{},logger:{error:(...gA)=>E.error?.(`[${Ee??me.id}]`,...gA),warn:(...gA)=>E.warn?.(`[${Ee??me.id}]`,...gA),info:(...gA)=>E.info?.(`[${Ee??me.id}]`,...gA),debug:(...gA)=>E.debug?.(`[${Ee??me.id}]`,...gA)}})},deleteState:async({botId:Ee,config:me})=>{K.delete(Ee);try{await VDe(q(me))}catch(_e){if(_e?.code!=="ENOENT")throw _e}}}),Ce=da(Be,{workspaces:T,stateFor:H,agentPresetCatalog:B}),ke=I({controller:Ce,harness:M,logger:E,retryDelaysMs:r.retryDelaysMs,healthyIntervalMs:r.healthyIntervalMs}).start();return{controller:Ce,ready:ke.ready,async close(){await ke.close(),await Ce.close(),M.stopManagedProcess(),te?.destroy?.()}}}import dwe from"qrcode";var ap=Je(SR(),1);var Ewe=Je(SR(),1);var Cwe=Object.freeze({$locale:"en",IM\u673A\u5668\u4EBA:"IM bots",IM\u673A\u5668\u4EBA\u8BBE\u7F6E:"IM bot settings","IM \u6E20\u9053":"IM channels","\u8BA9 DeepSeek Harness \u89E6\u624B\u53EF\u53CA":"DeepSeek Harness, always within reach","AI Office":"AI Office","\uFF08\u5B9E\u9A8C\u529F\u80FD\uFF09":"(Experimental)","AI Office \u8BBE\u7F6E":"AI Office settings","AI Office \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5":"AI Office settings are missing an RPC connection","\u6B63\u5728\u8BFB\u53D6 AI Office Connector\u2026":"Loading AI Office Connector\u2026","\u672C\u673A\u4E3B\u52A8\u8FDE\u63A5\u516C\u7F51 Office\uFF1BHarness \u4E0D\u5F00\u653E\u7AEF\u53E3\u3002\u534F\u8BAE Hook \u56FA\u5B9A\u4E3A ":"This machine connects outward to the public Office; Harness exposes no port. Protocol hooks: ",\u5C1A\u672A\u914D\u7F6E:"Not configured","\u5DF2\u8FDE\u63A5 Office":"Connected to Office",\u5DF2\u914D\u7F6E:"Configured",\u7B49\u5F85\u91CD\u8FDE:"Waiting to reconnect",\u51ED\u636E\u7F3A\u5931:"Credential missing",\u6700\u8FD1\u5FC3\u8DF3:"Last heartbeat",\u6700\u8FD1\u4E8B\u4EF6:"Last event",\u91CD\u8FDE\u6B21\u6570:"Reconnects","\u8FD0\u884C Job":"Running Jobs","\u5B8C\u6210 Job":"Completed Jobs",\u5C1A\u65E0:"None yet",\u8BBE\u5907\u8FDE\u63A5:"Device connection","Token \u53EA\u5199\u5165\u672C\u673A\u51ED\u636E\u5B58\u50A8":"Token is written only to the local credential store","\u7C98\u8D34 Office \u4E00\u6B21\u6027\u51ED\u636E":"Paste the one-time Office credential","\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF1B\u7559\u7A7A\u4FDD\u6301\u4E0D\u53D8":"Stored securely; leave blank to keep it",\u6700\u5927\u5E76\u53D1:"Max concurrency","Heartbeat \u79D2\u6570":"Heartbeat seconds","Workspace \u6620\u5C04":"Workspace mappings","\u6BCF\u884C alias=/\u672C\u673A/\u7EDD\u5BF9\u8DEF\u5F84\uFF1BOffice \u53EA\u80FD\u770B\u5230 alias\u3002":"One alias=/local/absolute/path per line; Office sees only aliases.","Instruction Preset \u6620\u5C04":"Instruction preset mappings","\u6BCF\u884C alias=\u6307\u4EE4\uFF1B\u65B0\u589E preset \u4E0D\u9700\u8981\u6539 Office \u4EE3\u7801\u3002":"One alias=instruction per line; new presets require no Office code change.",\u4FDD\u5B58\u5E76\u8FDE\u63A5:"Save and connect",\u6D4B\u8BD5\u8FDE\u63A5:"Test connection","\u6D4B\u8BD5\u4E2D\u2026":"Testing\u2026",\u91CD\u65B0\u8FDE\u63A5:"Reconnect",\u79FB\u9664\u8FDE\u63A5:"Remove connection","\u8FDE\u63A5\u6D4B\u8BD5\u901A\u8FC7\u3002":"Connection test passed.","\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002":"Configuration saved.","\u534F\u8BAE Hook \u9884\u89C8":"Protocol hook preview","\u7531 Base URL \u81EA\u52A8\u6D3E\u751F\uFF0C\u4E0D\u5355\u72EC\u586B\u5199":"Derived from Base URL; no separate input","Base URL \u65E0\u6548":"Invalid Base URL","Office Hook \u5C1A\u672A\u90E8\u7F72\u65F6\uFF0C\u914D\u7F6E\u4F1A\u5B89\u5168\u4FDD\u5B58\u5E76\u81EA\u52A8\u91CD\u8BD5\uFF1B\u51FA\u73B0 HTTP 404 \u4EE3\u8868\u534F\u8BAE\u7AEF\u70B9\u5F85\u4E0A\u7EBF\uFF0C\u4E0D\u4EE3\u8868 Harness \u6545\u969C\u3002":"Configuration is saved and retried while Office hooks are unavailable; HTTP 404 means the protocol endpoint is pending, not a Harness failure.","Workspace \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value":"Each workspace mapping must use alias=value","Instruction Preset \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value":"Each instruction preset mapping must use alias=value","action-items=\u8F6C\u6362\u4E3A\u8D1F\u8D23\u4EBA\u3001\u622A\u6B62\u548C\u9A8C\u6536\u660E\u786E\u7684\u5DE5\u5355":"action-items=Turn this into accountable tasks with deadlines and acceptance criteria","AI Office \u62D2\u7EDD\u4E86 Device Token\u3002":"AI Office rejected the Device Token.","AI Office Connector Hook \u5C1A\u672A\u5C31\u7EEA\u3002":"AI Office Connector hooks are not available yet.","AI Office Connector \u534F\u8BAE\u7248\u672C\u4E0D\u517C\u5BB9\u3002":"The AI Office Connector protocol is incompatible.","\u672C\u673A\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE AI Office\u3002":"AI Office cannot currently be reached from this machine.","AI Office \u8FDE\u63A5\u5DF2\u4E2D\u65AD\u3002":"The AI Office connection was interrupted.","\u5E2E\u52A9\u4E0E\u53CD\u9988 \xB7 \u524D\u5F80 GitHub":"Help & feedback \xB7 Open GitHub",\u5FAE\u4FE1:"WeChat",\u98DE\u4E66:"Feishu",\u9489\u9489:"DingTalk",\u4F01\u4E1A\u5FAE\u4FE1:"WeCom",\u5FAE\u4FE1\u673A\u5668\u4EBA:"WeChat bot",\u98DE\u4E66\u673A\u5668\u4EBA:"Feishu bot",\u9489\u9489\u673A\u5668\u4EBA:"DingTalk bot",\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA:"WeCom bot",QQ\u673A\u5668\u4EBA:"QQ bot",WhatsApp\u673A\u5668\u4EBA:"WhatsApp bot",WhatsApp\u8D26\u53F7:"WhatsApp account",\u5FAE\u4FE1\u8BBE\u7F6E:"WeChat settings",\u98DE\u4E66\u673A\u5668\u4EBA\u8BBE\u7F6E:"Feishu bot settings",\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F:"Group response mode","\u4EC5\u5728 @\u673A\u5668\u4EBA\u65F6\u54CD\u5E94\uFF08\u63A8\u8350\uFF09":"Only respond when @mentioned (recommended)",\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F:"Respond to all group messages","\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\uFF08\u9700\u98DE\u4E66\u654F\u611F\u6743\u9650\uFF09":"Respond to all group messages (requires a sensitive Feishu scope)",\u91CD\u65B0\u6388\u6743:"Reauthorize",\u53BB\u6388\u6743:"Authorize",\u91CD\u65B0\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650:"Reauthorize group-message permission",\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650:"Authorize group-message permission","\u6B63\u5728\u51C6\u5907\u6388\u6743\u2026":"Preparing authorization\u2026","\u6B63\u5728\u51C6\u5907\u2026":"Preparing\u2026","\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u518D\u6B21\u5207\u6362\u65E0\u9700\u6388\u6743\u3002":"Direct messages always work; group chats require an explicit @mention of this bot. The group-message permission is already granted, so switching again needs no authorization.","\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u9009\u62E9\u5168\u90E8\u6D88\u606F\u540E\u4F1A\u6253\u5F00\u98DE\u4E66\u5B98\u65B9\u6388\u6743\u6D41\u7A0B\u3002":"Direct messages always work; group chats require an explicit @mention of this bot. Selecting all messages opens the official Feishu authorization flow.","\u5DF2\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002":"The \u201CRead all messages in associated group chat\u201D scope (im:message.group_msg) is granted; the bot processes every visible group message.","\u5C1A\u672A\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF0C\u8BF7\u5B8C\u6210\u98DE\u4E66\u6388\u6743\u3002":"The \u201CRead all messages in associated group chat\u201D scope has not been confirmed. Complete Feishu authorization.","\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002":"Direct messages always work; group chats require an explicit @mention of this bot.","\u9700\u5728\u98DE\u4E66\u4E3A\u8BE5\u673A\u5668\u4EBA\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u5F00\u901A\u540E\uFF0C\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002":"Grant this bot the \u201CRead all messages in associated group chat\u201D Feishu scope (im:message.group_msg); once granted, it will process every visible group message.","\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002":"Could not update the group response mode. Try again.","\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002":"Could not authorize group-message permission. Try again.",\u9489\u9489\u8BBE\u7F6E:"DingTalk settings",\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E:"WeCom settings",\u626B\u7801\u63A5\u5165\u673A\u5668\u4EBA:"Scan QR code",\u6B63\u5728\u63A5\u5165:"Connecting",\u624B\u52A8\u63A5\u5165:"Manual setup",\u6536\u8D77\u51ED\u636E:"Hide credentials",\u6536\u8D77\u63A5\u5165:"Hide setup",\u63A5\u5165\u673A\u5668\u4EBA:"Connect bot",\u5F00\u59CB\u63A5\u5165:"Start setup",\u5728\u7EBF:"online",\u8FD0\u884C\u6B63\u5E38:"Connected",\u6B63\u5728\u8FDE\u63A5:"Connecting","\u6B63\u5728\u8FDE\u63A5\u2026":"Connecting\u2026",\u8FDE\u63A5\u672A\u5C31\u7EEA:"Not connected",\u8FDE\u63A5\u4E2D:"Connecting",\u8FDE\u63A5\u4E2D\u65AD:"Disconnected",\u9700\u8981\u5904\u7406:"Needs attention",\u72B6\u6001\u672A\u77E5:"Unknown status",\u79BB\u7EBF:"Offline",\u5DF2\u65AD\u5F00:"Disconnected",\u6D88\u606F\u901A\u9053:"Message channel",\u6700\u8FD1\u68C0\u67E5:"Last checked",\u5F53\u524D\u5DE5\u4F5C\u533A:"Current workspace",\u9009\u62E9\u76EE\u5F55:"Choose folder",\u9009\u62E9\u673A\u5668\u4EBA\u5DE5\u4F5C\u533A\u76EE\u5F55:"Select bot workspace folder",\u5F53\u524D\u76EE\u5F55:"Current folder",\u4E3B\u76EE\u5F55:"Home","\u6B63\u5728\u51C6\u5907\u76EE\u5F55\u9009\u62E9\u5668\u2026":"Preparing folder picker\u2026","\u6B63\u5728\u8BFB\u53D6\u76EE\u5F55\u2026":"Loading folders\u2026","\u8FD9\u4E2A\u76EE\u5F55\u4E2D\u6CA1\u6709\u5B50\u6587\u4EF6\u5939\u3002":"This folder has no subfolders.","\u6B64\u76EE\u5F55\u7684\u5B50\u6587\u4EF6\u5939\u8FC7\u591A\uFF0C\u4EC5\u663E\u793A\u524D\u4E00\u90E8\u5206\u3002":"This folder has too many subfolders; only the first group is shown.","\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF0C\u8BF7\u91CD\u8BD5\u3002":"Could not load the folder. Try again.",\u91CD\u8BD5:"Retry",\u663E\u793A\u9690\u85CF\u6587\u4EF6\u5939:"Show hidden folders","\u5207\u6362\u540E\u4F1A\u6E05\u9664\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u65E7\u4F1A\u8BDD\u6620\u5C04\u3002":"Switching clears this bot\u2019s previous session mappings.","\u5207\u6362\u4E2D\u2026":"Switching\u2026",\u9009\u62E9\u6B64\u76EE\u5F55:"Select this folder",\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84:"Absolute workspace path","/\u7EDD\u5BF9\u8DEF\u5F84/\u5230/\u5DE5\u4F5C\u533A":"/absolute/path/to/workspace",\u4FEE\u6539:"Change",\u4FDD\u5B58:"Save","\u4FDD\u5B58\u4E2D\u2026":"Saving\u2026",\u672A\u8BBE\u7F6E:"Not set","\u5DE5\u4F5C\u533A\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002":"Could not update the workspace. Try again.","\u8BF7\u8F93\u5165\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84\u3002":"Enter an absolute workspace path.","\u5DE5\u4F5C\u533A\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84\u3002":"The workspace must be an absolute path.","\u5DE5\u4F5C\u533A\u8DEF\u5F84\u4E0D\u5B58\u5728\u3002":"The workspace path does not exist.","\u5DE5\u4F5C\u533A\u8DEF\u5F84\u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u76EE\u5F55\u3002":"The workspace path must point to a directory.","\u627E\u4E0D\u5230\u8981\u4FEE\u6539\u7684\u673A\u5668\u4EBA\u3002":"The bot could not be found.","Agent Preset":"Agent Preset","\u67E5\u770B Agent Preset \u8BF4\u660E":"View Agent Preset help","\u8DDF\u968F Host \u9ED8\u8BA4":"Follow the Host default","\uFF08\u5DF2\u4E0D\u53EF\u7528\uFF09":" (unavailable)","\u53EA\u5F71\u54CD\u65B0\u5EFA\u4F1A\u8BDD\uFF1B\u82E5\u5F53\u524D\u804A\u5929\u5DF2\u6709\u4F1A\u8BDD\uFF0C\u5148\u53D1\u9001 /new\uFF0C\u518D\u53D1\u9001\u666E\u901A\u6D88\u606F\u751F\u6548\u3002":"This affects only new sessions. If the current chat already has a session, send /new, then send a regular message to apply it.","\u5F53\u524D Agent Preset \u5DF2\u4E0D\u53EF\u7528\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6 Preset \u6216\u8DDF\u968F Host \u9ED8\u8BA4\u3002":"The current Agent Preset is unavailable. Choose another preset or follow the Host default.","Agent Preset \u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002":"Could not update the Agent Preset. Try again.","\u8BF7\u9009\u62E9 Agent Preset\u3002":"Choose an Agent Preset.","Agent Preset \u65E0\u6548\u3002":"The Agent Preset is invalid.","Agent Preset \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u7528\u3002":"The Agent Preset does not exist or is unavailable.",\u5C1A\u672A\u68C0\u67E5:"Not checked yet",\u521A\u521A:"Just now",\u68C0\u67E5\u8FDE\u63A5:"Check connection","\u68C0\u67E5\u4E2D\u2026":"Checking\u2026","\u8FDE\u63A5\u68C0\u67E5\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002":"Connection check failed. Try again later.","\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230\u5BF9\u5E94\u673A\u5668\u4EBA\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002":"Test message sent. Check the matching bot conversation.","\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\u3002\u673A\u5668\u4EBA\u5C1A\u672A\u6536\u5230\u53EF\u7528\u4E8E\u6D4B\u8BD5\u7684\u79C1\u804A\u6D88\u606F\u3002":"Connection check completed. The bot has not received a direct message it can use for testing.","\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002":"Connection check completed, but the test message could not be sent.","\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230\u98DE\u4E66\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002":"Test message sent. Check the Feishu conversation.","\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230 WhatsApp \u81EA\u804A\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002":"Test message sent. Check the WhatsApp self-chat.","\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684 WhatsApp \u81EA\u804A\u76EE\u6807\u3002":"Connection check completed, but no WhatsApp self-chat target is available.","\u9489\u9489\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\u3002":"DingTalk connection check completed and the test message was sent.","\u9489\u9489\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002":"DingTalk connection check completed, but the test message could not be sent.","\u5FAE\u4FE1\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\u3002":"WeChat connection check completed and the test message was sent.","\u5FAE\u4FE1\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002":"WeChat connection check completed, but the test message could not be sent.","\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\u3002":"WeCom connection check completed and the test message was sent.","\u4F01\u4E1A\u5FAE\u4FE1\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002":"WeCom connection check completed, but the test message could not be sent.",\u91CD\u8BD5\u8FDE\u63A5:"Reconnect","\u91CD\u8BD5\u4E2D\u2026":"Retrying\u2026",\u79FB\u9664\u63A5\u5165:"Remove connection",\u786E\u8BA4\u79FB\u9664\u63A5\u5165:"Remove connection",\u786E\u8BA4\u79FB\u9664:"Remove","\u6B63\u5728\u79FB\u9664\u2026":"Removing\u2026",\u4FDD\u7559\u673A\u5668\u4EBA:"Keep bot",\u4FDD\u7559\u8D26\u53F7:"Keep account",\u53D6\u6D88:"Cancel",\u5173\u95ED:"Close",\u7ACB\u5373\u91CD\u8BD5:"Retry now",\u91CD\u65B0\u8BFB\u53D6:"Reload",\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801:"Generate a new QR code",\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801\u540E\u7EE7\u7EED:"Generate a new QR code",\u5237\u65B0\u4E8C\u7EF4\u7801:"Refresh QR code","\u5237\u65B0\u4E2D\u2026":"Refreshing\u2026",\u6362\u4E00\u4E2A\u4E8C\u7EF4\u7801:"Get another QR code",\u7EE7\u7EED\u8FDE\u63A5:"Continue connecting",\u7ED1\u5B9A\u5E76\u8FDE\u63A5:"Connect","\u6B63\u5728\u7ED1\u5B9A\u2026":"Connecting\u2026",\u9A8C\u8BC1\u5E76\u8FDE\u63A5:"Verify and connect","\u6B63\u5728\u9A8C\u8BC1\u5E76\u8FDE\u63A5\u2026":"Verifying and connecting\u2026","\u6B63\u5728\u9A8C\u8BC1\u2026":"Verifying\u2026","\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5":"The operation failed. Try again later.",\u8BF7\u7A0D\u540E\u91CD\u8BD5:"Try again later.",\u5F53\u524D\u4E8C\u7EF4\u7801\u6709\u6548\u65F6\u95F4:"QR code expires in",\u4E8C\u7EF4\u7801\u6709\u6548\u65F6\u95F4:"QR code expires in",\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F:"QR code expired",\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548:"QR code expired","\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\n\u8BF7\u91CD\u65B0\u751F\u6210":`QR code expired Generate a new one`,"\u4E8C\u7EF4\u7801\u56FE\u7247\u6B63\u5728\u751F\u6210\u2026":"Generating QR code\u2026","\u4E8C\u7EF4\u7801\u6B63\u5728\u751F\u6210\u2026":"Generating QR code\u2026","\u4E8C\u7EF4\u7801\u6B63\u5728\u81EA\u52A8\u5237\u65B0\u2026":"Refreshing QR code\u2026","\u4E8C\u7EF4\u7801\u672A\u5C31\u7EEA\uFF0C\u8BF7\u6253\u5F00\u6388\u6743\u94FE\u63A5":"The QR code is not ready. Open the authorization link.","\u4E8C\u7EF4\u7801\u56FE\u7247\u672A\u5C31\u7EEA\uFF0C\u8BF7\u4F7F\u7528\u5907\u7528\u94FE\u63A5\u3002":"The QR code is not ready. Use the alternate link.","\u4E8C\u7EF4\u7801\u56FE\u7247\u672A\u5C31\u7EEA\uFF0C\u8BF7\u91CD\u65B0\u751F\u6210\u3002":"The QR code is not ready. Generate a new one.",\u7B49\u5F85\u5237\u65B0:"Waiting to refresh",\u6B63\u5728\u5237\u65B0\u4E8C\u7EF4\u7801:"Refreshing QR code",\u6253\u5F00\u5907\u7528\u94FE\u63A5:"Open alternate link",\u751F\u6210\u4E8C\u7EF4\u7801:"Generate QR code",\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801:"Generate WeChat QR code",\u751F\u6210\u98DE\u4E66\u4E8C\u7EF4\u7801:"Generate Feishu QR code",\u751F\u6210\u9489\u9489\u4E8C\u7EF4\u7801:"Generate DingTalk QR code",\u751F\u6210\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801:"Generate WeCom QR code","\u751F\u6210 QQ \u4E8C\u7EF4\u7801":"Generate QQ QR code","\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026":"Generating QR code\u2026",\u6B63\u5728\u51C6\u5907\u6388\u6743\u4E8C\u7EF4\u7801:"Preparing authorization QR code",\u6B63\u5728\u51C6\u5907\u6743\u9650\u6388\u6743\u4E8C\u7EF4\u7801:"Preparing permission authorization QR code",\u6B63\u5728\u51C6\u5907\u5FAE\u4FE1\u4E8C\u7EF4\u7801:"Preparing WeChat QR code",\u6B63\u5728\u6DFB\u52A0\u65B0\u673A\u5668\u4EBA:"Adding a new bot","\u6B63\u5728\u7533\u8BF7\u9489\u9489\u6388\u6743\u4E8C\u7EF4\u7801\u2026":"Requesting DingTalk authorization QR code\u2026","\u6B63\u5728\u7533\u8BF7\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801\u2026":"Requesting WeCom QR code\u2026","\u6B63\u5728\u7533\u8BF7 QQ \u4E8C\u7EF4\u7801\u2026":"Requesting QQ QR code\u2026","\u6B63\u5728\u751F\u6210 WhatsApp \u4E8C\u7EF4\u7801":"Generating WhatsApp QR code","\u626B\u7801\uFF0C\u521B\u5EFA\u7B2C\u4E00\u4E2A\u98DE\u4E66\u5165\u53E3":"Scan to create your first Feishu bot","\u626B\u7801\u53EA\u4F1A\u65B0\u589E\u4E00\u4E2A\u673A\u5668\u4EBA\uFF0C\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA\u4F1A\u7EE7\u7EED\u6B63\u5E38\u6536\u53D1\u6D88\u606F\u3002":"Scanning adds one bot. Existing bots will continue to send and receive messages.","\u65E0\u9700\u624B\u52A8\u586B\u5199 App ID\u3002\u4EE5\u540E\u8FD8\u53EF\u4EE5\u7EE7\u7EED\u6DFB\u52A0\u673A\u5668\u4EBA\uFF0C\u5206\u522B\u670D\u52A1\u4E0D\u540C\u56E2\u961F\u6216\u98DE\u4E66\u79DF\u6237\u3002":"No App ID is required. You can add more bots later for different teams or Feishu tenants.",\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u521B\u5EFA\u673A\u5668\u4EBA:"Scan with Feishu to create a bot",\u5237\u65B0\u4E8C\u7EF4\u7801\u540E\u7EE7\u7EED:"Refresh the QR code to continue","\u6253\u5F00\u98DE\u4E66\u79FB\u52A8\u7AEF\uFF0C\u4F7F\u7528\u626B\u4E00\u626B\u8BFB\u53D6\u4E8C\u7EF4\u7801":"Open Feishu on your phone and scan the QR code","\u6838\u5BF9\u5E94\u7528\u540D\u79F0\u4E0E\u6743\u9650\u8303\u56F4\uFF0C\u5E76\u786E\u8BA4\u521B\u5EFA":"Review the app name and permissions, then confirm","\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u65B0\u673A\u5668\u4EBA\u7684\u957F\u8FDE\u63A5\u5C31\u7EEA":"Keep this page open until the bot connection is ready",\u5728\u98DE\u4E66\u4E2D\u6253\u5F00:"Open in Feishu",\u53D6\u6D88\u6DFB\u52A0:"Cancel",\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u4FEE\u590D\u5361\u7247\u6309\u94AE:"Scan with Feishu to repair card buttons",\u4F7F\u7528\u98DE\u4E66\u786E\u8BA4\u7FA4\u6D88\u606F\u6743\u9650:"Confirm group-message permission with Feishu","\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u53EA\u589E\u91CF\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u540E\u4F1A\u81EA\u52A8\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002":"Scanning updates the existing Feishu app with only the \u201CRead all messages in associated group chat\u201D scope. It does not create a new app. After confirmation, \u201CRespond to all group messages\u201D is enabled automatically; other bots are unaffected.","\u6838\u5BF9\u73B0\u6709\u5E94\u7528\uFF0C\u5E76\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650":"Review the existing app and confirm the \u201CRead all messages in associated group chat\u201D permission","\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u751F\u6548\u5E76\u81EA\u52A8\u5207\u6362\u54CD\u5E94\u65B9\u5F0F":"Keep this page open while the permission takes effect and the response mode switches automatically",\u53D6\u6D88\u6388\u6743:"Cancel authorization","\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u542F\u7528\u5168\u90E8\u6D88\u606F\u6A21\u5F0F":"Confirmed. Enabling all-message mode","\u6743\u9650\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002":"The permission update was submitted. Saving the setting and reconnecting this bot. This stage cannot be cancelled; other bots will not be interrupted.","\u6743\u9650\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u542F\u7528\u5168\u90E8\u6D88\u606F\u6A21\u5F0F\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002":"The permission update was submitted. Enabling all-message mode and reconnecting this bot. This stage cannot be cancelled; other bots will not be interrupted.","\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002":"Requesting a group-message permission QR code for the existing Feishu app\u2026",\u7FA4\u6D88\u606F\u6743\u9650\u6CA1\u6709\u5F00\u901A\u5B8C\u6210:"Group-message permission was not granted","\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u53EA\u589E\u91CF\u8865\u5145\u5361\u7247\u6309\u94AE\u56DE\u8C03\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u540E\u6B64\u673A\u5668\u4EBA\u4F1A\u77ED\u6682\u91CD\u8FDE\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002":"Scanning updates the existing Feishu app with only the card-button callback. It does not create a new app. This bot reconnects briefly after confirmation; other bots are not affected.","\u6838\u5BF9\u73B0\u6709\u5E94\u7528\u540D\u79F0\uFF0C\u5E76\u786E\u8BA4\u53EA\u65B0\u589E\u5361\u7247\u56DE\u8C03":"Review the existing app name and confirm that only the card callback is added","\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u5361\u7247\u6309\u94AE\u4FEE\u590D\u5B8C\u6210":"Keep this page open until card-button repair finishes",\u53D6\u6D88\u4FEE\u590D:"Cancel repair","\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u5B8C\u6210\u5361\u7247\u6309\u94AE\u4FEE\u590D":"Confirmed. Finishing card-button repair",\u6B63\u5728\u51C6\u5907\u4FEE\u590D\u4E8C\u7EF4\u7801:"Preparing the repair QR code","\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u9A8C\u8BC1\u5361\u7247\u6309\u94AE\u56DE\u8C03\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002":"The update was submitted. Verifying the card callback and reconnecting this bot. This stage cannot be cancelled; other bots will not be interrupted.","\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u4E00\u6B21\u6027\u66F4\u65B0\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002":"Requesting a one-time update QR code for the existing Feishu app\u2026",\u5361\u7247\u6309\u94AE\u6CA1\u6709\u4FEE\u590D\u5B8C\u6210:"Card-button repair did not finish",\u4FEE\u590D\u5361\u7247\u6309\u94AE:"Repair card buttons","\u7B49\u5F85\u626B\u7801\u2026":"Waiting for scan\u2026",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u5361\u7247\u4FEE\u590D\u4E8C\u7EF4\u7801:"Feishu returned a repair QR code for a different bot",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801:"Feishu returned a group-message permission QR code for a different bot","\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u7684\u4FEE\u590D\u4FE1\u606F\u7F3A\u5C11 botId":"Feishu repair status is missing the bot ID","\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u7684\u5E94\u7528\u66F4\u65B0\u4FE1\u606F\u7F3A\u5C11 botId":"Feishu app-update status is missing the bot ID",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u5339\u914D\u7684\u6CE8\u518C\u8FDB\u5EA6:"Feishu returned registration progress for a different operation",\u6B64\u673A\u5668\u4EBA:"this bot","\u7528\u4E8E\u4E3A${botName}\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801":"One-time QR code for granting group-message permission to ${botName}","\u6B63\u5728\u4E3A\u300C${botName}\u300D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650":"Granting group-message permission to \u201C${botName}\u201D",'${botName ?? "\u673A\u5668\u4EBA"}\u7684\u4FEE\u590D\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\uFF0C\u8BF7\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u3002':'Repair QR code generated for ${botName ?? "bot"}. Scan it with Feishu.','${botName ?? "\u673A\u5668\u4EBA"}\u7684\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\uFF0C\u8BF7\u4F7F\u7528\u98DE\u4E66\u786E\u8BA4\u3002':'Group-message permission QR code generated for ${botName ?? "bot"}. Confirm it with Feishu.',"${targetBotName}\u5DF2\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\uFF0C\u5E76\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\u3002":"${targetBotName} now has group-message permission and \u201CRespond to all group messages\u201D is enabled.","${targetBot.bot.name}\u5DF2\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\uFF0C\u5E76\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\u3002":"${targetBot.bot.name} now has group-message permission and \u201CRespond to all group messages\u201D is enabled.","${targetBot.bot.name}\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5728\u98DE\u4E66\u4E2D\u5F00\u59CB\u804A\u5929\u3002":"${targetBot.bot.name} is connected and ready to chat in Feishu.","\u5DF2\u53D6\u6D88\u5361\u7247\u6309\u94AE\u4FEE\u590D\u3002":"Card-button repair was cancelled.","\u5DF2\u53D6\u6D88\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u3002":"Group-message permission authorization was cancelled.","\u5361\u7247\u6309\u94AE\u5DF2\u66F4\u65B0\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u673A\u5668\u4EBA\u8FDE\u63A5\u72B6\u6001":"The card callback was updated, but the bot connection could not be confirmed yet","\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u66F4\u65B0\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u673A\u5668\u4EBA\u8FDE\u63A5\u72B6\u6001":"The group-message permission was updated, but the bot connection could not be confirmed yet",\u98DE\u4E66\u5361\u7247\u6309\u94AE\u4FEE\u590D\u5931\u8D25:"Could not repair the Feishu card buttons",\u98DE\u4E66\u7FA4\u6D88\u606F\u6743\u9650\u5F00\u901A\u5931\u8D25:"Could not grant the Feishu group-message permission","\u8BF7\u5148\u5B8C\u6210\u5F53\u524D\u98DE\u4E66\u6388\u6743\u64CD\u4F5C\uFF0C\u518D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u3002":"Finish the current Feishu authorization before granting group-message permission.","\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u8FDE\u63A5\u65B0\u673A\u5668\u4EBA":"Confirmed. Connecting the new bot","\u6B63\u5728\u5B89\u5168\u4FDD\u5B58\u51ED\u636E\u5E76\u68C0\u67E5\u65B0\u673A\u5668\u4EBA\u7684\u6D88\u606F\u901A\u9053\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002":"Saving credentials and checking the new bot connection. Existing bots will not be interrupted.","\u6B63\u5728\u5411\u98DE\u4E66\u7533\u8BF7\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002":"Requesting a one-time authorization QR code from Feishu\u2026",\u65B0\u673A\u5668\u4EBA\u6CA1\u6709\u6DFB\u52A0\u5B8C\u6210:"The new bot was not added","\u65B0\u98DE\u4E66\u673A\u5668\u4EBA\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5F00\u59CB\u804A\u5929\u3002":"The new Feishu bot is connected and ready to chat.",\u98DE\u4E66\u5E94\u7528\u521B\u5EFA\u5931\u8D25:"Could not create the Feishu app","\u673A\u5668\u4EBA\u5DF2\u7ECF\u521B\u5EFA\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u8FDE\u63A5\u72B6\u6001":"The bot was created, but its connection could not be confirmed yet",\u673A\u5668\u4EBA\u4ECD\u672A\u8FDE\u63A5:"The bot is still offline",\u673A\u5668\u4EBA\u5C1A\u672A\u8FDE\u63A5:"The bot is not connected yet",\u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38:"Persistent connection is healthy",\u957F\u8FDE\u63A5:"Persistent connection",\u5E94\u7528\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58:"App identifier stored securely",\u673A\u5668\u4EBA\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58:"Bot identifier stored securely",\u5DF2\u5B89\u5168\u4FDD\u5B58:"Stored securely",\u5DF2\u63A5\u5165\u7684\u5FAE\u4FE1\u8D26\u53F7:"Connected WeChat accounts",\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA:"Connected bots",\u5DF2\u63A5\u5165\u7684\u9489\u9489\u673A\u5668\u4EBA:"Connected DingTalk bots",\u5DF2\u7ED1\u5B9A\u7684\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA:"Connected WeCom bots","\u5DF2\u7ED1\u5B9A\u7684 QQ \u673A\u5668\u4EBA":"Connected QQ bots","\u5DF2\u63A5\u5165\u7684 WhatsApp \u673A\u5668\u4EBA":"Connected WhatsApp accounts",\u4F7F\u7528\u624B\u673A\u5FAE\u4FE1\u626B\u63CF\u4E8C\u7EF4\u7801:"Scan with WeChat on your phone","\u626B\u4E00\u6B21\u7801\uFF0C\u5C31\u80FD\u5728\u5FAE\u4FE1\u91CC\u4F7F\u7528 Harness":"Scan once to use Harness in WeChat",\u6253\u5F00\u624B\u673A\u5FAE\u4FE1\u5E76\u626B\u63CF\u5DE6\u4FA7\u4E8C\u7EF4\u7801:"Open WeChat on your phone and scan the QR code",\u5728\u5FAE\u4FE1\u4E2D\u786E\u8BA4\u8FDE\u63A5\u8BE5\u673A\u5668\u4EBA:"Confirm the bot connection in WeChat","\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u673A\u5668\u4EBA\u81EA\u52A8\u8FDE\u63A5":"Keep this page open while the bot connects",\u7B49\u5F85\u5FAE\u4FE1\u626B\u7801:"Waiting for WeChat scan",\u9700\u8981\u914D\u5BF9\u7801:"Pairing code required",\u8F93\u5165\u624B\u673A\u5FAE\u4FE1\u663E\u793A\u7684\u6570\u5B57:"Enter the number shown in WeChat",\u5FAE\u4FE1\u914D\u5BF9\u7801:"WeChat pairing code","\u5DF2\u626B\u7801\uFF0C\u8BF7\u5728\u624B\u673A\u4E0A\u786E\u8BA4":"Scanned. Confirm on your phone","\u914D\u5BF9\u7801\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u7B49\u5F85\u5FAE\u4FE1\u786E\u8BA4\u3002":"Pairing code submitted. Waiting for WeChat confirmation.","\u8FD9\u662F\u5FAE\u4FE1\u9644\u52A0\u7684\u5B89\u5168\u786E\u8BA4\u6B65\u9AA4\u3002\u914D\u5BF9\u7801\u53EA\u7528\u4E8E\u672C\u6B21\u626B\u7801\u8F6E\u8BE2\uFF0C\u4E0D\u4F1A\u5199\u5165\u914D\u7F6E\u6216\u65E5\u5FD7\u3002":"This is an additional WeChat confirmation step. The pairing code is used only for this connection and is never stored.","\u6B63\u5728\u4FDD\u5B58\u51ED\u636E\u5E76\u9A8C\u8BC1 Harness \u4E0E\u5FAE\u4FE1\u957F\u8F6E\u8BE2\u3002":"Saving credentials and verifying the WeChat connection.","\u5FAE\u4FE1\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u542F\u52A8\u6D88\u606F\u8FDE\u63A5":"Confirmed in WeChat. Starting the message connection","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u8BFB\u53D6\u73B0\u6709\u767B\u5F55\u51ED\u636E\u3002\u8BF7\u68C0\u67E5 DSH \u51ED\u636E\u5B58\u50A8\u3002":"WeChat was authorized, but the existing login credential could not be read. Check the DSH credential store.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u767B\u5F55\u51ED\u636E\u65E0\u6CD5\u5199\u5165 DSH \u51ED\u636E\u5B58\u50A8\u3002\u8BF7\u68C0\u67E5\u51ED\u636E\u5B58\u50A8\u662F\u5426\u53EF\u5199\u3002":"WeChat was authorized, but the login credential could not be written to the DSH credential store. Check that the store is writable.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u8D26\u53F7\u914D\u7F6E\u65E0\u6CD5\u5199\u5165\u672C\u673A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u76EE\u5F55\u6743\u9650\u3002":"WeChat was authorized, but the account configuration could not be saved locally. Check the DSH_HOME directory permissions.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u65E0\u6CD5\u521D\u59CB\u5316\u8D26\u53F7\u72B6\u6001\u6216\u5DE5\u4F5C\u533A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u548C\u5DE5\u4F5C\u533A\u76EE\u5F55\u3002":"WeChat was authorized, but the account state or workspace could not be initialized. Check DSH_HOME and the workspace directory.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u63D2\u4EF6\u65E0\u6CD5\u8FDE\u63A5\u672C\u673A Harness\u3002\u8BF7\u68C0\u67E5 dsh web \u5730\u5740\u548C\u7AEF\u53E3\u3002":"WeChat was authorized, but the plugin could not connect to the local Harness. Check the dsh web address and port.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u8D85\u65F6\u3002\u8BF7\u786E\u8BA4 dsh web \u672A\u963B\u585E\u3002":"WeChat was authorized, but the Harness health check timed out. Confirm that dsh web is not blocked.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u62D2\u7EDD\u4E86\u672C\u673A\u5065\u5EB7\u68C0\u67E5\u3002\u8BF7\u68C0\u67E5 Host \u4FE1\u4EFB\u914D\u7F6E\u3002":"WeChat was authorized, but Harness denied the local health check. Check the Host trust configuration.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u627E\u4E0D\u5230 Harness \u5065\u5EB7\u68C0\u67E5\u63A5\u53E3\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002":"WeChat was authorized, but the Harness health endpoint was not found. Confirm that Harness and the plugin are compatible.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u8FD4\u56DE\u670D\u52A1\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002":"WeChat was authorized, but the Harness health check returned a service error. Check the dsh web logs.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002":"WeChat was authorized, but Harness returned an unrecognized response. Confirm that Harness and the plugin are compatible.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u62D2\u7EDD\u4E86\u5065\u5EB7\u68C0\u67E5\u8BF7\u6C42\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002":"WeChat was authorized, but Harness rejected the health-check request. Check the dsh web logs.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46 Harness \u5065\u5EB7\u68C0\u67E5\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002":"WeChat was authorized, but the Harness health check failed unexpectedly. Check the dsh web logs.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u6D88\u606F\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u540E\u91CD\u8BD5\u3002":"WeChat was authorized, but the message connection could not be initialized. Check the dsh web logs and try again.","\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u4F46\u6FC0\u6D3B\u8FC7\u7A0B\u4E2D\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002\u8BF7\u67E5\u770B dsh web \u65E5\u5FD7\u3002":"WeChat was authorized, but an unknown error occurred during activation. Check the dsh web logs.","\u5FAE\u4FE1\u5DF2\u7ED1\u5B9A\uFF0C\u53EF\u4EE5\u5F00\u59CB\u5411\u5DF2\u7ED1\u5B9A\u7684\u673A\u5668\u4EBA\u53D1\u6D88\u606F\u3002":"WeChat is connected and ready for messages.","\u8FD9\u4E2A\u5FAE\u4FE1\u8D26\u53F7\u5DF2\u7ECF\u7ED1\u5B9A\u5E76\u4FDD\u6301\u5728\u7EBF\u3002":"This WeChat account is connected and online.","\u5FAE\u4FE1\u8D26\u53F7\u53CA\u672C\u673A\u51ED\u636E\u5DF2\u79FB\u9664\u3002":"The WeChat account and local credentials were removed.","\u5DF2\u53D6\u6D88\u5FAE\u4FE1\u7ED1\u5B9A\u3002":"WeChat setup was cancelled.","\u6B63\u5728\u8054\u7CFB\u817E\u8BAF\u5FAE\u4FE1 iLink \u670D\u52A1\u3002":"Contacting the WeChat iLink service.","iLink \u957F\u8F6E\u8BE2":"iLink long polling","\u626B\u4E00\u6B21\u7801\uFF0C\u81EA\u52A8\u521B\u5EFA\u5E76\u8FDE\u63A5\u673A\u5668\u4EBA":"Scan once to create and connect a bot","\u4F7F\u7528\u9489\u9489 App \u5B8C\u6210\u673A\u5668\u4EBA\u6388\u6743":"Authorize the bot with the DingTalk app","\u4F7F\u7528\u5DF2\u52A0\u5165\u4F01\u4E1A/\u7EC4\u7EC7\u7684\u9489\u9489\u8D26\u53F7\u626B\u63CF\u5DE6\u4FA7\u4E8C\u7EF4\u7801":"Scan the QR code with a DingTalk account that belongs to an organization","\u5728\u6388\u6743\u9875\u70B9\u51FB\u201C\u4E00\u952E\u521B\u5EFA\u65B0\u673A\u5668\u4EBA\u201D":"Select \u201CCreate new bot\u201D on the authorization page","\u8BF7\u52FF\u5173\u95ED\u672C\u9875\uFF0C\u9489\u9489\u5B8C\u6210\u6388\u6743\u540E\u5C06\u81EA\u52A8\u7EE7\u7EED\u3002":"Keep this page open. Setup will continue after DingTalk authorization.",\u7B49\u5F85\u9489\u9489\u626B\u7801\u6388\u6743:"Waiting for DingTalk authorization","\u6388\u6743\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u521B\u5EFA\u9489\u9489\u673A\u5668\u4EBA":"Authorized. Creating the DingTalk bot",\u6B63\u5728\u786E\u8BA4\u9489\u9489\u6388\u6743:"Confirming DingTalk authorization","\u6B63\u5728\u68C0\u67E5\u9489\u9489 Stream \u957F\u8FDE\u63A5\uFF0C\u6210\u529F\u540E\u4F1A\u81EA\u52A8\u663E\u793A\u4E3A\u5728\u7EBF\u3002":"Checking the DingTalk Stream connection. It will appear online when ready.","\u9489\u9489\u673A\u5668\u4EBA\u5DF2\u63A5\u5165\uFF0C\u53EF\u4EE5\u5F00\u59CB\u53D1\u9001\u6D88\u606F\u3002":"The DingTalk bot is connected and ready for messages.","\u8FD9\u4E2A\u9489\u9489\u673A\u5668\u4EBA\u5DF2\u7ECF\u63A5\u5165\u5E76\u4FDD\u6301\u5728\u7EBF\u3002":"This DingTalk bot is connected and online.","Stream \u957F\u8FDE\u63A5":"Stream persistent connection","\u4F7F\u7528\u4F01\u4E1A\u5FAE\u4FE1 App \u626B\u7801\u521B\u5EFA\u667A\u80FD\u673A\u5668\u4EBA":"Scan with WeCom to create an AI bot","\u4F7F\u7528\u4F01\u4E1A\u5FAE\u4FE1 App \u5B8C\u6210\u667A\u80FD\u673A\u5668\u4EBA\u6388\u6743":"Authorize the AI bot with WeCom","\u6253\u5F00\u4F01\u4E1A\u5FAE\u4FE1 App\uFF0C\u626B\u63CF\u5DE6\u4FA7\u4E8C\u7EF4\u7801":"Open WeCom and scan the QR code",\u5728\u817E\u8BAF\u6388\u6743\u9875\u9762\u786E\u8BA4\u521B\u5EFA\u667A\u80FD\u673A\u5668\u4EBA:"Confirm bot creation on the Tencent authorization page",\u8FD4\u56DE\u8FD9\u91CC\u7B49\u5F85\u8FDE\u63A5\u5B8C\u6210:"Return here and wait for the connection to complete","\u7B49\u5F85\u4F01\u4E1A\u5FAE\u4FE1 App \u626B\u7801":"Waiting for WeCom scan","\u4F01\u4E1A\u5FAE\u4FE1\u5DF2\u6388\u6743\uFF0C\u6B63\u5728\u8FDE\u63A5\u673A\u5668\u4EBA":"Authorized in WeCom. Connecting the bot","\u51ED\u636E\u6B63\u5728\u5199\u5165\u672C\u673A\uFF0C\u5E76\u542F\u52A8\u4F01\u4E1A\u5FAE\u4FE1 WebSocket \u6D88\u606F\u8FDE\u63A5\u3002":"Saving credentials locally and starting the WeCom WebSocket connection.","WebSocket \u957F\u8FDE\u63A5":"WebSocket persistent connection","\u4F7F\u7528\u624B\u673A QQ \u626B\u7801\u521B\u5EFA\u5E76\u7ED1\u5B9A\u673A\u5668\u4EBA":"Scan with mobile QQ to create and connect a bot","\u4F7F\u7528\u624B\u673A QQ \u5B8C\u6210\u673A\u5668\u4EBA\u7ED1\u5B9A":"Complete bot setup with mobile QQ","\u6253\u5F00\u624B\u673A QQ\uFF0C\u626B\u63CF\u5DE6\u4FA7\u4E8C\u7EF4\u7801":"Open mobile QQ and scan the QR code",\u5728\u817E\u8BAF\u6388\u6743\u9875\u9762\u786E\u8BA4\u521B\u5EFA\u6216\u7ED1\u5B9A\u673A\u5668\u4EBA:"Confirm bot creation or connection on the Tencent authorization page","\u7B49\u5F85\u624B\u673A QQ \u626B\u7801":"Waiting for mobile QQ scan","QQ \u5DF2\u6388\u6743\uFF0C\u6B63\u5728\u8FDE\u63A5\u673A\u5668\u4EBA":"Authorized in QQ. Connecting the bot","\u51ED\u636E\u6B63\u5728\u5199\u5165\u672C\u673A\uFF0C\u5E76\u542F\u52A8 QQ WebSocket \u6D88\u606F\u8FDE\u63A5\u3002":"Saving credentials locally and starting the QQ WebSocket connection.","\u4F7F\u7528\u624B\u673A WhatsApp \u626B\u63CF\u4E8C\u7EF4\u7801\u5373\u53EF\u63A5\u5165\u3002":"Scan the QR code with WhatsApp to connect.","\u7528\u624B\u673A WhatsApp \u626B\u63CF\u4E8C\u7EF4\u7801":"Scan with WhatsApp on your phone","\u6253\u5F00 WhatsApp \u2192 \u8BBE\u7F6E \u2192 \u5DF2\u5173\u8054\u8BBE\u5907":"Open WhatsApp \u2192 Settings \u2192 Linked devices","\u70B9\u51FB\u201C\u5173\u8054\u8BBE\u5907\u201D\u5E76\u626B\u63CF\u5DE6\u4FA7\u4E8C\u7EF4\u7801":"Select \u201CLink a device\u201D and scan the QR code","\u7B49\u5F85 WhatsApp \u626B\u7801":"Waiting for WhatsApp scan","\u5DF2\u626B\u7801\uFF0C\u6B63\u5728\u8FDE\u63A5 WhatsApp":"Scanned. Connecting WhatsApp","\u6B63\u5728\u5EFA\u7ACB\u5B89\u5168\u7684\u5173\u8054\u8BBE\u5907\u4F1A\u8BDD\u3002":"Creating a secure linked-device session.","\u5173\u8054\u8BBE\u5907\u6B63\u5728\u63A5\u5165 DeepSeek Harness\u3002":"Linking the device to DeepSeek Harness.","WhatsApp Web \u5173\u8054\u8BBE\u5907\u8FD0\u884C\u6B63\u5E38":"WhatsApp linked device is healthy","Bot API \u957F\u8F6E\u8BE2":"Bot API long polling"," Gateway \u957F\u8FDE\u63A5":" Gateway persistent connection","Gateway \u957F\u8FDE\u63A5":"Gateway persistent connection"," Socket Mode \u957F\u8FDE\u63A5":" Socket Mode persistent connection","Socket Mode \u957F\u8FDE\u63A5":"Socket Mode persistent connection","\u63A5\u5165 Telegram \u673A\u5668\u4EBA":"Connect a Telegram bot","\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002":"Get a Bot Token from @BotFather, then connect it here.","\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token":"Enter the Bot Token from @BotFather",\u8BBF\u95EE\u6A21\u5F0F:"Access mode",\u8BBF\u95EE\u8BBE\u7F6E:"Access settings","Telegram \u8BBF\u95EE\u6A21\u5F0F":"Telegram access mode","\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E":"View Telegram access mode details","\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002":"All group messages are ignored; only allowlisted users may send DMs.","\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002":"Keep the original behavior: respond to DMs and to group mentions or replies.",\u5B89\u5168\u6A21\u5F0F:"Safe mode",\u517C\u5BB9\u6A21\u5F0F:"Compatible mode","\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F":"Active: Safe mode","\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F":"Active: Compatible mode",\u6A21\u5F0F:"Mode","\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09":"Compatible mode (default)","\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09":"Safe mode (private-chat allowlist)","\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID":"Telegram User IDs allowed to send DMs","\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID":"One numeric User ID per line","\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002":"This allowlist belongs only to the current bot.","\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002":"Compatible mode does not enforce the allowlist; it is retained when modes change.","\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002":"The allowlist is empty; this bot will reject all inbound messages after saving.","\u6B63\u5728\u4FDD\u5B58\u2026":"Saving\u2026",\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E:"Save access settings","User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002":"Each User ID must be a 1\u201316 digit positive integer on its own line.","Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002":"Telegram access settings are currently unavailable.","Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002":"Could not save Telegram access settings.","\u63A5\u5165 Discord \u673A\u5668\u4EBA":"Connect a Discord bot","\u5148\u5728 Developer Portal \u521B\u5EFA Bot \u5E76\u9080\u8BF7\u5230\u670D\u52A1\u5668\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002":"Create a bot in the Developer Portal and invite it to your server, then connect it here.","\u586B\u5199 Discord Developer Portal \u7684 Bot Token":"Enter the Bot Token from the Discord Developer Portal","\u63A5\u5165 Slack \u673A\u5668\u4EBA":"Connect a Slack bot","\u5148\u7528 Manifest \u521B\u5EFA\u5E76\u914D\u7F6E Slack App":"Create and configure a Slack app with the manifest","\u590D\u5236\u914D\u7F6E\u540E\uFF0C\u5728 Slack \u9009\u62E9 From a manifest\uFF1B\u521B\u5EFA\u5B8C\u6210\u540E\u751F\u6210 connections:write App Token\uFF0C\u5E76\u5C06\u5E94\u7528\u5B89\u88C5\u5230\u5DE5\u4F5C\u533A\u3002":"Copy the manifest and choose \u201CFrom a manifest\u201D in Slack. Then create a connections:write App Token and install the app to your workspace.","\u590D\u5236 Manifest":"Copy manifest","\u5DF2\u590D\u5236 Manifest":"Manifest copied","\u6253\u5F00 Slack \u521B\u5EFA\u9875":"Open Slack app creation","Bot Token \u6765\u81EA OAuth & Permissions\uFF1BApp Token \u6765\u81EA Basic Information\uFF0C\u5E76\u4E14\u5FC5\u987B\u5305\u542B connections:write\u3002":"Get the Bot Token from OAuth & Permissions and the App Token from Basic Information. The App Token must include connections:write.","\u4F7F\u7528\u5B98\u65B9 App Manifest \u5FEB\u901F\u914D\u7F6E\u673A\u5668\u4EBA\uFF0C\u518D\u586B\u5199 Bot Token \u4E0E App Token \u5EFA\u7ACB\u672C\u5730 Socket Mode \u8FDE\u63A5\u3002":"Configure the bot with the official app manifest, then enter the Bot Token and App Token to start a local Socket Mode connection.","Slack \u5DE5\u4F5C\u533A":"Slack workspace","Bot Token \u4E0E App Token":"Bot Token and App Token","\u586B\u5199 Bot Token":"Enter Bot Token",\u624B\u52A8\u63A5\u5165\u98DE\u4E66\u673A\u5668\u4EBA:"Connect Feishu bot manually",\u624B\u52A8\u63A5\u5165\u9489\u9489\u673A\u5668\u4EBA:"Connect DingTalk bot manually",\u624B\u52A8\u63A5\u5165\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA:"Connect WeCom bot manually",\u624B\u52A8\u63A5\u5165QQ\u673A\u5668\u4EBA:"Connect QQ bot manually","\u586B\u5199\u98DE\u4E66\u5F00\u653E\u5E73\u53F0 App ID":"Enter the Feishu Open Platform App ID","\u586B\u5199\u98DE\u4E66\u5F00\u653E\u5E73\u53F0 App Secret":"Enter the Feishu Open Platform App Secret","\u586B\u5199\u9489\u9489\u5E94\u7528 Client ID":"Enter the DingTalk Client ID","\u586B\u5199\u9489\u9489\u5E94\u7528 Client Secret":"Enter the DingTalk Client Secret","\u586B\u5199\u4F01\u4E1A\u5FAE\u4FE1\u667A\u80FD\u673A\u5668\u4EBA Bot ID":"Enter the WeCom AI Bot ID","\u586B\u5199\u4F01\u4E1A\u5FAE\u4FE1\u667A\u80FD\u673A\u5668\u4EBA Secret":"Enter the WeCom AI Bot Secret","\u586B\u5199 QQ \u5F00\u653E\u5E73\u53F0 AppID":"Enter the QQ Open Platform AppID","\u586B\u5199 QQ \u5F00\u653E\u5E73\u53F0 AppSecret":"Enter the QQ Open Platform AppSecret",\u626B\u7801\u63A5\u5165\u5FAE\u4FE1\u673A\u5668\u4EBA:"Connect WeChat bot by QR code",\u626B\u7801\u63A5\u5165\u98DE\u4E66\u673A\u5668\u4EBA:"Connect Feishu bot by QR code",\u626B\u7801\u63A5\u5165\u9489\u9489\u673A\u5668\u4EBA:"Connect DingTalk bot by QR code",\u626B\u7801\u63A5\u5165\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA:"Connect WeCom bot by QR code","\u626B\u7801\u63A5\u5165 QQ \u673A\u5668\u4EBA":"Connect QQ bot by QR code","\u626B\u7801\u63A5\u5165 WhatsApp \u673A\u5668\u4EBA":"Connect WhatsApp by QR code","\u626B\u7801\u7ED1\u5B9A WhatsApp \u673A\u5668\u4EBA":"Connect WhatsApp by QR code","\u4F7F\u7528 App ID \u548C App Secret \u7ED1\u5B9A\u98DE\u4E66\u673A\u5668\u4EBA":"Connect a Feishu bot with App ID and App Secret","\u4F7F\u7528 Client ID \u548C Client Secret \u7ED1\u5B9A\u9489\u9489\u673A\u5668\u4EBA":"Connect a DingTalk bot with Client ID and Client Secret","\u4F7F\u7528 Bot ID \u548C Secret \u7ED1\u5B9A\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA":"Connect a WeCom bot with Bot ID and Secret","\u4F7F\u7528 AppID \u548C AppSecret \u7ED1\u5B9A QQ \u673A\u5668\u4EBA":"Connect a QQ bot with AppID and AppSecret","\u4F7F\u7528 Manifest \u548C\u53CC Token \u63A5\u5165 Slack \u673A\u5668\u4EBA":"Connect a Slack bot with a manifest and two tokens","\u4F7F\u7528 Bot Token \u63A5\u5165 Telegram \u673A\u5668\u4EBA":"Connect a Telegram bot with a Bot Token","\u4F7F\u7528 Bot Token \u63A5\u5165 Discord \u673A\u5668\u4EBA":"Connect a Discord bot with a Bot Token",\u53D6\u6D88\u7ED1\u5B9A:"Cancel setup",\u53D6\u6D88\u63A5\u5165:"Cancel setup","\u4E8C\u7EF4\u7801\u7531\u817E\u8BAF\u5FAE\u4FE1 iLink \u670D\u52A1\u7B7E\u53D1\u3002\u7528\u624B\u673A\u5FAE\u4FE1\u626B\u63CF\u5E76\u786E\u8BA4\u540E\uFF0C\u8D26\u53F7\u51ED\u636E\u4F1A\u76F4\u63A5\u5199\u5165 Harness Host\uFF0C\u6D4F\u89C8\u5668\u4E0D\u4F1A\u6536\u5230 bot_token\u3002":"The QR code is issued by Tencent WeChat iLink. After you scan and confirm, account credentials are written directly to the Harness Host and are never exposed to the browser.","\u626B\u7801\u8D26\u53F7\u5FC5\u987B\u5DF2\u52A0\u5165\u4F01\u4E1A/\u7EC4\u7EC7\u3002\u5982\u679C\u9489\u9489\u63D0\u793A\u5C1A\u672A\u52A0\u5165\u7EC4\u7EC7\uFF0C\u8BF7\u5728\u63D0\u793A\u9875\u521B\u5EFA\u7EC4\u7EC7\uFF0C\u6216\u6362\u7528\u5DF2\u52A0\u5165\u7EC4\u7EC7\u7684\u8D26\u53F7\u3002":"The DingTalk account must belong to an organization. If prompted, create an organization or use an account that already belongs to one.","\u8BF7\u5728\u624B\u673A\u4E0A\u6838\u5BF9\u5E76\u786E\u8BA4\u6388\u6743\u3002\u90E8\u5206\u8D26\u53F7\u4F1A\u989D\u5916\u663E\u793A\u4E00\u4E2A\u914D\u5BF9\u6570\u5B57\uFF0C\u9875\u9762\u4F1A\u5728\u9700\u8981\u65F6\u63D0\u793A\u8F93\u5165\u3002":"Review and confirm authorization on your phone. Some accounts may also require a pairing number.","\u6388\u6743\u7531\u9489\u9489\u5B98\u65B9\u9875\u9762\u5B8C\u6210\u3002\u626B\u7801\u8D26\u53F7\u5FC5\u987B\u5DF2\u52A0\u5165\u4E00\u4E2A\u4F01\u4E1A/\u7EC4\u7EC7\u5E76\u6709\u6743\u521B\u5EFA\u673A\u5668\u4EBA\uFF1B\u521B\u5EFA\u6210\u529F\u540E\uFF0C\u5E94\u7528\u51ED\u636E\u4F1A\u76F4\u63A5\u5199\u5165 Harness Host\u3002":"Authorization is completed on DingTalk\u2019s official page. The account must belong to an organization and be allowed to create bots. Credentials are written directly to the Harness Host.","\u626B\u7801\u7531\u817E\u8BAF\u5B98\u65B9\u9875\u9762\u5B8C\u6210\uFF0C\u4E0D\u9700\u8981\u624B\u52A8\u586B\u5199 AppID \u6216 AppSecret\u3002\u626B\u7801\u6210\u529F\u540E\uFF0C\u673A\u5668\u4EBA\u4F1A\u81EA\u52A8\u8FDE\u63A5 DeepSeek Harness\u3002":"Scanning is completed on Tencent\u2019s official page. No AppID or AppSecret is required, and the bot connects automatically.","\u626B\u7801\u7531\u817E\u8BAF\u5B98\u65B9\u9875\u9762\u5B8C\u6210\uFF0C\u4E0D\u9700\u8981\u624B\u52A8\u586B\u5199 Bot ID \u6216 Secret\u3002\u521B\u5EFA\u6210\u529F\u540E\uFF0C\u673A\u5668\u4EBA\u4F1A\u81EA\u52A8\u8FDE\u63A5 DeepSeek Harness\u3002":"Scanning is completed on Tencent\u2019s official page. No Bot ID or Secret is required, and the bot connects automatically.","\u817E\u8BAF\u9875\u9762\u4F1A\u521B\u5EFA\u6216\u7ED1\u5B9A\u4E00\u4E2A QQ \u673A\u5668\u4EBA\uFF0C\u5E76\u628A\u8FDE\u63A5\u51ED\u636E\u5B89\u5168\u4EA4\u7ED9\u672C\u673A Harness Host\u3002":"Tencent will create or connect a QQ bot and securely deliver its credentials to the local Harness Host.","\u4F01\u4E1A\u5FAE\u4FE1\u5B98\u65B9\u9875\u9762\u4F1A\u521B\u5EFA\u4E00\u4E2A\u667A\u80FD\u673A\u5668\u4EBA\uFF0C\u5E76\u628A\u8FDE\u63A5\u51ED\u636E\u5B89\u5168\u4EA4\u7ED9\u672C\u673A Harness Host\u3002":"WeCom will create an AI bot and securely deliver its credentials to the local Harness Host.","\u4ECE\u6B64 Harness \u79FB\u9664\u8FD9\u4E2A\u5FAE\u4FE1\u8D26\u53F7\uFF1F":"Remove this WeChat account from Harness?","\u8FD9\u4F1A\u505C\u6B62\u6D88\u606F\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u672C\u673A\u4FDD\u5B58\u7684 bot_token\u3001\u8D26\u53F7\u914D\u7F6E\u548C\u4F1A\u8BDD\u6620\u5C04\u3002\u5176\u4ED6\u5FAE\u4FE1\u8D26\u53F7\u4E0D\u53D7\u5F71\u54CD\u3002":"This stops the message connection and removes the locally stored bot_token, account configuration, and session mappings. Other WeChat accounts are not affected.","\u6B64\u64CD\u4F5C\u4F1A\u505C\u6B62\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u4FDD\u5B58\u5728\u672C\u673A\u7684\u63A5\u5165\u914D\u7F6E\u548C\u51ED\u636E\u3002\u98DE\u4E66\u5F00\u653E\u5E73\u53F0\u4E2D\u7684\u5E94\u7528\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E5F\u4E0D\u53D7\u5F71\u54CD\u3002":"This stops the bot connection and removes the locally stored configuration and credentials. The app in Feishu Open Platform is not deleted, and other bots are not affected.","\u8FD9\u4F1A\u505C\u6B62\u6D88\u606F\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u672C\u673A\u4FDD\u5B58\u7684\u5E94\u7528\u51ED\u636E\u3001\u673A\u5668\u4EBA\u914D\u7F6E\u53CA\u4F1A\u8BDD\u6620\u5C04\u3002\u9489\u9489\u5F00\u653E\u5E73\u53F0\u4E2D\u7684\u673A\u5668\u4EBA\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\u3002":"This stops the message connection and removes the locally stored app credentials, bot configuration, and session mappings. The bot in DingTalk Open Platform is not deleted.","\u8FD9\u4F1A\u505C\u6B62\u6D88\u606F\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u672C\u673A\u4FDD\u5B58\u7684\u5E94\u7528\u51ED\u636E\u3001\u673A\u5668\u4EBA\u914D\u7F6E\u53CA\u4F1A\u8BDD\u6620\u5C04\u3002\u4F01\u4E1A\u5FAE\u4FE1\u5E73\u53F0\u4E2D\u7684\u673A\u5668\u4EBA\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\u3002":"This stops the message connection and removes the locally stored app credentials, bot configuration, and session mappings. The bot in WeCom is not deleted.","\u8FD9\u4F1A\u505C\u6B62\u6D88\u606F\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u672C\u673A\u4FDD\u5B58\u7684\u5E94\u7528\u51ED\u636E\u3001\u673A\u5668\u4EBA\u914D\u7F6E\u53CA\u4F1A\u8BDD\u6620\u5C04\u3002\u817E\u8BAF\u5E73\u53F0\u4E2D\u7684\u673A\u5668\u4EBA\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\u3002":"This stops the message connection and removes the locally stored app credentials, bot configuration, and session mappings. The bot on Tencent\u2019s platform is not deleted.","\u8FD9\u4F1A\u505C\u6B62\u6D88\u606F\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u672C\u673A\u4FDD\u5B58\u7684 WhatsApp \u5173\u8054\u8BBE\u5907\u548C\u4F1A\u8BDD\u6620\u5C04\u3002":"This stops the message connection and removes the locally stored WhatsApp linked device and session mappings.",\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA\u5217\u8868:"Loading Feishu bots","\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u8FDE\u63A5\u72B6\u6001\u2026":"Loading Feishu connection status\u2026","\u6B63\u5728\u8BFB\u53D6\u5FAE\u4FE1\u8FDE\u63A5\u72B6\u6001\u2026":"Loading WeChat connection status\u2026","\u6B63\u5728\u8BFB\u53D6\u9489\u9489\u8FDE\u63A5\u72B6\u6001\u2026":"Loading DingTalk connection status\u2026","\u901A\u8FC7\u626B\u7801\u628A\u9489\u9489\u673A\u5668\u4EBA\u63A5\u5165 DeepSeek Harness":"Connect a DingTalk bot to DeepSeek Harness by QR code",\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u7ED1\u5B9A\u8FDB\u5EA6:"DingTalk did not return QR setup progress",\u9489\u9489\u626B\u7801\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u7ED1\u5B9A\u4EFB\u52A1:"DingTalk did not return a valid setup attempt","\u9489\u9489 Stream \u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38":"DingTalk Stream connection is healthy",\u9489\u9489\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u673A\u5668\u4EBA\u5217\u8868:"DingTalk did not return a valid bot list","${totals.connected} / ${totals.configured} \u5728\u7EBF":"${totals.connected} / ${totals.configured} online","\u7528\u4E8E\u628A\u9489\u9489\u673A\u5668\u4EBA\u63A5\u5165 DeepSeek Harness \u7684\u4E00\u6B21\u6027\u4E8C\u7EF4\u7801":"One-time QR code for connecting a DingTalk bot to DeepSeek Harness","\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\\n\u8BF7\u91CD\u65B0\u751F\u6210":"QR code expired\\nGenerate a new one","\u673A\u5668\u4EBA\u5DF2\u521B\u5EFA\uFF0C\u6B63\u5728\u5EFA\u7ACB\u6D88\u606F\u8FDE\u63A5":"Bot created. Starting the message connection",\u9489\u9489\u626B\u7801\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u5B89\u5168\u7684\u4E8C\u7EF4\u7801:"DingTalk did not return a secure QR code","\u9489\u9489\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\uFF0C\u8BF7\u4F7F\u7528\u9489\u9489 App \u626B\u63CF\u3002":"DingTalk QR code generated. Scan it with the DingTalk app.","\u9489\u9489\u673A\u5668\u4EBA\u51ED\u636E\u5DF2\u7ED1\u5B9A\u3002":"DingTalk bot credentials connected.","\u5DF2\u53D6\u6D88\u9489\u9489\u673A\u5668\u4EBA\u63A5\u5165\u3002":"DingTalk bot setup cancelled.","\u9489\u9489\u673A\u5668\u4EBA\u53CA\u672C\u673A\u51ED\u636E\u5DF2\u79FB\u9664\u3002":"DingTalk bot and local credentials removed.",\u98DE\u4E66\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u4E8C\u7EF4\u7801\u4FE1\u606F:"Feishu did not return QR code information",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u7684\u4E8C\u7EF4\u7801\u4FE1\u606F\u4E0D\u5B8C\u6574:"Feishu returned incomplete QR code information",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u673A\u5668\u4EBA\u72B6\u6001:"Feishu returned an invalid bot status","\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u7684\u673A\u5668\u4EBA\u7F3A\u5C11 botId":"The Feishu bot is missing botId",\u98DE\u4E66\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u8FDE\u63A5\u72B6\u6001:"Feishu did not return connection status",\u98DE\u4E66\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u521B\u5EFA\u8FDB\u5EA6:"Feishu did not return creation progress",\u98DE\u4E66\u670D\u52A1\u8FD4\u56DE\u4E86\u672A\u77E5\u7684\u521B\u5EFA\u72B6\u6001:"Feishu returned an unknown creation status","\u5DF2\u63A5\u5165 ${totals.configured} \u4E2A\u673A\u5668\u4EBA\uFF0C\u5176\u4E2D ${totals.connected} \u4E2A\u5728\u7EBF":"${totals.connected} of ${totals.configured} bots online",\u5C1A\u672A\u63A5\u5165\u673A\u5668\u4EBA:"No bot connected yet","\u7528\u4E8E\u65B0\u589E DeepSeek Harness \u98DE\u4E66\u673A\u5668\u4EBA\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801":"One-time authorization QR code for adding a Feishu bot to DeepSeek Harness",\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u626B\u7801:"Refresh and scan again",'${connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"}${bot.name}':'${connected ? "Check connection" : "Reconnect"} ${bot.name}',\u65E0\u6CD5\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA:"Could not load Feishu bots","\u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\uFF0C\u8BF7\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u3002":"Authorization QR code generated. Scan it with Feishu.","\u98DE\u4E66\u673A\u5668\u4EBA\u51ED\u636E\u5DF2\u7ED1\u5B9A\u3002":"Feishu bot credentials connected.","\u5DF2\u53D6\u6D88\u6DFB\u52A0\u673A\u5668\u4EBA\u3002":"Adding the bot was cancelled.","${newBot.bot.name}\u5DF2\u8FDE\u63A5\uFF0C\u53EF\u4EE5\u5728\u98DE\u4E66\u4E2D\u5F00\u59CB\u804A\u5929\u3002":"${newBot.bot.name} is connected and ready to chat in Feishu.","${bot.name}\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B\u673A\u5668\u4EBA\u72B6\u6001\u3002":"${bot.name} operation failed. Check the bot status.","${bot.name}\u5DF2\u4ECE\u6B64 DeepSeek Harness \u79FB\u9664\uFF1B\u98DE\u4E66\u5F00\u653E\u5E73\u53F0\u4E2D\u7684\u5E94\u7528\u672A\u88AB\u5220\u9664\u3002":"${bot.name} was removed from this DeepSeek Harness. The app in Feishu Open Platform was not deleted.",\u65E0\u6CD5\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001:"Could not load connection status","QQ \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u7ED1\u5B9A\u8FDB\u5EA6":"QQ did not return QR setup progress","QQ \u626B\u7801\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u7ED1\u5B9A\u4EFB\u52A1":"QQ did not return a valid setup attempt","QQ WebSocket \u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38":"QQ WebSocket connection is healthy","QQ \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u673A\u5668\u4EBA\u5217\u8868":"QQ did not return a valid bot list","\u5C1A\u672A\u7ED1\u5B9A QQ \u673A\u5668\u4EBA":"No QQ bot connected yet","\u7528\u4E8E\u7ED1\u5B9A QQ \u673A\u5668\u4EBA\u7684\u4E00\u6B21\u6027\u4E8C\u7EF4\u7801":"One-time QR code for connecting a QQ bot","${channel}${connectionSummary}\u8FD0\u884C\u6B63\u5E38":"${channel}${connectionSummary} is healthy","${channel} \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u673A\u5668\u4EBA\u5217\u8868":"${channel} did not return a valid bot list","\u4F7F\u7528 Bot Token \u63A5\u5165 ${channel} \u673A\u5668\u4EBA":"Connect a ${channel} bot with a Bot Token","${model.totals.connected} / ${model.totals.configured} \u5728\u7EBF":"${model.totals.connected}/${model.totals.configured} online"," Bot API \u957F\u8F6E\u8BE2":" Bot API long polling",\u4F01\u4E1A\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u7ED1\u5B9A\u8FDB\u5EA6:"WeCom did not return QR setup progress",\u4F01\u4E1A\u5FAE\u4FE1\u626B\u7801\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u7ED1\u5B9A\u4EFB\u52A1:"WeCom did not return a valid setup attempt","\u4F01\u4E1A\u5FAE\u4FE1 WebSocket \u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38":"WeCom WebSocket connection is healthy",\u4F01\u4E1A\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u673A\u5668\u4EBA\u5217\u8868:"WeCom did not return a valid bot list",\u5C1A\u672A\u7ED1\u5B9A\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA:"No WeCom bot connected yet",\u7528\u4E8E\u7ED1\u5B9A\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u7684\u4E00\u6B21\u6027\u4E8C\u7EF4\u7801:"One-time QR code for connecting a WeCom bot",\u5FAE\u4FE1\u626B\u7801\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u7ED1\u5B9A\u4EFB\u52A1:"WeChat did not return a valid setup attempt",\u5FAE\u4FE1\u7ED1\u5B9A\u6CA1\u6709\u5B8C\u6210:"WeChat setup did not complete",\u5FAE\u4FE1\u8FDE\u63A5\u6B63\u5E38:"WeChat connection is healthy",\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA:"WeChat connection is not ready","\u5F53\u524D\u6A21\u578B\u4E0D\u652F\u6301\u56FE\u7247\uFF0C\u8BF7\u7528 /models \u67E5\u770B\u53EF\u7528\u6A21\u578B\uFF0C\u518D\u7528 /model <\u5E8F\u53F7> \u5207\u6362\u540E\u91CD\u53D1\u3002":"The current model does not support images. Use /models to list models, then /model to switch and resend.","\u56FE\u7247\u8D85\u8FC7\u5BBF\u4E3B\u5141\u8BB8\u7684\u5927\u5C0F\uFF0C\u8BF7\u538B\u7F29\u540E\u91CD\u8BD5\u3002":"The image exceeds the Host size limit. Compress it and try again.","\u56FE\u7247\u5206\u8FA8\u7387\u8FC7\u9AD8\uFF0C\u8BF7\u538B\u7F29\u540E\u91CD\u8BD5\u3002":"The image resolution is too high. Compress it and try again.","\u56FE\u7247\u5185\u5BB9\u65E0\u6548\u6216\u683C\u5F0F\u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u3002":"The image is invalid or unsupported. Send it again.","\u672A\u80FD\u8BFB\u53D6\u56FE\u7247\u5185\u5BB9\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u3002":"The image could not be read. Send it again.","\u56FE\u7247\u683C\u5F0F\u4E0E\u5B9E\u9645\u5185\u5BB9\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u3002":"The declared image format does not match its content. Send it again.","\u4E00\u6B21\u53D1\u9001\u7684\u56FE\u7247\u6570\u91CF\u8D85\u8FC7\u5BBF\u4E3B\u9650\u5236\uFF0C\u8BF7\u51CF\u5C11\u540E\u91CD\u8BD5\u3002":"The message exceeds the Host image-count limit. Remove some images and try again.","\u56FE\u7247\u603B\u5927\u5C0F\u8D85\u8FC7\u5BBF\u4E3B\u9650\u5236\uFF0C\u8BF7\u51CF\u5C11\u56FE\u7247\u6216\u538B\u7F29\u540E\u91CD\u8BD5\u3002":"The images exceed the Host total-size limit. Remove or compress some images and try again.","\u56FE\u7247\u4E0B\u8F7D\u5730\u5740\u53D1\u751F\u4E86\u91CD\u5B9A\u5411\uFF0C\u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u3002":"The image download redirected and cannot be read.","\u56FE\u7247\u8D85\u8FC7 5 MB\uFF0C\u8BF7\u538B\u7F29\u540E\u91CD\u8BD5\u3002":"The image exceeds 5 MB. Compress it and try again.","\u4E00\u6B21\u53D1\u9001\u7684\u56FE\u7247\u603B\u5927\u5C0F\u8FC7\u5927\uFF0C\u8BF7\u51CF\u5C11\u56FE\u7247\u6570\u91CF\u6216\u538B\u7F29\u540E\u91CD\u8BD5\u3002":"The images are too large in total. Remove or compress some images and try again.","\u56FE\u7247\u4E0B\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u9001\u540E\u518D\u8BD5\u3002":"The image download failed. Send it again.","\u6682\u4E0D\u652F\u6301\u8BE5\u56FE\u7247\u683C\u5F0F\uFF0C\u8BF7\u53D1\u9001 JPEG\u3001PNG\u3001WebP \u6216 GIF \u56FE\u7247\u3002":"This image format is unsupported. Send a JPEG, PNG, WebP, or GIF image.","\u6D88\u606F\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002":"Message processing failed. Try again later.",\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u8D26\u53F7\u5217\u8868:"WeChat did not return a valid account list",\u5C1A\u672A\u7ED1\u5B9A\u5FAE\u4FE1:"No WeChat account connected yet","\u7528\u4E8E\u628A\u5FAE\u4FE1\u673A\u5668\u4EBA\u7ED1\u5B9A\u5230 DeepSeek Harness \u7684\u4E00\u6B21\u6027\u4E8C\u7EF4\u7801":"One-time QR code for connecting a WeChat bot to DeepSeek Harness","\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6D88\u606F\u957F\u8F6E\u8BE2\u53D8\u4E3A\u5728\u7EBF":"Keep this page open until long polling is online","\u5FAE\u4FE1\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210\uFF0C\u8BF7\u4F7F\u7528\u624B\u673A\u5FAE\u4FE1\u626B\u63CF\u3002":"WeChat QR code generated. Scan it with WeChat on your phone.","\u79FB\u9664\u5931\u8D25\uFF1A${presentError(error).message}":"Removal failed: ${presentError(error).message}",\u65E0\u6CD5\u8BFB\u53D6\u5FAE\u4FE1\u72B6\u6001:"Could not load WeChat status","WhatsApp \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u626B\u7801\u8FDB\u5EA6":"WhatsApp did not return QR setup progress","WhatsApp \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u626B\u7801\u4EFB\u52A1":"WhatsApp did not return a valid setup attempt","WhatsApp \u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u7684\u673A\u5668\u4EBA\u5217\u8868":"WhatsApp did not return a valid account list","\u7528\u4E8E\u5173\u8054 WhatsApp \u8BBE\u5907\u7684\u4E00\u6B21\u6027\u4E8C\u7EF4\u7801":"One-time QR code for linking a WhatsApp device"});var H9e=Object.freeze(Object.fromEntries(Object.keys(Cwe).map(n=>[n,n==="$locale"?"zh":n])));var K9e=Object.freeze(["aria-label","alt","placeholder","title"]);var hwe=Object.freeze({defaultId:"",items:Object.freeze([])}),J9e=ap.createContext(hwe);var DR="/feishu",wt=Object.freeze({status:"connection.status",beginProvisioning:"provision.begin",beginCallbackRepair:"bot.callback-repair.begin",beginGroupMessagePermission:"bot.group-message-permission.begin",pollProvisioning:"provision.poll",cancelProvisioning:"provision.cancel",bindCredentials:"bot.bind-credentials",reconnectBot:"bot.reconnect",disconnectBot:"bot.disconnect",deleteBot:"bot.delete",setWorkspace:"bot.workspace.set",setAgentPreset:"bot.preset.set",setGroupResponseMode:"bot.group-response-mode.set",testConnection:"connection.test",disconnect:"connection.disconnect"}),Z9e=Object.freeze({PROVISION:"provision",CALLBACK_REPAIR:"callback_repair",GROUP_MESSAGE_PERMISSION:"group_message_permission"});var xc=Object.freeze({reconnectBot:"bot.reconnect",disconnectBot:"bot.disconnect",deleteBot:"bot.delete"}),h4=Object.freeze([...new Set([...Object.values(wt),...Object.values(xc)])]),uwe=new Set(["idle","starting","qr_ready","polling","slow_down","domain_switched","saving","succeeded","expired","cancelled","error"]),Bwe=new Set(["provision","callback_repair","group_message_permission"]),d4="callback_repair",OR="group_message_permission",ry=new Set([d4,OR]),fwe=new Set(["accounts.feishu.cn","accounts.larksuite.com","open.feishu.cn","open.larksuite.com"]),Qwe=/^[A-Za-z0-9_-]{1,128}$/,ywe=/^cli_[A-Za-z0-9_-]+$/,l4=Object.freeze({abort:"Registration was cancelled.",access_denied:"Registration was denied.",expired_token:"The registration QR code expired.",invalid_credentials:"Feishu returned invalid app credentials.",credentials_callback_failed:"Unable to activate the Feishu connection.",registration_failed:"Unable to register the Feishu app.",connection_failed:"The bot was created, but its connection could not be started.",credential_removal_failed:"Unable to remove the Feishu credentials.",state_cleanup_failed:"Unable to remove the bot session data. Please retry.",deletion_pending:"Bot deletion is incomplete. Retry removal to finish cleanup.",missing_credentials:"The bot credentials are missing. Delete it and scan again.",repair_app_mismatch:"The authorized Feishu app does not match the selected bot.",repair_owner_missing:"Feishu did not return the authorizing account identity.",repair_domain_mismatch:"The authorized Feishu tenant does not match the selected bot.",repair_owner_mismatch:"The authorizing Feishu account is not an owner of the selected bot.",repair_credentials_invalid:"Feishu returned credentials that could not be verified for the selected bot.",repair_bot_mismatch:"The verified Feishu bot does not match the selected bot.",repair_target_changed:"The selected bot changed while repair was in progress. Start the repair again.",credential_update_failed:"Unable to store the repaired Feishu credentials.",credential_state_unknown:"The repaired Feishu credentials could not be confirmed after saving.",repair_connection_failed:"The callback update was accepted, but the selected bot could not reconnect.",group_message_permission_required:"Authorize access to all group messages before enabling this mode.",group_message_permission_save_failed:"Feishu granted the permission, but all-message mode could not be saved.",group_message_permission_connection_failed:"Feishu granted the permission, but the selected bot could not reconnect.",card_action_probe_unavailable:"The selected bot is not connected, so its card button cannot be verified.",card_action_probe_send_failed:"The callback update was accepted, but the verification card could not be sent.",card_action_probe_timeout:"Feishu accepted the update, but the card button was not verified in time. Start the repair again and click the test button within two minutes.",card_action_probe_failed:"Feishu accepted the update, but the card button verification failed."}),mwe=Object.freeze({idle:"pending",starting:"pending",qr_ready:"pending",polling:"pending",slow_down:"pending",domain_switched:"pending",saving:"connecting",succeeded:"connected",expired:"expired",cancelled:"failed",error:"failed"});function Swe(n){if(n===null||typeof n!="object"||Array.isArray(n))return!1;let r=Object.getPrototypeOf(n);return r===Object.prototype||r===null}function to(n,r){return Swe(n)&&Reflect.ownKeys(n).every(o=>typeof o=="string"&&r.has(o))}function Rh(n){return Number.isFinite(n)?n:void 0}function Go(n){return typeof n=="string"&&Qwe.test(n)}function p4(n,r){return typeof n=="string"&&n.trim().length>0&&n.length<=r}function MR(n){if(!n||typeof n!="object")return null;let r=typeof n.code=="string"&&Object.hasOwn(l4,n.code)?n.code:"registration_failed";return{code:r,message:l4[r]}}function un(n){if(!n||typeof n!="object")return{state:"idle",attempt:0};let r=uwe.has(n.state)?n.state:"error",o=Go(n.attempt)?n.attempt:Rh(n.attempt)??0,i={state:r,attempt:o};i.operation=Bwe.has(n.operation)?n.operation:"provision";let e=Rh(n.updatedAt),a=Rh(n.expiresAt),A=Rh(n.remainingSeconds),t=Rh(n.pollIntervalSeconds);e!==void 0&&(i.updatedAt=e),typeof n.qrCodeUrl=="string"&&n.qrCodeUrl.length>0&&(i.qrCodeUrl=n.qrCodeUrl),a!==void 0&&(i.expiresAt=a),A!==void 0&&(i.remainingSeconds=A),t!==void 0&&(i.pollIntervalSeconds=t),Go(n.botId)&&(i.botId=n.botId);let s=MR(n.error);return s&&(i.error=s),i}function Dwe(n,r,o){if(!(typeof n!="string"||n.length===0))try{let i=new URL(n);if(i.protocol!=="https:"||!fwe.has(i.hostname)||i.port||i.username||i.password)return;if(ry.has(r)){let e=i.searchParams.getAll("clientID"),a=i.searchParams.getAll("tp"),A=i.searchParams.getAll("addons"),t=[...i.searchParams.values()].some(s=>s.includes("{{")||s.includes("}}"));if(e.length!==1||a.length!==1||a[0]!=="sdk"||!ywe.test(e[0]??"")||i.hostname!==o||i.searchParams.has("createOnly")||A.length!==1||!A[0]?.trim()||t)return}return i.toString()}catch{return}}function ay(n){let r=n&&typeof n=="object"?n:{};return{connected:r.connected===!0||r.ready===!0&&r.feishuLongConnectionState==="connected"&&r.harnessReachable===!0,ready:r.ready===!0,harnessReachable:r.harnessReachable===!0}}function u4(n){let r=n&&typeof n=="object"?n:{},o={name:typeof r.name=="string"&&r.name.length>0?r.name:"\u98DE\u4E66\u673A\u5668\u4EBA"};return typeof r.avatarUrl=="string"&&(o.avatarUrl=r.avatarUrl),typeof r.appIdMasked=="string"&&(o.appIdMasked=r.appIdMasked),typeof r.tenantName=="string"&&(o.tenantName=r.tenantName),(r.domain==="feishu"||r.domain==="lark")&&(o.domain=r.domain),(typeof r.activated=="boolean"||typeof r.activated=="number")&&(o.activated=r.activated),o}function B4(n,r){return r?{status:"healthy",summary:"\u957F\u8FDE\u63A5\u8FD0\u884C\u6B63\u5E38",lastCheckedAt:Date.now()}:n?.configured===!0?{status:"offline",summary:"\u673A\u5668\u4EBA\u5C1A\u672A\u8FDE\u63A5",lastCheckedAt:Date.now()}:{status:"offline",summary:"\u5C1A\u672A\u63A5\u5165\u98DE\u4E66\u673A\u5668\u4EBA",lastCheckedAt:Date.now()}}function f4(n,r,o){return o?"connected":n?.phase==="error"||r.state==="error"?"error":n?.phase==="connecting"||r.state==="saving"?"connecting":n?.phase==="registering"||["starting","qr_ready","polling","slow_down","domain_switched"].includes(r.state)?"provisioning":"disconnected"}async function Q4(n){return dwe.toDataURL(n,{errorCorrectionLevel:"M",margin:1,width:320,type:"image/png"})}async function wwe(n,r,o){let i=Dwe(n.qrCodeUrl,n.operation,o),e={attemptId:String(n.attempt),operation:n.operation,...n.botId?{botId:n.botId}:{},expiresAt:n.expiresAt??Date.now()+5*6e4,pollIntervalMs:Math.max(800,Math.min(1e4,(n.pollIntervalSeconds??1.8)*1e3))};if(i)return{...e,verificationUrl:i,qrCodeDataUrl:await r(i)};if(n.state==="saving"&&ry.has(n.operation)&&n.botId)return{...e,submitted:!0}}function Owe(n){let r=n&&typeof n=="object"?n:{};if(!Go(r.botId))return null;let o=ay(r.connection),i=r.connected===!0||o.connected,e={state:"idle"},a={botId:r.botId,state:f4(r,e,i),connected:i,configured:r.configured===!0,agentPreset:Zn(r.agentPreset),groupResponseMode:Mi(r.groupResponseMode),groupMessagePermissionGranted:r.groupMessagePermissionGranted===!0,bot:u4(r.bot),health:B4(r,i)};typeof r.workspace=="string"&&r.workspace&&(a.workspace=r.workspace);let A=MR(r.error);return A&&(a.error=A),a}async function Ta(n,{encodeQr:r=Q4}={}){let o=n&&typeof n=="object"?n:{},i=un(o.registration),e=ay(o.connection),a=o.connected===!0||e.connected,t=(ry.has(i.operation)&&i.botId&&Array.isArray(o.bots)?o.bots.find(E=>E?.botId===i.botId):void 0)?.bot?.domain==="lark"?"open.larksuite.com":"open.feishu.cn",s=await wwe(i,r,t),g=MR(o.error)??i.error??null,c=Array.isArray(o.bots)?o.bots.map(Owe).filter(Boolean):[],I={schemaVersion:o.schemaVersion===2?2:1,revision:Number.isSafeInteger(o.revision)&&o.revision>=0?o.revision:0,state:f4(o,i,a),connected:a,configured:o.configured===!0,bot:u4(o.bot),health:B4(o,a),bots:c,agentPresetCatalog:rn(o.agentPresetCatalog),totals:{configured:c.length||(o.configured===!0?1:0),connected:c.length?c.filter(E=>E.connected).length:a?1:0}};return s&&(I.provisioning=s),g&&(I.error=g),I}function Ay(n){return{ok:!1,error:{code:"bad-request",message:n,details:{issues:[]}}}}function ty(){return{ok:!1,error:{code:"cancelled",message:"The Feishu request was cancelled.",details:{}}}}function bwe(){return{ok:!1,error:{code:"internal",message:"The Feishu integration operation failed.",details:{}}}}function Mwe(n,r){return n===wt.status?to(r,new Set)?null:"This endpoint accepts an empty payload only.":n===wt.testConnection?to(r,new Set)?null:"This endpoint accepts an empty payload only.":n===wt.beginProvisioning?to(r,new Set(["locale","replaceAttemptId"]))?r.locale!==void 0&&r.locale!=="zh-CN"?"The provisioning locale must be zh-CN.":r.replaceAttemptId!==void 0&&!Go(r.replaceAttemptId)?"replaceAttemptId must be a valid opaque id.":null:"Provisioning accepts locale and replaceAttemptId only.":n===wt.beginCallbackRepair?to(r,new Set(["botId"]))&&Go(r.botId)?null:"Callback repair requires a single valid botId.":n===wt.beginGroupMessagePermission?to(r,new Set(["botId"]))&&Go(r.botId)?null:"Group message permission update requires a single valid botId.":n===wt.bindCredentials?to(r,new Set(["appId","appSecret"]))&&p4(r.appId,256)&&p4(r.appSecret,1024)?null:"Credential binding requires App ID and App Secret.":n===wt.pollProvisioning||n===wt.cancelProvisioning?to(r,new Set(["attemptId"]))&&Go(r.attemptId)?null:"A single valid attemptId is required.":n===wt.disconnect?to(r,new Set(["removeCredentials"]))&&r.removeCredentials===!0?null:"Disconnect requires removeCredentials=true.":n===xc.reconnectBot?to(r,new Set(["botId","sendTest"]))&&Go(r.botId)&&(r.sendTest===void 0||typeof r.sendTest=="boolean")?null:"A valid botId and optional sendTest flag are required.":n===xc.disconnectBot?to(r,new Set(["botId"]))&&Go(r.botId)?null:"A single valid botId is required.":n===xc.deleteBot?to(r,new Set(["botId","confirm"]))&&Go(r.botId)&&r.confirm===!0?null:"Deleting a bot requires a valid botId and confirm=true.":n===wt.setWorkspace?fa(r)?null:"\u8BF7\u8F93\u5165\u5DE5\u4F5C\u533A\u7EDD\u5BF9\u8DEF\u5F84\u3002":n===wt.setAgentPreset?ya(r)?null:"\u8BF7\u9009\u62E9 Agent Preset\u3002":n===wt.setGroupResponseMode?to(r,new Set(["botId","groupResponseMode"]))&&Go(r.botId)&&NQ(r.groupResponseMode)?null:"\u8BF7\u9009\u62E9\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u3002":"Unknown Feishu endpoint."}function _we(n,r){return new Promise((o,i)=>{if(r?.aborted){i(r.reason??new Error("aborted"));return}let e=setTimeout(a,n);e.unref?.();function a(){r?.removeEventListener("abort",A),o()}function A(){clearTimeout(e),i(r.reason??new Error("aborted"))}r?.addEventListener("abort",A,{once:!0})})}async function bR(n,r){return typeof n.registrationStatus=="function"?n.registrationStatus(r):n.status()}async function wR(n,r,o,i){let e=r,a=Date.now()+15e3;for(;;){let A=un(e?.registration);if(A.qrCodeUrl)return e;if(["error","expired","cancelled"].includes(A.state))throw new Error("Provisioning stopped before the QR code was ready.");if(Date.now()>=a)throw new Error("Provisioning QR code timed out.");if(await _we(50,i),e=await bR(n,o),!e)throw new Error("The provisioning attempt is no longer active.")}}function E4(n,r){return String(un(n?.registration).attempt)===r}function C4(n){let r=un(n?.registration);return r.state==="succeeded"?r.botId&&(n?.connected===!0||ay(n?.connection).connected)?"connected":"connecting":mwe[r.state]??"failed"}function Nwe(n){if(!n||typeof n.status!="function"||typeof n.startRegistration!="function"||typeof n.cancelRegistration!="function"||typeof n.disconnect!="function")throw new TypeError("A Feishu controller with status/start/cancel/disconnect is required")}function y4(n,{encodeQr:r=Q4}={}){Nwe(n);let o=new Map,i=new Map,e=a=>{let A=o.get(a);return A||(o.size>=32&&o.delete(o.keys().next().value),A=Promise.resolve().then(()=>r(a)),o.set(a,A)),A};return async(a,A,t)=>{if(t?.aborted)return ty();if(!h4.includes(a))return Ay("Unknown Feishu endpoint.");let s=Mwe(a,A);if(s)return Ay(s);try{let g;if(a===wt.status)g=await Ta(await n.status(),{encodeQr:e});else if(a===wt.beginProvisioning){A.replaceAttemptId&&await n.cancelRegistration(A.replaceAttemptId);let c=await n.startRegistration({locale:A.locale}),I=String(un(c?.registration).attempt),E=await wR(n,c,I,t);if(g=(await Ta(E,{encodeQr:e})).provisioning,!g)throw new Error("Provisioning did not produce a QR code.");i.set(I,g.verificationUrl)}else if(a===wt.beginCallbackRepair){if(typeof n.startCallbackRepair!="function")throw new Error("Feishu callback repair is unavailable.");let c=await n.startCallbackRepair(A.botId),I=String(un(c?.registration).attempt),E=await wR(n,c,I,t);if(g=(await Ta(E,{encodeQr:e})).provisioning,!g||g.operation!==d4||g.botId!==A.botId)throw new Error("Callback repair did not produce a safe QR code.");i.set(I,g.verificationUrl)}else if(a===wt.beginGroupMessagePermission){if(typeof n.startGroupMessagePermission!="function")throw new Error("Feishu group message permission update is unavailable.");let c=await n.startGroupMessagePermission(A.botId),I=String(un(c?.registration).attempt),E=await wR(n,c,I,t);if(g=(await Ta(E,{encodeQr:e})).provisioning,!g||g.operation!==OR||g.botId!==A.botId)throw new Error("Group message permission update did not produce a safe QR code.");i.set(I,g.verificationUrl)}else if(a===wt.pollProvisioning){let c=await bR(n,A.attemptId);if(!c||!E4(c,A.attemptId))return Ay("The provisioning attempt is no longer active.");let I=un(c.registration),E=await Ta(c,{encodeQr:e});if(g={status:C4(c),operation:I.operation,...I.botId?{botId:I.botId}:{},...E.provisioning?{provisioning:E.provisioning}:{},...I.botId&&E.connected?{connection:E}:{},...E.error?{message:E.error.message}:{}},["connected","expired","failed"].includes(g.status)){let B=i.get(A.attemptId);B&&o.delete(B),i.delete(A.attemptId)}}else if(a===wt.cancelProvisioning){let c=await bR(n,A.attemptId);if(!c||!E4(c,A.attemptId))return Ay("The provisioning attempt is no longer active.");let I=typeof n.registrationStatus=="function",E=un(c.registration),B;!I&&E.state==="saving"?B=await n.disconnect():B=await n.cancelRegistration(A.attemptId);let f=un(B?.registration);if(ry.has(E.operation)&&E.state==="saving"&&["saving","succeeded"].includes(f.state)&&(g={status:C4(B),operation:f.operation,...f.botId?{botId:f.botId}:{},message:E.operation===OR?"The permission update was already submitted and is still being applied.":"Callback repair was already submitted and is still being verified."}),g?.status!=="connecting"){let Q=i.get(A.attemptId);Q&&o.delete(Q),i.delete(A.attemptId),g??={status:"failed",operation:E.operation,...E.botId?{botId:E.botId}:{},message:"Registration was cancelled."}}}else if(a===wt.bindCredentials){if(typeof n.bindCredentials!="function")throw new Error("Credential binding is unavailable");g=await Ta(await n.bindCredentials(A),{encodeQr:e})}else if(a===wt.testConnection){let c=await n.status(),E=c?.connected===!0||ay(c?.connection).connected||typeof n.reconnect!="function"?c:await n.reconnect();g=await Ta(E,{encodeQr:e})}else if(a===wt.disconnect)g=await Ta(await n.disconnect(),{encodeQr:e});else if(a===xc.reconnectBot){if(typeof n.reconnectBot!="function")throw new Error("Multi-bot reconnect is unavailable");let c=await n.reconnectBot(A.botId);if(t?.aborted)return ty();if(g=await Ta(c,{encodeQr:e}),A.sendTest===!0){let I=null;if(!(c?.bots?.some(B=>B?.botId===A.botId&&B.connected===!0)===!0))I=new Error("Feishu bot is not connected"),I.code="test-target-unavailable";else try{if(typeof n.sendConnectionTest!="function"){let B=new Error("Connection test is unavailable");throw B.code="test-target-unavailable",B}await n.sendConnectionTest(A.botId)}catch(B){I=B}g={...g,testMessage:Vt(I)}}}else if(a===xc.disconnectBot){if(typeof n.disconnectBot!="function")throw new Error("Multi-bot disconnect is unavailable");g=await Ta(await n.disconnectBot(A.botId),{encodeQr:e})}else if(a===wt.setWorkspace){if(typeof n.updateWorkspace!="function")throw new Error("Workspace update is unavailable");g=await Ta(await n.updateWorkspace(A.botId,A.workspace),{encodeQr:e})}else if(a===wt.setAgentPreset){if(typeof n.updateAgentPreset!="function")throw new Error("Agent preset update is unavailable");g=await Ta(await n.updateAgentPreset(A.botId,A.agentPreset),{encodeQr:e})}else if(a===wt.setGroupResponseMode){if(typeof n.updateGroupResponseMode!="function")throw new Error("Group response mode update is unavailable");g=await Ta(await n.updateGroupResponseMode(A.botId,A.groupResponseMode),{encodeQr:e})}else{if(typeof n.deleteBot!="function")throw new Error("Multi-bot delete is unavailable");g=await Ta(await n.deleteBot(A.botId),{encodeQr:e})}return t?.aborted?ty():{ok:!0,value:g}}catch(g){let c=Qa(g);return t?.aborted?ty():c?{ok:!1,error:{...c,details:{}}}:bwe()}}}function iy(n,r,o,i){if(!n?.connection?.rpc||typeof n.connection.rpc.handle!="function")throw new TypeError("DSH Host Connection RPC is required");return n.connection.rpc.handle(DR,y4(r,o),{authority:Cr(i)})}function Twe(n,r){if(r?.controller)return r.controller;if(typeof r?.createController=="function")return r.createController();if(typeof r?.createProvisioningManager=="function")return ib(r)}async function m4(n,r={}){let o=Twe(n,r);if(o)return iy(n,o,r.rpcOptions,r.rpcAuthority);let i=await dR(n,r),e=iy(n,i.controller,r.rpcOptions,r.rpcAuthority);return n.effect(()=>async()=>{await i.close()},"dsh-feishu: close controller and live connection"),e}import{unlink as gOe}from"node:fs/promises";import{homedir as cOe}from"node:os";import{join as Gh,resolve as qc}from"node:path";import{createHash as Rwe}from"node:crypto";import{mkdir as kwe,readFile as vwe,rename as Pwe,unlink as Gwe,writeFile as Fwe}from"node:fs/promises";import{dirname as Lwe}from"node:path";var _R=Object.freeze({version:1,bots:Object.freeze([])});function Cg(n){return typeof n=="string"&&n.trim()?n.trim():null}function S4(n){let r=Cg(n);return r&&/^qq_[a-f0-9]{24}$/.test(r)?r:null}function Uwe(n){let r=Cg(n);return r&&/^DSH_QQBOT_APP_SECRET_[A-F0-9]{24}$/.test(r)?r:null}function ny(n){let r=Cg(n);if(!r)throw new TypeError("appId is required");let o=Rwe("sha256").update(r).digest("hex").slice(0,24);return{botId:`qq_${o}`,secretRef:`DSH_QQBOT_APP_SECRET_${o.toUpperCase()}`}}function NR(n){let r=Cg(n)??"";return r.length<=10?r?`${r.slice(0,3)}\u2022\u2022\u2022`:"QQ\u673A\u5668\u4EBA":`${r.slice(0,6)}\u2022\u2022\u2022\u2022${r.slice(-4)}`}function D4(n){if(!n||typeof n!="object")return null;let r=Cg(n.appId),o=Cg(n.ownerUserOpenid),i=S4(n.botId),e=Uwe(n.secretRef);if(!r||!o||!i||!e)return null;let a=ny(r);return a.botId!==i||a.secretRef!==e?null:Object.freeze({botId:i,appId:r,secretRef:e,ownerUserOpenid:o,createdAt:Cg(n.createdAt)??new Date().toISOString(),connectedAt:Cg(n.connectedAt)})}function Hwe(n){if(!n||n.version!==1||!Array.isArray(n.bots))return null;let r=n.bots.map(D4);if(r.some(a=>a===null))return null;let o=new Set,i=new Set,e=new Set;for(let a of r){if(o.has(a.botId)||i.has(a.appId)||e.has(a.secretRef))return null;o.add(a.botId),i.add(a.appId),e.add(a.secretRef)}return Object.freeze({version:1,bots:Object.freeze(r)})}var oy=class{#e;#A=_R;#t=Promise.resolve();constructor(r){this.#e=r}async load(){try{let r=Hwe(JSON.parse(await vwe(this.#e,"utf8")));if(!r)throw new Error("dsh-im QQ config contains invalid bot data");this.#A=r}catch(r){if(r?.code!=="ENOENT")throw r;this.#A=_R}return this}list(){return structuredClone(this.#A.bots)}get(r){let o=this.#A.bots.find(i=>i.botId===r);return o?structuredClone(o):null}getByAppId(r){let o=this.#A.bots.find(i=>i.appId===r);return o?structuredClone(o):null}async save(r){let o=D4(r);if(!o)throw new Error("Refusing to persist incomplete QQ bot data");return this.#r(i=>{let e=i.find(t=>t.appId===o.appId&&t.botId!==o.botId),a=i.find(t=>t.secretRef===o.secretRef&&t.botId!==o.botId);if(e||a)throw new Error("Duplicate QQ bot identity");let A=i.findIndex(t=>t.botId===o.botId);return A===-1?i.push(o):i[A]=o,structuredClone(o)})}async remove(r){if(!S4(r))throw new TypeError("Invalid QQ bot id");return this.#r(o=>{let i=o.findIndex(a=>a.botId===r);if(i===-1)return null;let[e]=o.splice(i,1);return structuredClone(e)})}async clear(){let r=this.#t.then(async()=>{try{await Gwe(this.#e)}catch(o){if(o?.code!=="ENOENT")throw o}this.#A=_R});this.#t=r.then(()=>{},()=>{}),await r}async#r(r){let o,i=this.#t.then(async()=>{let e=[...this.#A.bots];o=r(e);let a=Object.freeze({version:1,bots:Object.freeze(e)});await this.#n(a),this.#A=a});return this.#t=i.then(()=>{},()=>{}),await i,o}async#n(r){await kwe(Lwe(this.#e),{recursive:!0,mode:448});let o=`${this.#e}.tmp`;await Fwe(o,`${JSON.stringify(r,null,2)} diff --git a/src/channels/feishu/bridge.mjs b/src/channels/feishu/bridge.mjs index 23153fd..7c55359 100644 --- a/src/channels/feishu/bridge.mjs +++ b/src/channels/feishu/bridge.mjs @@ -655,7 +655,7 @@ export class FeishuHarnessBridge { return; } if (MENU_COMMAND.test(commandText)) { - await this.#sendMenuCard(key, event.message.chat_id); + await this.#sendMenuCard(key, event.message.chat_id, { newCard: true }); return; } if (commandText === '/new') { @@ -1508,7 +1508,7 @@ export class FeishuHarnessBridge { return messageId; } - async #sendMenuCard(key, chatId) { + async #sendMenuCard(key, chatId, { newCard = false } = {}) { let workspaces = []; let currentWorkspace = null; try { @@ -1566,7 +1566,7 @@ export class FeishuHarnessBridge { currentSession: currentSessionId ? { id: currentSessionId, title: currentSessionTitle } : null, sessions, archiveVisible, }), - { key, update: true }, + { key, update: !newCard }, ); }