@leviyuan/lodestar 0.17.4 → 0.17.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lodestar.js CHANGED
@@ -1,49 +1,89 @@
1
1
  #!/usr/bin/env node
2
- var gz=Object.defineProperty;var mz=($)=>$;function cz($,Z){this[$]=mz.bind(null,Z)}var P0=($,Z)=>{for(var J in Z)gz($,J,{get:Z[J],enumerable:!0,configurable:!0,set:cz.bind(Z,J)})};var T=($,Z)=>()=>($&&(Z=$($=0)),Z);import{homedir as uz}from"node:os";import{join as d}from"node:path";function HJ($,Z,J){if($)return $;if(Z)return d(Z,"lodestar");return J}function pz(){if(WJ)return d(process.env.APPDATA??d(V9,"AppData","Roaming"),"Lodestar");return d(V9,".config","lodestar")}function lz(){if(WJ)return d(process.env.LOCALAPPDATA??d(V9,"AppData","Local"),"Lodestar");return d(V9,".local","share","lodestar")}var V9,WJ,O5,o,U$,i$,i1,T5,N5,E5,S5,k5,X9,X1,z9,z1,d1,VJ,XJ,zJ,x5,GJ,_J,C5,b5,G1,G9;var W$=T(()=>{V9=uz(),WJ=process.platform==="win32";O5=HJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,pz()),o=HJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,lz()),U$=process.env.LODESTAR_CONFIG??d(O5,"config.toml"),i$=d(o,"daemon.pid"),i1=d(o,"daemon.log"),T5=d(o,"session-chat-map.json"),N5=d(o,"session-resume-map.json"),E5=d(o,"session-turns-map.json"),S5=d(o,"session-model-map.json"),k5=d(o,"temp-session-leases.json"),X9=d(o,"tasklist-map.json"),X1=d(o,"agent-runs"),z9=d(o,"agent-session-ids.json"),z1=d(o,"managed-claude-plugin"),d1=d(o,"dsh"),VJ=d(o,"codex-accounts"),XJ=d(o,"codex-accounts.json"),zJ=d(o,"codex-quota-blocks.json"),x5=d(o,"agent-runtimes"),GJ=d(o,"context-window-cache.json"),_J=d(o,"notify-callbacks.json"),C5=d(o,"alive-on-shutdown.json"),b5=d(o,"inbox"),G1=d(o,"debug.sock"),G9=d(o,"debug-context.json")});import{execSync as KJ}from"node:child_process";import{readFileSync as BJ,writeFileSync as iz}from"node:fs";function dz(){return process.argv[1]??`pid:${process.pid}`}function nz($){try{if(process.platform==="linux")return BJ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return KJ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return KJ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function az($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=nz($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function _9($){let Z="";try{Z=BJ($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
- `),Y=parseInt((J[0]??"").trim(),10),Q=(J[1]??"").trim();if(!Number.isFinite(Y)||Y<=0)return{state:"continue"};if(!Q)try{return process.kill(Y,0),{state:"exit",pid:Y}}catch{return{state:"continue"}}if(az(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function AJ($){iz($,`${process.pid}
4
- ${dz()}`)}var y5=()=>{};import{chmodSync as oz,closeSync as w5,fsyncSync as qJ,mkdirSync as rz,openSync as PJ,renameSync as tz,unlinkSync as sz,writeFileSync as ez}from"node:fs";import{randomUUID as $G}from"node:crypto";import{dirname as LJ}from"node:path";function QG($){let Z=LJ($);rz(Z,{recursive:!0,mode:YG})}function jJ($,Z,J){QG($);let Y=`${$}.${process.pid}.${$G()}.tmp`,Q=null;try{Q=PJ(Y,"wx",J),ez(Q,Z),qJ(Q),w5(Q),Q=null,tz(Y,$);try{oz($,J)}catch{}if(process.platform!=="win32"){let W=null;try{W=PJ(LJ($),"r"),qJ(W)}catch{}finally{if(W!==null)try{w5(W)}catch{}}}}catch(W){if(Q!==null)try{w5(Q)}catch{}try{sz(Y)}catch{}throw W}}function $0($,Z){jJ($,Z,ZG)}function DJ($,Z){jJ($,Z,JG)}function t($,Z){$0($,JSON.stringify(Z,null,2)+`
5
- `)}var ZG=384,JG=448,YG=448;var w$=()=>{};import{execFile as WG}from"node:child_process";import{spawn as HG}from"cross-spawn";function XG($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{WG("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Y,Q,W)=>{if(Y)J(Error(`taskkill npm installer PID ${$} failed: ${Y.message}
6
- ${Q}${W}`));else Z()})})}async function f5($,Z,J={}){Z?.throwIfAborted();let Y=J.platform??process.platform,Q=J.timeoutMs??300000,W=J.terminationTimeoutMs??1e4;return await new Promise((H,V)=>{let X=(J.spawn??HG)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${VG}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),z="",G,K,B=!1,A=!1,P,L=(k)=>{z=(z+k.toString()).slice(-16384)};X.stdout.on("data",L),X.stderr.on("data",L);let j=(k)=>{if(B)return;if(B=!0,clearTimeout(M),P)clearTimeout(P);if(Z?.removeEventListener("abort",R),k)V(k);else H()},N=(k)=>new K9(`${G?.message??"Agent runtime install failed"}; npm installer PID ${X.pid??"MISS"} termination unconfirmed: ${k}; partial directory retained: ${$}
7
- ${z}`),F=(k)=>{if(B||A||K)return;G??=Error(k),P=setTimeout(()=>j(N(`stdio did not close within ${W}ms`)),W),K=Promise.resolve().then(async()=>{if(A)throw Error("installer closed before process-tree termination started");if(!X.pid)throw Error("installer PID unavailable");if(Y==="win32")await(J.terminateWindows??XG)(X.pid);else if(!X.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((C)=>j(N(C instanceof Error?C.message:String(C))))},R=()=>F("Agent runtime install aborted"),M=setTimeout(()=>F(`Agent runtime install timed out after ${Q}ms`),Q);if(Z?.addEventListener("abort",R,{once:!0}),X.on("error",(k)=>{if(G??=k,!X.pid)j(Error(`${k.message}
8
- ${z}`))}),X.once("close",async(k,C)=>{A=!0,clearTimeout(M),Z?.removeEventListener("abort",R);try{await K}catch(v){j(N(v instanceof Error?v.message:String(v)));return}if(G||k!==0)j(Error(`${G?.message??`npm install exited code=${k} signal=${C}`}
9
- ${z}`));else j()}),Z?.aborted)R()})}var VG="https://registry.npmjs.org",K9;var v5=T(()=>{K9=class K9 extends Error{}});import{createHash as zG,randomUUID as GG}from"node:crypto";import{createRequire as _G}from"node:module";import{existsSync as h5,readFileSync as FJ}from"node:fs";import{mkdir as RJ,mkdtemp as KG,readFile as UJ,rename as OJ,rm as B9,writeFile as I5}from"node:fs/promises";import{join as f$,isAbsolute as BG}from"node:path";import{fileURLToPath as AG,pathToFileURL as qG}from"node:url";function TJ($,Z=x5){let J=f$(Z,$,"current.json");if(!h5(J))return null;let Y=JSON.parse(FJ(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!BG(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function A9($){let Z=TJ($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function g5($,Z){return _G(f$(A9($),"package.json")).resolve(Z)}function d2($,Z){let J=f$(A9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!h5(J))throw Error(`${$} executable missing: ${J}`);return J}async function NJ(){return import(qG(g5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function DG($,Z,J){let Y=new AbortController,Q=()=>Y.abort(J?.reason);if(J?.addEventListener("abort",Q,{once:!0}),J?.aborted)Q();let W=setTimeout(()=>Y.abort(Error("npm registry request timed out")),30000);try{let H=await fetch(`${jG}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Y.signal});if(!H.ok)throw Error(`${$}@${Z}: npm HTTP ${H.status}`);let V=await H.json();if(V.name!==$||typeof V.version!=="string"||!V.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return V}finally{clearTimeout(W),J?.removeEventListener("abort",Q)}}async function MG($,Z){let J={};if($!=="dsh"){let H=await Promise.all(i2[$].map((V)=>Z(V,"latest")));for(let V of H)J[V.name]=V.version;return J}let Y=await Z("@deepseek-ai/dsh","latest"),Q=new Set(i2.dsh),W=new Set;while(Q.size){let H=[...Q].slice(0,12);for(let X of H)Q.delete(X),W.add(X);let V=await Promise.all(H.map((X)=>X===Y.name?Y:Z(X,Y.version)));for(let X of V){if(X.version!==Y.version)throw Error(`DSH release package mismatch: ${X.name}@${X.version}, expected ${Y.version}`);J[X.name]=X.version;for(let z of Object.keys({...X.dependencies,...X.peerDependencies,...X.optionalDependencies}))if(z.startsWith("@deepseek-ai/dsh")&&!W.has(z))Q.add(z)}}return J}async function n1($,Z=process.platform){for(let J=0;;J++)try{return await $()}catch(Y){let Q=Y.code;if(Z!=="win32"||!["EPERM","EACCES","EBUSY","ENOTEMPTY"].includes(Q??"")||J>=5)throw Y;await new Promise((W)=>setTimeout(W,100*(J+1)))}}async function MJ($,Z){let J=f$($,`current-${GG()}.json`),Y;try{await I5(J,JSON.stringify(Z)+`
10
- `,{mode:384}),await n1(()=>OJ(J,f$($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await n1(()=>B9(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${_1(Y)}; state temporary file cleanup failed: ${_1(Q)}`);throw Q}}}async function FG($,Z){let J=f$($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{return await RJ(J),await I5(f$(J,"pid"),String(process.pid)),()=>n1(()=>B9(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let W=Number(await UJ(f$(J,"pid"),"utf8"));if(!Number.isSafeInteger(W)||W<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(W,0)}catch(H){if(H.code!=="ESRCH")throw H;await n1(()=>B9(J,{recursive:!0}));continue}}catch(W){if(W.code!=="ENOENT")throw W}if(Date.now()>=Y)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((W)=>setTimeout(W,200))}}}async function q9($,Z={}){let J=Z.root??x5,Y=f$(J,$);await RJ(Y,{recursive:!0,mode:448});let Q=await FG(Y,Z.signal),W,H,V=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let X=TJ($,J),z=await MG($,Z.metadata??((P,L)=>DG(P,L,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(FJ(AG(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=zG("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(z).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),B=f$(Y,K);if(!h5(B)){W=await KG(f$(Y,".install-")),await I5(f$(W,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:z[i2[$][0]],private:!0,type:"module",dependencies:z,overrides:{...G,...$==="dsh"?z:{}}})+`
11
- `,{mode:384}),await(Z.install??f5)(W,Z.signal);for(let[L,j]of Object.entries(z)){let N=JSON.parse(await UJ(f$(W,"node_modules",L,"package.json"),"utf8"));if(N.version!==j)throw Error(`npm installed ${L}@${N.version}, expected ${j}`)}Z.signal?.throwIfAborted();let P=W;await n1(()=>OJ(P,B)),W=void 0}let A={directory:B,versions:z,checkedAt:Date.now()};return await MJ(Y,A),Z.report?.(`${$}: ${i2[$][0]}@${z[i2[$][0]]}${X?.directory===B?" 已是 latest":" 已更新,新进程使用新版"}`),A}catch(X){H=X,V=X instanceof K9;try{await MJ(Y,{checkedAt:Date.now(),error:_1(X)})}catch(z){throw H=AggregateError([X,z],`${_1(X)}; recording update failure also failed: ${_1(z)}`),H}throw X}finally{let X=[];if(W&&!V){let z=W;try{await n1(()=>B9(z,{recursive:!0}))}catch(G){X.push(G)}}try{await Q()}catch(z){X.push(z)}if(X.length){let z=H?[H,...X]:X;throw AggregateError(z,z.map(_1).join("; "))}}}function EJ($,Z={}){let J=PG.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,W,H=setInterval(()=>{if(W)return;W=(Z.update??q9)(Y,{report:$,signal:Q.signal}).catch((V)=>$(`${Y} 自动更新未完成: ${_1(V)}`)).finally(()=>{W=void 0})},LG);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var PG,LG=21600000,jG="https://registry.npmjs.org",i2,_1=($)=>$ instanceof Error?$.message:String($);var a1=T(()=>{W$();v5();v5();PG=["codex","claude","dsh"],i2={codex:["@openai/codex"],claude:["@anthropic-ai/claude-code","@anthropic-ai/claude-agent-sdk","@anthropic-ai/sdk"],dsh:["@deepseek-ai/dsh","@deepseek-ai/dsh-llm-pi-ai","@deepseek-ai/dsh-tool-ask-user"]}});var xJ={};P0(xJ,{runSetup:()=>hG});import{execFileSync as RG,spawn as L9}from"node:child_process";import{spawn as UG}from"cross-spawn";import{existsSync as c5,mkdirSync as kJ,readFileSync as OG}from"node:fs";import{createInterface as TG}from"node:readline/promises";import{dirname as NG,join as u5}from"node:path";import{homedir as EG}from"node:os";import{fileURLToPath as SG}from"node:url";async function K1($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Y=(await n2.question(`${q.cyan}? ${q.reset}${$}${J}
12
- ${q.green}>${q.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Y}}function kG($){let Z="═".repeat(58);console.log(`
2
+ import{createRequire as GG}from"node:module";var VG=Object.defineProperty;var zG=($)=>$;function XG($,Z){this[$]=zG.bind(null,Z)}var P0=($,Z)=>{for(var J in Z)VG($,J,{get:Z[J],enumerable:!0,configurable:!0,set:XG.bind(Z,J)})};var T=($,Z)=>()=>($&&(Z=$($=0)),Z);var _G=GG(import.meta.url);import{homedir as KG}from"node:os";import{join as d}from"node:path";function jJ($,Z,J){if($)return $;if(Z)return d(Z,"lodestar");return J}function BG(){if(LJ)return d(process.env.APPDATA??d(G9,"AppData","Roaming"),"Lodestar");return d(G9,".config","lodestar")}function AG(){if(LJ)return d(process.env.LOCALAPPDATA??d(G9,"AppData","Local"),"Lodestar");return d(G9,".local","share","lodestar")}var G9,LJ,w6,o,O$,d$,n1,f6,v6,h6,I6,g6,_9,G1,K9,_1,a1,PJ,DJ,MJ,m6,FJ,RJ,c6,p6,K1,B9;var H$=T(()=>{G9=KG(),LJ=process.platform==="win32";w6=jJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,BG()),o=jJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,AG()),O$=process.env.LODESTAR_CONFIG??d(w6,"config.toml"),d$=d(o,"daemon.pid"),n1=d(o,"daemon.log"),f6=d(o,"session-chat-map.json"),v6=d(o,"session-resume-map.json"),h6=d(o,"session-turns-map.json"),I6=d(o,"session-model-map.json"),g6=d(o,"temp-session-leases.json"),_9=d(o,"tasklist-map.json"),G1=d(o,"agent-runs"),K9=d(o,"agent-session-ids.json"),_1=d(o,"managed-claude-plugin"),a1=d(o,"dsh"),PJ=d(o,"codex-accounts"),DJ=d(o,"codex-accounts.json"),MJ=d(o,"codex-quota-blocks.json"),m6=d(o,"agent-runtimes"),FJ=d(o,"context-window-cache.json"),RJ=d(o,"notify-callbacks.json"),c6=d(o,"alive-on-shutdown.json"),p6=d(o,"inbox"),K1=d(o,"debug.sock"),B9=d(o,"debug-context.json")});import{execSync as UJ}from"node:child_process";import{readFileSync as OJ,writeFileSync as qG}from"node:fs";function LG(){return process.argv[1]??`pid:${process.pid}`}function jG($){try{if(process.platform==="linux")return OJ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return UJ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return UJ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function PG($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=jG($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function A9($){let Z="";try{Z=OJ($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
+ `),Y=parseInt((J[0]??"").trim(),10),Q=(J[1]??"").trim();if(!Number.isFinite(Y)||Y<=0)return{state:"continue"};if(!Q)try{return process.kill(Y,0),{state:"exit",pid:Y}}catch{return{state:"continue"}}if(PG(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function TJ($){qG($,`${process.pid}
4
+ ${LG()}`)}var u6=()=>{};import{execFile as DG}from"node:child_process";import{readFile as MG}from"node:fs/promises";import{homedir as FG}from"node:os";import{join as NJ}from"node:path";import{promisify as RG}from"node:util";import{Address4 as q9,Address6 as L9}from"ip-address";function o1($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function M9($){let Z=$.hostname.replace(/^\[|\]$/g,"").toLowerCase();return Z==="localhost"||Z.endsWith(".localhost")||Z==="::1"||/^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(Z)||/^::ffff:(?:127\.|7f[0-9a-f]{2}:)/.test(Z)}function l6($,Z=""){let J=$.hostname.replace(/^\[|\]$/g,"").toLowerCase(),Y=$.port||($.protocol==="https:"?"443":"80");return Z.split(/[,;\s]+/).filter(Boolean).some((Q)=>{let W=Q.toLowerCase();if(W==="*")return!0;if(W==="<local>")return!J.includes(".")&&!J.includes(":");if(W.includes("/")){if(q9.isValid(W))return q9.isValid(J)&&new q9(J).isInSubnet(new q9(W));if(L9.isValid(W))return L9.isValid(J)&&new L9(J).isInSubnet(new L9(W));throw Error("network proxy: invalid IP range in bypass list")}let H=W.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(H&&H[2]!==Y)return!1;let V=(H?H[1]:W).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===V||J.endsWith(`.${V}`)})}function EJ($,Z){let J;try{J=new URL($)}catch{throw Error(`network proxy: ${Z} contains an invalid proxy URL`)}if(!["http:","https:"].includes(J.protocol))throw Error(`network proxy: ${Z} must use an HTTP(S) proxy; SOCKS and PAC are not supported`);if(!J.hostname||J.search||J.hash||J.pathname&&J.pathname!=="/")throw Error(`network proxy: ${Z} must contain a proxy host and port without a path or query`);return J.href}function SJ($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(M9($)||l6($,o1(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=o1(Z,Y)||o1(Z,"ALL_PROXY");if(Q)return EJ(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(l6($,J.bypass))return;let W=($.protocol==="https:"?J.https:J.http)||J.all;return W?EJ(W,"system settings"):void 0}function D9($,Z,J="http"){if(typeof $!=="string"||!$.trim()||!Number.isInteger(Number(Z))||Number(Z)<1||Number(Z)>65535)throw Error("network proxy: system proxy has an invalid host or port");let Y=$.includes(":")&&!$.startsWith("[")?`[${$}]`:$;return`${J}://${Y}:${Z}`}function OG($){if($.AutoConfigURL)return{unsupported:"Windows PAC proxy is not supported; configure a manual HTTP(S) proxy or proxy environment variables"};if(!$.ProxyEnable)return $.AutoDetect?{unsupported:"Windows automatic proxy discovery is not supported; configure a manual HTTP(S) proxy or proxy environment variables"}:{};if(typeof $.ProxyServer!=="string"||!$.ProxyServer.trim())throw Error("network proxy: Windows proxy is enabled without a server");let Z={bypass:String($.ProxyOverride??"")};for(let J of $.ProxyServer.split(";").map((Y)=>Y.trim()).filter(Boolean)){let Y=J.match(/^(http|https|socks)=(.+)$/i),Q=Y?Y[2]:J,W=/^[a-z][\w+.-]*:\/\//i.test(Q)?Q:`http://${Q}`;if(!Y)Z.all=W;else if(Y[1].toLowerCase()==="socks")Z.all=`socks://${Q.replace(/^socks\w*:\/\//,"")}`;else Z[Y[1].toLowerCase()]=W}return Z}function TG($){let Z=(Q)=>$.match(new RegExp(`^\\s*${Q}\\s*:\\s*(.*?)\\s*$`,"m"))?.[1];if(Z("ProxyAutoConfigEnable")==="1"||Z("ProxyAutoDiscoveryEnable")==="1")return{unsupported:"macOS PAC/automatic proxy discovery is not supported; configure a manual HTTP(S) proxy or proxy environment variables"};let J={};if(Z("HTTPEnable")==="1")J.http=D9(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=D9(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=D9(Z("SOCKSProxy"),Z("SOCKSPort"),"socks");let Y=$.match(/ExceptionsList\s*:\s*<array>\s*\{([^}]*)\}/)?.[1]??"";if(J.bypass=[...Y.matchAll(/^\s*\d+\s*:\s*(.*?)\s*$/gm)].map((Q)=>Q[1]).join(","),Z("ExcludeSimpleHostnames")==="1")J.bypass+=",<local>";return J}function j9($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function NG($){let Z=new Map($.split(`
5
+ `).filter(Boolean).map((Q)=>{let W=Q.match(/^org\.gnome\.system\.proxy(\.\w+)?\s+([\w-]+)\s+(.*)$/);if(!W)throw Error("network proxy: invalid GNOME proxy settings");return[`${W[1]??""}/${W[2]}`,W[3]]})),J=j9(Z.get("/mode"));if(J==="none")return{};if(J==="auto")return{unsupported:"GNOME PAC proxy is not supported; configure a manual HTTP(S) proxy or proxy environment variables"};if(J!=="manual")throw Error("network proxy: unknown GNOME proxy mode");let Y={};for(let Q of["http","https","socks"]){let W=j9(Z.get(`.${Q}/host`));if(!W)continue;let H=new URL(D9(W,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")H.username=j9(Z.get(".http/authentication-user")),H.password=j9(Z.get(".http/authentication-password"));Y[Q==="socks"?"all":Q]=H.href}if(Z.get("/use-same-proxy")==="true"&&Y.http)Y.https=Y.http;return Y.bypass=[...(Z.get("/ignore-hosts")??"").matchAll(/'((?:\\.|[^'])*)'/g)].map((Q)=>Q[1]).join(","),Y}function EG($){let Z=$.match(/^\[Proxy Settings\]\s*\n([\s\S]*?)(?=^\[|$(?![\s\S]))/m)?.[1];if(Z===void 0)return;let J=new Map(Z.split(`
6
+ `).filter((W)=>W.includes("=")).map((W)=>{let H=W.indexOf("=");return[W.slice(0,H).trim(),W.slice(H+1).trim()]})),Y=J.get("ProxyType")??"0";if(Y==="0"||Y==="4")return{};if(Y!=="1")return{unsupported:"KDE PAC/automatic proxy discovery is not supported; configure a manual HTTP(S) proxy or proxy environment variables"};if(J.get("ReversedException")==="true")return{unsupported:"KDE reversed proxy exceptions are not supported"};let Q={bypass:J.get("NoProxyFor")};for(let W of["http","https","socks"]){let H=J.get(`${W}Proxy`);if(!H)continue;let V=H.replace(/\s+(\d+)$/,":$1");Q[W==="socks"?"all":W]=/^[a-z][\w+.-]*:\/\//i.test(V)?V:`${W==="socks"?"socks":"http"}://${V}`}return Q}async function P9($,Z){let{stdout:J}=await UG($,Z,{encoding:"utf8",timeout:5000,maxBuffer:262144,windowsHide:!0});return J}async function kG(){if(process.platform==="win32")return OG(JSON.parse(await P9("powershell.exe",["-NoProfile","-NonInteractive","-Command",SG])));if(process.platform==="darwin")return TG(await P9("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=NJ(process.env.XDG_CONFIG_HOME||NJ(FG(),".config"),"kioslaverc");try{let J=EG(await MG($,"utf8"));if(J&&(!process.env.XDG_CURRENT_DESKTOP||/kde/i.test(process.env.XDG_CURRENT_DESKTOP)))return J}catch(J){if(J?.code!=="ENOENT")throw J}let Z;try{Z=await P9("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return NG(await P9("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function xG($=kG,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(M9(Q)||l6(Q,o1(Z,"NO_PROXY"))||o1(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||o1(Z,"ALL_PROXY"))return SJ(Q,Z);if(!Y||Y.until<=J()){let W=$().catch((H)=>{if(Y?.value===W)Y=void 0;if(H instanceof Error&&H.message.startsWith("network proxy:"))throw H;let V=H instanceof Error?H.code??H.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${V})`,{cause:H})});Y={until:J()+30000,value:W}}return SJ(Q,Z,await Y.value)}}var UG,SG,kJ;var xJ=T(()=>{UG=RG(DG);SG=String.raw`
7
+ $ErrorActionPreference = 'Stop'
8
+ [Console]::OutputEncoding = New-Object Text.UTF8Encoding($false)
9
+ Add-Type @'
10
+ using System;
11
+ using System.Runtime.InteropServices;
12
+ public static class LodestarProxy {
13
+ [StructLayout(LayoutKind.Sequential)]
14
+ public struct Settings {
15
+ [MarshalAs(UnmanagedType.Bool)] public bool AutoDetect;
16
+ public IntPtr AutoConfigUrl, Proxy, Bypass;
17
+ }
18
+ [DllImport("winhttp.dll", SetLastError = true)]
19
+ [return: MarshalAs(UnmanagedType.Bool)]
20
+ public static extern bool WinHttpGetIEProxyConfigForCurrentUser(out Settings settings);
21
+ [DllImport("kernel32.dll")] public static extern IntPtr GlobalFree(IntPtr pointer);
22
+ }
23
+ '@
24
+ $settings = New-Object LodestarProxy+Settings
25
+ if (-not [LodestarProxy]::WinHttpGetIEProxyConfigForCurrentUser([ref]$settings)) {
26
+ $code = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
27
+ if ($code -eq 2) { '{}'; exit 0 }
28
+ throw (New-Object ComponentModel.Win32Exception($code))
29
+ }
30
+ try {
31
+ $proxy = [Runtime.InteropServices.Marshal]::PtrToStringUni($settings.Proxy)
32
+ @{
33
+ ProxyEnable = -not [string]::IsNullOrEmpty($proxy)
34
+ ProxyServer = $proxy
35
+ ProxyOverride = [Runtime.InteropServices.Marshal]::PtrToStringUni($settings.Bypass)
36
+ AutoConfigURL = [Runtime.InteropServices.Marshal]::PtrToStringUni($settings.AutoConfigUrl)
37
+ AutoDetect = $settings.AutoDetect
38
+ } | ConvertTo-Json -Compress
39
+ } finally {
40
+ foreach ($pointer in @($settings.Proxy, $settings.Bypass, $settings.AutoConfigUrl)) {
41
+ if ($pointer -ne [IntPtr]::Zero) { [void][LodestarProxy]::GlobalFree($pointer) }
42
+ }
43
+ }
44
+ `;kJ=xG()});import{Agent as CG}from"node:http";import{Agent as bG}from"node:https";import{Readable as CJ}from"node:stream";import yG from"node-fetch";import{HttpProxyAgent as wG}from"http-proxy-agent";import{HttpsProxyAgent as fG}from"https-proxy-agent";function IG($,Z){if(!Z)return $.protocol==="https:"?hG:vG;return $.protocol==="https:"?new fG(Z):new wG(Z)}async function gG($,Z,J){if(typeof Bun<"u"){let H=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[H.toLowerCase()]||process.env[H])){let V=await import("undici");return bJ??=new V.Agent,await V.fetch($,{...Z,redirect:"manual",dispatcher:bJ})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"}),Q=await yG($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?CJ.fromWeb(Y.body):void 0,signal:Y.signal,agent:IG($,J),redirect:"manual"}),W=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:CJ.toWeb(Q.body);return new Response(W,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function yJ($,Z,J,Y=kJ){let Q=new URL($),W={...Z};for(let H=0;;H++){if(!["http:","https:"].includes(Q.protocol))throw Error(`network: unsupported URL protocol ${Q.protocol}`);if(J&&!M9(Q))throw Error("network: local request must remain on loopback");W.signal?.throwIfAborted();let V=J?void 0:await Y(Q),z=await gG(Q,W,V),X=z.headers.get("location");if(![301,302,303,307,308].includes(z.status)||!X||Z.redirect==="manual")return z;if(await z.body?.cancel(),Z.redirect==="error")throw Error("network: redirect rejected");if(H>=20)throw Error("network: too many redirects");let G=new URL(X,Q),K=new Headers(W.headers);if(G.origin!==Q.origin)for(let L of["authorization","proxy-authorization","cookie","host"])K.delete(L);let B=(W.method??"GET").toUpperCase();if(z.status===303&&B!=="HEAD"||[301,302].includes(z.status)&&B==="POST"){W={...W,method:"GET",body:void 0};for(let L of["content-type","content-length","content-encoding"])K.delete(L)}else if(W.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");W.headers=K,Q=G}}function J$($,Z={}){return yJ($,Z,!1)}function wJ($,Z={}){return yJ($,Z,!0)}var vG,hG,bJ;var n$=T(()=>{xJ();vG=new CG({keepAlive:!0}),hG=new bG({keepAlive:!0})});import{chmodSync as mG,closeSync as i6,fsyncSync as fJ,mkdirSync as cG,openSync as vJ,renameSync as pG,unlinkSync as uG,writeFileSync as lG}from"node:fs";import{randomUUID as iG}from"node:crypto";import{dirname as hJ}from"node:path";function oG($){let Z=hJ($);cG(Z,{recursive:!0,mode:aG})}function IJ($,Z,J){oG($);let Y=`${$}.${process.pid}.${iG()}.tmp`,Q=null;try{Q=vJ(Y,"wx",J),lG(Q,Z),fJ(Q),i6(Q),Q=null,pG(Y,$);try{mG($,J)}catch{}if(process.platform!=="win32"){let W=null;try{W=vJ(hJ($),"r"),fJ(W)}catch{}finally{if(W!==null)try{i6(W)}catch{}}}}catch(W){if(Q!==null)try{i6(Q)}catch{}try{uG(Y)}catch{}throw W}}function J0($,Z){IJ($,Z,dG)}function gJ($,Z){IJ($,Z,nG)}function t($,Z){J0($,JSON.stringify(Z,null,2)+`
45
+ `)}var dG=384,nG=448,aG=448;var f$=()=>{};import{execFile as rG}from"node:child_process";import{spawn as tG}from"cross-spawn";function eG($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{rG("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Y,Q,W)=>{if(Y)J(Error(`taskkill npm installer PID ${$} failed: ${Y.message}
46
+ ${Q}${W}`));else Z()})})}async function d6($,Z,J={}){Z?.throwIfAborted();let Y=J.platform??process.platform,Q=J.timeoutMs??300000,W=J.terminationTimeoutMs??1e4;return await new Promise((H,V)=>{let z=(J.spawn??tG)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${sG}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),X="",G,K,B=!1,L=!1,A,j=(k)=>{X=(X+k.toString()).slice(-16384)};z.stdout.on("data",j),z.stderr.on("data",j);let P=(k)=>{if(B)return;if(B=!0,clearTimeout(M),A)clearTimeout(A);if(Z?.removeEventListener("abort",R),k)V(k);else H()},S=(k)=>new F9(`${G?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${k}; partial directory retained: ${$}
47
+ ${X}`),F=(k)=>{if(B||L||K)return;G??=Error(k),A=setTimeout(()=>P(S(`stdio did not close within ${W}ms`)),W),K=Promise.resolve().then(async()=>{if(L)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Y==="win32")await(J.terminateWindows??eG)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((C)=>P(S(C instanceof Error?C.message:String(C))))},R=()=>F("Agent runtime install aborted"),M=setTimeout(()=>F(`Agent runtime install timed out after ${Q}ms`),Q);if(Z?.addEventListener("abort",R,{once:!0}),z.on("error",(k)=>{if(G??=k,!z.pid)P(Error(`${k.message}
48
+ ${X}`))}),z.once("close",async(k,C)=>{L=!0,clearTimeout(M),Z?.removeEventListener("abort",R);try{await K}catch(c){P(S(c instanceof Error?c.message:String(c)));return}if(G||k!==0)P(Error(`${G?.message??`npm install exited code=${k} signal=${C}`}
49
+ ${X}`));else P()}),Z?.aborted)R()})}var sG="https://registry.npmjs.org",F9;var n6=T(()=>{F9=class F9 extends Error{}});import{createHash as $_,randomUUID as Z_}from"node:crypto";import{createRequire as J_}from"node:module";import{existsSync as a6,readFileSync as cJ}from"node:fs";import{mkdir as pJ,mkdtemp as Y_,readFile as uJ,rename as lJ,rm as R9,writeFile as o6}from"node:fs/promises";import{join as v$,isAbsolute as Q_}from"node:path";import{fileURLToPath as W_,pathToFileURL as H_}from"node:url";function iJ($,Z=m6){let J=v$(Z,$,"current.json");if(!a6(J))return null;let Y=JSON.parse(cJ(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!Q_(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function U9($){let Z=iJ($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function r6($,Z){return J_(v$(U9($),"package.json")).resolve(Z)}function a2($,Z){let J=v$(U9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!a6(J))throw Error(`${$} executable missing: ${J}`);return J}async function dJ(){return import(H_(r6("claude","@anthropic-ai/claude-agent-sdk")).href)}async function G_($,Z,J){let Y=new AbortController,Q=()=>Y.abort(J?.reason);if(J?.addEventListener("abort",Q,{once:!0}),J?.aborted)Q();let W=setTimeout(()=>Y.abort(Error("npm registry request timed out")),30000);try{let H=await J$(`${X_}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Y.signal});if(!H.ok)throw Error(`${$}@${Z}: npm HTTP ${H.status}`);let V=await H.json();if(V.name!==$||typeof V.version!=="string"||!V.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return V}finally{clearTimeout(W),J?.removeEventListener("abort",Q)}}async function __($,Z){let J={};if($!=="dsh"){let H=await Promise.all(n2[$].map((V)=>Z(V,"latest")));for(let V of H)J[V.name]=V.version;return J}let Y=await Z("@deepseek-ai/dsh","latest"),Q=new Set(n2.dsh),W=new Set;while(Q.size){let H=[...Q].slice(0,12);for(let z of H)Q.delete(z),W.add(z);let V=await Promise.all(H.map((z)=>z===Y.name?Y:Z(z,Y.version)));for(let z of V){if(z.version!==Y.version)throw Error(`DSH release package mismatch: ${z.name}@${z.version}, expected ${Y.version}`);J[z.name]=z.version;for(let X of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(X.startsWith("@deepseek-ai/dsh")&&!W.has(X))Q.add(X)}}return J}async function r1($,Z=process.platform){for(let J=0;;J++)try{return await $()}catch(Y){let Q=Y.code;if(Z!=="win32"||!["EPERM","EACCES","EBUSY","ENOTEMPTY"].includes(Q??"")||J>=5)throw Y;await new Promise((W)=>setTimeout(W,100*(J+1)))}}async function mJ($,Z){let J=v$($,`current-${Z_()}.json`),Y;try{await o6(J,JSON.stringify(Z)+`
50
+ `,{mode:384}),await r1(()=>lJ(J,v$($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await r1(()=>R9(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${B1(Y)}; state temporary file cleanup failed: ${B1(Q)}`);throw Q}}}async function K_($,Z){let J=v$($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{return await pJ(J),await o6(v$(J,"pid"),String(process.pid)),()=>r1(()=>R9(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let W=Number(await uJ(v$(J,"pid"),"utf8"));if(!Number.isSafeInteger(W)||W<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(W,0)}catch(H){if(H.code!=="ESRCH")throw H;await r1(()=>R9(J,{recursive:!0}));continue}}catch(W){if(W.code!=="ENOENT")throw W}if(Date.now()>=Y)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((W)=>setTimeout(W,200))}}}async function O9($,Z={}){let J=Z.root??m6,Y=v$(J,$);await pJ(Y,{recursive:!0,mode:448});let Q=await K_(Y,Z.signal),W,H,V=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let z=iJ($,J),X=await __($,Z.metadata??((A,j)=>G_(A,j,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(cJ(W_(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=$_("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(X).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),B=v$(Y,K);if(!a6(B)){W=await Y_(v$(Y,".install-")),await o6(v$(W,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:X[n2[$][0]],private:!0,type:"module",dependencies:X,overrides:{...G,...$==="dsh"?X:{}}})+`
51
+ `,{mode:384}),await(Z.install??d6)(W,Z.signal);for(let[j,P]of Object.entries(X)){let S=JSON.parse(await uJ(v$(W,"node_modules",j,"package.json"),"utf8"));if(S.version!==P)throw Error(`npm installed ${j}@${S.version}, expected ${P}`)}Z.signal?.throwIfAborted();let A=W;await r1(()=>lJ(A,B)),W=void 0}let L={directory:B,versions:X,checkedAt:Date.now()};return await mJ(Y,L),Z.report?.(`${$}: ${n2[$][0]}@${X[n2[$][0]]}${z?.directory===B?" 已是 latest":" 已更新,新进程使用新版"}`),L}catch(z){H=z,V=z instanceof F9;try{await mJ(Y,{checkedAt:Date.now(),error:B1(z)})}catch(X){throw H=AggregateError([z,X],`${B1(z)}; recording update failure also failed: ${B1(X)}`),H}throw z}finally{let z=[];if(W&&!V){let X=W;try{await r1(()=>R9(X,{recursive:!0}))}catch(G){z.push(G)}}try{await Q()}catch(X){z.push(X)}if(z.length){let X=H?[H,...z]:z;throw AggregateError(X,X.map(B1).join("; "))}}}function nJ($,Z={}){let J=V_.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,W,H=setInterval(()=>{if(W)return;W=(Z.update??O9)(Y,{report:$,signal:Q.signal}).catch((V)=>$(`${Y} 自动更新未完成: ${B1(V)}`)).finally(()=>{W=void 0})},z_);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var V_,z_=21600000,X_="https://registry.npmjs.org",n2,B1=($)=>$ instanceof Error?$.message:String($);var t1=T(()=>{n$();H$();n6();n6();V_=["codex","claude","dsh"],n2={codex:["@openai/codex"],claude:["@anthropic-ai/claude-code","@anthropic-ai/claude-agent-sdk","@anthropic-ai/sdk"],dsh:["@deepseek-ai/dsh","@deepseek-ai/dsh-llm-pi-ai","@deepseek-ai/dsh-tool-ask-user"]}});var rJ={};P0(rJ,{runSetup:()=>S_});import{execFileSync as B_,spawn as N9}from"node:child_process";import{spawn as A_}from"cross-spawn";import{existsSync as s6,mkdirSync as oJ,readFileSync as q_}from"node:fs";import{createInterface as L_}from"node:readline/promises";import{dirname as j_,join as e6}from"node:path";import{homedir as P_}from"node:os";import{fileURLToPath as D_}from"node:url";async function A1($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Y=(await o2.question(`${q.cyan}? ${q.reset}${$}${J}
52
+ ${q.green}>${q.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Y}}function M_($){let Z="═".repeat(58);console.log(`
13
53
  ${q.bold}${q.cyan}╔${Z}╗${q.reset}`),console.log(`${q.bold}${q.cyan}║ ${$.padEnd(54)} ║${q.reset}`),console.log(`${q.bold}${q.cyan}╚${Z}╝${q.reset}
14
- `)}function P9($,Z,J){console.log(`
54
+ `)}function T9($,Z,J){console.log(`
15
55
  ${q.bold}${q.yellow}[${$}/${Z}] ${J}${q.reset}
16
- `)}function m5($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function SJ($){try{let Z=RG($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function xG($){return new Promise((Z)=>{let J=UG($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function CG(){return process.env.CLAUDE_CONFIG_DIR||u5(EG(),".claude")}async function bG($){try{let Z=await fetch("https://open.bigmodel.cn/api/anthropic/v1/models",{headers:{Authorization:`Bearer ${$}`},signal:AbortSignal.timeout(1e4)});if(!Z.ok)return null;let J=await Z.json(),Y=(Array.isArray(J?.data)?J.data:[]).map((K)=>typeof K?.display_name==="string"&&K.display_name?K.display_name:String(K?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(K)=>{let B=K.match(/(\d+(?:\.\d+)?)/);return B?Number(B[1]):-1},W=(K)=>K.replace(/-Turbo|-Air$/i,""),V=[...Y.filter((K)=>!/-Turbo|-Air/i.test(K))].sort((K,B)=>Q(B)-Q(K)),X=V[0],z=V[V.length-1],G={};if(X)G.ANTHROPIC_DEFAULT_OPUS_MODEL=`${X}[1m]`,G.ANTHROPIC_DEFAULT_SONNET_MODEL=`${X}[1m]`;if(z&&W(z)!==W(X))G.ANTHROPIC_DEFAULT_HAIKU_MODEL=z;return Object.keys(G).length?G:null}catch{return null}}async function yG($){try{let Z=CG();kJ(Z,{recursive:!0});let J=u5(Z,"settings.json"),Y={};if(c5(J)){let V=OG(J,"utf8");try{let X=JSON.parse(V);if(!X||typeof X!=="object"||Array.isArray(X))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Y=X}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Q=Y.env&&typeof Y.env==="object"&&!Array.isArray(Y.env)?Y.env:{},W={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await bG($);if(H)Object.assign(W,H);return Y.env={...Q,...W},$0(J,JSON.stringify(Y,null,2)+`
17
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function wG($){try{if(process.platform==="win32")L9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")L9("open",[$],{detached:!0,stdio:"ignore"}).unref();else L9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function fG($,Z){try{let Y=await(await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:$,app_secret:Z}),signal:AbortSignal.timeout(15000)})).json();if(Y.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Y.code} msg=${Y.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function vG(){try{let $=NG(SG(import.meta.url)),Z=u5($,"lodestar.js");if(!c5(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=L9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function hG(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(c5(U$)){if(console.log(`${q.yellow}发现已有配置: ${U$}${q.reset}`),(await K1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),n2.close();return}}kG("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${q.yellow}⚠ Claude 官方限制:${q.reset}`),console.log(` ${q.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${q.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await n2.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),P9(1,4,"准备 Claude Code CLI"),await q9("claude",{report:(K)=>console.log(K)}),console.log(`${q.green}✓ Claude Code / SDK 已更新${q.reset}: ${q.dim}${d2("claude","claude")}${q.reset}`),console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${q.reset}`),P9(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${q.reset}`),console.log();let $=await K1("GLM API key (直接回车跳过)",{});if($){let K=await yG($);if("path"in K)console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${K.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);else console.log(`${q.red}✗ 写入失败:${q.reset} ${K.error}`),console.log(`${q.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${q.reset}`)}else console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await K1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await q9("codex",{report:(B)=>console.log(B)});let K=d2("codex","codex");if(SJ(K))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await xG(K)&&SJ(K))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);P9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${J}${q.reset}`),wG(J),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}开通权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",Q="";while(!0){Y=await K1("App ID (以 cli_ 开头)",{required:!0}),Q=await K1("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let K=await fG(Y,Q);if(K.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${K.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await K1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),n2.close(),process.exit(1)}P9(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let W=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",H=await K1("projects_root",{default:W});kJ(O5,{recursive:!0});let V=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${m5(Y)}"`,`app_secret = "${m5(Q)}"`,"","[runtime]",`projects_root = "${m5(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];$0(U$,V.join(`
56
+ `)}function t6($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function aJ($){try{let Z=B_($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function F_($){return new Promise((Z)=>{let J=A_($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function R_(){return process.env.CLAUDE_CONFIG_DIR||e6(P_(),".claude")}async function U_($){try{let Z=await J$("https://open.bigmodel.cn/api/anthropic/v1/models",{headers:{Authorization:`Bearer ${$}`},signal:AbortSignal.timeout(1e4)});if(!Z.ok)return null;let J=await Z.json(),Y=(Array.isArray(J?.data)?J.data:[]).map((K)=>typeof K?.display_name==="string"&&K.display_name?K.display_name:String(K?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(K)=>{let B=K.match(/(\d+(?:\.\d+)?)/);return B?Number(B[1]):-1},W=(K)=>K.replace(/-Turbo|-Air$/i,""),V=[...Y.filter((K)=>!/-Turbo|-Air/i.test(K))].sort((K,B)=>Q(B)-Q(K)),z=V[0],X=V[V.length-1],G={};if(z)G.ANTHROPIC_DEFAULT_OPUS_MODEL=`${z}[1m]`,G.ANTHROPIC_DEFAULT_SONNET_MODEL=`${z}[1m]`;if(X&&W(X)!==W(z))G.ANTHROPIC_DEFAULT_HAIKU_MODEL=X;return Object.keys(G).length?G:null}catch{return null}}async function O_($){try{let Z=R_();oJ(Z,{recursive:!0});let J=e6(Z,"settings.json"),Y={};if(s6(J)){let V=q_(J,"utf8");try{let z=JSON.parse(V);if(!z||typeof z!=="object"||Array.isArray(z))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Y=z}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Q=Y.env&&typeof Y.env==="object"&&!Array.isArray(Y.env)?Y.env:{},W={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await U_($);if(H)Object.assign(W,H);return Y.env={...Q,...W},J0(J,JSON.stringify(Y,null,2)+`
57
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function T_($){try{if(process.platform==="win32")N9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")N9("open",[$],{detached:!0,stdio:"ignore"}).unref();else N9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function N_($,Z){try{let Y=await(await J$("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:$,app_secret:Z}),signal:AbortSignal.timeout(15000)})).json();if(Y.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Y.code} msg=${Y.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function E_(){try{let $=j_(D_(import.meta.url)),Z=e6($,"lodestar.js");if(!s6(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=N9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function S_(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(s6(O$)){if(console.log(`${q.yellow}发现已有配置: ${O$}${q.reset}`),(await A1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),o2.close();return}}M_("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${q.yellow}⚠ Claude 官方限制:${q.reset}`),console.log(` ${q.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${q.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await o2.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),T9(1,4,"准备 Claude Code CLI"),await O9("claude",{report:(K)=>console.log(K)}),console.log(`${q.green}✓ Claude Code / SDK 已更新${q.reset}: ${q.dim}${a2("claude","claude")}${q.reset}`),console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${q.reset}`),T9(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${q.reset}`),console.log();let $=await A1("GLM API key (直接回车跳过)",{});if($){let K=await O_($);if("path"in K)console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${K.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);else console.log(`${q.red}✗ 写入失败:${q.reset} ${K.error}`),console.log(`${q.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${q.reset}`)}else console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await A1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await O9("codex",{report:(B)=>console.log(B)});let K=a2("codex","codex");if(aJ(K))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await F_(K)&&aJ(K))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);T9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${J}${q.reset}`),T_(J),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}开通权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",Q="";while(!0){Y=await A1("App ID (以 cli_ 开头)",{required:!0}),Q=await A1("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let K=await N_(Y,Q);if(K.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${K.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await A1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),o2.close(),process.exit(1)}T9(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let W=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",H=await A1("projects_root",{default:W});oJ(w6,{recursive:!0});let V=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${t6(Y)}"`,`app_secret = "${t6(Q)}"`,"","[runtime]",`projects_root = "${t6(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];J0(O$,V.join(`
18
58
  `)),console.log(`
19
- ${q.green}${q.bold}✓ 配置已写入${q.reset}`),console.log(` ${q.cyan}${U$}${q.reset}`),console.log(`
20
- ${q.bold}启动 daemon...${q.reset}`);let X=vG(),z=process.platform==="win32"?"\\":"/",G=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(X.pid)console.log(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${X.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${H}${z}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${G}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${X.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),n2.close()}var q,n2;var CJ=T(()=>{W$();w$();a1();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},n2=TG({input:process.stdin,output:process.stdout})});import{existsSync as IG,readFileSync as gG}from"node:fs";function bJ($,Z){return`${$}:${Z}`}function mG(){if(!IG(z9))return;try{let $=JSON.parse(gG(z9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");a2=new Set($.ids)}catch($){p5=$ instanceof Error?$:Error(String($))}}function yJ(){if(p5)throw Error(`delegated-agent session registry is unavailable: ${p5.message}`)}function wJ($,Z){yJ();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=bJ($,J);if(a2.has(Y))return;let Q=new Set(a2);Q.add(Y),t(z9,{version:1,ids:[...Q].sort()}),a2=Q}function o1($,Z){return yJ(),a2.has(bJ($,Z))}var a2,p5=null;var o2=T(()=>{W$();w$();a2=new Set;mG()});var fJ=1;import{appendFileSync as IJ,mkdirSync as cG,readdirSync as uG,unlinkSync as gJ,existsSync as vJ,statSync as pG,renameSync as lG,readFileSync as iG}from"node:fs";import{join as mJ}from"node:path";function d5($="development"){return $!=="test"}function cJ($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function uJ($,Z=o){return mJ(Z,`${l5}${cJ($)}${i5}`)}function nG($){if(!$.startsWith(l5)||!$.endsWith(i5))return null;let Z=$.slice(l5.length,$.length-i5.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Y=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Y.getTime())?null:Y}function pJ($,Z=new Date,J=dG){let Y;try{Y=uG($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),W=0;for(let H of Y){let V=nG(H);if(!V)continue;if(Math.round((Q.getTime()-V.getTime())/86400000)<J)continue;try{gJ(mJ($,H)),W++}catch{}}return W}function aG(){try{if(!vJ(i1))return;let $=pG(i1);if(!$.isFile()||$.size===0)return;let Z=uJ($.mtime);if(vJ(Z)){IJ(Z,iG(i1)),gJ(i1);return}lG(i1,Z)}catch{}}function _($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
21
- `;if(process.stderr.write(J),!d5())return;try{let Y=cJ(Z);if(hJ!==Y)hJ=Y,pJ(o,Z);IJ(uJ(Z),J)}catch{}}var dG=7,l5="daemon-",i5=".log",hJ=null;var I=T(()=>{W$();if(d5())try{cG(o,{recursive:!0})}catch{}if(d5()){aG();try{pJ(o)}catch{}}});import{EventEmitter as oG}from"node:events";import{createRequire as rG}from"node:module";import{createHash as tG,randomUUID as sG}from"node:crypto";import{createInterface as eG}from"node:readline";import{dirname as $_,join as L0,isAbsolute as Z_}from"node:path";import{fileURLToPath as n5}from"node:url";import{tmpdir as J_}from"node:os";import{existsSync as lJ,mkdirSync as iJ,mkdtempSync as Y_,readFileSync as r2,renameSync as Q_,writeFileSync as dJ,rmSync as a5}from"node:fs";import W_ from"cross-spawn";function H_($){let Z=$.LODESTAR_DSH_PROVIDER??"deepseek-official";if(Z==="deepseek-official")return[];if(Z!=="zai-coding-cn"&&Z!=="zai")throw Error(`Unsupported DSH provider: ${Z}`);let J=$.LODESTAR_DSH_MODELS===void 0?void 0:JSON.parse($.LODESTAR_DSH_MODELS);if(J!==void 0&&(!Array.isArray(J)||!J.every((Y)=>typeof Y==="string"&&Y)))throw Error("Invalid DSH GLM model catalog");return[{id:"llm-deepseek",disabled:!0},{id:"llm-pi-ai",disabled:!1,config:{providers:{[Z]:{apiKeyEnv:"LODESTAR_DSH_GLM_API_KEY",baseURL:$.LODESTAR_DSH_BASE_URL,compat:{supportsReasoningEffort:!0},reasoning:"high",...Array.isArray(J)?{models:J.map((Y)=>({id:Y,reasoningEfforts:{off:null,minimal:"minimal",low:"low",medium:"medium",high:"high",xhigh:"xhigh",max:"max"}}))}:{}}}}},{id:"agent-default-model",config:{provider:Z,model:$.LODESTAR_DSH_DEFAULT_MODEL??""}}]}function V_($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=r2(L0($,".mcp.json"),"utf8")}catch(Q){if(Q?.code==="ENOENT")return[];throw Q}let Y=JSON.parse(J);if(!Y.mcpServers||typeof Y.mcpServers!=="object"||Array.isArray(Y.mcpServers))throw Error("DSH project .mcp.json must contain an mcpServers object");return Object.entries(Y.mcpServers).map(([Q,W])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Q)||!W||typeof W!=="object")throw Error(`invalid DSH MCP server: ${Q}`);let H=W,V=H.type==="http"?{transport:"streamable-http",serverName:Q,url:H.url,headers:H.headers??{}}:H.type===void 0||H.type==="stdio"?{transport:"stdio",serverName:Q,command:H.command,args:H.args??[],env:H.env??{},cwd:$}:null;if(!V)throw Error(`DSH does not support MCP transport ${H.type} for ${Q}`);return{id:`lodestar-mcp-${Q}`,name:"@deepseek-ai/dsh-mcp-client",config:{...V,failOnStartupError:!0}}})}async function r1($,Z,J={}){let Y=new j9($);Y.on("failure",(H)=>_(`dsh catalog: ${H}`));let Q,W;try{await Y.initialize(),W=await Y.request(Z,J)}catch(H){Q=H}try{await Y.close()}catch(H){if(Q)throw AggregateError([Q,H],"DSH query and cleanup both failed");throw H}if(Q)throw Q;return W}var j9;var t2=T(()=>{W$();a1();I();j9=class j9 extends oG{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!Z_($.cwd))throw Error("DSH requires an absolute workspace");let Z=A9("dsh"),Y=rG(L0(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(r2(Y,"utf8"));_(`dsh runtime: ${Q.version} (${Z})`);let W=H_($.env),H=$.home??d1;iJ(H,{recursive:!0,mode:448});let V=V_($.cwd,$.profile);this.launchDir=Y_(L0(J_(),"lodestar-dsh-"));let X=import.meta.url.endsWith(".ts"),z=X?"dsh-bridge.ts":"dsh-bridge.js",G=r2(n5(new URL(`./${z}`,import.meta.url))),K=X?r2(n5(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),B=JSON.parse(r2(n5(new URL("../package.json",import.meta.url)),"utf8")),A=Buffer.from(JSON.stringify({name:B.name,version:B.version,type:"module",private:!0})),P=tG("sha256").update(G).update(K).update(A).digest("hex").slice(0,20),L=L0(Z,".lodestar-bridges",P);iJ(L,{recursive:!0});let j=L0(L,z),N=(b,c)=>{if(lJ(b))return;let S=`${b}.${sG()}.tmp`;try{dJ(S,c),Q_(S,b)}finally{if(lJ(S))a5(S)}};if(N(L0(L,"package.json"),A),X)N(L0(L,"dsh-protocol.ts"),K);N(j,G);let F=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((b)=>({id:b,disabled:!0})),{id:"approval",config:{policy:"ask"}},{id:"permission",config:{defaultPreset:"lodestar",presets:{lodestar:{sandbox:"danger-full-access",approval:"ask"}}}},{id:"system-prompt",config:{personaPrefix:"You are a coding agent powered by {{model}}.",personaSuffix:"Your working directory is {{cwd}}."}},{id:"skill-filesystem",config:{includeDefaultRoots:!0,...$.managedSkillDir?{customSkillDirs:[$.managedSkillDir]}:{}}},{insert:[{id:"lodestar-bridge",name:j},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...V]},...W],R=L0(this.launchDir,"bridge.patch.yml");dJ(R,JSON.stringify(F),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",k=[L0($_(Y),Q.bin.dsh),"--profile","sdk","--patch",R,...($.patches??[]).flatMap((b)=>["--patch",b])],C={...$.env};if(C.LODESTAR_AGENT_CAPABILITY&&C.LODESTAR_AGENT_URL)C.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:C.LODESTAR_AGENT_URL,capability:C.LODESTAR_AGENT_CAPABILITY});for(let b of Object.keys(C))if(b.startsWith("LODESTAR_AGENT_"))delete C[b];try{this.child=W_(M,k,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...C,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(b){throw a5(this.launchDir,{recursive:!0,force:!0}),b}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(b)=>{this.stderr=(this.stderr+b).slice(-16384),_(`dsh stderr: ${b.trimEnd()}`)}),this.child.stdin.on("error",(b)=>this.transportFailure(b));let v=eG({input:this.child.stdout,crlfDelay:1/0});v.on("line",(b)=>this.receive(b)),this.exitTask=new Promise((b)=>{this.child.once("error",(c)=>this.transportFailure(c)),this.child.once("close",(c,S)=>{this.exited=!0,v.close();let h=Error(`DSH exited code=${c} signal=${S}
22
- ${this.stderr}`);this.rejectPending(h),a5(this.launchDir,{recursive:!0,force:!0}),b(),this.emit("exit",{code:c,signal:S,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==fJ||typeof $.runtimeVersion!=="string"||!$.runtimeVersion)throw Error(`DSH handshake version mismatch: ${JSON.stringify($)}`);this.initialized=!0})}request($,Z={},J=30000){if(this.exited||this.closing&&$!=="shutdown")return Promise.reject(Error("DSH transport is closed"));let Y=++this.nextId;return new Promise((Q,W)=>{let H=J===null?void 0:setTimeout(()=>{this.pending.delete(Y),W(Error(`DSH ${$} timed out after ${J}ms
59
+ ${q.green}${q.bold}✓ 配置已写入${q.reset}`),console.log(` ${q.cyan}${O$}${q.reset}`),console.log(`
60
+ ${q.bold}启动 daemon...${q.reset}`);let z=E_(),X=process.platform==="win32"?"\\":"/",G=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(z.pid)console.log(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${z.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${H}${X}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${G}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${z.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),o2.close()}var q,o2;var tJ=T(()=>{n$();H$();f$();t1();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},o2=L_({input:process.stdin,output:process.stdout})});import{existsSync as k_,readFileSync as x_}from"node:fs";function sJ($,Z){return`${$}:${Z}`}function C_(){if(!k_(K9))return;try{let $=JSON.parse(x_(K9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");r2=new Set($.ids)}catch($){$5=$ instanceof Error?$:Error(String($))}}function eJ(){if($5)throw Error(`delegated-agent session registry is unavailable: ${$5.message}`)}function $Y($,Z){eJ();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=sJ($,J);if(r2.has(Y))return;let Q=new Set(r2);Q.add(Y),t(K9,{version:1,ids:[...Q].sort()}),r2=Q}function s1($,Z){return eJ(),r2.has(sJ($,Z))}var r2,$5=null;var t2=T(()=>{H$();f$();r2=new Set;C_()});var ZY=1;import{appendFileSync as QY,mkdirSync as b_,readdirSync as y_,unlinkSync as WY,existsSync as JY,statSync as w_,renameSync as f_,readFileSync as v_}from"node:fs";import{join as HY}from"node:path";function Y5($="development"){return $!=="test"}function VY($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function zY($,Z=o){return HY(Z,`${Z5}${VY($)}${J5}`)}function I_($){if(!$.startsWith(Z5)||!$.endsWith(J5))return null;let Z=$.slice(Z5.length,$.length-J5.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Y=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Y.getTime())?null:Y}function XY($,Z=new Date,J=h_){let Y;try{Y=y_($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),W=0;for(let H of Y){let V=I_(H);if(!V)continue;if(Math.round((Q.getTime()-V.getTime())/86400000)<J)continue;try{WY(HY($,H)),W++}catch{}}return W}function g_(){try{if(!JY(n1))return;let $=w_(n1);if(!$.isFile()||$.size===0)return;let Z=zY($.mtime);if(JY(Z)){QY(Z,v_(n1)),WY(n1);return}f_(n1,Z)}catch{}}function _($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
+ `;if(process.stderr.write(J),!Y5())return;try{let Y=VY(Z);if(YY!==Y)YY=Y,XY(o,Z);QY(zY(Z),J)}catch{}}var h_=7,Z5="daemon-",J5=".log",YY=null;var I=T(()=>{H$();if(Y5())try{b_(o,{recursive:!0})}catch{}if(Y5()){g_();try{XY(o)}catch{}}});import{EventEmitter as m_}from"node:events";import{createRequire as c_}from"node:module";import{createHash as p_,randomUUID as u_}from"node:crypto";import{createInterface as l_}from"node:readline";import{dirname as i_,join as D0,isAbsolute as d_}from"node:path";import{fileURLToPath as Q5}from"node:url";import{tmpdir as n_}from"node:os";import{existsSync as GY,mkdirSync as _Y,mkdtempSync as a_,readFileSync as s2,renameSync as o_,writeFileSync as KY,rmSync as W5}from"node:fs";import r_ from"cross-spawn";function t_($){let Z=$.LODESTAR_DSH_PROVIDER??"deepseek-official";if(Z==="deepseek-official")return[];if(Z!=="zai-coding-cn"&&Z!=="zai")throw Error(`Unsupported DSH provider: ${Z}`);let J=$.LODESTAR_DSH_MODELS===void 0?void 0:JSON.parse($.LODESTAR_DSH_MODELS);if(J!==void 0&&(!Array.isArray(J)||!J.every((Y)=>typeof Y==="string"&&Y)))throw Error("Invalid DSH GLM model catalog");return[{id:"llm-deepseek",disabled:!0},{id:"llm-pi-ai",disabled:!1,config:{providers:{[Z]:{apiKeyEnv:"LODESTAR_DSH_GLM_API_KEY",baseURL:$.LODESTAR_DSH_BASE_URL,compat:{supportsReasoningEffort:!0},reasoning:"high",...Array.isArray(J)?{models:J.map((Y)=>({id:Y,reasoningEfforts:{off:null,minimal:"minimal",low:"low",medium:"medium",high:"high",xhigh:"xhigh",max:"max"}}))}:{}}}}},{id:"agent-default-model",config:{provider:Z,model:$.LODESTAR_DSH_DEFAULT_MODEL??""}}]}function s_($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=s2(D0($,".mcp.json"),"utf8")}catch(Q){if(Q?.code==="ENOENT")return[];throw Q}let Y=JSON.parse(J);if(!Y.mcpServers||typeof Y.mcpServers!=="object"||Array.isArray(Y.mcpServers))throw Error("DSH project .mcp.json must contain an mcpServers object");return Object.entries(Y.mcpServers).map(([Q,W])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Q)||!W||typeof W!=="object")throw Error(`invalid DSH MCP server: ${Q}`);let H=W,V=H.type==="http"?{transport:"streamable-http",serverName:Q,url:H.url,headers:H.headers??{}}:H.type===void 0||H.type==="stdio"?{transport:"stdio",serverName:Q,command:H.command,args:H.args??[],env:H.env??{},cwd:$}:null;if(!V)throw Error(`DSH does not support MCP transport ${H.type} for ${Q}`);return{id:`lodestar-mcp-${Q}`,name:"@deepseek-ai/dsh-mcp-client",config:{...V,failOnStartupError:!0}}})}async function e1($,Z,J={}){let Y=new E9($);Y.on("failure",(H)=>_(`dsh catalog: ${H}`));let Q,W;try{await Y.initialize(),W=await Y.request(Z,J)}catch(H){Q=H}try{await Y.close()}catch(H){if(Q)throw AggregateError([Q,H],"DSH query and cleanup both failed");throw H}if(Q)throw Q;return W}var E9;var e2=T(()=>{H$();t1();I();E9=class E9 extends m_{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!d_($.cwd))throw Error("DSH requires an absolute workspace");let Z=U9("dsh"),Y=c_(D0(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(s2(Y,"utf8"));_(`dsh runtime: ${Q.version} (${Z})`);let W=t_($.env),H=$.home??a1;_Y(H,{recursive:!0,mode:448});let V=s_($.cwd,$.profile);this.launchDir=a_(D0(n_(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),X=z?"dsh-bridge.ts":"dsh-bridge.js",G=s2(Q5(new URL(`./${X}`,import.meta.url))),K=z?s2(Q5(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),B=JSON.parse(s2(Q5(new URL("../package.json",import.meta.url)),"utf8")),L=Buffer.from(JSON.stringify({name:B.name,version:B.version,type:"module",private:!0})),A=p_("sha256").update(G).update(K).update(L).digest("hex").slice(0,20),j=D0(Z,".lodestar-bridges",A);_Y(j,{recursive:!0});let P=D0(j,X),S=(b,h)=>{if(GY(b))return;let E=`${b}.${u_()}.tmp`;try{KY(E,h),o_(E,b)}finally{if(GY(E))W5(E)}};if(S(D0(j,"package.json"),L),z)S(D0(j,"dsh-protocol.ts"),K);S(P,G);let F=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((b)=>({id:b,disabled:!0})),{id:"approval",config:{policy:"ask"}},{id:"permission",config:{defaultPreset:"lodestar",presets:{lodestar:{sandbox:"danger-full-access",approval:"ask"}}}},{id:"system-prompt",config:{personaPrefix:"You are a coding agent powered by {{model}}.",personaSuffix:"Your working directory is {{cwd}}."}},{id:"skill-filesystem",config:{includeDefaultRoots:!0,...$.managedSkillDir?{customSkillDirs:[$.managedSkillDir]}:{}}},{insert:[{id:"lodestar-bridge",name:P},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...V]},...W],R=D0(this.launchDir,"bridge.patch.yml");KY(R,JSON.stringify(F),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",k=[D0(i_(Y),Q.bin.dsh),"--profile","sdk","--patch",R,...($.patches??[]).flatMap((b)=>["--patch",b])],C={...$.env};if(C.LODESTAR_AGENT_CAPABILITY&&C.LODESTAR_AGENT_URL)C.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:C.LODESTAR_AGENT_URL,capability:C.LODESTAR_AGENT_CAPABILITY});for(let b of Object.keys(C))if(b.startsWith("LODESTAR_AGENT_"))delete C[b];try{this.child=r_(M,k,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...C,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(b){throw W5(this.launchDir,{recursive:!0,force:!0}),b}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(b)=>{this.stderr=(this.stderr+b).slice(-16384),_(`dsh stderr: ${b.trimEnd()}`)}),this.child.stdin.on("error",(b)=>this.transportFailure(b));let c=l_({input:this.child.stdout,crlfDelay:1/0});c.on("line",(b)=>this.receive(b)),this.exitTask=new Promise((b)=>{this.child.once("error",(h)=>this.transportFailure(h)),this.child.once("close",(h,E)=>{this.exited=!0,c.close();let v=Error(`DSH exited code=${h} signal=${E}
62
+ ${this.stderr}`);this.rejectPending(v),W5(this.launchDir,{recursive:!0,force:!0}),b(),this.emit("exit",{code:h,signal:E,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==ZY||typeof $.runtimeVersion!=="string"||!$.runtimeVersion)throw Error(`DSH handshake version mismatch: ${JSON.stringify($)}`);this.initialized=!0})}request($,Z={},J=30000){if(this.exited||this.closing&&$!=="shutdown")return Promise.reject(Error("DSH transport is closed"));let Y=++this.nextId;return new Promise((Q,W)=>{let H=J===null?void 0:setTimeout(()=>{this.pending.delete(Y),W(Error(`DSH ${$} timed out after ${J}ms
23
63
  ${this.stderr}`))},J);this.pending.set(Y,{resolve:Q,reject:W,timer:H}),this.child.stdin.write(JSON.stringify({jsonrpc:"2.0",id:Y,method:$,params:Z})+`
24
- `,(V)=>{if(V)this.transportFailure(V)})})}receive($){try{let Z=JSON.parse($);if(Z.jsonrpc!=="2.0")throw Error("invalid DSH JSON-RPC envelope");if(typeof Z.id==="number"){let J=this.pending.get(Z.id);if(!J){_(`dsh: unexpected response id=${Z.id}`);return}if(this.pending.delete(Z.id),clearTimeout(J.timer),Z.error)J.reject(Error(`DSH RPC error: ${Z.error.message}`));else if("result"in Z)J.resolve(Z.result);else J.reject(Error("DSH response has neither result nor error"))}else if(typeof Z.method==="string"&&Z.params&&typeof Z.params==="object")this.emit("notification",{method:Z.method,params:Z.params});else throw Error("invalid DSH notification")}catch(Z){this.transportFailure(Z instanceof Error?Z:Error(String(Z)))}}rejectPending($){for(let Z of this.pending.values())clearTimeout(Z.timer),Z.reject($);this.pending.clear()}transportFailure($){this.rejectPending($),this.emit("failure",$)}close($=3000){return this.closeTask??=this.dispose($).catch((Z)=>{throw this.closeTask=void 0,Z})}async dispose($){if(this.exited)return;if(this.closing=!0,this.initialized)try{await this.request("shutdown",{},$)}catch(J){_(`dsh shutdown: ${J}`)}this.child.stdin.end();let Z=async(J)=>{let Y;return await Promise.race([this.exitTask,new Promise((Q)=>{Y=setTimeout(Q,J)})]),clearTimeout(Y),this.exited};if(await Z($))return;if(_(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(_(`dsh: kill unresponsive owned child pid=${this.pid}`),this.child.kill("SIGKILL"),!await Z($))throw Error(`DSH child exit not confirmed: pid=${this.pid}`)}}});function H0($){return typeof $==="string"&&o5.includes($)}function _$($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function O$($){return typeof $==="string"&&r5.includes($)}function t1($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function V0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var o5,r5,h0="max",B1;var L$=T(()=>{o5=["codex","claude","dsh"];r5=["low","medium","high","xhigh","max","default"];B1=class B1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as X_}from"node:fs";import{homedir as aJ}from"node:os";function nJ($){return $.replace(/^~(?=\/|$)/,aJ())}function z_($){let Z={_:{}},J="_";for(let Y of $.split(`
25
- `)){let Q=G_(Y).trim();if(!Q)continue;let W=Q.match(/^\[([^\]]+)\]$/);if(W){J=W[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let V=H[2].trim(),X=V.startsWith('"')&&V.endsWith('"'),z=V.startsWith("'")&&V.endsWith("'");if(X||z){if(V=V.slice(1,-1),X)V=V.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=V}}return Z}function G_($){let Z=null,J=!1;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==="double"){if(J){J=!1;continue}if(Q==="\\"){J=!0;continue}if(Q==='"')Z=null;continue}if(Z==="single"){if(Q==="'")Z=null;continue}if(Q==='"')Z="double";else if(Q==="'")Z="single";else if(Q==="#")return $.slice(0,Y)}return $}function D9(){let $;try{$=X_(U$,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${U$}
64
+ `,(V)=>{if(V)this.transportFailure(V)})})}receive($){try{let Z=JSON.parse($);if(Z.jsonrpc!=="2.0")throw Error("invalid DSH JSON-RPC envelope");if(typeof Z.id==="number"){let J=this.pending.get(Z.id);if(!J){_(`dsh: unexpected response id=${Z.id}`);return}if(this.pending.delete(Z.id),clearTimeout(J.timer),Z.error)J.reject(Error(`DSH RPC error: ${Z.error.message}`));else if("result"in Z)J.resolve(Z.result);else J.reject(Error("DSH response has neither result nor error"))}else if(typeof Z.method==="string"&&Z.params&&typeof Z.params==="object")this.emit("notification",{method:Z.method,params:Z.params});else throw Error("invalid DSH notification")}catch(Z){this.transportFailure(Z instanceof Error?Z:Error(String(Z)))}}rejectPending($){for(let Z of this.pending.values())clearTimeout(Z.timer),Z.reject($);this.pending.clear()}transportFailure($){this.rejectPending($),this.emit("failure",$)}close($=3000){return this.closeTask??=this.dispose($).catch((Z)=>{throw this.closeTask=void 0,Z})}async dispose($){if(this.exited)return;if(this.closing=!0,this.initialized)try{await this.request("shutdown",{},$)}catch(J){_(`dsh shutdown: ${J}`)}this.child.stdin.end();let Z=async(J)=>{let Y;return await Promise.race([this.exitTask,new Promise((Q)=>{Y=setTimeout(Q,J)})]),clearTimeout(Y),this.exited};if(await Z($))return;if(_(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(_(`dsh: kill unresponsive owned child pid=${this.pid}`),this.child.kill("SIGKILL"),!await Z($))throw Error(`DSH child exit not confirmed: pid=${this.pid}`)}}});function z0($){return typeof $==="string"&&H5.includes($)}function K$($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function T$($){return typeof $==="string"&&V5.includes($)}function $2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function X0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var H5,V5,g0="max",q1;var P$=T(()=>{H5=["codex","claude","dsh"];V5=["low","medium","high","xhigh","max","default"];q1=class q1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as e_}from"node:fs";import{homedir as AY}from"node:os";function BY($){return $.replace(/^~(?=\/|$)/,AY())}function $K($){let Z={_:{}},J="_";for(let Y of $.split(`
65
+ `)){let Q=ZK(Y).trim();if(!Q)continue;let W=Q.match(/^\[([^\]]+)\]$/);if(W){J=W[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let V=H[2].trim(),z=V.startsWith('"')&&V.endsWith('"'),X=V.startsWith("'")&&V.endsWith("'");if(z||X){if(V=V.slice(1,-1),z)V=V.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=V}}return Z}function ZK($){let Z=null,J=!1;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==="double"){if(J){J=!1;continue}if(Q==="\\"){J=!0;continue}if(Q==='"')Z=null;continue}if(Z==="single"){if(Q==="'")Z=null;continue}if(Q==='"')Z="double";else if(Q==="'")Z="single";else if(Q==="#")return $.slice(0,Y)}return $}function S9(){let $;try{$=e_(O$,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${O$}
26
66
  `+" → 运行 `lodestar-setup` 走交互式向导生成 (Feishu / Codex / 工作目录)\n"+` → 或手写: 设 LODESTAR_CONFIG=/path/to/config.toml 覆盖默认路径
27
67
  `+` [feishu]
28
68
  app_id = "cli_xxx"
29
69
  app_secret = "xxx"
30
70
 
31
- `),M}let Z=z_($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${U$} is missing [feishu].app_id / [feishu].app_secret`);let Q=nJ(Z.runtime?.projects_root??aJ()),W={codex:!1,claude:!1,dsh:!1},H=Z["runtime.agent_auto_update"],V=Z.runtime?.agent_auto_update;if(V!==void 0){if(H)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(V!=="true"&&V!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${V}"`);for(let M of["codex","claude","dsh"])W[M]=V==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
32
- `)}else if(H)for(let[M,k]of Object.entries(H)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(k!=="true"&&k!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${k}"`);W[M]=k==="true"}let X=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(X!=="bucket"&&X!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let z=X,G=Z.notify?.bind??"127.0.0.1",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let B=Number.parseInt(K,10);if(!Number.isFinite(B)||B<=0||B>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let A=(M)=>{let k=Z[M]??{},C={};for(let[v,b]of Object.entries(k))if(typeof b==="string"&&b.length>0)C[v]=b;return C},P=()=>{let M={};for(let[k,C]of Object.entries(Z)){if(!k.startsWith("claude.models."))continue;let b=k.slice(14).trim();if(!b)continue;let c={};for(let[S,h]of Object.entries(C)){if(typeof h!=="string"||h.length===0)continue;if(S.trim()==="model")c.model=h}M[b]=c}return M},L=()=>{let M={},k="projects.";for(let[C,v]of Object.entries(Z)){if(!C.startsWith("projects."))continue;let b=C.slice(9).trim();if(!b)continue;let c={};for(let[S,h]of Object.entries(v)){if(typeof h!=="string"||h.length===0)continue;switch(S.trim()){case"cwd":c.cwd=h;break;case"setting_sources":c.settingSources=h;break;case"strict_mcp":c.strictMcp=h==="true";break;case"tools":c.tools=h;break;case"load_project_mcp":c.loadProjectMcp=h==="true";break}}M[b]=c}return M},j=()=>{let M={},k="token_source.";for(let[C,v]of Object.entries(Z)){if(!C.startsWith("token_source."))continue;let b=C.slice(13).trim();if(!b)continue;let c={};for(let[S,h]of Object.entries(v)){if(typeof h!=="string")continue;let m=S.trim();if(m==="default")c.default=h==="true";else if(m==="agent"||m==="display"||m==="auth"||m==="base_url"||m==="auth_token"||m==="api_key"||m==="bin"||m==="model"||m==="effort"||m==="models"||m==="hidden_models"||m==="custom_models"||m==="slots"||m==="usage")c[m]=h}M[b]=c}return M},N=A("codex.env"),F=A("claude.env"),R=Z.claude?.bin?nJ(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:z,agent_auto_update:W},notify:{bind:G,port:B},codex:{env:N},claude:{bin:R,env:F,models:P()},projects:L(),token_sources:j()}}function oJ(){f.token_sources=D9().token_sources}var f;var k$=T(()=>{W$();f=D9()});function X$($){return typeof $==="string"&&$?$:void 0}function n($){return $!=null&&typeof $==="object"?$:null}function j0($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function M9($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Y=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Y}]`}function K_($){let Z=$.slice(0,e5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function B_($){let Z=n($);if(!Z)return null;let J=n(Z.event),Y=n(Z.payload);return n(Z.item)??n(Z.responseItem)??n(Z.rawItem)??n(J?.item)??n(J?.responseItem)??n(J?.rawItem)??n(Y?.item)??n(Y?.responseItem)??n(Y?.rawItem)??(s2(Z.type)?Z:null)??(J&&s2(J.type)?J:null)??(Y&&s2(Y.type)?Y:null)}function A_($){let Z=[],J=new WeakSet,Y=(Q,W,H)=>{if(Z.length>=e5||H>6)return;if(Array.isArray(Q)){if(W)Z.push(`${W}[]`);if(Q.length>0)Y(Q[0],W?`${W}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let V of Object.keys(Q)){if(Z.length>=e5)return;let X=W?`${W}.${V}`:V;Z.push(X),Y(Q[V],X,H+1)}};return Y($,"",0),Z}function $6($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Y,Q)=>{if(typeof Q==="bigint")return`${Q.toString()}n`;if(typeof Q==="string"&&Q.length>s5)return`${Q.slice(0,s5)}...<truncated ${Q.length-s5} chars>`;if(Q!=null&&typeof Q==="object"){if(Z.has(Q))return"[Circular]";Z.add(Q)}return Q})??String($)}catch(Y){J=`<unserializable: ${Y}>`}if(J.length>t5)return`${J.slice(0,t5)}...<truncated ${J.length-t5} chars>`;return J}function v$($,Z){let J=n(Z),Y=J?n(J.params):null,Q=J?n(J.item)??n(Y?.item):null,W=J?X$(J.method)??"-":"-";_([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${j0(W)}`,`rootKeys=${M9(J)}`,`itemKeys=${M9(Q)}`,`payload=${$6(Z)}`].join(" "))}function Z6($,Z,J){let Y=n(Z),Q=B_(Z),W=[`phase=${j0(J.phase??"event")}`,`method=${j0($)}`,`sourceMethod=${j0(J.sourceMethod)}`,`sourceType=${j0(J.sourceType)}`,`sessionId=${j0(J.sessionId)}`,`threadId=${j0(J.threadId)}`,`turnId=${j0(J.turnId)}`,`itemId=${j0(J.itemId)}`].join(" ");if(_(`codex-process: CONTEXT_COMPACTION_EVENT ${W} rootKeys=${M9(Y)} itemKeys=${M9(Q)}`),_(`codex-process: CONTEXT_COMPACTION_PATHS ${W} paths=${K_(A_(Z))}`),Q)_(`codex-process: CONTEXT_COMPACTION_ITEM ${W} item=${$6(Q)}`);_(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${W} payload=${$6(Z)}`)}function s2($){if(typeof $!=="string")return null;return __.has($)?$:null}function q_($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||rJ.has(Z))return"end";return"event"}function J6($,Z){return tJ($,n(Z)??{})}function Y6($){let Z=n($);if(!Z)return null;let J=X$(Z.method)??X$(Z.type)??"raw_message";return tJ(J,Z)}function tJ($,Z){let J=n(Z.payload),Y=[Z,n(Z.event),J,n(Z.item),n(Z.responseItem),n(Z.rawItem)].filter((X)=>X!=null),Q=null;for(let X of Y)if(Q=s2(X.type),Q)break;if(!rJ.has($)&&!Q)return null;let W=n(Z.item)??n(Z.responseItem)??n(Z.rawItem),H=Q==="compacted"&&J?J:W&&s2(W.type)?W:Z,V=n(H.item)??n(H.responseItem)??n(H.rawItem)??W??{};return{...H,threadId:X$(H.threadId)??X$(H.thread_id)??X$(Z.threadId)??X$(Z.thread_id),turnId:X$(H.turnId)??X$(H.turn_id)??X$(Z.turnId)??X$(Z.turn_id),itemId:X$(H.itemId)??X$(H.item_id)??X$(V.id)??X$(V.itemId)??X$(V.item_id),timestamp:X$(Z.timestamp)??X$(H.timestamp),recordType:X$(Z.type),phase:q_(Q,$),sourceMethod:$,sourceType:Q??$}}var rJ,__,t5=200000,s5=50000,e5=400;var Q6=T(()=>{I();rJ=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),__=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function e2($){return $!=null&&typeof $==="object"?$:null}function D0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function sJ($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function F9($,Z){return $?D0($[Z]):void 0}function s1($){let Z=e2($);if(!Z)return null;let J=e2(Z.inputTokensDetails)??e2(Z.input_tokens_details),Y=e2(Z.outputTokensDetails)??e2(Z.output_tokens_details),Q={total_tokens:D0(Z.totalTokens??Z.total_tokens),input_tokens:D0(Z.inputTokens??Z.input_tokens),output_tokens:D0(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:D0(Z.reasoningOutputTokens??Z.reasoning_output_tokens??F9(Y,"reasoningTokens")??F9(Y,"reasoning_tokens")),cache_creation_input_tokens:D0(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:D0(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??F9(J,"cachedTokens")??F9(J,"cached_tokens"))};return sJ(Q)?Q:null}function W6($,Z){let J=(Q)=>{let W=D0($?.[Q]),H=D0(Z?.[Q]);if(W===void 0&&H===void 0)return;return Math.max(0,(W??0)-(H??0))},Y={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return sJ(Y)?Y:null}function H6($){if(!$)return null;if(typeof $.input_tokens==="number"||typeof $.cache_creation_input_tokens==="number"||typeof $.output_tokens==="number")return($.input_tokens??0)+($.cache_creation_input_tokens??0)+($.output_tokens??0);return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function eJ($){let Z=$.trim();if(Z.length<2)return Z;let J=R9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/''/g,"'");if(Z[0]==='"')return Y.replace(/\\"/g,'"');return Y}function X6($){let Z=L_(String($??"")),J=Z.split(`
71
+ `),M}let Z=$K($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${O$} is missing [feishu].app_id / [feishu].app_secret`);let Q=BY(Z.runtime?.projects_root??AY()),W={codex:!1,claude:!1,dsh:!1},H=Z["runtime.agent_auto_update"],V=Z.runtime?.agent_auto_update;if(V!==void 0){if(H)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(V!=="true"&&V!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${V}"`);for(let M of["codex","claude","dsh"])W[M]=V==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
72
+ `)}else if(H)for(let[M,k]of Object.entries(H)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(k!=="true"&&k!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${k}"`);W[M]=k==="true"}let z=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(z!=="bucket"&&z!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let X=z,G=Z.notify?.bind??"127.0.0.1",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let B=Number.parseInt(K,10);if(!Number.isFinite(B)||B<=0||B>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let L=(M)=>{let k=Z[M]??{},C={};for(let[c,b]of Object.entries(k))if(typeof b==="string"&&b.length>0)C[c]=b;return C},A=()=>{let M={};for(let[k,C]of Object.entries(Z)){if(!k.startsWith("claude.models."))continue;let b=k.slice(14).trim();if(!b)continue;let h={};for(let[E,v]of Object.entries(C)){if(typeof v!=="string"||v.length===0)continue;if(E.trim()==="model")h.model=v}M[b]=h}return M},j=()=>{let M={},k="projects.";for(let[C,c]of Object.entries(Z)){if(!C.startsWith("projects."))continue;let b=C.slice(9).trim();if(!b)continue;let h={};for(let[E,v]of Object.entries(c)){if(typeof v!=="string"||v.length===0)continue;switch(E.trim()){case"cwd":h.cwd=v;break;case"setting_sources":h.settingSources=v;break;case"strict_mcp":h.strictMcp=v==="true";break;case"tools":h.tools=v;break;case"load_project_mcp":h.loadProjectMcp=v==="true";break}}M[b]=h}return M},P=()=>{let M={},k="token_source.";for(let[C,c]of Object.entries(Z)){if(!C.startsWith("token_source."))continue;let b=C.slice(13).trim();if(!b)continue;let h={};for(let[E,v]of Object.entries(c)){if(typeof v!=="string")continue;let m=E.trim();if(m==="default")h.default=v==="true";else if(m==="agent"||m==="display"||m==="auth"||m==="base_url"||m==="auth_token"||m==="api_key"||m==="bin"||m==="model"||m==="effort"||m==="models"||m==="hidden_models"||m==="custom_models"||m==="slots"||m==="usage")h[m]=v}M[b]=h}return M},S=L("codex.env"),F=L("claude.env"),R=Z.claude?.bin?BY(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:X,agent_auto_update:W},notify:{bind:G,port:B},codex:{env:S},claude:{bin:R,env:F,models:A()},projects:j(),token_sources:P()}}function qY(){f.token_sources=S9().token_sources}var f;var x$=T(()=>{H$();f=S9()});function X$($){return typeof $==="string"&&$?$:void 0}function n($){return $!=null&&typeof $==="object"?$:null}function M0($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function k9($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Y=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Y}]`}function YK($){let Z=$.slice(0,G5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function QK($){let Z=n($);if(!Z)return null;let J=n(Z.event),Y=n(Z.payload);return n(Z.item)??n(Z.responseItem)??n(Z.rawItem)??n(J?.item)??n(J?.responseItem)??n(J?.rawItem)??n(Y?.item)??n(Y?.responseItem)??n(Y?.rawItem)??($4(Z.type)?Z:null)??(J&&$4(J.type)?J:null)??(Y&&$4(Y.type)?Y:null)}function WK($){let Z=[],J=new WeakSet,Y=(Q,W,H)=>{if(Z.length>=G5||H>6)return;if(Array.isArray(Q)){if(W)Z.push(`${W}[]`);if(Q.length>0)Y(Q[0],W?`${W}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let V of Object.keys(Q)){if(Z.length>=G5)return;let z=W?`${W}.${V}`:V;Z.push(z),Y(Q[V],z,H+1)}};return Y($,"",0),Z}function _5($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Y,Q)=>{if(typeof Q==="bigint")return`${Q.toString()}n`;if(typeof Q==="string"&&Q.length>X5)return`${Q.slice(0,X5)}...<truncated ${Q.length-X5} chars>`;if(Q!=null&&typeof Q==="object"){if(Z.has(Q))return"[Circular]";Z.add(Q)}return Q})??String($)}catch(Y){J=`<unserializable: ${Y}>`}if(J.length>z5)return`${J.slice(0,z5)}...<truncated ${J.length-z5} chars>`;return J}function h$($,Z){let J=n(Z),Y=J?n(J.params):null,Q=J?n(J.item)??n(Y?.item):null,W=J?X$(J.method)??"-":"-";_([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${M0(W)}`,`rootKeys=${k9(J)}`,`itemKeys=${k9(Q)}`,`payload=${_5(Z)}`].join(" "))}function K5($,Z,J){let Y=n(Z),Q=QK(Z),W=[`phase=${M0(J.phase??"event")}`,`method=${M0($)}`,`sourceMethod=${M0(J.sourceMethod)}`,`sourceType=${M0(J.sourceType)}`,`sessionId=${M0(J.sessionId)}`,`threadId=${M0(J.threadId)}`,`turnId=${M0(J.turnId)}`,`itemId=${M0(J.itemId)}`].join(" ");if(_(`codex-process: CONTEXT_COMPACTION_EVENT ${W} rootKeys=${k9(Y)} itemKeys=${k9(Q)}`),_(`codex-process: CONTEXT_COMPACTION_PATHS ${W} paths=${YK(WK(Z))}`),Q)_(`codex-process: CONTEXT_COMPACTION_ITEM ${W} item=${_5(Q)}`);_(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${W} payload=${_5(Z)}`)}function $4($){if(typeof $!=="string")return null;return JK.has($)?$:null}function HK($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||LY.has(Z))return"end";return"event"}function B5($,Z){return jY($,n(Z)??{})}function A5($){let Z=n($);if(!Z)return null;let J=X$(Z.method)??X$(Z.type)??"raw_message";return jY(J,Z)}function jY($,Z){let J=n(Z.payload),Y=[Z,n(Z.event),J,n(Z.item),n(Z.responseItem),n(Z.rawItem)].filter((z)=>z!=null),Q=null;for(let z of Y)if(Q=$4(z.type),Q)break;if(!LY.has($)&&!Q)return null;let W=n(Z.item)??n(Z.responseItem)??n(Z.rawItem),H=Q==="compacted"&&J?J:W&&$4(W.type)?W:Z,V=n(H.item)??n(H.responseItem)??n(H.rawItem)??W??{};return{...H,threadId:X$(H.threadId)??X$(H.thread_id)??X$(Z.threadId)??X$(Z.thread_id),turnId:X$(H.turnId)??X$(H.turn_id)??X$(Z.turnId)??X$(Z.turn_id),itemId:X$(H.itemId)??X$(H.item_id)??X$(V.id)??X$(V.itemId)??X$(V.item_id),timestamp:X$(Z.timestamp)??X$(H.timestamp),recordType:X$(Z.type),phase:HK(Q,$),sourceMethod:$,sourceType:Q??$}}var LY,JK,z5=200000,X5=50000,G5=400;var q5=T(()=>{I();LY=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),JK=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function Z4($){return $!=null&&typeof $==="object"?$:null}function F0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function PY($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function x9($,Z){return $?F0($[Z]):void 0}function Z2($){let Z=Z4($);if(!Z)return null;let J=Z4(Z.inputTokensDetails)??Z4(Z.input_tokens_details),Y=Z4(Z.outputTokensDetails)??Z4(Z.output_tokens_details),Q={total_tokens:F0(Z.totalTokens??Z.total_tokens),input_tokens:F0(Z.inputTokens??Z.input_tokens),output_tokens:F0(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:F0(Z.reasoningOutputTokens??Z.reasoning_output_tokens??x9(Y,"reasoningTokens")??x9(Y,"reasoning_tokens")),cache_creation_input_tokens:F0(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:F0(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??x9(J,"cachedTokens")??x9(J,"cached_tokens"))};return PY(Q)?Q:null}function L5($,Z){let J=(Q)=>{let W=F0($?.[Q]),H=F0(Z?.[Q]);if(W===void 0&&H===void 0)return;return Math.max(0,(W??0)-(H??0))},Y={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return PY(Y)?Y:null}function j5($){if(!$)return null;if(typeof $.input_tokens==="number"||typeof $.cache_creation_input_tokens==="number"||typeof $.output_tokens==="number")return($.input_tokens??0)+($.cache_creation_input_tokens??0)+($.output_tokens??0);return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function DY($){let Z=$.trim();if(Z.length<2)return Z;let J=C9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/''/g,"'");if(Z[0]==='"')return Y.replace(/\\"/g,'"');return Y}function D5($){let Z=zK(String($??"")),J=Z.split(`
33
73
  `,1)[0]?.trim()??"",Q=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),W=Q?Z.split(`
34
74
  `).slice(1).join(`
35
- `).trimStart():Z;return{description:Q,command:W||Z}}function e1($,Z=60){let{description:J,command:Y}=X6($);if(J)return J;return P_(Y).replace(/\s+/g," ").trim().slice(0,Z)}function P_($){let Z=$.split(/\r?\n/).map((J)=>J.trim()).filter(Boolean);return Z.find((J)=>!J.startsWith("#")&&!/^set\s+-/.test(J)&&!/^cd\s+/.test(J)&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(J)&&!/^cat\s+<<['"]?\w+['"]?/.test(J))??Z[Z.length-1]??""}function L_($){let Z=$.replace(/\r\n/g,`
36
- `).trim(),J=Z.match(/^(?:\/usr\/bin\/env\s+)?(?:\/[\w./-]+\/)?(?:ba|z|fi)?sh\s+-[A-Za-z]*c[A-Za-z]*\s+([\s\S]+)$/);if(J){let Q=D_(J[1]);return V6(Q||Z)}let Y=j_(Z);if(Y)return Y;return V6(Z)}function j_($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=eJ(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Y=Z[2];for(;;){let Q=Y.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Q)break;let W=Q[1].toLowerCase();if(W==="-command"||W==="-c")return V6(eJ(Q[2]));if(Y=Q[2],W==="-executionpolicy"||W==="-inputformat"||W==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function D_($){let Z=$.trim();if(Z.length<2)return Z;let J=R9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/'\\''/g,"'");return Y.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
37
- `)}function V6($){let Z=$.trim(),J=Z[0];if(!R9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!M_(Y,J))return Z;if(J!=='"')return Y.replace(/'\s*$/,"");return Y.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
38
- `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(H,V)=>` $(${V})`)}function M_($,Z){let J=R9[Z];for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==='"'&&Q==="\\"&&Y+1<$.length){Y++;continue}if(Q===J)return/^[\s]*$/.test($.slice(Y+1))}return!1}var R9;var U9=T(()=>{R9={'"':'"',"'":"'","“":"”"}});function O($){return $ instanceof Error?$.message:String($)}function D$($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function $Y($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,W)=>{Y=setTimeout(()=>W(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as ZY}from"node:path";function F_($){return $.kind==="fresh"?null:$.source.provider}function K$($,Z,J){let Y=F_($);if(Y&&Y!==Z)throw Error(`conversation launch provider mismatch: source=${Y} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!ZY($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!ZY(J))throw Error(`expected conversation cwd is not absolute: ${J}`);if($.source.cwd===null)throw Error("conversation launch source cwd is missing");if($.source.cwd!==J)throw Error(`conversation launch cwd mismatch: source=${$.source.cwd} target=${J}`)}if($.kind!=="fork"||!$.through)return;if($.through.provider!==Z||$.through.source.provider!==Z)throw Error(`conversation checkpoint provider mismatch: checkpoint=${$.through.provider} target=${Z}`);if($.through.source.sessionId!==$.source.sessionId)throw Error("conversation checkpoint source does not match fork source");if($.through.source.cwd!==$.source.cwd)throw Error("conversation checkpoint cwd does not match fork source");if(!$.through.id.trim())throw Error("conversation checkpoint id is empty");if(Z==="dsh"&&(!/^\d+$/.test($.through.id)||!Number.isSafeInteger(Number($.through.id))))throw Error("DSH checkpoint must be a non-negative event sequence")}var A1=()=>{};import{createHash as R_,randomUUID as JY}from"node:crypto";import{existsSync as z6,lstatSync as G6,mkdirSync as _6,readFileSync as YY,readdirSync as U_,realpathSync as O9,symlinkSync as O_,writeFileSync as T_}from"node:fs";import{homedir as N_}from"node:os";import{join as M0,resolve as E_}from"node:path";class QY{defaultHome;root;stateFile;constructor($=E_(process.env.CODEX_HOME||M0(N_(),".codex")),Z=VJ,J=XJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!z6(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(YY(this.stateFile,"utf8"));if(!$||$.version!==1||!Array.isArray($.accounts)||!$.selections||typeof $.selections!=="object"||Array.isArray($.selections))throw Error("Codex 账号记录格式无效");let Z=new Set,J=new Set;for(let Y of $.accounts){if(!Y||!/^[a-f0-9-]{36}$/.test(Y.id)||typeof Y.name!=="string"||Z.has(Y.id)||J.has(this.nameKey(Y.name)))throw Error("Codex 账号记录重复或无效");this.validateName(Y.name),Z.add(Y.id),J.add(this.nameKey(Y.name))}for(let Y of Object.values($.selections))if(Y!==l&&!Z.has(Y))throw Error("Codex 账号选择指向不存在的账号");return $}nameKey($){return $.normalize("NFC").trim().toLowerCase()}validateName($){if(!$.trim()||$.length>80||/[\x00-\x1f\x7f/\\]/.test($)||["default","默认",".",".."].includes(this.nameKey($)))throw Error("备注名须为 1–80 个字符,不能包含换行或路径分隔符;default/默认为保留名称")}list(){return[{id:l,name:"默认"},...this.read().accounts.map(($)=>({...$}))]}get($){let Z=this.list().find((J)=>J.id===$);if(!Z)throw Error(`Codex 账号不存在:${$}`);return Z}find($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(l);let Z=this.list().find((J)=>this.nameKey(J.name)===this.nameKey($));if(!Z)throw Error(`Codex 账号不存在:${$};先发送 codex-login ${$}`);return Z}ensure($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(l);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:JY(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),t(this.stateFile,Z),Y}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:l}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],t(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),t(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==l){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:JY()}),t(this.stateFile,J)}}home($=l){return $===l?this.defaultHome:M0(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===l)return Z;let J;try{J=G6(Z)}catch(W){if(W.code!=="ENOENT")throw W}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(_6(Z,{recursive:!0,mode:448}),_6(this.defaultHome,{recursive:!0,mode:448}),O9(Z)===O9(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=G6(M0(Z,"auth.json"))}catch(W){if(W.code!=="ENOENT")throw W}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{T_(M0(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(W){if(W.code!=="EEXIST")throw W}for(let W of S_){let H=M0(this.defaultHome,W);_6(H,{recursive:!0,mode:448}),this.link(H,M0(Z,W),!0)}let Q=new Set([...k_,...U_(this.defaultHome).filter((W)=>W.endsWith(".config.toml"))]);for(let W of Q){let H=M0(this.defaultHome,W);if(z6(H))this.link(H,M0(Z,W),!1)}return Z}link($,Z,J){let Y;try{Y=G6(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||O9(Z)!==O9($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}O_($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&B6($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),W={...Z,CODEX_HOME:Q};if($!==l){W.CODEX_SQLITE_HOME=Z.CODEX_SQLITE_HOME||this.defaultHome;for(let H of["CODEX_API_KEY","OPENAI_API_KEY","CODEX_ACCESS_TOKEN","OPENAI_FEDERATION_RULE_ID","OPENAI_IDENTITY_TOKEN_FILE","OPENAI_WORKLOAD_IDENTITY_CONTEXT"])delete W[H]}return W}cliArgs($){return this.get($),$===l?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=M0(this.home($),"auth.json");if(!z6(Z))return null;let Y=JSON.parse(YY(Z,"utf8"))?.tokens;if(!Y?.account_id||typeof Y.id_token!=="string")return null;let Q=Y.id_token.split(".")[1];if(!Q)throw Error("Codex 身份 Token 格式无效");let W=JSON.parse(Buffer.from(Q,"base64url").toString("utf8"));if(typeof W.sub!=="string"||!W.sub)return null;return R_("sha256").update(JSON.stringify([Y.account_id,W.sub])).digest("hex")}}function $2($,Z,J=!0){if(WY.set($,Z),!J)return;if(!T9.has($))$.once("exit",()=>T9.delete($));T9.set($,Z)}function K6($){return[...T9].some(([Z,J])=>J===$&&Z.isAlive())}function B6($){return $4.has($)}function HY($){if($4.has($))throw Error("该账号已有登录任务");if(K6($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return $4.set($,Z),()=>{if($4.get($)===Z)$4.delete($)}}function F0($){return $?WY.get($)??l:l}var l="default",S_,k_,y,WY,T9,$4;var h$=T(()=>{W$();w$();S_=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],k_=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];y=new QY,WY=new WeakMap,T9=new Map;$4=new Map});function A6($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function x_($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function Z4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:A6($.subscriptionType,J.fiveHour)}}function q6($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=Z4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function P6($,Z,J=Date.now(),Y){let Q={state:"miss",score:null,shares:null,remaining:null,hours:null};if($.state!=="ok")return{...Q,reason:$.state==="network"?$.reason??"额度读取失败":$.state};let W=x_($.subscriptionType);if(W===null)return{...Q,reason:`未知周额度套餐:${$.subscriptionType??"MISS"}`};if(Q.shares=W,Y==="ultra"&&$.subscriptionType==="plus")return{...Q,state:"excluded",reason:"Ultra 自动选择不使用 Plus"};let H=Z4($,Z),V=[H.fiveHour,H.weekly].filter((P)=>P!==null),X=V.filter((P)=>P.percent!==null&&P.percent>=100);if(X.length||$.ordinaryUsageAllowed===!1||H.rateLimitReachedType||H.spendControlReached===!0){let P=X.map((L)=>L.resetsAt?.getTime()).filter((L)=>L!=null&&Number.isFinite(L)&&L>J);return{...Q,state:"exhausted",reason:"额度耗尽",...P.length===X.length&&P.length?{retryAt:Math.max(...P)}:{}}}if(V.some((P)=>P.percent===null||!Number.isFinite(P.percent)||P.percent<0))return{...Q,reason:"额度百分比 MISS"};let z=H.weekly;if(!z||z.percent===null)return{...Q,reason:"周额度 MISS"};let G=z.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Q,reason:"周重置时间 MISS 或已过期"};let K=W*(100-z.percent)/100,B=(G-J)/3600000,A=K/B;if(Y==="ultra"&&K<0.5)return{...Q,state:"waiting",remaining:K,hours:B,weeklyScore:A,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:G};if($.subscriptionType==="plus"){let P=H.fiveHour,L=0.15*(100-P.percent)/100,j=P.unreportedFull?5:((P.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(j)||j<=0)return{...Q,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:W,remaining:K,hours:B,weeklyScore:A,fiveHourRemaining:L,fiveHourHours:j,availableNow:Math.min(K,L),score:Math.min(A,L/j)}}return{state:"ready",shares:W,remaining:K,hours:B,weeklyScore:A,availableNow:K,score:A}}function N9($){if(!$||typeof $!=="object")return!1;let Z=$;if(Z.codexErrorInfo==="usageLimitExceeded"||Z.type==="usage_limit_reached"||Z.code==="usage_limit_reached")return!0;return typeof Z.message==="string"&&/^You(?:'|’)ve hit your usage limit\b/i.test(Z.message)}import{closeSync as C_,existsSync as b_,mkdirSync as y_,openSync as w_,readdirSync as f_,readSync as v_,statSync as S9,writeFileSync as h_}from"node:fs";import{homedir as L6}from"node:os";import{delimiter as VY,isAbsolute as XY,join as I0}from"node:path";import{EventEmitter as I_}from"node:events";import{StringDecoder as zY}from"node:string_decoder";import{spawn as g_}from"cross-spawn";function J4(){return d2("codex","codex")}function m_(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([I0(L6(),".local","npm-global","bin"),I0(L6(),".local","bin"),I0(L6(),".bun","bin"),...(process.env.PATH??"").split(VY),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(VY)}function _Y($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function n_($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function a_($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function d$($){return typeof $==="string"&&M6.includes($)}function o_($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Y of $){let Q=typeof Y==="string"?Y:typeof Y==="object"&&Y?Y.reasoningEffort:null;if(!d$(Q)||Z.has(Q))continue;Z.add(Q);let W=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:W})}return J}function j6($,Z){switch($.type){case"commandExecution":return{name:"Bash",input:{command:$.command,cwd:$.cwd,source:$.source}};case"fileChange":return{name:"FileChange",input:{changes:$.changes,status:$.status,cwd:Z}};case"mcpToolCall":return{name:"MCP",input:{server:$.server,tool:$.tool,arguments:$.arguments}};case"dynamicToolCall":return{name:$.namespace?`${$.namespace}.${$.tool}`:$.tool,input:$.arguments};case"webSearch":return{name:"WebSearch",input:{query:$.query,action:$.action}};case"imageGeneration":return{name:"ImageGeneration",input:D6($)}}return null}function r_($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function D6($){return{status:$.status,revisedPrompt:r_($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function KY($){if(!$||!b_(GY))return null;let Z=null,J=[GY];while(J.length){let Y=J.pop(),Q;try{Q=f_(Y,{withFileTypes:!0})}catch(W){_(`codex-process: cannot scan Codex session dir ${Y}: ${W instanceof Error?W.message:W}`);continue}for(let W of Q){let H=I0(Y,W.name);if(W.isDirectory()){J.push(H);continue}if(!W.isFile())continue;if(!W.name.startsWith("rollout-")||!W.name.endsWith(`${$}.jsonl`))continue;try{let V=S9(H).mtimeMs;if(!Z||V>Z.mtimeMs)Z={path:H,mtimeMs:V}}catch(V){_(`codex-process: cannot stat Codex rollout ${H}: ${V instanceof Error?V.message:V}`)}}}return Z?.path??null}function PY($,Z,J=c_){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let W=t_($,Z,J);if(W)return W;if(Q.length>2048){let H=LY($);return _(`codex-process: image generation inline result could not be decoded id=${H} length=${Q.length}`),`Image generation returned ${Q.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Q}if(Q&&typeof Q==="object"){let W=Q.savedPath??Q.saved_path??Q.path;if(typeof W==="string"&&W)return W;return JSON.stringify(Q,null,2)}return""}function t_($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=s_(Y);if(!Q)return null;let W=BY(Z??"unknown-thread"),H=BY(LY($)),V=I0(J,W),X=I0(V,`${H}.${Q.ext}`);try{return y_(V,{recursive:!0}),h_(X,Q.buffer),X}catch(z){return _(`codex-process: failed to write image generation result ${X}: ${z instanceof Error?z.message:z}`),null}}function LY($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function BY($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function s_($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=$K(Q[1]),J=Q[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let W=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(W,"base64")}catch{return null}if(H.length<12)return null;let V=e_(H)??Y;if(!V)return null;return{buffer:H,ext:V}}function e_($){if($[0]===137&&$[1]===80&&$[2]===78&&$[3]===71&&$[4]===13&&$[5]===10&&$[6]===26&&$[7]===10)return"png";if($[0]===255&&$[1]===216&&$[2]===255)return"jpg";let Z=$.subarray(0,6).toString("ascii");if(Z==="GIF87a"||Z==="GIF89a")return"gif";if($.subarray(0,4).toString("ascii")==="RIFF"&&$.subarray(8,12).toString("ascii")==="WEBP")return"webp";return null}function $K($){let Z=$.toLowerCase();if(Z==="jpeg"||Z==="jpg")return"jpg";if(Z==="png")return"png";if(Z==="gif")return"gif";if(Z==="webp")return"webp";return null}function AY($,Z,J){let Y=j6($,Z);if(!Y)return null;switch($.type){case"commandExecution":return{...Y,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Y,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Y,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Y,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Y,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Y,output:PY($,J),isError:$.status==="failed"}}return null}function E9($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return D$(Z)}function qY($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function ZK($,Z,J){let Y=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return e1(Y(Z?.command))||"(空命令)"}case"FileChange":{let Q=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Q>0?`改 ${Q} 个文件`:"文件变更"}case"MCP":return`${Y(Z?.server)}/${Y(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Y(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function jY($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function JK($){let Z=jY($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function YK($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let W=Q,H=typeof W?.status==="string"?W.status:"unknown";J.push(`${D$(Y)}: ${H}`)}return J.join(`
39
- `)}var GY,c_,u_=30000,p_=600000,l_=5000,i_=60000,d_="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",M6,Y4="xhigh",Z2,J2;var q1=T(()=>{k$();I();a1();Q6();U9();A1();o2();h$();Q6();GY=I0(y.defaultHome,"sessions"),c_=I0(y.defaultHome,"generated_images");M6=["none","minimal","low","medium","high","xhigh","max","ultra"];Z2=class Z2 extends Error{method;requestId;serverCode;serverMessage;serverData;constructor($,Z,J,Y,Q){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Y}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Y;this.serverData=Q;this.name="CodexRpcResponseError"}};J2=class J2 extends I_{provider="codex";tokenSourceId;launchKind;proc;stdoutBuf="";stderrBuf="";requestCounter=0;pending=new Map;serverRequests=new Map;alive=!0;expectedExit=!1;exitEventEmitted=!1;childExitCode=null;childExitSignal=null;exitPromise;resolveExit;opts;readyPromise=null;initializePromise=null;conversationResumable=!1;conversationRolloutPath=null;conversationMaterializationVerification=null;conversationMaterializationRetrySource=null;lastConversationMaterializationFailure=null;currentTurnId=null;turnStartGeneration=0;turnStartOwner=null;turnStartOwnersByTurnId=new Map;finishedTurnIds=new Set;capacityRetryTimer=null;capacityRetryCount=0;capacityRetryHasStarted=!1;capacityRetryEnabled=!0;turnError=null;rolloutFilePath=null;rolloutReadOffset=0;rolloutLineRemainder="";rolloutDecoder=new zY("utf8");emittedImageGenerationIds=new Set;collabAgentNames=new Map;collabAgentSettled=new Set;collabAgentWasActive=new Set;collabAgentSummaries=new Map;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel=null;lastEffort=null;lastUsage=null;lastTotalUsage=null;lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1};lastContextWindow=null;lastContextTokens=null;turnRetry=null;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((W)=>{this.resolveExit=W}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=J4(),J=[...n_($.allowDelegation!==!1),...y.cliArgs($.codexAccountId??l)];_(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:m_(),...f.codex.env,...$.hostEnv??{}},Q=y.env($.codexAccountId??l,$.transformEnv?$.transformEnv(Y):Y);this.proc=g_(Z,J,a_($.workDir,Q)),this.proc.stdout.on("data",(W)=>this.onStdout(W)),this.proc.stderr.on("data",(W)=>this.onStderr(W)),this.proc.stdin.on("error",(W)=>this.handleStdinError(W)),this.proc.on("exit",(W,H)=>this.handleChildExit(W,H)),this.proc.on("close",(W,H)=>this.handleChildClose(W,H)),this.proc.on("error",(W)=>this.handleChildProcessError(W)),$2(this,$.codexAccountId??l)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(_(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){_(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,_(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((W,H)=>Error(`codex app-server closed before ${H.method} response (id=${W})`)),this.serverRequests.clear();let J=$??this.childExitCode,Y=Z??this.childExitSignal,Q=this.conversationMaterializationBarrier();if(Q){Q.then(()=>this.emitProcessExit(J,Y),()=>this.emitProcessExit(J,Y));return}this.emitProcessExit(J,Y)}handleChildProcessError($){_(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Y,Q)=>Error(`codex app-server process failed before ${Q.method} response (id=${Y}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.cancelCapacityRetry(),this.serverRequests.clear(),J=!0;if(this.emit("error",$),J)_(`codex-process: spawn failed before pid assignment expected=${this.expectedExit}`),this.emitProcessExit(null,null)}emitProcessExit($,Z){if(this.exitEventEmitted)return;this.exitEventEmitted=!0,this.resolveExit(),_(`codex-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}onStdout($){this.stdoutBuf+=$.toString();let Z;while((Z=this.stdoutBuf.indexOf(`
75
+ `).trimStart():Z;return{description:Q,command:W||Z}}function J2($,Z=60){let{description:J,command:Y}=D5($);if(J)return J;return VK(Y).replace(/\s+/g," ").trim().slice(0,Z)}function VK($){let Z=$.split(/\r?\n/).map((J)=>J.trim()).filter(Boolean);return Z.find((J)=>!J.startsWith("#")&&!/^set\s+-/.test(J)&&!/^cd\s+/.test(J)&&!/^[A-Za-z_][A-Za-z0-9_]*=/.test(J)&&!/^cat\s+<<['"]?\w+['"]?/.test(J))??Z[Z.length-1]??""}function zK($){let Z=$.replace(/\r\n/g,`
76
+ `).trim(),J=Z.match(/^(?:\/usr\/bin\/env\s+)?(?:\/[\w./-]+\/)?(?:ba|z|fi)?sh\s+-[A-Za-z]*c[A-Za-z]*\s+([\s\S]+)$/);if(J){let Q=GK(J[1]);return P5(Q||Z)}let Y=XK(Z);if(Y)return Y;return P5(Z)}function XK($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=DY(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Y=Z[2];for(;;){let Q=Y.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Q)break;let W=Q[1].toLowerCase();if(W==="-command"||W==="-c")return P5(DY(Q[2]));if(Y=Q[2],W==="-executionpolicy"||W==="-inputformat"||W==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function GK($){let Z=$.trim();if(Z.length<2)return Z;let J=C9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/'\\''/g,"'");return Y.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
77
+ `)}function P5($){let Z=$.trim(),J=Z[0];if(!C9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!_K(Y,J))return Z;if(J!=='"')return Y.replace(/'\s*$/,"");return Y.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
78
+ `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(H,V)=>` $(${V})`)}function _K($,Z){let J=C9[Z];for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==='"'&&Q==="\\"&&Y+1<$.length){Y++;continue}if(Q===J)return/^[\s]*$/.test($.slice(Y+1))}return!1}var C9;var b9=T(()=>{C9={'"':'"',"'":"'","“":"”"}});function O($){return $ instanceof Error?$.message:String($)}function M$($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function MY($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,W)=>{Y=setTimeout(()=>W(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as FY}from"node:path";function KK($){return $.kind==="fresh"?null:$.source.provider}function B$($,Z,J){let Y=KK($);if(Y&&Y!==Z)throw Error(`conversation launch provider mismatch: source=${Y} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!FY($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!FY(J))throw Error(`expected conversation cwd is not absolute: ${J}`);if($.source.cwd===null)throw Error("conversation launch source cwd is missing");if($.source.cwd!==J)throw Error(`conversation launch cwd mismatch: source=${$.source.cwd} target=${J}`)}if($.kind!=="fork"||!$.through)return;if($.through.provider!==Z||$.through.source.provider!==Z)throw Error(`conversation checkpoint provider mismatch: checkpoint=${$.through.provider} target=${Z}`);if($.through.source.sessionId!==$.source.sessionId)throw Error("conversation checkpoint source does not match fork source");if($.through.source.cwd!==$.source.cwd)throw Error("conversation checkpoint cwd does not match fork source");if(!$.through.id.trim())throw Error("conversation checkpoint id is empty");if(Z==="dsh"&&(!/^\d+$/.test($.through.id)||!Number.isSafeInteger(Number($.through.id))))throw Error("DSH checkpoint must be a non-negative event sequence")}var L1=()=>{};import{createHash as BK,randomUUID as RY}from"node:crypto";import{existsSync as M5,lstatSync as F5,mkdirSync as R5,readFileSync as UY,readdirSync as AK,realpathSync as y9,symlinkSync as qK,writeFileSync as LK}from"node:fs";import{homedir as jK}from"node:os";import{join as R0,resolve as PK}from"node:path";class OY{defaultHome;root;stateFile;constructor($=PK(process.env.CODEX_HOME||R0(jK(),".codex")),Z=PJ,J=DJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!M5(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(UY(this.stateFile,"utf8"));if(!$||$.version!==1||!Array.isArray($.accounts)||!$.selections||typeof $.selections!=="object"||Array.isArray($.selections))throw Error("Codex 账号记录格式无效");let Z=new Set,J=new Set;for(let Y of $.accounts){if(!Y||!/^[a-f0-9-]{36}$/.test(Y.id)||typeof Y.name!=="string"||Z.has(Y.id)||J.has(this.nameKey(Y.name)))throw Error("Codex 账号记录重复或无效");this.validateName(Y.name),Z.add(Y.id),J.add(this.nameKey(Y.name))}for(let Y of Object.values($.selections))if(Y!==p&&!Z.has(Y))throw Error("Codex 账号选择指向不存在的账号");return $}nameKey($){return $.normalize("NFC").trim().toLowerCase()}validateName($){if(!$.trim()||$.length>80||/[\x00-\x1f\x7f/\\]/.test($)||["default","默认",".",".."].includes(this.nameKey($)))throw Error("备注名须为 1–80 个字符,不能包含换行或路径分隔符;default/默认为保留名称")}list(){return[{id:p,name:"默认"},...this.read().accounts.map(($)=>({...$}))]}get($){let Z=this.list().find((J)=>J.id===$);if(!Z)throw Error(`Codex 账号不存在:${$}`);return Z}find($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(p);let Z=this.list().find((J)=>this.nameKey(J.name)===this.nameKey($));if(!Z)throw Error(`Codex 账号不存在:${$};先发送 codex-login ${$}`);return Z}ensure($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(p);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:RY(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),t(this.stateFile,Z),Y}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:p}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],t(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),t(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==p){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:RY()}),t(this.stateFile,J)}}home($=p){return $===p?this.defaultHome:R0(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===p)return Z;let J;try{J=F5(Z)}catch(W){if(W.code!=="ENOENT")throw W}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(R5(Z,{recursive:!0,mode:448}),R5(this.defaultHome,{recursive:!0,mode:448}),y9(Z)===y9(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=F5(R0(Z,"auth.json"))}catch(W){if(W.code!=="ENOENT")throw W}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{LK(R0(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(W){if(W.code!=="EEXIST")throw W}for(let W of DK){let H=R0(this.defaultHome,W);R5(H,{recursive:!0,mode:448}),this.link(H,R0(Z,W),!0)}let Q=new Set([...MK,...AK(this.defaultHome).filter((W)=>W.endsWith(".config.toml"))]);for(let W of Q){let H=R0(this.defaultHome,W);if(M5(H))this.link(H,R0(Z,W),!1)}return Z}link($,Z,J){let Y;try{Y=F5(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||y9(Z)!==y9($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}qK($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&O5($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),W={...Z,CODEX_HOME:Q};if($!==p){W.CODEX_SQLITE_HOME=Z.CODEX_SQLITE_HOME||this.defaultHome;for(let H of["CODEX_API_KEY","OPENAI_API_KEY","CODEX_ACCESS_TOKEN","OPENAI_FEDERATION_RULE_ID","OPENAI_IDENTITY_TOKEN_FILE","OPENAI_WORKLOAD_IDENTITY_CONTEXT"])delete W[H]}return W}cliArgs($){return this.get($),$===p?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=R0(this.home($),"auth.json");if(!M5(Z))return null;let Y=JSON.parse(UY(Z,"utf8"))?.tokens;if(!Y?.account_id||typeof Y.id_token!=="string")return null;let Q=Y.id_token.split(".")[1];if(!Q)throw Error("Codex 身份 Token 格式无效");let W=JSON.parse(Buffer.from(Q,"base64url").toString("utf8"));if(typeof W.sub!=="string"||!W.sub)return null;return BK("sha256").update(JSON.stringify([Y.account_id,W.sub])).digest("hex")}}function Y2($,Z,J=!0){if(TY.set($,Z),!J)return;if(!w9.has($))$.once("exit",()=>w9.delete($));w9.set($,Z)}function U5($){return[...w9].some(([Z,J])=>J===$&&Z.isAlive())}function O5($){return J4.has($)}function NY($){if(J4.has($))throw Error("该账号已有登录任务");if(U5($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return J4.set($,Z),()=>{if(J4.get($)===Z)J4.delete($)}}function U0($){return $?TY.get($)??p:p}var p="default",DK,MK,y,TY,w9,J4;var I$=T(()=>{H$();f$();DK=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],MK=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];y=new OY,TY=new WeakMap,w9=new Map;J4=new Map});function T5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function FK($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function Y4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:T5($.subscriptionType,J.fiveHour)}}function N5($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=Y4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function E5($,Z,J=Date.now(),Y){let Q={state:"miss",score:null,shares:null,remaining:null,hours:null};if($.state!=="ok")return{...Q,reason:$.state==="network"?$.reason??"额度读取失败":$.state};let W=FK($.subscriptionType);if(W===null)return{...Q,reason:`未知周额度套餐:${$.subscriptionType??"MISS"}`};if(Q.shares=W,Y==="ultra"&&$.subscriptionType==="plus")return{...Q,state:"excluded",reason:"Ultra 自动选择不使用 Plus"};let H=Y4($,Z),V=[H.fiveHour,H.weekly].filter((A)=>A!==null),z=V.filter((A)=>A.percent!==null&&A.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||H.rateLimitReachedType||H.spendControlReached===!0){let A=z.map((j)=>j.resetsAt?.getTime()).filter((j)=>j!=null&&Number.isFinite(j)&&j>J);return{...Q,state:"exhausted",reason:"额度耗尽",...A.length===z.length&&A.length?{retryAt:Math.max(...A)}:{}}}if(V.some((A)=>A.percent===null||!Number.isFinite(A.percent)||A.percent<0))return{...Q,reason:"额度百分比 MISS"};let X=H.weekly;if(!X||X.percent===null)return{...Q,reason:"周额度 MISS"};let G=X.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Q,reason:"周重置时间 MISS 或已过期"};let K=W*(100-X.percent)/100,B=(G-J)/3600000,L=K/B;if(Y==="ultra"&&K<0.5)return{...Q,state:"waiting",remaining:K,hours:B,weeklyScore:L,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:G};if($.subscriptionType==="plus"){let A=H.fiveHour,j=0.15*(100-A.percent)/100,P=A.unreportedFull?5:((A.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(P)||P<=0)return{...Q,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:W,remaining:K,hours:B,weeklyScore:L,fiveHourRemaining:j,fiveHourHours:P,availableNow:Math.min(K,j),score:Math.min(L,j/P)}}return{state:"ready",shares:W,remaining:K,hours:B,weeklyScore:L,availableNow:K,score:L}}function f9($){if(!$||typeof $!=="object")return!1;let Z=$;if(Z.codexErrorInfo==="usageLimitExceeded"||Z.type==="usage_limit_reached"||Z.code==="usage_limit_reached")return!0;return typeof Z.message==="string"&&/^You(?:'|’)ve hit your usage limit\b/i.test(Z.message)}import{closeSync as RK,existsSync as UK,mkdirSync as OK,openSync as TK,readdirSync as NK,readSync as EK,statSync as h9,writeFileSync as SK}from"node:fs";import{homedir as S5}from"node:os";import{delimiter as EY,isAbsolute as SY,join as m0}from"node:path";import{EventEmitter as kK}from"node:events";import{StringDecoder as kY}from"node:string_decoder";import{spawn as xK}from"cross-spawn";function Q4(){return a2("codex","codex")}function CK(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([m0(S5(),".local","npm-global","bin"),m0(S5(),".local","bin"),m0(S5(),".bun","bin"),...(process.env.PATH??"").split(EY),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(EY)}function CY($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function IK($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function gK($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function a$($){return typeof $==="string"&&C5.includes($)}function mK($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Y of $){let Q=typeof Y==="string"?Y:typeof Y==="object"&&Y?Y.reasoningEffort:null;if(!a$(Q)||Z.has(Q))continue;Z.add(Q);let W=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:W})}return J}function k5($,Z){switch($.type){case"commandExecution":return{name:"Bash",input:{command:$.command,cwd:$.cwd,source:$.source}};case"fileChange":return{name:"FileChange",input:{changes:$.changes,status:$.status,cwd:Z}};case"mcpToolCall":return{name:"MCP",input:{server:$.server,tool:$.tool,arguments:$.arguments}};case"dynamicToolCall":return{name:$.namespace?`${$.namespace}.${$.tool}`:$.tool,input:$.arguments};case"webSearch":return{name:"WebSearch",input:{query:$.query,action:$.action}};case"imageGeneration":return{name:"ImageGeneration",input:x5($)}}return null}function cK($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function x5($){return{status:$.status,revisedPrompt:cK($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function bY($){if(!$||!UK(xY))return null;let Z=null,J=[xY];while(J.length){let Y=J.pop(),Q;try{Q=NK(Y,{withFileTypes:!0})}catch(W){_(`codex-process: cannot scan Codex session dir ${Y}: ${W instanceof Error?W.message:W}`);continue}for(let W of Q){let H=m0(Y,W.name);if(W.isDirectory()){J.push(H);continue}if(!W.isFile())continue;if(!W.name.startsWith("rollout-")||!W.name.endsWith(`${$}.jsonl`))continue;try{let V=h9(H).mtimeMs;if(!Z||V>Z.mtimeMs)Z={path:H,mtimeMs:V}}catch(V){_(`codex-process: cannot stat Codex rollout ${H}: ${V instanceof Error?V.message:V}`)}}}return Z?.path??null}function vY($,Z,J=bK){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let W=pK($,Z,J);if(W)return W;if(Q.length>2048){let H=hY($);return _(`codex-process: image generation inline result could not be decoded id=${H} length=${Q.length}`),`Image generation returned ${Q.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Q}if(Q&&typeof Q==="object"){let W=Q.savedPath??Q.saved_path??Q.path;if(typeof W==="string"&&W)return W;return JSON.stringify(Q,null,2)}return""}function pK($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=uK(Y);if(!Q)return null;let W=yY(Z??"unknown-thread"),H=yY(hY($)),V=m0(J,W),z=m0(V,`${H}.${Q.ext}`);try{return OK(V,{recursive:!0}),SK(z,Q.buffer),z}catch(X){return _(`codex-process: failed to write image generation result ${z}: ${X instanceof Error?X.message:X}`),null}}function hY($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function yY($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function uK($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=iK(Q[1]),J=Q[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let W=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(W,"base64")}catch{return null}if(H.length<12)return null;let V=lK(H)??Y;if(!V)return null;return{buffer:H,ext:V}}function lK($){if($[0]===137&&$[1]===80&&$[2]===78&&$[3]===71&&$[4]===13&&$[5]===10&&$[6]===26&&$[7]===10)return"png";if($[0]===255&&$[1]===216&&$[2]===255)return"jpg";let Z=$.subarray(0,6).toString("ascii");if(Z==="GIF87a"||Z==="GIF89a")return"gif";if($.subarray(0,4).toString("ascii")==="RIFF"&&$.subarray(8,12).toString("ascii")==="WEBP")return"webp";return null}function iK($){let Z=$.toLowerCase();if(Z==="jpeg"||Z==="jpg")return"jpg";if(Z==="png")return"png";if(Z==="gif")return"gif";if(Z==="webp")return"webp";return null}function wY($,Z,J){let Y=k5($,Z);if(!Y)return null;switch($.type){case"commandExecution":return{...Y,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Y,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Y,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Y,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Y,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Y,output:vY($,J),isError:$.status==="failed"}}return null}function v9($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return M$(Z)}function fY($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function dK($,Z,J){let Y=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return J2(Y(Z?.command))||"(空命令)"}case"FileChange":{let Q=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Q>0?`改 ${Q} 个文件`:"文件变更"}case"MCP":return`${Y(Z?.server)}/${Y(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Y(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function IY($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function nK($){let Z=IY($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function aK($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let W=Q,H=typeof W?.status==="string"?W.status:"unknown";J.push(`${M$(Y)}: ${H}`)}return J.join(`
79
+ `)}var xY,bK,yK=30000,wK=600000,fK=5000,vK=60000,hK="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",C5,W4="xhigh",Q2,W2;var j1=T(()=>{x$();I();t1();q5();b9();L1();t2();I$();q5();xY=m0(y.defaultHome,"sessions"),bK=m0(y.defaultHome,"generated_images");C5=["none","minimal","low","medium","high","xhigh","max","ultra"];Q2=class Q2 extends Error{method;requestId;serverCode;serverMessage;serverData;constructor($,Z,J,Y,Q){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Y}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Y;this.serverData=Q;this.name="CodexRpcResponseError"}};W2=class W2 extends kK{provider="codex";tokenSourceId;launchKind;proc;stdoutBuf="";stderrBuf="";requestCounter=0;pending=new Map;serverRequests=new Map;alive=!0;expectedExit=!1;exitEventEmitted=!1;childExitCode=null;childExitSignal=null;exitPromise;resolveExit;opts;readyPromise=null;initializePromise=null;conversationResumable=!1;conversationRolloutPath=null;conversationMaterializationVerification=null;conversationMaterializationRetrySource=null;lastConversationMaterializationFailure=null;currentTurnId=null;turnStartGeneration=0;turnStartOwner=null;turnStartOwnersByTurnId=new Map;finishedTurnIds=new Set;capacityRetryTimer=null;capacityRetryCount=0;capacityRetryHasStarted=!1;capacityRetryEnabled=!0;turnError=null;rolloutFilePath=null;rolloutReadOffset=0;rolloutLineRemainder="";rolloutDecoder=new kY("utf8");emittedImageGenerationIds=new Set;collabAgentNames=new Map;collabAgentSettled=new Set;collabAgentWasActive=new Set;collabAgentSummaries=new Map;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel=null;lastEffort=null;lastUsage=null;lastTotalUsage=null;lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1};lastContextWindow=null;lastContextTokens=null;turnRetry=null;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((W)=>{this.resolveExit=W}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=Q4(),J=[...IK($.allowDelegation!==!1),...y.cliArgs($.codexAccountId??p)];_(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:CK(),...f.codex.env,...$.hostEnv??{}},Q=y.env($.codexAccountId??p,$.transformEnv?$.transformEnv(Y):Y);this.proc=xK(Z,J,gK($.workDir,Q)),this.proc.stdout.on("data",(W)=>this.onStdout(W)),this.proc.stderr.on("data",(W)=>this.onStderr(W)),this.proc.stdin.on("error",(W)=>this.handleStdinError(W)),this.proc.on("exit",(W,H)=>this.handleChildExit(W,H)),this.proc.on("close",(W,H)=>this.handleChildClose(W,H)),this.proc.on("error",(W)=>this.handleChildProcessError(W)),Y2(this,$.codexAccountId??p)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(_(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){_(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,_(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((W,H)=>Error(`codex app-server closed before ${H.method} response (id=${W})`)),this.serverRequests.clear();let J=$??this.childExitCode,Y=Z??this.childExitSignal,Q=this.conversationMaterializationBarrier();if(Q){Q.then(()=>this.emitProcessExit(J,Y),()=>this.emitProcessExit(J,Y));return}this.emitProcessExit(J,Y)}handleChildProcessError($){_(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Y,Q)=>Error(`codex app-server process failed before ${Q.method} response (id=${Y}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.cancelCapacityRetry(),this.serverRequests.clear(),J=!0;if(this.emit("error",$),J)_(`codex-process: spawn failed before pid assignment expected=${this.expectedExit}`),this.emitProcessExit(null,null)}emitProcessExit($,Z){if(this.exitEventEmitted)return;this.exitEventEmitted=!0,this.resolveExit(),_(`codex-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}onStdout($){this.stdoutBuf+=$.toString();let Z;while((Z=this.stdoutBuf.indexOf(`
40
80
  `))>=0){let J=this.stdoutBuf.slice(0,Z).trim();if(this.stdoutBuf=this.stdoutBuf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch(Q){_(`codex-process: bad json: ${J.slice(0,200)} (${Q})`);continue}try{this.handleMessage(Y)}catch(Q){_(`codex-process: dispatch error: ${JSON.stringify(Y).slice(0,200)} (${Q})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
41
81
  `))}onStderr($){this.stderrBuf+=$.toString();let Z;while((Z=this.stderrBuf.indexOf(`
42
- `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())_(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())_(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){_(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Y=typeof $.error?.code==="number"?$.error.code:null,Q=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new Z2(J.method,$.id,Y,Q,$.error?.data))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=Y6($);if(Z){let J=this.withSessionId(Z);Z6(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}v$("RAW_MESSAGE",$),this.emit("raw",$)}handleNotification($,Z){if(this.isSubagentThread(Z)){if($==="thread/status/changed")this.handleThreadStatusChanged(Z);else if($==="item/started")this.handleSubagentItemStarted(Z);else if($==="item/completed")this.handleSubagentItemCompleted(Z);return}let J=J6($,Z);if(J){let Y=this.withSessionId(J);Z6($,Z,Y),this.emit("context_compacted",Y);return}switch($){case"thread/started":{let Y=Z.thread;if(Y?.id)this.sessionId=Y.id;return}case"thread/settings/updated":{let Y=Z.threadSettings;if(typeof Y?.model==="string")this.lastModel=Y.model;if(d$(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=s1(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else _("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=s1(Z.tokenUsage?.total);let Q=Z.tokenUsage?.modelContextWindow;if(typeof Q==="number"&&Q>0)this.lastContextWindow=Q;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){v$("TURN_STARTED_THREAD_MISMATCH",{method:$,params:Z});return}this.recordTurnStarted(Z.turn,Z.threadId,"turn/started notification"),this.markConversationMaterialized("turn/started notification");return}case"turn/completed":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){v$("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Y=Z.turn??{},Q=typeof Y.id==="string"&&Y.id?Y.id:null;if(Q){if(this.finishedTurnIds?.has(Q)){_(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),_(`codex-process: stale turn/completed ignored turn=${Q} current=${this.currentTurnId}`);return}this.flushRolloutImageGenerations(),this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q)}else v$("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let W=Y.status,H=Y.error??(W==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let V=W==="failed"||!!H,X=W==="completed"&&!V&&!!Q;if(this.lastCompletedTurnId=X?Q:null,this.currentTurnId=null,W==="failed"&&Q&&_Y(H?.message)&&this.scheduleCapacityRetry(H.message,d_))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let z=V?H?.type??H?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Y.durationMs==="number"?Y.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:z,is_error:V},this.emit("result",{subtype:z,is_error:V,...V&&typeof H?.message==="string"?{error:H.message}:{},...W==="failed"&&Q&&N9(H)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Q,checkpoint:X&&this.sessionId?{provider:"codex",kind:"turn",id:Q,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else _("codex-process: thread/goal/updated missing goal");return}case"thread/goal/cleared":{this.emit("thread_goal_cleared",Z);return}case"thread/status/changed":{this.handleThreadStatusChanged(Z);return}case"item/agentMessage/delta":{if(typeof Z.delta==="string"&&Z.delta.length>0)this.emit("assistant_text",{uuid:Z.itemId,text:Z.delta,parentToolUseId:null});else v$("AGENT_MESSAGE_DELTA_EMPTY",{method:$,params:Z});return}case"item/started":{this.handleItemStarted(Z);return}case"item/completed":{this.handleItemCompleted(Z);return}case"mcpServer/startupStatus/updated":{_(`codex-process: mcp ${Z.name} ${Z.status}${Z.error?`: ${Z.error}`:""}`);return}case"account/rateLimits/updated":{this.emit("rate_limits_updated",Z.rateLimits);return}case"configWarning":case"warning":case"guardianWarning":case"deprecationNotice":{_(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{_(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`);let Y=Z.error??Z;if(typeof Z.turnId==="string"&&Z.threadId===this.sessionId&&!this.finishedTurnIds?.has(Z.turnId)&&(!this.currentTurnId||this.currentTurnId===Z.turnId))this.turnError={turnId:Z.turnId,error:Y};this.emit("error",Error(Y.message??Y.summary??"codex app-server error"));return}}v$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){v$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=j6(Z,this.opts.workDir);if(!J){v$("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started"))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Y=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Y,J)}return}if(this.feedCollabItem(Z,"completed"))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){v$("ITEM_COMPLETED_MISSING_ID",{method:"item/completed",params:$});return}if(Z.type==="agentMessage"){this.lastAssistantUuid=Z.id,this.emit("assistant_block_stop",{index:Z.id,parentToolUseId:null});return}if(this.feedCollabItem(Z,"completed"))return;let J=AY(Z,this.opts.workDir,this.sessionId??void 0);if(!J){v$("ITEM_COMPLETED_UNMAPPED",{method:"item/completed",params:$});return}if(this.emit("tool_result",{tool_use_id:Z.id,content:J.output,is_error:J.isError,...Z.type==="imageGeneration"?{input:D6(Z)}:{}}),Z.type==="imageGeneration")this.emittedImageGenerationIds.add(Z.id)}isSubagentThread($){let Z=typeof $?.threadId==="string"?$.threadId:"";return!!this.sessionId&&!!Z&&Z!==this.sessionId}handleThreadStatusChanged($){let Z=typeof $?.threadId==="string"?$.threadId:"",J=$?.status?.type;if(!Z||typeof J!=="string")return;if(!this.collabAgentNames?.has(Z))return;if(J==="active"){if(this.collabAgentWasActive.add(Z),this.collabAgentSettled.has(Z))this.collabAgentSettled.delete(Z),this.emit("bg_task_started",{task_id:Z,task_type:"local_agent",description:this.collabAgentNames.get(Z)??D$(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Y=typeof J?.threadId==="string"?J.threadId:"",Q=Z==="started"?j6($,this.opts.workDir):AY($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let W="output"in Q&&typeof Q.output==="string"?Q.output:void 0;this.emit("subagent_step",{thread_id:Y,item_id:$.id,tool:Q.name,phase:Z,brief:ZK(Q.name,Q.input,W)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=E9($.agentPath,J);this.collabAgentNames.set(J,Y),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:J,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(J),Q=E9($.agentPath,J);if(Y!==Q&&!this.collabAgentSettled.has(J))this.collabAgentNames.set(J,Q),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Q})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:J,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let J=$.agentsStates;if(J&&typeof J==="object")for(let[Y,Q]of Object.entries(J))this.translateAgentState(Y,Q,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=jY($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,E9(null,Q));this.emit("bg_task_settled",{task_id:Q,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:qY($.prompt),description:JK($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:YK($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Y=Z?.status;if(typeof Y!=="string")return;if(this.collabAgentSettled.has($)){if(Y!=="running"&&Y!=="pendingInit"){if(Y==="errored"||Y==="shutdown"||Y==="notFound"||Y==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Y==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let W=this.collabAgentNames.get($)??E9(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:W}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let H={task_id:$,task_type:"local_agent",description:"子 agent",prompt:qY(J.prompt)};this.emit("bg_task_started",H);let V={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",V)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let W={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",W);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Q={task_id:$,status:Y==="completed"?"completed":Y==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Q)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new zY("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=KY(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=S9($).size,_(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){_(`codex-process: image generation rollout stat failed ${$}: ${Z instanceof Error?Z.message:Z}`),this.rolloutFilePath=null,this.rolloutReadOffset=0}}flushRolloutImageGenerations(){if(!this.sessionId)return;let $=this.rolloutFilePath??KY(this.sessionId);if(!$){_(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=S9($).size;if(Q<=this.rolloutReadOffset)return;let W=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(W);let H=w_($,"r"),V=0;try{while(V<W){let X=v_(H,Z,V,W-V,this.rolloutReadOffset+V);if(X===0)break;V+=X}}finally{C_(H)}Z=Z.subarray(0,V),this.rolloutReadOffset+=V}catch(Q){_(`codex-process: image generation rollout read failed ${$}: ${Q instanceof Error?Q.message:Q}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Y=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
43
- `)?"":Y.pop()??"";for(let Q of Y){if(!Q.trim())continue;let W;try{W=JSON.parse(Q)}catch(X){_(`codex-process: image generation rollout JSON parse failed ${$}: ${X instanceof Error?X.message:X}`);continue}let H=W?.payload,V=H?.type;if(V!=="image_generation_end"&&V!=="image_generation_call")continue;this.emitRolloutImageGeneration(H)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=PY($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&XY(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:D6({...$,status:Q})}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Y})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Y={questions:(J.questions??[]).map((Q)=>({id:Q.id,header:Q.header,question:Q.question,options:Array.isArray(Q.options)&&Q.options.length?Q.options.map((W)=>({label:W.label,description:W.description})):[{label:"自定义回答",description:Q.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Y}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Y,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:v$("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));return _(`codex-process: stdin write failed: ${Q.message}`),Z?.(Q),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
44
- `,(Y)=>{if(Y)J(Y)}),!0}catch(Y){return J(Y)}}request($,Z,J=u_){let Y=++this.requestCounter;return new Promise((Q,W)=>{let H=setTimeout(()=>{let X=this.pending.get(Y);if(!X)return;this.pending.delete(Y),X.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Y})`))},Math.max(0,J)),V={resolve:Q,reject:W,method:$,timeout:H};this.pending.set(Y,V),this.write({id:Y,method:$,params:Z},(X)=>{if(this.pending.get(Y)!==V)return;this.pending.delete(Y),clearTimeout(H),W(Error(`codex app-server ${$} request write failed (id=${Y}): ${X.message}`,{cause:X}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,result:Z})}respondError($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{_(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Y;if($.kind==="resume")J="thread/resume",Y=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Y=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Y=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Q=Y?.thread;if(typeof Q?.id!=="string"||!Q.id)throw Error(`codex app-server ${J} returned no thread.id`);let W=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(W!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${W??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Q.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Q.id}`);if($.kind==="resume"&&Q.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Q.id}, expected ${$.source.sessionId}`);let H=typeof Q.path==="string"&&Q.path?Q.path:null;if(!H||!XY(H)||!H.endsWith(`${Q.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${H??"MISS"}`);if(this.sessionId=Q.id,this.conversationRolloutPath=H,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Y?.model)this.lastModel=Y.model;if(d$(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;_(`codex-process: thread=${this.sessionId}`),this.primeRolloutImageGenerationScan(),this.emit("init",{session_id:this.sessionId,thread:Q})}markConversationMaterialized($){if(this.conversationResumable)return;if(!this.sessionId)throw Error(`codex ${$} arrived before thread initialization`);if(this.conversationMaterializationVerification){this.conversationMaterializationRetrySource=$;return}let Z=this.sessionId,J=this.verifyConversationMaterialized($);this.conversationMaterializationVerification=J,J.then(()=>{if(this.sessionId!==Z||this.conversationResumable)return;this.lastConversationMaterializationFailure=null,this.conversationResumable=!0,_(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));this.lastConversationMaterializationFailure=Q,_(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Q.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Q})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Y=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Y)this.markConversationMaterialized(Y)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Q=(await this.request("thread/read",{threadId:Z,includeTurns:!0},p_))?.thread;if(Q?.id!==Z||Q.cwd!==this.opts.workDir||Q.path!==J||!Array.isArray(Q.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=S9(Z)}catch(Y){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Y instanceof Error?Y.message:Y}`,{cause:Y})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(K$($,"codex",this.opts.workDir),$.kind!=="fresh"&&(typeof $.source.sessionId!=="string"||!$.source.sessionId))throw Error(`codex ${$.kind} launch requires a source session id`);if($.kind==="fork"&&$.through){if($.through.provider!=="codex"||$.through.kind!=="turn")throw Error("codex fork through checkpoint must be a codex turn checkpoint");if(typeof $.through.id!=="string"||!$.through.id)throw Error("codex fork through checkpoint requires a turn id")}return $}threadParams(){return{cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandbox:"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.allowDelegation===!1?{"features.multi_agent":!1}:{},...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:this.opts.serviceName??"lodestar"}}sendUserText($,Z=[]){let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).join(" ")+`
82
+ `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())_(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())_(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){_(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Y=typeof $.error?.code==="number"?$.error.code:null,Q=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new Q2(J.method,$.id,Y,Q,$.error?.data))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=A5($);if(Z){let J=this.withSessionId(Z);K5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}h$("RAW_MESSAGE",$),this.emit("raw",$)}handleNotification($,Z){if(this.isSubagentThread(Z)){if($==="thread/status/changed")this.handleThreadStatusChanged(Z);else if($==="item/started")this.handleSubagentItemStarted(Z);else if($==="item/completed")this.handleSubagentItemCompleted(Z);return}let J=B5($,Z);if(J){let Y=this.withSessionId(J);K5($,Z,Y),this.emit("context_compacted",Y);return}switch($){case"thread/started":{let Y=Z.thread;if(Y?.id)this.sessionId=Y.id;return}case"thread/settings/updated":{let Y=Z.threadSettings;if(typeof Y?.model==="string")this.lastModel=Y.model;if(a$(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=Z2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else _("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=Z2(Z.tokenUsage?.total);let Q=Z.tokenUsage?.modelContextWindow;if(typeof Q==="number"&&Q>0)this.lastContextWindow=Q;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){h$("TURN_STARTED_THREAD_MISMATCH",{method:$,params:Z});return}this.recordTurnStarted(Z.turn,Z.threadId,"turn/started notification"),this.markConversationMaterialized("turn/started notification");return}case"turn/completed":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){h$("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Y=Z.turn??{},Q=typeof Y.id==="string"&&Y.id?Y.id:null;if(Q){if(this.finishedTurnIds?.has(Q)){_(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),_(`codex-process: stale turn/completed ignored turn=${Q} current=${this.currentTurnId}`);return}this.flushRolloutImageGenerations(),this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q)}else h$("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let W=Y.status,H=Y.error??(W==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let V=W==="failed"||!!H,z=W==="completed"&&!V&&!!Q;if(this.lastCompletedTurnId=z?Q:null,this.currentTurnId=null,W==="failed"&&Q&&CY(H?.message)&&this.scheduleCapacityRetry(H.message,hK))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let X=V?H?.type??H?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Y.durationMs==="number"?Y.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:X,is_error:V},this.emit("result",{subtype:X,is_error:V,...V&&typeof H?.message==="string"?{error:H.message}:{},...W==="failed"&&Q&&f9(H)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Q,checkpoint:z&&this.sessionId?{provider:"codex",kind:"turn",id:Q,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else _("codex-process: thread/goal/updated missing goal");return}case"thread/goal/cleared":{this.emit("thread_goal_cleared",Z);return}case"thread/status/changed":{this.handleThreadStatusChanged(Z);return}case"item/agentMessage/delta":{if(typeof Z.delta==="string"&&Z.delta.length>0)this.emit("assistant_text",{uuid:Z.itemId,text:Z.delta,parentToolUseId:null});else h$("AGENT_MESSAGE_DELTA_EMPTY",{method:$,params:Z});return}case"item/started":{this.handleItemStarted(Z);return}case"item/completed":{this.handleItemCompleted(Z);return}case"mcpServer/startupStatus/updated":{_(`codex-process: mcp ${Z.name} ${Z.status}${Z.error?`: ${Z.error}`:""}`);return}case"account/rateLimits/updated":{this.emit("rate_limits_updated",Z.rateLimits);return}case"configWarning":case"warning":case"guardianWarning":case"deprecationNotice":{_(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{_(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`);let Y=Z.error??Z;if(typeof Z.turnId==="string"&&Z.threadId===this.sessionId&&!this.finishedTurnIds?.has(Z.turnId)&&(!this.currentTurnId||this.currentTurnId===Z.turnId))this.turnError={turnId:Z.turnId,error:Y};this.emit("error",Error(Y.message??Y.summary??"codex app-server error"));return}}h$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){h$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=k5(Z,this.opts.workDir);if(!J){h$("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started"))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Y=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Y,J)}return}if(this.feedCollabItem(Z,"completed"))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){h$("ITEM_COMPLETED_MISSING_ID",{method:"item/completed",params:$});return}if(Z.type==="agentMessage"){this.lastAssistantUuid=Z.id,this.emit("assistant_block_stop",{index:Z.id,parentToolUseId:null});return}if(this.feedCollabItem(Z,"completed"))return;let J=wY(Z,this.opts.workDir,this.sessionId??void 0);if(!J){h$("ITEM_COMPLETED_UNMAPPED",{method:"item/completed",params:$});return}if(this.emit("tool_result",{tool_use_id:Z.id,content:J.output,is_error:J.isError,...Z.type==="imageGeneration"?{input:x5(Z)}:{}}),Z.type==="imageGeneration")this.emittedImageGenerationIds.add(Z.id)}isSubagentThread($){let Z=typeof $?.threadId==="string"?$.threadId:"";return!!this.sessionId&&!!Z&&Z!==this.sessionId}handleThreadStatusChanged($){let Z=typeof $?.threadId==="string"?$.threadId:"",J=$?.status?.type;if(!Z||typeof J!=="string")return;if(!this.collabAgentNames?.has(Z))return;if(J==="active"){if(this.collabAgentWasActive.add(Z),this.collabAgentSettled.has(Z))this.collabAgentSettled.delete(Z),this.emit("bg_task_started",{task_id:Z,task_type:"local_agent",description:this.collabAgentNames.get(Z)??M$(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Y=typeof J?.threadId==="string"?J.threadId:"",Q=Z==="started"?k5($,this.opts.workDir):wY($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let W="output"in Q&&typeof Q.output==="string"?Q.output:void 0;this.emit("subagent_step",{thread_id:Y,item_id:$.id,tool:Q.name,phase:Z,brief:dK(Q.name,Q.input,W)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=v9($.agentPath,J);this.collabAgentNames.set(J,Y),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:J,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(J),Q=v9($.agentPath,J);if(Y!==Q&&!this.collabAgentSettled.has(J))this.collabAgentNames.set(J,Q),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Q})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:J,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let J=$.agentsStates;if(J&&typeof J==="object")for(let[Y,Q]of Object.entries(J))this.translateAgentState(Y,Q,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=IY($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,v9(null,Q));this.emit("bg_task_settled",{task_id:Q,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:fY($.prompt),description:nK($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:aK($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Y=Z?.status;if(typeof Y!=="string")return;if(this.collabAgentSettled.has($)){if(Y!=="running"&&Y!=="pendingInit"){if(Y==="errored"||Y==="shutdown"||Y==="notFound"||Y==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Y==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let W=this.collabAgentNames.get($)??v9(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:W}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let H={task_id:$,task_type:"local_agent",description:"子 agent",prompt:fY(J.prompt)};this.emit("bg_task_started",H);let V={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",V)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let W={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",W);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Q={task_id:$,status:Y==="completed"?"completed":Y==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Q)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new kY("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=bY(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=h9($).size,_(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){_(`codex-process: image generation rollout stat failed ${$}: ${Z instanceof Error?Z.message:Z}`),this.rolloutFilePath=null,this.rolloutReadOffset=0}}flushRolloutImageGenerations(){if(!this.sessionId)return;let $=this.rolloutFilePath??bY(this.sessionId);if(!$){_(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=h9($).size;if(Q<=this.rolloutReadOffset)return;let W=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(W);let H=TK($,"r"),V=0;try{while(V<W){let z=EK(H,Z,V,W-V,this.rolloutReadOffset+V);if(z===0)break;V+=z}}finally{RK(H)}Z=Z.subarray(0,V),this.rolloutReadOffset+=V}catch(Q){_(`codex-process: image generation rollout read failed ${$}: ${Q instanceof Error?Q.message:Q}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Y=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
83
+ `)?"":Y.pop()??"";for(let Q of Y){if(!Q.trim())continue;let W;try{W=JSON.parse(Q)}catch(z){_(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let H=W?.payload,V=H?.type;if(V!=="image_generation_end"&&V!=="image_generation_call")continue;this.emitRolloutImageGeneration(H)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=vY($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&SY(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:x5({...$,status:Q})}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Y})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Y={questions:(J.questions??[]).map((Q)=>({id:Q.id,header:Q.header,question:Q.question,options:Array.isArray(Q.options)&&Q.options.length?Q.options.map((W)=>({label:W.label,description:W.description})):[{label:"自定义回答",description:Q.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Y}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Y,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:h$("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));return _(`codex-process: stdin write failed: ${Q.message}`),Z?.(Q),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
84
+ `,(Y)=>{if(Y)J(Y)}),!0}catch(Y){return J(Y)}}request($,Z,J=yK){let Y=++this.requestCounter;return new Promise((Q,W)=>{let H=setTimeout(()=>{let z=this.pending.get(Y);if(!z)return;this.pending.delete(Y),z.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Y})`))},Math.max(0,J)),V={resolve:Q,reject:W,method:$,timeout:H};this.pending.set(Y,V),this.write({id:Y,method:$,params:Z},(z)=>{if(this.pending.get(Y)!==V)return;this.pending.delete(Y),clearTimeout(H),W(Error(`codex app-server ${$} request write failed (id=${Y}): ${z.message}`,{cause:z}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,result:Z})}respondError($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{_(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Y;if($.kind==="resume")J="thread/resume",Y=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Y=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Y=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Q=Y?.thread;if(typeof Q?.id!=="string"||!Q.id)throw Error(`codex app-server ${J} returned no thread.id`);let W=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(W!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${W??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Q.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Q.id}`);if($.kind==="resume"&&Q.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Q.id}, expected ${$.source.sessionId}`);let H=typeof Q.path==="string"&&Q.path?Q.path:null;if(!H||!SY(H)||!H.endsWith(`${Q.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${H??"MISS"}`);if(this.sessionId=Q.id,this.conversationRolloutPath=H,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Y?.model)this.lastModel=Y.model;if(a$(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;_(`codex-process: thread=${this.sessionId}`),this.primeRolloutImageGenerationScan(),this.emit("init",{session_id:this.sessionId,thread:Q})}markConversationMaterialized($){if(this.conversationResumable)return;if(!this.sessionId)throw Error(`codex ${$} arrived before thread initialization`);if(this.conversationMaterializationVerification){this.conversationMaterializationRetrySource=$;return}let Z=this.sessionId,J=this.verifyConversationMaterialized($);this.conversationMaterializationVerification=J,J.then(()=>{if(this.sessionId!==Z||this.conversationResumable)return;this.lastConversationMaterializationFailure=null,this.conversationResumable=!0,_(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));this.lastConversationMaterializationFailure=Q,_(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Q.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Q})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Y=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Y)this.markConversationMaterialized(Y)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Q=(await this.request("thread/read",{threadId:Z,includeTurns:!0},wK))?.thread;if(Q?.id!==Z||Q.cwd!==this.opts.workDir||Q.path!==J||!Array.isArray(Q.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=h9(Z)}catch(Y){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Y instanceof Error?Y.message:Y}`,{cause:Y})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(B$($,"codex",this.opts.workDir),$.kind!=="fresh"&&(typeof $.source.sessionId!=="string"||!$.source.sessionId))throw Error(`codex ${$.kind} launch requires a source session id`);if($.kind==="fork"&&$.through){if($.through.provider!=="codex"||$.through.kind!=="turn")throw Error("codex fork through checkpoint must be a codex turn checkpoint");if(typeof $.through.id!=="string"||!$.through.id)throw Error("codex fork through checkpoint requires a turn id")}return $}threadParams(){return{cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandbox:"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.allowDelegation===!1?{"features.multi_agent":!1}:{},...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:this.opts.serviceName??"lodestar"}}sendUserText($,Z=[]){let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).join(" ")+`
45
85
 
46
- `:"";this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.capacityRetryEnabled=!0,this.turnError=null;let Y=this.beginTurnStart(J+$);this.startTurn(J+$,Y).catch((Q)=>this.failTurnStart(Q,Y))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Y of J.data){if(typeof Y?.model!=="string"||!Y.model)continue;$.push({id:typeof Y.id==="string"&&Y.id?Y.id:Y.model,model:Y.model,displayName:typeof Y.displayName==="string"&&Y.displayName?Y.displayName:Y.model,description:typeof Y.description==="string"?Y.description:"",hidden:Y.hidden===!0,isDefault:Y.isDefault===!0,supportedReasoningEfforts:o_(Y.supportedReasoningEfforts),defaultReasoningEffort:d$(Y.defaultReasoningEffort)?Y.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Y=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Y?.data))throw Error("thread/list returned no data array");for(let W of Y.data){if(typeof W?.id!=="string"||!W.id||typeof W.preview!=="string"||typeof W.updatedAt!=="number"||!Number.isFinite(W.updatedAt)||typeof W.cwd!=="string"||W.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof W.status==="string"?W.status:typeof W.status?.type==="string"?W.status.type:void 0;if(o1("codex",W.id))continue;$.push({provider:"codex",sessionId:W.id,cwd:W.cwd,preview:W.preview,ts:W.updatedAt*1000,...H?{status:H}:{}})}let Q=Y?.nextCursor;if(Q!==null&&typeof Q!=="string")throw Error("thread/list returned an invalid nextCursor");if(Q&&Z.has(Q))throw Error(`thread/list repeated pagination cursor ${Q}`);if(Q)Z.add(Q);J=Q}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async setModelSettings($,Z){_("codex-process: model settings require a process restart")}async compactThread(){if(!this.readyPromise)throw Error("codex thread not initialized");if(await this.readyPromise,!this.sessionId)throw Error("codex thread not initialized");await this.request("thread/compact/start",{threadId:this.sessionId})}failTurnStart($,Z){if(!this.ownsTurnStartFailure(Z)){_(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(_(`codex-process: turn/start failed: ${J}`),$ instanceof Z2&&$.method==="turn/start"&&_Y($.serverMessage)&&Z.inputText!==void 0&&this.scheduleCapacityRetry($.serverMessage,Z.inputText))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"codex_turn_start_failed",is_error:!0},this.currentTurnId=null,this.lastCompletedTurnId=null,this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:J,...$ instanceof Z2&&$.method==="turn/start"&&Z.inputText!==void 0&&(N9($.serverData)||N9({message:$.serverMessage}))?{codexQuotaFailure:{accepted:!1,rejectedInput:Z.inputText}}:{}})}recordTurnStarted($,Z,J,Y){let Q=typeof $?.id==="string"&&$.id?$.id:null;if(!Q)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Q))return;let W=Y??this.turnStartOwner;if(W?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===W)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let V=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let X={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",X)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Q,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...V?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Y=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Y?.turn,this.sessionId,"turn/start response",J)}catch(Y){if(!this.ownsTurnStartFailure(J)){_(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Y}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>_(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Y=Math.min(l_*2**Math.min(J-1,4),i_),Q=this.turnStartGeneration??0,W={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=W,_(`codex-process: model capacity retry #${J} in ${Y}ms: ${$}`);let H=setTimeout(()=>{if(this.capacityRetryTimer!==H)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Q!==(this.turnStartGeneration??0))return;if(this.turnRetry={...W,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let V=this.beginTurnStart(Z);this.startTurn(Z,V).catch((X)=>this.failTurnStart(X,V))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",W),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){_(`codex-process: permission response for unknown request ${$}`);return}let Q=Z==="allow";switch(Y.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/permissions/requestApproval":if(Q)this.respond($,{permissions:Y.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Q){this.respondError($,J?.denyMessage??"denied by user");return}let W=J?.updatedInput?.answers??{},H={};for(let V of Y.params?.questions??[]){let X=W[V.question]??W[V.id];if(X!==void 0)H[V.id]={answers:[String(X)]}}this.respond($,{answers:H});return}default:v$("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Y.method,params:Y.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,_(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(_(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Y=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw _(`codex-process: kill failed: ${Y.message}`),Y}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function QK($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function F6($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let V=J.exec($);if(!V)break;let X=V[1],z=new RegExp(`^(?: {0,3})${QK(X[0])}{${X.length},}[ \\t]*(?:\\n|$)`,"gm");z.lastIndex=V.index+V[0].length;let G=z.exec($),K=G?G.index+G[0].length:$.length;Z.push({start:V.index,end:K}),Y=K}let Q=[...Z],W=[],H=0;for(let V of Z){if(H<V.start)W.push({start:H,end:V.start});H=V.end}if(H<$.length)W.push({start:H,end:$.length});for(let V of W){let X=$.slice(V.start,V.end),z=/(`+)[^\n]*?\1/g,G;while((G=z.exec(X))!==null)Q.push({start:V.start+G.index,end:V.start+G.index+G[0].length})}return Q.sort((V,X)=>V.start-X.start)}function R6($,Z){if(!$)return $;let J=F6($);if(!J.length)return Z($);let Y="",Q=0;for(let W of J){if(W.start>Q)Y+=Z($.slice(Q,W.start));Y+=$.slice(W.start,W.end),Q=Math.max(Q,W.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function WK($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function DY($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let W=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${W})`:`\uD83D\uDDBC️ ${W}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function g0($){if(Array.isArray($))return $.map((Y)=>g0(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=g0(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=U6(Z.content);return J}function e($){return R6($,(Z)=>HK(DY(WK(Z))))}function HK($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
86
+ `:"";this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.capacityRetryEnabled=!0,this.turnError=null;let Y=this.beginTurnStart(J+$);this.startTurn(J+$,Y).catch((Q)=>this.failTurnStart(Q,Y))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Y of J.data){if(typeof Y?.model!=="string"||!Y.model)continue;$.push({id:typeof Y.id==="string"&&Y.id?Y.id:Y.model,model:Y.model,displayName:typeof Y.displayName==="string"&&Y.displayName?Y.displayName:Y.model,description:typeof Y.description==="string"?Y.description:"",hidden:Y.hidden===!0,isDefault:Y.isDefault===!0,supportedReasoningEfforts:mK(Y.supportedReasoningEfforts),defaultReasoningEffort:a$(Y.defaultReasoningEffort)?Y.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Y=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Y?.data))throw Error("thread/list returned no data array");for(let W of Y.data){if(typeof W?.id!=="string"||!W.id||typeof W.preview!=="string"||typeof W.updatedAt!=="number"||!Number.isFinite(W.updatedAt)||typeof W.cwd!=="string"||W.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof W.status==="string"?W.status:typeof W.status?.type==="string"?W.status.type:void 0;if(s1("codex",W.id))continue;$.push({provider:"codex",sessionId:W.id,cwd:W.cwd,preview:W.preview,ts:W.updatedAt*1000,...H?{status:H}:{}})}let Q=Y?.nextCursor;if(Q!==null&&typeof Q!=="string")throw Error("thread/list returned an invalid nextCursor");if(Q&&Z.has(Q))throw Error(`thread/list repeated pagination cursor ${Q}`);if(Q)Z.add(Q);J=Q}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async setModelSettings($,Z){_("codex-process: model settings require a process restart")}async compactThread(){if(!this.readyPromise)throw Error("codex thread not initialized");if(await this.readyPromise,!this.sessionId)throw Error("codex thread not initialized");await this.request("thread/compact/start",{threadId:this.sessionId})}failTurnStart($,Z){if(!this.ownsTurnStartFailure(Z)){_(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(_(`codex-process: turn/start failed: ${J}`),$ instanceof Q2&&$.method==="turn/start"&&CY($.serverMessage)&&Z.inputText!==void 0&&this.scheduleCapacityRetry($.serverMessage,Z.inputText))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"codex_turn_start_failed",is_error:!0},this.currentTurnId=null,this.lastCompletedTurnId=null,this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:J,...$ instanceof Q2&&$.method==="turn/start"&&Z.inputText!==void 0&&(f9($.serverData)||f9({message:$.serverMessage}))?{codexQuotaFailure:{accepted:!1,rejectedInput:Z.inputText}}:{}})}recordTurnStarted($,Z,J,Y){let Q=typeof $?.id==="string"&&$.id?$.id:null;if(!Q)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Q))return;let W=Y??this.turnStartOwner;if(W?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===W)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let V=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let z={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",z)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Q,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...V?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Y=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Y?.turn,this.sessionId,"turn/start response",J)}catch(Y){if(!this.ownsTurnStartFailure(J)){_(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Y}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>_(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Y=Math.min(fK*2**Math.min(J-1,4),vK),Q=this.turnStartGeneration??0,W={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=W,_(`codex-process: model capacity retry #${J} in ${Y}ms: ${$}`);let H=setTimeout(()=>{if(this.capacityRetryTimer!==H)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Q!==(this.turnStartGeneration??0))return;if(this.turnRetry={...W,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let V=this.beginTurnStart(Z);this.startTurn(Z,V).catch((z)=>this.failTurnStart(z,V))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",W),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){_(`codex-process: permission response for unknown request ${$}`);return}let Q=Z==="allow";switch(Y.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/permissions/requestApproval":if(Q)this.respond($,{permissions:Y.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Q){this.respondError($,J?.denyMessage??"denied by user");return}let W=J?.updatedInput?.answers??{},H={};for(let V of Y.params?.questions??[]){let z=W[V.question]??W[V.id];if(z!==void 0)H[V.id]={answers:[String(z)]}}this.respond($,{answers:H});return}default:h$("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Y.method,params:Y.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,_(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(_(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Y=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw _(`codex-process: kill failed: ${Y.message}`),Y}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function oK($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b5($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let V=J.exec($);if(!V)break;let z=V[1],X=new RegExp(`^(?: {0,3})${oK(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");X.lastIndex=V.index+V[0].length;let G=X.exec($),K=G?G.index+G[0].length:$.length;Z.push({start:V.index,end:K}),Y=K}let Q=[...Z],W=[],H=0;for(let V of Z){if(H<V.start)W.push({start:H,end:V.start});H=V.end}if(H<$.length)W.push({start:H,end:$.length});for(let V of W){let z=$.slice(V.start,V.end),X=/(`+)[^\n]*?\1/g,G;while((G=X.exec(z))!==null)Q.push({start:V.start+G.index,end:V.start+G.index+G[0].length})}return Q.sort((V,z)=>V.start-z.start)}function y5($,Z){if(!$)return $;let J=b5($);if(!J.length)return Z($);let Y="",Q=0;for(let W of J){if(W.start>Q)Y+=Z($.slice(Q,W.start));Y+=$.slice(W.start,W.end),Q=Math.max(Q,W.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function rK($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function gY($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let W=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${W})`:`\uD83D\uDDBC️ ${W}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function c0($){if(Array.isArray($))return $.map((Y)=>c0(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=c0(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=w5(Z.content);return J}function e($){return y5($,(Z)=>tK(gY(rK(Z))))}function tK($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
47
87
  \`\`\`
48
88
  ${J.trim()}
49
89
  \`\`\`
@@ -51,181 +91,181 @@ ${J.trim()}
51
91
  \`\`\`
52
92
  ${J.trim()}
53
93
  \`\`\`
54
- `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function U6($){return R6($,DY)}var U;var x$=T(()=>{U={userInput:"user_input",footer:"footer",taskBoardLive:"task_board_live",planLive:"plan_live",tool:($)=>`tool_${$}`,planUpdate:($)=>`plan_update_${$}`,goalUpdate:($)=>`goal_update_${$}`,contextCompact:($)=>`context_compact_${$}`,assistant:($)=>`assistant_${$}`,consoleCurrentModel:"console_current_model",consoleProjects:"console_projects",consoleHost:"console_host",consoleUsage:"console_usage",modelPanel:"model_panel",codexAccountPanel:"codex_account_panel",modelAgentGroup:($)=>`model_agent_${$}`,tasklistPanel:"tasklist_panel",agentIdentityPanel:"agent_id_panel",agentRunFooter:"agent_run_footer"}});function MY($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function VK($,Z){let J=$??"";if(J==="subagent"||J==="local_agent")return"subagent";if(J==="shell"||J==="local_bash"||J==="local_shell")return"shell";if(J==="monitor"||J==="local_monitor")return"monitor";if(J==="workflow"||J==="local_workflow")return"workflow";if(Z)return"subagent";return"unknown"}function FY($){return $==="workflow"||$==="monitor"}function n$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function P1($){return $.some((Z)=>!n$(Z))}function E6($,Z,J=Date.now()){let Y=VK(Z.task_type,Z.subagent_type),Q=$.active.some((V)=>V.id===Z.task_id),W=$.pending.some((V)=>V.id===Z.task_id);if(Q||W){let V=(X)=>({...X,type:Y,toolUseId:Z.tool_use_id??X.toolUseId,description:Z.description||X.description,subagentType:Z.subagent_type??X.subagentType,workflowName:Z.workflow_name??X.workflowName,prompt:Z.prompt??X.prompt});return{active:Q?$.active.map((X)=>X.id===Z.task_id?V(X):X):$.active,pending:W?$.pending.map((X)=>X.id===Z.task_id?V(X):X):$.pending}}let H={id:Z.task_id,toolUseId:Z.tool_use_id,type:Y,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...FY(Y)?{isBackgrounded:!0}:{}};return FY(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function S6($,Z){let J=$.active.some((W)=>W.id===Z.task_id),Y=$.pending.some((W)=>W.id===Z.task_id);if(!J&&!Y)return $;let Q=(W)=>({...W,description:Z.description??W.description,subagentType:Z.subagent_type??W.subagentType,usage:Z.usage??W.usage,lastToolName:Z.last_tool_name??W.lastToolName,summary:Z.summary??W.summary,status:W.status==="pending"?"running":W.status});return{active:J?$.active.map((W)=>W.id===Z.task_id?Q(W):W):$.active,pending:Y?$.pending.map((W)=>W.id===Z.task_id?Q(W):W):$.pending}}function k6($,Z){let J=$.pending.findIndex((H)=>H.id===Z.task_id),Y=Z.patch;if(Y.is_backgrounded===!0&&J>=0){let H=$.pending[J],V={...H,isBackgrounded:!0,status:Y.status??H.status,description:Y.description??H.description,error:Y.error??H.error,endTime:Y.end_time??H.endTime};return{active:[...$.active,V],pending:$.pending.filter((X)=>X.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),W=J>=0;if(Q||W){let H=(V)=>({...V,status:Y.status??V.status,description:Y.description??V.description,error:Y.error??V.error,isBackgrounded:Y.is_backgrounded??V.isBackgrounded,endTime:Y.end_time??V.endTime});return{active:Q?$.active.map((V)=>V.id===Z.task_id?H(V):V):$.active,pending:W?$.pending.map((V)=>V.id===Z.task_id?H(V):V):$.pending}}return $}function x6($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function C6($,Z,J=Date.now()){let Y=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Q)=>Q.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Q)=>Q.id!==Z.task_id)};if($.active.some((Q)=>Q.id===Z.task_id))return{active:$.active.map((Q)=>Q.id===Z.task_id?{...Q,status:Y,usage:Z.usage??Q.usage,summary:Z.summary??Q.summary,endTime:Q.endTime??J}:Q),pending:$.pending};return $}function k9($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>XK){J=Y+1;break}return J===0?$:$.slice(J)}function zK($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return e1(J(Z?.command))||"(空命令)";case"Read":return J(Z?.file_path);case"Edit":return J(Z?.file_path);case"Write":return J(Z?.file_path);case"Grep":return`"${J(Z?.pattern)}" in ${J(Z?.path??".")}`;case"Glob":return`"${J(Z?.pattern)}"`;case"Task":return J(Z?.description);case"WebSearch":return`"${J(Z?.query)}"`;default:return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}function GK($,Z){let Y=((typeof $==="string"?$:Array.isArray($)?$.map((Q)=>typeof Q?.text==="string"?Q.text:JSON.stringify(Q)).join(`
55
- `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Y.slice(0,80)}`:Y.slice(0,80)}function b6($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((X)=>X.toolUseId===Z),H=$.pending.some((X)=>X.toolUseId===Z);if(!W&&!H)return $;let V=(X)=>X.map((z)=>z.toolUseId===Z?{...z,steps:k9([...z.steps,{toolUseId:J,tool:Y,brief:`${Y} ${zK(Y,Q)}`.trim()}])}:z);return{active:W?V($.active):$.active,pending:H?V($.pending):$.pending}}function y6($,Z,J,Y,Q,W){let H=$.active.some((z)=>z.id===Z),V=$.pending.some((z)=>z.id===Z);if(!H&&!V)return $;let X=(z)=>z.map((G)=>{if(G.id!==Z)return G;if(Q==="started")return{...G,steps:k9([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()}])};let K=!1,B=G.steps.map((A)=>{if(K||A.toolUseId!==J)return A;return K=!0,{...A,brief:W?`${A.brief} ${W}`:A.brief}});if(!K&&W)B.push({toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()});return{...G,steps:k9(B)}});return{active:H?X($.active):$.active,pending:V?X($.pending):$.pending}}function w6($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((X)=>X.toolUseId===Z),H=$.pending.some((X)=>X.toolUseId===Z);if(!W&&!H)return $;let V=(X)=>X.map((z)=>{if(z.toolUseId!==Z)return z;let G=!1,K=z.steps.map((B)=>{if(G||B.toolUseId!==J)return B;return G=!0,{...B,brief:`${B.brief} → ${GK(Y,Q)}`}});return{...z,steps:k9(K)}});return{active:W?V($.active):$.active,pending:H?V($.pending):$.pending}}function O6($){if(!$||$<0)return"0s";let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let J=Math.floor(Z/60);if(J<60)return`${J}m${Z%60}s`;return`${Math.floor(J/60)}h${J%60}m`}function OY($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let W of BK)if(Z<W.limit)return{label:W.label,nextDelayMs:W.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${(Y+1)*10}m+`,nextDelayMs:Q-Z}}function m0($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=T6){let Y=Math.floor((J-T6)/RY),Q=T6+(Y+1)*RY;return{label:`${10+Y*5}m+`,nextDelayMs:Q-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:UY}}return OY($)}function AK($){return $.subagentType??$.workflowName??KK[$.type]}function N6($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function qK($,Z,J="bucket"){let Y=(Q)=>m0(Q,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Y(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Y(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${O6(N6($))}`;case"failed":return`❌ 失败 ${O6(N6($))}`;case"killed":return`\uD83D\uDC80 已终止 ${O6(N6($))}`}}function TY($){let Z=$.filter((Y)=>!n$(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function x9($){return`\uD83E\uDDED 后台任务 · ${TY($)}`}function PK($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(n$($)&&$.summary)Z.push(`\uD83D\uDCDD ${$.summary.slice(0,400)}`,"");for(let J=0;J<$.steps.length;J++)Z.push(`${J+1}. ${$.steps[J].brief}`);return e(Z.length>0?Z.join(`
56
- `):"_(暂无执行记录)_")}function Y2($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:Q4.panel($.id),header:{title:{tag:"plain_text",content:`${_K[$.type]} ${AK($)} · ${$.description||"(无描述)"} — ${qK($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:Q4.body($.id),content:PK($)}]}}function f6($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:x9($)}},body:{elements:$.map((Y)=>Y2(Y,Z,J))}}}function C9($,Z=Date.now(),J="bucket"){let Y=$.filter(n$);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>Y2(Q,Z,J))}}}function v6(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var Q4,XK=1000,_K,KK,BK,UY=1000,T6=600000,RY=300000;var h6=T(()=>{x$();U9();Q4={panel:($)=>`bg_${MY($)}`,body:($)=>`bgb_${MY($)}`};_K={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},KK={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};BK=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as LK}from"node:events";import{join as jK,isAbsolute as DK,extname as MK,basename as FK}from"node:path";import{readFile as RK}from"node:fs/promises";function UK($){if($.length>=8&&$.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if($.length>=3&&$[0]===255&&$[1]===216&&$[2]===255)return"image/jpeg";let Z=$.subarray(0,12).toString("ascii");if(Z.startsWith("GIF87a")||Z.startsWith("GIF89a"))return"image/gif";if($.length>=12&&Z.startsWith("RIFF")&&Z.slice(8,12)==="WEBP")return"image/webp";throw Error("DSH image input has unsupported or invalid raster bytes")}var b9=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),I6,g6;var NY=T(()=>{L$();A1();t2();I();I6={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};g6=class g6 extends LK{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=b9();lastContextWindow=null;lastContextTokens=null;runtime;ready;models=[];busy=!1;closing=!1;startedAt=0;questionInputs=new Map;frames=new Map;toolInputs=new Map;children=new Set;settledChildren=new Set;childText=new Map;earlyNotifications=[];pendingInputs=0;terminalError=null;failedUnexpectedly=!1;constructor($){super();this.opts=$;this.tokenSourceId=$.tokenSourceId,this.lastModel=$.model,this.lastEffort=$.effort;let Z=$.launch??{kind:"fresh"};K$(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new j9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:jK($.managedSkillPluginPath,"skills")}:{},...$.runtimeOptions}),this.runtime.on("notification",(Y)=>{if(!this.sessionId&&Y.method!=="failure"){this.earlyNotifications.push(Y);return}if(this.terminalError)return;try{this.onNotification(Y)}catch(Q){this.fail(Q)}}),this.runtime.on("failure",(Y)=>this.fail(Y)),this.runtime.on("exit",(Y)=>this.emit("exit",{...Y,expected:Y.expected&&!this.failedUnexpectedly}))}sendInitialize(){this.initializationPromise().catch(($)=>this.fail($))}initializationPromise(){return this.ready??=(async()=>{await this.runtime.initialize();let $=await this.runtime.request("session/open",{cwd:this.opts.workDir,model:this.opts.model,effort:this.opts.effort,launch:this.opts.launch??{kind:"fresh"},developerInstructions:this.opts.developerInstructions??"",allowDelegation:this.opts.allowDelegation!==!1,...this.opts.profile?.tools?{allowedTools:this.opts.profile.tools.split(",").map((Z)=>{let J=Z.trim();return Object.keys(I6).find((Y)=>I6[Y]===J)??J})}:{}});if(typeof $.sessionId!=="string"||!Array.isArray($.models))throw Error("invalid DSH session/open response");this.sessionId=$.sessionId,this.models=$.models,this.lastContextWindow=this.models.find((Z)=>Z.model===this.lastModel)?.contextWindow??null,this.emit("init",{session_id:this.sessionId});for(let Z of this.earlyNotifications.splice(0))this.onNotification(Z)})()}isAlive(){return this.runtime.isAlive()}isConversationResumable(){return this.sessionId!==null}kill($){return this.closing=!0,this.runtime.close($)}sendUserText($,Z=[]){if(!this.isAlive()||this.closing)throw Error("DSH process is closed");if(Z.some((J)=>!DK(J)))throw Error("DSH file inputs must use absolute paths");if(this.terminalError)throw this.terminalError;this.pendingInputs++,this.initializationPromise().then(async()=>{let J=[{type:"text",text:[$,...Z.map((W)=>`[file: ${W}]`)].join(`
57
- `)}],Y=new Set([...Z,...Array.from($.matchAll(/\[file: ([^\]\r\n]+)\]/g),(W)=>W[1])]),Q=new Set([".png",".jpg",".jpeg",".webp",".gif"]);for(let W of Y){if(!Q.has(MK(W).toLowerCase()))continue;let H=await RK(W);J.push({type:"image",mediaType:UK(H),name:FK(W),data:H.toString("base64")})}await this.runtime.request("session/prompt",{mode:"auto",content:J}),this.pendingInputs--}).catch((J)=>this.fail(J))}sendInterrupt(){this.runtime.request("session/cancel").catch(($)=>this.fail($))}sendPermissionResponse($,Z,J){let Y=String($),Q=this.questionInputs.get(Y);if(!Q)throw Error(`unknown DSH question: ${Y}`);let W=J?.updatedInput?.answers,H=Z==="allow"?Q.map((V)=>{let X=W?.[V.question];if(typeof X!=="string")throw Error(`missing answer to DSH question: ${V.question}`);let z=V.options?.find((G)=>G.label===X);return{id:V.id,selected:z?[X]:[],...z?{}:{custom:X}}}):void 0;this.runtime.request("question/answer",{id:Y,answers:H,...Z==="deny"?{error:J?.denyMessage??"User declined the question"}:{}}).then(()=>{this.questionInputs.delete(Y),this.emit("tool_result",{tool_use_id:Y,content:JSON.stringify({answers:H}),is_error:Z==="deny",parentToolUseId:null})}).catch((V)=>this.fail(V))}sendHookResponse(){throw Error("DSH does not issue hook callback requests")}async listModels(){return await this.runtime.initialize(),this.models=await this.runtime.request("model/list",{models:[this.lastModel??this.opts.model]}),this.models.map(($)=>({id:$.model,model:$.model,displayName:$.display,description:"DeepSeek Harness",hidden:!1,isDefault:$.isDefault,defaultReasoningEffort:$.defaultEffort,supportedReasoningEfforts:$.efforts.map((Z)=>({reasoningEffort:Z,description:""}))}))}async setModelSettings($,Z){if(!_$(Z))throw Error(`invalid DSH effort: ${Z}`);if(await this.initializationPromise(),await this.runtime.request("session/model",{model:$,effort:Z}),!this.busy)this.lastModel=$,this.lastEffort=Z}async compactThread(){if(await this.initializationPromise(),await this.runtime.request("session/compact",{},null)===null)throw new B1}fail($){let Z=$ instanceof Error?$:Error(String($));if(this.terminalError)return;this.failedUnexpectedly=!this.closing,this.terminalError=Z,this.emit("error",Z);for(let J of this.children){if(this.settledChildren.has(J))continue;this.settledChildren.add(J),this.emit("bg_task_settled",{task_id:J,status:"failed",summary:Z.message})}if(this.busy||this.pendingInputs>0)this.busy=!1,this.lastResult={...b9(),is_error:!0,subtype:"error"},this.emit("result",{errors:[Z.message],error:Z.message,...this.lastResult});this.kill().catch((J)=>this.emit("error",J))}onNotification({method:$,params:Z}){let J=Z.sessionId!==this.sessionId;switch($){case"failure":this.fail(Error(Z.message));return;case"agent.error":this.emit("error",Error(Z.message));return;case"subagent.started":this.children.add(Z.sessionId),this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});return;case"subagent.disposed":if(this.children.has(Z.sessionId)&&!this.settledChildren.has(Z.sessionId))this.emit("bg_task_settled",{task_id:Z.sessionId,status:"stopped",summary:this.childText.get(Z.sessionId)??""});this.children.delete(Z.sessionId),this.settledChildren.delete(Z.sessionId),this.childText.delete(Z.sessionId);for(let Y of this.frames.keys())if(Y.startsWith(`${Z.sessionId}:`))this.frames.delete(Y);return;case"session.status":return;case"question":{this.questionInputs.set(Z.id,Z.questions);let Y={questions:Z.questions.map((Q)=>({...Q,question:Q.detail?`${Q.question}
58
-
59
- ${Q.detail}`:Q.question}))};this.questionInputs.set(Z.id,Y.questions),this.emit("tool_use",{id:Z.id,name:"AskUserQuestion",input:Y,parentToolUseId:null}),this.emit("can_use_tool",{request_id:Z.id,tool_use_id:Z.id,tool_name:"AskUserQuestion",input:Y});return}case"question.cancelled":this.questionInputs.delete(Z.id),this.emit("tool_result",{tool_use_id:Z.id,content:"Question cancelled",is_error:!0,parentToolUseId:null});return;case"assistant.frame":{let Y=Z.frame,Q=`${Z.sessionId}:${Y.attemptId}`;if(Y.type==="start"){this.frames.set(Q,{revision:Y.revision,nextIndex:0});return}let W=this.frames.get(Q);if(!W||W.revision+1!==Y.revision||W.nextIndex!==Y.index)throw Error("DSH assistant stream sequence mismatch");if(W.revision=Y.revision,Y.type==="end"){if(this.frames.delete(Q),!J)this.emit("assistant_block_stop",{parentToolUseId:null});return}if(Y.type!=="chunk")throw Error(`unknown DSH assistant frame: ${Y.type}`);W.nextIndex++;let H=Y.chunk;if(H.type==="text-delta"){if(J)this.childText.set(Z.sessionId,(this.childText.get(Z.sessionId)??"")+H.text);this.emit("assistant_text",{text:H.text,parentToolUseId:J?Z.sessionId:null})}else if(H.type==="block-end"&&H.block.type==="text"&&!J)this.emit("assistant_block_stop",{parentToolUseId:null});else if(H.type==="usage"&&!J)this.observeUsage(H.usage);return}case"session.event":{let Y=Z.event,Q=Y.data;if(!Y||!Q||typeof Y.type!=="string")throw Error("invalid DSH session event");if(Y.type==="turn/start"&&!J)this.busy=!0,this.startedAt=Date.now(),this.lastUsage=null,this.lastResult=b9(),this.emit("scheduled_turn_input",{text:"DeepSeek Harness 继续执行",promptId:`dsh-turn-${Q.turn}`}),this.emit("turn_started",{turn_id:String(Q.turn),thread_id:this.sessionId});else if(Y.type==="turn/start"&&J&&this.settledChildren.delete(Z.sessionId))this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});else if(Y.type==="request/header"&&!J&&Q.header?.config)this.lastModel=Q.header.config.model,this.lastEffort=Q.header.config.reasoningEffort,this.lastContextWindow=this.models.find((W)=>W.model===this.lastModel)?.contextWindow??null;else if(Y.type==="tool/call"){let W=JSON.parse(Q.arguments),H=I6[Q.name]??Q.name;if(["read","write","edit"].includes(Q.name)&&W.path)W.file_path=W.path;this.toolInputs.set(Q.callId,{name:H,input:W}),this.emit("tool_use",{id:Q.callId,name:H,input:W,parentToolUseId:J?Z.sessionId:null})}else if(Y.type==="tool/result"){let W=Q.message?.content?.[0];if(W?.type!=="tool-result"||typeof W.toolCallId!=="string")throw Error("invalid DSH tool result");this.emit("tool_result",{tool_use_id:W.toolCallId,content:W.content,is_error:W.isError===!0,parentToolUseId:J?Z.sessionId:null}),this.toolInputs.delete(W.toolCallId)}else if(Y.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Q.todos.map((W)=>({step:W.content,status:W.status==="in_progress"?"inProgress":W.status}))});else if(Y.type==="compaction/start"&&!J)this.emit("context_compacted",{threadId:this.sessionId,phase:"start",sourceType:"dsh"});else if(Y.type==="compaction/end"&&!J)if(Q.error)this.emit("error",Error(`DSH compaction: ${Q.error}`));else this.emit("context_compacted",{threadId:this.sessionId,phase:"end",sourceType:"dsh"});else if(Y.type==="goal/change"&&!J)if(Q.operation==="clear")this.emit("thread_goal_cleared",{threadId:this.sessionId});else this.emit("thread_goal_updated",{threadId:this.sessionId,objective:Q.goal.objective,status:Q.goal.phase,tokenBudget:null,tokensUsed:Number.NaN,timeUsedSeconds:Number.NaN});else if(Y.type==="turn/end"&&J&&this.children.has(Z.sessionId))this.settledChildren.add(Z.sessionId),this.emit("bg_task_settled",{task_id:Z.sessionId,status:Q.reason.kind==="completed"?"completed":Q.reason.kind==="aborted"?"stopped":"failed",summary:this.childText.get(Z.sessionId)??""}),this.childText.delete(Z.sessionId);return}case"settled":{if(J)throw Error("DSH settled a different root session");this.busy=!1;let Y=Z.event,Q=Y.data.reason;this.lastCompletedTurnId=String(Y.seq),this.lastResult={...b9(),duration_ms:Date.now()-this.startedAt,num_turns:1,usage:this.lastUsage,subtype:Q.kind,is_error:Q.kind!=="completed"},this.emit("result",{...this.lastResult,...Q.kind!=="completed"?{error:Q.error?.message??`DSH turn ended: ${Q.kind}`,errors:[Q.error?.message??`DSH turn ended: ${Q.kind}`]}:{},checkpoint:{provider:"dsh",kind:"event",id:String(Y.seq),source:{provider:"dsh",sessionId:this.sessionId,cwd:this.opts.workDir}}});return}default:_(`dsh: unknown notification ${$}`)}}observeUsage($){if(!Number.isFinite($.inputTokens)||!Number.isFinite($.outputTokens))throw Error("invalid DSH token usage");let Z={input_tokens:$.inputTokens,output_tokens:$.outputTokens,total_tokens:$.totalTokens,cache_read_input_tokens:$.cacheReadTokens,cache_creation_input_tokens:$.cacheWriteTokens,reasoning_output_tokens:$.reasoningTokens};this.lastUsage=Z;let J={...this.lastTotalUsage};for(let[Y,Q]of Object.entries(Z))if(Q!==void 0){let W=Y;J[W]=(J[W]??0)+Q}this.lastTotalUsage=J,this.lastContextTokens=$.inputTokens+($.cacheReadTokens??0)+($.cacheWriteTokens??0),this.emit("token_usage",{usage:Z,totalUsage:J,contextWindow:this.lastContextWindow,threadId:this.sessionId})}}});function c0($){return $.startsWith("claude:")?$:`claude:${$}`}function m6($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(f.claude.models,Z))return f.claude.models[Z]?.model?.trim()||"opus";return Z}var EY=T(()=>{k$()});import{existsSync as OK,readFileSync as TK}from"node:fs";function c6(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:GJ}function H4(){if(W4!==null)return W4;try{W4=OK(c6())?JSON.parse(TK(c6(),"utf8")):{}}catch($){_(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),W4={}}return W4??{}}function EK(){try{t(c6(),H4())}catch($){_(`context-window-observe: cache write MISS (${$?.message??$})`)}}function u6($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function SY($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=u6($,Z),Q=H4()[Y];if(Q===J)return;H4()[Y]=J,EK(),_(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function y9($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=H4()[u6($,Z)];return J!=null&&J<NK?Z:`${Z}[1m]`}function Q2($,Z){return H4()[u6($,Z)]}var NK=1e6,W4=null;var V4=T(()=>{W$();I();w$()});var lY={};P0(lY,{toolsFromProfile:()=>uY,settingSourcesFromProfile:()=>cY,resolveClaudeExecutableConfig:()=>n6,resetClaudeContextWindowCache:()=>yK,readProjectMcpServers:()=>pY,readLastCallUsageFromTranscript:()=>IY,claudeTranscriptPath:()=>h9,claudeTranscriptDir:()=>v9,claudeManagedSkillOptions:()=>vY,buildClaudeSpawnPath:()=>hY,assertClaudeCodeAvailable:()=>d6,ClaudeAgentProcess:()=>I9,CLAUDE_PERMISSION_MODE:()=>mY});import{existsSync as yY,readFileSync as wY}from"node:fs";import{homedir as f9}from"node:os";import{spawn as SK}from"cross-spawn";import{delimiter as kY,join as L1}from"node:path";import{EventEmitter as kK}from"node:events";function vY($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function xK($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function CK($){let Z=SK($.command,$.args,{cwd:$.cwd,env:$.env,shell:!1,signal:$.signal,stdio:["pipe","pipe","ignore"],windowsHide:!0});if(!Z.stdin||!Z.stdout)throw Z.kill(),Error("failed to open stdio for Claude Code Windows shell shim");return Z}function d6(){n6(),g5("claude","@anthropic-ai/claude-agent-sdk")}function n6($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?f.claude.bin:$.configuredBin;if(J){if(!($.exists??yY)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&xK(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:CK,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function hY(){if(process.platform==="win32")return process.env.PATH??"";let $=[L1(f9(),".local","npm-global","bin"),L1(f9(),".local","bin"),L1(f9(),".bun","bin"),...(process.env.PATH??"").split(kY),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(kY)}function bK($){let Z=s1($);if(!Z)return null;let J=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if((Z.total_tokens??J)<=0)return null;if(Z.total_tokens==null)Z.total_tokens=J;return Z}function xY($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function v9($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||L1(f9(),".claude");return L1(J,"projects",Z)}function h9($,Z){return L1(v9($),`${Z}.jsonl`)}function IY($){let Z;try{Z=wY($,"utf8")}catch{return null}let J=Z.split(`
60
- `);for(let Y=J.length-1;Y>=0;Y--){let Q=J[Y].trim();if(!Q)continue;try{let W=JSON.parse(Q);if(W?.type==="assistant"&&W?.message?.usage){let H=W.message.usage;if((H.input_tokens??0)+(H.cache_read_input_tokens??0)+(H.cache_creation_input_tokens??0)+(H.output_tokens??0)>0)return H}}catch{}}return null}function CY($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function yK(){l6.clear()}function wK($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Q of Object.values($)){if(!Q||typeof Q!=="object")continue;let W=Q;Z.input_tokens=(Z.input_tokens??0)+W2(W.inputTokens??W.input_tokens),Z.output_tokens=(Z.output_tokens??0)+W2(W.outputTokens??W.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+W2(W.reasoningOutputTokens??W.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+W2(W.cacheReadInputTokens??W.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+W2(W.cacheCreationInputTokens??W.cache_creation_input_tokens);let H=W2(W.contextWindow??W.context_window);if(H>0)J=Math.max(J??0,H)}let Y=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Y<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Y,{usage:Z,contextWindow:J}}function w9($){return{...$}}function p6($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function fK($,Z){let J=$?{...$}:{},Y=(Q)=>{let W=Z[Q];if(typeof W!=="number"||!Number.isFinite(W))return;J[Q]=(J[Q]??0)+W};return Y("total_tokens"),Y("input_tokens"),Y("output_tokens"),Y("reasoning_output_tokens"),Y("cache_creation_input_tokens"),Y("cache_read_input_tokens"),J}function W2($){return typeof $==="number"&&Number.isFinite($)?$:0}function gY($){if(typeof $==="string")return $;if(Array.isArray($))return $.map((Z)=>{if(typeof Z==="string")return Z;if(Z&&typeof Z==="object"&&typeof Z.text==="string")return Z.text;return JSON.stringify(Z)}).join(`
61
- `);return $==null?"":JSON.stringify($,null,2)}function vK($){let Z=gY($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Y=J.map((Q)=>{if(typeof Q==="string")return Q;if(Q&&typeof Q==="object"&&typeof Q.text==="string")return Q.text;return JSON.stringify(Q)}).filter(Boolean);if(Y.length>0)return Y.join(`
62
- `)}}catch{}return Z}function hK($){return`server_tool:${$}`}function IK($){let Z=$.match(/Built-in Tool:\s*([A-Za-z0-9_.:-]+)/)?.[1];if(!Z)return null;let J=$.match(/\*\*Input:\*\*\s*```(?:json)?\s*([\s\S]*?)```/)?.[1]?.trim();if(!J)return{name:Z,input:{}};try{return{name:Z,input:JSON.parse(J)}}catch{return{name:Z,input:{raw:J}}}}function gK($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function mK($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[h0];return{id:c0($.value),model:c0($.value),displayName:$.displayName||c0($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(h0)?h0:Z[0]}}function cY($){if(!$?.settingSources)return[...bY];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...bY]}function uY($){if(!$?.tools)return{type:"preset",preset:"claude_code"};let Z=$.tools.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:{type:"preset",preset:"claude_code"}}function pY($){let Z=L1($,".mcp.json"),J;try{J=wY(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")_(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Y}`);return}try{let Y=JSON.parse(J);if(Y&&typeof Y==="object"&&Y.mcpServers&&typeof Y.mcpServers==="object")return Y.mcpServers;_(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){_(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function cK($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>uK(Y)).filter((Y)=>Y!==null)}function uK($){let Z=$&&typeof $==="object"?$:{question:$},J=i6(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=pK(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Y,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function pK($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Y=J,Q=i6(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let W=i6(Y.description,Y.detail,Y.preview);Z.push(W?{label:Q,description:W}:{label:Q})}return Z}function i6(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var fY,l6,mY="default",bY,I9;var X4=T(()=>{a1();k$();I();L$();EY();V4();fY=class fY{items=[];waiters=[];closed=!1;push($){if(this.closed)throw Error("input stream is closed");let Z=this.waiters.shift();if(Z)Z({value:$,done:!1});else this.items.push($)}close(){if(this.closed)return;this.closed=!0;while(this.waiters.length)this.waiters.shift()?.({value:void 0,done:!0})}abort(){this.items=[],this.close()}[Symbol.asyncIterator](){return this}next(){if(this.items.length>0)return Promise.resolve({value:this.items.shift(),done:!1});if(this.closed)return Promise.resolve({value:void 0,done:!0});return new Promise(($)=>this.waiters.push($))}};l6=new Map;bY=["project","local"];I9=class I9 extends kK{provider="claude";tokenSourceId;opts;input=new fY;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;queryStart;pendingPermissions=new Map;requestCounter=0;cumulativeUsageFromResults=null;turnActive=!1;emittedToolUseIds=new Set;emittedToolResultIds=new Set;pendingServerToolInputs=[];sessionId=null;lastAssistantUuid=null;lastModel=null;lastEffort=null;lastThinkingTokens=null;lastUsage=null;lastTotalUsage=null;lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1};lastContextWindow=null;lastContextTokens=null;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((Z)=>{this.resolveExit=Z}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.lastEffort=$.effort,this.lastModel=$.model?c0($.model):null}sendInitialize(){if(this.started)return;this.started=!0,this.queryStart=this.initializeQuery().catch(($)=>{this.emit("error",$ instanceof Error?$:Error(String($))),this.finishExit(1,null)})}async initializeQuery(){let $=m6(this.opts.model),Z=this.opts.profile;if(Z)_(`claude-agent-process: project profile active — settingSources=${Z.settingSources??"-"} strictMcp=${Z.strictMcp??!1} tools=${Z.tools??"-"} loadProjectMcp=${Z.loadProjectMcp??!0}`);let J=this.opts.settingSources??cY(Z),Y=vY(J,this.opts.managedSkillPluginPath),Q=uY(Z),W=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?pY(this.opts.workDir):void 0;try{let V=n6(),{query:X}=await NJ();if(!this.alive||this.abortController.signal.aborted)return;let z={...process.env,PATH:hY(),...f.claude.env,...this.opts.hostEnv??{}},G=this.opts.transformEnv?this.opts.transformEnv(z):z;if(this.opts.effort==="default")G.CLAUDE_CODE_EFFORT_LEVEL="unset";_(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${V.description}`),this.query=X({prompt:this.input,options:{cwd:this.opts.workDir,abortController:this.abortController,...$?{model:$}:{},effort:this.opts.effort==="default"?"high":this.opts.effort,resume:this.opts.resumeSessionId,...this.opts.resumeSessionAt?{resumeSessionAt:this.opts.resumeSessionAt}:{},...this.opts.forkSession?{forkSession:!0}:{},...V.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:V.pathToClaudeCodeExecutable}:{},...V.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:V.spawnClaudeCodeProcess}:{},permissionMode:mY,env:G,settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...W?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(K,B,A)=>this.canUseTool(K,B,A),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(K)=>{let B=K.trim();if(B)_(`claude-agent-process[stderr]: ${B}`)}}})}catch(V){let X=V instanceof Error?V:Error(String(V));this.emit("error",X),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){_("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
63
-
64
- `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let Q=Y instanceof Error?Y:Error(String(Y));_(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>_(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){_(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Y.cleanup?.(),Z==="allow")Y.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Y.resolve({behavior:"deny",message:J?.denyMessage??""})}sendHookResponse($,Z={}){_("claude-agent-process: sendHookResponse ignored; hooks are handled by SDK callbacks")}isAlive(){return this.alive}async kill($=5000){if(!this.alive)return;if(this.expectedExit=!0,this.denyPendingPermissions("claude process is stopping"),this.input.abort(),!this.started||!this.query){this.finishExit(null,null);return}let Z=null;try{this.query.close()}catch(J){Z=J instanceof Error?J:Error(String(J))}if(!this.abortController.signal.aborted)this.abortController.abort(Z??Error("claude process shutdown requested"));if(!await this.waitForExit($)){let J=Error(`claude Agent SDK query did not exit within ${$}ms after close/abort`,Z?{cause:Z}:void 0);throw _(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw _(`claude-agent-process: kill failed: ${J.message}`),J}}async listModels(){if(!this.started)this.sendInitialize();if(await this.queryStart,!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");return(await this.query.supportedModels()).map(mK)}async setModelSettings($,Z){let J=m6($);if(!O$(Z))throw Error(`invalid Claude effort: ${String(Z)}`);if(this.opts.effort==="default"!==(Z==="default"))throw Error("effort 参数模式改变,需要使用新的启动环境恢复会话");if(!this.started)this.sendInitialize();if(await this.queryStart,!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");if(J)await this.query.setModel(J);await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null}),this.opts.model=$,this.opts.effort=Z,this.lastModel=J?c0($):"claude:default",this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Y=()=>{this.off("context_compacted",Q),this.off("assistant_text",W),this.off("exit",H),this.off("error",V)},Q=()=>{if(J)return;J=!0,Y(),$()},W=(X)=>{if(J)return;if((X?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new B1)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},V=(X)=>{if(J)return;J=!0,Y(),Z(X instanceof Error?X:Error(String(X)))};this.on("context_compacted",Q),this.on("assistant_text",W),this.once("exit",H),this.once("error",V)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=cK(Z);if(Y.length===0)return _("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},W=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||W,V={request_id:W,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},X=new Promise((z)=>{let G=(B)=>{J.signal.removeEventListener("abort",K),z(B)},K=()=>{if(!this.pendingPermissions.delete(W))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(W,{kind:"dialog",resolve:G,request:V})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",V),X}async readLoop($){try{for await(let Z of $)this.handleMessage(Z);this.finishExit(null,null)}catch(Z){let J=Z instanceof Error?Z:Error(String(Z));if(this.expectedExit&&this.abortController.signal.aborted){_(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}_(`claude-agent-process: read loop failed: ${J.message}`),this.emit("error",J),this.finishExit(1,null)}}finishExit($,Z){if(!this.alive)return;this.alive=!1,this.turnActive=!1,this.denyPendingPermissions("claude process exited"),this.resolveExit(),_(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:_(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=c0($.model);this.lastEffort=this.opts.effort,this.emit("init",{session_id:this.sessionId,raw:$});return;case"session_state_changed":if($.state==="running"&&!this.turnActive)this.turnActive=!0,this.lastThinkingTokens=null,this.lastAssistantUuid=null,this.emit("turn_started",{turn_id:$.uuid,thread_id:this.sessionId});else if($.state==="idle")this.turnActive=!1;return;case"compact_boundary":this.emit("context_compacted",{threadId:$.session_id??this.sessionId??void 0,sessionId:$.session_id??this.sessionId??void 0,itemId:$.uuid,phase:"event",sourceMethod:"claude_agent_sdk",sourceType:"compact_boundary",preTokens:$.compact_metadata?.pre_tokens,trigger:$.compact_metadata?.trigger});return;case"api_retry":_(`claude-agent-process: api retry attempt=${$.attempt}/${$.max_retries} status=${$.error_status} error=${$.error}`);return;case"thinking_tokens":if(typeof $.estimated_tokens!=="number"||!Number.isFinite($.estimated_tokens)||$.estimated_tokens<0){_("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":_(`claude-agent-process: permission denied ${$.tool_name} ${$.tool_use_id}: ${$.message}`);return;case"task_started":this.emit("bg_task_started",{task_id:String($.task_id??""),tool_use_id:typeof $.tool_use_id==="string"?$.tool_use_id:void 0,task_type:typeof $.task_type==="string"?$.task_type:void 0,description:String($.description??""),subagent_type:typeof $.subagent_type==="string"?$.subagent_type:void 0,workflow_name:typeof $.workflow_name==="string"?$.workflow_name:void 0,prompt:typeof $.prompt==="string"?$.prompt:void 0});return;case"task_progress":this.emit("bg_task_progress",{task_id:String($.task_id??""),description:typeof $.description==="string"?$.description:void 0,subagent_type:typeof $.subagent_type==="string"?$.subagent_type:void 0,usage:$.usage,last_tool_name:typeof $.last_tool_name==="string"?$.last_tool_name:void 0,summary:typeof $.summary==="string"?$.summary:void 0});return;case"task_updated":this.emit("bg_task_updated",{task_id:String($.task_id??""),patch:$.patch&&typeof $.patch==="object"?$.patch:{}});return;case"task_notification":if(typeof $.task_id!=="string"||!$.task_id){_("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){_(`claude-agent-process: task_notification unknown status=${String($.status)} task=${$.task_id}`);return}this.emit("bg_task_settled",{task_id:$.task_id,tool_use_id:typeof $.tool_use_id==="string"?$.tool_use_id:void 0,status:$.status,summary:typeof $.summary==="string"?$.summary:void 0,usage:$.usage});return;default:_(`claude-agent-process: unhandled system subtype=${String($.subtype??"unknown")}`);return}}handleAssistantMessage($){if(!$.parent_tool_use_id)this.lastThinkingTokens=null;let Z=$.message,J=typeof $.parent_tool_use_id==="string"&&$.parent_tool_use_id?$.parent_tool_use_id:null;if(!J&&typeof $.uuid==="string")this.lastAssistantUuid=$.uuid;if(typeof Z?.model==="string"&&Z.model)this.lastModel=c0(Z.model);let Y=Array.isArray(Z?.content)?Z.content:[];for(let Q of Y){if(!Q||typeof Q!=="object")continue;if(Q.type==="text"&&typeof Q.text==="string"&&Q.text.length>0){let W=IK(Q.text);if(W){if(this.pendingServerToolInputs.push(W),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(gK(Q.text))continue;let H=$.uuid??Z?.id;this.emit("assistant_text",{uuid:H,text:Q.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:H,parentToolUseId:J})}else if(Q.type==="tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Q.name,Q.input??{},J);else if(Q.type==="server_tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,hK(Q.name),{tool:Q.name,input:this.serverToolInput(Q.name,Q.input??{})},J);else if(Q.type==="tool_result"&&typeof Q.tool_use_id==="string")this.emitToolResultOnce(Q.tool_use_id,vK(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())_(`claude-agent-process: tool_use ${$} has an empty name`),Z="MISS";this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Y})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Y=this.pendingServerToolInputs.findIndex((Q)=>Q.name===$);if(Y>=0){let[Q]=this.pendingServerToolInputs.splice(Y,1);return Q.input}return J}emitToolResultOnce($,Z,J,Y){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Y})}handleUserMessage($){let Z=$.message?.content;if($.isMeta===!0&&$.promptSource==="sdk"&&typeof Z==="string"&&Z.trim())this.emit("scheduled_turn_input",{text:Z,promptId:typeof $.promptId==="string"&&$.promptId?$.promptId:null});let J=Array.isArray(Z)?Z:[];for(let Y of J){if(!Y||typeof Y!=="object")continue;if(Y.type!=="tool_result"||typeof Y.tool_use_id!=="string")continue;let Q=$.tool_use_result,W=gY(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
65
- `):"",V=W||H;this.emitToolResultOnce(Y.tool_use_id,V,Y.is_error===!0||Q?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=bK($.usage),J=$.modelUsage??$.model_usage,Y=wK(J);if(!Z&&!Y.usage)_(`claude-agent-process: result usage missing rootKeys=${p6($).join(",")||"-"} usageKeys=${p6($.usage).join(",")||"-"} modelUsageKeys=${p6(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=w9(Y.usage),this.lastTotalUsage=w9(Y.usage);else if(Z)this.cumulativeUsageFromResults=fK(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=w9(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?w9(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let V=CY(this.opts.model,this.tokenSourceId);if(l6.set(V,Y.contextWindow),this.tokenSourceId)for(let[X,z]of Object.entries(J??{})){let G=z?.contextWindow;if(typeof G==="number"&&G>0)SY(this.tokenSourceId,X,G)}}this.lastContextWindow=l6.get(CY(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=h9(this.opts.workDir,this.sessionId??""),W=IY(Q);if(this.lastContextTokens=xY(W)??(yY(Q)?xY(Z):null),this.lastTotalUsage||this.lastUsage)this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:this.sessionId??void 0,turnId:$.uuid});let H=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof $.duration_ms==="number"?$.duration_ms:null,num_turns:typeof $.num_turns==="number"?$.num_turns:1,usage:this.lastUsage,subtype:H,is_error:$.is_error===!0||H!=="success"},this.emit("result",{subtype:H,is_error:this.lastResult.is_error,...this.lastResult.is_error?{error:Array.isArray($.errors)&&$.errors.length?$.errors.map(String).join(`
66
- `):String($.result??$.error??$.api_error_message??H)}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,checkpoint:!this.lastResult.is_error&&this.lastAssistantUuid&&this.sessionId?{provider:"claude",kind:"assistant-message",id:this.lastAssistantUuid,source:{provider:"claude",sessionId:this.sessionId,cwd:this.opts.workDir}}:null})}failTurnStart($){this.turnActive=!1,this.lastAssistantUuid=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"claude_turn_start_failed",is_error:!0},this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:$.message})}}});var aY={};P0(aY,{waitForTokenSourceModelRefresh:()=>_2,tokenSourceRuntimeModels:()=>V2,tokenSourceRuntimeModel:()=>z0,tokenSourceProcessRevision:()=>X2,tokenSourceFactories:()=>z2,setDefaultTokenSource:()=>o6,scrubDshEnv:()=>z4,scrubAnthropicEnv:()=>X0,resetTokenSourceRegistry:()=>r6,registerTokenSourceFactory:()=>T$,registerTokenSource:()=>a6,refreshAllTokenSourceModels:()=>_4,pendingTokenSourceModelRefresh:()=>G2,listTokenSourcesByAgent:()=>nY,listTokenSources:()=>R0,listEnabledTokenSourcesByAgent:()=>m9,getTokenSourceForAccount:()=>H$,getTokenSource:()=>G0});function X0($){let Z={...$};for(let J of lK)delete Z[J];return Z}function z4($){let Z=X0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function V2($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function z0($,Z){let J=(Y)=>$.agent==="claude"?Y?.replace(/\[1m\]$/,""):Y;return V2($).find((Y)=>J(Y.model)===J(Z))}function X2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function T$($){iY.set($.kind,$)}function z2(){return[...iY.values()]}function a6($,Z){if(G4.set($.id,$),Z?.default||g9===null)g9=$.id}function G0($){return $?G4.get($):void 0}function H$($,Z="default"){let J=G0($);return J?.forAccount?J.forAccount(Z):J}function R0(){return[...G4.values()]}function nY($){return R0().filter((Z)=>Z.agent===$)}function m9($){return nY($).filter((Z)=>Z.enabled)}function o6($){if(G4.has($))g9=$}function r6(){G4.clear(),g9=null,dY++}function _4(){let $=dY;if(H2?.generation===$)return H2.promise;let Z=Promise.allSettled(R0().map(async(J)=>{await J.refreshModels(),_(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(H2?.promise===Z)H2=null});return H2={generation:$,promise:Z},Z}function G2(){return H2?.promise??null}async function _2(){let $;while($=G2())await $}var lK,iY,G4,g9=null,dY=0,H2=null;var J$=T(()=>{I();lK=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL","ANTHROPIC_DEFAULT_FABLE_MODEL","ANTHROPIC_MODEL","ANTHROPIC_SMALL_FAST_MODEL","CLAUDE_CODE_SUBAGENT_MODEL","ANTHROPIC_CUSTOM_HEADERS","CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX","CLAUDE_CODE_USE_FOUNDRY","CLAUDE_CODE_EFFORT_LEVEL"];iY=new Map;G4=new Map});import{spawn as iK}from"cross-spawn";import{EventEmitter as dK}from"node:events";import{StringDecoder as nK}from"node:string_decoder";import{createHash as aK}from"node:crypto";function rY($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function oK($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function c9($){if(!$)return null;return{percent:oK($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function rK($){let Z=c9($?.primary),J=c9($?.secondary),Y=(W)=>W?.durationMins!=null&&W.durationMins>0&&W.durationMins<=720,Q=(W)=>W?.durationMins!=null&&W.durationMins>720;if(Y(Z)&&Q(J))return{fiveHour:Z,weekly:J};if(Y(J)&&Q(Z))return{fiveHour:J,weekly:Z};if(Q(Z)&&!J)return{fiveHour:null,weekly:Z};if(Q(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function tK($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,W]of J){let{fiveHour:H,weekly:V}=rK(W);if(!H&&!V)continue;Y.push({limitId:Q,limitName:W?.limitName??null,fiveHour:H,weekly:V,normalModelSlug:W?.normalModelSlug??null,rateLimitReachedType:W?.rateLimitReachedType??null,spendControlReached:W?.spendControlReached??null})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function sK($){if(!$)return"empty";let Z=(J)=>J?`${J.usedPercent??"?"}%/${J.windowDurationMins??"?"}m`:"null";return`limitId=${$.limitId??"null"} name=${$.limitName??"null"} primary=${Z($.primary)} secondary=${Z($.secondary)}`}function tY($,Z=l){let J=sK($),Y=K2.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],W=Q.filter((H)=>oY(H.fiveHour,c9($?.primary))&&oY(H.weekly,c9($?.secondary)));if(Q.length>0&&W.length===0)_(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${J})`);else if($?.limitId&&W.length===1&&W[0].limitId!==$.limitId)_(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${W[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function oY($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function eK($){let Z=new B2({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await rY(Z.request("account/read",{}),t6))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await ZQ(()=>Z.request("account/rateLimits/read",{}));return sY(Q,Y.planType)}catch(J){return _(`usage: codex app-server usage failed: ${J?.message??J}`),{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function sY($,Z){let{buckets:J,defaultLimitId:Y}=tK($),Q=J.find((H)=>H.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};let W=Z??$?.rateLimits?.planType??void 0;return Q.fiveHour=A6(W,Q.fiveHour),{state:"ok",subscriptionType:W,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:aK("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:Q.rateLimitReachedType,spendControlReached:Q.spendControlReached,fiveHour:Q.fiveHour,weekly:Q.weekly,buckets:J,defaultLimitId:Q.limitId,resetCredits:Number.isInteger($?.rateLimitResetCredits?.availableCount)&&$.rateLimitResetCredits.availableCount>=0?$.rateLimitResetCredits.availableCount:null,fetchedAt:Date.now()}}function eY($=l){return K2.get($)??null}function j1($=l){let Z=K4.get($);if(Z)return Z;let J=u0.get($)??0,Y=Promise.resolve().then(()=>eK($)).catch((Q)=>{return _(`usage: ${$} fetch failed: ${Q}`),{state:"network",reason:String(Q)}}).then((Q)=>{if((u0.get($)??0)!==J)return{state:"auth_failed"};return K2.set($,Q),Q}).finally(()=>{if(K4.get($)===Y)K4.delete($)});return K4.set($,Y),Y}function u9($,Z=l){let J=B4.get(Z);if(J)return J;let Y=u0.get(Z)??0,Q=ZQ(()=>$("account/rateLimits/read",{})).then((W)=>{if((u0.get(Z)??0)!==Y)return null;let H=sY(W);if((u0.get(Z)??0)===Y)K2.set(Z,H);if(H.state!=="ok")_(`usage: refresh from connection: ${H.state==="network"?H.reason:H.state}`);return H}).catch((W)=>{if(_(`usage: refresh from connection failed: ${W?.message??W}`),(u0.get(Z)??0)===Y)K2.delete(Z);return null}).finally(()=>{if(B4.get(Z)===Q)B4.delete(Z)});return B4.set(Z,Q),Q}function $Q($){u0.set($,(u0.get($)??0)+1),K2.delete($),K4.delete($),B4.delete($)}async function ZQ($){let Z=[250,750];for(let J=0;;J++)try{return await rY($(),t6)}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(Q)||J>=Z.length)throw Y;_(`usage: rate limit request retry ${J+1}/${Z.length}: ${Q}`),await new Promise((H)=>setTimeout(H,Z[J]))}}var t6=1e4,K2,K4,B2,B4,u0;var p0=T(()=>{q1();I();k$();h$();K2=new Map,K4=new Map;B2=class B2 extends dK{proc;buf="";decoder=new nK("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??l;this.proc=iK($.bin??J4(),["app-server","--listen","stdio://",...$.args??y.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??y.env(Z,{...process.env,...f.codex.env},!0,$.login)}),this.exitPromise=new Promise((Y)=>{this.resolveExit=Y}),this.proc.stdout.on("data",(Y)=>this.onStdout(Y)),this.proc.stderr.on("data",(Y)=>{let Q=Y.toString().trim();if(Q)_(`usage[codex stderr]: ${Q}`)});let J=(Y)=>{if(!this.alive)return;this.alive=!1;for(let[Q,W]of this.pending)clearTimeout(W.timer),W.reject(Error(`${Y.message}; pending ${W.method} id=${Q}`));this.pending.clear(),this.resolveExit(),this.emit("closed",Y)};this.proc.on("error",(Y)=>J(Error(`codex app-server spawn failed: ${Y.message}`))),this.proc.stdin.on("error",(Y)=>{_(`usage: codex stdin failed: ${Y.message}`),this.emit("protocolError",Y)}),this.proc.on("close",(Y,Q)=>{J(Error(`codex app-server exited code=${Y} signal=${Q}`))})}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
94
+ `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function w5($){return y5($,gY)}var U;var C$=T(()=>{U={userInput:"user_input",footer:"footer",taskBoardLive:"task_board_live",planLive:"plan_live",tool:($)=>`tool_${$}`,planUpdate:($)=>`plan_update_${$}`,goalUpdate:($)=>`goal_update_${$}`,contextCompact:($)=>`context_compact_${$}`,assistant:($)=>`assistant_${$}`,consoleCurrentModel:"console_current_model",consoleProjects:"console_projects",consoleHost:"console_host",consoleUsage:"console_usage",modelPanel:"model_panel",codexAccountPanel:"codex_account_panel",modelAgentGroup:($)=>`model_agent_${$}`,tasklistPanel:"tasklist_panel",agentIdentityPanel:"agent_id_panel",agentRunFooter:"agent_run_footer"}});function mY($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function sK($,Z){let J=$??"";if(J==="subagent"||J==="local_agent")return"subagent";if(J==="shell"||J==="local_bash"||J==="local_shell")return"shell";if(J==="monitor"||J==="local_monitor")return"monitor";if(J==="workflow"||J==="local_workflow")return"workflow";if(Z)return"subagent";return"unknown"}function cY($){return $==="workflow"||$==="monitor"}function o$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function P1($){return $.some((Z)=>!o$(Z))}function I5($,Z,J=Date.now()){let Y=sK(Z.task_type,Z.subagent_type),Q=$.active.some((V)=>V.id===Z.task_id),W=$.pending.some((V)=>V.id===Z.task_id);if(Q||W){let V=(z)=>({...z,type:Y,toolUseId:Z.tool_use_id??z.toolUseId,description:Z.description||z.description,subagentType:Z.subagent_type??z.subagentType,workflowName:Z.workflow_name??z.workflowName,prompt:Z.prompt??z.prompt});return{active:Q?$.active.map((z)=>z.id===Z.task_id?V(z):z):$.active,pending:W?$.pending.map((z)=>z.id===Z.task_id?V(z):z):$.pending}}let H={id:Z.task_id,toolUseId:Z.tool_use_id,type:Y,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...cY(Y)?{isBackgrounded:!0}:{}};return cY(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function g5($,Z){let J=$.active.some((W)=>W.id===Z.task_id),Y=$.pending.some((W)=>W.id===Z.task_id);if(!J&&!Y)return $;let Q=(W)=>({...W,description:Z.description??W.description,subagentType:Z.subagent_type??W.subagentType,usage:Z.usage??W.usage,lastToolName:Z.last_tool_name??W.lastToolName,summary:Z.summary??W.summary,status:W.status==="pending"?"running":W.status});return{active:J?$.active.map((W)=>W.id===Z.task_id?Q(W):W):$.active,pending:Y?$.pending.map((W)=>W.id===Z.task_id?Q(W):W):$.pending}}function m5($,Z){let J=$.pending.findIndex((H)=>H.id===Z.task_id),Y=Z.patch;if(Y.is_backgrounded===!0&&J>=0){let H=$.pending[J],V={...H,isBackgrounded:!0,status:Y.status??H.status,description:Y.description??H.description,error:Y.error??H.error,endTime:Y.end_time??H.endTime};return{active:[...$.active,V],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),W=J>=0;if(Q||W){let H=(V)=>({...V,status:Y.status??V.status,description:Y.description??V.description,error:Y.error??V.error,isBackgrounded:Y.is_backgrounded??V.isBackgrounded,endTime:Y.end_time??V.endTime});return{active:Q?$.active.map((V)=>V.id===Z.task_id?H(V):V):$.active,pending:W?$.pending.map((V)=>V.id===Z.task_id?H(V):V):$.pending}}return $}function c5($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function p5($,Z,J=Date.now()){let Y=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Q)=>Q.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Q)=>Q.id!==Z.task_id)};if($.active.some((Q)=>Q.id===Z.task_id))return{active:$.active.map((Q)=>Q.id===Z.task_id?{...Q,status:Y,usage:Z.usage??Q.usage,summary:Z.summary??Q.summary,endTime:Q.endTime??J}:Q),pending:$.pending};return $}function I9($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>eK){J=Y+1;break}return J===0?$:$.slice(J)}function $B($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return J2(J(Z?.command))||"(空命令)";case"Read":return J(Z?.file_path);case"Edit":return J(Z?.file_path);case"Write":return J(Z?.file_path);case"Grep":return`"${J(Z?.pattern)}" in ${J(Z?.path??".")}`;case"Glob":return`"${J(Z?.pattern)}"`;case"Task":return J(Z?.description);case"WebSearch":return`"${J(Z?.query)}"`;default:return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}function ZB($,Z){let Y=((typeof $==="string"?$:Array.isArray($)?$.map((Q)=>typeof Q?.text==="string"?Q.text:JSON.stringify(Q)).join(`
95
+ `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Y.slice(0,80)}`:Y.slice(0,80)}function u5($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!W&&!H)return $;let V=(z)=>z.map((X)=>X.toolUseId===Z?{...X,steps:I9([...X.steps,{toolUseId:J,tool:Y,brief:`${Y} ${$B(Y,Q)}`.trim()}])}:X);return{active:W?V($.active):$.active,pending:H?V($.pending):$.pending}}function l5($,Z,J,Y,Q,W){let H=$.active.some((X)=>X.id===Z),V=$.pending.some((X)=>X.id===Z);if(!H&&!V)return $;let z=(X)=>X.map((G)=>{if(G.id!==Z)return G;if(Q==="started")return{...G,steps:I9([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()}])};let K=!1,B=G.steps.map((L)=>{if(K||L.toolUseId!==J)return L;return K=!0,{...L,brief:W?`${L.brief} ${W}`:L.brief}});if(!K&&W)B.push({toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()});return{...G,steps:I9(B)}});return{active:H?z($.active):$.active,pending:V?z($.pending):$.pending}}function i5($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!W&&!H)return $;let V=(z)=>z.map((X)=>{if(X.toolUseId!==Z)return X;let G=!1,K=X.steps.map((B)=>{if(G||B.toolUseId!==J)return B;return G=!0,{...B,brief:`${B.brief} → ${ZB(Y,Q)}`}});return{...X,steps:I9(K)}});return{active:W?V($.active):$.active,pending:H?V($.pending):$.pending}}function f5($){if(!$||$<0)return"0s";let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let J=Math.floor(Z/60);if(J<60)return`${J}m${Z%60}s`;return`${Math.floor(J/60)}h${J%60}m`}function lY($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let W of QB)if(Z<W.limit)return{label:W.label,nextDelayMs:W.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${(Y+1)*10}m+`,nextDelayMs:Q-Z}}function p0($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=v5){let Y=Math.floor((J-v5)/pY),Q=v5+(Y+1)*pY;return{label:`${10+Y*5}m+`,nextDelayMs:Q-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:uY}}return lY($)}function WB($){return $.subagentType??$.workflowName??YB[$.type]}function h5($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function HB($,Z,J="bucket"){let Y=(Q)=>p0(Q,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Y(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Y(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${f5(h5($))}`;case"failed":return`❌ 失败 ${f5(h5($))}`;case"killed":return`\uD83D\uDC80 已终止 ${f5(h5($))}`}}function iY($){let Z=$.filter((Y)=>!o$(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function g9($){return`\uD83E\uDDED 后台任务 · ${iY($)}`}function VB($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(o$($)&&$.summary)Z.push(`\uD83D\uDCDD ${$.summary.slice(0,400)}`,"");for(let J=0;J<$.steps.length;J++)Z.push(`${J+1}. ${$.steps[J].brief}`);return e(Z.length>0?Z.join(`
96
+ `):"_(暂无执行记录)_")}function H2($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:H4.panel($.id),header:{title:{tag:"plain_text",content:`${JB[$.type]} ${WB($)} · ${$.description||"(无描述)"} — ${HB($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:H4.body($.id),content:VB($)}]}}function d5($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:g9($)}},body:{elements:$.map((Y)=>H2(Y,Z,J))}}}function m9($,Z=Date.now(),J="bucket"){let Y=$.filter(o$);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>H2(Q,Z,J))}}}function n5(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var H4,eK=1000,JB,YB,QB,uY=1000,v5=600000,pY=300000;var a5=T(()=>{C$();b9();H4={panel:($)=>`bg_${mY($)}`,body:($)=>`bgb_${mY($)}`};JB={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},YB={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};QB=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as zB}from"node:events";import{join as XB,isAbsolute as GB,extname as _B,basename as KB}from"node:path";import{readFile as BB}from"node:fs/promises";function AB($){if($.length>=8&&$.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if($.length>=3&&$[0]===255&&$[1]===216&&$[2]===255)return"image/jpeg";let Z=$.subarray(0,12).toString("ascii");if(Z.startsWith("GIF87a")||Z.startsWith("GIF89a"))return"image/gif";if($.length>=12&&Z.startsWith("RIFF")&&Z.slice(8,12)==="WEBP")return"image/webp";throw Error("DSH image input has unsupported or invalid raster bytes")}var c9=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),o5,r5;var dY=T(()=>{P$();L1();e2();I();o5={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};r5=class r5 extends zB{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=c9();lastContextWindow=null;lastContextTokens=null;runtime;ready;models=[];busy=!1;closing=!1;startedAt=0;questionInputs=new Map;frames=new Map;toolInputs=new Map;children=new Set;settledChildren=new Set;childText=new Map;earlyNotifications=[];pendingInputs=0;terminalError=null;failedUnexpectedly=!1;constructor($){super();this.opts=$;this.tokenSourceId=$.tokenSourceId,this.lastModel=$.model,this.lastEffort=$.effort;let Z=$.launch??{kind:"fresh"};B$(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new E9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:XB($.managedSkillPluginPath,"skills")}:{},...$.runtimeOptions}),this.runtime.on("notification",(Y)=>{if(!this.sessionId&&Y.method!=="failure"){this.earlyNotifications.push(Y);return}if(this.terminalError)return;try{this.onNotification(Y)}catch(Q){this.fail(Q)}}),this.runtime.on("failure",(Y)=>this.fail(Y)),this.runtime.on("exit",(Y)=>this.emit("exit",{...Y,expected:Y.expected&&!this.failedUnexpectedly}))}sendInitialize(){this.initializationPromise().catch(($)=>this.fail($))}initializationPromise(){return this.ready??=(async()=>{await this.runtime.initialize();let $=await this.runtime.request("session/open",{cwd:this.opts.workDir,model:this.opts.model,effort:this.opts.effort,launch:this.opts.launch??{kind:"fresh"},developerInstructions:this.opts.developerInstructions??"",allowDelegation:this.opts.allowDelegation!==!1,...this.opts.profile?.tools?{allowedTools:this.opts.profile.tools.split(",").map((Z)=>{let J=Z.trim();return Object.keys(o5).find((Y)=>o5[Y]===J)??J})}:{}});if(typeof $.sessionId!=="string"||!Array.isArray($.models))throw Error("invalid DSH session/open response");this.sessionId=$.sessionId,this.models=$.models,this.lastContextWindow=this.models.find((Z)=>Z.model===this.lastModel)?.contextWindow??null,this.emit("init",{session_id:this.sessionId});for(let Z of this.earlyNotifications.splice(0))this.onNotification(Z)})()}isAlive(){return this.runtime.isAlive()}isConversationResumable(){return this.sessionId!==null}kill($){return this.closing=!0,this.runtime.close($)}sendUserText($,Z=[]){if(!this.isAlive()||this.closing)throw Error("DSH process is closed");if(Z.some((J)=>!GB(J)))throw Error("DSH file inputs must use absolute paths");if(this.terminalError)throw this.terminalError;this.pendingInputs++,this.initializationPromise().then(async()=>{let J=[{type:"text",text:[$,...Z.map((W)=>`[file: ${W}]`)].join(`
97
+ `)}],Y=new Set([...Z,...Array.from($.matchAll(/\[file: ([^\]\r\n]+)\]/g),(W)=>W[1])]),Q=new Set([".png",".jpg",".jpeg",".webp",".gif"]);for(let W of Y){if(!Q.has(_B(W).toLowerCase()))continue;let H=await BB(W);J.push({type:"image",mediaType:AB(H),name:KB(W),data:H.toString("base64")})}await this.runtime.request("session/prompt",{mode:"auto",content:J}),this.pendingInputs--}).catch((J)=>this.fail(J))}sendInterrupt(){this.runtime.request("session/cancel").catch(($)=>this.fail($))}sendPermissionResponse($,Z,J){let Y=String($),Q=this.questionInputs.get(Y);if(!Q)throw Error(`unknown DSH question: ${Y}`);let W=J?.updatedInput?.answers,H=Z==="allow"?Q.map((V)=>{let z=W?.[V.question];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${V.question}`);let X=V.options?.find((G)=>G.label===z);return{id:V.id,selected:X?[z]:[],...X?{}:{custom:z}}}):void 0;this.runtime.request("question/answer",{id:Y,answers:H,...Z==="deny"?{error:J?.denyMessage??"User declined the question"}:{}}).then(()=>{this.questionInputs.delete(Y),this.emit("tool_result",{tool_use_id:Y,content:JSON.stringify({answers:H}),is_error:Z==="deny",parentToolUseId:null})}).catch((V)=>this.fail(V))}sendHookResponse(){throw Error("DSH does not issue hook callback requests")}async listModels(){return await this.runtime.initialize(),this.models=await this.runtime.request("model/list",{models:[this.lastModel??this.opts.model]}),this.models.map(($)=>({id:$.model,model:$.model,displayName:$.display,description:"DeepSeek Harness",hidden:!1,isDefault:$.isDefault,defaultReasoningEffort:$.defaultEffort,supportedReasoningEfforts:$.efforts.map((Z)=>({reasoningEffort:Z,description:""}))}))}async setModelSettings($,Z){if(!K$(Z))throw Error(`invalid DSH effort: ${Z}`);if(await this.initializationPromise(),await this.runtime.request("session/model",{model:$,effort:Z}),!this.busy)this.lastModel=$,this.lastEffort=Z}async compactThread(){if(await this.initializationPromise(),await this.runtime.request("session/compact",{},null)===null)throw new q1}fail($){let Z=$ instanceof Error?$:Error(String($));if(this.terminalError)return;this.failedUnexpectedly=!this.closing,this.terminalError=Z,this.emit("error",Z);for(let J of this.children){if(this.settledChildren.has(J))continue;this.settledChildren.add(J),this.emit("bg_task_settled",{task_id:J,status:"failed",summary:Z.message})}if(this.busy||this.pendingInputs>0)this.busy=!1,this.lastResult={...c9(),is_error:!0,subtype:"error"},this.emit("result",{errors:[Z.message],error:Z.message,...this.lastResult});this.kill().catch((J)=>this.emit("error",J))}onNotification({method:$,params:Z}){let J=Z.sessionId!==this.sessionId;switch($){case"failure":this.fail(Error(Z.message));return;case"agent.error":this.emit("error",Error(Z.message));return;case"subagent.started":this.children.add(Z.sessionId),this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});return;case"subagent.disposed":if(this.children.has(Z.sessionId)&&!this.settledChildren.has(Z.sessionId))this.emit("bg_task_settled",{task_id:Z.sessionId,status:"stopped",summary:this.childText.get(Z.sessionId)??""});this.children.delete(Z.sessionId),this.settledChildren.delete(Z.sessionId),this.childText.delete(Z.sessionId);for(let Y of this.frames.keys())if(Y.startsWith(`${Z.sessionId}:`))this.frames.delete(Y);return;case"session.status":return;case"question":{this.questionInputs.set(Z.id,Z.questions);let Y={questions:Z.questions.map((Q)=>({...Q,question:Q.detail?`${Q.question}
98
+
99
+ ${Q.detail}`:Q.question}))};this.questionInputs.set(Z.id,Y.questions),this.emit("tool_use",{id:Z.id,name:"AskUserQuestion",input:Y,parentToolUseId:null}),this.emit("can_use_tool",{request_id:Z.id,tool_use_id:Z.id,tool_name:"AskUserQuestion",input:Y});return}case"question.cancelled":this.questionInputs.delete(Z.id),this.emit("tool_result",{tool_use_id:Z.id,content:"Question cancelled",is_error:!0,parentToolUseId:null});return;case"assistant.frame":{let Y=Z.frame,Q=`${Z.sessionId}:${Y.attemptId}`;if(Y.type==="start"){this.frames.set(Q,{revision:Y.revision,nextIndex:0});return}let W=this.frames.get(Q);if(!W||W.revision+1!==Y.revision||W.nextIndex!==Y.index)throw Error("DSH assistant stream sequence mismatch");if(W.revision=Y.revision,Y.type==="end"){if(this.frames.delete(Q),!J)this.emit("assistant_block_stop",{parentToolUseId:null});return}if(Y.type!=="chunk")throw Error(`unknown DSH assistant frame: ${Y.type}`);W.nextIndex++;let H=Y.chunk;if(H.type==="text-delta"){if(J)this.childText.set(Z.sessionId,(this.childText.get(Z.sessionId)??"")+H.text);this.emit("assistant_text",{text:H.text,parentToolUseId:J?Z.sessionId:null})}else if(H.type==="block-end"&&H.block.type==="text"&&!J)this.emit("assistant_block_stop",{parentToolUseId:null});else if(H.type==="usage"&&!J)this.observeUsage(H.usage);return}case"session.event":{let Y=Z.event,Q=Y.data;if(!Y||!Q||typeof Y.type!=="string")throw Error("invalid DSH session event");if(Y.type==="turn/start"&&!J)this.busy=!0,this.startedAt=Date.now(),this.lastUsage=null,this.lastResult=c9(),this.emit("scheduled_turn_input",{text:"DeepSeek Harness 继续执行",promptId:`dsh-turn-${Q.turn}`}),this.emit("turn_started",{turn_id:String(Q.turn),thread_id:this.sessionId});else if(Y.type==="turn/start"&&J&&this.settledChildren.delete(Z.sessionId))this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});else if(Y.type==="request/header"&&!J&&Q.header?.config)this.lastModel=Q.header.config.model,this.lastEffort=Q.header.config.reasoningEffort,this.lastContextWindow=this.models.find((W)=>W.model===this.lastModel)?.contextWindow??null;else if(Y.type==="tool/call"){let W=JSON.parse(Q.arguments),H=o5[Q.name]??Q.name;if(["read","write","edit"].includes(Q.name)&&W.path)W.file_path=W.path;this.toolInputs.set(Q.callId,{name:H,input:W}),this.emit("tool_use",{id:Q.callId,name:H,input:W,parentToolUseId:J?Z.sessionId:null})}else if(Y.type==="tool/result"){let W=Q.message?.content?.[0];if(W?.type!=="tool-result"||typeof W.toolCallId!=="string")throw Error("invalid DSH tool result");this.emit("tool_result",{tool_use_id:W.toolCallId,content:W.content,is_error:W.isError===!0,parentToolUseId:J?Z.sessionId:null}),this.toolInputs.delete(W.toolCallId)}else if(Y.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Q.todos.map((W)=>({step:W.content,status:W.status==="in_progress"?"inProgress":W.status}))});else if(Y.type==="compaction/start"&&!J)this.emit("context_compacted",{threadId:this.sessionId,phase:"start",sourceType:"dsh"});else if(Y.type==="compaction/end"&&!J)if(Q.error)this.emit("error",Error(`DSH compaction: ${Q.error}`));else this.emit("context_compacted",{threadId:this.sessionId,phase:"end",sourceType:"dsh"});else if(Y.type==="goal/change"&&!J)if(Q.operation==="clear")this.emit("thread_goal_cleared",{threadId:this.sessionId});else this.emit("thread_goal_updated",{threadId:this.sessionId,objective:Q.goal.objective,status:Q.goal.phase,tokenBudget:null,tokensUsed:Number.NaN,timeUsedSeconds:Number.NaN});else if(Y.type==="turn/end"&&J&&this.children.has(Z.sessionId))this.settledChildren.add(Z.sessionId),this.emit("bg_task_settled",{task_id:Z.sessionId,status:Q.reason.kind==="completed"?"completed":Q.reason.kind==="aborted"?"stopped":"failed",summary:this.childText.get(Z.sessionId)??""}),this.childText.delete(Z.sessionId);return}case"settled":{if(J)throw Error("DSH settled a different root session");this.busy=!1;let Y=Z.event,Q=Y.data.reason;this.lastCompletedTurnId=String(Y.seq),this.lastResult={...c9(),duration_ms:Date.now()-this.startedAt,num_turns:1,usage:this.lastUsage,subtype:Q.kind,is_error:Q.kind!=="completed"},this.emit("result",{...this.lastResult,...Q.kind!=="completed"?{error:Q.error?.message??`DSH turn ended: ${Q.kind}`,errors:[Q.error?.message??`DSH turn ended: ${Q.kind}`]}:{},checkpoint:{provider:"dsh",kind:"event",id:String(Y.seq),source:{provider:"dsh",sessionId:this.sessionId,cwd:this.opts.workDir}}});return}default:_(`dsh: unknown notification ${$}`)}}observeUsage($){if(!Number.isFinite($.inputTokens)||!Number.isFinite($.outputTokens))throw Error("invalid DSH token usage");let Z={input_tokens:$.inputTokens,output_tokens:$.outputTokens,total_tokens:$.totalTokens,cache_read_input_tokens:$.cacheReadTokens,cache_creation_input_tokens:$.cacheWriteTokens,reasoning_output_tokens:$.reasoningTokens};this.lastUsage=Z;let J={...this.lastTotalUsage};for(let[Y,Q]of Object.entries(Z))if(Q!==void 0){let W=Y;J[W]=(J[W]??0)+Q}this.lastTotalUsage=J,this.lastContextTokens=$.inputTokens+($.cacheReadTokens??0)+($.cacheWriteTokens??0),this.emit("token_usage",{usage:Z,totalUsage:J,contextWindow:this.lastContextWindow,threadId:this.sessionId})}}});function u0($){return $.startsWith("claude:")?$:`claude:${$}`}function t5($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(f.claude.models,Z))return f.claude.models[Z]?.model?.trim()||"opus";return Z}var nY=T(()=>{x$()});import{existsSync as qB,readFileSync as LB}from"node:fs";function s5(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:FJ}function z4(){if(V4!==null)return V4;try{V4=qB(s5())?JSON.parse(LB(s5(),"utf8")):{}}catch($){_(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),V4={}}return V4??{}}function PB(){try{t(s5(),z4())}catch($){_(`context-window-observe: cache write MISS (${$?.message??$})`)}}function e5($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function aY($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=e5($,Z),Q=z4()[Y];if(Q===J)return;z4()[Y]=J,PB(),_(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function p9($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=z4()[e5($,Z)];return J!=null&&J<jB?Z:`${Z}[1m]`}function V2($,Z){return z4()[e5($,Z)]}var jB=1e6,V4=null;var X4=T(()=>{H$();I();f$()});var GQ={};P0(GQ,{toolsFromProfile:()=>zQ,settingSourcesFromProfile:()=>VQ,resolveClaudeExecutableConfig:()=>Q3,resetClaudeContextWindowCache:()=>OB,readProjectMcpServers:()=>XQ,readLastCallUsageFromTranscript:()=>QQ,claudeTranscriptPath:()=>d9,claudeTranscriptDir:()=>i9,claudeManagedSkillOptions:()=>JQ,buildClaudeSpawnPath:()=>YQ,assertClaudeCodeAvailable:()=>Y3,ClaudeAgentProcess:()=>n9,CLAUDE_PERMISSION_MODE:()=>HQ});import{existsSync as eY,readFileSync as $Q}from"node:fs";import{homedir as l9}from"node:os";import{spawn as DB}from"cross-spawn";import{delimiter as oY,join as D1}from"node:path";import{EventEmitter as MB}from"node:events";function JQ($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function FB($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function RB($){let Z=DB($.command,$.args,{cwd:$.cwd,env:$.env,shell:!1,signal:$.signal,stdio:["pipe","pipe","ignore"],windowsHide:!0});if(!Z.stdin||!Z.stdout)throw Z.kill(),Error("failed to open stdio for Claude Code Windows shell shim");return Z}function Y3(){Q3(),r6("claude","@anthropic-ai/claude-agent-sdk")}function Q3($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?f.claude.bin:$.configuredBin;if(J){if(!($.exists??eY)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&FB(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:RB,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function YQ(){if(process.platform==="win32")return process.env.PATH??"";let $=[D1(l9(),".local","npm-global","bin"),D1(l9(),".local","bin"),D1(l9(),".bun","bin"),...(process.env.PATH??"").split(oY),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(oY)}function UB($){let Z=Z2($);if(!Z)return null;let J=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if((Z.total_tokens??J)<=0)return null;if(Z.total_tokens==null)Z.total_tokens=J;return Z}function rY($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function i9($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||D1(l9(),".claude");return D1(J,"projects",Z)}function d9($,Z){return D1(i9($),`${Z}.jsonl`)}function QQ($){let Z;try{Z=$Q($,"utf8")}catch{return null}let J=Z.split(`
100
+ `);for(let Y=J.length-1;Y>=0;Y--){let Q=J[Y].trim();if(!Q)continue;try{let W=JSON.parse(Q);if(W?.type==="assistant"&&W?.message?.usage){let H=W.message.usage;if((H.input_tokens??0)+(H.cache_read_input_tokens??0)+(H.cache_creation_input_tokens??0)+(H.output_tokens??0)>0)return H}}catch{}}return null}function tY($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function OB(){Z3.clear()}function TB($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Q of Object.values($)){if(!Q||typeof Q!=="object")continue;let W=Q;Z.input_tokens=(Z.input_tokens??0)+z2(W.inputTokens??W.input_tokens),Z.output_tokens=(Z.output_tokens??0)+z2(W.outputTokens??W.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+z2(W.reasoningOutputTokens??W.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+z2(W.cacheReadInputTokens??W.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+z2(W.cacheCreationInputTokens??W.cache_creation_input_tokens);let H=z2(W.contextWindow??W.context_window);if(H>0)J=Math.max(J??0,H)}let Y=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Y<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Y,{usage:Z,contextWindow:J}}function u9($){return{...$}}function $3($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function NB($,Z){let J=$?{...$}:{},Y=(Q)=>{let W=Z[Q];if(typeof W!=="number"||!Number.isFinite(W))return;J[Q]=(J[Q]??0)+W};return Y("total_tokens"),Y("input_tokens"),Y("output_tokens"),Y("reasoning_output_tokens"),Y("cache_creation_input_tokens"),Y("cache_read_input_tokens"),J}function z2($){return typeof $==="number"&&Number.isFinite($)?$:0}function WQ($){if(typeof $==="string")return $;if(Array.isArray($))return $.map((Z)=>{if(typeof Z==="string")return Z;if(Z&&typeof Z==="object"&&typeof Z.text==="string")return Z.text;return JSON.stringify(Z)}).join(`
101
+ `);return $==null?"":JSON.stringify($,null,2)}function EB($){let Z=WQ($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Y=J.map((Q)=>{if(typeof Q==="string")return Q;if(Q&&typeof Q==="object"&&typeof Q.text==="string")return Q.text;return JSON.stringify(Q)}).filter(Boolean);if(Y.length>0)return Y.join(`
102
+ `)}}catch{}return Z}function SB($){return`server_tool:${$}`}function kB($){let Z=$.match(/Built-in Tool:\s*([A-Za-z0-9_.:-]+)/)?.[1];if(!Z)return null;let J=$.match(/\*\*Input:\*\*\s*```(?:json)?\s*([\s\S]*?)```/)?.[1]?.trim();if(!J)return{name:Z,input:{}};try{return{name:Z,input:JSON.parse(J)}}catch{return{name:Z,input:{raw:J}}}}function xB($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function CB($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[g0];return{id:u0($.value),model:u0($.value),displayName:$.displayName||u0($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(g0)?g0:Z[0]}}function VQ($){if(!$?.settingSources)return[...sY];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...sY]}function zQ($){if(!$?.tools)return{type:"preset",preset:"claude_code"};let Z=$.tools.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:{type:"preset",preset:"claude_code"}}function XQ($){let Z=D1($,".mcp.json"),J;try{J=$Q(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")_(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Y}`);return}try{let Y=JSON.parse(J);if(Y&&typeof Y==="object"&&Y.mcpServers&&typeof Y.mcpServers==="object")return Y.mcpServers;_(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){_(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function bB($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>yB(Y)).filter((Y)=>Y!==null)}function yB($){let Z=$&&typeof $==="object"?$:{question:$},J=J3(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=wB(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Y,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function wB($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Y=J,Q=J3(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let W=J3(Y.description,Y.detail,Y.preview);Z.push(W?{label:Q,description:W}:{label:Q})}return Z}function J3(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var ZQ,Z3,HQ="default",sY,n9;var G4=T(()=>{t1();x$();I();P$();nY();X4();ZQ=class ZQ{items=[];waiters=[];closed=!1;push($){if(this.closed)throw Error("input stream is closed");let Z=this.waiters.shift();if(Z)Z({value:$,done:!1});else this.items.push($)}close(){if(this.closed)return;this.closed=!0;while(this.waiters.length)this.waiters.shift()?.({value:void 0,done:!0})}abort(){this.items=[],this.close()}[Symbol.asyncIterator](){return this}next(){if(this.items.length>0)return Promise.resolve({value:this.items.shift(),done:!1});if(this.closed)return Promise.resolve({value:void 0,done:!0});return new Promise(($)=>this.waiters.push($))}};Z3=new Map;sY=["project","local"];n9=class n9 extends MB{provider="claude";tokenSourceId;opts;input=new ZQ;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;queryStart;pendingPermissions=new Map;requestCounter=0;cumulativeUsageFromResults=null;turnActive=!1;emittedToolUseIds=new Set;emittedToolResultIds=new Set;pendingServerToolInputs=[];sessionId=null;lastAssistantUuid=null;lastModel=null;lastEffort=null;lastThinkingTokens=null;lastUsage=null;lastTotalUsage=null;lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1};lastContextWindow=null;lastContextTokens=null;constructor($){super();this.on("error",()=>{}),this.exitPromise=new Promise((Z)=>{this.resolveExit=Z}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.lastEffort=$.effort,this.lastModel=$.model?u0($.model):null}sendInitialize(){if(this.started)return;this.started=!0,this.queryStart=this.initializeQuery().catch(($)=>{this.emit("error",$ instanceof Error?$:Error(String($))),this.finishExit(1,null)})}async initializeQuery(){let $=t5(this.opts.model),Z=this.opts.profile;if(Z)_(`claude-agent-process: project profile active — settingSources=${Z.settingSources??"-"} strictMcp=${Z.strictMcp??!1} tools=${Z.tools??"-"} loadProjectMcp=${Z.loadProjectMcp??!0}`);let J=this.opts.settingSources??VQ(Z),Y=JQ(J,this.opts.managedSkillPluginPath),Q=zQ(Z),W=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?XQ(this.opts.workDir):void 0;try{let V=Q3(),{query:z}=await dJ();if(!this.alive||this.abortController.signal.aborted)return;let X={...process.env,PATH:YQ(),...f.claude.env,...this.opts.hostEnv??{}},G=this.opts.transformEnv?this.opts.transformEnv(X):X;if(this.opts.effort==="default")G.CLAUDE_CODE_EFFORT_LEVEL="unset";_(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${V.description}`),this.query=z({prompt:this.input,options:{cwd:this.opts.workDir,abortController:this.abortController,...$?{model:$}:{},effort:this.opts.effort==="default"?"high":this.opts.effort,resume:this.opts.resumeSessionId,...this.opts.resumeSessionAt?{resumeSessionAt:this.opts.resumeSessionAt}:{},...this.opts.forkSession?{forkSession:!0}:{},...V.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:V.pathToClaudeCodeExecutable}:{},...V.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:V.spawnClaudeCodeProcess}:{},permissionMode:HQ,env:G,settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...W?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(K,B,L)=>this.canUseTool(K,B,L),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(K)=>{let B=K.trim();if(B)_(`claude-agent-process[stderr]: ${B}`)}}})}catch(V){let z=V instanceof Error?V:Error(String(V));this.emit("error",z),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){_("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
103
+
104
+ `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let Q=Y instanceof Error?Y:Error(String(Y));_(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>_(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){_(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Y.cleanup?.(),Z==="allow")Y.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Y.resolve({behavior:"deny",message:J?.denyMessage??""})}sendHookResponse($,Z={}){_("claude-agent-process: sendHookResponse ignored; hooks are handled by SDK callbacks")}isAlive(){return this.alive}async kill($=5000){if(!this.alive)return;if(this.expectedExit=!0,this.denyPendingPermissions("claude process is stopping"),this.input.abort(),!this.started||!this.query){this.finishExit(null,null);return}let Z=null;try{this.query.close()}catch(J){Z=J instanceof Error?J:Error(String(J))}if(!this.abortController.signal.aborted)this.abortController.abort(Z??Error("claude process shutdown requested"));if(!await this.waitForExit($)){let J=Error(`claude Agent SDK query did not exit within ${$}ms after close/abort`,Z?{cause:Z}:void 0);throw _(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw _(`claude-agent-process: kill failed: ${J.message}`),J}}async listModels(){if(!this.started)this.sendInitialize();if(await this.queryStart,!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");return(await this.query.supportedModels()).map(CB)}async setModelSettings($,Z){let J=t5($);if(!T$(Z))throw Error(`invalid Claude effort: ${String(Z)}`);if(this.opts.effort==="default"!==(Z==="default"))throw Error("effort 参数模式改变,需要使用新的启动环境恢复会话");if(!this.started)this.sendInitialize();if(await this.queryStart,!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");if(J)await this.query.setModel(J);await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null}),this.opts.model=$,this.opts.effort=Z,this.lastModel=J?u0($):"claude:default",this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Y=()=>{this.off("context_compacted",Q),this.off("assistant_text",W),this.off("exit",H),this.off("error",V)},Q=()=>{if(J)return;J=!0,Y(),$()},W=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new q1)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},V=(z)=>{if(J)return;J=!0,Y(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Q),this.on("assistant_text",W),this.once("exit",H),this.once("error",V)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=bB(Z);if(Y.length===0)return _("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},W=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||W,V={request_id:W,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},z=new Promise((X)=>{let G=(B)=>{J.signal.removeEventListener("abort",K),X(B)},K=()=>{if(!this.pendingPermissions.delete(W))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(W,{kind:"dialog",resolve:G,request:V})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",V),z}async readLoop($){try{for await(let Z of $)this.handleMessage(Z);this.finishExit(null,null)}catch(Z){let J=Z instanceof Error?Z:Error(String(Z));if(this.expectedExit&&this.abortController.signal.aborted){_(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}_(`claude-agent-process: read loop failed: ${J.message}`),this.emit("error",J),this.finishExit(1,null)}}finishExit($,Z){if(!this.alive)return;this.alive=!1,this.turnActive=!1,this.denyPendingPermissions("claude process exited"),this.resolveExit(),_(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:_(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=u0($.model);this.lastEffort=this.opts.effort,this.emit("init",{session_id:this.sessionId,raw:$});return;case"session_state_changed":if($.state==="running"&&!this.turnActive)this.turnActive=!0,this.lastThinkingTokens=null,this.lastAssistantUuid=null,this.emit("turn_started",{turn_id:$.uuid,thread_id:this.sessionId});else if($.state==="idle")this.turnActive=!1;return;case"compact_boundary":this.emit("context_compacted",{threadId:$.session_id??this.sessionId??void 0,sessionId:$.session_id??this.sessionId??void 0,itemId:$.uuid,phase:"event",sourceMethod:"claude_agent_sdk",sourceType:"compact_boundary",preTokens:$.compact_metadata?.pre_tokens,trigger:$.compact_metadata?.trigger});return;case"api_retry":_(`claude-agent-process: api retry attempt=${$.attempt}/${$.max_retries} status=${$.error_status} error=${$.error}`);return;case"thinking_tokens":if(typeof $.estimated_tokens!=="number"||!Number.isFinite($.estimated_tokens)||$.estimated_tokens<0){_("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":_(`claude-agent-process: permission denied ${$.tool_name} ${$.tool_use_id}: ${$.message}`);return;case"task_started":this.emit("bg_task_started",{task_id:String($.task_id??""),tool_use_id:typeof $.tool_use_id==="string"?$.tool_use_id:void 0,task_type:typeof $.task_type==="string"?$.task_type:void 0,description:String($.description??""),subagent_type:typeof $.subagent_type==="string"?$.subagent_type:void 0,workflow_name:typeof $.workflow_name==="string"?$.workflow_name:void 0,prompt:typeof $.prompt==="string"?$.prompt:void 0});return;case"task_progress":this.emit("bg_task_progress",{task_id:String($.task_id??""),description:typeof $.description==="string"?$.description:void 0,subagent_type:typeof $.subagent_type==="string"?$.subagent_type:void 0,usage:$.usage,last_tool_name:typeof $.last_tool_name==="string"?$.last_tool_name:void 0,summary:typeof $.summary==="string"?$.summary:void 0});return;case"task_updated":this.emit("bg_task_updated",{task_id:String($.task_id??""),patch:$.patch&&typeof $.patch==="object"?$.patch:{}});return;case"task_notification":if(typeof $.task_id!=="string"||!$.task_id){_("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){_(`claude-agent-process: task_notification unknown status=${String($.status)} task=${$.task_id}`);return}this.emit("bg_task_settled",{task_id:$.task_id,tool_use_id:typeof $.tool_use_id==="string"?$.tool_use_id:void 0,status:$.status,summary:typeof $.summary==="string"?$.summary:void 0,usage:$.usage});return;default:_(`claude-agent-process: unhandled system subtype=${String($.subtype??"unknown")}`);return}}handleAssistantMessage($){if(!$.parent_tool_use_id)this.lastThinkingTokens=null;let Z=$.message,J=typeof $.parent_tool_use_id==="string"&&$.parent_tool_use_id?$.parent_tool_use_id:null;if(!J&&typeof $.uuid==="string")this.lastAssistantUuid=$.uuid;if(typeof Z?.model==="string"&&Z.model)this.lastModel=u0(Z.model);let Y=Array.isArray(Z?.content)?Z.content:[];for(let Q of Y){if(!Q||typeof Q!=="object")continue;if(Q.type==="text"&&typeof Q.text==="string"&&Q.text.length>0){let W=kB(Q.text);if(W){if(this.pendingServerToolInputs.push(W),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(xB(Q.text))continue;let H=$.uuid??Z?.id;this.emit("assistant_text",{uuid:H,text:Q.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:H,parentToolUseId:J})}else if(Q.type==="tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Q.name,Q.input??{},J);else if(Q.type==="server_tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,SB(Q.name),{tool:Q.name,input:this.serverToolInput(Q.name,Q.input??{})},J);else if(Q.type==="tool_result"&&typeof Q.tool_use_id==="string")this.emitToolResultOnce(Q.tool_use_id,EB(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())_(`claude-agent-process: tool_use ${$} has an empty name`),Z="MISS";this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Y})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Y=this.pendingServerToolInputs.findIndex((Q)=>Q.name===$);if(Y>=0){let[Q]=this.pendingServerToolInputs.splice(Y,1);return Q.input}return J}emitToolResultOnce($,Z,J,Y){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Y})}handleUserMessage($){let Z=$.message?.content;if($.isMeta===!0&&$.promptSource==="sdk"&&typeof Z==="string"&&Z.trim())this.emit("scheduled_turn_input",{text:Z,promptId:typeof $.promptId==="string"&&$.promptId?$.promptId:null});let J=Array.isArray(Z)?Z:[];for(let Y of J){if(!Y||typeof Y!=="object")continue;if(Y.type!=="tool_result"||typeof Y.tool_use_id!=="string")continue;let Q=$.tool_use_result,W=WQ(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
105
+ `):"",V=W||H;this.emitToolResultOnce(Y.tool_use_id,V,Y.is_error===!0||Q?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=UB($.usage),J=$.modelUsage??$.model_usage,Y=TB(J);if(!Z&&!Y.usage)_(`claude-agent-process: result usage missing rootKeys=${$3($).join(",")||"-"} usageKeys=${$3($.usage).join(",")||"-"} modelUsageKeys=${$3(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=u9(Y.usage),this.lastTotalUsage=u9(Y.usage);else if(Z)this.cumulativeUsageFromResults=NB(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=u9(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?u9(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let V=tY(this.opts.model,this.tokenSourceId);if(Z3.set(V,Y.contextWindow),this.tokenSourceId)for(let[z,X]of Object.entries(J??{})){let G=X?.contextWindow;if(typeof G==="number"&&G>0)aY(this.tokenSourceId,z,G)}}this.lastContextWindow=Z3.get(tY(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=d9(this.opts.workDir,this.sessionId??""),W=QQ(Q);if(this.lastContextTokens=rY(W)??(eY(Q)?rY(Z):null),this.lastTotalUsage||this.lastUsage)this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:this.sessionId??void 0,turnId:$.uuid});let H=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof $.duration_ms==="number"?$.duration_ms:null,num_turns:typeof $.num_turns==="number"?$.num_turns:1,usage:this.lastUsage,subtype:H,is_error:$.is_error===!0||H!=="success"},this.emit("result",{subtype:H,is_error:this.lastResult.is_error,...this.lastResult.is_error?{error:Array.isArray($.errors)&&$.errors.length?$.errors.map(String).join(`
106
+ `):String($.result??$.error??$.api_error_message??H)}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,checkpoint:!this.lastResult.is_error&&this.lastAssistantUuid&&this.sessionId?{provider:"claude",kind:"assistant-message",id:this.lastAssistantUuid,source:{provider:"claude",sessionId:this.sessionId,cwd:this.opts.workDir}}:null})}failTurnStart($){this.turnActive=!1,this.lastAssistantUuid=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"claude_turn_start_failed",is_error:!0},this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:$.message})}}});var AQ={};P0(AQ,{waitForTokenSourceModelRefresh:()=>A2,tokenSourceRuntimeModels:()=>G2,tokenSourceRuntimeModel:()=>_0,tokenSourceProcessRevision:()=>_2,tokenSourceFactories:()=>K2,setDefaultTokenSource:()=>H3,scrubDshEnv:()=>_4,scrubAnthropicEnv:()=>G0,resetTokenSourceRegistry:()=>V3,registerTokenSourceFactory:()=>N$,registerTokenSource:()=>W3,refreshAllTokenSourceModels:()=>B4,pendingTokenSourceModelRefresh:()=>B2,listTokenSourcesByAgent:()=>BQ,listTokenSources:()=>O0,listEnabledTokenSourcesByAgent:()=>o9,getTokenSourceForAccount:()=>V$,getTokenSource:()=>K0});function G0($){let Z={...$};for(let J of fB)delete Z[J];return Z}function _4($){let Z=G0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function G2($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function _0($,Z){let J=(Y)=>$.agent==="claude"?Y?.replace(/\[1m\]$/,""):Y;return G2($).find((Y)=>J(Y.model)===J(Z))}function _2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function N$($){_Q.set($.kind,$)}function K2(){return[..._Q.values()]}function W3($,Z){if(K4.set($.id,$),Z?.default||a9===null)a9=$.id}function K0($){return $?K4.get($):void 0}function V$($,Z="default"){let J=K0($);return J?.forAccount?J.forAccount(Z):J}function O0(){return[...K4.values()]}function BQ($){return O0().filter((Z)=>Z.agent===$)}function o9($){return BQ($).filter((Z)=>Z.enabled)}function H3($){if(K4.has($))a9=$}function V3(){K4.clear(),a9=null,KQ++}function B4(){let $=KQ;if(X2?.generation===$)return X2.promise;let Z=Promise.allSettled(O0().map(async(J)=>{await J.refreshModels(),_(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(X2?.promise===Z)X2=null});return X2={generation:$,promise:Z},Z}function B2(){return X2?.promise??null}async function A2(){let $;while($=B2())await $}var fB,_Q,K4,a9=null,KQ=0,X2=null;var Y$=T(()=>{I();fB=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL","ANTHROPIC_DEFAULT_FABLE_MODEL","ANTHROPIC_MODEL","ANTHROPIC_SMALL_FAST_MODEL","CLAUDE_CODE_SUBAGENT_MODEL","ANTHROPIC_CUSTOM_HEADERS","CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX","CLAUDE_CODE_USE_FOUNDRY","CLAUDE_CODE_EFFORT_LEVEL"];_Q=new Map;K4=new Map});import{spawn as vB}from"cross-spawn";import{EventEmitter as hB}from"node:events";import{StringDecoder as IB}from"node:string_decoder";import{createHash as gB}from"node:crypto";function LQ($,Z){if(L4.set($,Z),Z.state==="ok")r9.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")r9.delete($)}function jQ($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function mB($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function t9($){if(!$)return null;return{percent:mB($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function cB($){let Z=t9($?.primary),J=t9($?.secondary),Y=(W)=>W?.durationMins!=null&&W.durationMins>0&&W.durationMins<=720,Q=(W)=>W?.durationMins!=null&&W.durationMins>720;if(Y(Z)&&Q(J))return{fiveHour:Z,weekly:J};if(Y(J)&&Q(Z))return{fiveHour:J,weekly:Z};if(Q(Z)&&!J)return{fiveHour:null,weekly:Z};if(Q(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function pB($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,W]of J){let{fiveHour:H,weekly:V}=cB(W);if(!H&&!V)continue;Y.push({limitId:Q,limitName:W?.limitName??null,fiveHour:H,weekly:V,normalModelSlug:W?.normalModelSlug??null,rateLimitReachedType:W?.rateLimitReachedType??null,spendControlReached:W?.spendControlReached??null})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function uB($){if(!$)return"empty";let Z=(J)=>J?`${J.usedPercent??"?"}%/${J.windowDurationMins??"?"}m`:"null";return`limitId=${$.limitId??"null"} name=${$.limitName??"null"} primary=${Z($.primary)} secondary=${Z($.secondary)}`}function PQ($,Z=p){let J=uB($),Y=L4.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],W=Q.filter((H)=>qQ(H.fiveHour,t9($?.primary))&&qQ(H.weekly,t9($?.secondary)));if(Q.length>0&&W.length===0)_(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${J})`);else if($?.limitId&&W.length===1&&W[0].limitId!==$.limitId)_(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${W[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function qQ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function lB($){let Z=new q2({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await jQ(Z.request("account/read",{}),z3))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await UQ(()=>Z.request("account/rateLimits/read",{}));return DQ(Q,Y.planType)}catch(J){return _(`usage: codex app-server usage failed: ${J?.message??J}`),{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function DQ($,Z){let{buckets:J,defaultLimitId:Y}=pB($),Q=J.find((H)=>H.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};let W=Z??$?.rateLimits?.planType??void 0;return Q.fiveHour=T5(W,Q.fiveHour),{state:"ok",subscriptionType:W,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:gB("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:Q.rateLimitReachedType,spendControlReached:Q.spendControlReached,fiveHour:Q.fiveHour,weekly:Q.weekly,buckets:J,defaultLimitId:Q.limitId,resetCredits:Number.isInteger($?.rateLimitResetCredits?.availableCount)&&$.rateLimitResetCredits.availableCount>=0?$.rateLimitResetCredits.availableCount:null,fetchedAt:Date.now()}}function MQ($=p){return L4.get($)??null}function FQ($=p){return r9.get($)??null}function M1($=p){let Z=A4.get($);if(Z)return Z;let J=l0.get($)??0,Y=Promise.resolve().then(()=>lB($)).catch((Q)=>{return _(`usage: ${$} fetch failed: ${Q}`),{state:"network",reason:String(Q)}}).then((Q)=>{if((l0.get($)??0)!==J)return{state:"auth_failed"};return LQ($,Q),Q}).finally(()=>{if(A4.get($)===Y)A4.delete($)});return A4.set($,Y),Y}function s9($,Z=p){let J=q4.get(Z);if(J)return J;let Y=l0.get(Z)??0,Q=UQ(()=>$("account/rateLimits/read",{})).then((W)=>{if((l0.get(Z)??0)!==Y)return null;let H=DQ(W);if((l0.get(Z)??0)===Y)LQ(Z,H);if(H.state!=="ok")_(`usage: refresh from connection: ${H.state==="network"?H.reason:H.state}`);return H}).catch((W)=>{if(_(`usage: refresh from connection failed: ${W?.message??W}`),(l0.get(Z)??0)===Y)L4.delete(Z);return null}).finally(()=>{if(q4.get(Z)===Q)q4.delete(Z)});return q4.set(Z,Q),Q}function RQ($){l0.set($,(l0.get($)??0)+1),L4.delete($),r9.delete($),A4.delete($),q4.delete($)}async function UQ($){let Z=[250,750];for(let J=0;;J++)try{return await jQ($(),z3)}catch(Y){let Q=Y instanceof Error?Y.message:String(Y);if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(Q)||J>=Z.length)throw Y;_(`usage: rate limit request retry ${J+1}/${Z.length}: ${Q}`),await new Promise((H)=>setTimeout(H,Z[J]))}}var z3=1e4,L4,r9,A4,q2,q4,l0;var i0=T(()=>{j1();I();x$();I$();L4=new Map,r9=new Map,A4=new Map;q2=class q2 extends hB{proc;buf="";decoder=new IB("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??p;this.proc=vB($.bin??Q4(),["app-server","--listen","stdio://",...$.args??y.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??y.env(Z,{...process.env,...f.codex.env},!0,$.login)}),this.exitPromise=new Promise((Y)=>{this.resolveExit=Y}),this.proc.stdout.on("data",(Y)=>this.onStdout(Y)),this.proc.stderr.on("data",(Y)=>{let Q=Y.toString().trim();if(Q)_(`usage[codex stderr]: ${Q}`)});let J=(Y)=>{if(!this.alive)return;this.alive=!1;for(let[Q,W]of this.pending)clearTimeout(W.timer),W.reject(Error(`${Y.message}; pending ${W.method} id=${Q}`));this.pending.clear(),this.resolveExit(),this.emit("closed",Y)};this.proc.on("error",(Y)=>J(Error(`codex app-server spawn failed: ${Y.message}`))),this.proc.stdin.on("error",(Y)=>{_(`usage: codex stdin failed: ${Y.message}`),this.emit("protocolError",Y)}),this.proc.on("close",(Y,Q)=>{J(Error(`codex app-server exited code=${Y} signal=${Q}`))})}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
67
107
  `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch{this.emit("protocolError",Error("Codex app-server returned invalid JSON"));continue}if(!Y||typeof Y!=="object"||Array.isArray(Y)){this.emit("protocolError",Error("Codex app-server returned invalid RPC object"));continue}let Q=Object.prototype.hasOwnProperty.call(Y,"id");if(typeof Y.method==="string"){if(!Q)this.emit("notification",Y.method,Y.params);else _(`usage: unsupported Codex server request: ${Y.method}`),this.proc.stdin.write(JSON.stringify({id:Y.id,error:{code:-32601,message:`Unsupported server request: ${Y.method}`}})+`
68
108
  `);continue}if(!Q||!Object.prototype.hasOwnProperty.call(Y,"result")&&!Object.prototype.hasOwnProperty.call(Y,"error")){this.emit("protocolError",Error("Codex app-server returned an incomplete RPC response"));continue}let W=this.pending.get(Y.id);if(!W)continue;if(this.pending.delete(Y.id),clearTimeout(W.timer),Y.error)W.reject(Error(JSON.stringify(Y.error)));else W.resolve(Y.result)}}async initialize($){await this.request("initialize",{clientInfo:{name:$,version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}),await new Promise((Z,J)=>{this.proc.stdin.write(JSON.stringify({method:"initialized"})+`
69
- `,(Y)=>Y?J(Y):Z())})}isAlive(){return this.alive}request($,Z,J=t6){let Y=this.nextId++;return new Promise((Q,W)=>{if(!this.alive){W(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;W(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:W,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
70
- `,(V)=>{if(!V)return;let X=this.pending.get(Y);if(!X)return;this.pending.delete(Y),clearTimeout(X.timer),X.reject(Error(`codex app-server write failed for ${$}: ${V.message}`))})}catch(V){this.pending.delete(Y),clearTimeout(H),W(V instanceof Error?V:Error(String(V)))}})}async close($=2000){if(!this.alive)return;if(this.proc.exitCode!==null||this.proc.signalCode!==null){if(!await this.waitForExit($))throw Error("codex app-server stdio did not close after exit");return}if(!this.proc.kill("SIGTERM"))throw Error("codex app-server rejected SIGTERM");if(await this.waitForExit($))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await this.waitForExit($))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}async waitForExit($){let Z;try{return await Promise.race([this.exitPromise.then(()=>!0),new Promise((J)=>{Z=setTimeout(()=>J(!1),$)})])}finally{if(Z!==void 0)clearTimeout(Z)}}};B4=new Map,u0=new Map});import{existsSync as $B,readFileSync as ZB}from"node:fs";class JQ{deps;constructor($){this.deps=$}blocks(){if(!$B(this.deps.stateFile))return[];let $=JSON.parse(ZB(this.deps.stateFile,"utf8"));if($?.version!==1||!Array.isArray($.blocks)||$.blocks.some((Z)=>typeof Z?.key!=="string"||typeof Z?.identity!=="string"||typeof Z?.meter!=="string"||!Array.isArray(Z?.windows)||Z.windows.some((J)=>!["fiveHour","weekly"].includes(J?.kind)||J.percent!==null&&!Number.isFinite(J.percent)||J.reset!==null&&!Number.isFinite(J.reset))))throw Error("Codex 额度耗尽记录格式无效");return $.blocks}block($,Z){if(!$.usage)throw Error("未读取额度,不能记录耗尽窗口");let J=$.usage.state==="ok"?Z4($.usage,Z):null,Y=["fiveHour","weekly"].flatMap((V)=>{let X=J?.[V];return X?[{kind:V,percent:X.percent,reset:X.resetsAt?.getTime()??null}]:[]}),Q=q6($.usage,Z),W=JSON.stringify([$.identity,Q]),H=this.blocks().filter((V)=>V.key!==W);H.push({key:W,identity:$.identity,meter:Q,windows:Y}),t(this.deps.stateFile,{version:1,blocks:H})}async choose($){$.signal?.throwIfAborted();let Z=this.deps.accounts();if($.preferred){let A=Z.find((P)=>P.id===$.preferred);if(!A)throw Error(`指定 Codex 账号不存在:${$.preferred}`);return{selected:{account:A,identity:`record:${A.id}`,usage:null,state:"manual",score:null,shares:null,remaining:null,hours:null},candidates:[]}}let J=await Promise.all(Z.map(async(A)=>{let P,L=null,j=`record:${A.id}`;if(this.deps.pendingLogin(A.id))P={state:"network",reason:"正在登录"};else try{P=await this.deps.usage(A.id);let N=P.state==="ok"?P.accountFingerprint??this.deps.identity(A.id):null;if(N)j=N;else if(P.state==="ok")L="账号身份 MISS";if(P.state==="ok"&&!L)L=await this.deps.compatible(A.id,$.model,$.effort)}catch(N){P={state:"network",reason:String(N)}}return{account:A,usage:P,identity:j,reason:L}}));$.signal?.throwIfAborted();let Y=$.failedAccountId&&J.find((A)=>A.account.id===$.failedAccountId);if(Y&&Y.usage.state==="ok")this.block({account:Y.account,usage:Y.usage,identity:Y.identity,...P6(Y.usage,$.model,this.deps.now(),$.effort)},$.model);let Q=this.blocks(),W=this.deps.now(),H=new Set,V=new Map,X=J.map(({account:A,usage:P,identity:L,reason:j})=>{let N=P6(P,$.model,W,$.effort);if(j)N={...N,state:"miss",score:null,reason:j};let F=V.get(L);if(V.set(L,F??A.name),F)N={...N,state:"miss",score:null,reason:`重复账号:${F}`};let R=P.state==="ok"?q6(P,$.model):null,M=Q.find((k)=>(k.identity===L||k.identity===`record:${A.id}`)&&k.meter===R);if(M&&P.state==="ok"&&N.state==="ready"){let k=Z4(P,$.model);if(M.windows.some((v)=>{let b=k[v.kind];return b&&b.percent!==null&&(v.percent!==null&&b.percent<v.percent||v.reset!==null&&v.reset<=W&&(b.resetsAt?.getTime()??0)>v.reset)}))H.add(M.key);else N={...N,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:A,usage:P,identity:L,...N,...F?{duplicateOf:F}:{}}});if(H.size)t(this.deps.stateFile,{version:1,blocks:Q.filter((A)=>!H.has(A.key))});let z=X.filter((A)=>A.state==="ready");z.sort((A,P)=>P.score-A.score||(P.availableNow??0)-(A.availableNow??0)||A.account.id.localeCompare(P.account.id));let G=z[0]??null,K=X.filter((A)=>A.state==="exhausted"||A.state==="waiting"),B=K.length?Math.min(...K.map((A)=>A.retryAt??W+60000)):void 0;for(let A of X)_(`codex scheduler: ${A.account.name} ${A.state} score=${A.score??"MISS"}${A.reason?` (${A.reason})`:""}`);return{selected:G,candidates:X,...B!==void 0?{retryAt:B}:{}}}}var p9;var s6=T(()=>{h$();p0();J$();W$();w$();I();p9=new JQ({accounts:()=>y.list(),usage:j1,identity:($)=>y.fingerprint($),pendingLogin:B6,now:Date.now,stateFile:zJ,compatible:async($,Z,J)=>{let Y=H$("codex-sub",$);if(!Y)return"订阅来源 MISS";if(Y.modelCatalogState?.status!=="ready")await Y.refreshModels();if(!Y.enabled||Y.modelCatalogState?.status!=="ready")return Y.modelCatalogState?.error??"模型目录 MISS";let Q=z0(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as JB}from"node:events";function WB($,Z){return Z.throwIfAborted(),new Promise((J,Y)=>{let Q=()=>{clearTimeout(H),Z.removeEventListener("abort",W)},W=()=>{Q(),Y(Z.reason)},H=setTimeout(()=>{Q(),J()},$);Z.addEventListener("abort",W,{once:!0})})}var YB="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",QB,e6=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),$7;var YQ=T(()=>{h$();s6();p0();I();QB=["error","conversation_materialized","conversation_materialization_failed","token_usage","turn_plan_updated","plan_delta","context_compacted","rate_limits_updated","thread_goal_updated","thread_goal_cleared","assistant_text","assistant_block_stop","tool_use","tool_result","can_use_tool","hook_callback","bg_task_started","bg_task_progress","bg_task_updated","bg_task_settled","subagent_step","raw"];$7=class $7 extends JB{opts;provider="codex";tokenSourceId="codex-sub";launchKind;inner=null;selected=null;revision=null;ready=null;recovery=null;shutdown=null;lifetime=new AbortController;closed=!1;initialized=!1;starting=!1;retryTurn=!1;retryCount=0;ownRetry=null;result=null;fault=null;inputs=[];lastSession=null;backgroundTasks=new Set;resolveQuotaWait;quotaWait=new Promise(($)=>{this.resolveQuotaWait=$});constructor($){super();this.opts=$;this.launchKind=$.launch.kind,this.on("error",()=>{})}get sessionId(){return this.inner?.sessionId??this.lastSession}get lastAssistantUuid(){return this.inner?.lastAssistantUuid??null}get lastCompletedTurnId(){return this.result||this.ownRetry?null:this.inner?.lastCompletedTurnId??null}get lastModel(){return this.inner?.lastModel??this.opts.model}get lastEffort(){return this.inner?.lastEffort??this.opts.effort??null}get lastThinkingTokens(){return this.inner?.lastThinkingTokens??null}get lastUsage(){return this.inner?.lastUsage??null}get lastTotalUsage(){return this.inner?.lastTotalUsage??null}get lastResult(){return this.result??this.inner?.lastResult??e6()}get lastContextWindow(){return this.inner?.lastContextWindow??null}get lastContextTokens(){return this.inner?.lastContextTokens??null}get turnRetry(){return this.ownRetry??this.inner?.turnRetry??null}sourceRevision(){return this.revision}codexAccountSelectionMode(){return this.selected?this.selected.state==="manual"?"manual":"automatic":null}isAlive(){return!this.closed}isConversationResumable(){return this.inner?.isConversationResumable?.()===!0}conversationMaterializationBarrier(){return this.inner?.conversationMaterializationBarrier?.()??null}conversationMaterializationFailure(){return this.inner?.conversationMaterializationFailure?.()??null}initializationPromise(){if(!this.ready)this.sendInitialize();return this.ready}quotaWaitPromise(){return this.quotaWait}sendInitialize(){if(this.ready)return;this.ready=this.launch(this.opts.launch,this.opts.preferred),this.ready.catch(($)=>{if(!this.lifetime.signal.aborted)this.fail($)})}scheduler(){return this.opts.scheduler??p9}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},_(`codex account: ${$}`),this.emit("turn_retry",this.ownRetry)}async choose($,Z){let J={model:this.opts.model||this.lastModel||"",effort:this.opts.effort??this.lastEffort??void 0,preferred:$,failedAccountId:Z,signal:this.lifetime.signal};while(!0){let Y=await this.scheduler().choose(J);if(delete J.failedAccountId,this.lifetime.signal.throwIfAborted(),Y.selected)return{...Y,selected:Y.selected};let Q=Y.candidates.map((V)=>`${V.account.name}:${V.reason??V.state}`).join(";");if(Y.retryAt===void 0)throw Error(`没有可用的 Codex 账号;${Q}`);let W=Math.max(1000,Math.min(60000,Y.retryAt-Date.now())),H=Y.candidates.filter((V)=>V.state==="miss"&&!V.duplicateOf).length;_(`codex account: waiting for quota: ${Q}`),this.notice(`暂无可用账号 · 自动等待恢复${H?` · ${H} 个 MISS`:""}`,W),this.resolveQuotaWait(),await(this.opts.wait??WB)(W,this.lifetime.signal)}}async launch($,Z,J){this.starting=!0;let Y=await this.choose(Z,J);this.lifetime.signal.throwIfAborted();let Q=this.selected?.account.id??null,{process:W,sourceRevision:H}=this.opts.create(Y.selected.account.id,$,Y.selected.state==="manual",this.opts.model||this.lastModel||void 0,this.opts.effort??this.lastEffort??void 0);this.inner=W,this.selected=Y.selected,this.revision=H,$2(this,Y.selected.account.id,!1),this.wire(W),this.emit("codex_account_changed",{accountId:Y.selected.account.id,previousAccountId:Q,diagnostics:Y.candidates.filter((X)=>X.state==="miss"&&!X.duplicateOf).map((X)=>`${X.account.name}:${X.reason}`)}),this.lifetime.signal.throwIfAborted(),W.sendInitialize();let V=W.initializationPromise?.();if(!V)throw Error("Codex 初始化未提供确认事务");if(await V,this.lifetime.signal.throwIfAborted(),this.lastSession=W.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:W.sessionId});if(!this.recovery)this.drainInputs()}wire($){for(let Z of QB)$.on(Z,(...J)=>{if(this.inner===$&&!this.closed){if(Z==="bg_task_started")this.backgroundTasks.add(J[0].task_id);if(Z==="bg_task_settled")this.backgroundTasks.delete(J[0].task_id);this.emit(Z,...J)}});$.on("turn_retry",(Z)=>{if(this.inner===$&&!this.closed)this.emit("turn_retry",Z)}),$.on("turn_started",(Z)=>{if(this.inner!==$||this.closed)return;this.result=null,this.ownRetry=null;let J=this.retryTurn||Z.retry;this.retryTurn=!1,this.emit("turn_started",{...Z,...J?{retry:!0}:{}})}),$.on("result",(Z)=>{if(this.inner!==$||this.closed||this.lifetime.signal.aborted)return;if(Z?.is_error&&Z.codexQuotaFailure&&!this.recovery){this.retryCount++;let J=Promise.resolve().then(()=>this.recover($,Z.codexQuotaFailure)).catch((Y)=>{if(!this.lifetime.signal.aborted)this.fail(Y)}).finally(()=>{if(this.recovery===J)this.recovery=null});this.recovery=J,this.notice(`「${this.selected?.account.name??"MISS"}」额度耗尽 · 正在换号续跑`);return}if(this.recovery)return;this.retryCount=0,this.result=null,this.emit("result",Z)}),$.on("exit",(Z)=>{if(this.inner!==$||this.closed)return;if((this.recovery||this.shutdown)&&Z.expected)return;this.lifetime.abort(Error("Codex 进程退出")),this.closed=!0,this.emit("exit",Z)})}async recover($,Z){if(this.lifetime.signal.throwIfAborted(),!this.selected)throw Error("额度耗尽时未记录运行账号");if($.readRateLimits){let V=await u9(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),V?.state==="ok")this.selected={...this.selected,usage:V,identity:V.accountFingerprint??this.selected.identity};else this.notice("已确认额度耗尽 · 用量读取 MISS,正在换号")}let J=this.selected.usage===null?this.selected.account.id:void 0;if(this.selected.usage)this.scheduler().block(this.selected,this.lastModel??this.opts.model);let Y=$.conversationMaterializationBarrier?.();if(Y)await Y;this.lifetime.signal.throwIfAborted();let Q=$.isConversationResumable?.()===!0&&$.sessionId;if(Z.accepted&&!Q)throw Error("额度耗尽后未确认原会话落盘,不能重放已执行的任务");if(!Z.accepted&&typeof Z.rejectedInput!=="string")throw Error("额度耗尽的拒绝响应缺少原始输入");let W=Q?{kind:"resume",source:{provider:"codex",sessionId:$.sessionId,cwd:this.opts.workDir}}:this.opts.launch;if(await $.kill(),$.isAlive())throw Error("旧 Codex 进程退出未确认,不能启动下一账号");for(let V of this.backgroundTasks)this.emit("bg_task_settled",{task_id:V,status:"failed",summary:"账号额度耗尽,原进程已退出;主任务换号后继续"});this.backgroundTasks.clear(),this.lifetime.signal.throwIfAborted(),await this.launch(W,void 0,J),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let H=Z.accepted?YB:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(H),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...e6(),is_error:!0,subtype:"codex_account_failed"},this.emit("error",Z),this.emit("result",{...this.result,error:Z.message,checkpoint:null})}sendUserText($,Z=[]){if(this.fault)throw this.fault;if(this.closed||this.lifetime.signal.aborted)throw Error("Codex 进程已关闭");if(this.result=null,this.inputs.push({text:$,files:[...Z]}),!this.ready)this.sendInitialize();if(!this.starting&&!this.recovery)this.drainInputs()}drainInputs(){if(!this.inner||this.starting||this.recovery||this.lifetime.signal.aborted)return;while(this.inputs.length){let $=this.inputs.shift();this.inner.sendUserText($.text,$.files)}}sendInterrupt(){if(this.inputs.length=0,!this.recovery&&!this.starting){this.inner?.sendInterrupt();return}this.lifetime.abort(Error("用户已停止额度恢复")),this.ownRetry=null,this.result={...e6(),subtype:"interrupted"},this.emit("result",{...this.result,checkpoint:null}),this.kill().catch(($)=>this.emit("error",$))}kill($){if(this.shutdown)return this.shutdown;return this.lifetime.abort(Error("Codex 已停止")),this.inputs.length=0,this.ownRetry=null,this.shutdown=Promise.resolve().then(async()=>{if(await this.inner?.kill($),this.inner?.isAlive())throw Error("Codex 退出未确认");if(!this.closed)this.closed=!0,this.emit("exit",{code:0,signal:null,expected:!0})}).catch((Z)=>{throw this.shutdown=null,Z}),this.shutdown}active(){if(!this.inner||this.starting||this.recovery||!this.inner.isAlive())throw Error("Codex 正在选择或恢复账号");return this.inner}async listModels(){return await this.initializationPromise(),this.active().listModels()}async setModelSettings($,Z){await this.active().setModelSettings($,Z)}async compactThread(){await this.active().compactThread()}async readRateLimits(){let $=this.active();if(!$.readRateLimits)throw Error("Codex 额度接口 MISS");return $.readRateLimits()}respondingChild(){if(!this.inner?.isAlive()||this.lifetime.signal.aborted)throw Error("Codex 请求所属进程已退出");return this.inner}sendPermissionResponse(...$){this.respondingChild().sendPermissionResponse(...$)}sendHookResponse(...$){this.respondingChild().sendHookResponse(...$)}}});function A4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new $7({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,B,A,P,L)=>A4({...$,model:P,effort:L,codexAccountPreference:void 0,codexManualAccount:A,codexAccountId:K,launch:B})}),sourceRevision:null}}let Z=$.codexAccountId??l,J=H$($.tokenSourceId,Z),Y=$.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexManualAccount===!0;if($.tokenSourceId&&!J)throw Error(`token source not found: ${$.tokenSourceId}`);if(J&&!J.enabled&&!Y)throw Error(`token source disabled: ${J.id}`);if(J&&J.agent!==$.provider)throw Error(`token source ${J.id} belongs to ${J.agent}, not ${$.provider}`);if(!Y&&J?.modelCatalogState?.status==="failed")throw Error(`model catalog refresh failed for ${J.id}: ${J.modelCatalogState.error??"MISS"}`);if(!Y&&(J?.modelCatalogState?.status==="idle"||J?.modelCatalogState?.status==="loading"))throw Error(`model catalog is not ready for ${J.id}: ${J.modelCatalogState.status}`);let Q=$.model||J?.defaultModel||void 0,W=X2(J,Q),H=!Y&&J&&z0(J,Q);if(!Y&&J&&Q&&!H)throw Error(`model is not present in token source ${J.id}: ${Q}`);if(!Y&&H&&(H.unavailableReason||!H.efforts.length||$.effort!==void 0&&!H.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Q}/${$.effort??"MISS"}`);let V=!Y&&J&&Q?J.resolveSpawnModel(Q):Q;if(Q&&!V)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Q}`);let X=J?(G)=>J.spawnEnv(G,V):void 0;if($.provider==="dsh"){if(!J||!V||!_$($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new g6({...$,model:V,effort:$.effort,tokenSourceId:J.id,transformEnv:X}),sourceRevision:W}}if($.provider==="claude"){if(d6(),!O$($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new I9({workDir:$.workDir,model:V,effort:$.effort,...$.launch?.kind==="fresh"||!$.launch?{}:{resumeSessionId:$.launch.source.sessionId,...$.launch.kind==="fork"?{forkSession:!0}:{},...$.launch.kind==="fork"&&$.launch.through?.provider==="claude"?{resumeSessionAt:$.launch.through.id}:{}},...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},...$.profile?{profile:$.profile}:{},...J?{settingSources:J.settingSources??["project","local"]}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:X,hostEnv:$.hostEnv}),sourceRevision:W}}if($.effort!==void 0&&!d$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let z=new J2({workDir:$.workDir,model:V,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:X,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z});return $2(z,Z),{process:z,sourceRevision:W}}var Z7=T(()=>{L$();NY();X4();q1();J$();h$();YQ()});function l9($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}import{execFile as HB}from"node:child_process";import{readFileSync as J7,statfsSync as VB,statSync as QQ}from"node:fs";import{cpus as XB,homedir as zB}from"node:os";import{promisify as GB}from"node:util";function KB(){try{let $=J7("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:XB().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return _(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function BB(){try{let $=J7("/proc/meminfo","utf8"),Z=(W)=>{let H=$.match(new RegExp(`^${W}:\\s+(\\d+)\\s*kB`,"m"));return H?parseInt(H[1],10)*1024:0},J=Z("MemTotal"),Y=Z("MemAvailable");if(!J)return null;let Q=Math.max(0,J-Y);return{totalBytes:J,availBytes:Y,usedBytes:Q,percent:Math.round(Q/J*100)}}catch($){return _(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function WQ($,Z){try{let J=VB(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,W=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:W,percent:Math.round(W/Y*100)}}catch(J){return _(`sysinfo: statfs ${Z} failed: ${J}`),null}}function AB(){let $=[],Z=WQ("/","/");if(Z)$.push(Z);let J=zB();if(J&&J!=="/"){let Y=!1;try{let Q=QQ("/"),W=QQ(J);Y=Q.dev===W.dev}catch{}if(!Y){let Q=WQ("$HOME",J);if(Q)$.push(Q)}}return $}function qB(){try{let $=J7("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function HQ($,Z=2000){try{let{stdout:J}=await _B("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return _(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function VQ($){return XQ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function PB(){let $=await HQ(["list-units","--type=service","--all","--no-legend","--plain",...XQ.map((X)=>`${X}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
71
- `).map((X)=>X.trim()).filter((X)=>X.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let X of Z){let G=X.replace(/^●\s*/,"").split(/\s+/)[0];if(!G)continue;if(!VQ(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await HQ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=qB(),W=Y.split(/\n\s*\n/),H=[],V=(X)=>{let z=parseInt(X??"0",10);if(z<=0||Q===null)return null;return Math.max(0,Q-z/1e6)};for(let X of W){let z={};for(let K of X.split(`
72
- `)){let B=K.indexOf("=");if(B<=0)continue;z[K.slice(0,B)]=K.slice(B+1)}let G=z.Id??"";if(!VQ(G))continue;H.push({name:G.replace(/\.service$/,""),active:z.ActiveState??"unknown",sub:z.SubState??"",lastActiveAgoSec:V(z.ActiveEnterTimestampMonotonic),stateAgoSec:V(z.StateChangeTimestampMonotonic)})}return H.sort((X,z)=>X.name.localeCompare(z.name)),{services:H,error:null}}async function zQ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=KB(),Z=BB(),J=AB(),{services:Y,error:Q}=await PB();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var _B,XQ,q4="cc-* / codex-*";var Y7=T(()=>{I();_B=GB(HB),XQ=["cc-","codex-"]});function L4($,Z){return Z}function Q7($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:U.footer,content:L4($.title,$.status)}]}}}function GQ($){if($<1024)return`${$}B`;if($<1048576)return`${($/1024).toFixed(0)}K`;if($<1073741824)return`${($/1048576).toFixed(0)}M`;let Z=$/1073741824;return Z<10?`${Z.toFixed(1)}G`:`${Z.toFixed(0)}G`}function LB($){if(!$)return"0";if($<1000)return String($);if($<1e6)return($/1000).toFixed($<1e4?1:0).replace(/\.0$/,"")+"K";return($/1e6).toFixed(2).replace(/\.?0+$/,"")+"M"}function P4($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Y=Z%60;if(J<24)return`${J}h ${Y}m`;return`${Math.floor(J/24)}d ${J%24}h`}function j4($){if(!$)return"?";let Z=$.getTime()-Date.now();if(Z<=0)return"已重置";if(Z<3600000)return`${Math.max(1,Math.round(Z/60000))}m`;if(Z<86400000)return`${(Z/3600000).toFixed(1)}h`;return`${(Z/86400000).toFixed(1)}d`}function FB($){let Z=[];if($?.cpu)Z.push(`L${$.cpu.load1.toFixed(2)}`);if($?.mem)Z.push(`M${$.mem.percent}%`);if($&&!$.servicesError)Z.push(`S${$.services.length}`);return Z}function RB($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${q4} _n/a_`].join(`
73
- `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:W}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${W.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${GQ($.mem.usedBytes)}/${GQ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${q4} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${q4} _无_`);else{Z.push(`**服务** ${q4} (${$.services.length})`);for(let J of $.services){let Y=MB[J.active]??"·",Q=J.lastActiveAgoSec,W=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(W!=null)H.push(`已运行 ${P4(W*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${P4(Q*1000)}前`);else H.push("从未启动");if(W!=null){let V=J.active==="failed"?"已挂":"已停";H.push(`${V} ${P4(W*1000)}`)}}else if(W!=null)H.push(`已 ${P4(W*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
74
- `)}function UB($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=jB[J.status]??"·",Q=DB[J.status]??J.status,W=J.uptimeMs!=null&&J.uptimeMs>0?` · ${P4(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"";return` · ${Y} \`${J.name}\` · ${Q}${W}${H}`}).join(`
75
- `)}function i9($,Z=U.consoleProjects){let J=$.peers??[];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83D\uDDC2 活跃项目 (${J.length})`}},expanded:!1,elements:[{tag:"markdown",content:UB($)}]}}function OB($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${G7($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
76
- `)}function d9($,Z=U.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:OB($)}}function n9($,Z=U.consoleHost){let J=FB($);return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:J.length>0?`\uD83D\uDDA5 主机 · ${J.join(" · ")}`:"\uD83D\uDDA5 主机"}},expanded:!1,elements:[{tag:"markdown",content:RB($)}]}}function a9($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(Y,Q)=>`${Q==="USD"?"$":Q==="CNY"?"¥":`${Q} `}${Y.toFixed(2)}`;if($.kind==="balance")return $.balance?`余额 ${J($.balance.remaining,$.balance.currency)}`:"余额 MISS";if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${J($.quota.remaining,$.quota.currency)} / ${J($.quota.limit,$.quota.currency)}`;if(!$.windows.length)return"额度 MISS";return`额度 ${$.windows.map(_Q).join(" · ")}`}function _Q($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function TB($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.map(_Q)].join(`
77
- `):a9($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=$?.resetCredits===void 0?"":`
78
- **重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`;return Z+J}function D4($){let Z=TB($.unifiedUsage);return{tag:"markdown",element_id:U.consoleUsage,content:Z}}function KQ($,Z){return[d9($,Z),i9($),n9($.sysinfo),D4($)]}function W7($){let{sessionName:Z,status:J}=$,Y=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Y},body:{elements:KQ($)}}}function H7($){return A2($.sessionName,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${D1($.currentDisplay??"未选择")}
79
- 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:U.modelAgentGroup(Z),expanded:!0,header:{title:{tag:"markdown",content:`**Agent · ${{claude:"Claude Code",codex:"Codex",dsh:"DeepSeek Harness"}[Z]}**`},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"8px",margin:"8px 0px 0px 0px",elements:J.map((Y)=>NB(Y,$.panelId))}]:[]})]})}function NB($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${_0($.display)}** · 未配置`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启"},type:"primary",behaviors:[{type:"callback",value:{kind:"token_source_enable",source_id:$.sourceId}}]}]}]};let J=$.catalogStatus==="failed"?`模型目录 MISS${$.catalogError?`:${$.catalogError}`:""}`:$.catalogStatus==="loading"||$.catalogStatus==="idle"?"模型目录加载中":`${$.modelCount} 个模型`,Y=[$.selected?"当前账号":"",J].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${_0($.display)}**
80
- ${Y}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:{kind:"provider_select",panel_id:Z,source_id:$.sourceId,...$.provider?{provider:$.provider}:{}}}]}]}]}}function V7($){return A2($.sessionName,BQ($))}function X7($){return A2($.sessionName,t9($))}function o9($){return A2($.sessionName,s9($),"green")}function A2($,Z,J="turquoise"){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83E\uDD16 model · ${$}`},template:J},body:{elements:[Z]}}}function BQ($){let Z=kB($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${AQ($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
81
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?EB($.panelId,$.pagination):[],...$.editable&&$.allowCustom?[{tag:"button",text:{tag:"plain_text",content:"补录模型"},type:"default",behaviors:[{type:"callback",value:{kind:"model_custom_prompt",panel_id:$.panelId,source_id:$.sourceId}}]}]:[],{tag:"button",text:{tag:"plain_text",content:$.editable?$.mode==="add"?"返回模型列表":"显示模型":"补录模型"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:$.editable?"model_list_open":"model_custom_prompt",panel_id:$.panelId,...$.sourceId||$.models[0]?.sourceId?{source_id:$.sourceId??$.models[0]?.sourceId}:{},...$.editable?{mode:$.mode==="add"?"select":"add"}:{}}}]}]}}function EB($,Z){let{sourceId:J,page:Y,totalPages:Q}=Z,W=(H,V)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:H},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:V}}]}]});return[{tag:"markdown",content:`第 ${Y+1} / ${Q} 页`},{tag:"column_set",columns:[...Y>0?[W("上一页",Y-1)]:[],...Y+1<Q?[W("下一页",Y+1)]:[]]}]}function r9($,Z="cancelled"){return A2($,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function z7($,Z,J){return A2($,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
82
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function q2($,Z,J){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
83
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function t9($){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${bB($.model)}`,`当前: ${AQ($.currentModel,$.currentEffort)}`].join(`
84
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>xB($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function s9($){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",D1(qQ($.model,$.effort,$.provider)),_0($.scope)].join(`
85
- `)}]}}function SB($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${_0($.displayName)}** · 未配置
86
- ${_0($.description??"")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启"},type:"primary",behaviors:[{type:"callback",value:{kind:"token_source_enable",source_id:$.sourceId}}]}]}]}];let Q=$.displayName&&$.displayName!==$.model?`**${_0($.displayName)}**`:`**${D1($.model)}**`,W=[$.isDefault?`${G7($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
87
- `+_0(yB($.description,110)):"",V=(z,G)=>({tag:"button",text:{tag:"plain_text",content:G},type:"default",behaviors:[{type:"callback",value:{kind:z,panel_id:Z,source_id:$.sourceId,model:$.model}}]});return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,vertical_align:"center",elements:[{tag:"markdown",content:[Q,$.displayName&&$.displayName!==$.model?D1($.model):"",W.length?W.join(" · "):""].filter(Boolean).join(`
88
- `)+H}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[V("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:CB($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?V("model_custom_remove","删"):V("model_remove","隐")]:[]]}]}]}function kB($,Z,J,Y=!1){let Q=[{title:"Codex",models:$.filter((V)=>(V.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((V)=>V.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((V)=>V.provider==="dsh")}].filter((V)=>V.models.length>0),W=(V)=>V.flatMap((X,z)=>[...z?[{tag:"hr"}]:[],...SB(X,Z,J,Y)]);if(Q.length<=1)return W($);let H=[];for(let V of Q)H.push({tag:"markdown",content:`**${V.title}**`}),H.push(...W(V.models));return H}function xB($,Z,J,Y,Q){let W=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",W?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":_0(Z.effort)}**`,H,Z.description?_0(Z.description):""].filter(Boolean).join(`
89
- `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:W?"primary":"default",behaviors:[{type:"callback",value:{kind:"model_effort_select",panel_id:J,...$.sourceId?{source_id:$.sourceId}:{},...$.provider?{provider:$.provider}:{},model:$.model,effort:Z.effort}}]}]}]}}function CB($,Z){return{kind:"model_select",panel_id:Z,...$.sourceId?{source_id:$.sourceId}:{},...$.provider&&$.provider!=="codex"?{provider:$.provider}:{},model:$.model,display_name:$.displayName,is_default:$.isDefault===!0,efforts:$.efforts.map((J)=>({effort:J.effort,description:J.description??"",is_default:J.isDefault===!0}))}}function bB($){return $.displayName&&$.displayName!==$.model?`${_0($.displayName)} (${D1($.model)})`:D1($.model)}function AQ($,Z){return D1(qQ($,Z))}function qQ($,Z,J){let Y=J&&J!=="codex"?`${G7(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function G7($){return V0($??"codex")}function yB($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function _0($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function D1($){return"`"+$.replace(/`/g,"\\`")+"`"}function U0($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec)Z.push(`⏱ ${$.durationSec}s`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${LB($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var jB,DB,MB;var _7=T(()=>{L$();Y7();x$();jB={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},DB={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},MB={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});var jQ={};P0(jQ,{codexAccountSummary:()=>M4,codexAccountPanel:()=>F4,codexAccountCard:()=>Z0,CODEX_ACCOUNTS_PAGE_SIZE:()=>e9});function O0($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function K7($){return{tag:"column_set",flex_mode:"none",horizontal_spacing:"12px",columns:$.map((Z)=>({tag:"column",width:"weighted",weight:1,vertical_align:"center",vertical_spacing:"4px",elements:Z}))}}function M4($){let[Z,J]=LQ[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function Z0($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:M4($)}},body:{elements:[F4($)]}}}function F4($){let[,,Z]=LQ[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(C$(["连接","授权","就绪"].map((Q,W)=>W===Y?`**${W+1} ${Q}**`:`${W<Y?"✓":W+1} ${Q}`).join(" → ")))}if($.phase==="waiting"&&$.verification){let Y=new URL($.verification.url);if(Y.protocol!=="https:"||/[\s<>]/.test($.verification.url))throw Error("授权链接无效");if(!/^[A-Za-z0-9-]{1,64}$/.test($.verification.code))throw Error("验证码格式无效");J.push(K7([[I$("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[C$(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),I$("登录账号,输入左侧验证码")]]))}if($.current)J.push(K7([[I$("当前使用"),C$(`**${O0($.current)}**`)],...$.selected&&$.selected!==$.current?[[I$("下次启动"),C$(`**${O0($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(C$([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>O0(Y)).join(" · ")));if($.message)J.push(C$(O0($.message)));if($.total)J.push(...wB($));if($.hint)J.push(I$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[C$(O0($.details))]});return{tag:"collapsible_panel",element_id:U.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:M4($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function wB($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/e9)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[I$(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],W=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort((H,V)=>V.score-H.score||(V.availableNow??0)-(H.availableNow??0)||H.account.id.localeCompare(V.account.id));if($.scheduling)Q.push(I$(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${W.length}`));for(let H of Z.entries.slice((Y-1)*e9,Y*e9)){let V=[H.account.id===$.currentId?"使用中":"",H.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),X=H.usage,z=[];if(Q.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${H.account.name}${V.length?` · ${V.join(" · ")}`:""}`},background_color:H.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:z}),H.duplicateOf){z.push(I$(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}let G=$.scheduling?.candidates.find((P)=>P.account.id===H.account.id);if(G){let P=W.findIndex((L)=>L.account.id===H.account.id);if(z.push(G.state==="ready"?C$(`**#${P+1} · ${G.score.toPrecision(3)} 份/h**`):I$(G.state==="exhausted"?"⏳ 耗尽 · 暂不参与":G.state==="excluded"?"Ultra 自动排除 Plus":G.state==="waiting"?`⏳ 周余量 ${G.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),G.state==="ready"&&G.remaining!=null)z.push(I$(`周余量 ${G.remaining.toPrecision(3)} 份${G.fiveHourRemaining!=null?` · 5h ${G.fiveHourRemaining.toPrecision(3)} 份`:""}`));if(G.state==="miss"&&G.reason&&X.state==="ok")z.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[C$(O0(G.reason))]})}if(X.state!=="ok"){if(z.push(C$(X.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),X.state==="network"&&X.reason)z.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[C$(O0(X.reason))]});continue}let K=X.subscriptionType==="pro"?"Pro 20×":X.subscriptionType==="prolite"?"Pro 5×":X.subscriptionType==="plus"?"Plus 1×":X.subscriptionType??"套餐 MISS";z.push(I$(`${K} · 重置卡 ${X.resetCredits??"MISS"}`));let B=[PQ(X.fiveHour,"5h"),PQ(X.weekly,"周")].filter((P)=>P!==null);if(B.length)z.push(K7(B));let A=X.buckets?.filter((P)=>P.limitId!==X.defaultLimitId)??[];if(A.length)z.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:`其他额度 · ${A.length}`}},elements:A.map((P)=>C$(`${O0(P.limitName??P.limitId)} · ${fB(P.fiveHour,P.weekly)}`))})}if(J>1)Q.push(I$(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}function PQ($,Z){if(!$)return null;let J=$.percent;if(J===null||!Number.isFinite(J)||J<0||J>100)return[C$(`**${Z} · MISS**`)];let Y=Math.round(J/100*8),Q=J>=100?"red":J>=80?"orange":"green";return[C$(`**${Z} · ${Math.round(J)}%**
90
- <font color='${Q}'>${"▰".repeat(Y)}${"▱".repeat(8-Y)}</font>`),I$($.unreportedFull?"满窗 · 0.15 份":$.resetsAt?`${j4($.resetsAt)} 重置`:"重置时间 MISS")]}function fB($,Z){return[$?`5h ${$.percent??"MISS"}${$.percent===null?"":"%"}`:"",Z?`周 ${Z.percent??"MISS"}${Z.percent===null?"":"%"}`:""].filter(Boolean).join(" · ")}var e9=4,LQ,C$=($)=>({tag:"markdown",content:$}),I$=($)=>({tag:"markdown",content:`<font color='grey'>${O0($)}</font>`,text_size:"notation"});var P2=T(()=>{x$();_7();LQ={connecting:["\uD83D\uDD04","连接中","blue"],waiting:["\uD83D\uDD10","等待授权","blue"],checking:["\uD83D\uDD0E","校验中","blue"],success:["✅","登录成功","green"],selected:["\uD83C\uDFAF","下次启动生效","green"],current:["\uD83E\uDDED","当前账号","blue"],accounts:["\uD83D\uDDC2","账号与额度","blue"],cancelled:["⏹","已取消","grey"],expired:["⌛","等待超时","orange"],error:["❌","未完成","red"],warning:["⚠️","需要处理","orange"]}});async function B7($){let Z=await P7("feishu chat.get",()=>Y$.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)$8("feishu chat.get",Z);let J=Z.data?.owner_id;if(!J)throw Error("feishu chat.get returned no owner_id; cannot add project group owner to tasklist");return J}async function A7($,Z){let J=await P7("feishu tasklist.create",()=>Y$.task.v2.tasklist.create({params:{user_id_type:"open_id"},data:{name:$,members:[{id:Z,type:"user",role:"editor"}]}}));if(J.code&&J.code!==0)$8("feishu tasklist.create",J);let Y=J.data?.tasklist,Q=Y?.guid;if(!Q)throw Error("feishu tasklist.create returned no guid");return{guid:Q,name:Y?.name||$,url:Y?.url??"",createdAt:Y?.created_at}}async function q7($){let Z=await P7("feishu tasklist.delete",()=>Y$.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)$8("feishu tasklist.delete",Z)}function DQ($,Z){let J=Z&&typeof Z==="object"?Z:{},Y=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Q=Y.code??J.code,W=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,V=Array.isArray(H)?H.map((X)=>X?.scope??X?.subject??X?.name??X).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${W}${V?` missing_scopes=${V}`:""}`}async function P7($,Z){try{return await Z()}catch(J){$8($,J)}}function $8($,Z){throw Error(DQ($,Z))}var MQ=T(()=>{$$()});var Q$={};P0(Q$,{writeAliveMarker:()=>f7,urgentApp:()=>O1,uploadImageKey:()=>p7,uploadAndSend:()=>C4,updateCard:()=>B0,unbindSessionChat:()=>Y8,tempProjectName:()=>K0,tempChatName:()=>x7,setPendingConversationLaunchChecked:()=>i0,sendTextRaw:()=>w,sendText:()=>E,sendImage:()=>G8,sendFile:()=>pQ,sendCard:()=>u,sanitizeSessionName:()=>i7,resolveProjectDir:()=>H8,replaceTurnAnchors:()=>a$,registerTempSessionLease:()=>U7,refreshChatList:()=>k4,readAliveMarker:()=>v7,provisionProject:()=>l7,projectProfile:()=>j2,preferredChatForSession:()=>A$,loadTempSessionLeases:()=>R7,loadSessionTurnsMap:()=>S7,loadSessionResumeMap:()=>N7,loadSessionModelMap:()=>C7,loadSessionChatMap:()=>T7,listNormalChatIdsByName:()=>X8,isOpenAIChatGPTAuthenticated:()=>b4,hasTempSessionLease:()=>O7,getTurnAnchors:()=>N4,getTenantToken:()=>T0,getSessionResumeRef:()=>l0,getSessionModelSelection:()=>y7,getSessionBranchBase:()=>E4,getPendingConversationLaunch:()=>S4,formatFeishuApiError:()=>DQ,findNormalChatIdByName:()=>z8,fetchChatOwnerOpenId:()=>B7,fetchChatName:()=>c7,ensureChatForSession:()=>h7,downloadAttachment:()=>x4,disbandChatForSessionExact:()=>m7,disbandChatForSession:()=>g7,deleteTasklistByGuid:()=>q7,deleteReaction:()=>E$,createTempChatForSession:()=>I7,createTasklistWithOwner:()=>A7,client:()=>Y$,clearSessionResumeChecked:()=>D2,clearSessionConversationState:()=>w7,chatNameCache:()=>q$,chatIdForSession:()=>V8,bindSessionToChat:()=>L2,bindSessionResumeChecked:()=>T4,bindSessionModelChecked:()=>U1,bindSessionModel:()=>b7,appendTurnAnchorChecked:()=>k7,addReaction:()=>m$,PROJECTS_ROOT:()=>wQ,MAX_UPLOAD_BYTES:()=>u7});import*as EQ from"@larksuiteoapi/node-sdk";import{execSync as vB}from"node:child_process";import{randomUUID as F7}from"node:crypto";import{mkdirSync as j7,readFileSync as F1,statSync as SQ,writeFileSync as kQ}from"node:fs";import{readFile as xQ}from"node:fs/promises";import{homedir as FQ}from"node:os";import{basename as M1,extname as hB,isAbsolute as CQ,join as J8}from"node:path";import{sync as IB}from"cross-spawn";function D7(){let $={};for(let[Z,J]of g$)$[Z]=J;t(k5,$)}function R7(){g$.clear();try{let $=JSON.parse(F1(k5,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Y=J;if(typeof Z!=="string"||!Z||Y.chatId!==Z||typeof Y.sessionName!=="string"||!K0(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){_(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}g$.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}_(`feishu: loaded ${g$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")_(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function U7($,Z){if(!K0($))throw Error(`refusing to lease non-temporary session name "${$}"`);if(!Z)throw Error("cannot lease a temporary session without chat_id");for(let Q of g$.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=g$.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};g$.set(Z,Y);try{D7()}catch(Q){if(J)g$.set(Z,J);else g$.delete(Z);throw Q}}function O7($,Z){let J=g$.get(Z);return J?.sessionName===$&&J.chatId===Z}function j2($){return f.projects[$]}function H8($){return j2($)?.cwd?.trim()||J8(wQ,$)}function R1($,Z={}){return fetch($,{...Z,signal:Z.signal??AbortSignal.timeout(gB)})}async function T0(){if(Z8&&Date.now()<RQ)return Z8;return L7??=(async()=>{let $=await R1("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:bQ,app_secret:yQ})}),Z=await $.json();if(!$.ok||!Z.tenant_access_token)throw Error(`feishu: tenant token failed HTTP ${$.status} code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);return Z8=Z.tenant_access_token,RQ=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,Z8})().finally(()=>{L7=null}),L7}function T7(){try{let $=JSON.parse(F1(T5,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")A$.set(Z,J);_(`feishu: loaded ${A$.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function fQ(){try{M7()}catch($){_(`feishu: save session-chat-map failed: ${$}`)}}function M7(){let $={};for(let[Z,J]of A$)$[Z]=J;t(T5,$)}function L2($,Z){if(A$.get($)===Z)return;let J=A$.get($);A$.set($,Z),fQ(),_(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function Y8($){let Z=A$.get($);if(!Z)return;A$.delete($),fQ(),_(`feishu: unbound session "${$}" from ${Z}`)}function U4($,Z){let J=B$.get($)??{};J[Z.provider]=Z,B$.set($,J)}function UQ($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=H0(J.provider)?J.provider:Z??null;if(!Y||Z&&Y!==Z)return null;let Q=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Q)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Y,sessionId:Q,cwd:null};if(typeof J.cwd!=="string"||!CQ(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function OQ($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!H0($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!CQ($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function mB($,Z,J){if(typeof $!=="string")return OQ($);if(!Z)throw Error("cannot bind a conversation without a provider");return OQ({provider:Z,sessionId:$,cwd:J??null})}function N7(){try{let $=JSON.parse(F1(N5,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");B$.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){U4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=UQ(Y);if(Q){U4(Z,Q);continue}for(let W of o5){let H=Y[W];if(typeof H==="string"&&H.trim()){U4(Z,{provider:W,sessionId:H.trim(),cwd:null});continue}let V=UQ(H,W);if(V)U4(Z,V)}}_(`feishu: loaded ${B$.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function Q8(){let $={};for(let[Z,J]of B$){let Y={};if(J.codex)Y.codex={...J.codex};if(J.claude)Y.claude={...J.claude};if(J.dsh)Y.dsh={...J.dsh};$[Z]=Y}t(N5,$)}function T4($,Z,J,Y){let Q=mB(Z,J,Y),W=B$.get($),H=W?{...W}:void 0,V=W?.[Q.provider];if(V?.sessionId===Q.sessionId&&V.cwd===Q.cwd)return;U4($,Q);try{Q8()}catch(X){if(H)B$.set($,H);else B$.delete($);throw X}}function l0($,Z="codex"){let J=B$.get($)?.[Z];return J?{...J}:null}function D2($,Z){let J=B$.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)B$.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)B$.delete($);else B$.set($,Q)}try{Q8()}catch(Q){throw B$.set($,Y),Q}}function vQ($){if(!$||typeof $!=="object")return null;let Z=$;if(!H0(Z.provider))return null;let J=typeof Z.sessionId==="string"?Z.sessionId.trim():"";if(!J)return null;let Y;if(Z.cwd===void 0||Z.cwd===null)Y=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Y=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Y}}function hQ($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=vQ(J),Q=typeof Z.id==="string"?Z.id.trim():"";if(!Q||!Y)return null;if(Z.provider==="dsh"&&Z.kind==="event"&&Y.provider==="dsh"&&/^\d+$/.test(Q)&&Number.isSafeInteger(Number(Q)))return{provider:"dsh",kind:"event",id:Q,source:{...Y,provider:"dsh"}};if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Y.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Q,source:{...Y,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Y.provider==="codex")return{provider:"codex",kind:"turn",id:Q,source:{...Y,provider:"codex"}};return null}function IQ($){if(!$||typeof $!=="object")return null;let Z=$;if(Z.kind==="fresh")return{kind:"fresh"};if(Z.kind!=="resume"&&Z.kind!=="fork")return null;let J=vQ(Z.source);if(!J)return null;let Y=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Q=hQ(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{K$(Y,J.provider)}catch{return null}return Y}function cB($){if(!Array.isArray($))return[];return $.filter((Z)=>Z&&typeof Z.path==="string").map((Z)=>({tool:String(Z.tool??"Write"),path:String(Z.path),body:String(Z.body??"")})).filter((Z)=>Z.path!==""||Z.body!=="")}function uB($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Y=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Q=hQ(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let W=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!W||!H)return null;Q={provider:"claude",kind:"assistant-message",id:W,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:cB(J.writes)}}function pB($){if(!$||typeof $!=="object")return null;let Z=$,J=IQ(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Y=Z.previousSessionId,Q=Y===null?null:typeof Y==="string"&&Y.trim()?Y.trim():void 0;if(Q===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Q}}function E7($){let Z=$.launch.through;if($.launch.source.provider!=="claude"||Z&&(Z.provider!=="claude"||Z.kind!=="assistant-message"||Z.source.provider!=="claude"))throw Error("pending conversation launch is not a Claude fork");return{launch:{kind:"fork",source:{...$.launch.source,provider:"claude"},...Z?{through:{...Z,provider:"claude",kind:"assistant-message",source:{...Z.source,provider:"claude"}}}:{}},previousSessionId:$.previousSessionId}}function S7(){try{let $=JSON.parse(F1(E5,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");s.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let W,H,V=null;if(Array.isArray(Q))W=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let K=Q;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(W=K.anchors,K.base===null)H=null;else{let B=IQ(K.base);if(!B){J++;continue}H=B}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let B=pB(K.pendingLaunch);if(!B){J++;continue}V=B}}else{J++;continue}let X=B$.get(Y),z=X?.claude!==void 0&&X.codex===void 0?"claude":null,G=[];for(let K of W){let B=uB(K,z);if(B)G.push(B);else J++}if(G.length||H!==null||V)s.set(Y,{base:H,anchors:G,...V?{pendingLaunch:V}:{}}),Z+=G.length}if(_(`feishu: loaded ${Z} turn anchors across ${s.size} sessions`),J>0)_(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function O4(){let $={};for(let[Z,J]of s)$[Z]=J;t(E5,$)}function k7($,Z){let J=s.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>TQ){let W=Y.splice(0,Y.length-TQ),H=W[W.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}s.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{O4()}catch(W){if(J)s.set($,J);else s.delete($);throw W}}function N4($){return s.get($)?.anchors??[]}function E4($){return s.get($)?.base??null}function S4($){let Z=s.get($)?.pendingLaunch;return Z?E7(Z):null}function i0($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");K$(Z.launch,"claude",Z.launch.source.cwd)}let J=s.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)s.delete($);else s.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:E7(Z)}:{}});try{O4()}catch(W){if(J)s.set($,J);else s.delete($);throw W}}function a$($,Z,J,Y){let Q=s.get($),W=Y===void 0?Q?.pendingLaunch:Y??void 0,H=W?E7(W):void 0;if(Z.length===0&&J===null&&!H)s.delete($);else s.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{O4()}catch(V){if(Q)s.set($,Q);else s.delete($);throw V}}function K0($){return NQ.test($)?$.replace(NQ,""):null}function x7($,Z=[]){let J=new Date,Y=(V)=>String(V).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,W=new Set([...q$.values(),...s.keys(),...Z]),H=`${$}*${Q}`;for(let V=2;W.has(H);V++)H=`${$}*${Q}-${V}`;return H}function C7(){try{let $=JSON.parse(F1(S5,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){N$.set(Z,{provider:t1(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,W=H0(Q)?Q:typeof Y==="string"&&Y.trim()?t1(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(W==="claude"&&!H)continue;let{effort:V,tokenSourceId:X}=J,z=typeof X==="string"&&X.trim()?X.trim():null,G=W==="dsh"?_$(V)?V:null:W==="claude"?O$(V)?V:null:d$(V)?V:null;N$.set(Z,{provider:W,model:H,effort:G,...z?{tokenSourceId:z}:{}})}_(`feishu: loaded ${N$.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-model-map failed: ${$?.message??$}`)}}function lB(){try{W8()}catch($){_(`feishu: save session-model-map failed: ${$}`)}}function W8(){let $={};for(let[Z,J]of N$)$[Z]=J;t(S5,$)}function b7($,Z,J,Y,Q){let W=N$.get($);if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;N$.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),lB()}function U1($,Z,J,Y,Q){let W=N$.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;N$.set($,H);try{W8()}catch(V){if(W)N$.set($,W);else N$.delete($);throw V}}function y7($){let Z=N$.get($);if(Z)return Z;let J=K0($);return J?N$.get(J)??null:null}function w7($){let Z=A$.get($),J=B$.get($),Y=N$.get($),Q=s.get($),W=[...g$.entries()].filter(([,H])=>H.sessionName===$);A$.delete($),B$.delete($),N$.delete($),s.delete($);for(let[H]of W)g$.delete(H);try{M7(),Q8(),W8(),O4(),D7()}catch(H){if(Z)A$.set($,Z);if(J)B$.set($,J);if(Y)N$.set($,Y);if(Q)s.set($,Q);for(let[X,z]of W)g$.set(X,z);let V=[H];for(let X of[M7,Q8,W8,O4,D7])try{X()}catch(z){V.push(z)}throw V.length===1?V[0]:AggregateError(V,`failed to clear and restore conversation state for ${$}`)}}function f7($){t(C5,$)}function v7(){let $;try{$=F1(C5,"utf8")}catch(J){if(J.code==="ENOENT")return[];throw J}let Z=JSON.parse($);if(!Array.isArray(Z)||Z.some((J)=>typeof J!=="string"||!J.trim()))throw Error("invalid alive session marker: expected non-empty session names");return Z}function V8($){let Z=A$.get($);if(Z){let Y=q$.get(Z);if(Y&&Y!==$)_(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of q$)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)_(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function k4(){try{let $;do{let Z=await Y$.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)q$.set(J.chat_id,J.name);$=Z.data?.page_token}while($);_(`feishu: refreshed chat list — ${q$.size} groups`)}catch($){_(`feishu: refresh chat list failed: ${$}`)}}async function X8(){let $=new Map,Z;do{let J=await Y$.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Y of J.data?.items??[]){if(!Y.chat_id||!Y.name)continue;if(Y.chat_status&&Y.chat_status!=="normal")continue;q$.set(Y.chat_id,Y.name);let Q=$.get(Y.name)??[];Q.push(Y.chat_id),$.set(Y.name,Q)}Z=J.data?.page_token}while(Z);return $}async function z8($){let Z=A$.get($);if(Z&&q$.get(Z)===$){let W=await mQ(Z);if(W.name===$&&cQ(W.status))return Z;q$.delete(Z),Y8($)}let Y=(await X8()).get($)??[];if(Y.length===0)return null;let Q=A$.get($);if(Q&&Y.includes(Q))return Q;if(Y.length===1)return Y[0];throw Error(`multiple Feishu groups named "${$}": ${Y.join(", ")}`)}async function h7($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await z8($);if(J){let W=await iB(J,Z);return L2($,J),{chatId:J,created:!1,joined:W}}let Y=await Y$.im.chat.create({params:{user_id_type:"open_id",uuid:F7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return q$.set(Q,$),L2($,Q),{chatId:Q,created:!0,joined:!0}}async function I7($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await z8($))throw Error(`temporary group name already exists: ${$}`);let Y=await Y$.im.chat.create({params:{user_id_type:"open_id",uuid:F7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return q$.set(Q,$),L2($,Q),{chatId:Q,created:!0,joined:!0}}async function g7($){let Z=await z8($);if(!Z)return Y8($),{chatId:null,disbanded:!1};let J=await Y$.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw Error(`feishu chat.delete failed code=${J.code} msg=${J.msg}`);if(q$.delete(Z),A$.get($)===Z)Y8($);return{chatId:Z,disbanded:!0}}async function m7($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await mQ(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!cQ(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await Y$.im.chat.delete({path:{chat_id:Z}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.delete failed code=${Y.code} msg=${Y.msg}`);return q$.delete(Z),{chatId:Z,disbanded:!0}}async function iB($,Z){let J;do{let Q=await Y$.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.get failed code=${Q.code} msg=${Q.msg}`);for(let W of Q.data?.items??[])if(W.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await Y$.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.create failed code=${Y.code} msg=${Y.msg}`);return!0}async function c7($){try{let Z=await T0(),Y=await(await R1(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return _(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return q$.set($,Q),_(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return _(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return _(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function gQ($,Z,J,Y){let Q=F7(),W=null;for(let H=0;H<R4.length;H++){if(R4[H]>0)await new Promise((V)=>setTimeout(V,R4[H]));try{let V=await Y$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(V?.code&&V.code!==0)return _(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${V.code} msg=${V.msg}`),null;return V?.data?.message_id??null}catch(V){W=V,_(`feishu: send${$==="text"?"Text":"Card"} attempt ${H+1}/${R4.length} chat=${Z} failed: ${V}`)}}return _(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${R4.length} retries: ${W}`),null}async function mQ($){let Z=await Y$.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw Error(`feishu chat.get failed code=${Z.code} msg=${Z.msg}`);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function cQ($){return $===null||$==="normal"}async function E($,Z){return gQ("text",$,"text",JSON.stringify({text:Z}))}async function u($,Z){return gQ("card",$,"interactive",JSON.stringify(g0(Z)))}async function B0($,Z){let J=await Y$.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(g0(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){try{let J=await T0(),Q=await(await R1("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Q?.code!==0)return _(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return _(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function m$($,Z){if(!$)return null;try{return(await Y$.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return _(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function E$($,Z){if(!$||!Z)return;try{await Y$.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){_(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function O1($,Z){if(!$){_("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){_(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await T0(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let W=await(await R1(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(W?.code!==0){_(`feishu: urgentApp ${$} code=${W?.code} msg=${W?.msg}`);return}let H=W.data?.invalid_user_id_list??[],V=Z.length-H.length;_(`feishu: urgentApp ${$} ok — delivered=${V}${H.length?` invalid=${H.length}`:""}`)}catch(Q){_(`feishu: urgentApp ${$} failed: ${Q}`)}}async function x4($,Z,J,Y){try{let Q=await T0(),W=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await R1(W,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){_(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let V=Buffer.from(await H.arrayBuffer());j7(b5,{recursive:!0});let X=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,z=J8(b5,`${Date.now()}-${X}`);return kQ(z,V),_(`feishu: downloaded ${J} ${z} (${V.length}B)`),z}catch(Q){_(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function nB($){return dB.has(hB($).toLowerCase())}async function uQ($){let Z=await T0(),J=new Blob([Uint8Array.from(await xQ($))]),Y=new FormData;Y.append("image_type","message"),Y.append("image",J,M1($));let W=await(await R1("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return _(`feishu: uploadImage ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.image_key??null}async function p7($){try{let Z=SQ($);if(!Z.isFile())return _(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>u7)return _(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return _(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return uQ($)}async function aB($){let Z=await T0(),J=new Blob([Uint8Array.from(await xQ($))]),Y=new FormData;Y.append("file_type","stream"),Y.append("file_name",M1($)),Y.append("file",J,M1($));let W=await(await R1("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return _(`feishu: uploadFile ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.file_key??null}async function G8($,Z){try{let J=await Y$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"image",content:JSON.stringify({image_key:Z})}});if(J?.code&&J.code!==0)return _(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return _(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function pQ($,Z){try{let J=await Y$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"file",content:JSON.stringify({file_key:Z})}});if(J?.code&&J.code!==0)return _(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return _(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function C4($,Z){try{let Y=SQ(Z);if(!Y.isFile())return await E($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>u7)return await E($,`❌ 出站文件: ${M1(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return await E($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=nB(Z);try{if(J){let Y=await uQ(Z);if(!Y)return await E($,`❌ 出站图片上传失败: ${M1(Z)}`),!1;return await G8($,Y)!=null}else{let Y=await aB(Z);if(!Y)return await E($,`❌ 出站文件上传失败: ${M1(Z)}`),!1;return await pQ($,Y)!=null}}catch(Y){return _(`feishu: uploadAndSend ${Z} failed: ${Y}`),await E($,`❌ 出站文件异常: ${M1(Z)} — ${Y}`),!1}}function l7($){j7($,{recursive:!0}),_(`feishu: provisioned ${$}`);let Z=J8(FQ(),".codex","config.toml");try{j7(J8(FQ(),".codex"),{recursive:!0});let J="";try{J=F1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
109
+ `,(Y)=>Y?J(Y):Z())})}isAlive(){return this.alive}request($,Z,J=z3){let Y=this.nextId++;return new Promise((Q,W)=>{if(!this.alive){W(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;W(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:W,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
110
+ `,(V)=>{if(!V)return;let z=this.pending.get(Y);if(!z)return;this.pending.delete(Y),clearTimeout(z.timer),z.reject(Error(`codex app-server write failed for ${$}: ${V.message}`))})}catch(V){this.pending.delete(Y),clearTimeout(H),W(V instanceof Error?V:Error(String(V)))}})}async close($=2000){if(!this.alive)return;if(this.proc.exitCode!==null||this.proc.signalCode!==null){if(!await this.waitForExit($))throw Error("codex app-server stdio did not close after exit");return}if(!this.proc.kill("SIGTERM"))throw Error("codex app-server rejected SIGTERM");if(await this.waitForExit($))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await this.waitForExit($))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}async waitForExit($){let Z;try{return await Promise.race([this.exitPromise.then(()=>!0),new Promise((J)=>{Z=setTimeout(()=>J(!1),$)})])}finally{if(Z!==void 0)clearTimeout(Z)}}};q4=new Map,l0=new Map});import{existsSync as iB,readFileSync as dB}from"node:fs";class OQ{deps;constructor($){this.deps=$}blocks(){if(!iB(this.deps.stateFile))return[];let $=JSON.parse(dB(this.deps.stateFile,"utf8"));if($?.version!==1||!Array.isArray($.blocks)||$.blocks.some((Z)=>typeof Z?.key!=="string"||typeof Z?.identity!=="string"||typeof Z?.meter!=="string"||!Array.isArray(Z?.windows)||Z.windows.some((J)=>!["fiveHour","weekly"].includes(J?.kind)||J.percent!==null&&!Number.isFinite(J.percent)||J.reset!==null&&!Number.isFinite(J.reset))))throw Error("Codex 额度耗尽记录格式无效");return $.blocks}block($,Z){if(!$.usage)throw Error("未读取额度,不能记录耗尽窗口");let J=$.usage.state==="ok"?Y4($.usage,Z):null,Y=["fiveHour","weekly"].flatMap((V)=>{let z=J?.[V];return z?[{kind:V,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Q=N5($.usage,Z),W=JSON.stringify([$.identity,Q]),H=this.blocks().filter((V)=>V.key!==W);H.push({key:W,identity:$.identity,meter:Q,windows:Y}),t(this.deps.stateFile,{version:1,blocks:H})}async choose($){$.signal?.throwIfAborted();let Z=this.deps.accounts();if($.preferred){let J=Z.find((Y)=>Y.id===$.preferred);if(!J)throw Error(`指定 Codex 账号不存在:${$.preferred}`);return{selected:{account:J,identity:`record:${J.id}`,usage:null,state:"manual",score:null,shares:null,remaining:null,hours:null},candidates:[]}}if($.preferCachedUsage){let J=await this.chooseAutomatic(Z,$,!0);if(J.selected)return J}return this.chooseAutomatic(Z,$,!1)}async chooseAutomatic($,Z,J){Z.signal?.throwIfAborted();let Y=await Promise.all($.map(async(A)=>{let j,P=null,S=`record:${A.id}`;if(this.deps.pendingLogin(A.id))j={state:"network",reason:"正在登录"};else try{j=J?this.deps.cachedUsage(A.id):await this.deps.usage(A.id);let F=j?.state==="ok"?j.accountFingerprint??this.deps.identity(A.id):null;if(F)S=F;else if(j?.state==="ok")P="账号身份 MISS";if(j?.state==="ok"&&!P)P=await this.deps.compatible(A.id,Z.model,Z.effort)}catch(F){j={state:"network",reason:String(F)}}return{account:A,usage:j,identity:S,reason:P}}));Z.signal?.throwIfAborted();let Q=Z.failedAccountId&&Y.find((A)=>A.account.id===Z.failedAccountId);if(Q&&Q.usage?.state==="ok")this.block({account:Q.account,usage:Q.usage,identity:Q.identity,...E5(Q.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let W=this.blocks(),H=this.deps.now(),V=new Set,z=new Map,X=Y.map(({account:A,usage:j,identity:P,reason:S})=>{let F=E5(j??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(S)F={...F,state:"miss",score:null,reason:S};let R=z.get(P);if(z.set(P,R??A.name),R)F={...F,state:"miss",score:null,reason:`重复账号:${R}`};let M=j?.state==="ok"?N5(j,Z.model):null,k=W.find((C)=>(C.identity===P||C.identity===`record:${A.id}`)&&C.meter===M);if(k&&j?.state==="ok"&&F.state==="ready"){let C=Y4(j,Z.model);if(!J&&k.windows.some((b)=>{let h=C[b.kind];return h&&h.percent!==null&&(b.percent!==null&&h.percent<b.percent||b.reset!==null&&b.reset<=H&&(h.resetsAt?.getTime()??0)>b.reset)}))V.add(k.key);else F={...F,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:A,usage:j,identity:P,...F,...R?{duplicateOf:R}:{}}});if(V.size)t(this.deps.stateFile,{version:1,blocks:W.filter((A)=>!V.has(A.key))});let G=X.filter((A)=>A.state==="ready");G.sort((A,j)=>j.score-A.score||(j.availableNow??0)-(A.availableNow??0)||A.account.id.localeCompare(j.account.id));let K=G[0]??null,B=X.filter((A)=>A.state==="exhausted"||A.state==="waiting"),L=B.length?Math.min(...B.map((A)=>A.retryAt??H+60000)):void 0;for(let A of X)_(`codex scheduler${J?" [cache]":""}: ${A.account.name} ${A.state} score=${A.score??"MISS"}${A.reason?` (${A.reason})`:""}`);return{selected:K,candidates:X,...L!==void 0?{retryAt:L}:{}}}}var e9;var X3=T(()=>{I$();i0();Y$();H$();f$();I();e9=new OQ({accounts:()=>y.list(),usage:M1,cachedUsage:FQ,identity:($)=>y.fingerprint($),pendingLogin:O5,now:Date.now,stateFile:MJ,compatible:async($,Z,J)=>{let Y=V$("codex-sub",$);if(!Y)return"订阅来源 MISS";if(Y.modelCatalogState?.status!=="ready")await Y.refreshModels();if(!Y.enabled||Y.modelCatalogState?.status!=="ready")return Y.modelCatalogState?.error??"模型目录 MISS";let Q=_0(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as nB}from"node:events";function rB($,Z){return Z.throwIfAborted(),new Promise((J,Y)=>{let Q=()=>{clearTimeout(H),Z.removeEventListener("abort",W)},W=()=>{Q(),Y(Z.reason)},H=setTimeout(()=>{Q(),J()},$);Z.addEventListener("abort",W,{once:!0})})}var aB="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",oB,G3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),_3;var TQ=T(()=>{I$();X3();i0();I();oB=["error","conversation_materialized","conversation_materialization_failed","token_usage","turn_plan_updated","plan_delta","context_compacted","rate_limits_updated","thread_goal_updated","thread_goal_cleared","assistant_text","assistant_block_stop","tool_use","tool_result","can_use_tool","hook_callback","bg_task_started","bg_task_progress","bg_task_updated","bg_task_settled","subagent_step","raw"];_3=class _3 extends nB{opts;provider="codex";tokenSourceId="codex-sub";launchKind;inner=null;selected=null;revision=null;ready=null;recovery=null;shutdown=null;lifetime=new AbortController;closed=!1;initialized=!1;starting=!1;retryTurn=!1;retryCount=0;ownRetry=null;result=null;fault=null;inputs=[];lastSession=null;backgroundTasks=new Set;resolveQuotaWait;quotaWait=new Promise(($)=>{this.resolveQuotaWait=$});constructor($){super();this.opts=$;this.launchKind=$.launch.kind,this.on("error",()=>{})}get sessionId(){return this.inner?.sessionId??this.lastSession}get lastAssistantUuid(){return this.inner?.lastAssistantUuid??null}get lastCompletedTurnId(){return this.result||this.ownRetry?null:this.inner?.lastCompletedTurnId??null}get lastModel(){return this.inner?.lastModel??this.opts.model}get lastEffort(){return this.inner?.lastEffort??this.opts.effort??null}get lastThinkingTokens(){return this.inner?.lastThinkingTokens??null}get lastUsage(){return this.inner?.lastUsage??null}get lastTotalUsage(){return this.inner?.lastTotalUsage??null}get lastResult(){return this.result??this.inner?.lastResult??G3()}get lastContextWindow(){return this.inner?.lastContextWindow??null}get lastContextTokens(){return this.inner?.lastContextTokens??null}get turnRetry(){return this.ownRetry??this.inner?.turnRetry??null}sourceRevision(){return this.revision}codexAccountSelectionMode(){return this.selected?this.selected.state==="manual"?"manual":"automatic":null}isAlive(){return!this.closed}isConversationResumable(){return this.inner?.isConversationResumable?.()===!0}conversationMaterializationBarrier(){return this.inner?.conversationMaterializationBarrier?.()??null}conversationMaterializationFailure(){return this.inner?.conversationMaterializationFailure?.()??null}initializationPromise(){if(!this.ready)this.sendInitialize();return this.ready}quotaWaitPromise(){return this.quotaWait}sendInitialize(){if(this.ready)return;this.ready=this.launch(this.opts.launch,this.opts.preferred),this.ready.catch(($)=>{if(!this.lifetime.signal.aborted)this.fail($)})}scheduler(){return this.opts.scheduler??e9}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},_(`codex account: ${$}`),this.emit("turn_retry",this.ownRetry)}async choose($,Z){let J={model:this.opts.model||this.lastModel||"",effort:this.opts.effort??this.lastEffort??void 0,preferred:$,failedAccountId:Z,preferCachedUsage:!0,signal:this.lifetime.signal};while(!0){let Y=await this.scheduler().choose(J);if(delete J.failedAccountId,this.lifetime.signal.throwIfAborted(),Y.selected)return{...Y,selected:Y.selected};J.preferCachedUsage=!1;let Q=Y.candidates.map((V)=>`${V.account.name}:${V.reason??V.state}`).join(";");if(Y.retryAt===void 0)throw Error(`没有可用的 Codex 账号;${Q}`);let W=Math.max(1000,Math.min(60000,Y.retryAt-Date.now())),H=Y.candidates.filter((V)=>V.state==="miss"&&!V.duplicateOf).length;_(`codex account: waiting for quota: ${Q}`),this.notice(`暂无可用账号 · 自动等待恢复${H?` · ${H} 个 MISS`:""}`,W),this.resolveQuotaWait(),await(this.opts.wait??rB)(W,this.lifetime.signal)}}async launch($,Z,J){this.starting=!0;let Y=await this.choose(Z,J);this.lifetime.signal.throwIfAborted();let Q=this.selected?.account.id??null,{process:W,sourceRevision:H}=this.opts.create(Y.selected.account.id,$,Y.selected.state==="manual",this.opts.model||this.lastModel||void 0,this.opts.effort??this.lastEffort??void 0);this.inner=W,this.selected=Y.selected,this.revision=H,Y2(this,Y.selected.account.id,!1),this.wire(W),this.emit("codex_account_changed",{accountId:Y.selected.account.id,previousAccountId:Q,diagnostics:Y.candidates.filter((z)=>z.usage!==null&&z.state==="miss"&&!z.duplicateOf).map((z)=>`${z.account.name}:${z.reason}`)}),this.lifetime.signal.throwIfAborted(),W.sendInitialize();let V=W.initializationPromise?.();if(!V)throw Error("Codex 初始化未提供确认事务");if(await V,this.lifetime.signal.throwIfAborted(),this.lastSession=W.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:W.sessionId});if(!this.recovery)this.drainInputs()}wire($){for(let Z of oB)$.on(Z,(...J)=>{if(this.inner===$&&!this.closed){if(Z==="bg_task_started")this.backgroundTasks.add(J[0].task_id);if(Z==="bg_task_settled")this.backgroundTasks.delete(J[0].task_id);this.emit(Z,...J)}});$.on("turn_retry",(Z)=>{if(this.inner===$&&!this.closed)this.emit("turn_retry",Z)}),$.on("turn_started",(Z)=>{if(this.inner!==$||this.closed)return;this.result=null,this.ownRetry=null;let J=this.retryTurn||Z.retry;this.retryTurn=!1,this.emit("turn_started",{...Z,...J?{retry:!0}:{}})}),$.on("result",(Z)=>{if(this.inner!==$||this.closed||this.lifetime.signal.aborted)return;if(Z?.is_error&&Z.codexQuotaFailure&&!this.recovery){this.retryCount++;let J=Promise.resolve().then(()=>this.recover($,Z.codexQuotaFailure)).catch((Y)=>{if(!this.lifetime.signal.aborted)this.fail(Y)}).finally(()=>{if(this.recovery===J)this.recovery=null});this.recovery=J,this.notice(`「${this.selected?.account.name??"MISS"}」额度耗尽 · 正在换号续跑`);return}if(this.recovery)return;this.retryCount=0,this.result=null,this.emit("result",Z)}),$.on("exit",(Z)=>{if(this.inner!==$||this.closed)return;if((this.recovery||this.shutdown)&&Z.expected)return;this.lifetime.abort(Error("Codex 进程退出")),this.closed=!0,this.emit("exit",Z)})}async recover($,Z){if(this.lifetime.signal.throwIfAborted(),!this.selected)throw Error("额度耗尽时未记录运行账号");if($.readRateLimits){let V=await s9(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),V?.state==="ok")this.selected={...this.selected,usage:V,identity:V.accountFingerprint??this.selected.identity};else this.notice("已确认额度耗尽 · 用量读取 MISS,正在换号")}let J=this.selected.usage===null?this.selected.account.id:void 0;if(this.selected.usage)this.scheduler().block(this.selected,this.lastModel??this.opts.model);let Y=$.conversationMaterializationBarrier?.();if(Y)await Y;this.lifetime.signal.throwIfAborted();let Q=$.isConversationResumable?.()===!0&&$.sessionId;if(Z.accepted&&!Q)throw Error("额度耗尽后未确认原会话落盘,不能重放已执行的任务");if(!Z.accepted&&typeof Z.rejectedInput!=="string")throw Error("额度耗尽的拒绝响应缺少原始输入");let W=Q?{kind:"resume",source:{provider:"codex",sessionId:$.sessionId,cwd:this.opts.workDir}}:this.opts.launch;if(await $.kill(),$.isAlive())throw Error("旧 Codex 进程退出未确认,不能启动下一账号");for(let V of this.backgroundTasks)this.emit("bg_task_settled",{task_id:V,status:"failed",summary:"账号额度耗尽,原进程已退出;主任务换号后继续"});this.backgroundTasks.clear(),this.lifetime.signal.throwIfAborted(),await this.launch(W,void 0,J),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let H=Z.accepted?aB:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(H),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...G3(),is_error:!0,subtype:"codex_account_failed"},this.emit("error",Z),this.emit("result",{...this.result,error:Z.message,checkpoint:null})}sendUserText($,Z=[]){if(this.fault)throw this.fault;if(this.closed||this.lifetime.signal.aborted)throw Error("Codex 进程已关闭");if(this.result=null,this.inputs.push({text:$,files:[...Z]}),!this.ready)this.sendInitialize();if(!this.starting&&!this.recovery)this.drainInputs()}drainInputs(){if(!this.inner||this.starting||this.recovery||this.lifetime.signal.aborted)return;while(this.inputs.length){let $=this.inputs.shift();this.inner.sendUserText($.text,$.files)}}sendInterrupt(){if(this.inputs.length=0,!this.recovery&&!this.starting){this.inner?.sendInterrupt();return}this.lifetime.abort(Error("用户已停止额度恢复")),this.ownRetry=null,this.result={...G3(),subtype:"interrupted"},this.emit("result",{...this.result,checkpoint:null}),this.kill().catch(($)=>this.emit("error",$))}kill($){if(this.shutdown)return this.shutdown;return this.lifetime.abort(Error("Codex 已停止")),this.inputs.length=0,this.ownRetry=null,this.shutdown=Promise.resolve().then(async()=>{if(await this.inner?.kill($),this.inner?.isAlive())throw Error("Codex 退出未确认");if(!this.closed)this.closed=!0,this.emit("exit",{code:0,signal:null,expected:!0})}).catch((Z)=>{throw this.shutdown=null,Z}),this.shutdown}active(){if(!this.inner||this.starting||this.recovery||!this.inner.isAlive())throw Error("Codex 正在选择或恢复账号");return this.inner}async listModels(){return await this.initializationPromise(),this.active().listModels()}async setModelSettings($,Z){await this.active().setModelSettings($,Z)}async compactThread(){await this.active().compactThread()}async readRateLimits(){let $=this.active();if(!$.readRateLimits)throw Error("Codex 额度接口 MISS");return $.readRateLimits()}respondingChild(){if(!this.inner?.isAlive()||this.lifetime.signal.aborted)throw Error("Codex 请求所属进程已退出");return this.inner}sendPermissionResponse(...$){this.respondingChild().sendPermissionResponse(...$)}sendHookResponse(...$){this.respondingChild().sendHookResponse(...$)}}});function j4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new _3({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,B,L,A,j)=>j4({...$,model:A,effort:j,codexAccountPreference:void 0,codexManualAccount:L,codexAccountId:K,launch:B})}),sourceRevision:null}}let Z=$.codexAccountId??p,J=V$($.tokenSourceId,Z),Y=$.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexManualAccount===!0;if($.tokenSourceId&&!J)throw Error(`token source not found: ${$.tokenSourceId}`);if(J&&!J.enabled&&!Y)throw Error(`token source disabled: ${J.id}`);if(J&&J.agent!==$.provider)throw Error(`token source ${J.id} belongs to ${J.agent}, not ${$.provider}`);if(!Y&&J?.modelCatalogState?.status==="failed")throw Error(`model catalog refresh failed for ${J.id}: ${J.modelCatalogState.error??"MISS"}`);if(!Y&&(J?.modelCatalogState?.status==="idle"||J?.modelCatalogState?.status==="loading"))throw Error(`model catalog is not ready for ${J.id}: ${J.modelCatalogState.status}`);let Q=$.model||J?.defaultModel||void 0,W=_2(J,Q),H=!Y&&J&&_0(J,Q);if(!Y&&J&&Q&&!H)throw Error(`model is not present in token source ${J.id}: ${Q}`);if(!Y&&H&&(H.unavailableReason||!H.efforts.length||$.effort!==void 0&&!H.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Q}/${$.effort??"MISS"}`);let V=!Y&&J&&Q?J.resolveSpawnModel(Q):Q;if(Q&&!V)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Q}`);let z=J?(G)=>J.spawnEnv(G,V):void 0;if($.provider==="dsh"){if(!J||!V||!K$($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new r5({...$,model:V,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:W}}if($.provider==="claude"){if(Y3(),!T$($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new n9({workDir:$.workDir,model:V,effort:$.effort,...$.launch?.kind==="fresh"||!$.launch?{}:{resumeSessionId:$.launch.source.sessionId,...$.launch.kind==="fork"?{forkSession:!0}:{},...$.launch.kind==="fork"&&$.launch.through?.provider==="claude"?{resumeSessionAt:$.launch.through.id}:{}},...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},...$.profile?{profile:$.profile}:{},...J?{settingSources:J.settingSources??["project","local"]}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv}),sourceRevision:W}}if($.effort!==void 0&&!a$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let X=new W2({workDir:$.workDir,model:V,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z});return Y2(X,Z),{process:X,sourceRevision:W}}var K3=T(()=>{P$();dY();G4();j1();Y$();I$();TQ()});function $8($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}import{execFile as tB}from"node:child_process";import{readFileSync as B3,statfsSync as sB,statSync as NQ}from"node:fs";import{cpus as eB,homedir as $A}from"node:os";import{promisify as ZA}from"node:util";function YA(){try{let $=B3("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:eB().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return _(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function QA(){try{let $=B3("/proc/meminfo","utf8"),Z=(W)=>{let H=$.match(new RegExp(`^${W}:\\s+(\\d+)\\s*kB`,"m"));return H?parseInt(H[1],10)*1024:0},J=Z("MemTotal"),Y=Z("MemAvailable");if(!J)return null;let Q=Math.max(0,J-Y);return{totalBytes:J,availBytes:Y,usedBytes:Q,percent:Math.round(Q/J*100)}}catch($){return _(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function EQ($,Z){try{let J=sB(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,W=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:W,percent:Math.round(W/Y*100)}}catch(J){return _(`sysinfo: statfs ${Z} failed: ${J}`),null}}function WA(){let $=[],Z=EQ("/","/");if(Z)$.push(Z);let J=$A();if(J&&J!=="/"){let Y=!1;try{let Q=NQ("/"),W=NQ(J);Y=Q.dev===W.dev}catch{}if(!Y){let Q=EQ("$HOME",J);if(Q)$.push(Q)}}return $}function HA(){try{let $=B3("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function SQ($,Z=2000){try{let{stdout:J}=await JA("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return _(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function kQ($){return xQ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function VA(){let $=await SQ(["list-units","--type=service","--all","--no-legend","--plain",...xQ.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
111
+ `).map((z)=>z.trim()).filter((z)=>z.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let z of Z){let G=z.replace(/^●\s*/,"").split(/\s+/)[0];if(!G)continue;if(!kQ(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await SQ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=HA(),W=Y.split(/\n\s*\n/),H=[],V=(z)=>{let X=parseInt(z??"0",10);if(X<=0||Q===null)return null;return Math.max(0,Q-X/1e6)};for(let z of W){let X={};for(let K of z.split(`
112
+ `)){let B=K.indexOf("=");if(B<=0)continue;X[K.slice(0,B)]=K.slice(B+1)}let G=X.Id??"";if(!kQ(G))continue;H.push({name:G.replace(/\.service$/,""),active:X.ActiveState??"unknown",sub:X.SubState??"",lastActiveAgoSec:V(X.ActiveEnterTimestampMonotonic),stateAgoSec:V(X.StateChangeTimestampMonotonic)})}return H.sort((z,X)=>z.name.localeCompare(X.name)),{services:H,error:null}}async function CQ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=YA(),Z=QA(),J=WA(),{services:Y,error:Q}=await VA();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var JA,xQ,P4="cc-* / codex-*";var A3=T(()=>{I();JA=ZA(tB),xQ=["cc-","codex-"]});function M4($,Z){return Z}function q3($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:U.footer,content:M4($.title,$.status)}]}}}function bQ($){if($<1024)return`${$}B`;if($<1048576)return`${($/1024).toFixed(0)}K`;if($<1073741824)return`${($/1048576).toFixed(0)}M`;let Z=$/1073741824;return Z<10?`${Z.toFixed(1)}G`:`${Z.toFixed(0)}G`}function zA($){if(!$)return"0";if($<1000)return String($);if($<1e6)return($/1000).toFixed($<1e4?1:0).replace(/\.0$/,"")+"K";return($/1e6).toFixed(2).replace(/\.?0+$/,"")+"M"}function D4($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Y=Z%60;if(J<24)return`${J}h ${Y}m`;return`${Math.floor(J/24)}d ${J%24}h`}function F4($){if(!$)return"?";let Z=$.getTime()-Date.now();if(Z<=0)return"已重置";if(Z<3600000)return`${Math.max(1,Math.round(Z/60000))}m`;if(Z<86400000)return`${(Z/3600000).toFixed(1)}h`;return`${(Z/86400000).toFixed(1)}d`}function KA($){let Z=[];if($?.cpu)Z.push(`L${$.cpu.load1.toFixed(2)}`);if($?.mem)Z.push(`M${$.mem.percent}%`);if($&&!$.servicesError)Z.push(`S${$.services.length}`);return Z}function BA($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${P4} _n/a_`].join(`
113
+ `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:W}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${W.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${bQ($.mem.usedBytes)}/${bQ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${P4} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${P4} _无_`);else{Z.push(`**服务** ${P4} (${$.services.length})`);for(let J of $.services){let Y=_A[J.active]??"·",Q=J.lastActiveAgoSec,W=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(W!=null)H.push(`已运行 ${D4(W*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${D4(Q*1000)}前`);else H.push("从未启动");if(W!=null){let V=J.active==="failed"?"已挂":"已停";H.push(`${V} ${D4(W*1000)}`)}}else if(W!=null)H.push(`已 ${D4(W*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
114
+ `)}function AA($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=XA[J.status]??"·",Q=GA[J.status]??J.status,W=J.uptimeMs!=null&&J.uptimeMs>0?` · ${D4(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"";return` · ${Y} \`${J.name}\` · ${Q}${W}${H}`}).join(`
115
+ `)}function Z8($,Z=U.consoleProjects){let J=$.peers??[];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83D\uDDC2 活跃项目 (${J.length})`}},expanded:!1,elements:[{tag:"markdown",content:AA($)}]}}function qA($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${F3($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
116
+ `)}function J8($,Z=U.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:qA($)}}function Y8($,Z=U.consoleHost){let J=KA($);return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:J.length>0?`\uD83D\uDDA5 主机 · ${J.join(" · ")}`:"\uD83D\uDDA5 主机"}},expanded:!1,elements:[{tag:"markdown",content:BA($)}]}}function Q8($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(Y,Q)=>`${Q==="USD"?"$":Q==="CNY"?"¥":`${Q} `}${Y.toFixed(2)}`;if($.kind==="balance")return $.balance?`余额 ${J($.balance.remaining,$.balance.currency)}`:"余额 MISS";if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${J($.quota.remaining,$.quota.currency)} / ${J($.quota.limit,$.quota.currency)}`;if(!$.windows.length)return"额度 MISS";return`额度 ${$.windows.map(yQ).join(" · ")}`}function yQ($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function LA($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.map(yQ)].join(`
117
+ `):Q8($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=$?.resetCredits===void 0?"":`
118
+ **重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`;return Z+J}function R4($){let Z=LA($.unifiedUsage);return{tag:"markdown",element_id:U.consoleUsage,content:Z}}function wQ($,Z){return[J8($,Z),Z8($),Y8($.sysinfo),R4($)]}function L3($){let{sessionName:Z,status:J}=$,Y=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Y},body:{elements:wQ($)}}}function j3($){return L2($.sessionName,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${F1($.currentDisplay??"未选择")}
119
+ 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:U.modelAgentGroup(Z),expanded:!0,header:{title:{tag:"markdown",content:`**Agent · ${{claude:"Claude Code",codex:"Codex",dsh:"DeepSeek Harness"}[Z]}**`},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"8px",margin:"8px 0px 0px 0px",elements:J.map((Y)=>jA(Y,$.panelId))}]:[]})]})}function jA($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${B0($.display)}** · 未配置`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启"},type:"primary",behaviors:[{type:"callback",value:{kind:"token_source_enable",source_id:$.sourceId}}]}]}]};let J=$.catalogStatus==="failed"?`模型目录 MISS${$.catalogError?`:${$.catalogError}`:""}`:$.catalogStatus==="loading"||$.catalogStatus==="idle"?"模型目录加载中":`${$.modelCount} 个模型`,Y=[$.selected?"当前账号":"",J].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${B0($.display)}**
120
+ ${Y}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:{kind:"provider_select",panel_id:Z,source_id:$.sourceId,...$.provider?{provider:$.provider}:{}}}]}]}]}}function P3($){return L2($.sessionName,fQ($))}function D3($){return L2($.sessionName,V8($))}function W8($){return L2($.sessionName,z8($),"green")}function L2($,Z,J="turquoise"){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83E\uDD16 model · ${$}`},template:J},body:{elements:[Z]}}}function fQ($){let Z=MA($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${vQ($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
121
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?PA($.panelId,$.pagination):[],...$.editable&&$.allowCustom?[{tag:"button",text:{tag:"plain_text",content:"补录模型"},type:"default",behaviors:[{type:"callback",value:{kind:"model_custom_prompt",panel_id:$.panelId,source_id:$.sourceId}}]}]:[],{tag:"button",text:{tag:"plain_text",content:$.editable?$.mode==="add"?"返回模型列表":"显示模型":"补录模型"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:$.editable?"model_list_open":"model_custom_prompt",panel_id:$.panelId,...$.sourceId||$.models[0]?.sourceId?{source_id:$.sourceId??$.models[0]?.sourceId}:{},...$.editable?{mode:$.mode==="add"?"select":"add"}:{}}}]}]}}function PA($,Z){let{sourceId:J,page:Y,totalPages:Q}=Z,W=(H,V)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:H},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:V}}]}]});return[{tag:"markdown",content:`第 ${Y+1} / ${Q} 页`},{tag:"column_set",columns:[...Y>0?[W("上一页",Y-1)]:[],...Y+1<Q?[W("下一页",Y+1)]:[]]}]}function H8($,Z="cancelled"){return L2($,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function M3($,Z,J){return L2($,{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
122
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function j2($,Z,J){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
123
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function V8($){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${UA($.model)}`,`当前: ${vQ($.currentModel,$.currentEffort)}`].join(`
124
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>FA($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function z8($){return{tag:"collapsible_panel",element_id:U.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",F1(hQ($.model,$.effort,$.provider)),B0($.scope)].join(`
125
+ `)}]}}function DA($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${B0($.displayName)}** · 未配置
126
+ ${B0($.description??"")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启"},type:"primary",behaviors:[{type:"callback",value:{kind:"token_source_enable",source_id:$.sourceId}}]}]}]}];let Q=$.displayName&&$.displayName!==$.model?`**${B0($.displayName)}**`:`**${F1($.model)}**`,W=[$.isDefault?`${F3($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
127
+ `+B0(OA($.description,110)):"",V=(X,G)=>({tag:"button",text:{tag:"plain_text",content:G},type:"default",behaviors:[{type:"callback",value:{kind:X,panel_id:Z,source_id:$.sourceId,model:$.model}}]});return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,vertical_align:"center",elements:[{tag:"markdown",content:[Q,$.displayName&&$.displayName!==$.model?F1($.model):"",W.length?W.join(" · "):""].filter(Boolean).join(`
128
+ `)+H}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[V("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:RA($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?V("model_custom_remove","删"):V("model_remove","隐")]:[]]}]}]}function MA($,Z,J,Y=!1){let Q=[{title:"Codex",models:$.filter((V)=>(V.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((V)=>V.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((V)=>V.provider==="dsh")}].filter((V)=>V.models.length>0),W=(V)=>V.flatMap((z,X)=>[...X?[{tag:"hr"}]:[],...DA(z,Z,J,Y)]);if(Q.length<=1)return W($);let H=[];for(let V of Q)H.push({tag:"markdown",content:`**${V.title}**`}),H.push(...W(V.models));return H}function FA($,Z,J,Y,Q){let W=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",W?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":B0(Z.effort)}**`,H,Z.description?B0(Z.description):""].filter(Boolean).join(`
129
+ `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:W?"primary":"default",behaviors:[{type:"callback",value:{kind:"model_effort_select",panel_id:J,...$.sourceId?{source_id:$.sourceId}:{},...$.provider?{provider:$.provider}:{},model:$.model,effort:Z.effort}}]}]}]}}function RA($,Z){return{kind:"model_select",panel_id:Z,...$.sourceId?{source_id:$.sourceId}:{},...$.provider&&$.provider!=="codex"?{provider:$.provider}:{},model:$.model,display_name:$.displayName,is_default:$.isDefault===!0,efforts:$.efforts.map((J)=>({effort:J.effort,description:J.description??"",is_default:J.isDefault===!0}))}}function UA($){return $.displayName&&$.displayName!==$.model?`${B0($.displayName)} (${F1($.model)})`:F1($.model)}function vQ($,Z){return F1(hQ($,Z))}function hQ($,Z,J){let Y=J&&J!=="codex"?`${F3(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function F3($){return X0($??"codex")}function OA($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function B0($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function F1($){return"`"+$.replace(/`/g,"\\`")+"`"}function T0($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec)Z.push(`⏱ ${$.durationSec}s`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${zA($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var XA,GA,_A;var R3=T(()=>{P$();A3();C$();XA={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},GA={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},_A={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});var mQ={};P0(mQ,{codexAccountSummary:()=>U4,codexAccountPanel:()=>O4,codexAccountCard:()=>Y0,CODEX_ACCOUNTS_PAGE_SIZE:()=>X8});function N0($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function U3($){return{tag:"column_set",flex_mode:"none",horizontal_spacing:"12px",columns:$.map((Z)=>({tag:"column",width:"weighted",weight:1,vertical_align:"center",vertical_spacing:"4px",elements:Z}))}}function U4($){let[Z,J]=gQ[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function Y0($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:U4($)}},body:{elements:[O4($)]}}}function O4($){let[,,Z]=gQ[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(b$(["连接","授权","就绪"].map((Q,W)=>W===Y?`**${W+1} ${Q}**`:`${W<Y?"✓":W+1} ${Q}`).join(" → ")))}if($.phase==="waiting"&&$.verification){let Y=new URL($.verification.url);if(Y.protocol!=="https:"||/[\s<>]/.test($.verification.url))throw Error("授权链接无效");if(!/^[A-Za-z0-9-]{1,64}$/.test($.verification.code))throw Error("验证码格式无效");J.push(U3([[g$("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[b$(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),g$("登录账号,输入左侧验证码")]]))}if($.current)J.push(U3([[g$("当前使用"),b$(`**${N0($.current)}**`)],...$.selected&&$.selected!==$.current?[[g$("下次启动"),b$(`**${N0($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(b$([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>N0(Y)).join(" · ")));if($.message)J.push(b$(N0($.message)));if($.total)J.push(...TA($));if($.hint)J.push(g$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[b$(N0($.details))]});return{tag:"collapsible_panel",element_id:U.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:U4($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function TA($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/X8)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[g$(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],W=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort((H,V)=>V.score-H.score||(V.availableNow??0)-(H.availableNow??0)||H.account.id.localeCompare(V.account.id));if($.scheduling)Q.push(g$(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${W.length}`));for(let H of Z.entries.slice((Y-1)*X8,Y*X8)){let V=[H.account.id===$.currentId?"使用中":"",H.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),z=H.usage,X=[];if(Q.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${H.account.name}${V.length?` · ${V.join(" · ")}`:""}`},background_color:H.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:X}),H.duplicateOf){X.push(g$(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}let G=$.scheduling?.candidates.find((A)=>A.account.id===H.account.id);if(G){let A=W.findIndex((j)=>j.account.id===H.account.id);if(X.push(G.state==="ready"?b$(`**#${A+1} · ${G.score.toPrecision(3)} 份/h**`):g$(G.state==="exhausted"?"⏳ 耗尽 · 暂不参与":G.state==="excluded"?"Ultra 自动排除 Plus":G.state==="waiting"?`⏳ 周余量 ${G.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),G.state==="ready"&&G.remaining!=null)X.push(g$(`周余量 ${G.remaining.toPrecision(3)} 份${G.fiveHourRemaining!=null?` · 5h ${G.fiveHourRemaining.toPrecision(3)} 份`:""}`));if(G.state==="miss"&&G.reason&&z.state==="ok")X.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[b$(N0(G.reason))]})}if(z.state!=="ok"){if(X.push(b$(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)X.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[b$(N0(z.reason))]});continue}let K=z.subscriptionType==="pro"?"Pro 20×":z.subscriptionType==="prolite"?"Pro 5×":z.subscriptionType==="plus"?"Plus 1×":z.subscriptionType??"套餐 MISS";X.push(g$(`${K} · 重置卡 ${z.resetCredits??"MISS"}`));let B=[IQ(z.fiveHour,"5h"),IQ(z.weekly,"周")].filter((A)=>A!==null);if(B.length)X.push(U3(B));let L=z.buckets?.filter((A)=>A.limitId!==z.defaultLimitId)??[];if(L.length)X.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:`其他额度 · ${L.length}`}},elements:L.map((A)=>b$(`${N0(A.limitName??A.limitId)} · ${NA(A.fiveHour,A.weekly)}`))})}if(J>1)Q.push(g$(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}function IQ($,Z){if(!$)return null;let J=$.percent;if(J===null||!Number.isFinite(J)||J<0||J>100)return[b$(`**${Z} · MISS**`)];let Y=Math.round(J/100*8),Q=J>=100?"red":J>=80?"orange":"green";return[b$(`**${Z} · ${Math.round(J)}%**
130
+ <font color='${Q}'>${"▰".repeat(Y)}${"▱".repeat(8-Y)}</font>`),g$($.unreportedFull?"满窗 · 0.15 份":$.resetsAt?`${F4($.resetsAt)} 重置`:"重置时间 MISS")]}function NA($,Z){return[$?`5h ${$.percent??"MISS"}${$.percent===null?"":"%"}`:"",Z?`周 ${Z.percent??"MISS"}${Z.percent===null?"":"%"}`:""].filter(Boolean).join(" · ")}var X8=4,gQ,b$=($)=>({tag:"markdown",content:$}),g$=($)=>({tag:"markdown",content:`<font color='grey'>${N0($)}</font>`,text_size:"notation"});var P2=T(()=>{C$();R3();gQ={connecting:["\uD83D\uDD04","连接中","blue"],waiting:["\uD83D\uDD10","等待授权","blue"],checking:["\uD83D\uDD0E","校验中","blue"],success:["✅","登录成功","green"],selected:["\uD83C\uDFAF","下次启动生效","green"],current:["\uD83E\uDDED","当前账号","blue"],accounts:["\uD83D\uDDC2","账号与额度","blue"],cancelled:["⏹","已取消","grey"],expired:["⌛","等待超时","orange"],error:["❌","未完成","red"],warning:["⚠️","需要处理","orange"]}});async function O3($){let Z=await E3("feishu chat.get",()=>Q$.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)G8("feishu chat.get",Z);let J=Z.data?.owner_id;if(!J)throw Error("feishu chat.get returned no owner_id; cannot add project group owner to tasklist");return J}async function T3($,Z){let J=await E3("feishu tasklist.create",()=>Q$.task.v2.tasklist.create({params:{user_id_type:"open_id"},data:{name:$,members:[{id:Z,type:"user",role:"editor"}]}}));if(J.code&&J.code!==0)G8("feishu tasklist.create",J);let Y=J.data?.tasklist,Q=Y?.guid;if(!Q)throw Error("feishu tasklist.create returned no guid");return{guid:Q,name:Y?.name||$,url:Y?.url??"",createdAt:Y?.created_at}}async function N3($){let Z=await E3("feishu tasklist.delete",()=>Q$.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)G8("feishu tasklist.delete",Z)}function cQ($,Z){let J=Z&&typeof Z==="object"?Z:{},Y=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Q=Y.code??J.code,W=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,V=Array.isArray(H)?H.map((z)=>z?.scope??z?.subject??z?.name??z).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${W}${V?` missing_scopes=${V}`:""}`}async function E3($,Z){try{return await Z()}catch(J){G8($,J)}}function G8($,Z){throw Error(cQ($,Z))}var pQ=T(()=>{$$()});var W$={};P0(W$,{writeAliveMarker:()=>d3,urgentApp:()=>N1,uploadImageKey:()=>$7,uploadAndSend:()=>w4,updateCard:()=>q0,unbindSessionChat:()=>B8,tempProjectName:()=>A0,tempChatName:()=>c3,setPendingConversationLaunchChecked:()=>n0,sendTextRaw:()=>w,sendText:()=>N,sendImage:()=>M8,sendFile:()=>_W,sendCard:()=>u,sanitizeSessionName:()=>J7,resolveProjectDir:()=>L8,replaceTurnAnchors:()=>r$,registerTempSessionLease:()=>w3,refreshChatList:()=>b4,readAliveMarker:()=>n3,provisionProject:()=>Z7,projectProfile:()=>M2,preferredChatForSession:()=>q$,loadTempSessionLeases:()=>y3,loadSessionTurnsMap:()=>g3,loadSessionResumeMap:()=>h3,loadSessionModelMap:()=>p3,loadSessionChatMap:()=>v3,listNormalChatIdsByName:()=>P8,isOpenAIChatGPTAuthenticated:()=>f4,hasTempSessionLease:()=>f3,getTurnAnchors:()=>k4,getTenantToken:()=>E0,getSessionResumeRef:()=>d0,getSessionModelSelection:()=>l3,getSessionBranchBase:()=>x4,getPendingConversationLaunch:()=>C4,formatFeishuApiError:()=>cQ,findNormalChatIdByName:()=>D8,fetchChatOwnerOpenId:()=>O3,fetchChatName:()=>s3,ensureChatForSession:()=>a3,downloadAttachment:()=>y4,disbandChatForSessionExact:()=>t3,disbandChatForSession:()=>r3,deleteTasklistByGuid:()=>N3,deleteReaction:()=>S$,createTempChatForSession:()=>o3,createTasklistWithOwner:()=>T3,client:()=>Q$,clearSessionResumeChecked:()=>F2,clearSessionConversationState:()=>i3,chatNameCache:()=>L$,chatIdForSession:()=>j8,bindSessionToChat:()=>D2,bindSessionResumeChecked:()=>S4,bindSessionModelChecked:()=>T1,bindSessionModel:()=>u3,appendTurnAnchorChecked:()=>m3,addReaction:()=>c$,PROJECTS_ROOT:()=>JW,MAX_UPLOAD_BYTES:()=>e3});import*as oQ from"@larksuiteoapi/node-sdk";import{execSync as EA}from"node:child_process";import{randomUUID as b3}from"node:crypto";import{mkdirSync as k3,readFileSync as U1,statSync as rQ,writeFileSync as tQ}from"node:fs";import{readFile as sQ}from"node:fs/promises";import{homedir as uQ}from"node:os";import{basename as R1,extname as SA,isAbsolute as eQ,join as K8}from"node:path";import{sync as kA}from"cross-spawn";function x3(){let $={};for(let[Z,J]of m$)$[Z]=J;t(g6,$)}function y3(){m$.clear();try{let $=JSON.parse(U1(g6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Y=J;if(typeof Z!=="string"||!Z||Y.chatId!==Z||typeof Y.sessionName!=="string"||!A0(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){_(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}m$.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}_(`feishu: loaded ${m$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")_(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function w3($,Z){if(!A0($))throw Error(`refusing to lease non-temporary session name "${$}"`);if(!Z)throw Error("cannot lease a temporary session without chat_id");for(let Q of m$.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=m$.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};m$.set(Z,Y);try{x3()}catch(Q){if(J)m$.set(Z,J);else m$.delete(Z);throw Q}}function f3($,Z){let J=m$.get(Z);return J?.sessionName===$&&J.chatId===Z}function M2($){return f.projects[$]}function L8($){return M2($)?.cwd?.trim()||K8(JW,$)}function O1($,Z={}){return J$($,{...Z,signal:Z.signal??AbortSignal.timeout(xA)})}async function E0(){if(_8&&Date.now()<lQ)return _8;return S3??=(async()=>{let $=await O1("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:$W,app_secret:ZW})}),Z=await $.json();if(!$.ok||!Z.tenant_access_token)throw Error(`feishu: tenant token failed HTTP ${$.status} code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);return _8=Z.tenant_access_token,lQ=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,_8})().finally(()=>{S3=null}),S3}function v3(){try{let $=JSON.parse(U1(f6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")q$.set(Z,J);_(`feishu: loaded ${q$.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function YW(){try{C3()}catch($){_(`feishu: save session-chat-map failed: ${$}`)}}function C3(){let $={};for(let[Z,J]of q$)$[Z]=J;t(f6,$)}function D2($,Z){if(q$.get($)===Z)return;let J=q$.get($);q$.set($,Z),YW(),_(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function B8($){let Z=q$.get($);if(!Z)return;q$.delete($),YW(),_(`feishu: unbound session "${$}" from ${Z}`)}function N4($,Z){let J=A$.get($)??{};J[Z.provider]=Z,A$.set($,J)}function iQ($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=z0(J.provider)?J.provider:Z??null;if(!Y||Z&&Y!==Z)return null;let Q=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Q)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Y,sessionId:Q,cwd:null};if(typeof J.cwd!=="string"||!eQ(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function dQ($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!z0($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!eQ($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function CA($,Z,J){if(typeof $!=="string")return dQ($);if(!Z)throw Error("cannot bind a conversation without a provider");return dQ({provider:Z,sessionId:$,cwd:J??null})}function h3(){try{let $=JSON.parse(U1(v6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");A$.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){N4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=iQ(Y);if(Q){N4(Z,Q);continue}for(let W of H5){let H=Y[W];if(typeof H==="string"&&H.trim()){N4(Z,{provider:W,sessionId:H.trim(),cwd:null});continue}let V=iQ(H,W);if(V)N4(Z,V)}}_(`feishu: loaded ${A$.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function A8(){let $={};for(let[Z,J]of A$){let Y={};if(J.codex)Y.codex={...J.codex};if(J.claude)Y.claude={...J.claude};if(J.dsh)Y.dsh={...J.dsh};$[Z]=Y}t(v6,$)}function S4($,Z,J,Y){let Q=CA(Z,J,Y),W=A$.get($),H=W?{...W}:void 0,V=W?.[Q.provider];if(V?.sessionId===Q.sessionId&&V.cwd===Q.cwd)return;N4($,Q);try{A8()}catch(z){if(H)A$.set($,H);else A$.delete($);throw z}}function d0($,Z="codex"){let J=A$.get($)?.[Z];return J?{...J}:null}function F2($,Z){let J=A$.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)A$.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)A$.delete($);else A$.set($,Q)}try{A8()}catch(Q){throw A$.set($,Y),Q}}function QW($){if(!$||typeof $!=="object")return null;let Z=$;if(!z0(Z.provider))return null;let J=typeof Z.sessionId==="string"?Z.sessionId.trim():"";if(!J)return null;let Y;if(Z.cwd===void 0||Z.cwd===null)Y=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Y=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Y}}function WW($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=QW(J),Q=typeof Z.id==="string"?Z.id.trim():"";if(!Q||!Y)return null;if(Z.provider==="dsh"&&Z.kind==="event"&&Y.provider==="dsh"&&/^\d+$/.test(Q)&&Number.isSafeInteger(Number(Q)))return{provider:"dsh",kind:"event",id:Q,source:{...Y,provider:"dsh"}};if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Y.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Q,source:{...Y,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Y.provider==="codex")return{provider:"codex",kind:"turn",id:Q,source:{...Y,provider:"codex"}};return null}function HW($){if(!$||typeof $!=="object")return null;let Z=$;if(Z.kind==="fresh")return{kind:"fresh"};if(Z.kind!=="resume"&&Z.kind!=="fork")return null;let J=QW(Z.source);if(!J)return null;let Y=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Q=WW(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{B$(Y,J.provider)}catch{return null}return Y}function bA($){if(!Array.isArray($))return[];return $.filter((Z)=>Z&&typeof Z.path==="string").map((Z)=>({tool:String(Z.tool??"Write"),path:String(Z.path),body:String(Z.body??"")})).filter((Z)=>Z.path!==""||Z.body!=="")}function yA($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Y=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Q=WW(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let W=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!W||!H)return null;Q={provider:"claude",kind:"assistant-message",id:W,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:bA(J.writes)}}function wA($){if(!$||typeof $!=="object")return null;let Z=$,J=HW(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Y=Z.previousSessionId,Q=Y===null?null:typeof Y==="string"&&Y.trim()?Y.trim():void 0;if(Q===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Q}}function I3($){let Z=$.launch.through;if($.launch.source.provider!=="claude"||Z&&(Z.provider!=="claude"||Z.kind!=="assistant-message"||Z.source.provider!=="claude"))throw Error("pending conversation launch is not a Claude fork");return{launch:{kind:"fork",source:{...$.launch.source,provider:"claude"},...Z?{through:{...Z,provider:"claude",kind:"assistant-message",source:{...Z.source,provider:"claude"}}}:{}},previousSessionId:$.previousSessionId}}function g3(){try{let $=JSON.parse(U1(h6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");s.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let W,H,V=null;if(Array.isArray(Q))W=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let K=Q;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(W=K.anchors,K.base===null)H=null;else{let B=HW(K.base);if(!B){J++;continue}H=B}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let B=wA(K.pendingLaunch);if(!B){J++;continue}V=B}}else{J++;continue}let z=A$.get(Y),X=z?.claude!==void 0&&z.codex===void 0?"claude":null,G=[];for(let K of W){let B=yA(K,X);if(B)G.push(B);else J++}if(G.length||H!==null||V)s.set(Y,{base:H,anchors:G,...V?{pendingLaunch:V}:{}}),Z+=G.length}if(_(`feishu: loaded ${Z} turn anchors across ${s.size} sessions`),J>0)_(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function E4(){let $={};for(let[Z,J]of s)$[Z]=J;t(h6,$)}function m3($,Z){let J=s.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>nQ){let W=Y.splice(0,Y.length-nQ),H=W[W.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}s.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{E4()}catch(W){if(J)s.set($,J);else s.delete($);throw W}}function k4($){return s.get($)?.anchors??[]}function x4($){return s.get($)?.base??null}function C4($){let Z=s.get($)?.pendingLaunch;return Z?I3(Z):null}function n0($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");B$(Z.launch,"claude",Z.launch.source.cwd)}let J=s.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)s.delete($);else s.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:I3(Z)}:{}});try{E4()}catch(W){if(J)s.set($,J);else s.delete($);throw W}}function r$($,Z,J,Y){let Q=s.get($),W=Y===void 0?Q?.pendingLaunch:Y??void 0,H=W?I3(W):void 0;if(Z.length===0&&J===null&&!H)s.delete($);else s.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{E4()}catch(V){if(Q)s.set($,Q);else s.delete($);throw V}}function A0($){return aQ.test($)?$.replace(aQ,""):null}function c3($,Z=[]){let J=new Date,Y=(V)=>String(V).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,W=new Set([...L$.values(),...s.keys(),...Z]),H=`${$}*${Q}`;for(let V=2;W.has(H);V++)H=`${$}*${Q}-${V}`;return H}function p3(){try{let $=JSON.parse(U1(I6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){E$.set(Z,{provider:$2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,W=z0(Q)?Q:typeof Y==="string"&&Y.trim()?$2(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(W==="claude"&&!H)continue;let{effort:V,tokenSourceId:z}=J,X=typeof z==="string"&&z.trim()?z.trim():null,G=W==="dsh"?K$(V)?V:null:W==="claude"?T$(V)?V:null:a$(V)?V:null;E$.set(Z,{provider:W,model:H,effort:G,...X?{tokenSourceId:X}:{}})}_(`feishu: loaded ${E$.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")_(`feishu: load session-model-map failed: ${$?.message??$}`)}}function fA(){try{q8()}catch($){_(`feishu: save session-model-map failed: ${$}`)}}function q8(){let $={};for(let[Z,J]of E$)$[Z]=J;t(I6,$)}function u3($,Z,J,Y,Q){let W=E$.get($);if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;E$.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),fA()}function T1($,Z,J,Y,Q){let W=E$.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;E$.set($,H);try{q8()}catch(V){if(W)E$.set($,W);else E$.delete($);throw V}}function l3($){let Z=E$.get($);if(Z)return Z;let J=A0($);return J?E$.get(J)??null:null}function i3($){let Z=q$.get($),J=A$.get($),Y=E$.get($),Q=s.get($),W=[...m$.entries()].filter(([,H])=>H.sessionName===$);q$.delete($),A$.delete($),E$.delete($),s.delete($);for(let[H]of W)m$.delete(H);try{C3(),A8(),q8(),E4(),x3()}catch(H){if(Z)q$.set($,Z);if(J)A$.set($,J);if(Y)E$.set($,Y);if(Q)s.set($,Q);for(let[z,X]of W)m$.set(z,X);let V=[H];for(let z of[C3,A8,q8,E4,x3])try{z()}catch(X){V.push(X)}throw V.length===1?V[0]:AggregateError(V,`failed to clear and restore conversation state for ${$}`)}}function d3($){t(c6,$)}function n3(){let $;try{$=U1(c6,"utf8")}catch(J){if(J.code==="ENOENT")return[];throw J}let Z=JSON.parse($);if(!Array.isArray(Z)||Z.some((J)=>typeof J!=="string"||!J.trim()))throw Error("invalid alive session marker: expected non-empty session names");return Z}function j8($){let Z=q$.get($);if(Z){let Y=L$.get(Z);if(Y&&Y!==$)_(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of L$)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)_(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function b4(){try{let $;do{let Z=await Q$.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)L$.set(J.chat_id,J.name);$=Z.data?.page_token}while($);_(`feishu: refreshed chat list — ${L$.size} groups`)}catch($){_(`feishu: refresh chat list failed: ${$}`)}}async function P8(){let $=new Map,Z;do{let J=await Q$.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Y of J.data?.items??[]){if(!Y.chat_id||!Y.name)continue;if(Y.chat_status&&Y.chat_status!=="normal")continue;L$.set(Y.chat_id,Y.name);let Q=$.get(Y.name)??[];Q.push(Y.chat_id),$.set(Y.name,Q)}Z=J.data?.page_token}while(Z);return $}async function D8($){let Z=q$.get($);if(Z&&L$.get(Z)===$){let W=await zW(Z);if(W.name===$&&XW(W.status))return Z;L$.delete(Z),B8($)}let Y=(await P8()).get($)??[];if(Y.length===0)return null;let Q=q$.get($);if(Q&&Y.includes(Q))return Q;if(Y.length===1)return Y[0];throw Error(`multiple Feishu groups named "${$}": ${Y.join(", ")}`)}async function a3($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await D8($);if(J){let W=await vA(J,Z);return D2($,J),{chatId:J,created:!1,joined:W}}let Y=await Q$.im.chat.create({params:{user_id_type:"open_id",uuid:b3()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return L$.set(Q,$),D2($,Q),{chatId:Q,created:!0,joined:!0}}async function o3($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await D8($))throw Error(`temporary group name already exists: ${$}`);let Y=await Q$.im.chat.create({params:{user_id_type:"open_id",uuid:b3()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return L$.set(Q,$),D2($,Q),{chatId:Q,created:!0,joined:!0}}async function r3($){let Z=await D8($);if(!Z)return B8($),{chatId:null,disbanded:!1};let J=await Q$.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw Error(`feishu chat.delete failed code=${J.code} msg=${J.msg}`);if(L$.delete(Z),q$.get($)===Z)B8($);return{chatId:Z,disbanded:!0}}async function t3($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await zW(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!XW(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await Q$.im.chat.delete({path:{chat_id:Z}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.delete failed code=${Y.code} msg=${Y.msg}`);return L$.delete(Z),{chatId:Z,disbanded:!0}}async function vA($,Z){let J;do{let Q=await Q$.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.get failed code=${Q.code} msg=${Q.msg}`);for(let W of Q.data?.items??[])if(W.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await Q$.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.create failed code=${Y.code} msg=${Y.msg}`);return!0}async function s3($){try{let Z=await E0(),Y=await(await O1(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return _(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return L$.set($,Q),_(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return _(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return _(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function VW($,Z,J,Y){let Q=b3(),W=null;for(let H=0;H<T4.length;H++){if(T4[H]>0)await new Promise((V)=>setTimeout(V,T4[H]));try{let V=await Q$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(V?.code&&V.code!==0)return _(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${V.code} msg=${V.msg}`),null;return V?.data?.message_id??null}catch(V){W=V,_(`feishu: send${$==="text"?"Text":"Card"} attempt ${H+1}/${T4.length} chat=${Z} failed: ${V}`)}}return _(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${T4.length} retries: ${W}`),null}async function zW($){let Z=await Q$.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw Error(`feishu chat.get failed code=${Z.code} msg=${Z.msg}`);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function XW($){return $===null||$==="normal"}async function N($,Z){return VW("text",$,"text",JSON.stringify({text:Z}))}async function u($,Z){return VW("card",$,"interactive",JSON.stringify(c0(Z)))}async function q0($,Z){let J=await Q$.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(c0(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){try{let J=await E0(),Q=await(await O1("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Q?.code!==0)return _(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return _(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function c$($,Z){if(!$)return null;try{return(await Q$.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return _(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function S$($,Z){if(!$||!Z)return;try{await Q$.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){_(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function N1($,Z){if(!$){_("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){_(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await E0(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let W=await(await O1(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(W?.code!==0){_(`feishu: urgentApp ${$} code=${W?.code} msg=${W?.msg}`);return}let H=W.data?.invalid_user_id_list??[],V=Z.length-H.length;_(`feishu: urgentApp ${$} ok — delivered=${V}${H.length?` invalid=${H.length}`:""}`)}catch(Q){_(`feishu: urgentApp ${$} failed: ${Q}`)}}async function y4($,Z,J,Y){try{let Q=await E0(),W=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await O1(W,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){_(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let V=Buffer.from(await H.arrayBuffer());k3(p6,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,X=K8(p6,`${Date.now()}-${z}`);return tQ(X,V),_(`feishu: downloaded ${J} ${X} (${V.length}B)`),X}catch(Q){_(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function IA($){return hA.has(SA($).toLowerCase())}async function GW($){let Z=await E0(),J=new Blob([Uint8Array.from(await sQ($))]),Y=new FormData;Y.append("image_type","message"),Y.append("image",J,R1($));let W=await(await O1("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return _(`feishu: uploadImage ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.image_key??null}async function $7($){try{let Z=rQ($);if(!Z.isFile())return _(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>e3)return _(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return _(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return GW($)}async function gA($){let Z=await E0(),J=new Blob([Uint8Array.from(await sQ($))]),Y=new FormData;Y.append("file_type","stream"),Y.append("file_name",R1($)),Y.append("file",J,R1($));let W=await(await O1("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return _(`feishu: uploadFile ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.file_key??null}async function M8($,Z){try{let J=await Q$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"image",content:JSON.stringify({image_key:Z})}});if(J?.code&&J.code!==0)return _(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return _(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function _W($,Z){try{let J=await Q$.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"file",content:JSON.stringify({file_key:Z})}});if(J?.code&&J.code!==0)return _(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return _(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function w4($,Z){try{let Y=rQ(Z);if(!Y.isFile())return await N($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>e3)return await N($,`❌ 出站文件: ${R1(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return await N($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=IA(Z);try{if(J){let Y=await GW(Z);if(!Y)return await N($,`❌ 出站图片上传失败: ${R1(Z)}`),!1;return await M8($,Y)!=null}else{let Y=await gA(Z);if(!Y)return await N($,`❌ 出站文件上传失败: ${R1(Z)}`),!1;return await _W($,Y)!=null}}catch(Y){return _(`feishu: uploadAndSend ${Z} failed: ${Y}`),await N($,`❌ 出站文件异常: ${R1(Z)} — ${Y}`),!1}}function Z7($){k3($,{recursive:!0}),_(`feishu: provisioned ${$}`);let Z=K8(uQ(),".codex","config.toml");try{k3(K8(uQ(),".codex"),{recursive:!0});let J="";try{J=U1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
91
131
 
92
132
  `:""}${Y}
93
133
  trust_level = "trusted"
94
- `,kQ(Z,J)}}catch(J){_(`feishu: codex trust write failed for ${$}: ${J}`)}try{vB("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function b4($=l){let Z=IB(J4(),["login","status",...y.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:y.env($,{...process.env,...f.codex.env})});if(Z.error)_(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
95
- ${Z.stderr}`)}function i7($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var bQ,yQ,wQ,g$,Y$,gB=15000,Z8="",RQ=0,L7=null,q$,A$,B$,s,TQ=200,NQ,N$,R4,u7=31457280,dB;var $$=T(()=>{L$();k$();q1();L$();W$();I();h$();w$();x$();A1();MQ();bQ=f.feishu.app_id,yQ=f.feishu.app_secret,wQ=f.runtime.projects_root,g$=new Map;Y$=new EQ.Client({appId:bQ,appSecret:yQ,disableTokenCache:!1});q$=new Map,A$=new Map;B$=new Map;s=new Map;NQ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;N$=new Map;R4=[0,1000,4000];dB=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as lQ}from"node:crypto";function d7($,Z){if($===300305||$===200860)return!0;if($!==300315)return!1;let J=Z?.message??"";return/(?:code\s*[:=]\s*(?:300305|200860)\b|number of card components[^\n.]{0,60}exceed|\bcard over max size\b)/i.test(J)}function iQ($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function d0($){let Z=J0.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function N0($){return!J0.has($)}function c$($,Z,J){J0.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,failedReplacements:new Set,onFailure:J,closing:!1})}function n7($){return J0.get($)?.elementCount??0}function dQ($){let Z=J0.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function F2($,Z){return J0.get($)?.deadElements.has(Z)??!1}function nQ($,Z){let J=J0.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function _8($){let Z=d0($);return Z.sequence+=1,Z.sequence}function aQ($,Z){$.deadElements.add(Z)}function oQ($){return lQ("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function eB($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==U.footer)Y.push(J);return lQ("sha256").update(Y.sort().join(`
96
- `)).digest("hex")}async function M2($,Z,J){let Y=await T0(),Q=await fetch(`${oB}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(rB)}),W=await Q.json();if(!Q.ok||W?.code!==0){let H=typeof W?.code==="number"?W.code:Q.status,V=Q.headers.get("x-tt-logid")??Q.headers.get("x-request-id")??Q.headers.get("request-id")??void 0,X=Error(`cardkit ${$} ${Z}: HTTP ${Q.status} code=${String(W?.code??"MISS")} msg=${W?.msg??"MISS"}${V?` log_id=${V}`:""}`);throw X.code=H,X.httpStatus=Q.status,X.logId=V,X}return W?.data}function $A($){return new Promise((Z)=>setTimeout(Z,$))}function ZA($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function JA($){let Z=_8($);await M2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function a7($,Z,J,Y,Q=!1,W={}){let H=(V)=>{let X=typeof V==="object"&&V!==null?V:null,z={cardId:$,operation:Z,elementId:W.elementId,targetElementId:W.targetElementId,code:X?.code,httpStatus:X?.httpStatus,logId:X?.logId,message:V instanceof Error?V.message:String(V)};if(d7(z.code,z))z.capacityFingerprint=eB(d0($),W.elementId,W.contentFingerprint);try{if(!Q)d0($).onFailure?.(z.code,z)}catch(G){_(`cardkit failure callback ${$}: ${G}`)}try{Y?.(z)}catch(G){_(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(V){if(!ZA(V)){_(`cardkit ${Z} ${$}: ${V}`),H(V);return}_(`cardkit ${Z} ${$}: streaming closed (code=${V.code}) — reopening`)}try{await JA($)}catch(V){_(`cardkit STREAMING_REOPEN_FAILED ${$}: ${V}`),H(V);return}try{await J()}catch(V){_(`cardkit ${Z} ${$} retry-after-reopen: ${V}`),H(V)}}function YA($){return typeof $==="object"&&$!==null&&$.code===200740}async function o$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:tB,Y=null;for(let Q=0;Q<J.length;Q++){let W=J[Q]??0;if(W>0)await $A(W);try{let H=await M2("POST","/cards/id_convert",{message_id:$});if(typeof H?.card_id!=="string"||!H.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return H.card_id}catch(H){if(Y=H,!YA(H)||Q===J.length-1)throw H;let V=J[Q+1]??0;_(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${V}ms`)}}throw Y}async function r$($){let Z=J0.get($);if(!Z)return;await Z.queue}function j$($,Z,J={},Y){if(N0($))return Promise.resolve();let Q=d0($);if(Q.closing)return Promise.resolve();let W=g0(Z),H=W.element_id,V=oQ(W),X=()=>{if(!H)return;aQ(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>a7($,"addElement",async()=>{let z=_8($);if(await M2("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([W]),sequence:z}),Q.elementCount+=1,H!==U.footer)Q.contentFingerprints.set(H??`#${z}`,V);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(z)=>{X(),Y?.(z.code,z)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:V})),Q.queue}function Z$($,Z,J,Y,Q=!0){if(N0($))return Promise.resolve();let W=d0($);if(W.closing)return Promise.resolve();let H=g0(J),V=oQ(H),X=()=>{aQ(W,Z),W.failedReplacements.add(Z)};return W.queue=W.queue.then(()=>a7($,`replaceElement ${Z}`,async()=>{let z=W.failedAdds.get(Z);if(W.deadElements.has(Z)&&!z&&!W.failedReplacements.has(Z))return;let G=_8($);if(z)await M2("POST",`/cards/${$}/elements`,{type:z.type??"append",...z.targetElementId?{target_element_id:z.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),W.elementCount++;else await M2("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(W.deadElements.delete(Z),W.failedAdds.delete(Z),W.failedReplacements.delete(Z),Z!==U.footer)W.contentFingerprints.set(Z,V)},(z)=>{if(Q)X();Y?.(z.code,z)},!Q,{elementId:Z,contentFingerprint:V})),W.queue}async function z$($,Z,J,Y={}){if(N0($))return!1;let Q=d0($);if(Q.closing)return!1;let W=!1;return await Z$($,Z,J,()=>{W=!0},Y.notifyCardFailure!==!1),!W&&!Q.deadElements.has(Z)}async function n0($,Z,J={}){return(await K8($,Z,J)).landed}async function K8($,Z,J={}){if(N0($))return{landed:!1};let Y=d0($);if(Y.closing)return{landed:!1};let Q=Z.element_id,W;return await j$($,Z,J,(H,V)=>{W=V}),{landed:!W&&!(Q&&Y.deadElements.has(Q)),...W?{failure:W}:{}}}function E0($,Z){if(N0($)||J0.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=T1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},T1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=T1.get($);if(!Q)return;if(N0($)){T1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let W=Q.latest;P$($,{config:{summary:{content:W}}}).then((H)=>{let V=T1.get($);if(H&&V===Q)V.lastSent=W})},sB)}function M$($){let Z=T1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;T1.delete($)}function B8($,Z){return P$($,Z).then(()=>{})}async function P$($,Z){if(N0($))return!1;let J=d0($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>a7($,"patchSettings",async()=>{if(N0($))return;let W=_8($);await M2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:W}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!N0($)}async function b$($){let Z=J0.get($);if(!Z){M$($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,M$($),await Z.queue,J0.delete($)}var oB="https://open.feishu.cn/open-apis/cardkit/v1",rB=15000,tB,J0,T1,sB=1500;var a0=T(()=>{$$();I();x$();tB=[0,250,750,1500];J0=new Map,T1=new Map});function A8($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function q8($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function QA($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),W=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,W/Y*100)))}function tQ($,Z,J){let Y=QA($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function rQ($){let Z=Math.max(0,$);if(Z<1000)return String(Math.round(Z));if(Z<1e6)return(Z/1000).toFixed(Z<1e4?1:0).replace(/\.0$/,"")+"K";return(Z/1e6).toFixed(Z<1e7?1:0).replace(/\.0$/,"")+"M"}function P8($,Z){let J=rQ($);return Z!=null&&Z>0?`${J}/${rQ(Z)}`:`${J}/--`}function sQ($,Z){if(Z==null||Z<=0)return"--";let J=Math.max(0,$/Z*100);if(J>0&&J<1)return"<1%";return`${Math.round(Math.min(100,J))}%`}function r7($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function j8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function WA($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function HA($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function L8($){if(!Number.isFinite($)||$<0)return"--";if($<1000)return String(Math.round($));if($<1e6)return($/1000).toFixed($<1e4?1:0).replace(/\.0$/,"")+"k";return($/1e6).toFixed(2).replace(/\.?0+$/,"")+"m"}function eQ($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function ZW($){let Z=$.filter((W)=>W.status==="completed").length,J=$.filter((W)=>W.status==="inProgress").length,Y=$.filter((W)=>W.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function VA($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${ZW($)}`}function JW($){if(!Number.isFinite($)||$<0)return"MISS";if($<60)return`${Math.round($)}s`;let Z=Math.floor($/60),J=Math.round($%60);if(Z<60)return J?`${Z}m ${J}s`:`${Z}m`;let Y=Math.floor(Z/60),Q=Z%60;return Q?`${Y}h ${Q}m`:`${Y}h`}function o7($){return typeof $==="number"&&Number.isFinite($)?$:null}function XA($){let Z=o7($.startedAtMs),J=o7($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${JW((J-Z)/1000)}`}function zA($){let Z=o7($);return Z==null?null:L8(Z)}function GA($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=zA($.preTokens),W=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(W)J.push(`**来源**: ${W}`);return J.length>0?J:["压缩完成,无摘要内容"]}function t7($,Z,J){if($==null||!Number.isFinite($))return null;let Y=tQ($,Z,J);return Y?`${Y.used}% · ${P8($,Z)}`:"--"}function s7($){let Z=L8($?.input_tokens??Number.NaN),J=L8($?.cache_read_input_tokens??Number.NaN),Y=L8($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function y4($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",W=Q?"✅":"⏳",H=Q?XA(Y):"",V=`${W} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,X=GA(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:X.join(`
97
- `)}]}}function YW($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let W of $)Y.push(`- ${WA(W.status)} ${W.step}`)}else{let W=J.trim();if(Y.push(""),W)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(W);else Y.push("--")}return Y.join(`
98
- `)}function e7($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:VA($,J)}},expanded:!1,elements:[{tag:"markdown",content:YW($,Z,J)}]}}function w4($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${ZW($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:YW($,Z)}]}}function $3($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${eQ($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${JW($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${eQ($.status)}: ${HA($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
99
- `)}]}}function D8($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Y=$.userInputs??[],Q=`\uD83D\uDCE5 收到 (${Y.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,W=Y.length>0?[{tag:"collapsible_panel",element_id:U.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((H)=>({tag:"markdown",content:e(H)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...W,{tag:"markdown",element_id:U.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function QW($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function _A($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function KA($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let W=$.options[Q],H=W.description?` · ${e(W.description)}`:"";Y.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Q}}],elements:[{tag:"markdown",content:`**${e(W.label)}**${H}`}]})}return Y}function $W($,Z,J,Y){if($.length===0)return null;let Q=$.length,W=[];for(let H=0;H<$.length;H++){let V=$[H];if(!V)continue;let X=QW(V,H,Q),z=Y.get(H);if(z){let G=_A(V,z),K=[`**✅ ${X}**`,`**回答**:${G}`];W.push({tag:"markdown",content:K.join(`
100
- `)});continue}if(H===J){if(W.push({tag:"markdown",content:`**\uD83E\uDD14 ${X}**`}),V.options.length>0)W.push(...KA(V,Z,H));W.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}W.push({tag:"markdown",content:`**⏳ ${X}**`})}return W}function R2($,Z,J,Y="\uD83E\uDD14",Q){let W=J.length,H=Q?.answered??new Map,V=Q?.currentIdx,X=V===void 0&&H.size>0,z=[],G;if(Q?.waitingFor)G=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",z.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(X){G=`${Y} 已回答 · ${W}/${W}`,z.push(...$W(J,Z,V,H)??[]);let K=[...H.values()].reverse().find((B)=>B.user)?.user;if(K)z.push({tag:"markdown",content:`
101
- *— 由 ${K} 回答*`})}else if(V!==void 0&&J[V])G=`${Y} 等你确认 · ${V+1}/${W}`,z.push(...$W(J,Z,V,H)??[]);else if(G=`${Y} 等你确认`,J[0])z.push({tag:"markdown",content:`**${QW(J[0],0,W||1)}**`});return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!X&&!Q?.waitingFor,elements:z}}var WW=T(()=>{x$()});import{isAbsolute as Z3,relative as BA}from"node:path";function F8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function R8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function qA($){return F8($)||R8($)}function U8($){return $==="FileChange"||$==="fileChange"}function v4($){return $==="WebSearch"||$==="webSearch"}function O8($){return $==="WebFetch"||$==="webFetch"}function V3($){return $==="MCP"}function h4($){return $==="ImageGeneration"||$==="imageGeneration"}function X3($){return $==="Agent"||$==="Task"}function T8($){return $==="Read"}function N8($){return $==="Write"}function E8($){return $==="Edit"||$==="NotebookEdit"}function S8($){return $==="MultiEdit"}function z3($){return $==="Glob"||$==="Grep"||$==="LS"}function k8($){return $==="TodoWrite"}function x8($){return $==="ExitPlanMode"}function C8($){return $.startsWith(VW)}function XW($){return C8($)?$.slice(VW.length):$}function E1($){if(C8($))return"服务端工具";if(U8($))return"文件变更";if(v4($))return"网页搜索";if(O8($))return"网页读取";if(h4($))return"图片生成";if(T8($))return"读取文件";if(N8($))return"写入文件";if(E8($)||S8($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(k8($))return"更新待办";if(x8($))return"确认计划";if($==="Task")return"子任务";return qA($)?"Bash":$}function o0($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(C8($))return J(PA($,Z),80);if(!Z||typeof Z!=="object")return"";if(F8($))return LA(Z);if(R8($))return jA(Z);if(U8($))return J(FA(Z),80);if(v4($))return J(TW(Z),80);if(O8($))return J(SA(Z),80);if(V3($))return J(xA(Z),80);if(h4($))return J(bA(Z),80);if(X3($))return J(yA(Z),80);if(T8($))return J(RA(Z),80);if(N8($))return J(UA(Z),80);if(E8($))return J(OA(Z),80);if(S8($))return J(TA(Z),80);if(z3($))return J(NA($,Z),80);if(k8($))return J(EA(Z),80);if(x8($))return J(I4(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Y of Object.values(Z))if(typeof Y==="string"&&Y)return J(Y,80);return""}function PA($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:XW($),Y=I4(Z?.input);return Y?`${J}: ${Y}`:J}function LA($){let Z=(W,H)=>W.length>H?W.slice(0,H)+"…":W,J=GW($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Y=J.command;if(!Y)return"";let Q=Y.split(/\r?\n/).map((W)=>W.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(e1(Y),46)}`}function zW($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function jA($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${zW($)}${J}`}function GW($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=X6(Z);return{description:Y.description||J,command:Y.command}}function u$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
134
+ `,tQ(Z,J)}}catch(J){_(`feishu: codex trust write failed for ${$}: ${J}`)}try{EA("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function f4($=p){let Z=kA(Q4(),["login","status",...y.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:y.env($,{...process.env,...f.codex.env})});if(Z.error)_(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
135
+ ${Z.stderr}`)}function J7($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var $W,ZW,JW,m$,Q$,xA=15000,_8="",lQ=0,S3=null,L$,q$,A$,s,nQ=200,aQ,E$,T4,e3=31457280,hA;var $$=T(()=>{n$();P$();x$();j1();P$();H$();I();I$();f$();C$();L1();pQ();$W=f.feishu.app_id,ZW=f.feishu.app_secret,JW=f.runtime.projects_root,m$=new Map;Q$=new oQ.Client({appId:$W,appSecret:ZW,disableTokenCache:!1});L$=new Map,q$=new Map;A$=new Map;s=new Map;aQ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;E$=new Map;T4=[0,1000,4000];hA=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as KW}from"node:crypto";function Y7($,Z){if($===300305||$===200860)return!0;if($!==300315)return!1;let J=Z?.message??"";return/(?:code\s*[:=]\s*(?:300305|200860)\b|number of card components[^\n.]{0,60}exceed|\bcard over max size\b)/i.test(J)}function BW($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function a0($){let Z=Q0.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function S0($){return!Q0.has($)}function p$($,Z,J){Q0.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,failedReplacements:new Set,onFailure:J,closing:!1})}function Q7($){return Q0.get($)?.elementCount??0}function AW($){let Z=Q0.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function U2($,Z){return Q0.get($)?.deadElements.has(Z)??!1}function qW($,Z){let J=Q0.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function F8($){let Z=a0($);return Z.sequence+=1,Z.sequence}function LW($,Z){$.deadElements.add(Z)}function jW($){return KW("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function lA($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==U.footer)Y.push(J);return KW("sha256").update(Y.sort().join(`
136
+ `)).digest("hex")}async function R2($,Z,J){let Y=await E0(),Q=await J$(`${mA}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(cA)}),W=await Q.json();if(!Q.ok||W?.code!==0){let H=typeof W?.code==="number"?W.code:Q.status,V=Q.headers.get("x-tt-logid")??Q.headers.get("x-request-id")??Q.headers.get("request-id")??void 0,z=Error(`cardkit ${$} ${Z}: HTTP ${Q.status} code=${String(W?.code??"MISS")} msg=${W?.msg??"MISS"}${V?` log_id=${V}`:""}`);throw z.code=H,z.httpStatus=Q.status,z.logId=V,z}return W?.data}function iA($){return new Promise((Z)=>setTimeout(Z,$))}function dA($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function nA($){let Z=F8($);await R2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function W7($,Z,J,Y,Q=!1,W={}){let H=(V)=>{let z=typeof V==="object"&&V!==null?V:null,X={cardId:$,operation:Z,elementId:W.elementId,targetElementId:W.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:V instanceof Error?V.message:String(V)};if(Y7(X.code,X))X.capacityFingerprint=lA(a0($),W.elementId,W.contentFingerprint);try{if(!Q)a0($).onFailure?.(X.code,X)}catch(G){_(`cardkit failure callback ${$}: ${G}`)}try{Y?.(X)}catch(G){_(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(V){if(!dA(V)){_(`cardkit ${Z} ${$}: ${V}`),H(V);return}_(`cardkit ${Z} ${$}: streaming closed (code=${V.code}) — reopening`)}try{await nA($)}catch(V){_(`cardkit STREAMING_REOPEN_FAILED ${$}: ${V}`),H(V);return}try{await J()}catch(V){_(`cardkit ${Z} ${$} retry-after-reopen: ${V}`),H(V)}}function aA($){return typeof $==="object"&&$!==null&&$.code===200740}async function t$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:pA,Y=null;for(let Q=0;Q<J.length;Q++){let W=J[Q]??0;if(W>0)await iA(W);try{let H=await R2("POST","/cards/id_convert",{message_id:$});if(typeof H?.card_id!=="string"||!H.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return H.card_id}catch(H){if(Y=H,!aA(H)||Q===J.length-1)throw H;let V=J[Q+1]??0;_(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${V}ms`)}}throw Y}async function s$($){let Z=Q0.get($);if(!Z)return;await Z.queue}function D$($,Z,J={},Y){if(S0($))return Promise.resolve();let Q=a0($);if(Q.closing)return Promise.resolve();let W=c0(Z),H=W.element_id,V=jW(W),z=()=>{if(!H)return;LW(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>W7($,"addElement",async()=>{let X=F8($);if(await R2("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([W]),sequence:X}),Q.elementCount+=1,H!==U.footer)Q.contentFingerprints.set(H??`#${X}`,V);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(X)=>{z(),Y?.(X.code,X)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:V})),Q.queue}function Z$($,Z,J,Y,Q=!0){if(S0($))return Promise.resolve();let W=a0($);if(W.closing)return Promise.resolve();let H=c0(J),V=jW(H),z=()=>{LW(W,Z),W.failedReplacements.add(Z)};return W.queue=W.queue.then(()=>W7($,`replaceElement ${Z}`,async()=>{let X=W.failedAdds.get(Z);if(W.deadElements.has(Z)&&!X&&!W.failedReplacements.has(Z))return;let G=F8($);if(X)await R2("POST",`/cards/${$}/elements`,{type:X.type??"append",...X.targetElementId?{target_element_id:X.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),W.elementCount++;else await R2("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(W.deadElements.delete(Z),W.failedAdds.delete(Z),W.failedReplacements.delete(Z),Z!==U.footer)W.contentFingerprints.set(Z,V)},(X)=>{if(Q)z();Y?.(X.code,X)},!Q,{elementId:Z,contentFingerprint:V})),W.queue}async function G$($,Z,J,Y={}){if(S0($))return!1;let Q=a0($);if(Q.closing)return!1;let W=!1;return await Z$($,Z,J,()=>{W=!0},Y.notifyCardFailure!==!1),!W&&!Q.deadElements.has(Z)}async function o0($,Z,J={}){return(await R8($,Z,J)).landed}async function R8($,Z,J={}){if(S0($))return{landed:!1};let Y=a0($);if(Y.closing)return{landed:!1};let Q=Z.element_id,W;return await D$($,Z,J,(H,V)=>{W=V}),{landed:!W&&!(Q&&Y.deadElements.has(Q)),...W?{failure:W}:{}}}function k0($,Z){if(S0($)||Q0.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=E1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},E1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=E1.get($);if(!Q)return;if(S0($)){E1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let W=Q.latest;j$($,{config:{summary:{content:W}}}).then((H)=>{let V=E1.get($);if(H&&V===Q)V.lastSent=W})},uA)}function F$($){let Z=E1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;E1.delete($)}function U8($,Z){return j$($,Z).then(()=>{})}async function j$($,Z){if(S0($))return!1;let J=a0($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>W7($,"patchSettings",async()=>{if(S0($))return;let W=F8($);await R2("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:W}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!S0($)}async function y$($){let Z=Q0.get($);if(!Z){F$($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,F$($),await Z.queue,Q0.delete($)}var mA="https://open.feishu.cn/open-apis/cardkit/v1",cA=15000,pA,Q0,E1,uA=1500;var r0=T(()=>{n$();$$();I();C$();pA=[0,250,750,1500];Q0=new Map,E1=new Map});function O8($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function T8($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function oA($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),W=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,W/Y*100)))}function DW($,Z,J){let Y=oA($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function PW($){let Z=Math.max(0,$);if(Z<1000)return String(Math.round(Z));if(Z<1e6)return(Z/1000).toFixed(Z<1e4?1:0).replace(/\.0$/,"")+"K";return(Z/1e6).toFixed(Z<1e7?1:0).replace(/\.0$/,"")+"M"}function N8($,Z){let J=PW($);return Z!=null&&Z>0?`${J}/${PW(Z)}`:`${J}/--`}function MW($,Z){if(Z==null||Z<=0)return"--";let J=Math.max(0,$/Z*100);if(J>0&&J<1)return"<1%";return`${Math.round(Math.min(100,J))}%`}function V7($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function S8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function rA($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function tA($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function E8($){if(!Number.isFinite($)||$<0)return"--";if($<1000)return String(Math.round($));if($<1e6)return($/1000).toFixed($<1e4?1:0).replace(/\.0$/,"")+"k";return($/1e6).toFixed(2).replace(/\.?0+$/,"")+"m"}function FW($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function UW($){let Z=$.filter((W)=>W.status==="completed").length,J=$.filter((W)=>W.status==="inProgress").length,Y=$.filter((W)=>W.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function sA($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${UW($)}`}function OW($){if(!Number.isFinite($)||$<0)return"MISS";if($<60)return`${Math.round($)}s`;let Z=Math.floor($/60),J=Math.round($%60);if(Z<60)return J?`${Z}m ${J}s`:`${Z}m`;let Y=Math.floor(Z/60),Q=Z%60;return Q?`${Y}h ${Q}m`:`${Y}h`}function H7($){return typeof $==="number"&&Number.isFinite($)?$:null}function eA($){let Z=H7($.startedAtMs),J=H7($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${OW((J-Z)/1000)}`}function $q($){let Z=H7($);return Z==null?null:E8(Z)}function Zq($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=$q($.preTokens),W=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(W)J.push(`**来源**: ${W}`);return J.length>0?J:["压缩完成,无摘要内容"]}function z7($,Z,J){if($==null||!Number.isFinite($))return null;let Y=DW($,Z,J);return Y?`${Y.used}% · ${N8($,Z)}`:"--"}function X7($){let Z=E8($?.input_tokens??Number.NaN),J=E8($?.cache_read_input_tokens??Number.NaN),Y=E8($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function v4($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",W=Q?"✅":"⏳",H=Q?eA(Y):"",V=`${W} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,z=Zq(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:V}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
137
+ `)}]}}function TW($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let W of $)Y.push(`- ${rA(W.status)} ${W.step}`)}else{let W=J.trim();if(Y.push(""),W)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(W);else Y.push("--")}return Y.join(`
138
+ `)}function G7($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:sA($,J)}},expanded:!1,elements:[{tag:"markdown",content:TW($,Z,J)}]}}function h4($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${UW($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:TW($,Z)}]}}function _7($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${FW($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${OW($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${FW($.status)}: ${tA($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
139
+ `)}]}}function k8($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Y=$.userInputs??[],Q=`\uD83D\uDCE5 收到 (${Y.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,W=Y.length>0?[{tag:"collapsible_panel",element_id:U.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((H)=>({tag:"markdown",content:e(H)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...W,{tag:"markdown",element_id:U.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function NW($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function Jq($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function Yq($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let W=$.options[Q],H=W.description?` · ${e(W.description)}`:"";Y.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Q}}],elements:[{tag:"markdown",content:`**${e(W.label)}**${H}`}]})}return Y}function RW($,Z,J,Y){if($.length===0)return null;let Q=$.length,W=[];for(let H=0;H<$.length;H++){let V=$[H];if(!V)continue;let z=NW(V,H,Q),X=Y.get(H);if(X){let G=Jq(V,X),K=[`**✅ ${z}**`,`**回答**:${G}`];W.push({tag:"markdown",content:K.join(`
140
+ `)});continue}if(H===J){if(W.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),V.options.length>0)W.push(...Yq(V,Z,H));W.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}W.push({tag:"markdown",content:`**⏳ ${z}**`})}return W}function O2($,Z,J,Y="\uD83E\uDD14",Q){let W=J.length,H=Q?.answered??new Map,V=Q?.currentIdx,z=V===void 0&&H.size>0,X=[],G;if(Q?.waitingFor)G=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",X.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){G=`${Y} 已回答 · ${W}/${W}`,X.push(...RW(J,Z,V,H)??[]);let K=[...H.values()].reverse().find((B)=>B.user)?.user;if(K)X.push({tag:"markdown",content:`
141
+ *— 由 ${K} 回答*`})}else if(V!==void 0&&J[V])G=`${Y} 等你确认 · ${V+1}/${W}`,X.push(...RW(J,Z,V,H)??[]);else if(G=`${Y} 等你确认`,J[0])X.push({tag:"markdown",content:`**${NW(J[0],0,W||1)}**`});return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!z&&!Q?.waitingFor,elements:X}}var EW=T(()=>{C$()});import{isAbsolute as K7,relative as Qq}from"node:path";function C8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function b8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function Hq($){return C8($)||b8($)}function y8($){return $==="FileChange"||$==="fileChange"}function g4($){return $==="WebSearch"||$==="webSearch"}function w8($){return $==="WebFetch"||$==="webFetch"}function P7($){return $==="MCP"}function m4($){return $==="ImageGeneration"||$==="imageGeneration"}function D7($){return $==="Agent"||$==="Task"}function f8($){return $==="Read"}function v8($){return $==="Write"}function h8($){return $==="Edit"||$==="NotebookEdit"}function I8($){return $==="MultiEdit"}function M7($){return $==="Glob"||$==="Grep"||$==="LS"}function g8($){return $==="TodoWrite"}function m8($){return $==="ExitPlanMode"}function c8($){return $.startsWith(kW)}function xW($){return c8($)?$.slice(kW.length):$}function k1($){if(c8($))return"服务端工具";if(y8($))return"文件变更";if(g4($))return"网页搜索";if(w8($))return"网页读取";if(m4($))return"图片生成";if(f8($))return"读取文件";if(v8($))return"写入文件";if(h8($)||I8($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(g8($))return"更新待办";if(m8($))return"确认计划";if($==="Task")return"子任务";return Hq($)?"Bash":$}function t0($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(c8($))return J(Vq($,Z),80);if(!Z||typeof Z!=="object")return"";if(C8($))return zq(Z);if(b8($))return Xq(Z);if(y8($))return J(Kq(Z),80);if(g4($))return J(nW(Z),80);if(w8($))return J(Dq(Z),80);if(P7($))return J(Fq(Z),80);if(m4($))return J(Uq(Z),80);if(D7($))return J(Oq(Z),80);if(f8($))return J(Bq(Z),80);if(v8($))return J(Aq(Z),80);if(h8($))return J(qq(Z),80);if(I8($))return J(Lq(Z),80);if(M7($))return J(jq($,Z),80);if(g8($))return J(Pq(Z),80);if(m8($))return J(c4(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Y of Object.values(Z))if(typeof Y==="string"&&Y)return J(Y,80);return""}function Vq($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:xW($),Y=c4(Z?.input);return Y?`${J}: ${Y}`:J}function zq($){let Z=(W,H)=>W.length>H?W.slice(0,H)+"…":W,J=bW($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Y=J.command;if(!Y)return"";let Q=Y.split(/\r?\n/).map((W)=>W.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(J2(Y),46)}`}function CW($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function Xq($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${CW($)}${J}`}function bW($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=D5(Z);return{description:Y.description||J,command:Y.command}}function u$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
102
142
  ${$}
103
- ${J}`}function S0($,Z=AA,J=""){if($.length<=Z)return u$($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,u$(`${Y}
143
+ ${J}`}function x0($,Z=Wq,J=""){if($.length<=Z)return u$($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,u$(`${Y}
104
144
  ... output 已截断 ...`,J)].join(`
105
- `)}function g($){return"`"+String($??"").replace(/`/g,"'")+"`"}function t$($,Z=3000){return u$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function I4($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Y=Z[J];if(typeof Y==="string"&&Y.length>0)return Y}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function _W($,Z,J){let Y=GW($),Q=Y.command,W=Y.description,H=[];if(W)H.push(`**目的**: ${W}`);let V=$?.cwd??$?.workdir;if(V)H.push(`**cwd**: ${g(V)}`);if($?.source)H.push(`**source**: ${g($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(u$(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(S0(Z));return H.join(`
106
- `)}function KW($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${zW($)}`),Q!==void 0)Y.push(`**session**: ${g(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let W=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(u$(W))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(S0(Z));return Y.join(`
107
- `)}function BW($){return Array.isArray($?.changes)?$.changes:[]}function AW($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function f4($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&Z3(J)&&Z3(Z)){let Y=BA(Z,J);if(Y&&!Y.startsWith("..")&&!Z3(Y))return Y}return J}function DA($){let Z=$?.kind;if(typeof Z==="string")return Z.toLowerCase();if(typeof Z?.type==="string")return Z.type.toLowerCase();if(typeof $?.type==="string")return $.type.toLowerCase();return""}function qW($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function Y3($){let Z=DA($);if(qW($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function Q3($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function W3($){let Z=0,J=0;for(let Y of $.split(/\r?\n/)){if(Y.startsWith("+++")||Y.startsWith("---"))continue;if(Y.startsWith("+"))Z++;if(Y.startsWith("-"))J++}return{added:Z,removed:J}}function PW($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function H3($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function MA($){return $.length>1800?$.slice(0,1800)+`
108
- ... diff 已截断 ...`:$}function FA($){let Z=BW($),J=AW($);if(Z.length===0){let X=typeof $?.reason==="string"?$.reason.trim():"",z=$?.grantRoot?f4($.grantRoot):"";if(X&&z)return`${X} · ${z}`;return X||(z?`申请修改 ${z}`:"")}let Y=Z.map((X)=>W3(Q3(X))).reduce(PW,{added:0,removed:0}),Q=H3(Y),W=[...new Set(Z.map(Y3))],H=f4(Z[0]?.path,J),V=Q?` · ${Q}`:"";if(Z.length===1)return`${W[0]} ${H}${V}`;return`${Z.length} 个文件 · ${W.join("/")} · ${H} 等${V}`}function LW($,Z,J){let Y=BW($),Q=AW($),W=[];if(Y.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"";if(z)W.push(`**原因**: ${z}`);if($?.grantRoot)W.push(`**范围**: ${g(f4($.grantRoot))}`);if(J)W.push(""),W.push(J);if(Z!=null)W.push(""),W.push("---"),W.push("**output:**"),W.push(u$(Z.slice(0,3000)));return W.length>0?W.join(`
109
- `):u$(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((z)=>W3(Q3(z))).reduce(PW,{added:0,removed:0}),V=H3(H);if(W.push(`**文件**: ${Y.length} 个`),V)W.push(`**行数**: ${V}`);if($?.status)W.push(`**状态**: ${g($.status)}`);let X=Y.slice(0,5);for(let z of X){let G=Q3(z),K=H3(W3(G)),B=f4(z?.path,Q),A=K?`**${Y3(z)}** ${g(B)} · ${K}`:`**${Y3(z)}** ${g(B)}`;W.push(""),W.push(A);let P=qW(z);if(P)W.push(`来自 ${g(f4(P,Q))}`);W.push(G?u$(MA(G),"diff"):"_无 diff 内容_")}if(Y.length>X.length)W.push(""),W.push(`还有 ${Y.length-X.length} 个文件未展开显示。`);if(J)W.push(""),W.push(J);return W.join(`
110
- `)}function r0($){return String($?.file_path??$?.path??$?.notebook_path??"")}function RA($){let Z=r0($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function UA($){let Z=r0($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function OA($){let Z=r0($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function TA($){let Z=r0($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function NA($,Z){if($==="Glob"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}if($==="Grep"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}return String(Z?.path??"")}function jW($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function EA($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let W=jW(Q?.status);J.set(W,(J.get(W)??0)+1)}let Y=[...J.entries()].map(([Q,W])=>`${Q} ${W}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function SA($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function U2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(S0(Z,1200))}function DW($,Z,J){let Y=[],Q=r0($);if(Q)Y.push(`**路径**: ${g(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${g($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${g($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
111
- `):t$($??{},2000)}function MW($,Z,J){let Y=[],Q=r0($),W=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${g(Q)}`);if(W){let H=W.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${W.length} 字符`),Y.push(S0(W,1200))}if(J)Y.push(""),Y.push(J);return U2(Y,Z),Y.length>0?Y.join(`
112
- `):t$($??{},2000)}function FW($,Z,J){let Y=[],Q=r0($);if(Q)Y.push(`**路径**: ${g(Q)}`);if($?.cell_id)Y.push(`**cell**: ${g($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${g($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(S0($.old_string,800));let W=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(W)Y.push(""),Y.push("**替换为**"),Y.push(S0(W,800));if(J)Y.push(""),Y.push(J);return U2(Y,Z),Y.length>0?Y.join(`
113
- `):t$($??{},2000)}function RW($,Z,J){let Y=[],Q=r0($),W=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${g(Q)}`);Y.push(`**编辑**: ${W.length} 处`);for(let[H,V]of W.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${V?.replace_all?" · 全局替换":""}**`),typeof V?.old_string==="string")Y.push("查找:"),Y.push(S0(V.old_string,500));if(typeof V?.new_string==="string")Y.push("替换为:"),Y.push(S0(V.new_string,500))}if(W.length>5)Y.push(""),Y.push(`还有 ${W.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return U2(Y,Z),Y.join(`
114
- `)}function UW($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${g(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${g(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${g(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${g(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${g(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${g(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${g(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${g(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(g).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return U2(Q,J),Q.join(`
115
- `)}function OW($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let W of Y.slice(0,12)){let H=jW(W?.status),V=String(W?.content??W?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${V}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return U2(Q,Z),Q.join(`
116
- `)}function G3($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function _3($,Z){return G3(Z)??$?.action??{}}function K3($,Z){let J=_3($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((W)=>typeof W==="string"&&W.length>0):[],Q=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Y.length>0?Y:Q?[Q]:[]}function B3($,Z){let J=_3($,Z);return String(J?.url??$?.url??"")}function TW($){let Z=K3($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=B3($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function kA($,Z){let J=K3($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=B3($,Z);if(Y)return Y;return TW($)}function NW($,Z,J){let Y=_3($,Z),Q=K3($,Z),W=B3($,Z),H=[],V=typeof Y?.type==="string"?Y.type:"";if(V==="search"||Q.length>0){if(H.push("**动作**: 搜索"),Q.length>0){H.push(""),H.push("**查询**");for(let X of Q.slice(0,6))H.push(`- ${g(X)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(V==="open_page"){if(H.push("**动作**: 打开页面"),W)H.push(`**URL**: ${g(W)}`)}else if(V==="find_in_page"){if(H.push("**动作**: 页内查找"),W)H.push(`**URL**: ${g(W)}`);if(Y?.pattern)H.push(`**关键词**: ${g(Y.pattern)}`)}else if(H.push(`**动作**: ${V?g(V):"网页搜索"}`),W)H.push(`**URL**: ${g(W)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!W&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(u$(Z.slice(0,3000),"json"));return H.join(`
117
- `)}function EW($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${g($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return U2(Y,Z),Y.join(`
118
- `)}function xA($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=I4($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function SW($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${g($.server)}`);if($?.tool)Y.push(`**tool**: ${g($.tool)}`);let Q=$?.arguments;if(Q&&typeof Q==="object"&&Object.keys(Q).length>0){if(Y.length>0)Y.push("");Y.push("**arguments**"),Y.push(t$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let W=G3(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),W&&Array.isArray(W.content)){let H=W.content.map((V)=>typeof V?.text==="string"?V.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
119
- `).slice(0,3000));if(W.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(t$(W.structuredContent,2000));if(H.length===0&&!W.structuredContent)Y.push(t$(W,3000))}else Y.push(W?t$(W,3000):u$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
120
- `):t$($??{},2000)}function CA($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${g(typeof Z?.tool==="string"&&Z.tool?Z.tool:XW($))}`],W=Z?.input;if(W&&typeof W==="object")if(Q.push(""),Q.push("**input**"),Object.keys(W).length>0)Q.push(t$(W,2000));else Q.push("_provider 未提供结构化 input_");else if(W!=null&&W!=="")Q.push(`**input**: ${g(W)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(S0(J,3000));return Q.join(`
121
- `)}function bA($){return typeof $?.status==="string"?$.status:""}function kW($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${g($.status)}`);if($?.prompt)Q.push("","**提示词**",u$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",u$(String($.revisedPrompt)))}if(J)Q.push(""),Q.push(J);if(!Y&&Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(g(Z.trim()));return Q.length>0?Q.join(`
122
- `):t$($??{},2000)}function yA($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",W=Y||Q||J;return Z&&W?`${Z}: ${W}`:W||Z}function M8($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${g($.tool)}`);if($?.model)Y.push(`**model**: ${g($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${g($.subagent_type)}`);if($?.prompt){if(Y.length>0)Y.push("");Y.push("**prompt**"),Y.push(String($.prompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){Y.push(""),Y.push("---"),Y.push("**状态**");let Q=G3(Z);Y.push(Q?t$(Q,3000):u$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
123
- `):t$($??{},2000)}function A0($,Z,J,Y,Q="⏳",W,H){let V=v4(Z)&&Y!=null?kA(J,Y):o0(Z,J),X=V.length>80?V.slice(0,80)+"…":V,z=E1(Z),G=X?`${Q} \uD83D\uDD27 ${z}: ${X}`:`${Q} \uD83D\uDD27 ${z}`,K=W?`
124
-
125
- ${W}`:"",B=F8(Z)?_W(J,Y,W):R8(Z)?KW(J,Y,W):C8(Z)?CA(Z,J,Y,W):U8(Z)?LW(J,Y,W):v4(Z)?NW(J,Y,W):O8(Z)?EW(J,Y,W):V3(Z)?SW(J,Y,W):h4(Z)?kW(J,Y,W,H):T8(Z)?DW(J,Y,W):N8(Z)?MW(J,Y,W):E8(Z)?FW(J,Y,W):S8(Z)?RW(J,Y,W):z3(Z)?UW(Z,J,Y,W):k8(Z)?OW(J,Y,W):x8(Z)?M8({prompt:I4(J)||"提交计划"},Y,W):X3(Z)?M8(J,Y,W):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Y!=null?`
145
+ `)}function g($){return"`"+String($??"").replace(/`/g,"'")+"`"}function e$($,Z=3000){return u$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function c4($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Y=Z[J];if(typeof Y==="string"&&Y.length>0)return Y}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function yW($,Z,J){let Y=bW($),Q=Y.command,W=Y.description,H=[];if(W)H.push(`**目的**: ${W}`);let V=$?.cwd??$?.workdir;if(V)H.push(`**cwd**: ${g(V)}`);if($?.source)H.push(`**source**: ${g($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(u$(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(x0(Z));return H.join(`
146
+ `)}function wW($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${CW($)}`),Q!==void 0)Y.push(`**session**: ${g(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let W=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(u$(W))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(x0(Z));return Y.join(`
147
+ `)}function fW($){return Array.isArray($?.changes)?$.changes:[]}function vW($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function I4($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&K7(J)&&K7(Z)){let Y=Qq(Z,J);if(Y&&!Y.startsWith("..")&&!K7(Y))return Y}return J}function Gq($){let Z=$?.kind;if(typeof Z==="string")return Z.toLowerCase();if(typeof Z?.type==="string")return Z.type.toLowerCase();if(typeof $?.type==="string")return $.type.toLowerCase();return""}function hW($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function A7($){let Z=Gq($);if(hW($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function q7($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function L7($){let Z=0,J=0;for(let Y of $.split(/\r?\n/)){if(Y.startsWith("+++")||Y.startsWith("---"))continue;if(Y.startsWith("+"))Z++;if(Y.startsWith("-"))J++}return{added:Z,removed:J}}function IW($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function j7($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function _q($){return $.length>1800?$.slice(0,1800)+`
148
+ ... diff 已截断 ...`:$}function Kq($){let Z=fW($),J=vW($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",X=$?.grantRoot?I4($.grantRoot):"";if(z&&X)return`${z} · ${X}`;return z||(X?`申请修改 ${X}`:"")}let Y=Z.map((z)=>L7(q7(z))).reduce(IW,{added:0,removed:0}),Q=j7(Y),W=[...new Set(Z.map(A7))],H=I4(Z[0]?.path,J),V=Q?` · ${Q}`:"";if(Z.length===1)return`${W[0]} ${H}${V}`;return`${Z.length} 个文件 · ${W.join("/")} · ${H} 等${V}`}function gW($,Z,J){let Y=fW($),Q=vW($),W=[];if(Y.length===0){let X=typeof $?.reason==="string"?$.reason.trim():"";if(X)W.push(`**原因**: ${X}`);if($?.grantRoot)W.push(`**范围**: ${g(I4($.grantRoot))}`);if(J)W.push(""),W.push(J);if(Z!=null)W.push(""),W.push("---"),W.push("**output:**"),W.push(u$(Z.slice(0,3000)));return W.length>0?W.join(`
149
+ `):u$(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((X)=>L7(q7(X))).reduce(IW,{added:0,removed:0}),V=j7(H);if(W.push(`**文件**: ${Y.length} 个`),V)W.push(`**行数**: ${V}`);if($?.status)W.push(`**状态**: ${g($.status)}`);let z=Y.slice(0,5);for(let X of z){let G=q7(X),K=j7(L7(G)),B=I4(X?.path,Q),L=K?`**${A7(X)}** ${g(B)} · ${K}`:`**${A7(X)}** ${g(B)}`;W.push(""),W.push(L);let A=hW(X);if(A)W.push(`来自 ${g(I4(A,Q))}`);W.push(G?u$(_q(G),"diff"):"_无 diff 内容_")}if(Y.length>z.length)W.push(""),W.push(`还有 ${Y.length-z.length} 个文件未展开显示。`);if(J)W.push(""),W.push(J);return W.join(`
150
+ `)}function s0($){return String($?.file_path??$?.path??$?.notebook_path??"")}function Bq($){let Z=s0($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function Aq($){let Z=s0($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function qq($){let Z=s0($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function Lq($){let Z=s0($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function jq($,Z){if($==="Glob"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}if($==="Grep"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}return String(Z?.path??"")}function mW($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function Pq($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let W=mW(Q?.status);J.set(W,(J.get(W)??0)+1)}let Y=[...J.entries()].map(([Q,W])=>`${Q} ${W}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function Dq($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function T2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(x0(Z,1200))}function cW($,Z,J){let Y=[],Q=s0($);if(Q)Y.push(`**路径**: ${g(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${g($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${g($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
151
+ `):e$($??{},2000)}function pW($,Z,J){let Y=[],Q=s0($),W=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${g(Q)}`);if(W){let H=W.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${W.length} 字符`),Y.push(x0(W,1200))}if(J)Y.push(""),Y.push(J);return T2(Y,Z),Y.length>0?Y.join(`
152
+ `):e$($??{},2000)}function uW($,Z,J){let Y=[],Q=s0($);if(Q)Y.push(`**路径**: ${g(Q)}`);if($?.cell_id)Y.push(`**cell**: ${g($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${g($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(x0($.old_string,800));let W=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(W)Y.push(""),Y.push("**替换为**"),Y.push(x0(W,800));if(J)Y.push(""),Y.push(J);return T2(Y,Z),Y.length>0?Y.join(`
153
+ `):e$($??{},2000)}function lW($,Z,J){let Y=[],Q=s0($),W=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${g(Q)}`);Y.push(`**编辑**: ${W.length} 处`);for(let[H,V]of W.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${V?.replace_all?" · 全局替换":""}**`),typeof V?.old_string==="string")Y.push("查找:"),Y.push(x0(V.old_string,500));if(typeof V?.new_string==="string")Y.push("替换为:"),Y.push(x0(V.new_string,500))}if(W.length>5)Y.push(""),Y.push(`还有 ${W.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return T2(Y,Z),Y.join(`
154
+ `)}function iW($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${g(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${g(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${g(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${g(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${g(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${g(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${g(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${g(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(g).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return T2(Q,J),Q.join(`
155
+ `)}function dW($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let W of Y.slice(0,12)){let H=mW(W?.status),V=String(W?.content??W?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${V}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return T2(Q,Z),Q.join(`
156
+ `)}function F7($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function R7($,Z){return F7(Z)??$?.action??{}}function U7($,Z){let J=R7($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((W)=>typeof W==="string"&&W.length>0):[],Q=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Y.length>0?Y:Q?[Q]:[]}function O7($,Z){let J=R7($,Z);return String(J?.url??$?.url??"")}function nW($){let Z=U7($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=O7($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function Mq($,Z){let J=U7($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=O7($,Z);if(Y)return Y;return nW($)}function aW($,Z,J){let Y=R7($,Z),Q=U7($,Z),W=O7($,Z),H=[],V=typeof Y?.type==="string"?Y.type:"";if(V==="search"||Q.length>0){if(H.push("**动作**: 搜索"),Q.length>0){H.push(""),H.push("**查询**");for(let z of Q.slice(0,6))H.push(`- ${g(z)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(V==="open_page"){if(H.push("**动作**: 打开页面"),W)H.push(`**URL**: ${g(W)}`)}else if(V==="find_in_page"){if(H.push("**动作**: 页内查找"),W)H.push(`**URL**: ${g(W)}`);if(Y?.pattern)H.push(`**关键词**: ${g(Y.pattern)}`)}else if(H.push(`**动作**: ${V?g(V):"网页搜索"}`),W)H.push(`**URL**: ${g(W)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!W&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(u$(Z.slice(0,3000),"json"));return H.join(`
157
+ `)}function oW($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${g($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return T2(Y,Z),Y.join(`
158
+ `)}function Fq($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=c4($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function rW($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${g($.server)}`);if($?.tool)Y.push(`**tool**: ${g($.tool)}`);let Q=$?.arguments;if(Q&&typeof Q==="object"&&Object.keys(Q).length>0){if(Y.length>0)Y.push("");Y.push("**arguments**"),Y.push(e$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let W=F7(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),W&&Array.isArray(W.content)){let H=W.content.map((V)=>typeof V?.text==="string"?V.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
159
+ `).slice(0,3000));if(W.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(e$(W.structuredContent,2000));if(H.length===0&&!W.structuredContent)Y.push(e$(W,3000))}else Y.push(W?e$(W,3000):u$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
160
+ `):e$($??{},2000)}function Rq($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${g(typeof Z?.tool==="string"&&Z.tool?Z.tool:xW($))}`],W=Z?.input;if(W&&typeof W==="object")if(Q.push(""),Q.push("**input**"),Object.keys(W).length>0)Q.push(e$(W,2000));else Q.push("_provider 未提供结构化 input_");else if(W!=null&&W!=="")Q.push(`**input**: ${g(W)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(x0(J,3000));return Q.join(`
161
+ `)}function Uq($){return typeof $?.status==="string"?$.status:""}function tW($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${g($.status)}`);if($?.prompt)Q.push("","**提示词**",u$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",u$(String($.revisedPrompt)))}if(J)Q.push(""),Q.push(J);if(!Y&&Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(g(Z.trim()));return Q.length>0?Q.join(`
162
+ `):e$($??{},2000)}function Oq($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",W=Y||Q||J;return Z&&W?`${Z}: ${W}`:W||Z}function x8($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${g($.tool)}`);if($?.model)Y.push(`**model**: ${g($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${g($.subagent_type)}`);if($?.prompt){if(Y.length>0)Y.push("");Y.push("**prompt**"),Y.push(String($.prompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){Y.push(""),Y.push("---"),Y.push("**状态**");let Q=F7(Z);Y.push(Q?e$(Q,3000):u$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
163
+ `):e$($??{},2000)}function L0($,Z,J,Y,Q="⏳",W,H){let V=g4(Z)&&Y!=null?Mq(J,Y):t0(Z,J),z=V.length>80?V.slice(0,80)+"…":V,X=k1(Z),G=z?`${Q} \uD83D\uDD27 ${X}: ${z}`:`${Q} \uD83D\uDD27 ${X}`,K=W?`
164
+
165
+ ${W}`:"",B=C8(Z)?yW(J,Y,W):b8(Z)?wW(J,Y,W):c8(Z)?Rq(Z,J,Y,W):y8(Z)?gW(J,Y,W):g4(Z)?aW(J,Y,W):w8(Z)?oW(J,Y,W):P7(Z)?rW(J,Y,W):m4(Z)?tW(J,Y,W,H):f8(Z)?cW(J,Y,W):v8(Z)?pW(J,Y,W):h8(Z)?uW(J,Y,W):I8(Z)?lW(J,Y,W):M7(Z)?iW(Z,J,Y,W):g8(Z)?dW(J,Y,W):m8(Z)?x8({prompt:c4(J)||"提交计划"},Y,W):D7(Z)?x8(J,Y,W):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Y!=null?`
126
166
  ---
127
167
  **output:**
128
168
  \`\`\`
129
- `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:e(B)},...h4(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function g4($,Z){let J=Z.length,Y=Z.some((X)=>X.isError),Q=Z.every((X)=>X.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let X=HW(Z[0]);return X?`${W} \uD83D\uDD27 编辑文件: ${X}`:`${W} \uD83D\uDD27 编辑文件`})():`${W} \uD83D\uDD27 编辑文件 · ${J} 次`,V=Z.map((X)=>{let z=HW(X);return z?`\`${z}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(V.join(`
130
- `))}]}}function HW($){let Z=$.input??{},J=String(Z.file_path??Z.path??Z.notebook_path??"");if(Array.isArray(Z.edits)&&Z.edits.length>0)return J?`${J} · ${Z.edits.length} 处`:`${Z.edits.length} 处`;if(Z.replace_all&&J)return`${J} · 全局替换`;return J}function m4($,Z){let J=Z.length,Y=Z.some((X)=>X.isError),Q=Z.every((X)=>X.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let X=o0("Read",Z[0]?.input);return X?`${W} \uD83D\uDD27 Read: ${X}`:`${W} \uD83D\uDD27 Read`})():`${W} \uD83D\uDD27 Read · ${J} 次`,V=Z.map((X)=>`\`${String(X.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(V.join(`
131
- `))}]}}function A3($,Z,J,Y){let Q=o0(Z,J),W=E1(Z),H=Q?`\uD83D\uDD10 等审批 · ${W}: ${Q}`:`\uD83D\uDD10 等审批 · ${W}`,V=F8(Z)?_W(J,null):R8(Z)?KW(J,null):U8(Z)?LW(J,null):v4(Z)?NW(J,null):O8(Z)?EW(J,null):V3(Z)?SW(J,null):h4(Z)?kW(J,null):T8(Z)?DW(J,null):N8(Z)?MW(J,null):E8(Z)?FW(J,null):S8(Z)?RW(J,null):z3(Z)?UW(Z,J,null):k8(Z)?OW(J,null):x8(Z)?M8({prompt:I4(J)||"提交计划"},null):X3(Z)?M8(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:V},{tag:"column_set",columns:[J3("✅ 允许","primary",Y,"allow"),J3("♾️ 始终允许","default",Y,"allow_always"),J3("❌ 拒绝","danger",Y,"deny")]}]}}function J3($,Z,J,Y){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Y}}]}]}}var AA=300,VW="server_tool:";var xW=T(()=>{x$();U9()});function q3($){let Z=vA($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:wA($.notice)},body:{elements:[...$.notice?[fA($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(hA)]}}}function wA($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function fA($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
169
+ `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:e(B)},...m4(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function p4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=SW(Z[0]);return z?`${W} \uD83D\uDD27 编辑文件: ${z}`:`${W} \uD83D\uDD27 编辑文件`})():`${W} \uD83D\uDD27 编辑文件 · ${J} 次`,V=Z.map((z)=>{let X=SW(z);return X?`\`${X}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(V.join(`
170
+ `))}]}}function SW($){let Z=$.input??{},J=String(Z.file_path??Z.path??Z.notebook_path??"");if(Array.isArray(Z.edits)&&Z.edits.length>0)return J?`${J} · ${Z.edits.length} 处`:`${Z.edits.length} 处`;if(Z.replace_all&&J)return`${J} · 全局替换`;return J}function u4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=t0("Read",Z[0]?.input);return z?`${W} \uD83D\uDD27 Read: ${z}`:`${W} \uD83D\uDD27 Read`})():`${W} \uD83D\uDD27 Read · ${J} 次`,V=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(V.join(`
171
+ `))}]}}function T7($,Z,J,Y){let Q=t0(Z,J),W=k1(Z),H=Q?`\uD83D\uDD10 等审批 · ${W}: ${Q}`:`\uD83D\uDD10 等审批 · ${W}`,V=C8(Z)?yW(J,null):b8(Z)?wW(J,null):y8(Z)?gW(J,null):g4(Z)?aW(J,null):w8(Z)?oW(J,null):P7(Z)?rW(J,null):m4(Z)?tW(J,null):f8(Z)?cW(J,null):v8(Z)?pW(J,null):h8(Z)?uW(J,null):I8(Z)?lW(J,null):M7(Z)?iW(Z,J,null):g8(Z)?dW(J,null):m8(Z)?x8({prompt:c4(J)||"提交计划"},null):D7(Z)?x8(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:V},{tag:"column_set",columns:[B7("✅ 允许","primary",Y,"allow"),B7("♾️ 始终允许","default",Y,"allow_always"),B7("❌ 拒绝","danger",Y,"deny")]}]}}function B7($,Z,J,Y){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Y}}]}]}}var Wq=300,kW="server_tool:";var sW=T(()=>{C$();b9()});function N7($){let Z=Eq($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:Tq($.notice)},body:{elements:[...$.notice?[Nq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(Sq)]}}}function Tq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function Nq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
132
172
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
133
- `)}}function vA($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${b8("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function hA($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Y=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${b8($.slug)}**
173
+ `)}}function Eq($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${p8("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function Sq($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Y=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${p8($.slug)}**
134
174
  ${Z} · ${J}
135
- ${b8($.branch)}`}]}];if($.mounted||$.chatId)Y.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Y}]}function c4($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF3F ${$.slug}`},template:$.template??"green"},body:{elements:[{tag:"markdown",content:[$.status,b8($.branch),...$.body?[$.body]:[]].join(`
136
- `)}]}}}function b8($){return"`"+$.replace(/`/g,"\\`")+"`"}function L3($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
175
+ ${p8($.branch)}`}]}];if($.mounted||$.chatId)Y.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Y}]}function l4($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF3F ${$.slug}`},template:$.template??"green"},body:{elements:[{tag:"markdown",content:[$.status,p8($.branch),...$.body?[$.body]:[]].join(`
176
+ `)}]}}}function p8($){return"`"+$.replace(/`/g,"\\`")+"`"}function S7($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
137
177
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
138
- 只回退对话历史,不会回滚 cwd 中的文件。`,W=[];if($.notice)W.push({tag:"markdown",content:IA($.notice)});if(!$.entries.length)W.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{W.push({tag:"markdown",content:Q});for(let H of $.entries)W.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${F3(H.ts)}**
139
- ${t0(H.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Y,panel_id:$.panelId,choice_id:H.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`${Z?"\uD83D\uDD31 fk 分叉":"⏪ bk 回退"} · ${$.projectName}`},template:Z?"turquoise":"orange"},body:{elements:W}}}function j3($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
140
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${F3(J.ts)}**
141
- ${t0(J.preview.slice(0,60)||"(无摘要)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"分支"},type:"primary",behaviors:[{type:"callback",value:{kind:"temp_resume_select",panel_id:$.panelId,choice_id:J.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs 独立分支 · ${$.projectName}`},template:"purple"},body:{elements:Z}}}function D3($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
178
+ 只回退对话历史,不会回滚 cwd 中的文件。`,W=[];if($.notice)W.push({tag:"markdown",content:kq($.notice)});if(!$.entries.length)W.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{W.push({tag:"markdown",content:Q});for(let H of $.entries)W.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${b7(H.ts)}**
179
+ ${e0(H.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Y,panel_id:$.panelId,choice_id:H.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`${Z?"\uD83D\uDD31 fk 分叉":"⏪ bk 回退"} · ${$.projectName}`},template:Z?"turquoise":"orange"},body:{elements:W}}}function k7($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
180
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${b7(J.ts)}**
181
+ ${e0(J.preview.slice(0,60)||"(无摘要)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"分支"},type:"primary",behaviors:[{type:"callback",value:{kind:"temp_resume_select",panel_id:$.panelId,choice_id:J.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs 独立分支 · ${$.projectName}`},template:"purple"},body:{elements:Z}}}function x7($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
142
182
  …(截断)`:J.body;return`${J.path} (${J.tool})
143
183
  ${Y}`}).join(`
144
184
 
145
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function s0($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${P3($.message)}`}]}}}function M3($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Y=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Q=$.selectedPreview.slice(0,80)||"(无摘要)",W=$.sourceStatus?` · 状态 ${t0($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${t0(y8($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
185
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function $1($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${E7($.message)}`}]}}}function C7($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Y=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Q=$.selectedPreview.slice(0,80)||"(无摘要)",W=$.sourceStatus?` · 状态 ${e0($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${e0(u8($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
146
186
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
147
- `):$.bindingState==="unchanged"?[`${P3($.message)}`,"",`本群原绑定 ${t0(y8($.previousSessionId))};源会话未修改。`].join(`
148
- `):[`${P3($.message)}`,"",`后端返回会话 ${t0(y8($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
149
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Y} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${F3($.selectedTs)}**${W}`,t0(Q),`源会话 ${t0(y8($.sourceSessionId))}`].join(`
150
- `)},{tag:"markdown",content:H}]}}}function F3($){let Z=new Date($),J=(Y)=>String(Y).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function t0($){return"`"+CW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function y8($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function P3($){return CW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function CW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function IA($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
187
+ `):$.bindingState==="unchanged"?[`${E7($.message)}`,"",`本群原绑定 ${e0(u8($.previousSessionId))};源会话未修改。`].join(`
188
+ `):[`${E7($.message)}`,"",`后端返回会话 ${e0(u8($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
189
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Y} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${b7($.selectedTs)}**${W}`,e0(Q),`源会话 ${e0(u8($.sourceSessionId))}`].join(`
190
+ `)},{tag:"markdown",content:H}]}}}function b7($){let Z=new Date($),J=(Y)=>String(Y).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function e0($){return"`"+eW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function u8($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function E7($){return eW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function eW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function kq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
151
191
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
152
- `)}function bW($){if(!$||typeof $!=="object")return"";if(typeof $.content==="string")return $.content;if(typeof $.new_string==="string")return $.new_string;if(typeof $.new_source==="string")return $.new_source;if(Array.isArray($.edits))return $.edits.map((Z)=>typeof Z?.new_string==="string"?Z.new_string:"").filter(Boolean).join(`
192
+ `)}function $H($){if(!$||typeof $!=="object")return"";if(typeof $.content==="string")return $.content;if(typeof $.new_string==="string")return $.new_string;if(typeof $.new_source==="string")return $.new_source;if(Array.isArray($.edits))return $.edits.map((Z)=>typeof Z?.new_string==="string"?Z.new_string:"").filter(Boolean).join(`
153
193
  ---
154
- `);return""}function R3($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Y)=>Y&&typeof Y==="object").map((Y)=>({tool:$,path:typeof Y.path==="string"&&Y.path?Y.path:"?",body:typeof Y.diff==="string"?Y.diff:typeof Y.unified_diff==="string"?Y.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:bW(Z)}]}function O3($){let Z=!!$.binding,J=$.notice?.type==="error"?"red":$.confirmDelete?"red":Z?"green":"blue";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"task"},template:J},body:{elements:[...$.notice?[cA($.notice)]:[],{tag:"markdown",element_id:U.tasklistPanel,content:gA($)},mA($)]}}}function gA($){let Z=[`项目:${U3($.projectName)}`,`清单:${U3($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
155
- `);if(Z.push("","已启用"),Z.push(`GUID:${U3($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
156
- `)}function mA($){if(!$.binding)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启用"},type:"primary",behaviors:[{type:"callback",value:{kind:"tasklist_enable"}}]}]}]};if($.confirmDelete)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:"<font color='red'>会删除所有清单内任务</font>"}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"确认"},type:"danger",behaviors:[{type:"callback",value:{kind:"tasklist_delete_confirm",guid:$.binding.guid}}]}]}]};return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"tasklist_delete_prompt",guid:$.binding.guid}}]}]}]}}function cA($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
157
- `).map((J)=>`<font color='${Z}'>${uA(J)||" "}</font>`).join(`
158
- `)}}function U3($){return"`"+$.replace(/`/g,"\\`")+"`"}function uA($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var yW=T(()=>{x$()});import{createHash as pA}from"node:crypto";function E3($){let Z=[{tag:"markdown",element_id:U.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
159
- `)}];if($.failures.length)Z.push({tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`MISS · ${$.failures.length} 个账号`}},expanded:!1,elements:[{tag:"markdown",content:$.failures.map((J)=>`- **${e0(J.display)}**:${e0(J.reason)}`).join(`
160
- `)}]});return Z.push(...$.catalog.map(dA),nA($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function S3($){let Z=v8($.workers.length);return{schema:"2.0",config:{update_multi:!0,streaming_mode:!vW($.status),summary:{content:p4($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.parentKind==="follow_up"?"继续委派任务":"委派任务"} · ${$.workers.length} 位 Agent`},template:"purple"},body:{elements:[u4($),{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`任务说明 · ${N3($.prompt,56)}`}},expanded:!1,elements:[{tag:"markdown",content:oA($.prompt)}]},...$.workers.map((J)=>w8(J,Z,$.workers.length===1))]}}}function w8($,Z=fW,J=!1){let Y=aA($),Q=[`模型 ${S1($.model)} · 推理 ${S1($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${IW($.durationMs)}`);if($.status==="queued"&&$.queuedReason)Q.push("",e0($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let W of $.pendingInput.questions)if(Q.push(`- ${e0(W.question)}`),W.options.length)Q.push(` 选项:${W.options.map((H)=>S1(H.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",e($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",rA(e($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let W of $.steps.slice(-3)){let H=W.tool==="tool error"?"❌":W.phase==="completed"?"✓":W.phase==="started"?"→":"·",V=W.tool==="tool error"?"工具执行失败":W.tool==="tool result"?"工具执行完成":W.tool;Q.push(`- ${H} ${S1(V)} ${e0(N3(W.detail,180))}`)}}return{tag:"collapsible_panel",element_id:f8($.identityId),header:{title:{tag:"plain_text",content:`${Y} · ${N3($.identityName,48)}`}},expanded:$.status==="failed"||$.status==="needs_input"||J&&$.status==="completed"&&!!$.output,elements:[{tag:"markdown",content:Q.join(`
161
- `)}]}}function u4($){let Z=$.workers.filter((G)=>G.status==="completed").length,J=$.workers.filter((G)=>G.status==="failed").length,Y=$.workers.filter((G)=>G.status==="needs_input").length,Q=$.workers.filter((G)=>G.status==="running").length,W=$.workers.filter((G)=>G.status==="queued").length,H=$.workers.filter((G)=>G.status==="cancelled").length,V=[Q?`执行中 ${Q}`:"",W?`排队 ${W}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),X=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null,z=[`**${hW($)}** · 完成 ${Z}/${$.workers.length}`,...V.length?[V.join(" · ")]:[],...X!=null&&Number.isFinite(X)?[`⏱ 用时 ${IW(X)}`]:[],...$.error?[e0($.error)]:[]];return{tag:"markdown",element_id:U.agentRunFooter,content:z.join(`
162
- `)}}function f8($){return`aw_${pA("sha256").update($).digest("hex").slice(0,16)}`}function v8($){let Z=Math.max(1,Math.floor($));return Math.min(fW,Math.max(iA,Math.floor(lA/Z)))}function p4($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${hW($)} · ${Z}/${$.workers.length}`}function dA($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${e0($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${S1($.id)}
163
- ${S1($.model)} · 默认 ${S1($.defaultEffort??"MISS")} · ${e0(J)}`].join(`
164
- `)}}function nA($){return{tag:"column_set",columns:[T3("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),T3("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),T3("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function T3($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function aA($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function vW($){return $==="completed"||$==="failed"||$==="cancelled"}function hW($){switch($.status){case"completed":return"✅ 委派完成";case"failed":return"❌ 委派失败";case"cancelled":return"\uD83D\uDED1 委派已取消";case"needs_input":return"❓ 等待主 Agent 回复";case"queued":return"⏳ 等待执行";case"running":return $.workers.length>0&&$.workers.every((Z)=>vW(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function IW($){if(!Number.isFinite($)||$<0)return"—";let Z=Math.floor($/1000);if(Z<60)return`${Z} 秒`;let J=Math.floor(Z/60);if(J<60)return`${J} 分 ${Z%60} 秒`;return`${Math.floor(J/60)} 小时 ${J%60} 分`}function oA($){let Z=e($);if(Z.length<=wW)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,wW-J.length-2)}
165
-
166
- ${J}`}function rA($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
167
-
168
- ${J}`}function S1($){return"`"+$.replace(/`/g,"\\`")+"`"}function e0($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function N3($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var wW=1e4,lA=48000,fW=8000,iA=512;var gW=T(()=>{x$()});function x1($){return tA.has($)?$:null}function h8($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function O2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function k1($){return String($?.subject??$?.content??"").trim()}function k3($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function uW($){return`subj:${$}`}function mW($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function Zq($){let Z=k1($);if(!Z)return null;return{id:O2($)||uW(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:k3($)??"pending"}}function x3($,Z,J,Y){if(Z==="TaskList"){let Q=h8(Y),W=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(W===null)return $;let H=[];for(let V of W){let X=Zq(V);if(X)H.push(X)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let z=h8(Y),G=Array.isArray(z?.tasks)?z.tasks:Array.isArray(z)?z:null,K=$;return Q.forEach((B,A)=>{let P=k1(B);if(!P)return;let L=G?.[A],j=L&&O2(L)||mW(Y??"");K=cW(K,j,P,B)}),K}let W=h8(Y),H=W?.task??W,V=O2(H)||mW(Y??""),X=k1(H)||k1(J);if(!X)return $;return cW($,V,X,J)}if(Z==="TaskUpdate"){let Q=O2(J);if(!Q)return $;let W=k3(J);if(W==="deleted")return $.filter((V)=>V.id!==Q);let H=k1(J);if($.some((V)=>V.id===Q))return $.map((V)=>V.id===Q?{...V,...W?{status:W}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:V);return $}if(Z==="TaskGet"){let Q=h8(Y),W=Q?.task??Q,H=O2(W)||O2(J);if(!H)return $;let V=$.find((G)=>G.id===H),X=k1(W)||V?.subject||k1(J);if(!X)return $;let z={id:H,subject:X,description:typeof W?.description==="string"?W.description:V?.description,activeForm:typeof W?.activeForm==="string"?W.activeForm:V?.activeForm,status:k3(W)??V?.status??"pending"};return V?$.map((G)=>G.id===H?z:G):[...$,z]}return $}function cW($,Z,J,Y){let Q=Z||uW(J),W={...typeof Y?.activeForm==="string"&&Y.activeForm?{activeForm:Y.activeForm}:{},...typeof Y?.description==="string"&&Y.description?{description:Y.description}:{}};if($.some((H)=>H.id===Q))return $.map((H)=>H.id===Q?{...H,id:Q,subject:J,...W}:H);return[...$,{id:Q,subject:J,status:"pending",...W}]}function C3($){let Z=$.filter((W)=>W.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let W of Z){let H=eA[W.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((W)=>J.has(W)?`${W} ${J.get(W)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function pW($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let V=parseInt(H,10);return Number.isNaN(V)?Number.MAX_SAFE_INTEGER:V},W=[...J].sort((H,V)=>{let X=Q(H.id)-Q(V.id);return X!==0?X:H.id.localeCompare(V.id)});for(let H of W.slice(0,12)){let V=$q[H.status],X=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${V} ${X||"(空)"}`)}if(W.length>12)Y.push(`- 还有 ${W.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
169
- `)}function $1($,Z,J,Y){let Q=sA[J.name],W=C3(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${W}`;return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:pW(Z,Y)}]}}function C1($){return{tag:"collapsible_panel",element_id:U.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${C3($)}`}},expanded:!0,elements:[{tag:"markdown",content:pW($)}]}}var tA,sA,eA,$q;var lW=T(()=>{x$();tA=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);sA={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},eA={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},$q={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var s$=T(()=>{x$();WW();xW();_7();yW();gW();lW();h6()});import{readFileSync as Jq}from"node:fs";import{homedir as Yq}from"node:os";import{join as aW}from"node:path";function Qq(){return process.env.CLAUDE_CONFIG_DIR||aW(Yq(),".claude")}function y3(){try{let $=Jq(aW(Qq(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return _(`glm-usage: read settings.json env failed: ${$}`),{}}}function b1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function Wq($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function Hq($){let Z=Wq($);return Z&&b1($)?Z:null}function dW($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function nW($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function Vq($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((G)=>G?.type==="TOKENS_LIMIT"),Y=J.find((G)=>G?.unit===3&&G?.number===5),Q=J.find((G)=>G?.unit===6&&G?.number===1),W=Z.find((G)=>G?.type==="TIME_LIMIT"),H=(G)=>G?{percent:dW(G.percentage),resetsAt:nW(G.nextResetTime)}:null,V=H(Y),X=H(Q),z=W?{percent:dW(W.percentage),resetsAt:nW(W.nextResetTime),...typeof W.currentValue==="number"?{used:W.currentValue}:{},...typeof W.usage==="number"?{total:W.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:V,weekly:X,monthly:z,fetchedAt:Date.now()}}async function l4($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:y3(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let W=Hq(Q);if(!W)return{state:"not_glm",baseUrl:Q||void 0};let H=`${W}/api/monitor/usage/quota/limit`,V=new AbortController,X=setTimeout(()=>V.abort(),iW);try{let z=await fetch(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:V.signal});if(z.status===429)return{state:"rate_limited"};if(!z.ok)return{state:"network",reason:`HTTP ${z.status}`};let G=await z.json();if(G?.success===!1||typeof G?.code==="number"&&G.code!==200)return{state:"network",reason:G?.msg?String(G.msg):`code ${G?.code}`};let K=G?.data??G;return Vq(K)}catch(z){let G=z?.name==="AbortError"?`timeout ${iW}ms`:z?.message??String(z);return _(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(X)}}async function oW(){if(T2)return T2;return T2=l4().then(($)=>{if(T2=null,$.state==="network")return b3??$;return b3=$,$}).catch(($)=>{return _(`glm-usage: fetchGlmUsage threw: ${$}`),T2=null,b3??{state:"network",reason:String($)}}),T2}var iW=1e4,b3=null,T2=null;var i4=T(()=>{I()});function rW($){let Z=[];for(let J of $.matchAll(Xq)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function I8($,Z=process.platform){if(Z!=="win32")return $;let J=zq.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var Xq,zq;var w3=T(()=>{Xq=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;zq=/^\/([a-zA-Z])\//});function eW($){if(tW.test($))return{marker:"start",body:$.replace(tW,"")};if(sW.test($))return{marker:"end",body:$.replace(sW,"")};return{marker:"none",body:$}}var tW,sW;var $H=T(()=>{tW=/^>{3,}[ \t]?/,sW=/^<{3,}[ \t]?/});async function ZH($,Z,J,Y,Q){let{marker:W,body:H}=eW(Z);if(W==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)v3($,"reopen");return $.multiMsgBuffer=[],f3($,H,J,Y,Q),!0}if(W==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return _(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}f3($,H,J,Y,Q);let{multiMsgBuffer:V,multiMsgReactions:X}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await _q($,V,X),!0}if($.multiMsgBuffer!==null)return f3($,Z,J,Y,Q),!0;return!1}function f3($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)Gq($,Q)}function Gq($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await m$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else E$(Z,J)})()}async function _q($,Z,J){for(let[H,V]of J)if(V)E$(H,V);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){_(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await E($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((H)=>{return(H.files.length?H.files.map((X)=>`[file: ${X}]`).join(" ")+`
194
+ `);return""}function y7($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Y)=>Y&&typeof Y==="object").map((Y)=>({tool:$,path:typeof Y.path==="string"&&Y.path?Y.path:"?",body:typeof Y.diff==="string"?Y.diff:typeof Y.unified_diff==="string"?Y.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:$H(Z)}]}function f7($){let Z=!!$.binding,J=$.notice?.type==="error"?"red":$.confirmDelete?"red":Z?"green":"blue";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"task"},template:J},body:{elements:[...$.notice?[bq($.notice)]:[],{tag:"markdown",element_id:U.tasklistPanel,content:xq($)},Cq($)]}}}function xq($){let Z=[`项目:${w7($.projectName)}`,`清单:${w7($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
195
+ `);if(Z.push("","已启用"),Z.push(`GUID:${w7($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
196
+ `)}function Cq($){if(!$.binding)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"启用"},type:"primary",behaviors:[{type:"callback",value:{kind:"tasklist_enable"}}]}]}]};if($.confirmDelete)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:"<font color='red'>会删除所有清单内任务</font>"}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"确认"},type:"danger",behaviors:[{type:"callback",value:{kind:"tasklist_delete_confirm",guid:$.binding.guid}}]}]}]};return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"tasklist_delete_prompt",guid:$.binding.guid}}]}]}]}}function bq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
197
+ `).map((J)=>`<font color='${Z}'>${yq(J)||" "}</font>`).join(`
198
+ `)}}function w7($){return"`"+$.replace(/`/g,"\\`")+"`"}function yq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var ZH=T(()=>{C$()});import{createHash as wq}from"node:crypto";function I7($){let Z=[{tag:"markdown",element_id:U.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
199
+ `)}];if($.failures.length)Z.push({tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`MISS · ${$.failures.length} 个账号`}},expanded:!1,elements:[{tag:"markdown",content:$.failures.map((J)=>`- **${Z1(J.display)}**:${Z1(J.reason)}`).join(`
200
+ `)}]});return Z.push(...$.catalog.map(hq),Iq($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function g7($){let Z=d8($.workers.length);return{schema:"2.0",config:{update_multi:!0,streaming_mode:!QH($.status),summary:{content:d4($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.parentKind==="follow_up"?"继续委派任务":"委派任务"} · ${$.workers.length} 位 Agent`},template:"purple"},body:{elements:[i4($),{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`任务说明 · ${h7($.prompt,56)}`}},expanded:!1,elements:[{tag:"markdown",content:mq($.prompt)}]},...$.workers.map((J)=>l8(J,Z,$.workers.length===1))]}}}function l8($,Z=YH,J=!1){let Y=gq($),Q=[`模型 ${x1($.model)} · 推理 ${x1($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${HH($.durationMs)}`);if($.status==="queued"&&$.queuedReason)Q.push("",Z1($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let W of $.pendingInput.questions)if(Q.push(`- ${Z1(W.question)}`),W.options.length)Q.push(` 选项:${W.options.map((H)=>x1(H.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",e($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",cq(e($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let W of $.steps.slice(-3)){let H=W.tool==="tool error"?"❌":W.phase==="completed"?"✓":W.phase==="started"?"→":"·",V=W.tool==="tool error"?"工具执行失败":W.tool==="tool result"?"工具执行完成":W.tool;Q.push(`- ${H} ${x1(V)} ${Z1(h7(W.detail,180))}`)}}return{tag:"collapsible_panel",element_id:i8($.identityId),header:{title:{tag:"plain_text",content:`${Y} · ${h7($.identityName,48)}`}},expanded:$.status==="failed"||$.status==="needs_input"||J&&$.status==="completed"&&!!$.output,elements:[{tag:"markdown",content:Q.join(`
201
+ `)}]}}function i4($){let Z=$.workers.filter((G)=>G.status==="completed").length,J=$.workers.filter((G)=>G.status==="failed").length,Y=$.workers.filter((G)=>G.status==="needs_input").length,Q=$.workers.filter((G)=>G.status==="running").length,W=$.workers.filter((G)=>G.status==="queued").length,H=$.workers.filter((G)=>G.status==="cancelled").length,V=[Q?`执行中 ${Q}`:"",W?`排队 ${W}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null,X=[`**${WH($)}** · 完成 ${Z}/${$.workers.length}`,...V.length?[V.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${HH(z)}`]:[],...$.error?[Z1($.error)]:[]];return{tag:"markdown",element_id:U.agentRunFooter,content:X.join(`
202
+ `)}}function i8($){return`aw_${wq("sha256").update($).digest("hex").slice(0,16)}`}function d8($){let Z=Math.max(1,Math.floor($));return Math.min(YH,Math.max(vq,Math.floor(fq/Z)))}function d4($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${WH($)} · ${Z}/${$.workers.length}`}function hq($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${Z1($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${x1($.id)}
203
+ ${x1($.model)} · 默认 ${x1($.defaultEffort??"MISS")} · ${Z1(J)}`].join(`
204
+ `)}}function Iq($){return{tag:"column_set",columns:[v7("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),v7("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),v7("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function v7($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function gq($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function QH($){return $==="completed"||$==="failed"||$==="cancelled"}function WH($){switch($.status){case"completed":return"✅ 委派完成";case"failed":return"❌ 委派失败";case"cancelled":return"\uD83D\uDED1 委派已取消";case"needs_input":return"❓ 等待主 Agent 回复";case"queued":return"⏳ 等待执行";case"running":return $.workers.length>0&&$.workers.every((Z)=>QH(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function HH($){if(!Number.isFinite($)||$<0)return"—";let Z=Math.floor($/1000);if(Z<60)return`${Z} 秒`;let J=Math.floor(Z/60);if(J<60)return`${J} 分 ${Z%60} 秒`;return`${Math.floor(J/60)} 小时 ${J%60} 分`}function mq($){let Z=e($);if(Z.length<=JH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,JH-J.length-2)}
205
+
206
+ ${J}`}function cq($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
207
+
208
+ ${J}`}function x1($){return"`"+$.replace(/`/g,"\\`")+"`"}function Z1($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function h7($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var JH=1e4,fq=48000,YH=8000,vq=512;var VH=T(()=>{C$()});function b1($){return pq.has($)?$:null}function n8($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function N2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function C1($){return String($?.subject??$?.content??"").trim()}function m7($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function GH($){return`subj:${$}`}function zH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function dq($){let Z=C1($);if(!Z)return null;return{id:N2($)||GH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:m7($)??"pending"}}function c7($,Z,J,Y){if(Z==="TaskList"){let Q=n8(Y),W=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(W===null)return $;let H=[];for(let V of W){let z=dq(V);if(z)H.push(z)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let X=n8(Y),G=Array.isArray(X?.tasks)?X.tasks:Array.isArray(X)?X:null,K=$;return Q.forEach((B,L)=>{let A=C1(B);if(!A)return;let j=G?.[L],P=j&&N2(j)||zH(Y??"");K=XH(K,P,A,B)}),K}let W=n8(Y),H=W?.task??W,V=N2(H)||zH(Y??""),z=C1(H)||C1(J);if(!z)return $;return XH($,V,z,J)}if(Z==="TaskUpdate"){let Q=N2(J);if(!Q)return $;let W=m7(J);if(W==="deleted")return $.filter((V)=>V.id!==Q);let H=C1(J);if($.some((V)=>V.id===Q))return $.map((V)=>V.id===Q?{...V,...W?{status:W}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:V);return $}if(Z==="TaskGet"){let Q=n8(Y),W=Q?.task??Q,H=N2(W)||N2(J);if(!H)return $;let V=$.find((G)=>G.id===H),z=C1(W)||V?.subject||C1(J);if(!z)return $;let X={id:H,subject:z,description:typeof W?.description==="string"?W.description:V?.description,activeForm:typeof W?.activeForm==="string"?W.activeForm:V?.activeForm,status:m7(W)??V?.status??"pending"};return V?$.map((G)=>G.id===H?X:G):[...$,X]}return $}function XH($,Z,J,Y){let Q=Z||GH(J),W={...typeof Y?.activeForm==="string"&&Y.activeForm?{activeForm:Y.activeForm}:{},...typeof Y?.description==="string"&&Y.description?{description:Y.description}:{}};if($.some((H)=>H.id===Q))return $.map((H)=>H.id===Q?{...H,id:Q,subject:J,...W}:H);return[...$,{id:Q,subject:J,status:"pending",...W}]}function p7($){let Z=$.filter((W)=>W.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let W of Z){let H=lq[W.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((W)=>J.has(W)?`${W} ${J.get(W)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function _H($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let V=parseInt(H,10);return Number.isNaN(V)?Number.MAX_SAFE_INTEGER:V},W=[...J].sort((H,V)=>{let z=Q(H.id)-Q(V.id);return z!==0?z:H.id.localeCompare(V.id)});for(let H of W.slice(0,12)){let V=iq[H.status],z=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${V} ${z||"(空)"}`)}if(W.length>12)Y.push(`- 还有 ${W.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
209
+ `)}function J1($,Z,J,Y){let Q=uq[J.name],W=p7(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${W}`;return{tag:"collapsible_panel",element_id:U.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:_H(Z,Y)}]}}function y1($){return{tag:"collapsible_panel",element_id:U.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${p7($)}`}},expanded:!0,elements:[{tag:"markdown",content:_H($)}]}}var pq,uq,lq,iq;var KH=T(()=>{C$();pq=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);uq={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},lq={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},iq={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var $0=T(()=>{C$();EW();sW();R3();ZH();VH();KH();a5()});import{readFileSync as nq}from"node:fs";import{homedir as aq}from"node:os";import{join as LH}from"node:path";function oq(){return process.env.CLAUDE_CONFIG_DIR||LH(aq(),".claude")}function l7(){try{let $=nq(LH(oq(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return _(`glm-usage: read settings.json env failed: ${$}`),{}}}function w1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function rq($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function tq($){let Z=rq($);return Z&&w1($)?Z:null}function AH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function qH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function sq($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((G)=>G?.type==="TOKENS_LIMIT"),Y=J.find((G)=>G?.unit===3&&G?.number===5),Q=J.find((G)=>G?.unit===6&&G?.number===1),W=Z.find((G)=>G?.type==="TIME_LIMIT"),H=(G)=>G?{percent:AH(G.percentage),resetsAt:qH(G.nextResetTime)}:null,V=H(Y),z=H(Q),X=W?{percent:AH(W.percentage),resetsAt:qH(W.nextResetTime),...typeof W.currentValue==="number"?{used:W.currentValue}:{},...typeof W.usage==="number"?{total:W.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:V,weekly:z,monthly:X,fetchedAt:Date.now()}}async function n4($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:l7(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let W=tq(Q);if(!W)return{state:"not_glm",baseUrl:Q||void 0};let H=`${W}/api/monitor/usage/quota/limit`,V=new AbortController,z=setTimeout(()=>V.abort(),BH);try{let X=await J$(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:V.signal});if(X.status===429)return{state:"rate_limited"};if(!X.ok)return{state:"network",reason:`HTTP ${X.status}`};let G=await X.json();if(G?.success===!1||typeof G?.code==="number"&&G.code!==200)return{state:"network",reason:G?.msg?String(G.msg):`code ${G?.code}`};let K=G?.data??G;return sq(K)}catch(X){let G=X?.name==="AbortError"?`timeout ${BH}ms`:X?.message??String(X);return _(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(z)}}async function jH(){if(E2)return E2;return E2=n4().then(($)=>{if(E2=null,$.state==="network")return u7??$;return u7=$,$}).catch(($)=>{return _(`glm-usage: fetchGlmUsage threw: ${$}`),E2=null,u7??{state:"network",reason:String($)}}),E2}var BH=1e4,u7=null,E2=null;var a4=T(()=>{n$();I()});function PH($){let Z=[];for(let J of $.matchAll(eq)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function a8($,Z=process.platform){if(Z!=="win32")return $;let J=$L.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var eq,$L;var i7=T(()=>{eq=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;$L=/^\/([a-zA-Z])\//});function FH($){if(DH.test($))return{marker:"start",body:$.replace(DH,"")};if(MH.test($))return{marker:"end",body:$.replace(MH,"")};return{marker:"none",body:$}}var DH,MH;var RH=T(()=>{DH=/^>{3,}[ \t]?/,MH=/^<{3,}[ \t]?/});async function UH($,Z,J,Y,Q){let{marker:W,body:H}=FH(Z);if(W==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)n7($,"reopen");return $.multiMsgBuffer=[],d7($,H,J,Y,Q),!0}if(W==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return _(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}d7($,H,J,Y,Q);let{multiMsgBuffer:V,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await JL($,V,z),!0}if($.multiMsgBuffer!==null)return d7($,Z,J,Y,Q),!0;return!1}function d7($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)ZL($,Q)}function ZL($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await c$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else S$(Z,J)})()}async function JL($,Z,J){for(let[H,V]of J)if(V)S$(H,V);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){_(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await N($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((H)=>{return(H.files.length?H.files.map((z)=>`[file: ${z}]`).join(" ")+`
170
210
  `:"")+H.text}).join(`
171
211
 
172
- `),W=Y[Y.length-1];_(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],W.userOpenId,W.msgId)}function v3($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;_(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)E$(Y,Q);m$(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var JH=T(()=>{$$();I();$H()});import{mkdtemp as Bq,rm as Aq,writeFile as qq}from"node:fs/promises";import{createRequire as Pq}from"node:module";import{tmpdir as Lq}from"node:os";import{join as YH}from"node:path";function Tq($){let Z=VH.get($);if(Z)return Z;let{liteAdaptor:J}=w1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=w1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=w1("mathjax-full/js/mathjax.js"),{TeX:W}=w1("mathjax-full/js/input/tex.js"),{AllPackages:H}=w1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:V}=w1("mathjax-full/js/output/svg.js"),X=J({fontSize:$});Y(X);let z=Q.document("",{InputJax:new W({packages:H}),OutputJax:new V({fontCache:"none"})}),G={adaptor:X,doc:z};return VH.set($,G),G}function XH($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function Nq($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Eq($,Z=g3,J=!0){try{let Y=Z*jq,{adaptor:Q,doc:W}=Tq(Z),H=W.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),V=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(V)){let G$=V.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(G$)}let X=V.indexOf("<svg"),z=V.lastIndexOf("</svg>");if(X<0||z<0)throw Error("MathJax returned no SVG");let G=V.slice(X,z+6),K=G.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let B=XH(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),A=XH(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),P=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!P)throw Error("MathJax SVG missing viewBox");let L=P.trim().split(/[\s,]+/).map(Number);if(L.length!==4||L.some((G$)=>!Number.isFinite(G$))||L[2]<=0||L[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[j,N,F,R]=L,M=/<text\b/.test(G)?Uq:0,k=`${j} ${N} ${F+M} ${R}`,C=B*Y,v=M*(C/F),b=Math.max(1,Math.ceil(C+v)),c=Math.max(1,Math.ceil(A*Y)),S=Dq-h3*2,h=Math.min(1,S/b),m=Math.max(1,Math.round(b*h)),p=Math.max(1,Math.round(c*h));if(h<1&&p<Mq)throw Error(`formula would be unreadable after width cap (${m}x${p})`);let D=m+h3*2,x=p+WH*2,i=G.slice(K.length,-6).replace(/currentColor/g,QH).replace(/font-family="serif"/g,`font-family="${Oq}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${D}" height="${x}" viewBox="0 0 ${D} ${x}" style="color:${QH}">`,`<rect x="0" y="0" width="${D}" height="${x}" rx="6" fill="${KH}"/>`,`<svg x="${h3}" y="${WH}" width="${m}" height="${p}" viewBox="${Nq(k)}" preserveAspectRatio="xMidYMid meet">`,i,"</svg>","</svg>"].join(""),width:D,height:x}}catch(Y){return _(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function Sq($,Z=g3,J=!0){let Y=Eq($,Z,J);if(!Y)return null;try{let{Resvg:Q}=w1("@resvg/resvg-js"),H=new Q(Y.svg,{background:KH,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:HH,sansSerifFamily:HH}}).render().asPng(),V=new DataView(H.buffer,H.byteOffset,H.byteLength),X=V.getUint32(16),z=V.getUint32(20);if(X!==Y.width||z!==Y.height)throw Error(`PNG dimensions ${X}x${z} != SVG ${Y.width}x${Y.height}`);return{png:H,width:X,height:z}}catch(Q){return _(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function kq($){if(/^[A-Za-zΑ-ω]$/.test($))return!0;if(/\\[A-Za-z]+|[_^=]|[{}]|[≤≥≠≈∑∫√]/.test($))return!0;return/[A-Za-zΑ-ω]\s*[+\-*/<>]\s*[A-Za-zΑ-ω0-9]/.test($)}function zH($,Z){let J=[],Y=(G,K,B)=>{let A=G[0],P=K.trim();if(!P)return;J.push({start:Z+G.index,end:Z+G.index+A.length,tex:P,raw:A,display:B})},Q,W=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=W.exec($))!==null)Y(Q,Q[1]??Q[2]??"",!0);let H=/\\\(([\s\S]+?)\\\)/g;while((Q=H.exec($))!==null)Y(Q,Q[1]??"",!1);let V=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=V.exec($))!==null){let G=(Q[1]??"").trim();if(kq(G))Y(Q,G,!1)}J.sort((G,K)=>G.start-K.start||K.end-G.end);let X=[],z=-1;for(let G of J){if(G.start<z)continue;X.push(G),z=G.end}return X}function BH($){let Z=F6($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...zH($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...zH($.slice(Y),Y));return J}function xq($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Y)=>{if(GH[Y])return GH[Y];if(Y==="times")return"×";if(Y==="cdot")return"·";if(Y==="div")return"÷";if(Y==="pm")return"±";if(Y==="leq"||Y==="le")return"≤";if(Y==="geq"||Y==="ge")return"≥";if(Y==="neq"||Y==="ne")return"≠";if(Y==="approx")return"≈";if(Y==="sim")return"~";if(Y==="infty")return"∞";if(Y==="partial")return"∂";if(Y==="nabla")return"∇";if(Y==="sqrt")return"√";if(Y==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Y,Q)=>Q.length===1?`${Y}${Q}`:`${Y}(${Q})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function wq($){let Z=_H.get($);if(Z!==void 0)return Z;return Z=bq++,_H.set($,Z),Z}function fq($,Z){return`${Rq}\x00${wq(Z)}\x00${$}`}function vq($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}async function hq($,Z){let J=fq($,Z),Y=y1.get(J);if(Y)return Y;let Q=I3.get(J);if(Q)return Q;let W=(async()=>{let H=Sq($,g3,!0);if(!H)return null;let V=null;try{V=await Bq(YH(Lq(),"lodestar-math-"));let X=YH(V,`formula-${vq($)}.png`);await qq(X,H.png);let z=await Z(X,{tex:$,width:H.width,height:H.height});if(!z)return _(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:z,width:H.width,height:H.height};if(y1.has(J))y1.delete(J);y1.set(J,G);while(y1.size>yq){let K=y1.keys().next().value;if(typeof K!=="string")break;y1.delete(K)}return G}catch(X){return _(`math-render: upload failed for ${$.slice(0,80)}…: ${X}`),null}finally{if(V)try{await Aq(V,{recursive:!0,force:!0})}catch(X){_(`math-render: temp cleanup failed for ${V}: ${X}`)}}})();I3.set(J,W);try{return await W}finally{I3.delete(J)}}function Iq($,Z,J){let Y=$.width<=Fq;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Y?"crop_center":"fit_horizontal",...Y?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function AH($,Z={}){let J=BH($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??Cq,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let K=xq(G.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await hq(G.tex,Y)}})),W=[],H="",V=0,X=0,z=()=>{if(!H)return;if(H.trim())W.push({type:"markdown",text:H});H=""};for(let G=0;G<J.length;G++){let K=J[G],B=Q[G];if(H+=$.slice(V,K.start),B.unicode!==null){H+=B.unicode,V=K.end;continue}let A=B.uploaded;if(!A){H+=K.raw,V=K.end;continue}z(),W.push(Iq(A,K,X++)),V=K.end}if(H+=$.slice(V),z(),!W.length)W.push({type:"markdown",text:$});return{blocks:W,formulaCount:J.length,renderedImageCount:X}}function m3($){return BH($).length>0}var w1,jq=0.5,g3=22,QH="#1F2329",KH="#F7F8FA",h3=12,WH=8,Dq=720,Mq=14,Fq=278,Rq="v4-native-cjk-tail-pad",Uq=1100,HH,Oq="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",VH,GH,Cq=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => ($$(),Q$));return Z($)},_H,bq=1,y1,I3,yq=512;var qH=T(()=>{I();w1=Pq(import.meta.url),HH=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",VH=new Map;GH={alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",pi:"π",rho:"ρ",sigma:"σ",tau:"τ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",Gamma:"Γ",Delta:"Δ",Theta:"Θ",Lambda:"Λ",Pi:"Π",Sigma:"Σ",Phi:"Φ",Psi:"Ψ",Omega:"Ω"};_H=new WeakMap,y1=new Map,I3=new Map});import{readFileSync as mq}from"node:fs";function N2($){return c3.has($)}function d4($){c3.add($)}function n4($){c3.delete($)}function E2(){try{let $={};for(let[Z,J]of p$)$[Z]=J;t(g8,$)}catch($){throw _(`notify-callbacks: save failed (${g8}): ${$}`),$}}function DH(){let $=[],Z;try{Z=mq(g8,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-jH,Q=0,W=0;for(let H of Object.values(J)){if(!H||typeof H!=="object")continue;if(typeof H.notifyId!=="string"||typeof H.callbackUrl!=="string")continue;if(typeof H.createdAt!=="number"||H.createdAt<Y){Q++;continue}if(H.replyState?.status==="sending"&&!H.resolvedAt&&!H.unknownAt)H.unknownAt=Date.now(),H.unknownBy={openId:H.replyState.openId},H.unknownReason="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",W++;if(p$.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(_(`notify-callbacks: loaded ${p$.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),W)_(`notify-callbacks: ${W} interrupted text reply(s) marked UNKNOWN`);if(Q>0||W>0)E2()}catch(J){_(`notify-callbacks: load failed (${g8}): ${J}`)}return $}function MH($){let Z=Date.now();if(Z-LH>=cq)uq(Z),LH=Z;p$.set($.notifyId,$),E2()}function k0($){return p$.get($)}function u3($){return[...p$.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function a4($,Z){if(!$)return;return u3($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function FH($,Z){return!!Z&&[...p$.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function S2($,Z){let J=p$.get($);if(!J)throw Error(`notify registration not found: ${$}`);let{replyState:Y,replyMessageIds:Q}=J;if(J.replyState=Z,Z.response&&!J.replyMessageIds?.includes(Z.response.message_id))J.replyMessageIds=[...J.replyMessageIds??[],Z.response.message_id];try{E2()}catch(W){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw W}}function o4($,Z,J){let Y=p$.get($);if(!Y)throw Error(`notify registration not found: ${$}`);let Q={resolvedAt:Y.resolvedAt,resolvedBy:Y.resolvedBy,unknownAt:Y.unknownAt,unknownBy:Y.unknownBy,unknownReason:Y.unknownReason};Y.resolvedAt=Date.now(),Y.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Y.unknownAt,delete Y.unknownBy,delete Y.unknownReason;try{E2()}catch(W){if(Q.resolvedAt===void 0)delete Y.resolvedAt;else Y.resolvedAt=Q.resolvedAt;if(Q.resolvedBy===void 0)delete Y.resolvedBy;else Y.resolvedBy=Q.resolvedBy;if(Q.unknownAt===void 0)delete Y.unknownAt;else Y.unknownAt=Q.unknownAt;if(Q.unknownBy===void 0)delete Y.unknownBy;else Y.unknownBy=Q.unknownBy;if(Q.unknownReason===void 0)delete Y.unknownReason;else Y.unknownReason=Q.unknownReason;throw W}}function p3($,Z,J,Y){let Q=p$.get($);if(!Q)throw Error(`notify registration not found: ${$}`);delete Q.resolvedAt,delete Q.resolvedBy,Q.unknownAt=Date.now(),Q.unknownBy={...Z!==void 0?{buttonId:Z}:{},openId:J},Q.unknownReason=Y,E2()}function m8($,Z,J){try{return o4($,Z,J),{state:"complete"}}catch(Y){let W=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{p3($,Z,J,W)}catch(H){let V=H instanceof Error?H.message:String(H);W+=`; unknown tombstone persistence also failed: ${V}`;let X=p$.get($);if(X)X.unknownReason=W}return{state:"unknown",detail:W}}}function uq($=Date.now()){let Z=$-jH,J=0;for(let[Y,Q]of p$)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)p$.delete(Y),J++;if(J>0)E2();return J}async function l3($,Z,J){let Y={notify_id:$.notifyId,message_id:$.messageId,chat_id:$.chatId,project:$.project,..."id"in Z?{button:{id:Z.id,text:Z.text,type:Z.type}}:{response:{type:"text",...Z}},operator:{open_id:J},timestamp:Math.floor(Date.now()/1000)},Q=new AbortController,W=setTimeout(()=>Q.abort(),PH);try{let H=await fetch($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Y),signal:Q.signal});if(H.status>=200&&H.status<300){let X;try{let z=(await H.text()).trim();if(z.startsWith("{")){let G=JSON.parse(z),K=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(K.trim())X=K.trim().slice(0,500)}else if(z)X=z.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:X}}let V="";try{V=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${V?` ${V}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${PH}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(W)}}function RH($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((V)=>V.id===Y):void 0,W=$.replyState?.response,H=Y!==void 0?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y}}:W?{response:{type:"text",...W}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Y===void 0?"resolved":J&&Y===void 0?"unknown":$.replyState.status,prompt_message_id:$.replyState.promptMessageId,operator:{open_id:$.replyState.openId},...$.replyState.cancelReason?{cancel_reason:$.replyState.cancelReason}:{},...$.replyState.error?{error:$.replyState.error}:{}}}:{},...Z?{...H,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...H,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var jH=604800000,PH=2500,p$,LH,cq=86400000,c3,g8;var r4=T(()=>{I();W$();w$();p$=new Map,LH=Date.now(),c3=new Set;g8=_J});function c8($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function k2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(a4($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(c8($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function i3($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:a4($.chatId)?"notification":c8($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function d3($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||k2($,Z)||!Y?.userOpenId||!Y.messageId)return;J.announced=!0;let Q=(J.announcementVersion??0)+1;J.announcementVersion=Q;let W=J.questions[J.currentIdx]?.question.trim()??"",H=W.length>40?W.slice(0,40)+"…":W,V=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${H?`: ${H}`:""}`:H?`❓ ${H}`:"❓ 等你回答问题";(async()=>{if(M$(Y.cardId),await B8(Y.cardId,{config:{summary:{content:V}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||k2($,Z))return;await O1(Y.messageId,[Y.userOpenId])})().catch((X)=>_(`session "${$.sessionName}": question notification failed: ${X}`))}function u8($){let Z=$.currentTurn;if(!Z)return;for(let[J,Y]of $.pendingAsks){let Q=Z.toolByUseId.get(J);if(!Q||Y.currentIdx===void 0)continue;let W=i3($,J);if(W.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;Z$(Z.cardId,U.tool(Q.i),R2(Q.i,J,Y.questions,"\uD83E\uDD14",W)),d3($,J)}}function UH($){return c8($)!==void 0}async function OH($,Z,J,Y){let Q=c8($);if(!Q){_(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[W,H]=Q,V=k2($,W);if(V){let z=`${V}。这条文字未提交,请稍后重新发送。`;if(!await E($.chatId,z))throw Error(`提问等待提示发送失败: ${z}`);return}if(await n3($,W,H.currentIdx,Z,J)&&Y)m$(Y,"CheckMark")}async function TH($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return _(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==W.currentIdx)return _(`session "${$.sessionName}": stale ask click q=${J} current=${W.currentIdx}`),!1;return NH($,Z,{optionIdx:Y,user:Q})}async function n3($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return _(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return _(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==W.currentIdx)return _(`session "${$.sessionName}": stale ask custom q=${J} current=${W.currentIdx}`),!1;return NH($,Z,{customText:H,user:Q})}function NH($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=k2($,Z);if(Q)return _(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let W=Y.currentIdx,H=Y.questions[W];if(!H)return _(`session "${$.sessionName}": advanceAsk currentIdx=${W} out of range`),!1;let V;if(J.customText!==void 0)V=J.customText;else if(J.optionIdx!==void 0){let B=H.options?.[J.optionIdx];if(!B)return _(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;V=B.label}else return _(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[H.question]=V,Y.answered.set(W,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let X=Y.questions.length,z=void 0;for(let B=W+1;B<X;B++)if(!Y.answered.has(B)){z=B;break}Y.currentIdx=z;let G=$.currentTurn,K=G?.toolByUseId.get(Z);if(G&&K){let B=R2(K.i,Z,Y.questions,z===void 0?"✅":"\uD83E\uDD14",{currentIdx:z,answered:Y.answered});Z$(G.cardId,U.tool(K.i),B)}if(z===void 0)if(Y.requestId)a3($,Z);else _(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),u8($);return!0}function a3($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Y=$.currentTurn?.toolByUseId.get(Z),Q=Y?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Q,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Y)Y.output=JSON.stringify({answers:J.answers}),Y.isError=!1;if($.pendingAsks.delete(Z),u8($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var p8=T(()=>{a0();s$();$$();I();r4()});import{isAbsolute as lq}from"node:path";function F$($){if($?.planLiveInserted)return U.planLive;return $?.taskLiveInserted?U.taskBoardLive:U.footer}function iq($){return $==="ImageGeneration"||$==="imageGeneration"}function dq($,Z,J){if(J||!iq($))return null;let Y=I8(Z.trim());return lq(Y)?Y:null}function nq($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function EH($,Z,J){return $==="read"?m4(Z,J):g4(Z,J)}function SH($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=nq(J);if(Q&&$.currentTurn.openBatchI!==null){let X=$.currentTurn.openBatchI,z=$.currentTurn.toolBatches.get(X);if(z&&z.kind===Q){let G=z.items.length;z.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Y,batchSlot:G});let K=Q==="read"?m4(X,z.items):g4(X,z.items);Z$($.currentTurn.cardId,U.tool(X),K),l8($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let W=x1(J);if(W){let X=$.currentTurn;if(W==="TaskCreate"&&!X.taskBoardResetThisTurn)$.taskBoard=[],X.taskBoardResetThisTurn=!0;if(!X.taskLiveInserted)X.taskLiveInserted=!0,j$(X.cardId,C1($.taskBoard),{type:"insert_before",targetElementId:U.footer});else Z$(X.cardId,U.taskBoardLive,C1($.taskBoard));let z=W==="TaskCreate";if(z)X.taskUpdateI=null;else X.taskCreateI=null;let G=(z?X.taskCreateI:X.taskUpdateI)===null;if(G)if(z)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let K=z?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(Z,{i:K,name:J,input:Y});let B=$1(K,$.taskBoard,{name:W,status:"⏳"});G?j$(X.cardId,B,{type:"insert_before",targetElementId:F$(X)}):Z$(X.cardId,U.tool(K),B),l8(X,J,Y);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let H=$.currentTurn.toolCount++;if(Q){$.currentTurn.openBatchI=H;let X=[{toolUseId:Z,input:Y,output:null,isError:!1}];$.currentTurn.toolBatches.set(H,{kind:Q,items:X}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y,batchSlot:0});let z=Q==="read"?m4(H,X):g4(H,X);j$($.currentTurn.cardId,z,{type:"insert_before",targetElementId:F$($.currentTurn)}),l8($.currentTurn,J,Y);return}if($.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y}),J==="AskUserQuestion"){let X=Array.isArray(Y?.questions)?Y.questions:[],z=X.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:X,i:H,answers:{},answered:G,currentIdx:z});let K=R2(H,Z,X,"\uD83E\uDD14",i3($,Z));j$($.currentTurn.cardId,K,{type:"insert_before",targetElementId:F$($.currentTurn)}),d3($,Z);return}let V=A0(H,J,Y,null,"⏳");j$($.currentTurn.cardId,V,{type:"insert_before",targetElementId:F$($.currentTurn)}),l8($.currentTurn,J,Y)}function l8($,Z,J){if(!$)return;let Y=o0(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,W=E1(Z),H=Q?`\uD83D\uDD27 ${W}: ${Q}`:`\uD83D\uDD27 ${W}`;E0($.cardId,H)}function kH($,Z,J,Y,Q){if(!$.currentTurn)return;let W=$.currentTurn.toolByUseId.get(Z);if(!W)return;if(Q&&typeof Q==="object")W.input={...W.input,...Object.fromEntries(Object.entries(Q).filter(([,G])=>G!==void 0))};let H=typeof J==="string"?J:Array.isArray(J)?J.map((G)=>G?.text??JSON.stringify(G)).join(`
173
- `):JSON.stringify(J);if(W.output=H,W.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let V=dq(W.name,H,Y);if(V){aq($,$.currentTurn,W,V),t4($);return}if(W.name==="AskUserQuestion"){t4($);return}if(W.batchSlot!=null){let G=$.currentTurn.toolBatches.get(W.i);if(G){let K=G.items[W.batchSlot];if(K)K.output=H,K.isError=Y;let B=EH(G.kind,W.i,G.items);Z$($.currentTurn.cardId,U.tool(W.i),B)}t4($);return}let X=x1(W.name);if(X){oq($,W,X,W.input,H,Y,W.resolvedNote);return}let z=A0(W.i,W.name,W.input,H,Y?"❌":"✅",W.resolvedNote);Z$($.currentTurn.cardId,U.tool(W.i),z),t4($)}function aq($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,W=U.tool(J.i),H=Z.imageDeliveryInflight??=new Map,V=H.get(Q)??new Set;H.set(Q,V);let X=(async()=>{let z=null;try{z=await p7(Y)}catch(K){_(`generated image upload failed: ${K}`)}if(z){let K=!1;try{K=await z$(Q,W,A0(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,z),{notifyCardFailure:!1})}catch(B){_(`generated image embed failed: ${B}`)}if(K){J.imageKey=z,Z.outboundSentPaths.add(Y);return}_(`generated image could not be embedded in card ${Q}; sending it as a separate message`)}let G=z?await G8($.chatId,z)!==null:await C4($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else _(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await z$(Q,W,A0(J.i,J.name,J.input,J.output??null,G?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!G&&z)await E($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(z)=>{_(`generated image delivery failed: ${z}`),await E($.chatId,`❌ 生成图片发送失败:${z instanceof Error?z.message:String(z)}`)});V.add(X),X.finally(()=>{if(V.delete(X),!V.size)H.delete(Q)}).catch((z)=>_(`generated image failure notice failed: ${z}`))}async function o3($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function oq($,Z,J,Y,Q,W,H){if(!$.currentTurn)return;if(!W)$.taskBoard=x3($.taskBoard,J,Y,Q);let V=$1(Z.i,$.taskBoard,{name:J,status:W?"❌":"✅"},H);if(Z$($.currentTurn.cardId,U.tool(Z.i),V),$.currentTurn.taskLiveInserted)Z$($.currentTurn.cardId,U.taskBoardLive,C1($.taskBoard));t4($)}function t4($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function r3($,Z,J,Y,Q,W=$.currentTurn){let H=W;if(!H)return;for(let[V,X]of Y){if(H.toolByUseId.has(V))continue;let z=X.batchSlot??null,G=X.input,K,B;if(z!=null){let F=Q.get(X.i)?.items[z];if(!F)continue;G=F.input,K=F.output,B=F.isError}else K=X.output??null,B=X.isError??!1;let A=K!=null,P=F2(Z,U.tool(X.i));if(A&&!P)continue;if(z!=null){let F=Q.get(X.i)?.kind;if(!F)continue;let R=H.toolCount++,M={toolUseId:V,input:G,output:K,isError:B};H.toolBatches.set(R,{kind:F,items:[M]}),H.toolByUseId.set(V,{...X,i:R,batchSlot:0}),j$(J,EH(F,R,[M]),{type:"insert_before",targetElementId:F$(H)});continue}let L=x1(X.name);if(L){let F=L==="TaskCreate";if(F)H.taskUpdateI=null;else H.taskCreateI=null;let R=(F?H.taskCreateI:H.taskUpdateI)===null;if(R)if(F)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let M=F?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(V,{...X,i:M});let k=!A?"⏳":B?"❌":"✅",C=$1(M,$.taskBoard,{name:L,status:k},X.resolvedNote);R?j$(J,C,{type:"insert_before",targetElementId:F$(H)}):Z$(J,U.tool(M),C);continue}let j=H.toolCount++;H.toolByUseId.set(V,{...X,i:j});let N=!A?"⏳":B?"❌":"✅";j$(J,A0(j,X.name,X.input,K,N,X.resolvedNote,X.imageKey),{type:"insert_before",targetElementId:F$(H)})}}var xH=T(()=>{w3();a0();s$();$$();I();p8()});async function CH($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return _(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let W=$.proc;if(!W)return _(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{W.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(z){return _(`session "${$.sessionName}": permission response ${Z} failed: ${z}`),{ok:!1,message:`权限决定发送失败: ${z instanceof Error?z.message:z}`}}$.pendingPermissions.delete(Z);let V=$.currentTurn,X=V?.toolByUseId.get(Q.toolUseId);if(V&&X){let z=x1(X.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,K=z?$1(X.i,$.taskBoard,{name:z,status:"❌"},G):A0(X.i,X.name,X.input,G,"❌");Z$(V.cardId,U.tool(X.i),K)}else{let G=J==="allow_always"?"始终允许":"已允许";X.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let K=z?$1(X.i,$.taskBoard,{name:z,status:"⏳"},X.resolvedNote):A0(X.i,X.name,X.input,null,"⏳",X.resolvedNote);Z$(V.cardId,U.tool(X.i),K)}}if(_(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Q.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function bH($,Z){let J=$.currentTurn;if(!J){_(`session "${$.sessionName}": can_use_tool with no current turn — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no active turn"});return}let Y=Z.tool_use_id;if(!Y){_(`session "${$.sessionName}": can_use_tool without tool_use_id — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no tool_use_id"});return}let Q=J.toolByUseId.get(Y);if(!Q){_(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Y} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Q.name==="AskUserQuestion"){let H=$.pendingAsks.get(Y);if(!H){_(`session "${$.sessionName}": AskUserQuestion ${Y} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(H.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Y}),H.currentIdx===void 0)a3($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),_(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let W=A3(Q.i,Q.name,Q.input,Z.request_id);if(Z$(J.cardId,U.tool(Q.i),W),J.userOpenId&&J.messageId){let H=o0(Q.name,Q.input),V=E1(Q.name),X=H&&H.length>30?H.slice(0,30)+"…":H,z=X?`\uD83D\uDD10 等审批: ${V} · ${X}`:`\uD83D\uDD10 等审批: ${V}`;(async()=>{M$(J.cardId),await B8(J.cardId,{config:{summary:{content:z}}}),await O1(J.messageId,[J.userOpenId])})()}}var yH=T(()=>{a0();s$();$$();I();p8()});class wH{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new B2({accountId:Q,login:!0}),Z=900000,J=(Q,W)=>{y.recordLogin(Q,W),$Q(Q)},Y=1e4){this.createClient=$;this.waitMs=Z;this.recordLogin=J;this.stateWaitMs=Y}async start($,Z){if(this.stopping)throw Error("服务正在退出,无法开始登录");if(!Z.userOpenId)throw Error("无法确认登录发起者");if(this.attempts.has($))throw Error("该账号已有登录任务;使用 codex-login-cancel 取消后再登录");let J=HY($),Y;try{Y=this.createClient($)}catch(X){throw J(),X}let Q,W,H=new Promise((X,z)=>{Q=X,W=z});H.catch(()=>{});let V={owner:Z,client:Y,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:H,resolve:Q,reject:W,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};V.notification=(X,z)=>{if(V.finishing||!V.loginRequested)return;if(X==="account/updated"){if(z?.authMode==="chatgpt"){if(V.authUpdated=!0,V.loginSucceeded)this.finish(V)}return}if(X!=="account/login/completed")return;if(!V.loginId){V.early.push(z);return}if(z?.loginId!==V.loginId)return;if(z?.success!==!0){this.finish(V,Error(typeof z?.error==="string"?z.error:"Codex 登录未成功"));return}if(V.loginSucceeded)return;if(V.loginSucceeded=!0,_(`codex-login: authorization completed account=${$} authUpdated=${V.authUpdated}`),V.timer)clearTimeout(V.timer);if(V.authUpdated)this.finish(V);else V.timer=setTimeout(()=>{this.finish(V,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},V.closed=(X)=>{this.finish(V,X)},Y.on("notification",V.notification),Y.on("closed",V.closed),Y.on("protocolError",V.closed),this.attempts.set($,V);try{await Y.initialize("lodestar-login"),V.loginRequested=!0;let X=await Y.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(X?.type!=="chatgptDeviceCode"||typeof X.loginId!=="string"||!X.loginId||typeof X.userCode!=="string"||!X.userCode||typeof X.verificationUrl!=="string"||new URL(X.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(V.loginId=X.loginId,V.finishing)throw await H,Error("登录已结束");V.timer=setTimeout(()=>{this.cancelAttempt(V,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let z of V.early)V.notification("account/login/completed",z);return V.early.length=0,{accountId:$,loginId:X.loginId,verificationUrl:X.verificationUrl,userCode:X.userCode,done:H}}catch(X){return await this.finish(V,i8(X)),await H}}pending($){return[...this.attempts.values()].filter((Z)=>Z.owner.chatId===$.chatId&&Z.owner.userOpenId===$.userOpenId).map((Z)=>Z.accountId)}async cancel($,Z){let J=this.attempts.get($);if(!J)throw Error("该账号没有等待中的登录");if(!Z.userOpenId||Z.chatId!==J.owner.chatId||Z.userOpenId!==J.owner.userOpenId)throw Error("只有发起登录的用户可在原群取消");if(J.finishing)throw Error("登录正在收尾,请等待结果");await this.cancelAttempt(J,"登录已取消")}async cancelAttempt($,Z){if($.finishing)return;$.finishing=!0;let J=Error(Z);if($.loginId&&$.client.isAlive())try{await $.client.request("account/login/cancel",{loginId:$.loginId})}catch(Y){J=Error(`${Z};取消请求失败:${i8(Y).message}`)}await this.complete($,J)}async finish($,Z){if($.finishing)return;if($.finishing=!0,$.timer)clearTimeout($.timer);let J;if(!Z)try{let Y=await $.client.request("account/read",{refreshToken:!1});if(Y?.account?.type!=="chatgpt"){let Q=typeof Y?.account?.type==="string"?Y.account.type:"null";throw Error(`设备码授权已完成,但账号状态校验失败(account/read.type=${Q});认证文件已保留`)}J=Y.account,this.recordLogin($.accountId,J)}catch(Y){Z=i8(Y)}await this.complete($,Z,J)}async complete($,Z,J){if($.timer)clearTimeout($.timer);$.client.off("notification",$.notification),$.client.off("closed",$.closed),$.client.off("protocolError",$.closed);try{await $.client.close()}catch(Y){Z=Error([Z?.message,`登录进程关闭失败:${i8(Y).message}`].filter(Boolean).join(";"))}if(!$.client.isAlive())this.attempts.delete($.accountId),$.releaseAuth();if(Z)$.reject(Z);else if(J)$.resolve(J);else $.reject(Error("登录结束但账号信息缺失"))}async shutdown(){this.stopping=!0;let Z=(await Promise.allSettled([...this.attempts.values()].map(async(J)=>{if(await this.cancelAttempt(J,"服务退出,登录已取消"),J.client.isAlive())await J.client.close();if(J.client.isAlive())throw Error("登录进程仍未退出");J.releaseAuth(),this.attempts.delete(J.accountId),await J.done.then(()=>{},()=>{})}))).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 登录进程未完全退出")}}function i8($){return $ instanceof Error?$:Error(String($))}var f1;var t3=T(()=>{p0();h$();I();f1=new wH});function fH($){let Z=new Map,J=$.map((G)=>{let K=G.fingerprint?Z.get(G.fingerprint):void 0;if(G.fingerprint&&!K)Z.set(G.fingerprint,G.account.name);return{...G,...K?{duplicateOf:K}:{}}}),Y=J.filter((G)=>!G.duplicateOf),W=(Y.length<=1||Y.every((G)=>G.fingerprint!==null))&&Y.every((G)=>G.usage.state==="ok"),H=Y.flatMap((G)=>G.usage.state==="ok"?[G.usage]:[]),V=W&&H.every((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent!==null))?H.filter((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,X=W&&H.every((G)=>G.resetCredits!=null)?H.reduce((G,K)=>G+K.resetCredits,0):null,z=["fiveHour","weekly"].map((G)=>{let K=H.map((A)=>A[G]).filter((A)=>A!==null),B=W&&K.every((A)=>A.percent!==null&&A.percent>=0&&A.percent<=100);return{kind:G,count:K.length,remaining:B?K.reduce((A,P)=>A+(100-P.percent)/100,0):null}}).filter((G)=>G.count||!W);return{entries:J,complete:W,available:V,resetCredits:X,windows:z}}var vH=T(()=>{h$();p0()});class s4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=sq){let Y=await J.sendCard($,Z0(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new s4(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=F4($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=F4($);return this.terminal=this.enqueue(()=>this.write($,Z,!0)),this.terminal}enqueue($){let Z=this.tail.then($);return this.tail=Z.then(()=>{},()=>{}),Z}async write($,Z,J){let Y=await this.deps.replaceElementChecked(this.cardId,U.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:M4($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var sq;var hH=T(()=>{$$();a0();x$();P2();sq={sendCard:u,convertMessageToCard:o$,recordCardCreated:c$,replaceElementChecked:z$,patchSettingsChecked:P$,dispose:b$}});var e3={};P0(e3,{settleCodexAccountCards:()=>s3,runCodexNamedHi:()=>$P,runCodexAccountCommand:()=>ZP});function d8($,Z){let J=$ instanceof Error?$.message:String($),Y=!/失败|未完全退出/.test(J)&&/登录已取消|服务退出/.test(J),Q=/过期|等待超过|expired/i.test(J),W=J.split(/[\n;]/)[0];return{phase:Y?"cancelled":Q?"expired":"error",name:Z,message:W.length>80?W.slice(0,77)+"…":W,...J!==W||W.length>80?{details:J}:{}}}async function eq($,Z){if(!await u($.chatId,Z0(d8(Z))))throw Error("Codex 错误卡片发送失败")}async function $P($,Z){let J=await s4.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Y=y.find(Z),Q="";if(!await $.startWithCodexAccount(Y.id,{announce:!1,onStatus:(H)=>{Q=H}}))throw Error(Q||"指定账号启动失败");await J.finish({phase:"current",name:Y.name,current:Y.name,title:"已指定账号",hint:"本次手动指定 · 不参与自动排序"}),await $.showConsole()}catch(Y){await J.finish(d8(Y,Z))}}async function s3(){let Z=(await Promise.allSettled([...x2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function ZP($,Z,J,Y){let Q={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let V=f1.pending(Q);if(!J&&V.length!==1)throw Error(V.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let X=J?y.find(J).id:V[0];await f1.cancel(X,Q),await x2.get(X)}catch(V){await eq($,V)}return}let W=Z==="login"?J||"默认":Z==="account"?J||void 0:void 0,H=await s4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:W,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let K=J?Number(J):1,B=$.currentProvider()==="codex"?$.currentModelLabel():H$("codex-sub")?.defaultModel;if(!B)throw Error("Codex 模型 MISS,无法计算调度顺序");let A=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,P=await p9.choose({model:B,effort:A}),L=fH(P.candidates.flatMap((j)=>j.usage?[{account:j.account,usage:j.usage,fingerprint:j.identity.startsWith("record:")?null:j.identity}]:[]));await H.finish({phase:"accounts",total:L,currentId:$.codexAccountId(),...y.preferred($.sessionName)?{selectedId:y.selected($.sessionName)}:{},page:K,scheduling:{candidates:P.candidates,ultra:A==="ultra"},hint:"最高分优先 · hi 备注可直接指定账号"});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");y.selectAuto($.sessionName),await H.finish({phase:"selected",name:"自动选择",current:y.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await H.finish({phase:"current",current:y.get($.codexAccountId()).name,selected:y.preferred($.sessionName)===null?"自动 · 最高分优先":y.get(y.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let K=y.find(J),B=$.currentProvider()==="codex"?$.currentModelLabel():null,A=$.currentProvider()==="codex"?$.currentEffortLabel():null,P=y.get($.codexAccountId()).name;if($.currentProvider()==="codex")U1($.sessionName,"codex",B,A,"codex-sub");if(y.select($.sessionName,K.id),$.currentProvider()==="codex")$.selectedModel=B,$.selectedEffort=A,$.selectedTokenSourceId="codex-sub";await H.finish({phase:"selected",name:K.name,current:P,selected:K.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Y)throw Error("无法确认登录发起者");let V=y.ensure(J);if(K6(V.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(x2.has(V.id))throw Error("登录结果正在更新,请稍等");let X=await f1.start(V.id,Q);try{await H.update({phase:"waiting",flow:"login",name:V.name,verification:{url:X.verificationUrl,code:X.userCode},hint:`取消:codex-login-cancel${J?` ${V.name}`:""}`})}catch(K){throw await f1.cancel(V.id,Q),K}let z=(async()=>{let K;try{K=await X.done}catch(A){await H.finish(d8(A,V.name));return}await H.update({phase:"checking",flow:"login",name:V.name,message:"授权完成,正在读取模型…"});let B;try{await _2();let A=H$("codex-sub",V.id);if(!A)throw Error("Codex 订阅来源尚未初始化");if(await A.refreshModels(),A.modelCatalogState?.status!=="ready")throw Error(A.modelCatalogState?.error??"模型目录未就绪")}catch(A){B=A instanceof Error?A.message:String(A)}await H.finish({phase:B?"warning":"success",flow:"login",name:V.name,email:K.email,plan:K.planType,...B?{title:"已登录 · 目录 MISS",details:B}:{},hint:`已加入自动选择 · 优先使用:codex-account ${V.id==="default"?"default":V.name}`})})();x2.set(V.id,z);let G=()=>{if(x2.get(V.id)===z)x2.delete(V.id)};z.then(G,(K)=>{_(`codex-login: terminal card write failed: ${K}`),G()})}catch(V){await H.finish(d8(V,W))}}var x2;var n8=T(()=>{$$();h$();t3();J$();vH();s6();hH();P2();I();x2=new Map});function S$($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function $Z($,Z){let J=$.agent==="claude"?r5.filter((Q)=>Q!=="default"):$.agent==="codex"?[...M6]:["off","minimal","low","medium","high","xhigh","max"],Y=Z.effort?.trim();return{efforts:J,defaultEffort:Y&&J.includes(Y)?Y:$.agent==="claude"?"max":$.agent==="codex"?"xhigh":"high"}}function a8($,Z){let J=$.modelSelection,Y=new Set(S$(Z.hidden_models)),Q=[...new Set([...S$(Z.custom_models),...J?[]:S$(Z.models)])],W=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},H=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],W.availableModels=[],!J)W.modelIds=[];try{await H()}catch(G){throw $.models=[],$.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G instanceof Error?G.message:String(G)},G}if($.modelCatalogState?.status!=="ready")return;let V=$.models,X=(J?W.availableModels:V).map((G)=>({...G,origin:G.origin??"upstream"}));for(let G of Q){if(X.some((K)=>K.model.toLowerCase()===G.toLowerCase()))continue;X.push({model:G,display:G,origin:"custom",...$Z($,Z)})}W.availableModels=X;let z=J?V.map((G)=>X.find((K)=>K.model===G.model)??{...G,origin:"upstream"}):X;$.models=[...z.filter((G)=>G.origin==="custom"||!Y.has(G.model)),...X.filter((G)=>G.origin==="custom"&&!z.some((K)=>K.model===G.model))],W.modelIds=$.models.map((G)=>G.model)},$}var C2=T(()=>{L$();q1()});import{homedir as JP}from"node:os";function mH($,Z=gH){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function IH($){return typeof $==="string"&&YP.includes($)?$:null}async function cH(){let{ClaudeAgentProcess:$}=await Promise.resolve().then(() => (X4(),lY)),Z=new $({workDir:JP(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1}});Z.on("error",(J)=>_(`Claude model catalog MISS: ${J.message}`));try{let J=await mH(Z.listModels());if(!J.length)throw Error("Claude SDK model catalog is empty");return J.map((Y)=>({model:Y.model.replace(/^claude:/,""),display:Y.displayName,efforts:Y.supportedReasoningEfforts.map((Q)=>Q.reasoningEffort),defaultEffort:Y.defaultReasoningEffort}))}finally{await Z.kill()}}async function uH($="default"){let Z=new B2({accountId:$});try{if(await Z.initialize("lodestar-models"),(await Z.request("account/read",{refreshToken:!1}))?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await mH(Z.request("model/list",{}));if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let Q=Y.data,W=[];for(let H of Q){if(!H||H.hidden||!H.id)continue;let V=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((z)=>IH(z?.reasoningEffort)).filter((z)=>z!==null);if(!V.length)continue;let X=IH(H.defaultReasoningEffort)??V[0];W.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:V,defaultEffort:X})}return W}finally{await Z.close()}}async function pH($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,W=await fetch(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(gH)});if(!W.ok)throw Error(`HTTP ${W.status}`);let H=await W.json();if(!Array.isArray(H?.data))throw Error("GLM models 缺少 data 数组");return H.data.filter((X)=>X&&(X.display_name||X.id)).map((X)=>{let z=String(X.display_name||X.id);return{model:z,display:z,efforts:b2,defaultEffort:"max"}})}var gH=1e4,YP,b2;var e4=T(()=>{p0();I();YP=["none","minimal","low","medium","high","xhigh","max","ultra"];b2=["max","xhigh","high","medium","low"]});import{existsSync as QP}from"node:fs";import{join as WP}from"node:path";function o8($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function HP($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null};let Z=[];if($.fiveHour)Z.push(o8($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(o8($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function VP($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Y=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(o8(J.fiveHour,"fiveHour",`${Y} 5h`));if(J.weekly)Z.push(o8(J.weekly,"weekly",`${Y} 周`))}return Z.length?Z:null}function lH($){return $===l||QP(WP(y.home($),"auth.json"))}var iH=T(()=>{k$();J$();p0();e4();I();h$();C2();T$({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(W)=>{let H=lH(W),V=$.model?.trim()||void 0,X=$.effort?.trim()||void 0,z={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,y.revision(W)]),enabled:H,models:[],modelCatalogState:{status:H?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(z.enabled=lH(W),!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{if(z.models=await uH(W),X)for(let G of z.models)G.defaultEffort=X;if(!V)z.defaultModel=z.models[0]?.model??"";z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(_(`codex-sub ${W} refreshModels MISS: ${G?.message??G}`),z.models=[],G?.code==="CODEX_AUTH_MISSING")z.enabled=!1;z.modelCatalogState={status:z.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let K=X0(G);return Object.assign(K,f.codex.env),y.env(W,K)},resolveSpawnModel(G){return G},async readUsage(){let G=await j1(W),K=HP(G),B=VP(G);if(B)K.windows=B;return K}};return z},Y=J(l);Y.forAccount=(W)=>{if(W===l)return Y;let H=y.revision(W),V=Z.get(W);if(V?.revision===H)return V.source;let X=a8(J(W),$);return Z.set(W,{revision:H,source:X}),X};let Q=Y.refreshModels.bind(Y);return Y.refreshModels=async()=>{await Promise.all([Q(),...y.list().filter((W)=>W.id!==l).map((W)=>Y.forAccount(W.id).refreshModels())])},Y}})});function zP($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function r8($,Z,J){try{let Y=await fetch(zP($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(XP)});if(Y.ok)return"exists";if(Y.status===400){let Q=await Y.text();return Q.includes("1214")||Q.includes("不存在")||Q.includes("not exist")?"not_found":"no_verdict"}return _(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return _(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var XP=15000;var ZZ=T(()=>{I()});function dH($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function GP($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function nH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function _P($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function KP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function JZ($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(dH($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(dH($.weekly,"weekly","周额度"));if($.monthly)Z.push(GP($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var YZ=T(()=>{J$();i4();e4();V4();ZZ();I();T$({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Y=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Q=!!(J&&Y)&&b1(J),W=$.model?.trim()||void 0,H=KP($.slots),V={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let X=await pH(J,Y),G=[...new Set([...nH($.models),...nH($.custom_models)])].filter((K)=>!X.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:b2,defaultEffort:"max",origin:"custom"}));if(V.models=[...X,...G],!W)V.defaultModel=_P(V.models.map((K)=>K.model));for(let K of V.models){let B=Q2("glm",K.model);K.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){_(`glm refreshModels MISS: ${X?.message??X}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:X?.message??String(X)}}},spawnEnv(X){let G={...X0(X)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_AUTH_TOKEN=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(X){return y9("glm",X)},async verifyModel(X){return r8(J,{Authorization:`Bearer ${Y}`},X)},async readUsage(){return JZ(await l4(J,Y))}};return V},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
212
+ `),W=Y[Y.length-1];_(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],W.userOpenId,W.msgId)}function n7($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;_(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)S$(Y,Q);c$(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var OH=T(()=>{$$();I();RH()});import{mkdtemp as QL,rm as WL,writeFile as HL}from"node:fs/promises";import{createRequire as VL}from"node:module";import{tmpdir as zL}from"node:os";import{join as TH}from"node:path";function LL($){let Z=kH.get($);if(Z)return Z;let{liteAdaptor:J}=v1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=v1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=v1("mathjax-full/js/mathjax.js"),{TeX:W}=v1("mathjax-full/js/input/tex.js"),{AllPackages:H}=v1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:V}=v1("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Y(z);let X=Q.document("",{InputJax:new W({packages:H}),OutputJax:new V({fontCache:"none"})}),G={adaptor:z,doc:X};return kH.set($,G),G}function xH($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function jL($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function PL($,Z=r7,J=!0){try{let Y=Z*XL,{adaptor:Q,doc:W}=LL(Z),H=W.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),V=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(V)){let _$=V.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(_$)}let z=V.indexOf("<svg"),X=V.lastIndexOf("</svg>");if(z<0||X<0)throw Error("MathJax returned no SVG");let G=V.slice(z,X+6),K=G.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let B=xH(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),L=xH(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),A=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!A)throw Error("MathJax SVG missing viewBox");let j=A.trim().split(/[\s,]+/).map(Number);if(j.length!==4||j.some((_$)=>!Number.isFinite(_$))||j[2]<=0||j[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[P,S,F,R]=j,M=/<text\b/.test(G)?AL:0,k=`${P} ${S} ${F+M} ${R}`,C=B*Y,c=M*(C/F),b=Math.max(1,Math.ceil(C+c)),h=Math.max(1,Math.ceil(L*Y)),E=GL-a7*2,v=Math.min(1,E/b),m=Math.max(1,Math.round(b*v)),l=Math.max(1,Math.round(h*v));if(v<1&&l<_L)throw Error(`formula would be unreadable after width cap (${m}x${l})`);let D=m+a7*2,x=l+EH*2,i=G.slice(K.length,-6).replace(/currentColor/g,NH).replace(/font-family="serif"/g,`font-family="${qL}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${D}" height="${x}" viewBox="0 0 ${D} ${x}" style="color:${NH}">`,`<rect x="0" y="0" width="${D}" height="${x}" rx="6" fill="${wH}"/>`,`<svg x="${a7}" y="${EH}" width="${m}" height="${l}" viewBox="${jL(k)}" preserveAspectRatio="xMidYMid meet">`,i,"</svg>","</svg>"].join(""),width:D,height:x}}catch(Y){return _(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function DL($,Z=r7,J=!0){let Y=PL($,Z,J);if(!Y)return null;try{let{Resvg:Q}=v1("@resvg/resvg-js"),H=new Q(Y.svg,{background:wH,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:SH,sansSerifFamily:SH}}).render().asPng(),V=new DataView(H.buffer,H.byteOffset,H.byteLength),z=V.getUint32(16),X=V.getUint32(20);if(z!==Y.width||X!==Y.height)throw Error(`PNG dimensions ${z}x${X} != SVG ${Y.width}x${Y.height}`);return{png:H,width:z,height:X}}catch(Q){return _(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function ML($){if(/^[A-Za-zΑ-ω]$/.test($))return!0;if(/\\[A-Za-z]+|[_^=]|[{}]|[≤≥≠≈∑∫√]/.test($))return!0;return/[A-Za-zΑ-ω]\s*[+\-*/<>]\s*[A-Za-zΑ-ω0-9]/.test($)}function CH($,Z){let J=[],Y=(G,K,B)=>{let L=G[0],A=K.trim();if(!A)return;J.push({start:Z+G.index,end:Z+G.index+L.length,tex:A,raw:L,display:B})},Q,W=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=W.exec($))!==null)Y(Q,Q[1]??Q[2]??"",!0);let H=/\\\(([\s\S]+?)\\\)/g;while((Q=H.exec($))!==null)Y(Q,Q[1]??"",!1);let V=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=V.exec($))!==null){let G=(Q[1]??"").trim();if(ML(G))Y(Q,G,!1)}J.sort((G,K)=>G.start-K.start||K.end-G.end);let z=[],X=-1;for(let G of J){if(G.start<X)continue;z.push(G),X=G.end}return z}function fH($){let Z=b5($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...CH($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...CH($.slice(Y),Y));return J}function FL($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Y)=>{if(bH[Y])return bH[Y];if(Y==="times")return"×";if(Y==="cdot")return"·";if(Y==="div")return"÷";if(Y==="pm")return"±";if(Y==="leq"||Y==="le")return"≤";if(Y==="geq"||Y==="ge")return"≥";if(Y==="neq"||Y==="ne")return"≠";if(Y==="approx")return"≈";if(Y==="sim")return"~";if(Y==="infty")return"∞";if(Y==="partial")return"∂";if(Y==="nabla")return"∇";if(Y==="sqrt")return"√";if(Y==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Y,Q)=>Q.length===1?`${Y}${Q}`:`${Y}(${Q})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function TL($){let Z=yH.get($);if(Z!==void 0)return Z;return Z=UL++,yH.set($,Z),Z}function NL($,Z){return`${BL}\x00${TL(Z)}\x00${$}`}function EL($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}async function SL($,Z){let J=NL($,Z),Y=f1.get(J);if(Y)return Y;let Q=o7.get(J);if(Q)return Q;let W=(async()=>{let H=DL($,r7,!0);if(!H)return null;let V=null;try{V=await QL(TH(zL(),"lodestar-math-"));let z=TH(V,`formula-${EL($)}.png`);await HL(z,H.png);let X=await Z(z,{tex:$,width:H.width,height:H.height});if(!X)return _(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:X,width:H.width,height:H.height};if(f1.has(J))f1.delete(J);f1.set(J,G);while(f1.size>OL){let K=f1.keys().next().value;if(typeof K!=="string")break;f1.delete(K)}return G}catch(z){return _(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(V)try{await WL(V,{recursive:!0,force:!0})}catch(z){_(`math-render: temp cleanup failed for ${V}: ${z}`)}}})();o7.set(J,W);try{return await W}finally{o7.delete(J)}}function kL($,Z,J){let Y=$.width<=KL;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Y?"crop_center":"fit_horizontal",...Y?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function vH($,Z={}){let J=fH($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??RL,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let K=FL(G.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await SL(G.tex,Y)}})),W=[],H="",V=0,z=0,X=()=>{if(!H)return;if(H.trim())W.push({type:"markdown",text:H});H=""};for(let G=0;G<J.length;G++){let K=J[G],B=Q[G];if(H+=$.slice(V,K.start),B.unicode!==null){H+=B.unicode,V=K.end;continue}let L=B.uploaded;if(!L){H+=K.raw,V=K.end;continue}X(),W.push(kL(L,K,z++)),V=K.end}if(H+=$.slice(V),X(),!W.length)W.push({type:"markdown",text:$});return{blocks:W,formulaCount:J.length,renderedImageCount:z}}function t7($){return fH($).length>0}var v1,XL=0.5,r7=22,NH="#1F2329",wH="#F7F8FA",a7=12,EH=8,GL=720,_L=14,KL=278,BL="v4-native-cjk-tail-pad",AL=1100,SH,qL="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",kH,bH,RL=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => ($$(),W$));return Z($)},yH,UL=1,f1,o7,OL=512;var hH=T(()=>{I();v1=VL(import.meta.url),SH=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",kH=new Map;bH={alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",pi:"π",rho:"ρ",sigma:"σ",tau:"τ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",Gamma:"Γ",Delta:"Δ",Theta:"Θ",Lambda:"Λ",Pi:"Π",Sigma:"Σ",Phi:"Φ",Psi:"Ψ",Omega:"Ω"};yH=new WeakMap,f1=new Map,o7=new Map});import{readFileSync as CL}from"node:fs";function S2($){return s7.has($)}function o4($){s7.add($)}function r4($){s7.delete($)}function k2(){try{let $={};for(let[Z,J]of l$)$[Z]=J;t(o8,$)}catch($){throw _(`notify-callbacks: save failed (${o8}): ${$}`),$}}function cH(){let $=[],Z;try{Z=CL(o8,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-mH,Q=0,W=0;for(let H of Object.values(J)){if(!H||typeof H!=="object")continue;if(typeof H.notifyId!=="string"||typeof H.callbackUrl!=="string")continue;if(typeof H.createdAt!=="number"||H.createdAt<Y){Q++;continue}if(H.replyState?.status==="sending"&&!H.resolvedAt&&!H.unknownAt)H.unknownAt=Date.now(),H.unknownBy={openId:H.replyState.openId},H.unknownReason="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",W++;if(l$.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(_(`notify-callbacks: loaded ${l$.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),W)_(`notify-callbacks: ${W} interrupted text reply(s) marked UNKNOWN`);if(Q>0||W>0)k2()}catch(J){_(`notify-callbacks: load failed (${o8}): ${J}`)}return $}function pH($){let Z=Date.now();if(Z-gH>=bL)yL(Z),gH=Z;l$.set($.notifyId,$),k2()}function C0($){return l$.get($)}function e7($){return[...l$.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function t4($,Z){if(!$)return;return e7($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function uH($,Z){return!!Z&&[...l$.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function x2($,Z){let J=l$.get($);if(!J)throw Error(`notify registration not found: ${$}`);let{replyState:Y,replyMessageIds:Q}=J;if(J.replyState=Z,Z.response&&!J.replyMessageIds?.includes(Z.response.message_id))J.replyMessageIds=[...J.replyMessageIds??[],Z.response.message_id];try{k2()}catch(W){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw W}}function s4($,Z,J){let Y=l$.get($);if(!Y)throw Error(`notify registration not found: ${$}`);let Q={resolvedAt:Y.resolvedAt,resolvedBy:Y.resolvedBy,unknownAt:Y.unknownAt,unknownBy:Y.unknownBy,unknownReason:Y.unknownReason};Y.resolvedAt=Date.now(),Y.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Y.unknownAt,delete Y.unknownBy,delete Y.unknownReason;try{k2()}catch(W){if(Q.resolvedAt===void 0)delete Y.resolvedAt;else Y.resolvedAt=Q.resolvedAt;if(Q.resolvedBy===void 0)delete Y.resolvedBy;else Y.resolvedBy=Q.resolvedBy;if(Q.unknownAt===void 0)delete Y.unknownAt;else Y.unknownAt=Q.unknownAt;if(Q.unknownBy===void 0)delete Y.unknownBy;else Y.unknownBy=Q.unknownBy;if(Q.unknownReason===void 0)delete Y.unknownReason;else Y.unknownReason=Q.unknownReason;throw W}}function $Z($,Z,J,Y){let Q=l$.get($);if(!Q)throw Error(`notify registration not found: ${$}`);delete Q.resolvedAt,delete Q.resolvedBy,Q.unknownAt=Date.now(),Q.unknownBy={...Z!==void 0?{buttonId:Z}:{},openId:J},Q.unknownReason=Y,k2()}function r8($,Z,J){try{return s4($,Z,J),{state:"complete"}}catch(Y){let W=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{$Z($,Z,J,W)}catch(H){let V=H instanceof Error?H.message:String(H);W+=`; unknown tombstone persistence also failed: ${V}`;let z=l$.get($);if(z)z.unknownReason=W}return{state:"unknown",detail:W}}}function yL($=Date.now()){let Z=$-mH,J=0;for(let[Y,Q]of l$)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)l$.delete(Y),J++;if(J>0)k2();return J}async function ZZ($,Z,J){let Y={notify_id:$.notifyId,message_id:$.messageId,chat_id:$.chatId,project:$.project,..."id"in Z?{button:{id:Z.id,text:Z.text,type:Z.type}}:{response:{type:"text",...Z}},operator:{open_id:J},timestamp:Math.floor(Date.now()/1000)},Q=new AbortController,W=setTimeout(()=>Q.abort(),IH);try{let H=await wJ($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Y),signal:Q.signal});if(H.status>=200&&H.status<300){let z;try{let X=(await H.text()).trim();if(X.startsWith("{")){let G=JSON.parse(X),K=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(K.trim())z=K.trim().slice(0,500)}else if(X)z=X.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:z}}let V="";try{V=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${V?` ${V}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${IH}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(W)}}function lH($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((V)=>V.id===Y):void 0,W=$.replyState?.response,H=Y!==void 0?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y}}:W?{response:{type:"text",...W}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Y===void 0?"resolved":J&&Y===void 0?"unknown":$.replyState.status,prompt_message_id:$.replyState.promptMessageId,operator:{open_id:$.replyState.openId},...$.replyState.cancelReason?{cancel_reason:$.replyState.cancelReason}:{},...$.replyState.error?{error:$.replyState.error}:{}}}:{},...Z?{...H,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...H,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var mH=604800000,IH=2500,l$,gH,bL=86400000,s7,o8;var e4=T(()=>{n$();I();H$();f$();l$=new Map,gH=Date.now(),s7=new Set;o8=RJ});function t8($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function C2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(t4($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(t8($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function JZ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:t4($.chatId)?"notification":t8($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function YZ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||C2($,Z)||!Y?.userOpenId||!Y.messageId)return;J.announced=!0;let Q=(J.announcementVersion??0)+1;J.announcementVersion=Q;let W=J.questions[J.currentIdx]?.question.trim()??"",H=W.length>40?W.slice(0,40)+"…":W,V=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${H?`: ${H}`:""}`:H?`❓ ${H}`:"❓ 等你回答问题";(async()=>{if(F$(Y.cardId),await U8(Y.cardId,{config:{summary:{content:V}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||C2($,Z))return;await N1(Y.messageId,[Y.userOpenId])})().catch((z)=>_(`session "${$.sessionName}": question notification failed: ${z}`))}function s8($){let Z=$.currentTurn;if(!Z)return;for(let[J,Y]of $.pendingAsks){let Q=Z.toolByUseId.get(J);if(!Q||Y.currentIdx===void 0)continue;let W=JZ($,J);if(W.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;Z$(Z.cardId,U.tool(Q.i),O2(Q.i,J,Y.questions,"\uD83E\uDD14",W)),YZ($,J)}}function iH($){return t8($)!==void 0}async function dH($,Z,J,Y){let Q=t8($);if(!Q){_(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[W,H]=Q,V=C2($,W);if(V){let X=`${V}。这条文字未提交,请稍后重新发送。`;if(!await N($.chatId,X))throw Error(`提问等待提示发送失败: ${X}`);return}if(await QZ($,W,H.currentIdx,Z,J)&&Y)c$(Y,"CheckMark")}async function nH($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return _(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==W.currentIdx)return _(`session "${$.sessionName}": stale ask click q=${J} current=${W.currentIdx}`),!1;return aH($,Z,{optionIdx:Y,user:Q})}async function QZ($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return _(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return _(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==W.currentIdx)return _(`session "${$.sessionName}": stale ask custom q=${J} current=${W.currentIdx}`),!1;return aH($,Z,{customText:H,user:Q})}function aH($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=C2($,Z);if(Q)return _(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let W=Y.currentIdx,H=Y.questions[W];if(!H)return _(`session "${$.sessionName}": advanceAsk currentIdx=${W} out of range`),!1;let V;if(J.customText!==void 0)V=J.customText;else if(J.optionIdx!==void 0){let B=H.options?.[J.optionIdx];if(!B)return _(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;V=B.label}else return _(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[H.question]=V,Y.answered.set(W,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Y.questions.length,X=void 0;for(let B=W+1;B<z;B++)if(!Y.answered.has(B)){X=B;break}Y.currentIdx=X;let G=$.currentTurn,K=G?.toolByUseId.get(Z);if(G&&K){let B=O2(K.i,Z,Y.questions,X===void 0?"✅":"\uD83E\uDD14",{currentIdx:X,answered:Y.answered});Z$(G.cardId,U.tool(K.i),B)}if(X===void 0)if(Y.requestId)WZ($,Z);else _(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),s8($);return!0}function WZ($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Y=$.currentTurn?.toolByUseId.get(Z),Q=Y?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Q,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Y)Y.output=JSON.stringify({answers:J.answers}),Y.isError=!1;if($.pendingAsks.delete(Z),s8($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var e8=T(()=>{r0();$0();$$();I();e4()});import{isAbsolute as fL}from"node:path";function R$($){if($?.planLiveInserted)return U.planLive;return $?.taskLiveInserted?U.taskBoardLive:U.footer}function vL($){return $==="ImageGeneration"||$==="imageGeneration"}function hL($,Z,J){if(J||!vL($))return null;let Y=a8(Z.trim());return fL(Y)?Y:null}function IL($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function oH($,Z,J){return $==="read"?u4(Z,J):p4(Z,J)}function rH($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=IL(J);if(Q&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,X=$.currentTurn.toolBatches.get(z);if(X&&X.kind===Q){let G=X.items.length;X.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:z,name:J,input:Y,batchSlot:G});let K=Q==="read"?u4(z,X.items):p4(z,X.items);Z$($.currentTurn.cardId,U.tool(z),K),$6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let W=b1(J);if(W){let z=$.currentTurn;if(W==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,D$(z.cardId,y1($.taskBoard),{type:"insert_before",targetElementId:U.footer});else Z$(z.cardId,U.taskBoardLive,y1($.taskBoard));let X=W==="TaskCreate";if(X)z.taskUpdateI=null;else z.taskCreateI=null;let G=(X?z.taskCreateI:z.taskUpdateI)===null;if(G)if(X)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let K=X?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:K,name:J,input:Y});let B=J1(K,$.taskBoard,{name:W,status:"⏳"});G?D$(z.cardId,B,{type:"insert_before",targetElementId:R$(z)}):Z$(z.cardId,U.tool(K),B),$6(z,J,Y);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let H=$.currentTurn.toolCount++;if(Q){$.currentTurn.openBatchI=H;let z=[{toolUseId:Z,input:Y,output:null,isError:!1}];$.currentTurn.toolBatches.set(H,{kind:Q,items:z}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y,batchSlot:0});let X=Q==="read"?u4(H,z):p4(H,z);D$($.currentTurn.cardId,X,{type:"insert_before",targetElementId:R$($.currentTurn)}),$6($.currentTurn,J,Y);return}if($.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y}),J==="AskUserQuestion"){let z=Array.isArray(Y?.questions)?Y.questions:[],X=z.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:z,i:H,answers:{},answered:G,currentIdx:X});let K=O2(H,Z,z,"\uD83E\uDD14",JZ($,Z));D$($.currentTurn.cardId,K,{type:"insert_before",targetElementId:R$($.currentTurn)}),YZ($,Z);return}let V=L0(H,J,Y,null,"⏳");D$($.currentTurn.cardId,V,{type:"insert_before",targetElementId:R$($.currentTurn)}),$6($.currentTurn,J,Y)}function $6($,Z,J){if(!$)return;let Y=t0(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,W=k1(Z),H=Q?`\uD83D\uDD27 ${W}: ${Q}`:`\uD83D\uDD27 ${W}`;k0($.cardId,H)}function tH($,Z,J,Y,Q){if(!$.currentTurn)return;let W=$.currentTurn.toolByUseId.get(Z);if(!W)return;if(Q&&typeof Q==="object")W.input={...W.input,...Object.fromEntries(Object.entries(Q).filter(([,G])=>G!==void 0))};let H=typeof J==="string"?J:Array.isArray(J)?J.map((G)=>G?.text??JSON.stringify(G)).join(`
213
+ `):JSON.stringify(J);if(W.output=H,W.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let V=hL(W.name,H,Y);if(V){gL($,$.currentTurn,W,V),$9($);return}if(W.name==="AskUserQuestion"){$9($);return}if(W.batchSlot!=null){let G=$.currentTurn.toolBatches.get(W.i);if(G){let K=G.items[W.batchSlot];if(K)K.output=H,K.isError=Y;let B=oH(G.kind,W.i,G.items);Z$($.currentTurn.cardId,U.tool(W.i),B)}$9($);return}let z=b1(W.name);if(z){mL($,W,z,W.input,H,Y,W.resolvedNote);return}let X=L0(W.i,W.name,W.input,H,Y?"❌":"✅",W.resolvedNote);Z$($.currentTurn.cardId,U.tool(W.i),X),$9($)}function gL($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,W=U.tool(J.i),H=Z.imageDeliveryInflight??=new Map,V=H.get(Q)??new Set;H.set(Q,V);let z=(async()=>{let X=null;try{X=await $7(Y)}catch(K){_(`generated image upload failed: ${K}`)}if(X){let K=!1;try{K=await G$(Q,W,L0(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,X),{notifyCardFailure:!1})}catch(B){_(`generated image embed failed: ${B}`)}if(K){J.imageKey=X,Z.outboundSentPaths.add(Y);return}_(`generated image could not be embedded in card ${Q}; sending it as a separate message`)}let G=X?await M8($.chatId,X)!==null:await w4($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else _(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await G$(Q,W,L0(J.i,J.name,J.input,J.output??null,G?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!G&&X)await N($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(X)=>{_(`generated image delivery failed: ${X}`),await N($.chatId,`❌ 生成图片发送失败:${X instanceof Error?X.message:String(X)}`)});V.add(z),z.finally(()=>{if(V.delete(z),!V.size)H.delete(Q)}).catch((X)=>_(`generated image failure notice failed: ${X}`))}async function HZ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function mL($,Z,J,Y,Q,W,H){if(!$.currentTurn)return;if(!W)$.taskBoard=c7($.taskBoard,J,Y,Q);let V=J1(Z.i,$.taskBoard,{name:J,status:W?"❌":"✅"},H);if(Z$($.currentTurn.cardId,U.tool(Z.i),V),$.currentTurn.taskLiveInserted)Z$($.currentTurn.cardId,U.taskBoardLive,y1($.taskBoard));$9($)}function $9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function VZ($,Z,J,Y,Q,W=$.currentTurn){let H=W;if(!H)return;for(let[V,z]of Y){if(H.toolByUseId.has(V))continue;let X=z.batchSlot??null,G=z.input,K,B;if(X!=null){let F=Q.get(z.i)?.items[X];if(!F)continue;G=F.input,K=F.output,B=F.isError}else K=z.output??null,B=z.isError??!1;let L=K!=null,A=U2(Z,U.tool(z.i));if(L&&!A)continue;if(X!=null){let F=Q.get(z.i)?.kind;if(!F)continue;let R=H.toolCount++,M={toolUseId:V,input:G,output:K,isError:B};H.toolBatches.set(R,{kind:F,items:[M]}),H.toolByUseId.set(V,{...z,i:R,batchSlot:0}),D$(J,oH(F,R,[M]),{type:"insert_before",targetElementId:R$(H)});continue}let j=b1(z.name);if(j){let F=j==="TaskCreate";if(F)H.taskUpdateI=null;else H.taskCreateI=null;let R=(F?H.taskCreateI:H.taskUpdateI)===null;if(R)if(F)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let M=F?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(V,{...z,i:M});let k=!L?"⏳":B?"❌":"✅",C=J1(M,$.taskBoard,{name:j,status:k},z.resolvedNote);R?D$(J,C,{type:"insert_before",targetElementId:R$(H)}):Z$(J,U.tool(M),C);continue}let P=H.toolCount++;H.toolByUseId.set(V,{...z,i:P});let S=!L?"⏳":B?"❌":"✅";D$(J,L0(P,z.name,z.input,K,S,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:R$(H)})}}var sH=T(()=>{i7();r0();$0();$$();I();e8()});async function eH($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return _(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let W=$.proc;if(!W)return _(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{W.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(X){return _(`session "${$.sessionName}": permission response ${Z} failed: ${X}`),{ok:!1,message:`权限决定发送失败: ${X instanceof Error?X.message:X}`}}$.pendingPermissions.delete(Z);let V=$.currentTurn,z=V?.toolByUseId.get(Q.toolUseId);if(V&&z){let X=b1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,K=X?J1(z.i,$.taskBoard,{name:X,status:"❌"},G):L0(z.i,z.name,z.input,G,"❌");Z$(V.cardId,U.tool(z.i),K)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let K=X?J1(z.i,$.taskBoard,{name:X,status:"⏳"},z.resolvedNote):L0(z.i,z.name,z.input,null,"⏳",z.resolvedNote);Z$(V.cardId,U.tool(z.i),K)}}if(_(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Q.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function $V($,Z){let J=$.currentTurn;if(!J){_(`session "${$.sessionName}": can_use_tool with no current turn — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no active turn"});return}let Y=Z.tool_use_id;if(!Y){_(`session "${$.sessionName}": can_use_tool without tool_use_id — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no tool_use_id"});return}let Q=J.toolByUseId.get(Y);if(!Q){_(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Y} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Q.name==="AskUserQuestion"){let H=$.pendingAsks.get(Y);if(!H){_(`session "${$.sessionName}": AskUserQuestion ${Y} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(H.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Y}),H.currentIdx===void 0)WZ($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),_(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let W=T7(Q.i,Q.name,Q.input,Z.request_id);if(Z$(J.cardId,U.tool(Q.i),W),J.userOpenId&&J.messageId){let H=t0(Q.name,Q.input),V=k1(Q.name),z=H&&H.length>30?H.slice(0,30)+"…":H,X=z?`\uD83D\uDD10 等审批: ${V} · ${z}`:`\uD83D\uDD10 等审批: ${V}`;(async()=>{F$(J.cardId),await U8(J.cardId,{config:{summary:{content:X}}}),await N1(J.messageId,[J.userOpenId])})()}}var ZV=T(()=>{r0();$0();$$();I();e8()});class JV{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new q2({accountId:Q,login:!0}),Z=900000,J=(Q,W)=>{y.recordLogin(Q,W),RQ(Q)},Y=1e4){this.createClient=$;this.waitMs=Z;this.recordLogin=J;this.stateWaitMs=Y}async start($,Z){if(this.stopping)throw Error("服务正在退出,无法开始登录");if(!Z.userOpenId)throw Error("无法确认登录发起者");if(this.attempts.has($))throw Error("该账号已有登录任务;使用 codex-login-cancel 取消后再登录");let J=NY($),Y;try{Y=this.createClient($)}catch(z){throw J(),z}let Q,W,H=new Promise((z,X)=>{Q=z,W=X});H.catch(()=>{});let V={owner:Z,client:Y,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:H,resolve:Q,reject:W,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};V.notification=(z,X)=>{if(V.finishing||!V.loginRequested)return;if(z==="account/updated"){if(X?.authMode==="chatgpt"){if(V.authUpdated=!0,V.loginSucceeded)this.finish(V)}return}if(z!=="account/login/completed")return;if(!V.loginId){V.early.push(X);return}if(X?.loginId!==V.loginId)return;if(X?.success!==!0){this.finish(V,Error(typeof X?.error==="string"?X.error:"Codex 登录未成功"));return}if(V.loginSucceeded)return;if(V.loginSucceeded=!0,_(`codex-login: authorization completed account=${$} authUpdated=${V.authUpdated}`),V.timer)clearTimeout(V.timer);if(V.authUpdated)this.finish(V);else V.timer=setTimeout(()=>{this.finish(V,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},V.closed=(z)=>{this.finish(V,z)},Y.on("notification",V.notification),Y.on("closed",V.closed),Y.on("protocolError",V.closed),this.attempts.set($,V);try{await Y.initialize("lodestar-login"),V.loginRequested=!0;let z=await Y.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(z?.type!=="chatgptDeviceCode"||typeof z.loginId!=="string"||!z.loginId||typeof z.userCode!=="string"||!z.userCode||typeof z.verificationUrl!=="string"||new URL(z.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(V.loginId=z.loginId,V.finishing)throw await H,Error("登录已结束");V.timer=setTimeout(()=>{this.cancelAttempt(V,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let X of V.early)V.notification("account/login/completed",X);return V.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:H}}catch(z){return await this.finish(V,Z6(z)),await H}}pending($){return[...this.attempts.values()].filter((Z)=>Z.owner.chatId===$.chatId&&Z.owner.userOpenId===$.userOpenId).map((Z)=>Z.accountId)}async cancel($,Z){let J=this.attempts.get($);if(!J)throw Error("该账号没有等待中的登录");if(!Z.userOpenId||Z.chatId!==J.owner.chatId||Z.userOpenId!==J.owner.userOpenId)throw Error("只有发起登录的用户可在原群取消");if(J.finishing)throw Error("登录正在收尾,请等待结果");await this.cancelAttempt(J,"登录已取消")}async cancelAttempt($,Z){if($.finishing)return;$.finishing=!0;let J=Error(Z);if($.loginId&&$.client.isAlive())try{await $.client.request("account/login/cancel",{loginId:$.loginId})}catch(Y){J=Error(`${Z};取消请求失败:${Z6(Y).message}`)}await this.complete($,J)}async finish($,Z){if($.finishing)return;if($.finishing=!0,$.timer)clearTimeout($.timer);let J;if(!Z)try{let Y=await $.client.request("account/read",{refreshToken:!1});if(Y?.account?.type!=="chatgpt"){let Q=typeof Y?.account?.type==="string"?Y.account.type:"null";throw Error(`设备码授权已完成,但账号状态校验失败(account/read.type=${Q});认证文件已保留`)}J=Y.account,this.recordLogin($.accountId,J)}catch(Y){Z=Z6(Y)}await this.complete($,Z,J)}async complete($,Z,J){if($.timer)clearTimeout($.timer);$.client.off("notification",$.notification),$.client.off("closed",$.closed),$.client.off("protocolError",$.closed);try{await $.client.close()}catch(Y){Z=Error([Z?.message,`登录进程关闭失败:${Z6(Y).message}`].filter(Boolean).join(";"))}if(!$.client.isAlive())this.attempts.delete($.accountId),$.releaseAuth();if(Z)$.reject(Z);else if(J)$.resolve(J);else $.reject(Error("登录结束但账号信息缺失"))}async shutdown(){this.stopping=!0;let Z=(await Promise.allSettled([...this.attempts.values()].map(async(J)=>{if(await this.cancelAttempt(J,"服务退出,登录已取消"),J.client.isAlive())await J.client.close();if(J.client.isAlive())throw Error("登录进程仍未退出");J.releaseAuth(),this.attempts.delete(J.accountId),await J.done.then(()=>{},()=>{})}))).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 登录进程未完全退出")}}function Z6($){return $ instanceof Error?$:Error(String($))}var h1;var zZ=T(()=>{i0();I$();I();h1=new JV});function YV($){let Z=new Map,J=$.map((G)=>{let K=G.fingerprint?Z.get(G.fingerprint):void 0;if(G.fingerprint&&!K)Z.set(G.fingerprint,G.account.name);return{...G,...K?{duplicateOf:K}:{}}}),Y=J.filter((G)=>!G.duplicateOf),W=(Y.length<=1||Y.every((G)=>G.fingerprint!==null))&&Y.every((G)=>G.usage.state==="ok"),H=Y.flatMap((G)=>G.usage.state==="ok"?[G.usage]:[]),V=W&&H.every((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent!==null))?H.filter((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,z=W&&H.every((G)=>G.resetCredits!=null)?H.reduce((G,K)=>G+K.resetCredits,0):null,X=["fiveHour","weekly"].map((G)=>{let K=H.map((L)=>L[G]).filter((L)=>L!==null),B=W&&K.every((L)=>L.percent!==null&&L.percent>=0&&L.percent<=100);return{kind:G,count:K.length,remaining:B?K.reduce((L,A)=>L+(100-A.percent)/100,0):null}}).filter((G)=>G.count||!W);return{entries:J,complete:W,available:V,resetCredits:z,windows:X}}var QV=T(()=>{I$();i0()});class Z9{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=uL){let Y=await J.sendCard($,Y0(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new Z9(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=O4($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=O4($);return this.terminal=this.enqueue(()=>this.write($,Z,!0)),this.terminal}enqueue($){let Z=this.tail.then($);return this.tail=Z.then(()=>{},()=>{}),Z}async write($,Z,J){let Y=await this.deps.replaceElementChecked(this.cardId,U.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:U4($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var uL;var WV=T(()=>{$$();r0();C$();P2();uL={sendCard:u,convertMessageToCard:t$,recordCardCreated:p$,replaceElementChecked:G$,patchSettingsChecked:j$,dispose:y$}});var GZ={};P0(GZ,{settleCodexAccountCards:()=>XZ,runCodexNamedHi:()=>iL,runCodexAccountCommand:()=>dL});function J6($,Z){let J=$ instanceof Error?$.message:String($),Y=!/失败|未完全退出/.test(J)&&/登录已取消|服务退出/.test(J),Q=/过期|等待超过|expired/i.test(J),W=J.split(/[\n;]/)[0];return{phase:Y?"cancelled":Q?"expired":"error",name:Z,message:W.length>80?W.slice(0,77)+"…":W,...J!==W||W.length>80?{details:J}:{}}}async function lL($,Z){if(!await u($.chatId,Y0(J6(Z))))throw Error("Codex 错误卡片发送失败")}async function iL($,Z){let J=await Z9.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Y=y.find(Z),Q="";if(!await $.startWithCodexAccount(Y.id,{announce:!1,onStatus:(H)=>{Q=H}}))throw Error(Q||"指定账号启动失败");await J.finish({phase:"current",name:Y.name,current:Y.name,title:"已指定账号",hint:"本次手动指定 · 不参与自动排序"}),await $.showConsole()}catch(Y){await J.finish(J6(Y,Z))}}async function XZ(){let Z=(await Promise.allSettled([...b2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function dL($,Z,J,Y){let Q={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let V=h1.pending(Q);if(!J&&V.length!==1)throw Error(V.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let z=J?y.find(J).id:V[0];await h1.cancel(z,Q),await b2.get(z)}catch(V){await lL($,V)}return}let W=Z==="login"?J||"默认":Z==="account"?J||void 0:void 0,H=await Z9.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:W,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let K=J?Number(J):1,B=$.currentProvider()==="codex"?$.currentModelLabel():V$("codex-sub")?.defaultModel;if(!B)throw Error("Codex 模型 MISS,无法计算调度顺序");let L=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,A=await e9.choose({model:B,effort:L}),j=YV(A.candidates.flatMap((P)=>P.usage?[{account:P.account,usage:P.usage,fingerprint:P.identity.startsWith("record:")?null:P.identity}]:[]));await H.finish({phase:"accounts",total:j,currentId:$.codexAccountId(),...y.preferred($.sessionName)?{selectedId:y.selected($.sessionName)}:{},page:K,scheduling:{candidates:A.candidates,ultra:L==="ultra"},hint:"最高分优先 · hi 备注可直接指定账号"});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");y.selectAuto($.sessionName),await H.finish({phase:"selected",name:"自动选择",current:y.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await H.finish({phase:"current",current:y.get($.codexAccountId()).name,selected:y.preferred($.sessionName)===null?"自动 · 最高分优先":y.get(y.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let K=y.find(J),B=$.currentProvider()==="codex"?$.currentModelLabel():null,L=$.currentProvider()==="codex"?$.currentEffortLabel():null,A=y.get($.codexAccountId()).name;if($.currentProvider()==="codex")T1($.sessionName,"codex",B,L,"codex-sub");if(y.select($.sessionName,K.id),$.currentProvider()==="codex")$.selectedModel=B,$.selectedEffort=L,$.selectedTokenSourceId="codex-sub";await H.finish({phase:"selected",name:K.name,current:A,selected:K.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Y)throw Error("无法确认登录发起者");let V=y.ensure(J);if(U5(V.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(b2.has(V.id))throw Error("登录结果正在更新,请稍等");let z=await h1.start(V.id,Q);try{await H.update({phase:"waiting",flow:"login",name:V.name,verification:{url:z.verificationUrl,code:z.userCode},hint:`取消:codex-login-cancel${J?` ${V.name}`:""}`})}catch(K){throw await h1.cancel(V.id,Q),K}let X=(async()=>{let K;try{K=await z.done}catch(L){await H.finish(J6(L,V.name));return}await H.update({phase:"checking",flow:"login",name:V.name,message:"授权完成,正在读取模型…"});let B;try{await A2();let L=V$("codex-sub",V.id);if(!L)throw Error("Codex 订阅来源尚未初始化");if(await L.refreshModels(),L.modelCatalogState?.status!=="ready")throw Error(L.modelCatalogState?.error??"模型目录未就绪")}catch(L){B=L instanceof Error?L.message:String(L)}await H.finish({phase:B?"warning":"success",flow:"login",name:V.name,email:K.email,plan:K.planType,...B?{title:"已登录 · 目录 MISS",details:B}:{},hint:`已加入自动选择 · 优先使用:codex-account ${V.id==="default"?"default":V.name}`})})();b2.set(V.id,X);let G=()=>{if(b2.get(V.id)===X)b2.delete(V.id)};X.then(G,(K)=>{_(`codex-login: terminal card write failed: ${K}`),G()})}catch(V){await H.finish(J6(V,W))}}var b2;var Y6=T(()=>{$$();I$();zZ();Y$();QV();X3();WV();P2();I();b2=new Map});function k$($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function _Z($,Z){let J=$.agent==="claude"?V5.filter((Q)=>Q!=="default"):$.agent==="codex"?[...C5]:["off","minimal","low","medium","high","xhigh","max"],Y=Z.effort?.trim();return{efforts:J,defaultEffort:Y&&J.includes(Y)?Y:$.agent==="claude"?"max":$.agent==="codex"?"xhigh":"high"}}function Q6($,Z){let J=$.modelSelection,Y=new Set(k$(Z.hidden_models)),Q=[...new Set([...k$(Z.custom_models),...J?[]:k$(Z.models)])],W=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},H=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],W.availableModels=[],!J)W.modelIds=[];try{await H()}catch(G){throw $.models=[],$.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G instanceof Error?G.message:String(G)},G}if($.modelCatalogState?.status!=="ready")return;let V=$.models,z=(J?W.availableModels:V).map((G)=>({...G,origin:G.origin??"upstream"}));for(let G of Q){if(z.some((K)=>K.model.toLowerCase()===G.toLowerCase()))continue;z.push({model:G,display:G,origin:"custom",..._Z($,Z)})}W.availableModels=z;let X=J?V.map((G)=>z.find((K)=>K.model===G.model)??{...G,origin:"upstream"}):z;$.models=[...X.filter((G)=>G.origin==="custom"||!Y.has(G.model)),...z.filter((G)=>G.origin==="custom"&&!X.some((K)=>K.model===G.model))],W.modelIds=$.models.map((G)=>G.model)},$}var y2=T(()=>{P$();j1()});import{homedir as nL}from"node:os";function zV($,Z=VV){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function HV($){return typeof $==="string"&&aL.includes($)?$:null}async function XV(){let{ClaudeAgentProcess:$}=await Promise.resolve().then(() => (G4(),GQ)),Z=new $({workDir:nL(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1}});Z.on("error",(J)=>_(`Claude model catalog MISS: ${J.message}`));try{let J=await zV(Z.listModels());if(!J.length)throw Error("Claude SDK model catalog is empty");return J.map((Y)=>({model:Y.model.replace(/^claude:/,""),display:Y.displayName,efforts:Y.supportedReasoningEfforts.map((Q)=>Q.reasoningEffort),defaultEffort:Y.defaultReasoningEffort}))}finally{await Z.kill()}}async function GV($="default"){let Z=new q2({accountId:$});try{if(await Z.initialize("lodestar-models"),(await Z.request("account/read",{refreshToken:!1}))?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await zV(Z.request("model/list",{}));if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let Q=Y.data,W=[];for(let H of Q){if(!H||H.hidden||!H.id)continue;let V=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((X)=>HV(X?.reasoningEffort)).filter((X)=>X!==null);if(!V.length)continue;let z=HV(H.defaultReasoningEffort)??V[0];W.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:V,defaultEffort:z})}return W}finally{await Z.close()}}async function _V($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,W=await J$(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(VV)});if(!W.ok)throw Error(`HTTP ${W.status}`);let H=await W.json();if(!Array.isArray(H?.data))throw Error("GLM models 缺少 data 数组");return H.data.filter((z)=>z&&(z.display_name||z.id)).map((z)=>{let X=String(z.display_name||z.id);return{model:X,display:X,efforts:w2,defaultEffort:"max"}})}var VV=1e4,aL,w2;var J9=T(()=>{n$();i0();I();aL=["none","minimal","low","medium","high","xhigh","max","ultra"];w2=["max","xhigh","high","medium","low"]});import{existsSync as oL}from"node:fs";import{join as rL}from"node:path";function W6($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function tL($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null};let Z=[];if($.fiveHour)Z.push(W6($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(W6($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function sL($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Y=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(W6(J.fiveHour,"fiveHour",`${Y} 5h`));if(J.weekly)Z.push(W6(J.weekly,"weekly",`${Y} 周`))}return Z.length?Z:null}function KV($){return $===p||oL(rL(y.home($),"auth.json"))}var BV=T(()=>{x$();Y$();i0();J9();I();I$();y2();N$({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(W)=>{let H=KV(W),V=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,X={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,y.revision(W)]),enabled:H,models:[],modelCatalogState:{status:H?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(X.enabled=KV(W),!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{if(X.models=await GV(W),z)for(let G of X.models)G.defaultEffort=z;if(!V)X.defaultModel=X.models[0]?.model??"";X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(_(`codex-sub ${W} refreshModels MISS: ${G?.message??G}`),X.models=[],G?.code==="CODEX_AUTH_MISSING")X.enabled=!1;X.modelCatalogState={status:X.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let K=G0(G);return Object.assign(K,f.codex.env),y.env(W,K)},resolveSpawnModel(G){return G},async readUsage(){let G=await M1(W),K=tL(G),B=sL(G);if(B)K.windows=B;return K}};return X},Y=J(p);Y.forAccount=(W)=>{if(W===p)return Y;let H=y.revision(W),V=Z.get(W);if(V?.revision===H)return V.source;let z=Q6(J(W),$);return Z.set(W,{revision:H,source:z}),z};let Q=Y.refreshModels.bind(Y);return Y.refreshModels=async()=>{await Promise.all([Q(),...y.list().filter((W)=>W.id!==p).map((W)=>Y.forAccount(W.id).refreshModels())])},Y}})});function $j($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function H6($,Z,J){try{let Y=await J$($j($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(eL)});if(Y.ok)return"exists";if(Y.status===400){let Q=await Y.text();return Q.includes("1214")||Q.includes("不存在")||Q.includes("not exist")?"not_found":"no_verdict"}return _(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return _(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var eL=15000;var KZ=T(()=>{n$();I()});function AV($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function Zj($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function qV($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function Jj($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function Yj($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function BZ($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(AV($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(AV($.weekly,"weekly","周额度"));if($.monthly)Z.push(Zj($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var AZ=T(()=>{Y$();a4();J9();X4();KZ();I();N$({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Y=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Q=!!(J&&Y)&&w1(J),W=$.model?.trim()||void 0,H=Yj($.slots),V={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let z=await _V(J,Y),G=[...new Set([...qV($.models),...qV($.custom_models)])].filter((K)=>!z.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:w2,defaultEffort:"max",origin:"custom"}));if(V.models=[...z,...G],!W)V.defaultModel=Jj(V.models.map((K)=>K.model));for(let K of V.models){let B=V2("glm",K.model);K.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){_(`glm refreshModels MISS: ${z?.message??z}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...G0(z)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_AUTH_TOKEN=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(z){return p9("glm",z)},async verifyModel(z){return H6(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return BZ(await n4(J,Y))}};return V},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
174
214
  \`\`\`
175
215
  glm-setup <base_url> <token>
176
- \`\`\``,parseArgs:($)=>{let Z=$.trim().split(/\s+/);if(Z.length<2)return{error:"用法:`glm-setup <base_url> <token>`"};return{config:{agent:"claude",base_url:Z[0],auth_token:Z[1]}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!b1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var aH=T(()=>{J$();e4();T$({kind:"claude-native",configSectionId:"claude-native",build:($)=>{let Z={id:"claude-native",kind:"claude-native",agent:"claude",display:$.display?.trim()||"Claude",enabled:!1,models:[],modelCatalogState:{status:"disabled",updatedAt:Date.now()},defaultModel:$.model?.trim()||"opus",settingSources:["user","project","local"],async refreshModels(){if(Z.models=[],!Z.enabled){Z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Z.modelCatalogState={status:"loading",updatedAt:null};try{if(Z.models=await cH(),!Z.models.some((J)=>J.model===Z.defaultModel))throw Error("Claude 默认模型不在 SDK 目录中");Z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(J){throw Z.models=[],Z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:J instanceof Error?J.message:String(J)},J}},spawnEnv(J){return J},resolveSpawnModel(J){return J},async readUsage(){return{state:"not_applicable",windows:[]}}};return Z}})});function oH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function AP($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function qP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function PP($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function LP($,Z){let J=new URL($).origin,Y=await fetch(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json();if(!Array.isArray(Q?.data))throw Error("DeepSeek models 缺少 data 数组");return Q.data.filter((H)=>H&&typeof H.id==="string"&&H.id).map((H)=>({model:H.id,display:H.id,efforts:b2,defaultEffort:"high"}))}async function QZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await fetch(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(jP)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],V=typeof H?.currency==="string"?H.currency:"",X=H?.total_balance;if(!V||typeof X!=="string"&&typeof X!=="number"||String(X).trim()===""||!Number.isFinite(Number(X)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",windows:[],balance:{remaining:Number(X),currency:V}}}catch(Y){return _(`deepseek readUsage MISS: ${Y?.message??Y}`),{kind:"balance",state:"network",windows:[],reason:Y?.message??String(Y)}}}var BP="https://api.deepseek.com/anthropic",jP=1e4;var WZ=T(()=>{J$();e4();V4();ZZ();I();T$({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||BP,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,W=$.model?.trim()||void 0,H=qP($.slots),V={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let X=await LP(J,Y),G=[...new Set([...oH($.models),...oH($.custom_models)])].filter((K)=>!X.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:b2,defaultEffort:"high",origin:"custom"}));if(V.models=[...X,...G],!W)V.defaultModel=AP(V.models.map((K)=>K.model));for(let K of V.models){let B=Q2("deepseek",K.model);K.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){_(`deepseek refreshModels MISS: ${X?.message??X}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:X?.message??String(X)}}},spawnEnv(X){let G={...X0(X)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_API_KEY=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(X){return y9("deepseek",X)},async verifyModel(X){return r8(J,{"x-api-key":Y},X)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return QZ(J,Y)}};return V},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
216
+ \`\`\``,parseArgs:($)=>{let Z=$.trim().split(/\s+/);if(Z.length<2)return{error:"用法:`glm-setup <base_url> <token>`"};return{config:{agent:"claude",base_url:Z[0],auth_token:Z[1]}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!w1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var LV=T(()=>{Y$();J9();N$({kind:"claude-native",configSectionId:"claude-native",build:($)=>{let Z={id:"claude-native",kind:"claude-native",agent:"claude",display:$.display?.trim()||"Claude",enabled:!1,models:[],modelCatalogState:{status:"disabled",updatedAt:Date.now()},defaultModel:$.model?.trim()||"opus",settingSources:["user","project","local"],async refreshModels(){if(Z.models=[],!Z.enabled){Z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Z.modelCatalogState={status:"loading",updatedAt:null};try{if(Z.models=await XV(),!Z.models.some((J)=>J.model===Z.defaultModel))throw Error("Claude 默认模型不在 SDK 目录中");Z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(J){throw Z.models=[],Z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:J instanceof Error?J.message:String(J)},J}},spawnEnv(J){return J},resolveSpawnModel(J){return J},async readUsage(){return{state:"not_applicable",windows:[]}}};return Z}})});function jV($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function Wj($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function Hj($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function Vj($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function zj($,Z){let J=new URL($).origin,Y=await J$(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json();if(!Array.isArray(Q?.data))throw Error("DeepSeek models 缺少 data 数组");return Q.data.filter((H)=>H&&typeof H.id==="string"&&H.id).map((H)=>({model:H.id,display:H.id,efforts:w2,defaultEffort:"high"}))}async function qZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await J$(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(Xj)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],V=typeof H?.currency==="string"?H.currency:"",z=H?.total_balance;if(!V||typeof z!=="string"&&typeof z!=="number"||String(z).trim()===""||!Number.isFinite(Number(z)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",windows:[],balance:{remaining:Number(z),currency:V}}}catch(Y){return _(`deepseek readUsage MISS: ${Y?.message??Y}`),{kind:"balance",state:"network",windows:[],reason:Y?.message??String(Y)}}}var Qj="https://api.deepseek.com/anthropic",Xj=1e4;var LZ=T(()=>{n$();Y$();J9();X4();KZ();I();N$({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||Qj,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,W=$.model?.trim()||void 0,H=Hj($.slots),V={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!V.enabled){V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let z=await zj(J,Y),G=[...new Set([...jV($.models),...jV($.custom_models)])].filter((K)=>!z.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:w2,defaultEffort:"high",origin:"custom"}));if(V.models=[...z,...G],!W)V.defaultModel=Wj(V.models.map((K)=>K.model));for(let K of V.models){let B=V2("deepseek",K.model);K.context1m=B!=null&&B>=1e6||void 0}V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){_(`deepseek refreshModels MISS: ${z?.message??z}`),V.models=[],V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...G0(z)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_API_KEY=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(z){return p9("deepseek",z)},async verifyModel(z){return H6(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return qZ(J,Y)}};return V},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
177
217
  \`\`\`
178
218
  deepseek-setup <api_key>
179
219
  \`\`\`
180
- 默认官方 Anthropic 端点;自建中转用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length)return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Y=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Y}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!PP(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function v1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var HZ;var rH=T(()=>{HZ=[{rank:1,lab:"Anthropic",model:"anthropic/claude-fable-5.1",effort:"max"},{rank:3,lab:"Moonshot",model:"moonshotai/kimi-k3",effort:"max"},{rank:4,lab:"Tencent",model:"tencent/hy4-preview",effort:"high"},{rank:7,lab:"Google",model:"google/gemini-3.8-flash",effort:"high"},{rank:8,lab:"SpaceXAI",model:"x-ai/grok-4.5",effort:"high"},{rank:9,lab:"Alibaba",model:"qwen/qwen3.8-max-0902",effort:"xhigh"},{rank:10,lab:"Meta",model:"meta/muse-spark-1.2",effort:"xhigh"},{rank:11,lab:"Xiaomi",model:"xiaomi/mimo-v2.5-pro",effort:"default"},{rank:12,lab:"MiniMax",model:"minimax/minimax-m3",effort:"default"},{lab:"ByteDance",model:"bytedance-seed/seed-2-1-turbo",effort:"default"},{lab:"Meituan",model:"meituan/longcat-2.0",effort:"default"}]});function Z1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function XZ($){return $ instanceof Error?$.message:String($)}function tH($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function y2($){return $.replace(/\[1m\]$/,"")}function t8($){let Z=new URL($);if(!["https:","http:"].includes(Z.protocol)||Z.username||Z.password||Z.search||Z.hash)throw Error("OpenRouter base_url 必须是无凭据、查询参数和 fragment 的 HTTP(S) API 根地址");return Z.pathname=Z.pathname.replace(/\/+$/,"").replace(/\/v1$/,""),Z.toString().replace(/\/+$/,"")}async function eH($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await fetch(`${t8($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(MP)});if(!Y.ok){let Q=await Y.text(),W="";if(Q.trim().startsWith("{"))try{let H=JSON.parse(Q);if(Z1(H)&&Z1(H.error)&&typeof H.error.message==="string")W=H.error.message}catch{}throw new zZ(Y.status,W.replaceAll(Z,"[redacted]"))}return Y.json()}async function FP($,Z){let J=await eH($,Z,"models/user");if(!Z1(J)||!Array.isArray(J.data))throw Error("OpenRouter models: data 数组缺失");let Y=[],Q=new Set;for(let W of J.data){if(!Z1(W)||typeof W.id!=="string"||!W.id||typeof W.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!Z1(W.architecture)||!Array.isArray(W.architecture.output_modalities)||!Array.isArray(W.supported_parameters))throw Error(`OpenRouter models: ${W.id} 的模型能力缺失`);if(v1(W.id)||!W.architecture.output_modalities.includes("text")||!W.supported_parameters.includes("tools")||W.id.endsWith(":batch")||Q.has(W.id))continue;let H=Z1(W.reasoning)?W.reasoning:void 0,V=H?.supported_efforts,X=V===null||V===void 0&&W.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(V)?[...new Set(V.filter((B)=>B!=="default"&&O$(B)))]:["default"],z=HZ.find((B)=>B.model===W.id),G=z?X.includes(z.effort)?z.effort:null:X[0]==="default"?"default":O$(H?.default_effort)&&X.includes(H.default_effort)?H.default_effort:null,K=Q2("openrouter",W.id);Y.push({model:W.id,display:W.name,efforts:X,defaultEffort:G,context1m:K!==void 0&&K>=1e6||void 0}),Q.add(W.id)}if(!Y.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Y}function sH($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function RP($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await eH($,Z,"credits");if(!Z1(J)||!Z1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!sH(Y)||!sH(Q))throw Error("OpenRouter credits: total_credits/total_usage 缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Y-Q,currency:"USD"}}}catch(J){let Y=XZ(J);return _(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof zZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var DP="https://openrouter.ai/api",MP=1e4,VZ,zZ;var $V=T(()=>{L$();J$();V4();I();rH();VZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};zZ=class zZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};T$({kind:"openrouter",configSectionId:"openrouter",build($,Z){let J=$.api_key||$.auth_token||$.base_url?$:Z,Y=J?.api_key?.trim()||J?.auth_token?.trim()||"",Q=J?.base_url?.trim()||DP,W=$.model?.trim()||"",H=$.models===void 0?HZ.map((X)=>X.model):tH($.models),V={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Y,models:[],defaultModel:W,modelSelection:{mode:"allowlist",modelIds:H,availableModels:[]},validateCustomModelId(X){if(v1(X))throw Error(`OpenRouter 已排除此厂商或自动路由: ${X}`);if(!X.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(X){let z=V.modelSelection.availableModels.find((G)=>y2(G.model)===y2(X));if(!z||z.unavailableReason||!z.efforts.length)return"model-unavailable";return z.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(V.models=[],V.modelSelection.availableModels=[],!V.enabled){V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let X=await FP(Q,Y),z=X.find((K)=>K.model===y2(W));if(W&&!z)throw Error(`OpenRouter 默认模型不在账号目录中: ${W}`);if($.effort){if(!W)throw Error("OpenRouter effort 需要同时配置 model");if(!O$($.effort)||!z.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${W} 不支持 effort ${$.effort}`);z.defaultEffort=$.effort}let G=H.map((K)=>{let B=X.find((A)=>A.model===y2(K));if(!B)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:v1(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{...B,model:K}});V.models=G,V.modelSelection.availableModels=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let z=XZ(X);_(`openrouter refreshModels MISS: ${z}`),V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z}}},spawnEnv(X,z){if(!Y)throw Error("OpenRouter API key missing");let G=z||W;if(!G)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(v1(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let K=X0(X);K.ANTHROPIC_BASE_URL=t8(Q),K.ANTHROPIC_AUTH_TOKEN=Y,K.ANTHROPIC_API_KEY="",K.CLAUDE_CODE_NO_MODEL_FALLBACK="1",K.ANTHROPIC_MODEL=G,K.ANTHROPIC_SMALL_FAST_MODEL=G,K.CLAUDE_CODE_SUBAGENT_MODEL=G,K.ANTHROPIC_DEFAULT_FABLE_MODEL=G;for(let B of Object.values(VZ))K[B]=G;for(let B of tH($.slots)){let A=B.indexOf("="),P=B.slice(0,A).trim(),L=B.slice(A+1).trim();if(A<1||!Object.hasOwn(VZ,P)||!L)throw Error(`OpenRouter slots 无效: ${B}`);if(v1(L)||!V.modelSelection.availableModels.some((j)=>!j.unavailableReason&&y2(j.model)===y2(L)))throw Error(`OpenRouter slot 模型不在账号目录中: ${L}`);if(V.modelEnvironmentRevision(L)!==V.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${L}`);K[VZ[P]]=L}return K},resolveSpawnModel(X){if(v1(X))throw Error(`OpenRouter 已排除此厂商或自动路由: ${X}`);return X||void 0},readUsage(){return RP(Q,Y)}};return V},setup:{commandSuffix:"openrouter",hint:($)=>`启用 ${$}:发送 \`openrouter-setup <api_key>\`,然后通过 \`model\` 选择模型。自建端点用 \`openrouter-setup <base_url> <api_key>\`。`,parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||Z.length===1&&/^https?:\/\//i.test(Z[0]))return{error:"用法: openrouter-setup <api_key> 或 openrouter-setup <base_url> <api_key>"};try{return{config:{agent:"claude",api_key:Z[Z.length-1],...Z.length===2?{base_url:t8(Z[0])}:{}}}}catch(J){return{error:XZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=t8(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var ZV=T(()=>{J$();L$();t2();W$();WZ();C2();T$({kind:"deepseek-harness",configSectionId:"deepseek-harness",build($){let Z=$.api_key?.trim()??"",J=$.base_url?.trim()||"https://api.deepseek.com",Y={id:"deepseek-harness",kind:"deepseek-harness",agent:"dsh",display:$.display?.trim()||"DeepSeek",enabled:!!Z,models:[],defaultModel:$.model?.trim()??"",modelCatalogState:{status:Z?"idle":"disabled",updatedAt:Date.now()},spawnEnv(Q){let W=z4(Q);if(!Z)throw Error("DeepSeek Harness API key is missing");if(W.DEEPSEEK_API_KEY=Z,W.DEEPSEEK_BASE_URL=J,W.LODESTAR_DSH_PROVIDER="deepseek-official",$.bin)W.LODESTAR_DSH_NODE=$.bin;return W},async refreshModels(){if(!Y.enabled){Y.models=[],Y.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Y.modelCatalogState={status:"loading",updatedAt:null};try{let Q=await r1({cwd:d1,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...S$($.models),...S$($.custom_models)]});if(!Array.isArray(Q)||!Q.length)throw Error("DeepSeek Harness model catalog is empty");for(let H of Q)if(!H.model||!H.efforts.length||!H.efforts.every(_$)||!_$(H.defaultEffort)||!H.efforts.includes(H.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${H.model}`);let W=$.model?.trim()||Q.find((H)=>H.isDefault)?.model;if(!W||!Q.some((H)=>H.model===W))throw Error("DSH default model is not in its catalog");Y.models=Q.map(({model:H,display:V,efforts:X,defaultEffort:z,isCustom:G})=>{let K=$.effort?.trim();if(K&&(!_$(K)||!X.includes(K)))throw Error(`DSH model ${H} does not support configured effort ${K}`);return{model:H,display:V,efforts:X,defaultEffort:K?K:z,origin:G?"custom":"upstream"}}),Y.defaultModel=W,Y.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(Q){throw Y.models=[],Y.modelCatalogState={status:"failed",updatedAt:Date.now(),error:Q instanceof Error?Q.message:String(Q)},Q}},resolveSpawnModel(Q){return V2(Y).find((W)=>W.model===Q)?.model},readUsage(){return Z?QZ(J,Z):Promise.resolve({kind:"balance",state:"no_credentials",windows:[]})}};return Y},setup:{commandSuffix:"deepseek-harness",hint:()=>"启用 DeepSeek Harness:发送 `deepseek-harness-setup <api_key>`,或 `deepseek-harness-setup <base_url> <api_key>`。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2)return{error:"用法:deepseek-harness-setup [base_url] <api_key>"};return{config:{agent:"dsh",api_key:Z.at(-1),...Z.length===2?{base_url:Z[0]}:{}}}}}})});function GZ($){let Z=new URL($);if(!b1(Z.origin))throw Error("DSH GLM 需要 bigmodel.cn 或 z.ai 的 Coding Plan 端点");return Z.pathname="/api/coding/paas/v4",Z.search="",Z.hash="",Z.toString().replace(/\/$/,"")}async function UP($,Z){let J=await fetch(`${$}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!J.ok)throw Error(`GLM Coding Plan models HTTP ${J.status}`);let Y=await J.json();if(!Array.isArray(Y?.data)||!Y.data.length)throw Error("GLM Coding Plan 模型目录为空或无效");return Y.data.map((Q)=>{if(typeof Q?.id!=="string"||!Q.id)throw Error("GLM Coding Plan 模型 id 无效");return{model:Q.id,display:typeof Q.name==="string"?Q.name:Q.id}})}var JV=T(()=>{k$();L$();J$();t2();W$();i4();YZ();C2();T$({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=f.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&b1(Y)?{api_key:J,base_url:GZ(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=GZ($.base_url?.trim()||Z?.base_url?.trim()||"https://open.bigmodel.cn/api/coding/paas/v4"),Q=new URL(Y).hostname.endsWith("bigmodel.cn")?"zai-coding-cn":"zai",W,H={id:"dsh-glm",kind:"dsh-glm",agent:"dsh",display:$.display?.trim()||"GLM Coding Plan",enabled:!!J,models:[],defaultModel:$.model?.trim().toLowerCase()??"",modelEnvironmentRevision(){return JSON.stringify([...W??[]].sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(V){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let X=z4(V);if(X.LODESTAR_DSH_PROVIDER=Q,X.LODESTAR_DSH_GLM_API_KEY=J,X.LODESTAR_DSH_BASE_URL=Y,X.LODESTAR_DSH_DEFAULT_MODEL=H.defaultModel,W)X.LODESTAR_DSH_MODELS=JSON.stringify(W);if($.bin)X.LODESTAR_DSH_NODE=$.bin;return X},async refreshModels(){if(H.models=[],W=void 0,!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let V=await UP(Y,J),X=[...V];for(let G of[...S$($.models),...S$($.custom_models)])if(!X.some((K)=>K.model.toLowerCase()===G.toLowerCase()))X.push({model:G,display:G});if(W=X.map((G)=>G.model),!$.model?.trim()){let G=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);H.defaultModel=[...V].sort((K,B)=>G(B.model)-G(K.model))[0].model}let z=await r1({cwd:d1,env:H.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");H.models=X.map((G)=>{let K=z.find((L)=>L.model===G.model),B=$Z(H,$),A=K?K.efforts.filter(_$):B.efforts,P=$.effort?.trim()||K?.defaultEffort||B.defaultEffort;return{...G,display:K?.display??G.display,efforts:A,defaultEffort:_$(P)&&A.includes(P)?P:null,origin:V.some((L)=>L.model===G.model)?"upstream":"custom"}}),H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){throw H.models=[],W=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V instanceof Error?V.message:String(V)},V}},resolveSpawnModel(V){return V2(H).find((X)=>X.model===V&&!X.unavailableReason)?.model},async readUsage(){return J?JZ(await l4(Y,J)):{state:"no_credentials",windows:[]}}};return H},setup:{commandSuffix:"dsh-glm",hint:()=>"DSH 可复用已配置的 GLM Coding Plan;独立账号用 `dsh-glm-setup [base_url] <api_key>`。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2)return{error:"用法:dsh-glm-setup [base_url] <api_key>"};try{return{config:{agent:"dsh",api_key:Z.at(-1),base_url:GZ(Z.length===2?Z[0]:"https://open.bigmodel.cn/api/coding/paas/v4")}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}}}})});var QV={};P0(QV,{tokenSourceSpawnRevision:()=>YV,buildTokenSourcesFromConfig:()=>_Z});import{createHash as OP}from"node:crypto";function _Z(){r6();let $=y3(),Z=z2().map((W)=>{let H=W.configSectionId?(f.token_sources??{})[W.configSectionId]??{}:{},V=W.detect?.fromSettingsEnv($)??null,X=a8(W.build(H,V),H);return X.spawnRevision=YV(W.kind,H,V),X}),J=Z.find((W)=>W.kind==="claude-native");if(J){let W=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!W,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let W of Z)a6(W);let Q=Z.find((W)=>W.enabled&&f.token_sources?.[W.id]?.default===!0)??Z.find((W)=>W.enabled);if(Q)o6(Q.id);return Z.length}function YV($,Z,J){let Y=(Q)=>({agent:Q?.agent,auth:Q?.auth,base_url:Q?.base_url,auth_token:Q?.auth_token,api_key:Q?.api_key,bin:Q?.bin,model:Q?.model,effort:Q?.effort,slots:Q?.slots});return OP("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var KZ=T(()=>{k$();J$();i4();C2();iH();YZ();aH();WZ();$V();ZV();JV()});import{readFileSync as TP}from"node:fs";function NP($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function EP($,Z){let J=[`[token_source.${$}]`],Y=(Q,W)=>{if(W!==void 0)J.push(`${Q} = "${NP(W)}"`)};if(Y("agent",Z.agent),Y("display",Z.display),Y("auth",Z.auth),Y("base_url",Z.base_url),Y("auth_token",Z.auth_token),Y("api_key",Z.api_key),Y("bin",Z.bin),Y("model",Z.model),Y("effort",Z.effort),Y("models",Z.models),Y("hidden_models",Z.hidden_models),Y("custom_models",Z.custom_models),Y("slots",Z.slots),Y("usage",Z.usage),Z.default!==void 0)J.push(`default = "${Z.default}"`);return J.join(`
181
- `)}function SP($,Z){let J=TP(U$,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
182
- `),W=!1,H=D9().token_sources[$]??{},V=[];for(let K of Q){let B=K.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(B)W=B===Y;if(!W)V.push(K)}let X={...H},z={...Z};for(let K of Object.keys(z))if(z[K]!==void 0)X[K]=z[K];let G=X;while(V.length&&V[V.length-1]==="")V.pop();$0(U$,V.join(`
220
+ 默认官方 Anthropic 端点;自建中转用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length)return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Y=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Y}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!Vj(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function I1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var jZ;var PV=T(()=>{jZ=[{rank:1,lab:"Anthropic",model:"anthropic/claude-fable-5.1",effort:"max"},{rank:3,lab:"Moonshot",model:"moonshotai/kimi-k3",effort:"max"},{rank:4,lab:"Tencent",model:"tencent/hy4-preview",effort:"high"},{rank:7,lab:"Google",model:"google/gemini-3.8-flash",effort:"high"},{rank:8,lab:"SpaceXAI",model:"x-ai/grok-4.5",effort:"high"},{rank:9,lab:"Alibaba",model:"qwen/qwen3.8-max-0902",effort:"xhigh"},{rank:10,lab:"Meta",model:"meta/muse-spark-1.2",effort:"xhigh"},{rank:11,lab:"Xiaomi",model:"xiaomi/mimo-v2.5-pro",effort:"default"},{rank:12,lab:"MiniMax",model:"minimax/minimax-m3",effort:"default"},{lab:"ByteDance",model:"bytedance-seed/seed-2-1-turbo",effort:"default"},{lab:"Meituan",model:"meituan/longcat-2.0",effort:"default"}]});function Y1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function DZ($){return $ instanceof Error?$.message:String($)}function DV($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function f2($){return $.replace(/\[1m\]$/,"")}function V6($){let Z=new URL($);if(!["https:","http:"].includes(Z.protocol)||Z.username||Z.password||Z.search||Z.hash)throw Error("OpenRouter base_url 必须是无凭据、查询参数和 fragment 的 HTTP(S) API 根地址");return Z.pathname=Z.pathname.replace(/\/+$/,"").replace(/\/v1$/,""),Z.toString().replace(/\/+$/,"")}async function FV($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await J$(`${V6($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(_j)});if(!Y.ok){let Q=await Y.text(),W="";if(Q.trim().startsWith("{"))try{let H=JSON.parse(Q);if(Y1(H)&&Y1(H.error)&&typeof H.error.message==="string")W=H.error.message}catch{}throw new MZ(Y.status,W.replaceAll(Z,"[redacted]"))}return Y.json()}async function Kj($,Z){let J=await FV($,Z,"models/user");if(!Y1(J)||!Array.isArray(J.data))throw Error("OpenRouter models: data 数组缺失");let Y=[],Q=new Set;for(let W of J.data){if(!Y1(W)||typeof W.id!=="string"||!W.id||typeof W.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!Y1(W.architecture)||!Array.isArray(W.architecture.output_modalities)||!Array.isArray(W.supported_parameters))throw Error(`OpenRouter models: ${W.id} 的模型能力缺失`);if(I1(W.id)||!W.architecture.output_modalities.includes("text")||!W.supported_parameters.includes("tools")||W.id.endsWith(":batch")||Q.has(W.id))continue;let H=Y1(W.reasoning)?W.reasoning:void 0,V=H?.supported_efforts,z=V===null||V===void 0&&W.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(V)?[...new Set(V.filter((B)=>B!=="default"&&T$(B)))]:["default"],X=jZ.find((B)=>B.model===W.id),G=X?z.includes(X.effort)?X.effort:null:z[0]==="default"?"default":T$(H?.default_effort)&&z.includes(H.default_effort)?H.default_effort:null,K=V2("openrouter",W.id);Y.push({model:W.id,display:W.name,efforts:z,defaultEffort:G,context1m:K!==void 0&&K>=1e6||void 0}),Q.add(W.id)}if(!Y.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Y}function MV($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function Bj($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await FV($,Z,"credits");if(!Y1(J)||!Y1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!MV(Y)||!MV(Q))throw Error("OpenRouter credits: total_credits/total_usage 缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Y-Q,currency:"USD"}}}catch(J){let Y=DZ(J);return _(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof MZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var Gj="https://openrouter.ai/api",_j=1e4,PZ,MZ;var RV=T(()=>{n$();P$();Y$();X4();I();PV();PZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};MZ=class MZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};N$({kind:"openrouter",configSectionId:"openrouter",build($,Z){let J=$.api_key||$.auth_token||$.base_url?$:Z,Y=J?.api_key?.trim()||J?.auth_token?.trim()||"",Q=J?.base_url?.trim()||Gj,W=$.model?.trim()||"",H=$.models===void 0?jZ.map((z)=>z.model):DV($.models),V={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Y,models:[],defaultModel:W,modelSelection:{mode:"allowlist",modelIds:H,availableModels:[]},validateCustomModelId(z){if(I1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let X=V.modelSelection.availableModels.find((G)=>f2(G.model)===f2(z));if(!X||X.unavailableReason||!X.efforts.length)return"model-unavailable";return X.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(V.models=[],V.modelSelection.availableModels=[],!V.enabled){V.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}V.modelCatalogState={status:"loading",updatedAt:null};try{let z=await Kj(Q,Y),X=z.find((K)=>K.model===f2(W));if(W&&!X)throw Error(`OpenRouter 默认模型不在账号目录中: ${W}`);if($.effort){if(!W)throw Error("OpenRouter effort 需要同时配置 model");if(!T$($.effort)||!X.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${W} 不支持 effort ${$.effort}`);X.defaultEffort=$.effort}let G=H.map((K)=>{let B=z.find((L)=>L.model===f2(K));if(!B)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:I1(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{...B,model:K}});V.models=G,V.modelSelection.availableModels=z,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let X=DZ(z);_(`openrouter refreshModels MISS: ${X}`),V.modelCatalogState={status:"failed",updatedAt:Date.now(),error:X}}},spawnEnv(z,X){if(!Y)throw Error("OpenRouter API key missing");let G=X||W;if(!G)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(I1(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let K=G0(z);K.ANTHROPIC_BASE_URL=V6(Q),K.ANTHROPIC_AUTH_TOKEN=Y,K.ANTHROPIC_API_KEY="",K.CLAUDE_CODE_NO_MODEL_FALLBACK="1",K.ANTHROPIC_MODEL=G,K.ANTHROPIC_SMALL_FAST_MODEL=G,K.CLAUDE_CODE_SUBAGENT_MODEL=G,K.ANTHROPIC_DEFAULT_FABLE_MODEL=G;for(let B of Object.values(PZ))K[B]=G;for(let B of DV($.slots)){let L=B.indexOf("="),A=B.slice(0,L).trim(),j=B.slice(L+1).trim();if(L<1||!Object.hasOwn(PZ,A)||!j)throw Error(`OpenRouter slots 无效: ${B}`);if(I1(j)||!V.modelSelection.availableModels.some((P)=>!P.unavailableReason&&f2(P.model)===f2(j)))throw Error(`OpenRouter slot 模型不在账号目录中: ${j}`);if(V.modelEnvironmentRevision(j)!==V.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${j}`);K[PZ[A]]=j}return K},resolveSpawnModel(z){if(I1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return Bj(Q,Y)}};return V},setup:{commandSuffix:"openrouter",hint:($)=>`启用 ${$}:发送 \`openrouter-setup <api_key>\`,然后通过 \`model\` 选择模型。自建端点用 \`openrouter-setup <base_url> <api_key>\`。`,parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||Z.length===1&&/^https?:\/\//i.test(Z[0]))return{error:"用法: openrouter-setup <api_key> 或 openrouter-setup <base_url> <api_key>"};try{return{config:{agent:"claude",api_key:Z[Z.length-1],...Z.length===2?{base_url:V6(Z[0])}:{}}}}catch(J){return{error:DZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=V6(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var UV=T(()=>{Y$();P$();e2();H$();LZ();y2();N$({kind:"deepseek-harness",configSectionId:"deepseek-harness",build($){let Z=$.api_key?.trim()??"",J=$.base_url?.trim()||"https://api.deepseek.com",Y={id:"deepseek-harness",kind:"deepseek-harness",agent:"dsh",display:$.display?.trim()||"DeepSeek",enabled:!!Z,models:[],defaultModel:$.model?.trim()??"",modelCatalogState:{status:Z?"idle":"disabled",updatedAt:Date.now()},spawnEnv(Q){let W=_4(Q);if(!Z)throw Error("DeepSeek Harness API key is missing");if(W.DEEPSEEK_API_KEY=Z,W.DEEPSEEK_BASE_URL=J,W.LODESTAR_DSH_PROVIDER="deepseek-official",$.bin)W.LODESTAR_DSH_NODE=$.bin;return W},async refreshModels(){if(!Y.enabled){Y.models=[],Y.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Y.modelCatalogState={status:"loading",updatedAt:null};try{let Q=await e1({cwd:a1,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...k$($.models),...k$($.custom_models)]});if(!Array.isArray(Q)||!Q.length)throw Error("DeepSeek Harness model catalog is empty");for(let H of Q)if(!H.model||!H.efforts.length||!H.efforts.every(K$)||!K$(H.defaultEffort)||!H.efforts.includes(H.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${H.model}`);let W=$.model?.trim()||Q.find((H)=>H.isDefault)?.model;if(!W||!Q.some((H)=>H.model===W))throw Error("DSH default model is not in its catalog");Y.models=Q.map(({model:H,display:V,efforts:z,defaultEffort:X,isCustom:G})=>{let K=$.effort?.trim();if(K&&(!K$(K)||!z.includes(K)))throw Error(`DSH model ${H} does not support configured effort ${K}`);return{model:H,display:V,efforts:z,defaultEffort:K?K:X,origin:G?"custom":"upstream"}}),Y.defaultModel=W,Y.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(Q){throw Y.models=[],Y.modelCatalogState={status:"failed",updatedAt:Date.now(),error:Q instanceof Error?Q.message:String(Q)},Q}},resolveSpawnModel(Q){return G2(Y).find((W)=>W.model===Q)?.model},readUsage(){return Z?qZ(J,Z):Promise.resolve({kind:"balance",state:"no_credentials",windows:[]})}};return Y},setup:{commandSuffix:"deepseek-harness",hint:()=>"启用 DeepSeek Harness:发送 `deepseek-harness-setup <api_key>`,或 `deepseek-harness-setup <base_url> <api_key>`。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2)return{error:"用法:deepseek-harness-setup [base_url] <api_key>"};return{config:{agent:"dsh",api_key:Z.at(-1),...Z.length===2?{base_url:Z[0]}:{}}}}}})});function FZ($){let Z=new URL($);if(!w1(Z.origin))throw Error("DSH GLM 需要 bigmodel.cn 或 z.ai 的 Coding Plan 端点");return Z.pathname="/api/coding/paas/v4",Z.search="",Z.hash="",Z.toString().replace(/\/$/,"")}async function Aj($,Z){let J=await J$(`${$}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!J.ok)throw Error(`GLM Coding Plan models HTTP ${J.status}`);let Y=await J.json();if(!Array.isArray(Y?.data)||!Y.data.length)throw Error("GLM Coding Plan 模型目录为空或无效");return Y.data.map((Q)=>{if(typeof Q?.id!=="string"||!Q.id)throw Error("GLM Coding Plan 模型 id 无效");return{model:Q.id,display:typeof Q.name==="string"?Q.name:Q.id}})}var OV=T(()=>{n$();x$();P$();Y$();e2();H$();a4();AZ();y2();N$({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=f.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&w1(Y)?{api_key:J,base_url:FZ(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=FZ($.base_url?.trim()||Z?.base_url?.trim()||"https://open.bigmodel.cn/api/coding/paas/v4"),Q=new URL(Y).hostname.endsWith("bigmodel.cn")?"zai-coding-cn":"zai",W,H={id:"dsh-glm",kind:"dsh-glm",agent:"dsh",display:$.display?.trim()||"GLM Coding Plan",enabled:!!J,models:[],defaultModel:$.model?.trim().toLowerCase()??"",modelEnvironmentRevision(){return JSON.stringify([...W??[]].sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(V){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=_4(V);if(z.LODESTAR_DSH_PROVIDER=Q,z.LODESTAR_DSH_GLM_API_KEY=J,z.LODESTAR_DSH_BASE_URL=Y,z.LODESTAR_DSH_DEFAULT_MODEL=H.defaultModel,W)z.LODESTAR_DSH_MODELS=JSON.stringify(W);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(H.models=[],W=void 0,!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let V=await Aj(Y,J),z=[...V];for(let G of[...k$($.models),...k$($.custom_models)])if(!z.some((K)=>K.model.toLowerCase()===G.toLowerCase()))z.push({model:G,display:G});if(W=z.map((G)=>G.model),!$.model?.trim()){let G=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);H.defaultModel=[...V].sort((K,B)=>G(B.model)-G(K.model))[0].model}let X=await e1({cwd:a1,env:H.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");H.models=z.map((G)=>{let K=X.find((j)=>j.model===G.model),B=_Z(H,$),L=K?K.efforts.filter(K$):B.efforts,A=$.effort?.trim()||K?.defaultEffort||B.defaultEffort;return{...G,display:K?.display??G.display,efforts:L,defaultEffort:K$(A)&&L.includes(A)?A:null,origin:V.some((j)=>j.model===G.model)?"upstream":"custom"}}),H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){throw H.models=[],W=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V instanceof Error?V.message:String(V)},V}},resolveSpawnModel(V){return G2(H).find((z)=>z.model===V&&!z.unavailableReason)?.model},async readUsage(){return J?BZ(await n4(Y,J)):{state:"no_credentials",windows:[]}}};return H},setup:{commandSuffix:"dsh-glm",hint:()=>"DSH 可复用已配置的 GLM Coding Plan;独立账号用 `dsh-glm-setup [base_url] <api_key>`。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2)return{error:"用法:dsh-glm-setup [base_url] <api_key>"};try{return{config:{agent:"dsh",api_key:Z.at(-1),base_url:FZ(Z.length===2?Z[0]:"https://open.bigmodel.cn/api/coding/paas/v4")}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}}}})});var NV={};P0(NV,{tokenSourceSpawnRevision:()=>TV,buildTokenSourcesFromConfig:()=>RZ});import{createHash as qj}from"node:crypto";function RZ(){V3();let $=l7(),Z=K2().map((W)=>{let H=W.configSectionId?(f.token_sources??{})[W.configSectionId]??{}:{},V=W.detect?.fromSettingsEnv($)??null,z=Q6(W.build(H,V),H);return z.spawnRevision=TV(W.kind,H,V),z}),J=Z.find((W)=>W.kind==="claude-native");if(J){let W=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!W,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let W of Z)W3(W);let Q=Z.find((W)=>W.enabled&&f.token_sources?.[W.id]?.default===!0)??Z.find((W)=>W.enabled);if(Q)H3(Q.id);return Z.length}function TV($,Z,J){let Y=(Q)=>({agent:Q?.agent,auth:Q?.auth,base_url:Q?.base_url,auth_token:Q?.auth_token,api_key:Q?.api_key,bin:Q?.bin,model:Q?.model,effort:Q?.effort,slots:Q?.slots});return qj("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var UZ=T(()=>{x$();Y$();a4();y2();BV();AZ();LV();LZ();RV();UV();OV()});import{readFileSync as Lj}from"node:fs";function jj($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function Pj($,Z){let J=[`[token_source.${$}]`],Y=(Q,W)=>{if(W!==void 0)J.push(`${Q} = "${jj(W)}"`)};if(Y("agent",Z.agent),Y("display",Z.display),Y("auth",Z.auth),Y("base_url",Z.base_url),Y("auth_token",Z.auth_token),Y("api_key",Z.api_key),Y("bin",Z.bin),Y("model",Z.model),Y("effort",Z.effort),Y("models",Z.models),Y("hidden_models",Z.hidden_models),Y("custom_models",Z.custom_models),Y("slots",Z.slots),Y("usage",Z.usage),Z.default!==void 0)J.push(`default = "${Z.default}"`);return J.join(`
221
+ `)}function Dj($,Z){let J=Lj(O$,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
222
+ `),W=!1,H=S9().token_sources[$]??{},V=[];for(let K of Q){let B=K.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(B)W=B===Y;if(!W)V.push(K)}let z={...H},X={...Z};for(let K of Object.keys(X))if(X[K]!==void 0)z[K]=X[K];let G=z;while(V.length&&V[V.length-1]==="")V.pop();J0(O$,V.join(`
183
223
  `)+`
184
224
 
185
- `+EP($,G)+`
186
- `)}function s8($){let Z=WV.then($);return WV=Z.then(()=>{},()=>{}),Z}async function e8($,Z){SP($,Z),oJ(),_Z(),await _4()}function HV($,Z){return s8(()=>e8($,Z))}function VV($,Z,J,Y="default"){return s8(async()=>{let Q=H$($,Y);if(!Q?.enabled||!Q.modelSelection)throw Error("此账号不支持维护可选模型列表");let W=Q.modelSelection.modelIds.filter((B)=>Q.models.find((A)=>A.model===B)?.origin!=="custom");if(J==="add"){if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");let B=Q.modelSelection.availableModels.find((A)=>A.model===Z);if(B?.origin==="custom")throw Error("补录模型请使用删除操作");if(!B||Q.modelSelection.mode!=="catalog"&&(B.unavailableReason||!B.efforts.length))throw Error("模型不在允许添加的账号目录中");if(W.includes(Z))throw Error("模型已在可选列表中")}else if(!W.includes(Z))throw Error("模型已不在可选列表中");let H=J==="add"?[...W,Z]:W.filter((B)=>B!==Z),V=f.token_sources[$],X=Q.modelSelection.mode==="catalog",z=S$(V?.hidden_models),G=X?{hidden_models:(J==="remove"?[...new Set([...z,Z])]:z.filter((B)=>B!==Z)).join(",")}:{models:H.join(",")};await e8($,G);let K=H$($,Y);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function XV($,Z,J="default"){return s8(async()=>{let Y=Z.trim();if(!Y||Y.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Y))throw Error("模型 ID 无效,请只填写一个完整模型名");let Q=H$($,J);if(!Q?.enabled)throw Error("账号不可用");if(Q.validateCustomModelId?.(Y),(Q.modelSelection?.availableModels??Q.models).some((X)=>X.model.toLowerCase()===Y.toLowerCase()))throw Error("模型已在目录或补录记录中;隐藏项请使用“显示”");if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");if(Q.verifyModel){let X=await Q.verifyModel(Y);if(X!=="exists")throw Error(X==="not_found"?"端点确认不存在":"无法校验模型:端点无响应或凭据问题")}let H=f.token_sources[$];await e8($,{custom_models:[...S$(H?.custom_models),Y].join(",")});let V=H$($,J);if(V?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${V?.modelCatalogState?.error??"MISS"}`)})}function zV($,Z,J="default"){return s8(async()=>{let Y=H$($,J),Q=Y?.modelSelection?.availableModels.find((z)=>z.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let W=f.token_sources[$]??{},H=(z)=>z?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),V={custom_models:S$(W.custom_models).filter((z)=>!H(z)).join(","),hidden_models:S$(W.hidden_models).filter((z)=>!H(z)).join(","),...W.models!==void 0?{models:S$(W.models).filter((z)=>!H(z)).join(",")}:{},...H(W.model)?{model:"",effort:""}:{},...W.slots?{slots:W.slots.split(",").filter((z)=>!H(z.slice(z.indexOf("=")+1))).join(",")}:{}};await e8($,V);let X=H$($,J);if(X?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${X?.modelCatalogState?.error??"MISS"}`)})}var WV;var BZ=T(()=>{W$();k$();KZ();J$();w$();C2();WV=Promise.resolve()});var AZ={};P0(AZ,{runTokenSourceSetup:()=>xP,onTokenSourceEnable:()=>kP});async function kP($,Z){let J=G0(Z);if(!J){await E($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await E($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=z2().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup)await E($.chatId,Y.setup.hint(J.display));else if(J.kind==="codex-subscription"){if(!await u($.chatId,Z0({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-native")await E($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function xP($,Z,J){let Y=z2().find((W)=>W.setup?.commandSuffix===Z);if(!Y?.setup||!Y.configSectionId){await E($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Q=Y.setup.parseArgs(J);if("error"in Q){await E($.chatId,Q.error);return}try{await HV(Y.configSectionId,Q.config);let W=G0(Y.configSectionId);if(W?.modelCatalogState?.status==="failed"){await E($.chatId,`❌ ${W.display} 配置已保存,但模型目录未就绪:${W.modelCatalogState.error??"MISS"}`);return}await E($.chatId,`✅ ${W?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(W){await E($.chatId,`❌ 启用失败: ${W?.message??W}`)}}var qZ=T(()=>{$$();J$();BZ();P2()});async function GV($,Z,J=""){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:X}=await Promise.resolve().then(() => (n8(),e3));return await X($,Y[1].trim()),!0}let Q=Z.trim().match(/^codex-(login-cancel|login|accounts|account|auto)(?:[ \t]+([^\r\n]+))?$/i);if(Q){let{runCodexAccountCommand:X}=await Promise.resolve().then(() => (n8(),e3));return await X($,Q[1].toLowerCase(),(Q[2]??"").trim(),J),!0}let W=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(W)return await $.runWorktreeCommand((W[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let H=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(H){let{runTokenSourceSetup:X}=await Promise.resolve().then(() => (qZ(),AZ));return await X($,H[1].trim().toLowerCase(),(H[2]??"").trim()),!0}let V=CP.get(Z.trim().toLowerCase());if(!V)return!1;switch(V){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let z=!$.isRunning(),G=$.backendLabel(),K=z?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${G}`)):null,B=$.withModel(`\uD83D\uDE80 启动 ${G}`);if(!(z?await $.start({announce:!K,onStatus:(P)=>{B=P,$.setStatusCard(K,P)}}):!0))return await $.closeStatusCard(K,B.startsWith("❌")?B:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(K)await $.closeStatusCard(K,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:L}=await Promise.resolve().then(() => (P2(),jQ));if(!await u($.chatId,L({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(K)return await $.replaceStatusCardWithConsole(K,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(z)await $.closeStatusCard(K,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let z=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!z,onStatus:(G)=>$.setStatusCard(z,G)}),await $.closeStatusCard(z,"\uD83D\uDED1 已取消额度恢复")}catch(G){throw await $.closeStatusCard(z,`❌ ${O(G)}`),G}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let z=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(z)await $.closeStatusCard(z,"⚪ 无正在执行的 turn");else await E($.chatId,"⚪ 当前没有正在执行的 turn");return!0}_(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let X=new Set;for(let[z,G]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(G)E$(z,G);m$(z,"CrossMark"),X.add(z)}for(let z of $.pendingMidTurnMsgs)if(z.msgId&&!X.has(z.msgId))m$(z.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0;case"kill":{let z=$.isRunning(),G=$.backendLabel($.proc?.provider??$.currentProvider()),K=z?`\uD83D\uDED1 停止 ${G}`:"⚪ session 当前未运行",B=await $.openStatusCard("kill",K,z?"red":"grey"),A=null,P=z?`✅ ${G} 已终止`:`⚪ ${G} 未运行`;try{await $.stop("已终止",{announce:!B,onStatus:(L)=>{$.setStatusCard(B,L)}})}catch(L){A=L,P=$.isRunning()?`❌ ${G} 未确认终止: ${O(L)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${G} 停止收尾失败: ${O(L)}`}finally{try{await $.closeStatusCard(B,P)}catch(L){_(`session "${$.sessionName}": kill status card close failed: ${O(L)}`),await w($.chatId,`${P}
187
- ⚠️ kill 状态卡片终态写入失败: ${O(L)}`)}}if(A&&!B)await w($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let z=$.lastSessionId?D$($.lastSessionId):"",G=$.backendLabel($.proc?.provider??$.currentProvider()),K=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${G}`):z?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${z}`):$.withModel(`\uD83D\uDD01 启动 ${G}`),B=await $.openStatusCard("restart",K),A=K,P=await $.restart(!0,{announce:!B,onStatus:(j)=>{A=j,$.setStatusCard(B,j)}}),L=P?A.startsWith("✅")?A:$.withWorktreeInstructionNotice(z?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):A.startsWith("❌")?A:"❌ 重启失败";await $.closeStatusCard(B,P?$.withModel(L):L)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let z=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(z)await $.closeStatusCard(z,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let z=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),G="\uD83E\uDDF9 清空并启动新会话",K=await $.restart(!1,{announce:!z,onStatus:(B)=>{G=B,$.setStatusCard(z,B)}});await $.closeStatusCard(z,K?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):G.startsWith("❌")?G:"❌ 清空失败")}return!0}}var CP;var _V=T(()=>{$$();I();CP=new Map([["hi","hi"],["stop","stop"],["st","stop"],["kill","kill"],["kl","kill"],["restart","restart"],["rs","restart"],["clear","clear"],["cl","clear"],["compact","compact"],["cm","compact"],["model","model"],["md","model"]])});function wP($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,W=()=>{$.off("context_compacted",X),$.off("exit",z),$.off("error",G)},H=(B)=>{if(Z)return;Z=!0,W(),J(B)},V=(B)=>{if(Z)return;Z=!0,W(),Y(B)},X=(B)=>{if(B.phase==="start")return;if(B.threadId&&Q&&B.threadId!==Q)return;H(B)},z=()=>V(Error(`${$.provider} process exited before context compaction completed`)),G=(B)=>V(B instanceof Error?B:Error(String(B))),K=new Promise((B,A)=>{J=B,Y=A});return $.on("context_compacted",X),$.once("exit",z),$.once("error",G),{promise:K,cancel(){if(Z)return;Z=!0,W()}}}function fP($,Z){let J=[],Y=new Set,Q=(V,X)=>{let z=X.threadId??Z;if(z&&V.threadId&&V.threadId!==z)return!1;if(X.turnId)return V.turnId===X.turnId;return!0},W=(V)=>{for(let X=J.length-1;X>=0;X--){let z=J[X];if(z&&Q(z,V))return z}return null},H=(V)=>{if(Z&&V.threadId&&V.threadId!==Z)return;let X={usage:V.usage,contextWindow:V.contextWindow,threadId:V.threadId,turnId:V.turnId};J.push(X);for(let z of[...Y])if(Q(X,z.notice))z.finish(X)};return $.on("token_usage",H),{waitFor(V,X){let z=W(V);if(z)return Promise.resolve(z);return new Promise((G)=>{let K=null,B={notice:V,finish:(A)=>{if(K)clearTimeout(K);Y.delete(B),G(A)}};K=setTimeout(()=>B.finish(null),X),Y.add(B)})},cancel(){$.off("token_usage",H);for(let V of[...Y])V.finish(null)}}}function vP($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=A8($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=q8($.contextWindow);return` · \uD83E\uDDE0 ${sQ(Z,J)} (${P8(Z,J)})`}async function KV($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let z=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(z)await $.closeStatusCard(z,"⚪ 后端未运行,compact 无效");else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let z=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(z)await $.closeStatusCard(z,"⚠️ 先 stop 当前 turn,再 compact");else await E($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let z=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(z)await $.closeStatusCard(z,"⏳ 上下文压缩已在进行中");else await E($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?D$(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),W=await $.openStatusCard("compact",Q,"orange"),H=async(z)=>{if(W)await $.closeStatusCard(W,z);else await E($.chatId,z)},V=wP(J),X=fP(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(W,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(W,$.withModel("⏳ 等待压缩完成事件"));let z=await V.promise,G=await X.waitFor(z,yP),K=z.threadId?` thread=${D$(z.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${K}${vP(G)}`))}catch(z){if(V.cancel(),z instanceof B1)await H($.withModel(`ⓘ ${z.message}`));else await H(`❌ 上下文压缩失败: ${O(z)}`)}finally{X.cancel(),$.manualContextCompactionPending=!1}}var yP=1500;var BV=T(()=>{L$();$$()});import{randomUUID as IP}from"node:crypto";function gP($){let Z=$.currentTokenSource();return R0().map((J)=>$.tokenSource(J.id)).filter((J)=>J.enabled||J.kind!=="claude-native").map((J)=>({provider:J.agent,sourceId:J.id,display:J.display,enabled:J.enabled,modelCount:J.models.length,catalogStatus:J.modelCatalogState?.status,catalogError:J.modelCatalogState?.error,selected:Z?.id===J.id}))}function LZ($,Z,J=Z.models){let Y=$.currentModelLabel(),Q=$.currentEffortLabel(),W=$.currentTokenSource()?.id===Z.id;return J.map((H)=>{let V=W&&Y===H.model;return{provider:Z.agent,sourceId:Z.id,model:H.model,displayName:H.display,description:H.unavailableReason??(H.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:H.unavailableReason,origin:H.origin,enabled:!0,isDefault:!1,selected:V,efforts:H.efforts.map((X)=>({effort:X,description:X==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:X===H.defaultEffort,selected:V&&Q===X}))}})}async function AV($){await _4();let Z=IP(),J=gP($);$.modelPanels.set(Z,{models:[]});let Y=await u($.chatId,H7({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}));if(!Y)$.modelPanels.delete(Z),await w($.chatId,"❌ 模型面板发送失败");else{let Q=$.modelPanels.get(Z);if(Q)Q.messageId=Y}}async function jZ($,Z,J=""){let Y=Z.trim(),Q=$.tokenSource(Y);if(!Q)return{ok:!1,message:`未知账号: ${Y}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置,请先点「启用」`};let W=J.trim();if(!$.modelPanels.has(W))return{ok:!1,message:"模型面板已失效,请重新发送 model"};if(Q.modelCatalogState?.status==="failed")return{ok:!1,message:`模型目录 MISS:${Q.modelCatalogState.error??"刷新失败"}`};let H=LZ($,Q),V=$.modelPanels.get(W)?.messageId;return $.modelPanels.set(W,{models:[],catalog:H,sourceId:Y,messageId:V,mode:"select",editable:!!Q.modelSelection,sourceRevision:Q.spawnRevision}),$5($,W,Y,0)}async function $5($,Z,J,Y){let Q=$.modelPanels.get(Z);if(!Q?.catalog||Q.sourceId!==J)return{ok:!1,message:"模型面板已失效,请重新发送 model"};let W=Math.max(1,Math.ceil(Q.catalog.length/PZ));if(!Number.isInteger(Y)||Y<0||Y>=W)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*PZ,(Y+1)*PZ),Q.page=Y,Q.totalPages=W,{ok:!0,message:"",card:V7({sessionName:$.sessionName,panelId:Z,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:Q.models,sourceId:J,editable:Q.editable,allowCustom:!0,mode:Q.mode,...W>1?{pagination:{sourceId:J,page:Y,totalPages:W}}:{}})}}async function qV($,Z,J){let Y=$.modelPanels.get(Z),Q=$.tokenSource(J);if(!Y||Y.sourceId!==J||!Q?.enabled||!Q.modelSelection)return{ok:!1,message:"模型管理面板已失效,请重新发送 md"};if(Q.modelCatalogState?.status!=="ready")return{ok:!1,message:Q.modelCatalogState?.error??"目录未就绪"};let W=Q.modelSelection.availableModels.filter((H)=>H.origin!=="custom"&&!Q.modelSelection.modelIds.includes(H.model)&&(Q.modelSelection.mode==="catalog"||!H.unavailableReason&&H.efforts.length>0));return $.modelPanels.set(Z,{models:[],catalog:LZ($,Q,W),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),$5($,Z,J,0)}async function PV($,Z,J,Y,Q){let W=$.modelPanels.get(Z),H=$.tokenSource(J);if(!W?.editable||W.sourceId!==J||!H?.modelSelection||W.sourceRevision!==H.spawnRevision||W.mode!==(Q==="add"?"add":"select")||!W.models.some((V)=>V.model===Y))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Q==="delete"){let V=[...Q0.all].filter((X)=>X.currentTokenSource()?.id===J&&X.currentModelLabel()===Y.replace(/\[1m\]$/,""));if(V.length)return{ok:!1,message:`补录模型仍被会话 ${V.map((X)=>X.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Q==="delete")await zV(J,Y,$.codexAccountId());else await VV(J,Y,Q,$.codexAccountId());for(let X of Q0.all)for(let[z,G]of X.modelPanels)if(G.sourceId===J&&(X!==$||z!==Z))X.modelPanels.delete(z);return{...await jZ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(V){return{ok:!1,message:`模型列表更新失败:${O(V)}`}}}async function LV($,Z,J,Y=""){let Q=$.tokenSource(Z.trim());if(!Q)return{ok:!1,message:`未知账号: ${Z}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置`};let W=J.trim();if(!W)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:W,cardMessageId:Y},{ok:!0,message:"等待模型名",card:z7($.sessionName,Q.display,W)}}async function jV($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),W=$.tokenSource(Y.sourceId),H=async(B)=>{if(!Y.cardMessageId)return!1;let A="",P=!1,L=!1;try{if(A=await o$(Y.cardMessageId),c$(A,1),P=await z$(A,U.modelPanel,B,{notifyCardFailure:!1}),!P)throw Error("model panel replace rejected");if(L=await P$(A,{config:{streaming_mode:!1}}),!L)throw Error("model panel streaming-off rejected")}catch(j){_(`model-custom: card update MISS (${j?.message??j})`)}finally{if(A){if(!L)try{L=await P$(A,{config:{streaming_mode:!1}})}catch(j){_(`model-custom: streaming-off retry MISS (${j?.message??j})`)}if(P&&L)try{await b$(A)}catch(j){_(`model-custom: card dispose MISS (${j?.message??j})`)}else _(`model-custom: retain card state after checked MISS mutation=${P} streamingOff=${L} card=${A.slice(0,12)}`)}}return P&&L},V=async(B,A)=>{if(await H(B))return!0;let L=`⚠️ 模型补录结果未能写回原卡。${A}
188
- 请重新发送 model 打开面板。`;if(!await w($.chatId,L))_(`model-custom: visible fallback send MISS (${A})`);return!1},X=(B)=>V(q2(!1,Q,B),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${B}。`);if(!W||!W.enabled)return await X("账号不可用"),!0;if(!Q)return await X("模型名为空"),!0;if(W.models.some((B)=>B.model.toLowerCase()===Q.toLowerCase()))return await V(q2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await XV(W.id,Q,$.codexAccountId())}catch(B){return _(`model-custom: config/refresh MISS (${O(B)})`),await X(`配置写入或模型刷新失败:${O(B)}`),!0}_(`model-custom: ${W.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let B of Q0.all)for(let[A,P]of B.modelPanels)if(P.sourceId===W.id&&(B!==$||A!==Y.panelId))B.modelPanels.delete(A);let z=$.tokenSource(W.id);if(!z||z.modelCatalogState?.status!=="ready")return await X(z?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let G=LZ($,z),K=G.find((B)=>B.model===Q);if(!K)return await X("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Y.panelId,{models:G,messageId:Y.cardMessageId}),K.unavailableReason||!K.efforts.length)return await V(q2(!0,Q,`**MISS**:${K.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Q} 已补录,能力尚未确认。`),!0;if(K.efforts.length===1){let B=await $.onModelEffortSelect(K.model,K.efforts[0].effort,Y.panelId,J,K.provider);return await V(B.ok?s9({sessionName:$.sessionName,provider:K.provider,model:K.model,effort:K.efforts[0].effort,scope:MV($,K.provider??"codex")}):q2(!0,Q,B.message),B.message),!0}return await V(t9({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:K}),`✅ 模型 ${Q} 已补录成功。`),!0}async function DV($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:r9($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:r9($.sessionName)}}function mP($,Z){return H0(Z?.provider)?Z.provider:t1($)}function MV($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${V0(Z)} 时使用。`}async function FV($,Z,J="",Y="",Q=null){let W=Z.trim();if(!W)return await E($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=mP(W,Q),V=$.modelPanels.get(J.trim())?.models.find((X)=>X.model===W&&(X.provider??"codex")===H);if(!V)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(V.unavailableReason)return{ok:!1,message:V.unavailableReason};if(V.enabled===!1)return{ok:!1,message:`${V.displayName} 未配置,请先点「启用」`};if(V.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(V.efforts.length===1)return DZ($,W,V.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:X7({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:V})}}async function DZ($,Z,J,Y="",Q="",W=""){let H=Z.trim(),V=J.trim();if(!H)return{ok:!1,message:"模型为空"};let X=Y.trim(),z=$.modelPanels.get(X),G=H0(W)?W:z?.models.find((M)=>M.model===H)?.provider??t1(H);if(G==="dsh"){if(!_$(V))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!O$(V))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!d$(V))return{ok:!1,message:"Codex reasoning effort 无效"};let K=V,B=z?.models.find((M)=>M.model===H&&(M.provider??"codex")===G);if(!B||!B.efforts.some((M)=>M.effort===K))return{ok:!1,message:`${V0(G)} · ${H}/${K} 不在选项中`};let A=$.tokenSource(B.sourceId);if(A?.modelCatalogState){if(!A.enabled||A.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${A.modelCatalogState.error??A.modelCatalogState.status}`};if(!A.models.some((M)=>M.model===H&&M.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let P=!!B.sourceId&&$.currentTokenSource()?.id!==B.sourceId,L=!$.processSourceMatches(A,H)||!!A?.modelEnvironmentRevision&&A.modelEnvironmentRevision($.currentModelLabel()??"")!==A.modelEnvironmentRevision(H);if($.currentProvider()===G&&!P&&$.currentModelLabel()===H&&$.currentEffortLabel()===K)return $.modelPanels.delete(X),{ok:!0,message:`当前已是 ${V0(G)} · ${H} / ${K}`,card:o9({sessionName:$.sessionName,provider:G,model:H,effort:K,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${V0(G)}`};let F=$.currentModelLabel()!==H||P,R=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(L&&$.proc?.isAlive()&&R)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&F&&R)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!P&&!L){let k=B.sourceId?$.tokenSource(B.sourceId)?.resolveSpawnModel(H)??H:H;await $Y($.proc.setModelSettings(k,K),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,K,B.sourceId);let M=MV($,G);return $.modelPanels.delete(X),{ok:!0,message:`已选择 ${V0(G)} · ${H} / ${K}`,card:o9({sessionName:$.sessionName,provider:G,model:H,effort:K,scope:M})}}catch(M){let k=`模型切换失败: ${O(M)}`;return _(`session "${$.sessionName}": set model settings failed: ${O(M)}`),await E($.chatId,`❌ ${k}`),{ok:!1,message:k}}}var PZ=20;var RV=T(()=>{L$();MZ();J$();BZ();q1();L$();s$();a0();$$();I()});import{createHash as uP}from"node:crypto";function pP($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function h1($="default"){return lP(R0().map((Z)=>Z.forAccount?.($)??Z))}function lP($){let Z=[],J=[];for(let Y of $)iP(Y,Z,J);return{catalogGeneration:uP("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function iP($,Z,J){let Y=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Y==="loading"||Y==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Y==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Q of $.models)Z.push(dP($,Q,Y))}function dP($,Z,J){let Y="ready",Q;if(!$.enabled)Y="source_disabled",Q="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Y="catalog_loading",Q="模型目录正在刷新";else if(J==="failed")Y="catalog_failed",Q=$.modelCatalogState?.error??"模型目录刷新失败";else if(Z.unavailableReason||!Z.efforts.length)Y="model_unavailable",Q=Z.unavailableReason??"effort MISS:上游未声明该后端支持的推理档位";return{id:pP($.id,Z.model),displayName:`${$.display} · ${Z.display}`,tokenSourceId:$.id,tokenSourceDisplay:$.display,provider:$.agent,model:Z.model,modelDisplay:Z.display,defaultEffort:Z.defaultEffort,supportedEfforts:[...Z.efforts],sourceDefault:UV($.defaultModel)===UV(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function UV($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var Z5=T(()=>{J$()});import{randomUUID as nP}from"node:crypto";async function OV($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}EV(),await G2();let J=`agents_${nP()}`;if($9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,NV(J)))await w($.chatId,"❌ agents 面板发送失败")}function TV($,Z,J){let Y=rP($,J),Q=Number(Z);if(!Number.isInteger(Q))return tP("无效页码");let W=oP(Y.codexAccountId);return Y.page=Math.max(0,Math.min(W-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:NV($)}}function NV($){let Z=$9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=h1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/J5));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*J5;return E3({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+J5),failures:J.sourceFailures})}function oP($){return Math.max(1,Math.ceil(h1($).identities.length/J5))}function rP($,Z){EV();let J=$9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function tP($){return{ok:!1,message:$,card:s0({title:"agents",message:$,ok:!1})}}function EV(){let $=Date.now()-aP;for(let[Z,J]of $9)if(J.createdAt<$)$9.delete(Z)}var J5=8,aP=1800000,$9;var SV=T(()=>{s$();$$();Z5();J$();$9=new Map});var UZ={};P0(UZ,{withTasklistLifecycleLock:()=>H5,tasklistNameForProject:()=>W5,reconcileTasklistDeletions:()=>ZL,isTasklistAlreadyDeletedError:()=>kV,getTasklistBinding:()=>C0,enableTasklist:()=>FZ,deleteTasklistRemoteIdempotently:()=>xV,deleteTasklist:()=>RZ});import{existsSync as eP,readFileSync as $L}from"node:fs";function W5($){return`${$}[lodestar]`}function C0($){let Z=x0.get($);return Z?w2(Z):null}async function H5($,Z){let J=Y5.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),W=J.catch(()=>{}).then(()=>Q);Y5.set($,W),await J.catch(()=>{});try{return await Z()}finally{if(Y(),Y5.get($)===W)Y5.delete($)}}function kV($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function xV($,Z=q7){try{return await Z($),"deleted"}catch(J){if(kV(J))return"already_deleted";throw J}}async function FZ($,Z){return await H5($,async()=>{let J=C0($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=W5($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await B7(Z),W=await A7(Y,Q),H={guid:W.guid,name:W.name,url:W.url,projectName:$,ownerOpenId:Q,createdAt:W.createdAt};return Q5($,H),w2(H)})}async function RZ($,Z){return await H5($,async()=>{let J=C0($);if(!J)throw Error("tasklist is not enabled");if(J.guid!==Z)throw Error(`tasklist binding changed: current=${J.guid} requested=${Z}`);if(!J.deleting)J.deleting={requestedAt:new Date().toISOString(),attempts:0},Q5($,J);return await CV($,Z)})}async function CV($,Z){let J=C0($);if(!J||J.guid!==Z)throw Error(`tasklist binding changed during deletion: ${$}`);J.deleting??={requestedAt:new Date().toISOString(),attempts:0},J.deleting.attempts++,J.deleting.lastAttemptAt=new Date().toISOString(),J.deleting.lastError=void 0,Q5($,J);try{if(await xV(Z)==="already_deleted")_(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(x0);return Q.delete($),bV(Q),x0.delete($),w2(J)}catch(Y){let Q=C0($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),Q5($,Q);throw Y}}async function ZL(){let $=[...x0.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await H5(J.projectName,()=>CV(J.projectName,J.guid)),_(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Y){Z.push(`${J.projectName}: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function JL(){if(!eP(X9))return;try{let $=JSON.parse($L(X9,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Y=J;if(typeof Y.guid!=="string"||!Y.guid||typeof Y.name!=="string"||!Y.name)continue;let Q={guid:Y.guid,name:Y.name,url:typeof Y.url==="string"?Y.url:"",projectName:Z,ownerOpenId:typeof Y.ownerOpenId==="string"?Y.ownerOpenId:"",createdAt:typeof Y.createdAt==="string"?Y.createdAt:void 0,deleting:YL(Y.deleting)};x0.set(Z,Q)}_(`tasklist: loaded ${x0.size} project bindings`)}catch($){_(`tasklist: load map failed: ${$}`)}}function YL($){if(!$||typeof $!=="object")return;let Z=$;if(typeof Z.requestedAt!=="string"||!Z.requestedAt)return;return{requestedAt:Z.requestedAt,lastAttemptAt:typeof Z.lastAttemptAt==="string"?Z.lastAttemptAt:void 0,attempts:typeof Z.attempts==="number"&&Number.isFinite(Z.attempts)&&Z.attempts>=0?Math.floor(Z.attempts):0,lastError:typeof Z.lastError==="string"?Z.lastError:void 0}}function Q5($,Z){let J=new Map(x0);J.set($,w2(Z)),bV(J),x0.set($,w2(Z))}function bV($=x0){let Z={};for(let[J,Y]of $)Z[J]=w2(Y);t(X9,Z)}function w2($){return JSON.parse(JSON.stringify($))}var x0,Y5;var OZ=T(()=>{W$();$$();I();w$();x0=new Map,Y5=new Map;JL()});function J1($,Z,J=!1){let Y=$.worktreeProjectName();return O3({projectName:Y,tasklistName:W5(Y),binding:C0(Y),notice:Z,confirmDelete:J})}async function yV($){if(!await u($.chatId,J1($)))await w($.chatId,"❌ task 面板发送失败")}async function wV($){let Z=$.worktreeProjectName();try{let J=C0(Z),Y=await FZ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:J1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${O(J)}`;return _(`session "${$.sessionName}": tasklist enable failed: ${O(J)}`),{ok:!1,message:Y,card:J1($,{type:"error",content:`❌ ${Y}`})}}}function fV($,Z){let J=$.worktreeProjectName(),Y=C0(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:J1($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:J1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:J1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function vV($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let W=`已删除 ${(await RZ(J,Y)).name}`;return{ok:!0,message:W,card:J1($,{type:"success",content:`✅ ${W}`})}}catch(Q){let W=`删除失败: ${O(Q)}`;return _(`session "${$.sessionName}": tasklist delete failed: ${O(Q)}`),{ok:!1,message:W,card:J1($,{type:"error",content:`❌ ${W}`})}}}var hV=T(()=>{s$();$$();I();OZ()});var TZ,NZ,IV,gV,mV;var cV=T(()=>{TZ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。","- 飞书单个出站文件不能超过 30 MB(30 × 1024 × 1024 字节)。交付前检查大小;超限先压缩或分卷,确保每个文件都不超过上限,再发送。"],NZ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],IV=[...TZ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...NZ].join(`
189
- `),gV=[...TZ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...NZ].join(`
190
- `),mV=[...TZ,"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。",...NZ].join(`
191
- `)});import{execFileSync as WL}from"node:child_process";import{existsSync as I1,readdirSync as HL,readFileSync as VL,realpathSync as EZ,statSync as XL}from"node:fs";import{dirname as zL,join as pV,resolve as X5}from"node:path";async function z5($,Z){let J=EZ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=V5.get(Y)??Promise.resolve(),W,H=new Promise((X)=>{W=X}),V=Q.catch(()=>{}).then(()=>H);V5.set(Y,V),await Q.catch(()=>{});try{return await Z()}finally{if(W(),V5.get(Y)===V)V5.delete(Y)}}function g1($){let Z=$.trim();if(!GL.test(Z))return null;return Z}function lV($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function v2($,Z){return`${$}[${Z}]`}function iV($){return`${f2}${$}`}function h2($,Z,J){return pV(zL($),v2(Z,J))}function dV($,Z,J){let Y=_L($,Z,J);if(!Y)return null;let Q=VL(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function nV($,Z){kZ($);let J=R$($,["for-each-ref","--format=%(refname:short)",`refs/heads/${f2}`]).split(`
192
- `).map((W)=>W.trim()).filter(Boolean).filter((W)=>W.startsWith(f2)),Y=xZ($),Q=[];for(let W of J){let H=W.slice(f2.length);if(!g1(H))continue;let V=v2(Z,H),X=h2($,Z,H),z=Y.get(W)??null,G=!!z&&I1(z),K=tV($,W,G),B={slug:H,chatName:V,branch:W,state:K,expectedPath:X,worktreePath:G?z:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(z&&I1(z))try{let P=R$(z,["status","--porcelain=v1","--branch"]).split(`
193
- `).filter(Boolean);B.statusLine=P[0]?.startsWith("## ")?P[0].slice(3):null,B.dirtyCount=P.filter((L)=>!L.startsWith("## ")).length}catch(A){B.error=CZ(A)}Q.push(B)}return Q.sort((W,H)=>W.slug.localeCompare(H.slug))}function aV($,Z,J){let Y=g1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);kZ($);let Q=iV(Y),W=v2(Z,Y),H=h2($,Z,Y),V=qL($,Q),X=xZ($).get(Q)??null,z=V&&!X&&tV($,Q,!1)==="merged"?R$($,["rev-parse","HEAD"]).trim():null;if(X){if(X5(X)!==X5(H))throw Error(`branch ${Q} is already mounted at ${X}`);return rV(H,Q),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(I1(H)){if(!XL(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!V)throw Error(`${H} already exists while branch ${Q} does not`)}if(V){if(R$($,["worktree","add",H,Q]),z)R$(H,["rebase",z]);return{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return R$($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function oV($,Z,J){let Y=SZ($,Z,J);if(!I1(Y.worktreePath))return Y;return R$($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function SZ($,Z,J){let Y=g1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);kZ($);let Q=iV(Y),W=v2(Z,Y),H=h2($,Z,Y),X=xZ($).get(Q)??null??H;if(!I1(X))return{slug:Y,chatName:W,branch:Q,worktreePath:X,removedWorktree:!1};rV(X,Q);let z=R$(X,["status","--porcelain=v1"]).split(`
194
- `).filter(Boolean);if(z.length>0){let G=z.slice(0,8).join(`
225
+ `+Pj($,G)+`
226
+ `)}function z6($){let Z=EV.then($);return EV=Z.then(()=>{},()=>{}),Z}async function X6($,Z){Dj($,Z),qY(),RZ(),await B4()}function SV($,Z){return z6(()=>X6($,Z))}function kV($,Z,J,Y="default"){return z6(async()=>{let Q=V$($,Y);if(!Q?.enabled||!Q.modelSelection)throw Error("此账号不支持维护可选模型列表");let W=Q.modelSelection.modelIds.filter((B)=>Q.models.find((L)=>L.model===B)?.origin!=="custom");if(J==="add"){if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");let B=Q.modelSelection.availableModels.find((L)=>L.model===Z);if(B?.origin==="custom")throw Error("补录模型请使用删除操作");if(!B||Q.modelSelection.mode!=="catalog"&&(B.unavailableReason||!B.efforts.length))throw Error("模型不在允许添加的账号目录中");if(W.includes(Z))throw Error("模型已在可选列表中")}else if(!W.includes(Z))throw Error("模型已不在可选列表中");let H=J==="add"?[...W,Z]:W.filter((B)=>B!==Z),V=f.token_sources[$],z=Q.modelSelection.mode==="catalog",X=k$(V?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...X,Z])]:X.filter((B)=>B!==Z)).join(",")}:{models:H.join(",")};await X6($,G);let K=V$($,Y);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function xV($,Z,J="default"){return z6(async()=>{let Y=Z.trim();if(!Y||Y.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Y))throw Error("模型 ID 无效,请只填写一个完整模型名");let Q=V$($,J);if(!Q?.enabled)throw Error("账号不可用");if(Q.validateCustomModelId?.(Y),(Q.modelSelection?.availableModels??Q.models).some((z)=>z.model.toLowerCase()===Y.toLowerCase()))throw Error("模型已在目录或补录记录中;隐藏项请使用“显示”");if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");if(Q.verifyModel){let z=await Q.verifyModel(Y);if(z!=="exists")throw Error(z==="not_found"?"端点确认不存在":"无法校验模型:端点无响应或凭据问题")}let H=f.token_sources[$];await X6($,{custom_models:[...k$(H?.custom_models),Y].join(",")});let V=V$($,J);if(V?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${V?.modelCatalogState?.error??"MISS"}`)})}function CV($,Z,J="default"){return z6(async()=>{let Y=V$($,J),Q=Y?.modelSelection?.availableModels.find((X)=>X.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let W=f.token_sources[$]??{},H=(X)=>X?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),V={custom_models:k$(W.custom_models).filter((X)=>!H(X)).join(","),hidden_models:k$(W.hidden_models).filter((X)=>!H(X)).join(","),...W.models!==void 0?{models:k$(W.models).filter((X)=>!H(X)).join(",")}:{},...H(W.model)?{model:"",effort:""}:{},...W.slots?{slots:W.slots.split(",").filter((X)=>!H(X.slice(X.indexOf("=")+1))).join(",")}:{}};await X6($,V);let z=V$($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var EV;var OZ=T(()=>{H$();x$();UZ();Y$();f$();y2();EV=Promise.resolve()});var TZ={};P0(TZ,{runTokenSourceSetup:()=>Fj,onTokenSourceEnable:()=>Mj});async function Mj($,Z){let J=K0(Z);if(!J){await N($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await N($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=K2().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup)await N($.chatId,Y.setup.hint(J.display));else if(J.kind==="codex-subscription"){if(!await u($.chatId,Y0({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-native")await N($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function Fj($,Z,J){let Y=K2().find((W)=>W.setup?.commandSuffix===Z);if(!Y?.setup||!Y.configSectionId){await N($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Q=Y.setup.parseArgs(J);if("error"in Q){await N($.chatId,Q.error);return}try{await SV(Y.configSectionId,Q.config);let W=K0(Y.configSectionId);if(W?.modelCatalogState?.status==="failed"){await N($.chatId,`❌ ${W.display} 配置已保存,但模型目录未就绪:${W.modelCatalogState.error??"MISS"}`);return}await N($.chatId,`✅ ${W?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(W){await N($.chatId,`❌ 启用失败: ${W?.message??W}`)}}var NZ=T(()=>{$$();Y$();OZ();P2()});async function bV($,Z,J=""){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:z}=await Promise.resolve().then(() => (Y6(),GZ));return await z($,Y[1].trim()),!0}let Q=Z.trim().match(/^codex-(login-cancel|login|accounts|account|auto)(?:[ \t]+([^\r\n]+))?$/i);if(Q){let{runCodexAccountCommand:z}=await Promise.resolve().then(() => (Y6(),GZ));return await z($,Q[1].toLowerCase(),(Q[2]??"").trim(),J),!0}let W=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(W)return await $.runWorktreeCommand((W[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let H=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(H){let{runTokenSourceSetup:z}=await Promise.resolve().then(() => (NZ(),TZ));return await z($,H[1].trim().toLowerCase(),(H[2]??"").trim()),!0}let V=Rj.get(Z.trim().toLowerCase());if(!V)return!1;switch(V){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let X=!$.isRunning(),G=$.backendLabel(),K=X?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${G}`)):null,B=$.withModel(`\uD83D\uDE80 启动 ${G}`);if(!(X?await $.start({announce:!K,onStatus:(A)=>{B=A,$.setStatusCard(K,A)}}):!0))return await $.closeStatusCard(K,B.startsWith("❌")?B:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(K)await $.closeStatusCard(K,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:j}=await Promise.resolve().then(() => (P2(),mQ));if(!await u($.chatId,j({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(K)return await $.replaceStatusCardWithConsole(K,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(X)await $.closeStatusCard(K,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let X=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!X,onStatus:(G)=>$.setStatusCard(X,G)}),await $.closeStatusCard(X,"\uD83D\uDED1 已取消额度恢复")}catch(G){throw await $.closeStatusCard(X,`❌ ${O(G)}`),G}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let X=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(X)await $.closeStatusCard(X,"⚪ 无正在执行的 turn");else await N($.chatId,"⚪ 当前没有正在执行的 turn");return!0}_(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let z=new Set;for(let[X,G]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(G)S$(X,G);c$(X,"CrossMark"),z.add(X)}for(let X of $.pendingMidTurnMsgs)if(X.msgId&&!z.has(X.msgId))c$(X.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0;case"kill":{let X=$.isRunning(),G=$.backendLabel($.proc?.provider??$.currentProvider()),K=X?`\uD83D\uDED1 停止 ${G}`:"⚪ session 当前未运行",B=await $.openStatusCard("kill",K,X?"red":"grey"),L=null,A=X?`✅ ${G} 已终止`:`⚪ ${G} 未运行`;try{await $.stop("已终止",{announce:!B,onStatus:(j)=>{$.setStatusCard(B,j)}})}catch(j){L=j,A=$.isRunning()?`❌ ${G} 未确认终止: ${O(j)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${G} 停止收尾失败: ${O(j)}`}finally{try{await $.closeStatusCard(B,A)}catch(j){_(`session "${$.sessionName}": kill status card close failed: ${O(j)}`),await w($.chatId,`${A}
227
+ ⚠️ kill 状态卡片终态写入失败: ${O(j)}`)}}if(L&&!B)await w($.chatId,A)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let X=$.lastSessionId?M$($.lastSessionId):"",G=$.backendLabel($.proc?.provider??$.currentProvider()),K=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${G}`):X?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${X}`):$.withModel(`\uD83D\uDD01 启动 ${G}`),B=await $.openStatusCard("restart",K),L=K,A=await $.restart(!0,{announce:!B,onStatus:(P)=>{L=P,$.setStatusCard(B,P)}}),j=A?L.startsWith("✅")?L:$.withWorktreeInstructionNotice(X?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):L.startsWith("❌")?L:"❌ 重启失败";await $.closeStatusCard(B,A?$.withModel(j):j)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let X=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(X)await $.closeStatusCard(X,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await N($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let X=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),G="\uD83E\uDDF9 清空并启动新会话",K=await $.restart(!1,{announce:!X,onStatus:(B)=>{G=B,$.setStatusCard(X,B)}});await $.closeStatusCard(X,K?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):G.startsWith("❌")?G:"❌ 清空失败")}return!0}}var Rj;var yV=T(()=>{$$();I();Rj=new Map([["hi","hi"],["stop","stop"],["st","stop"],["kill","kill"],["kl","kill"],["restart","restart"],["rs","restart"],["clear","clear"],["cl","clear"],["compact","compact"],["cm","compact"],["model","model"],["md","model"]])});function Tj($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,W=()=>{$.off("context_compacted",z),$.off("exit",X),$.off("error",G)},H=(B)=>{if(Z)return;Z=!0,W(),J(B)},V=(B)=>{if(Z)return;Z=!0,W(),Y(B)},z=(B)=>{if(B.phase==="start")return;if(B.threadId&&Q&&B.threadId!==Q)return;H(B)},X=()=>V(Error(`${$.provider} process exited before context compaction completed`)),G=(B)=>V(B instanceof Error?B:Error(String(B))),K=new Promise((B,L)=>{J=B,Y=L});return $.on("context_compacted",z),$.once("exit",X),$.once("error",G),{promise:K,cancel(){if(Z)return;Z=!0,W()}}}function Nj($,Z){let J=[],Y=new Set,Q=(V,z)=>{let X=z.threadId??Z;if(X&&V.threadId&&V.threadId!==X)return!1;if(z.turnId)return V.turnId===z.turnId;return!0},W=(V)=>{for(let z=J.length-1;z>=0;z--){let X=J[z];if(X&&Q(X,V))return X}return null},H=(V)=>{if(Z&&V.threadId&&V.threadId!==Z)return;let z={usage:V.usage,contextWindow:V.contextWindow,threadId:V.threadId,turnId:V.turnId};J.push(z);for(let X of[...Y])if(Q(z,X.notice))X.finish(z)};return $.on("token_usage",H),{waitFor(V,z){let X=W(V);if(X)return Promise.resolve(X);return new Promise((G)=>{let K=null,B={notice:V,finish:(L)=>{if(K)clearTimeout(K);Y.delete(B),G(L)}};K=setTimeout(()=>B.finish(null),z),Y.add(B)})},cancel(){$.off("token_usage",H);for(let V of[...Y])V.finish(null)}}}function Ej($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=O8($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=T8($.contextWindow);return` · \uD83E\uDDE0 ${MW(Z,J)} (${N8(Z,J)})`}async function wV($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let X=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(X)await $.closeStatusCard(X,"⚪ 后端未运行,compact 无效");else await N($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let X=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(X)await $.closeStatusCard(X,"⚠️ 先 stop 当前 turn,再 compact");else await N($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let X=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(X)await $.closeStatusCard(X,"⏳ 上下文压缩已在进行中");else await N($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?M$(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),W=await $.openStatusCard("compact",Q,"orange"),H=async(X)=>{if(W)await $.closeStatusCard(W,X);else await N($.chatId,X)},V=Tj(J),z=Nj(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(W,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(W,$.withModel("⏳ 等待压缩完成事件"));let X=await V.promise,G=await z.waitFor(X,Oj),K=X.threadId?` thread=${M$(X.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${K}${Ej(G)}`))}catch(X){if(V.cancel(),X instanceof q1)await H($.withModel(`ⓘ ${X.message}`));else await H(`❌ 上下文压缩失败: ${O(X)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var Oj=1500;var fV=T(()=>{P$();$$()});import{randomUUID as kj}from"node:crypto";function xj($){let Z=$.currentTokenSource();return O0().map((J)=>$.tokenSource(J.id)).filter((J)=>J.enabled||J.kind!=="claude-native").map((J)=>({provider:J.agent,sourceId:J.id,display:J.display,enabled:J.enabled,modelCount:J.models.length,catalogStatus:J.modelCatalogState?.status,catalogError:J.modelCatalogState?.error,selected:Z?.id===J.id}))}function SZ($,Z,J=Z.models){let Y=$.currentModelLabel(),Q=$.currentEffortLabel(),W=$.currentTokenSource()?.id===Z.id;return J.map((H)=>{let V=W&&Y===H.model;return{provider:Z.agent,sourceId:Z.id,model:H.model,displayName:H.display,description:H.unavailableReason??(H.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:H.unavailableReason,origin:H.origin,enabled:!0,isDefault:!1,selected:V,efforts:H.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===H.defaultEffort,selected:V&&Q===z}))}})}async function vV($){await B4();let Z=kj(),J=xj($);$.modelPanels.set(Z,{models:[]});let Y=await u($.chatId,j3({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}));if(!Y)$.modelPanels.delete(Z),await w($.chatId,"❌ 模型面板发送失败");else{let Q=$.modelPanels.get(Z);if(Q)Q.messageId=Y}}async function kZ($,Z,J=""){let Y=Z.trim(),Q=$.tokenSource(Y);if(!Q)return{ok:!1,message:`未知账号: ${Y}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置,请先点「启用」`};let W=J.trim();if(!$.modelPanels.has(W))return{ok:!1,message:"模型面板已失效,请重新发送 model"};if(Q.modelCatalogState?.status==="failed")return{ok:!1,message:`模型目录 MISS:${Q.modelCatalogState.error??"刷新失败"}`};let H=SZ($,Q),V=$.modelPanels.get(W)?.messageId;return $.modelPanels.set(W,{models:[],catalog:H,sourceId:Y,messageId:V,mode:"select",editable:!!Q.modelSelection,sourceRevision:Q.spawnRevision}),G6($,W,Y,0)}async function G6($,Z,J,Y){let Q=$.modelPanels.get(Z);if(!Q?.catalog||Q.sourceId!==J)return{ok:!1,message:"模型面板已失效,请重新发送 model"};let W=Math.max(1,Math.ceil(Q.catalog.length/EZ));if(!Number.isInteger(Y)||Y<0||Y>=W)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*EZ,(Y+1)*EZ),Q.page=Y,Q.totalPages=W,{ok:!0,message:"",card:P3({sessionName:$.sessionName,panelId:Z,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:Q.models,sourceId:J,editable:Q.editable,allowCustom:!0,mode:Q.mode,...W>1?{pagination:{sourceId:J,page:Y,totalPages:W}}:{}})}}async function hV($,Z,J){let Y=$.modelPanels.get(Z),Q=$.tokenSource(J);if(!Y||Y.sourceId!==J||!Q?.enabled||!Q.modelSelection)return{ok:!1,message:"模型管理面板已失效,请重新发送 md"};if(Q.modelCatalogState?.status!=="ready")return{ok:!1,message:Q.modelCatalogState?.error??"目录未就绪"};let W=Q.modelSelection.availableModels.filter((H)=>H.origin!=="custom"&&!Q.modelSelection.modelIds.includes(H.model)&&(Q.modelSelection.mode==="catalog"||!H.unavailableReason&&H.efforts.length>0));return $.modelPanels.set(Z,{models:[],catalog:SZ($,Q,W),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),G6($,Z,J,0)}async function IV($,Z,J,Y,Q){let W=$.modelPanels.get(Z),H=$.tokenSource(J);if(!W?.editable||W.sourceId!==J||!H?.modelSelection||W.sourceRevision!==H.spawnRevision||W.mode!==(Q==="add"?"add":"select")||!W.models.some((V)=>V.model===Y))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Q==="delete"){let V=[...H0.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Y.replace(/\[1m\]$/,""));if(V.length)return{ok:!1,message:`补录模型仍被会话 ${V.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Q==="delete")await CV(J,Y,$.codexAccountId());else await kV(J,Y,Q,$.codexAccountId());for(let z of H0.all)for(let[X,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||X!==Z))z.modelPanels.delete(X);return{...await kZ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(V){return{ok:!1,message:`模型列表更新失败:${O(V)}`}}}async function gV($,Z,J,Y=""){let Q=$.tokenSource(Z.trim());if(!Q)return{ok:!1,message:`未知账号: ${Z}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置`};let W=J.trim();if(!W)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:W,cardMessageId:Y},{ok:!0,message:"等待模型名",card:M3($.sessionName,Q.display,W)}}async function mV($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),W=$.tokenSource(Y.sourceId),H=async(B)=>{if(!Y.cardMessageId)return!1;let L="",A=!1,j=!1;try{if(L=await t$(Y.cardMessageId),p$(L,1),A=await G$(L,U.modelPanel,B,{notifyCardFailure:!1}),!A)throw Error("model panel replace rejected");if(j=await j$(L,{config:{streaming_mode:!1}}),!j)throw Error("model panel streaming-off rejected")}catch(P){_(`model-custom: card update MISS (${P?.message??P})`)}finally{if(L){if(!j)try{j=await j$(L,{config:{streaming_mode:!1}})}catch(P){_(`model-custom: streaming-off retry MISS (${P?.message??P})`)}if(A&&j)try{await y$(L)}catch(P){_(`model-custom: card dispose MISS (${P?.message??P})`)}else _(`model-custom: retain card state after checked MISS mutation=${A} streamingOff=${j} card=${L.slice(0,12)}`)}}return A&&j},V=async(B,L)=>{if(await H(B))return!0;let j=`⚠️ 模型补录结果未能写回原卡。${L}
228
+ 请重新发送 model 打开面板。`;if(!await w($.chatId,j))_(`model-custom: visible fallback send MISS (${L})`);return!1},z=(B)=>V(j2(!1,Q,B),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${B}。`);if(!W||!W.enabled)return await z("账号不可用"),!0;if(!Q)return await z("模型名为空"),!0;if(W.models.some((B)=>B.model.toLowerCase()===Q.toLowerCase()))return await V(j2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await xV(W.id,Q,$.codexAccountId())}catch(B){return _(`model-custom: config/refresh MISS (${O(B)})`),await z(`配置写入或模型刷新失败:${O(B)}`),!0}_(`model-custom: ${W.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let B of H0.all)for(let[L,A]of B.modelPanels)if(A.sourceId===W.id&&(B!==$||L!==Y.panelId))B.modelPanels.delete(L);let X=$.tokenSource(W.id);if(!X||X.modelCatalogState?.status!=="ready")return await z(X?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let G=SZ($,X),K=G.find((B)=>B.model===Q);if(!K)return await z("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Y.panelId,{models:G,messageId:Y.cardMessageId}),K.unavailableReason||!K.efforts.length)return await V(j2(!0,Q,`**MISS**:${K.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Q} 已补录,能力尚未确认。`),!0;if(K.efforts.length===1){let B=await $.onModelEffortSelect(K.model,K.efforts[0].effort,Y.panelId,J,K.provider);return await V(B.ok?z8({sessionName:$.sessionName,provider:K.provider,model:K.model,effort:K.efforts[0].effort,scope:pV($,K.provider??"codex")}):j2(!0,Q,B.message),B.message),!0}return await V(V8({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:K}),`✅ 模型 ${Q} 已补录成功。`),!0}async function cV($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:H8($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:H8($.sessionName)}}function Cj($,Z){return z0(Z?.provider)?Z.provider:$2($)}function pV($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${X0(Z)} 时使用。`}async function uV($,Z,J="",Y="",Q=null){let W=Z.trim();if(!W)return await N($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=Cj(W,Q),V=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===W&&(z.provider??"codex")===H);if(!V)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(V.unavailableReason)return{ok:!1,message:V.unavailableReason};if(V.enabled===!1)return{ok:!1,message:`${V.displayName} 未配置,请先点「启用」`};if(V.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(V.efforts.length===1)return xZ($,W,V.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:D3({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:V})}}async function xZ($,Z,J,Y="",Q="",W=""){let H=Z.trim(),V=J.trim();if(!H)return{ok:!1,message:"模型为空"};let z=Y.trim(),X=$.modelPanels.get(z),G=z0(W)?W:X?.models.find((M)=>M.model===H)?.provider??$2(H);if(G==="dsh"){if(!K$(V))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!T$(V))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!a$(V))return{ok:!1,message:"Codex reasoning effort 无效"};let K=V,B=X?.models.find((M)=>M.model===H&&(M.provider??"codex")===G);if(!B||!B.efforts.some((M)=>M.effort===K))return{ok:!1,message:`${X0(G)} · ${H}/${K} 不在选项中`};let L=$.tokenSource(B.sourceId);if(L?.modelCatalogState){if(!L.enabled||L.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${L.modelCatalogState.error??L.modelCatalogState.status}`};if(!L.models.some((M)=>M.model===H&&M.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let A=!!B.sourceId&&$.currentTokenSource()?.id!==B.sourceId,j=!$.processSourceMatches(L,H)||!!L?.modelEnvironmentRevision&&L.modelEnvironmentRevision($.currentModelLabel()??"")!==L.modelEnvironmentRevision(H);if($.currentProvider()===G&&!A&&$.currentModelLabel()===H&&$.currentEffortLabel()===K)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${X0(G)} · ${H} / ${K}`,card:W8({sessionName:$.sessionName,provider:G,model:H,effort:K,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${X0(G)}`};let F=$.currentModelLabel()!==H||A,R=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(j&&$.proc?.isAlive()&&R)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&F&&R)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!A&&!j){let k=B.sourceId?$.tokenSource(B.sourceId)?.resolveSpawnModel(H)??H:H;await MY($.proc.setModelSettings(k,K),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,K,B.sourceId);let M=pV($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${X0(G)} · ${H} / ${K}`,card:W8({sessionName:$.sessionName,provider:G,model:H,effort:K,scope:M})}}catch(M){let k=`模型切换失败: ${O(M)}`;return _(`session "${$.sessionName}": set model settings failed: ${O(M)}`),await N($.chatId,`❌ ${k}`),{ok:!1,message:k}}}var EZ=20;var lV=T(()=>{P$();CZ();Y$();OZ();j1();P$();$0();r0();$$();I()});import{createHash as yj}from"node:crypto";function wj($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function g1($="default"){return fj(O0().map((Z)=>Z.forAccount?.($)??Z))}function fj($){let Z=[],J=[];for(let Y of $)vj(Y,Z,J);return{catalogGeneration:yj("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function vj($,Z,J){let Y=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Y==="loading"||Y==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Y==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Q of $.models)Z.push(hj($,Q,Y))}function hj($,Z,J){let Y="ready",Q;if(!$.enabled)Y="source_disabled",Q="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Y="catalog_loading",Q="模型目录正在刷新";else if(J==="failed")Y="catalog_failed",Q=$.modelCatalogState?.error??"模型目录刷新失败";else if(Z.unavailableReason||!Z.efforts.length)Y="model_unavailable",Q=Z.unavailableReason??"effort MISS:上游未声明该后端支持的推理档位";return{id:wj($.id,Z.model),displayName:`${$.display} · ${Z.display}`,tokenSourceId:$.id,tokenSourceDisplay:$.display,provider:$.agent,model:Z.model,modelDisplay:Z.display,defaultEffort:Z.defaultEffort,supportedEfforts:[...Z.efforts],sourceDefault:iV($.defaultModel)===iV(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function iV($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var _6=T(()=>{Y$()});import{randomUUID as Ij}from"node:crypto";async function dV($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}oV(),await B2();let J=`agents_${Ij()}`;if(Y9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,aV(J)))await w($.chatId,"❌ agents 面板发送失败")}function nV($,Z,J){let Y=cj($,J),Q=Number(Z);if(!Number.isInteger(Q))return pj("无效页码");let W=mj(Y.codexAccountId);return Y.page=Math.max(0,Math.min(W-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:aV($)}}function aV($){let Z=Y9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=g1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/K6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*K6;return I7({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+K6),failures:J.sourceFailures})}function mj($){return Math.max(1,Math.ceil(g1($).identities.length/K6))}function cj($,Z){oV();let J=Y9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function pj($){return{ok:!1,message:$,card:$1({title:"agents",message:$,ok:!1})}}function oV(){let $=Date.now()-gj;for(let[Z,J]of Y9)if(J.createdAt<$)Y9.delete(Z)}var K6=8,gj=1800000,Y9;var rV=T(()=>{$0();$$();_6();Y$();Y9=new Map});var wZ={};P0(wZ,{withTasklistLifecycleLock:()=>L6,tasklistNameForProject:()=>q6,reconcileTasklistDeletions:()=>dj,isTasklistAlreadyDeletedError:()=>tV,getTasklistBinding:()=>y0,enableTasklist:()=>bZ,deleteTasklistRemoteIdempotently:()=>sV,deleteTasklist:()=>yZ});import{existsSync as lj,readFileSync as ij}from"node:fs";function q6($){return`${$}[lodestar]`}function y0($){let Z=b0.get($);return Z?v2(Z):null}async function L6($,Z){let J=B6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),W=J.catch(()=>{}).then(()=>Q);B6.set($,W),await J.catch(()=>{});try{return await Z()}finally{if(Y(),B6.get($)===W)B6.delete($)}}function tV($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function sV($,Z=N3){try{return await Z($),"deleted"}catch(J){if(tV(J))return"already_deleted";throw J}}async function bZ($,Z){return await L6($,async()=>{let J=y0($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=q6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await O3(Z),W=await T3(Y,Q),H={guid:W.guid,name:W.name,url:W.url,projectName:$,ownerOpenId:Q,createdAt:W.createdAt};return A6($,H),v2(H)})}async function yZ($,Z){return await L6($,async()=>{let J=y0($);if(!J)throw Error("tasklist is not enabled");if(J.guid!==Z)throw Error(`tasklist binding changed: current=${J.guid} requested=${Z}`);if(!J.deleting)J.deleting={requestedAt:new Date().toISOString(),attempts:0},A6($,J);return await eV($,Z)})}async function eV($,Z){let J=y0($);if(!J||J.guid!==Z)throw Error(`tasklist binding changed during deletion: ${$}`);J.deleting??={requestedAt:new Date().toISOString(),attempts:0},J.deleting.attempts++,J.deleting.lastAttemptAt=new Date().toISOString(),J.deleting.lastError=void 0,A6($,J);try{if(await sV(Z)==="already_deleted")_(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(b0);return Q.delete($),$z(Q),b0.delete($),v2(J)}catch(Y){let Q=y0($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),A6($,Q);throw Y}}async function dj(){let $=[...b0.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await L6(J.projectName,()=>eV(J.projectName,J.guid)),_(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Y){Z.push(`${J.projectName}: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function nj(){if(!lj(_9))return;try{let $=JSON.parse(ij(_9,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Y=J;if(typeof Y.guid!=="string"||!Y.guid||typeof Y.name!=="string"||!Y.name)continue;let Q={guid:Y.guid,name:Y.name,url:typeof Y.url==="string"?Y.url:"",projectName:Z,ownerOpenId:typeof Y.ownerOpenId==="string"?Y.ownerOpenId:"",createdAt:typeof Y.createdAt==="string"?Y.createdAt:void 0,deleting:aj(Y.deleting)};b0.set(Z,Q)}_(`tasklist: loaded ${b0.size} project bindings`)}catch($){_(`tasklist: load map failed: ${$}`)}}function aj($){if(!$||typeof $!=="object")return;let Z=$;if(typeof Z.requestedAt!=="string"||!Z.requestedAt)return;return{requestedAt:Z.requestedAt,lastAttemptAt:typeof Z.lastAttemptAt==="string"?Z.lastAttemptAt:void 0,attempts:typeof Z.attempts==="number"&&Number.isFinite(Z.attempts)&&Z.attempts>=0?Math.floor(Z.attempts):0,lastError:typeof Z.lastError==="string"?Z.lastError:void 0}}function A6($,Z){let J=new Map(b0);J.set($,v2(Z)),$z(J),b0.set($,v2(Z))}function $z($=b0){let Z={};for(let[J,Y]of $)Z[J]=v2(Y);t(_9,Z)}function v2($){return JSON.parse(JSON.stringify($))}var b0,B6;var fZ=T(()=>{H$();$$();I();f$();b0=new Map,B6=new Map;nj()});function Q1($,Z,J=!1){let Y=$.worktreeProjectName();return f7({projectName:Y,tasklistName:q6(Y),binding:y0(Y),notice:Z,confirmDelete:J})}async function Zz($){if(!await u($.chatId,Q1($)))await w($.chatId,"❌ task 面板发送失败")}async function Jz($){let Z=$.worktreeProjectName();try{let J=y0(Z),Y=await bZ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:Q1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${O(J)}`;return _(`session "${$.sessionName}": tasklist enable failed: ${O(J)}`),{ok:!1,message:Y,card:Q1($,{type:"error",content:`❌ ${Y}`})}}}function Yz($,Z){let J=$.worktreeProjectName(),Y=y0(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:Q1($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:Q1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:Q1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function Qz($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let W=`已删除 ${(await yZ(J,Y)).name}`;return{ok:!0,message:W,card:Q1($,{type:"success",content:`✅ ${W}`})}}catch(Q){let W=`删除失败: ${O(Q)}`;return _(`session "${$.sessionName}": tasklist delete failed: ${O(Q)}`),{ok:!1,message:W,card:Q1($,{type:"error",content:`❌ ${W}`})}}}var Wz=T(()=>{$0();$$();I();fZ()});var vZ,hZ,Hz,Vz,zz;var Xz=T(()=>{vZ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。","- 飞书单个出站文件不能超过 30 MB(30 × 1024 × 1024 字节)。交付前检查大小;超限先压缩或分卷,确保每个文件都不超过上限,再发送。"],hZ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],Hz=[...vZ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...hZ].join(`
229
+ `),Vz=[...vZ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...hZ].join(`
230
+ `),zz=[...vZ,"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。",...hZ].join(`
231
+ `)});import{execFileSync as rj}from"node:child_process";import{existsSync as m1,readdirSync as tj,readFileSync as sj,realpathSync as IZ,statSync as ej}from"node:fs";import{dirname as $P,join as _z,resolve as P6}from"node:path";async function D6($,Z){let J=IZ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=j6.get(Y)??Promise.resolve(),W,H=new Promise((z)=>{W=z}),V=Q.catch(()=>{}).then(()=>H);j6.set(Y,V),await Q.catch(()=>{});try{return await Z()}finally{if(W(),j6.get(Y)===V)j6.delete(Y)}}function c1($){let Z=$.trim();if(!ZP.test(Z))return null;return Z}function Kz($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function I2($,Z){return`${$}[${Z}]`}function Bz($){return`${h2}${$}`}function g2($,Z,J){return _z($P($),I2(Z,J))}function Az($,Z,J){let Y=JP($,Z,J);if(!Y)return null;let Q=sj(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function qz($,Z){mZ($);let J=U$($,["for-each-ref","--format=%(refname:short)",`refs/heads/${h2}`]).split(`
232
+ `).map((W)=>W.trim()).filter(Boolean).filter((W)=>W.startsWith(h2)),Y=cZ($),Q=[];for(let W of J){let H=W.slice(h2.length);if(!c1(H))continue;let V=I2(Z,H),z=g2($,Z,H),X=Y.get(W)??null,G=!!X&&m1(X),K=Dz($,W,G),B={slug:H,chatName:V,branch:W,state:K,expectedPath:z,worktreePath:G?X:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(X&&m1(X))try{let A=U$(X,["status","--porcelain=v1","--branch"]).split(`
233
+ `).filter(Boolean);B.statusLine=A[0]?.startsWith("## ")?A[0].slice(3):null,B.dirtyCount=A.filter((j)=>!j.startsWith("## ")).length}catch(L){B.error=pZ(L)}Q.push(B)}return Q.sort((W,H)=>W.slug.localeCompare(H.slug))}function Lz($,Z,J){let Y=c1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);mZ($);let Q=Bz(Y),W=I2(Z,Y),H=g2($,Z,Y),V=HP($,Q),z=cZ($).get(Q)??null,X=V&&!z&&Dz($,Q,!1)==="merged"?U$($,["rev-parse","HEAD"]).trim():null;if(z){if(P6(z)!==P6(H))throw Error(`branch ${Q} is already mounted at ${z}`);return Pz(H,Q),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(m1(H)){if(!ej(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!V)throw Error(`${H} already exists while branch ${Q} does not`)}if(V){if(U$($,["worktree","add",H,Q]),X)U$(H,["rebase",X]);return{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return U$($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function jz($,Z,J){let Y=gZ($,Z,J);if(!m1(Y.worktreePath))return Y;return U$($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function gZ($,Z,J){let Y=c1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);mZ($);let Q=Bz(Y),W=I2(Z,Y),H=g2($,Z,Y),z=cZ($).get(Q)??null??H;if(!m1(z))return{slug:Y,chatName:W,branch:Q,worktreePath:z,removedWorktree:!1};Pz(z,Q);let X=U$(z,["status","--porcelain=v1"]).split(`
234
+ `).filter(Boolean);if(X.length>0){let G=X.slice(0,8).join(`
195
235
  `);throw Error(`worktree has uncommitted changes:
196
- ${G}`)}return{slug:Y,chatName:W,branch:Q,worktreePath:X,removedWorktree:!1}}function kZ($){if(!I1($))throw Error(`project directory does not exist: ${$}`);let Z=R$($,["rev-parse","--show-toplevel"]).trim();if(EZ(Z)!==EZ($))throw Error(`${$} is not the git repository root (${Z})`)}function rV($,Z){let J=R$($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function _L($,Z,J){let Y=KL($);if(!Y?.startsWith(f2))return null;let Q=Y.slice(f2.length);if(!g1(Q))throw Error(`invalid worktree branch "${Y}"`);let W=h2(Z,J,Q);if(X5($)!==X5(W))return null;let H=AL($,BL(Q));return H?{path:H,slug:Q}:null}function KL($){if(!I1($))return null;try{return R$($,["branch","--show-current"]).trim()||null}catch(Z){if(PL(Z))return null;throw Z}}function BL($){return $.split("-",1)[0]??$}function AL($,Z){let J=`agents.${Z}.md`,Y=HL($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?pV($,Y[0]):null}function qL($,Z){try{return R$($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function tV($,Z,J){let Y=R$($,["rev-parse",Z]).trim(),Q=R$($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(uV($,Z,"HEAD"))return"merged";if(uV($,"HEAD",Z))return"active";return"stale"}function uV($,Z,J){try{return R$($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function xZ($){let Z=new Map,J=R$($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
197
- `)){if(Q.startsWith("worktree ")){Y=Q.slice(9);continue}if(Q.startsWith("branch refs/heads/")&&Y)Z.set(Q.slice(18),Y)}return Z}function R$($,Z){try{return WL("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(CZ(J))}}function CZ($){if($&&typeof $==="object"){let Z=$,J=Z.stderr?String(Z.stderr).trim():"";if(J)return J;if(Z.message)return Z.message}return String($)}function PL($){return/not a git repository/i.test(CZ($))}var f2="work/",GL,V5;var sV=T(()=>{GL=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,V5=new Map});function Y1($){return lV(K0($.sessionName)??$.sessionName)}function I2($){return H8(Y1($))}function $X($){let Z=K0($.sessionName)??$.sessionName,J=Y1($),Y=H8(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return h2(Y,J,Q)}function ZX($,Z=$.currentProvider()){let J=Z==="dsh"?mV:Z==="claude"?gV:IV,Y=Z9($);return Y?`${J}
198
- ${Y}`:J}function JX($,Z){return Z9($)??""}function bZ($){return Z9($)?"已载入wt特殊约定":null}function YX($,Z){let J=bZ($);return J?`${Z}
199
- ${J}`:Z}function Z9($){let Z=Y1($),J=dV($.workDir,I2($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
200
- `)}async function QX($,Z,J){if(!Z){await yZ($);return}let Y=g1(Z);if(!Y){await E($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await E($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=Y1($),W=I2($);try{await z5(W,async()=>{let H;try{H=aV(W,Q,Y)}catch(V){await E($.chatId,`❌ wt 失败: ${O(V)}`);return}try{let V=await h7(H.chatName,J),X=V.created?"已创建":V.joined?"已加入":"已在群内";if(!await u($.chatId,c4({slug:Y,branch:H.branch,status:X})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await u(V.chatId,c4({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await w(V.chatId,`❌ wt 卡片失败: ${Y}`)}catch(V){await E($.chatId,`❌ wt 已建,拉群失败: ${O(V)}`)}})}catch(H){await E($.chatId,`❌ wt 失败: ${O(H)}`)}}async function WX($,Z){let J=Y1($),Y=I2($);return await z5(Y,async()=>{return await jL(J,Y,Z)})}async function jL($,Z,J){let Y=nV(Z,$),Q=Y.filter((V)=>V.state==="merged"&&!V.mounted).length,W=Y.filter((V)=>V.state!=="merged"||V.mounted),H=await X8();return q3({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:W.map((V)=>{let X=H.get(V.chatName)??[],z=A$.get(V.chatName),G=z&&X.includes(z)?z:X.length===1?X[0]:null;return{slug:V.slug,chatName:V.chatName,branch:V.branch,state:V.state,path:V.worktreePath??V.expectedPath,mounted:V.mounted,dirtyCount:V.dirtyCount,statusLine:V.statusLine,error:V.error,chatId:G,duplicateChatCount:X.length}})})}async function yZ($){try{let Z=await WX($);if(!await u($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await E($.chatId,`❌ wt 列表失败: ${O(Z)}`)}}async function eV($,Z,J,Y){try{return{ok:Z,message:J,card:await WX($,{type:Y,content:J})}}catch(Q){let W=`列表刷新失败: ${O(Q)}`;return _(`session "${$.sessionName}": wt action panel refresh failed: ${O(Q)}`),{ok:!1,message:`${J}
201
- ${W}`,card:c4({slug:"wt",branch:"work/*",status:J,body:W,template:"red"})}}}async function HX($,Z){let J=g1(Z);if(!J)return eV($,!1,"❌ 名称无效","error");let Y=Y1($),Q=I2($),W;try{W=await z5(Q,async()=>{let H=v2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};SZ(Q,Y,J);let V=await g7(H),X=oV(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,X.removedWorktree?"dir removed":"dir missing",V.disbanded?"group removed":"group missing",X.branch].join(`
202
- `),type:"success"}})}catch(H){W={ok:!1,message:`❌ 解散 ${J} 失败: ${O(H)}`,type:"error"}}return eV($,W.ok,W.message,W.type)}var VX=T(()=>{cV();s$();$$();I();sV()});import{closeSync as ML,openSync as FL,readSync as RL,readdirSync as UL,statSync as OL}from"node:fs";import{randomUUID as fZ}from"node:crypto";import{join as TL}from"node:path";function _5($){return K0($.sessionName)??$.sessionName}function zX($){let Z=x7($,wZ);return wZ.add(Z),Z}function GX($){wZ.delete($)}function g2($){let Z=XX.get($);if(!Z)Z=new Map,XX.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let W=Q.status==="consumed"?SL:EL,H=Q.consumedAt??Q.createdAt;if(J-H>W)Z.delete(Y)}return Z}function xL($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function _X($,Z,J,Y){let Q={id:fZ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:_5($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return g2($).set(Q.id,Q),Q}function vZ($,Z,J,Y,Q){let W=g2($).get(J);if(!W||W.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||W.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(W.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(W.provider!==$.selectedProvider||W.workDir!==$.workDir||W.sourceSessionId!==$.lastSessionId||!xL(W.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=W.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return W.status="processing",{panel:W,choice:H}}function G5($){$.status="consumed",$.consumedAt=Date.now()}function CL($){return{kind:"fork",source:$.source,through:$}}function bL($){return N4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function yL($){let Z=E4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return K$(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function wL($){let Z=v9($),J;try{J=UL(Z)}catch(Q){if(Q?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Q?.message??Q}`)}let Y=[];for(let Q of J){if(!Q.endsWith(".jsonl"))continue;let W=Q.slice(0,-6);if(o1("claude",W))continue;let H=TL(Z,Q),V;try{V=OL(H).mtimeMs}catch(X){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${X?.message??X}`)}Y.push({provider:"claude",sessionId:W,cwd:$,preview:vL(H),ts:V})}return Y.sort((Q,W)=>W.ts-Q.ts)}function fL($){let Z=$.slice().sort((Q,W)=>W.ts-Q.ts),J=Date.now()-NL,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(kL,Math.max(10,Y)))}function vL($){let Z="",J=null;try{J=FL($,"r");let Q=Buffer.alloc(65536),W=RL(J,Q,0,65536,0);Z=Q.subarray(0,W).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)ML(J)}let Y="";for(let Q of Z.split(`
203
- `)){let W=Q.trim();if(!W)continue;let H;try{H=JSON.parse(W)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let V=H.content.trim();if(V)return V.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let V=hL(H.message);if(V)Y=V}}return Y.slice(0,80)}function hL($){let Z=$?.content;if(typeof Z==="string")return Z;if(!Array.isArray(Z))return"";for(let J of Z)if(J?.type==="text"&&typeof J.text==="string")return J.text;return""}async function KX($,Z,J){if(!J){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=bL($),Q=yL($),W=new Map,H=[];for(let G=0;G<Y.length;G++){let K=Y[G];if(G===0&&Q===null)continue;let B=fZ(),A=G===0?Q:CL(Y[G-1].checkpoint);W.set(B,{kind:Z,launch:A,branchBase:Q,seedAnchors:Y.slice(0,G),writes:Y.slice(G).flatMap((P)=>P.writes)}),H.push({choiceId:B,preview:K.preview,ts:K.ts})}H.reverse();let V=_X($,Z,J,W),X=L3({projectName:_5($),panelId:V.id,mode:Z,entries:H}),z;try{z=await u($.chatId,X)}catch(G){throw g2($).delete(V.id),G}if(!z)g2($).delete(V.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function BX($,Z){return KX($,"fork",Z)}function AX($,Z){return KX($,"back",Z)}async function qX($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():wL($.workDir)}catch(X){await w($.chatId,`❌ 历史会话读取失败: ${X instanceof Error?X.message:X}`);return}let Y=new Map,Q=fL(J).map((X)=>{let z=fZ();return Y.set(z,{kind:"resume",launch:{kind:"fork",source:{provider:X.provider,sessionId:X.sessionId,cwd:X.cwd}},sourcePreview:X.preview,sourceTs:X.ts,sourceStatus:X.status}),{choiceId:z,preview:X.preview,ts:X.ts}}),W=_X($,"resume",Z,Y),H=j3({projectName:_5($),panelId:W.id,entries:Q}),V;try{V=await u($.chatId,H)}catch(X){throw g2($).delete(W.id),X}if(!V)g2($).delete(W.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function PX($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await E($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=zX(_5($));await E($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Y;try{Y=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{GX(J)}if(!Y.ok){await E($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await E($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function LX($){if(!K0($.sessionName)){await E($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await E($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await E($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await E($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function jX($,Z,J,Y){let Q=vZ($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let V=zX(W.baseName);_(`session-temp: fork ${$.sessionName} → ${V} (${H.launch.kind})`),await E($.chatId,`\uD83D\uDD31 正在分叉到 ${V}…`);let X;try{X=await $.opts.onCreateTempSession({chatName:V,userOpenId:Y,workDir:W.workDir,routing:W.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{GX(V)}if(!X.ok)return{ok:!1,message:`分叉失败: ${X.error??"未知"}`};return{ok:!0,message:`已分叉到 ${V};原会话和磁盘文件未回滚`}}catch(V){return{ok:!1,message:`分叉失败: ${V instanceof Error?V.message:V}`}}finally{G5(W)}}async function DX($,Z,J,Y){let Q=vZ($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let V="";try{if(!await u($.chatId,D3({projectName:W.baseName,entries:H.writes})))V=";文件变更记录卡发送失败"}catch(G){V=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(_(`session-temp: back ${$.sessionName} (${H.launch.kind}, writes=${H.writes.length})`),!await $.rollbackTo(H.launch,{anchors:H.seedAnchors,base:H.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${V}`};if(W.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${V}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${D$($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${V}`}}catch(V){return{ok:!1,message:`回退失败: ${V instanceof Error?V.message:V}`}}finally{G5(W)}}async function MX($,Z,J,Y){let Q=vZ($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;if(H.kind!=="resume")throw G5(W),Error("resume panel contained a non-resume choice");let V=H.launch.source.sessionId,X=$.lastSessionId,z=(K,B)=>({projectName:W.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:V,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:X,newSessionId:K,bindingState:B}),G=(K,B,A,P=null)=>({ok:K,message:B,resumePresentation:z(P,A)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(_(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${V}`),!await $.rollbackTo(H.launch,{anchors:[],base:H.launch,pendingLaunch:H.launch.source.provider==="claude"?{launch:H.launch,previousSessionId:X}:null}))return G(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(H.launch.source.provider==="claude")return G(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let B=$.lastSessionId;if(!B)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(B===V||X&&B===X)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",B);return G(!0,"已创建并接入独立分支;源会话未修改","changed",B)}catch(K){return G(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{G5(W)}}var NL=86400000,EL=1800000,SL=3600000,kL=40,XX,wZ;var FX=T(()=>{$$();s$();I();X4();o2();A1();XX=new WeakMap,wZ=new Set});import{existsSync as RX}from"node:fs";import{randomBytes as gL,timingSafeEqual as mL}from"node:crypto";import{isAbsolute as cL}from"node:path";function IZ($,Z=new Set){if($ instanceof Z2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=IZ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return IZ($.cause,Z);return null}function uL($){return $.itemId||$.turnId||"__latest__"}function UX($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function pL($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function lL($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function m1(){return f.runtime?.live_elapsed??"bucket"}function NX($,Z){return`${$} (${m0(Date.now()-Z,m1()).label})`}var OX="Thinking...",iL="Writing...",dL="Working...",hZ=1e4,K5=720000,nL=50,aL=256,B5=1e4,TX=250,Q0;var MZ=T(()=>{o2();t2();L$();q1();h6();L$();k$();Z7();J$();h$();P2();X4();a0();s$();$$();I();W$();Y7();p0();i4();w3();JH();qH();xH();p8();yH();_V();BV();RV();SV();hV();VX();FX();A1();Q0=class Q0{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;agentCapability=null;procSourceRevisions=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];backgroundCard=null;settlingBackgroundCard=!1;migratingBackgroundCard=null;backgroundRefreshTimer=null;backgroundRefreshTick=null;openingBackground=!1;openingBackgroundOwner=null;backgroundOpenSequence=0;backgroundGeneration=0;backgroundDetailAdded=new Set;backgroundDetailAdding=new Set;lastMainTaskToolUseId=null;pendingRebuildBackgroundCard=!1;bgResumePending=!1;orphanAssistantSegments=[];orphanAssistantCurrent="";bgResumeCardless=!1;pendingPermissions=new Map;pendingAsks=new Map;currentGoal=null;status="stopped";pendingUserMessageCount=0;pendingMidTurnMsgs=[];pendingTurnInputs=[];multiMsgBuffer=null;multiMsgReactions=new Map;lastUserOpenId="";pendingReactionIds=new Map;currentBatchReactionIds=new Map;initCount=0;openingTurn=!1;openingTurnOwner=null;turnOpenSequence=0;turnCloseInflight=new Set;turnCounter=0;userInterrupted=!1;lastSessionId=null;lastSessionRef=null;selectedProvider="claude";selectedModel=null;selectedEffort=null;selectedTokenSourceId=null;modelPanels=new Map;modelCustomPrompt=null;startedAt=0;cumStats={tokens:0,costUsd:0,turns:0};lastTurnDelta=null;currentTurnUsageBaseline=null;currentTurnUsageBaselineKnown=!1;lastTurnUsage=null;usageTotalsSeedUnknown=!1;resumePersistenceError=null;daemonRestoreRequired=!1;manualContextCompactionPending=!1;taskBoard=[];constructor($,Z,J={}){this.sessionName=$;this.chatId=Z;this.opts=J;Q0.all.add(this);let Y=y7($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=G0(this.selectedTokenSourceId);if(Q){if(this.selectedProvider=Q.agent,Q.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Q.defaultModel,this.selectedEffort="max"}if(this.selectedModel)_(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=l0($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)_(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let W=S4($);if(W)if(this.selectedProvider!=="claude")a$($,[],null,null),_(`session "${$}": cleared pending Claude fork after provider changed`);else{K$(W.launch,"claude",this.workDir);let H=this.lastSessionId===W.previousSessionId,V=this.lastSessionRef,X=!H&&V?.provider==="claude"&&V.cwd===this.workDir&&V.sessionId!==W.launch.source.sessionId&&V.sessionId!==W.previousSessionId;if(!H&&!X)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=W,_(`session "${$}": restored ${X?"materialized":"pending"} Claude fork source=${W.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return $X(this)}isRunning(){return!!this.proc&&this.proc.isAlive()}shouldRevive(){return this.daemonRestoreRequired||this.isRunning()&&this.stoppingProc!==this.proc&&this.blockedProc!==this.proc}deriveTokenSourceId($){let Z=$?.tokenSourceId;if(typeof Z==="string"&&Z.trim())return Z.trim();let J=$?.provider??this.selectedProvider;return m9(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?F0(this.proc):this.codexStartAccountOverride??y.selected(this.sessionName)}tokenSource($){let Z=G0($);return Z?.forAccount?H$($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...this.codexAccountId()===l?{}:{codexAccountId:this.codexAccountId()},...y.preferred(this.sessionName)===null?{codexAccountAutomatic:!0}:{}}}applyConversationRouting($){if(this.isRunning()||this.currentTurn||this.openingTurn)throw Error("cannot change conversation routing while the session is running");if($.codexAccountId)y.get($.codexAccountId);let Z=G0($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)a$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=l0(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,U1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??l;if($.codexAccountAutomatic)y.selectAuto(this.sessionName);else if(y.selected(this.sessionName)!==J)y.select(this.sessionName,J)}dshEffortForSpawn(){if(_$(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&z0($,this.selectedModel??$.defaultModel);if(!Z||!_$(Z.defaultEffort))throw Error("DSH model reasoning effort is unavailable");return Z.defaultEffort}async listDshConversations(){if(this.selectedProvider!=="dsh")throw Error("DSH history requested under a different provider");let $=this.currentTokenSource();if(!$?.enabled||$.agent!=="dsh")throw Error("DSH token source is unavailable");return(await r1({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!o1("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!b4(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");let $=this.currentTokenSource();if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(V)=>Z.spawnEnv(V):void 0,Y=new J2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,W=null;try{Q=await Y.listConversations()}catch(V){W=V}let H=null;try{await Y.kill(2000)}catch(V){H=V}if(W&&H)throw AggregateError([W,H],`Codex history query and cleanup failed: ${O(W)}; ${O(H)}`);if(W)throw W;if(H)throw H;return Q??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="dsh")throw Error("DSH resume reference requires its original cwd");else if($.provider==="claude"){let J=h9(this.workDir,$.sessionId);if(!RX(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${D$($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!b4(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Y=J?.enabled?J:void 0,Q=new J2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(V)=>Y.spawnEnv(V):void 0}),W=null;try{Z=await Q.readConversationRef($.sessionId)}catch(V){W=V,Z=$}let H=null;try{await Q.kill(2000)}catch(V){H=V}if(W&&H)throw AggregateError([W,H],`Codex legacy resume lookup and cleanup failed: read=${O(W)}; cleanup=${O(H)}`);if(W)throw W;if(H)throw H}return K$({kind:"resume",source:Z},this.selectedProvider,this.workDir),T4(this.sessionName,Z),Z}hasRunningPeerSession($){return[...Q0.all].some((Z)=>Z.sessionName===$&&Z.isRunning())}modelForSpawn(){if(this.selectedProvider==="codex")return;return this.selectedModel??void 0}effortForSpawn(){if(this.selectedProvider==="codex"){let $=this.currentTokenSource();if(!$||!$.enabled&&$.id!=="codex-sub")return;return d$(this.selectedEffort)?this.selectedEffort:Y4}return Y4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&O$(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=z0($,this.selectedModel??$.defaultModel);if(!O$(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return h0}currentModelLabel(){return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude")return this.selectedEffort??z0($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?h0:Y4)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Y=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Q=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?h0:Y4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return Z$($,U.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:U.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return r7($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return V0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(K$($.launch,"claude",this.workDir),this.selectedProvider!=="claude")throw Error("pending Claude fork cannot launch under a non-Claude provider");if(this.lastSessionId===$.previousSessionId)return $.launch;let Z=this.lastSessionRef;if(Z?.provider==="claude"&&Z.cwd===this.workDir&&Z.sessionId!==$.launch.source.sessionId&&Z.sessionId!==$.previousSessionId)return{kind:"resume",source:Z};throw Error("pending Claude fork has no safe launch target")}spawnAgent($){this.agentCapability=gL(32).toString("base64url");let Z={LODESTAR_AGENT_URL:l9(f.notify.bind,f.notify.port),LODESTAR_AGENT_CAPABILITY:this.agentCapability,LODESTAR_AGENT_SESSION:this.sessionName,LODESTAR_AGENT_ROLE:"main"},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});K$(J,this.selectedProvider,this.workDir);let Y=this.currentTokenSource(),Q=this.selectedProvider==="codex"&&this.selectedTokenSourceId==="codex-sub";if(this.selectedTokenSourceId&&(!Y||!Y.enabled&&!Q))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let W=Y?.enabled||Q?Y:void 0,H=A4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:W?.id??null,...this.selectedProvider==="codex"?{codexAccountId:y.selected(this.sessionName)}:{},...Q?{codexAccountPreference:this.codexStartAccountOverride??y.preferred(this.sessionName)}:{},model:W?this.selectedModel??W.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="dsh"?this.dshEffortForSpawn():this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:j2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:z1},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),H.process}async applyModelSelection($,Z,J,Y){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Y))}async applyModelSelectionUnlocked($,Z,J,Y){if(this.selectedProvider!==$)a$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let W=G0(this.selectedTokenSourceId);if(W)this.selectedModel=Z||null,this.selectedEffort=J??z0(W,Z||W.defaultModel)?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=l0(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,b7(this.sessionName,$,this.selectedModel,this.selectedEffort,this.selectedTokenSourceId),await this.stopIdleMismatchedProcessUnlocked()}async stopIdleMismatchedProcess(){await this.runLifecycle("stop-idle-mismatched",()=>this.stopIdleMismatchedProcessUnlocked())}processSourceMatches($,Z){if(this.proc?.quotaWaitPromise&&!this.proc.sessionId&&this.proc.turnRetry?.reason==="quota")return!0;if(this.proc?.sourceRevision)return this.proc.sourceRevision()===X2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===X2($,Z)}async stopIdleMismatchedProcessUnlocked(){if(!this.proc?.isAlive())return;let $=this.currentTokenSource(),Z=this.processSourceMatches($,this.selectedModel);if(this.proc.provider===this.selectedProvider&&this.proc.tokenSourceId===this.selectedTokenSourceId&&Z)return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let J=this.proc;_(`session "${this.sessionName}": stop idle ${J.provider} process after switching to ${this.selectedProvider}`),this.beginProcStop(J),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let Y=await this.settleProcResumableState(J),Q=null;try{await J.kill(1000)}catch(V){Q=V}Y=await this.settleProcResumableState(J);let W=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!W?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Y?[Error(Y)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(O).join("; ")}`)}async stopIdleCurrentProcess($){return await this.runLifecycle("stop-idle-current",()=>this.stopIdleCurrentProcessUnlocked($))}async stopIdleCurrentProcessUnlocked($){if(!this.proc?.isAlive())return!1;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return!1;let Z=this.proc;_(`session "${this.sessionName}": stop idle ${Z.provider} process: ${$}`),this.beginProcStop(Z),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let J=await this.settleProcResumableState(Z),Y=null;try{await Z.kill(1000)}catch(H){Y=H}J=await this.settleProcResumableState(Z);let Q=this.finishProcStop(Z,Y);this.opts.onLifecycleChange?.();let W=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(W.length===1)throw W[0];if(W.length>1)throw AggregateError(W,`idle process stop failed: ${W.map(O).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,W=!1,H=()=>{if(W)return;this.replaceFooterContent($,J(NX(Q,Y)))},V=null,X=()=>{if(W)return;let{nextDelayMs:z}=m0(Date.now()-Y,m1());V=setTimeout(()=>{H(),X()},Math.max(1,Math.ceil(z)))};return H(),X(),{setStatus(z){Q=z,H()},stop(){if(W=!0,V)clearTimeout(V)},elapsedSec(){return((Date.now()-Y)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=Q7({sessionName:this.sessionName,title:$,status:NX(Z,Y),template:J}),W=await u(this.chatId,Q);if(!W)return _(`session "${this.sessionName}": status card send failed title=${$}`),await w(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await o$(W)}catch(V){return _(`session "${this.sessionName}": status card id_convert failed title=${$}: ${V}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return c$(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(V)=>L4($,V))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=L4($.title,`${Z} (${J}s)`);await r$($.cardId);let Q=await z$($.cardId,U.footer,this.footerElement(Y));M$($.cardId);let W=await P$($.cardId,U0({durationSec:J,suffix:Z}));if(Q&&W)await b$($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${W?"ok":"MISS"}`;_(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await w(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Y;this.lifecycleTail=new Promise((W)=>{Y=W}),await J;let Q=++this.lifecycleSequence;_(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),_(`session "${this.sessionName}": lifecycle#${Q} ${$} end`)}}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){if(this.openingTurnOwner)throw Error(`turn card open already owned by token=${this.openingTurnOwner.token}; same-process opens must wait for the current owner`);let Y,Q=new Promise((H)=>{Y=H}),W={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=W,this.openingTurn=!0,W}ownsTurnOpen($){return this.openingTurnOwner===$&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseTurnOpen($){if(this.openingTurnOwner!==$)return;this.openingTurnOwner=null,this.openingTurn=!1,$.resolveDone()}invalidateTurnOpen(){let $=this.openingTurnOwner;this.openingTurnOwner=null,this.openingTurn=!1,$?.resolveDone()}async waitForTurnOpenSlot($,Z){while(this.openingTurnOwner)if(await this.openingTurnOwner.done,this.proc!==$||this.procEpoch!==Z||!$.isAlive())return!1;return this.proc===$&&this.procEpoch===Z&&$.isAlive()}beginBackgroundOpen(){if(this.backgroundCard||this.openingBackgroundOwner)return null;let $={token:++this.backgroundOpenSequence,proc:this.proc,procEpoch:this.procEpoch,generation:this.backgroundGeneration};return this.openingBackgroundOwner=$,this.openingBackground=!0,$}ownsBackgroundOpen($){return this.openingBackgroundOwner===$&&this.backgroundGeneration===$.generation&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseBackgroundOpen($){if(this.openingBackgroundOwner!==$)return;this.openingBackgroundOwner=null,this.openingBackground=!1}invalidateBackgroundOpen(){this.backgroundGeneration++,this.openingBackgroundOwner=null,this.openingBackground=!1}attachProc($){this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.stoppingProc=null,this.blockedProc=null,this.blockedProcReason=null,this.proc=$;let Z=++this.procEpoch;this.wireProc($,Z)}detachProc($){if(this.proc!==$)return!1;if(this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.proc=null,this.agentCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.agentCapability=null}acceptsAgentCapability($){let Z=this.agentCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Y=Buffer.from($);return J.length===Y.length&&mL(J,Y)}async cancelAgentRuns($="用户取消"){await this.opts.onCancelAgentRuns?.(this.sessionName,this.chatId,$)}finishProcStop($,Z){if(this.stoppingProc===$)this.stoppingProc=null;if(!$.isAlive())return this.discardPendingCodexTurnAnchors($,"confirmed process stop"),this.detachProc($),!0;return this.blockedProc=$,this.blockedProcReason=Z?O(Z):"kill returned while process still reports alive",_(`session "${this.sessionName}": process stop unconfirmed; lifecycle blocked: ${this.blockedProcReason}`),!1}blockedProcessMessage(){let $=this.blockedProc;if(!$)return null;if(!$.isAlive())return this.detachProc($),null;return`旧 ${this.backendLabel($.provider)} 进程尚未确认退出,会话已阻断: ${this.blockedProcReason??"未知原因"}`}async stopOwnedProc($,Z){if(this.proc!==$)return!$.isAlive();this.beginProcStop($);let J=null;try{await $.kill(Z)}catch(Y){J=Y}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(W){Z=`Codex 会话落盘确认失败: ${O(W)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${O(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,a$(this.sessionName,[],{kind:"fresh"},null),this.currentGoal=null,this.cumStats={tokens:0,costUsd:0,turns:0},this.lastTurnDelta=null,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.lastTurnUsage=null,this.usageTotalsSeedUnknown=!1}async start($={}){return await this.runLifecycle("start",()=>this.startUnlocked($))}async startWithCodexAccount($,Z={}){return this.runLifecycle("hi-account",async()=>{if(y.get($),this.selectedProvider!=="codex"){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Y=H$("codex-sub",$)?.defaultModel||null;a$(this.sessionName,[],null,null),U1(this.sessionName,"codex",Y,null,"codex-sub"),this.pendingConversationMaterialization=null,this.selectedProvider="codex",this.selectedTokenSourceId="codex-sub",this.selectedModel=Y,this.selectedEffort=null,this.lastSessionRef=l0(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")U1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&F0(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${y.get($).name}」`),!0;return this.proc?.isAlive()?await this.restartUnlocked(!0,Z):await this.startUnlocked(Z)}finally{this.codexStartAccountOverride=void 0}})}async startUnlocked($={}){let Z=$.announce??!0,J=$.onStatus,Y=this.blockedProcessMessage();if(Y){if(this.status="stopped",J?.(`❌ ${Y}`),Z)await E(this.chatId,`❌ ${Y}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&this.selectedTokenSourceId!=="codex-sub"&&!b4(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,Z0({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!RX(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await E(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{l7(this.workDir)}catch(G){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${G}`),Z)await E(this.chatId,`❌ 创建项目失败: ${G}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Q;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await _2();Q=this.spawnAgent()}catch(G){let K=`${this.backendLabel()} 启动失败: ${O(G)}`;if(_(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await E(this.chatId,`❌ ${K}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let W=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,TX):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${W} 启动`:`⏳ 等待 ${W} init`);let V,X=null;try{Q.sendInitialize(),V=Q.initializationPromise?.()}catch(G){V=void 0,X=G}let z=X?{state:"error",error:X}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(V),()=>{_(`session "${this.sessionName}": codex init still pending after ${hZ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${W} init 确认`))});if(z.state==="error"||z.state==="exit"){let G=z.error?O(z.error):z.state;_(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,A=`❌ ${W} 启动失败: ${G}${B}`;if(J?.(A),Z)await E(this.chatId,A);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(z.state==="timeout"){_(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${K5/1000}s)`);let K=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${W} 启动超时: ${K5/1000} 秒内初始化事务未完成${K}`;if(J?.(B),Z)await E(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let G=`${W} 启动期间已退出`;if(_(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await E(this.chatId,`❌ ${G}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(z.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,Z0({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let G=this.modelLine();await E(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),G].filter(Boolean).join(`
204
- `))}return this.status="idle",this.startedAt=Date.now(),this.daemonRestoreRequired=!1,this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Y=!1,Q=(V,X)=>{if(Y)return;Y=!0,clearTimeout(W),clearTimeout(H),J({state:V,error:X})},W=setTimeout(()=>{if(Y)return;try{Z?.()}catch(V){Q("error",V)}},hZ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${K5/1000}s`))},K5);$.then(()=>Q("init"),(V)=>Q("error",V)),this.proc?.quotaWaitPromise?.().then(()=>Q("waiting_quota"),(V)=>Q("error",V))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(z,G)=>{if(Y)return;Y=!0,clearTimeout(W),$.off("init",H),$.off("error",V),$.off("exit",X),J({state:z,error:G})},W=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),V=(z)=>Q("error",z),X=(z)=>Q("exit",z);$.once("init",H),$.once("error",V),$.once("exit",X)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)E$($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;_(`session "${this.sessionName}": clear stale pending queue before ${$} pendingCount=${this.pendingUserMessageCount} reactions=${this.pendingReactionIds.size}`),this.pendingUserMessageCount=0;for(let[Z,J]of this.pendingReactionIds)if(J)E$(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}async stopUnlocked($="已终止",Z={}){let J=Z.announce??!0,Y=Z.onStatus;if(this.daemonRestoreRequired=!1,await this.cancelAgentRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.("⚪ session 当前未运行"),J)await E(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Q=this.proc,W=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),_(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((j)=>{_(`session "${this.sessionName}": stop current main-card close failed: ${O(j)}`)});let V=this.waitForTurnCloses().catch((j)=>_(`session "${this.sessionName}": stop main-card close failed: ${O(j)}`));this.beginProcStop(Q),this.status="stopped";let X=[];try{this.opts.onLifecycleChange?.()}catch(j){X.push(j),_(`session "${this.sessionName}": stop intent lifecycle write failed: ${O(j)}`)}let z=Q.conversationMaterializationBarrier?.();if(z){try{await z}catch(j){H=`Codex 会话落盘确认失败: ${O(j)}`}W=this.persistResumableSessionId(!1,Q,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let G=null;try{await Q.kill()}catch(j){G=j}let K=Q.conversationMaterializationFailure?.();if(K&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${O(K)}`;W=this.persistResumableSessionId(!1,Q,!1);let A=(await Promise.allSettled([this.resetBackgroundTasks(),V])).filter((j)=>j.status==="rejected").map((j)=>j.reason);for(let j of A)_(`session "${this.sessionName}": stop terminal cleanup failed: ${O(j)}`);let P=this.finishProcStop(Q,G);try{this.opts.onLifecycleChange?.()}catch(j){X.push(j),_(`session "${this.sessionName}": stop final lifecycle write failed: ${O(j)}`)}let L=[...G?[G]:[],...!P&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...A,...X,...W?[Error(W)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(L.length===1)throw L[0];if(L.length>1)throw AggregateError(L,`stop failed: ${L.map(O).join("; ")}`);if(Y?.(`✅ ${$}`),J)await E(this.chatId,`\uD83D\uDD34 ${$} (session: ${this.sessionName})`)}async restart($=!1,Z={}){return await this.runLifecycle("restart",()=>this.restartUnlocked($,Z))}requireDaemonRestore(){this.daemonRestoreRequired=!0}async restoreAfterDaemonRestart(){return await this.runLifecycle("daemon-restore",async()=>{if(this.requireDaemonRestore(),!this.lastSessionRef&&!this.pendingMaterializationLaunch())return this.status="stopped",this.opts.onLifecycleChange?.(),await E(this.chatId,"❌ daemon 重启后没有可用的恢复点。请发送 rs 选择历史会话,或 hi 明确启动新会话。"),!1;return await this.restartUnlocked(!0)})}async restartUnlocked($=!1,Z={},J){let Y=Z.announce??!0,Q=Z.onStatus,W=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,i0(this.sessionName,null),this.pendingConversationMaterialization=null;let V=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),X=this.lastSessionRef;if($&&!V&&X?.cwd===null)try{X=await this.resolveLegacyResumeRef(X),this.lastSessionRef=X,this.lastSessionId=X.sessionId}catch(S){let h=this.invalidateMissingCodexResume(X.sessionId,S,J),m=h?`❌ 旧会话不可恢复: ${O(S)};${h}`:`❌ 旧会话 cwd 校验失败: ${O(S)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?W:"stopped",Q?.(m),Y)await E(this.chatId,m);return!1}let z=X?.sessionId??null,G=V&&V.kind!=="fresh"?V.source.sessionId:z,K=G?D$(G):"",B=null,A=(S=this.proc)=>{if(!$||V||S?.provider!=="codex"||S.isConversationResumable?.()!==!0)return;B=this.persistResumableSessionId(!1,S,!1),X=this.lastSessionRef,z=X?.sessionId??null,G=z,K=G?D$(G):""},P=null;if(!Q&&Y&&$&&z){let S=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(P=await this.openStatusCard("restart",S),P)Q=(h)=>this.setStatusCard(P,h)}let L=Y&&!P,j=async(S)=>{if(P)await this.closeStatusCard(P,S)},N=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||this.backgroundTasks.length>0||this.pendingBgTasks.length>0||this.openingBackground);if(this.bgResumePending=!1,this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.discardOrphanAssistant(),this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((S)=>{_(`session "${this.sessionName}": restart current main-card close failed: ${O(S)}`)});let F=this.waitForTurnCloses().catch((S)=>_(`session "${this.sessionName}": restart main-card close failed: ${O(S)}`)),R=null,M=null;if(this.proc){let S=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(S.provider)}`),M=S,this.beginProcStop(S);let h=S.conversationMaterializationBarrier?.();if(h)try{await h}catch(p){B=`Codex 会话落盘确认失败: ${O(p)}`}if(A(S),$&&!V&&B&&!N&&S.isAlive()){if(this.stoppingProc===S)this.stoppingProc=null;this.status=W;let p=`❌ ${this.backendLabel(S.provider)} 恢复点尚未安全落盘,已保留当前进程: ${B}`;if(_(`session "${this.sessionName}": abort restart before kill: ${B}`),Q?.(p),L)await E(this.chatId,p);return await j(p),!1}try{await S.kill()}catch(p){R=p}let m=S.conversationMaterializationFailure?.();if(m&&S.isConversationResumable?.()!==!0)B=`Codex 会话落盘确认失败: ${O(m)}`;A(S)}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let C=(await Promise.allSettled([this.resetBackgroundTasks(),F])).filter((S)=>S.status==="rejected").map((S)=>S.reason);for(let S of C)_(`session "${this.sessionName}": restart terminal cleanup failed: ${O(S)}`);let v=M?this.finishProcStop(M,R):!0,b=[...R?[`kill=${O(R)}`]:[],...!v&&!R?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...C.map((S)=>`cleanup=${O(S)}`),...B?[`resume=${B}`]:[]];if(b.length>0&&H)try{i0(this.sessionName,H),this.pendingConversationMaterialization=H}catch(S){b.push(`pendingRestore=${O(S)}`)}if(b.length>0){let S=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${b.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(S),L)await E(this.chatId,S);return await j(S),!1}let c=V?.kind==="resume"||V?.kind==="fork";if($&&X||c){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let S;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await _2();S=this.spawnAgent(X??void 0)}catch(a){let G$=`❌ ${this.backendLabel()} 恢复失败: ${O(a)}`;if(_(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${O(a)}`),Q?.(G$),L)await E(this.chatId,G$);return this.status="stopped",this.opts.onLifecycleChange?.(),await j(G$),!1}this.attachProc(S);let h=this.backendLabel(),m=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(S,TX):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${h} 恢复启动`:`⏳ 等待 ${h} init 确认`);let p,D=null;try{S.sendInitialize(),p=S.initializationPromise?.()}catch(a){p=void 0,D=a}let x=D?{state:"error",error:D}:this.selectedProvider==="claude"?await m:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(p),()=>{_(`session "${this.sessionName}": codex resume init still pending after ${hZ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${h} init 确认 thread=${K}`))});if(x.state==="error"||x.state==="exit"||x.state==="timeout"){let a=x.state==="error"?this.invalidateMissingCodexResume(G,x.error,J):null,G$=[x.error?O(x.error):x.state,a].filter(Boolean).join(";");_(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${G$}`);let H9=await this.stopOwnedProc(S,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,l1=x.state==="timeout"?`❌ ${h} 恢复超时${H9}`:`❌ ${h} 恢复失败: ${G$}${H9}`;if(Q?.(l1),L)await E(this.chatId,l1);return this.status="stopped",this.opts.onLifecycleChange?.(),await j(l1),!1}if(this.proc!==S||!S.isAlive()){let a=`❌ ${h} 恢复期间已退出`;if(_(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(a),L)await E(this.chatId,a);return this.detachProc(S),this.status="stopped",this.opts.onLifecycleChange?.(),await j(a),!1}let i=this.withModel(this.withWorktreeInstructionNotice(x.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&x.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Q?.(i),L)await E(this.chatId,i);if(this.status=x.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),x.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await j(i)}catch(a){_(`session "${this.sessionName}": restart succeeded but status-card close failed: ${O(a)}`),await w(this.chatId,`⚠️ ${i}
205
- 状态卡收尾失败: ${O(a)}`)}return!0}else{if($&&!V){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),L)await E(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{K$($,this.selectedProvider,this.workDir);let J=S4(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)i0(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)i0(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{i0(this.sessionName,J),this.pendingConversationMaterialization=J}catch(W){throw AggregateError([Q,W],`fork start and pending-intent restore failed: ${O(Q)}; ${O(W)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{K$($,this.selectedProvider,this.workDir);let Y=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Q=this.proc,W=this.lastSessionId,H=this.lastSessionRef,V=N4(this.sessionName).slice(),X=E4(this.sessionName),z=S4(this.sessionName),G={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,B=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,D2(this.sessionName,"codex");else if(this.lastSessionId=W,this.lastSessionRef=H,H)T4(this.sessionName,H);else D2(this.sessionName,this.selectedProvider);a$(this.sessionName,V,X,z),this.pendingConversationMaterialization=z,this.turnCounter=G.turnCounter,this.currentGoal=G.currentGoal,this.cumStats=G.cumStats,this.lastTurnDelta=G.lastTurnDelta,this.currentTurnUsageBaseline=G.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=G.currentTurnUsageBaselineKnown,this.lastTurnUsage=G.lastTurnUsage,this.usageTotalsSeedUnknown=G.usageTotalsSeedUnknown},A=!1;if(Y?.pendingLaunch)a$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,A=!0;this.pendingConversationLaunch=$;let P=(L)=>{K=H?.provider==="codex"&&H.sessionId===L};try{let L;try{L=$.kind==="fresh"?await this.restartUnlocked(!1,J,P):await this.restartUnlocked(!0,J,P)}catch(j){let N=null,F=this.proc&&this.proc!==Q?this.proc:null;if(F)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(C){N=C}let R=!F||this.proc!==F&&!F.isAlive();if(!R&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(R)try{B()}catch(C){M=C}let k=[j,...N?[N]:[],...M?[M]:[]];if(k.length===1)throw j;throw AggregateError(k,`rollback launch and cleanup failed: ${k.map(O).join("; ")}`)}if(!L)return B(),!1;if(Y)try{if(!A)a$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(j){let N=null,F=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(C){N=C}let R=!F||this.proc!==F&&!F.isAlive();if(!R&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(R)try{B()}catch(C){M=C}let k=[j,...N?[N]:[],...M?[M]:[]];if(k.length===1)throw j;throw AggregateError(k,`rollback branch commit failed: ${k.map(O).join("; ")}`)}return L}finally{this.pendingConversationLaunch=null}})}dispose(){Q0.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Y=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return _(`session "${this.sessionName}": ${Y}`),this.lastTurnUserPreview="",Y}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Q)=>Q.proc===Z).length>=64)return _(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),_(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return k7(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${O(Z)}`;return _(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Y of this.pendingCodexTurnAnchors){if(Y.proc!==$||Z){J.push(Y);continue}if(Z=this.appendTurnAnchor(Y.anchor),Z)J.push(Y)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Q)=>Q.proc!==$);let Y=J-this.pendingCodexTurnAnchors.length;if(Y>0)_(`session "${this.sessionName}": dropped ${Y} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...R3(J.name,J.input));return Z}worktreeProjectName(){return Y1(this)}worktreeProjectDir(){return I2(this)}spawnDeveloperInstructions(){return ZX(this)}delegatedAgentDeveloperInstructions($){return JX(this,$)}worktreeInstructionLoadedNotice(){return bZ(this)}withWorktreeInstructionNotice($){return YX(this,$)}worktreeExtraInstruction(){return Z9(this)}runWorktreeCommand($,Z){return QX(this,$,Z)}showWorktrees(){return yZ(this)}showTasklistPanel(){return yV(this)}showAgentIdentityPanel($=""){return OV(this,$)}onAgentIdentityPage($,Z,J){return TV($,Z,J)}onTasklistEnable(){return wV(this)}onTasklistDeletePrompt($){return fV(this,$)}onTasklistDeleteConfirm($){return vV(this,$)}runCompactCommand(){return KV(this)}showModelPanel(){return AV(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>FV(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>DZ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return jZ(this,$,Z)}onModelPage($,Z,J){return $5(this,$,Z,J)}onModelAddOpen($,Z){return qV(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>PV(this,$,Z,J,Y))}onModelPanelCancel($=""){return DV(this,$)}onModelCustomPrompt($,Z,J=""){return LV(this,$,Z,J)}consumeModelCustomMessage($,Z){return jV(this,$,Z)}onWorktreeDisband($){return HX(this,$)}showForkList($=""){return BX(this,$)}showBackList($=""){return AX(this,$)}showResumeList($=""){return qX(this,$)}runBtwCommand($){return PX(this,$)}runByeCommand(){return LX(this)}onForkSelect($,Z,J=""){return jX(this,$,Z,J)}onBackSelect($,Z,J=""){return DX(this,$,Z,J)}onResumeSelect($,Z,J=""){return MX(this,$,Z,J)}runCommand($,Z=""){return GV(this,$,Z)}async buildConsoleOpts($,Z){let J=await zQ(),Y=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Y.provider,model:Y.model??void 0,effort:Y.effort??"MISS",worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...Q0.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return W7(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Y=this.currentTokenSource(),Q=Y&&Y.agent===J&&Y.enabled?Y:this.selectedTokenSourceId?void 0:m9(J)[0];if(Q)Z.unifiedUsage=await Q.readUsage();else if(this.selectedTokenSourceId)Z.unifiedUsage={state:"no_credentials",windows:[],reason:`token source ${this.selectedTokenSourceId} unavailable`};else if(Z.provider==="claude")Z.glmUsage=await oW();else Z.usage=await j1(this.codexAccountId());if(!await z$($,U.consoleUsage,D4(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(W){Y=!1,_(`session "${this.sessionName}": ${Z} mutation failed: ${O(W)}`)}let Q=!1;try{Q=await P$($,{config:{streaming_mode:!1}})}catch(W){_(`session "${this.sessionName}": ${Z} streaming-off failed: ${O(W)}`)}if(!Y||!Q)return _(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await b$($)}catch(W){return _(`session "${this.sessionName}": ${Z} dispose failed: ${O(W)}`),!1}return Y}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Y=await this.buildConsoleOpts(void 0);await r$($.cardId);let Q=await z$($.cardId,U.footer,d9(Y,U.footer)),W=await n0($.cardId,i9(Y),{type:"insert_after",targetElementId:U.footer}),H=await n0($.cardId,n9(Y.sysinfo),{type:"insert_after",targetElementId:U.consoleProjects}),V=await n0($.cardId,D4(Y),{type:"insert_after",targetElementId:U.consoleHost});if(!Q||!W||!H||!V){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}M$($.cardId),await P$($.cardId,U0({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await u(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await o$(Z),c$(J,4)}catch(Y){_(`session "${this.sessionName}": console card conversion failed: ${O(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>_(`session "${this.sessionName}": console async update rejected: ${O(J)}`))}interrupt(){if(!this.proc)return;_(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){this.pendingUserMessageCount++;try{$.sendUserText(Z,[])}catch(J){throw this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),J}}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Y=this.beginTurnOpen();try{let W=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!W||this.currentTurn!==W)return;let H=this.startFooterTimer(W.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),V=`\uD83D\uDE80 启动 ${this.backendLabel()}`,X=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{V=G,H.setStatus(G)}});if(H.stop(),await r$(W.cardId),!X){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(V.startsWith("❌")?V:"❌ 启动失败",{forcePush:!0});return}let z=this.proc;if(!z?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(W),this.sendClaimedUserText(z,Z),this.status="working"}finally{this.releaseTurnOpen(Y)}}async onUserMessage($,Z=[],J="",Y=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Y))}async onUserMessageUnlocked($,Z,J,Y){let Q=this.blockedProcessMessage();if(Q){await E(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await E(this.chatId,"❌ daemon 重启后的会话恢复尚未成功,这条消息未送给 Agent。请发送 rs 选择历史会话,或 hi 明确启动新会话,然后重发消息。");return}if(this.clearStaleIdleQueueState("user_message"),this.proc?.isAlive()&&!this.currentTurn&&!this.openingTurn&&this.pendingUserMessageCount===0&&this.pendingMidTurnMsgs.length===0)await this.stopIdleMismatchedProcessUnlocked();let W=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let V=(Z.length?Z.map((z)=>`[file: ${z}]`).join(" ")+`
206
- `:"")+$,X=(z)=>{this.pendingReactionIds.set(z,""),(async()=>{let G=await m$(z,"OneSecond");if(!G)return;if(this.pendingReactionIds.has(z))this.pendingReactionIds.set(z,G);else if(this.currentBatchReactionIds.has(z))this.currentBatchReactionIds.set(z,G);else E$(z,G)})().catch((G)=>{_(`session "${this.sessionName}": reaction tracking failed: ${O(G)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)X(Y);return}await this.startColdUserTurn($,V,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)X(Y);return}if(!this.openingTurn&&this.initCount>=1){let z=this.proc,G=this.procEpoch,K=this.beginTurnOpen(z,G);try{this.pendingTurnInputs.push($);let B=await this.openTurnCard(K,J,"user_message");if(!B||this.currentTurn!==B)return;if(this.proc!==z||this.procEpoch!==G||!z.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(z.provider)} 已退出`);return}this.sendClaimedUserText(z,V),this.status="working"}finally{this.releaseTurnOpen(K)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)X(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,V),W&&Y)X(Y)}hasPendingAsk(){return UH(this)}refreshPendingAsks(){u8(this)}askBlockReason($){return k2(this,$)}onMultiMessageInbound($,Z,J,Y){return ZH(this,$,Z,J,Y)}clearMultiMsgBuffer($){v3(this,$)}onAskMessageAnswer($,Z,J){return OH(this,$,Z,J)}onAskAnswer($,Z,J,Y){return TH(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return n3(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return CH(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=l0(this.sessionName,"codex");if(D2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)_(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=IZ(Z);if(!Y||!["thread/read","thread/resume","thread/fork"].includes(Y.method)||Y.serverCode!==-32600||Y.serverMessage!==`no rollout found for thread id ${$}`)return null;let Q=l0(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{D2(this.sessionName,"codex")}catch(H){let V=`已确认恢复点无 rollout,但作废失败: ${O(H)}`;return _(`session "${this.sessionName}": ${V} thread=${$}`),V}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let W=`已作废无 rollout 的恢复点 thread=${D$($)}`;return _(`session "${this.sessionName}": ${W} fullThread=${$}`),W}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Y=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Q=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Q){if(!Y)return null;let V=Error("Claude pending fork did not provide a materialized session id");if(_(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}let W={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let V=Error(`Claude fork did not materialize an independent session id (${Q})`);if(_(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}try{T4(this.sessionName,W)}catch(V){let X=`会话恢复点持久化失败: ${O(V)}`,z=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;if(_(`session "${this.sessionName}": ${X}`),$)throw V;if(z&&J)w(this.chatId,`⚠️ ${X};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return X}if(Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let V=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(V&&J)w(this.chatId,`⚠️ ${H}`);return H}return this.resumePersistenceError=null,null}consumePendingConversationMaterialization(){let $=this.pendingConversationMaterialization;if(!$)return null;let Z=this.lastSessionRef;if(Z?.provider!=="claude"||Z.cwd!==this.workDir||Z.sessionId===$.launch.source.sessionId||Z.sessionId===$.previousSessionId)return _(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return i0(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${O(J)}`;return _(`session "${this.sessionName}": ${Y}`),Y}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(x6(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}onBackgroundTaskChanged(){if(this.migratingBackgroundCard){this.pendingRebuildBackgroundCard=!0;return}if(!P1(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{_(`session "${this.sessionName}": background settle failed: ${O(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{_(`session "${this.sessionName}": background open failed: ${O(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=f6(Z,Date.now(),m1()),Y=await u(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))_(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await o$(Y)}catch(W){_(`session "${this.sessionName}": background card id_convert failed: ${W}`);return}if(c$(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((W)=>W.id)),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!P1(this.backgroundTasks)){this.settleBackgroundCard().catch((W)=>{_(`session "${this.sessionName}": background settle-after-open failed: ${O(W)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!P1(this.backgroundTasks))return;let Z=m1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(n$(Q))continue;let W=m0(J-Q.startedAt,Z).nextDelayMs;if(W<Y)Y=W}if(!isFinite(Y))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Y)))};$()}stopBackgroundRefreshTick(){if(this.backgroundRefreshTick)clearTimeout(this.backgroundRefreshTick),this.backgroundRefreshTick=null}scheduleBackgroundRefresh(){if(!this.backgroundCard||this.settlingBackgroundCard||this.migratingBackgroundCard)return;if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull()},1500)}refreshBackgroundCardFull(){if(this.migratingBackgroundCard)return;let $=this.backgroundCard;if(!$)return;let Z=Date.now(),J=m1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),n0($.cardId,Y2(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else _(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else Z$($.cardId,Q4.panel(Y.id),Y2(Y,Z,J));E0($.cardId,x9(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!n$($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>n$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$})}if(this.pendingBgTasks=[],this.backgroundCard)await this.settleBackgroundCard();if(this.stopBackgroundRefreshTick(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.backgroundTasks=[],this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear()}async settleBackgroundCard(){if(this.migratingBackgroundCard)try{await this.migratingBackgroundCard}catch(J){_(`session "${this.sessionName}": background migration failed before settle; retry terminal snapshot: ${O(J)}`)}let $=this.backgroundCard;if(!$||this.settlingBackgroundCard)return;this.settlingBackgroundCard=!0;let Z=[...this.backgroundTasks];if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.stopBackgroundRefreshTick();try{if(await r$($.cardId),await B0($.messageId,C9(Z)),M$($.cardId),!await P$($.cardId,U0({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await b$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!n$(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&P1(this.backgroundTasks))this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(this.backgroundTasks.length>0)this.onBackgroundTaskChanged()}migrateBackgroundCard(){if(this.migratingBackgroundCard)return this.migratingBackgroundCard;let $=this.backgroundCard;if(!$)return Promise.resolve();let Z=this.performBackgroundCardMigration($),J;return J=Z.finally(()=>{if(this.migratingBackgroundCard===J)this.migratingBackgroundCard=null}),this.migratingBackgroundCard=J,J}async performBackgroundCardMigration($){if(this.backgroundCard!==$)return;if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;if(this.stopBackgroundRefreshTick(),await r$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(n$).map((W)=>W.id)),Y=J.size;if(Y>0)await B0($.messageId,C9(Z));else await B0($.messageId,v6());if(M$($.cardId),!await P$($.cardId,U0({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await b$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((W)=>!J.has(W.id)||!n$(W)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Y} active=${this.backgroundTasks.length}`)}startScheduledTurnCard($,Z,J,Y){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Q;try{Q=this.beginTurnOpen($,Z,!0)}catch(H){_(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${O(H)}`);return}let W=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${W.slice(0,78)}`,_(`session "${this.sessionName}": scheduled wakeup prompt=${Y??"MISS"}`),(async()=>{try{let H=await this.openTurnCard(Q,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(_(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),H&&this.currentTurn===H)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!H||this.currentTurn!==H){if(!this.ownsTurnOpen(Q))return;if(this.bgResumeCardless=!0,Q.sawResult)Q.sawResult=!1,_(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else _(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,_(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Q.terminalSuffix,{forcePush:Q.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Q)}})().catch((H)=>{_(`session "${this.sessionName}": scheduled turn-open handler failed: ${O(H)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Y=()=>this.proc===$&&this.procEpoch===J,Q=!1,W=!1,H=(V,X)=>{$.on(V,(z)=>{if(!Y()){if(!Q)Q=!0,_(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(V)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(V!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!W)W=!0,_(`session "${this.sessionName}": ignore ${$.provider} event=${String(V)} while process stop is pending`);return}X(z)})};H("error",(V)=>{_(`session "${this.sessionName}": ${$.provider} process error: ${V}`)}),H("init",()=>{if($.provider==="codex"&&$.quotaWaitPromise){if(this.daemonRestoreRequired=!1,this.status==="starting")this.status=this.currentTurn?"working":"idle";this.opts.onLifecycleChange?.()}if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,_(`session "${this.sessionName}": SDK init#${this.initCount} pendingCount=${this.pendingUserMessageCount} midBuffer=${this.pendingMidTurnMsgs.length} currentTurn=${this.currentTurn?"yes":"no"} openingTurn=${this.openingTurn}`),this.currentTurn||this.openingTurn){if(this.pendingUserMessageCount>0)_(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let V=this.pendingUserMessageCount>0,X=!V&&this.bgResumePending;if(!V&&!X)return;let z=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(A){_(`session "${this.sessionName}": init turn-open ownership conflict: ${O(A)}`);return}if(this.bgResumePending=!1,V)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=V?[...this.currentBatchReactionIds.keys()]:[],B=()=>{for(let A of K){let P=this.currentBatchReactionIds.get(A);if(this.currentBatchReactionIds.delete(A),P)E$(A,P)}};(async()=>{try{let A=await this.openTurnCard(G,z,V?"user_message":"bg_task_resume");if(!Y()){if(_(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),A&&this.currentTurn===A)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);B();return}if(!A||this.currentTurn!==A){if(!this.ownsTurnOpen(G)){B();return}if(G.sawResult&&G.terminalSuffix)w(this.chatId,G.terminalSuffix);if(V)_(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),B();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,_(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else _(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,_(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(G.terminalSuffix,{forcePush:G.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(G)}})().catch((A)=>{_(`session "${this.sessionName}": init turn-open handler failed: ${O(A)}`)})}),H("scheduled_turn_input",({text:V,promptId:X})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,V,X)}),H("conversation_materialized",({session_id:V,source:X})=>{if($.provider!=="codex")return;if($.sessionId!==V){_(`session "${this.sessionName}": ignore mismatched Codex materialization session=${V} current=${$.sessionId??"MISS"} source=${X}`);return}_(`session "${this.sessionName}": Codex resume point materialized thread=${V} source=${X}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:V,source:X,error:z})=>{if($.provider!=="codex"||$.sessionId!==V)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${O(z)}`,K=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,_(`session "${this.sessionName}": ${G} thread=${V} source=${X}`),K)w(this.chatId,`⚠️ ${G}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("codex_account_changed",({accountId:V,diagnostics:X})=>{if(_(`session "${this.sessionName}": Codex account=${V}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),X.length)u(this.chatId,Z0({phase:"warning",title:"部分账号 MISS",message:`${X.length} 个账号未参与选择`,details:X.join(`
207
- `),hint:"详情:codex-accounts"})).catch((z)=>{_(`session "${this.sessionName}": 账号诊断卡失败: ${O(z)}`)})}),H("turn_started",({retry:V})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)_(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),V){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let X=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!X){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=X?{...X}:null,this.currentTurnUsageBaselineKnown=!0}),H("token_usage",({totalUsage:V})=>{if(this.persistResumableSessionId(),V)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(V)=>{this.handleTurnPlanUpdated(V)}),H("plan_delta",(V)=>{this.handlePlanDelta(V)}),H("context_compacted",(V)=>{this.handleContextCompacted(V)}),H("rate_limits_updated",(V)=>{if($.provider==="codex")tY(V,F0($))}),H("thread_goal_updated",(V)=>{this.handleThreadGoalUpdated(V)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:V,parentToolUseId:X})=>{if(X)return;this.appendAssistant(V)}),H("assistant_block_stop",({parentToolUseId:V})=>{if(V)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:V,name:X,input:z,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(b6({active:this.backgroundTasks,pending:this.pendingBgTasks},G,V,X,z)),this.onBackgroundTaskChanged();return}if(SH(this,V,X,z),!G)this.onMainThreadAdvance();if(!G&&(X==="Task"||X==="Agent"))this.lastMainTaskToolUseId=V}),H("tool_result",({tool_use_id:V,content:X,is_error:z,parentToolUseId:G,input:K})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(w6({active:this.backgroundTasks,pending:this.pendingBgTasks},G,V,X,z)),this.onBackgroundTaskChanged();return}kH(this,V,X,z,K)}),H("can_use_tool",(V)=>{bH(this,V)}),H("hook_callback",(V)=>{this.proc?.sendHookResponse(V.request_id,{})}),H("result",(V)=>{let X=this.persistResumableSessionId(),z=X?null:this.consumePendingConversationMaterialization(),G=[X,z].filter(Boolean).join(";")||null;if(this.accumulateResultStats(),this.openingTurnOwner)this.openingTurnOwner.sawResult=!0;if(this.userInterrupted){this.userInterrupted=!1,this.discardOrphanAssistant(),this.bgResumePending=!1;let M=this.proc?.lastResult.subtype??"unknown",k=this.proc?.lastResult.is_error===!0;_(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${k} — ignored`),this.status="idle";return}let K=V?.is_error!==!0?this.recordTurnAnchor(V?.checkpoint):null;if(V?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let B=this.pendingMidTurnMsgs.length>0,A=this.proc?.lastResult.is_error===!0,P=this.proc?.lastResult.subtype??"success",L=typeof V?.error==="string"&&V.error.trim()?V.error.trim():P,j,N=!1,F=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),R=[G,K].filter(Boolean).join(";")||null;if(R)j=`⚠️ ${R}`,N=!0;else if(B)j=A?`⚠️ ${F} ${L},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(A)j=`⚠️ ${F} ${L}`,N=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=j,this.openingTurnOwner.terminalForcePush=N;if(R&&!this.currentTurn&&!this.openingTurn)w(this.chatId,`⚠️ ${R}`);if(_(`session "${this.sessionName}": SDK result subtype=${P} isError=${A} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${N}`),this.closeTurnCard(j,{forcePush:N,hasFreshResult:!0}).catch((M)=>{_(`session "${this.sessionName}": result card close failed: ${O(M)}`)}),this.status="idle",B)this.drainMidTurnAndOpen().catch((M)=>{_(`session "${this.sessionName}": mid-turn drain failed: ${O(M)}`)})}),H("bg_task_started",(V)=>{let X=V.tool_use_id??this.lastMainTaskToolUseId??void 0;_(`session "${this.sessionName}": bg_task_started task=${V.task_id} type=${V.task_type??"-"} subagent=${V.subagent_type??"-"} toolUseId=${X?.slice(0,8)??"-"} desc=${(V.description??"").slice(0,40)}`),this.applyBgStore(E6(this.bgStore(),{...V,tool_use_id:X})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(V)=>{this.applyBgStore(S6(this.bgStore(),V)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(V)=>{this.applyBgStore(k6(this.bgStore(),V)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(V)=>{if(_(`session "${this.sessionName}": bg_task_settled task=${V.task_id} status=${V.status}`),this.applyBgStore(C6(this.bgStore(),V)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(V)=>{this.applyBgStore(y6(this.bgStore(),V.thread_id,V.item_id,V.tool,V.phase,V.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:V,signal:X,expected:z})=>{if(_(`session "${this.sessionName}": ${$.provider} exited code=${V} signal=${X} expected=${z}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let P=$.conversationMaterializationFailure?.(),L=this.persistResumableSessionId(!1,$,!1),j=[P&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${O(P)}`:null,L].filter(Boolean).join(";");if(j)w(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${j}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}_(`session "${this.sessionName}": blocked/stopping ${$.provider} exit confirmed`),this.detachProc($),this.status="stopped",this.opts.onLifecycleChange?.();return}this.discardPendingCodexTurnAnchors($,"unexpected process exit"),this.cancelAgentRuns(`${$.provider} process exited`).catch((P)=>{_(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${O(P)}`)});let G=this.backendLabel($.provider),K=`code=${V??"null"}, signal=${X??"null"}`,B=z?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(B).catch((P)=>{_(`session "${this.sessionName}": process-exit current main-card close failed: ${O(P)}`)});let A=this.waitForTurnCloses().catch((P)=>{_(`session "${this.sessionName}": process-exit main-card close failed: ${O(P)}`)});this.detachProc($),this.flushOrphanAssistantToChat("process exit"),this.bgResumePending=!1,this.bgResumeCardless=!1,this.clearMultiMsgBuffer("process exit"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.userInterrupted=!1,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped",this.opts.onLifecycleChange?.(),this.runLifecycle("process-exit-cleanup",async()=>{let P=await Promise.allSettled([A,this.resetBackgroundTasks()]);for(let L of P)if(L.status==="rejected")_(`session "${this.sessionName}": process-exit terminal cleanup failed: ${O(L.reason)}`);if(!z)await E(this.chatId,`⚠️ ${G} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((P)=>{_(`session "${this.sessionName}": process-exit cleanup rejected: ${O(P)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?W6(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=H6(Z),Y=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Q=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Y,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Y,durationMs:Q}}currentContextTokens($=this.proc){if($?.provider==="claude"||$?.provider==="dsh")return $.lastContextTokens??null;let Z=$?.lastUsage;return A8(Z)}contextLimitForDisplay($=this.proc){return q8($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;if(!await this.waitForTurnOpenSlot($,Z))return;if(this.currentTurn||this.openingTurn||this.pendingMidTurnMsgs.length===0)return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){_(`session "${this.sessionName}": mid-turn open ownership conflict: ${O(Q)}`);return}let Y=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let X of Y)if(this.pendingTurnInputs.push(X.text),X.msgId){let z=this.pendingReactionIds.get(X.msgId)??"";this.currentBatchReactionIds.set(X.msgId,z),this.pendingReactionIds.delete(X.msgId)}let Q=Y.map((X)=>X.wireText).join(`
208
-
209
- `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,V=await this.openTurnCard(J,H,"user_message");if(!V||this.currentTurn!==V){for(let X of Y){if(!X.msgId)continue;let z=this.currentBatchReactionIds.get(X.msgId);if(this.currentBatchReactionIds.delete(X.msgId),z)E$(X.msgId,z)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let X of Y){if(!X.msgId)continue;let z=this.currentBatchReactionIds.get(X.msgId);if(this.currentBatchReactionIds.delete(X.msgId),z)E$(X.msgId,z)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(X){_(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${X}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await w(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${O(X)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Y=J?await z$($,U.footer,this.footerElement(Z)):!0;M$($);let Q=await P$($,U0({suffix:Z}));if(Y&&Q){await b$($);return}let W=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;_(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${W}`),await w(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${W})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{_(`session "${this.sessionName}": background rebuild after turn-open failure failed: ${O($)}`)})}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&P1(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(P){_(`session "${this.sessionName}": background migrate failed (non-blocking): ${P}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,W=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=W[0]?.slice(0,80)??this.lastTurnUserPreview,_(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${W.length}`);let H=this.runtimeModelSelection(),V=this.withModel(Y.initialFooter??"Waiting...(0s)",H),X=D8({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort??"MISS",kind:J,userInputs:W,initialFooter:V,directStart:Y.directStart}),z=await u(this.chatId,X);if(!z){if(!this.ownsTurnOpen($))return null;if(_(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await w(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return this.rebuildBackgroundAfterTurnOpenFailure(),null}let G;try{G=await o$(z)}catch(P){if(_(`session "${this.sessionName}": id_convert failed: ${P}`),J==="user_message"&&this.ownsTurnOpen($))await w(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let K=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(W.length>0?1:0)+1;if(!this.ownsTurnOpen($))return c$(G,K),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let B={cardId:G,...H,messageId:z,userOpenId:Z,trigger:J,toolCount:0,toolByUseId:new Map,planSteps:[],planExplanation:null,planUpdateCount:0,goalUpdateCount:0,contextCompactCount:0,contextCompactionPending:new Map,contextCompactionCompleted:new Set,contextCompactionCompleting:new Set,contextCompactionEndOnly:new Map,lastContextCompactionCompletedAt:0,lastContextCompactionWasAnonymous:!1,toolBatches:new Map,openBatchI:null,taskCreateI:null,taskUpdateI:null,taskBoardResetThisTurn:!1,taskLiveInserted:!1,planLiveInserted:!1,assistantSegmentCount:0,currentAssistantSegmentId:null,currentAssistantText:"",segmentTexts:new Map,startedAt:Date.now(),footerStatusHandle:null,footerStatusStartedAt:0,footerStatusLabel:null,rotating:null,rotateCount:0,failureRotateCount:0,cardCapacityFailures:new Map,cardWriteFailureNotices:new Set,cardRotationFailed:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(c$(G,K,(P,L)=>{this.onCardWriteFailure(B,G,P,L)}),this.currentTurn=B,Y.startThinking!==!1)this.startThinkingFooter(B);if($.pendingCompactions.length>0){let P=$.pendingCompactions.splice(0);_(`session "${this.sessionName}": replay ${P.length} context compaction event(s) buffered during card open`);for(let L of P)this.handleContextCompacted(L)}let A=this.takeOrphanAssistantText();if(A)this.appendAssistant(A),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((P)=>{_(`session "${this.sessionName}": background rebuild failed: ${O(P)}`)})}return B}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&n7($.cardId)<nL)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){_(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){_(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Q.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Q.rotating)return;if(Q.cardRotationFailed)return;if(!d7(J,Y)){let H=Y?.operation??"unknown operation",V=Y?.elementId?` element=${Y.elementId}`:"";_(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${V} code=${J??"n/a"} — not rotating`);let X=`${Z}:${H}:${Y?.elementId??""}:${J??"MISS"}`;if(!Q.cardWriteFailureNotices.has(X))Q.cardWriteFailureNotices.add(X),w(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H}${V})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let W=Y?.capacityFingerprint;if(W){let H=Q.cardCapacityFailures.get(W);if(H!==void 0){if(_(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Y.operation} element=${Y.elementId??"MISS"} code=${J??"MISS"}`),!H)Q.cardCapacityFailures.set(W,!0),w(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(W,!1)}_(`session "${this.sessionName}": confirmed card capacity limit (${J}) on card=${Q.cardId.slice(0,8)}… — rotating to fresh card`),Q.failureRotateCount++,this.startMidTurnRotate(Q)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Y}=$,Q={value:null},W=(H,V)=>{if(!Q.value)Q.value={code:H,failure:V}};$.rotating=(async()=>{try{_(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${n7(Z)}`);let H=D8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),V=await u(this.chatId,H);if(!V){if(_(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await w(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let X;try{X=await o$(V)}catch(L){if(_(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${L}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await w(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}c$(X,2,(L,j)=>{if($.rotating){W(L,j);return}this.onCardWriteFailure($,X,L,j)});let z=$.assistantWriteInflight?.get(Z);if(z?.size)await Promise.allSettled([...z]);this.stopFooterStatus($),$.cardId=X,$.cardRotationFailed=!1,$.messageId=V,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,K=$.currentAssistantText??"",B=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&K){let L=U.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=L,$.currentAssistantText=K,$.segmentTexts.set(L,K)}if(K)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)j$($.cardId,C1(this.taskBoard),{type:"insert_before",targetElementId:U.footer});if($.planLiveInserted)j$($.cardId,w4($.planSteps,$.planExplanation,U.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?U.taskBoardLive:U.footer});for(let L of $.contextCompactionPending.values()){if(L.cardId!==Z)continue;L.cardId=X,L.created=!1,L.createFailure=void 0;let j=U.contextCompact(L.i);L.createPromise=K8(X,y4(L.i,L.notice,j),{type:"insert_before",targetElementId:F$($)}).then((N)=>{if(L.cardId===X)L.created=N.landed,L.createFailure=N.failure;return N.landed})}for(let[L,j]of B){if(G&&K&&L===G)continue;if(!F2(Z,L))continue;let N=$.assistantSegmentCount++,F=U.assistant(N);$.segmentTexts.set(F,j),await this.addCompletedAssistantSegment($,F,j)}r3(this,Z,X,J,Y,$),await r$(Z),r3(this,Z,X,J,Y,$);let A=new Set([U.taskBoardLive,U.planLive,...[...$.contextCompactionPending.values()].map((L)=>U.contextCompact(L.i))]);if(G)A.add(G);for(let L of J.values())if(L.output==null)A.add(U.tool(L.i));if(dQ(Z).some((L)=>!A.has(L)))$.cardCapacityFailures.clear();await r$(X);try{await o3($,Z);let L=$.mathRenderInflight?.get(Z);if(L?.size)await Promise.allSettled([...L]);await r$(Z);let j=$.mathRendered?.get(Z);for(let[M,k]of B){if(G&&K&&M===G)continue;if(F2(Z,M))continue;if(j?.has(M))continue;await Z$(Z,M,this.completedAssistantElement(M,k))}let N=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",F=await z$(Z,U.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${N}`)),{notifyCardFailure:!1});M$(Z);let R=await P$(Z,U0({suffix:"\uD83D\uDCE8 转下一张"}));if(F&&R)await b$(Z);else _(`session "${this.sessionName}": rotate old-card terminal MISS footer=${F} settings=${R}`),await w(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${F?"ok":"MISS"}, settings=${R?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(L){_(`session "${this.sessionName}": mid-turn rotate close-old failed: ${L}`)}_(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${X.slice(0,8)}…`)}finally{$.rotating=null;let H=Q.value;if(H&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,H.code,H.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=U.planUpdate($.planUpdateCount++);j$(Z,e7($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:F$($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=U.goalUpdate(Z.goalUpdateCount++);j$(Z.cardId,$3($,J),{type:"insert_before",targetElementId:F$(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=U.goalUpdate($.goalUpdateCount++);j$($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
210
-
211
- 已清除`},{type:"insert_before",targetElementId:F$($)})}handleContextCompacted($){let Z=UX($);if(this.manualContextCompactionPending){if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");if($.phase!=="start")this.lastManualContextCompactionCompletedAt=Date.now(),this.lastManualContextCompactionWasAnonymous=Z.length===0;_(`session "${this.sessionName}": manual context compaction ${$.phase??"event"} handled by command status card`);return}if($.phase==="start")this.lastManualContextCompactionWasAnonymous=!1;else if((Z.length===0||this.lastManualContextCompactionWasAnonymous)&&Date.now()-this.lastManualContextCompactionCompletedAt<B5){_(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((F)=>F.startsWith("turn:")),W=Y??Q,H=W?this.contextCompactionReceipts.get(W):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let F=this.contextCompactionReceipts.get(Q);if(!F?.hasItemAlias&&F?.completed&&Date.now()-F.completedAt<B5||!F?.hasItemAlias&&F?.completionKey&&J?.contextCompactionCompleting.has(F.completionKey))W=Q,H=F,F.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,F)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),_(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");_(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(W&&H?.completed){_(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${W}`);return}let V=this.contextCompactionOwnerId(J);if(W&&H&&H.ownerId!==V){this.rememberContextCompactionReceipt(Z,null,!0),_(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${W} (turn owner changed)`);return}if(W&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){_(`session "${this.sessionName}": context compaction alias already writing receipt=${W}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){_(`session "${this.sessionName}": identified context compaction duplicate ignored while anonymous completion writes`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.lastContextCompactionWasAnonymous&&Date.now()-J.lastContextCompactionCompletedAt<B5){_(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let F=uL($);if(J.contextCompactionPending.has(F)||J.contextCompactionCompleted.has(F)){_(`session "${this.sessionName}": duplicate context compaction start ignored key=${F}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,V,!1);let R=J.contextCompactCount++,M=J.cardId,k=U.contextCompact(R),C={i:R,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};C.createPromise=K8(M,y4(R,$,k),{type:"insert_before",targetElementId:F$(J)}).then((v)=>{if(C.cardId===M)C.created=v.landed,C.createFailure=v.failure;return v.landed}),J.contextCompactionPending.set(F,C),_(`session "${this.sessionName}": context compaction start #${R+1} key=${F}`),E0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){_(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<B5){_(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let X=$.itemId||$.turnId;if(X&&J.contextCompactionCompleted.has(X)){_(`session "${this.sessionName}": duplicate context compaction completion ignored key=${X}`);return}let z=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:pL(J),G=z?J.contextCompactionPending.get(z):void 0,K=z??X??"__anonymous__";if(J.contextCompactionCompleting.has(K)){_(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let B=lL(G?.notice,$),A=J.contextCompactionEndOnly.get(K),P=G?.i??A??J.contextCompactCount++;if(!G&&A===void 0)J.contextCompactionEndOnly.set(K,P);J.contextCompactionCompleting.add(K);let L=[...new Set([...UX(G?.notice??{}),...Z])];if(L.length>0)this.rememberContextCompactionReceipt(L,V,!1,K);let j=U.contextCompact(P),N=y4(P,B,j);_(`session "${this.sessionName}": context compaction completion write #${P+1} key=${K}`),(async()=>{let F=!1;if(!G)while(!0){let R=J.cardId;if(F=await n0(R,N,{type:"insert_before",targetElementId:F$(J)}),F)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==R)continue;break}else while(!0){let R=G.cardId;if(await G.createPromise,G.cardId!==R)continue;if(G.created)F=await z$(R,j,N);else{if(iQ(G.createFailure?.code,G.createFailure))nQ(R,j),F=await z$(R,j,N,{notifyCardFailure:!1});if(!F)F=await n0(R,N,{type:"insert_before",targetElementId:F$(J)})}if(G.cardId!==R)continue;if(F){G.created=!0;break}let M=J.rotating;if(M){await M;continue}if(G.cardId!==R)continue;break}if(J.contextCompactionCompleting.delete(K),!F){_(`session "${this.sessionName}": context compaction completion write MISS #${P+1} key=${K}`);return}if(z&&J.contextCompactionPending.get(z)===G)J.contextCompactionPending.delete(z);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",L.length>0){let R=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===K).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...L,...R])],null,!0)}_(`session "${this.sessionName}": context compaction completed #${P+1} key=${K}`)})().catch((F)=>{J.contextCompactionCompleting.delete(K),_(`session "${this.sessionName}": context compaction completion transaction failed: ${O(F)}`)}),E0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Y){let Q={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Y?{}:{completionKey:Y},hasItemAlias:$.some((W)=>W.startsWith("item:"))};for(let W of $)this.contextCompactionReceipts.delete(W),this.contextCompactionReceipts.set(W,Q);while(this.contextCompactionReceipts.size>aL){let W;for(let H of this.contextCompactionReceipts.values()){if(H.completed){W=H;break}W??=H}if(!W)break;for(let[H,V]of this.contextCompactionReceipts)if(V===W)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){_(`session "${this.sessionName}": turn/plan/updated with no current turn`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openBatchI=null,!Array.isArray($.plan))_(`session "${this.sessionName}": turn/plan/updated missing plan array`),Z.planSteps=[];else Z.planSteps=$.plan.map((J)=>({step:typeof J.step==="string"&&J.step?J.step:"MISS",status:typeof J.status==="string"&&J.status?J.status:"MISS"}));if(Z.planExplanation=typeof $.explanation==="string"?$.explanation:null,Z.planSteps.length>0)if(!Z.planLiveInserted){let J=Z.taskLiveInserted?U.taskBoardLive:U.footer;Z.planLiveInserted=!0,j$(Z.cardId,w4(Z.planSteps,Z.planExplanation,U.planLive),{type:"insert_before",targetElementId:J})}else Z$(Z.cardId,U.planLive,w4(Z.planSteps,Z.planExplanation,U.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){_(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)_(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){_(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")_(`session "${this.sessionName}": thread/goal/updated invalid tokenBudget`);let Z=this.currentGoal,J={objective:$.objective,status:typeof $.status==="string"&&$.status?$.status:"MISS",tokenBudget:typeof $.tokenBudget==="number"?$.tokenBudget:$.tokenBudget===null?null:Number.NaN,tokensUsed:typeof $.tokensUsed==="number"?$.tokensUsed:Number.NaN,timeUsedSeconds:typeof $.timeUsedSeconds==="number"?$.timeUsedSeconds:Number.NaN};if(this.currentGoal=J,Z&&j8(Z)===j8(J))return;let Y=this.currentTurn;if(Y){if(this.startWorkingFooter(Y),Y.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Y.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let W=Z.assistantSegmentCount++,H=U.assistant(W);Z.currentAssistantSegmentId=H,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Q=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);E0(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
212
-
213
- `).trim()}discardOrphanAssistant(){this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",this.bgResumeCardless=!1}flushOrphanAssistantToChat($){let Z=this.takeOrphanAssistantText();if(!Z)return;let J=this.cleanAssistantTextForDisplay(Z).trim();if(!J)return;_(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),E(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
214
-
215
- ${J}`)}completedAssistantElement($,Z){if(m3(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Y)=>Y.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Y.text).trim()||" "}:{...Y.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Y){let Q=await AH(Y);if(!await z$(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){_(`session "${this.sessionName}": math render ${J} write dropped (card closed/element dead) — raw text stays`);return}$.mathRendered??=new Map,$.mathRendered.get(Z)??$.mathRendered.set(Z,new Set),$.mathRendered.get(Z).add(J),_(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=F$($),W=(async()=>{if(!await n0(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return _(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(m3(J)){let V=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((X)=>_(`session "${this.sessionName}": math render ${Z} failed: ${X}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(V),V.finally(()=>$.mathRenderInflight?.get(Y)?.delete(V))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(W),W.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(W)),W}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
216
-
217
- ${J}`;if(!await E(this.chatId,Y))_(`session "${this.sessionName}": ASSISTANT_TEXT_PRESERVATION_FAILED (${Z}, ${J.length} chars)`)}finalizeCurrentAssistantSegment(){let $=this.currentTurn;if(!$){if(this.orphanAssistantCurrent.trim())this.orphanAssistantSegments.push(this.orphanAssistantCurrent);this.orphanAssistantCurrent="";return}if($.cardRotationFailed)this.maybeMidTurnRotate();if($.rotating)return;let Z=$.currentAssistantSegmentId,J=$.currentAssistantText??"";if(Z&&J.trim())this.addCompletedAssistantSegment($,Z,J),this.startWorkingFooter($);$.currentAssistantSegmentId=null,$.currentAssistantText=""}processOutboundMarkers($){for(let Z of rW($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return e($)}sendOutboundPath($,Z){let J=I8($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!cL(J)){_(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),_(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),C4(this.chatId,J)}startFooterStatus($,Z){if($.cardRotationFailed)return;let J=$.provider==="codex"?this.proc?.turnRetry:null;if(J)Z=J.reason==="quota"?`⏳ ${J.message}`:J.phase==="waiting"?`⏳ 模型满载 · ${J.delayMs/1000}s 后重试 #${J.attempt}`:`⏳ 模型满载 · 正在重试 #${J.attempt}`;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Y=()=>{if($.footerStatusLabel!==Z)return;let{label:W}=m0(Date.now()-$.footerStatusStartedAt,m1()),H=Z===OX?this.proc?.lastThinkingTokens:null,V=typeof H==="number"?` · 约 ${H} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${V} (${W})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:W}=m0(Date.now()-$.footerStatusStartedAt,m1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(W)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,OX)}startWritingFooter($){this.startFooterStatus($,iL)}startWorkingFooter($){this.startFooterStatus($,dL)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Y,Q){if(J&&(!Y||!Y.enabled||Y.agent!==$))return" | 额度 MISS";if(Y?.agent===$&&Y.enabled&&($==="claude"||$==="dsh")){let W=await Y.readUsage();if(W.state==="ok"&&W.kind!=="balance"){let H=W.windows.find((X)=>X.kind==="fiveHour"),V=W.windows.find((X)=>X.kind==="weekly");if(H||V)return this.fmtDualWindowSuffix(H??null,V??null)}return` | ${a9(W)}`}if($==="codex"){let W=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,H=W?await u9(()=>W.readRateLimits(),F0(W)):null,V=W?H:Q;return V?.state==="ok"?this.fmtDualWindowSuffix(V.fiveHour??null,V.weekly??null):" | 额度 MISS"}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(W)=>{if(!W)return null;if(W.percent==null)return"MISS";let H=W.resetsAt&&W.resetsAt.getTime()>Date.now()?j4(W.resetsAt):"",V=`${Math.round(W.percent)}%`;return H?`${H}·${V}`:V},Y=J($),Q=J(Z);if(Y&&Q)return` | ${Y}·[${Q}]`;if(Y)return` | ${Y}`;if(Q)return` | [${Q}]`;return" | 额度 MISS"}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Y)=>Y.status==="rejected").map((Y)=>Y.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(O).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)E$(Z,J)}closeTurnCard($,Z={}){let J=this.currentTurn;if(!J)return this.waitForTurnCloses();if(!$&&J.cardRotationFailed)this.maybeMidTurnRotate();this.currentTurn=null,this.stopFooterStatus(J);let Y=this.proc,Q={turn:J,proc:Y,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Y),contextLimit:this.contextLimitForDisplay(Y),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:Y?.provider==="codex"?H$(Y.tokenSourceId??this.selectedTokenSourceId,F0(Y)):this.currentTokenSource(),codexUsage:eY(F0(Y)),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let W=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(W),W.then(()=>{this.turnCloseInflight.delete(W)},()=>{this.turnCloseInflight.delete(W)}),W}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;await o3(Y),this.stopFooterStatus(Y);let Q=((Date.now()-Y.startedAt)/1000).toFixed(1),W=Y.cardId,H=Y.segmentTexts;await r$(W);let V=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:R,currentAssistantText:M}=Y;if(!await this.addCompletedAssistantSegment(Y,R,M))V.set(R,M);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let X=Y.assistantWriteInflight?.get(W);if(X?.size)await Promise.allSettled([...X]);let z=Y.mathRenderInflight?.get(W);if(z?.size)await Promise.allSettled([...z]);let G=Y.mathRendered?.get(W);for(let[R,M]of H){if(F2(W,R)){V.set(R,M);continue}if(G?.has(R))continue;await Z$(W,R,this.completedAssistantElement(R,M))}if(Y.cardRotationFailed)for(let[R,M]of H)V.set(R,M);let K=Z?Z:"✅",B=[`${K} ⏱ ${Q}s`];if(J.hasFreshResult){let{contextTokens:R,contextLimit:M}=$,k=Y.provider==="claude",C=t7(R,M,k?0:void 0);if(C)B.push(`\uD83E\uDDE0 ${C}`);let v=$.lastTurnDelta?.costUsd??0;if(v>0)B.push(`\uD83D\uDCB0 $${v.toFixed(3)}`)}if(Y.contextCompactCount>0)B.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)B.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let A=this.modelLine(Y);if(A)B.push(A);let P=B.join(" | "),L=J.hasFreshResult?s7($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",j=L?`${P}
218
- ${L}`:P,N=await z$(W,U.footer,this.footerElement(j));M$(W);let F=await P$(W,U0({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(N&&F)await b$(W);else{let R=`footer=${N?"ok":"MISS"}, settings=${F?"ok":"MISS"}`;_(`session "${this.sessionName}": terminal card transaction incomplete card=${W.slice(0,12)} ${R}`),await w(this.chatId,`⚠️ 对话卡片终态写入失败 (${R})。本轮已结束: ${K}`)}for(let R of V.values())await this.sendAssistantTextFallback(R,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)O1(Y.messageId,[Y.userOpenId])}}});function e$($){return{card:{type:"raw",data:$}}}import{randomUUID as oL}from"node:crypto";function gZ($){return{session_name:$.sessionName,chat_id:$.chatId,status:$.status,running:$.isRunning(),native_session_id:$.proc?.sessionId??null,codex_account:$.proc?.provider==="codex"&&$.proc.isAlive()?{name:y.get(F0($.proc)).name,mode:$.proc.codexAccountSelectionMode?.()??"native",policy:"highest-score-plus-5h-ultra-pro-0.5"}:null,busy:!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount||$.pendingMidTurnMsgs.length),awaiting_model_input:!!$.modelCustomPrompt,last_result:$.proc?{anchor:$.proc.lastAssistantUuid,subtype:$.proc.lastResult.subtype,is_error:$.proc.lastResult.is_error}:null,selection:{provider:$.selectedProvider,source_id:$.selectedTokenSourceId,model:$.selectedModel,effort:$.selectedEffort},panels:[...$.modelPanels].map(([Z,J])=>({panel_id:Z,message_id:J.messageId,source_id:J.sourceId,mode:J.mode,editable:J.editable,total_models:J.catalog?.length,page:J.page,total_pages:J.totalPages,models:J.models.map((Y)=>({model:Y.model,provider:Y.provider,source_id:Y.sourceId,efforts:Y.efforts.map((Q)=>Q.effort),origin:Y.origin}))})),sources:R0().map((Z)=>({id:Z.id,display:Z.display,agent:Z.agent,enabled:Z.enabled,validates_custom_model:!!Z.verifyModel,status:Z.modelCatalogState?.status,error:Z.modelCatalogState?.error,models:Z.models.map((J)=>({model:J.model,efforts:J.efforts,default_effort:J.defaultEffort,unavailable_reason:J.unavailableReason,origin:J.origin}))}))}}function EX($,Z,J,Y,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let W=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(W.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof W.message_id!=="string"||!W.message_id.startsWith("om_"))throw Error("message_id required");if(!Q||W.message_id!==Q)throw Error("stale or mismatched model panel");if(!J||J.message_id!==W.message_id||J.chat_id!==Z.chat_id||J.msg_type!=="interactive"||J.sender?.sender_type!=="app"||J.sender.id!==Y)throw Error("model card must belong to this app and debug chat");if(!W.value||typeof W.value!=="object"||Array.isArray(W.value))throw Error("action value required");let H={};for(let[V,X]of Object.entries(W.value)){if(!tL.has(V))throw Error(`unsupported model action field: ${V}`);if(V==="page"){if(typeof X!=="number"||!Number.isSafeInteger(X)||X<0)throw Error("invalid page");H.page=X}else{if(typeof X!=="string"||!X.trim()||X.length>1024)throw Error(`invalid ${V}`);H[V]=X.trim()}}if(!rL.has(String(H.kind)))throw Error("only model panel actions are supported");for(let V of["panel_id","source_id"])if(!H[V])throw Error(`${V} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(H.kind))&&!H.model)throw Error("model required");if(H.kind==="model_effort_select"&&!H.effort)throw Error("effort required");if(H.kind==="model_page"&&H.page===void 0)throw Error("page required");if(H.kind==="model_list_open"&&H.mode!=="select"&&H.mode!=="add")throw Error("invalid model list mode");if(H.provider!==void 0&&!H0(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${oL()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:W.message_id},action:{tag:"button",value:H}}}var rL,tL;var SX=T(()=>{L$();J$();h$();rL=new Set(["provider_select","model_select","model_effort_select","model_page","model_list_open","model_add","model_remove","model_custom_remove","model_custom_prompt","model_panel_cancel"]),tL=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as sL}from"node:http";import{randomUUID as eL}from"node:crypto";function bX($){if($.allowReply&&$.buttons?.length)throw Error(CX);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Q=new Date,W=`${String(Q.getHours()).padStart(2,"0")}:${String(Q.getMinutes()).padStart(2,"0")}`,H=[];for(let X of $.images??[])if(X.key)H.push({tag:"img",img_key:X.key,alt:{tag:"plain_text",content:"screenshot"}});else H.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${X.src}</font>`});if(H.push({tag:"markdown",content:U6($.text??"")||"_(空消息)_"}),$.resolution){let X=$.resolution,z=X.kind==="text"?"已回复":`已选择:${X.text}`,G;if(X.status==="processing")G=`<font color='blue'>⏳ ${z} · 推送中…</font>`;else if(X.status==="failed")G=`<font color='red'>⚠️ ${X.kind==="text"?z:`已选:${X.text}`} · 回调失败:${e(X.detail??"未知")} · ${W}</font>`;else if(X.status==="delivered")G=`<font color='green'>✅ ${z} · 反馈已送达 · ${W}</font>`;else if(X.status==="unknown")G=`<font color='red'>⚠️ ${z} · ${X.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${W}</font>`;else G=`<font color='green'>✅ ${z} · ${W}</font>`;if(H.push({tag:"markdown",content:G}),X.status==="delivered"&&X.reply)H.push({tag:"markdown",content:e(X.reply)})}let V=Y&&(!$.resolution||$.resolution.status==="failed");if(V&&$.buttons?.length)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((X)=>({tag:"button",text:{tag:"plain_text",content:X.text},type:X.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:X.id}}]}))}]});if(H.push({tag:"hr"}),H.push({tag:"markdown",content:`<font color='grey'>via notify · ${W}</font>`}),V&&$.allowReply)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"回复"},type:"primary",behaviors:[{type:"callback",value:{kind:"notify_reply",notify_id:$.notifyId}}]}]}]});return{schema:"2.0",config:Y?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:H}}}function Q1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},W=[{tag:"markdown",content:`通知:${e($.title)}`}];if(Z.response)W.push({tag:"markdown",content:e(Z.response.text)});if(Y==="waiting")W.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
219
- 你的下一条文字优先用于这条通知,完成后再回答 Agent 的提问。点击其他通知的「回复」会放弃本次回复;群控制命令仍然优先。`}),W.push({tag:"button",text:{tag:"plain_text",content:"取消回复"},type:"default",behaviors:[{type:"callback",value:{kind:"notify_reply_cancel",notify_id:$.notifyId,reply_id:Z.id}}]});if(Y==="cancelled"&&Z.cancelReason==="switched")W.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let H=J?.detail??Z.error;if(H)W.push({tag:"markdown",content:`<font color='red'>${e(H)}</font>`});if(Y==="failed")W.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Y==="unknown")W.push({tag:"markdown",content:"无法确认是否已送达,请联系通知发起方核实;已禁止自动重试。"});if(J?.reply)W.push({tag:"markdown",content:e(J.reply)});return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:Q[Y]},template:Y==="failed"||Y==="unknown"?"red":Y==="delivered"||Y==="done"?"green":"blue"},body:{elements:W}}}function Yj($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Y of $){if(!Y||typeof Y!=="object")return{error:"each button must be an object"};let Q=String(Y.id??"").trim(),W=String(Y.text??"").trim();if(!Jj.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!W)return{error:`button "${Q}" missing text`};if(W.length>kX)return{error:`button "${Q}" text > ${kX} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),V=Zj.has(H)?H:"default";J.push({id:Q,text:W,type:V})}return{buttons:J}}function Qj($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Y=J.hostname.replace(/^\[|]$/g,"");if(Y!=="127.0.0.1"&&Y!=="localhost"&&Y!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function yX($){try{let Z=sL((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:xX(J,Y)):xX(J,Y)).catch((H)=>{if(_(`notify: handler crash: ${H?.message??H}`),!Y.headersSent)Y.statusCode=500,Y.setHeader("content-type","text/plain; charset=utf-8"),Y.end("internal error");else try{Y.end()}catch{}})});Z.on("error",(J)=>{_(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{_(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){_(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function xX($,Z,J=Q$){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(p,D)=>{Z.statusCode=p,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(D)},W=(p,D)=>{Z.statusCode=p,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(D))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
236
+ ${G}`)}return{slug:Y,chatName:W,branch:Q,worktreePath:z,removedWorktree:!1}}function mZ($){if(!m1($))throw Error(`project directory does not exist: ${$}`);let Z=U$($,["rev-parse","--show-toplevel"]).trim();if(IZ(Z)!==IZ($))throw Error(`${$} is not the git repository root (${Z})`)}function Pz($,Z){let J=U$($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function JP($,Z,J){let Y=YP($);if(!Y?.startsWith(h2))return null;let Q=Y.slice(h2.length);if(!c1(Q))throw Error(`invalid worktree branch "${Y}"`);let W=g2(Z,J,Q);if(P6($)!==P6(W))return null;let H=WP($,QP(Q));return H?{path:H,slug:Q}:null}function YP($){if(!m1($))return null;try{return U$($,["branch","--show-current"]).trim()||null}catch(Z){if(VP(Z))return null;throw Z}}function QP($){return $.split("-",1)[0]??$}function WP($,Z){let J=`agents.${Z}.md`,Y=tj($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?_z($,Y[0]):null}function HP($,Z){try{return U$($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function Dz($,Z,J){let Y=U$($,["rev-parse",Z]).trim(),Q=U$($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(Gz($,Z,"HEAD"))return"merged";if(Gz($,"HEAD",Z))return"active";return"stale"}function Gz($,Z,J){try{return U$($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function cZ($){let Z=new Map,J=U$($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
237
+ `)){if(Q.startsWith("worktree ")){Y=Q.slice(9);continue}if(Q.startsWith("branch refs/heads/")&&Y)Z.set(Q.slice(18),Y)}return Z}function U$($,Z){try{return rj("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(pZ(J))}}function pZ($){if($&&typeof $==="object"){let Z=$,J=Z.stderr?String(Z.stderr).trim():"";if(J)return J;if(Z.message)return Z.message}return String($)}function VP($){return/not a git repository/i.test(pZ($))}var h2="work/",ZP,j6;var Mz=T(()=>{ZP=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,j6=new Map});function W1($){return Kz(A0($.sessionName)??$.sessionName)}function m2($){return L8(W1($))}function Rz($){let Z=A0($.sessionName)??$.sessionName,J=W1($),Y=L8(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return g2(Y,J,Q)}function Uz($,Z=$.currentProvider()){let J=Z==="dsh"?zz:Z==="claude"?Vz:Hz,Y=Q9($);return Y?`${J}
238
+ ${Y}`:J}function Oz($,Z){return Q9($)??""}function uZ($){return Q9($)?"已载入wt特殊约定":null}function Tz($,Z){let J=uZ($);return J?`${Z}
239
+ ${J}`:Z}function Q9($){let Z=W1($),J=Az($.workDir,m2($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
240
+ `)}async function Nz($,Z,J){if(!Z){await lZ($);return}let Y=c1(Z);if(!Y){await N($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await N($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=W1($),W=m2($);try{await D6(W,async()=>{let H;try{H=Lz(W,Q,Y)}catch(V){await N($.chatId,`❌ wt 失败: ${O(V)}`);return}try{let V=await a3(H.chatName,J),z=V.created?"已创建":V.joined?"已加入":"已在群内";if(!await u($.chatId,l4({slug:Y,branch:H.branch,status:z})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await u(V.chatId,l4({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await w(V.chatId,`❌ wt 卡片失败: ${Y}`)}catch(V){await N($.chatId,`❌ wt 已建,拉群失败: ${O(V)}`)}})}catch(H){await N($.chatId,`❌ wt 失败: ${O(H)}`)}}async function Ez($,Z){let J=W1($),Y=m2($);return await D6(Y,async()=>{return await XP(J,Y,Z)})}async function XP($,Z,J){let Y=qz(Z,$),Q=Y.filter((V)=>V.state==="merged"&&!V.mounted).length,W=Y.filter((V)=>V.state!=="merged"||V.mounted),H=await P8();return N7({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:W.map((V)=>{let z=H.get(V.chatName)??[],X=q$.get(V.chatName),G=X&&z.includes(X)?X:z.length===1?z[0]:null;return{slug:V.slug,chatName:V.chatName,branch:V.branch,state:V.state,path:V.worktreePath??V.expectedPath,mounted:V.mounted,dirtyCount:V.dirtyCount,statusLine:V.statusLine,error:V.error,chatId:G,duplicateChatCount:z.length}})})}async function lZ($){try{let Z=await Ez($);if(!await u($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await N($.chatId,`❌ wt 列表失败: ${O(Z)}`)}}async function Fz($,Z,J,Y){try{return{ok:Z,message:J,card:await Ez($,{type:Y,content:J})}}catch(Q){let W=`列表刷新失败: ${O(Q)}`;return _(`session "${$.sessionName}": wt action panel refresh failed: ${O(Q)}`),{ok:!1,message:`${J}
241
+ ${W}`,card:l4({slug:"wt",branch:"work/*",status:J,body:W,template:"red"})}}}async function Sz($,Z){let J=c1(Z);if(!J)return Fz($,!1,"❌ 名称无效","error");let Y=W1($),Q=m2($),W;try{W=await D6(Q,async()=>{let H=I2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};gZ(Q,Y,J);let V=await r3(H),z=jz(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",V.disbanded?"group removed":"group missing",z.branch].join(`
242
+ `),type:"success"}})}catch(H){W={ok:!1,message:`❌ 解散 ${J} 失败: ${O(H)}`,type:"error"}}return Fz($,W.ok,W.message,W.type)}var kz=T(()=>{Xz();$0();$$();I();Mz()});import{closeSync as _P,openSync as KP,readSync as BP,readdirSync as AP,statSync as qP}from"node:fs";import{randomUUID as dZ}from"node:crypto";import{join as LP}from"node:path";function F6($){return A0($.sessionName)??$.sessionName}function Cz($){let Z=c3($,iZ);return iZ.add(Z),Z}function bz($){iZ.delete($)}function c2($){let Z=xz.get($);if(!Z)Z=new Map,xz.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let W=Q.status==="consumed"?DP:PP,H=Q.consumedAt??Q.createdAt;if(J-H>W)Z.delete(Y)}return Z}function FP($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function yz($,Z,J,Y){let Q={id:dZ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:F6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return c2($).set(Q.id,Q),Q}function nZ($,Z,J,Y,Q){let W=c2($).get(J);if(!W||W.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||W.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(W.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(W.provider!==$.selectedProvider||W.workDir!==$.workDir||W.sourceSessionId!==$.lastSessionId||!FP(W.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=W.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return W.status="processing",{panel:W,choice:H}}function M6($){$.status="consumed",$.consumedAt=Date.now()}function RP($){return{kind:"fork",source:$.source,through:$}}function UP($){return k4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function OP($){let Z=x4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return B$(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function TP($){let Z=i9($),J;try{J=AP(Z)}catch(Q){if(Q?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Q?.message??Q}`)}let Y=[];for(let Q of J){if(!Q.endsWith(".jsonl"))continue;let W=Q.slice(0,-6);if(s1("claude",W))continue;let H=LP(Z,Q),V;try{V=qP(H).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:W,cwd:$,preview:EP(H),ts:V})}return Y.sort((Q,W)=>W.ts-Q.ts)}function NP($){let Z=$.slice().sort((Q,W)=>W.ts-Q.ts),J=Date.now()-jP,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(MP,Math.max(10,Y)))}function EP($){let Z="",J=null;try{J=KP($,"r");let Q=Buffer.alloc(65536),W=BP(J,Q,0,65536,0);Z=Q.subarray(0,W).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)_P(J)}let Y="";for(let Q of Z.split(`
243
+ `)){let W=Q.trim();if(!W)continue;let H;try{H=JSON.parse(W)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let V=H.content.trim();if(V)return V.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let V=SP(H.message);if(V)Y=V}}return Y.slice(0,80)}function SP($){let Z=$?.content;if(typeof Z==="string")return Z;if(!Array.isArray(Z))return"";for(let J of Z)if(J?.type==="text"&&typeof J.text==="string")return J.text;return""}async function wz($,Z,J){if(!J){await N($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=UP($),Q=OP($),W=new Map,H=[];for(let G=0;G<Y.length;G++){let K=Y[G];if(G===0&&Q===null)continue;let B=dZ(),L=G===0?Q:RP(Y[G-1].checkpoint);W.set(B,{kind:Z,launch:L,branchBase:Q,seedAnchors:Y.slice(0,G),writes:Y.slice(G).flatMap((A)=>A.writes)}),H.push({choiceId:B,preview:K.preview,ts:K.ts})}H.reverse();let V=yz($,Z,J,W),z=S7({projectName:F6($),panelId:V.id,mode:Z,entries:H}),X;try{X=await u($.chatId,z)}catch(G){throw c2($).delete(V.id),G}if(!X)c2($).delete(V.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function fz($,Z){return wz($,"fork",Z)}function vz($,Z){return wz($,"back",Z)}async function hz($,Z){if(!Z){await N($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():TP($.workDir)}catch(z){await w($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=NP(J).map((z)=>{let X=dZ();return Y.set(X,{kind:"resume",launch:{kind:"fork",source:{provider:z.provider,sessionId:z.sessionId,cwd:z.cwd}},sourcePreview:z.preview,sourceTs:z.ts,sourceStatus:z.status}),{choiceId:X,preview:z.preview,ts:z.ts}}),W=yz($,"resume",Z,Y),H=k7({projectName:F6($),panelId:W.id,entries:Q}),V;try{V=await u($.chatId,H)}catch(z){throw c2($).delete(W.id),z}if(!V)c2($).delete(W.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function Iz($,Z){if(!Z){await N($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await N($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=Cz(F6($));await N($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Y;try{Y=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{bz(J)}if(!Y.ok){await N($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await N($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function gz($){if(!A0($.sessionName)){await N($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await N($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await N($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await N($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function mz($,Z,J,Y){let Q=nZ($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let V=Cz(W.baseName);_(`session-temp: fork ${$.sessionName} → ${V} (${H.launch.kind})`),await N($.chatId,`\uD83D\uDD31 正在分叉到 ${V}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:V,userOpenId:Y,workDir:W.workDir,routing:W.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{bz(V)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${V};原会话和磁盘文件未回滚`}}catch(V){return{ok:!1,message:`分叉失败: ${V instanceof Error?V.message:V}`}}finally{M6(W)}}async function cz($,Z,J,Y){let Q=nZ($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let V="";try{if(!await u($.chatId,x7({projectName:W.baseName,entries:H.writes})))V=";文件变更记录卡发送失败"}catch(G){V=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(_(`session-temp: back ${$.sessionName} (${H.launch.kind}, writes=${H.writes.length})`),!await $.rollbackTo(H.launch,{anchors:H.seedAnchors,base:H.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${V}`};if(W.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${V}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${M$($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${V}`}}catch(V){return{ok:!1,message:`回退失败: ${V instanceof Error?V.message:V}`}}finally{M6(W)}}async function pz($,Z,J,Y){let Q=nZ($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;if(H.kind!=="resume")throw M6(W),Error("resume panel contained a non-resume choice");let V=H.launch.source.sessionId,z=$.lastSessionId,X=(K,B)=>({projectName:W.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:V,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:z,newSessionId:K,bindingState:B}),G=(K,B,L,A=null)=>({ok:K,message:B,resumePresentation:X(A,L)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(_(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${V}`),!await $.rollbackTo(H.launch,{anchors:[],base:H.launch,pendingLaunch:H.launch.source.provider==="claude"?{launch:H.launch,previousSessionId:z}:null}))return G(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(H.launch.source.provider==="claude")return G(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let B=$.lastSessionId;if(!B)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(B===V||z&&B===z)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",B);return G(!0,"已创建并接入独立分支;源会话未修改","changed",B)}catch(K){return G(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{M6(W)}}var jP=86400000,PP=1800000,DP=3600000,MP=40,xz,iZ;var uz=T(()=>{$$();$0();I();G4();t2();L1();xz=new WeakMap,iZ=new Set});import{existsSync as lz}from"node:fs";import{randomBytes as xP,timingSafeEqual as CP}from"node:crypto";import{isAbsolute as bP}from"node:path";function oZ($,Z=new Set){if($ instanceof Q2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=oZ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return oZ($.cause,Z);return null}function yP($){return $.itemId||$.turnId||"__latest__"}function iz($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function wP($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function fP($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function p1(){return f.runtime?.live_elapsed??"bucket"}function az($,Z){return`${$} (${p0(Date.now()-Z,p1()).label})`}var dz="Thinking...",vP="Writing...",hP="Working...",aZ=1e4,R6=720000,IP=50,gP=256,U6=1e4,nz=250,H0;var CZ=T(()=>{t2();e2();P$();j1();a5();P$();x$();K3();Y$();I$();P2();G4();r0();$0();$$();I();H$();A3();i0();a4();i7();OH();hH();sH();e8();ZV();yV();fV();lV();rV();Wz();kz();uz();L1();H0=class H0{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;agentCapability=null;procSourceRevisions=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];backgroundCard=null;settlingBackgroundCard=!1;migratingBackgroundCard=null;backgroundRefreshTimer=null;backgroundRefreshTick=null;openingBackground=!1;openingBackgroundOwner=null;backgroundOpenSequence=0;backgroundGeneration=0;backgroundDetailAdded=new Set;backgroundDetailAdding=new Set;lastMainTaskToolUseId=null;pendingRebuildBackgroundCard=!1;bgResumePending=!1;orphanAssistantSegments=[];orphanAssistantCurrent="";bgResumeCardless=!1;pendingPermissions=new Map;pendingAsks=new Map;currentGoal=null;status="stopped";pendingUserMessageCount=0;pendingMidTurnMsgs=[];pendingTurnInputs=[];multiMsgBuffer=null;multiMsgReactions=new Map;lastUserOpenId="";pendingReactionIds=new Map;currentBatchReactionIds=new Map;initCount=0;openingTurn=!1;openingTurnOwner=null;turnOpenSequence=0;turnCloseInflight=new Set;turnCounter=0;userInterrupted=!1;lastSessionId=null;lastSessionRef=null;selectedProvider="claude";selectedModel=null;selectedEffort=null;selectedTokenSourceId=null;modelPanels=new Map;modelCustomPrompt=null;startedAt=0;cumStats={tokens:0,costUsd:0,turns:0};lastTurnDelta=null;currentTurnUsageBaseline=null;currentTurnUsageBaselineKnown=!1;lastTurnUsage=null;usageTotalsSeedUnknown=!1;resumePersistenceError=null;daemonRestoreRequired=!1;manualContextCompactionPending=!1;taskBoard=[];constructor($,Z,J={}){this.sessionName=$;this.chatId=Z;this.opts=J;H0.all.add(this);let Y=l3($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=K0(this.selectedTokenSourceId);if(Q){if(this.selectedProvider=Q.agent,Q.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Q.defaultModel,this.selectedEffort="max"}if(this.selectedModel)_(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=d0($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)_(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let W=C4($);if(W)if(this.selectedProvider!=="claude")r$($,[],null,null),_(`session "${$}": cleared pending Claude fork after provider changed`);else{B$(W.launch,"claude",this.workDir);let H=this.lastSessionId===W.previousSessionId,V=this.lastSessionRef,z=!H&&V?.provider==="claude"&&V.cwd===this.workDir&&V.sessionId!==W.launch.source.sessionId&&V.sessionId!==W.previousSessionId;if(!H&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=W,_(`session "${$}": restored ${z?"materialized":"pending"} Claude fork source=${W.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return Rz(this)}isRunning(){return!!this.proc&&this.proc.isAlive()}shouldRevive(){return this.daemonRestoreRequired||this.isRunning()&&this.stoppingProc!==this.proc&&this.blockedProc!==this.proc}deriveTokenSourceId($){let Z=$?.tokenSourceId;if(typeof Z==="string"&&Z.trim())return Z.trim();let J=$?.provider??this.selectedProvider;return o9(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?U0(this.proc):this.codexStartAccountOverride??y.selected(this.sessionName)}tokenSource($){let Z=K0($);return Z?.forAccount?V$($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...this.codexAccountId()===p?{}:{codexAccountId:this.codexAccountId()},...y.preferred(this.sessionName)===null?{codexAccountAutomatic:!0}:{}}}applyConversationRouting($){if(this.isRunning()||this.currentTurn||this.openingTurn)throw Error("cannot change conversation routing while the session is running");if($.codexAccountId)y.get($.codexAccountId);let Z=K0($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)r$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=d0(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,T1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??p;if($.codexAccountAutomatic)y.selectAuto(this.sessionName);else if(y.selected(this.sessionName)!==J)y.select(this.sessionName,J)}dshEffortForSpawn(){if(K$(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&_0($,this.selectedModel??$.defaultModel);if(!Z||!K$(Z.defaultEffort))throw Error("DSH model reasoning effort is unavailable");return Z.defaultEffort}async listDshConversations(){if(this.selectedProvider!=="dsh")throw Error("DSH history requested under a different provider");let $=this.currentTokenSource();if(!$?.enabled||$.agent!=="dsh")throw Error("DSH token source is unavailable");return(await e1({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!s1("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!f4(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");let $=this.currentTokenSource();if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(V)=>Z.spawnEnv(V):void 0,Y=new W2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,W=null;try{Q=await Y.listConversations()}catch(V){W=V}let H=null;try{await Y.kill(2000)}catch(V){H=V}if(W&&H)throw AggregateError([W,H],`Codex history query and cleanup failed: ${O(W)}; ${O(H)}`);if(W)throw W;if(H)throw H;return Q??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="dsh")throw Error("DSH resume reference requires its original cwd");else if($.provider==="claude"){let J=d9(this.workDir,$.sessionId);if(!lz(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${M$($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!f4(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Y=J?.enabled?J:void 0,Q=new W2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(V)=>Y.spawnEnv(V):void 0}),W=null;try{Z=await Q.readConversationRef($.sessionId)}catch(V){W=V,Z=$}let H=null;try{await Q.kill(2000)}catch(V){H=V}if(W&&H)throw AggregateError([W,H],`Codex legacy resume lookup and cleanup failed: read=${O(W)}; cleanup=${O(H)}`);if(W)throw W;if(H)throw H}return B$({kind:"resume",source:Z},this.selectedProvider,this.workDir),S4(this.sessionName,Z),Z}hasRunningPeerSession($){return[...H0.all].some((Z)=>Z.sessionName===$&&Z.isRunning())}modelForSpawn(){if(this.selectedProvider==="codex")return;return this.selectedModel??void 0}effortForSpawn(){if(this.selectedProvider==="codex"){let $=this.currentTokenSource();if(!$||!$.enabled&&$.id!=="codex-sub")return;return a$(this.selectedEffort)?this.selectedEffort:W4}return W4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&T$(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=_0($,this.selectedModel??$.defaultModel);if(!T$(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return g0}currentModelLabel(){return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude")return this.selectedEffort??_0($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?g0:W4)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Y=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Q=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?g0:W4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return Z$($,U.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:U.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return V7($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return X0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(B$($.launch,"claude",this.workDir),this.selectedProvider!=="claude")throw Error("pending Claude fork cannot launch under a non-Claude provider");if(this.lastSessionId===$.previousSessionId)return $.launch;let Z=this.lastSessionRef;if(Z?.provider==="claude"&&Z.cwd===this.workDir&&Z.sessionId!==$.launch.source.sessionId&&Z.sessionId!==$.previousSessionId)return{kind:"resume",source:Z};throw Error("pending Claude fork has no safe launch target")}spawnAgent($){this.agentCapability=xP(32).toString("base64url");let Z={LODESTAR_AGENT_URL:$8(f.notify.bind,f.notify.port),LODESTAR_AGENT_CAPABILITY:this.agentCapability,LODESTAR_AGENT_SESSION:this.sessionName,LODESTAR_AGENT_ROLE:"main"},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});B$(J,this.selectedProvider,this.workDir);let Y=this.currentTokenSource(),Q=this.selectedProvider==="codex"&&this.selectedTokenSourceId==="codex-sub";if(this.selectedTokenSourceId&&(!Y||!Y.enabled&&!Q))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let W=Y?.enabled||Q?Y:void 0,H=j4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:W?.id??null,...this.selectedProvider==="codex"?{codexAccountId:y.selected(this.sessionName)}:{},...Q?{codexAccountPreference:this.codexStartAccountOverride??y.preferred(this.sessionName)}:{},model:W?this.selectedModel??W.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="dsh"?this.dshEffortForSpawn():this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:M2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:_1},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),H.process}async applyModelSelection($,Z,J,Y){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Y))}async applyModelSelectionUnlocked($,Z,J,Y){if(this.selectedProvider!==$)r$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let W=K0(this.selectedTokenSourceId);if(W)this.selectedModel=Z||null,this.selectedEffort=J??_0(W,Z||W.defaultModel)?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=d0(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,u3(this.sessionName,$,this.selectedModel,this.selectedEffort,this.selectedTokenSourceId),await this.stopIdleMismatchedProcessUnlocked()}async stopIdleMismatchedProcess(){await this.runLifecycle("stop-idle-mismatched",()=>this.stopIdleMismatchedProcessUnlocked())}processSourceMatches($,Z){if(this.proc?.quotaWaitPromise&&!this.proc.sessionId&&this.proc.turnRetry?.reason==="quota")return!0;if(this.proc?.sourceRevision)return this.proc.sourceRevision()===_2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===_2($,Z)}async stopIdleMismatchedProcessUnlocked(){if(!this.proc?.isAlive())return;let $=this.currentTokenSource(),Z=this.processSourceMatches($,this.selectedModel);if(this.proc.provider===this.selectedProvider&&this.proc.tokenSourceId===this.selectedTokenSourceId&&Z)return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let J=this.proc;_(`session "${this.sessionName}": stop idle ${J.provider} process after switching to ${this.selectedProvider}`),this.beginProcStop(J),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let Y=await this.settleProcResumableState(J),Q=null;try{await J.kill(1000)}catch(V){Q=V}Y=await this.settleProcResumableState(J);let W=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!W?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Y?[Error(Y)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(O).join("; ")}`)}async stopIdleCurrentProcess($){return await this.runLifecycle("stop-idle-current",()=>this.stopIdleCurrentProcessUnlocked($))}async stopIdleCurrentProcessUnlocked($){if(!this.proc?.isAlive())return!1;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return!1;let Z=this.proc;_(`session "${this.sessionName}": stop idle ${Z.provider} process: ${$}`),this.beginProcStop(Z),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let J=await this.settleProcResumableState(Z),Y=null;try{await Z.kill(1000)}catch(H){Y=H}J=await this.settleProcResumableState(Z);let Q=this.finishProcStop(Z,Y);this.opts.onLifecycleChange?.();let W=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(W.length===1)throw W[0];if(W.length>1)throw AggregateError(W,`idle process stop failed: ${W.map(O).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,W=!1,H=()=>{if(W)return;this.replaceFooterContent($,J(az(Q,Y)))},V=null,z=()=>{if(W)return;let{nextDelayMs:X}=p0(Date.now()-Y,p1());V=setTimeout(()=>{H(),z()},Math.max(1,Math.ceil(X)))};return H(),z(),{setStatus(X){Q=X,H()},stop(){if(W=!0,V)clearTimeout(V)},elapsedSec(){return((Date.now()-Y)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=q3({sessionName:this.sessionName,title:$,status:az(Z,Y),template:J}),W=await u(this.chatId,Q);if(!W)return _(`session "${this.sessionName}": status card send failed title=${$}`),await w(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await t$(W)}catch(V){return _(`session "${this.sessionName}": status card id_convert failed title=${$}: ${V}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return p$(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(V)=>M4($,V))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=M4($.title,`${Z} (${J}s)`);await s$($.cardId);let Q=await G$($.cardId,U.footer,this.footerElement(Y));F$($.cardId);let W=await j$($.cardId,T0({durationSec:J,suffix:Z}));if(Q&&W)await y$($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${W?"ok":"MISS"}`;_(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await w(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Y;this.lifecycleTail=new Promise((W)=>{Y=W}),await J;let Q=++this.lifecycleSequence;_(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),_(`session "${this.sessionName}": lifecycle#${Q} ${$} end`)}}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){if(this.openingTurnOwner)throw Error(`turn card open already owned by token=${this.openingTurnOwner.token}; same-process opens must wait for the current owner`);let Y,Q=new Promise((H)=>{Y=H}),W={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=W,this.openingTurn=!0,W}ownsTurnOpen($){return this.openingTurnOwner===$&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseTurnOpen($){if(this.openingTurnOwner!==$)return;this.openingTurnOwner=null,this.openingTurn=!1,$.resolveDone()}invalidateTurnOpen(){let $=this.openingTurnOwner;this.openingTurnOwner=null,this.openingTurn=!1,$?.resolveDone()}async waitForTurnOpenSlot($,Z){while(this.openingTurnOwner)if(await this.openingTurnOwner.done,this.proc!==$||this.procEpoch!==Z||!$.isAlive())return!1;return this.proc===$&&this.procEpoch===Z&&$.isAlive()}beginBackgroundOpen(){if(this.backgroundCard||this.openingBackgroundOwner)return null;let $={token:++this.backgroundOpenSequence,proc:this.proc,procEpoch:this.procEpoch,generation:this.backgroundGeneration};return this.openingBackgroundOwner=$,this.openingBackground=!0,$}ownsBackgroundOpen($){return this.openingBackgroundOwner===$&&this.backgroundGeneration===$.generation&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseBackgroundOpen($){if(this.openingBackgroundOwner!==$)return;this.openingBackgroundOwner=null,this.openingBackground=!1}invalidateBackgroundOpen(){this.backgroundGeneration++,this.openingBackgroundOwner=null,this.openingBackground=!1}attachProc($){this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.stoppingProc=null,this.blockedProc=null,this.blockedProcReason=null,this.proc=$;let Z=++this.procEpoch;this.wireProc($,Z)}detachProc($){if(this.proc!==$)return!1;if(this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.proc=null,this.agentCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.agentCapability=null}acceptsAgentCapability($){let Z=this.agentCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Y=Buffer.from($);return J.length===Y.length&&CP(J,Y)}async cancelAgentRuns($="用户取消"){await this.opts.onCancelAgentRuns?.(this.sessionName,this.chatId,$)}finishProcStop($,Z){if(this.stoppingProc===$)this.stoppingProc=null;if(!$.isAlive())return this.discardPendingCodexTurnAnchors($,"confirmed process stop"),this.detachProc($),!0;return this.blockedProc=$,this.blockedProcReason=Z?O(Z):"kill returned while process still reports alive",_(`session "${this.sessionName}": process stop unconfirmed; lifecycle blocked: ${this.blockedProcReason}`),!1}blockedProcessMessage(){let $=this.blockedProc;if(!$)return null;if(!$.isAlive())return this.detachProc($),null;return`旧 ${this.backendLabel($.provider)} 进程尚未确认退出,会话已阻断: ${this.blockedProcReason??"未知原因"}`}async stopOwnedProc($,Z){if(this.proc!==$)return!$.isAlive();this.beginProcStop($);let J=null;try{await $.kill(Z)}catch(Y){J=Y}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(W){Z=`Codex 会话落盘确认失败: ${O(W)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${O(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,r$(this.sessionName,[],{kind:"fresh"},null),this.currentGoal=null,this.cumStats={tokens:0,costUsd:0,turns:0},this.lastTurnDelta=null,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.lastTurnUsage=null,this.usageTotalsSeedUnknown=!1}async start($={}){return await this.runLifecycle("start",()=>this.startUnlocked($))}async startWithCodexAccount($,Z={}){return this.runLifecycle("hi-account",async()=>{if(y.get($),this.selectedProvider!=="codex"){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Y=V$("codex-sub",$)?.defaultModel||null;r$(this.sessionName,[],null,null),T1(this.sessionName,"codex",Y,null,"codex-sub"),this.pendingConversationMaterialization=null,this.selectedProvider="codex",this.selectedTokenSourceId="codex-sub",this.selectedModel=Y,this.selectedEffort=null,this.lastSessionRef=d0(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")T1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&U0(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${y.get($).name}」`),!0;return this.proc?.isAlive()?await this.restartUnlocked(!0,Z):await this.startUnlocked(Z)}finally{this.codexStartAccountOverride=void 0}})}async startUnlocked($={}){let Z=$.announce??!0,J=$.onStatus,Y=this.blockedProcessMessage();if(Y){if(this.status="stopped",J?.(`❌ ${Y}`),Z)await N(this.chatId,`❌ ${Y}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&this.selectedTokenSourceId!=="codex-sub"&&!f4(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,Y0({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!lz(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await N(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{Z7(this.workDir)}catch(G){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${G}`),Z)await N(this.chatId,`❌ 创建项目失败: ${G}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Q;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await A2();Q=this.spawnAgent()}catch(G){let K=`${this.backendLabel()} 启动失败: ${O(G)}`;if(_(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await N(this.chatId,`❌ ${K}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let W=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,nz):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${W} 启动`:`⏳ 等待 ${W} init`);let V,z=null;try{Q.sendInitialize(),V=Q.initializationPromise?.()}catch(G){V=void 0,z=G}let X=z?{state:"error",error:z}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(V),()=>{_(`session "${this.sessionName}": codex init still pending after ${aZ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${W} init 确认`))});if(X.state==="error"||X.state==="exit"){let G=X.error?O(X.error):X.state;_(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,L=`❌ ${W} 启动失败: ${G}${B}`;if(J?.(L),Z)await N(this.chatId,L);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(X.state==="timeout"){_(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${R6/1000}s)`);let K=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${W} 启动超时: ${R6/1000} 秒内初始化事务未完成${K}`;if(J?.(B),Z)await N(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let G=`${W} 启动期间已退出`;if(_(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await N(this.chatId,`❌ ${G}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(X.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,Y0({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let G=this.modelLine();await N(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),G].filter(Boolean).join(`
244
+ `))}return this.status="idle",this.startedAt=Date.now(),this.daemonRestoreRequired=!1,this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Y=!1,Q=(V,z)=>{if(Y)return;Y=!0,clearTimeout(W),clearTimeout(H),J({state:V,error:z})},W=setTimeout(()=>{if(Y)return;try{Z?.()}catch(V){Q("error",V)}},aZ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${R6/1000}s`))},R6);$.then(()=>Q("init"),(V)=>Q("error",V)),this.proc?.quotaWaitPromise?.().then(()=>Q("waiting_quota"),(V)=>Q("error",V))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(X,G)=>{if(Y)return;Y=!0,clearTimeout(W),$.off("init",H),$.off("error",V),$.off("exit",z),J({state:X,error:G})},W=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),V=(X)=>Q("error",X),z=(X)=>Q("exit",X);$.once("init",H),$.once("error",V),$.once("exit",z)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)S$($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;_(`session "${this.sessionName}": clear stale pending queue before ${$} pendingCount=${this.pendingUserMessageCount} reactions=${this.pendingReactionIds.size}`),this.pendingUserMessageCount=0;for(let[Z,J]of this.pendingReactionIds)if(J)S$(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}async stopUnlocked($="已终止",Z={}){let J=Z.announce??!0,Y=Z.onStatus;if(this.daemonRestoreRequired=!1,await this.cancelAgentRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.("⚪ session 当前未运行"),J)await N(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Q=this.proc,W=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),_(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((P)=>{_(`session "${this.sessionName}": stop current main-card close failed: ${O(P)}`)});let V=this.waitForTurnCloses().catch((P)=>_(`session "${this.sessionName}": stop main-card close failed: ${O(P)}`));this.beginProcStop(Q),this.status="stopped";let z=[];try{this.opts.onLifecycleChange?.()}catch(P){z.push(P),_(`session "${this.sessionName}": stop intent lifecycle write failed: ${O(P)}`)}let X=Q.conversationMaterializationBarrier?.();if(X){try{await X}catch(P){H=`Codex 会话落盘确认失败: ${O(P)}`}W=this.persistResumableSessionId(!1,Q,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let G=null;try{await Q.kill()}catch(P){G=P}let K=Q.conversationMaterializationFailure?.();if(K&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${O(K)}`;W=this.persistResumableSessionId(!1,Q,!1);let L=(await Promise.allSettled([this.resetBackgroundTasks(),V])).filter((P)=>P.status==="rejected").map((P)=>P.reason);for(let P of L)_(`session "${this.sessionName}": stop terminal cleanup failed: ${O(P)}`);let A=this.finishProcStop(Q,G);try{this.opts.onLifecycleChange?.()}catch(P){z.push(P),_(`session "${this.sessionName}": stop final lifecycle write failed: ${O(P)}`)}let j=[...G?[G]:[],...!A&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...L,...z,...W?[Error(W)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(j.length===1)throw j[0];if(j.length>1)throw AggregateError(j,`stop failed: ${j.map(O).join("; ")}`);if(Y?.(`✅ ${$}`),J)await N(this.chatId,`\uD83D\uDD34 ${$} (session: ${this.sessionName})`)}async restart($=!1,Z={}){return await this.runLifecycle("restart",()=>this.restartUnlocked($,Z))}requireDaemonRestore(){this.daemonRestoreRequired=!0}async restoreAfterDaemonRestart(){return await this.runLifecycle("daemon-restore",async()=>{if(this.requireDaemonRestore(),!this.lastSessionRef&&!this.pendingMaterializationLaunch())return this.status="stopped",this.opts.onLifecycleChange?.(),await N(this.chatId,"❌ daemon 重启后没有可用的恢复点。请发送 rs 选择历史会话,或 hi 明确启动新会话。"),!1;return await this.restartUnlocked(!0)})}async restartUnlocked($=!1,Z={},J){let Y=Z.announce??!0,Q=Z.onStatus,W=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,n0(this.sessionName,null),this.pendingConversationMaterialization=null;let V=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!V&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(E){let v=this.invalidateMissingCodexResume(z.sessionId,E,J),m=v?`❌ 旧会话不可恢复: ${O(E)};${v}`:`❌ 旧会话 cwd 校验失败: ${O(E)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?W:"stopped",Q?.(m),Y)await N(this.chatId,m);return!1}let X=z?.sessionId??null,G=V&&V.kind!=="fresh"?V.source.sessionId:X,K=G?M$(G):"",B=null,L=(E=this.proc)=>{if(!$||V||E?.provider!=="codex"||E.isConversationResumable?.()!==!0)return;B=this.persistResumableSessionId(!1,E,!1),z=this.lastSessionRef,X=z?.sessionId??null,G=X,K=G?M$(G):""},A=null;if(!Q&&Y&&$&&X){let E=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(A=await this.openStatusCard("restart",E),A)Q=(v)=>this.setStatusCard(A,v)}let j=Y&&!A,P=async(E)=>{if(A)await this.closeStatusCard(A,E)},S=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||this.backgroundTasks.length>0||this.pendingBgTasks.length>0||this.openingBackground);if(this.bgResumePending=!1,this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.discardOrphanAssistant(),this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((E)=>{_(`session "${this.sessionName}": restart current main-card close failed: ${O(E)}`)});let F=this.waitForTurnCloses().catch((E)=>_(`session "${this.sessionName}": restart main-card close failed: ${O(E)}`)),R=null,M=null;if(this.proc){let E=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(E.provider)}`),M=E,this.beginProcStop(E);let v=E.conversationMaterializationBarrier?.();if(v)try{await v}catch(l){B=`Codex 会话落盘确认失败: ${O(l)}`}if(L(E),$&&!V&&B&&!S&&E.isAlive()){if(this.stoppingProc===E)this.stoppingProc=null;this.status=W;let l=`❌ ${this.backendLabel(E.provider)} 恢复点尚未安全落盘,已保留当前进程: ${B}`;if(_(`session "${this.sessionName}": abort restart before kill: ${B}`),Q?.(l),j)await N(this.chatId,l);return await P(l),!1}try{await E.kill()}catch(l){R=l}let m=E.conversationMaterializationFailure?.();if(m&&E.isConversationResumable?.()!==!0)B=`Codex 会话落盘确认失败: ${O(m)}`;L(E)}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let C=(await Promise.allSettled([this.resetBackgroundTasks(),F])).filter((E)=>E.status==="rejected").map((E)=>E.reason);for(let E of C)_(`session "${this.sessionName}": restart terminal cleanup failed: ${O(E)}`);let c=M?this.finishProcStop(M,R):!0,b=[...R?[`kill=${O(R)}`]:[],...!c&&!R?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...C.map((E)=>`cleanup=${O(E)}`),...B?[`resume=${B}`]:[]];if(b.length>0&&H)try{n0(this.sessionName,H),this.pendingConversationMaterialization=H}catch(E){b.push(`pendingRestore=${O(E)}`)}if(b.length>0){let E=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${b.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(E),j)await N(this.chatId,E);return await P(E),!1}let h=V?.kind==="resume"||V?.kind==="fork";if($&&z||h){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let E;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await A2();E=this.spawnAgent(z??void 0)}catch(a){let _$=`❌ ${this.backendLabel()} 恢复失败: ${O(a)}`;if(_(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${O(a)}`),Q?.(_$),j)await N(this.chatId,_$);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(_$),!1}this.attachProc(E);let v=this.backendLabel(),m=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(E,nz):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${v} 恢复启动`:`⏳ 等待 ${v} init 确认`);let l,D=null;try{E.sendInitialize(),l=E.initializationPromise?.()}catch(a){l=void 0,D=a}let x=D?{state:"error",error:D}:this.selectedProvider==="claude"?await m:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{_(`session "${this.sessionName}": codex resume init still pending after ${aZ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${v} init 确认 thread=${K}`))});if(x.state==="error"||x.state==="exit"||x.state==="timeout"){let a=x.state==="error"?this.invalidateMissingCodexResume(G,x.error,J):null,_$=[x.error?O(x.error):x.state,a].filter(Boolean).join(";");_(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${_$}`);let X9=await this.stopOwnedProc(E,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,d1=x.state==="timeout"?`❌ ${v} 恢复超时${X9}`:`❌ ${v} 恢复失败: ${_$}${X9}`;if(Q?.(d1),j)await N(this.chatId,d1);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(d1),!1}if(this.proc!==E||!E.isAlive()){let a=`❌ ${v} 恢复期间已退出`;if(_(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(a),j)await N(this.chatId,a);return this.detachProc(E),this.status="stopped",this.opts.onLifecycleChange?.(),await P(a),!1}let i=this.withModel(this.withWorktreeInstructionNotice(x.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&x.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Q?.(i),j)await N(this.chatId,i);if(this.status=x.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),x.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await P(i)}catch(a){_(`session "${this.sessionName}": restart succeeded but status-card close failed: ${O(a)}`),await w(this.chatId,`⚠️ ${i}
245
+ 状态卡收尾失败: ${O(a)}`)}return!0}else{if($&&!V){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),j)await N(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{B$($,this.selectedProvider,this.workDir);let J=C4(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)n0(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)n0(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{n0(this.sessionName,J),this.pendingConversationMaterialization=J}catch(W){throw AggregateError([Q,W],`fork start and pending-intent restore failed: ${O(Q)}; ${O(W)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{B$($,this.selectedProvider,this.workDir);let Y=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Q=this.proc,W=this.lastSessionId,H=this.lastSessionRef,V=k4(this.sessionName).slice(),z=x4(this.sessionName),X=C4(this.sessionName),G={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,B=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,F2(this.sessionName,"codex");else if(this.lastSessionId=W,this.lastSessionRef=H,H)S4(this.sessionName,H);else F2(this.sessionName,this.selectedProvider);r$(this.sessionName,V,z,X),this.pendingConversationMaterialization=X,this.turnCounter=G.turnCounter,this.currentGoal=G.currentGoal,this.cumStats=G.cumStats,this.lastTurnDelta=G.lastTurnDelta,this.currentTurnUsageBaseline=G.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=G.currentTurnUsageBaselineKnown,this.lastTurnUsage=G.lastTurnUsage,this.usageTotalsSeedUnknown=G.usageTotalsSeedUnknown},L=!1;if(Y?.pendingLaunch)r$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,L=!0;this.pendingConversationLaunch=$;let A=(j)=>{K=H?.provider==="codex"&&H.sessionId===j};try{let j;try{j=$.kind==="fresh"?await this.restartUnlocked(!1,J,A):await this.restartUnlocked(!0,J,A)}catch(P){let S=null,F=this.proc&&this.proc!==Q?this.proc:null;if(F)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(C){S=C}let R=!F||this.proc!==F&&!F.isAlive();if(!R&&!S)S=Error("replacement process stop was not confirmed");let M=null;if(R)try{B()}catch(C){M=C}let k=[P,...S?[S]:[],...M?[M]:[]];if(k.length===1)throw P;throw AggregateError(k,`rollback launch and cleanup failed: ${k.map(O).join("; ")}`)}if(!j)return B(),!1;if(Y)try{if(!L)r$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(P){let S=null,F=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(C){S=C}let R=!F||this.proc!==F&&!F.isAlive();if(!R&&!S)S=Error("replacement process stop was not confirmed");let M=null;if(R)try{B()}catch(C){M=C}let k=[P,...S?[S]:[],...M?[M]:[]];if(k.length===1)throw P;throw AggregateError(k,`rollback branch commit failed: ${k.map(O).join("; ")}`)}return j}finally{this.pendingConversationLaunch=null}})}dispose(){H0.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Y=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return _(`session "${this.sessionName}": ${Y}`),this.lastTurnUserPreview="",Y}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Q)=>Q.proc===Z).length>=64)return _(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),_(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return m3(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${O(Z)}`;return _(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Y of this.pendingCodexTurnAnchors){if(Y.proc!==$||Z){J.push(Y);continue}if(Z=this.appendTurnAnchor(Y.anchor),Z)J.push(Y)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Q)=>Q.proc!==$);let Y=J-this.pendingCodexTurnAnchors.length;if(Y>0)_(`session "${this.sessionName}": dropped ${Y} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...y7(J.name,J.input));return Z}worktreeProjectName(){return W1(this)}worktreeProjectDir(){return m2(this)}spawnDeveloperInstructions(){return Uz(this)}delegatedAgentDeveloperInstructions($){return Oz(this,$)}worktreeInstructionLoadedNotice(){return uZ(this)}withWorktreeInstructionNotice($){return Tz(this,$)}worktreeExtraInstruction(){return Q9(this)}runWorktreeCommand($,Z){return Nz(this,$,Z)}showWorktrees(){return lZ(this)}showTasklistPanel(){return Zz(this)}showAgentIdentityPanel($=""){return dV(this,$)}onAgentIdentityPage($,Z,J){return nV($,Z,J)}onTasklistEnable(){return Jz(this)}onTasklistDeletePrompt($){return Yz(this,$)}onTasklistDeleteConfirm($){return Qz(this,$)}runCompactCommand(){return wV(this)}showModelPanel(){return vV(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>uV(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>xZ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return kZ(this,$,Z)}onModelPage($,Z,J){return G6(this,$,Z,J)}onModelAddOpen($,Z){return hV(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>IV(this,$,Z,J,Y))}onModelPanelCancel($=""){return cV(this,$)}onModelCustomPrompt($,Z,J=""){return gV(this,$,Z,J)}consumeModelCustomMessage($,Z){return mV(this,$,Z)}onWorktreeDisband($){return Sz(this,$)}showForkList($=""){return fz(this,$)}showBackList($=""){return vz(this,$)}showResumeList($=""){return hz(this,$)}runBtwCommand($){return Iz(this,$)}runByeCommand(){return gz(this)}onForkSelect($,Z,J=""){return mz(this,$,Z,J)}onBackSelect($,Z,J=""){return cz(this,$,Z,J)}onResumeSelect($,Z,J=""){return pz(this,$,Z,J)}runCommand($,Z=""){return bV(this,$,Z)}async buildConsoleOpts($,Z){let J=await CQ(),Y=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Y.provider,model:Y.model??void 0,effort:Y.effort??"MISS",worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...H0.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return L3(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Y=this.currentTokenSource(),Q=Y&&Y.agent===J&&Y.enabled?Y:this.selectedTokenSourceId?void 0:o9(J)[0];if(Q)Z.unifiedUsage=await Q.readUsage();else if(this.selectedTokenSourceId)Z.unifiedUsage={state:"no_credentials",windows:[],reason:`token source ${this.selectedTokenSourceId} unavailable`};else if(Z.provider==="claude")Z.glmUsage=await jH();else Z.usage=await M1(this.codexAccountId());if(!await G$($,U.consoleUsage,R4(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(W){Y=!1,_(`session "${this.sessionName}": ${Z} mutation failed: ${O(W)}`)}let Q=!1;try{Q=await j$($,{config:{streaming_mode:!1}})}catch(W){_(`session "${this.sessionName}": ${Z} streaming-off failed: ${O(W)}`)}if(!Y||!Q)return _(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await y$($)}catch(W){return _(`session "${this.sessionName}": ${Z} dispose failed: ${O(W)}`),!1}return Y}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Y=await this.buildConsoleOpts(void 0);await s$($.cardId);let Q=await G$($.cardId,U.footer,J8(Y,U.footer)),W=await o0($.cardId,Z8(Y),{type:"insert_after",targetElementId:U.footer}),H=await o0($.cardId,Y8(Y.sysinfo),{type:"insert_after",targetElementId:U.consoleProjects}),V=await o0($.cardId,R4(Y),{type:"insert_after",targetElementId:U.consoleHost});if(!Q||!W||!H||!V){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}F$($.cardId),await j$($.cardId,T0({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await u(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await t$(Z),p$(J,4)}catch(Y){_(`session "${this.sessionName}": console card conversion failed: ${O(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>_(`session "${this.sessionName}": console async update rejected: ${O(J)}`))}interrupt(){if(!this.proc)return;_(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){this.pendingUserMessageCount++;try{$.sendUserText(Z,[])}catch(J){throw this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),J}}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Y=this.beginTurnOpen();try{let W=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!W||this.currentTurn!==W)return;let H=this.startFooterTimer(W.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),V=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{V=G,H.setStatus(G)}});if(H.stop(),await s$(W.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(V.startsWith("❌")?V:"❌ 启动失败",{forcePush:!0});return}let X=this.proc;if(!X?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(W),this.sendClaimedUserText(X,Z),this.status="working"}finally{this.releaseTurnOpen(Y)}}async onUserMessage($,Z=[],J="",Y=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Y))}async onUserMessageUnlocked($,Z,J,Y){let Q=this.blockedProcessMessage();if(Q){await N(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await N(this.chatId,"❌ daemon 重启后的会话恢复尚未成功,这条消息未送给 Agent。请发送 rs 选择历史会话,或 hi 明确启动新会话,然后重发消息。");return}if(this.clearStaleIdleQueueState("user_message"),this.proc?.isAlive()&&!this.currentTurn&&!this.openingTurn&&this.pendingUserMessageCount===0&&this.pendingMidTurnMsgs.length===0)await this.stopIdleMismatchedProcessUnlocked();let W=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let V=(Z.length?Z.map((X)=>`[file: ${X}]`).join(" ")+`
246
+ `:"")+$,z=(X)=>{this.pendingReactionIds.set(X,""),(async()=>{let G=await c$(X,"OneSecond");if(!G)return;if(this.pendingReactionIds.has(X))this.pendingReactionIds.set(X,G);else if(this.currentBatchReactionIds.has(X))this.currentBatchReactionIds.set(X,G);else S$(X,G)})().catch((G)=>{_(`session "${this.sessionName}": reaction tracking failed: ${O(G)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)z(Y);return}await this.startColdUserTurn($,V,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)z(Y);return}if(!this.openingTurn&&this.initCount>=1){let X=this.proc,G=this.procEpoch,K=this.beginTurnOpen(X,G);try{this.pendingTurnInputs.push($);let B=await this.openTurnCard(K,J,"user_message");if(!B||this.currentTurn!==B)return;if(this.proc!==X||this.procEpoch!==G||!X.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(X.provider)} 已退出`);return}this.sendClaimedUserText(X,V),this.status="working"}finally{this.releaseTurnOpen(K)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:V,userOpenId:J,msgId:Y}),Y)z(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,V),W&&Y)z(Y)}hasPendingAsk(){return iH(this)}refreshPendingAsks(){s8(this)}askBlockReason($){return C2(this,$)}onMultiMessageInbound($,Z,J,Y){return UH(this,$,Z,J,Y)}clearMultiMsgBuffer($){n7(this,$)}onAskMessageAnswer($,Z,J){return dH(this,$,Z,J)}onAskAnswer($,Z,J,Y){return nH(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return QZ(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return eH(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=d0(this.sessionName,"codex");if(F2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)_(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=oZ(Z);if(!Y||!["thread/read","thread/resume","thread/fork"].includes(Y.method)||Y.serverCode!==-32600||Y.serverMessage!==`no rollout found for thread id ${$}`)return null;let Q=d0(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{F2(this.sessionName,"codex")}catch(H){let V=`已确认恢复点无 rollout,但作废失败: ${O(H)}`;return _(`session "${this.sessionName}": ${V} thread=${$}`),V}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let W=`已作废无 rollout 的恢复点 thread=${M$($)}`;return _(`session "${this.sessionName}": ${W} fullThread=${$}`),W}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Y=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Q=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Q){if(!Y)return null;let V=Error("Claude pending fork did not provide a materialized session id");if(_(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}let W={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let V=Error(`Claude fork did not materialize an independent session id (${Q})`);if(_(`session "${this.sessionName}": ${V.message}`),$)throw V;return V.message}try{S4(this.sessionName,W)}catch(V){let z=`会话恢复点持久化失败: ${O(V)}`,X=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;if(_(`session "${this.sessionName}": ${z}`),$)throw V;if(X&&J)w(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let V=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(V&&J)w(this.chatId,`⚠️ ${H}`);return H}return this.resumePersistenceError=null,null}consumePendingConversationMaterialization(){let $=this.pendingConversationMaterialization;if(!$)return null;let Z=this.lastSessionRef;if(Z?.provider!=="claude"||Z.cwd!==this.workDir||Z.sessionId===$.launch.source.sessionId||Z.sessionId===$.previousSessionId)return _(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return n0(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${O(J)}`;return _(`session "${this.sessionName}": ${Y}`),Y}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(c5(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}onBackgroundTaskChanged(){if(this.migratingBackgroundCard){this.pendingRebuildBackgroundCard=!0;return}if(!P1(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{_(`session "${this.sessionName}": background settle failed: ${O(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{_(`session "${this.sessionName}": background open failed: ${O(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=d5(Z,Date.now(),p1()),Y=await u(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))_(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await t$(Y)}catch(W){_(`session "${this.sessionName}": background card id_convert failed: ${W}`);return}if(p$(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((W)=>W.id)),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!P1(this.backgroundTasks)){this.settleBackgroundCard().catch((W)=>{_(`session "${this.sessionName}": background settle-after-open failed: ${O(W)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!P1(this.backgroundTasks))return;let Z=p1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(o$(Q))continue;let W=p0(J-Q.startedAt,Z).nextDelayMs;if(W<Y)Y=W}if(!isFinite(Y))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Y)))};$()}stopBackgroundRefreshTick(){if(this.backgroundRefreshTick)clearTimeout(this.backgroundRefreshTick),this.backgroundRefreshTick=null}scheduleBackgroundRefresh(){if(!this.backgroundCard||this.settlingBackgroundCard||this.migratingBackgroundCard)return;if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull()},1500)}refreshBackgroundCardFull(){if(this.migratingBackgroundCard)return;let $=this.backgroundCard;if(!$)return;let Z=Date.now(),J=p1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),o0($.cardId,H2(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else _(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else Z$($.cardId,H4.panel(Y.id),H2(Y,Z,J));k0($.cardId,g9(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!o$($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>o$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$})}if(this.pendingBgTasks=[],this.backgroundCard)await this.settleBackgroundCard();if(this.stopBackgroundRefreshTick(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.backgroundTasks=[],this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear()}async settleBackgroundCard(){if(this.migratingBackgroundCard)try{await this.migratingBackgroundCard}catch(J){_(`session "${this.sessionName}": background migration failed before settle; retry terminal snapshot: ${O(J)}`)}let $=this.backgroundCard;if(!$||this.settlingBackgroundCard)return;this.settlingBackgroundCard=!0;let Z=[...this.backgroundTasks];if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.stopBackgroundRefreshTick();try{if(await s$($.cardId),await q0($.messageId,m9(Z)),F$($.cardId),!await j$($.cardId,T0({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await y$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!o$(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&P1(this.backgroundTasks))this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(this.backgroundTasks.length>0)this.onBackgroundTaskChanged()}migrateBackgroundCard(){if(this.migratingBackgroundCard)return this.migratingBackgroundCard;let $=this.backgroundCard;if(!$)return Promise.resolve();let Z=this.performBackgroundCardMigration($),J;return J=Z.finally(()=>{if(this.migratingBackgroundCard===J)this.migratingBackgroundCard=null}),this.migratingBackgroundCard=J,J}async performBackgroundCardMigration($){if(this.backgroundCard!==$)return;if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;if(this.stopBackgroundRefreshTick(),await s$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(o$).map((W)=>W.id)),Y=J.size;if(Y>0)await q0($.messageId,m9(Z));else await q0($.messageId,n5());if(F$($.cardId),!await j$($.cardId,T0({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await y$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((W)=>!J.has(W.id)||!o$(W)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),_(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Y} active=${this.backgroundTasks.length}`)}startScheduledTurnCard($,Z,J,Y){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Q;try{Q=this.beginTurnOpen($,Z,!0)}catch(H){_(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${O(H)}`);return}let W=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${W.slice(0,78)}`,_(`session "${this.sessionName}": scheduled wakeup prompt=${Y??"MISS"}`),(async()=>{try{let H=await this.openTurnCard(Q,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(_(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),H&&this.currentTurn===H)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!H||this.currentTurn!==H){if(!this.ownsTurnOpen(Q))return;if(this.bgResumeCardless=!0,Q.sawResult)Q.sawResult=!1,_(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else _(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,_(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Q.terminalSuffix,{forcePush:Q.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Q)}})().catch((H)=>{_(`session "${this.sessionName}": scheduled turn-open handler failed: ${O(H)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Y=()=>this.proc===$&&this.procEpoch===J,Q=!1,W=!1,H=(V,z)=>{$.on(V,(X)=>{if(!Y()){if(!Q)Q=!0,_(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(V)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(V!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!W)W=!0,_(`session "${this.sessionName}": ignore ${$.provider} event=${String(V)} while process stop is pending`);return}z(X)})};H("error",(V)=>{_(`session "${this.sessionName}": ${$.provider} process error: ${V}`)}),H("init",()=>{if($.provider==="codex"&&$.quotaWaitPromise){if(this.daemonRestoreRequired=!1,this.status==="starting")this.status=this.currentTurn?"working":"idle";this.opts.onLifecycleChange?.()}if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,_(`session "${this.sessionName}": SDK init#${this.initCount} pendingCount=${this.pendingUserMessageCount} midBuffer=${this.pendingMidTurnMsgs.length} currentTurn=${this.currentTurn?"yes":"no"} openingTurn=${this.openingTurn}`),this.currentTurn||this.openingTurn){if(this.pendingUserMessageCount>0)_(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let V=this.pendingUserMessageCount>0,z=!V&&this.bgResumePending;if(!V&&!z)return;let X=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(L){_(`session "${this.sessionName}": init turn-open ownership conflict: ${O(L)}`);return}if(this.bgResumePending=!1,V)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=V?[...this.currentBatchReactionIds.keys()]:[],B=()=>{for(let L of K){let A=this.currentBatchReactionIds.get(L);if(this.currentBatchReactionIds.delete(L),A)S$(L,A)}};(async()=>{try{let L=await this.openTurnCard(G,X,V?"user_message":"bg_task_resume");if(!Y()){if(_(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),L&&this.currentTurn===L)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);B();return}if(!L||this.currentTurn!==L){if(!this.ownsTurnOpen(G)){B();return}if(G.sawResult&&G.terminalSuffix)w(this.chatId,G.terminalSuffix);if(V)_(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),B();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,_(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else _(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,_(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(G.terminalSuffix,{forcePush:G.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(G)}})().catch((L)=>{_(`session "${this.sessionName}": init turn-open handler failed: ${O(L)}`)})}),H("scheduled_turn_input",({text:V,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,V,z)}),H("conversation_materialized",({session_id:V,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==V){_(`session "${this.sessionName}": ignore mismatched Codex materialization session=${V} current=${$.sessionId??"MISS"} source=${z}`);return}_(`session "${this.sessionName}": Codex resume point materialized thread=${V} source=${z}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:V,source:z,error:X})=>{if($.provider!=="codex"||$.sessionId!==V)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${O(X)}`,K=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,_(`session "${this.sessionName}": ${G} thread=${V} source=${z}`),K)w(this.chatId,`⚠️ ${G}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("codex_account_changed",({accountId:V,diagnostics:z})=>{if(_(`session "${this.sessionName}": Codex account=${V}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)u(this.chatId,Y0({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
247
+ `),hint:"详情:codex-accounts"})).catch((X)=>{_(`session "${this.sessionName}": 账号诊断卡失败: ${O(X)}`)})}),H("turn_started",({retry:V})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)_(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),V){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let z=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!z){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=z?{...z}:null,this.currentTurnUsageBaselineKnown=!0}),H("token_usage",({totalUsage:V})=>{if(this.persistResumableSessionId(),V)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(V)=>{this.handleTurnPlanUpdated(V)}),H("plan_delta",(V)=>{this.handlePlanDelta(V)}),H("context_compacted",(V)=>{this.handleContextCompacted(V)}),H("rate_limits_updated",(V)=>{if($.provider==="codex")PQ(V,U0($))}),H("thread_goal_updated",(V)=>{this.handleThreadGoalUpdated(V)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:V,parentToolUseId:z})=>{if(z)return;this.appendAssistant(V)}),H("assistant_block_stop",({parentToolUseId:V})=>{if(V)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:V,name:z,input:X,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(u5({active:this.backgroundTasks,pending:this.pendingBgTasks},G,V,z,X)),this.onBackgroundTaskChanged();return}if(rH(this,V,z,X),!G)this.onMainThreadAdvance();if(!G&&(z==="Task"||z==="Agent"))this.lastMainTaskToolUseId=V}),H("tool_result",({tool_use_id:V,content:z,is_error:X,parentToolUseId:G,input:K})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(i5({active:this.backgroundTasks,pending:this.pendingBgTasks},G,V,z,X)),this.onBackgroundTaskChanged();return}tH(this,V,z,X,K)}),H("can_use_tool",(V)=>{$V(this,V)}),H("hook_callback",(V)=>{this.proc?.sendHookResponse(V.request_id,{})}),H("result",(V)=>{let z=this.persistResumableSessionId(),X=z?null:this.consumePendingConversationMaterialization(),G=[z,X].filter(Boolean).join(";")||null;if(this.accumulateResultStats(),this.openingTurnOwner)this.openingTurnOwner.sawResult=!0;if(this.userInterrupted){this.userInterrupted=!1,this.discardOrphanAssistant(),this.bgResumePending=!1;let M=this.proc?.lastResult.subtype??"unknown",k=this.proc?.lastResult.is_error===!0;_(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${k} — ignored`),this.status="idle";return}let K=V?.is_error!==!0?this.recordTurnAnchor(V?.checkpoint):null;if(V?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let B=this.pendingMidTurnMsgs.length>0,L=this.proc?.lastResult.is_error===!0,A=this.proc?.lastResult.subtype??"success",j=typeof V?.error==="string"&&V.error.trim()?V.error.trim():A,P,S=!1,F=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),R=[G,K].filter(Boolean).join(";")||null;if(R)P=`⚠️ ${R}`,S=!0;else if(B)P=L?`⚠️ ${F} ${j},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(L)P=`⚠️ ${F} ${j}`,S=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=P,this.openingTurnOwner.terminalForcePush=S;if(R&&!this.currentTurn&&!this.openingTurn)w(this.chatId,`⚠️ ${R}`);if(_(`session "${this.sessionName}": SDK result subtype=${A} isError=${L} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${S}`),this.closeTurnCard(P,{forcePush:S,hasFreshResult:!0}).catch((M)=>{_(`session "${this.sessionName}": result card close failed: ${O(M)}`)}),this.status="idle",B)this.drainMidTurnAndOpen().catch((M)=>{_(`session "${this.sessionName}": mid-turn drain failed: ${O(M)}`)})}),H("bg_task_started",(V)=>{let z=V.tool_use_id??this.lastMainTaskToolUseId??void 0;_(`session "${this.sessionName}": bg_task_started task=${V.task_id} type=${V.task_type??"-"} subagent=${V.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(V.description??"").slice(0,40)}`),this.applyBgStore(I5(this.bgStore(),{...V,tool_use_id:z})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(V)=>{this.applyBgStore(g5(this.bgStore(),V)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(V)=>{this.applyBgStore(m5(this.bgStore(),V)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(V)=>{if(_(`session "${this.sessionName}": bg_task_settled task=${V.task_id} status=${V.status}`),this.applyBgStore(p5(this.bgStore(),V)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(V)=>{this.applyBgStore(l5(this.bgStore(),V.thread_id,V.item_id,V.tool,V.phase,V.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:V,signal:z,expected:X})=>{if(_(`session "${this.sessionName}": ${$.provider} exited code=${V} signal=${z} expected=${X}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let A=$.conversationMaterializationFailure?.(),j=this.persistResumableSessionId(!1,$,!1),P=[A&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${O(A)}`:null,j].filter(Boolean).join(";");if(P)w(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${P}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}_(`session "${this.sessionName}": blocked/stopping ${$.provider} exit confirmed`),this.detachProc($),this.status="stopped",this.opts.onLifecycleChange?.();return}this.discardPendingCodexTurnAnchors($,"unexpected process exit"),this.cancelAgentRuns(`${$.provider} process exited`).catch((A)=>{_(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${O(A)}`)});let G=this.backendLabel($.provider),K=`code=${V??"null"}, signal=${z??"null"}`,B=X?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(B).catch((A)=>{_(`session "${this.sessionName}": process-exit current main-card close failed: ${O(A)}`)});let L=this.waitForTurnCloses().catch((A)=>{_(`session "${this.sessionName}": process-exit main-card close failed: ${O(A)}`)});this.detachProc($),this.flushOrphanAssistantToChat("process exit"),this.bgResumePending=!1,this.bgResumeCardless=!1,this.clearMultiMsgBuffer("process exit"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.userInterrupted=!1,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped",this.opts.onLifecycleChange?.(),this.runLifecycle("process-exit-cleanup",async()=>{let A=await Promise.allSettled([L,this.resetBackgroundTasks()]);for(let j of A)if(j.status==="rejected")_(`session "${this.sessionName}": process-exit terminal cleanup failed: ${O(j.reason)}`);if(!X)await N(this.chatId,`⚠️ ${G} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((A)=>{_(`session "${this.sessionName}": process-exit cleanup rejected: ${O(A)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?L5(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=j5(Z),Y=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Q=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Y,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Y,durationMs:Q}}currentContextTokens($=this.proc){if($?.provider==="claude"||$?.provider==="dsh")return $.lastContextTokens??null;let Z=$?.lastUsage;return O8(Z)}contextLimitForDisplay($=this.proc){return T8($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;if(!await this.waitForTurnOpenSlot($,Z))return;if(this.currentTurn||this.openingTurn||this.pendingMidTurnMsgs.length===0)return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){_(`session "${this.sessionName}": mid-turn open ownership conflict: ${O(Q)}`);return}let Y=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let z of Y)if(this.pendingTurnInputs.push(z.text),z.msgId){let X=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,X),this.pendingReactionIds.delete(z.msgId)}let Q=Y.map((z)=>z.wireText).join(`
248
+
249
+ `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,V=await this.openTurnCard(J,H,"user_message");if(!V||this.currentTurn!==V){for(let z of Y){if(!z.msgId)continue;let X=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),X)S$(z.msgId,X)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let z of Y){if(!z.msgId)continue;let X=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),X)S$(z.msgId,X)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(z){_(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${z}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await w(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${O(z)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Y=J?await G$($,U.footer,this.footerElement(Z)):!0;F$($);let Q=await j$($,T0({suffix:Z}));if(Y&&Q){await y$($);return}let W=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;_(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${W}`),await w(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${W})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{_(`session "${this.sessionName}": background rebuild after turn-open failure failed: ${O($)}`)})}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&P1(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(A){_(`session "${this.sessionName}": background migrate failed (non-blocking): ${A}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,W=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=W[0]?.slice(0,80)??this.lastTurnUserPreview,_(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${W.length}`);let H=this.runtimeModelSelection(),V=this.withModel(Y.initialFooter??"Waiting...(0s)",H),z=k8({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort??"MISS",kind:J,userInputs:W,initialFooter:V,directStart:Y.directStart}),X=await u(this.chatId,z);if(!X){if(!this.ownsTurnOpen($))return null;if(_(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await w(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return this.rebuildBackgroundAfterTurnOpenFailure(),null}let G;try{G=await t$(X)}catch(A){if(_(`session "${this.sessionName}": id_convert failed: ${A}`),J==="user_message"&&this.ownsTurnOpen($))await w(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let K=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(W.length>0?1:0)+1;if(!this.ownsTurnOpen($))return p$(G,K),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let B={cardId:G,...H,messageId:X,userOpenId:Z,trigger:J,toolCount:0,toolByUseId:new Map,planSteps:[],planExplanation:null,planUpdateCount:0,goalUpdateCount:0,contextCompactCount:0,contextCompactionPending:new Map,contextCompactionCompleted:new Set,contextCompactionCompleting:new Set,contextCompactionEndOnly:new Map,lastContextCompactionCompletedAt:0,lastContextCompactionWasAnonymous:!1,toolBatches:new Map,openBatchI:null,taskCreateI:null,taskUpdateI:null,taskBoardResetThisTurn:!1,taskLiveInserted:!1,planLiveInserted:!1,assistantSegmentCount:0,currentAssistantSegmentId:null,currentAssistantText:"",segmentTexts:new Map,startedAt:Date.now(),footerStatusHandle:null,footerStatusStartedAt:0,footerStatusLabel:null,rotating:null,rotateCount:0,failureRotateCount:0,cardCapacityFailures:new Map,cardWriteFailureNotices:new Set,cardRotationFailed:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(p$(G,K,(A,j)=>{this.onCardWriteFailure(B,G,A,j)}),this.currentTurn=B,Y.startThinking!==!1)this.startThinkingFooter(B);if($.pendingCompactions.length>0){let A=$.pendingCompactions.splice(0);_(`session "${this.sessionName}": replay ${A.length} context compaction event(s) buffered during card open`);for(let j of A)this.handleContextCompacted(j)}let L=this.takeOrphanAssistantText();if(L)this.appendAssistant(L),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((A)=>{_(`session "${this.sessionName}": background rebuild failed: ${O(A)}`)})}return B}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&Q7($.cardId)<IP)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){_(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){_(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Q.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Q.rotating)return;if(Q.cardRotationFailed)return;if(!Y7(J,Y)){let H=Y?.operation??"unknown operation",V=Y?.elementId?` element=${Y.elementId}`:"";_(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${V} code=${J??"n/a"} — not rotating`);let z=`${Z}:${H}:${Y?.elementId??""}:${J??"MISS"}`;if(!Q.cardWriteFailureNotices.has(z))Q.cardWriteFailureNotices.add(z),w(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H}${V})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let W=Y?.capacityFingerprint;if(W){let H=Q.cardCapacityFailures.get(W);if(H!==void 0){if(_(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Y.operation} element=${Y.elementId??"MISS"} code=${J??"MISS"}`),!H)Q.cardCapacityFailures.set(W,!0),w(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(W,!1)}_(`session "${this.sessionName}": confirmed card capacity limit (${J}) on card=${Q.cardId.slice(0,8)}… — rotating to fresh card`),Q.failureRotateCount++,this.startMidTurnRotate(Q)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Y}=$,Q={value:null},W=(H,V)=>{if(!Q.value)Q.value={code:H,failure:V}};$.rotating=(async()=>{try{_(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${Q7(Z)}`);let H=k8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),V=await u(this.chatId,H);if(!V){if(_(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await w(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let z;try{z=await t$(V)}catch(j){if(_(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${j}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await w(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}p$(z,2,(j,P)=>{if($.rotating){W(j,P);return}this.onCardWriteFailure($,z,j,P)});let X=$.assistantWriteInflight?.get(Z);if(X?.size)await Promise.allSettled([...X]);this.stopFooterStatus($),$.cardId=z,$.cardRotationFailed=!1,$.messageId=V,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,K=$.currentAssistantText??"",B=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&K){let j=U.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=j,$.currentAssistantText=K,$.segmentTexts.set(j,K)}if(K)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)D$($.cardId,y1(this.taskBoard),{type:"insert_before",targetElementId:U.footer});if($.planLiveInserted)D$($.cardId,h4($.planSteps,$.planExplanation,U.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?U.taskBoardLive:U.footer});for(let j of $.contextCompactionPending.values()){if(j.cardId!==Z)continue;j.cardId=z,j.created=!1,j.createFailure=void 0;let P=U.contextCompact(j.i);j.createPromise=R8(z,v4(j.i,j.notice,P),{type:"insert_before",targetElementId:R$($)}).then((S)=>{if(j.cardId===z)j.created=S.landed,j.createFailure=S.failure;return S.landed})}for(let[j,P]of B){if(G&&K&&j===G)continue;if(!U2(Z,j))continue;let S=$.assistantSegmentCount++,F=U.assistant(S);$.segmentTexts.set(F,P),await this.addCompletedAssistantSegment($,F,P)}VZ(this,Z,z,J,Y,$),await s$(Z),VZ(this,Z,z,J,Y,$);let L=new Set([U.taskBoardLive,U.planLive,...[...$.contextCompactionPending.values()].map((j)=>U.contextCompact(j.i))]);if(G)L.add(G);for(let j of J.values())if(j.output==null)L.add(U.tool(j.i));if(AW(Z).some((j)=>!L.has(j)))$.cardCapacityFailures.clear();await s$(z);try{await HZ($,Z);let j=$.mathRenderInflight?.get(Z);if(j?.size)await Promise.allSettled([...j]);await s$(Z);let P=$.mathRendered?.get(Z);for(let[M,k]of B){if(G&&K&&M===G)continue;if(U2(Z,M))continue;if(P?.has(M))continue;await Z$(Z,M,this.completedAssistantElement(M,k))}let S=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",F=await G$(Z,U.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${S}`)),{notifyCardFailure:!1});F$(Z);let R=await j$(Z,T0({suffix:"\uD83D\uDCE8 转下一张"}));if(F&&R)await y$(Z);else _(`session "${this.sessionName}": rotate old-card terminal MISS footer=${F} settings=${R}`),await w(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${F?"ok":"MISS"}, settings=${R?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(j){_(`session "${this.sessionName}": mid-turn rotate close-old failed: ${j}`)}_(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${z.slice(0,8)}…`)}finally{$.rotating=null;let H=Q.value;if(H&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,H.code,H.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=U.planUpdate($.planUpdateCount++);D$(Z,G7($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:R$($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=U.goalUpdate(Z.goalUpdateCount++);D$(Z.cardId,_7($,J),{type:"insert_before",targetElementId:R$(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=U.goalUpdate($.goalUpdateCount++);D$($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
250
+
251
+ 已清除`},{type:"insert_before",targetElementId:R$($)})}handleContextCompacted($){let Z=iz($);if(this.manualContextCompactionPending){if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");if($.phase!=="start")this.lastManualContextCompactionCompletedAt=Date.now(),this.lastManualContextCompactionWasAnonymous=Z.length===0;_(`session "${this.sessionName}": manual context compaction ${$.phase??"event"} handled by command status card`);return}if($.phase==="start")this.lastManualContextCompactionWasAnonymous=!1;else if((Z.length===0||this.lastManualContextCompactionWasAnonymous)&&Date.now()-this.lastManualContextCompactionCompletedAt<U6){_(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((F)=>F.startsWith("turn:")),W=Y??Q,H=W?this.contextCompactionReceipts.get(W):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let F=this.contextCompactionReceipts.get(Q);if(!F?.hasItemAlias&&F?.completed&&Date.now()-F.completedAt<U6||!F?.hasItemAlias&&F?.completionKey&&J?.contextCompactionCompleting.has(F.completionKey))W=Q,H=F,F.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,F)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),_(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");_(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(W&&H?.completed){_(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${W}`);return}let V=this.contextCompactionOwnerId(J);if(W&&H&&H.ownerId!==V){this.rememberContextCompactionReceipt(Z,null,!0),_(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${W} (turn owner changed)`);return}if(W&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){_(`session "${this.sessionName}": context compaction alias already writing receipt=${W}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){_(`session "${this.sessionName}": identified context compaction duplicate ignored while anonymous completion writes`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.lastContextCompactionWasAnonymous&&Date.now()-J.lastContextCompactionCompletedAt<U6){_(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let F=yP($);if(J.contextCompactionPending.has(F)||J.contextCompactionCompleted.has(F)){_(`session "${this.sessionName}": duplicate context compaction start ignored key=${F}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,V,!1);let R=J.contextCompactCount++,M=J.cardId,k=U.contextCompact(R),C={i:R,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};C.createPromise=R8(M,v4(R,$,k),{type:"insert_before",targetElementId:R$(J)}).then((c)=>{if(C.cardId===M)C.created=c.landed,C.createFailure=c.failure;return c.landed}),J.contextCompactionPending.set(F,C),_(`session "${this.sessionName}": context compaction start #${R+1} key=${F}`),k0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){_(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<U6){_(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){_(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let X=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:wP(J),G=X?J.contextCompactionPending.get(X):void 0,K=X??z??"__anonymous__";if(J.contextCompactionCompleting.has(K)){_(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let B=fP(G?.notice,$),L=J.contextCompactionEndOnly.get(K),A=G?.i??L??J.contextCompactCount++;if(!G&&L===void 0)J.contextCompactionEndOnly.set(K,A);J.contextCompactionCompleting.add(K);let j=[...new Set([...iz(G?.notice??{}),...Z])];if(j.length>0)this.rememberContextCompactionReceipt(j,V,!1,K);let P=U.contextCompact(A),S=v4(A,B,P);_(`session "${this.sessionName}": context compaction completion write #${A+1} key=${K}`),(async()=>{let F=!1;if(!G)while(!0){let R=J.cardId;if(F=await o0(R,S,{type:"insert_before",targetElementId:R$(J)}),F)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==R)continue;break}else while(!0){let R=G.cardId;if(await G.createPromise,G.cardId!==R)continue;if(G.created)F=await G$(R,P,S);else{if(BW(G.createFailure?.code,G.createFailure))qW(R,P),F=await G$(R,P,S,{notifyCardFailure:!1});if(!F)F=await o0(R,S,{type:"insert_before",targetElementId:R$(J)})}if(G.cardId!==R)continue;if(F){G.created=!0;break}let M=J.rotating;if(M){await M;continue}if(G.cardId!==R)continue;break}if(J.contextCompactionCompleting.delete(K),!F){_(`session "${this.sessionName}": context compaction completion write MISS #${A+1} key=${K}`);return}if(X&&J.contextCompactionPending.get(X)===G)J.contextCompactionPending.delete(X);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",j.length>0){let R=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===K).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...j,...R])],null,!0)}_(`session "${this.sessionName}": context compaction completed #${A+1} key=${K}`)})().catch((F)=>{J.contextCompactionCompleting.delete(K),_(`session "${this.sessionName}": context compaction completion transaction failed: ${O(F)}`)}),k0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Y){let Q={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Y?{}:{completionKey:Y},hasItemAlias:$.some((W)=>W.startsWith("item:"))};for(let W of $)this.contextCompactionReceipts.delete(W),this.contextCompactionReceipts.set(W,Q);while(this.contextCompactionReceipts.size>gP){let W;for(let H of this.contextCompactionReceipts.values()){if(H.completed){W=H;break}W??=H}if(!W)break;for(let[H,V]of this.contextCompactionReceipts)if(V===W)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){_(`session "${this.sessionName}": turn/plan/updated with no current turn`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openBatchI=null,!Array.isArray($.plan))_(`session "${this.sessionName}": turn/plan/updated missing plan array`),Z.planSteps=[];else Z.planSteps=$.plan.map((J)=>({step:typeof J.step==="string"&&J.step?J.step:"MISS",status:typeof J.status==="string"&&J.status?J.status:"MISS"}));if(Z.planExplanation=typeof $.explanation==="string"?$.explanation:null,Z.planSteps.length>0)if(!Z.planLiveInserted){let J=Z.taskLiveInserted?U.taskBoardLive:U.footer;Z.planLiveInserted=!0,D$(Z.cardId,h4(Z.planSteps,Z.planExplanation,U.planLive),{type:"insert_before",targetElementId:J})}else Z$(Z.cardId,U.planLive,h4(Z.planSteps,Z.planExplanation,U.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){_(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)_(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){_(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")_(`session "${this.sessionName}": thread/goal/updated invalid tokenBudget`);let Z=this.currentGoal,J={objective:$.objective,status:typeof $.status==="string"&&$.status?$.status:"MISS",tokenBudget:typeof $.tokenBudget==="number"?$.tokenBudget:$.tokenBudget===null?null:Number.NaN,tokensUsed:typeof $.tokensUsed==="number"?$.tokensUsed:Number.NaN,timeUsedSeconds:typeof $.timeUsedSeconds==="number"?$.timeUsedSeconds:Number.NaN};if(this.currentGoal=J,Z&&S8(Z)===S8(J))return;let Y=this.currentTurn;if(Y){if(this.startWorkingFooter(Y),Y.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Y.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let W=Z.assistantSegmentCount++,H=U.assistant(W);Z.currentAssistantSegmentId=H,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Q=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);k0(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
252
+
253
+ `).trim()}discardOrphanAssistant(){this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",this.bgResumeCardless=!1}flushOrphanAssistantToChat($){let Z=this.takeOrphanAssistantText();if(!Z)return;let J=this.cleanAssistantTextForDisplay(Z).trim();if(!J)return;_(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),N(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
254
+
255
+ ${J}`)}completedAssistantElement($,Z){if(t7(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Y)=>Y.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Y.text).trim()||" "}:{...Y.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Y){let Q=await vH(Y);if(!await G$(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){_(`session "${this.sessionName}": math render ${J} write dropped (card closed/element dead) — raw text stays`);return}$.mathRendered??=new Map,$.mathRendered.get(Z)??$.mathRendered.set(Z,new Set),$.mathRendered.get(Z).add(J),_(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=R$($),W=(async()=>{if(!await o0(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return _(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(t7(J)){let V=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((z)=>_(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(V),V.finally(()=>$.mathRenderInflight?.get(Y)?.delete(V))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(W),W.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(W)),W}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
256
+
257
+ ${J}`;if(!await N(this.chatId,Y))_(`session "${this.sessionName}": ASSISTANT_TEXT_PRESERVATION_FAILED (${Z}, ${J.length} chars)`)}finalizeCurrentAssistantSegment(){let $=this.currentTurn;if(!$){if(this.orphanAssistantCurrent.trim())this.orphanAssistantSegments.push(this.orphanAssistantCurrent);this.orphanAssistantCurrent="";return}if($.cardRotationFailed)this.maybeMidTurnRotate();if($.rotating)return;let Z=$.currentAssistantSegmentId,J=$.currentAssistantText??"";if(Z&&J.trim())this.addCompletedAssistantSegment($,Z,J),this.startWorkingFooter($);$.currentAssistantSegmentId=null,$.currentAssistantText=""}processOutboundMarkers($){for(let Z of PH($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return e($)}sendOutboundPath($,Z){let J=a8($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!bP(J)){_(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),_(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),w4(this.chatId,J)}startFooterStatus($,Z){if($.cardRotationFailed)return;let J=$.provider==="codex"?this.proc?.turnRetry:null;if(J)Z=J.reason==="quota"?`⏳ ${J.message}`:J.phase==="waiting"?`⏳ 模型满载 · ${J.delayMs/1000}s 后重试 #${J.attempt}`:`⏳ 模型满载 · 正在重试 #${J.attempt}`;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Y=()=>{if($.footerStatusLabel!==Z)return;let{label:W}=p0(Date.now()-$.footerStatusStartedAt,p1()),H=Z===dz?this.proc?.lastThinkingTokens:null,V=typeof H==="number"?` · 约 ${H} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${V} (${W})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:W}=p0(Date.now()-$.footerStatusStartedAt,p1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(W)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,dz)}startWritingFooter($){this.startFooterStatus($,vP)}startWorkingFooter($){this.startFooterStatus($,hP)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Y,Q){if(J&&(!Y||!Y.enabled||Y.agent!==$))return" | 额度 MISS";if(Y?.agent===$&&Y.enabled&&($==="claude"||$==="dsh")){let W=await Y.readUsage();if(W.state==="ok"&&W.kind!=="balance"){let H=W.windows.find((z)=>z.kind==="fiveHour"),V=W.windows.find((z)=>z.kind==="weekly");if(H||V)return this.fmtDualWindowSuffix(H??null,V??null)}return` | ${Q8(W)}`}if($==="codex"){let W=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,H=W?await s9(()=>W.readRateLimits(),U0(W)):null,V=W?H:Q;return V?.state==="ok"?this.fmtDualWindowSuffix(V.fiveHour??null,V.weekly??null):" | 额度 MISS"}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(W)=>{if(!W)return null;if(W.percent==null)return"MISS";let H=W.resetsAt&&W.resetsAt.getTime()>Date.now()?F4(W.resetsAt):"",V=`${Math.round(W.percent)}%`;return H?`${H}·${V}`:V},Y=J($),Q=J(Z);if(Y&&Q)return` | ${Y}·[${Q}]`;if(Y)return` | ${Y}`;if(Q)return` | [${Q}]`;return" | 额度 MISS"}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Y)=>Y.status==="rejected").map((Y)=>Y.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(O).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)S$(Z,J)}closeTurnCard($,Z={}){let J=this.currentTurn;if(!J)return this.waitForTurnCloses();if(!$&&J.cardRotationFailed)this.maybeMidTurnRotate();this.currentTurn=null,this.stopFooterStatus(J);let Y=this.proc,Q={turn:J,proc:Y,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Y),contextLimit:this.contextLimitForDisplay(Y),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:Y?.provider==="codex"?V$(Y.tokenSourceId??this.selectedTokenSourceId,U0(Y)):this.currentTokenSource(),codexUsage:MQ(U0(Y)),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let W=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(W),W.then(()=>{this.turnCloseInflight.delete(W)},()=>{this.turnCloseInflight.delete(W)}),W}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;await HZ(Y),this.stopFooterStatus(Y);let Q=((Date.now()-Y.startedAt)/1000).toFixed(1),W=Y.cardId,H=Y.segmentTexts;await s$(W);let V=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:R,currentAssistantText:M}=Y;if(!await this.addCompletedAssistantSegment(Y,R,M))V.set(R,M);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let z=Y.assistantWriteInflight?.get(W);if(z?.size)await Promise.allSettled([...z]);let X=Y.mathRenderInflight?.get(W);if(X?.size)await Promise.allSettled([...X]);let G=Y.mathRendered?.get(W);for(let[R,M]of H){if(U2(W,R)){V.set(R,M);continue}if(G?.has(R))continue;await Z$(W,R,this.completedAssistantElement(R,M))}if(Y.cardRotationFailed)for(let[R,M]of H)V.set(R,M);let K=Z?Z:"✅",B=[`${K} ⏱ ${Q}s`];if(J.hasFreshResult){let{contextTokens:R,contextLimit:M}=$,k=Y.provider==="claude",C=z7(R,M,k?0:void 0);if(C)B.push(`\uD83E\uDDE0 ${C}`);let c=$.lastTurnDelta?.costUsd??0;if(c>0)B.push(`\uD83D\uDCB0 $${c.toFixed(3)}`)}if(Y.contextCompactCount>0)B.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)B.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let L=this.modelLine(Y);if(L)B.push(L);let A=B.join(" | "),j=J.hasFreshResult?X7($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",P=j?`${A}
258
+ ${j}`:A,S=await G$(W,U.footer,this.footerElement(P));F$(W);let F=await j$(W,T0({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(S&&F)await y$(W);else{let R=`footer=${S?"ok":"MISS"}, settings=${F?"ok":"MISS"}`;_(`session "${this.sessionName}": terminal card transaction incomplete card=${W.slice(0,12)} ${R}`),await w(this.chatId,`⚠️ 对话卡片终态写入失败 (${R})。本轮已结束: ${K}`)}for(let R of V.values())await this.sendAssistantTextFallback(R,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)N1(Y.messageId,[Y.userOpenId])}}});function Z0($){return{card:{type:"raw",data:$}}}import{randomUUID as mP}from"node:crypto";function rZ($){return{session_name:$.sessionName,chat_id:$.chatId,status:$.status,running:$.isRunning(),native_session_id:$.proc?.sessionId??null,codex_account:$.proc?.provider==="codex"&&$.proc.isAlive()?{name:y.get(U0($.proc)).name,mode:$.proc.codexAccountSelectionMode?.()??"native",policy:"highest-score-plus-5h-ultra-pro-0.5"}:null,busy:!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount||$.pendingMidTurnMsgs.length),awaiting_model_input:!!$.modelCustomPrompt,last_result:$.proc?{anchor:$.proc.lastAssistantUuid,subtype:$.proc.lastResult.subtype,is_error:$.proc.lastResult.is_error}:null,selection:{provider:$.selectedProvider,source_id:$.selectedTokenSourceId,model:$.selectedModel,effort:$.selectedEffort},panels:[...$.modelPanels].map(([Z,J])=>({panel_id:Z,message_id:J.messageId,source_id:J.sourceId,mode:J.mode,editable:J.editable,total_models:J.catalog?.length,page:J.page,total_pages:J.totalPages,models:J.models.map((Y)=>({model:Y.model,provider:Y.provider,source_id:Y.sourceId,efforts:Y.efforts.map((Q)=>Q.effort),origin:Y.origin}))})),sources:O0().map((Z)=>({id:Z.id,display:Z.display,agent:Z.agent,enabled:Z.enabled,validates_custom_model:!!Z.verifyModel,status:Z.modelCatalogState?.status,error:Z.modelCatalogState?.error,models:Z.models.map((J)=>({model:J.model,efforts:J.efforts,default_effort:J.defaultEffort,unavailable_reason:J.unavailableReason,origin:J.origin}))}))}}function oz($,Z,J,Y,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let W=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(W.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof W.message_id!=="string"||!W.message_id.startsWith("om_"))throw Error("message_id required");if(!Q||W.message_id!==Q)throw Error("stale or mismatched model panel");if(!J||J.message_id!==W.message_id||J.chat_id!==Z.chat_id||J.msg_type!=="interactive"||J.sender?.sender_type!=="app"||J.sender.id!==Y)throw Error("model card must belong to this app and debug chat");if(!W.value||typeof W.value!=="object"||Array.isArray(W.value))throw Error("action value required");let H={};for(let[V,z]of Object.entries(W.value)){if(!pP.has(V))throw Error(`unsupported model action field: ${V}`);if(V==="page"){if(typeof z!=="number"||!Number.isSafeInteger(z)||z<0)throw Error("invalid page");H.page=z}else{if(typeof z!=="string"||!z.trim()||z.length>1024)throw Error(`invalid ${V}`);H[V]=z.trim()}}if(!cP.has(String(H.kind)))throw Error("only model panel actions are supported");for(let V of["panel_id","source_id"])if(!H[V])throw Error(`${V} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(H.kind))&&!H.model)throw Error("model required");if(H.kind==="model_effort_select"&&!H.effort)throw Error("effort required");if(H.kind==="model_page"&&H.page===void 0)throw Error("page required");if(H.kind==="model_list_open"&&H.mode!=="select"&&H.mode!=="add")throw Error("invalid model list mode");if(H.provider!==void 0&&!z0(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${mP()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:W.message_id},action:{tag:"button",value:H}}}var cP,pP;var rz=T(()=>{P$();Y$();I$();cP=new Set(["provider_select","model_select","model_effort_select","model_page","model_list_open","model_add","model_remove","model_custom_remove","model_custom_prompt","model_panel_cancel"]),pP=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as uP}from"node:http";import{randomUUID as lP}from"node:crypto";function $X($){if($.allowReply&&$.buttons?.length)throw Error(ez);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Q=new Date,W=`${String(Q.getHours()).padStart(2,"0")}:${String(Q.getMinutes()).padStart(2,"0")}`,H=[];for(let z of $.images??[])if(z.key)H.push({tag:"img",img_key:z.key,alt:{tag:"plain_text",content:"screenshot"}});else H.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${z.src}</font>`});if(H.push({tag:"markdown",content:w5($.text??"")||"_(空消息)_"}),$.resolution){let z=$.resolution,X=z.kind==="text"?"已回复":`已选择:${z.text}`,G;if(z.status==="processing")G=`<font color='blue'>⏳ ${X} · 推送中…</font>`;else if(z.status==="failed")G=`<font color='red'>⚠️ ${z.kind==="text"?X:`已选:${z.text}`} · 回调失败:${e(z.detail??"未知")} · ${W}</font>`;else if(z.status==="delivered")G=`<font color='green'>✅ ${X} · 反馈已送达 · ${W}</font>`;else if(z.status==="unknown")G=`<font color='red'>⚠️ ${X} · ${z.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${W}</font>`;else G=`<font color='green'>✅ ${X} · ${W}</font>`;if(H.push({tag:"markdown",content:G}),z.status==="delivered"&&z.reply)H.push({tag:"markdown",content:e(z.reply)})}let V=Y&&(!$.resolution||$.resolution.status==="failed");if(V&&$.buttons?.length)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((z)=>({tag:"button",text:{tag:"plain_text",content:z.text},type:z.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:z.id}}]}))}]});if(H.push({tag:"hr"}),H.push({tag:"markdown",content:`<font color='grey'>via notify · ${W}</font>`}),V&&$.allowReply)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"回复"},type:"primary",behaviors:[{type:"callback",value:{kind:"notify_reply",notify_id:$.notifyId}}]}]}]});return{schema:"2.0",config:Y?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:H}}}function H1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},W=[{tag:"markdown",content:`通知:${e($.title)}`}];if(Z.response)W.push({tag:"markdown",content:e(Z.response.text)});if(Y==="waiting")W.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
259
+ 你的下一条文字优先用于这条通知,完成后再回答 Agent 的提问。点击其他通知的「回复」会放弃本次回复;群控制命令仍然优先。`}),W.push({tag:"button",text:{tag:"plain_text",content:"取消回复"},type:"default",behaviors:[{type:"callback",value:{kind:"notify_reply_cancel",notify_id:$.notifyId,reply_id:Z.id}}]});if(Y==="cancelled"&&Z.cancelReason==="switched")W.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let H=J?.detail??Z.error;if(H)W.push({tag:"markdown",content:`<font color='red'>${e(H)}</font>`});if(Y==="failed")W.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Y==="unknown")W.push({tag:"markdown",content:"无法确认是否已送达,请联系通知发起方核实;已禁止自动重试。"});if(J?.reply)W.push({tag:"markdown",content:e(J.reply)});return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:Q[Y]},template:Y==="failed"||Y==="unknown"?"red":Y==="delivered"||Y==="done"?"green":"blue"},body:{elements:W}}}function aP($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Y of $){if(!Y||typeof Y!=="object")return{error:"each button must be an object"};let Q=String(Y.id??"").trim(),W=String(Y.text??"").trim();if(!nP.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!W)return{error:`button "${Q}" missing text`};if(W.length>tz)return{error:`button "${Q}" text > ${tz} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),V=dP.has(H)?H:"default";J.push({id:Q,text:W,type:V})}return{buttons:J}}function oP($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Y=J.hostname.replace(/^\[|]$/g,"");if(Y!=="127.0.0.1"&&Y!=="localhost"&&Y!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function ZX($){try{let Z=uP((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:sz(J,Y)):sz(J,Y)).catch((H)=>{if(_(`notify: handler crash: ${H?.message??H}`),!Y.headersSent)Y.statusCode=500,Y.setHeader("content-type","text/plain; charset=utf-8"),Y.end("internal error");else try{Y.end()}catch{}})});Z.on("error",(J)=>{_(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{_(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){_(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function sz($,Z,J=W$){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(l,D)=>{Z.statusCode=l,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(D)},W=(l,D)=>{Z.statusCode=l,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(D))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
220
260
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
221
261
  `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
222
262
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
223
263
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
224
264
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
225
265
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
226
- `);if($.method==="GET"&&Y.pathname.startsWith("/notify/result/")){let p=decodeURIComponent(Y.pathname.slice(15)).trim();if(!p)return Q(400,"missing notify_id in path");let D=k0(p);if(!D)return W(404,{error:"unknown notify_id",notify_id:p});return W(200,RH(D))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let p of $)H+=p.toString();let V={};try{V=JSON.parse(H)}catch{return Q(400,"bad json")}if(!V||typeof V!=="object"||Array.isArray(V))return Q(400,"body must be an object");if(V.allow_reply!==void 0&&typeof V.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let X=V.allow_reply===!0,z=String(V.project??"").trim(),G=String(V.text??""),K=String(V.title??"").trim(),B=String(V.level??"info").toLowerCase();if(!z)return Q(400,'missing "project"');if(!G)return Q(400,'missing "text"');let{buttons:A,error:P}=Yj(V.buttons);if(P)return Q(400,P);let{url:L,error:j}=Qj(V.callback);if(j)return Q(400,j);let N=!!(A&&A.length);if(N&&X)return Q(400,CX);let F=N||X,R=L??"",M=$j.has(B)?B:"info",k=K||z,C=J.sanitizeSessionName(z),v=J.chatIdForSession(C);if(!v)return _(`notify: project "${z}" (sanitized "${C}") has no chat binding → 404`),Q(404,`project "${z}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let b=Array.isArray(V.images)?V.images:[],c=[];for(let p of b){let D=String(p??"").trim();if(!D)continue;let x=await J.uploadImageKey(D);c.push({key:x??"",src:D})}let S=F?`nf_${eL()}`:"",h=bX({title:k,text:G,level:M,images:c,buttons:A,allowReply:X,notifyId:S}),m=await J.sendCard(v,h);if(!m)return _(`notify: sendCard failed → 502 (project="${z}" chat=${v.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(F&&S){let p={notifyId:S,callbackUrl:R,chatId:v,messageId:m,project:z,title:k,text:G,level:M,imageKeys:c,buttons:A,allowReply:X,createdAt:Date.now()};MH(p)}_(`notify: → ${z} (${v.slice(0,8)}…) level=${M} bytes=${G.length} images=${c.length} buttons=${A?.length??0} allowReply=${X} push=${F&&!!R?1:0} msg=${m}`),W(200,{ok:!0,chat_id:v,message_id:m,...S?{notify_id:S}:{}})}function c1($,Z){return bX({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var $j,Zj,Jj,kX=64,CX='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var A5=T(()=>{I();$$();x$();r4();$j=new Set(["info","warn","error"]),Zj=new Set(["default","primary","danger"]),Jj=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as mZ,readFileSync as cZ,rmSync as Wj}from"node:fs";import{homedir as q5}from"node:os";import{join as q0}from"node:path";function P5($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[q0(q5(),".codex","skills"),q0(q5(),".claude","skills")];for(let Y of J){let Q=q0(Y,$.name,"SKILL.md");try{let W=mZ(Q)?cZ(Q,"utf8"):null;if(W===$.body)continue;$0(Q,$.body),_(`skill: ${W===null?"installed":"updated"} ${Q}`)}catch(W){_(`skill: sync failed (${Q}): ${W}`)}}if(!Z)Hj($,z1)}function Hj($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=q0(Z,".claude-plugin","plugin.json"),Y=q0(Z,"skills",$.name,"SKILL.md"),Q=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
227
- `;for(let[W,H]of[[J,Q],[Y,$.body]])try{let V=mZ(W)?cZ(W,"utf8"):null;if(V===H)continue;$0(W,H),_(`skill: ${V===null?"installed":"updated"} ${W}`)}catch(V){_(`skill: Claude plugin sync failed (${W}): ${V}`)}}function wX($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[q0(q5(),".codex","skills"),q0(q5(),".claude","skills")]).map((Q)=>q0(Q,$));if(!Z)Y.push(q0(z1,"skills",$));for(let Q of Y){let W=q0(Q,"SKILL.md");if(!mZ(W))continue;try{let H=cZ(W,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){_(`skill: obsolete path preserved because ownership is unclear ${W}`);continue}Wj(Q,{recursive:!0,force:!1}),_(`skill: removed obsolete ${Q}`)}catch(H){_(`skill: obsolete removal failed (${Q}): ${H}`)}}}var uZ=T(()=>{I();w$();W$()});function Vj($){let Z=`Push a one-shot notification card to a Feishu (Lark) group via the local lodestar daemon's HTTP endpoint. Auto-trigger whenever the user asks to "通知飞书", "推送到飞书", "推到飞书群", "飞书推送", "发到飞书", "脚本跑完通知我", "进程完成发个消息", "send to feishu", "feishu notify", "lodestar notify", "post to lark group", or wants any local script / cron / long-running process to ping a Feishu group (build done, deploy finished, trade filled, monitor alert, error caught). Encodes the call shape — POST http://127.0.0.1:${$}/notify with \`{project, text, level}\` — so consumers do not have to re-derive it. Also covers interactive buttons: add \`buttons\` and either pledge a loopback \`callback\` URL (daemon POSTs the click back) or omit it and poll \`GET /notify/result/NOTIFY_ID\`; all on localhost.`;return`---
228
- name: ${fX}
266
+ `);if($.method==="GET"&&Y.pathname.startsWith("/notify/result/")){let l=decodeURIComponent(Y.pathname.slice(15)).trim();if(!l)return Q(400,"missing notify_id in path");let D=C0(l);if(!D)return W(404,{error:"unknown notify_id",notify_id:l});return W(200,lH(D))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let l of $)H+=l.toString();let V={};try{V=JSON.parse(H)}catch{return Q(400,"bad json")}if(!V||typeof V!=="object"||Array.isArray(V))return Q(400,"body must be an object");if(V.allow_reply!==void 0&&typeof V.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let z=V.allow_reply===!0,X=String(V.project??"").trim(),G=String(V.text??""),K=String(V.title??"").trim(),B=String(V.level??"info").toLowerCase();if(!X)return Q(400,'missing "project"');if(!G)return Q(400,'missing "text"');let{buttons:L,error:A}=aP(V.buttons);if(A)return Q(400,A);let{url:j,error:P}=oP(V.callback);if(P)return Q(400,P);let S=!!(L&&L.length);if(S&&z)return Q(400,ez);let F=S||z,R=j??"",M=iP.has(B)?B:"info",k=K||X,C=J.sanitizeSessionName(X),c=J.chatIdForSession(C);if(!c)return _(`notify: project "${X}" (sanitized "${C}") has no chat binding → 404`),Q(404,`project "${X}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let b=Array.isArray(V.images)?V.images:[],h=[];for(let l of b){let D=String(l??"").trim();if(!D)continue;let x=await J.uploadImageKey(D);h.push({key:x??"",src:D})}let E=F?`nf_${lP()}`:"",v=$X({title:k,text:G,level:M,images:h,buttons:L,allowReply:z,notifyId:E}),m=await J.sendCard(c,v);if(!m)return _(`notify: sendCard failed → 502 (project="${X}" chat=${c.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(F&&E){let l={notifyId:E,callbackUrl:R,chatId:c,messageId:m,project:X,title:k,text:G,level:M,imageKeys:h,buttons:L,allowReply:z,createdAt:Date.now()};pH(l)}_(`notify: → ${X} (${c.slice(0,8)}…) level=${M} bytes=${G.length} images=${h.length} buttons=${L?.length??0} allowReply=${z} push=${F&&!!R?1:0} msg=${m}`),W(200,{ok:!0,chat_id:c,message_id:m,...E?{notify_id:E}:{}})}function u1($,Z){return $X({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var iP,dP,nP,tz=64,ez='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var O6=T(()=>{I();$$();C$();e4();iP=new Set(["info","warn","error"]),dP=new Set(["default","primary","danger"]),nP=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as tZ,readFileSync as sZ,rmSync as rP}from"node:fs";import{homedir as T6}from"node:os";import{join as j0}from"node:path";function N6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[j0(T6(),".codex","skills"),j0(T6(),".claude","skills")];for(let Y of J){let Q=j0(Y,$.name,"SKILL.md");try{let W=tZ(Q)?sZ(Q,"utf8"):null;if(W===$.body)continue;J0(Q,$.body),_(`skill: ${W===null?"installed":"updated"} ${Q}`)}catch(W){_(`skill: sync failed (${Q}): ${W}`)}}if(!Z)tP($,_1)}function tP($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=j0(Z,".claude-plugin","plugin.json"),Y=j0(Z,"skills",$.name,"SKILL.md"),Q=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
267
+ `;for(let[W,H]of[[J,Q],[Y,$.body]])try{let V=tZ(W)?sZ(W,"utf8"):null;if(V===H)continue;J0(W,H),_(`skill: ${V===null?"installed":"updated"} ${W}`)}catch(V){_(`skill: Claude plugin sync failed (${W}): ${V}`)}}function JX($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){_(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[j0(T6(),".codex","skills"),j0(T6(),".claude","skills")]).map((Q)=>j0(Q,$));if(!Z)Y.push(j0(_1,"skills",$));for(let Q of Y){let W=j0(Q,"SKILL.md");if(!tZ(W))continue;try{let H=sZ(W,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){_(`skill: obsolete path preserved because ownership is unclear ${W}`);continue}rP(Q,{recursive:!0,force:!1}),_(`skill: removed obsolete ${Q}`)}catch(H){_(`skill: obsolete removal failed (${Q}): ${H}`)}}}var eZ=T(()=>{I();f$();H$()});function sP($){let Z=`Push a one-shot notification card to a Feishu (Lark) group via the local lodestar daemon's HTTP endpoint. Auto-trigger whenever the user asks to "通知飞书", "推送到飞书", "推到飞书群", "飞书推送", "发到飞书", "脚本跑完通知我", "进程完成发个消息", "send to feishu", "feishu notify", "lodestar notify", "post to lark group", or wants any local script / cron / long-running process to ping a Feishu group (build done, deploy finished, trade filled, monitor alert, error caught). Encodes the call shape — POST http://127.0.0.1:${$}/notify with \`{project, text, level}\` — so consumers do not have to re-derive it. Also covers interactive buttons: add \`buttons\` and either pledge a loopback \`callback\` URL (daemon POSTs the click back) or omit it and poll \`GET /notify/result/NOTIFY_ID\`; all on localhost.`;return`---
268
+ name: ${YX}
229
269
  description: ${JSON.stringify(Z+" Also receive free-text replies with allow_reply:true: a fixed 回复 button opens a waiting card, then the user types in the group and the daemon returns the text through the same callback or result endpoint.")}
230
270
  ---
231
271
 
@@ -482,13 +522,13 @@ is the script's acknowledgement, distinct from the user's response.
482
522
  Hand-edits will be overwritten — set
483
523
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
484
524
  to maintain the file yourself.
485
- `}function vX(){P5({name:fX,body:Vj(f.notify.port)})}var fX="feishu-notify";var hX=T(()=>{k$();uZ()});import{randomUUID as Xj}from"node:crypto";function IX($){let Z=(W)=>W instanceof Error?W.message:String(W),J=(W,H,V)=>{if(!W)return"通知已过期或已移除";if(!V)return"无法识别回复人,操作未执行";if(H&&H!==W.chatId)return"通知不属于当前群,操作未执行";if(!W.allowReply)return"此通知未开启文字回复";if(W.unknownAt)return`回复送达状态未知,禁止自动重试:${W.unknownReason}`;if(W.resolvedAt)return"此通知已处理";if(N2(W.notifyId))return"通知正在处理中";return null},Y=async(W,H)=>{if($.log(`notify-reply: ${H}`),!await $.sendText(W,`❌ ${H}`))throw Error(`通知回复错误提示发送失败: ${H}`)},Q=async(W,H,V,X)=>{try{await $.updateCard(H,V)}catch(z){await Y(W.chatId,`${X},卡片更新失败:${Z(z)}`)}};return{async recover(W){let H=W.replyState;if(!H||!W.unknownAt)return;let V={kind:"text",status:"unknown",text:H.response?.text??"",operatorOpenId:H.openId,detail:W.unknownReason};await Q(W,H.promptMessageId,Q1(W,H,V),"回复送达状态未知"),await Q(W,W.messageId,c1(W,V),"回复送达状态未知")},async open(W,H,V){let X=k0(W),z=J(X,H,V);if(z||!X)return{ok:!1,message:z};if(X.replyState?.status==="waiting"||X.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=u3(X.chatId);if(G.some((K)=>K.replyState?.status==="sending"||N2(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};d4(W);try{for(let A of G){let P={...A.replyState,status:"cancelled",cancelReason:"switched"};S2(A.notifyId,P),await Q(A,P.promptMessageId,Q1(A,P),"已放弃上一条回复并切换通知")}let K={id:Xj(),openId:V,promptMessageId:"",openedAt:Date.now(),status:"waiting"},B=await $.sendCard(X.chatId,Q1(X,K));if(!B)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};K.promptMessageId=B;try{S2(W,K)}catch(A){let P=`等待输入状态保存失败,未开始接收回复:${Z(A)}`;return await Q(X,B,Q1(X,K,{status:"failed",detail:P}),P),{ok:!1,message:P,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{n4(W),$.onWaitingChanged(X.chatId)}},async cancel(W,H,V,X){let z=k0(W),G=J(z,V,X);if(G||!z)return{ok:!1,message:G};let K=z.replyState;if(!K||K.id!==H||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==X)return{ok:!1,message:"仅点击「回复」的人可以取消"};let B={...K,status:"cancelled"};return S2(W,B),$.onWaitingChanged(z.chatId),await Q(z,K.promptMessageId,Q1(z,B),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(W){let{chatId:H,openId:V,messageId:X,text:z,createTime:G}=W;if(!V||!X||!z.trim())return!1;if(FH(H,X))return!0;let K=a4(H,V);if(!K?.replyState)return!1;let B=K.replyState;if(G>0&&G<B.openedAt)return!1;if(B.status!=="waiting"||N2(K.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let A={text:z,message_id:X,prompt_message_id:B.promptMessageId},P={...B,status:"sending",response:A};d4(K.notifyId);try{try{S2(K.notifyId,P)}catch(F){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(F)}`),!0}let L;try{if(await $.updateCard(B.promptMessageId,Q1(K,P)),K.callbackUrl)L=await $.dispatch(K,A,V);else o4(K.notifyId,void 0,V),L={ok:!0,detail:"已记录"}}catch(F){L={ok:!1,detail:Z(F)}}let j;if(L.ok){let F=K.callbackUrl?m8(K.notifyId,void 0,V):{state:"complete"};j={kind:"text",text:z,operatorOpenId:V,status:F.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...F.state==="unknown"?{detail:F.detail}:{reply:L.reply}}}else{j={kind:"text",text:z,operatorOpenId:V,status:"failed",detail:L.detail};try{S2(K.notifyId,{...P,status:"failed",error:L.detail})}catch(F){let R=`${L.detail};失败状态保存失败:${Z(F)}`;try{p3(K.notifyId,void 0,V,R)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}j={...j,status:"unknown",detail:R}}}let N=j.status==="delivered"?"回复已送达":j.status==="done"?"回复已记录":j.status==="unknown"?`回复送达状态未知:${j.detail}`:`回复未送达:${j.detail}`;return await Q(K,B.promptMessageId,Q1(K,P,j),N),await Q(K,K.messageId,c1(K,j),N),$.log(`notify-reply: notify_id=${K.notifyId} status=${j.status}`),!0}finally{n4(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var gX=T(()=>{r4();A5()});function zj(){return["---",`name: ${mX}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar. Delegated Agents and subagents must not use this Skill or delegate further. Main-Agent self-calls use native delegation capabilities.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Hard rule: native Agent capabilities for self-calls","","- For the main Agent only: when calling yourself or your own model/Agent, use your current"," Agent's native Agent/subagent capabilities. You MUST NOT use this Skill"," or the `lodestar-agent` command for self-calls.","- For example, Codex calling Codex uses Codex native subagents; Claude"," calling Claude uses Claude native Agent capabilities.","- This does not exempt delegated Agents from the single-level rule above.","- If native delegation is unavailable, report that limitation. It does not"," permit routing a self-call through this Skill.","","## Required workflow","","1. For another model/Agent, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon fans them out concurrently.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Continue the same native Agent session","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --stdin <<'EOF'","<follow-up prompt>","EOF","```","","## Answer a child question","","When a run returns `Status: needs_input`, answer the exact request id. JSON","keys may be the question id or the full question text:","","```bash","# desc: 回答 Agent 的阻塞问题并继续运行","lodestar-agent answer '<run-id>' --identity '<identity-id>' --request '<request-id>' --stdin <<'EOF'",'{"question-id":"answer"}',"EOF","```","","## Boundaries","","- Do not invoke provider CLIs or provider HTTP APIs directly for delegation.","- Never expose `LODESTAR_AGENT_CAPABILITY` in prompts, output, logs, or args.","- A non-zero command exit is a real failure. Do not claim the child succeeded.","- Scope the Agent task and authorized actions to the user request.",""].join(`
486
- `)}function uX(){wX("lodestar-consult"),P5({name:mX,body:zj()})}var mX="lodestar-agent",cX;var pZ=T(()=>{uZ();cX=["You are a delegated Agent working on a task assigned by the main Agent.","Complete this task yourself. You must not create or invoke any further Agents or subagents.","This includes Lodestar delegation, provider-native Agent/subagent tools, and delegation through CLIs or HTTP APIs.","If additional Agent work is needed, report the need to the main Agent so it can assign that work."].join(`
487
- `)});function pX($){let Z=H$($.identity.tokenSourceId,$.codexAccountId);if(!Z)throw Error(`agent token source not found: ${$.identity.tokenSourceId}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`agent token source changed after identity discovery: ${Z.id}`);if(!$.identity.supportedEfforts.includes($.effort))throw Error(`${$.identity.displayName} does not support effort ${$.effort}`);let J=$.resumeSessionId?{kind:"resume",source:{provider:$.identity.provider,sessionId:$.resumeSessionId,cwd:$.workDir}}:{kind:"fresh"},{process:Y}=A4({provider:$.identity.provider,workDir:$.workDir,tokenSourceId:$.identity.tokenSourceId,codexAccountId:$.codexAccountId,...$.identity.provider==="codex"&&$.identity.tokenSourceId==="codex-sub"?{codexAccountPreference:null}:{},model:$.identity.model,effort:$.effort,launch:J,developerInstructions:[$.developerInstructions,cX].filter(Boolean).join(`
525
+ `}function QX(){N6({name:YX,body:sP(f.notify.port)})}var YX="feishu-notify";var WX=T(()=>{x$();eZ()});import{randomUUID as eP}from"node:crypto";function HX($){let Z=(W)=>W instanceof Error?W.message:String(W),J=(W,H,V)=>{if(!W)return"通知已过期或已移除";if(!V)return"无法识别回复人,操作未执行";if(H&&H!==W.chatId)return"通知不属于当前群,操作未执行";if(!W.allowReply)return"此通知未开启文字回复";if(W.unknownAt)return`回复送达状态未知,禁止自动重试:${W.unknownReason}`;if(W.resolvedAt)return"此通知已处理";if(S2(W.notifyId))return"通知正在处理中";return null},Y=async(W,H)=>{if($.log(`notify-reply: ${H}`),!await $.sendText(W,`❌ ${H}`))throw Error(`通知回复错误提示发送失败: ${H}`)},Q=async(W,H,V,z)=>{try{await $.updateCard(H,V)}catch(X){await Y(W.chatId,`${z},卡片更新失败:${Z(X)}`)}};return{async recover(W){let H=W.replyState;if(!H||!W.unknownAt)return;let V={kind:"text",status:"unknown",text:H.response?.text??"",operatorOpenId:H.openId,detail:W.unknownReason};await Q(W,H.promptMessageId,H1(W,H,V),"回复送达状态未知"),await Q(W,W.messageId,u1(W,V),"回复送达状态未知")},async open(W,H,V){let z=C0(W),X=J(z,H,V);if(X||!z)return{ok:!1,message:X};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=e7(z.chatId);if(G.some((K)=>K.replyState?.status==="sending"||S2(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};o4(W);try{for(let L of G){let A={...L.replyState,status:"cancelled",cancelReason:"switched"};x2(L.notifyId,A),await Q(L,A.promptMessageId,H1(L,A),"已放弃上一条回复并切换通知")}let K={id:eP(),openId:V,promptMessageId:"",openedAt:Date.now(),status:"waiting"},B=await $.sendCard(z.chatId,H1(z,K));if(!B)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};K.promptMessageId=B;try{x2(W,K)}catch(L){let A=`等待输入状态保存失败,未开始接收回复:${Z(L)}`;return await Q(z,B,H1(z,K,{status:"failed",detail:A}),A),{ok:!1,message:A,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{r4(W),$.onWaitingChanged(z.chatId)}},async cancel(W,H,V,z){let X=C0(W),G=J(X,V,z);if(G||!X)return{ok:!1,message:G};let K=X.replyState;if(!K||K.id!==H||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let B={...K,status:"cancelled"};return x2(W,B),$.onWaitingChanged(X.chatId),await Q(X,K.promptMessageId,H1(X,B),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(W){let{chatId:H,openId:V,messageId:z,text:X,createTime:G}=W;if(!V||!z||!X.trim())return!1;if(uH(H,z))return!0;let K=t4(H,V);if(!K?.replyState)return!1;let B=K.replyState;if(G>0&&G<B.openedAt)return!1;if(B.status!=="waiting"||S2(K.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let L={text:X,message_id:z,prompt_message_id:B.promptMessageId},A={...B,status:"sending",response:L};o4(K.notifyId);try{try{x2(K.notifyId,A)}catch(F){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(F)}`),!0}let j;try{if(await $.updateCard(B.promptMessageId,H1(K,A)),K.callbackUrl)j=await $.dispatch(K,L,V);else s4(K.notifyId,void 0,V),j={ok:!0,detail:"已记录"}}catch(F){j={ok:!1,detail:Z(F)}}let P;if(j.ok){let F=K.callbackUrl?r8(K.notifyId,void 0,V):{state:"complete"};P={kind:"text",text:X,operatorOpenId:V,status:F.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...F.state==="unknown"?{detail:F.detail}:{reply:j.reply}}}else{P={kind:"text",text:X,operatorOpenId:V,status:"failed",detail:j.detail};try{x2(K.notifyId,{...A,status:"failed",error:j.detail})}catch(F){let R=`${j.detail};失败状态保存失败:${Z(F)}`;try{$Z(K.notifyId,void 0,V,R)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}P={...P,status:"unknown",detail:R}}}let S=P.status==="delivered"?"回复已送达":P.status==="done"?"回复已记录":P.status==="unknown"?`回复送达状态未知:${P.detail}`:`回复未送达:${P.detail}`;return await Q(K,B.promptMessageId,H1(K,A,P),S),await Q(K,K.messageId,u1(K,P),S),$.log(`notify-reply: notify_id=${K.notifyId} status=${P.status}`),!0}finally{r4(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var VX=T(()=>{e4();O6()});function $D(){return["---",`name: ${zX}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar. Delegated Agents and subagents must not use this Skill or delegate further. Main-Agent self-calls use native delegation capabilities.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Hard rule: native Agent capabilities for self-calls","","- For the main Agent only: when calling yourself or your own model/Agent, use your current"," Agent's native Agent/subagent capabilities. You MUST NOT use this Skill"," or the `lodestar-agent` command for self-calls.","- For example, Codex calling Codex uses Codex native subagents; Claude"," calling Claude uses Claude native Agent capabilities.","- This does not exempt delegated Agents from the single-level rule above.","- If native delegation is unavailable, report that limitation. It does not"," permit routing a self-call through this Skill.","","## Required workflow","","1. For another model/Agent, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon fans them out concurrently.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Continue the same native Agent session","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --stdin <<'EOF'","<follow-up prompt>","EOF","```","","## Answer a child question","","When a run returns `Status: needs_input`, answer the exact request id. JSON","keys may be the question id or the full question text:","","```bash","# desc: 回答 Agent 的阻塞问题并继续运行","lodestar-agent answer '<run-id>' --identity '<identity-id>' --request '<request-id>' --stdin <<'EOF'",'{"question-id":"answer"}',"EOF","```","","## Boundaries","","- Do not invoke provider CLIs or provider HTTP APIs directly for delegation.","- Never expose `LODESTAR_AGENT_CAPABILITY` in prompts, output, logs, or args.","- A non-zero command exit is a real failure. Do not claim the child succeeded.","- Scope the Agent task and authorized actions to the user request.",""].join(`
526
+ `)}function GX(){JX("lodestar-consult"),N6({name:zX,body:$D()})}var zX="lodestar-agent",XX;var $J=T(()=>{eZ();XX=["You are a delegated Agent working on a task assigned by the main Agent.","Complete this task yourself. You must not create or invoke any further Agents or subagents.","This includes Lodestar delegation, provider-native Agent/subagent tools, and delegation through CLIs or HTTP APIs.","If additional Agent work is needed, report the need to the main Agent so it can assign that work."].join(`
527
+ `)});function _X($){let Z=V$($.identity.tokenSourceId,$.codexAccountId);if(!Z)throw Error(`agent token source not found: ${$.identity.tokenSourceId}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`agent token source changed after identity discovery: ${Z.id}`);if(!$.identity.supportedEfforts.includes($.effort))throw Error(`${$.identity.displayName} does not support effort ${$.effort}`);let J=$.resumeSessionId?{kind:"resume",source:{provider:$.identity.provider,sessionId:$.resumeSessionId,cwd:$.workDir}}:{kind:"fresh"},{process:Y}=j4({provider:$.identity.provider,workDir:$.workDir,tokenSourceId:$.identity.tokenSourceId,codexAccountId:$.codexAccountId,...$.identity.provider==="codex"&&$.identity.tokenSourceId==="codex-sub"?{codexAccountPreference:null}:{},model:$.identity.model,effort:$.effort,launch:J,developerInstructions:[$.developerInstructions,XX].filter(Boolean).join(`
488
528
 
489
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return Gj(Y,$.prompt,$.callbacks)}function Gj($,Z,J={},Y=wJ){let Q=[],W=null,H=!1,V=null,X=null,z=[],G,K,B=Date.now(),A=new Promise((D,x)=>{G=D,K=x}),P=(D)=>{if(!D)return null;try{return Y($.provider,D),J.onSession?.(D),null}catch(x){return x instanceof Error?x:Error(String(x))}},L=()=>{if($.off("assistant_text",N),$.off("tool_use",R),$.off("tool_result",M),$.off("subagent_step",k),$.off("can_use_tool",C),$.off("hook_callback",v),$.off("init",b),!$.isAlive())$.off("error",c);$.off("turn_retry",h),$.off("codex_account_changed",S),$.off("result",m),$.off("exit",p)},j=(D,x)=>{if(V)return V;return H=!0,z.length=0,V=Promise.resolve().then(async()=>{let i=P($.sessionId);try{await $.kill(3000)}catch(V1){X=V1 instanceof Error?V1:Error(String(V1))}L();let a=[D,i,X].filter((V1)=>!!V1),G$=a.length>1?AggregateError(a,a.map((V1)=>V1.message).join("; ")):a[0];if(G$){K(new J9(G$,Q.join("").trim(),$.sessionId));return}let l2=$.sessionId;if(!l2){K(new J9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let H9=Q.join("").trim(),l1=Bj(x?.checkpoint,$);G({output:H9,outputTruncated:!1,sessionId:l2,...l1?{checkpointId:l1}:{},durationMs:Date.now()-B,usage:$.lastUsage?{...$.lastUsage}:null})}),V},N=(D)=>{if(H||D?.parentToolUseId||typeof D?.text!=="string")return;Q.push(D.text)},F=(D)=>{if(H)return;try{J.onProgress?.(D)}catch(x){j(x instanceof Error?x:Error(String(x)))}},R=(D)=>F({at:new Date().toISOString(),phase:"started",tool:String(D?.name??"tool"),detail:""}),M=(D)=>F({at:new Date().toISOString(),phase:"completed",tool:D?.is_error?"tool error":"tool result",detail:""}),k=(D)=>F({at:new Date().toISOString(),phase:D?.phase??"info",tool:String(D?.tool??"subagent"),detail:""}),C=(D)=>{if(H)return;if(D.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(D.request_id,"allow",{updatedInput:D.input??{}})}catch(i){j(i instanceof Error?i:Error(String(i)))}return}let x;try{x=_j(D)}catch(i){j(i instanceof Error?i:Error(String(i)));return}if(z.some((i)=>i.request.requestId===x.requestId))return;z.push({request:x,originalInput:D.input??{}});try{if(z.length===1)J.onNeedsInput?.(x)}catch(i){j(i instanceof Error?i:Error(String(i)))}},v=(D)=>{if(H)return;try{$.sendHookResponse(String(D.request_id),{})}catch(x){j(x instanceof Error?x:Error(String(x)))}},b=(D)=>{let x=P(D?.session_id??$.sessionId);if(x)j(x)},c=(D)=>{W=D instanceof Error?D:Error(String(D))},S=(D)=>{if(H)return;try{J.onCodexAccount?.(D.accountId)}catch(x){j(x instanceof Error?x:Error(String(x)))}if(D.diagnostics.length)F({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:D.diagnostics.join(";")})},h=(D)=>{F({at:new Date().toISOString(),phase:"info",tool:D.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:D.phase==="waiting"?`${D.message} · ${D.delayMs/1000}s 后重试 #${D.attempt}`:`正在重试 #${D.attempt}`})},m=(D)=>{let x=D?.is_error?Error(String(D.error??D.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;j(x,D)},p=(D)=>{if(H)return;let x=`code=${D?.code??"null"} signal=${D?.signal??"null"}`;j(W??Error(`delegated agent exited before result (${x})`))};$.on("assistant_text",N),$.on("tool_use",R),$.on("tool_result",M),$.on("subagent_step",k),$.on("can_use_tool",C),$.on("hook_callback",v),$.on("init",b),$.on("error",c),$.on("turn_retry",h),$.on("codex_account_changed",S),$.on("result",m),$.on("exit",p);try{$.sendInitialize(),$.sendUserText(Z)}catch(D){j(D instanceof Error?D:Error(String(D)))}return{done:A,isAlive:()=>$.isAlive(),pendingInput:()=>z[0]?.request??null,answer(D,x){let i=z[0];if(!i)throw Error("delegated agent is not waiting for input");if(i.request.requestId!==D)throw Error(`delegated agent input request mismatch: expected ${i.request.requestId}`);if($.sendPermissionResponse(D,"allow",{updatedInput:{...i.originalInput,answers:x}}),z.shift(),z[0])J.onNeedsInput?.(z[0].request)},async cancel(D="delegated agent cancelled"){let x=H;if(await j(Error(D)),await A.catch(()=>{}),x){if($.isAlive())await $.kill(3000);X=null,L()}if(X)throw X}}}function _j($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,W)=>Kj(Q,W));if(Y.length===0)throw Error("delegated agent input request contains no questions");return{requestId:String($.request_id),...$.tool_use_id?{toolUseId:$.tool_use_id}:{},questions:Y}}function Kj($,Z){let J=$&&typeof $==="object"?$:{question:$},Y=String(J.question??J.prompt??J.title??"").trim();if(!Y)throw Error(`delegated agent input question ${Z+1} is empty`);let Q=String(J.id??Y),W=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let V=H&&typeof H==="object"?H:{};return{label:String(V.label??V.value??""),...V.description?{description:String(V.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:W}}function Bj($,Z){if(typeof $?.id==="string"&&$.id)return $.id;if((Z.provider==="codex"||Z.provider==="dsh")&&typeof Z.lastCompletedTurnId==="string"&&Z.lastCompletedTurnId)return Z.lastCompletedTurnId;if(Z.provider==="claude"&&Z.lastAssistantUuid)return Z.lastAssistantUuid;return}var J9;var lX=T(()=>{Z7();o2();J$();pZ();J9=class J9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as Aj,randomBytes as qj,randomUUID as Pj}from"node:crypto";import{existsSync as Lj,readdirSync as jj,readFileSync as eX}from"node:fs";import{join as j5}from"node:path";class iZ{deps;runs=new Map;capabilities=new Map;activeTurns=0;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;constructor($=Dj){this.deps=$;this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(dX);let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if($.kind!=="session")throw Error(dX);let Y=this.requireMutableDescendant($,Z);if(!m2(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=tX(Y.snapshot,J.identityId);if(Y.handles.get(Q.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Q.sessionId)throw Error(`${Q.identityName} has no resumable native session id`);let W=J.effort??Q.effort,H=this.reserveCapacity($,1);try{return await this.createRun($.session,{identityIds:[Q.identityId],prompt:J.prompt,effort:W},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeByIdentity:new Map([[Q.identityId,Q.sessionId]])})}finally{H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=tX(Y.snapshot,J.identityId);if(Q.status!=="needs_input"||!Q.pendingInput)throw Error(`${Q.identityName} is not waiting for input`);if(Q.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Q.pendingInput.requestId}`);let W=Y.handles.get(Q.identityId);if(!W)throw Error("waiting agent process is no longer alive; start a follow-up run");W.answer(J.requestId,J.answers);let H=W.pendingInput();if(Q.status=H?"needs_input":"running",H)Q.pendingInput=H;else delete Q.pendingInput;return delete Q.queuedReason,this.refreshNonterminalStatus(Y),this.persist(Y),await this.updateWorkerCard(Y,Q),Y9(Y.snapshot)}getRun($,Z){return Y9(this.requireAccessibleRun($,Z).snapshot)}async cancelRun($,Z,J="agent run cancelled"){let Y=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Y))return!1;return await this.cancelTree(Y,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Y=[...this.runs.values()].filter((W)=>W.snapshot.sessionName===$&&W.snapshot.chatId===Z&&!W.snapshot.parentRunId&&this.treeHasActiveRun(W)),Q=await Promise.allSettled(Y.map((W)=>this.cancelTree(W,J)));lZ(Q)}async shutdown($){let Z=new Set([...this.runs.values()].map((H)=>`${H.snapshot.sessionName}\x00${H.snapshot.chatId}`));for(let H of Z){let[V,X]=H.split("\x00");this.bumpCancellationEpoch(V,X)}let J=[...this.runs.values()].filter((H)=>!H.snapshot.parentRunId&&this.treeHasActiveRun(H)),Y=await Promise.allSettled(J.map((H)=>this.cancelTree(H,$))),Q=[...this.runs.values()].flatMap((H)=>[...H.handles.values()]),W=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));lZ([...Y,...W])}async createRun($,Z,J){this.pruneRuns();let Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let Q=$.codexAccountId(),W=this.deps.getCatalog(Q),H=Z.identityIds.map((P)=>{let L=W.identities.find((j)=>j.id===P);if(!L)throw Error(`agent identity not found: ${P}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),V=H.map((P)=>Mj(P,Fj(P,Z.effort),J.resumeByIdentity?.get(P.id))),X=`agent_${Pj()}`,z={runId:X,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:V,createdAt:new Date().toISOString()},G=await this.deps.sendCard($.chatId,S3(z));if(!G)throw Error("agent card creation failed; delegated agents were not started");let K;try{K=await this.deps.convertMessageToCard(G)}catch(P){throw await this.deps.sendTextRaw($.chatId,`❌ agent 卡片初始化失败,Agent 未启动: ${y$(P)}`),P}z.cardMessageId=G,this.deps.recordCardCreated(K,V.length+2,(P)=>{_(`agent: card write failed run=${X} code=${P??"MISS"}`)});let B={snapshot:z,session:$,cardId:K,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};if(this.runs.set(X,B),J.parentRunId)Y?.children.add(X);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){B.cancelled=!0;let P="任务已在启动前取消";for(let L of B.snapshot.workers)L.status="cancelled",L.error=P,L.finishedAt=new Date().toISOString();return this.persist(B),await Promise.all(B.snapshot.workers.map((L)=>this.updateWorkerCard(B,L))),await this.finalizeRun(B,"cancelled",P),Y9(B.snapshot)}this.persist(B);for(let P of H){let L=J.resumeByIdentity?.get(P.id);this.executeWorker(B,P,Z.prompt,L).catch((j)=>{_(`agent: run=${X} worker=${P.id} crashed: ${y$(j)}`)})}return Y9(z)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(()=>{Q.queuedReason=`等待执行名额(最多同时运行 ${iX} 个 Agent)`,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.add(Z.id),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let W="";try{if(W=qj(32).toString("base64url"),this.capabilities.set(W,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,W),Q.status="running",Q.startedAt=new Date().toISOString(),delete Q.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Q),$.cancelled)return;let H=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Q.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:Oj(j2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:z1},hostEnv:{LODESTAR_AGENT_URL:l9(f.notify.bind,f.notify.port),LODESTAR_AGENT_CAPABILITY:W,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(X)=>{if($.cancelled)return;Q.status="needs_input",Q.pendingInput=X,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Q)},onProgress:(X)=>this.recordStep($,Q,X),onCodexAccount:(X)=>{if($.cancelled)return;Q.codexAccountId=X,this.persist($)},onSession:(X)=>{if(Q.sessionId===X)return;Q.sessionId=X,this.persist($)}}});$.handles.set(Z.id,H);let V=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=V.output,Q.outputTruncated=V.outputTruncated,Q.sessionId=V.sessionId,Q.checkpointId=V.checkpointId,Q.durationMs=V.durationMs,Q.usage=V.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof J9){if(Q.output=H.output,Q.outputTruncated=!1,H.sessionId)Q.sessionId=H.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Q.status="failed",Q.error=y$(H),Q.finishedAt=new Date().toISOString(),Q.startedAt)Q.durationMs=Date.now()-Date.parse(Q.startedAt);delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(W)this.capabilities.delete(W);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||L5(Z.status))return;if(Z.steps.push(J),Z.steps.length>aX)Z.steps.splice(0,Z.steps.length-aX);if($.progressTimers.has(Z.identityId))return;let Y=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z)},250);$.progressTimers.set(Z.identityId,Y)}clearProgressTimer($,Z){let J=$.progressTimers.get(Z);if(J)clearTimeout(J);$.progressTimers.delete(Z)}refreshNonterminalStatus($){if($.cancelled)return;if($.snapshot.workers.some((Z)=>Z.status==="needs_input"))$.snapshot.status="needs_input";else if($.snapshot.workers.some((Z)=>Z.status==="running"))$.snapshot.status="running";else $.snapshot.status="queued";delete $.snapshot.finishedAt}recomputeRun($){if($.cancelled||$.finalized||$.finalizing)return;let Z=$.snapshot.workers;if(Z.some((Y)=>Y.status==="needs_input"||Y.status==="running"||Y.status==="queued")){this.refreshNonterminalStatus($),this.persist($);return}let J=Z.some((Y)=>Y.status==="failed")?"failed":"completed";this.finalizeRun($,J,J==="failed"?"一个或多个 Agent 失败":void 0).catch((Y)=>{$.finalizing=!1,$.finalized=!1,$.snapshot.status="failed",$.snapshot.error=`Agent terminal persistence failed: ${y$(Y)}`,_(`agent: terminal finalization failed run=${$.snapshot.runId}: ${y$(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${y$(Y)}`).catch((Q)=>_(`agent: terminal failure delivery failed: ${y$(Q)}`))})}async cancelTree($,Z){let J=!m2($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let W of[...$.progressTimers.keys()])this.clearProgressTimer($,W);for(let W of $.capabilityByIdentity.values())this.capabilities.delete(W);$.capabilityByIdentity.clear()}while(!0){let W=[...$.children].map((V)=>this.runs.get(V)).filter((V)=>!!V&&this.treeHasActiveRun(V));if(W.length===0)break;let H=await Promise.allSettled(W.map((V)=>this.cancelTree(V,Z)));if(Y.push(...H),H.some((V)=>V.status==="rejected"))break}if(!J){lZ(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([W,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${W}: Agent process is still alive after cancellation`);$.handles.delete(W),this.releaseWorkerSlot($,W)}))),Y.some((W)=>W.status==="rejected")){let W=$z(Y);throw $.snapshot.status="failed",$.snapshot.error=W.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${W.message}`).catch((H)=>_(`agent: cancellation failure notice failed: ${y$(H)}`)),W}let Q=[];for(let W of $.snapshot.workers)if(!L5(W.status))W.status="cancelled",W.error=Z,W.finishedAt=new Date().toISOString(),delete W.pendingInput,Q.push(W);await Promise.all(Q.map((W)=>this.updateWorkerCard($,W))),await this.finalizeRun($,"cancelled",Z)}async finalizeRun($,Z,J){if($.finalized||$.finalizing)return;$.finalizing=!0;for(let Y of[...$.progressTimers.keys()])this.clearProgressTimer($,Y);if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)$.snapshot.error=J;try{if($.cardId){if(this.deps.cancelSummary($.cardId),await this.deps.flush($.cardId),!await this.deps.replaceElementChecked($.cardId,U.agentRunFooter,u4($.snapshot)))this.recordPresentationError($,"agent footer update MISS");if(!await this.deps.patchSettingsChecked($.cardId,{config:{streaming_mode:!1,summary:{content:p4($.snapshot)}}}))this.recordPresentationError($,"agent terminal settings update MISS");await this.deps.flush($.cardId),await this.deps.dispose($.cardId)}}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${y$(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,$.snapshot.presentationErrors?.length)await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ agent ${$.snapshot.runId} 结果已保存,但卡片有 ${$.snapshot.presentationErrors.length} 个呈现错误。`).catch((Y)=>_(`agent: warning delivery failed run=${$.snapshot.runId}: ${y$(Y)}`))}async updateWorkerCard($,Z){if(!$.cardId||$.finalized)return;try{if(!await this.deps.replaceElementChecked($.cardId,f8(Z.identityId),w8(Z,v8($.snapshot.workers.length),$.snapshot.workers.length===1)))this.recordPresentationError($,`agent worker card MISS: ${Z.identityName}`);if(!await this.deps.replaceElementChecked($.cardId,U.agentRunFooter,u4($.snapshot)))_(`agent: progress update MISS run=${$.snapshot.runId}; later updates will refresh it`);this.deps.patchSummaryThrottled($.cardId,p4($.snapshot))}catch(J){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${y$(J)}`)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,_(`agent: ${Z} run=${$.snapshot.runId}`)}persist($){if(!$.snapshot.promptArtifact)$.snapshot.promptArtifact=`${$.snapshot.runId}.prompt.txt`;this.persistTextArtifact($,$.snapshot.promptArtifact,$.snapshot.prompt);for(let J of $.snapshot.workers){if(!J.output)continue;if(!J.outputArtifact){let Y=Aj("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=Y9($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(j5(X1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;Zz(Z),this.deps.writeTextArtifact(j5(X1,Z),J),$.persistedArtifacts.add(Z)}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||$.snapshot.workDir!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!m2($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Y=[...this.runs.values()].filter((V)=>this.sessionKey(V.snapshot.sessionName,V.snapshot.chatId)===J&&(!m2(V.snapshot.status)||V.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=oX)throw Error(`Session has reached ${oX} active Agent runs`);if([...this.runs.values()].reduce((V,X)=>V+X.snapshot.workers.filter((z)=>!L5(z.status)||X.handles.get(z.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>rX)throw Error(`global Agent worker limit ${rX} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Q+1);let H=!1;return()=>{if(H)return;H=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),Nj(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){return this.cancellationEpochBySession.get(this.sessionKey($.sessionName,$.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}acquireSlot($){if(this.activeTurns<iX)return this.activeTurns++,Promise.resolve();return $(),new Promise((Z)=>this.slotWaiters.push(Z))}releaseSlot(){let $=this.slotWaiters.shift();if($){$();return}this.activeTurns--}releaseWorkerSlot($,Z){if($.slotOwners.delete(Z))this.releaseSlot()}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!m2($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!L5(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,cardId:null,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRuns()}pruneRuns(){if(this.runs.size<=nX)return;let $=[...this.runs.values()].filter((Z)=>m2(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0&&Z.children.size===0).sort((Z,J)=>Date.parse(Z.snapshot.finishedAt??Z.snapshot.createdAt)-Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt));for(let Z of $){if(this.runs.size<=nX)break;if(this.runs.delete(Z.snapshot.runId),Z.snapshot.parentRunId)this.runs.get(Z.snapshot.parentRunId)?.children.delete(Z.snapshot.runId)}}}function Mj($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function Fj($,Z){let J=Z??$.defaultEffort;if(!J)throw Error(`${$.displayName} default effort MISS; specify effort explicitly`);if(!$.supportedEfforts.includes(J))throw Error(`${$.displayName} does not support effort ${J}`);return J}function tX($,Z){if(Z){let J=$.workers.find((Y)=>Y.identityId===Z);if(!J)throw Error(`agent identity is not part of run ${$.runId}: ${Z}`);return J}if($.workers.length!==1)throw Error("run has multiple Agents; specify identity_id");return $.workers[0]}function m2($){return $==="completed"||$==="failed"||$==="cancelled"}function L5($){return $==="completed"||$==="failed"||$==="cancelled"}function Y9($){return JSON.parse(JSON.stringify($))}function Rj(){if(!Lj(X1))return[];let $=[];for(let Z of jj(X1).filter((J)=>J.endsWith(".json")).sort()){let J=j5(X1,Z),Y;try{Y=JSON.parse(eX(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${y$(Q)}`)}if(!Uj(Y))throw Error(`agent run artifact is invalid: ${J}`);Tj(Y,J),$.push(Y)}return $}function Uj($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&typeof Z.prompt==="string"&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function $z($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(y$).join("; ")}`)}function lZ($){if($.some((Z)=>Z.status==="rejected"))throw $z($)}function y$($){return $ instanceof Error?$.message:String($)}function Oj($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function Tj($,Z){if($.promptArtifact)$.prompt=sX($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=sX(J.outputArtifact,`output for ${Z}`)}function sX($,Z){Zz($);try{return eX(j5(X1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${y$(J)}`)}}function Zz($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function Nj($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var iX=8,dX="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",nX=512,aX=50,oX=64,rX=128,Dj;var Jz=T(()=>{a0();s$();$$();k$();Z5();lX();W$();w$();I();Dj={getCatalog:h1,startWorker:pX,sendCard:u,sendTextRaw:w,convertMessageToCard:o$,recordCardCreated:c$,replaceElementChecked:z$,patchSummaryThrottled:E0,flush:r$,cancelSummary:M$,patchSettingsChecked:P$,dispose:b$,writeArtifact:t,writeTextArtifact:$0,loadArtifacts:Rj}});function Yz($){let Z=dZ($,"agent run request"),J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Y=[...new Set(J.map((H)=>H.trim()).filter(Boolean))];if(Y.length===0)throw Error("agent run requires at least one identity_id");if(Y.length>64)throw Error("agent run supports at most 64 identities");let Q=Hz(Z.prompt,'agent run requires "prompt"'),W=Q9(Z.effort);return{identityIds:Y,prompt:Q,...W?{effort:W}:{}}}function Qz($){let Z=dZ($,"agent follow-up request"),J=Hz(Z.prompt,'agent follow-up requires "prompt"'),Y=Q9(Z.identity_id??Z.identityId),Q=Q9(Z.effort);return{prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function Wz($){let Z=dZ($,"agent answer request"),J=Q9(Z.identity_id??Z.identityId),Y=Q9(Z.request_id??Z.requestId);if(!Y)throw Error("agent answer requires request_id");if(!Z.answers||typeof Z.answers!=="object"||Array.isArray(Z.answers))throw Error("agent answer requires an answers object");let Q={};for(let[W,H]of Object.entries(Z.answers)){if(!W.trim())throw Error("agent answer contains an empty question key");Q[W]=String(H)}if(Object.keys(Q).length===0)throw Error("agent answer requires at least one answer");return{requestId:Y,answers:Q,...J?{identityId:J}:{}}}function dZ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function Hz($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function Q9($){return(typeof $==="string"?$.trim():"")||void 0}async function zz($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(G,K)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},W=kj($.headers.authorization);if(!W)return Q(401,{error:"missing bearer capability"});let H=Ej(Y,W);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await G2(),Q(200,xj(h1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,Yz(await nZ($)));return Q(202,D5(G))}catch(G){return Q(409,{error:Xz(G)})}let V=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!V)return Q(405,{error:"unsupported agent endpoint"});let X=Sj(V[1]);if(!X)return Q(400,{error:"invalid agent run id encoding"});let z=V[2];try{if(!z&&$.method==="GET")return Q(200,D5(Y.service.getRun(H,X)));if(!z&&$.method==="DELETE"){let G=await Y.service.cancelRun(H,X,"cancelled by agent client");return Q(G?200:409,G?{ok:!0,run_id:X}:{error:"agent run is already terminal",run_id:X})}if(z==="follow-up"&&$.method==="POST"){let G=await Y.service.followUp(H,X,Qz(await nZ($)));return Q(202,D5(G))}if(z==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,X,Wz(await nZ($)));return Q(200,D5(G))}}catch(G){return Q(409,{error:Xz(G)})}return Q(405,{error:"unsupported agent endpoint"})}function Ej($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function Sj($){try{return decodeURIComponent($)}catch{return null}}function kj($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function nZ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>Vz)throw Error(`request body exceeds ${Vz} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function xj($){return{catalog_generation:$.catalogGeneration,identities:$.identities.map((Z)=>({id:Z.id,display_name:Z.displayName,token_source_id:Z.tokenSourceId,token_source_display:Z.tokenSourceDisplay,provider:Z.provider,model:Z.model,model_display:Z.modelDisplay,default_effort:Z.defaultEffort,supported_efforts:Z.supportedEfforts,source_default:Z.sourceDefault,status:Z.status,reason:Z.reason})),source_failures:$.sourceFailures.map((Z)=>({token_source_id:Z.tokenSourceId,display:Z.display,status:Z.status,reason:Z.reason}))}}function D5($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,parent_run_id:$.parentRunId,parent_kind:$.parentKind,depth:$.depth,status:$.status,workers:$.workers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,provider:Z.provider,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,output_truncated:Z.outputTruncated,session_id:Z.sessionId,checkpoint_id:Z.checkpointId,pending_input:Z.pendingInput&&{request_id:Z.pendingInput.requestId,tool_use_id:Z.pendingInput.toolUseId,questions:Z.pendingInput.questions},queued_reason:Z.queuedReason,steps:Z.steps,error:Z.error,started_at:Z.startedAt,finished_at:Z.finishedAt,duration_ms:Z.durationMs,usage:Z.usage})),created_at:$.createdAt,finished_at:$.finishedAt,error:$.error,presentation_errors:$.presentationErrors,card_message_id:$.cardMessageId}}function Xz($){return $ instanceof Error?$.message:String($)}var Vz=4194304;var Gz=T(()=>{Z5();J$()});import{chmodSync as Cj,existsSync as aZ,readFileSync as Bz,realpathSync as bj,unlinkSync as yj}from"node:fs";import{homedir as wj}from"node:os";import{basename as fj,dirname as vj,join as W1,resolve as hj}from"node:path";function Ij($={}){let Z=bj(hj($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??aZ,Q=vj(Z),W=W1(Q,"src","agent-cli.ts"),H=W1(Q,"lodestar-agent.js"),V=W1(Q,"dist","lodestar-agent.js"),z=/^bun(?:\.exe)?$/i.test(fj(J))?[W,H,V]:[H,V],G=z.find(Y);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${z.join(", ")}`);return{runtime:J,entry:G}}function Az($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??mj(Z,$.homeDir??wj(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??Ij(),W=W1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${Kz(Q.runtime)}" "${Kz(Q.entry)}" %*\r
529
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return ZD(Y,$.prompt,$.callbacks)}function ZD($,Z,J={},Y=$Y){let Q=[],W=null,H=!1,V=null,z=null,X=[],G,K,B=Date.now(),L=new Promise((D,x)=>{G=D,K=x}),A=(D)=>{if(!D)return null;try{return Y($.provider,D),J.onSession?.(D),null}catch(x){return x instanceof Error?x:Error(String(x))}},j=()=>{if($.off("assistant_text",S),$.off("tool_use",R),$.off("tool_result",M),$.off("subagent_step",k),$.off("can_use_tool",C),$.off("hook_callback",c),$.off("init",b),!$.isAlive())$.off("error",h);$.off("turn_retry",v),$.off("codex_account_changed",E),$.off("result",m),$.off("exit",l)},P=(D,x)=>{if(V)return V;return H=!0,X.length=0,V=Promise.resolve().then(async()=>{let i=A($.sessionId);try{await $.kill(3000)}catch(X1){z=X1 instanceof Error?X1:Error(String(X1))}j();let a=[D,i,z].filter((X1)=>!!X1),_$=a.length>1?AggregateError(a,a.map((X1)=>X1.message).join("; ")):a[0];if(_$){K(new W9(_$,Q.join("").trim(),$.sessionId));return}let d2=$.sessionId;if(!d2){K(new W9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let X9=Q.join("").trim(),d1=QD(x?.checkpoint,$);G({output:X9,outputTruncated:!1,sessionId:d2,...d1?{checkpointId:d1}:{},durationMs:Date.now()-B,usage:$.lastUsage?{...$.lastUsage}:null})}),V},S=(D)=>{if(H||D?.parentToolUseId||typeof D?.text!=="string")return;Q.push(D.text)},F=(D)=>{if(H)return;try{J.onProgress?.(D)}catch(x){P(x instanceof Error?x:Error(String(x)))}},R=(D)=>F({at:new Date().toISOString(),phase:"started",tool:String(D?.name??"tool"),detail:""}),M=(D)=>F({at:new Date().toISOString(),phase:"completed",tool:D?.is_error?"tool error":"tool result",detail:""}),k=(D)=>F({at:new Date().toISOString(),phase:D?.phase??"info",tool:String(D?.tool??"subagent"),detail:""}),C=(D)=>{if(H)return;if(D.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(D.request_id,"allow",{updatedInput:D.input??{}})}catch(i){P(i instanceof Error?i:Error(String(i)))}return}let x;try{x=JD(D)}catch(i){P(i instanceof Error?i:Error(String(i)));return}if(X.some((i)=>i.request.requestId===x.requestId))return;X.push({request:x,originalInput:D.input??{}});try{if(X.length===1)J.onNeedsInput?.(x)}catch(i){P(i instanceof Error?i:Error(String(i)))}},c=(D)=>{if(H)return;try{$.sendHookResponse(String(D.request_id),{})}catch(x){P(x instanceof Error?x:Error(String(x)))}},b=(D)=>{let x=A(D?.session_id??$.sessionId);if(x)P(x)},h=(D)=>{W=D instanceof Error?D:Error(String(D))},E=(D)=>{if(H)return;try{J.onCodexAccount?.(D.accountId)}catch(x){P(x instanceof Error?x:Error(String(x)))}if(D.diagnostics.length)F({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:D.diagnostics.join(";")})},v=(D)=>{F({at:new Date().toISOString(),phase:"info",tool:D.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:D.phase==="waiting"?`${D.message} · ${D.delayMs/1000}s 后重试 #${D.attempt}`:`正在重试 #${D.attempt}`})},m=(D)=>{let x=D?.is_error?Error(String(D.error??D.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;P(x,D)},l=(D)=>{if(H)return;let x=`code=${D?.code??"null"} signal=${D?.signal??"null"}`;P(W??Error(`delegated agent exited before result (${x})`))};$.on("assistant_text",S),$.on("tool_use",R),$.on("tool_result",M),$.on("subagent_step",k),$.on("can_use_tool",C),$.on("hook_callback",c),$.on("init",b),$.on("error",h),$.on("turn_retry",v),$.on("codex_account_changed",E),$.on("result",m),$.on("exit",l);try{$.sendInitialize(),$.sendUserText(Z)}catch(D){P(D instanceof Error?D:Error(String(D)))}return{done:L,isAlive:()=>$.isAlive(),pendingInput:()=>X[0]?.request??null,answer(D,x){let i=X[0];if(!i)throw Error("delegated agent is not waiting for input");if(i.request.requestId!==D)throw Error(`delegated agent input request mismatch: expected ${i.request.requestId}`);if($.sendPermissionResponse(D,"allow",{updatedInput:{...i.originalInput,answers:x}}),X.shift(),X[0])J.onNeedsInput?.(X[0].request)},async cancel(D="delegated agent cancelled"){let x=H;if(await P(Error(D)),await L.catch(()=>{}),x){if($.isAlive())await $.kill(3000);z=null,j()}if(z)throw z}}}function JD($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,W)=>YD(Q,W));if(Y.length===0)throw Error("delegated agent input request contains no questions");return{requestId:String($.request_id),...$.tool_use_id?{toolUseId:$.tool_use_id}:{},questions:Y}}function YD($,Z){let J=$&&typeof $==="object"?$:{question:$},Y=String(J.question??J.prompt??J.title??"").trim();if(!Y)throw Error(`delegated agent input question ${Z+1} is empty`);let Q=String(J.id??Y),W=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let V=H&&typeof H==="object"?H:{};return{label:String(V.label??V.value??""),...V.description?{description:String(V.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:W}}function QD($,Z){if(typeof $?.id==="string"&&$.id)return $.id;if((Z.provider==="codex"||Z.provider==="dsh")&&typeof Z.lastCompletedTurnId==="string"&&Z.lastCompletedTurnId)return Z.lastCompletedTurnId;if(Z.provider==="claude"&&Z.lastAssistantUuid)return Z.lastAssistantUuid;return}var W9;var KX=T(()=>{K3();t2();Y$();$J();W9=class W9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as WD,randomBytes as HD,randomUUID as VD}from"node:crypto";import{existsSync as zD,readdirSync as XD,readFileSync as FX}from"node:fs";import{join as S6}from"node:path";class JJ{deps;runs=new Map;capabilities=new Map;activeTurns=0;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;constructor($=GD){this.deps=$;this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(AX);let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if($.kind!=="session")throw Error(AX);let Y=this.requireMutableDescendant($,Z);if(!p2(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=DX(Y.snapshot,J.identityId);if(Y.handles.get(Q.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Q.sessionId)throw Error(`${Q.identityName} has no resumable native session id`);let W=J.effort??Q.effort,H=this.reserveCapacity($,1);try{return await this.createRun($.session,{identityIds:[Q.identityId],prompt:J.prompt,effort:W},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeByIdentity:new Map([[Q.identityId,Q.sessionId]])})}finally{H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=DX(Y.snapshot,J.identityId);if(Q.status!=="needs_input"||!Q.pendingInput)throw Error(`${Q.identityName} is not waiting for input`);if(Q.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Q.pendingInput.requestId}`);let W=Y.handles.get(Q.identityId);if(!W)throw Error("waiting agent process is no longer alive; start a follow-up run");W.answer(J.requestId,J.answers);let H=W.pendingInput();if(Q.status=H?"needs_input":"running",H)Q.pendingInput=H;else delete Q.pendingInput;return delete Q.queuedReason,this.refreshNonterminalStatus(Y),this.persist(Y),await this.updateWorkerCard(Y,Q),H9(Y.snapshot)}getRun($,Z){return H9(this.requireAccessibleRun($,Z).snapshot)}async cancelRun($,Z,J="agent run cancelled"){let Y=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Y))return!1;return await this.cancelTree(Y,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Y=[...this.runs.values()].filter((W)=>W.snapshot.sessionName===$&&W.snapshot.chatId===Z&&!W.snapshot.parentRunId&&this.treeHasActiveRun(W)),Q=await Promise.allSettled(Y.map((W)=>this.cancelTree(W,J)));ZJ(Q)}async shutdown($){let Z=new Set([...this.runs.values()].map((H)=>`${H.snapshot.sessionName}\x00${H.snapshot.chatId}`));for(let H of Z){let[V,z]=H.split("\x00");this.bumpCancellationEpoch(V,z)}let J=[...this.runs.values()].filter((H)=>!H.snapshot.parentRunId&&this.treeHasActiveRun(H)),Y=await Promise.allSettled(J.map((H)=>this.cancelTree(H,$))),Q=[...this.runs.values()].flatMap((H)=>[...H.handles.values()]),W=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));ZJ([...Y,...W])}async createRun($,Z,J){this.pruneRuns();let Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let Q=$.codexAccountId(),W=this.deps.getCatalog(Q),H=Z.identityIds.map((A)=>{let j=W.identities.find((P)=>P.id===A);if(!j)throw Error(`agent identity not found: ${A}`);if(j.status!=="ready")throw Error(`${j.displayName}: ${j.reason??j.status}`);return j}),V=H.map((A)=>_D(A,KD(A,Z.effort),J.resumeByIdentity?.get(A.id))),z=`agent_${VD()}`,X={runId:z,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:V,createdAt:new Date().toISOString()},G=await this.deps.sendCard($.chatId,g7(X));if(!G)throw Error("agent card creation failed; delegated agents were not started");let K;try{K=await this.deps.convertMessageToCard(G)}catch(A){throw await this.deps.sendTextRaw($.chatId,`❌ agent 卡片初始化失败,Agent 未启动: ${w$(A)}`),A}X.cardMessageId=G,this.deps.recordCardCreated(K,V.length+2,(A)=>{_(`agent: card write failed run=${z} code=${A??"MISS"}`)});let B={snapshot:X,session:$,cardId:K,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};if(this.runs.set(z,B),J.parentRunId)Y?.children.add(z);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){B.cancelled=!0;let A="任务已在启动前取消";for(let j of B.snapshot.workers)j.status="cancelled",j.error=A,j.finishedAt=new Date().toISOString();return this.persist(B),await Promise.all(B.snapshot.workers.map((j)=>this.updateWorkerCard(B,j))),await this.finalizeRun(B,"cancelled",A),H9(B.snapshot)}this.persist(B);for(let A of H){let j=J.resumeByIdentity?.get(A.id);this.executeWorker(B,A,Z.prompt,j).catch((P)=>{_(`agent: run=${z} worker=${A.id} crashed: ${w$(P)}`)})}return H9(X)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(()=>{Q.queuedReason=`等待执行名额(最多同时运行 ${BX} 个 Agent)`,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.add(Z.id),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let W="";try{if(W=HD(32).toString("base64url"),this.capabilities.set(W,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,W),Q.status="running",Q.startedAt=new Date().toISOString(),delete Q.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Q),$.cancelled)return;let H=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Q.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:qD(M2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:_1},hostEnv:{LODESTAR_AGENT_URL:$8(f.notify.bind,f.notify.port),LODESTAR_AGENT_CAPABILITY:W,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(z)=>{if($.cancelled)return;Q.status="needs_input",Q.pendingInput=z,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Q)},onProgress:(z)=>this.recordStep($,Q,z),onCodexAccount:(z)=>{if($.cancelled)return;Q.codexAccountId=z,this.persist($)},onSession:(z)=>{if(Q.sessionId===z)return;Q.sessionId=z,this.persist($)}}});$.handles.set(Z.id,H);let V=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=V.output,Q.outputTruncated=V.outputTruncated,Q.sessionId=V.sessionId,Q.checkpointId=V.checkpointId,Q.durationMs=V.durationMs,Q.usage=V.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof W9){if(Q.output=H.output,Q.outputTruncated=!1,H.sessionId)Q.sessionId=H.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Q.status="failed",Q.error=w$(H),Q.finishedAt=new Date().toISOString(),Q.startedAt)Q.durationMs=Date.now()-Date.parse(Q.startedAt);delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(W)this.capabilities.delete(W);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||E6(Z.status))return;if(Z.steps.push(J),Z.steps.length>LX)Z.steps.splice(0,Z.steps.length-LX);if($.progressTimers.has(Z.identityId))return;let Y=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z)},250);$.progressTimers.set(Z.identityId,Y)}clearProgressTimer($,Z){let J=$.progressTimers.get(Z);if(J)clearTimeout(J);$.progressTimers.delete(Z)}refreshNonterminalStatus($){if($.cancelled)return;if($.snapshot.workers.some((Z)=>Z.status==="needs_input"))$.snapshot.status="needs_input";else if($.snapshot.workers.some((Z)=>Z.status==="running"))$.snapshot.status="running";else $.snapshot.status="queued";delete $.snapshot.finishedAt}recomputeRun($){if($.cancelled||$.finalized||$.finalizing)return;let Z=$.snapshot.workers;if(Z.some((Y)=>Y.status==="needs_input"||Y.status==="running"||Y.status==="queued")){this.refreshNonterminalStatus($),this.persist($);return}let J=Z.some((Y)=>Y.status==="failed")?"failed":"completed";this.finalizeRun($,J,J==="failed"?"一个或多个 Agent 失败":void 0).catch((Y)=>{$.finalizing=!1,$.finalized=!1,$.snapshot.status="failed",$.snapshot.error=`Agent terminal persistence failed: ${w$(Y)}`,_(`agent: terminal finalization failed run=${$.snapshot.runId}: ${w$(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${w$(Y)}`).catch((Q)=>_(`agent: terminal failure delivery failed: ${w$(Q)}`))})}async cancelTree($,Z){let J=!p2($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let W of[...$.progressTimers.keys()])this.clearProgressTimer($,W);for(let W of $.capabilityByIdentity.values())this.capabilities.delete(W);$.capabilityByIdentity.clear()}while(!0){let W=[...$.children].map((V)=>this.runs.get(V)).filter((V)=>!!V&&this.treeHasActiveRun(V));if(W.length===0)break;let H=await Promise.allSettled(W.map((V)=>this.cancelTree(V,Z)));if(Y.push(...H),H.some((V)=>V.status==="rejected"))break}if(!J){ZJ(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([W,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${W}: Agent process is still alive after cancellation`);$.handles.delete(W),this.releaseWorkerSlot($,W)}))),Y.some((W)=>W.status==="rejected")){let W=RX(Y);throw $.snapshot.status="failed",$.snapshot.error=W.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${W.message}`).catch((H)=>_(`agent: cancellation failure notice failed: ${w$(H)}`)),W}let Q=[];for(let W of $.snapshot.workers)if(!E6(W.status))W.status="cancelled",W.error=Z,W.finishedAt=new Date().toISOString(),delete W.pendingInput,Q.push(W);await Promise.all(Q.map((W)=>this.updateWorkerCard($,W))),await this.finalizeRun($,"cancelled",Z)}async finalizeRun($,Z,J){if($.finalized||$.finalizing)return;$.finalizing=!0;for(let Y of[...$.progressTimers.keys()])this.clearProgressTimer($,Y);if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)$.snapshot.error=J;try{if($.cardId){if(this.deps.cancelSummary($.cardId),await this.deps.flush($.cardId),!await this.deps.replaceElementChecked($.cardId,U.agentRunFooter,i4($.snapshot)))this.recordPresentationError($,"agent footer update MISS");if(!await this.deps.patchSettingsChecked($.cardId,{config:{streaming_mode:!1,summary:{content:d4($.snapshot)}}}))this.recordPresentationError($,"agent terminal settings update MISS");await this.deps.flush($.cardId),await this.deps.dispose($.cardId)}}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${w$(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,$.snapshot.presentationErrors?.length)await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ agent ${$.snapshot.runId} 结果已保存,但卡片有 ${$.snapshot.presentationErrors.length} 个呈现错误。`).catch((Y)=>_(`agent: warning delivery failed run=${$.snapshot.runId}: ${w$(Y)}`))}async updateWorkerCard($,Z){if(!$.cardId||$.finalized)return;try{if(!await this.deps.replaceElementChecked($.cardId,i8(Z.identityId),l8(Z,d8($.snapshot.workers.length),$.snapshot.workers.length===1)))this.recordPresentationError($,`agent worker card MISS: ${Z.identityName}`);if(!await this.deps.replaceElementChecked($.cardId,U.agentRunFooter,i4($.snapshot)))_(`agent: progress update MISS run=${$.snapshot.runId}; later updates will refresh it`);this.deps.patchSummaryThrottled($.cardId,d4($.snapshot))}catch(J){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${w$(J)}`)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,_(`agent: ${Z} run=${$.snapshot.runId}`)}persist($){if(!$.snapshot.promptArtifact)$.snapshot.promptArtifact=`${$.snapshot.runId}.prompt.txt`;this.persistTextArtifact($,$.snapshot.promptArtifact,$.snapshot.prompt);for(let J of $.snapshot.workers){if(!J.output)continue;if(!J.outputArtifact){let Y=WD("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=H9($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(S6(G1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;UX(Z),this.deps.writeTextArtifact(S6(G1,Z),J),$.persistedArtifacts.add(Z)}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||$.snapshot.workDir!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!p2($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Y=[...this.runs.values()].filter((V)=>this.sessionKey(V.snapshot.sessionName,V.snapshot.chatId)===J&&(!p2(V.snapshot.status)||V.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=jX)throw Error(`Session has reached ${jX} active Agent runs`);if([...this.runs.values()].reduce((V,z)=>V+z.snapshot.workers.filter((X)=>!E6(X.status)||z.handles.get(X.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>PX)throw Error(`global Agent worker limit ${PX} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Q+1);let H=!1;return()=>{if(H)return;H=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),jD(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){return this.cancellationEpochBySession.get(this.sessionKey($.sessionName,$.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}acquireSlot($){if(this.activeTurns<BX)return this.activeTurns++,Promise.resolve();return $(),new Promise((Z)=>this.slotWaiters.push(Z))}releaseSlot(){let $=this.slotWaiters.shift();if($){$();return}this.activeTurns--}releaseWorkerSlot($,Z){if($.slotOwners.delete(Z))this.releaseSlot()}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!p2($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!E6(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,cardId:null,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRuns()}pruneRuns(){if(this.runs.size<=qX)return;let $=[...this.runs.values()].filter((Z)=>p2(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0&&Z.children.size===0).sort((Z,J)=>Date.parse(Z.snapshot.finishedAt??Z.snapshot.createdAt)-Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt));for(let Z of $){if(this.runs.size<=qX)break;if(this.runs.delete(Z.snapshot.runId),Z.snapshot.parentRunId)this.runs.get(Z.snapshot.parentRunId)?.children.delete(Z.snapshot.runId)}}}function _D($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function KD($,Z){let J=Z??$.defaultEffort;if(!J)throw Error(`${$.displayName} default effort MISS; specify effort explicitly`);if(!$.supportedEfforts.includes(J))throw Error(`${$.displayName} does not support effort ${J}`);return J}function DX($,Z){if(Z){let J=$.workers.find((Y)=>Y.identityId===Z);if(!J)throw Error(`agent identity is not part of run ${$.runId}: ${Z}`);return J}if($.workers.length!==1)throw Error("run has multiple Agents; specify identity_id");return $.workers[0]}function p2($){return $==="completed"||$==="failed"||$==="cancelled"}function E6($){return $==="completed"||$==="failed"||$==="cancelled"}function H9($){return JSON.parse(JSON.stringify($))}function BD(){if(!zD(G1))return[];let $=[];for(let Z of XD(G1).filter((J)=>J.endsWith(".json")).sort()){let J=S6(G1,Z),Y;try{Y=JSON.parse(FX(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${w$(Q)}`)}if(!AD(Y))throw Error(`agent run artifact is invalid: ${J}`);LD(Y,J),$.push(Y)}return $}function AD($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&typeof Z.prompt==="string"&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function RX($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(w$).join("; ")}`)}function ZJ($){if($.some((Z)=>Z.status==="rejected"))throw RX($)}function w$($){return $ instanceof Error?$.message:String($)}function qD($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function LD($,Z){if($.promptArtifact)$.prompt=MX($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=MX(J.outputArtifact,`output for ${Z}`)}function MX($,Z){UX($);try{return FX(S6(G1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${w$(J)}`)}}function UX($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function jD($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var BX=8,AX="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",qX=512,LX=50,jX=64,PX=128,GD;var OX=T(()=>{r0();$0();$$();x$();_6();KX();H$();f$();I();GD={getCatalog:g1,startWorker:_X,sendCard:u,sendTextRaw:w,convertMessageToCard:t$,recordCardCreated:p$,replaceElementChecked:G$,patchSummaryThrottled:k0,flush:s$,cancelSummary:F$,patchSettingsChecked:j$,dispose:y$,writeArtifact:t,writeTextArtifact:J0,loadArtifacts:BD}});function TX($){let Z=YJ($,"agent run request"),J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Y=[...new Set(J.map((H)=>H.trim()).filter(Boolean))];if(Y.length===0)throw Error("agent run requires at least one identity_id");if(Y.length>64)throw Error("agent run supports at most 64 identities");let Q=SX(Z.prompt,'agent run requires "prompt"'),W=V9(Z.effort);return{identityIds:Y,prompt:Q,...W?{effort:W}:{}}}function NX($){let Z=YJ($,"agent follow-up request"),J=SX(Z.prompt,'agent follow-up requires "prompt"'),Y=V9(Z.identity_id??Z.identityId),Q=V9(Z.effort);return{prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function EX($){let Z=YJ($,"agent answer request"),J=V9(Z.identity_id??Z.identityId),Y=V9(Z.request_id??Z.requestId);if(!Y)throw Error("agent answer requires request_id");if(!Z.answers||typeof Z.answers!=="object"||Array.isArray(Z.answers))throw Error("agent answer requires an answers object");let Q={};for(let[W,H]of Object.entries(Z.answers)){if(!W.trim())throw Error("agent answer contains an empty question key");Q[W]=String(H)}if(Object.keys(Q).length===0)throw Error("agent answer requires at least one answer");return{requestId:Y,answers:Q,...J?{identityId:J}:{}}}function YJ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function SX($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function V9($){return(typeof $==="string"?$.trim():"")||void 0}async function CX($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(G,K)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},W=MD($.headers.authorization);if(!W)return Q(401,{error:"missing bearer capability"});let H=PD(Y,W);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await B2(),Q(200,FD(g1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,TX(await QJ($)));return Q(202,k6(G))}catch(G){return Q(409,{error:xX(G)})}let V=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!V)return Q(405,{error:"unsupported agent endpoint"});let z=DD(V[1]);if(!z)return Q(400,{error:"invalid agent run id encoding"});let X=V[2];try{if(!X&&$.method==="GET")return Q(200,k6(Y.service.getRun(H,z)));if(!X&&$.method==="DELETE"){let G=await Y.service.cancelRun(H,z,"cancelled by agent client");return Q(G?200:409,G?{ok:!0,run_id:z}:{error:"agent run is already terminal",run_id:z})}if(X==="follow-up"&&$.method==="POST"){let G=await Y.service.followUp(H,z,NX(await QJ($)));return Q(202,k6(G))}if(X==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,z,EX(await QJ($)));return Q(200,k6(G))}}catch(G){return Q(409,{error:xX(G)})}return Q(405,{error:"unsupported agent endpoint"})}function PD($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function DD($){try{return decodeURIComponent($)}catch{return null}}function MD($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function QJ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>kX)throw Error(`request body exceeds ${kX} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function FD($){return{catalog_generation:$.catalogGeneration,identities:$.identities.map((Z)=>({id:Z.id,display_name:Z.displayName,token_source_id:Z.tokenSourceId,token_source_display:Z.tokenSourceDisplay,provider:Z.provider,model:Z.model,model_display:Z.modelDisplay,default_effort:Z.defaultEffort,supported_efforts:Z.supportedEfforts,source_default:Z.sourceDefault,status:Z.status,reason:Z.reason})),source_failures:$.sourceFailures.map((Z)=>({token_source_id:Z.tokenSourceId,display:Z.display,status:Z.status,reason:Z.reason}))}}function k6($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,parent_run_id:$.parentRunId,parent_kind:$.parentKind,depth:$.depth,status:$.status,workers:$.workers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,provider:Z.provider,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,output_truncated:Z.outputTruncated,session_id:Z.sessionId,checkpoint_id:Z.checkpointId,pending_input:Z.pendingInput&&{request_id:Z.pendingInput.requestId,tool_use_id:Z.pendingInput.toolUseId,questions:Z.pendingInput.questions},queued_reason:Z.queuedReason,steps:Z.steps,error:Z.error,started_at:Z.startedAt,finished_at:Z.finishedAt,duration_ms:Z.durationMs,usage:Z.usage})),created_at:$.createdAt,finished_at:$.finishedAt,error:$.error,presentation_errors:$.presentationErrors,card_message_id:$.cardMessageId}}function xX($){return $ instanceof Error?$.message:String($)}var kX=4194304;var bX=T(()=>{_6();Y$()});import{chmodSync as RD,existsSync as WJ,readFileSync as fX,realpathSync as UD,unlinkSync as OD}from"node:fs";import{homedir as TD}from"node:os";import{basename as ND,dirname as ED,join as V1,resolve as SD}from"node:path";function kD($={}){let Z=UD(SD($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??WJ,Q=ED(Z),W=V1(Q,"src","agent-cli.ts"),H=V1(Q,"lodestar-agent.js"),V=V1(Q,"dist","lodestar-agent.js"),X=/^bun(?:\.exe)?$/i.test(ND(J))?[W,H,V]:[H,V],G=X.find(Y);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${X.join(", ")}`);return{runtime:J,entry:G}}function vX($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??CD(Z,$.homeDir??TD(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??kD(),W=V1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${wX(Q.runtime)}" "${wX(Q.entry)}" %*\r
490
530
  `:`#!/bin/sh
491
- exec ${_z(Q.runtime)} ${_z(Q.entry)} "$@"
492
- `,V=aZ(W)?Bz(W,"utf8"):null;if(V!==H)DJ(W,H),_(`command: ${V===null?"installed":"updated"} ${W}`);else Cj(W,448);return cj(J,Y,Z),gj(Y,Z),W}function gj($,Z){let J=W1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!aZ(J))return;try{let Y=Bz(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){_(`command: obsolete path preserved because ownership is unclear ${J}`);return}yj(J),_(`command: removed obsolete ${J}`)}catch(Y){_(`command: obsolete removal failed (${J}): ${Y}`)}}function mj($,Z,J){if($==="win32")return W1(J??W1(Z,"AppData","Local"),"Lodestar","bin");return W1(Z,".local","bin")}function cj($,Z,J){let Y=J==="win32"?Object.keys($).find((V)=>V.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",W=$[Y]??"",H=(V)=>J==="win32"?V.toLowerCase():V;if(W.split(Q).some((V)=>H(V)===H(Z)))return;$[Y]=W?`${Z}${Q}${W}`:Z}function _z($){return`'${$.replaceAll("'",`'"'"'`)}'`}function Kz($){return $.replaceAll('"','""')}var qz=T(()=>{I();w$()});function Pz($,Z,J){return $>0&&Z-$>J}async function Lz($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function jz($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function oZ($){return typeof $==="string"&&$.length>0?$:void 0}function Dz($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=oZ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=oZ(J.file_key);if(!Y)return null;let Q=oZ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function Mz($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function Fz($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class rZ{deps;pending=null;shutdownSnapshot=null;revival=null;constructor($){this.deps=$}load(){if(this.pending)throw Error("session recovery already loaded");this.pending=new Set(this.deps.readMarker())}transferPending($){if(!this.pending)throw Error("session recovery not loaded");if(!this.pending.has($.sessionName))return;$.requireDaemonRestore(),this.pending.delete($.sessionName)}currentNames(){let $=new Set(this.pending);for(let Z of this.deps.sessions())if(Z.shouldRevive())$.add(Z.sessionName);return[...$]}persist(){if(!this.pending)return;this.deps.writeMarker(this.shutdownSnapshot??this.currentNames())}freezeForShutdown(){if(!this.pending)return;this.shutdownSnapshot??=this.currentNames(),this.persist()}enqueue(){if(!this.pending)throw Error("session recovery not loaded");if(this.revival)return this.revival;if(this.deps.isShuttingDown())return Promise.resolve();let $=[...this.pending];return this.deps.log(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`),this.revival=Promise.all($.map((Z)=>{let J=this.deps.chatIdForSession(Z);if(!J)return this.deps.log(`revive: no chatId binding for "${Z}"; recovery remains pending`),Promise.resolve();return this.deps.actor.enqueue(J,async()=>{if(this.deps.isShuttingDown())return;let Y;try{Y=this.deps.sessionFor(J,Z);let Q=await Y.restoreAfterDaemonRestart();this.deps.log(`revive: "${Z}" ${Q?"restored":"did not start"}`)}catch(Q){this.deps.log(`revive: restore "${Z}" failed: ${Q}`)}finally{if(Y)this.pending.delete(Z);this.persist()}})})).then(()=>{}),this.revival}}function pj($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!uj.has(J))return`不支持的操作: ${J}`;let Y=J==="notify_callback"||J==="notify_reply"||J==="notify_reply_cancel";if(!Y&&!String($?.context?.open_chat_id??""))return"回调缺少 chat_id,操作未执行";if(!Y&&!String($?.context?.open_message_id??""))return"回调缺少原卡 message_id,操作未执行";if(J==="permission"&&!["allow","allow_always","deny"].includes(String(Z.decision??"")))return"无效的权限决定,操作未执行";return null}class sZ{tails=new Map;accepting=!0;tryEnqueue($,Z){if(!this.accepting)return{accepted:!1,reason:"closed"};let J=$.trim();if(!J)return{accepted:!1,reason:"invalid-key"};let Q=(this.tails.get(J)??Promise.resolve()).then(Z),W;return W=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===W)this.tails.delete(J)}),this.tails.set(J,W),{accepted:!0,completion:Q}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function Rz($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class eZ{completedTtlMs;now;maxCompletedEntries;inflight=new Set;completed=new Map;constructor($=30000,Z=Date.now,J=4096){this.completedTtlMs=$;this.now=Z;this.maxCompletedEntries=J}claim($){return this.claimAll([$])}claimAll($){if(this.prune(),$.some((Z)=>this.inflight.has(Z)))return"inflight";if($.some((Z)=>this.completed.has(Z)))return"completed";for(let Z of $)this.inflight.add(Z);return"started"}complete($){this.completeAll([$])}completeAll($){this.prune();let Z=this.now()+this.completedTtlMs;for(let J of $)this.inflight.delete(J),this.completed.delete(J),this.completed.set(J,Z);while(this.completed.size>this.maxCompletedEntries){let J=this.completed.keys().next().value;if(J===void 0)break;this.completed.delete(J)}}fail($){this.failAll([$])}failAll($){for(let Z of $)this.inflight.delete(Z)}prune(){let $=this.now();for(let[Z,J]of this.completed)if(J<=$)this.completed.delete(Z)}}function tZ($){if(Array.isArray($))return`[${$.map(tZ).join(",")}]`;if($===void 0)return"undefined";if(!$||typeof $!=="object")return JSON.stringify($);return`{${Object.entries($).sort(([Z],[J])=>Z.localeCompare(J)).map(([Z,J])=>`${JSON.stringify(Z)}:${tZ(J)}`).join(",")}}`}function lj($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),W=null;switch(J){case"menu":W={request_id:Z.request_id};break;case"permission":W={request_id:Z.request_id};break;case"ask":W={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":W={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":W={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":W={guid:Z.guid};break;case"tasklist_enable":W={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":W={source_id:Z.source_id};break;case"agent_identity_page":W={panel_id:Z.panel_id,page:Z.page};break;case"model_page":W={panel_id:Z.panel_id,source_id:Z.source_id,page:Z.page};break;case"model_list_open":W={panel_id:Z.panel_id,source_id:Z.source_id,mode:Z.mode};break;case"model_add":case"model_remove":case"model_custom_remove":W={panel_id:Z.panel_id,source_id:Z.source_id,model:Z.model};break;case"notify_callback":W={notify_id:Z.notify_id};break;case"notify_reply":W={notify_id:Z.notify_id};break;case"notify_reply_cancel":W={notify_id:Z.notify_id,reply_id:Z.reply_id};break;case"provider_select":case"model_select":case"model_custom_prompt":case"model_panel_cancel":case"model_effort_select":W={panel_id:Z.panel_id};break;default:W=Z}return`${Y}\x00${Q}\x00${J}\x00${tZ(W)}`}function ij($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${lj($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function dj(){return new Promise(($)=>setTimeout($,0))}function W9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function Uz($){let Z=$.afterAck??dj,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(W){J(W)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let W=pj(Q);if(W)return $.responses.invalid(Q,W);let H=ij(Q),V=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],X=$.deduper.claimAll(V);if(X==="inflight")return $.responses.inflight(Q);if(X==="completed")return $.responses.completed(Q);let z=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(B){$.deduper.failAll(V),J(B);return}let G;try{G=await $.execute(Q)}catch(B){W9($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,B));return}await Y(async()=>{try{await $.present(Q,G)}catch(B){await $.presentPresentationFailure(Q,B)}});let K;try{K=$.completion(Q,G)}catch(B){W9($.deduper,H,!1),J(B);return}if(K){let B=K.then((A)=>{W9($.deduper,H,A==="complete")},(A)=>{W9($.deduper,H,!1),J(A)});$.track(B);return}W9($.deduper,H,$.businessSucceeded(Q,G))});if(!z.accepted)return $.deduper.failAll(V),$.responses.closed(Q);return $.track(z.completion),z.completion.catch(J),$.responses.accepted(Q)}}}var uj;var Oz=T(()=>{uj=new Set(["permission","menu","provider_select","model_select","model_custom_prompt","model_panel_cancel","model_effort_select","ask","worktree_disband","temp_fork_select","temp_back_select","temp_resume_select","tasklist_enable","tasklist_delete_prompt","tasklist_delete_confirm","token_source_enable","agent_identity_page","model_page","notify_callback","notify_reply","notify_reply_cancel","model_list_open","model_add","model_remove","model_custom_remove"])});function b0($){return $ instanceof Error?$.message:String($)}function Tz($,Z,J){if(!J.disbanded||!J.chatId)throw Error(`飞书未确认删除临时群 "${$}"`);if(Z&&J.chatId!==Z)throw Error(`飞书删除结果 chat_id 不匹配: expected=${Z} actual=${J.chatId}`);return J.chatId}function Nz($){let Z=(Q,W)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==W)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${W}"`);if(!H)H=$.createSession(W,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let W;try{if(K$(Q.launch,Q.routing.provider,Q.workDir),Q.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(W=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!W.created)return{ok:!1,chatId:W.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(V){let X=b0(V);return $.log(`temp-session: create "${Q.chatName}" failed: ${X}`),{ok:!1,error:X}}let H=async()=>{let V=null;try{if($.registerTempSessionLease(Q.chatName,W.chatId),V=Z(W.chatId,Q.chatName),V.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(V.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${V.workDir}`);if(V.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await V.startForked(Q.launch,{announce:!1}):await V.start({announce:!1})))throw Error(`${V.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:W.chatId}}catch(X){let z=b0(X);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${z}`),V)try{await V.stop("临时群启动失败清理",{announce:!1})}catch(K){let B=b0(K);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};无法确认 Session 已停止,临时群/session 仍保留: ${B}`}}if(!W.created)return{ok:!1,error:`${z};既有群保留,未执行删除`};let G;try{let K=await $.disbandChatForSessionExact(Q.chatName,W.chatId);G=Tz(Q.chatName,W.chatId,K)}catch(K){let B=b0(K);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};自动解散失败,临时群/session 仍保留: ${B}`}}try{$.registry.delete(G),V?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(K){let B=b0(K);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,error:`${z};临时群已确认解散,但本地状态清理失败: ${B}`}}return{ok:!1,error:`${z};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(W.chatId,H):await H()}catch(V){let X=b0(V);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${X}`),{ok:!1,chatId:W.chatId,error:`${X};临时群/session 仍保留`}}},disbandTempSession:async(Q,W)=>{let H=$.chatIdForSession(Q);if(!W||H!==W){let z=`临时群 chat_id 已变化: expected=${W||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,W)){let z=`群 ${W} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}let V=$.registry.get(H);try{if(V)await V.stop("bye 解散",{announce:!1})}catch(z){let G=b0(z);return $.log(`temp-session: stop before disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let X;try{let z=await $.disbandChatForSessionExact(Q,H);X=Tz(Q,H,z)}catch(z){let G=b0(z);return $.log(`temp-session: disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(X),V?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(z){let G=b0(z);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var Ez=T(()=>{A1()});var qD={};import*as u2 from"@larksuiteoapi/node-sdk";import{chmodSync as nj,existsSync as ZJ,mkdirSync as aj,readFileSync as oj,unlinkSync as F5,writeFileSync as rj}from"node:fs";import{dirname as tj}from"node:path";function p2($,Z){if(H1=Math.max(H1,Z),M5)return M5;l$=!0,xz?.(),v0.close();try{Cz?.()}catch(J){H1=1,_(`shutdown WebSocket close failed: ${J}`)}try{p1.persist()}catch(J){_(`shutdown alive marker write failed: ${J}`),H1=1}return M5=(async()=>{_(`${$}: staged shutdown begin sessions=${f0.size}`);try{let J=(async()=>{await Fz(()=>[...v0.pending(),...yz]),p1.freezeForShutdown();let H=await Promise.allSettled([JJ.shutdown(`daemon ${$}`),f1.shutdown()]),V=await Promise.allSettled([s3()]),X=await Promise.allSettled([...f0.values()].map((z)=>z.stop(`daemon ${$}`,{announce:!1})));return[...H,...V,...X]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),kz)}),W=await Promise.race([J.then((H)=>{for(let V of H)if(V.status==="rejected")H1=1,_(`shutdown session stop failed: ${V.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(W==="deadline")H1=1,_(`${$}: shutdown deadline ${kz}ms reached; forcing exit`);else _(`${$}: all sessions stopped`)}catch(J){_(`${$}: staged shutdown failed: ${J}`),H1=1}finally{bz(),process.exit(H1)}})(),M5}function YJ($){return Mz(yz,$)}function wz($,Z="ws"){if(l$)return _(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=ej.accept($);if(!Y.accepted)return _(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{_(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function $D(){p1.persist()}function fz($,Z){return QJ.sessionFor($,Z)}async function ZD($){return await QJ.createTempSession($)}async function JD($,Z){return await QJ.disbandTempSession($,Z)}function YD($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let W=Array.isArray($?.content)?$.content:[];for(let H of W){if(!Array.isArray(H))continue;let V=[];for(let z of H){if(!z||typeof z!=="object")continue;switch(z.tag){case"text":{let G=String(z.text??""),K=Array.isArray(z.style)?z.style:[];if(K.includes("bold"))G=`**${G}**`;if(K.includes("italic"))G=`*${G}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))G=`~~${G}~~`;V.push(G);break}case"a":{let G=String(z.href??""),K=String(z.text??G);V.push(`[${K}](${G})`);break}case"at":{let G=String(z.user_name??z.user_id??"");V.push(`@${G}`);break}case"code_inline":V.push(`\`${String(z.text??"")}\``);break;case"hr":V.push("---");break;case"img":if(z.image_key)Z.push(String(z.image_key));break;case"media":if(z.file_key)J.push({key:String(z.file_key),name:z.file_name});break;case"emotion":break;default:if(typeof z.text==="string")V.push(z.text)}}let X=V.join("");if(X.trim())Y.push(X)}return{markdown:Y.join(`
531
+ exec ${yX(Q.runtime)} ${yX(Q.entry)} "$@"
532
+ `,V=WJ(W)?fX(W,"utf8"):null;if(V!==H)gJ(W,H),_(`command: ${V===null?"installed":"updated"} ${W}`);else RD(W,448);return bD(J,Y,Z),xD(Y,Z),W}function xD($,Z){let J=V1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!WJ(J))return;try{let Y=fX(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){_(`command: obsolete path preserved because ownership is unclear ${J}`);return}OD(J),_(`command: removed obsolete ${J}`)}catch(Y){_(`command: obsolete removal failed (${J}): ${Y}`)}}function CD($,Z,J){if($==="win32")return V1(J??V1(Z,"AppData","Local"),"Lodestar","bin");return V1(Z,".local","bin")}function bD($,Z,J){let Y=J==="win32"?Object.keys($).find((V)=>V.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",W=$[Y]??"",H=(V)=>J==="win32"?V.toLowerCase():V;if(W.split(Q).some((V)=>H(V)===H(Z)))return;$[Y]=W?`${Z}${Q}${W}`:Z}function yX($){return`'${$.replaceAll("'",`'"'"'`)}'`}function wX($){return $.replaceAll('"','""')}var hX=T(()=>{I();f$()});function IX($,Z,J){return $>0&&Z-$>J}async function gX($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function mX($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function HJ($){return typeof $==="string"&&$.length>0?$:void 0}function cX($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=HJ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=HJ(J.file_key);if(!Y)return null;let Q=HJ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function pX($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function uX($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class VJ{deps;pending=null;shutdownSnapshot=null;revival=null;constructor($){this.deps=$}load(){if(this.pending)throw Error("session recovery already loaded");this.pending=new Set(this.deps.readMarker())}transferPending($){if(!this.pending)throw Error("session recovery not loaded");if(!this.pending.has($.sessionName))return;$.requireDaemonRestore(),this.pending.delete($.sessionName)}currentNames(){let $=new Set(this.pending);for(let Z of this.deps.sessions())if(Z.shouldRevive())$.add(Z.sessionName);return[...$]}persist(){if(!this.pending)return;this.deps.writeMarker(this.shutdownSnapshot??this.currentNames())}freezeForShutdown(){if(!this.pending)return;this.shutdownSnapshot??=this.currentNames(),this.persist()}enqueue(){if(!this.pending)throw Error("session recovery not loaded");if(this.revival)return this.revival;if(this.deps.isShuttingDown())return Promise.resolve();let $=[...this.pending];return this.deps.log(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`),this.revival=Promise.all($.map((Z)=>{let J=this.deps.chatIdForSession(Z);if(!J)return this.deps.log(`revive: no chatId binding for "${Z}"; recovery remains pending`),Promise.resolve();return this.deps.actor.enqueue(J,async()=>{if(this.deps.isShuttingDown())return;let Y;try{Y=this.deps.sessionFor(J,Z);let Q=await Y.restoreAfterDaemonRestart();this.deps.log(`revive: "${Z}" ${Q?"restored":"did not start"}`)}catch(Q){this.deps.log(`revive: restore "${Z}" failed: ${Q}`)}finally{if(Y)this.pending.delete(Z);this.persist()}})})).then(()=>{}),this.revival}}function wD($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!yD.has(J))return`不支持的操作: ${J}`;let Y=J==="notify_callback"||J==="notify_reply"||J==="notify_reply_cancel";if(!Y&&!String($?.context?.open_chat_id??""))return"回调缺少 chat_id,操作未执行";if(!Y&&!String($?.context?.open_message_id??""))return"回调缺少原卡 message_id,操作未执行";if(J==="permission"&&!["allow","allow_always","deny"].includes(String(Z.decision??"")))return"无效的权限决定,操作未执行";return null}class XJ{tails=new Map;accepting=!0;tryEnqueue($,Z){if(!this.accepting)return{accepted:!1,reason:"closed"};let J=$.trim();if(!J)return{accepted:!1,reason:"invalid-key"};let Q=(this.tails.get(J)??Promise.resolve()).then(Z),W;return W=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===W)this.tails.delete(J)}),this.tails.set(J,W),{accepted:!0,completion:Q}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function lX($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class GJ{completedTtlMs;now;maxCompletedEntries;inflight=new Set;completed=new Map;constructor($=30000,Z=Date.now,J=4096){this.completedTtlMs=$;this.now=Z;this.maxCompletedEntries=J}claim($){return this.claimAll([$])}claimAll($){if(this.prune(),$.some((Z)=>this.inflight.has(Z)))return"inflight";if($.some((Z)=>this.completed.has(Z)))return"completed";for(let Z of $)this.inflight.add(Z);return"started"}complete($){this.completeAll([$])}completeAll($){this.prune();let Z=this.now()+this.completedTtlMs;for(let J of $)this.inflight.delete(J),this.completed.delete(J),this.completed.set(J,Z);while(this.completed.size>this.maxCompletedEntries){let J=this.completed.keys().next().value;if(J===void 0)break;this.completed.delete(J)}}fail($){this.failAll([$])}failAll($){for(let Z of $)this.inflight.delete(Z)}prune(){let $=this.now();for(let[Z,J]of this.completed)if(J<=$)this.completed.delete(Z)}}function zJ($){if(Array.isArray($))return`[${$.map(zJ).join(",")}]`;if($===void 0)return"undefined";if(!$||typeof $!=="object")return JSON.stringify($);return`{${Object.entries($).sort(([Z],[J])=>Z.localeCompare(J)).map(([Z,J])=>`${JSON.stringify(Z)}:${zJ(J)}`).join(",")}}`}function fD($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),W=null;switch(J){case"menu":W={request_id:Z.request_id};break;case"permission":W={request_id:Z.request_id};break;case"ask":W={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":W={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":W={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":W={guid:Z.guid};break;case"tasklist_enable":W={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":W={source_id:Z.source_id};break;case"agent_identity_page":W={panel_id:Z.panel_id,page:Z.page};break;case"model_page":W={panel_id:Z.panel_id,source_id:Z.source_id,page:Z.page};break;case"model_list_open":W={panel_id:Z.panel_id,source_id:Z.source_id,mode:Z.mode};break;case"model_add":case"model_remove":case"model_custom_remove":W={panel_id:Z.panel_id,source_id:Z.source_id,model:Z.model};break;case"notify_callback":W={notify_id:Z.notify_id};break;case"notify_reply":W={notify_id:Z.notify_id};break;case"notify_reply_cancel":W={notify_id:Z.notify_id,reply_id:Z.reply_id};break;case"provider_select":case"model_select":case"model_custom_prompt":case"model_panel_cancel":case"model_effort_select":W={panel_id:Z.panel_id};break;default:W=Z}return`${Y}\x00${Q}\x00${J}\x00${zJ(W)}`}function vD($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${fD($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function hD(){return new Promise(($)=>setTimeout($,0))}function z9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function iX($){let Z=$.afterAck??hD,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(W){J(W)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let W=wD(Q);if(W)return $.responses.invalid(Q,W);let H=vD(Q),V=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],z=$.deduper.claimAll(V);if(z==="inflight")return $.responses.inflight(Q);if(z==="completed")return $.responses.completed(Q);let X=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(B){$.deduper.failAll(V),J(B);return}let G;try{G=await $.execute(Q)}catch(B){z9($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,B));return}await Y(async()=>{try{await $.present(Q,G)}catch(B){await $.presentPresentationFailure(Q,B)}});let K;try{K=$.completion(Q,G)}catch(B){z9($.deduper,H,!1),J(B);return}if(K){let B=K.then((L)=>{z9($.deduper,H,L==="complete")},(L)=>{z9($.deduper,H,!1),J(L)});$.track(B);return}z9($.deduper,H,$.businessSucceeded(Q,G))});if(!X.accepted)return $.deduper.failAll(V),$.responses.closed(Q);return $.track(X.completion),X.completion.catch(J),$.responses.accepted(Q)}}}var yD;var dX=T(()=>{yD=new Set(["permission","menu","provider_select","model_select","model_custom_prompt","model_panel_cancel","model_effort_select","ask","worktree_disband","temp_fork_select","temp_back_select","temp_resume_select","tasklist_enable","tasklist_delete_prompt","tasklist_delete_confirm","token_source_enable","agent_identity_page","model_page","notify_callback","notify_reply","notify_reply_cancel","model_list_open","model_add","model_remove","model_custom_remove"])});function w0($){return $ instanceof Error?$.message:String($)}function nX($,Z,J){if(!J.disbanded||!J.chatId)throw Error(`飞书未确认删除临时群 "${$}"`);if(Z&&J.chatId!==Z)throw Error(`飞书删除结果 chat_id 不匹配: expected=${Z} actual=${J.chatId}`);return J.chatId}function aX($){let Z=(Q,W)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==W)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${W}"`);if(!H)H=$.createSession(W,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let W;try{if(B$(Q.launch,Q.routing.provider,Q.workDir),Q.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(W=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!W.created)return{ok:!1,chatId:W.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(V){let z=w0(V);return $.log(`temp-session: create "${Q.chatName}" failed: ${z}`),{ok:!1,error:z}}let H=async()=>{let V=null;try{if($.registerTempSessionLease(Q.chatName,W.chatId),V=Z(W.chatId,Q.chatName),V.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(V.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${V.workDir}`);if(V.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await V.startForked(Q.launch,{announce:!1}):await V.start({announce:!1})))throw Error(`${V.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:W.chatId}}catch(z){let X=w0(z);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${X}`),V)try{await V.stop("临时群启动失败清理",{announce:!1})}catch(K){let B=w0(K);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${X};无法确认 Session 已停止,临时群/session 仍保留: ${B}`}}if(!W.created)return{ok:!1,error:`${X};既有群保留,未执行删除`};let G;try{let K=await $.disbandChatForSessionExact(Q.chatName,W.chatId);G=nX(Q.chatName,W.chatId,K)}catch(K){let B=w0(K);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${X};自动解散失败,临时群/session 仍保留: ${B}`}}try{$.registry.delete(G),V?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(K){let B=w0(K);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,error:`${X};临时群已确认解散,但本地状态清理失败: ${B}`}}return{ok:!1,error:`${X};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(W.chatId,H):await H()}catch(V){let z=w0(V);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${z}`),{ok:!1,chatId:W.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Q,W)=>{let H=$.chatIdForSession(Q);if(!W||H!==W){let X=`临时群 chat_id 已变化: expected=${W||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${X}`),{ok:!1,error:`${X};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,W)){let X=`群 ${W} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${X}`),{ok:!1,error:`${X};未执行停止或删群`}}let V=$.registry.get(H);try{if(V)await V.stop("bye 解散",{announce:!1})}catch(X){let G=w0(X);return $.log(`temp-session: stop before disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let z;try{let X=await $.disbandChatForSessionExact(Q,H);z=nX(Q,H,X)}catch(X){let G=w0(X);return $.log(`temp-session: disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(z),V?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(X){let G=w0(X);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var oX=T(()=>{L1()});var HM={};import*as l2 from"@larksuiteoapi/node-sdk";import{chmodSync as ID,existsSync as KJ,mkdirSync as gD,readFileSync as mD,unlinkSync as C6,writeFileSync as cD}from"node:fs";import{dirname as pD}from"node:path";function i2($,Z){if(z1=Math.max(z1,Z),x6)return x6;i$=!0,sX?.(),I0.close();try{eX?.()}catch(J){z1=1,_(`shutdown WebSocket close failed: ${J}`)}try{i1.persist()}catch(J){_(`shutdown alive marker write failed: ${J}`),z1=1}return x6=(async()=>{_(`${$}: staged shutdown begin sessions=${h0.size}`);try{let J=(async()=>{await uX(()=>[...I0.pending(),...ZG]),i1.freezeForShutdown();let H=await Promise.allSettled([BJ.shutdown(`daemon ${$}`),h1.shutdown()]),V=await Promise.allSettled([XZ()]),z=await Promise.allSettled([...h0.values()].map((X)=>X.stop(`daemon ${$}`,{announce:!1})));return[...H,...V,...z]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),tX)}),W=await Promise.race([J.then((H)=>{for(let V of H)if(V.status==="rejected")z1=1,_(`shutdown session stop failed: ${V.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(W==="deadline")z1=1,_(`${$}: shutdown deadline ${tX}ms reached; forcing exit`);else _(`${$}: all sessions stopped`)}catch(J){_(`${$}: staged shutdown failed: ${J}`),z1=1}finally{$G(),process.exit(z1)}})(),x6}function AJ($){return pX(ZG,$)}function JG($,Z="ws"){if(i$)return _(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=lD.accept($);if(!Y.accepted)return _(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{_(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function iD(){i1.persist()}function YG($,Z){return qJ.sessionFor($,Z)}async function dD($){return await qJ.createTempSession($)}async function nD($,Z){return await qJ.disbandTempSession($,Z)}function aD($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let W=Array.isArray($?.content)?$.content:[];for(let H of W){if(!Array.isArray(H))continue;let V=[];for(let X of H){if(!X||typeof X!=="object")continue;switch(X.tag){case"text":{let G=String(X.text??""),K=Array.isArray(X.style)?X.style:[];if(K.includes("bold"))G=`**${G}**`;if(K.includes("italic"))G=`*${G}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))G=`~~${G}~~`;V.push(G);break}case"a":{let G=String(X.href??""),K=String(X.text??G);V.push(`[${K}](${G})`);break}case"at":{let G=String(X.user_name??X.user_id??"");V.push(`@${G}`);break}case"code_inline":V.push(`\`${String(X.text??"")}\``);break;case"hr":V.push("---");break;case"img":if(X.image_key)Z.push(String(X.image_key));break;case"media":if(X.file_key)J.push({key:String(X.file_key),name:X.file_name});break;case"emotion":break;default:if(typeof X.text==="string")V.push(X.text)}}let z=V.join("");if(z.trim())Y.push(z)}return{markdown:Y.join(`
493
533
 
494
- `),imageKeys:Z,fileKeys:J}}async function WD($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",W=J.message_id;if(W&&c2.has(W))return;if(W){if(c2.add(W),c2.size>200){let R=[...c2];c2.clear();for(let M of R.slice(-100))c2.add(M)}}let H=Number(J.create_time??0);if(Pz(H,Z,QD)){if(_(`drop stale message ${W} ageAtReceipt=${Math.round((Z-H)/1000)}s`),W)m$(W,"CrossMark");return}let V=J.chat_id,X={};try{X=JSON.parse(J.content??"{}")}catch{}let z=J.message_type==="text"?X.text??"":"";if(typeof z==="string"&&z.startsWith("[DEBUG]")){try{rj(G9,JSON.stringify({chat_id:V,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:W??""},null,2)),_(`debug: seeded inject context chat=${V.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(M){_(`debug: seed context failed: ${M}`)}let R=z.slice(7);X.text=R,J.content=JSON.stringify(X)}let G=q$.get(V);if(!G)await k4(),G=q$.get(V);if(!G)G=await c7(V)??void 0;if(!G){_(`unknown chat ${V}, dropping message`),await E(V,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=i7(G);L2(K,V);let B=fz(V,K),A={};try{A=JSON.parse(J.content??"{}")}catch{}let P=J.message_type,L="",j=!1,N=[];if(P==="text")L=(A.text??"").trim();else if(P==="post"){let R=YD(A);j=R.imageKeys.length>0||R.fileKeys.length>0,L=R.markdown.trim();for(let M of R.imageKeys){let k=await x4(J.message_id,M,"image");if(k)N.push(k)}for(let M of R.fileKeys){let k=await x4(J.message_id,M.key,"file",M.name);if(k)N.push(k)}}if(P==="text"&&L){if(await B.runCommand(L,Q))return}if((P==="text"||P==="post")&&L&&!j&&await Lz({reply:()=>R5.consume({chatId:V,openId:Q,messageId:W??"",text:L,createTime:H,parentId:J.parent_id}),hasQuestion:()=>B.hasPendingAsk(),answerQuestion:()=>B.onAskMessageAnswer(L,Q,W??"")}))return;if(P==="text"&&L&&await B.consumeModelCustomMessage(L,Q))return;let F=Dz(P,A);if(F){let R=await x4(J.message_id,F.key,F.type,F.name);if(!R){await E(V,jz(P));return}if(N.push(R),!L&&F.displayText)L=F.displayText}if(!L&&N.length===0){_(`drop empty message ${W} type=${P}`);return}if(await B.onMultiMessageInbound(L,N,Q,W??""))return;await B.onUserMessage(L||"(empty)",N,Q,W??"")}function U5($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复"}[$]??$}function HD($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function V$($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function w0($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function y0($){return V$($.card?e$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function u1($,Z){if(!$){_(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await w($,Z))_(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function VD($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=U5(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),W=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=HD(Z),V=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&W)try{await B0(W,H);return}catch(A){_(`card-action: ${J} original-card update failed: ${A instanceof Error?A.message:A}`),await u1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await u1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let X=Z?.toast,z=typeof X?.content==="string"&&X.content.trim()?X.content.trim():`${Y}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||X?.type==="error"&&!G;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await u1(Q,`${K?"❌":"✅"} ${Y}: ${z}`)}async function XD($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await u1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${U5(J)}失败: ${Y}`)}function vz($){return zD.accept($)}async function GD($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Y=$?.context?.open_chat_id??"",Q=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let H=String(J.notify_id??""),V=k0(H);if(V)$.__cardActionChatId=V.chatId;if(J.kind==="notify_callback")return await _D(J,Y,Q);let X=J.kind==="notify_reply"?await R5.open(H,Y,Q):await R5.cancel(H,String(J.reply_id??""),Y,Q),z=V$({toast:{type:X.ok?"success":"error",content:X.message},__cardActionPresented:X.presented===!0},X.ok);return V?w0(V,z):z}let W=f0.get(Y);if(!W)return V$({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let H=String(J.decision??"");if(!["allow","allow_always","deny"].includes(H))return{toast:{type:"error",content:"无效的权限决定"}};let V=await W.onPermissionDecision(J.request_id,H,Q);return V$({toast:{type:V.ok?H==="deny"?"error":"success":"error",content:V.message}},V.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await W.onUserMessage(`(menu choice ${H+1})`),V$(e$(s0({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(V){let X=V instanceof Error?V.message:String(V);return V$(e$(s0({title:"\uD83D\uDCCB 菜单选择",message:X,ok:!1})),!1)}}case"provider_select":{let H=await W.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return y0(H)}case"model_page":{let H=await W.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return y0(H)}case"model_list_open":{let H=String(J.panel_id??""),V=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return y0(await(J.mode==="add"?W.onModelAddOpen(H,V):W.onProviderSelect(V,H)))}case"model_add":case"model_remove":case"model_custom_remove":return y0(await W.onModelListEdit(String(J.panel_id??""),String(J.source_id??""),String(J.model??""),J.kind==="model_add"?"add":J.kind==="model_remove"?"remove":"delete"));case"model_select":{let H=await W.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return y0(H)}case"model_custom_prompt":{let H=await W.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return y0(H)}case"model_panel_cancel":{let H=await W.onModelPanelCancel(String(J.panel_id??""));return y0(H)}case"model_effort_select":{let H=await W.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return y0(H)}case"ask":{let H=W.askBlockReason(String(J.tool_use_id??""));if(H)return V$({toast:{type:"error",content:H}},!1);if(J.custom){let z=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await W.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,z,Q);return V$({toast:{type:G?"success":"error",content:G?"已回答":z.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let V=await W.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return V$({toast:{type:V?"success":"error",content:V?"已回答":"问题已失效或选项无效"}},V)}case"worktree_disband":{let H=await W.onWorktreeDisband(String(J.slug??""));return V$(e$(H.card),H.ok)}case"temp_fork_select":{let H=await W.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return V$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:e$(s0({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await W.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return V$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:e$(s0({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await W.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return V$({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return V$(e$(M3({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await W.onTasklistEnable();return V$(e$(H.card),H.ok)}case"tasklist_delete_prompt":{let H=W.onTasklistDeletePrompt(String(J.guid??""));return V$(e$(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await W.onTasklistDeleteConfirm(String(J.guid??""));return V$(e$(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (qZ(),AZ));return await H(W,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return y0(W.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function _D($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let W=k0(Y);if(!W)return _(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(W.unknownAt)return w0(W,V$({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${W.unknownReason?`: ${W.unknownReason}`:""}`}},!0));if(W.resolvedAt)return w0(W,{toast:{type:"info",content:"已处理过"}});if(N2(Y))return w0(W,{toast:{type:"info",content:"处理中…"}});if(W.replyState?.status==="waiting"||W.replyState?.status==="sending")return w0(W,V$({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let H=W.buttons.find((z)=>z.id===Q);if(!H)return _(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),w0(W,V$({toast:{type:"error",content:"未知按钮"}},!1));if(!W.callbackUrl){try{o4(W.notifyId,H.id,J)}catch(z){return w0(W,V$({toast:{type:"error",content:`保存反馈结果失败: ${z instanceof Error?z.message:z}`}},!1))}return _(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),w0(W,{...e$(c1(W,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}d4(W.notifyId);let V=YJ(KD(W,H,J));V.catch((z)=>{_(`notify-callback: notify_id=${W.notifyId.slice(0,12)}… phase-2 rejected: ${z instanceof Error?z.message:z}`)});let X=V.then((z)=>z==="retry"?"retry":"complete").catch(()=>"retry");return w0(W,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:X})}async function KD($,Z,J){try{let Y=c1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await B0($.messageId,Y)}catch(V){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${V instanceof Error?V.message:V}`)}let Q=await l3($,Z,J),W=Q.ok?"complete":"retry",H;if(Q.ok){let V=m8($.notifyId,Z.id,J);if(V.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{W="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:V.detail},_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${V.detail}`);try{await u1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${V.detail}`)}catch(X){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${X instanceof Error?X.message:X}`)}}}else H={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Q.detail};try{let V=c1($,H);await B0($.messageId,V)}catch(V){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${V instanceof Error?V.message:V}`);try{await u1($.chatId,`⚠️ 通知反馈${W==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${V instanceof Error?V.message:V}`)}catch(X){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${X instanceof Error?X.message:X}`)}}return _(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${W==="complete"?"delivered":W==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),W}finally{n4($.notifyId)}}function $J($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function BD(){if(process.platform==="win32"){_("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){_("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(ZJ(G1))F5(G1)}catch{}try{Bun.serve({unix:G1,fetch:async($)=>{let Z=new URL($.url),J=$.method==="GET"&&Z.pathname==="/model-state";if($.method!=="POST"&&!J)return new Response("unsupported debug method",{status:405});if(l$)return new Response("daemon shutdown in progress",{status:503});let Y={};if($.method==="POST")try{Y=await $.json()}catch{return new Response("bad json",{status:400})}if(!ZJ(G9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(oj(G9,"utf8"))}catch(G){return new Response(`ctx read failed: ${G}`,{status:500})}let W=J?Z.searchParams.get("chat_id"):Y.chat_id;if(W!==void 0&&W!==Q.chat_id||Z.pathname!=="/"&&!W)return new Response("explicit debug chat_id must match the seeded context",{status:409});if(J){let G=f0.get(Q.chat_id);return G?Response.json(gZ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=f0.get(Q.chat_id);if(!G)return new Response("debug session not found",{status:404});try{if(typeof Y.message_id!=="string"||!Y.message_id.startsWith("om_"))throw Error("message_id required");let K=typeof Y.value?.panel_id==="string"?Y.value.panel_id.trim():"",B=G.modelPanels.get(K);if(!B?.messageId||B.messageId!==Y.message_id)throw Error("stale or mismatched model panel");let A=await Y$.im.v1.message.get({path:{message_id:Y.message_id}});if(A.code!==0)throw Error(`message.get failed: ${A.code} ${A.msg}`);let P=EX(Y,Q,A.data?.items?.[0],f.feishu.app_id,B.messageId);_(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let L=vz(P);return await v0.enqueue(Q.chat_id,async()=>{}),Response.json({admission:L,state:gZ(G)})}catch(K){return new Response(K instanceof Error?K.message:String(K),{status:400})}}if(Z.pathname!=="/")return new Response("unknown debug endpoint",{status:404});let H=String(Y.text??"");if(!H)return new Response("text required",{status:400});let V=`【自动化测试】:${H}`,X=await E(Q.chat_id,V);if(!X)return new Response("sendText failed — see daemon log",{status:502});let z={sender:{sender_id:{open_id:Q.sender_open_id}},message:{message_id:X,chat_id:Q.chat_id,message_type:"text",content:JSON.stringify({text:H}),create_time:String(Date.now())}};if(_(`debug: inject text=${JSON.stringify(H).slice(0,80)} msg_id=${X}`),!wz(z,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Y.wait_for_handling===!0)await v0.enqueue(Q.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:X}),{headers:{"content-type":"application/json"}})}});try{nj(G1,384)}catch{}_(`debug: inject socket listening at ${G1}`)}catch($){_(`debug: socket bind failed: ${$}`)}}async function AD(){_(`lodestar-daemon: pid ${process.pid} starting`),p1.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (KZ(),QV));if(l$)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (J$(),aY));if(l$)return;if(await Z(),l$)return;if(R7(),T7(),N7(),S7(),C7(),await k4(),l$)return;setInterval(()=>{k4()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (OZ(),UZ));if(l$)return;try{await J()}catch(D){_(`tasklist deletion reconcile failed: ${D instanceof Error?D.message:D}`)}if(l$)return;let Y,Q=Date.now(),W=0,H=!1,V=null,X=1500,z=90000,G=600000,K=3,B=null,A=0,P="",L=!1,j=(D)=>{_(`[ws] rebuild requested before WS init — ${D}`)},N=(D,x=0,i=!1)=>{if(l$)return;let a=Date.now()+x;if(B){if(L||=i,a>=A){_(`[ws] rebuild already scheduled — ${D}`);return}clearTimeout(B)}A=a,P=D,L=i,B=setTimeout(()=>{let G$=P,l2=L;B=null,A=0,P="",L=!1,j(G$,l2)},x)},F={error:(D)=>_(`[ws-sdk error] ${$J(D)}`),warn:(D)=>{let x=$J(D);if(_(`[ws-sdk warn] ${x}`),x.includes("no pong/inbound"))N("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(D)=>_(`[ws-sdk] ${$J(D)}`),debug:(D)=>{},trace:(D)=>{}},R=new u2.EventDispatcher({}),M=()=>{if(Q=Date.now(),W=0,V)clearTimeout(V),V=null};R.register({"im.message.receive_v1":async(D)=>{if(M(),!wz(D))throw Error("daemon shutdown in progress")}}),R.register({"card.action.trigger":async(D)=>{return M(),vz(D)}});let k=()=>new u2.WSClient({appId:f.feishu.app_id,appSecret:f.feishu.app_secret,loggerLevel:u2.LoggerLevel.info,logger:F,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>_("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>v(),onError:(D)=>j(`SDK onError: ${D?.message??D}`)});j=(D,x=!1)=>{if(l$)return;if(H){_(`[ws] rebuild skipped (already rebuilding) — ${D}`);return}if(B)clearTimeout(B),B=null,A=0;H=!0,W++,_(`[ws] rebuild #${W} (fresh WSClient) — ${D}`);let i=Y;try{i?.close({force:!0})}catch(a){_(`[ws] rebuild: old close failed: ${a}`)}if(Y=k(),Y.start({eventDispatcher:R}).catch((a)=>{_(`[ws] rebuild start failed: ${a}`),N(`fresh client start failed: ${a}`,X,x)}),H=!1,x)C()};let C=()=>{if(V)clearTimeout(V);let D=Date.now();V=setTimeout(()=>{if(V=null,Q>=D){W=0;return}if(W>=K){_(`[ws] STILL deaf after ${K} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),W=0;return}j(`verify: no event ${Math.round((Date.now()-D)/1000)}s after rebuild`,!0)},z)},v=()=>{let D=Date.now()-Q<G;_("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${D})`),W=0,N("post-reconnect precaution",X,D)};Y=k();let b=15000,c=2,S=0,h=setInterval(()=>{if(l$)return;let{state:D}=Y.getConnectionStatus();if(D==="connected"){S=0;return}if(D==="failed"||D==="idle"){S=0,j(`watchdog: state=${D}`);return}if(S++,_(`[ws] watchdog: state=${D} (${S}/${c})`),S>=c)S=0,j(`watchdog: stuck in '${D}' ~${Math.round(b*c/1000)}s`)},b);Cz=()=>{if(clearInterval(h),B)clearTimeout(B);if(V)clearTimeout(V);Y.close({force:!0})};let m=DH();yX({bind:f.notify.bind,port:f.notify.port,extraHandler:(D,x,i)=>zz(D,x,i,{service:JJ,authorizeSession:(a)=>{for(let G$ of f0.values())if(G$.acceptsAgentCapability(a))return G$;return null}})}),Az(),vX(),uX();let p=p1.enqueue();xz=EJ(_,{enabled:f.runtime.agent_auto_update}),Y.start({eventDispatcher:R}).catch((D)=>{_(`[ws] initial start failed: ${D}`),N(`initial start failed: ${D}`,X,!1)}),_(`lodestar-daemon: WS start requested, watching ${q$.size} groups`),BD();for(let D of m)YJ(v0.enqueue(D.chatId,()=>R5.recover(D))).catch((x)=>_(`notify-reply recovery failed: ${x instanceof Error?x.message:x}`));await p}var Sz=!1,l$=!1,M5=null,H1=0,xz,Cz,kz=15000,bz=()=>{if(Sz)return;Sz=!0;try{p1.persist()}catch($){_(`alive marker write failed: ${$}`)}try{F5(i$)}catch{}try{F5(G1)}catch{}},f0,JJ,v0,p1,sj,yz,ej,QJ,QD=30000,c2,R5,zD;var hz=T(()=>{MZ();$$();s$();SX();r4();A5();A5();hX();gX();Jz();t3();n8();Gz();pZ();qz();k$();I();a1();W$();y5();Oz();Ez();{let $=_9(i$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(ZJ(i$))try{F5(i$)}catch{}}aj(tj(i$),{recursive:!0});AJ(i$);process.on("exit",bz);process.on("SIGTERM",()=>{p2("SIGTERM",0)});process.on("SIGINT",()=>{p2("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{p2("SIGBREAK",0)});process.on("unhandledRejection",($)=>{_(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),p2("unhandledRejection",1)});process.on("uncaughtException",($)=>{_(`uncaughtException: ${$.stack??$.message}`),p2("uncaughtException",1)});f0=new Map,JJ=new iZ,v0=new sZ,p1=new rZ({readMarker:v7,writeMarker:f7,sessions:()=>f0.values(),chatIdForSession:V8,sessionFor:fz,actor:v0,isShuttingDown:()=>l$,log:_}),sj=new eZ(30000),yz=new Set,ej=Rz({actor:v0,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>WD($,Z)});QJ=Nz({registry:f0,createSession:($,Z)=>{let J=new Q0($,Z,{onLifecycleChange:$D,onCreateTempSession:ZD,onDisbandTempSession:JD,onCancelAgentRuns:(Y,Q,W)=>JJ.cancelSessionRuns(Y,Q,W)});return p1.transferPending(J),J},ensureChatForSession:I7,disbandChatForSessionExact:m7,chatIdForSession:V8,clearSessionConversationState:w7,registerTempSessionLease:U7,hasTempSessionLease:O7,replaceTurnAnchors:a$,runExclusive:($,Z)=>v0.enqueue($,Z),log:_});c2=new Set,R5=IX({sendCard:u,updateCard:B0,sendText:E,dispatch:l3,onWaitingChanged:($)=>f0.get($)?.refreshPendingAsks(),log:_});zD=Uz({actor:v0,deduper:sj,scope:($)=>{let Z=String($?.action?.value?.kind??"");if(Z.startsWith("agent_identity_"))return"__agent_identities_global__";if(Z==="notify_callback"||Z==="notify_reply"||Z==="notify_reply_cancel"){let J=k0(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:GD,present:VD,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");_(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await XD($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");_(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await u1(String($?.context?.open_chat_id??""),`⚠️ ${U5(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__cardActionCompletion;return J&&typeof J.then==="function"?J:null},track:($)=>{YJ($)},onBackgroundError:($)=>{_(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${U5(String($?.action?.value?.kind??"unknown"))}已接收,后台处理中…`}}),inflight:()=>({toast:{type:"info",content:"相同操作正在处理…"}}),completed:()=>({toast:{type:"info",content:"该操作近期已执行或尝试;为防重复暂不再次执行,请查看原卡或群消息"}}),closed:()=>({toast:{type:"error",content:"服务正在重启,请稍后重试"}}),invalid:($,Z)=>({toast:{type:"error",content:Z}})}});AD().catch(($)=>{_(`boot fatal: ${$}`),p2("boot fatal",1)})});W$();y5();import{existsSync as Iz,unlinkSync as PD}from"node:fs";var W0={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function LD(){if(!Iz(U$)){if(process.stdin.isTTY){console.log(),console.log(`${W0.bold}${W0.yellow}Lodestar: 未找到配置, 启动安装向导...${W0.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (CJ(),xJ));await Z();return}console.error(`${W0.red}Lodestar: 未找到配置 ${U$}${W0.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${W0.green}lodestar-setup${W0.reset} 完成首次配置 (或直接运行 ${W0.green}lodestar-daemon${W0.reset} 也会触发同一个向导)。`),process.exit(1)}let $=_9(i$);if($.state==="exit")console.error(`${W0.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${W0.reset}`),console.error(" • 想看日志:"+(process.platform==="win32"?" %LOCALAPPDATA%\\Lodestar\\daemon-YYYY-MM-DD.log":" ~/.local/share/lodestar/daemon-YYYY-MM-DD.log")),console.error(" • 想停: 任务管理器结束 pid 上面那个号 (Windows) / `kill "+$.pid+"` (Linux/macOS)"),console.error(` • 误判 / 已经死了: 手删 ${i$} 后再跑`),process.exit(1);if(Iz(i$))try{PD(i$)}catch{}await Promise.resolve().then(() => (hz(),qD))}LD().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
534
+ `),imageKeys:Z,fileKeys:J}}async function rD($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",W=J.message_id;if(W&&u2.has(W))return;if(W){if(u2.add(W),u2.size>200){let R=[...u2];u2.clear();for(let M of R.slice(-100))u2.add(M)}}let H=Number(J.create_time??0);if(IX(H,Z,oD)){if(_(`drop stale message ${W} ageAtReceipt=${Math.round((Z-H)/1000)}s`),W)c$(W,"CrossMark");return}let V=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let X=J.message_type==="text"?z.text??"":"";if(typeof X==="string"&&X.startsWith("[DEBUG]")){try{cD(B9,JSON.stringify({chat_id:V,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:W??""},null,2)),_(`debug: seeded inject context chat=${V.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(M){_(`debug: seed context failed: ${M}`)}let R=X.slice(7);z.text=R,J.content=JSON.stringify(z)}let G=L$.get(V);if(!G)await b4(),G=L$.get(V);if(!G)G=await s3(V)??void 0;if(!G){_(`unknown chat ${V}, dropping message`),await N(V,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=J7(G);D2(K,V);let B=YG(V,K),L={};try{L=JSON.parse(J.content??"{}")}catch{}let A=J.message_type,j="",P=!1,S=[];if(A==="text")j=(L.text??"").trim();else if(A==="post"){let R=aD(L);P=R.imageKeys.length>0||R.fileKeys.length>0,j=R.markdown.trim();for(let M of R.imageKeys){let k=await y4(J.message_id,M,"image");if(k)S.push(k)}for(let M of R.fileKeys){let k=await y4(J.message_id,M.key,"file",M.name);if(k)S.push(k)}}if(A==="text"&&j){if(await B.runCommand(j,Q))return}if((A==="text"||A==="post")&&j&&!P&&await gX({reply:()=>b6.consume({chatId:V,openId:Q,messageId:W??"",text:j,createTime:H,parentId:J.parent_id}),hasQuestion:()=>B.hasPendingAsk(),answerQuestion:()=>B.onAskMessageAnswer(j,Q,W??"")}))return;if(A==="text"&&j&&await B.consumeModelCustomMessage(j,Q))return;let F=cX(A,L);if(F){let R=await y4(J.message_id,F.key,F.type,F.name);if(!R){await N(V,mX(A));return}if(S.push(R),!j&&F.displayText)j=F.displayText}if(!j&&S.length===0){_(`drop empty message ${W} type=${A}`);return}if(await B.onMultiMessageInbound(j,S,Q,W??""))return;await B.onUserMessage(j||"(empty)",S,Q,W??"")}function y6($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复"}[$]??$}function tD($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function z$($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function v0($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function f0($){return z$($.card?Z0($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function l1($,Z){if(!$){_(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await w($,Z))_(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function sD($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=y6(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),W=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=tD(Z),V=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&W)try{await q0(W,H);return}catch(L){_(`card-action: ${J} original-card update failed: ${L instanceof Error?L.message:L}`),await l1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await l1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${V}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,X=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Y}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||z?.type==="error"&&!G;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await l1(Q,`${K?"❌":"✅"} ${Y}: ${X}`)}async function eD($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await l1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${y6(J)}失败: ${Y}`)}function QG($){return $M.accept($)}async function ZM($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Y=$?.context?.open_chat_id??"",Q=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let H=String(J.notify_id??""),V=C0(H);if(V)$.__cardActionChatId=V.chatId;if(J.kind==="notify_callback")return await JM(J,Y,Q);let z=J.kind==="notify_reply"?await b6.open(H,Y,Q):await b6.cancel(H,String(J.reply_id??""),Y,Q),X=z$({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return V?v0(V,X):X}let W=h0.get(Y);if(!W)return z$({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let H=String(J.decision??"");if(!["allow","allow_always","deny"].includes(H))return{toast:{type:"error",content:"无效的权限决定"}};let V=await W.onPermissionDecision(J.request_id,H,Q);return z$({toast:{type:V.ok?H==="deny"?"error":"success":"error",content:V.message}},V.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await W.onUserMessage(`(menu choice ${H+1})`),z$(Z0($1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(V){let z=V instanceof Error?V.message:String(V);return z$(Z0($1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let H=await W.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return f0(H)}case"model_page":{let H=await W.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return f0(H)}case"model_list_open":{let H=String(J.panel_id??""),V=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return f0(await(J.mode==="add"?W.onModelAddOpen(H,V):W.onProviderSelect(V,H)))}case"model_add":case"model_remove":case"model_custom_remove":return f0(await W.onModelListEdit(String(J.panel_id??""),String(J.source_id??""),String(J.model??""),J.kind==="model_add"?"add":J.kind==="model_remove"?"remove":"delete"));case"model_select":{let H=await W.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return f0(H)}case"model_custom_prompt":{let H=await W.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return f0(H)}case"model_panel_cancel":{let H=await W.onModelPanelCancel(String(J.panel_id??""));return f0(H)}case"model_effort_select":{let H=await W.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return f0(H)}case"ask":{let H=W.askBlockReason(String(J.tool_use_id??""));if(H)return z$({toast:{type:"error",content:H}},!1);if(J.custom){let X=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await W.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,X,Q);return z$({toast:{type:G?"success":"error",content:G?"已回答":X.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let V=await W.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return z$({toast:{type:V?"success":"error",content:V?"已回答":"问题已失效或选项无效"}},V)}case"worktree_disband":{let H=await W.onWorktreeDisband(String(J.slug??""));return z$(Z0(H.card),H.ok)}case"temp_fork_select":{let H=await W.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Z0($1({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await W.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Z0($1({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await W.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return z$({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return z$(Z0(C7({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await W.onTasklistEnable();return z$(Z0(H.card),H.ok)}case"tasklist_delete_prompt":{let H=W.onTasklistDeletePrompt(String(J.guid??""));return z$(Z0(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await W.onTasklistDeleteConfirm(String(J.guid??""));return z$(Z0(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (NZ(),TZ));return await H(W,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return f0(W.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function JM($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let W=C0(Y);if(!W)return _(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(W.unknownAt)return v0(W,z$({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${W.unknownReason?`: ${W.unknownReason}`:""}`}},!0));if(W.resolvedAt)return v0(W,{toast:{type:"info",content:"已处理过"}});if(S2(Y))return v0(W,{toast:{type:"info",content:"处理中…"}});if(W.replyState?.status==="waiting"||W.replyState?.status==="sending")return v0(W,z$({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let H=W.buttons.find((X)=>X.id===Q);if(!H)return _(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),v0(W,z$({toast:{type:"error",content:"未知按钮"}},!1));if(!W.callbackUrl){try{s4(W.notifyId,H.id,J)}catch(X){return v0(W,z$({toast:{type:"error",content:`保存反馈结果失败: ${X instanceof Error?X.message:X}`}},!1))}return _(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),v0(W,{...Z0(u1(W,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}o4(W.notifyId);let V=AJ(YM(W,H,J));V.catch((X)=>{_(`notify-callback: notify_id=${W.notifyId.slice(0,12)}… phase-2 rejected: ${X instanceof Error?X.message:X}`)});let z=V.then((X)=>X==="retry"?"retry":"complete").catch(()=>"retry");return v0(W,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:z})}async function YM($,Z,J){try{let Y=u1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await q0($.messageId,Y)}catch(V){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${V instanceof Error?V.message:V}`)}let Q=await ZZ($,Z,J),W=Q.ok?"complete":"retry",H;if(Q.ok){let V=r8($.notifyId,Z.id,J);if(V.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{W="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:V.detail},_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${V.detail}`);try{await l1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${V.detail}`)}catch(z){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${z instanceof Error?z.message:z}`)}}}else H={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Q.detail};try{let V=u1($,H);await q0($.messageId,V)}catch(V){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${V instanceof Error?V.message:V}`);try{await l1($.chatId,`⚠️ 通知反馈${W==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${V instanceof Error?V.message:V}`)}catch(z){_(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return _(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${W==="complete"?"delivered":W==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),W}finally{r4($.notifyId)}}function _J($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function QM(){if(process.platform==="win32"){_("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){_("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(KJ(K1))C6(K1)}catch{}try{Bun.serve({unix:K1,fetch:async($)=>{let Z=new URL($.url),J=$.method==="GET"&&Z.pathname==="/model-state";if($.method!=="POST"&&!J)return new Response("unsupported debug method",{status:405});if(i$)return new Response("daemon shutdown in progress",{status:503});let Y={};if($.method==="POST")try{Y=await $.json()}catch{return new Response("bad json",{status:400})}if(!KJ(B9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(mD(B9,"utf8"))}catch(G){return new Response(`ctx read failed: ${G}`,{status:500})}let W=J?Z.searchParams.get("chat_id"):Y.chat_id;if(W!==void 0&&W!==Q.chat_id||Z.pathname!=="/"&&!W)return new Response("explicit debug chat_id must match the seeded context",{status:409});if(J){let G=h0.get(Q.chat_id);return G?Response.json(rZ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=h0.get(Q.chat_id);if(!G)return new Response("debug session not found",{status:404});try{if(typeof Y.message_id!=="string"||!Y.message_id.startsWith("om_"))throw Error("message_id required");let K=typeof Y.value?.panel_id==="string"?Y.value.panel_id.trim():"",B=G.modelPanels.get(K);if(!B?.messageId||B.messageId!==Y.message_id)throw Error("stale or mismatched model panel");let L=await Q$.im.v1.message.get({path:{message_id:Y.message_id}});if(L.code!==0)throw Error(`message.get failed: ${L.code} ${L.msg}`);let A=oz(Y,Q,L.data?.items?.[0],f.feishu.app_id,B.messageId);_(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let j=QG(A);return await I0.enqueue(Q.chat_id,async()=>{}),Response.json({admission:j,state:rZ(G)})}catch(K){return new Response(K instanceof Error?K.message:String(K),{status:400})}}if(Z.pathname!=="/")return new Response("unknown debug endpoint",{status:404});let H=String(Y.text??"");if(!H)return new Response("text required",{status:400});let V=`【自动化测试】:${H}`,z=await N(Q.chat_id,V);if(!z)return new Response("sendText failed — see daemon log",{status:502});let X={sender:{sender_id:{open_id:Q.sender_open_id}},message:{message_id:z,chat_id:Q.chat_id,message_type:"text",content:JSON.stringify({text:H}),create_time:String(Date.now())}};if(_(`debug: inject text=${JSON.stringify(H).slice(0,80)} msg_id=${z}`),!JG(X,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Y.wait_for_handling===!0)await I0.enqueue(Q.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{ID(K1,384)}catch{}_(`debug: inject socket listening at ${K1}`)}catch($){_(`debug: socket bind failed: ${$}`)}}async function WM(){_(`lodestar-daemon: pid ${process.pid} starting`),i1.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (UZ(),NV));if(i$)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Y$(),AQ));if(i$)return;if(await Z(),i$)return;if(y3(),v3(),h3(),g3(),p3(),await b4(),i$)return;setInterval(()=>{b4()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (fZ(),wZ));if(i$)return;try{await J()}catch(D){_(`tasklist deletion reconcile failed: ${D instanceof Error?D.message:D}`)}if(i$)return;let Y,Q=Date.now(),W=0,H=!1,V=null,z=1500,X=90000,G=600000,K=3,B=null,L=0,A="",j=!1,P=(D)=>{_(`[ws] rebuild requested before WS init — ${D}`)},S=(D,x=0,i=!1)=>{if(i$)return;let a=Date.now()+x;if(B){if(j||=i,a>=L){_(`[ws] rebuild already scheduled — ${D}`);return}clearTimeout(B)}L=a,A=D,j=i,B=setTimeout(()=>{let _$=A,d2=j;B=null,L=0,A="",j=!1,P(_$,d2)},x)},F={error:(D)=>_(`[ws-sdk error] ${_J(D)}`),warn:(D)=>{let x=_J(D);if(_(`[ws-sdk warn] ${x}`),x.includes("no pong/inbound"))S("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(D)=>_(`[ws-sdk] ${_J(D)}`),debug:(D)=>{},trace:(D)=>{}},R=new l2.EventDispatcher({}),M=()=>{if(Q=Date.now(),W=0,V)clearTimeout(V),V=null};R.register({"im.message.receive_v1":async(D)=>{if(M(),!JG(D))throw Error("daemon shutdown in progress")}}),R.register({"card.action.trigger":async(D)=>{return M(),QG(D)}});let k=()=>new l2.WSClient({appId:f.feishu.app_id,appSecret:f.feishu.app_secret,loggerLevel:l2.LoggerLevel.info,logger:F,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>_("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>c(),onError:(D)=>P(`SDK onError: ${D?.message??D}`)});P=(D,x=!1)=>{if(i$)return;if(H){_(`[ws] rebuild skipped (already rebuilding) — ${D}`);return}if(B)clearTimeout(B),B=null,L=0;H=!0,W++,_(`[ws] rebuild #${W} (fresh WSClient) — ${D}`);let i=Y;try{i?.close({force:!0})}catch(a){_(`[ws] rebuild: old close failed: ${a}`)}if(Y=k(),Y.start({eventDispatcher:R}).catch((a)=>{_(`[ws] rebuild start failed: ${a}`),S(`fresh client start failed: ${a}`,z,x)}),H=!1,x)C()};let C=()=>{if(V)clearTimeout(V);let D=Date.now();V=setTimeout(()=>{if(V=null,Q>=D){W=0;return}if(W>=K){_(`[ws] STILL deaf after ${K} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),W=0;return}P(`verify: no event ${Math.round((Date.now()-D)/1000)}s after rebuild`,!0)},X)},c=()=>{let D=Date.now()-Q<G;_("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${D})`),W=0,S("post-reconnect precaution",z,D)};Y=k();let b=15000,h=2,E=0,v=setInterval(()=>{if(i$)return;let{state:D}=Y.getConnectionStatus();if(D==="connected"){E=0;return}if(D==="failed"||D==="idle"){E=0,P(`watchdog: state=${D}`);return}if(E++,_(`[ws] watchdog: state=${D} (${E}/${h})`),E>=h)E=0,P(`watchdog: stuck in '${D}' ~${Math.round(b*h/1000)}s`)},b);eX=()=>{if(clearInterval(v),B)clearTimeout(B);if(V)clearTimeout(V);Y.close({force:!0})};let m=cH();ZX({bind:f.notify.bind,port:f.notify.port,extraHandler:(D,x,i)=>CX(D,x,i,{service:BJ,authorizeSession:(a)=>{for(let _$ of h0.values())if(_$.acceptsAgentCapability(a))return _$;return null}})}),vX(),QX(),GX();let l=i1.enqueue();sX=nJ(_,{enabled:f.runtime.agent_auto_update}),Y.start({eventDispatcher:R}).catch((D)=>{_(`[ws] initial start failed: ${D}`),S(`initial start failed: ${D}`,z,!1)}),_(`lodestar-daemon: WS start requested, watching ${L$.size} groups`),QM();for(let D of m)AJ(I0.enqueue(D.chatId,()=>b6.recover(D))).catch((x)=>_(`notify-reply recovery failed: ${x instanceof Error?x.message:x}`));await l}var rX=!1,i$=!1,x6=null,z1=0,sX,eX,tX=15000,$G=()=>{if(rX)return;rX=!0;try{i1.persist()}catch($){_(`alive marker write failed: ${$}`)}try{C6(d$)}catch{}try{C6(K1)}catch{}},h0,BJ,I0,i1,uD,ZG,lD,qJ,oD=30000,u2,b6,$M;var WG=T(()=>{CZ();$$();$0();rz();e4();O6();O6();WX();VX();OX();zZ();Y6();bX();$J();hX();x$();I();t1();H$();u6();dX();oX();{let $=A9(d$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(KJ(d$))try{C6(d$)}catch{}}gD(pD(d$),{recursive:!0});TJ(d$);process.on("exit",$G);process.on("SIGTERM",()=>{i2("SIGTERM",0)});process.on("SIGINT",()=>{i2("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{i2("SIGBREAK",0)});process.on("unhandledRejection",($)=>{_(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),i2("unhandledRejection",1)});process.on("uncaughtException",($)=>{_(`uncaughtException: ${$.stack??$.message}`),i2("uncaughtException",1)});h0=new Map,BJ=new JJ,I0=new XJ,i1=new VJ({readMarker:n3,writeMarker:d3,sessions:()=>h0.values(),chatIdForSession:j8,sessionFor:YG,actor:I0,isShuttingDown:()=>i$,log:_}),uD=new GJ(30000),ZG=new Set,lD=lX({actor:I0,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>rD($,Z)});qJ=aX({registry:h0,createSession:($,Z)=>{let J=new H0($,Z,{onLifecycleChange:iD,onCreateTempSession:dD,onDisbandTempSession:nD,onCancelAgentRuns:(Y,Q,W)=>BJ.cancelSessionRuns(Y,Q,W)});return i1.transferPending(J),J},ensureChatForSession:o3,disbandChatForSessionExact:t3,chatIdForSession:j8,clearSessionConversationState:i3,registerTempSessionLease:w3,hasTempSessionLease:f3,replaceTurnAnchors:r$,runExclusive:($,Z)=>I0.enqueue($,Z),log:_});u2=new Set,b6=HX({sendCard:u,updateCard:q0,sendText:N,dispatch:ZZ,onWaitingChanged:($)=>h0.get($)?.refreshPendingAsks(),log:_});$M=iX({actor:I0,deduper:uD,scope:($)=>{let Z=String($?.action?.value?.kind??"");if(Z.startsWith("agent_identity_"))return"__agent_identities_global__";if(Z==="notify_callback"||Z==="notify_reply"||Z==="notify_reply_cancel"){let J=C0(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:ZM,present:sD,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");_(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await eD($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");_(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await l1(String($?.context?.open_chat_id??""),`⚠️ ${y6(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__cardActionCompletion;return J&&typeof J.then==="function"?J:null},track:($)=>{AJ($)},onBackgroundError:($)=>{_(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${y6(String($?.action?.value?.kind??"unknown"))}已接收,后台处理中…`}}),inflight:()=>({toast:{type:"info",content:"相同操作正在处理…"}}),completed:()=>({toast:{type:"info",content:"该操作近期已执行或尝试;为防重复暂不再次执行,请查看原卡或群消息"}}),closed:()=>({toast:{type:"error",content:"服务正在重启,请稍后重试"}}),invalid:($,Z)=>({toast:{type:"error",content:Z}})}});WM().catch(($)=>{_(`boot fatal: ${$}`),i2("boot fatal",1)})});H$();u6();import{existsSync as HG,unlinkSync as VM}from"node:fs";var V0={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function zM(){if(!HG(O$)){if(process.stdin.isTTY){console.log(),console.log(`${V0.bold}${V0.yellow}Lodestar: 未找到配置, 启动安装向导...${V0.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (tJ(),rJ));await Z();return}console.error(`${V0.red}Lodestar: 未找到配置 ${O$}${V0.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${V0.green}lodestar-setup${V0.reset} 完成首次配置 (或直接运行 ${V0.green}lodestar-daemon${V0.reset} 也会触发同一个向导)。`),process.exit(1)}let $=A9(d$);if($.state==="exit")console.error(`${V0.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${V0.reset}`),console.error(" • 想看日志:"+(process.platform==="win32"?" %LOCALAPPDATA%\\Lodestar\\daemon-YYYY-MM-DD.log":" ~/.local/share/lodestar/daemon-YYYY-MM-DD.log")),console.error(" • 想停: 任务管理器结束 pid 上面那个号 (Windows) / `kill "+$.pid+"` (Linux/macOS)"),console.error(` • 误判 / 已经死了: 手删 ${d$} 后再跑`),process.exit(1);if(HG(d$))try{VM(d$)}catch{}await Promise.resolve().then(() => (WG(),HM))}zM().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});