@leviyuan/lodestar 0.17.11 → 0.17.12

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,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as NG}from"node:module";var OG=Object.defineProperty;var RG=($)=>$;function TG($,Z){this[$]=RG.bind(null,Z)}var T$=($,Z)=>{for(var J in Z)OG($,J,{get:Z[J],enumerable:!0,configurable:!0,set:TG.bind(Z,J)})};var T=($,Z)=>()=>($&&(Z=$($=0)),Z);var EG=NG(import.meta.url);import{homedir as xG}from"node:os";import{join as n}from"node:path";function SJ($,Z,J){if($)return $;if(Z)return n(Z,"lodestar");return J}function SG(){if(xJ)return n(process.env.APPDATA??n(O9,"AppData","Roaming"),"Lodestar");return n(O9,".config","lodestar")}function bG(){if(xJ)return n(process.env.LOCALAPPDATA??n(O9,"AppData","Local"),"Lodestar");return n(O9,".local","share","lodestar")}var O9,xJ,n6,r,T0,n0,e1,a6,o6,r6,s6,t6,R9,_1,T9,j1,$2,bJ,CJ,kJ,e6,yJ,wJ,$8,Z8,L1,N9;var H0=T(()=>{O9=xG(),xJ=process.platform==="win32";n6=SJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,SG()),r=SJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,bG()),T0=process.env.LODESTAR_CONFIG??n(n6,"config.toml"),n0=n(r,"daemon.pid"),e1=n(r,"daemon.log"),a6=n(r,"session-chat-map.json"),o6=n(r,"session-resume-map.json"),r6=n(r,"session-turns-map.json"),s6=n(r,"session-model-map.json"),t6=n(r,"temp-session-leases.json"),R9=n(r,"tasklist-map.json"),_1=n(r,"agent-runs"),T9=n(r,"agent-session-ids.json"),j1=n(r,"managed-claude-plugin"),$2=n(r,"dsh"),bJ=n(r,"codex-accounts"),CJ=n(r,"codex-accounts.json"),kJ=n(r,"codex-quota-blocks.json"),e6=n(r,"agent-runtimes"),yJ=n(r,"context-window-cache.json"),wJ=n(r,"notify-callbacks.json"),$8=n(r,"alive-on-shutdown.json"),Z8=n(r,"inbox"),L1=n(r,"debug.sock"),N9=n(r,"debug-context.json")});import{execSync as vJ}from"node:child_process";import{readFileSync as fJ,writeFileSync as CG}from"node:fs";function kG(){return process.argv[1]??`pid:${process.pid}`}function yG($){try{if(process.platform==="linux")return fJ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return vJ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return vJ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function wG($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=yG($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function E9($){let Z="";try{Z=fJ($,"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(wG(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function hJ($){CG($,`${process.pid}
4
- ${kG()}`)}var J8=()=>{};import{execFile as vG}from"node:child_process";import{readFile as fG}from"node:fs/promises";import{homedir as hG}from"node:os";import{join as IJ}from"node:path";import{promisify as IG}from"node:util";import{Address4 as x9,Address6 as S9}from"ip-address";function Z2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function y9($){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 Y8($,Z=""){let J=$.hostname.replace(/^\[|\]$/g,"").toLowerCase(),Y=$.port||($.protocol==="https:"?"443":"80");return Z.split(/[,;\s]+/).filter(Boolean).some((Q)=>{let V=Q.toLowerCase();if(V==="*")return!0;if(V==="<local>")return!J.includes(".")&&!J.includes(":");if(V.includes("/")){if(x9.isValid(V))return x9.isValid(J)&&new x9(J).isInSubnet(new x9(V));if(S9.isValid(V))return S9.isValid(J)&&new S9(J).isInSubnet(new S9(V));throw Error("network proxy: invalid IP range in bypass list")}let H=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(H&&H[2]!==Y)return!1;let X=(H?H[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===X||J.endsWith(`.${X}`)})}function gJ($,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 mJ($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(y9($)||Y8($,Z2(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=Z2(Z,Y)||Z2(Z,"ALL_PROXY");if(Q)return gJ(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(Y8($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?gJ(V,"system settings"):void 0}function k9($,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 mG($){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,V=/^[a-z][\w+.-]*:\/\//i.test(Q)?Q:`http://${Q}`;if(!Y)Z.all=V;else if(Y[1].toLowerCase()==="socks")Z.all=`socks://${Q.replace(/^socks\w*:\/\//,"")}`;else Z[Y[1].toLowerCase()]=V}return Z}function pG($){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=k9(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=k9(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=k9(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 b9($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function cG($){let Z=new Map($.split(`
5
- `).filter(Boolean).map((Q)=>{let V=Q.match(/^org\.gnome\.system\.proxy(\.\w+)?\s+([\w-]+)\s+(.*)$/);if(!V)throw Error("network proxy: invalid GNOME proxy settings");return[`${V[1]??""}/${V[2]}`,V[3]]})),J=b9(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 V=b9(Z.get(`.${Q}/host`));if(!V)continue;let H=new URL(k9(V,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")H.username=b9(Z.get(".http/authentication-user")),H.password=b9(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 uG($){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((V)=>V.includes("=")).map((V)=>{let H=V.indexOf("=");return[V.slice(0,H).trim(),V.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 V of["http","https","socks"]){let H=J.get(`${V}Proxy`);if(!H)continue;let X=H.replace(/\s+(\d+)$/,":$1");Q[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(X)?X:`${V==="socks"?"socks":"http"}://${X}`}return Q}async function C9($,Z){let{stdout:J}=await gG($,Z,{encoding:"utf8",timeout:5000,maxBuffer:262144,windowsHide:!0});return J}async function dG(){if(process.platform==="win32")return mG(JSON.parse(await C9("powershell.exe",["-NoProfile","-NonInteractive","-Command",lG])));if(process.platform==="darwin")return pG(await C9("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=IJ(process.env.XDG_CONFIG_HOME||IJ(hG(),".config"),"kioslaverc");try{let J=uG(await fG($,"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 C9("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return cG(await C9("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function iG($=dG,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(y9(Q)||Y8(Q,Z2(Z,"NO_PROXY"))||Z2(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||Z2(Z,"ALL_PROXY"))return mJ(Q,Z);if(!Y||Y.until<=J()){let V=$().catch((H)=>{if(Y?.value===V)Y=void 0;if(H instanceof Error&&H.message.startsWith("network proxy:"))throw H;let X=H instanceof Error?H.code??H.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${X})`,{cause:H})});Y={until:J()+30000,value:V}}return mJ(Q,Z,await Y.value)}}var gG,lG,pJ;var cJ=T(()=>{gG=IG(vG);lG=String.raw`
2
+ import{createRequire as kG}from"node:module";var SG=Object.defineProperty;var bG=($)=>$;function CG($,Z){this[$]=bG.bind(null,Z)}var N$=($,Z)=>{for(var J in Z)SG($,J,{get:Z[J],enumerable:!0,configurable:!0,set:CG.bind(Z,J)})};var N=($,Z)=>()=>($&&(Z=$($=0)),Z);var yG=kG(import.meta.url);import{homedir as wG}from"node:os";import{join as n}from"node:path";function CJ($,Z,J){if($)return $;if(Z)return n(Z,"lodestar");return J}function vG(){if(bJ)return n(process.env.APPDATA??n(O9,"AppData","Roaming"),"Lodestar");return n(O9,".config","lodestar")}function fG(){if(bJ)return n(process.env.LOCALAPPDATA??n(O9,"AppData","Local"),"Lodestar");return n(O9,".local","share","lodestar")}var O9,bJ,a6,r,N0,n0,s1,o6,r6,s6,t6,e6,R9,_1,N9,j1,t1,kJ,yJ,wJ,$8,vJ,fJ,Z8,J8,L1,T9;var V0=N(()=>{O9=wG(),bJ=process.platform==="win32";a6=CJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,vG()),r=CJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,fG()),N0=process.env.LODESTAR_CONFIG??n(a6,"config.toml"),n0=n(r,"daemon.pid"),s1=n(r,"daemon.log"),o6=n(r,"session-chat-map.json"),r6=n(r,"session-resume-map.json"),s6=n(r,"session-turns-map.json"),t6=n(r,"session-model-map.json"),e6=n(r,"temp-session-leases.json"),R9=n(r,"tasklist-map.json"),_1=n(r,"agent-runs"),N9=n(r,"agent-session-ids.json"),j1=n(r,"managed-claude-plugin"),t1=n(r,"dsh"),kJ=n(r,"codex-accounts"),yJ=n(r,"codex-accounts.json"),wJ=n(r,"codex-quota-blocks.json"),$8=n(r,"agent-runtimes"),vJ=n(r,"context-window-cache.json"),fJ=n(r,"notify-callbacks.json"),Z8=n(r,"alive-on-shutdown.json"),J8=n(r,"inbox"),L1=n(r,"debug.sock"),T9=n(r,"debug-context.json")});import{execSync as hJ}from"node:child_process";import{readFileSync as IJ,writeFileSync as hG}from"node:fs";function IG(){return process.argv[1]??`pid:${process.pid}`}function gG($){try{if(process.platform==="linux")return IJ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return hJ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return hJ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function mG($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=gG($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function E9($){let Z="";try{Z=IJ($,"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(mG(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function gJ($){hG($,`${process.pid}
4
+ ${IG()}`)}var Y8=()=>{};import{execFile as pG}from"node:child_process";import{readFile as cG}from"node:fs/promises";import{homedir as uG}from"node:os";import{join as mJ}from"node:path";import{promisify as lG}from"node:util";import{Address4 as x9,Address6 as S9}from"ip-address";function e1($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function y9($){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 Q8($,Z=""){let J=$.hostname.replace(/^\[|\]$/g,"").toLowerCase(),Y=$.port||($.protocol==="https:"?"443":"80");return Z.split(/[,;\s]+/).filter(Boolean).some((Q)=>{let V=Q.toLowerCase();if(V==="*")return!0;if(V==="<local>")return!J.includes(".")&&!J.includes(":");if(V.includes("/")){if(x9.isValid(V))return x9.isValid(J)&&new x9(J).isInSubnet(new x9(V));if(S9.isValid(V))return S9.isValid(J)&&new S9(J).isInSubnet(new S9(V));throw Error("network proxy: invalid IP range in bypass list")}let H=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(H&&H[2]!==Y)return!1;let X=(H?H[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===X||J.endsWith(`.${X}`)})}function pJ($,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 cJ($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(y9($)||Q8($,e1(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=e1(Z,Y)||e1(Z,"ALL_PROXY");if(Q)return pJ(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(Q8($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?pJ(V,"system settings"):void 0}function k9($,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 iG($){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,V=/^[a-z][\w+.-]*:\/\//i.test(Q)?Q:`http://${Q}`;if(!Y)Z.all=V;else if(Y[1].toLowerCase()==="socks")Z.all=`socks://${Q.replace(/^socks\w*:\/\//,"")}`;else Z[Y[1].toLowerCase()]=V}return Z}function nG($){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=k9(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=k9(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=k9(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 b9($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function aG($){let Z=new Map($.split(`
5
+ `).filter(Boolean).map((Q)=>{let V=Q.match(/^org\.gnome\.system\.proxy(\.\w+)?\s+([\w-]+)\s+(.*)$/);if(!V)throw Error("network proxy: invalid GNOME proxy settings");return[`${V[1]??""}/${V[2]}`,V[3]]})),J=b9(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 V=b9(Z.get(`.${Q}/host`));if(!V)continue;let H=new URL(k9(V,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")H.username=b9(Z.get(".http/authentication-user")),H.password=b9(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 oG($){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((V)=>V.includes("=")).map((V)=>{let H=V.indexOf("=");return[V.slice(0,H).trim(),V.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 V of["http","https","socks"]){let H=J.get(`${V}Proxy`);if(!H)continue;let X=H.replace(/\s+(\d+)$/,":$1");Q[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(X)?X:`${V==="socks"?"socks":"http"}://${X}`}return Q}async function C9($,Z){let{stdout:J}=await dG($,Z,{encoding:"utf8",timeout:5000,maxBuffer:262144,windowsHide:!0});return J}async function sG(){if(process.platform==="win32")return iG(JSON.parse(await C9("powershell.exe",["-NoProfile","-NonInteractive","-Command",rG])));if(process.platform==="darwin")return nG(await C9("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=mJ(process.env.XDG_CONFIG_HOME||mJ(uG(),".config"),"kioslaverc");try{let J=oG(await cG($,"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 C9("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return aG(await C9("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function tG($=sG,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(y9(Q)||Q8(Q,e1(Z,"NO_PROXY"))||e1(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||e1(Z,"ALL_PROXY"))return cJ(Q,Z);if(!Y||Y.until<=J()){let V=$().catch((H)=>{if(Y?.value===V)Y=void 0;if(H instanceof Error&&H.message.startsWith("network proxy:"))throw H;let X=H instanceof Error?H.code??H.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${X})`,{cause:H})});Y={until:J()+30000,value:V}}return cJ(Q,Z,await Y.value)}}var dG,rG,uJ;var lJ=N(()=>{dG=lG(pG);rG=String.raw`
7
7
  $ErrorActionPreference = 'Stop'
8
8
  [Console]::OutputEncoding = New-Object Text.UTF8Encoding($false)
9
9
  Add-Type @'
@@ -41,49 +41,49 @@ try {
41
41
  if ($pointer -ne [IntPtr]::Zero) { [void][LodestarProxy]::GlobalFree($pointer) }
42
42
  }
43
43
  }
44
- `;pJ=iG()});import{Agent as nG}from"node:http";import{Agent as aG}from"node:https";import{Readable as uJ}from"node:stream";import oG from"node-fetch";import{HttpProxyAgent as rG}from"http-proxy-agent";import{HttpsProxyAgent as sG}from"https-proxy-agent";function $K($,Z){if(!Z)return $.protocol==="https:"?eG:tG;return $.protocol==="https:"?new sG(Z):new rG(Z)}async function ZK($,Z,J){if(typeof Bun<"u"){let H=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[H.toLowerCase()]||process.env[H])){let X=await import("undici");return lJ??=new X.Agent,await X.fetch($,{...Z,redirect:"manual",dispatcher:lJ})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"}),Q=await oG($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?uJ.fromWeb(Y.body):void 0,signal:Y.signal,agent:$K($,J),redirect:"manual"}),V=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:uJ.toWeb(Q.body);return new Response(V,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function dJ($,Z,J,Y=pJ){let Q=new URL($),V={...Z};for(let H=0;;H++){if(!["http:","https:"].includes(Q.protocol))throw Error(`network: unsupported URL protocol ${Q.protocol}`);if(J&&!y9(Q))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let X=J?void 0:await Y(Q),z=await ZK(Q,V,X),W=z.headers.get("location");if(![301,302,303,307,308].includes(z.status)||!W||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(W,Q),B=new Headers(V.headers);if(G.origin!==Q.origin)for(let j of["authorization","proxy-authorization","cookie","host"])B.delete(j);let _=(V.method??"GET").toUpperCase();if(z.status===303&&_!=="HEAD"||[301,302].includes(z.status)&&_==="POST"){V={...V,method:"GET",body:void 0};for(let j of["content-type","content-length","content-encoding"])B.delete(j)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=B,Q=G}}function Y0($,Z={}){return dJ($,Z,!1)}function iJ($,Z={}){return dJ($,Z,!0)}var tG,eG,lJ;var a0=T(()=>{cJ();tG=new nG({keepAlive:!0}),eG=new aG({keepAlive:!0})});import{chmodSync as JK,closeSync as Q8,fsyncSync as nJ,mkdirSync as YK,openSync as aJ,renameSync as QK,unlinkSync as VK,writeFileSync as HK}from"node:fs";import{randomUUID as XK}from"node:crypto";import{dirname as oJ}from"node:path";function KK($){let Z=oJ($);YK(Z,{recursive:!0,mode:GK})}function rJ($,Z,J){KK($);let Y=`${$}.${process.pid}.${XK()}.tmp`,Q=null;try{Q=aJ(Y,"wx",J),HK(Q,Z),nJ(Q),Q8(Q),Q=null,QK(Y,$);try{JK($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=aJ(oJ($),"r"),nJ(V)}catch{}finally{if(V!==null)try{Q8(V)}catch{}}}}catch(V){if(Q!==null)try{Q8(Q)}catch{}try{VK(Y)}catch{}throw V}}function Q$($,Z){rJ($,Z,zK)}function sJ($,Z){rJ($,Z,WK)}function s($,Z){Q$($,JSON.stringify(Z,null,2)+`
45
- `)}var zK=384,WK=448,GK=448;var f0=()=>{};import{execFile as BK}from"node:child_process";import{spawn as _K}from"cross-spawn";function LK($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{BK("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Y,Q,V)=>{if(Y)J(Error(`taskkill npm installer PID ${$} failed: ${Y.message}
46
- ${Q}${V}`));else Z()})})}async function V8($,Z,J={}){Z?.throwIfAborted();let Y=J.platform??process.platform,Q=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((H,X)=>{let z=(J.spawn??_K)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${jK}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),W="",G,B,_=!1,j=!1,q,P=(S)=>{W=(W+S.toString()).slice(-16384)};z.stdout.on("data",P),z.stderr.on("data",P);let D=(S)=>{if(_)return;if(_=!0,clearTimeout(M),q)clearTimeout(q);if(Z?.removeEventListener("abort",A),S)X(S);else H()},N=(S)=>new w9(`${G?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${S}; partial directory retained: ${$}
47
- ${W}`),U=(S)=>{if(_||j||B)return;G??=Error(S),q=setTimeout(()=>D(N(`stdio did not close within ${V}ms`)),V),B=Promise.resolve().then(async()=>{if(j)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Y==="win32")await(J.terminateWindows??LK)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),B.catch((C)=>D(N(C instanceof Error?C.message:String(C))))},A=()=>U("Agent runtime install aborted"),M=setTimeout(()=>U(`Agent runtime install timed out after ${Q}ms`),Q);if(Z?.addEventListener("abort",A,{once:!0}),z.on("error",(S)=>{if(G??=S,!z.pid)D(Error(`${S.message}
48
- ${W}`))}),z.once("close",async(S,C)=>{j=!0,clearTimeout(M),Z?.removeEventListener("abort",A);try{await B}catch(p){D(N(p instanceof Error?p.message:String(p)));return}if(G||S!==0)D(Error(`${G?.message??`npm install exited code=${S} signal=${C}`}
49
- ${W}`));else D()}),Z?.aborted)A()})}var jK="https://registry.npmjs.org",w9;var H8=T(()=>{w9=class w9 extends Error{}});import{createHash as qK,randomUUID as PK}from"node:crypto";import{createRequire as DK}from"node:module";import{existsSync as X8,readFileSync as eJ}from"node:fs";import{mkdir as $Y,mkdtemp as FK,readFile as ZY,rename as JY,rm as v9,writeFile as z8}from"node:fs/promises";import{join as h0,isAbsolute as MK}from"node:path";import{fileURLToPath as UK,pathToFileURL as AK}from"node:url";function YY($,Z=e6){let J=h0(Z,$,"current.json");if(!X8(J))return null;let Y=JSON.parse(eJ(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!MK(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function f9($){let Z=YY($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function W8($,Z){return DK(h0(f9($),"package.json")).resolve(Z)}function Q4($,Z){let J=h0(f9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!X8(J))throw Error(`${$} executable missing: ${J}`);return J}async function QY(){return import(AK(W8("claude","@anthropic-ai/claude-agent-sdk")).href)}async function NK($,Z,J){let Y=new AbortController,Q=()=>Y.abort(J?.reason);if(J?.addEventListener("abort",Q,{once:!0}),J?.aborted)Q();let V=setTimeout(()=>Y.abort(Error("npm registry request timed out")),30000);try{let H=await Y0(`${TK}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Y.signal});if(!H.ok)throw Error(`${$}@${Z}: npm HTTP ${H.status}`);let X=await H.json();if(X.name!==$||typeof X.version!=="string"||!X.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return X}finally{clearTimeout(V),J?.removeEventListener("abort",Q)}}async function EK($,Z){let J={};if($!=="dsh"){let H=await Promise.all(Y4[$].map((X)=>Z(X,"latest")));for(let X of H)J[X.name]=X.version;return J}let Y=await Z("@deepseek-ai/dsh","latest"),Q=new Set(Y4.dsh),V=new Set;while(Q.size){let H=[...Q].slice(0,12);for(let z of H)Q.delete(z),V.add(z);let X=await Promise.all(H.map((z)=>z===Y.name?Y:Z(z,Y.version)));for(let z of X){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 W of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(W.startsWith("@deepseek-ai/dsh")&&!V.has(W))Q.add(W)}}return J}async function J2($,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((V)=>setTimeout(V,100*(J+1)))}}async function tJ($,Z){let J=h0($,`current-${PK()}.json`),Y;try{await z8(J,JSON.stringify(Z)+`
50
- `,{mode:384}),await J2(()=>JY(J,h0($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await J2(()=>v9(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${q1(Y)}; state temporary file cleanup failed: ${q1(Q)}`);throw Q}}}async function xK($,Z){let J=h0($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{return await $Y(J),await z8(h0(J,"pid"),String(process.pid)),()=>J2(()=>v9(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let V=Number(await ZY(h0(J,"pid"),"utf8"));if(!Number.isSafeInteger(V)||V<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(V,0)}catch(H){if(H.code!=="ESRCH")throw H;await J2(()=>v9(J,{recursive:!0}));continue}}catch(V){if(V.code!=="ENOENT")throw V}if(Date.now()>=Y)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((V)=>setTimeout(V,200))}}}async function h9($,Z={}){let J=Z.root??e6,Y=h0(J,$);await $Y(Y,{recursive:!0,mode:448});let Q=await xK(Y,Z.signal),V,H,X=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let z=YY($,J),W=await EK($,Z.metadata??((q,P)=>NK(q,P,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(eJ(UK(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},B=qK("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(W).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=h0(Y,B);if(!X8(_)){V=await FK(h0(Y,".install-")),await z8(h0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:W[Y4[$][0]],private:!0,type:"module",dependencies:W,overrides:{...G,...$==="dsh"?W:{}}})+`
51
- `,{mode:384}),await(Z.install??V8)(V,Z.signal);for(let[P,D]of Object.entries(W)){let N=JSON.parse(await ZY(h0(V,"node_modules",P,"package.json"),"utf8"));if(N.version!==D)throw Error(`npm installed ${P}@${N.version}, expected ${D}`)}Z.signal?.throwIfAborted();let q=V;await J2(()=>JY(q,_)),V=void 0}let j={directory:_,versions:W,checkedAt:Date.now()};return await tJ(Y,j),Z.report?.(`${$}: ${Y4[$][0]}@${W[Y4[$][0]]}${z?.directory===_?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){H=z,X=z instanceof w9;try{await tJ(Y,{checkedAt:Date.now(),error:q1(z)})}catch(W){throw H=AggregateError([z,W],`${q1(z)}; recording update failure also failed: ${q1(W)}`),H}throw z}finally{let z=[];if(V&&!X){let W=V;try{await J2(()=>v9(W,{recursive:!0}))}catch(G){z.push(G)}}try{await Q()}catch(W){z.push(W)}if(z.length){let W=H?[H,...z]:z;throw AggregateError(W,W.map(q1).join("; "))}}}function VY($,Z={}){let J=OK.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,V,H=setInterval(()=>{if(V)return;V=(Z.update??h9)(Y,{report:$,signal:Q.signal}).catch((X)=>$(`${Y} 自动更新未完成: ${q1(X)}`)).finally(()=>{V=void 0})},RK);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var OK,RK=21600000,TK="https://registry.npmjs.org",Y4,q1=($)=>$ instanceof Error?$.message:String($);var Y2=T(()=>{a0();H0();H8();H8();OK=["codex","claude","dsh"],Y4={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 zY={};T$(zY,{runSetup:()=>lK});import{execFileSync as SK,spawn as g9}from"node:child_process";import{spawn as bK}from"cross-spawn";import{existsSync as K8,mkdirSync as XY,readFileSync as CK}from"node:fs";import{createInterface as kK}from"node:readline/promises";import{dirname as yK,join as B8}from"node:path";import{homedir as wK}from"node:os";import{fileURLToPath as vK}from"node:url";async function P1($,Z={}){while(!0){let J=Z.default?`${L.dim} [${Z.default}]${L.reset}`:"",Y=(await V4.question(`${L.cyan}? ${L.reset}${$}${J}
52
- ${L.green}>${L.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${L.red}必填,请重新输入${L.reset}`);continue}return Y}}function fK($){let Z="═".repeat(58);console.log(`
44
+ `;uJ=tG()});import{Agent as eG}from"node:http";import{Agent as $K}from"node:https";import{Readable as dJ}from"node:stream";import ZK from"node-fetch";import{HttpProxyAgent as JK}from"http-proxy-agent";import{HttpsProxyAgent as YK}from"https-proxy-agent";function HK($,Z){if(!Z)return $.protocol==="https:"?VK:QK;return $.protocol==="https:"?new YK(Z):new JK(Z)}async function XK($,Z,J){if(typeof Bun<"u"){let H=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[H.toLowerCase()]||process.env[H])){let X=await import("undici");return iJ??=new X.Agent,await X.fetch($,{...Z,redirect:"manual",dispatcher:iJ})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"}),Q=await ZK($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?dJ.fromWeb(Y.body):void 0,signal:Y.signal,agent:HK($,J),redirect:"manual"}),V=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:dJ.toWeb(Q.body);return new Response(V,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function nJ($,Z,J,Y=uJ){let Q=new URL($),V={...Z};for(let H=0;;H++){if(!["http:","https:"].includes(Q.protocol))throw Error(`network: unsupported URL protocol ${Q.protocol}`);if(J&&!y9(Q))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let X=J?void 0:await Y(Q),z=await XK(Q,V,X),W=z.headers.get("location");if(![301,302,303,307,308].includes(z.status)||!W||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(W,Q),B=new Headers(V.headers);if(G.origin!==Q.origin)for(let j of["authorization","proxy-authorization","cookie","host"])B.delete(j);let _=(V.method??"GET").toUpperCase();if(z.status===303&&_!=="HEAD"||[301,302].includes(z.status)&&_==="POST"){V={...V,method:"GET",body:void 0};for(let j of["content-type","content-length","content-encoding"])B.delete(j)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=B,Q=G}}function J0($,Z={}){return nJ($,Z,!1)}function aJ($,Z={}){return nJ($,Z,!0)}var QK,VK,iJ;var a0=N(()=>{lJ();QK=new eG({keepAlive:!0}),VK=new $K({keepAlive:!0})});import{chmodSync as zK,closeSync as V8,fsyncSync as oJ,mkdirSync as WK,openSync as rJ,renameSync as GK,unlinkSync as KK,writeFileSync as BK}from"node:fs";import{randomUUID as _K}from"node:crypto";import{dirname as sJ}from"node:path";function PK($){let Z=sJ($);WK(Z,{recursive:!0,mode:qK})}function tJ($,Z,J){PK($);let Y=`${$}.${process.pid}.${_K()}.tmp`,Q=null;try{Q=rJ(Y,"wx",J),BK(Q,Z),oJ(Q),V8(Q),Q=null,GK(Y,$);try{zK($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=rJ(sJ($),"r"),oJ(V)}catch{}finally{if(V!==null)try{V8(V)}catch{}}}}catch(V){if(Q!==null)try{V8(Q)}catch{}try{KK(Y)}catch{}throw V}}function Q$($,Z){tJ($,Z,jK)}function eJ($,Z){tJ($,Z,LK)}function s($,Z){Q$($,JSON.stringify(Z,null,2)+`
45
+ `)}var jK=384,LK=448,qK=448;var f0=()=>{};import{execFile as DK}from"node:child_process";import{spawn as FK}from"cross-spawn";function MK($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{DK("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Y,Q,V)=>{if(Y)J(Error(`taskkill npm installer PID ${$} failed: ${Y.message}
46
+ ${Q}${V}`));else Z()})})}async function H8($,Z,J={}){Z?.throwIfAborted();let Y=J.platform??process.platform,Q=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((H,X)=>{let z=(J.spawn??FK)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${UK}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),W="",G,B,_=!1,j=!1,q,P=(S)=>{W=(W+S.toString()).slice(-16384)};z.stdout.on("data",P),z.stderr.on("data",P);let D=(S)=>{if(_)return;if(_=!0,clearTimeout(U),q)clearTimeout(q);if(Z?.removeEventListener("abort",A),S)X(S);else H()},T=(S)=>new w9(`${G?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${S}; partial directory retained: ${$}
47
+ ${W}`),M=(S)=>{if(_||j||B)return;G??=Error(S),q=setTimeout(()=>D(T(`stdio did not close within ${V}ms`)),V),B=Promise.resolve().then(async()=>{if(j)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Y==="win32")await(J.terminateWindows??MK)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),B.catch((C)=>D(T(C instanceof Error?C.message:String(C))))},A=()=>M("Agent runtime install aborted"),U=setTimeout(()=>M(`Agent runtime install timed out after ${Q}ms`),Q);if(Z?.addEventListener("abort",A,{once:!0}),z.on("error",(S)=>{if(G??=S,!z.pid)D(Error(`${S.message}
48
+ ${W}`))}),z.once("close",async(S,C)=>{j=!0,clearTimeout(U),Z?.removeEventListener("abort",A);try{await B}catch(p){D(T(p instanceof Error?p.message:String(p)));return}if(G||S!==0)D(Error(`${G?.message??`npm install exited code=${S} signal=${C}`}
49
+ ${W}`));else D()}),Z?.aborted)A()})}var UK="https://registry.npmjs.org",w9;var X8=N(()=>{w9=class w9 extends Error{}});import{createHash as AK,randomUUID as OK}from"node:crypto";import{createRequire as RK}from"node:module";import{existsSync as z8,readFileSync as ZY}from"node:fs";import{mkdir as JY,mkdtemp as NK,readFile as YY,rename as QY,rm as v9,writeFile as W8}from"node:fs/promises";import{join as h0,isAbsolute as TK}from"node:path";import{fileURLToPath as EK,pathToFileURL as xK}from"node:url";function VY($,Z=$8){let J=h0(Z,$,"current.json");if(!z8(J))return null;let Y=JSON.parse(ZY(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!TK(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function f9($){let Z=VY($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function G8($,Z){return RK(h0(f9($),"package.json")).resolve(Z)}function Y4($,Z){let J=h0(f9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!z8(J))throw Error(`${$} executable missing: ${J}`);return J}async function HY(){return import(xK(G8("claude","@anthropic-ai/claude-agent-sdk")).href)}async function kK($,Z,J){let Y=new AbortController,Q=()=>Y.abort(J?.reason);if(J?.addEventListener("abort",Q,{once:!0}),J?.aborted)Q();let V=setTimeout(()=>Y.abort(Error("npm registry request timed out")),30000);try{let H=await J0(`${CK}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Y.signal});if(!H.ok)throw Error(`${$}@${Z}: npm HTTP ${H.status}`);let X=await H.json();if(X.name!==$||typeof X.version!=="string"||!X.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return X}finally{clearTimeout(V),J?.removeEventListener("abort",Q)}}async function yK($,Z){let J={};if($!=="dsh"){let H=await Promise.all(J4[$].map((X)=>Z(X,"latest")));for(let X of H)J[X.name]=X.version;return J}let Y=await Z("@deepseek-ai/dsh","latest"),Q=new Set(J4.dsh),V=new Set;while(Q.size){let H=[...Q].slice(0,12);for(let z of H)Q.delete(z),V.add(z);let X=await Promise.all(H.map((z)=>z===Y.name?Y:Z(z,Y.version)));for(let z of X){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 W of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(W.startsWith("@deepseek-ai/dsh")&&!V.has(W))Q.add(W)}}return J}async function $2($,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((V)=>setTimeout(V,100*(J+1)))}}async function $Y($,Z){let J=h0($,`current-${OK()}.json`),Y;try{await W8(J,JSON.stringify(Z)+`
50
+ `,{mode:384}),await $2(()=>QY(J,h0($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await $2(()=>v9(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${q1(Y)}; state temporary file cleanup failed: ${q1(Q)}`);throw Q}}}async function wK($,Z){let J=h0($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{return await JY(J),await W8(h0(J,"pid"),String(process.pid)),()=>$2(()=>v9(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let V=Number(await YY(h0(J,"pid"),"utf8"));if(!Number.isSafeInteger(V)||V<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(V,0)}catch(H){if(H.code!=="ESRCH")throw H;await $2(()=>v9(J,{recursive:!0}));continue}}catch(V){if(V.code!=="ENOENT")throw V}if(Date.now()>=Y)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((V)=>setTimeout(V,200))}}}async function h9($,Z={}){let J=Z.root??$8,Y=h0(J,$);await JY(Y,{recursive:!0,mode:448});let Q=await wK(Y,Z.signal),V,H,X=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let z=VY($,J),W=await yK($,Z.metadata??((q,P)=>kK(q,P,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(ZY(EK(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},B=AK("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(W).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=h0(Y,B);if(!z8(_)){V=await NK(h0(Y,".install-")),await W8(h0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:W[J4[$][0]],private:!0,type:"module",dependencies:W,overrides:{...G,...$==="dsh"?W:{}}})+`
51
+ `,{mode:384}),await(Z.install??H8)(V,Z.signal);for(let[P,D]of Object.entries(W)){let T=JSON.parse(await YY(h0(V,"node_modules",P,"package.json"),"utf8"));if(T.version!==D)throw Error(`npm installed ${P}@${T.version}, expected ${D}`)}Z.signal?.throwIfAborted();let q=V;await $2(()=>QY(q,_)),V=void 0}let j={directory:_,versions:W,checkedAt:Date.now()};return await $Y(Y,j),Z.report?.(`${$}: ${J4[$][0]}@${W[J4[$][0]]}${z?.directory===_?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){H=z,X=z instanceof w9;try{await $Y(Y,{checkedAt:Date.now(),error:q1(z)})}catch(W){throw H=AggregateError([z,W],`${q1(z)}; recording update failure also failed: ${q1(W)}`),H}throw z}finally{let z=[];if(V&&!X){let W=V;try{await $2(()=>v9(W,{recursive:!0}))}catch(G){z.push(G)}}try{await Q()}catch(W){z.push(W)}if(z.length){let W=H?[H,...z]:z;throw AggregateError(W,W.map(q1).join("; "))}}}function XY($,Z={}){let J=SK.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,V,H=setInterval(()=>{if(V)return;V=(Z.update??h9)(Y,{report:$,signal:Q.signal}).catch((X)=>$(`${Y} 自动更新未完成: ${q1(X)}`)).finally(()=>{V=void 0})},bK);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var SK,bK=21600000,CK="https://registry.npmjs.org",J4,q1=($)=>$ instanceof Error?$.message:String($);var Z2=N(()=>{a0();V0();X8();X8();SK=["codex","claude","dsh"],J4={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 GY={};N$(GY,{runSetup:()=>rK});import{execFileSync as vK,spawn as g9}from"node:child_process";import{spawn as fK}from"cross-spawn";import{existsSync as B8,mkdirSync as WY,readFileSync as hK}from"node:fs";import{createInterface as IK}from"node:readline/promises";import{dirname as gK,join as _8}from"node:path";import{homedir as mK}from"node:os";import{fileURLToPath as pK}from"node:url";async function P1($,Z={}){while(!0){let J=Z.default?`${L.dim} [${Z.default}]${L.reset}`:"",Y=(await Q4.question(`${L.cyan}? ${L.reset}${$}${J}
52
+ ${L.green}>${L.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${L.red}必填,请重新输入${L.reset}`);continue}return Y}}function cK($){let Z="═".repeat(58);console.log(`
53
53
  ${L.bold}${L.cyan}╔${Z}╗${L.reset}`),console.log(`${L.bold}${L.cyan}║ ${$.padEnd(54)} ║${L.reset}`),console.log(`${L.bold}${L.cyan}╚${Z}╝${L.reset}
54
54
  `)}function I9($,Z,J){console.log(`
55
55
  ${L.bold}${L.yellow}[${$}/${Z}] ${J}${L.reset}
56
- `)}function G8($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function HY($){try{let Z=SK($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function hK($){return new Promise((Z)=>{let J=bK($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function IK(){return process.env.CLAUDE_CONFIG_DIR||B8(wK(),".claude")}async function gK($){try{let Z=await Y0("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((B)=>typeof B?.display_name==="string"&&B.display_name?B.display_name:String(B?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(B)=>{let _=B.match(/(\d+(?:\.\d+)?)/);return _?Number(_[1]):-1},V=(B)=>B.replace(/-Turbo|-Air$/i,""),X=[...Y.filter((B)=>!/-Turbo|-Air/i.test(B))].sort((B,_)=>Q(_)-Q(B)),z=X[0],W=X[X.length-1],G={};if(z)G.ANTHROPIC_DEFAULT_OPUS_MODEL=`${z}[1m]`,G.ANTHROPIC_DEFAULT_SONNET_MODEL=`${z}[1m]`;if(W&&V(W)!==V(z))G.ANTHROPIC_DEFAULT_HAIKU_MODEL=W;return Object.keys(G).length?G:null}catch{return null}}async function mK($){try{let Z=IK();XY(Z,{recursive:!0});let J=B8(Z,"settings.json"),Y={};if(K8(J)){let X=CK(J,"utf8");try{let z=JSON.parse(X);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:{},V={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await gK($);if(H)Object.assign(V,H);return Y.env={...Q,...V},Q$(J,JSON.stringify(Y,null,2)+`
57
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function pK($){try{if(process.platform==="win32")g9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")g9("open",[$],{detached:!0,stdio:"ignore"}).unref();else g9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function cK($,Z){try{let Y=await(await Y0("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 uK(){try{let $=yK(vK(import.meta.url)),Z=B8($,"lodestar.js");if(!K8(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=g9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function lK(){if(!process.stdin.isTTY)console.error(`${L.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${L.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(K8(T0)){if(console.log(`${L.yellow}发现已有配置: ${T0}${L.reset}`),(await P1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),V4.close();return}}fK("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${L.yellow}⚠ Claude 官方限制:${L.reset}`),console.log(` ${L.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${L.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${L.dim}1) 确保 Claude Code CLI 已装好${L.reset}`),console.log(` ${L.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${L.reset}`),console.log(` ${L.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${L.reset}`),console.log(` ${L.dim}4) 工作目录, 自动启动 daemon${L.reset}`),console.log(),await V4.question(`${L.dim}按 Enter 开始 (Ctrl+C 退出)...${L.reset}`),I9(1,4,"准备 Claude Code CLI"),await h9("claude",{report:(B)=>console.log(B)}),console.log(`${L.green}✓ Claude Code / SDK 已更新${L.reset}: ${L.dim}${Q4("claude","claude")}${L.reset}`),console.log(),console.log(`${L.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${L.reset}`),console.log(`${L.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${L.reset}`),I9(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${L.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${L.reset}`),console.log(` ${L.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${L.reset}`),console.log();let $=await P1("GLM API key (直接回车跳过)",{});if($){let B=await mK($);if("path"in B)console.log(`${L.green}✓ GLM 路由已写入${L.reset}: ${L.dim}${B.path}${L.reset}`),console.log(`${L.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${L.reset}`);else console.log(`${L.red}✗ 写入失败:${L.reset} ${B.error}`),console.log(`${L.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${L.reset}`)}else console.log(`${L.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${L.reset}`);if(console.log(),console.log(`${L.bold}Codex (可选第二后端)${L.reset}`),console.log(` ${L.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${L.reset}`),(await P1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await h9("codex",{report:(_)=>console.log(_)});let B=Q4("codex","codex");if(HY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else if(console.log(`${L.dim}启动 \`codex login\`...${L.reset}`),await hK(B)&&HY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else console.log(`${L.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${L.reset}`)}else console.log(`${L.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${L.reset}`);I9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${L.cyan}${J}${L.reset}`),pK(J),console.log(`${L.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${L.reset}`),console.log(),console.log(`${L.bold}详细操作步骤:${L.reset}`),console.log(),console.log(` ${L.bold}① 创建应用${L.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${L.dim}Lodestar${L.reset}), logo 随意。`),console.log(),console.log(` ${L.bold}② 添加机器人能力${L.reset}`),console.log(` 左侧菜单 "${L.cyan}添加应用能力${L.reset}" → 找到 "机器人" → 点 "${L.bold}添加${L.reset}" 按钮。`),console.log(),console.log(` ${L.bold}③ 申请权限 (左侧 "${L.cyan}权限管理${L.reset}" → "${L.bold}开通权限${L.reset}")${L.reset}`),console.log(` ${L.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${L.reset}`),console.log(` ${L.dim}消息类:${L.reset}`),console.log(` • ${L.bold}im:message:send_as_bot${L.reset} ${L.dim}# 以机器人身份发消息${L.reset}`),console.log(` • ${L.bold}im:message${L.reset} ${L.dim}# 接收/操作消息 (核心)${L.reset}`),console.log(` • ${L.bold}im:chat${L.reset} ${L.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${L.reset}`),console.log(` • ${L.bold}im:chat:create${L.reset} ${L.dim}# wt: 自动创建 worktree 群${L.reset}`),console.log(` • ${L.bold}im:chat:delete${L.reset} ${L.dim}# wt: 解散 worktree 群${L.reset}`),console.log(` • ${L.bold}im:chat.members:read${L.reset} ${L.dim}# wt: 判断发起人是否已在群内${L.reset}`),console.log(` • ${L.bold}im:chat.members:write_only${L.reset} ${L.dim}# wt: 把发起人拉进已有 worktree 群${L.reset}`),console.log(` • ${L.bold}im:resource${L.reset} ${L.dim}# 上传/下载附件 (图文双向)${L.reset}`),console.log(` • ${L.bold}im:message.urgent${L.reset} ${L.dim}# 加急推送 (锁屏通知 / Ask)${L.reset}`),console.log(` • ${L.bold}im:message.group_msg${L.reset} ${L.dim}# 敏感: 接收群里所有消息${L.reset}`),console.log(` ${L.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${L.reset}`),console.log(` ${L.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${L.reset}`),console.log(` • ${L.bold}im:message.group_at_msg:readonly${L.reset} ${L.dim}# 读 @ 机器人消息 (兜底)${L.reset}`),console.log(` ${L.dim}卡片类 (Card Kit):${L.reset}`),console.log(` • ${L.bold}cardkit:card:read${L.reset} ${L.dim}# 读卡片状态${L.reset}`),console.log(` • ${L.bold}cardkit:card:write${L.reset} ${L.dim}# 创建/更新卡片 (流式渲染核心)${L.reset}`),console.log(),console.log(` ${L.bold}④ 订阅事件 (左侧 "${L.cyan}事件与回调${L.reset}", 拆两个子页:)${L.reset}`),console.log(` ${L.dim}a)${L.reset} ${L.bold}事件配置${L.reset} 页:`),console.log(` ${L.yellow}• "订阅方式" → 选 "长连接" → 点保存${L.reset}`),console.log(` • 添加事件: ${L.bold}im.message.receive_v1${L.reset} ${L.dim}# 收群消息${L.reset}`),console.log(` ${L.dim}b)${L.reset} ${L.bold}回调配置${L.reset} 页:`),console.log(` ${L.yellow}• "订阅方式" → 选 "长连接" → 点保存${L.reset}`),console.log(` • 添加事件: ${L.bold}card.action.trigger${L.reset} ${L.dim}# 卡片按钮点击回调${L.reset}`),console.log(),console.log(` ${L.bold}⑤ 发布版本${L.reset}`),console.log(` 页面顶部 "${L.bold}创建版本${L.reset}" → 滚到底点 "${L.bold}保存${L.reset}" → 弹框点 "${L.bold}发布${L.reset}"。`),console.log(` ${L.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${L.reset}`),console.log(),console.log(` ${L.bold}⑥ 拿凭据${L.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${L.bold}App ID${L.reset} (${L.dim}cli_...${L.reset}) 和 ${L.bold}App Secret${L.reset}, 待会粘到下面。`),console.log(),console.log(` ${L.bold}⑦ 把机器人拉进群${L.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${L.yellow}群名要等于 projects_root 下的项目目录名${L.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",Q="";while(!0){Y=await P1("App ID (以 cli_ 开头)",{required:!0}),Q=await P1("App Secret",{required:!0}),console.log(`${L.dim}测试中... (调 tenant_access_token endpoint)${L.reset}`);let B=await cK(Y,Q);if(B.ok){console.log(`${L.green}✓ Feishu 凭据测试通过${L.reset}`);break}if(console.log(`${L.red}✗ 测试失败:${L.reset} ${B.error}`),console.log(`${L.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${L.reset}`),console.log(),(await P1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${L.yellow}已取消, 配置未写盘。${L.reset}`),V4.close(),process.exit(1)}I9(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let V=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",H=await P1("projects_root",{default:V});XY(n6,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${G8(Y)}"`,`app_secret = "${G8(Q)}"`,"","[runtime]",`projects_root = "${G8(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];Q$(T0,X.join(`
56
+ `)}function K8($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function zY($){try{let Z=vK($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function uK($){return new Promise((Z)=>{let J=fK($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function lK(){return process.env.CLAUDE_CONFIG_DIR||_8(mK(),".claude")}async function dK($){try{let Z=await J0("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((B)=>typeof B?.display_name==="string"&&B.display_name?B.display_name:String(B?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(B)=>{let _=B.match(/(\d+(?:\.\d+)?)/);return _?Number(_[1]):-1},V=(B)=>B.replace(/-Turbo|-Air$/i,""),X=[...Y.filter((B)=>!/-Turbo|-Air/i.test(B))].sort((B,_)=>Q(_)-Q(B)),z=X[0],W=X[X.length-1],G={};if(z)G.ANTHROPIC_DEFAULT_OPUS_MODEL=`${z}[1m]`,G.ANTHROPIC_DEFAULT_SONNET_MODEL=`${z}[1m]`;if(W&&V(W)!==V(z))G.ANTHROPIC_DEFAULT_HAIKU_MODEL=W;return Object.keys(G).length?G:null}catch{return null}}async function iK($){try{let Z=lK();WY(Z,{recursive:!0});let J=_8(Z,"settings.json"),Y={};if(B8(J)){let X=hK(J,"utf8");try{let z=JSON.parse(X);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:{},V={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await dK($);if(H)Object.assign(V,H);return Y.env={...Q,...V},Q$(J,JSON.stringify(Y,null,2)+`
57
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function nK($){try{if(process.platform==="win32")g9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")g9("open",[$],{detached:!0,stdio:"ignore"}).unref();else g9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function aK($,Z){try{let Y=await(await J0("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 oK(){try{let $=gK(pK(import.meta.url)),Z=_8($,"lodestar.js");if(!B8(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=g9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function rK(){if(!process.stdin.isTTY)console.error(`${L.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${L.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(B8(N0)){if(console.log(`${L.yellow}发现已有配置: ${N0}${L.reset}`),(await P1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),Q4.close();return}}cK("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${L.yellow}⚠ Claude 官方限制:${L.reset}`),console.log(` ${L.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${L.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${L.dim}1) 确保 Claude Code CLI 已装好${L.reset}`),console.log(` ${L.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${L.reset}`),console.log(` ${L.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${L.reset}`),console.log(` ${L.dim}4) 工作目录, 自动启动 daemon${L.reset}`),console.log(),await Q4.question(`${L.dim}按 Enter 开始 (Ctrl+C 退出)...${L.reset}`),I9(1,4,"准备 Claude Code CLI"),await h9("claude",{report:(B)=>console.log(B)}),console.log(`${L.green}✓ Claude Code / SDK 已更新${L.reset}: ${L.dim}${Y4("claude","claude")}${L.reset}`),console.log(),console.log(`${L.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${L.reset}`),console.log(`${L.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${L.reset}`),I9(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${L.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${L.reset}`),console.log(` ${L.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${L.reset}`),console.log();let $=await P1("GLM API key (直接回车跳过)",{});if($){let B=await iK($);if("path"in B)console.log(`${L.green}✓ GLM 路由已写入${L.reset}: ${L.dim}${B.path}${L.reset}`),console.log(`${L.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${L.reset}`);else console.log(`${L.red}✗ 写入失败:${L.reset} ${B.error}`),console.log(`${L.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${L.reset}`)}else console.log(`${L.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${L.reset}`);if(console.log(),console.log(`${L.bold}Codex (可选第二后端)${L.reset}`),console.log(` ${L.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${L.reset}`),(await P1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await h9("codex",{report:(_)=>console.log(_)});let B=Y4("codex","codex");if(zY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else if(console.log(`${L.dim}启动 \`codex login\`...${L.reset}`),await uK(B)&&zY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else console.log(`${L.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${L.reset}`)}else console.log(`${L.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${L.reset}`);I9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${L.cyan}${J}${L.reset}`),nK(J),console.log(`${L.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${L.reset}`),console.log(),console.log(`${L.bold}详细操作步骤:${L.reset}`),console.log(),console.log(` ${L.bold}① 创建应用${L.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${L.dim}Lodestar${L.reset}), logo 随意。`),console.log(),console.log(` ${L.bold}② 添加机器人能力${L.reset}`),console.log(` 左侧菜单 "${L.cyan}添加应用能力${L.reset}" → 找到 "机器人" → 点 "${L.bold}添加${L.reset}" 按钮。`),console.log(),console.log(` ${L.bold}③ 申请权限 (左侧 "${L.cyan}权限管理${L.reset}" → "${L.bold}开通权限${L.reset}")${L.reset}`),console.log(` ${L.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${L.reset}`),console.log(` ${L.dim}消息类:${L.reset}`),console.log(` • ${L.bold}im:message:send_as_bot${L.reset} ${L.dim}# 以机器人身份发消息${L.reset}`),console.log(` • ${L.bold}im:message${L.reset} ${L.dim}# 接收/操作消息 (核心)${L.reset}`),console.log(` • ${L.bold}im:chat${L.reset} ${L.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${L.reset}`),console.log(` • ${L.bold}im:chat:create${L.reset} ${L.dim}# wt: 自动创建 worktree 群${L.reset}`),console.log(` • ${L.bold}im:chat:delete${L.reset} ${L.dim}# wt: 解散 worktree 群${L.reset}`),console.log(` • ${L.bold}im:chat.members:read${L.reset} ${L.dim}# wt: 判断发起人是否已在群内${L.reset}`),console.log(` • ${L.bold}im:chat.members:write_only${L.reset} ${L.dim}# wt: 把发起人拉进已有 worktree 群${L.reset}`),console.log(` • ${L.bold}im:resource${L.reset} ${L.dim}# 上传/下载附件 (图文双向)${L.reset}`),console.log(` • ${L.bold}im:message.urgent${L.reset} ${L.dim}# 加急推送 (锁屏通知 / Ask)${L.reset}`),console.log(` • ${L.bold}im:message.group_msg${L.reset} ${L.dim}# 敏感: 接收群里所有消息${L.reset}`),console.log(` ${L.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${L.reset}`),console.log(` ${L.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${L.reset}`),console.log(` • ${L.bold}im:message.group_at_msg:readonly${L.reset} ${L.dim}# 读 @ 机器人消息 (兜底)${L.reset}`),console.log(` ${L.dim}卡片类 (Card Kit):${L.reset}`),console.log(` • ${L.bold}cardkit:card:read${L.reset} ${L.dim}# 读卡片状态${L.reset}`),console.log(` • ${L.bold}cardkit:card:write${L.reset} ${L.dim}# 创建/更新卡片 (流式渲染核心)${L.reset}`),console.log(),console.log(` ${L.bold}④ 订阅事件 (左侧 "${L.cyan}事件与回调${L.reset}", 拆两个子页:)${L.reset}`),console.log(` ${L.dim}a)${L.reset} ${L.bold}事件配置${L.reset} 页:`),console.log(` ${L.yellow}• "订阅方式" → 选 "长连接" → 点保存${L.reset}`),console.log(` • 添加事件: ${L.bold}im.message.receive_v1${L.reset} ${L.dim}# 收群消息${L.reset}`),console.log(` ${L.dim}b)${L.reset} ${L.bold}回调配置${L.reset} 页:`),console.log(` ${L.yellow}• "订阅方式" → 选 "长连接" → 点保存${L.reset}`),console.log(` • 添加事件: ${L.bold}card.action.trigger${L.reset} ${L.dim}# 卡片按钮点击回调${L.reset}`),console.log(),console.log(` ${L.bold}⑤ 发布版本${L.reset}`),console.log(` 页面顶部 "${L.bold}创建版本${L.reset}" → 滚到底点 "${L.bold}保存${L.reset}" → 弹框点 "${L.bold}发布${L.reset}"。`),console.log(` ${L.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${L.reset}`),console.log(),console.log(` ${L.bold}⑥ 拿凭据${L.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${L.bold}App ID${L.reset} (${L.dim}cli_...${L.reset}) 和 ${L.bold}App Secret${L.reset}, 待会粘到下面。`),console.log(),console.log(` ${L.bold}⑦ 把机器人拉进群${L.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${L.yellow}群名要等于 projects_root 下的项目目录名${L.reset} (下一步设, 默认是用户主目录)。`),console.log();let Y="",Q="";while(!0){Y=await P1("App ID (以 cli_ 开头)",{required:!0}),Q=await P1("App Secret",{required:!0}),console.log(`${L.dim}测试中... (调 tenant_access_token endpoint)${L.reset}`);let B=await aK(Y,Q);if(B.ok){console.log(`${L.green}✓ Feishu 凭据测试通过${L.reset}`);break}if(console.log(`${L.red}✗ 测试失败:${L.reset} ${B.error}`),console.log(`${L.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${L.reset}`),console.log(),(await P1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${L.yellow}已取消, 配置未写盘。${L.reset}`),Q4.close(),process.exit(1)}I9(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let V=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",H=await P1("projects_root",{default:V});WY(a6,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${K8(Y)}"`,`app_secret = "${K8(Q)}"`,"","[runtime]",`projects_root = "${K8(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];Q$(N0,X.join(`
58
58
  `)),console.log(`
59
- ${L.green}${L.bold}✓ 配置已写入${L.reset}`),console.log(` ${L.cyan}${T0}${L.reset}`),console.log(`
60
- ${L.bold}启动 daemon...${L.reset}`);let z=uK(),W=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(`${L.green}✓ daemon 已在后台启动${L.reset} (pid ${z.pid})`),console.log(),console.log(`${L.bold}最后一步: 在 Feishu 验证${L.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${L.cyan}${H}${W}<群名>${L.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${L.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${L.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${L.cyan}${G}${L.reset}`),console.log(),console.log(`${L.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${L.reset}`);else console.log(`${L.yellow}启动失败: ${z.error}${L.reset}`),console.log(`手动运行: ${L.cyan}lodestar-daemon${L.reset}`);console.log(),V4.close()}var L,V4;var WY=T(()=>{a0();H0();f0();Y2();L={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},V4=kK({input:process.stdin,output:process.stdout})});import{existsSync as dK,readFileSync as iK}from"node:fs";function GY($,Z){return`${$}:${Z}`}function nK(){if(!dK(T9))return;try{let $=JSON.parse(iK(T9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");H4=new Set($.ids)}catch($){_8=$ instanceof Error?$:Error(String($))}}function KY(){if(_8)throw Error(`delegated-agent session registry is unavailable: ${_8.message}`)}function BY($,Z){KY();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=GY($,J);if(H4.has(Y))return;let Q=new Set(H4);Q.add(Y),s(T9,{version:1,ids:[...Q].sort()}),H4=Q}function Q2($,Z){return KY(),H4.has(GY($,Z))}var H4,_8=null;var X4=T(()=>{H0();f0();H4=new Set;nK()});var _Y=1;import{appendFileSync as qY,mkdirSync as aK,readdirSync as oK,unlinkSync as PY,existsSync as jY,statSync as rK,renameSync as sK,readFileSync as tK}from"node:fs";import{join as DY}from"node:path";function q8($="development"){return $!=="test"}function FY($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function MY($,Z=r){return DY(Z,`${j8}${FY($)}${L8}`)}function $B($){if(!$.startsWith(j8)||!$.endsWith(L8))return null;let Z=$.slice(j8.length,$.length-L8.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 UY($,Z=new Date,J=eK){let Y;try{Y=oK($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let H of Y){let X=$B(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{PY(DY($,H)),V++}catch{}}return V}function ZB(){try{if(!jY(e1))return;let $=rK(e1);if(!$.isFile()||$.size===0)return;let Z=MY($.mtime);if(jY(Z)){qY(Z,tK(e1)),PY(e1);return}sK(e1,Z)}catch{}}function K($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
- `;if(process.stderr.write(J),!q8())return;try{let Y=FY(Z);if(LY!==Y)LY=Y,UY(r,Z);qY(MY(Z),J)}catch{}}var eK=7,j8="daemon-",L8=".log",LY=null;var I=T(()=>{H0();if(q8())try{aK(r,{recursive:!0})}catch{}if(q8()){ZB();try{UY(r)}catch{}}});import{EventEmitter as JB}from"node:events";import{createRequire as YB}from"node:module";import{createHash as QB,randomUUID as VB}from"node:crypto";import{createInterface as HB}from"node:readline";import{dirname as XB,join as N$,isAbsolute as zB}from"node:path";import{fileURLToPath as P8}from"node:url";import{tmpdir as WB}from"node:os";import{existsSync as AY,mkdirSync as OY,mkdtempSync as GB,readFileSync as z4,renameSync as KB,writeFileSync as RY,rmSync as D8}from"node:fs";import BB from"cross-spawn";function _B($){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 jB($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=z4(N$($,".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,V])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Q)||!V||typeof V!=="object")throw Error(`invalid DSH MCP server: ${Q}`);let H=V,X=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(!X)throw Error(`DSH does not support MCP transport ${H.type} for ${Q}`);return{id:`lodestar-mcp-${Q}`,name:"@deepseek-ai/dsh-mcp-client",config:{...X,failOnStartupError:!0}}})}async function V2($,Z,J={}){let Y=new m9($);Y.on("failure",(H)=>K(`dsh catalog: ${H}`));let Q,V;try{await Y.initialize(),V=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 V}var m9;var W4=T(()=>{H0();Y2();I();m9=class m9 extends JB{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!zB($.cwd))throw Error("DSH requires an absolute workspace");let Z=f9("dsh"),Y=YB(N$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(z4(Y,"utf8"));K(`dsh runtime: ${Q.version} (${Z})`);let V=_B($.env),H=$.home??$2;OY(H,{recursive:!0,mode:448});let X=jB($.cwd,$.profile);this.launchDir=GB(N$(WB(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),W=z?"dsh-bridge.ts":"dsh-bridge.js",G=z4(P8(new URL(`./${W}`,import.meta.url))),B=z?z4(P8(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(z4(P8(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),q=QB("sha256").update(G).update(B).update(j).digest("hex").slice(0,20),P=N$(Z,".lodestar-bridges",q);OY(P,{recursive:!0});let D=N$(P,W),N=(y,h)=>{if(AY(y))return;let x=`${y}.${VB()}.tmp`;try{RY(x,h),KB(x,y)}finally{if(AY(x))D8(x)}};if(N(N$(P,"package.json"),j),z)N(N$(P,"dsh-protocol.ts"),B);N(D,G);let U=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((y)=>({id:y,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:D},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...X]},...V],A=N$(this.launchDir,"bridge.patch.yml");RY(A,JSON.stringify(U),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",S=[N$(XB(Y),Q.bin.dsh),"--profile","sdk","--patch",A,...($.patches??[]).flatMap((y)=>["--patch",y])],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 y of Object.keys(C))if(y.startsWith("LODESTAR_AGENT_"))delete C[y];try{this.child=BB(M,S,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...C,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(y){throw D8(this.launchDir,{recursive:!0,force:!0}),y}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(y)=>{this.stderr=(this.stderr+y).slice(-16384),K(`dsh stderr: ${y.trimEnd()}`)}),this.child.stdin.on("error",(y)=>this.transportFailure(y));let p=HB({input:this.child.stdout,crlfDelay:1/0});p.on("line",(y)=>this.receive(y)),this.exitTask=new Promise((y)=>{this.child.once("error",(h)=>this.transportFailure(h)),this.child.once("close",(h,x)=>{this.exited=!0,p.close();let f=Error(`DSH exited code=${h} signal=${x}
62
- ${this.stderr}`);this.rejectPending(f),D8(this.launchDir,{recursive:!0,force:!0}),y(),this.emit("exit",{code:h,signal:x,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==_Y||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,V)=>{let H=J===null?void 0:setTimeout(()=>{this.pending.delete(Y),V(Error(`DSH ${$} timed out after ${J}ms
59
+ ${L.green}${L.bold}✓ 配置已写入${L.reset}`),console.log(` ${L.cyan}${N0}${L.reset}`),console.log(`
60
+ ${L.bold}启动 daemon...${L.reset}`);let z=oK(),W=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(`${L.green}✓ daemon 已在后台启动${L.reset} (pid ${z.pid})`),console.log(),console.log(`${L.bold}最后一步: 在 Feishu 验证${L.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${L.cyan}${H}${W}<群名>${L.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${L.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${L.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${L.cyan}${G}${L.reset}`),console.log(),console.log(`${L.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${L.reset}`);else console.log(`${L.yellow}启动失败: ${z.error}${L.reset}`),console.log(`手动运行: ${L.cyan}lodestar-daemon${L.reset}`);console.log(),Q4.close()}var L,Q4;var KY=N(()=>{a0();V0();f0();Z2();L={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},Q4=IK({input:process.stdin,output:process.stdout})});import{existsSync as sK,readFileSync as tK}from"node:fs";function BY($,Z){return`${$}:${Z}`}function eK(){if(!sK(N9))return;try{let $=JSON.parse(tK(N9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");V4=new Set($.ids)}catch($){j8=$ instanceof Error?$:Error(String($))}}function _Y(){if(j8)throw Error(`delegated-agent session registry is unavailable: ${j8.message}`)}function jY($,Z){_Y();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=BY($,J);if(V4.has(Y))return;let Q=new Set(V4);Q.add(Y),s(N9,{version:1,ids:[...Q].sort()}),V4=Q}function J2($,Z){return _Y(),V4.has(BY($,Z))}var V4,j8=null;var H4=N(()=>{V0();f0();V4=new Set;eK()});var LY=1;import{appendFileSync as DY,mkdirSync as $B,readdirSync as ZB,unlinkSync as FY,existsSync as qY,statSync as JB,renameSync as YB,readFileSync as QB}from"node:fs";import{join as UY}from"node:path";function P8($="development"){return $!=="test"}function MY($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function AY($,Z=r){return UY(Z,`${L8}${MY($)}${q8}`)}function HB($){if(!$.startsWith(L8)||!$.endsWith(q8))return null;let Z=$.slice(L8.length,$.length-q8.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 OY($,Z=new Date,J=VB){let Y;try{Y=ZB($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let H of Y){let X=HB(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{FY(UY($,H)),V++}catch{}}return V}function XB(){try{if(!qY(s1))return;let $=JB(s1);if(!$.isFile()||$.size===0)return;let Z=AY($.mtime);if(qY(Z)){DY(Z,QB(s1)),FY(s1);return}YB(s1,Z)}catch{}}function K($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
+ `;if(process.stderr.write(J),!P8())return;try{let Y=MY(Z);if(PY!==Y)PY=Y,OY(r,Z);DY(AY(Z),J)}catch{}}var VB=7,L8="daemon-",q8=".log",PY=null;var h=N(()=>{V0();if(P8())try{$B(r,{recursive:!0})}catch{}if(P8()){XB();try{OY(r)}catch{}}});import{EventEmitter as zB}from"node:events";import{createRequire as WB}from"node:module";import{createHash as GB,randomUUID as KB}from"node:crypto";import{createInterface as BB}from"node:readline";import{dirname as _B,join as T$,isAbsolute as jB}from"node:path";import{fileURLToPath as D8}from"node:url";import{tmpdir as LB}from"node:os";import{existsSync as RY,mkdirSync as NY,mkdtempSync as qB,readFileSync as X4,renameSync as PB,writeFileSync as TY,rmSync as F8}from"node:fs";import DB from"cross-spawn";function FB($){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 UB($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=X4(T$($,".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,V])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Q)||!V||typeof V!=="object")throw Error(`invalid DSH MCP server: ${Q}`);let H=V,X=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(!X)throw Error(`DSH does not support MCP transport ${H.type} for ${Q}`);return{id:`lodestar-mcp-${Q}`,name:"@deepseek-ai/dsh-mcp-client",config:{...X,failOnStartupError:!0}}})}async function Y2($,Z,J={}){let Y=new m9($);Y.on("failure",(H)=>K(`dsh catalog: ${H}`));let Q,V;try{await Y.initialize(),V=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 V}var m9;var z4=N(()=>{V0();Z2();h();m9=class m9 extends zB{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!jB($.cwd))throw Error("DSH requires an absolute workspace");let Z=f9("dsh"),Y=WB(T$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(X4(Y,"utf8"));K(`dsh runtime: ${Q.version} (${Z})`);let V=FB($.env),H=$.home??t1;NY(H,{recursive:!0,mode:448});let X=UB($.cwd,$.profile);this.launchDir=qB(T$(LB(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),W=z?"dsh-bridge.ts":"dsh-bridge.js",G=X4(D8(new URL(`./${W}`,import.meta.url))),B=z?X4(D8(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(X4(D8(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),q=GB("sha256").update(G).update(B).update(j).digest("hex").slice(0,20),P=T$(Z,".lodestar-bridges",q);NY(P,{recursive:!0});let D=T$(P,W),T=(y,I)=>{if(RY(y))return;let E=`${y}.${KB()}.tmp`;try{TY(E,I),PB(E,y)}finally{if(RY(E))F8(E)}};if(T(T$(P,"package.json"),j),z)T(T$(P,"dsh-protocol.ts"),B);T(D,G);let M=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((y)=>({id:y,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:D},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...X]},...V],A=T$(this.launchDir,"bridge.patch.yml");TY(A,JSON.stringify(M),{mode:384});let U=$.env.LODESTAR_DSH_NODE||"node",S=[T$(_B(Y),Q.bin.dsh),"--profile","sdk","--patch",A,...($.patches??[]).flatMap((y)=>["--patch",y])],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 y of Object.keys(C))if(y.startsWith("LODESTAR_AGENT_"))delete C[y];try{this.child=DB(U,S,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...C,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(y){throw F8(this.launchDir,{recursive:!0,force:!0}),y}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(y)=>{this.stderr=(this.stderr+y).slice(-16384),K(`dsh stderr: ${y.trimEnd()}`)}),this.child.stdin.on("error",(y)=>this.transportFailure(y));let p=BB({input:this.child.stdout,crlfDelay:1/0});p.on("line",(y)=>this.receive(y)),this.exitTask=new Promise((y)=>{this.child.once("error",(I)=>this.transportFailure(I)),this.child.once("close",(I,E)=>{this.exited=!0,p.close();let f=Error(`DSH exited code=${I} signal=${E}
62
+ ${this.stderr}`);this.rejectPending(f),F8(this.launchDir,{recursive:!0,force:!0}),y(),this.emit("exit",{code:I,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!==LY||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,V)=>{let H=J===null?void 0:setTimeout(()=>{this.pending.delete(Y),V(Error(`DSH ${$} timed out after ${J}ms
63
63
  ${this.stderr}`))},J);this.pending.set(Y,{resolve:Q,reject:V,timer:H}),this.child.stdin.write(JSON.stringify({jsonrpc:"2.0",id:Y,method:$,params:Z})+`
64
- `,(X)=>{if(X)this.transportFailure(X)})})}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){K(`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){K(`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(K(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(K(`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 B$($){return typeof $==="string"&&F8.includes($)}function B0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function N0($){return typeof $==="string"&&M8.includes($)}function H2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function _$($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var F8,M8,l$="max",D1;var D0=T(()=>{F8=["codex","claude","dsh"];M8=["low","medium","high","xhigh","max","default"];D1=class D1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as LB}from"node:fs";import{homedir as NY}from"node:os";function TY($){return $.replace(/^~(?=\/|$)/,NY())}function qB($){let Z={_:{}},J="_";for(let Y of $.split(`
65
- `)){let Q=PB(Y).trim();if(!Q)continue;let V=Q.match(/^\[([^\]]+)\]$/);if(V){J=V[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let X=H[2].trim(),z=X.startsWith('"')&&X.endsWith('"'),W=X.startsWith("'")&&X.endsWith("'");if(z||W){if(X=X.slice(1,-1),z)X=X.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=X}}return Z}function PB($){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 p9(){let $;try{$=LB(T0,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${T0}
64
+ `,(X)=>{if(X)this.transportFailure(X)})})}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){K(`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){K(`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(K(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(K(`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 B$($){return typeof $==="string"&&U8.includes($)}function B0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function T0($){return typeof $==="string"&&M8.includes($)}function Q2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function _$($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var U8,M8,u$="max",D1;var D0=N(()=>{U8=["codex","claude","dsh"];M8=["low","medium","high","xhigh","max","default"];D1=class D1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as MB}from"node:fs";import{homedir as xY}from"node:os";function EY($){return $.replace(/^~(?=\/|$)/,xY())}function AB($){let Z={_:{}},J="_";for(let Y of $.split(`
65
+ `)){let Q=OB(Y).trim();if(!Q)continue;let V=Q.match(/^\[([^\]]+)\]$/);if(V){J=V[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let X=H[2].trim(),z=X.startsWith('"')&&X.endsWith('"'),W=X.startsWith("'")&&X.endsWith("'");if(z||W){if(X=X.slice(1,-1),z)X=X.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=X}}return Z}function OB($){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 p9(){let $;try{$=MB(N0,"utf8")}catch(U){throw process.stderr.write(`lodestar: cannot read config at ${N0}
66
66
  `+" → 运行 `lodestar-setup` 走交互式向导生成 (Feishu / Codex / 工作目录)\n"+` → 或手写: 设 LODESTAR_CONFIG=/path/to/config.toml 覆盖默认路径
67
67
  `+` [feishu]
68
68
  app_id = "cli_xxx"
69
69
  app_secret = "xxx"
70
70
 
71
- `),M}let Z=qB($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${T0} is missing [feishu].app_id / [feishu].app_secret`);let Q=TY(Z.runtime?.projects_root??NY()),V={codex:!1,claude:!1,dsh:!1},H=Z["runtime.agent_auto_update"],X=Z.runtime?.agent_auto_update;if(X!==void 0){if(H)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(X!=="true"&&X!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${X}"`);for(let M of["codex","claude","dsh"])V[M]=X==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
72
- `)}else if(H)for(let[M,S]of Object.entries(H)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(S!=="true"&&S!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${S}"`);V[M]=S==="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 W=z,G=Z.notify?.bind??"127.0.0.1",B=Z.notify?.port??"9876";if(!/^\d+$/.test(B.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${B}"`);let _=Number.parseInt(B,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${B}"`);let j=(M)=>{let S=Z[M]??{},C={};for(let[p,y]of Object.entries(S))if(typeof y==="string"&&y.length>0)C[p]=y;return C},q=()=>{let M={};for(let[S,C]of Object.entries(Z)){if(!S.startsWith("claude.models."))continue;let y=S.slice(14).trim();if(!y)continue;let h={};for(let[x,f]of Object.entries(C)){if(typeof f!=="string"||f.length===0)continue;if(x.trim()==="model")h.model=f}M[y]=h}return M},P=()=>{let M={},S="projects.";for(let[C,p]of Object.entries(Z)){if(!C.startsWith("projects."))continue;let y=C.slice(9).trim();if(!y)continue;let h={};for(let[x,f]of Object.entries(p)){if(typeof f!=="string"||f.length===0)continue;switch(x.trim()){case"cwd":h.cwd=f;break;case"setting_sources":h.settingSources=f;break;case"strict_mcp":h.strictMcp=f==="true";break;case"tools":h.tools=f;break;case"load_project_mcp":h.loadProjectMcp=f==="true";break}}M[y]=h}return M},D=()=>{let M={},S="token_source.";for(let[C,p]of Object.entries(Z)){if(!C.startsWith("token_source."))continue;let y=C.slice(13).trim();if(!y)continue;let h={};for(let[x,f]of Object.entries(p)){if(typeof f!=="string")continue;let m=x.trim();if(m==="default")h.default=f==="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]=f}M[y]=h}return M},N=j("codex.env"),U=j("claude.env"),A=Z.claude?.bin?TY(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:W,agent_auto_update:V},notify:{bind:G,port:_},codex:{env:N},claude:{bin:A,env:U,models:q()},projects:P(),token_sources:D()}}function EY(){v.token_sources=p9().token_sources}var v;var C0=T(()=>{H0();v=p9()});function W0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function E$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function c9($){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 FB($){let Z=$.slice(0,O8),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function MB($){let Z=a($);if(!Z)return null;let J=a(Z.event),Y=a(Z.payload);return a(Z.item)??a(Z.responseItem)??a(Z.rawItem)??a(J?.item)??a(J?.responseItem)??a(J?.rawItem)??a(Y?.item)??a(Y?.responseItem)??a(Y?.rawItem)??(G4(Z.type)?Z:null)??(J&&G4(J.type)?J:null)??(Y&&G4(Y.type)?Y:null)}function UB($){let Z=[],J=new WeakSet,Y=(Q,V,H)=>{if(Z.length>=O8||H>6)return;if(Array.isArray(Q)){if(V)Z.push(`${V}[]`);if(Q.length>0)Y(Q[0],V?`${V}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let X of Object.keys(Q)){if(Z.length>=O8)return;let z=V?`${V}.${X}`:X;Z.push(z),Y(Q[X],z,H+1)}};return Y($,"",0),Z}function R8($){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>A8)return`${Q.slice(0,A8)}...<truncated ${Q.length-A8} 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>U8)return`${J.slice(0,U8)}...<truncated ${J.length-U8} chars>`;return J}function I0($,Z){let J=a(Z),Y=J?a(J.params):null,Q=J?a(J.item)??a(Y?.item):null,V=J?W0(J.method)??"-":"-";K([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${E$(V)}`,`rootKeys=${c9(J)}`,`itemKeys=${c9(Q)}`,`payload=${R8(Z)}`].join(" "))}function T8($,Z,J){let Y=a(Z),Q=MB(Z),V=[`phase=${E$(J.phase??"event")}`,`method=${E$($)}`,`sourceMethod=${E$(J.sourceMethod)}`,`sourceType=${E$(J.sourceType)}`,`sessionId=${E$(J.sessionId)}`,`threadId=${E$(J.threadId)}`,`turnId=${E$(J.turnId)}`,`itemId=${E$(J.itemId)}`].join(" ");if(K(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${c9(Y)} itemKeys=${c9(Q)}`),K(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${FB(UB(Z))}`),Q)K(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${R8(Q)}`);K(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${R8(Z)}`)}function G4($){if(typeof $!=="string")return null;return DB.has($)?$:null}function AB($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||xY.has(Z))return"end";return"event"}function N8($,Z){return SY($,a(Z)??{})}function E8($){let Z=a($);if(!Z)return null;let J=W0(Z.method)??W0(Z.type)??"raw_message";return SY(J,Z)}function SY($,Z){let J=a(Z.payload),Y=[Z,a(Z.event),J,a(Z.item),a(Z.responseItem),a(Z.rawItem)].filter((z)=>z!=null),Q=null;for(let z of Y)if(Q=G4(z.type),Q)break;if(!xY.has($)&&!Q)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),H=Q==="compacted"&&J?J:V&&G4(V.type)?V:Z,X=a(H.item)??a(H.responseItem)??a(H.rawItem)??V??{};return{...H,threadId:W0(H.threadId)??W0(H.thread_id)??W0(Z.threadId)??W0(Z.thread_id),turnId:W0(H.turnId)??W0(H.turn_id)??W0(Z.turnId)??W0(Z.turn_id),itemId:W0(H.itemId)??W0(H.item_id)??W0(X.id)??W0(X.itemId)??W0(X.item_id),timestamp:W0(Z.timestamp)??W0(H.timestamp),recordType:W0(Z.type),phase:AB(Q,$),sourceMethod:$,sourceType:Q??$}}var xY,DB,U8=200000,A8=50000,O8=400;var x8=T(()=>{I();xY=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),DB=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function K4($){return $!=null&&typeof $==="object"?$:null}function x$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function bY($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function u9($,Z){return $?x$($[Z]):void 0}function X2($){let Z=K4($);if(!Z)return null;let J=K4(Z.inputTokensDetails)??K4(Z.input_tokens_details),Y=K4(Z.outputTokensDetails)??K4(Z.output_tokens_details),Q={total_tokens:x$(Z.totalTokens??Z.total_tokens),input_tokens:x$(Z.inputTokens??Z.input_tokens),output_tokens:x$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:x$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??u9(Y,"reasoningTokens")??u9(Y,"reasoning_tokens")),cache_creation_input_tokens:x$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:x$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??u9(J,"cachedTokens")??u9(J,"cached_tokens"))};return bY(Q)?Q:null}function S8($,Z){let J=(Q)=>{let V=x$($?.[Q]),H=x$(Z?.[Q]);if(V===void 0&&H===void 0)return;return Math.max(0,(V??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 bY(Y)?Y:null}function b8($){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 CY($){let Z=$.trim();if(Z.length<2)return Z;let J=l9[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 k8($){let Z=RB(String($??"")),J=Z.split(`
71
+ `),U}let Z=AB($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${N0} is missing [feishu].app_id / [feishu].app_secret`);let Q=EY(Z.runtime?.projects_root??xY()),V={codex:!1,claude:!1,dsh:!1},H=Z["runtime.agent_auto_update"],X=Z.runtime?.agent_auto_update;if(X!==void 0){if(H)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(X!=="true"&&X!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${X}"`);for(let U of["codex","claude","dsh"])V[U]=X==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
72
+ `)}else if(H)for(let[U,S]of Object.entries(H)){if(U!=="codex"&&U!=="claude"&&U!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${U}"`);if(S!=="true"&&S!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${U} must be true or false, got "${S}"`);V[U]=S==="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 W=z,G=Z.notify?.bind??"127.0.0.1",B=Z.notify?.port??"9876";if(!/^\d+$/.test(B.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${B}"`);let _=Number.parseInt(B,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${B}"`);let j=(U)=>{let S=Z[U]??{},C={};for(let[p,y]of Object.entries(S))if(typeof y==="string"&&y.length>0)C[p]=y;return C},q=()=>{let U={};for(let[S,C]of Object.entries(Z)){if(!S.startsWith("claude.models."))continue;let y=S.slice(14).trim();if(!y)continue;let I={};for(let[E,f]of Object.entries(C)){if(typeof f!=="string"||f.length===0)continue;if(E.trim()==="model")I.model=f}U[y]=I}return U},P=()=>{let U={},S="projects.";for(let[C,p]of Object.entries(Z)){if(!C.startsWith("projects."))continue;let y=C.slice(9).trim();if(!y)continue;let I={};for(let[E,f]of Object.entries(p)){if(typeof f!=="string"||f.length===0)continue;switch(E.trim()){case"cwd":I.cwd=f;break;case"setting_sources":I.settingSources=f;break;case"strict_mcp":I.strictMcp=f==="true";break;case"tools":I.tools=f;break;case"load_project_mcp":I.loadProjectMcp=f==="true";break}}U[y]=I}return U},D=()=>{let U={},S="token_source.";for(let[C,p]of Object.entries(Z)){if(!C.startsWith("token_source."))continue;let y=C.slice(13).trim();if(!y)continue;let I={};for(let[E,f]of Object.entries(p)){if(typeof f!=="string")continue;let m=E.trim();if(m==="default")I.default=f==="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")I[m]=f}U[y]=I}return U},T=j("codex.env"),M=j("claude.env"),A=Z.claude?.bin?EY(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:W,agent_auto_update:V},notify:{bind:G,port:_},codex:{env:T},claude:{bin:A,env:M,models:q()},projects:P(),token_sources:D()}}function SY(){v.token_sources=p9().token_sources}var v;var C0=N(()=>{V0();v=p9()});function W0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function E$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function c9($){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 NB($){let Z=$.slice(0,R8),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function TB($){let Z=a($);if(!Z)return null;let J=a(Z.event),Y=a(Z.payload);return a(Z.item)??a(Z.responseItem)??a(Z.rawItem)??a(J?.item)??a(J?.responseItem)??a(J?.rawItem)??a(Y?.item)??a(Y?.responseItem)??a(Y?.rawItem)??(W4(Z.type)?Z:null)??(J&&W4(J.type)?J:null)??(Y&&W4(Y.type)?Y:null)}function EB($){let Z=[],J=new WeakSet,Y=(Q,V,H)=>{if(Z.length>=R8||H>6)return;if(Array.isArray(Q)){if(V)Z.push(`${V}[]`);if(Q.length>0)Y(Q[0],V?`${V}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let X of Object.keys(Q)){if(Z.length>=R8)return;let z=V?`${V}.${X}`:X;Z.push(z),Y(Q[X],z,H+1)}};return Y($,"",0),Z}function N8($){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>O8)return`${Q.slice(0,O8)}...<truncated ${Q.length-O8} 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>A8)return`${J.slice(0,A8)}...<truncated ${J.length-A8} chars>`;return J}function I0($,Z){let J=a(Z),Y=J?a(J.params):null,Q=J?a(J.item)??a(Y?.item):null,V=J?W0(J.method)??"-":"-";K([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${E$(V)}`,`rootKeys=${c9(J)}`,`itemKeys=${c9(Q)}`,`payload=${N8(Z)}`].join(" "))}function T8($,Z,J){let Y=a(Z),Q=TB(Z),V=[`phase=${E$(J.phase??"event")}`,`method=${E$($)}`,`sourceMethod=${E$(J.sourceMethod)}`,`sourceType=${E$(J.sourceType)}`,`sessionId=${E$(J.sessionId)}`,`threadId=${E$(J.threadId)}`,`turnId=${E$(J.turnId)}`,`itemId=${E$(J.itemId)}`].join(" ");if(K(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${c9(Y)} itemKeys=${c9(Q)}`),K(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${NB(EB(Z))}`),Q)K(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${N8(Q)}`);K(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${N8(Z)}`)}function W4($){if(typeof $!=="string")return null;return RB.has($)?$:null}function xB($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||bY.has(Z))return"end";return"event"}function E8($,Z){return CY($,a(Z)??{})}function x8($){let Z=a($);if(!Z)return null;let J=W0(Z.method)??W0(Z.type)??"raw_message";return CY(J,Z)}function CY($,Z){let J=a(Z.payload),Y=[Z,a(Z.event),J,a(Z.item),a(Z.responseItem),a(Z.rawItem)].filter((z)=>z!=null),Q=null;for(let z of Y)if(Q=W4(z.type),Q)break;if(!bY.has($)&&!Q)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),H=Q==="compacted"&&J?J:V&&W4(V.type)?V:Z,X=a(H.item)??a(H.responseItem)??a(H.rawItem)??V??{};return{...H,threadId:W0(H.threadId)??W0(H.thread_id)??W0(Z.threadId)??W0(Z.thread_id),turnId:W0(H.turnId)??W0(H.turn_id)??W0(Z.turnId)??W0(Z.turn_id),itemId:W0(H.itemId)??W0(H.item_id)??W0(X.id)??W0(X.itemId)??W0(X.item_id),timestamp:W0(Z.timestamp)??W0(H.timestamp),recordType:W0(Z.type),phase:xB(Q,$),sourceMethod:$,sourceType:Q??$}}var bY,RB,A8=200000,O8=50000,R8=400;var S8=N(()=>{h();bY=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),RB=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function G4($){return $!=null&&typeof $==="object"?$:null}function x$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function kY($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function u9($,Z){return $?x$($[Z]):void 0}function V2($){let Z=G4($);if(!Z)return null;let J=G4(Z.inputTokensDetails)??G4(Z.input_tokens_details),Y=G4(Z.outputTokensDetails)??G4(Z.output_tokens_details),Q={total_tokens:x$(Z.totalTokens??Z.total_tokens),input_tokens:x$(Z.inputTokens??Z.input_tokens),output_tokens:x$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:x$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??u9(Y,"reasoningTokens")??u9(Y,"reasoning_tokens")),cache_creation_input_tokens:x$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:x$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??u9(J,"cachedTokens")??u9(J,"cached_tokens"))};return kY(Q)?Q:null}function b8($,Z){let J=(Q)=>{let V=x$($?.[Q]),H=x$(Z?.[Q]);if(V===void 0&&H===void 0)return;return Math.max(0,(V??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 kY(Y)?Y:null}function C8($){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 yY($){let Z=$.trim();if(Z.length<2)return Z;let J=l9[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 y8($){let Z=bB(String($??"")),J=Z.split(`
73
73
  `,1)[0]?.trim()??"",Q=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),V=Q?Z.split(`
74
74
  `).slice(1).join(`
75
- `).trimStart():Z;return{description:Q,command:V||Z}}function z2($,Z=60){let{description:J,command:Y}=k8($);if(J)return J;return OB(Y).replace(/\s+/g," ").trim().slice(0,Z)}function OB($){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 RB($){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=NB(J[1]);return C8(Q||Z)}let Y=TB(Z);if(Y)return Y;return C8(Z)}function TB($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=CY(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 V=Q[1].toLowerCase();if(V==="-command"||V==="-c")return C8(CY(Q[2]));if(Y=Q[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function NB($){let Z=$.trim();if(Z.length<2)return Z;let J=l9[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 C8($){let Z=$.trim(),J=Z[0];if(!l9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!EB(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,X)=>` $(${X})`)}function EB($,Z){let J=l9[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 l9;var d9=T(()=>{l9={'"':'"',"'":"'","“":"”"}});function O($){return $ instanceof Error?$.message:String($)}function U0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function kY($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,V)=>{Y=setTimeout(()=>V(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as yY}from"node:path";function xB($){return $.kind==="fresh"?null:$.source.provider}function _0($,Z,J){let Y=xB($);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"||!yY($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!yY(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 F1=()=>{};import{createHash as SB,randomUUID as wY}from"node:crypto";import{existsSync as i9,lstatSync as n9,mkdirSync as y8,readFileSync as vY,readdirSync as bB,realpathSync as W2,rmSync as CB,symlinkSync as kB,writeFileSync as yB}from"node:fs";import{homedir as wB}from"node:os";import{isAbsolute as vB,join as S$,relative as fB,resolve as hB,sep as IB}from"node:path";class fY{defaultHome;root;stateFile;constructor($=hB(process.env.CODEX_HOME||S$(wB(),".codex")),Z=bJ,J=CJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!i9(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(vY(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!==c&&!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:c,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(c);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(c);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:wY(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),s(this.stateFile,Z),Y}remove($){let Z=this.get($);if($===c)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(o9($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(r9($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Y=this.home($),Q;try{Q=n9(Y)}catch(H){if(H.code!=="ENOENT")throw H}if(Q){if(Q.isSymbolicLink()||!Q.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(i9(this.defaultHome)){let H=fB(W2(Y),W2(this.defaultHome));if(!H||!vB(H)&&H!==".."&&!H.startsWith(`..${IB}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{CB(Y,{recursive:!0})}catch(H){throw Error(`账号文件删除失败,账号记录已保留;${H}`)}}J.accounts=J.accounts.filter((H)=>H.id!==$);let V=0;for(let[H,X]of Object.entries(J.selections)){if(X!==$)continue;delete J.selections[H],V++}try{s(this.stateFile,J)}catch(H){throw Error(`账号文件已移除,但账号记录保存失败;请重试 codex-account-delete ${Z.name};${H}`)}return{account:Z,clearedSelections:V}}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:c}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],s(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),s(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==c){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:wY()}),s(this.stateFile,J)}}home($=c){return $===c?this.defaultHome:S$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===c)return Z;let J;try{J=n9(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(y8(Z,{recursive:!0,mode:448}),y8(this.defaultHome,{recursive:!0,mode:448}),W2(Z)===W2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=n9(S$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{yB(S$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of gB){let H=S$(this.defaultHome,V);y8(H,{recursive:!0,mode:448}),this.link(H,S$(Z,V),!0)}let Q=new Set([...mB,...bB(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Q){let H=S$(this.defaultHome,V);if(i9(H))this.link(H,S$(Z,V),!1)}return Z}link($,Z,J){let Y;try{Y=n9(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||W2(Z)!==W2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}kB($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&o9($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Q};if($!==c){V.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 V[H]}return V}cliArgs($){return this.get($),$===c?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=S$(this.home($),"auth.json");if(!i9(Z))return null;let Y=JSON.parse(vY(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 V=JSON.parse(Buffer.from(Q,"base64url").toString("utf8"));if(typeof V.sub!=="string"||!V.sub)return null;return SB("sha256").update(JSON.stringify([Y.account_id,V.sub])).digest("hex")}}function d$($,Z,J=!0){if(hY.set($,Z),!a9.has($))$.once("exit",()=>a9.delete($));a9.set($,{id:Z,ownsNativeProcess:J})}function r9($,Z=!1){return[...a9].some(([J,Y])=>Y.id===$&&(Y.ownsNativeProcess||Z)&&J.isAlive())}function o9($){return B4.has($)}function IY($){if(B4.has($))throw Error("该账号已有登录任务");if(r9($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return B4.set($,Z),()=>{if(B4.get($)===Z)B4.delete($)}}function o0($){return $?hY.get($)??c:c}var c="default",gB,mB,k,hY,a9,B4;var g0=T(()=>{H0();f0();gB=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],mB=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];k=new fY,hY=new WeakMap,a9=new Map;B4=new Map});function w8($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function pB($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function _4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:w8($.subscriptionType,J.fiveHour)}}function v8($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=_4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function f8($,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 V=pB($.subscriptionType);if(V===null)return{...Q,reason:`未知周额度套餐:${$.subscriptionType??"MISS"}`};if(Q.shares=V,Y==="ultra"&&$.subscriptionType==="plus")return{...Q,state:"excluded",reason:"Ultra 自动选择不使用 Plus"};let H=_4($,Z),X=[H.fiveHour,H.weekly].filter((q)=>q!==null),z=X.filter((q)=>q.percent!==null&&q.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||H.rateLimitReachedType||H.spendControlReached===!0){let q=z.map((P)=>P.resetsAt?.getTime()).filter((P)=>P!=null&&Number.isFinite(P)&&P>J);return{...Q,state:"exhausted",reason:"额度耗尽",...q.length===z.length&&q.length?{retryAt:Math.max(...q)}:{}}}if(X.some((q)=>q.percent===null||!Number.isFinite(q.percent)||q.percent<0))return{...Q,reason:"额度百分比 MISS"};let W=H.weekly;if(!W||W.percent===null)return{...Q,reason:"周额度 MISS"};let G=W.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Q,reason:"周重置时间 MISS 或已过期"};let B=V*(100-W.percent)/100,_=(G-J)/3600000,j=B/_;if(Y==="ultra"&&B<0.5)return{...Q,state:"waiting",remaining:B,hours:_,weeklyScore:j,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:G};if($.subscriptionType==="plus"){let q=H.fiveHour,P=0.15*(100-q.percent)/100,D=q.unreportedFull?5:((q.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(D)||D<=0)return{...Q,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:B,hours:_,weeklyScore:j,fiveHourRemaining:P,fiveHourHours:D,availableNow:Math.min(B,P),score:Math.min(j,P/D)}}return{state:"ready",shares:V,remaining:B,hours:_,weeklyScore:j,availableNow:B,score:j}}function s9($){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 cB,existsSync as uB,mkdirSync as lB,openSync as dB,readdirSync as iB,readSync as nB,statSync as e9,writeFileSync as aB}from"node:fs";import{homedir as h8}from"node:os";import{delimiter as gY,isAbsolute as mY,join as i$}from"node:path";import{EventEmitter as oB}from"node:events";import{StringDecoder as pY}from"node:string_decoder";import{spawn as rB}from"cross-spawn";function j4(){return Q4("codex","codex")}function sB(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([i$(h8(),".local","npm-global","bin"),i$(h8(),".local","bin"),i$(h8(),".bun","bin"),...(process.env.PATH??"").split(gY),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(gY)}function uY($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function Q_($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function V_($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function r0($){return typeof $==="string"&&m8.includes($)}function H_($){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(!r0(Q)||Z.has(Q))continue;Z.add(Q);let V=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:V})}return J}function I8($,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:g8($)}}return null}function X_($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function g8($){return{status:$.status,revisedPrompt:X_($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function lY($){if(!$||!uB(cY))return null;let Z=null,J=[cY];while(J.length){let Y=J.pop(),Q;try{Q=iB(Y,{withFileTypes:!0})}catch(V){K(`codex-process: cannot scan Codex session dir ${Y}: ${V instanceof Error?V.message:V}`);continue}for(let V of Q){let H=i$(Y,V.name);if(V.isDirectory()){J.push(H);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let X=e9(H).mtimeMs;if(!Z||X>Z.mtimeMs)Z={path:H,mtimeMs:X}}catch(X){K(`codex-process: cannot stat Codex rollout ${H}: ${X instanceof Error?X.message:X}`)}}}return Z?.path??null}function aY($,Z,J=tB){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let V=z_($,Z,J);if(V)return V;if(Q.length>2048){let H=oY($);return K(`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 V=Q.savedPath??Q.saved_path??Q.path;if(typeof V==="string"&&V)return V;return JSON.stringify(Q,null,2)}return""}function z_($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=W_(Y);if(!Q)return null;let V=dY(Z??"unknown-thread"),H=dY(oY($)),X=i$(J,V),z=i$(X,`${H}.${Q.ext}`);try{return lB(X,{recursive:!0}),aB(z,Q.buffer),z}catch(W){return K(`codex-process: failed to write image generation result ${z}: ${W instanceof Error?W.message:W}`),null}}function oY($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function dY($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function W_($){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 V=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(V,"base64")}catch{return null}if(H.length<12)return null;let X=G_(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function G_($){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 iY($,Z,J){let Y=I8($,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:aY($,J),isError:$.status==="failed"}}return null}function t9($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return U0(Z)}function nY($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function B_($,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 z2(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 rY($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function __($){let Z=rY($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function j_($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let V=Q,H=typeof V?.status==="string"?V.status:"unknown";J.push(`${U0(Y)}: ${H}`)}return J.join(`
79
- `)}var cY,tB,eB=30000,$_=600000,Z_=5000,J_=60000,Y_="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",m8,L4="xhigh",G2,K2;var M1=T(()=>{C0();I();Y2();x8();d9();F1();X4();g0();x8();cY=i$(k.defaultHome,"sessions"),tB=i$(k.defaultHome,"generated_images");m8=["none","minimal","low","medium","high","xhigh","max","ultra"];G2=class G2 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"}};K2=class K2 extends oB{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 pY("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((V)=>{this.resolveExit=V}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=j4(),J=[...Q_($.allowDelegation!==!1),...k.cliArgs($.codexAccountId??c)];K(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:sB(),...v.codex.env,...$.hostEnv??{}},Q=k.env($.codexAccountId??c,$.transformEnv?$.transformEnv(Y):Y);this.proc=rB(Z,J,V_($.workDir,Q)),this.proc.stdout.on("data",(V)=>this.onStdout(V)),this.proc.stderr.on("data",(V)=>this.onStderr(V)),this.proc.stdin.on("error",(V)=>this.handleStdinError(V)),this.proc.on("exit",(V,H)=>this.handleChildExit(V,H)),this.proc.on("close",(V,H)=>this.handleChildClose(V,H)),this.proc.on("error",(V)=>this.handleChildProcessError(V)),d$(this,$.codexAccountId??c)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(K(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){K(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,K(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((V,H)=>Error(`codex app-server closed before ${H.method} response (id=${V})`)),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($){K(`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)K(`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(),K(`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:V||Z}}function H2($,Z=60){let{description:J,command:Y}=y8($);if(J)return J;return SB(Y).replace(/\s+/g," ").trim().slice(0,Z)}function SB($){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 bB($){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=kB(J[1]);return k8(Q||Z)}let Y=CB(Z);if(Y)return Y;return k8(Z)}function CB($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=yY(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 V=Q[1].toLowerCase();if(V==="-command"||V==="-c")return k8(yY(Q[2]));if(Y=Q[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function kB($){let Z=$.trim();if(Z.length<2)return Z;let J=l9[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 k8($){let Z=$.trim(),J=Z[0];if(!l9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!yB(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,X)=>` $(${X})`)}function yB($,Z){let J=l9[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 l9;var d9=N(()=>{l9={'"':'"',"'":"'","“":"”"}});function O($){return $ instanceof Error?$.message:String($)}function M0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function wY($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,V)=>{Y=setTimeout(()=>V(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as vY}from"node:path";function wB($){return $.kind==="fresh"?null:$.source.provider}function _0($,Z,J){let Y=wB($);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"||!vY($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!vY(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 F1=()=>{};import{createHash as vB,randomUUID as fY}from"node:crypto";import{existsSync as i9,lstatSync as n9,mkdirSync as w8,readFileSync as hY,readdirSync as fB,realpathSync as X2,rmSync as hB,symlinkSync as IB,writeFileSync as gB}from"node:fs";import{homedir as mB}from"node:os";import{isAbsolute as pB,join as S$,relative as cB,resolve as uB,sep as lB}from"node:path";class IY{defaultHome;root;stateFile;constructor($=uB(process.env.CODEX_HOME||S$(mB(),".codex")),Z=kJ,J=yJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!i9(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(hY(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!==c&&!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:c,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(c);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(c);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:fY(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),s(this.stateFile,Z),Y}remove($){let Z=this.get($);if($===c)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(o9($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(r9($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Y=this.home($),Q;try{Q=n9(Y)}catch(H){if(H.code!=="ENOENT")throw H}if(Q){if(Q.isSymbolicLink()||!Q.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(i9(this.defaultHome)){let H=cB(X2(Y),X2(this.defaultHome));if(!H||!pB(H)&&H!==".."&&!H.startsWith(`..${lB}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{hB(Y,{recursive:!0})}catch(H){throw Error(`账号文件删除失败,账号记录已保留;${H}`)}}J.accounts=J.accounts.filter((H)=>H.id!==$);let V=0;for(let[H,X]of Object.entries(J.selections)){if(X!==$)continue;delete J.selections[H],V++}try{s(this.stateFile,J)}catch(H){throw Error(`账号文件已移除,但账号记录保存失败;请重试 codex-account-delete ${Z.name};${H}`)}return{account:Z,clearedSelections:V}}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:c}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],s(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),s(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==c){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:fY()}),s(this.stateFile,J)}}home($=c){return $===c?this.defaultHome:S$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===c)return Z;let J;try{J=n9(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(w8(Z,{recursive:!0,mode:448}),w8(this.defaultHome,{recursive:!0,mode:448}),X2(Z)===X2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=n9(S$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{gB(S$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of dB){let H=S$(this.defaultHome,V);w8(H,{recursive:!0,mode:448}),this.link(H,S$(Z,V),!0)}let Q=new Set([...iB,...fB(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Q){let H=S$(this.defaultHome,V);if(i9(H))this.link(H,S$(Z,V),!1)}return Z}link($,Z,J){let Y;try{Y=n9(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||X2(Z)!==X2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}IB($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&o9($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Q};if($!==c){V.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 V[H]}return V}cliArgs($){return this.get($),$===c?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=S$(this.home($),"auth.json");if(!i9(Z))return null;let Y=JSON.parse(hY(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 V=JSON.parse(Buffer.from(Q,"base64url").toString("utf8"));if(typeof V.sub!=="string"||!V.sub)return null;return vB("sha256").update(JSON.stringify([Y.account_id,V.sub])).digest("hex")}}function l$($,Z,J=!0){if(gY.set($,Z),!a9.has($))$.once("exit",()=>a9.delete($));a9.set($,{id:Z,ownsNativeProcess:J})}function r9($,Z=!1){return[...a9].some(([J,Y])=>Y.id===$&&(Y.ownsNativeProcess||Z)&&J.isAlive())}function o9($){return K4.has($)}function mY($){if(K4.has($))throw Error("该账号已有登录任务");if(r9($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return K4.set($,Z),()=>{if(K4.get($)===Z)K4.delete($)}}function o0($){return $?gY.get($)??c:c}var c="default",dB,iB,k,gY,a9,K4;var g0=N(()=>{V0();f0();dB=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],iB=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];k=new IY,gY=new WeakMap,a9=new Map;K4=new Map});function v8($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function nB($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function B4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:v8($.subscriptionType,J.fiveHour)}}function f8($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=B4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function h8($,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 V=nB($.subscriptionType);if(V===null)return{...Q,reason:`未知周额度套餐:${$.subscriptionType??"MISS"}`};if(Q.shares=V,Y==="ultra"&&$.subscriptionType==="plus")return{...Q,state:"excluded",reason:"Ultra 自动选择不使用 Plus"};let H=B4($,Z),X=[H.fiveHour,H.weekly].filter((q)=>q!==null),z=X.filter((q)=>q.percent!==null&&q.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||H.rateLimitReachedType||H.spendControlReached===!0){let q=z.map((P)=>P.resetsAt?.getTime()).filter((P)=>P!=null&&Number.isFinite(P)&&P>J);return{...Q,state:"exhausted",reason:"额度耗尽",...q.length===z.length&&q.length?{retryAt:Math.max(...q)}:{}}}if(X.some((q)=>q.percent===null||!Number.isFinite(q.percent)||q.percent<0))return{...Q,reason:"额度百分比 MISS"};let W=H.weekly;if(!W||W.percent===null)return{...Q,reason:"周额度 MISS"};let G=W.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Q,reason:"周重置时间 MISS 或已过期"};let B=V*(100-W.percent)/100,_=(G-J)/3600000,j=B/_;if(Y==="ultra"&&B<0.5)return{...Q,state:"waiting",remaining:B,hours:_,weeklyScore:j,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:G};if($.subscriptionType==="plus"){let q=H.fiveHour,P=0.15*(100-q.percent)/100,D=q.unreportedFull?5:((q.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(D)||D<=0)return{...Q,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:B,hours:_,weeklyScore:j,fiveHourRemaining:P,fiveHourHours:D,availableNow:Math.min(B,P),score:Math.min(j,P/D)}}return{state:"ready",shares:V,remaining:B,hours:_,weeklyScore:j,availableNow:B,score:j}}function s9($){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 aB,existsSync as oB,mkdirSync as rB,openSync as sB,readdirSync as tB,readSync as eB,statSync as e9,writeFileSync as $_}from"node:fs";import{homedir as I8}from"node:os";import{delimiter as pY,isAbsolute as cY,join as d$}from"node:path";import{EventEmitter as Z_}from"node:events";import{StringDecoder as uY}from"node:string_decoder";import{spawn as J_}from"cross-spawn";function _4(){return Y4("codex","codex")}function Y_(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([d$(I8(),".local","npm-global","bin"),d$(I8(),".local","bin"),d$(I8(),".bun","bin"),...(process.env.PATH??"").split(pY),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(pY)}function dY($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function G_($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function K_($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function r0($){return typeof $==="string"&&p8.includes($)}function B_($){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(!r0(Q)||Z.has(Q))continue;Z.add(Q);let V=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:V})}return J}function g8($,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:m8($)}}return null}function __($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function m8($){return{status:$.status,revisedPrompt:__($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function iY($){if(!$||!oB(lY))return null;let Z=null,J=[lY];while(J.length){let Y=J.pop(),Q;try{Q=tB(Y,{withFileTypes:!0})}catch(V){K(`codex-process: cannot scan Codex session dir ${Y}: ${V instanceof Error?V.message:V}`);continue}for(let V of Q){let H=d$(Y,V.name);if(V.isDirectory()){J.push(H);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let X=e9(H).mtimeMs;if(!Z||X>Z.mtimeMs)Z={path:H,mtimeMs:X}}catch(X){K(`codex-process: cannot stat Codex rollout ${H}: ${X instanceof Error?X.message:X}`)}}}return Z?.path??null}function rY($,Z,J=Q_){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let V=j_($,Z,J);if(V)return V;if(Q.length>2048){let H=sY($);return K(`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 V=Q.savedPath??Q.saved_path??Q.path;if(typeof V==="string"&&V)return V;return JSON.stringify(Q,null,2)}return""}function j_($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=L_(Y);if(!Q)return null;let V=nY(Z??"unknown-thread"),H=nY(sY($)),X=d$(J,V),z=d$(X,`${H}.${Q.ext}`);try{return rB(X,{recursive:!0}),$_(z,Q.buffer),z}catch(W){return K(`codex-process: failed to write image generation result ${z}: ${W instanceof Error?W.message:W}`),null}}function sY($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function nY($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function L_($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=P_(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 V=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(V,"base64")}catch{return null}if(H.length<12)return null;let X=q_(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function q_($){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 P_($){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=g8($,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:rY($,J),isError:$.status==="failed"}}return null}function t9($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return M0(Z)}function oY($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function D_($,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 H2(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 tY($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function F_($){let Z=tY($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function U_($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let V=Q,H=typeof V?.status==="string"?V.status:"unknown";J.push(`${M0(Y)}: ${H}`)}return J.join(`
79
+ `)}var lY,Q_,V_=30000,H_=600000,X_=5000,z_=60000,W_="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",p8,j4="xhigh",z2,W2;var U1=N(()=>{C0();h();Z2();S8();d9();F1();H4();g0();S8();lY=d$(k.defaultHome,"sessions"),Q_=d$(k.defaultHome,"generated_images");p8=["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"}};W2=class W2 extends Z_{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 uY("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((V)=>{this.resolveExit=V}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=_4(),J=[...G_($.allowDelegation!==!1),...k.cliArgs($.codexAccountId??c)];K(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:Y_(),...v.codex.env,...$.hostEnv??{}},Q=k.env($.codexAccountId??c,$.transformEnv?$.transformEnv(Y):Y);this.proc=J_(Z,J,K_($.workDir,Q)),this.proc.stdout.on("data",(V)=>this.onStdout(V)),this.proc.stderr.on("data",(V)=>this.onStderr(V)),this.proc.stdin.on("error",(V)=>this.handleStdinError(V)),this.proc.on("exit",(V,H)=>this.handleChildExit(V,H)),this.proc.on("close",(V,H)=>this.handleChildClose(V,H)),this.proc.on("error",(V)=>this.handleChildProcessError(V)),l$(this,$.codexAccountId??c)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(K(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){K(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,K(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((V,H)=>Error(`codex app-server closed before ${H.method} response (id=${V})`)),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($){K(`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)K(`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(),K(`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(`
80
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){K(`codex-process: bad json: ${J.slice(0,200)} (${Q})`);continue}try{this.handleMessage(Y)}catch(Q){K(`codex-process: dispatch error: ${JSON.stringify(Y).slice(0,200)} (${Q})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
81
81
  `))}onStderr($){this.stderrBuf+=$.toString();let Z;while((Z=this.stderrBuf.indexOf(`
82
- `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())K(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())K(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){K(`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 G2(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=E8($);if(Z){let J=this.withSessionId(Z);T8(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}I0("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=N8($,Z);if(J){let Y=this.withSessionId(J);T8($,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(r0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=X2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else K("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=X2(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){I0("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){I0("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)){K(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),K(`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 I0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Y.status,H=Y.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let X=V==="failed"||!!H,z=V==="completed"&&!X&&!!Q;if(this.lastCompletedTurnId=z?Q:null,this.currentTurnId=null,V==="failed"&&Q&&uY(H?.message)&&this.scheduleCapacityRetry(H.message,Y_))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let W=X?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:W,is_error:X},this.emit("result",{subtype:W,is_error:X,...X&&typeof H?.message==="string"?{error:H.message}:{},...V==="failed"&&Q&&s9(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 K("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 I0("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":{K(`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":{K(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{K(`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}}I0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){I0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=I8(Z,this.opts.workDir);if(!J){I0("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){I0("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=iY(Z,this.opts.workDir,this.sessionId??void 0);if(!J){I0("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:g8(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)??U0(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"?I8($,this.opts.workDir):iY($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let V="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:B_(Q.name,Q.input,V)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=t9($.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=t9($.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=rY($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,t9(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:nY($.prompt),description:__($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:j_($),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 V=this.collabAgentNames.get($)??t9(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:V}),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:nY(J.prompt)};this.emit("bg_task_started",H);let X={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",X)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let V={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",V);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 pY("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=lY(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=e9($).size,K(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){K(`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??lY(this.sessionId);if(!$){K(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=e9($).size;if(Q<=this.rolloutReadOffset)return;let V=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let H=dB($,"r"),X=0;try{while(X<V){let z=nB(H,Z,X,V-X,this.rolloutReadOffset+X);if(z===0)break;X+=z}}finally{cB(H)}Z=Z.subarray(0,X),this.rolloutReadOffset+=X}catch(Q){K(`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 V;try{V=JSON.parse(Q)}catch(z){K(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let H=V?.payload,X=H?.type;if(X!=="image_generation_end"&&X!=="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=aY($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&mY(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:g8({...$,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((V)=>({label:V.label,description:V.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:I0("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 K(`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=eB){let Y=++this.requestCounter;return new Promise((Q,V)=>{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)),X={resolve:Q,reject:V,method:$,timeout:H};this.pending.set(Y,X),this.write({id:Y,method:$,params:Z},(z)=>{if(this.pending.get(Y)!==X)return;this.pending.delete(Y),clearTimeout(H),V(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(($)=>{K(`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 V=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(V!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${V??"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||!mY(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(r0(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;K(`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,K(`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,K(`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},$_))?.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=e9(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(_0($,"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())K(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())K(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){K(`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=x8($);if(Z){let J=this.withSessionId(Z);T8(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}I0("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=E8($,Z);if(J){let Y=this.withSessionId(J);T8($,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(r0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=V2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else K("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=V2(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){I0("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){I0("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)){K(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),K(`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 I0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Y.status,H=Y.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let X=V==="failed"||!!H,z=V==="completed"&&!X&&!!Q;if(this.lastCompletedTurnId=z?Q:null,this.currentTurnId=null,V==="failed"&&Q&&dY(H?.message)&&this.scheduleCapacityRetry(H.message,W_))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let W=X?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:W,is_error:X},this.emit("result",{subtype:W,is_error:X,...X&&typeof H?.message==="string"?{error:H.message}:{},...V==="failed"&&Q&&s9(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 K("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 I0("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":{K(`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":{K(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{K(`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}}I0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){I0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=g8(Z,this.opts.workDir);if(!J){I0("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){I0("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){I0("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:m8(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)??M0(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"?g8($,this.opts.workDir):aY($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let V="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:D_(Q.name,Q.input,V)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=t9($.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=t9($.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=tY($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,t9(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:oY($.prompt),description:F_($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:U_($),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 V=this.collabAgentNames.get($)??t9(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:V}),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:oY(J.prompt)};this.emit("bg_task_started",H);let X={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",X)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let V={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",V);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 uY("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=iY(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=e9($).size,K(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){K(`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??iY(this.sessionId);if(!$){K(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=e9($).size;if(Q<=this.rolloutReadOffset)return;let V=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let H=sB($,"r"),X=0;try{while(X<V){let z=eB(H,Z,X,V-X,this.rolloutReadOffset+X);if(z===0)break;X+=z}}finally{aB(H)}Z=Z.subarray(0,X),this.rolloutReadOffset+=X}catch(Q){K(`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 V;try{V=JSON.parse(Q)}catch(z){K(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let H=V?.payload,X=H?.type;if(X!=="image_generation_end"&&X!=="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=rY($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&cY(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:m8({...$,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((V)=>({label:V.label,description:V.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:I0("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 K(`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=V_){let Y=++this.requestCounter;return new Promise((Q,V)=>{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)),X={resolve:Q,reject:V,method:$,timeout:H};this.pending.set(Y,X),this.write({id:Y,method:$,params:Z},(z)=>{if(this.pending.get(Y)!==X)return;this.pending.delete(Y),clearTimeout(H),V(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(($)=>{K(`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 V=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(V!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${V??"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||!cY(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(r0(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;K(`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,K(`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,K(`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},H_))?.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=e9(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(_0($,"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(" ")+`
85
85
 
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:H_(Y.supportedReasoningEfforts),defaultReasoningEffort:r0(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 V of Y.data){if(typeof V?.id!=="string"||!V.id||typeof V.preview!=="string"||typeof V.updatedAt!=="number"||!Number.isFinite(V.updatedAt)||typeof V.cwd!=="string"||V.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof V.status==="string"?V.status:typeof V.status?.type==="string"?V.status.type:void 0;if(Q2("codex",V.id))continue;$.push({provider:"codex",sessionId:V.id,cwd:V.cwd,preview:V.preview,ts:V.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){K("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)){K(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(K(`codex-process: turn/start failed: ${J}`),$ instanceof G2&&$.method==="turn/start"&&uY($.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 G2&&$.method==="turn/start"&&Z.inputText!==void 0&&(s9($.serverData)||s9({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 V=Y??this.turnStartOwner;if(V?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===V)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let X=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,...X?{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)){K(`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)=>K(`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(Z_*2**Math.min(J-1,4),J_),Q=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=V,K(`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={...V,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let X=this.beginTurnStart(Z);this.startTurn(Z,X).catch((z)=>this.failTurnStart(z,X))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){K(`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 V=J?.updatedInput?.answers??{},H={};for(let X of Y.params?.questions??[]){let z=V[X.question]??V[X.id];if(z!==void 0)H[X.id]={answers:[String(z)]}}this.respond($,{answers:H});return}default:I0("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,K(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(K(`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 K(`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=(V)=>{if(J)return;J=!0,clearTimeout(Q),Z(V)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function L_($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function p8($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let X=J.exec($);if(!X)break;let z=X[1],W=new RegExp(`^(?: {0,3})${L_(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");W.lastIndex=X.index+X[0].length;let G=W.exec($),B=G?G.index+G[0].length:$.length;Z.push({start:X.index,end:B}),Y=B}let Q=[...Z],V=[],H=0;for(let X of Z){if(H<X.start)V.push({start:H,end:X.start});H=X.end}if(H<$.length)V.push({start:H,end:$.length});for(let X of V){let z=$.slice(X.start,X.end),W=/(`+)[^\n]*?\1/g,G;while((G=W.exec(z))!==null)Q.push({start:X.start+G.index,end:X.start+G.index+G[0].length})}return Q.sort((X,z)=>X.start-z.start)}function c8($,Z){if(!$)return $;let J=p8($);if(!J.length)return Z($);let Y="",Q=0;for(let V of J){if(V.start>Q)Y+=Z($.slice(Q,V.start));Y+=$.slice(V.start,V.end),Q=Math.max(Q,V.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function q_($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function sY($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let V=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${V})`:`\uD83D\uDDBC️ ${V}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function n$($){if(Array.isArray($))return $.map((Y)=>n$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=n$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=u8(Z.content);return J}function e($){return c8($,(Z)=>P_(sY(q_(Z))))}function P_($){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:B_(Y.supportedReasoningEfforts),defaultReasoningEffort:r0(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 V of Y.data){if(typeof V?.id!=="string"||!V.id||typeof V.preview!=="string"||typeof V.updatedAt!=="number"||!Number.isFinite(V.updatedAt)||typeof V.cwd!=="string"||V.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof V.status==="string"?V.status:typeof V.status?.type==="string"?V.status.type:void 0;if(J2("codex",V.id))continue;$.push({provider:"codex",sessionId:V.id,cwd:V.cwd,preview:V.preview,ts:V.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){K("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)){K(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(K(`codex-process: turn/start failed: ${J}`),$ instanceof z2&&$.method==="turn/start"&&dY($.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&&(s9($.serverData)||s9({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 V=Y??this.turnStartOwner;if(V?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===V)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let X=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,...X?{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)){K(`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)=>K(`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(X_*2**Math.min(J-1,4),z_),Q=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=V,K(`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={...V,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let X=this.beginTurnStart(Z);this.startTurn(Z,X).catch((z)=>this.failTurnStart(z,X))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){K(`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 V=J?.updatedInput?.answers??{},H={};for(let X of Y.params?.questions??[]){let z=V[X.question]??V[X.id];if(z!==void 0)H[X.id]={answers:[String(z)]}}this.respond($,{answers:H});return}default:I0("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,K(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(K(`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 K(`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=(V)=>{if(J)return;J=!0,clearTimeout(Q),Z(V)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function M_($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function c8($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let X=J.exec($);if(!X)break;let z=X[1],W=new RegExp(`^(?: {0,3})${M_(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");W.lastIndex=X.index+X[0].length;let G=W.exec($),B=G?G.index+G[0].length:$.length;Z.push({start:X.index,end:B}),Y=B}let Q=[...Z],V=[],H=0;for(let X of Z){if(H<X.start)V.push({start:H,end:X.start});H=X.end}if(H<$.length)V.push({start:H,end:$.length});for(let X of V){let z=$.slice(X.start,X.end),W=/(`+)[^\n]*?\1/g,G;while((G=W.exec(z))!==null)Q.push({start:X.start+G.index,end:X.start+G.index+G[0].length})}return Q.sort((X,z)=>X.start-z.start)}function u8($,Z){if(!$)return $;let J=c8($);if(!J.length)return Z($);let Y="",Q=0;for(let V of J){if(V.start>Q)Y+=Z($.slice(Q,V.start));Y+=$.slice(V.start,V.end),Q=Math.max(Q,V.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function A_($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function eY($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let V=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${V})`:`\uD83D\uDDBC️ ${V}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function i$($){if(Array.isArray($))return $.map((Y)=>i$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=i$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=l8(Z.content);return J}function e($){return u8($,(Z)=>O_(eY(A_(Z))))}function O_($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
87
87
  \`\`\`
88
88
  ${J.trim()}
89
89
  \`\`\`
@@ -91,186 +91,186 @@ ${J.trim()}
91
91
  \`\`\`
92
92
  ${J.trim()}
93
93
  \`\`\`
94
- `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function u8($){return c8($,sY)}var R;var k0=T(()=>{R={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_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 G0($,Z="nearest"){if(!Number.isFinite($)||$<0)return"MISS";let[J,Y]=$>=3600?[$/3600,"h"]:$>=60?[$/60,"m"]:[$,"s"];return`${Z==="down"?Math.floor(J*10)/10:Number(J.toFixed(1))}${Y}`}function tY($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function D_($,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 eY($){return $==="workflow"||$==="monitor"}function s0($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function U1($){return $.some((Z)=>!s0(Z))}function i8($,Z,J=Date.now()){let Y=D_(Z.task_type,Z.subagent_type),Q=$.active.some((X)=>X.id===Z.task_id),V=$.pending.some((X)=>X.id===Z.task_id);if(Q||V){let X=(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?X(z):z):$.active,pending:V?$.pending.map((z)=>z.id===Z.task_id?X(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:[],...eY(Y)?{isBackgrounded:!0}:{}};return eY(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function n8($,Z){let J=$.active.some((V)=>V.id===Z.task_id),Y=$.pending.some((V)=>V.id===Z.task_id);if(!J&&!Y)return $;let Q=(V)=>({...V,description:Z.description??V.description,subagentType:Z.subagent_type??V.subagentType,usage:Z.usage??V.usage,lastToolName:Z.last_tool_name??V.lastToolName,summary:Z.summary??V.summary,status:V.status==="pending"?"running":V.status});return{active:J?$.active.map((V)=>V.id===Z.task_id?Q(V):V):$.active,pending:Y?$.pending.map((V)=>V.id===Z.task_id?Q(V):V):$.pending}}function a8($,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],X={...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,X],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),V=J>=0;if(Q||V){let H=(X)=>({...X,status:Y.status??X.status,description:Y.description??X.description,error:Y.error??X.error,isBackgrounded:Y.is_backgrounded??X.isBackgrounded,endTime:Y.end_time??X.endTime});return{active:Q?$.active.map((X)=>X.id===Z.task_id?H(X):X):$.active,pending:V?$.pending.map((X)=>X.id===Z.task_id?H(X):X):$.pending}}return $}function o8($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function r8($,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 $3($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>F_){J=Y+1;break}return J===0?$:$.slice(J)}function M_($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return z2(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 U_($,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 s8($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!H)return $;let X=(z)=>z.map((W)=>W.toolUseId===Z?{...W,steps:$3([...W.steps,{toolUseId:J,tool:Y,brief:`${Y} ${M_(Y,Q)}`.trim()}])}:W);return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function t8($,Z,J,Y,Q,V){let H=$.active.some((W)=>W.id===Z),X=$.pending.some((W)=>W.id===Z);if(!H&&!X)return $;let z=(W)=>W.map((G)=>{if(G.id!==Z)return G;if(Q==="started")return{...G,steps:$3([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()}])};let B=!1,_=G.steps.map((j)=>{if(B||j.toolUseId!==J)return j;return B=!0,{...j,brief:V?`${j.brief} ${V}`:j.brief}});if(!B&&V)_.push({toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()});return{...G,steps:$3(_)}});return{active:H?z($.active):$.active,pending:X?z($.pending):$.pending}}function e8($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!H)return $;let X=(z)=>z.map((W)=>{if(W.toolUseId!==Z)return W;let G=!1,B=W.steps.map((_)=>{if(G||_.toolUseId!==J)return _;return G=!0,{..._,brief:`${_.brief} → ${U_(Y,Q)}`}});return{...W,steps:$3(B)}});return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function JQ($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of R_)if(Z<V.limit)return{label:V.label,nextDelayMs:V.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${G0((Y+1)*600,"down")}+`,nextDelayMs:Q-Z}}function a$($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=l8){let Y=Math.floor((J-l8)/$Q),Q=l8+(Y+1)*$Q;return{label:`${G0((10+Y*5)*60,"down")}+`,nextDelayMs:Q-J}}return{label:G0(Math.floor(J/1000)),nextDelayMs:ZQ}}return JQ($)}function T_($){return $.subagentType??$.workflowName??O_[$.type]}function d8($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function N_($,Z,J="bucket"){let Y=(Q)=>a$(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`✅ 用时 ${G0(d8($)/1000)}`;case"failed":return`❌ 失败 ${G0(d8($)/1000)}`;case"killed":return`\uD83D\uDC80 已终止 ${G0(d8($)/1000)}`}}function YQ($){let Z=$.filter((Y)=>!s0(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function Z3($){return`\uD83E\uDDED 后台任务 · ${YQ($)}`}function E_($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(s0($)&&$.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 B2($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:q4.panel($.id),header:{title:{tag:"plain_text",content:`${A_[$.type]} ${T_($)} · ${$.description||"(无描述)"} — ${N_($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:q4.body($.id),content:E_($)}]}}function $7($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:Z3($)}},body:{elements:$.map((Y)=>B2(Y,Z,J))}}}function J3($,Z=Date.now(),J="bucket"){let Y=$.filter(s0);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>B2(Q,Z,J))}}}function Z7(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var q4,F_=1000,A_,O_,R_,ZQ=1000,l8=600000,$Q=300000;var J7=T(()=>{k0();d9();q4={panel:($)=>`bg_${tY($)}`,body:($)=>`bgb_${tY($)}`};A_={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},O_={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"},R_=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as x_}from"node:events";import{join as S_,isAbsolute as b_,extname as C_,basename as k_}from"node:path";import{readFile as y_}from"node:fs/promises";function w_($){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 Y3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),Y7,Q7;var QQ=T(()=>{D0();F1();W4();I();Y7={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};Q7=class Q7 extends x_{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=Y3();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"};_0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new m9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:S_($.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(Y7).find((Y)=>Y7[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)=>!b_(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((V)=>`[file: ${V}]`)].join(`
97
- `)}],Y=new Set([...Z,...Array.from($.matchAll(/\[file: ([^\]\r\n]+)\]/g),(V)=>V[1])]),Q=new Set([".png",".jpg",".jpeg",".webp",".gif"]);for(let V of Y){if(!Q.has(C_(V).toLowerCase()))continue;let H=await y_(V);J.push({type:"image",mediaType:w_(H),name:k_(V),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 V=J?.updatedInput?.answers,H=Z==="allow"?Q.map((X)=>{let z=V?.[X.question];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${X.question}`);let W=X.options?.find((G)=>G.label===z);return{id:X.id,selected:W?[z]:[],...W?{}:{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((X)=>this.fail(X))}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(!B0(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 D1}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={...Y3(),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 V=this.frames.get(Q);if(!V||V.revision+1!==Y.revision||V.nextIndex!==Y.index)throw Error("DSH assistant stream sequence mismatch");if(V.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}`);V.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=Y3(),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((V)=>V.model===this.lastModel)?.contextWindow??null;else if(Y.type==="tool/call"){let V=JSON.parse(Q.arguments),H=Y7[Q.name]??Q.name;if(["read","write","edit"].includes(Q.name)&&V.path)V.file_path=V.path;this.toolInputs.set(Q.callId,{name:H,input:V}),this.emit("tool_use",{id:Q.callId,name:H,input:V,parentToolUseId:J?Z.sessionId:null})}else if(Y.type==="tool/result"){let V=Q.message?.content?.[0];if(V?.type!=="tool-result"||typeof V.toolCallId!=="string")throw Error("invalid DSH tool result");this.emit("tool_result",{tool_use_id:V.toolCallId,content:V.content,is_error:V.isError===!0,parentToolUseId:J?Z.sessionId:null}),this.toolInputs.delete(V.toolCallId)}else if(Y.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Q.todos.map((V)=>({step:V.content,status:V.status==="in_progress"?"inProgress":V.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={...Y3(),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:K(`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 V=Y;J[V]=(J[V]??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 o$($){return $.startsWith("claude:")?$:`claude:${$}`}function V7($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(v.claude.models,Z))return v.claude.models[Z]?.model?.trim()||"opus";return Z}var VQ=T(()=>{C0()});import{existsSync as v_,readFileSync as f_}from"node:fs";function H7(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:yJ}function D4(){if(P4!==null)return P4;try{P4=v_(H7())?JSON.parse(f_(H7(),"utf8")):{}}catch($){K(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),P4={}}return P4??{}}function I_(){try{s(H7(),D4())}catch($){K(`context-window-observe: cache write MISS (${$?.message??$})`)}}function X7($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function HQ($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=X7($,Z),Q=D4()[Y];if(Q===J)return;D4()[Y]=J,I_(),K(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function Q3($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=D4()[X7($,Z)];return J!=null&&J<h_?Z:`${Z}[1m]`}function _2($,Z){return D4()[X7($,Z)]}var h_=1e6,P4=null;var F4=T(()=>{H0();I();f0()});var AQ={};T$(AQ,{toolsFromProfile:()=>MQ,settingSourcesFromProfile:()=>FQ,resolveClaudeExecutableConfig:()=>B7,resetClaudeContextWindowCache:()=>l_,readProjectMcpServers:()=>UQ,readLastCallUsageFromTranscript:()=>qQ,claudeTranscriptPath:()=>z3,claudeTranscriptDir:()=>X3,claudeManagedSkillOptions:()=>jQ,buildClaudeSpawnPath:()=>LQ,assertClaudeCodeAvailable:()=>K7,ClaudeAgentProcess:()=>W3,CLAUDE_PERMISSION_MODE:()=>DQ});import{existsSync as KQ,readFileSync as BQ}from"node:fs";import{homedir as H3}from"node:os";import{spawn as g_}from"cross-spawn";import{delimiter as XQ,join as A1}from"node:path";import{EventEmitter as m_}from"node:events";function jQ($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function p_($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function c_($){let Z=g_($.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 K7(){B7(),W8("claude","@anthropic-ai/claude-agent-sdk")}function B7($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?v.claude.bin:$.configuredBin;if(J){if(!($.exists??KQ)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&p_(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:c_,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function LQ(){if(process.platform==="win32")return process.env.PATH??"";let $=[A1(H3(),".local","npm-global","bin"),A1(H3(),".local","bin"),A1(H3(),".bun","bin"),...(process.env.PATH??"").split(XQ),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(XQ)}function u_($){let Z=X2($);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 zQ($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function X3($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||A1(H3(),".claude");return A1(J,"projects",Z)}function z3($,Z){return A1(X3($),`${Z}.jsonl`)}function qQ($){let Z;try{Z=BQ($,"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 V=JSON.parse(Q);if(V?.type==="assistant"&&V?.message?.usage){let H=V.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 WQ($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function l_(){W7.clear()}function d_($){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 V=Q;Z.input_tokens=(Z.input_tokens??0)+j2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+j2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+j2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+j2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+j2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let H=j2(V.contextWindow??V.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 V3($){return{...$}}function z7($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function i_($,Z){let J=$?{...$}:{},Y=(Q)=>{let V=Z[Q];if(typeof V!=="number"||!Number.isFinite(V))return;J[Q]=(J[Q]??0)+V};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 j2($){return typeof $==="number"&&Number.isFinite($)?$:0}function PQ($){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 n_($){let Z=PQ($);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 a_($){return`server_tool:${$}`}function o_($){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 r_($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function s_($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[l$];return{id:o$($.value),model:o$($.value),displayName:$.displayName||o$($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(l$)?l$:Z[0]}}function FQ($){if(!$?.settingSources)return[...GQ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...GQ]}function MQ($){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 UQ($){let Z=A1($,".mcp.json"),J;try{J=BQ(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")K(`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;K(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){K(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function t_($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>e_(Y)).filter((Y)=>Y!==null)}function e_($){let Z=$&&typeof $==="object"?$:{question:$},J=G7(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=$j(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 $j($){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=G7(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let V=G7(Y.description,Y.detail,Y.preview);Z.push(V?{label:Q,description:V}:{label:Q})}return Z}function G7(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var _Q,W7,DQ="default",GQ,W3;var M4=T(()=>{Y2();C0();I();D0();VQ();F4();_Q=class _Q{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($))}};W7=new Map;GQ=["project","local"];W3=class W3 extends m_{provider="claude";tokenSourceId;opts;input=new _Q;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?o$($.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 $=V7(this.opts.model),Z=this.opts.profile;if(Z)K(`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??FQ(Z),Y=jQ(J,this.opts.managedSkillPluginPath),Q=MQ(Z),V=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?UQ(this.opts.workDir):void 0;try{let X=B7(),{query:z}=await QY();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:LQ(),...v.claude.env,...this.opts.hostEnv??{}},G=this.opts.transformEnv?this.opts.transformEnv(W):W;if(this.opts.effort==="default")G.CLAUDE_CODE_EFFORT_LEVEL="unset";K(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${X.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}:{},...X.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:X.pathToClaudeCodeExecutable}:{},...X.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:X.spawnClaudeCodeProcess}:{},permissionMode:DQ,env:G,settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...V?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(B,_,j)=>this.canUseTool(B,_,j),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(B)=>{let _=B.trim();if(_)K(`claude-agent-process[stderr]: ${_}`)}}})}catch(X){let z=X instanceof Error?X:Error(String(X));this.emit("error",z),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){K("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));K(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>K(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){K(`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={}){K("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 K(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw K(`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(s_)}async setModelSettings($,Z){let J=V7($);if(!N0(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?o$($):"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",V),this.off("exit",H),this.off("error",X)},Q=()=>{if(J)return;J=!0,Y(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new D1)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},X=(z)=>{if(J)return;J=!0,Y(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Q),this.on("assistant_text",V),this.once("exit",H),this.once("error",X)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=t_(Z);if(Y.length===0)return K("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},V=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||V,X={request_id:V,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},z=new Promise((W)=>{let G=(_)=>{J.signal.removeEventListener("abort",B),W(_)},B=()=>{if(!this.pendingPermissions.delete(V))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",B,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:G,request:X})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",X),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){K(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}K(`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(),K(`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=(V)=>{if(J)return;J=!0,clearTimeout(Q),Z(V)},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:K(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=o$($.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":K(`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){K("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":K(`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){K("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){K(`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:K(`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=o$(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 V=o_(Q.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(r_(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,a_(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,n_(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())K(`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,V=PQ(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
105
- `):"",X=V||H;this.emitToolResultOnce(Y.tool_use_id,X,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=u_($.usage),J=$.modelUsage??$.model_usage,Y=d_(J);if(!Z&&!Y.usage)K(`claude-agent-process: result usage missing rootKeys=${z7($).join(",")||"-"} usageKeys=${z7($.usage).join(",")||"-"} modelUsageKeys=${z7(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=V3(Y.usage),this.lastTotalUsage=V3(Y.usage);else if(Z)this.cumulativeUsageFromResults=i_(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=V3(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?V3(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=WQ(this.opts.model,this.tokenSourceId);if(W7.set(X,Y.contextWindow),this.tokenSourceId)for(let[z,W]of Object.entries(J??{})){let G=W?.contextWindow;if(typeof G==="number"&&G>0)HQ(this.tokenSourceId,z,G)}}this.lastContextWindow=W7.get(WQ(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=z3(this.opts.workDir,this.sessionId??""),V=qQ(Q);if(this.lastContextTokens=zQ(V)??(KQ(Q)?zQ(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 NQ={};T$(NQ,{waitForTokenSourceModelRefresh:()=>M2,tokenSourceRuntimeModels:()=>q2,tokenSourceRuntimeModel:()=>L$,tokenSourceProcessRevision:()=>P2,tokenSourceFactories:()=>D2,setDefaultTokenSource:()=>j7,scrubDshEnv:()=>U4,scrubAnthropicEnv:()=>j$,resetTokenSourceRegistry:()=>L7,registerTokenSourceFactory:()=>E0,registerTokenSource:()=>_7,refreshAllTokenSourceModels:()=>O4,pendingTokenSourceModelRefresh:()=>F2,listTokenSourcesByAgent:()=>TQ,listTokenSources:()=>b$,listEnabledTokenSourcesByAgent:()=>K3,getTokenSourceForAccount:()=>X0,getTokenSource:()=>q$});function j$($){let Z={...$};for(let J of Zj)delete Z[J];return Z}function U4($){let Z=j$($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function q2($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function L$($,Z){let J=(Y)=>$.agent==="claude"?Y?.replace(/\[1m\]$/,""):Y;return q2($).find((Y)=>J(Y.model)===J(Z))}function P2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function E0($){OQ.set($.kind,$)}function D2(){return[...OQ.values()]}function _7($,Z){if(A4.set($.id,$),Z?.default||G3===null)G3=$.id}function q$($){return $?A4.get($):void 0}function X0($,Z="default"){let J=q$($);return J?.forAccount?J.forAccount(Z):J}function b$(){return[...A4.values()]}function TQ($){return b$().filter((Z)=>Z.agent===$)}function K3($){return TQ($).filter((Z)=>Z.enabled)}function j7($){if(A4.has($))G3=$}function L7(){A4.clear(),G3=null,RQ++}function O4(){let $=RQ;if(L2?.generation===$)return L2.promise;let Z=Promise.allSettled(b$().map(async(J)=>{await J.refreshModels(),K(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(L2?.promise===Z)L2=null});return L2={generation:$,promise:Z},Z}function F2(){return L2?.promise??null}async function M2(){let $;while($=F2())await $}var Zj,OQ,A4,G3=null,RQ=0,L2=null;var Q0=T(()=>{I();Zj=["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"];OQ=new Map;A4=new Map});import{spawn as Jj}from"cross-spawn";import{EventEmitter as Yj}from"node:events";import{StringDecoder as Qj}from"node:string_decoder";import{createHash as Vj}from"node:crypto";function P7($,Z){if(N4.set($,Z),Z.state==="ok")_3.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")_3.delete($)}function xQ($,Z,J=(Y)=>new O1({accountId:Y})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Y=B3.get($);if(Y)return Y.key===Z?Y.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Q=Promise.resolve().then(async()=>{let V=J($),H,X;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");U2($);let W;try{W=await L3(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}))}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{U2($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(W?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(W)};请用 codex-accounts 核对后再操作`);let G=P$.get($),B;try{B=D7(await L3(()=>V.request("account/rateLimits/read",{})),z.planType)}catch(_){B={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(P$.get($)!==G)B={state:"auth_failed"};else P7($,B);if(B.state!=="ok")K(`codex-reset: ${$} quota refresh failed: ${B.state==="network"?B.reason:B.state}`);H={outcome:W.outcome,usage:B}}catch(z){X=z,K(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let W=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(K(`codex-reset: ${$}: ${W}`),H)H.cleanupError=W;else throw AggregateError([X,z],`${String(X)};${W}`)}if(!H)throw X;return H}).finally(()=>{if(B3.get($)?.promise===Q)B3.delete($)});return B3.set($,{key:Z,promise:Q}),Q}function SQ($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Q),J(V)},(V)=>{clearTimeout(Q),Y(V)})})}function Hj($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function j3($){if(!$)return null;return{percent:Hj($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function Xj($){let Z=j3($?.primary),J=j3($?.secondary),Y=(V)=>V?.durationMins!=null&&V.durationMins>0&&V.durationMins<=720,Q=(V)=>V?.durationMins!=null&&V.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 zj($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,V]of J){let{fiveHour:H,weekly:X}=Xj(V);if(!H&&!X)continue;Y.push({limitId:Q,limitName:V?.limitName??null,fiveHour:H,weekly:X,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function Wj($){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 bQ($,Z=c){let J=Wj($),Y=N4.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],V=Q.filter((H)=>EQ(H.fiveHour,j3($?.primary))&&EQ(H.weekly,j3($?.secondary)));if(Q.length>0&&V.length===0)K(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${J})`);else if($?.limitId&&V.length===1&&V[0].limitId!==$.limitId)K(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${V[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function EQ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function Gj($){let Z=new O1({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await SQ(Z.request("account/read",{}),q7))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await L3(()=>Z.request("account/rateLimits/read",{}));return D7(Q,Y.planType)}catch(J){return K(`usage: codex app-server usage failed: ${J?.message??J}`),{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function D7($,Z){let{buckets:J,defaultLimitId:Y}=zj($),Q=J.find((H)=>H.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};let V=Z??$?.rateLimits?.planType??void 0;return Q.fiveHour=w8(V,Q.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:Vj("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 CQ($=c){return N4.get($)??null}function kQ($=c){return _3.get($)??null}function R1($=c){let Z=R4.get($);if(Z)return Z;let J=P$.get($)??0,Y=Promise.resolve().then(()=>Gj($)).catch((Q)=>{return K(`usage: ${$} fetch failed: ${Q}`),{state:"network",reason:String(Q)}}).then((Q)=>{if((P$.get($)??0)!==J)return{state:"auth_failed"};return P7($,Q),Q}).finally(()=>{if(R4.get($)===Y)R4.delete($)});return R4.set($,Y),Y}function q3($,Z=c){let J=T4.get(Z);if(J)return J;let Y=P$.get(Z)??0,Q=L3(()=>$("account/rateLimits/read",{})).then((V)=>{if((P$.get(Z)??0)!==Y)return null;let H=D7(V);if((P$.get(Z)??0)===Y)P7(Z,H);if(H.state!=="ok")K(`usage: refresh from connection: ${H.state==="network"?H.reason:H.state}`);return H}).catch((V)=>{if(K(`usage: refresh from connection failed: ${V?.message??V}`),(P$.get(Z)??0)===Y)N4.delete(Z);return null}).finally(()=>{if(T4.get(Z)===Q)T4.delete(Z)});return T4.set(Z,Q),Q}function U2($){P$.set($,(P$.get($)??0)+1),N4.delete($),_3.delete($),R4.delete($),T4.delete($)}async function L3($){let Z=[250,750];for(let J=0;;J++)try{return await SQ($(),q7)}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;K(`usage: rate limit request retry ${J+1}/${Z.length}: ${Q}`),await new Promise((H)=>setTimeout(H,Z[J]))}}var q7=1e4,N4,_3,R4,B3,O1,T4,P$;var C$=T(()=>{M1();I();C0();g0();N4=new Map,_3=new Map,R4=new Map;B3=new Map;O1=class O1 extends Yj{proc;buf="";decoder=new Qj("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??c;this.proc=Jj($.bin??j4(),["app-server","--listen","stdio://",...$.args??k.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??k.env(Z,{...process.env,...v.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)K(`usage[codex stderr]: ${Q}`)});let J=(Y)=>{if(!this.alive)return;this.alive=!1;for(let[Q,V]of this.pending)clearTimeout(V.timer),V.reject(Error(`${Y.message}; pending ${V.method} id=${Q}`));this.pending.clear(),this.resolveExit(),this.emit("exit"),this.emit("closed",Y)};this.proc.on("error",(Y)=>J(Error(`codex app-server spawn failed: ${Y.message}`))),this.proc.stdin.on("error",(Y)=>{K(`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}`))}),d$(this,Z)}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 l8($){return u8($,eY)}var R;var k0=N(()=>{R={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_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 G0($,Z="nearest"){if(!Number.isFinite($)||$<0)return"MISS";let[J,Y]=$>=3600?[$/3600,"h"]:$>=60?[$/60,"m"]:[$,"s"];return`${Z==="down"?Math.floor(J*10)/10:Number(J.toFixed(1))}${Y}`}function $Q($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function R_($,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 ZQ($){return $==="workflow"||$==="monitor"}function s0($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function M1($){return $.some((Z)=>!s0(Z))}function n8($,Z,J=Date.now()){let Y=R_(Z.task_type,Z.subagent_type),Q=$.active.some((X)=>X.id===Z.task_id),V=$.pending.some((X)=>X.id===Z.task_id);if(Q||V){let X=(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?X(z):z):$.active,pending:V?$.pending.map((z)=>z.id===Z.task_id?X(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:[],...ZQ(Y)?{isBackgrounded:!0}:{}};return ZQ(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function a8($,Z){let J=$.active.some((V)=>V.id===Z.task_id),Y=$.pending.some((V)=>V.id===Z.task_id);if(!J&&!Y)return $;let Q=(V)=>({...V,description:Z.description??V.description,subagentType:Z.subagent_type??V.subagentType,usage:Z.usage??V.usage,lastToolName:Z.last_tool_name??V.lastToolName,summary:Z.summary??V.summary,status:V.status==="pending"?"running":V.status});return{active:J?$.active.map((V)=>V.id===Z.task_id?Q(V):V):$.active,pending:Y?$.pending.map((V)=>V.id===Z.task_id?Q(V):V):$.pending}}function o8($,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],X={...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,X],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),V=J>=0;if(Q||V){let H=(X)=>({...X,status:Y.status??X.status,description:Y.description??X.description,error:Y.error??X.error,isBackgrounded:Y.is_backgrounded??X.isBackgrounded,endTime:Y.end_time??X.endTime});return{active:Q?$.active.map((X)=>X.id===Z.task_id?H(X):X):$.active,pending:V?$.pending.map((X)=>X.id===Z.task_id?H(X):X):$.pending}}return $}function r8($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function s8($,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 $3($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>N_){J=Y+1;break}return J===0?$:$.slice(J)}function T_($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return H2(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 E_($,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 t8($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!H)return $;let X=(z)=>z.map((W)=>W.toolUseId===Z?{...W,steps:$3([...W.steps,{toolUseId:J,tool:Y,brief:`${Y} ${T_(Y,Q)}`.trim()}])}:W);return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function e8($,Z,J,Y,Q,V){let H=$.active.some((W)=>W.id===Z),X=$.pending.some((W)=>W.id===Z);if(!H&&!X)return $;let z=(W)=>W.map((G)=>{if(G.id!==Z)return G;if(Q==="started")return{...G,steps:$3([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()}])};let B=!1,_=G.steps.map((j)=>{if(B||j.toolUseId!==J)return j;return B=!0,{...j,brief:V?`${j.brief} ${V}`:j.brief}});if(!B&&V)_.push({toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()});return{...G,steps:$3(_)}});return{active:H?z($.active):$.active,pending:X?z($.pending):$.pending}}function $7($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),H=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!H)return $;let X=(z)=>z.map((W)=>{if(W.toolUseId!==Z)return W;let G=!1,B=W.steps.map((_)=>{if(G||_.toolUseId!==J)return _;return G=!0,{..._,brief:`${_.brief} → ${E_(Y,Q)}`}});return{...W,steps:$3(B)}});return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function QQ($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of b_)if(Z<V.limit)return{label:V.label,nextDelayMs:V.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${G0((Y+1)*600,"down")}+`,nextDelayMs:Q-Z}}function n$($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=d8){let Y=Math.floor((J-d8)/JQ),Q=d8+(Y+1)*JQ;return{label:`${G0((10+Y*5)*60,"down")}+`,nextDelayMs:Q-J}}return{label:G0(Math.floor(J/1000)),nextDelayMs:YQ}}return QQ($)}function C_($){return $.subagentType??$.workflowName??S_[$.type]}function i8($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function k_($,Z,J="bucket"){let Y=(Q)=>n$(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`✅ 用时 ${G0(i8($)/1000)}`;case"failed":return`❌ 失败 ${G0(i8($)/1000)}`;case"killed":return`\uD83D\uDC80 已终止 ${G0(i8($)/1000)}`}}function VQ($){let Z=$.filter((Y)=>!s0(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function Z3($){return`\uD83E\uDDED 后台任务 · ${VQ($)}`}function y_($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(s0($)&&$.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 G2($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:L4.panel($.id),header:{title:{tag:"plain_text",content:`${x_[$.type]} ${C_($)} · ${$.description||"(无描述)"} — ${k_($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:L4.body($.id),content:y_($)}]}}function Z7($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:Z3($)}},body:{elements:$.map((Y)=>G2(Y,Z,J))}}}function J3($,Z=Date.now(),J="bucket"){let Y=$.filter(s0);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>G2(Q,Z,J))}}}function J7(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var L4,N_=1000,x_,S_,b_,YQ=1000,d8=600000,JQ=300000;var Y7=N(()=>{k0();d9();L4={panel:($)=>`bg_${$Q($)}`,body:($)=>`bgb_${$Q($)}`};x_={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},S_={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"},b_=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as w_}from"node:events";import{join as v_,isAbsolute as f_,extname as h_,basename as I_}from"node:path";import{readFile as g_}from"node:fs/promises";function m_($){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 Y3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),Q7,V7;var HQ=N(()=>{D0();F1();z4();h();Q7={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};V7=class V7 extends w_{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=Y3();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"};_0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new m9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:v_($.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(Q7).find((Y)=>Q7[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)=>!f_(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((V)=>`[file: ${V}]`)].join(`
97
+ `)}],Y=new Set([...Z,...Array.from($.matchAll(/\[file: ([^\]\r\n]+)\]/g),(V)=>V[1])]),Q=new Set([".png",".jpg",".jpeg",".webp",".gif"]);for(let V of Y){if(!Q.has(h_(V).toLowerCase()))continue;let H=await g_(V);J.push({type:"image",mediaType:m_(H),name:I_(V),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 V=J?.updatedInput?.answers,H=Z==="allow"?Q.map((X)=>{let z=V?.[X.question];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${X.question}`);let W=X.options?.find((G)=>G.label===z);return{id:X.id,selected:W?[z]:[],...W?{}:{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((X)=>this.fail(X))}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(!B0(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 D1}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={...Y3(),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 V=this.frames.get(Q);if(!V||V.revision+1!==Y.revision||V.nextIndex!==Y.index)throw Error("DSH assistant stream sequence mismatch");if(V.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}`);V.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=Y3(),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((V)=>V.model===this.lastModel)?.contextWindow??null;else if(Y.type==="tool/call"){let V=JSON.parse(Q.arguments),H=Q7[Q.name]??Q.name;if(["read","write","edit"].includes(Q.name)&&V.path)V.file_path=V.path;this.toolInputs.set(Q.callId,{name:H,input:V}),this.emit("tool_use",{id:Q.callId,name:H,input:V,parentToolUseId:J?Z.sessionId:null})}else if(Y.type==="tool/result"){let V=Q.message?.content?.[0];if(V?.type!=="tool-result"||typeof V.toolCallId!=="string")throw Error("invalid DSH tool result");this.emit("tool_result",{tool_use_id:V.toolCallId,content:V.content,is_error:V.isError===!0,parentToolUseId:J?Z.sessionId:null}),this.toolInputs.delete(V.toolCallId)}else if(Y.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Q.todos.map((V)=>({step:V.content,status:V.status==="in_progress"?"inProgress":V.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={...Y3(),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:K(`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 V=Y;J[V]=(J[V]??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 a$($){return $.startsWith("claude:")?$:`claude:${$}`}function H7($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(v.claude.models,Z))return v.claude.models[Z]?.model?.trim()||"opus";return Z}var XQ=N(()=>{C0()});import{existsSync as p_,readFileSync as c_}from"node:fs";function X7(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:vJ}function P4(){if(q4!==null)return q4;try{q4=p_(X7())?JSON.parse(c_(X7(),"utf8")):{}}catch($){K(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),q4={}}return q4??{}}function l_(){try{s(X7(),P4())}catch($){K(`context-window-observe: cache write MISS (${$?.message??$})`)}}function z7($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function zQ($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=z7($,Z),Q=P4()[Y];if(Q===J)return;P4()[Y]=J,l_(),K(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function Q3($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=P4()[z7($,Z)];return J!=null&&J<u_?Z:`${Z}[1m]`}function K2($,Z){return P4()[z7($,Z)]}var u_=1e6,q4=null;var D4=N(()=>{V0();h();f0()});var RQ={};N$(RQ,{toolsFromProfile:()=>AQ,settingSourcesFromProfile:()=>MQ,resolveClaudeExecutableConfig:()=>_7,resetClaudeContextWindowCache:()=>r_,readProjectMcpServers:()=>OQ,readLastCallUsageFromTranscript:()=>DQ,claudeTranscriptPath:()=>z3,claudeTranscriptDir:()=>X3,claudeManagedSkillOptions:()=>qQ,buildClaudeSpawnPath:()=>PQ,assertClaudeCodeAvailable:()=>B7,ClaudeAgentProcess:()=>W3,CLAUDE_PERMISSION_MODE:()=>UQ});import{existsSync as _Q,readFileSync as jQ}from"node:fs";import{homedir as H3}from"node:os";import{spawn as d_}from"cross-spawn";import{delimiter as WQ,join as A1}from"node:path";import{EventEmitter as i_}from"node:events";function qQ($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function n_($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function a_($){let Z=d_($.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 B7(){_7(),G8("claude","@anthropic-ai/claude-agent-sdk")}function _7($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?v.claude.bin:$.configuredBin;if(J){if(!($.exists??_Q)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&n_(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:a_,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function PQ(){if(process.platform==="win32")return process.env.PATH??"";let $=[A1(H3(),".local","npm-global","bin"),A1(H3(),".local","bin"),A1(H3(),".bun","bin"),...(process.env.PATH??"").split(WQ),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(WQ)}function o_($){let Z=V2($);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 GQ($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function X3($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||A1(H3(),".claude");return A1(J,"projects",Z)}function z3($,Z){return A1(X3($),`${Z}.jsonl`)}function DQ($){let Z;try{Z=jQ($,"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 V=JSON.parse(Q);if(V?.type==="assistant"&&V?.message?.usage){let H=V.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 KQ($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function r_(){G7.clear()}function s_($){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 V=Q;Z.input_tokens=(Z.input_tokens??0)+B2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+B2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+B2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+B2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+B2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let H=B2(V.contextWindow??V.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 V3($){return{...$}}function W7($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function t_($,Z){let J=$?{...$}:{},Y=(Q)=>{let V=Z[Q];if(typeof V!=="number"||!Number.isFinite(V))return;J[Q]=(J[Q]??0)+V};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 B2($){return typeof $==="number"&&Number.isFinite($)?$:0}function FQ($){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 e_($){let Z=FQ($);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 $j($){return`server_tool:${$}`}function Zj($){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 Jj($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function Yj($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[u$];return{id:a$($.value),model:a$($.value),displayName:$.displayName||a$($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(u$)?u$:Z[0]}}function MQ($){if(!$?.settingSources)return[...BQ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...BQ]}function AQ($){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 OQ($){let Z=A1($,".mcp.json"),J;try{J=jQ(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")K(`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;K(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){K(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function Qj($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>Vj(Y)).filter((Y)=>Y!==null)}function Vj($){let Z=$&&typeof $==="object"?$:{question:$},J=K7(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=Hj(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 Hj($){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=K7(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let V=K7(Y.description,Y.detail,Y.preview);Z.push(V?{label:Q,description:V}:{label:Q})}return Z}function K7(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var LQ,G7,UQ="default",BQ,W3;var F4=N(()=>{Z2();C0();h();D0();XQ();D4();LQ=class LQ{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($))}};G7=new Map;BQ=["project","local"];W3=class W3 extends i_{provider="claude";tokenSourceId;opts;input=new LQ;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?a$($.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 $=H7(this.opts.model),Z=this.opts.profile;if(Z)K(`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??MQ(Z),Y=qQ(J,this.opts.managedSkillPluginPath),Q=AQ(Z),V=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?OQ(this.opts.workDir):void 0;try{let X=_7(),{query:z}=await HY();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:PQ(),...v.claude.env,...this.opts.hostEnv??{}},G=this.opts.transformEnv?this.opts.transformEnv(W):W;if(this.opts.effort==="default")G.CLAUDE_CODE_EFFORT_LEVEL="unset";K(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${X.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}:{},...X.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:X.pathToClaudeCodeExecutable}:{},...X.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:X.spawnClaudeCodeProcess}:{},permissionMode:UQ,env:G,settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...V?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(B,_,j)=>this.canUseTool(B,_,j),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(B)=>{let _=B.trim();if(_)K(`claude-agent-process[stderr]: ${_}`)}}})}catch(X){let z=X instanceof Error?X:Error(String(X));this.emit("error",z),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){K("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));K(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>K(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){K(`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={}){K("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 K(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw K(`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(Yj)}async setModelSettings($,Z){let J=H7($);if(!T0(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?a$($):"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",V),this.off("exit",H),this.off("error",X)},Q=()=>{if(J)return;J=!0,Y(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new D1)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},X=(z)=>{if(J)return;J=!0,Y(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Q),this.on("assistant_text",V),this.once("exit",H),this.once("error",X)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=Qj(Z);if(Y.length===0)return K("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},V=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||V,X={request_id:V,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},z=new Promise((W)=>{let G=(_)=>{J.signal.removeEventListener("abort",B),W(_)},B=()=>{if(!this.pendingPermissions.delete(V))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",B,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:G,request:X})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",X),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){K(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}K(`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(),K(`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=(V)=>{if(J)return;J=!0,clearTimeout(Q),Z(V)},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:K(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=a$($.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":K(`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){K("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":K(`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){K("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){K(`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:K(`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=a$(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 V=Zj(Q.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(Jj(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,$j(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,e_(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())K(`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,V=FQ(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
105
+ `):"",X=V||H;this.emitToolResultOnce(Y.tool_use_id,X,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=o_($.usage),J=$.modelUsage??$.model_usage,Y=s_(J);if(!Z&&!Y.usage)K(`claude-agent-process: result usage missing rootKeys=${W7($).join(",")||"-"} usageKeys=${W7($.usage).join(",")||"-"} modelUsageKeys=${W7(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=V3(Y.usage),this.lastTotalUsage=V3(Y.usage);else if(Z)this.cumulativeUsageFromResults=t_(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=V3(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?V3(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=KQ(this.opts.model,this.tokenSourceId);if(G7.set(X,Y.contextWindow),this.tokenSourceId)for(let[z,W]of Object.entries(J??{})){let G=W?.contextWindow;if(typeof G==="number"&&G>0)zQ(this.tokenSourceId,z,G)}}this.lastContextWindow=G7.get(KQ(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=z3(this.opts.workDir,this.sessionId??""),V=DQ(Q);if(this.lastContextTokens=GQ(V)??(_Q(Q)?GQ(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 xQ={};N$(xQ,{waitForTokenSourceModelRefresh:()=>D2,tokenSourceRuntimeModels:()=>j2,tokenSourceRuntimeModel:()=>L$,tokenSourceProcessRevision:()=>L2,tokenSourceFactories:()=>q2,setDefaultTokenSource:()=>L7,scrubDshEnv:()=>U4,scrubAnthropicEnv:()=>j$,resetTokenSourceRegistry:()=>q7,registerTokenSourceFactory:()=>E0,registerTokenSource:()=>j7,refreshAllTokenSourceModels:()=>A4,pendingTokenSourceModelRefresh:()=>P2,listTokenSourcesByAgent:()=>EQ,listTokenSources:()=>b$,listEnabledTokenSourcesByAgent:()=>K3,getTokenSourceForAccount:()=>H0,getTokenSource:()=>q$});function j$($){let Z={...$};for(let J of Xj)delete Z[J];return Z}function U4($){let Z=j$($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function j2($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function L$($,Z){let J=(Y)=>$.agent==="claude"?Y?.replace(/\[1m\]$/,""):Y;return j2($).find((Y)=>J(Y.model)===J(Z))}function L2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function E0($){NQ.set($.kind,$)}function q2(){return[...NQ.values()]}function j7($,Z){if(M4.set($.id,$),Z?.default||G3===null)G3=$.id}function q$($){return $?M4.get($):void 0}function H0($,Z="default"){let J=q$($);return J?.forAccount?J.forAccount(Z):J}function b$(){return[...M4.values()]}function EQ($){return b$().filter((Z)=>Z.agent===$)}function K3($){return EQ($).filter((Z)=>Z.enabled)}function L7($){if(M4.has($))G3=$}function q7(){M4.clear(),G3=null,TQ++}function A4(){let $=TQ;if(_2?.generation===$)return _2.promise;let Z=Promise.allSettled(b$().map(async(J)=>{await J.refreshModels(),K(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(_2?.promise===Z)_2=null});return _2={generation:$,promise:Z},Z}function P2(){return _2?.promise??null}async function D2(){let $;while($=P2())await $}var Xj,NQ,M4,G3=null,TQ=0,_2=null;var Y0=N(()=>{h();Xj=["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"];NQ=new Map;M4=new Map});import{spawn as zj}from"cross-spawn";import{EventEmitter as Wj}from"node:events";import{StringDecoder as Gj}from"node:string_decoder";import{createHash as Kj}from"node:crypto";function D7($,Z){if(N4.set($,Z),Z.state==="ok")_3.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")_3.delete($)}function bQ($,Z,J=(Y)=>new O1({accountId:Y})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Y=B3.get($);if(Y)return Y.key===Z?Y.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Q=Promise.resolve().then(async()=>{let V=J($),H,X;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");F2($);let W;try{W=await L3(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}))}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{F2($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(W?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(W)};请用 codex-accounts 核对后再操作`);let G=P$.get($),B;try{B=F7(await L3(()=>V.request("account/rateLimits/read",{})),z.planType)}catch(_){B={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(P$.get($)!==G)B={state:"auth_failed"};else D7($,B);if(B.state!=="ok")K(`codex-reset: ${$} quota refresh failed: ${B.state==="network"?B.reason:B.state}`);H={outcome:W.outcome,usage:B}}catch(z){X=z,K(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let W=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(K(`codex-reset: ${$}: ${W}`),H)H.cleanupError=W;else throw AggregateError([X,z],`${String(X)};${W}`)}if(!H)throw X;return H}).finally(()=>{if(B3.get($)?.promise===Q)B3.delete($)});return B3.set($,{key:Z,promise:Q}),Q}function CQ($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Q),J(V)},(V)=>{clearTimeout(Q),Y(V)})})}function Bj($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function j3($){if(!$)return null;return{percent:Bj($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function _j($){let Z=j3($?.primary),J=j3($?.secondary),Y=(V)=>V?.durationMins!=null&&V.durationMins>0&&V.durationMins<=720,Q=(V)=>V?.durationMins!=null&&V.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 jj($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,V]of J){let{fiveHour:H,weekly:X}=_j(V);if(!H&&!X)continue;Y.push({limitId:Q,limitName:V?.limitName??null,fiveHour:H,weekly:X,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function Lj($){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 kQ($,Z=c){let J=Lj($),Y=N4.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],V=Q.filter((H)=>SQ(H.fiveHour,j3($?.primary))&&SQ(H.weekly,j3($?.secondary)));if(Q.length>0&&V.length===0)K(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${J})`);else if($?.limitId&&V.length===1&&V[0].limitId!==$.limitId)K(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${V[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function SQ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function qj($){let Z=new O1({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await CQ(Z.request("account/read",{}),P7))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await L3(()=>Z.request("account/rateLimits/read",{}));return F7(Q,Y.planType)}catch(J){return K(`usage: codex app-server usage failed: ${J?.message??J}`),{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function F7($,Z){let{buckets:J,defaultLimitId:Y}=jj($),Q=J.find((H)=>H.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};let V=Z??$?.rateLimits?.planType??void 0;return Q.fiveHour=v8(V,Q.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:Kj("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 yQ($=c){return N4.get($)??null}function wQ($=c){return _3.get($)??null}function R1($=c){let Z=O4.get($);if(Z)return Z;let J=P$.get($)??0,Y=Promise.resolve().then(()=>qj($)).catch((Q)=>{return K(`usage: ${$} fetch failed: ${Q}`),{state:"network",reason:String(Q)}}).then((Q)=>{if((P$.get($)??0)!==J)return{state:"auth_failed"};return D7($,Q),Q}).finally(()=>{if(O4.get($)===Y)O4.delete($)});return O4.set($,Y),Y}function q3($,Z=c){let J=R4.get(Z);if(J)return J;let Y=P$.get(Z)??0,Q=L3(()=>$("account/rateLimits/read",{})).then((V)=>{if((P$.get(Z)??0)!==Y)return null;let H=F7(V);if((P$.get(Z)??0)===Y)D7(Z,H);if(H.state!=="ok")K(`usage: refresh from connection: ${H.state==="network"?H.reason:H.state}`);return H}).catch((V)=>{if(K(`usage: refresh from connection failed: ${V?.message??V}`),(P$.get(Z)??0)===Y)N4.delete(Z);return null}).finally(()=>{if(R4.get(Z)===Q)R4.delete(Z)});return R4.set(Z,Q),Q}function F2($){P$.set($,(P$.get($)??0)+1),N4.delete($),_3.delete($),O4.delete($),R4.delete($)}async function L3($){let Z=[250,750];for(let J=0;;J++)try{return await CQ($(),P7)}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;K(`usage: rate limit request retry ${J+1}/${Z.length}: ${Q}`),await new Promise((H)=>setTimeout(H,Z[J]))}}var P7=1e4,N4,_3,O4,B3,O1,R4,P$;var C$=N(()=>{U1();h();C0();g0();N4=new Map,_3=new Map,O4=new Map;B3=new Map;O1=class O1 extends Wj{proc;buf="";decoder=new Gj("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??c;this.proc=zj($.bin??_4(),["app-server","--listen","stdio://",...$.args??k.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??k.env(Z,{...process.env,...v.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)K(`usage[codex stderr]: ${Q}`)});let J=(Y)=>{if(!this.alive)return;this.alive=!1;for(let[Q,V]of this.pending)clearTimeout(V.timer),V.reject(Error(`${Y.message}; pending ${V.method} id=${Q}`));this.pending.clear(),this.resolveExit(),this.emit("exit"),this.emit("closed",Y)};this.proc.on("error",(Y)=>J(Error(`codex app-server spawn failed: ${Y.message}`))),this.proc.stdin.on("error",(Y)=>{K(`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}`))}),l$(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
107
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 K(`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}`}})+`
108
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 V=this.pending.get(Y.id);if(!V)continue;if(this.pending.delete(Y.id),clearTimeout(V.timer),Y.error)V.reject(Error(JSON.stringify(Y.error)));else V.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"})+`
109
- `,(Y)=>Y?J(Y):Z())})}isAlive(){return this.alive}request($,Z,J=q7){let Y=this.nextId++;return new Promise((Q,V)=>{if(!this.alive){V(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;V(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:V,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
110
- `,(X)=>{if(!X)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 ${$}: ${X.message}`))})}catch(X){this.pending.delete(Y),clearTimeout(H),V(X instanceof Error?X:Error(String(X)))}})}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)}}};T4=new Map,P$=new Map});import{existsSync as Kj,readFileSync as Bj}from"node:fs";class yQ{deps;constructor($){this.deps=$}blocks(){if(!Kj(this.deps.stateFile))return[];let $=JSON.parse(Bj(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"?_4($.usage,Z):null,Y=["fiveHour","weekly"].flatMap((X)=>{let z=J?.[X];return z?[{kind:X,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Q=v8($.usage,Z),V=JSON.stringify([$.identity,Q]),H=this.blocks().filter((X)=>X.key!==V);H.push({key:V,identity:$.identity,meter:Q,windows:Y}),s(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(q)=>{let P,D=null,N=`record:${q.id}`;if(this.deps.pendingLogin(q.id))P={state:"network",reason:"正在登录"};else try{P=J?this.deps.cachedUsage(q.id):await this.deps.usage(q.id);let U=P?.state==="ok"?P.accountFingerprint??this.deps.identity(q.id):null;if(U)N=U;else if(P?.state==="ok")D="账号身份 MISS";if(P?.state==="ok"&&!D)D=await this.deps.compatible(q.id,Z.model,Z.effort)}catch(U){P={state:"network",reason:String(U)}}return{account:q,usage:P,identity:N,reason:D}}));Z.signal?.throwIfAborted();let Q=Z.failedAccountId&&Y.find((q)=>q.account.id===Z.failedAccountId);if(Q&&Q.usage?.state==="ok")this.block({account:Q.account,usage:Q.usage,identity:Q.identity,...f8(Q.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let V=this.blocks(),H=this.deps.now(),X=new Set,z=new Map,W=Y.map(({account:q,usage:P,identity:D,reason:N})=>{let U=f8(P??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(N)U={...U,state:"miss",score:null,reason:N};let A=z.get(D);if(z.set(D,A??q.name),A)U={...U,state:"miss",score:null,reason:`重复账号:${A}`};let M=P?.state==="ok"?v8(P,Z.model):null,S=V.find((C)=>(C.identity===D||C.identity===`record:${q.id}`)&&C.meter===M);if(S&&P?.state==="ok"&&U.state==="ready"){let C=_4(P,Z.model);if(!J&&S.windows.some((y)=>{let h=C[y.kind];return h&&h.percent!==null&&(y.percent!==null&&h.percent<y.percent||y.reset!==null&&y.reset<=H&&(h.resetsAt?.getTime()??0)>y.reset)}))X.add(S.key);else U={...U,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:q,usage:P,identity:D,...U,...A?{duplicateOf:A}:{}}});if(X.size)s(this.deps.stateFile,{version:1,blocks:V.filter((q)=>!X.has(q.key))});let G=W.filter((q)=>q.state==="ready");G.sort((q,P)=>P.score-q.score||(P.availableNow??0)-(q.availableNow??0)||q.account.id.localeCompare(P.account.id));let B=G[0]??null,_=W.filter((q)=>q.state==="exhausted"||q.state==="waiting"),j=_.length?Math.min(..._.map((q)=>q.retryAt??H+60000)):void 0;for(let q of W)K(`codex scheduler${J?" [cache]":""}: ${q.account.name} ${q.state} score=${q.score??"MISS"}${q.reason?` (${q.reason})`:""}`);return{selected:B,candidates:W,...j!==void 0?{retryAt:j}:{}}}}var P3;var F7=T(()=>{g0();C$();Q0();H0();f0();I();P3=new yQ({accounts:()=>k.list(),usage:R1,cachedUsage:kQ,identity:($)=>k.fingerprint($),pendingLogin:o9,now:Date.now,stateFile:kJ,compatible:async($,Z,J)=>{let Y=X0("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=L$(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as _j}from"node:events";function qj($,Z){return Z.throwIfAborted(),new Promise((J,Y)=>{let Q=()=>{clearTimeout(H),Z.removeEventListener("abort",V)},V=()=>{Q(),Y(Z.reason)},H=setTimeout(()=>{Q(),J()},$);Z.addEventListener("abort",V,{once:!0})})}var jj="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",Lj,M7=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),U7;var wQ=T(()=>{g0();F7();C$();I();Lj=["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"];U7=class U7 extends _j{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??M7()}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??P3}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},K(`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((X)=>`${X.account.name}:${X.reason??X.state}`).join(";");if(Y.retryAt===void 0)throw Error(`没有可用的 Codex 账号;${Q}`);let V=Math.max(1000,Math.min(60000,Y.retryAt-Date.now())),H=Y.candidates.filter((X)=>X.state==="miss"&&!X.duplicateOf).length;K(`codex account: waiting for quota: ${Q}`),this.notice(`暂无可用账号 · 自动等待恢复${H?` · ${H} 个 MISS`:""}`,V),this.resolveQuotaWait(),await(this.opts.wait??qj)(V,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:V,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=V,this.selected=Y.selected,this.revision=H,d$(this,Y.selected.account.id,!1),this.wire(V),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(),V.sendInitialize();let X=V.initializationPromise?.();if(!X)throw Error("Codex 初始化未提供确认事务");if(await X,this.lifetime.signal.throwIfAborted(),this.lastSession=V.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:V.sessionId});if(!this.recovery)this.drainInputs()}wire($){for(let Z of Lj)$.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 X=await q3(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),X?.state==="ok")this.selected={...this.selected,usage:X,identity:X.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 V=Q?{kind:"resume",source:{provider:"codex",sessionId:$.sessionId,cwd:this.opts.workDir}}:this.opts.launch;if(await $.kill(),$.isAlive())throw Error("旧 Codex 进程退出未确认,不能启动下一账号");for(let X of this.backgroundTasks)this.emit("bg_task_settled",{task_id:X,status:"failed",summary:"账号额度耗尽,原进程已退出;主任务换号后继续"});this.backgroundTasks.clear(),this.lifetime.signal.throwIfAborted(),await this.launch(V,void 0,J),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let H=Z.accepted?jj: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={...M7(),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={...M7(),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 E4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new U7({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(B,_,j,q,P)=>E4({...$,model:q,effort:P,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:B,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??c,J=X0($.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,V=P2(J,Q),H=!Y&&J&&L$(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 X=!Y&&J&&Q?J.resolveSpawnModel(Q):Q;if(Q&&!X)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Q}`);let z=J?(G)=>J.spawnEnv(G,X):void 0;if($.provider==="dsh"){if(!J||!X||!B0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new Q7({...$,model:X,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(K7(),!N0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new W3({workDir:$.workDir,model:X,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:V}}if($.effort!==void 0&&!r0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let W=new K2({workDir:$.workDir,model:X,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z});return d$(W,Z),{process:W,sourceRevision:V}}var A7=T(()=>{D0();QQ();M4();M1();Q0();g0();wQ()});function D3($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function A2($){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 O2($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(z)=>`&#${z.charCodeAt(0)};`),Y=typeof $.used==="number"&&typeof $.total==="number"?` · ${$.used}/${$.total}`:"",Q=$.percent;if(Q===null||!Number.isFinite(Q)||Q<0||Q>100)return[{tag:"markdown",content:`**${J} · MISS${Y}**`}];let V=Math.round(Q/100*6),H=Q>=100?"red":Q>=80?"orange":"green",X=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${A2($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Q)}%${Y}**
111
- <font color='${H}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${X}</font>`,text_size:"notation"}]}var fQ={};T$(fQ,{codexAccountSummary:()=>x4,codexAccountPanel:()=>S4,codexAccountCard:()=>V$,CODEX_ACCOUNTS_PAGE_SIZE:()=>F3});function r$($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function O7($){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 x4($){let[Z,J]=vQ[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function V$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:x4($)}},body:{elements:[S4($)]}}}function S4($){let[,,Z]=vQ[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(y0(["连接","授权","就绪"].map((Q,V)=>V===Y?`**${V+1} ${Q}**`:`${V<Y?"✓":V+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(O7([[m0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[y0(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),m0("登录账号,输入左侧验证码")]]))}if($.current)J.push(O7([[m0("当前使用"),y0(`**${r$($.current)}**`)],...$.selected&&$.selected!==$.current?[[m0("下次启动"),y0(`**${r$($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(y0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>r$(Y)).join(" · ")));if($.message)J.push(y0(r$($.message)));if($.resetUsage){let Y=$.resetUsage;if(J.push(y0(`**重置卡** ${Y.state==="ok"&&Y.resetCredits!=null?`${Y.resetCredits} 次可用`:"MISS"}`)),Y.state==="ok"){for(let[Q,V]of[[Y.fiveHour,"5h"],[Y.weekly,"周"]])if(Q)J.push(...O2(Q,V))}else J.push(y0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...Pj($));if($.phase==="accounts")J.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:"⌨️ Codex 命令"},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",elements:[y0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
112
- `)),m0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(m0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[y0(r$($.details))]});return{tag:"collapsible_panel",element_id:R.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:x4($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function Pj($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/F3)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[m0(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],V=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort((H,X)=>X.score-H.score||(X.availableNow??0)-(H.availableNow??0)||H.account.id.localeCompare(X.account.id));if($.scheduling)Q.push(m0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let H of Z.entries.slice((Y-1)*F3,Y*F3)){let X=[H.account.id===$.currentId?"使用中":"",H.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),z=H.usage,W=[];if(Q.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${H.account.name}${X.length?` · ${X.join(" · ")}`:""}`},background_color:H.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:W}),H.duplicateOf){W.push(m0(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}let G=$.scheduling?.candidates.find((j)=>j.account.id===H.account.id);if(G){let j=V.findIndex((q)=>q.account.id===H.account.id);if(W.push(G.state==="ready"?y0(`**#${j+1} · ${G.score.toPrecision(3)} 份/h**`):m0(G.state==="exhausted"?"⏳ 耗尽 · 暂不参与":G.state==="excluded"?"Ultra 自动排除 Plus":G.state==="waiting"?`⏳ 周余量 ${G.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),G.state==="ready"&&G.remaining!=null)W.push(m0(`周余量 ${G.remaining.toPrecision(3)} 份${G.fiveHourRemaining!=null?` · 5h ${G.fiveHourRemaining.toPrecision(3)} 份`:""}`));if(G.state==="miss"&&G.reason&&z.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[y0(r$(G.reason))]})}if(z.state!=="ok"){if(W.push(y0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[y0(r$(z.reason))]});continue}let B=z.subscriptionType==="pro"?"Pro 20×":z.subscriptionType==="prolite"?"Pro 5×":z.subscriptionType==="plus"?"Plus 1×":z.subscriptionType??"套餐 MISS";W.push(m0(`${B} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([j,q])=>j?[O2(j,q)]:[]);if(_.length)W.push(O7(_))}if(J>1)Q.push(m0(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}var F3=4,vQ,y0=($)=>({tag:"markdown",content:$}),m0=($)=>({tag:"markdown",content:`<font color='grey'>${r$($)}</font>`,text_size:"notation"});var R2=T(()=>{k0();vQ={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"],deleted:["\uD83D\uDDD1","已删除","grey"],error:["❌","未完成","red"],warning:["⚠️","需要处理","orange"]}});function Fj($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!Dj.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 C4{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),V;return V=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===V)this.tails.delete(J)}),this.tails.set(J,V),{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 hQ($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class T7{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 R7($){if(Array.isArray($))return`[${$.map(R7).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)}:${R7(J)}`).join(",")}}`}function Mj($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),V=null;switch(J){case"menu":V={request_id:Z.request_id};break;case"permission":V={request_id:Z.request_id};break;case"ask":V={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":V={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":V={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":V={guid:Z.guid};break;case"tasklist_enable":V={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":V={source_id:Z.source_id};break;case"agent_identity_page":V={panel_id:Z.panel_id,page:Z.page};break;case"model_page":V={panel_id:Z.panel_id,source_id:Z.source_id,page:Z.page};break;case"model_list_open":V={panel_id:Z.panel_id,source_id:Z.source_id,mode:Z.mode};break;case"model_add":case"model_remove":case"model_custom_remove":V={panel_id:Z.panel_id,source_id:Z.source_id,model:Z.model};break;case"notify_callback":V={notify_id:Z.notify_id};break;case"notify_reply":V={notify_id:Z.notify_id};break;case"notify_reply_cancel":V={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":V={panel_id:Z.panel_id};break;default:V=Z}return`${Y}\x00${Q}\x00${J}\x00${R7(V)}`}function Uj($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${Mj($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function Aj(){return new Promise(($)=>setTimeout($,0))}function b4($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function IQ($){let Z=$.afterAck??Aj,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(V){J(V)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let V=Fj(Q);if(V)return $.responses.invalid(Q,V);let H=Uj(Q),X=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],z=$.deduper.claimAll(X);if(z==="inflight")return $.responses.inflight(Q);if(z==="completed")return $.responses.completed(Q);let W=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(_){$.deduper.failAll(X),J(_);return}let G;try{G=await $.execute(Q)}catch(_){b4($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,_));return}await Y(async()=>{try{await $.present(Q,G)}catch(_){await $.presentPresentationFailure(Q,_)}});let B;try{B=$.completion(Q,G)}catch(_){b4($.deduper,H,!1),J(_);return}if(B){let _=B.then((j)=>{b4($.deduper,H,j==="complete")},(j)=>{b4($.deduper,H,!1),J(j)});$.track(_);return}b4($.deduper,H,$.businessSucceeded(Q,G))});if(!W.accepted)return $.deduper.failAll(X),$.responses.closed(Q);return $.track(W.completion),W.completion.catch(J),$.responses.accepted(Q)}}}var Dj;var N7=T(()=>{Dj=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"])});import{AsyncLocalStorage as Oj}from"node:async_hooks";class gQ{actor=new C4;context=new Oj;run($,Z){let J=this.context.getStore();if(J?.active&&J.chatId===$)return Z();return this.actor.enqueue($,async()=>{let Y={chatId:$,active:!0};try{return await this.context.run(Y,Z)}finally{Y.active=!1}})}}function D$($,Z){return Rj.run($,Z)}var Rj;var E7=T(()=>{N7();Rj=new gQ});async function x7($){let Z=await C7("feishu chat.get",()=>Z0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)M3("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 S7($,Z){let J=await C7("feishu tasklist.create",()=>Z0.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)M3("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 b7($){let Z=await C7("feishu tasklist.delete",()=>Z0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)M3("feishu tasklist.delete",Z)}function mQ($,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,V=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,X=Array.isArray(H)?H.map((z)=>z?.scope??z?.subject??z?.name??z).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${V}${X?` missing_scopes=${X}`:""}`}async function C7($,Z){try{return await Z()}catch(J){M3($,J)}}function M3($,Z){throw Error(mQ($,Z))}var pQ=T(()=>{J0()});var V0={};T$(V0,{writeAliveMarker:()=>r7,urgentApp:()=>S1,uploadImageKey:()=>V5,uploadAndSend:()=>p4,updateCard:()=>M$,unbindSessionChat:()=>O3,tempProjectName:()=>F$,tempChatName:()=>d7,setPendingConversationLaunchChecked:()=>t$,sendTextRaw:()=>w,sendText:()=>E,sendImage:()=>b3,sendFile:()=>GV,sendCard:()=>u,sanitizeSessionName:()=>X5,resolveProjectDir:()=>N3,replaceTurnAnchors:()=>t0,registerTempSessionLease:()=>I7,refreshChatList:()=>g4,readAliveMarker:()=>s7,provisionProject:()=>H5,projectProfile:()=>N2,preferredChatForSession:()=>L0,loadTempSessionLeases:()=>h7,loadSessionTurnsMap:()=>u7,loadSessionResumeMap:()=>p7,loadSessionModelMap:()=>i7,loadSessionChatMap:()=>m7,listNormalChatIdsByName:()=>x3,isOpenAIChatGPTAuthenticated:()=>c4,hasTempSessionLease:()=>g7,getTurnAnchors:()=>f4,getTenantToken:()=>k$,getSessionResumeRef:()=>s$,getSessionModelSelection:()=>a7,getSessionBranchBase:()=>h4,getPendingConversationLaunch:()=>I4,getChatTailMessageId:()=>Y5,formatFeishuApiError:()=>mQ,findNormalChatIdByName:()=>S3,fetchChatOwnerOpenId:()=>x7,fetchChatName:()=>J5,ensureChatForSession:()=>t7,downloadAttachment:()=>m4,disbandChatForSessionExact:()=>Z5,disbandChatForSession:()=>$5,deleteTasklistByGuid:()=>b7,deleteReaction:()=>S0,createTempChatForSession:()=>e7,createTasklistWithOwner:()=>S7,client:()=>Z0,clearSessionResumeChecked:()=>E2,clearSessionConversationState:()=>o7,chatNameCache:()=>q0,chatIdForSession:()=>E3,bindSessionToChat:()=>T2,bindSessionResumeChecked:()=>v4,bindSessionModelChecked:()=>x1,bindSessionModel:()=>n7,appendTurnAnchorChecked:()=>l7,addReaction:()=>c0,PROJECTS_ROOT:()=>ZV,MAX_UPLOAD_BYTES:()=>Q5});import*as aQ from"@larksuiteoapi/node-sdk";import{execSync as Tj}from"node:child_process";import{randomUUID as f7}from"node:crypto";import{mkdirSync as y7,readFileSync as N1,statSync as oQ,writeFileSync as rQ}from"node:fs";import{readFile as sQ}from"node:fs/promises";import{homedir as cQ}from"node:os";import{basename as T1,extname as Nj,isAbsolute as tQ,join as A3}from"node:path";import{sync as Ej}from"cross-spawn";function w7(){let $={};for(let[Z,J]of p0)$[Z]=J;s(t6,$)}function h7(){p0.clear();try{let $=JSON.parse(N1(t6,"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"||!F$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){K(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}p0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}K(`feishu: loaded ${p0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")K(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function I7($,Z){if(!F$($))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 p0.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=p0.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};p0.set(Z,Y);try{w7()}catch(Q){if(J)p0.set(Z,J);else p0.delete(Z);throw Q}}function g7($,Z){let J=p0.get(Z);return J?.sessionName===$&&J.chatId===Z}function N2($){return v.projects[$]}function N3($){return N2($)?.cwd?.trim()||A3(ZV,$)}function E1($,Z={}){return Y0($,{...Z,signal:Z.signal??AbortSignal.timeout(xj)})}async function k$(){if(U3&&Date.now()<uQ)return U3;return k7??=(async()=>{let $=await E1("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:eQ,app_secret:$V})}),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 U3=Z.tenant_access_token,uQ=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,U3})().finally(()=>{k7=null}),k7}function m7(){try{let $=JSON.parse(N1(a6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")L0.set(Z,J);K(`feishu: loaded ${L0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function JV(){try{v7()}catch($){K(`feishu: save session-chat-map failed: ${$}`)}}function v7(){let $={};for(let[Z,J]of L0)$[Z]=J;s(a6,$)}function T2($,Z){if(L0.get($)===Z)return;let J=L0.get($);L0.set($,Z),JV(),K(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function O3($){let Z=L0.get($);if(!Z)return;L0.delete($),JV(),K(`feishu: unbound session "${$}" from ${Z}`)}function y4($,Z){let J=j0.get($)??{};J[Z.provider]=Z,j0.set($,J)}function lQ($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=B$(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"||!tQ(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(!B$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!tQ($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function Sj($,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 p7(){try{let $=JSON.parse(N1(o6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");j0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){y4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=lQ(Y);if(Q){y4(Z,Q);continue}for(let V of F8){let H=Y[V];if(typeof H==="string"&&H.trim()){y4(Z,{provider:V,sessionId:H.trim(),cwd:null});continue}let X=lQ(H,V);if(X)y4(Z,X)}}K(`feishu: loaded ${j0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function R3(){let $={};for(let[Z,J]of j0){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}s(o6,$)}function v4($,Z,J,Y){let Q=Sj(Z,J,Y),V=j0.get($),H=V?{...V}:void 0,X=V?.[Q.provider];if(X?.sessionId===Q.sessionId&&X.cwd===Q.cwd)return;y4($,Q);try{R3()}catch(z){if(H)j0.set($,H);else j0.delete($);throw z}}function s$($,Z="codex"){let J=j0.get($)?.[Z];return J?{...J}:null}function E2($,Z){let J=j0.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)j0.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)j0.delete($);else j0.set($,Q)}try{R3()}catch(Q){throw j0.set($,Y),Q}}function YV($){if(!$||typeof $!=="object")return null;let Z=$;if(!B$(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 QV($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=YV(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 VV($){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=YV(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=QV(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{_0(Y,J.provider)}catch{return null}return Y}function bj($){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 Cj($,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=QV(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let V=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!V||!H)return null;Q={provider:"claude",kind:"assistant-message",id:V,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:bj(J.writes)}}function kj($){if(!$||typeof $!=="object")return null;let Z=$,J=VV(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 c7($){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 u7(){try{let $=JSON.parse(N1(r6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");t.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let V,H,X=null;if(Array.isArray(Q))V=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let B=Q;if(!Array.isArray(B.anchors)||!Object.prototype.hasOwnProperty.call(B,"base")){J++;continue}if(V=B.anchors,B.base===null)H=null;else{let _=VV(B.base);if(!_){J++;continue}H=_}if(Object.prototype.hasOwnProperty.call(B,"pendingLaunch")){let _=kj(B.pendingLaunch);if(!_){J++;continue}X=_}}else{J++;continue}let z=j0.get(Y),W=z?.claude!==void 0&&z.codex===void 0?"claude":null,G=[];for(let B of V){let _=Cj(B,W);if(_)G.push(_);else J++}if(G.length||H!==null||X)t.set(Y,{base:H,anchors:G,...X?{pendingLaunch:X}:{}}),Z+=G.length}if(K(`feishu: loaded ${Z} turn anchors across ${t.size} sessions`),J>0)K(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function w4(){let $={};for(let[Z,J]of t)$[Z]=J;s(r6,$)}function l7($,Z){let J=t.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>iQ){let V=Y.splice(0,Y.length-iQ),H=V[V.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}t.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{w4()}catch(V){if(J)t.set($,J);else t.delete($);throw V}}function f4($){return t.get($)?.anchors??[]}function h4($){return t.get($)?.base??null}function I4($){let Z=t.get($)?.pendingLaunch;return Z?c7(Z):null}function t$($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");_0(Z.launch,"claude",Z.launch.source.cwd)}let J=t.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)t.delete($);else t.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:c7(Z)}:{}});try{w4()}catch(V){if(J)t.set($,J);else t.delete($);throw V}}function t0($,Z,J,Y){let Q=t.get($),V=Y===void 0?Q?.pendingLaunch:Y??void 0,H=V?c7(V):void 0;if(Z.length===0&&J===null&&!H)t.delete($);else t.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{w4()}catch(X){if(Q)t.set($,Q);else t.delete($);throw X}}function F$($){return nQ.test($)?$.replace(nQ,""):null}function d7($,Z=[]){let J=new Date,Y=(X)=>String(X).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,V=new Set([...q0.values(),...t.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;V.has(H);X++)H=`${$}*${Q}-${X}`;return H}function i7(){try{let $=JSON.parse(N1(s6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){x0.set(Z,{provider:H2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,V=B$(Q)?Q:typeof Y==="string"&&Y.trim()?H2(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(V==="claude"&&!H)continue;let{effort:X,tokenSourceId:z}=J,W=typeof z==="string"&&z.trim()?z.trim():null,G=V==="dsh"?B0(X)?X:null:V==="claude"?N0(X)?X:null:r0(X)?X:null;x0.set(Z,{provider:V,model:H,effort:G,...W?{tokenSourceId:W}:{}})}K(`feishu: loaded ${x0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-model-map failed: ${$?.message??$}`)}}function yj(){try{T3()}catch($){K(`feishu: save session-model-map failed: ${$}`)}}function T3(){let $={};for(let[Z,J]of x0)$[Z]=J;s(s6,$)}function n7($,Z,J,Y,Q){let V=x0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;x0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),yj()}function x1($,Z,J,Y,Q){let V=x0.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;x0.set($,H);try{T3()}catch(X){if(V)x0.set($,V);else x0.delete($);throw X}}function a7($){let Z=x0.get($);if(Z)return Z;let J=F$($);return J?x0.get(J)??null:null}function o7($){let Z=L0.get($),J=j0.get($),Y=x0.get($),Q=t.get($),V=[...p0.entries()].filter(([,H])=>H.sessionName===$);L0.delete($),j0.delete($),x0.delete($),t.delete($);for(let[H]of V)p0.delete(H);try{v7(),R3(),T3(),w4(),w7()}catch(H){if(Z)L0.set($,Z);if(J)j0.set($,J);if(Y)x0.set($,Y);if(Q)t.set($,Q);for(let[z,W]of V)p0.set(z,W);let X=[H];for(let z of[v7,R3,T3,w4,w7])try{z()}catch(W){X.push(W)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function r7($){s($8,$)}function s7(){let $;try{$=N1($8,"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 E3($){let Z=L0.get($);if(Z){let Y=q0.get(Z);if(Y&&Y!==$)K(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of q0)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)K(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function g4(){try{let $;do{let Z=await Z0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)q0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);K(`feishu: refreshed chat list — ${q0.size} groups`)}catch($){K(`feishu: refresh chat list failed: ${$}`)}}async function x3(){let $=new Map,Z;do{let J=await Z0.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;q0.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 S3($){let Z=L0.get($);if(Z&&q0.get(Z)===$){let V=await XV(Z);if(V.name===$&&zV(V.status))return Z;q0.delete(Z),O3($)}let Y=(await x3()).get($)??[];if(Y.length===0)return null;let Q=L0.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 t7($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await S3($);if(J){let V=await wj(J,Z);return T2($,J),{chatId:J,created:!1,joined:V}}let Y=await Z0.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 q0.set(Q,$),T2($,Q),{chatId:Q,created:!0,joined:!0}}async function e7($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await S3($))throw Error(`temporary group name already exists: ${$}`);let Y=await Z0.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 q0.set(Q,$),T2($,Q),{chatId:Q,created:!0,joined:!0}}async function $5($){let Z=await S3($);if(!Z)return O3($),{chatId:null,disbanded:!1};let J=await Z0.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(q0.delete(Z),L0.get($)===Z)O3($);return{chatId:Z,disbanded:!0}}async function Z5($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await XV(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!zV(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await Z0.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 q0.delete(Z),{chatId:Z,disbanded:!0}}async function wj($,Z){let J;do{let Q=await Z0.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 V of Q.data?.items??[])if(V.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await Z0.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 J5($){try{let Z=await k$(),Y=await(await E1(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return K(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return q0.set($,Q),K(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return K(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return K(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function HV($,Z,J,Y){let Q=f7(),V=null;for(let H=0;H<k4.length;H++){if(k4[H]>0)await new Promise((X)=>setTimeout(X,k4[H]));try{let X=await Z0.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(X?.code&&X.code!==0)return K(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${X.code} msg=${X.msg}`),null;return X?.data?.message_id??null}catch(X){V=X,K(`feishu: send${$==="text"?"Text":"Card"} attempt ${H+1}/${k4.length} chat=${Z} failed: ${X}`)}}return K(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${k4.length} retries: ${V}`),null}async function XV($){let Z=await Z0.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 zV($){return $===null||$==="normal"}async function E($,Z){return D$($,()=>HV("text",$,"text",JSON.stringify({text:Z})))}async function u($,Z){return D$($,()=>HV("card",$,"interactive",JSON.stringify(n$(Z))))}async function Y5($){let Z=await Z0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw Error(`feishu message.list failed code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);if(!Array.isArray(Z.data?.items))throw Error("feishu message.list items MISS");if(Z.data.items.length===0)return null;let J=Z.data.items[0]?.message_id;if(typeof J!=="string"||!J.trim())throw Error("feishu message.list message_id MISS");return J}async function M$($,Z){let J=await Z0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(n$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){return D$($,()=>vj($,Z))}async function vj($,Z){try{let J=await k$(),Q=await(await E1("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 K(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return K(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function c0($,Z){if(!$)return null;try{return(await Z0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return K(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function S0($,Z){if(!$||!Z)return;try{await Z0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){K(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function S1($,Z){if(!$){K("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){K(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await k$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await E1(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(V?.code!==0){K(`feishu: urgentApp ${$} code=${V?.code} msg=${V?.msg}`);return}let H=V.data?.invalid_user_id_list??[],X=Z.length-H.length;K(`feishu: urgentApp ${$} ok — delivered=${X}${H.length?` invalid=${H.length}`:""}`)}catch(Q){K(`feishu: urgentApp ${$} failed: ${Q}`)}}async function m4($,Z,J,Y){try{let Q=await k$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await E1(V,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){K(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let X=Buffer.from(await H.arrayBuffer());y7(Z8,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,W=A3(Z8,`${Date.now()}-${z}`);return rQ(W,X),K(`feishu: downloaded ${J} ${W} (${X.length}B)`),W}catch(Q){K(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function hj($){return fj.has(Nj($).toLowerCase())}async function WV($){let Z=await k$(),J=new Blob([Uint8Array.from(await sQ($))]),Y=new FormData;Y.append("image_type","message"),Y.append("image",J,T1($));let V=await(await E1("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(V?.code!==0)return K(`feishu: uploadImage ${$} code=${V.code} msg=${V.msg}`),null;return V.data?.image_key??null}async function V5($){try{let Z=oQ($);if(!Z.isFile())return K(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>Q5)return K(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return K(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return WV($)}async function Ij($){let Z=await k$(),J=new Blob([Uint8Array.from(await sQ($))]),Y=new FormData;Y.append("file_type","stream"),Y.append("file_name",T1($)),Y.append("file",J,T1($));let V=await(await E1("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(V?.code!==0)return K(`feishu: uploadFile ${$} code=${V.code} msg=${V.msg}`),null;return V.data?.file_key??null}async function b3($,Z){return D$($,()=>gj($,Z))}async function gj($,Z){try{let J=await Z0.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 K(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return K(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function GV($,Z){return D$($,()=>mj($,Z))}async function mj($,Z){try{let J=await Z0.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 K(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return K(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function p4($,Z){try{let Y=oQ(Z);if(!Y.isFile())return await E($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>Q5)return await E($,`❌ 出站文件: ${T1(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return await E($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=hj(Z);try{if(J){let Y=await WV(Z);if(!Y)return await E($,`❌ 出站图片上传失败: ${T1(Z)}`),!1;return await b3($,Y)!=null}else{let Y=await Ij(Z);if(!Y)return await E($,`❌ 出站文件上传失败: ${T1(Z)}`),!1;return await GV($,Y)!=null}}catch(Y){return K(`feishu: uploadAndSend ${Z} failed: ${Y}`),await E($,`❌ 出站文件异常: ${T1(Z)} — ${Y}`),!1}}function H5($){y7($,{recursive:!0}),K(`feishu: provisioned ${$}`);let Z=A3(cQ(),".codex","config.toml");try{y7(A3(cQ(),".codex"),{recursive:!0});let J="";try{J=N1(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=P7){let Y=this.nextId++;return new Promise((Q,V)=>{if(!this.alive){V(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;V(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:V,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
110
+ `,(X)=>{if(!X)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 ${$}: ${X.message}`))})}catch(X){this.pending.delete(Y),clearTimeout(H),V(X instanceof Error?X:Error(String(X)))}})}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)}}};R4=new Map,P$=new Map});import{existsSync as Pj,readFileSync as Dj}from"node:fs";class vQ{deps;constructor($){this.deps=$}blocks(){if(!Pj(this.deps.stateFile))return[];let $=JSON.parse(Dj(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"?B4($.usage,Z):null,Y=["fiveHour","weekly"].flatMap((X)=>{let z=J?.[X];return z?[{kind:X,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Q=f8($.usage,Z),V=JSON.stringify([$.identity,Q]),H=this.blocks().filter((X)=>X.key!==V);H.push({key:V,identity:$.identity,meter:Q,windows:Y}),s(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(q)=>{let P,D=null,T=`record:${q.id}`;if(this.deps.pendingLogin(q.id))P={state:"network",reason:"正在登录"};else try{P=J?this.deps.cachedUsage(q.id):await this.deps.usage(q.id);let M=P?.state==="ok"?P.accountFingerprint??this.deps.identity(q.id):null;if(M)T=M;else if(P?.state==="ok")D="账号身份 MISS";if(P?.state==="ok"&&!D)D=await this.deps.compatible(q.id,Z.model,Z.effort)}catch(M){P={state:"network",reason:String(M)}}return{account:q,usage:P,identity:T,reason:D}}));Z.signal?.throwIfAborted();let Q=Z.failedAccountId&&Y.find((q)=>q.account.id===Z.failedAccountId);if(Q&&Q.usage?.state==="ok")this.block({account:Q.account,usage:Q.usage,identity:Q.identity,...h8(Q.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let V=this.blocks(),H=this.deps.now(),X=new Set,z=new Map,W=Y.map(({account:q,usage:P,identity:D,reason:T})=>{let M=h8(P??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(T)M={...M,state:"miss",score:null,reason:T};let A=z.get(D);if(z.set(D,A??q.name),A)M={...M,state:"miss",score:null,reason:`重复账号:${A}`};let U=P?.state==="ok"?f8(P,Z.model):null,S=V.find((C)=>(C.identity===D||C.identity===`record:${q.id}`)&&C.meter===U);if(S&&P?.state==="ok"&&M.state==="ready"){let C=B4(P,Z.model);if(!J&&S.windows.some((y)=>{let I=C[y.kind];return I&&I.percent!==null&&(y.percent!==null&&I.percent<y.percent||y.reset!==null&&y.reset<=H&&(I.resetsAt?.getTime()??0)>y.reset)}))X.add(S.key);else M={...M,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:q,usage:P,identity:D,...M,...A?{duplicateOf:A}:{}}});if(X.size)s(this.deps.stateFile,{version:1,blocks:V.filter((q)=>!X.has(q.key))});let G=W.filter((q)=>q.state==="ready");G.sort((q,P)=>P.score-q.score||(P.availableNow??0)-(q.availableNow??0)||q.account.id.localeCompare(P.account.id));let B=G[0]??null,_=W.filter((q)=>q.state==="exhausted"||q.state==="waiting"),j=_.length?Math.min(..._.map((q)=>q.retryAt??H+60000)):void 0;for(let q of W)K(`codex scheduler${J?" [cache]":""}: ${q.account.name} ${q.state} score=${q.score??"MISS"}${q.reason?` (${q.reason})`:""}`);return{selected:B,candidates:W,...j!==void 0?{retryAt:j}:{}}}}var P3;var U7=N(()=>{g0();C$();Y0();V0();f0();h();P3=new vQ({accounts:()=>k.list(),usage:R1,cachedUsage:wQ,identity:($)=>k.fingerprint($),pendingLogin:o9,now:Date.now,stateFile:wJ,compatible:async($,Z,J)=>{let Y=H0("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=L$(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as Fj}from"node:events";function Aj($,Z){return Z.throwIfAborted(),new Promise((J,Y)=>{let Q=()=>{clearTimeout(H),Z.removeEventListener("abort",V)},V=()=>{Q(),Y(Z.reason)},H=setTimeout(()=>{Q(),J()},$);Z.addEventListener("abort",V,{once:!0})})}var Uj="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",Mj,M7=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),A7;var fQ=N(()=>{g0();U7();C$();h();Mj=["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"];A7=class A7 extends Fj{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??M7()}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??P3}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},K(`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((X)=>`${X.account.name}:${X.reason??X.state}`).join(";");if(Y.retryAt===void 0)throw Error(`没有可用的 Codex 账号;${Q}`);let V=Math.max(1000,Math.min(60000,Y.retryAt-Date.now())),H=Y.candidates.filter((X)=>X.state==="miss"&&!X.duplicateOf).length;K(`codex account: waiting for quota: ${Q}`),this.notice(`暂无可用账号 · 自动等待恢复${H?` · ${H} 个 MISS`:""}`,V),this.resolveQuotaWait(),await(this.opts.wait??Aj)(V,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:V,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=V,this.selected=Y.selected,this.revision=H,l$(this,Y.selected.account.id,!1),this.wire(V),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(),V.sendInitialize();let X=V.initializationPromise?.();if(!X)throw Error("Codex 初始化未提供确认事务");if(await X,this.lifetime.signal.throwIfAborted(),this.lastSession=V.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:V.sessionId});if(!this.recovery)this.drainInputs()}wire($){for(let Z of Mj)$.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 X=await q3(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),X?.state==="ok")this.selected={...this.selected,usage:X,identity:X.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 V=Q?{kind:"resume",source:{provider:"codex",sessionId:$.sessionId,cwd:this.opts.workDir}}:this.opts.launch;if(await $.kill(),$.isAlive())throw Error("旧 Codex 进程退出未确认,不能启动下一账号");for(let X of this.backgroundTasks)this.emit("bg_task_settled",{task_id:X,status:"failed",summary:"账号额度耗尽,原进程已退出;主任务换号后继续"});this.backgroundTasks.clear(),this.lifetime.signal.throwIfAborted(),await this.launch(V,void 0,J),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let H=Z.accepted?Uj: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={...M7(),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={...M7(),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 T4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new A7({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(B,_,j,q,P)=>T4({...$,model:q,effort:P,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:B,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??c,J=H0($.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,V=L2(J,Q),H=!Y&&J&&L$(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 X=!Y&&J&&Q?J.resolveSpawnModel(Q):Q;if(Q&&!X)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Q}`);let z=J?(G)=>J.spawnEnv(G,X):void 0;if($.provider==="dsh"){if(!J||!X||!B0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new V7({...$,model:X,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(B7(),!T0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new W3({workDir:$.workDir,model:X,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:V}}if($.effort!==void 0&&!r0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let W=new W2({workDir:$.workDir,model:X,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z});return l$(W,Z),{process:W,sourceRevision:V}}var O7=N(()=>{D0();HQ();F4();U1();Y0();g0();fQ()});function D3($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function U2($){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 M2($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(z)=>`&#${z.charCodeAt(0)};`),Y=typeof $.used==="number"&&typeof $.total==="number"?` · ${$.used}/${$.total}`:"",Q=$.percent;if(Q===null||!Number.isFinite(Q)||Q<0||Q>100)return[{tag:"markdown",content:`**${J} · MISS${Y}**`}];let V=Math.round(Q/100*6),H=Q>=100?"red":Q>=80?"orange":"green",X=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${U2($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Q)}%${Y}**
111
+ <font color='${H}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${X}</font>`,text_size:"notation"}]}var IQ={};N$(IQ,{codexAccountSummary:()=>E4,codexAccountPanel:()=>x4,codexAccountCard:()=>V$,CODEX_ACCOUNTS_PAGE_SIZE:()=>F3});function o$($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function R7($){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 E4($){let[Z,J]=hQ[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function V$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:E4($)}},body:{elements:[x4($)]}}}function x4($){let[,,Z]=hQ[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(y0(["连接","授权","就绪"].map((Q,V)=>V===Y?`**${V+1} ${Q}**`:`${V<Y?"✓":V+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(R7([[m0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[y0(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),m0("登录账号,输入左侧验证码")]]))}if($.current)J.push(R7([[m0("当前使用"),y0(`**${o$($.current)}**`)],...$.selected&&$.selected!==$.current?[[m0("下次启动"),y0(`**${o$($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(y0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>o$(Y)).join(" · ")));if($.message)J.push(y0(o$($.message)));if($.resetUsage){let Y=$.resetUsage;if(J.push(y0(`**重置卡** ${Y.state==="ok"&&Y.resetCredits!=null?`${Y.resetCredits} 次可用`:"MISS"}`)),Y.state==="ok"){for(let[Q,V]of[[Y.fiveHour,"5h"],[Y.weekly,"周"]])if(Q)J.push(...M2(Q,V))}else J.push(y0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...Oj($));if($.phase==="accounts")J.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:"⌨️ Codex 命令"},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",elements:[y0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
112
+ `)),m0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(m0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[y0(o$($.details))]});return{tag:"collapsible_panel",element_id:R.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:E4($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function Oj($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/F3)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[m0(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],V=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort((H,X)=>X.score-H.score||(X.availableNow??0)-(H.availableNow??0)||H.account.id.localeCompare(X.account.id));if($.scheduling)Q.push(m0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let H of Z.entries.slice((Y-1)*F3,Y*F3)){let X=[H.account.id===$.currentId?"使用中":"",H.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),z=H.usage,W=[];if(Q.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${H.account.name}${X.length?` · ${X.join(" · ")}`:""}`},background_color:H.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:W}),H.duplicateOf){W.push(m0(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}let G=$.scheduling?.candidates.find((j)=>j.account.id===H.account.id);if(G){let j=V.findIndex((q)=>q.account.id===H.account.id);if(W.push(G.state==="ready"?y0(`**#${j+1} · ${G.score.toPrecision(3)} 份/h**`):m0(G.state==="exhausted"?"⏳ 耗尽 · 暂不参与":G.state==="excluded"?"Ultra 自动排除 Plus":G.state==="waiting"?`⏳ 周余量 ${G.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),G.state==="ready"&&G.remaining!=null)W.push(m0(`周余量 ${G.remaining.toPrecision(3)} 份${G.fiveHourRemaining!=null?` · 5h ${G.fiveHourRemaining.toPrecision(3)} 份`:""}`));if(G.state==="miss"&&G.reason&&z.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[y0(o$(G.reason))]})}if(z.state!=="ok"){if(W.push(y0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[y0(o$(z.reason))]});continue}let B=z.subscriptionType==="pro"?"Pro 20×":z.subscriptionType==="prolite"?"Pro 5×":z.subscriptionType==="plus"?"Plus 1×":z.subscriptionType??"套餐 MISS";W.push(m0(`${B} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([j,q])=>j?[M2(j,q)]:[]);if(_.length)W.push(R7(_))}if(J>1)Q.push(m0(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}var F3=4,hQ,y0=($)=>({tag:"markdown",content:$}),m0=($)=>({tag:"markdown",content:`<font color='grey'>${o$($)}</font>`,text_size:"notation"});var A2=N(()=>{k0();hQ={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"],deleted:["\uD83D\uDDD1","已删除","grey"],error:["❌","未完成","red"],warning:["⚠️","需要处理","orange"]}});function gQ($){if(!$||typeof $!=="object")return!1;let Z=$.response?.status??$.status,J=$.response?.data?.code??$.code;if(J===99991400||J===230020||Rj.has(Z))return!0;if(typeof Z==="number"&&Z>=400)return!1;if(Nj.has(J)||$.name==="TimeoutError")return!0;return $.cause!==$&&gQ($.cause)}function Tj($){let Z=$?.retryAfter??$?.response?.headers?.["retry-after"]??$?.response?.headers?.["x-ogw-ratelimit-reset"];if(typeof Z!=="string"||!Z.trim())return 0;let J=Number(Z),Y=Number.isFinite(J)?J*1000:Date.parse(Z)-Date.now();return Number.isFinite(Y)?Math.max(0,Y):0}async function T7($,Z){for(let J=0;;J++)try{return await Z()}catch(Y){let Q=Math.max(N7[J]??0,Tj(Y)),V=gQ(Y)&&J<N7.length&&Q<=60000;if(K(`feishu: ${$} attempt ${J+1}/${N7.length+1} failed: ${Y}; ${V?`retry in ${Q}ms`:"FINAL"}`),!V)throw Y;await new Promise((H)=>setTimeout(H,Q))}}async function mQ($,Z){let J=await $.text(),Y=$.headers.get("retry-after")??$.headers.get("x-ogw-ratelimit-reset"),Q;try{Q=JSON.parse(J)}catch{throw new S4(`${Z} HTTP ${$.status}: invalid JSON — ${J.slice(0,200)}`,$.status,void 0,Y)}if(!$.ok||Q?.code!==0)throw new S4(`${Z} HTTP ${$.status} code=${Q?.code??"MISS"} msg=${Q?.msg??"MISS"}`,$.status,Q?.code,Y);return Q}var N7,Rj,Nj,S4;var pQ=N(()=>{h();N7=[1000,4000],Rj=new Set([408,429,500,502,503,504]),Nj=new Set(["ECONNRESET","ECONNREFUSED","ECONNABORTED","ETIMEDOUT","EPIPE","EAI_AGAIN","ConnectionRefused","UND_ERR_CONNECT_TIMEOUT","UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_SOCKET"]);S4=class S4 extends Error{status;code;retryAfter;constructor($,Z,J,Y){super($);this.status=Z;this.code=J;this.retryAfter=Y;this.name="FeishuRequestError"}}});function xj($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!Ej.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 C4{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),V;return V=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===V)this.tails.delete(J)}),this.tails.set(J,V),{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 cQ($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class x7{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 E7($){if(Array.isArray($))return`[${$.map(E7).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)}:${E7(J)}`).join(",")}}`}function Sj($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),V=null;switch(J){case"menu":V={request_id:Z.request_id};break;case"permission":V={request_id:Z.request_id};break;case"ask":V={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":V={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":V={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":V={guid:Z.guid};break;case"tasklist_enable":V={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":V={source_id:Z.source_id};break;case"agent_identity_page":V={panel_id:Z.panel_id,page:Z.page};break;case"model_page":V={panel_id:Z.panel_id,source_id:Z.source_id,page:Z.page};break;case"model_list_open":V={panel_id:Z.panel_id,source_id:Z.source_id,mode:Z.mode};break;case"model_add":case"model_remove":case"model_custom_remove":V={panel_id:Z.panel_id,source_id:Z.source_id,model:Z.model};break;case"notify_callback":V={notify_id:Z.notify_id};break;case"notify_reply":V={notify_id:Z.notify_id};break;case"notify_reply_cancel":V={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":V={panel_id:Z.panel_id};break;default:V=Z}return`${Y}\x00${Q}\x00${J}\x00${E7(V)}`}function bj($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${Sj($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function Cj(){return new Promise(($)=>setTimeout($,0))}function b4($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function uQ($){let Z=$.afterAck??Cj,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(V){J(V)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let V=xj(Q);if(V)return $.responses.invalid(Q,V);let H=bj(Q),X=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],z=$.deduper.claimAll(X);if(z==="inflight")return $.responses.inflight(Q);if(z==="completed")return $.responses.completed(Q);let W=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(_){$.deduper.failAll(X),J(_);return}let G;try{G=await $.execute(Q)}catch(_){b4($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,_));return}await Y(async()=>{try{await $.present(Q,G)}catch(_){await $.presentPresentationFailure(Q,_)}});let B;try{B=$.completion(Q,G)}catch(_){b4($.deduper,H,!1),J(_);return}if(B){let _=B.then((j)=>{b4($.deduper,H,j==="complete")},(j)=>{b4($.deduper,H,!1),J(j)});$.track(_);return}b4($.deduper,H,$.businessSucceeded(Q,G))});if(!W.accepted)return $.deduper.failAll(X),$.responses.closed(Q);return $.track(W.completion),W.completion.catch(J),$.responses.accepted(Q)}}}var Ej;var S7=N(()=>{Ej=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"])});import{AsyncLocalStorage as kj}from"node:async_hooks";class lQ{actor=new C4;context=new kj;run($,Z){let J=this.context.getStore();if(J?.active&&J.chatId===$)return Z();return this.actor.enqueue($,async()=>{let Y={chatId:$,active:!0};try{return await this.context.run(Y,Z)}finally{Y.active=!1}})}}function D$($,Z){return yj.run($,Z)}var yj;var b7=N(()=>{S7();yj=new lQ});async function C7($){let Z=await w7("feishu chat.get",()=>X0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)U3("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 k7($,Z){let J=await w7("feishu tasklist.create",()=>X0.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)U3("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 y7($){let Z=await w7("feishu tasklist.delete",()=>X0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)U3("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,V=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,X=Array.isArray(H)?H.map((z)=>z?.scope??z?.subject??z?.name??z).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${V}${X?` missing_scopes=${X}`:""}`}async function w7($,Z){try{return await Z()}catch(J){U3($,J)}}function U3($,Z){throw Error(dQ($,Z))}var iQ=N(()=>{Z0()});var Q0={};N$(Q0,{writeAliveMarker:()=>e7,urgentApp:()=>E1,uploadImageKey:()=>X5,uploadAndSend:()=>p4,updateCard:()=>U$,unbindSessionChat:()=>O3,tempProjectName:()=>F$,tempChatName:()=>a7,setPendingConversationLaunchChecked:()=>t$,sendTextRaw:()=>w,sendText:()=>x,sendImage:()=>k3,sendFile:()=>LV,sendCard:()=>u,sanitizeSessionName:()=>W5,resolveProjectDir:()=>T3,replaceTurnAnchors:()=>t0,registerTempSessionLease:()=>p7,refreshChatList:()=>g4,readAliveMarker:()=>$5,provisionProject:()=>z5,projectProfile:()=>N2,preferredChatForSession:()=>L0,loadTempSessionLeases:()=>m7,loadSessionTurnsMap:()=>i7,loadSessionResumeMap:()=>l7,loadSessionModelMap:()=>o7,loadSessionChatMap:()=>u7,listNormalChatIdsByName:()=>x3,isOpenAIChatGPTAuthenticated:()=>c4,hasTempSessionLease:()=>c7,getTurnAnchors:()=>f4,getTenantToken:()=>r$,getSessionResumeRef:()=>s$,getSessionModelSelection:()=>s7,getSessionBranchBase:()=>h4,getPendingConversationLaunch:()=>I4,getChatTailMessageId:()=>H5,formatFeishuApiError:()=>dQ,findNormalChatIdByName:()=>S3,fetchChatOwnerOpenId:()=>C7,fetchChatName:()=>V5,ensureChatForSession:()=>Z5,downloadAttachment:()=>m4,disbandChatForSessionExact:()=>Q5,disbandChatForSession:()=>Y5,deleteTasklistByGuid:()=>y7,deleteReaction:()=>S0,createTempChatForSession:()=>J5,createTasklistWithOwner:()=>k7,client:()=>X0,clearSessionResumeChecked:()=>T2,clearSessionConversationState:()=>t7,chatNameCache:()=>q0,chatIdForSession:()=>E3,bindSessionToChat:()=>R2,bindSessionResumeChecked:()=>v4,bindSessionModelChecked:()=>T1,bindSessionModel:()=>r7,appendTurnAnchorChecked:()=>n7,addReaction:()=>c0,PROJECTS_ROOT:()=>VV,MAX_UPLOAD_BYTES:()=>C3});import*as eQ from"@larksuiteoapi/node-sdk";import{execSync as wj}from"node:child_process";import{randomUUID as g7}from"node:crypto";import{mkdirSync as f7,readFileSync as N1,statSync as $V,writeFileSync as ZV}from"node:fs";import{readFile as vj}from"node:fs/promises";import{homedir as nQ}from"node:os";import{basename as O2,extname as fj,isAbsolute as JV,join as A3}from"node:path";import{sync as hj}from"cross-spawn";function h7(){let $={};for(let[Z,J]of p0)$[Z]=J;s(e6,$)}function m7(){p0.clear();try{let $=JSON.parse(N1(e6,"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"||!F$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){K(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}p0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}K(`feishu: loaded ${p0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")K(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function p7($,Z){if(!F$($))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 p0.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=p0.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};p0.set(Z,Y);try{h7()}catch(Q){if(J)p0.set(Z,J);else p0.delete(Z);throw Q}}function c7($,Z){let J=p0.get(Z);return J?.sessionName===$&&J.chatId===Z}function N2($){return v.projects[$]}function T3($){return N2($)?.cwd?.trim()||A3(VV,$)}function w4($,Z={}){return J0($,{...Z,signal:Z.signal??AbortSignal.timeout(HV)})}async function XV($,Z,J){let Y=Z.signal??AbortSignal.timeout(HV);try{return await mQ(await w4($,{...Z,signal:Y}),J)}catch(Q){if(Y.aborted&&Y.reason?.name==="TimeoutError")throw Y.reason;throw Q}}async function r$(){if(M3&&Date.now()<aQ)return M3;return v7??=(async()=>{let $=await XV("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:YV,app_secret:QV})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return M3=$.tenant_access_token,aQ=Date.now()+Math.max(0,($.expire??7200)-60)*1000,M3})().finally(()=>{v7=null}),v7}function u7(){try{let $=JSON.parse(N1(o6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")L0.set(Z,J);K(`feishu: loaded ${L0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function zV(){try{I7()}catch($){K(`feishu: save session-chat-map failed: ${$}`)}}function I7(){let $={};for(let[Z,J]of L0)$[Z]=J;s(o6,$)}function R2($,Z){if(L0.get($)===Z)return;let J=L0.get($);L0.set($,Z),zV(),K(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function O3($){let Z=L0.get($);if(!Z)return;L0.delete($),zV(),K(`feishu: unbound session "${$}" from ${Z}`)}function k4($,Z){let J=j0.get($)??{};J[Z.provider]=Z,j0.set($,J)}function oQ($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=B$(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"||!JV(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function rQ($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!B$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!JV($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function Ij($,Z,J){if(typeof $!=="string")return rQ($);if(!Z)throw Error("cannot bind a conversation without a provider");return rQ({provider:Z,sessionId:$,cwd:J??null})}function l7(){try{let $=JSON.parse(N1(r6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");j0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){k4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=oQ(Y);if(Q){k4(Z,Q);continue}for(let V of U8){let H=Y[V];if(typeof H==="string"&&H.trim()){k4(Z,{provider:V,sessionId:H.trim(),cwd:null});continue}let X=oQ(H,V);if(X)k4(Z,X)}}K(`feishu: loaded ${j0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function R3(){let $={};for(let[Z,J]of j0){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}s(r6,$)}function v4($,Z,J,Y){let Q=Ij(Z,J,Y),V=j0.get($),H=V?{...V}:void 0,X=V?.[Q.provider];if(X?.sessionId===Q.sessionId&&X.cwd===Q.cwd)return;k4($,Q);try{R3()}catch(z){if(H)j0.set($,H);else j0.delete($);throw z}}function s$($,Z="codex"){let J=j0.get($)?.[Z];return J?{...J}:null}function T2($,Z){let J=j0.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)j0.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)j0.delete($);else j0.set($,Q)}try{R3()}catch(Q){throw j0.set($,Y),Q}}function WV($){if(!$||typeof $!=="object")return null;let Z=$;if(!B$(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 GV($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=WV(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 KV($){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=WV(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=GV(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{_0(Y,J.provider)}catch{return null}return Y}function gj($){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 mj($,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=GV(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let V=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!V||!H)return null;Q={provider:"claude",kind:"assistant-message",id:V,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:gj(J.writes)}}function pj($){if(!$||typeof $!=="object")return null;let Z=$,J=KV(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 d7($){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 i7(){try{let $=JSON.parse(N1(s6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");t.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let V,H,X=null;if(Array.isArray(Q))V=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let B=Q;if(!Array.isArray(B.anchors)||!Object.prototype.hasOwnProperty.call(B,"base")){J++;continue}if(V=B.anchors,B.base===null)H=null;else{let _=KV(B.base);if(!_){J++;continue}H=_}if(Object.prototype.hasOwnProperty.call(B,"pendingLaunch")){let _=pj(B.pendingLaunch);if(!_){J++;continue}X=_}}else{J++;continue}let z=j0.get(Y),W=z?.claude!==void 0&&z.codex===void 0?"claude":null,G=[];for(let B of V){let _=mj(B,W);if(_)G.push(_);else J++}if(G.length||H!==null||X)t.set(Y,{base:H,anchors:G,...X?{pendingLaunch:X}:{}}),Z+=G.length}if(K(`feishu: loaded ${Z} turn anchors across ${t.size} sessions`),J>0)K(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function y4(){let $={};for(let[Z,J]of t)$[Z]=J;s(s6,$)}function n7($,Z){let J=t.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>sQ){let V=Y.splice(0,Y.length-sQ),H=V[V.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}t.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{y4()}catch(V){if(J)t.set($,J);else t.delete($);throw V}}function f4($){return t.get($)?.anchors??[]}function h4($){return t.get($)?.base??null}function I4($){let Z=t.get($)?.pendingLaunch;return Z?d7(Z):null}function t$($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");_0(Z.launch,"claude",Z.launch.source.cwd)}let J=t.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)t.delete($);else t.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:d7(Z)}:{}});try{y4()}catch(V){if(J)t.set($,J);else t.delete($);throw V}}function t0($,Z,J,Y){let Q=t.get($),V=Y===void 0?Q?.pendingLaunch:Y??void 0,H=V?d7(V):void 0;if(Z.length===0&&J===null&&!H)t.delete($);else t.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{y4()}catch(X){if(Q)t.set($,Q);else t.delete($);throw X}}function F$($){return tQ.test($)?$.replace(tQ,""):null}function a7($,Z=[]){let J=new Date,Y=(X)=>String(X).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,V=new Set([...q0.values(),...t.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;V.has(H);X++)H=`${$}*${Q}-${X}`;return H}function o7(){try{let $=JSON.parse(N1(t6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){x0.set(Z,{provider:Q2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,V=B$(Q)?Q:typeof Y==="string"&&Y.trim()?Q2(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(V==="claude"&&!H)continue;let{effort:X,tokenSourceId:z}=J,W=typeof z==="string"&&z.trim()?z.trim():null,G=V==="dsh"?B0(X)?X:null:V==="claude"?T0(X)?X:null:r0(X)?X:null;x0.set(Z,{provider:V,model:H,effort:G,...W?{tokenSourceId:W}:{}})}K(`feishu: loaded ${x0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-model-map failed: ${$?.message??$}`)}}function cj(){try{N3()}catch($){K(`feishu: save session-model-map failed: ${$}`)}}function N3(){let $={};for(let[Z,J]of x0)$[Z]=J;s(t6,$)}function r7($,Z,J,Y,Q){let V=x0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;x0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),cj()}function T1($,Z,J,Y,Q){let V=x0.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;x0.set($,H);try{N3()}catch(X){if(V)x0.set($,V);else x0.delete($);throw X}}function s7($){let Z=x0.get($);if(Z)return Z;let J=F$($);return J?x0.get(J)??null:null}function t7($){let Z=L0.get($),J=j0.get($),Y=x0.get($),Q=t.get($),V=[...p0.entries()].filter(([,H])=>H.sessionName===$);L0.delete($),j0.delete($),x0.delete($),t.delete($);for(let[H]of V)p0.delete(H);try{I7(),R3(),N3(),y4(),h7()}catch(H){if(Z)L0.set($,Z);if(J)j0.set($,J);if(Y)x0.set($,Y);if(Q)t.set($,Q);for(let[z,W]of V)p0.set(z,W);let X=[H];for(let z of[I7,R3,N3,y4,h7])try{z()}catch(W){X.push(W)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function e7($){s(Z8,$)}function $5(){let $;try{$=N1(Z8,"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 E3($){let Z=L0.get($);if(Z){let Y=q0.get(Z);if(Y&&Y!==$)K(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of q0)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)K(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function g4(){try{let $;do{let Z=await X0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)q0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);K(`feishu: refreshed chat list — ${q0.size} groups`)}catch($){K(`feishu: refresh chat list failed: ${$}`)}}async function x3(){let $=new Map,Z;do{let J=await X0.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;q0.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 S3($){let Z=L0.get($);if(Z&&q0.get(Z)===$){let V=await BV(Z);if(V.name===$&&_V(V.status))return Z;q0.delete(Z),O3($)}let Y=(await x3()).get($)??[];if(Y.length===0)return null;let Q=L0.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 Z5($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await S3($);if(J){let V=await uj(J,Z);return R2($,J),{chatId:J,created:!1,joined:V}}let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:g7()},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 q0.set(Q,$),R2($,Q),{chatId:Q,created:!0,joined:!0}}async function J5($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await S3($))throw Error(`temporary group name already exists: ${$}`);let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:g7()},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 q0.set(Q,$),R2($,Q),{chatId:Q,created:!0,joined:!0}}async function Y5($){let Z=await S3($);if(!Z)return O3($),{chatId:null,disbanded:!1};let J=await X0.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(q0.delete(Z),L0.get($)===Z)O3($);return{chatId:Z,disbanded:!0}}async function Q5($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await BV(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!_V(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await X0.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 q0.delete(Z),{chatId:Z,disbanded:!0}}async function uj($,Z){let J;do{let Q=await X0.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 V of Q.data?.items??[])if(V.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await X0.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 V5($){try{let Z=await r$(),Y=await(await w4(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return K(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return q0.set($,Q),K(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return K(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return K(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function b3($,Z,J,Y){let Q=g7();try{return await T7(`send${$} chat=${Z}`,async()=>{let V=await X0.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(V?.code!==0)throw new S4(`send${$} code=${V?.code??"MISS"} msg=${V?.msg??"MISS"}`,void 0,V?.code);let H=V?.data?.message_id;if(typeof H!=="string"||!H.trim())throw Error(`send${$} message_id MISS`);return H})}catch{return null}}async function BV($){let Z=await X0.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 _V($){return $===null||$==="normal"}async function x($,Z){return D$($,()=>b3("Text",$,"text",JSON.stringify({text:Z})))}async function u($,Z){return D$($,()=>b3("Card",$,"interactive",JSON.stringify(i$(Z))))}async function H5($){let Z=await X0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw Error(`feishu message.list failed code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);if(!Array.isArray(Z.data?.items))throw Error("feishu message.list items MISS");if(Z.data.items.length===0)return null;let J=Z.data.items[0]?.message_id;if(typeof J!=="string"||!J.trim())throw Error("feishu message.list message_id MISS");return J}async function U$($,Z){let J=await X0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(i$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){return D$($,()=>lj($,Z))}async function lj($,Z){try{let J=await r$(),Q=await(await w4("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 K(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return K(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function c0($,Z){if(!$)return null;try{return(await X0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return K(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function S0($,Z){if(!$||!Z)return;try{await X0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){K(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function E1($,Z){if(!$){K("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){K(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await r$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await w4(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(V?.code!==0){K(`feishu: urgentApp ${$} code=${V?.code} msg=${V?.msg}`);return}let H=V.data?.invalid_user_id_list??[],X=Z.length-H.length;K(`feishu: urgentApp ${$} ok — delivered=${X}${H.length?` invalid=${H.length}`:""}`)}catch(Q){K(`feishu: urgentApp ${$} failed: ${Q}`)}}async function m4($,Z,J,Y){try{let Q=await r$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await w4(V,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){K(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let X=Buffer.from(await H.arrayBuffer());f7(J8,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,W=A3(J8,`${Date.now()}-${z}`);return ZV(W,X),K(`feishu: downloaded ${J} ${W} (${X.length}B)`),W}catch(Q){K(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function ij($){return dj.has(fj($).toLowerCase())}async function jV($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Y;return T7(`${J} ${$}`,async()=>{if(Y??=new Blob([Uint8Array.from(await vj($))]),Y.size>C3)throw Error(`${O2($)} 超过 30 MB`);let Q=await r$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",O2($));V.append(Z,Y,O2($));let X=(await XV(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Q}`},body:V},J)).data?.[`${Z}_key`];if(typeof X!=="string"||!X.trim())throw Error(`${J} ${Z}_key MISS`);return X})}async function X5($){try{let Z=$V($);if(!Z.isFile())return K(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>C3)return K(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return K(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}try{return await jV($,"image")}catch{return null}}async function k3($,Z){return D$($,()=>b3("Image",$,"image",JSON.stringify({image_key:Z})))}async function LV($,Z){return D$($,()=>b3("File",$,"file",JSON.stringify({file_key:Z})))}async function p4($,Z){try{let Q=$V(Z);if(!Q.isFile())return K(`feishu: uploadAndSend not a file — ${Z}`),await x($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>C3)return K(`feishu: uploadAndSend oversize — ${Z} (${Q.size}B)`),await x($,`❌ 出站文件: ${O2(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return K(`feishu: uploadAndSend stat failed — ${Z}: ${Q}`),await x($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=ij(Z)?"image":"file",Y=J==="image"?"出站图片":"出站文件";try{let Q=await jV(Z,J),V=await(J==="image"?k3($,Q):LV($,Q));if(!V)return K(`feishu: uploadAndSend ${Z} send failed after upload`),await x($,`❌ ${Y}发送失败: ${O2(Z)}(上传已完成)`),!1;return K(`feishu: uploadAndSend ${Z} delivered msg=${V}`),!0}catch(Q){return K(`feishu: uploadAndSend ${Z} failed: ${Q}`),await x($,`❌ ${Y}上传失败: ${O2(Z)} — ${Q}`),!1}}function z5($){f7($,{recursive:!0}),K(`feishu: provisioned ${$}`);let Z=A3(nQ(),".codex","config.toml");try{f7(A3(nQ(),".codex"),{recursive:!0});let J="";try{J=N1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
113
113
 
114
114
  `:""}${Y}
115
115
  trust_level = "trusted"
116
- `,rQ(Z,J)}}catch(J){K(`feishu: codex trust write failed for ${$}: ${J}`)}try{Tj("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function c4($=c){let Z=Ej(j4(),["login","status",...k.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:k.env($,{...process.env,...v.codex.env})});if(Z.error)K(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
117
- ${Z.stderr}`)}function X5($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var eQ,$V,ZV,p0,Z0,xj=15000,U3="",uQ=0,k7=null,q0,L0,j0,t,iQ=200,nQ,x0,k4,Q5=31457280,fj;var J0=T(()=>{a0();E7();D0();C0();M1();D0();H0();I();g0();f0();k0();F1();pQ();eQ=v.feishu.app_id,$V=v.feishu.app_secret,ZV=v.runtime.projects_root,p0=new Map;Z0=new aQ.Client({appId:eQ,appSecret:$V,disableTokenCache:!1});q0=new Map,L0=new Map;j0=new Map;t=new Map;nQ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;x0=new Map;k4=[0,1000,4000];fj=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as KV}from"node:crypto";function u4($,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 BV($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function X$($){let Z=H$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function e0($){return!H$.has($)}function u0($,Z,J){H$.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 l4($){return H$.get($)?.elementCount??0}function _V($){let Z=H$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function x2($,Z){return H$.get($)?.deadElements.has(Z)??!1}function jV($,Z){let J=H$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function d4($){let Z=X$($);return Z.sequence+=1,Z.sequence}function z5($,Z){$.deadElements.add(Z)}function LV($){return KV("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function dj($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==R.footer)Y.push(J);return KV("sha256").update(Y.sort().join(`
118
- `)).digest("hex")}async function C1($,Z,J){let Y=await k$(),Q=await Y0(`${pj}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(cj)}),V=await Q.json();if(!Q.ok||V?.code!==0){let H=typeof V?.code==="number"?V.code:Q.status,X=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(V?.code??"MISS")} msg=${V?.msg??"MISS"}${X?` log_id=${X}`:""}`);throw z.code=H,z.httpStatus=Q.status,z.logId=X,z}return V?.data}function ij($){return new Promise((Z)=>setTimeout(Z,$))}function nj($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function aj($){let Z=d4($);await C1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function C3($,Z,J,Y,Q=!1,V={}){let H=(X)=>{let z=typeof X==="object"&&X!==null?X:null,W={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:X instanceof Error?X.message:String(X)};if(u4(W.code,W))W.capacityFingerprint=dj(X$($),V.elementId,V.contentFingerprint);try{if(!Q)X$($).onFailure?.(W.code,W)}catch(G){K(`cardkit failure callback ${$}: ${G}`)}try{Y?.(W)}catch(G){K(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(X){if(!nj(X)){K(`cardkit ${Z} ${$}: ${X}`),H(X);return}K(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await aj($)}catch(X){K(`cardkit STREAMING_REOPEN_FAILED ${$}: ${X}`),H(X);return}try{await J()}catch(X){K(`cardkit ${Z} ${$} retry-after-reopen: ${X}`),H(X)}}function oj($){return typeof $==="object"&&$!==null&&$.code===200740}async function $$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:uj,Y=null;for(let Q=0;Q<J.length;Q++){let V=J[Q]??0;if(V>0)await ij(V);try{let H=await C1("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,!oj(H)||Q===J.length-1)throw H;let X=J[Q+1]??0;K(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${X}ms`)}}throw Y}async function U$($){let Z=H$.get($);if(!Z)return;await Z.queue}function F0($,Z,J={},Y){if(e0($))return Promise.resolve();let Q=X$($);if(Q.closing)return Promise.resolve();let V=n$(Z),H=V.element_id,X=LV(V),z=()=>{if(!H)return;z5(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>C3($,"addElement",async()=>{let W=d4($);if(await C1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([V]),sequence:W}),Q.elementCount+=1,H!==R.footer)Q.contentFingerprints.set(H??`#${W}`,X);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(W)=>{z(),Y?.(W.code,W)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:X})),Q.queue}function $0($,Z,J,Y,Q=!0){if(e0($))return Promise.resolve();let V=X$($);if(V.closing)return Promise.resolve();let H=n$(J),X=LV(H),z=()=>{z5(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>C3($,`replaceElement ${Z}`,async()=>{let W=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!W&&!V.failedReplacements.has(Z))return;let G=d4($);if(W)await C1("POST",`/cards/${$}/elements`,{type:W.type??"append",...W.targetElementId?{target_element_id:W.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),V.elementCount++;else await C1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.failedReplacements.delete(Z),Z!==R.footer)V.contentFingerprints.set(Z,X)},(W)=>{if(Q)z();Y?.(W.code,W)},!Q,{elementId:Z,contentFingerprint:X})),V.queue}async function M0($,Z,J,Y={}){if(e0($))return!1;let Q=X$($);if(Q.closing)return!1;let V=!1;return await $0($,Z,J,()=>{V=!0},Y.notifyCardFailure!==!1),!V&&!Q.deadElements.has(Z)}async function qV($,Z,J){if(e0($))return{landed:!1};let Y=X$($);if(Y.closing)return{landed:!1};let Q;return await $0($,Z,J,(V,H)=>{Q=H}),{landed:!Q&&!Y.deadElements.has(Z),...Q?{failure:Q}:{}}}async function e$($,Z,J={}){return(await S2($,Z,J)).landed}async function S2($,Z,J={}){if(e0($))return{landed:!1};let Y=X$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,V;return await F0($,Z,J,(H,X)=>{V=X}),{landed:!V&&!(Q&&Y.deadElements.has(Q)),...V?{failure:V}:{}}}function rj($,Z,J){if(e0($))return Promise.resolve();let Y=X$($);if(Y.closing)return Promise.resolve();let Q=()=>Y.deadElements.has(Z)&&!Y.failedAdds.has(Z)&&!Y.failedReplacements.has(Z);if(Q())return Promise.resolve();return Y.queue=Y.queue.then(()=>C3($,`deleteElement ${Z}`,async()=>{if(Q())return;let V=d4($);await C1("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Y.elementCount=Math.max(0,Y.elementCount-1),Y.contentFingerprints.delete(Z),Y.failedAdds.delete(Z),Y.failedReplacements.delete(Z),z5(Y,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Y.queue}async function PV($,Z){if(e0($))return!1;let J=X$($);if(J.closing)return!1;if(J.deadElements.has(Z)&&!J.failedAdds.has(Z)&&!J.failedReplacements.has(Z))return!0;let Y=!1;return await rj($,Z,()=>{Y=!0}),!Y&&J.deadElements.has(Z)}function k1($,Z){if(e0($)||H$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=b1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},b1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=b1.get($);if(!Q)return;if(e0($)){b1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let V=Q.latest;P0($,{config:{summary:{content:V}}}).then((H)=>{let X=b1.get($);if(H&&X===Q)X.lastSent=V})},lj)}function A0($){let Z=b1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;b1.delete($)}function k3($,Z){return P0($,Z).then(()=>{})}async function P0($,Z){if(e0($))return!1;let J=X$($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>C3($,"patchSettings",async()=>{if(e0($))return;let V=d4($);await C1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:V}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!e0($)}async function w0($){let Z=H$.get($);if(!Z){A0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,A0($),await Z.queue,H$.delete($)}var pj="https://open.feishu.cn/open-apis/cardkit/v1",cj=15000,uj,H$,b1,lj=1500;var y$=T(()=>{a0();J0();I();k0();uj=[0,250,750,1500];H$=new Map,b1=new Map});function y3($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function w3($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function sj($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),V=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,V/Y*100)))}function FV($,Z,J){let Y=sj($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function DV($){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 v3($,Z){let J=DV($);return Z!=null&&Z>0?`${J}/${DV(Z)}`:`${J}/--`}function MV($,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 G5($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function h3($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function tj($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function ej($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function f3($){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 UV($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function OV($){let Z=$.filter((V)=>V.status==="completed").length,J=$.filter((V)=>V.status==="inProgress").length,Y=$.filter((V)=>V.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function $L($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${OV($)}`}function W5($){return typeof $==="number"&&Number.isFinite($)?$:null}function ZL($){let Z=W5($.startedAtMs),J=W5($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${G0((J-Z)/1000)}`}function JL($){let Z=W5($);return Z==null?null:f3(Z)}function YL($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=JL($.preTokens),V=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(V)J.push(`**来源**: ${V}`);return J.length>0?J:["压缩完成,无摘要内容"]}function K5($,Z,J){if($==null||!Number.isFinite($))return null;let Y=FV($,Z,J);return Y?`${Y.used}% · ${v3($,Z)}`:"--"}function B5($){let Z=f3($?.input_tokens??Number.NaN),J=f3($?.cache_read_input_tokens??Number.NaN),Y=f3($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function i4($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",V=Q?"✅":"⏳",H=Q?ZL(Y):"",X=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,z=YL(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
119
- `)}]}}function RV($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let V of $)Y.push(`- ${tj(V.status)} ${V.step}`)}else{let V=J.trim();if(Y.push(""),V)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(V);else Y.push("--")}return Y.join(`
120
- `)}function _5($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:$L($,J)}},expanded:!1,elements:[{tag:"markdown",content:RV($,Z,J)}]}}function n4($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${OV($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:RV($,Z)}]}}function j5($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${UV($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${G0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${UV($.status)}: ${ej($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
121
- `)}]}}function I3($){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}`}`,V=Y.length>0?[{tag:"collapsible_panel",element_id:R.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,...V,{tag:"markdown",element_id:R.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function TV($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function QL($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function VL($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let V=$.options[Q],H=V.description?` · ${e(V.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(V.label)}**${H}`}]})}return Y}function AV($,Z,J,Y){if($.length===0)return null;let Q=$.length,V=[];for(let H=0;H<$.length;H++){let X=$[H];if(!X)continue;let z=TV(X,H,Q),W=Y.get(H);if(W){let G=QL(X,W),B=[`**✅ ${z}**`,`**回答**:${G}`];V.push({tag:"markdown",content:B.join(`
122
- `)});continue}if(H===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),X.options.length>0)V.push(...VL(X,Z,H));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function b2($,Z,J,Y="\uD83E\uDD14",Q){let V=J.length,H=Q?.answered??new Map,X=Q?.currentIdx,z=X===void 0&&H.size>0,W=[],G;if(Q?.waitingFor)G=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",W.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){G=`${Y} 已回答 · ${V}/${V}`,W.push(...AV(J,Z,X,H)??[]);let B=[...H.values()].reverse().find((_)=>_.user)?.user;if(B)W.push({tag:"markdown",content:`
123
- *— 由 ${B} 回答*`})}else if(X!==void 0&&J[X])G=`${Y} 等你确认 · ${X+1}/${V}`,W.push(...AV(J,Z,X,H)??[]);else if(G=`${Y} 等你确认`,J[0])W.push({tag:"markdown",content:`**${TV(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!z&&!Q?.waitingFor,elements:W}}var NV=T(()=>{k0()});import{isAbsolute as L5,relative as HL}from"node:path";function m3($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function p3($){return $==="write_stdin"||$.endsWith(".write_stdin")}function zL($){return m3($)||p3($)}function c3($){return $==="FileChange"||$==="fileChange"}function o4($){return $==="WebSearch"||$==="webSearch"}function u3($){return $==="WebFetch"||$==="webFetch"}function U5($){return $==="MCP"}function r4($){return $==="ImageGeneration"||$==="imageGeneration"}function A5($){return $==="Agent"||$==="Task"}function l3($){return $==="Read"}function d3($){return $==="Write"}function i3($){return $==="Edit"||$==="NotebookEdit"}function n3($){return $==="MultiEdit"}function O5($){return $==="Glob"||$==="Grep"||$==="LS"}function a3($){return $==="TodoWrite"}function o3($){return $==="ExitPlanMode"}function r3($){return $.startsWith(xV)}function SV($){return r3($)?$.slice(xV.length):$}function w1($){if(r3($))return"服务端工具";if(c3($))return"文件变更";if(o4($))return"网页搜索";if(u3($))return"网页读取";if(r4($))return"图片生成";if(l3($))return"读取文件";if(d3($))return"写入文件";if(i3($)||n3($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(a3($))return"更新待办";if(o3($))return"确认计划";if($==="Task")return"子任务";return zL($)?"Bash":$}function $1($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(r3($))return J(WL($,Z),80);if(!Z||typeof Z!=="object")return"";if(m3($))return GL(Z);if(p3($))return KL(Z);if(c3($))return J(jL(Z),80);if(o4($))return J(iV(Z),80);if(u3($))return J(UL(Z),80);if(U5($))return J(OL(Z),80);if(r4($))return J(TL(Z),80);if(A5($))return J(NL(Z),80);if(l3($))return J(LL(Z),80);if(d3($))return J(qL(Z),80);if(i3($))return J(PL(Z),80);if(n3($))return J(DL(Z),80);if(O5($))return J(FL($,Z),80);if(a3($))return J(ML(Z),80);if(o3($))return J(s4(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 WL($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:SV($),Y=s4(Z?.input);return Y?`${J}: ${Y}`:J}function GL($){let Z=(V,H)=>V.length>H?V.slice(0,H)+"…":V,J=CV($);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((V)=>V.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(z2(Y),46)}`}function bV($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function KL($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${bV($)}${J}`}function CV($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=k8(Z);return{description:Y.description||J,command:Y.command}}function l0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
116
+ `,ZV(Z,J)}}catch(J){K(`feishu: codex trust write failed for ${$}: ${J}`)}try{wj("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function c4($=c){let Z=hj(_4(),["login","status",...k.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:k.env($,{...process.env,...v.codex.env})});if(Z.error)K(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
117
+ ${Z.stderr}`)}function W5($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var YV,QV,VV,p0,X0,HV=15000,M3="",aQ=0,v7=null,q0,L0,j0,t,sQ=200,tQ,x0,C3=31457280,dj;var Z0=N(()=>{a0();pQ();b7();D0();C0();U1();D0();V0();h();g0();f0();k0();F1();iQ();YV=v.feishu.app_id,QV=v.feishu.app_secret,VV=v.runtime.projects_root,p0=new Map;X0=new eQ.Client({appId:YV,appSecret:QV,disableTokenCache:!1});q0=new Map,L0=new Map;j0=new Map;t=new Map;tQ=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;x0=new Map;dj=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as qV}from"node:crypto";function u4($,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 PV($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function X$($){let Z=H$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function e0($){return!H$.has($)}function u0($,Z,J){H$.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 l4($){return H$.get($)?.elementCount??0}function DV($){let Z=H$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function E2($,Z){return H$.get($)?.deadElements.has(Z)??!1}function FV($,Z){let J=H$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function d4($){let Z=X$($);return Z.sequence+=1,Z.sequence}function G5($,Z){$.deadElements.add(Z)}function UV($){return qV("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function sj($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==R.footer)Y.push(J);return qV("sha256").update(Y.sort().join(`
118
+ `)).digest("hex")}async function S1($,Z,J){let Y=await r$(),Q=await J0(`${nj}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(aj)}),V=await Q.json();if(!Q.ok||V?.code!==0){let H=typeof V?.code==="number"?V.code:Q.status,X=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(V?.code??"MISS")} msg=${V?.msg??"MISS"}${X?` log_id=${X}`:""}`);throw z.code=H,z.httpStatus=Q.status,z.logId=X,z}return V?.data}function tj($){return new Promise((Z)=>setTimeout(Z,$))}function ej($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function $L($){let Z=d4($);await S1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function y3($,Z,J,Y,Q=!1,V={}){let H=(X)=>{let z=typeof X==="object"&&X!==null?X:null,W={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:X instanceof Error?X.message:String(X)};if(u4(W.code,W))W.capacityFingerprint=sj(X$($),V.elementId,V.contentFingerprint);try{if(!Q)X$($).onFailure?.(W.code,W)}catch(G){K(`cardkit failure callback ${$}: ${G}`)}try{Y?.(W)}catch(G){K(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(X){if(!ej(X)){K(`cardkit ${Z} ${$}: ${X}`),H(X);return}K(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await $L($)}catch(X){K(`cardkit STREAMING_REOPEN_FAILED ${$}: ${X}`),H(X);return}try{await J()}catch(X){K(`cardkit ${Z} ${$} retry-after-reopen: ${X}`),H(X)}}function ZL($){return typeof $==="object"&&$!==null&&$.code===200740}async function $$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:oj,Y=null;for(let Q=0;Q<J.length;Q++){let V=J[Q]??0;if(V>0)await tj(V);try{let H=await S1("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,!ZL(H)||Q===J.length-1)throw H;let X=J[Q+1]??0;K(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${X}ms`)}}throw Y}async function M$($){let Z=H$.get($);if(!Z)return;await Z.queue}function F0($,Z,J={},Y){if(e0($))return Promise.resolve();let Q=X$($);if(Q.closing)return Promise.resolve();let V=i$(Z),H=V.element_id,X=UV(V),z=()=>{if(!H)return;G5(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>y3($,"addElement",async()=>{let W=d4($);if(await S1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([V]),sequence:W}),Q.elementCount+=1,H!==R.footer)Q.contentFingerprints.set(H??`#${W}`,X);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(W)=>{z(),Y?.(W.code,W)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:X})),Q.queue}function $0($,Z,J,Y,Q=!0){if(e0($))return Promise.resolve();let V=X$($);if(V.closing)return Promise.resolve();let H=i$(J),X=UV(H),z=()=>{G5(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>y3($,`replaceElement ${Z}`,async()=>{let W=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!W&&!V.failedReplacements.has(Z))return;let G=d4($);if(W)await S1("POST",`/cards/${$}/elements`,{type:W.type??"append",...W.targetElementId?{target_element_id:W.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),V.elementCount++;else await S1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.failedReplacements.delete(Z),Z!==R.footer)V.contentFingerprints.set(Z,X)},(W)=>{if(Q)z();Y?.(W.code,W)},!Q,{elementId:Z,contentFingerprint:X})),V.queue}async function U0($,Z,J,Y={}){if(e0($))return!1;let Q=X$($);if(Q.closing)return!1;let V=!1;return await $0($,Z,J,()=>{V=!0},Y.notifyCardFailure!==!1),!V&&!Q.deadElements.has(Z)}async function MV($,Z,J){if(e0($))return{landed:!1};let Y=X$($);if(Y.closing)return{landed:!1};let Q;return await $0($,Z,J,(V,H)=>{Q=H}),{landed:!Q&&!Y.deadElements.has(Z),...Q?{failure:Q}:{}}}async function e$($,Z,J={}){return(await x2($,Z,J)).landed}async function x2($,Z,J={}){if(e0($))return{landed:!1};let Y=X$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,V;return await F0($,Z,J,(H,X)=>{V=X}),{landed:!V&&!(Q&&Y.deadElements.has(Q)),...V?{failure:V}:{}}}function JL($,Z,J){if(e0($))return Promise.resolve();let Y=X$($);if(Y.closing)return Promise.resolve();let Q=()=>Y.deadElements.has(Z)&&!Y.failedAdds.has(Z)&&!Y.failedReplacements.has(Z);if(Q())return Promise.resolve();return Y.queue=Y.queue.then(()=>y3($,`deleteElement ${Z}`,async()=>{if(Q())return;let V=d4($);await S1("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Y.elementCount=Math.max(0,Y.elementCount-1),Y.contentFingerprints.delete(Z),Y.failedAdds.delete(Z),Y.failedReplacements.delete(Z),G5(Y,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Y.queue}async function AV($,Z){if(e0($))return!1;let J=X$($);if(J.closing)return!1;if(J.deadElements.has(Z)&&!J.failedAdds.has(Z)&&!J.failedReplacements.has(Z))return!0;let Y=!1;return await JL($,Z,()=>{Y=!0}),!Y&&J.deadElements.has(Z)}function b1($,Z){if(e0($)||H$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=x1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},x1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=x1.get($);if(!Q)return;if(e0($)){x1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let V=Q.latest;P0($,{config:{summary:{content:V}}}).then((H)=>{let X=x1.get($);if(H&&X===Q)X.lastSent=V})},rj)}function A0($){let Z=x1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;x1.delete($)}function w3($,Z){return P0($,Z).then(()=>{})}async function P0($,Z){if(e0($))return!1;let J=X$($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>y3($,"patchSettings",async()=>{if(e0($))return;let V=d4($);await S1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:V}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!e0($)}async function w0($){let Z=H$.get($);if(!Z){A0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,A0($),await Z.queue,H$.delete($)}var nj="https://open.feishu.cn/open-apis/cardkit/v1",aj=15000,oj,H$,x1,rj=1500;var k$=N(()=>{a0();Z0();h();k0();oj=[0,250,750,1500];H$=new Map,x1=new Map});function v3($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function f3($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function YL($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),V=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,V/Y*100)))}function RV($,Z,J){let Y=YL($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function OV($){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 h3($,Z){let J=OV($);return Z!=null&&Z>0?`${J}/${OV(Z)}`:`${J}/--`}function NV($,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 B5($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function g3($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function QL($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function VL($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function I3($){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 TV($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function xV($){let Z=$.filter((V)=>V.status==="completed").length,J=$.filter((V)=>V.status==="inProgress").length,Y=$.filter((V)=>V.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function HL($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${xV($)}`}function K5($){return typeof $==="number"&&Number.isFinite($)?$:null}function XL($){let Z=K5($.startedAtMs),J=K5($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${G0((J-Z)/1000)}`}function zL($){let Z=K5($);return Z==null?null:I3(Z)}function WL($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=zL($.preTokens),V=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(V)J.push(`**来源**: ${V}`);return J.length>0?J:["压缩完成,无摘要内容"]}function _5($,Z,J){if($==null||!Number.isFinite($))return null;let Y=RV($,Z,J);return Y?`${Y.used}% · ${h3($,Z)}`:"--"}function j5($){let Z=I3($?.input_tokens??Number.NaN),J=I3($?.cache_read_input_tokens??Number.NaN),Y=I3($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function i4($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",V=Q?"✅":"⏳",H=Q?XL(Y):"",X=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,z=WL(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
119
+ `)}]}}function SV($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let V of $)Y.push(`- ${QL(V.status)} ${V.step}`)}else{let V=J.trim();if(Y.push(""),V)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(V);else Y.push("--")}return Y.join(`
120
+ `)}function L5($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:HL($,J)}},expanded:!1,elements:[{tag:"markdown",content:SV($,Z,J)}]}}function n4($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${xV($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:SV($,Z)}]}}function q5($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${TV($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${G0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${TV($.status)}: ${VL($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
121
+ `)}]}}function m3($){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}`}`,V=Y.length>0?[{tag:"collapsible_panel",element_id:R.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,...V,{tag:"markdown",element_id:R.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function bV($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function GL($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function KL($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let V=$.options[Q],H=V.description?` · ${e(V.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(V.label)}**${H}`}]})}return Y}function EV($,Z,J,Y){if($.length===0)return null;let Q=$.length,V=[];for(let H=0;H<$.length;H++){let X=$[H];if(!X)continue;let z=bV(X,H,Q),W=Y.get(H);if(W){let G=GL(X,W),B=[`**✅ ${z}**`,`**回答**:${G}`];V.push({tag:"markdown",content:B.join(`
122
+ `)});continue}if(H===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),X.options.length>0)V.push(...KL(X,Z,H));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function S2($,Z,J,Y="\uD83E\uDD14",Q){let V=J.length,H=Q?.answered??new Map,X=Q?.currentIdx,z=X===void 0&&H.size>0,W=[],G;if(Q?.waitingFor)G=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",W.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){G=`${Y} 已回答 · ${V}/${V}`,W.push(...EV(J,Z,X,H)??[]);let B=[...H.values()].reverse().find((_)=>_.user)?.user;if(B)W.push({tag:"markdown",content:`
123
+ *— 由 ${B} 回答*`})}else if(X!==void 0&&J[X])G=`${Y} 等你确认 · ${X+1}/${V}`,W.push(...EV(J,Z,X,H)??[]);else if(G=`${Y} 等你确认`,J[0])W.push({tag:"markdown",content:`**${bV(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!z&&!Q?.waitingFor,elements:W}}var CV=N(()=>{k0()});import{isAbsolute as P5,relative as BL}from"node:path";function c3($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function u3($){return $==="write_stdin"||$.endsWith(".write_stdin")}function jL($){return c3($)||u3($)}function l3($){return $==="FileChange"||$==="fileChange"}function o4($){return $==="WebSearch"||$==="webSearch"}function d3($){return $==="WebFetch"||$==="webFetch"}function O5($){return $==="MCP"}function r4($){return $==="ImageGeneration"||$==="imageGeneration"}function R5($){return $==="Agent"||$==="Task"}function i3($){return $==="Read"}function n3($){return $==="Write"}function a3($){return $==="Edit"||$==="NotebookEdit"}function o3($){return $==="MultiEdit"}function N5($){return $==="Glob"||$==="Grep"||$==="LS"}function r3($){return $==="TodoWrite"}function s3($){return $==="ExitPlanMode"}function t3($){return $.startsWith(yV)}function wV($){return t3($)?$.slice(yV.length):$}function k1($){if(t3($))return"服务端工具";if(l3($))return"文件变更";if(o4($))return"网页搜索";if(d3($))return"网页读取";if(r4($))return"图片生成";if(i3($))return"读取文件";if(n3($))return"写入文件";if(a3($)||o3($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(r3($))return"更新待办";if(s3($))return"确认计划";if($==="Task")return"子任务";return jL($)?"Bash":$}function $1($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(t3($))return J(LL($,Z),80);if(!Z||typeof Z!=="object")return"";if(c3($))return qL(Z);if(u3($))return PL(Z);if(l3($))return J(UL(Z),80);if(o4($))return J(sV(Z),80);if(d3($))return J(EL(Z),80);if(O5($))return J(SL(Z),80);if(r4($))return J(CL(Z),80);if(R5($))return J(kL(Z),80);if(i3($))return J(ML(Z),80);if(n3($))return J(AL(Z),80);if(a3($))return J(OL(Z),80);if(o3($))return J(RL(Z),80);if(N5($))return J(NL($,Z),80);if(r3($))return J(TL(Z),80);if(s3($))return J(s4(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 LL($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:wV($),Y=s4(Z?.input);return Y?`${J}: ${Y}`:J}function qL($){let Z=(V,H)=>V.length>H?V.slice(0,H)+"…":V,J=fV($);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((V)=>V.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(H2(Y),46)}`}function vV($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function PL($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${vV($)}${J}`}function fV($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=y8(Z);return{description:Y.description||J,command:Y.command}}function l0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
124
124
  ${$}
125
- ${J}`}function w$($,Z=XL,J=""){if($.length<=Z)return l0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,l0(`${Y}
125
+ ${J}`}function y$($,Z=_L,J=""){if($.length<=Z)return l0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,l0(`${Y}
126
126
  ... output 已截断 ...`,J)].join(`
127
- `)}function g($){return"`"+String($??"").replace(/`/g,"'")+"`"}function Z$($,Z=3000){return l0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function s4($){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 kV($,Z,J){let Y=CV($),Q=Y.command,V=Y.description,H=[];if(V)H.push(`**目的**: ${V}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${g(X)}`);if($?.source)H.push(`**source**: ${g($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(l0(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(w$(Z));return H.join(`
128
- `)}function yV($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${bV($)}`),Q!==void 0)Y.push(`**session**: ${g(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(l0(V))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(w$(Z));return Y.join(`
129
- `)}function wV($){return Array.isArray($?.changes)?$.changes:[]}function vV($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function a4($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&L5(J)&&L5(Z)){let Y=HL(Z,J);if(Y&&!Y.startsWith("..")&&!L5(Y))return Y}return J}function BL($){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 fV($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function P5($){let Z=BL($);if(fV($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function D5($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function F5($){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 hV($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function M5($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function _L($){return $.length>1800?$.slice(0,1800)+`
130
- ... diff 已截断 ...`:$}function jL($){let Z=wV($),J=vV($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",W=$?.grantRoot?a4($.grantRoot):"";if(z&&W)return`${z} · ${W}`;return z||(W?`申请修改 ${W}`:"")}let Y=Z.map((z)=>F5(D5(z))).reduce(hV,{added:0,removed:0}),Q=M5(Y),V=[...new Set(Z.map(P5))],H=a4(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${V[0]} ${H}${X}`;return`${Z.length} 个文件 · ${V.join("/")} · ${H} 等${X}`}function IV($,Z,J){let Y=wV($),Q=vV($),V=[];if(Y.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"";if(W)V.push(`**原因**: ${W}`);if($?.grantRoot)V.push(`**范围**: ${g(a4($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(l0(Z.slice(0,3000)));return V.length>0?V.join(`
131
- `):l0(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((W)=>F5(D5(W))).reduce(hV,{added:0,removed:0}),X=M5(H);if(V.push(`**文件**: ${Y.length} 个`),X)V.push(`**行数**: ${X}`);if($?.status)V.push(`**状态**: ${g($.status)}`);let z=Y.slice(0,5);for(let W of z){let G=D5(W),B=M5(F5(G)),_=a4(W?.path,Q),j=B?`**${P5(W)}** ${g(_)} · ${B}`:`**${P5(W)}** ${g(_)}`;V.push(""),V.push(j);let q=fV(W);if(q)V.push(`来自 ${g(a4(q,Q))}`);V.push(G?l0(_L(G),"diff"):"_无 diff 内容_")}if(Y.length>z.length)V.push(""),V.push(`还有 ${Y.length-z.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
132
- `)}function Z1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function LL($){let Z=Z1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function qL($){let Z=Z1($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function PL($){let Z=Z1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function DL($){let Z=Z1($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function FL($,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 gV($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function ML($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let V=gV(Q?.status);J.set(V,(J.get(V)??0)+1)}let Y=[...J.entries()].map(([Q,V])=>`${Q} ${V}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function UL($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function C2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(w$(Z,1200))}function mV($,Z,J){let Y=[],Q=Z1($);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(`
133
- `):Z$($??{},2000)}function pV($,Z,J){let Y=[],Q=Z1($),V=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${g(Q)}`);if(V){let H=V.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${V.length} 字符`),Y.push(w$(V,1200))}if(J)Y.push(""),Y.push(J);return C2(Y,Z),Y.length>0?Y.join(`
134
- `):Z$($??{},2000)}function cV($,Z,J){let Y=[],Q=Z1($);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(w$($.old_string,800));let V=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(V)Y.push(""),Y.push("**替换为**"),Y.push(w$(V,800));if(J)Y.push(""),Y.push(J);return C2(Y,Z),Y.length>0?Y.join(`
135
- `):Z$($??{},2000)}function uV($,Z,J){let Y=[],Q=Z1($),V=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${g(Q)}`);Y.push(`**编辑**: ${V.length} 处`);for(let[H,X]of V.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${X?.replace_all?" · 全局替换":""}**`),typeof X?.old_string==="string")Y.push("查找:"),Y.push(w$(X.old_string,500));if(typeof X?.new_string==="string")Y.push("替换为:"),Y.push(w$(X.new_string,500))}if(V.length>5)Y.push(""),Y.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return C2(Y,Z),Y.join(`
136
- `)}function lV($,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 C2(Q,J),Q.join(`
137
- `)}function dV($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let V of Y.slice(0,12)){let H=gV(V?.status),X=String(V?.content??V?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${X}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return C2(Q,Z),Q.join(`
138
- `)}function R5($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function T5($,Z){return R5(Z)??$?.action??{}}function N5($,Z){let J=T5($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((V)=>typeof V==="string"&&V.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 E5($,Z){let J=T5($,Z);return String(J?.url??$?.url??"")}function iV($){let Z=N5($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=E5($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function AL($,Z){let J=N5($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=E5($,Z);if(Y)return Y;return iV($)}function nV($,Z,J){let Y=T5($,Z),Q=N5($,Z),V=E5($,Z),H=[],X=typeof Y?.type==="string"?Y.type:"";if(X==="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(X==="open_page"){if(H.push("**动作**: 打开页面"),V)H.push(`**URL**: ${g(V)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),V)H.push(`**URL**: ${g(V)}`);if(Y?.pattern)H.push(`**关键词**: ${g(Y.pattern)}`)}else if(H.push(`**动作**: ${X?g(X):"网页搜索"}`),V)H.push(`**URL**: ${g(V)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!V&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(l0(Z.slice(0,3000),"json"));return H.join(`
139
- `)}function aV($,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 C2(Y,Z),Y.join(`
140
- `)}function OL($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=s4($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function oV($,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(Z$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let V=R5(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),V&&Array.isArray(V.content)){let H=V.content.map((X)=>typeof X?.text==="string"?X.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
127
+ `)}function g($){return"`"+String($??"").replace(/`/g,"'")+"`"}function Z$($,Z=3000){return l0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function s4($){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 hV($,Z,J){let Y=fV($),Q=Y.command,V=Y.description,H=[];if(V)H.push(`**目的**: ${V}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${g(X)}`);if($?.source)H.push(`**source**: ${g($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(l0(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(y$(Z));return H.join(`
128
+ `)}function IV($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${vV($)}`),Q!==void 0)Y.push(`**session**: ${g(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(l0(V))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(y$(Z));return Y.join(`
129
+ `)}function gV($){return Array.isArray($?.changes)?$.changes:[]}function mV($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function a4($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&P5(J)&&P5(Z)){let Y=BL(Z,J);if(Y&&!Y.startsWith("..")&&!P5(Y))return Y}return J}function DL($){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 pV($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function F5($){let Z=DL($);if(pV($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function U5($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function M5($){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 cV($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function A5($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function FL($){return $.length>1800?$.slice(0,1800)+`
130
+ ... diff 已截断 ...`:$}function UL($){let Z=gV($),J=mV($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",W=$?.grantRoot?a4($.grantRoot):"";if(z&&W)return`${z} · ${W}`;return z||(W?`申请修改 ${W}`:"")}let Y=Z.map((z)=>M5(U5(z))).reduce(cV,{added:0,removed:0}),Q=A5(Y),V=[...new Set(Z.map(F5))],H=a4(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${V[0]} ${H}${X}`;return`${Z.length} 个文件 · ${V.join("/")} · ${H} 等${X}`}function uV($,Z,J){let Y=gV($),Q=mV($),V=[];if(Y.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"";if(W)V.push(`**原因**: ${W}`);if($?.grantRoot)V.push(`**范围**: ${g(a4($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(l0(Z.slice(0,3000)));return V.length>0?V.join(`
131
+ `):l0(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((W)=>M5(U5(W))).reduce(cV,{added:0,removed:0}),X=A5(H);if(V.push(`**文件**: ${Y.length} 个`),X)V.push(`**行数**: ${X}`);if($?.status)V.push(`**状态**: ${g($.status)}`);let z=Y.slice(0,5);for(let W of z){let G=U5(W),B=A5(M5(G)),_=a4(W?.path,Q),j=B?`**${F5(W)}** ${g(_)} · ${B}`:`**${F5(W)}** ${g(_)}`;V.push(""),V.push(j);let q=pV(W);if(q)V.push(`来自 ${g(a4(q,Q))}`);V.push(G?l0(FL(G),"diff"):"_无 diff 内容_")}if(Y.length>z.length)V.push(""),V.push(`还有 ${Y.length-z.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
132
+ `)}function Z1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function ML($){let Z=Z1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function AL($){let Z=Z1($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function OL($){let Z=Z1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function RL($){let Z=Z1($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function NL($,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 lV($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function TL($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let V=lV(Q?.status);J.set(V,(J.get(V)??0)+1)}let Y=[...J.entries()].map(([Q,V])=>`${Q} ${V}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function EL($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function b2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(y$(Z,1200))}function dV($,Z,J){let Y=[],Q=Z1($);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(`
133
+ `):Z$($??{},2000)}function iV($,Z,J){let Y=[],Q=Z1($),V=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${g(Q)}`);if(V){let H=V.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${V.length} 字符`),Y.push(y$(V,1200))}if(J)Y.push(""),Y.push(J);return b2(Y,Z),Y.length>0?Y.join(`
134
+ `):Z$($??{},2000)}function nV($,Z,J){let Y=[],Q=Z1($);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(y$($.old_string,800));let V=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(V)Y.push(""),Y.push("**替换为**"),Y.push(y$(V,800));if(J)Y.push(""),Y.push(J);return b2(Y,Z),Y.length>0?Y.join(`
135
+ `):Z$($??{},2000)}function aV($,Z,J){let Y=[],Q=Z1($),V=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${g(Q)}`);Y.push(`**编辑**: ${V.length} 处`);for(let[H,X]of V.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${X?.replace_all?" · 全局替换":""}**`),typeof X?.old_string==="string")Y.push("查找:"),Y.push(y$(X.old_string,500));if(typeof X?.new_string==="string")Y.push("替换为:"),Y.push(y$(X.new_string,500))}if(V.length>5)Y.push(""),Y.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return b2(Y,Z),Y.join(`
136
+ `)}function oV($,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 b2(Q,J),Q.join(`
137
+ `)}function rV($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let V of Y.slice(0,12)){let H=lV(V?.status),X=String(V?.content??V?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${X}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return b2(Q,Z),Q.join(`
138
+ `)}function T5($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function E5($,Z){return T5(Z)??$?.action??{}}function x5($,Z){let J=E5($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((V)=>typeof V==="string"&&V.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 S5($,Z){let J=E5($,Z);return String(J?.url??$?.url??"")}function sV($){let Z=x5($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=S5($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function xL($,Z){let J=x5($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=S5($,Z);if(Y)return Y;return sV($)}function tV($,Z,J){let Y=E5($,Z),Q=x5($,Z),V=S5($,Z),H=[],X=typeof Y?.type==="string"?Y.type:"";if(X==="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(X==="open_page"){if(H.push("**动作**: 打开页面"),V)H.push(`**URL**: ${g(V)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),V)H.push(`**URL**: ${g(V)}`);if(Y?.pattern)H.push(`**关键词**: ${g(Y.pattern)}`)}else if(H.push(`**动作**: ${X?g(X):"网页搜索"}`),V)H.push(`**URL**: ${g(V)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!V&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(l0(Z.slice(0,3000),"json"));return H.join(`
139
+ `)}function eV($,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 b2(Y,Z),Y.join(`
140
+ `)}function SL($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=s4($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function $H($,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(Z$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let V=T5(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),V&&Array.isArray(V.content)){let H=V.content.map((X)=>typeof X?.text==="string"?X.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
141
141
  `).slice(0,3000));if(V.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(Z$(V.structuredContent,2000));if(H.length===0&&!V.structuredContent)Y.push(Z$(V,3000))}else Y.push(V?Z$(V,3000):l0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
142
- `):Z$($??{},2000)}function RL($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${g(typeof Z?.tool==="string"&&Z.tool?Z.tool:SV($))}`],V=Z?.input;if(V&&typeof V==="object")if(Q.push(""),Q.push("**input**"),Object.keys(V).length>0)Q.push(Z$(V,2000));else Q.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Q.push(`**input**: ${g(V)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(w$(J,3000));return Q.join(`
143
- `)}function TL($){return typeof $?.status==="string"?$.status:""}function rV($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${g($.status)}`);if($?.prompt)Q.push("","**提示词**",l0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",l0(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(`
144
- `):Z$($??{},2000)}function NL($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",V=Y||Q||J;return Z&&V?`${Z}: ${V}`:V||Z}function g3($,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=R5(Z);Y.push(Q?Z$(Q,3000):l0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
145
- `):Z$($??{},2000)}function A$($,Z,J,Y,Q="⏳",V,H){let X=o4(Z)&&Y!=null?AL(J,Y):$1(Z,J),z=X.length>80?X.slice(0,80)+"…":X,W=w1(Z),G=z?`${Q} \uD83D\uDD27 ${W}: ${z}`:`${Q} \uD83D\uDD27 ${W}`,B=V?`
142
+ `):Z$($??{},2000)}function bL($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${g(typeof Z?.tool==="string"&&Z.tool?Z.tool:wV($))}`],V=Z?.input;if(V&&typeof V==="object")if(Q.push(""),Q.push("**input**"),Object.keys(V).length>0)Q.push(Z$(V,2000));else Q.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Q.push(`**input**: ${g(V)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(y$(J,3000));return Q.join(`
143
+ `)}function CL($){return typeof $?.status==="string"?$.status:""}function ZH($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${g($.status)}`);if($?.prompt)Q.push("","**提示词**",l0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",l0(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(`
144
+ `):Z$($??{},2000)}function kL($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",V=Y||Q||J;return Z&&V?`${Z}: ${V}`:V||Z}function p3($,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=T5(Z);Y.push(Q?Z$(Q,3000):l0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
145
+ `):Z$($??{},2000)}function A$($,Z,J,Y,Q="⏳",V,H){let X=o4(Z)&&Y!=null?xL(J,Y):$1(Z,J),z=X.length>80?X.slice(0,80)+"…":X,W=k1(Z),G=z?`${Q} \uD83D\uDD27 ${W}: ${z}`:`${Q} \uD83D\uDD27 ${W}`,B=V?`
146
146
 
147
- ${V}`:"",_=m3(Z)?kV(J,Y,V):p3(Z)?yV(J,Y,V):r3(Z)?RL(Z,J,Y,V):c3(Z)?IV(J,Y,V):o4(Z)?nV(J,Y,V):u3(Z)?aV(J,Y,V):U5(Z)?oV(J,Y,V):r4(Z)?rV(J,Y,V,H):l3(Z)?mV(J,Y,V):d3(Z)?pV(J,Y,V):i3(Z)?cV(J,Y,V):n3(Z)?uV(J,Y,V):O5(Z)?lV(Z,J,Y,V):a3(Z)?dV(J,Y,V):o3(Z)?g3({prompt:s4(J)||"提交计划"},Y,V):A5(Z)?g3(J,Y,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+B+(Y!=null?`
147
+ ${V}`:"",_=c3(Z)?hV(J,Y,V):u3(Z)?IV(J,Y,V):t3(Z)?bL(Z,J,Y,V):l3(Z)?uV(J,Y,V):o4(Z)?tV(J,Y,V):d3(Z)?eV(J,Y,V):O5(Z)?$H(J,Y,V):r4(Z)?ZH(J,Y,V,H):i3(Z)?dV(J,Y,V):n3(Z)?iV(J,Y,V):a3(Z)?nV(J,Y,V):o3(Z)?aV(J,Y,V):N5(Z)?oV(Z,J,Y,V):r3(Z)?rV(J,Y,V):s3(Z)?p3({prompt:s4(J)||"提交计划"},Y,V):R5(Z)?p3(J,Y,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+B+(Y!=null?`
148
148
  ---
149
149
  **output:**
150
150
  \`\`\`
151
- `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:e(_)},...r4(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function t4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),V=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=EV(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((z)=>{let W=EV(z);return W?`\`${W}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(X.join(`
152
- `))}]}}function EV($){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 e4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),V=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=$1("Read",Z[0]?.input);return z?`${V} \uD83D\uDD27 Read: ${z}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,X=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(X.join(`
153
- `))}]}}function x5($,Z,J,Y){let Q=$1(Z,J),V=w1(Z),H=Q?`\uD83D\uDD10 等审批 · ${V}: ${Q}`:`\uD83D\uDD10 等审批 · ${V}`,X=m3(Z)?kV(J,null):p3(Z)?yV(J,null):c3(Z)?IV(J,null):o4(Z)?nV(J,null):u3(Z)?aV(J,null):U5(Z)?oV(J,null):r4(Z)?rV(J,null):l3(Z)?mV(J,null):d3(Z)?pV(J,null):i3(Z)?cV(J,null):n3(Z)?uV(J,null):O5(Z)?lV(Z,J,null):a3(Z)?dV(J,null):o3(Z)?g3({prompt:s4(J)||"提交计划"},null):A5(Z)?g3(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[q5("✅ 允许","primary",Y,"allow"),q5("♾️ 始终允许","default",Y,"allow_always"),q5("❌ 拒绝","danger",Y,"deny")]}]}}function q5($,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 XL=300,xV="server_tool:";var sV=T(()=>{k0();d9()});import{execFile as EL}from"node:child_process";import{readFileSync as S5,statfsSync as xL,statSync as tV}from"node:fs";import{cpus as SL,homedir as bL}from"node:os";import{promisify as CL}from"node:util";function yL(){try{let $=S5("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:SL().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return K(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function wL(){try{let $=S5("/proc/meminfo","utf8"),Z=(V)=>{let H=$.match(new RegExp(`^${V}:\\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 K(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function eV($,Z){try{let J=xL(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,V=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:V,percent:Math.round(V/Y*100)}}catch(J){return K(`sysinfo: statfs ${Z} failed: ${J}`),null}}function vL(){let $=[],Z=eV("/","/");if(Z)$.push(Z);let J=bL();if(J&&J!=="/"){let Y=!1;try{let Q=tV("/"),V=tV(J);Y=Q.dev===V.dev}catch{}if(!Y){let Q=eV("$HOME",J);if(Q)$.push(Q)}}return $}function fL(){try{let $=S5("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function $H($,Z=2000){try{let{stdout:J}=await kL("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return K(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function ZH($){return JH.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function hL(){let $=await $H(["list-units","--type=service","--all","--no-legend","--plain",...JH.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
154
- `).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(!ZH(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await $H(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=fL(),V=Y.split(/\n\s*\n/),H=[],X=(z)=>{let W=parseInt(z??"0",10);if(W<=0||Q===null)return null;return Math.max(0,Q-W/1e6)};for(let z of V){let W={};for(let B of z.split(`
155
- `)){let _=B.indexOf("=");if(_<=0)continue;W[B.slice(0,_)]=B.slice(_+1)}let G=W.Id??"";if(!ZH(G))continue;H.push({name:G.replace(/\.service$/,""),active:W.ActiveState??"unknown",sub:W.SubState??"",lastActiveAgoSec:X(W.ActiveEnterTimestampMonotonic),stateAgoSec:X(W.StateChangeTimestampMonotonic)})}return H.sort((z,W)=>z.name.localeCompare(W.name)),{services:H,error:null}}async function YH(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=yL(),Z=wL(),J=vL(),{services:Y,error:Q}=await hL();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var kL,JH,$9="cc-* / codex-*";var b5=T(()=>{I();kL=CL(EL),JH=["cc-","codex-"]});function J9($,Z){return Z}function C5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:R.footer,content:J9($.title,$.status)}]}}}function QH($){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 IL($){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 Z9($){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 cL($){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 uL($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${$9} _n/a_`].join(`
156
- `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:V}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${V.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${QH($.mem.usedBytes)}/${QH($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${$9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${$9} _无_`);else{Z.push(`**服务** ${$9} (${$.services.length})`);for(let J of $.services){let Y=pL[J.active]??"·",Q=J.lastActiveAgoSec,V=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(V!=null)H.push(`已运行 ${Z9(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${Z9(Q*1000)}前`);else H.push("从未启动");if(V!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${Z9(V*1000)}`)}}else if(V!=null)H.push(`已 ${Z9(V*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
157
- `)}function lL($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=gL[J.status]??"·",Q=mL[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${Z9(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"",X=J.codexAccountName===void 0?"":` · Codex:${J1(z$(J.codexAccountName))}`;return` · ${Y} \`${J.name}\` · ${Q}${V}${H}${X}`}).join(`
158
- `)}function s3($,Z=R.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:lL($)}]}}function dL($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${h5($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
159
- `)}function t3($,Z=R.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:dL($)}}function e3($,Z=R.consoleHost){let J=cL($);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:uL($)}]}}function $6($){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(iL).join(" · ")}`}function iL($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function nL($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.flatMap((Y)=>O2(Y,Y.label).map((Q)=>Q.content))].join(`
160
- `):$6($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=VH($);return J?`${Z}
161
- ${J}`:Z}function VH($){return $?.resetCredits===void 0?"":`**重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`}function Y9($){let Z=$.unifiedUsage;if(Z?.state==="ok"&&Z.kind!=="balance"&&!Z.quota&&Z.windows.length){let J=[];for(let Q of Z.windows){if(J.length)J.push({tag:"hr"});J.push(...O2(Q,Q.label))}let Y=VH(Z);if(Y)J.push({tag:"hr"},{tag:"markdown",content:Y});return{tag:"collapsible_panel",element_id:R.consoleUsage,expanded:!0,header:{title:{tag:"plain_text",content:"\uD83D\uDCCA 额度"},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"12px",vertical_spacing:"4px",elements:J}}return{tag:"markdown",element_id:R.consoleUsage,content:nL(Z)}}function HH($,Z){return[t3($,Z),s3($),e3($.sysinfo),Y9($)]}function k5($){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:HH($)}}}function y5($){return k2($.sessionName,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${J1($.currentDisplay??"未选择")}
162
- 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:R.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)=>aL(Y,$.panelId))}]:[]})]})}function aL($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${z$($.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:`**${z$($.display)}**
163
- ${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 w5($){return k2($.sessionName,XH($))}function v5($){return k2($.sessionName,Y6($))}function Z6($){return k2($.sessionName,Q6($),"green")}function k2($,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 XH($){let Z=sL($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${zH($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
164
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?oL($.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 oL($,Z){let{sourceId:J,page:Y,totalPages:Q}=Z,V=(H,X)=>({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:X}}]}]});return[{tag:"markdown",content:`第 ${Y+1} / ${Q} 页`},{tag:"column_set",columns:[...Y>0?[V("上一页",Y-1)]:[],...Y+1<Q?[V("下一页",Y+1)]:[]]}]}function J6($,Z="cancelled"){return k2($,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function f5($,Z,J){return k2($,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
165
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function y2($,Z,J){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
166
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function Y6($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${$q($.model)}`,`当前: ${zH($.currentModel,$.currentEffort)}`].join(`
167
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>tL($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function Q6($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",J1(WH($.model,$.effort,$.provider)),z$($.scope)].join(`
168
- `)}]}}function rL($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${z$($.displayName)}** · 未配置
169
- ${z$($.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?`**${z$($.displayName)}**`:`**${J1($.model)}**`,V=[$.isDefault?`${h5($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
170
- `+z$(Zq($.description,110)):"",X=(W,G)=>({tag:"button",text:{tag:"plain_text",content:G},type:"default",behaviors:[{type:"callback",value:{kind:W,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?J1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
171
- `)+H}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[X("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:eL($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?X("model_custom_remove","删"):X("model_remove","隐")]:[]]}]}]}function sL($,Z,J,Y=!1){let Q=[{title:"Codex",models:$.filter((X)=>(X.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((X)=>X.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((X)=>X.provider==="dsh")}].filter((X)=>X.models.length>0),V=(X)=>X.flatMap((z,W)=>[...W?[{tag:"hr"}]:[],...rL(z,Z,J,Y)]);if(Q.length<=1)return V($);let H=[];for(let X of Q)H.push({tag:"markdown",content:`**${X.title}**`}),H.push(...V(X.models));return H}function tL($,Z,J,Y,Q){let V=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",V?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":z$(Z.effort)}**`,H,Z.description?z$(Z.description):""].filter(Boolean).join(`
172
- `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:V?"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 eL($,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 $q($){return $.displayName&&$.displayName!==$.model?`${z$($.displayName)} (${J1($.model)})`:J1($.model)}function zH($,Z){return J1(WH($,Z))}function WH($,Z,J){let Y=J&&J!=="codex"?`${h5(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function h5($){return _$($??"codex")}function Zq($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function z$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function J1($){return"`"+$.replace(/`/g,"\\`")+"`"}function v$($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${G0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${IL($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var gL,mL,pL;var GH=T(()=>{D0();b5();k0();gL={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},mL={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},pL={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function I5($){let Z=Qq($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:Jq($.notice)},body:{elements:[...$.notice?[Yq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(Vq)]}}}function Jq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function Yq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
151
+ `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:e(_)},...r4(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function t4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),V=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=kV(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((z)=>{let W=kV(z);return W?`\`${W}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(X.join(`
152
+ `))}]}}function kV($){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 e4($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),V=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let z=$1("Read",Z[0]?.input);return z?`${V} \uD83D\uDD27 Read: ${z}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,X=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:e(X.join(`
153
+ `))}]}}function b5($,Z,J,Y){let Q=$1(Z,J),V=k1(Z),H=Q?`\uD83D\uDD10 等审批 · ${V}: ${Q}`:`\uD83D\uDD10 等审批 · ${V}`,X=c3(Z)?hV(J,null):u3(Z)?IV(J,null):l3(Z)?uV(J,null):o4(Z)?tV(J,null):d3(Z)?eV(J,null):O5(Z)?$H(J,null):r4(Z)?ZH(J,null):i3(Z)?dV(J,null):n3(Z)?iV(J,null):a3(Z)?nV(J,null):o3(Z)?aV(J,null):N5(Z)?oV(Z,J,null):r3(Z)?rV(J,null):s3(Z)?p3({prompt:s4(J)||"提交计划"},null):R5(Z)?p3(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[D5("✅ 允许","primary",Y,"allow"),D5("♾️ 始终允许","default",Y,"allow_always"),D5("❌ 拒绝","danger",Y,"deny")]}]}}function D5($,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 _L=300,yV="server_tool:";var JH=N(()=>{k0();d9()});import{execFile as yL}from"node:child_process";import{readFileSync as C5,statfsSync as wL,statSync as YH}from"node:fs";import{cpus as vL,homedir as fL}from"node:os";import{promisify as hL}from"node:util";function gL(){try{let $=C5("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:vL().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return K(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function mL(){try{let $=C5("/proc/meminfo","utf8"),Z=(V)=>{let H=$.match(new RegExp(`^${V}:\\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 K(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function QH($,Z){try{let J=wL(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,V=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:V,percent:Math.round(V/Y*100)}}catch(J){return K(`sysinfo: statfs ${Z} failed: ${J}`),null}}function pL(){let $=[],Z=QH("/","/");if(Z)$.push(Z);let J=fL();if(J&&J!=="/"){let Y=!1;try{let Q=YH("/"),V=YH(J);Y=Q.dev===V.dev}catch{}if(!Y){let Q=QH("$HOME",J);if(Q)$.push(Q)}}return $}function cL(){try{let $=C5("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function VH($,Z=2000){try{let{stdout:J}=await IL("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return K(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function HH($){return XH.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function uL(){let $=await VH(["list-units","--type=service","--all","--no-legend","--plain",...XH.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
154
+ `).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(!HH(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await VH(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=cL(),V=Y.split(/\n\s*\n/),H=[],X=(z)=>{let W=parseInt(z??"0",10);if(W<=0||Q===null)return null;return Math.max(0,Q-W/1e6)};for(let z of V){let W={};for(let B of z.split(`
155
+ `)){let _=B.indexOf("=");if(_<=0)continue;W[B.slice(0,_)]=B.slice(_+1)}let G=W.Id??"";if(!HH(G))continue;H.push({name:G.replace(/\.service$/,""),active:W.ActiveState??"unknown",sub:W.SubState??"",lastActiveAgoSec:X(W.ActiveEnterTimestampMonotonic),stateAgoSec:X(W.StateChangeTimestampMonotonic)})}return H.sort((z,W)=>z.name.localeCompare(W.name)),{services:H,error:null}}async function zH(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=gL(),Z=mL(),J=pL(),{services:Y,error:Q}=await uL();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var IL,XH,$9="cc-* / codex-*";var k5=N(()=>{h();IL=hL(yL),XH=["cc-","codex-"]});function J9($,Z){return Z}function y5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:R.footer,content:J9($.title,$.status)}]}}}function WH($){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 lL($){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 Z9($){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 aL($){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 oL($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${$9} _n/a_`].join(`
156
+ `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:V}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${V.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${WH($.mem.usedBytes)}/${WH($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${$9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${$9} _无_`);else{Z.push(`**服务** ${$9} (${$.services.length})`);for(let J of $.services){let Y=nL[J.active]??"·",Q=J.lastActiveAgoSec,V=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(V!=null)H.push(`已运行 ${Z9(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${Z9(Q*1000)}前`);else H.push("从未启动");if(V!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${Z9(V*1000)}`)}}else if(V!=null)H.push(`已 ${Z9(V*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
157
+ `)}function rL($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=dL[J.status]??"·",Q=iL[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${Z9(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"",X=J.codexAccountName===void 0?"":` · Codex:${J1(z$(J.codexAccountName))}`;return` · ${Y} \`${J.name}\` · ${Q}${V}${H}${X}`}).join(`
158
+ `)}function e3($,Z=R.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:rL($)}]}}function sL($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${g5($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
159
+ `)}function $6($,Z=R.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:sL($)}}function Z6($,Z=R.consoleHost){let J=aL($);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:oL($)}]}}function J6($){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(tL).join(" · ")}`}function tL($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function eL($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.flatMap((Y)=>M2(Y,Y.label).map((Q)=>Q.content))].join(`
160
+ `):J6($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=GH($);return J?`${Z}
161
+ ${J}`:Z}function GH($){return $?.resetCredits===void 0?"":`**重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`}function Y9($){let Z=$.unifiedUsage;if(Z?.state==="ok"&&Z.kind!=="balance"&&!Z.quota&&Z.windows.length){let J=[];for(let Q of Z.windows){if(J.length)J.push({tag:"hr"});J.push(...M2(Q,Q.label))}let Y=GH(Z);if(Y)J.push({tag:"hr"},{tag:"markdown",content:Y});return{tag:"collapsible_panel",element_id:R.consoleUsage,expanded:!0,header:{title:{tag:"plain_text",content:"\uD83D\uDCCA 额度"},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"12px",vertical_spacing:"4px",elements:J}}return{tag:"markdown",element_id:R.consoleUsage,content:eL(Z)}}function KH($,Z){return[$6($,Z),e3($),Z6($.sysinfo),Y9($)]}function w5($){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:KH($)}}}function v5($){return C2($.sessionName,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${J1($.currentDisplay??"未选择")}
162
+ 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:R.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)=>$q(Y,$.panelId))}]:[]})]})}function $q($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${z$($.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:`**${z$($.display)}**
163
+ ${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 f5($){return C2($.sessionName,BH($))}function h5($){return C2($.sessionName,V6($))}function Y6($){return C2($.sessionName,H6($),"green")}function C2($,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 BH($){let Z=Yq($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${_H($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
164
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?Zq($.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 Zq($,Z){let{sourceId:J,page:Y,totalPages:Q}=Z,V=(H,X)=>({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:X}}]}]});return[{tag:"markdown",content:`第 ${Y+1} / ${Q} 页`},{tag:"column_set",columns:[...Y>0?[V("上一页",Y-1)]:[],...Y+1<Q?[V("下一页",Y+1)]:[]]}]}function Q6($,Z="cancelled"){return C2($,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function I5($,Z,J){return C2($,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
165
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function k2($,Z,J){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
166
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function V6($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${Hq($.model)}`,`当前: ${_H($.currentModel,$.currentEffort)}`].join(`
167
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>Qq($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function H6($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",J1(jH($.model,$.effort,$.provider)),z$($.scope)].join(`
168
+ `)}]}}function Jq($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${z$($.displayName)}** · 未配置
169
+ ${z$($.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?`**${z$($.displayName)}**`:`**${J1($.model)}**`,V=[$.isDefault?`${g5($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
170
+ `+z$(Xq($.description,110)):"",X=(W,G)=>({tag:"button",text:{tag:"plain_text",content:G},type:"default",behaviors:[{type:"callback",value:{kind:W,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?J1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
171
+ `)+H}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[X("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:Vq($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?X("model_custom_remove","删"):X("model_remove","隐")]:[]]}]}]}function Yq($,Z,J,Y=!1){let Q=[{title:"Codex",models:$.filter((X)=>(X.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((X)=>X.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((X)=>X.provider==="dsh")}].filter((X)=>X.models.length>0),V=(X)=>X.flatMap((z,W)=>[...W?[{tag:"hr"}]:[],...Jq(z,Z,J,Y)]);if(Q.length<=1)return V($);let H=[];for(let X of Q)H.push({tag:"markdown",content:`**${X.title}**`}),H.push(...V(X.models));return H}function Qq($,Z,J,Y,Q){let V=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",V?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":z$(Z.effort)}**`,H,Z.description?z$(Z.description):""].filter(Boolean).join(`
172
+ `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:V?"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 Vq($,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 Hq($){return $.displayName&&$.displayName!==$.model?`${z$($.displayName)} (${J1($.model)})`:J1($.model)}function _H($,Z){return J1(jH($,Z))}function jH($,Z,J){let Y=J&&J!=="codex"?`${g5(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function g5($){return _$($??"codex")}function Xq($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function z$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function J1($){return"`"+$.replace(/`/g,"\\`")+"`"}function w$($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${G0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${lL($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var dL,iL,nL;var LH=N(()=>{D0();k5();k0();dL={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},iL={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},nL={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function m5($){let Z=Gq($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:zq($.notice)},body:{elements:[...$.notice?[Wq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(Kq)]}}}function zq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function Wq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
173
173
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
174
- `)}}function Qq($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${V6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function Vq($){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:`**${V6($.slug)}**
174
+ `)}}function Gq($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${X6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function Kq($){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:`**${X6($.slug)}**
175
175
  ${Z} · ${J}
176
- ${V6($.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 Q9($){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,V6($.branch),...$.body?[$.body]:[]].join(`
177
- `)}]}}}function V6($){return"`"+$.replace(/`/g,"\\`")+"`"}function m5($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
176
+ ${X6($.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 Q9($){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,X6($.branch),...$.body?[$.body]:[]].join(`
177
+ `)}]}}}function X6($){return"`"+$.replace(/`/g,"\\`")+"`"}function c5($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
178
178
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
179
- 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:Hq($.notice)});if(!$.entries.length)V.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{V.push({tag:"markdown",content:Q});for(let H of $.entries)V.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${l5(H.ts)}**
180
- ${Y1(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:V}}}function p5($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
181
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${l5(J.ts)}**
182
- ${Y1(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 c5($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
179
+ 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:Bq($.notice)});if(!$.entries.length)V.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{V.push({tag:"markdown",content:Q});for(let H of $.entries)V.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${i5(H.ts)}**
180
+ ${Y1(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:V}}}function u5($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
181
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${i5(J.ts)}**
182
+ ${Y1(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 l5($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
183
183
  …(截断)`:J.body;return`${J.path} (${J.tool})
184
184
  ${Y}`}).join(`
185
185
 
186
- `);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 Q1($){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?"✅":"❌"} ${g5($.message)}`}]}}}function u5($){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)||"(无摘要)",V=$.sourceStatus?` · 状态 ${Y1($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${Y1(H6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
186
+ `);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 Q1($){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?"✅":"❌"} ${p5($.message)}`}]}}}function d5($){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)||"(无摘要)",V=$.sourceStatus?` · 状态 ${Y1($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${Y1(z6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
187
187
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
188
- `):$.bindingState==="unchanged"?[`${g5($.message)}`,"",`本群原绑定 ${Y1(H6($.previousSessionId))};源会话未修改。`].join(`
189
- `):[`${g5($.message)}`,"",`后端返回会话 ${Y1(H6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
190
- `);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}**`,`**${l5($.selectedTs)}**${V}`,Y1(Q),`源会话 ${Y1(H6($.sourceSessionId))}`].join(`
191
- `)},{tag:"markdown",content:H}]}}}function l5($){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 Y1($){return"`"+KH($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function H6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function g5($){return KH($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function KH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Hq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
188
+ `):$.bindingState==="unchanged"?[`${p5($.message)}`,"",`本群原绑定 ${Y1(z6($.previousSessionId))};源会话未修改。`].join(`
189
+ `):[`${p5($.message)}`,"",`后端返回会话 ${Y1(z6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
190
+ `);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}**`,`**${i5($.selectedTs)}**${V}`,Y1(Q),`源会话 ${Y1(z6($.sourceSessionId))}`].join(`
191
+ `)},{tag:"markdown",content:H}]}}}function i5($){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 Y1($){return"`"+qH($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function z6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function p5($){return qH($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function qH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Bq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
192
192
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
193
- `)}function BH($){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(`
193
+ `)}function PH($){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(`
194
194
  ---
195
- `);return""}function d5($,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:BH(Z)}]}function n5($){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?[Wq($.notice)]:[],{tag:"markdown",element_id:R.tasklistPanel,content:Xq($)},zq($)]}}}function Xq($){let Z=[`项目:${i5($.projectName)}`,`清单:${i5($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
196
- `);if(Z.push("","已启用"),Z.push(`GUID:${i5($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
197
- `)}function zq($){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 Wq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
198
- `).map((J)=>`<font color='${Z}'>${Gq(J)||" "}</font>`).join(`
199
- `)}}function i5($){return"`"+$.replace(/`/g,"\\`")+"`"}function Gq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var _H=T(()=>{k0()});import{createHash as Kq}from"node:crypto";function o5($){let Z=[{tag:"markdown",element_id:R.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
195
+ `);return""}function n5($,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:PH(Z)}]}function o5($){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?[Lq($.notice)]:[],{tag:"markdown",element_id:R.tasklistPanel,content:_q($)},jq($)]}}}function _q($){let Z=[`项目:${a5($.projectName)}`,`清单:${a5($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
196
+ `);if(Z.push("","已启用"),Z.push(`GUID:${a5($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
197
+ `)}function jq($){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 Lq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
198
+ `).map((J)=>`<font color='${Z}'>${qq(J)||" "}</font>`).join(`
199
+ `)}}function a5($){return"`"+$.replace(/`/g,"\\`")+"`"}function qq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var DH=N(()=>{k0()});import{createHash as Pq}from"node:crypto";function s5($){let Z=[{tag:"markdown",element_id:R.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
200
200
  `)}];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)=>`- **${O$(J.display)}**:${O$(J.reason)}`).join(`
201
- `)}]});return Z.push(...$.catalog.map(jq),Lq($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function r5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!t5($.status),summary:{content:X6($)}},body:{elements:[V9($)]}}}function V9($){return{tag:"collapsible_panel",element_id:H9($.runId),header:{title:{tag:"plain_text",content:X6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${O$($.description??"说明 MISS")}**`,PH($).content,`**任务说明**
202
- ${Pq($.prompt)}`,...$.workers.map((Z)=>qH(Z,DH($.workers.length)).content)].join(`
201
+ `)}]});return Z.push(...$.catalog.map(Uq),Mq($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function t5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!$Z($.status),summary:{content:W6($)}},body:{elements:[V9($)]}}}function V9($){return{tag:"collapsible_panel",element_id:H9($.runId),header:{title:{tag:"plain_text",content:W6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${O$($.description??"说明 MISS")}**`,AH($).content,`**任务说明**
202
+ ${Oq($.prompt)}`,...$.workers.map((Z)=>MH(Z,OH($.workers.length)).content)].join(`
203
203
 
204
- `)}]}}function H9($){return`ar_${Kq("sha256").update($).digest("hex").slice(0,16)}`}function s5($){if($.length===1)return X6($[0]);let Z=$.filter((Q)=>t5(Q.status)).length,J=$.filter((Q)=>Q.status==="failed").length,Y=$.filter((Q)=>Q.status==="needs_input").length;return`\uD83E\uDDE0 委派任务 · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Y?` · 待答 ${Y}`:""}`}function qH($,Z=LH){let J=qq($),Y=[`模型 ${v1($.model)} · 推理 ${v1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${G0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",O$($.queuedReason));if($.pendingInput){Y.push("","**等待主 Agent 回答**");for(let Q of $.pendingInput.questions)if(Y.push(`- ${O$(Q.question)}`),Q.options.length)Y.push(` 选项:${Q.options.map((V)=>v1(V.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",e($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",Dq(e($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Y.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Y.push("","**最近动作**");for(let Q of $.steps.slice(-3)){let V=Q.tool==="tool error"?"❌":Q.phase==="completed"?"✓":Q.phase==="started"?"→":"·",H=Q.tool==="tool error"?"工具执行失败":Q.tool==="tool result"?"工具执行完成":Q.tool;Y.push(`- ${V} ${v1(H)} ${O$(MH(Q.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${O$($.identityName)}**`,...Y].join(`
205
- `)}}function PH($){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,V=$.workers.filter((G)=>G.status==="queued").length,H=$.workers.filter((G)=>G.status==="cancelled").length,X=[Q?`执行中 ${Q}`:"",V?`排队 ${V}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${FH($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${G0(z/1000)}`]:[],...$.error?[O$($.error)]:[]].join(`
206
- `)}}function DH($){let Z=Math.max(1,Math.floor($));return Math.min(LH,Math.max(_q,Math.floor(Bq/Z)))}function X6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${FH($)} · ${MH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function jq($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${O$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${v1($.id)}
207
- ${v1($.model)} · 默认 ${v1($.defaultEffort??"MISS")} · ${O$(J)}`].join(`
208
- `)}}function Lq($){return{tag:"column_set",columns:[a5("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),a5("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),a5("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function a5($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function qq($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function t5($){return $==="completed"||$==="failed"||$==="cancelled"}function FH($){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)=>t5(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function Pq($){let Z=e($);if(Z.length<=jH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,jH-J.length-2)}
204
+ `)}]}}function H9($){return`ar_${Pq("sha256").update($).digest("hex").slice(0,16)}`}function e5($){if($.length===1)return W6($[0]);let Z=$.filter((Q)=>$Z(Q.status)).length,J=$.filter((Q)=>Q.status==="failed").length,Y=$.filter((Q)=>Q.status==="needs_input").length;return`\uD83E\uDDE0 委派任务 · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Y?` · 待答 ${Y}`:""}`}function MH($,Z=UH){let J=Aq($),Y=[`模型 ${y1($.model)} · 推理 ${y1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${G0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",O$($.queuedReason));if($.pendingInput){Y.push("","**等待主 Agent 回答**");for(let Q of $.pendingInput.questions)if(Y.push(`- ${O$(Q.question)}`),Q.options.length)Y.push(` 选项:${Q.options.map((V)=>y1(V.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",e($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",Rq(e($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Y.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Y.push("","**最近动作**");for(let Q of $.steps.slice(-3)){let V=Q.tool==="tool error"?"❌":Q.phase==="completed"?"✓":Q.phase==="started"?"→":"·",H=Q.tool==="tool error"?"工具执行失败":Q.tool==="tool result"?"工具执行完成":Q.tool;Y.push(`- ${V} ${y1(H)} ${O$(NH(Q.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${O$($.identityName)}**`,...Y].join(`
205
+ `)}}function AH($){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,V=$.workers.filter((G)=>G.status==="queued").length,H=$.workers.filter((G)=>G.status==="cancelled").length,X=[Q?`执行中 ${Q}`:"",V?`排队 ${V}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${RH($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${G0(z/1000)}`]:[],...$.error?[O$($.error)]:[]].join(`
206
+ `)}}function OH($){let Z=Math.max(1,Math.floor($));return Math.min(UH,Math.max(Fq,Math.floor(Dq/Z)))}function W6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${RH($)} · ${NH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function Uq($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${O$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${y1($.id)}
207
+ ${y1($.model)} · 默认 ${y1($.defaultEffort??"MISS")} · ${O$(J)}`].join(`
208
+ `)}}function Mq($){return{tag:"column_set",columns:[r5("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),r5("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),r5("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function r5($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function Aq($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function $Z($){return $==="completed"||$==="failed"||$==="cancelled"}function RH($){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)=>$Z(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function Oq($){let Z=e($);if(Z.length<=FH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,FH-J.length-2)}
209
209
 
210
- ${J}`}function Dq($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
210
+ ${J}`}function Rq($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
211
211
 
212
- ${J}`}function v1($){return"`"+$.replace(/`/g,"\\`")+"`"}function O$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function MH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var jH=1e4,Bq=48000,LH=8000,_q=512;var UH=T(()=>{k0()});function h1($){return Fq.has($)?$:null}function z6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function w2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function f1($){return String($?.subject??$?.content??"").trim()}function e5($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function RH($){return`subj:${$}`}function AH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function Oq($){let Z=f1($);if(!Z)return null;return{id:w2($)||RH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:e5($)??"pending"}}function $Z($,Z,J,Y){if(Z==="TaskList"){let Q=z6(Y),V=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(V===null)return $;let H=[];for(let X of V){let z=Oq(X);if(z)H.push(z)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let W=z6(Y),G=Array.isArray(W?.tasks)?W.tasks:Array.isArray(W)?W:null,B=$;return Q.forEach((_,j)=>{let q=f1(_);if(!q)return;let P=G?.[j],D=P&&w2(P)||AH(Y??"");B=OH(B,D,q,_)}),B}let V=z6(Y),H=V?.task??V,X=w2(H)||AH(Y??""),z=f1(H)||f1(J);if(!z)return $;return OH($,X,z,J)}if(Z==="TaskUpdate"){let Q=w2(J);if(!Q)return $;let V=e5(J);if(V==="deleted")return $.filter((X)=>X.id!==Q);let H=f1(J);if($.some((X)=>X.id===Q))return $.map((X)=>X.id===Q?{...X,...V?{status:V}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:X);return $}if(Z==="TaskGet"){let Q=z6(Y),V=Q?.task??Q,H=w2(V)||w2(J);if(!H)return $;let X=$.find((G)=>G.id===H),z=f1(V)||X?.subject||f1(J);if(!z)return $;let W={id:H,subject:z,description:typeof V?.description==="string"?V.description:X?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:X?.activeForm,status:e5(V)??X?.status??"pending"};return X?$.map((G)=>G.id===H?W:G):[...$,W]}return $}function OH($,Z,J,Y){let Q=Z||RH(J),V={...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,...V}:H);return[...$,{id:Q,subject:J,status:"pending",...V}]}function ZZ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let H=Uq[V.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((V)=>J.has(V)?`${V} ${J.get(V)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function TH($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let X=parseInt(H,10);return Number.isNaN(X)?Number.MAX_SAFE_INTEGER:X},V=[...J].sort((H,X)=>{let z=Q(H.id)-Q(X.id);return z!==0?z:H.id.localeCompare(X.id)});for(let H of V.slice(0,12)){let X=Aq[H.status],z=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${X} ${z||"(空)"}`)}if(V.length>12)Y.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
213
- `)}function V1($,Z,J,Y){let Q=Mq[J.name],V=ZZ(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${V}`;return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:TH(Z,Y)}]}}function I1($){return{tag:"collapsible_panel",element_id:R.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${ZZ($)}`}},expanded:!0,elements:[{tag:"markdown",content:TH($)}]}}var Fq,Mq,Uq,Aq;var NH=T(()=>{k0();Fq=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);Mq={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},Uq={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},Aq={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var J$=T(()=>{k0();NV();sV();GH();_H();UH();NH();J7()});import{readFileSync as Rq}from"node:fs";import{homedir as Tq}from"node:os";import{join as bH}from"node:path";function Nq(){return process.env.CLAUDE_CONFIG_DIR||bH(Tq(),".claude")}function YZ(){try{let $=Rq(bH(Nq(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return K(`glm-usage: read settings.json env failed: ${$}`),{}}}function g1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function Eq($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function xq($){let Z=Eq($);return Z&&g1($)?Z:null}function xH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function SH($){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),V=Z.find((G)=>G?.type==="TIME_LIMIT"),H=(G)=>G?{percent:xH(G.percentage),resetsAt:SH(G.nextResetTime)}:null,X=H(Y),z=H(Q),W=V?{percent:xH(V.percentage),resetsAt:SH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:X,weekly:z,monthly:W,fetchedAt:Date.now()}}async function X9($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:YZ(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let V=xq(Q);if(!V)return{state:"not_glm",baseUrl:Q||void 0};let H=`${V}/api/monitor/usage/quota/limit`,X=new AbortController,z=setTimeout(()=>X.abort(),EH);try{let W=await Y0(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:X.signal});if(W.status===429)return{state:"rate_limited"};if(!W.ok)return{state:"network",reason:`HTTP ${W.status}`};let G=await W.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 B=G?.data??G;return Sq(B)}catch(W){let G=W?.name==="AbortError"?`timeout ${EH}ms`:W?.message??String(W);return K(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(z)}}async function CH(){if(v2)return v2;return v2=X9().then(($)=>{if(v2=null,$.state==="network")return JZ??$;return JZ=$,$}).catch(($)=>{return K(`glm-usage: fetchGlmUsage threw: ${$}`),v2=null,JZ??{state:"network",reason:String($)}}),v2}var EH=1e4,JZ=null,v2=null;var z9=T(()=>{a0();I()});function kH($){let Z=[];for(let J of $.matchAll(bq)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function W6($,Z=process.platform){if(Z!=="win32")return $;let J=Cq.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var bq,Cq;var QZ=T(()=>{bq=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;Cq=/^\/([a-zA-Z])\//});function vH($){if(yH.test($))return{marker:"start",body:$.replace(yH,"")};if(wH.test($))return{marker:"end",body:$.replace(wH,"")};return{marker:"none",body:$}}var yH,wH;var fH=T(()=>{yH=/^>{3,}[ \t]?/,wH=/^<{3,}[ \t]?/});async function hH($,Z,J,Y,Q){let{marker:V,body:H}=vH(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)HZ($,"reopen");return $.multiMsgBuffer=[],VZ($,H,J,Y,Q),!0}if(V==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return K(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}VZ($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await yq($,X,z),!0}if($.multiMsgBuffer!==null)return VZ($,Z,J,Y,Q),!0;return!1}function VZ($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)kq($,Q)}function kq($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await c0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else S0(Z,J)})()}async function yq($,Z,J){for(let[H,X]of J)if(X)S0(H,X);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){K(`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((z)=>`[file: ${z}]`).join(" ")+`
212
+ ${J}`}function y1($){return"`"+$.replace(/`/g,"\\`")+"`"}function O$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function NH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var FH=1e4,Dq=48000,UH=8000,Fq=512;var TH=N(()=>{k0()});function v1($){return Nq.has($)?$:null}function G6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function y2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function w1($){return String($?.subject??$?.content??"").trim()}function ZZ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function SH($){return`subj:${$}`}function EH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function Sq($){let Z=w1($);if(!Z)return null;return{id:y2($)||SH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:ZZ($)??"pending"}}function JZ($,Z,J,Y){if(Z==="TaskList"){let Q=G6(Y),V=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(V===null)return $;let H=[];for(let X of V){let z=Sq(X);if(z)H.push(z)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let W=G6(Y),G=Array.isArray(W?.tasks)?W.tasks:Array.isArray(W)?W:null,B=$;return Q.forEach((_,j)=>{let q=w1(_);if(!q)return;let P=G?.[j],D=P&&y2(P)||EH(Y??"");B=xH(B,D,q,_)}),B}let V=G6(Y),H=V?.task??V,X=y2(H)||EH(Y??""),z=w1(H)||w1(J);if(!z)return $;return xH($,X,z,J)}if(Z==="TaskUpdate"){let Q=y2(J);if(!Q)return $;let V=ZZ(J);if(V==="deleted")return $.filter((X)=>X.id!==Q);let H=w1(J);if($.some((X)=>X.id===Q))return $.map((X)=>X.id===Q?{...X,...V?{status:V}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:X);return $}if(Z==="TaskGet"){let Q=G6(Y),V=Q?.task??Q,H=y2(V)||y2(J);if(!H)return $;let X=$.find((G)=>G.id===H),z=w1(V)||X?.subject||w1(J);if(!z)return $;let W={id:H,subject:z,description:typeof V?.description==="string"?V.description:X?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:X?.activeForm,status:ZZ(V)??X?.status??"pending"};return X?$.map((G)=>G.id===H?W:G):[...$,W]}return $}function xH($,Z,J,Y){let Q=Z||SH(J),V={...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,...V}:H);return[...$,{id:Q,subject:J,status:"pending",...V}]}function YZ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let H=Eq[V.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((V)=>J.has(V)?`${V} ${J.get(V)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function bH($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let X=parseInt(H,10);return Number.isNaN(X)?Number.MAX_SAFE_INTEGER:X},V=[...J].sort((H,X)=>{let z=Q(H.id)-Q(X.id);return z!==0?z:H.id.localeCompare(X.id)});for(let H of V.slice(0,12)){let X=xq[H.status],z=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${X} ${z||"(空)"}`)}if(V.length>12)Y.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
213
+ `)}function V1($,Z,J,Y){let Q=Tq[J.name],V=YZ(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${V}`;return{tag:"collapsible_panel",element_id:R.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:bH(Z,Y)}]}}function f1($){return{tag:"collapsible_panel",element_id:R.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${YZ($)}`}},expanded:!0,elements:[{tag:"markdown",content:bH($)}]}}var Nq,Tq,Eq,xq;var CH=N(()=>{k0();Nq=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);Tq={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},Eq={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},xq={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var J$=N(()=>{k0();CV();JH();LH();DH();TH();CH();Y7()});import{readFileSync as bq}from"node:fs";import{homedir as Cq}from"node:os";import{join as vH}from"node:path";function kq(){return process.env.CLAUDE_CONFIG_DIR||vH(Cq(),".claude")}function VZ(){try{let $=bq(vH(kq(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return K(`glm-usage: read settings.json env failed: ${$}`),{}}}function h1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function yq($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function wq($){let Z=yq($);return Z&&h1($)?Z:null}function yH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function wH($){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),V=Z.find((G)=>G?.type==="TIME_LIMIT"),H=(G)=>G?{percent:yH(G.percentage),resetsAt:wH(G.nextResetTime)}:null,X=H(Y),z=H(Q),W=V?{percent:yH(V.percentage),resetsAt:wH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:X,weekly:z,monthly:W,fetchedAt:Date.now()}}async function X9($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:VZ(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let V=wq(Q);if(!V)return{state:"not_glm",baseUrl:Q||void 0};let H=`${V}/api/monitor/usage/quota/limit`,X=new AbortController,z=setTimeout(()=>X.abort(),kH);try{let W=await J0(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:X.signal});if(W.status===429)return{state:"rate_limited"};if(!W.ok)return{state:"network",reason:`HTTP ${W.status}`};let G=await W.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 B=G?.data??G;return vq(B)}catch(W){let G=W?.name==="AbortError"?`timeout ${kH}ms`:W?.message??String(W);return K(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(z)}}async function fH(){if(w2)return w2;return w2=X9().then(($)=>{if(w2=null,$.state==="network")return QZ??$;return QZ=$,$}).catch(($)=>{return K(`glm-usage: fetchGlmUsage threw: ${$}`),w2=null,QZ??{state:"network",reason:String($)}}),w2}var kH=1e4,QZ=null,w2=null;var z9=N(()=>{a0();h()});function hH($){let Z=[];for(let J of $.matchAll(fq)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function K6($,Z=process.platform){if(Z!=="win32")return $;let J=hq.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var fq,hq;var HZ=N(()=>{fq=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;hq=/^\/([a-zA-Z])\//});function mH($){if(IH.test($))return{marker:"start",body:$.replace(IH,"")};if(gH.test($))return{marker:"end",body:$.replace(gH,"")};return{marker:"none",body:$}}var IH,gH;var pH=N(()=>{IH=/^>{3,}[ \t]?/,gH=/^<{3,}[ \t]?/});async function cH($,Z,J,Y,Q){let{marker:V,body:H}=mH(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)zZ($,"reopen");return $.multiMsgBuffer=[],XZ($,H,J,Y,Q),!0}if(V==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return K(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}XZ($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await gq($,X,z),!0}if($.multiMsgBuffer!==null)return XZ($,Z,J,Y,Q),!0;return!1}function XZ($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)Iq($,Q)}function Iq($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await c0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else S0(Z,J)})()}async function gq($,Z,J){for(let[H,X]of J)if(X)S0(H,X);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){K(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await x($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((H)=>{return(H.files.length?H.files.map((z)=>`[file: ${z}]`).join(" ")+`
214
214
  `:"")+H.text}).join(`
215
215
 
216
- `),V=Y[Y.length-1];K(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],V.userOpenId,V.msgId)}function HZ($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;K(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)S0(Y,Q);c0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var IH=T(()=>{J0();I();fH()});import{mkdtemp as vq,rm as fq,writeFile as hq}from"node:fs/promises";import{createRequire as Iq}from"node:module";import{tmpdir as gq}from"node:os";import{join as gH}from"node:path";function nq($){let Z=uH.get($);if(Z)return Z;let{liteAdaptor:J}=p1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=p1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=p1("mathjax-full/js/mathjax.js"),{TeX:V}=p1("mathjax-full/js/input/tex.js"),{AllPackages:H}=p1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=p1("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Y(z);let W=Q.document("",{InputJax:new V({packages:H}),OutputJax:new X({fontCache:"none"})}),G={adaptor:z,doc:W};return uH.set($,G),G}function lH($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function aq($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function oq($,Z=WZ,J=!0){try{let Y=Z*mq,{adaptor:Q,doc:V}=nq(Z),H=V.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),X=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(X)){let K0=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(K0)}let z=X.indexOf("<svg"),W=X.lastIndexOf("</svg>");if(z<0||W<0)throw Error("MathJax returned no SVG");let G=X.slice(z,W+6),B=G.match(/^<svg\b[^>]*>/)?.[0];if(!B)throw Error("MathJax returned malformed SVG root");let _=lH(B.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=lH(B.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),q=B.match(/\bviewBox="([^"]+)"/)?.[1];if(!q)throw Error("MathJax SVG missing viewBox");let P=q.trim().split(/[\s,]+/).map(Number);if(P.length!==4||P.some((K0)=>!Number.isFinite(K0))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,N,U,A]=P,M=/<text\b/.test(G)?dq:0,S=`${D} ${N} ${U+M} ${A}`,C=_*Y,p=M*(C/U),y=Math.max(1,Math.ceil(C+p)),h=Math.max(1,Math.ceil(j*Y)),x=pq-XZ*2,f=Math.min(1,x/y),m=Math.max(1,Math.round(y*f)),l=Math.max(1,Math.round(h*f));if(f<1&&l<cq)throw Error(`formula would be unreadable after width cap (${m}x${l})`);let F=m+XZ*2,b=l+pH*2,d=G.slice(B.length,-6).replace(/currentColor/g,mH).replace(/font-family="serif"/g,`font-family="${iq}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${F}" height="${b}" viewBox="0 0 ${F} ${b}" style="color:${mH}">`,`<rect x="0" y="0" width="${F}" height="${b}" rx="6" fill="${aH}"/>`,`<svg x="${XZ}" y="${pH}" width="${m}" height="${l}" viewBox="${aq(S)}" preserveAspectRatio="xMidYMid meet">`,d,"</svg>","</svg>"].join(""),width:F,height:b}}catch(Y){return K(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function rq($,Z=WZ,J=!0){let Y=oq($,Z,J);if(!Y)return null;try{let{Resvg:Q}=p1("@resvg/resvg-js"),H=new Q(Y.svg,{background:aH,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:cH,sansSerifFamily:cH}}).render().asPng(),X=new DataView(H.buffer,H.byteOffset,H.byteLength),z=X.getUint32(16),W=X.getUint32(20);if(z!==Y.width||W!==Y.height)throw Error(`PNG dimensions ${z}x${W} != SVG ${Y.width}x${Y.height}`);return{png:H,width:z,height:W}}catch(Q){return K(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function sq($){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 dH($,Z){let J=[],Y=(G,B,_)=>{let j=G[0],q=B.trim();if(!q)return;J.push({start:Z+G.index,end:Z+G.index+j.length,tex:q,raw:j,display:_})},Q,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=V.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 X=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=X.exec($))!==null){let G=(Q[1]??"").trim();if(sq(G))Y(Q,G,!1)}J.sort((G,B)=>G.start-B.start||B.end-G.end);let z=[],W=-1;for(let G of J){if(G.start<W)continue;z.push(G),W=G.end}return z}function oH($){let Z=p8($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...dH($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...dH($.slice(Y),Y));return J}function tq($){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(iH[Y])return iH[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 JP($){let Z=nH.get($);if(Z!==void 0)return Z;return Z=$P++,nH.set($,Z),Z}function YP($,Z){return`${lq}\x00${JP(Z)}\x00${$}`}function QP($){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 VP($,Z){let J=YP($,Z),Y=m1.get(J);if(Y)return Y;let Q=zZ.get(J);if(Q)return Q;let V=(async()=>{let H=rq($,WZ,!0);if(!H)return null;let X=null;try{X=await vq(gH(gq(),"lodestar-math-"));let z=gH(X,`formula-${QP($)}.png`);await hq(z,H.png);let W=await Z(z,{tex:$,width:H.width,height:H.height});if(!W)return K(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:W,width:H.width,height:H.height};if(m1.has(J))m1.delete(J);m1.set(J,G);while(m1.size>ZP){let B=m1.keys().next().value;if(typeof B!=="string")break;m1.delete(B)}return G}catch(z){return K(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(X)try{await fq(X,{recursive:!0,force:!0})}catch(z){K(`math-render: temp cleanup failed for ${X}: ${z}`)}}})();zZ.set(J,V);try{return await V}finally{zZ.delete(J)}}function HP($,Z,J){let Y=$.width<=uq;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 rH($,Z={}){let J=oH($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??eq,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let B=tq(G.tex);if(B!==null)return{unicode:B,uploaded:null}}return{unicode:null,uploaded:await VP(G.tex,Y)}})),V=[],H="",X=0,z=0,W=()=>{if(!H)return;if(H.trim())V.push({type:"markdown",text:H});H=""};for(let G=0;G<J.length;G++){let B=J[G],_=Q[G];if(H+=$.slice(X,B.start),_.unicode!==null){H+=_.unicode,X=B.end;continue}let j=_.uploaded;if(!j){H+=B.raw,X=B.end;continue}W(),V.push(HP(j,B,z++)),X=B.end}if(H+=$.slice(X),W(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function GZ($){return oH($).length>0}var p1,mq=0.5,WZ=22,mH="#1F2329",aH="#F7F8FA",XZ=12,pH=8,pq=720,cq=14,uq=278,lq="v4-native-cjk-tail-pad",dq=1100,cH,iq="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",uH,iH,eq=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (J0(),V0));return Z($)},nH,$P=1,m1,zZ,ZP=512;var sH=T(()=>{I();p1=Iq(import.meta.url),cH=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",uH=new Map;iH={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:"Ω"};nH=new WeakMap,m1=new Map,zZ=new Map});import{readFileSync as zP}from"node:fs";function f2($){return KZ.has($)}function W9($){KZ.add($)}function G9($){KZ.delete($)}function h2(){try{let $={};for(let[Z,J]of d0)$[Z]=J;s(G6,$)}catch($){throw K(`notify-callbacks: save failed (${G6}): ${$}`),$}}function ZX(){let $=[],Z;try{Z=zP(G6,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-$X,Q=0,V=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="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",V++;if(d0.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(K(`notify-callbacks: loaded ${d0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),V)K(`notify-callbacks: ${V} interrupted text reply(s) marked UNKNOWN`);if(Q>0||V>0)h2()}catch(J){K(`notify-callbacks: load failed (${G6}): ${J}`)}return $}function JX($){let Z=Date.now();if(Z-eH>=WP)GP(Z),eH=Z;d0.set($.notifyId,$),h2()}function f$($){return d0.get($)}function BZ($){return[...d0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function K9($,Z){if(!$)return;return BZ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function YX($,Z){return!!Z&&[...d0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function I2($,Z){let J=d0.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{h2()}catch(V){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw V}}function B9($,Z,J){let Y=d0.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{h2()}catch(V){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 V}}function _Z($,Z,J,Y){let Q=d0.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,h2()}function K6($,Z,J){try{return B9($,Z,J),{state:"complete"}}catch(Y){let V=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{_Z($,Z,J,V)}catch(H){let X=H instanceof Error?H.message:String(H);V+=`; unknown tombstone persistence also failed: ${X}`;let z=d0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function GP($=Date.now()){let Z=$-$X,J=0;for(let[Y,Q]of d0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)d0.delete(Y),J++;if(J>0)h2();return J}async function jZ($,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,V=setTimeout(()=>Q.abort(),tH);try{let H=await iJ($.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 W=(await H.text()).trim();if(W.startsWith("{")){let G=JSON.parse(W),B=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(B.trim())z=B.trim().slice(0,500)}else if(W)z=W.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:z}}let X="";try{X=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${X?` ${X}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${tH}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(V)}}function QX($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((X)=>X.id===Y):void 0,V=$.replyState?.response,H=Y!==void 0?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y}}:V?{response:{type:"text",...V}}:{};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 $X=604800000,tH=2500,d0,eH,WP=86400000,KZ,G6;var _9=T(()=>{a0();I();H0();f0();d0=new Map,eH=Date.now(),KZ=new Set;G6=wJ});function B6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function g2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(K9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(B6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function LZ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:K9($.chatId)?"notification":B6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function qZ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||g2($,Z)||!Y?.userOpenId||!Y.messageId)return;J.announced=!0;let Q=(J.announcementVersion??0)+1;J.announcementVersion=Q;let V=J.questions[J.currentIdx]?.question.trim()??"",H=V.length>40?V.slice(0,40)+"…":V,X=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${H?`: ${H}`:""}`:H?`❓ ${H}`:"❓ 等你回答问题";(async()=>{if(A0(Y.cardId),await k3(Y.cardId,{config:{summary:{content:X}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||g2($,Z))return;await S1(Y.messageId,[Y.userOpenId])})().catch((z)=>K(`session "${$.sessionName}": question notification failed: ${z}`))}function _6($){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 V=LZ($,J);if(V.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;$0(Z.cardId,R.tool(Q.i),b2(Q.i,J,Y.questions,"\uD83E\uDD14",V)),qZ($,J)}}function VX($){return B6($)!==void 0}async function HX($,Z,J,Y){let Q=B6($);if(!Q){K(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[V,H]=Q,X=g2($,V);if(X){let W=`${X}。这条文字未提交,请稍后重新发送。`;if(!await E($.chatId,W))throw Error(`提问等待提示发送失败: ${W}`);return}if(await PZ($,V,H.currentIdx,Z,J)&&Y)c0(Y,"CheckMark")}async function XX($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return K(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==V.currentIdx)return K(`session "${$.sessionName}": stale ask click q=${J} current=${V.currentIdx}`),!1;return zX($,Z,{optionIdx:Y,user:Q})}async function PZ($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return K(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return K(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==V.currentIdx)return K(`session "${$.sessionName}": stale ask custom q=${J} current=${V.currentIdx}`),!1;return zX($,Z,{customText:H,user:Q})}function zX($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=g2($,Z);if(Q)return K(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let V=Y.currentIdx,H=Y.questions[V];if(!H)return K(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let X;if(J.customText!==void 0)X=J.customText;else if(J.optionIdx!==void 0){let _=H.options?.[J.optionIdx];if(!_)return K(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;X=_.label}else return K(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[H.question]=X,Y.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Y.questions.length,W=void 0;for(let _=V+1;_<z;_++)if(!Y.answered.has(_)){W=_;break}Y.currentIdx=W;let G=$.currentTurn,B=G?.toolByUseId.get(Z);if(G&&B){let _=b2(B.i,Z,Y.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Y.answered});$0(G.cardId,R.tool(B.i),_)}if(W===void 0)if(Y.requestId)DZ($,Z);else K(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),_6($);return!0}function DZ($,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),_6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var j6=T(()=>{y$();J$();J0();I();_9()});import{isAbsolute as BP}from"node:path";function O0($){if($?.planLiveInserted)return R.planLive;return $?.taskLiveInserted?R.taskBoardLive:R.footer}function _P($){return $==="ImageGeneration"||$==="imageGeneration"}function jP($,Z,J){if(J||!_P($))return null;let Y=W6(Z.trim());return BP(Y)?Y:null}function LP($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function WX($,Z,J){return $==="read"?e4(Z,J):t4(Z,J)}function GX($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=LP(J);if(Q&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,W=$.currentTurn.toolBatches.get(z);if(W&&W.kind===Q){let G=W.items.length;W.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:z,name:J,input:Y,batchSlot:G});let B=Q==="read"?e4(z,W.items):t4(z,W.items);$0($.currentTurn.cardId,R.tool(z),B),L6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let V=h1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,F0(z.cardId,I1($.taskBoard),{type:"insert_before",targetElementId:R.footer});else $0(z.cardId,R.taskBoardLive,I1($.taskBoard));let W=V==="TaskCreate";if(W)z.taskUpdateI=null;else z.taskCreateI=null;let G=(W?z.taskCreateI:z.taskUpdateI)===null;if(G)if(W)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let B=W?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:B,name:J,input:Y});let _=V1(B,$.taskBoard,{name:V,status:"⏳"});G?F0(z.cardId,_,{type:"insert_before",targetElementId:O0(z)}):$0(z.cardId,R.tool(B),_),L6(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 W=Q==="read"?e4(H,z):t4(H,z);F0($.currentTurn.cardId,W,{type:"insert_before",targetElementId:O0($.currentTurn)}),L6($.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:[],W=z.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:z,i:H,answers:{},answered:G,currentIdx:W});let B=b2(H,Z,z,"\uD83E\uDD14",LZ($,Z));F0($.currentTurn.cardId,B,{type:"insert_before",targetElementId:O0($.currentTurn)}),qZ($,Z);return}let X=A$(H,J,Y,null,"⏳");F0($.currentTurn.cardId,X,{type:"insert_before",targetElementId:O0($.currentTurn)}),L6($.currentTurn,J,Y)}function L6($,Z,J){if(!$)return;let Y=$1(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,V=w1(Z),H=Q?`\uD83D\uDD27 ${V}: ${Q}`:`\uD83D\uDD27 ${V}`;k1($.cardId,H)}function KX($,Z,J,Y,Q){if(!$.currentTurn)return;let V=$.currentTurn.toolByUseId.get(Z);if(!V)return;if(Q&&typeof Q==="object")V.input={...V.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(`
217
- `):JSON.stringify(J);if(V.output=H,V.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let X=jP(V.name,H,Y);if(X){qP($,$.currentTurn,V,X),j9($);return}if(V.name==="AskUserQuestion"){j9($);return}if(V.batchSlot!=null){let G=$.currentTurn.toolBatches.get(V.i);if(G){let B=G.items[V.batchSlot];if(B)B.output=H,B.isError=Y;let _=WX(G.kind,V.i,G.items);$0($.currentTurn.cardId,R.tool(V.i),_)}j9($);return}let z=h1(V.name);if(z){PP($,V,z,V.input,H,Y,V.resolvedNote);return}let W=A$(V.i,V.name,V.input,H,Y?"❌":"✅",V.resolvedNote);$0($.currentTurn.cardId,R.tool(V.i),W),j9($)}function qP($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,V=R.tool(J.i),H=Z.imageDeliveryInflight??=new Map,X=H.get(Q)??new Set;H.set(Q,X);let z=(async()=>{let W=null;try{W=await V5(Y)}catch(B){K(`generated image upload failed: ${B}`)}if(W){let B=!1;try{B=await M0(Q,V,A$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1})}catch(_){K(`generated image embed failed: ${_}`)}if(B){J.imageKey=W,Z.outboundSentPaths.add(Y);return}K(`generated image could not be embedded in card ${Q}; sending it as a separate message`)}let G=W?await b3($.chatId,W)!==null:await p4($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else K(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await M0(Q,V,A$(J.i,J.name,J.input,J.output??null,G?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!G&&W)await E($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(W)=>{K(`generated image delivery failed: ${W}`),await E($.chatId,`❌ 生成图片发送失败:${W instanceof Error?W.message:String(W)}`)});X.add(z),z.finally(()=>{if(X.delete(z),!X.size)H.delete(Q)}).catch((W)=>K(`generated image failure notice failed: ${W}`))}async function FZ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function PP($,Z,J,Y,Q,V,H){if(!$.currentTurn)return;if(!V)$.taskBoard=$Z($.taskBoard,J,Y,Q);let X=V1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},H);if($0($.currentTurn.cardId,R.tool(Z.i),X),$.currentTurn.taskLiveInserted)$0($.currentTurn.cardId,R.taskBoardLive,I1($.taskBoard));j9($)}function j9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function MZ($,Z,J,Y,Q,V=$.currentTurn){let H=V;if(!H)return;for(let[X,z]of Y){if(H.toolByUseId.has(X))continue;let W=z.batchSlot??null,G=z.input,B,_;if(W!=null){let U=Q.get(z.i)?.items[W];if(!U)continue;G=U.input,B=U.output,_=U.isError}else B=z.output??null,_=z.isError??!1;let j=B!=null,q=x2(Z,R.tool(z.i));if(j&&!q)continue;if(W!=null){let U=Q.get(z.i)?.kind;if(!U)continue;let A=H.toolCount++,M={toolUseId:X,input:G,output:B,isError:_};H.toolBatches.set(A,{kind:U,items:[M]}),H.toolByUseId.set(X,{...z,i:A,batchSlot:0}),F0(J,WX(U,A,[M]),{type:"insert_before",targetElementId:O0(H)});continue}let P=h1(z.name);if(P){let U=P==="TaskCreate";if(U)H.taskUpdateI=null;else H.taskCreateI=null;let A=(U?H.taskCreateI:H.taskUpdateI)===null;if(A)if(U)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let M=U?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(X,{...z,i:M});let S=!j?"⏳":_?"❌":"✅",C=V1(M,$.taskBoard,{name:P,status:S},z.resolvedNote);A?F0(J,C,{type:"insert_before",targetElementId:O0(H)}):$0(J,R.tool(M),C);continue}let D=H.toolCount++;H.toolByUseId.set(X,{...z,i:D});let N=!j?"⏳":_?"❌":"✅";F0(J,A$(D,z.name,z.input,B,N,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:O0(H)})}}var BX=T(()=>{QZ();y$();J$();J0();I();j6()});async function _X($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return K(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let V=$.proc;if(!V)return K(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{V.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(W){return K(`session "${$.sessionName}": permission response ${Z} failed: ${W}`),{ok:!1,message:`权限决定发送失败: ${W instanceof Error?W.message:W}`}}$.pendingPermissions.delete(Z);let X=$.currentTurn,z=X?.toolByUseId.get(Q.toolUseId);if(X&&z){let W=h1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,B=W?V1(z.i,$.taskBoard,{name:W,status:"❌"},G):A$(z.i,z.name,z.input,G,"❌");$0(X.cardId,R.tool(z.i),B)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let B=W?V1(z.i,$.taskBoard,{name:W,status:"⏳"},z.resolvedNote):A$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);$0(X.cardId,R.tool(z.i),B)}}if(K(`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 jX($,Z){let J=$.currentTurn;if(!J){K(`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){K(`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){K(`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){K(`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)DZ($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),K(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let V=x5(Q.i,Q.name,Q.input,Z.request_id);if($0(J.cardId,R.tool(Q.i),V),J.userOpenId&&J.messageId){let H=$1(Q.name,Q.input),X=w1(Q.name),z=H&&H.length>30?H.slice(0,30)+"…":H,W=z?`\uD83D\uDD10 等审批: ${X} · ${z}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{A0(J.cardId),await k3(J.cardId,{config:{summary:{content:W}}}),await S1(J.messageId,[J.userOpenId])})()}}var LX=T(()=>{y$();J$();J0();I();j6()});class qX{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new O1({accountId:Q,login:!0}),Z=900000,J=(Q,V)=>{k.recordLogin(Q,V),U2(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=IY($),Y;try{Y=this.createClient($)}catch(z){throw J(),z}let Q,V,H=new Promise((z,W)=>{Q=z,V=W});H.catch(()=>{});let X={owner:Z,client:Y,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:H,resolve:Q,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};X.notification=(z,W)=>{if(X.finishing||!X.loginRequested)return;if(z==="account/updated"){if(W?.authMode==="chatgpt"){if(X.authUpdated=!0,X.loginSucceeded)this.finish(X)}return}if(z!=="account/login/completed")return;if(!X.loginId){X.early.push(W);return}if(W?.loginId!==X.loginId)return;if(W?.success!==!0){this.finish(X,Error(typeof W?.error==="string"?W.error:"Codex 登录未成功"));return}if(X.loginSucceeded)return;if(X.loginSucceeded=!0,K(`codex-login: authorization completed account=${$} authUpdated=${X.authUpdated}`),X.timer)clearTimeout(X.timer);if(X.authUpdated)this.finish(X);else X.timer=setTimeout(()=>{this.finish(X,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},X.closed=(z)=>{this.finish(X,z)},Y.on("notification",X.notification),Y.on("closed",X.closed),Y.on("protocolError",X.closed),this.attempts.set($,X);try{await Y.initialize("lodestar-login"),X.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(X.loginId=z.loginId,X.finishing)throw await H,Error("登录已结束");X.timer=setTimeout(()=>{this.cancelAttempt(X,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let W of X.early)X.notification("account/login/completed",W);return X.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:H}}catch(z){return await this.finish(X,q6(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};取消请求失败:${q6(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=q6(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,`登录进程关闭失败:${q6(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 q6($){return $ instanceof Error?$:Error(String($))}var c1;var UZ=T(()=>{C$();g0();I();c1=new qX});function PX($){let Z=new Map,J=$.map((G)=>{let B=G.fingerprint?Z.get(G.fingerprint):void 0;if(G.fingerprint&&!B)Z.set(G.fingerprint,G.account.name);return{...G,...B?{duplicateOf:B}:{}}}),Y=J.filter((G)=>!G.duplicateOf),V=(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]:[]),X=V&&H.every((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((B)=>B.percent!==null))?H.filter((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((B)=>B.percent<100)).length:null,z=V&&H.every((G)=>G.resetCredits!=null)?H.reduce((G,B)=>G+B.resetCredits,0):null,W=["fiveHour","weekly"].map((G)=>{let B=H.map((j)=>j[G]).filter((j)=>j!==null),_=V&&B.every((j)=>j.percent!==null&&j.percent>=0&&j.percent<=100);return{kind:G,count:B.length,remaining:_?B.reduce((j,q)=>j+(100-q.percent)/100,0):null}}).filter((G)=>G.count||!V);return{entries:J,complete:V,available:X,resetCredits:z,windows:W}}var DX=T(()=>{g0();C$()});class m2{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=MP){let Y=await J.sendCard($,V$(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new m2(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=S4($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=S4($);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,R.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:x4($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var MP;var FX=T(()=>{J0();y$();k0();R2();MP={sendCard:u,convertMessageToCard:$$,recordCardCreated:u0,replaceElementChecked:M0,patchSettingsChecked:P0,dispose:w0}});var OZ={};T$(OZ,{settleCodexAccountCards:()=>AZ,runCodexNamedHi:()=>AP,runCodexAccountCommand:()=>OP});import{createHash as UP}from"node:crypto";function L9($,Z){let J=$ instanceof Error?$.message:String($),Y=!/失败|未完全退出/.test(J)&&/登录已取消|服务退出/.test(J),Q=/过期|等待超过|expired/i.test(J),V=J.split(/[\n;]/)[0];return{phase:Y?"cancelled":Q?"expired":"error",name:Z,message:V.length>80?V.slice(0,77)+"…":V,...J!==V||V.length>80?{details:J}:{}}}async function MX($,Z){if(!await u($.chatId,V$(L9(Z))))throw Error("Codex 错误卡片发送失败")}async function AP($,Z){let J=await m2.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Y=k.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(L9(Y,Z))}}async function AZ(){let Z=(await Promise.allSettled([...u1.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function OP($,Z,J,Y,Q){if(Z==="reset"){await TP($,J,Q);return}let V={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let z=c1.pending(V);if(!J&&z.length!==1)throw Error(z.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?k.find(J).id:z[0];await c1.cancel(W,V),await u1.get(W)}catch(z){await MX($,z)}return}let H=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,X=await m2.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:H,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let _=k.find(J);if(u1.has(_.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:j}=k.remove(_.id);U2(_.id),await X.finish({phase:"deleted",name:_.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:j?`已清除 ${j} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let _=J?Number(J):1,j=$.currentProvider()==="codex"?$.currentModelLabel():X0("codex-sub")?.defaultModel;if(!j)throw Error("Codex 模型 MISS,无法计算调度顺序");let q=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,P=await P3.choose({model:j,effort:q}),D=PX(P.candidates.flatMap((N)=>N.usage?[{account:N.account,usage:N.usage,fingerprint:N.identity.startsWith("record:")?null:N.identity}]:[]));await X.finish({phase:"accounts",total:D,currentId:$.codexAccountId(),...k.preferred($.sessionName)?{selectedId:k.selected($.sessionName)}:{},page:_,scheduling:{candidates:P.candidates,ultra:q==="ultra"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");k.selectAuto($.sessionName),await X.finish({phase:"selected",name:"自动选择",current:k.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await X.finish({phase:"current",current:k.get($.codexAccountId()).name,selected:k.preferred($.sessionName)===null?"自动 · 最高分优先":k.get(k.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let _=k.find(J),j=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,P=k.get($.codexAccountId()).name;if($.currentProvider()==="codex")x1($.sessionName,"codex",j,q,"codex-sub");if(k.select($.sessionName,_.id),$.currentProvider()==="codex")$.selectedModel=j,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await X.finish({phase:"selected",name:_.name,current:P,selected:_.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Y)throw Error("无法确认登录发起者");let z=k.ensure(J);if(r9(z.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(u1.has(z.id))throw Error("登录结果正在更新,请稍等");let W=await c1.start(z.id,V);try{await X.update({phase:"waiting",flow:"login",name:z.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${z.name}`:""}`})}catch(_){throw await c1.cancel(z.id,V),_}let G=(async()=>{let _;try{_=await W.done}catch(q){await X.finish(L9(q,z.name));return}await X.update({phase:"checking",flow:"login",name:z.name,message:"授权完成,正在读取模型…"});let j;try{await M2();let q=X0("codex-sub",z.id);if(!q)throw Error("Codex 订阅来源尚未初始化");if(await q.refreshModels(),q.modelCatalogState?.status!=="ready")throw Error(q.modelCatalogState?.error??"模型目录未就绪")}catch(q){j=q instanceof Error?q.message:String(q)}await X.finish({phase:j?"warning":"success",flow:"login",name:z.name,email:_.email,plan:_.planType,...j?{title:"已登录 · 目录 MISS",details:j}:{},hint:`已加入自动选择 · 优先使用:codex-account ${z.id==="default"?"default":z.name}`})})();u1.set(z.id,G);let B=()=>{if(u1.get(z.id)===G)u1.delete(z.id)};G.then(B,(_)=>{K(`codex-login: terminal card write failed: ${_}`),B()})}catch(z){K(`codex-${Z}: ${z}`),await X.finish(L9(z,H))}}async function TP($,Z,J){let Y;try{if(!J?.trim())throw Error("缺少消息 ID,未使用重置卡;请在群内发送 codex-reset [备注]");if(!Z&&(!$.proc?.isAlive()||$.proc.provider!=="codex"||$.proc.codexAccountSelectionMode?.()===null||$.proc.turnRetry?.reason==="quota"&&$.proc.turnRetry.phase==="waiting"))throw Error("当前没有正在使用的 Codex 账号;请用 codex-reset 备注,或 codex-reset default 指定默认账号");Y=Z?k.find(Z):k.get(o0($.proc))}catch(W){K(`codex-reset: ${W}`),await MX($,W);return}let Q=await m2.open($.chatId,{phase:"checking",name:Y.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let W=UP("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await xQ(Y.id,W)}catch(W){K(`codex-reset: ${W}`),await Q.finish(L9(W,Y.name));return}let H=RP[V.outcome],z=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
218
- `);await Q.finish({...H,name:Y.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var u1,RP;var P6=T(()=>{J0();g0();UZ();Q0();DX();F7();FX();R2();I();C$();u1=new Map;RP={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});function b0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function RZ($,Z){let J=$.agent==="claude"?M8.filter((Q)=>Q!=="default"):$.agent==="codex"?[...m8]:["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 D6($,Z){let J=$.modelSelection,Y=new Set(b0(Z.hidden_models)),Q=[...new Set([...b0(Z.custom_models),...J?[]:b0(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},H=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.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 X=$.models,z=(J?V.availableModels:X).map((G)=>({...G,origin:G.origin??"upstream"}));for(let G of Q){if(z.some((B)=>B.model.toLowerCase()===G.toLowerCase()))continue;z.push({model:G,display:G,origin:"custom",...RZ($,Z)})}V.availableModels=z;let W=J?X.map((G)=>z.find((B)=>B.model===G.model)??{...G,origin:"upstream"}):z;$.models=[...W.filter((G)=>G.origin==="custom"||!Y.has(G.model)),...z.filter((G)=>G.origin==="custom"&&!W.some((B)=>B.model===G.model))],V.modelIds=$.models.map((G)=>G.model)},$}var p2=T(()=>{D0();M1()});import{homedir as NP}from"node:os";function OX($,Z=AX){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Q),J(V)},(V)=>{clearTimeout(Q),Y(V)})})}function UX($){return typeof $==="string"&&EP.includes($)?$:null}async function RX(){let{ClaudeAgentProcess:$}=await Promise.resolve().then(() => (M4(),AQ)),Z=new $({workDir:NP(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1}});Z.on("error",(J)=>K(`Claude model catalog MISS: ${J.message}`));try{let J=await OX(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 TX($="default"){let Z=new O1({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 OX(Z.request("model/list",{}));if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let Q=Y.data,V=[];for(let H of Q){if(!H||H.hidden||!H.id)continue;let X=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((W)=>UX(W?.reasoningEffort)).filter((W)=>W!==null);if(!X.length)continue;let z=UX(H.defaultReasoningEffort)??X[0];V.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:X,defaultEffort:z})}return V}finally{await Z.close()}}async function NX($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,V=await Y0(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(AX)});if(!V.ok)throw Error(`HTTP ${V.status}`);let H=await V.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 W=String(z.display_name||z.id);return{model:W,display:W,efforts:c2,defaultEffort:"max"}})}var AX=1e4,EP,c2;var q9=T(()=>{a0();C$();I();EP=["none","minimal","low","medium","high","xhigh","max","ultra"];c2=["max","xhigh","high","medium","low"]});import{existsSync as xP}from"node:fs";import{join as SP}from"node:path";function F6($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function bP($){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(F6($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(F6($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function CP($){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(F6(J.fiveHour,"fiveHour",`${Y} 5h`));if(J.weekly)Z.push(F6(J.weekly,"weekly",`${Y} 周`))}return Z.length?Z:null}function EX($){return $===c||xP(SP(k.home($),"auth.json"))}var xX=T(()=>{C0();Q0();C$();q9();I();g0();p2();E0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let H=EX(V),X=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,W={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,k.revision(V)]),enabled:H,models:[],modelCatalogState:{status:H?"idle":"disabled",updatedAt:Date.now()},defaultModel:X??"",async refreshModels(){if(W.enabled=EX(V),!W.enabled){W.models=[],W.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}W.modelCatalogState={status:"loading",updatedAt:null};try{if(W.models=await TX(V),z)for(let G of W.models)G.defaultEffort=z;if(!X)W.defaultModel=W.models[0]?.model??"";W.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(K(`codex-sub ${V} refreshModels MISS: ${G?.message??G}`),W.models=[],G?.code==="CODEX_AUTH_MISSING")W.enabled=!1;W.modelCatalogState={status:W.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let B=j$(G);return Object.assign(B,v.codex.env),k.env(V,B)},resolveSpawnModel(G){return G},async readUsage(){let G=await R1(V),B=bP(G),_=CP(G);if(_)B.windows=_;return B}};return W},Y=J(c);Y.forAccount=(V)=>{if(V===c)return Y;let H=k.revision(V),X=Z.get(V);if(X?.revision===H)return X.source;let z=D6(J(V),$);return Z.set(V,{revision:H,source:z}),z};let Q=Y.refreshModels.bind(Y);return Y.refreshModels=async()=>{await Promise.all([Q(),...k.list().filter((V)=>V.id!==c).map((V)=>Y.forAccount(V.id).refreshModels())])},Y}})});function yP($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function M6($,Z,J){try{let Y=await Y0(yP($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(kP)});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 K(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return K(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var kP=15000;var TZ=T(()=>{a0();I()});function SX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function wP($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function bX($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function vP($){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 fP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),V=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&V)Z[Q]=V}return Z}function NZ($){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(SX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(SX($.weekly,"weekly","周额度"));if($.monthly)Z.push(wP($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var EZ=T(()=>{Q0();z9();q9();F4();TZ();I();E0({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)&&g1(J),V=$.model?.trim()||void 0,H=fP($.slots),X={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:V??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await NX(J,Y),G=[...new Set([...bX($.models),...bX($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:c2,defaultEffort:"max",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=vP(X.models.map((B)=>B.model));for(let B of X.models){let _=_2("glm",B.model);B.context1m=_!=null&&_>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){K(`glm refreshModels MISS: ${z?.message??z}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...j$(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 Q3("glm",z)},async verifyModel(z){return M6(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return NZ(await X9(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
216
+ `),V=Y[Y.length-1];K(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],V.userOpenId,V.msgId)}function zZ($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;K(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)S0(Y,Q);c0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var uH=N(()=>{Z0();h();pH()});import{mkdtemp as pq,rm as cq,writeFile as uq}from"node:fs/promises";import{createRequire as lq}from"node:module";import{tmpdir as dq}from"node:os";import{join as lH}from"node:path";function eq($){let Z=aH.get($);if(Z)return Z;let{liteAdaptor:J}=g1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=g1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=g1("mathjax-full/js/mathjax.js"),{TeX:V}=g1("mathjax-full/js/input/tex.js"),{AllPackages:H}=g1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=g1("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Y(z);let W=Q.document("",{InputJax:new V({packages:H}),OutputJax:new X({fontCache:"none"})}),G={adaptor:z,doc:W};return aH.set($,G),G}function oH($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function $P($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function ZP($,Z=KZ,J=!0){try{let Y=Z*iq,{adaptor:Q,doc:V}=eq(Z),H=V.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),X=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(X)){let K0=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(K0)}let z=X.indexOf("<svg"),W=X.lastIndexOf("</svg>");if(z<0||W<0)throw Error("MathJax returned no SVG");let G=X.slice(z,W+6),B=G.match(/^<svg\b[^>]*>/)?.[0];if(!B)throw Error("MathJax returned malformed SVG root");let _=oH(B.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=oH(B.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),q=B.match(/\bviewBox="([^"]+)"/)?.[1];if(!q)throw Error("MathJax SVG missing viewBox");let P=q.trim().split(/[\s,]+/).map(Number);if(P.length!==4||P.some((K0)=>!Number.isFinite(K0))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,T,M,A]=P,U=/<text\b/.test(G)?sq:0,S=`${D} ${T} ${M+U} ${A}`,C=_*Y,p=U*(C/M),y=Math.max(1,Math.ceil(C+p)),I=Math.max(1,Math.ceil(j*Y)),E=nq-WZ*2,f=Math.min(1,E/y),m=Math.max(1,Math.round(y*f)),l=Math.max(1,Math.round(I*f));if(f<1&&l<aq)throw Error(`formula would be unreadable after width cap (${m}x${l})`);let F=m+WZ*2,b=l+iH*2,d=G.slice(B.length,-6).replace(/currentColor/g,dH).replace(/font-family="serif"/g,`font-family="${tq}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${F}" height="${b}" viewBox="0 0 ${F} ${b}" style="color:${dH}">`,`<rect x="0" y="0" width="${F}" height="${b}" rx="6" fill="${eH}"/>`,`<svg x="${WZ}" y="${iH}" width="${m}" height="${l}" viewBox="${$P(S)}" preserveAspectRatio="xMidYMid meet">`,d,"</svg>","</svg>"].join(""),width:F,height:b}}catch(Y){return K(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function JP($,Z=KZ,J=!0){let Y=ZP($,Z,J);if(!Y)return null;try{let{Resvg:Q}=g1("@resvg/resvg-js"),H=new Q(Y.svg,{background:eH,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:nH,sansSerifFamily:nH}}).render().asPng(),X=new DataView(H.buffer,H.byteOffset,H.byteLength),z=X.getUint32(16),W=X.getUint32(20);if(z!==Y.width||W!==Y.height)throw Error(`PNG dimensions ${z}x${W} != SVG ${Y.width}x${Y.height}`);return{png:H,width:z,height:W}}catch(Q){return K(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function YP($){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 rH($,Z){let J=[],Y=(G,B,_)=>{let j=G[0],q=B.trim();if(!q)return;J.push({start:Z+G.index,end:Z+G.index+j.length,tex:q,raw:j,display:_})},Q,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=V.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 X=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=X.exec($))!==null){let G=(Q[1]??"").trim();if(YP(G))Y(Q,G,!1)}J.sort((G,B)=>G.start-B.start||B.end-G.end);let z=[],W=-1;for(let G of J){if(G.start<W)continue;z.push(G),W=G.end}return z}function $X($){let Z=c8($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...rH($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...rH($.slice(Y),Y));return J}function QP($){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(sH[Y])return sH[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 zP($){let Z=tH.get($);if(Z!==void 0)return Z;return Z=HP++,tH.set($,Z),Z}function WP($,Z){return`${rq}\x00${zP(Z)}\x00${$}`}function GP($){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 KP($,Z){let J=WP($,Z),Y=I1.get(J);if(Y)return Y;let Q=GZ.get(J);if(Q)return Q;let V=(async()=>{let H=JP($,KZ,!0);if(!H)return null;let X=null;try{X=await pq(lH(dq(),"lodestar-math-"));let z=lH(X,`formula-${GP($)}.png`);await uq(z,H.png);let W=await Z(z,{tex:$,width:H.width,height:H.height});if(!W)return K(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:W,width:H.width,height:H.height};if(I1.has(J))I1.delete(J);I1.set(J,G);while(I1.size>XP){let B=I1.keys().next().value;if(typeof B!=="string")break;I1.delete(B)}return G}catch(z){return K(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(X)try{await cq(X,{recursive:!0,force:!0})}catch(z){K(`math-render: temp cleanup failed for ${X}: ${z}`)}}})();GZ.set(J,V);try{return await V}finally{GZ.delete(J)}}function BP($,Z,J){let Y=$.width<=oq;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 ZX($,Z={}){let J=$X($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??VP,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let B=QP(G.tex);if(B!==null)return{unicode:B,uploaded:null}}return{unicode:null,uploaded:await KP(G.tex,Y)}})),V=[],H="",X=0,z=0,W=()=>{if(!H)return;if(H.trim())V.push({type:"markdown",text:H});H=""};for(let G=0;G<J.length;G++){let B=J[G],_=Q[G];if(H+=$.slice(X,B.start),_.unicode!==null){H+=_.unicode,X=B.end;continue}let j=_.uploaded;if(!j){H+=B.raw,X=B.end;continue}W(),V.push(BP(j,B,z++)),X=B.end}if(H+=$.slice(X),W(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function BZ($){return $X($).length>0}var g1,iq=0.5,KZ=22,dH="#1F2329",eH="#F7F8FA",WZ=12,iH=8,nq=720,aq=14,oq=278,rq="v4-native-cjk-tail-pad",sq=1100,nH,tq="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",aH,sH,VP=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (Z0(),Q0));return Z($)},tH,HP=1,I1,GZ,XP=512;var JX=N(()=>{h();g1=lq(import.meta.url),nH=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",aH=new Map;sH={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:"Ω"};tH=new WeakMap,I1=new Map,GZ=new Map});import{readFileSync as jP}from"node:fs";function v2($){return _Z.has($)}function W9($){_Z.add($)}function G9($){_Z.delete($)}function f2(){try{let $={};for(let[Z,J]of d0)$[Z]=J;s(B6,$)}catch($){throw K(`notify-callbacks: save failed (${B6}): ${$}`),$}}function HX(){let $=[],Z;try{Z=jP(B6,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-VX,Q=0,V=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="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",V++;if(d0.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(K(`notify-callbacks: loaded ${d0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),V)K(`notify-callbacks: ${V} interrupted text reply(s) marked UNKNOWN`);if(Q>0||V>0)f2()}catch(J){K(`notify-callbacks: load failed (${B6}): ${J}`)}return $}function XX($){let Z=Date.now();if(Z-QX>=LP)qP(Z),QX=Z;d0.set($.notifyId,$),f2()}function v$($){return d0.get($)}function jZ($){return[...d0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function K9($,Z){if(!$)return;return jZ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function zX($,Z){return!!Z&&[...d0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function h2($,Z){let J=d0.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{f2()}catch(V){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw V}}function B9($,Z,J){let Y=d0.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{f2()}catch(V){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 V}}function LZ($,Z,J,Y){let Q=d0.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,f2()}function _6($,Z,J){try{return B9($,Z,J),{state:"complete"}}catch(Y){let V=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{LZ($,Z,J,V)}catch(H){let X=H instanceof Error?H.message:String(H);V+=`; unknown tombstone persistence also failed: ${X}`;let z=d0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function qP($=Date.now()){let Z=$-VX,J=0;for(let[Y,Q]of d0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)d0.delete(Y),J++;if(J>0)f2();return J}async function qZ($,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,V=setTimeout(()=>Q.abort(),YX);try{let H=await aJ($.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 W=(await H.text()).trim();if(W.startsWith("{")){let G=JSON.parse(W),B=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(B.trim())z=B.trim().slice(0,500)}else if(W)z=W.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:z}}let X="";try{X=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${X?` ${X}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${YX}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(V)}}function WX($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((X)=>X.id===Y):void 0,V=$.replyState?.response,H=Y!==void 0?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y}}:V?{response:{type:"text",...V}}:{};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 VX=604800000,YX=2500,d0,QX,LP=86400000,_Z,B6;var _9=N(()=>{a0();h();V0();f0();d0=new Map,QX=Date.now(),_Z=new Set;B6=fJ});function j6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function I2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(K9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(j6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function PZ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:K9($.chatId)?"notification":j6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function DZ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||I2($,Z)||!Y?.userOpenId||!Y.messageId)return;J.announced=!0;let Q=(J.announcementVersion??0)+1;J.announcementVersion=Q;let V=J.questions[J.currentIdx]?.question.trim()??"",H=V.length>40?V.slice(0,40)+"…":V,X=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${H?`: ${H}`:""}`:H?`❓ ${H}`:"❓ 等你回答问题";(async()=>{if(A0(Y.cardId),await w3(Y.cardId,{config:{summary:{content:X}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||I2($,Z))return;await E1(Y.messageId,[Y.userOpenId])})().catch((z)=>K(`session "${$.sessionName}": question notification failed: ${z}`))}function L6($){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 V=PZ($,J);if(V.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;$0(Z.cardId,R.tool(Q.i),S2(Q.i,J,Y.questions,"\uD83E\uDD14",V)),DZ($,J)}}function GX($){return j6($)!==void 0}async function KX($,Z,J,Y){let Q=j6($);if(!Q){K(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[V,H]=Q,X=I2($,V);if(X){let W=`${X}。这条文字未提交,请稍后重新发送。`;if(!await x($.chatId,W))throw Error(`提问等待提示发送失败: ${W}`);return}if(await FZ($,V,H.currentIdx,Z,J)&&Y)c0(Y,"CheckMark")}async function BX($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return K(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==V.currentIdx)return K(`session "${$.sessionName}": stale ask click q=${J} current=${V.currentIdx}`),!1;return _X($,Z,{optionIdx:Y,user:Q})}async function FZ($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return K(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return K(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==V.currentIdx)return K(`session "${$.sessionName}": stale ask custom q=${J} current=${V.currentIdx}`),!1;return _X($,Z,{customText:H,user:Q})}function _X($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=I2($,Z);if(Q)return K(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let V=Y.currentIdx,H=Y.questions[V];if(!H)return K(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let X;if(J.customText!==void 0)X=J.customText;else if(J.optionIdx!==void 0){let _=H.options?.[J.optionIdx];if(!_)return K(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;X=_.label}else return K(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[H.question]=X,Y.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Y.questions.length,W=void 0;for(let _=V+1;_<z;_++)if(!Y.answered.has(_)){W=_;break}Y.currentIdx=W;let G=$.currentTurn,B=G?.toolByUseId.get(Z);if(G&&B){let _=S2(B.i,Z,Y.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Y.answered});$0(G.cardId,R.tool(B.i),_)}if(W===void 0)if(Y.requestId)UZ($,Z);else K(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),L6($);return!0}function UZ($,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),L6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var q6=N(()=>{k$();J$();Z0();h();_9()});import{isAbsolute as DP}from"node:path";function O0($){if($?.planLiveInserted)return R.planLive;return $?.taskLiveInserted?R.taskBoardLive:R.footer}function FP($){return $==="ImageGeneration"||$==="imageGeneration"}function UP($,Z,J){if(J||!FP($))return null;let Y=K6(Z.trim());return DP(Y)?Y:null}function MP($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function jX($,Z,J){return $==="read"?e4(Z,J):t4(Z,J)}function LX($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=MP(J);if(Q&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,W=$.currentTurn.toolBatches.get(z);if(W&&W.kind===Q){let G=W.items.length;W.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:z,name:J,input:Y,batchSlot:G});let B=Q==="read"?e4(z,W.items):t4(z,W.items);$0($.currentTurn.cardId,R.tool(z),B),P6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let V=v1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,F0(z.cardId,f1($.taskBoard),{type:"insert_before",targetElementId:R.footer});else $0(z.cardId,R.taskBoardLive,f1($.taskBoard));let W=V==="TaskCreate";if(W)z.taskUpdateI=null;else z.taskCreateI=null;let G=(W?z.taskCreateI:z.taskUpdateI)===null;if(G)if(W)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let B=W?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:B,name:J,input:Y});let _=V1(B,$.taskBoard,{name:V,status:"⏳"});G?F0(z.cardId,_,{type:"insert_before",targetElementId:O0(z)}):$0(z.cardId,R.tool(B),_),P6(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 W=Q==="read"?e4(H,z):t4(H,z);F0($.currentTurn.cardId,W,{type:"insert_before",targetElementId:O0($.currentTurn)}),P6($.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:[],W=z.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:z,i:H,answers:{},answered:G,currentIdx:W});let B=S2(H,Z,z,"\uD83E\uDD14",PZ($,Z));F0($.currentTurn.cardId,B,{type:"insert_before",targetElementId:O0($.currentTurn)}),DZ($,Z);return}let X=A$(H,J,Y,null,"⏳");F0($.currentTurn.cardId,X,{type:"insert_before",targetElementId:O0($.currentTurn)}),P6($.currentTurn,J,Y)}function P6($,Z,J){if(!$)return;let Y=$1(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,V=k1(Z),H=Q?`\uD83D\uDD27 ${V}: ${Q}`:`\uD83D\uDD27 ${V}`;b1($.cardId,H)}function qX($,Z,J,Y,Q){if(!$.currentTurn)return;let V=$.currentTurn.toolByUseId.get(Z);if(!V)return;if(Q&&typeof Q==="object")V.input={...V.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(`
217
+ `):JSON.stringify(J);if(V.output=H,V.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let X=UP(V.name,H,Y);if(X){AP($,$.currentTurn,V,X),j9($);return}if(V.name==="AskUserQuestion"){j9($);return}if(V.batchSlot!=null){let G=$.currentTurn.toolBatches.get(V.i);if(G){let B=G.items[V.batchSlot];if(B)B.output=H,B.isError=Y;let _=jX(G.kind,V.i,G.items);$0($.currentTurn.cardId,R.tool(V.i),_)}j9($);return}let z=v1(V.name);if(z){OP($,V,z,V.input,H,Y,V.resolvedNote);return}let W=A$(V.i,V.name,V.input,H,Y?"❌":"✅",V.resolvedNote);$0($.currentTurn.cardId,R.tool(V.i),W),j9($)}function AP($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,V=R.tool(J.i),H=Z.imageDeliveryInflight??=new Map,X=H.get(Q)??new Set;H.set(Q,X);let z=(async()=>{let W=null;try{W=await X5(Y)}catch(B){K(`generated image upload failed: ${B}`)}if(W){let B=!1;try{B=await U0(Q,V,A$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1})}catch(_){K(`generated image embed failed: ${_}`)}if(B){J.imageKey=W,Z.outboundSentPaths.add(Y);return}K(`generated image could not be embedded in card ${Q}; sending it as a separate message`)}let G=W?await k3($.chatId,W)!==null:await p4($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else K(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await U0(Q,V,A$(J.i,J.name,J.input,J.output??null,G?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!G&&W)await x($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(W)=>{K(`generated image delivery failed: ${W}`),await x($.chatId,`❌ 生成图片发送失败:${W instanceof Error?W.message:String(W)}`)});X.add(z),z.finally(()=>{if(X.delete(z),!X.size)H.delete(Q)}).catch((W)=>K(`generated image failure notice failed: ${W}`))}async function MZ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function OP($,Z,J,Y,Q,V,H){if(!$.currentTurn)return;if(!V)$.taskBoard=JZ($.taskBoard,J,Y,Q);let X=V1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},H);if($0($.currentTurn.cardId,R.tool(Z.i),X),$.currentTurn.taskLiveInserted)$0($.currentTurn.cardId,R.taskBoardLive,f1($.taskBoard));j9($)}function j9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function AZ($,Z,J,Y,Q,V=$.currentTurn){let H=V;if(!H)return;for(let[X,z]of Y){if(H.toolByUseId.has(X))continue;let W=z.batchSlot??null,G=z.input,B,_;if(W!=null){let M=Q.get(z.i)?.items[W];if(!M)continue;G=M.input,B=M.output,_=M.isError}else B=z.output??null,_=z.isError??!1;let j=B!=null,q=E2(Z,R.tool(z.i));if(j&&!q)continue;if(W!=null){let M=Q.get(z.i)?.kind;if(!M)continue;let A=H.toolCount++,U={toolUseId:X,input:G,output:B,isError:_};H.toolBatches.set(A,{kind:M,items:[U]}),H.toolByUseId.set(X,{...z,i:A,batchSlot:0}),F0(J,jX(M,A,[U]),{type:"insert_before",targetElementId:O0(H)});continue}let P=v1(z.name);if(P){let M=P==="TaskCreate";if(M)H.taskUpdateI=null;else H.taskCreateI=null;let A=(M?H.taskCreateI:H.taskUpdateI)===null;if(A)if(M)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let U=M?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(X,{...z,i:U});let S=!j?"⏳":_?"❌":"✅",C=V1(U,$.taskBoard,{name:P,status:S},z.resolvedNote);A?F0(J,C,{type:"insert_before",targetElementId:O0(H)}):$0(J,R.tool(U),C);continue}let D=H.toolCount++;H.toolByUseId.set(X,{...z,i:D});let T=!j?"⏳":_?"❌":"✅";F0(J,A$(D,z.name,z.input,B,T,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:O0(H)})}}var PX=N(()=>{HZ();k$();J$();Z0();h();q6()});async function DX($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return K(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let V=$.proc;if(!V)return K(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{V.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(W){return K(`session "${$.sessionName}": permission response ${Z} failed: ${W}`),{ok:!1,message:`权限决定发送失败: ${W instanceof Error?W.message:W}`}}$.pendingPermissions.delete(Z);let X=$.currentTurn,z=X?.toolByUseId.get(Q.toolUseId);if(X&&z){let W=v1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,B=W?V1(z.i,$.taskBoard,{name:W,status:"❌"},G):A$(z.i,z.name,z.input,G,"❌");$0(X.cardId,R.tool(z.i),B)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let B=W?V1(z.i,$.taskBoard,{name:W,status:"⏳"},z.resolvedNote):A$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);$0(X.cardId,R.tool(z.i),B)}}if(K(`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 FX($,Z){let J=$.currentTurn;if(!J){K(`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){K(`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){K(`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){K(`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)UZ($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),K(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let V=b5(Q.i,Q.name,Q.input,Z.request_id);if($0(J.cardId,R.tool(Q.i),V),J.userOpenId&&J.messageId){let H=$1(Q.name,Q.input),X=k1(Q.name),z=H&&H.length>30?H.slice(0,30)+"…":H,W=z?`\uD83D\uDD10 等审批: ${X} · ${z}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{A0(J.cardId),await w3(J.cardId,{config:{summary:{content:W}}}),await E1(J.messageId,[J.userOpenId])})()}}var UX=N(()=>{k$();J$();Z0();h();q6()});class MX{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new O1({accountId:Q,login:!0}),Z=900000,J=(Q,V)=>{k.recordLogin(Q,V),F2(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=mY($),Y;try{Y=this.createClient($)}catch(z){throw J(),z}let Q,V,H=new Promise((z,W)=>{Q=z,V=W});H.catch(()=>{});let X={owner:Z,client:Y,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:H,resolve:Q,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};X.notification=(z,W)=>{if(X.finishing||!X.loginRequested)return;if(z==="account/updated"){if(W?.authMode==="chatgpt"){if(X.authUpdated=!0,X.loginSucceeded)this.finish(X)}return}if(z!=="account/login/completed")return;if(!X.loginId){X.early.push(W);return}if(W?.loginId!==X.loginId)return;if(W?.success!==!0){this.finish(X,Error(typeof W?.error==="string"?W.error:"Codex 登录未成功"));return}if(X.loginSucceeded)return;if(X.loginSucceeded=!0,K(`codex-login: authorization completed account=${$} authUpdated=${X.authUpdated}`),X.timer)clearTimeout(X.timer);if(X.authUpdated)this.finish(X);else X.timer=setTimeout(()=>{this.finish(X,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},X.closed=(z)=>{this.finish(X,z)},Y.on("notification",X.notification),Y.on("closed",X.closed),Y.on("protocolError",X.closed),this.attempts.set($,X);try{await Y.initialize("lodestar-login"),X.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(X.loginId=z.loginId,X.finishing)throw await H,Error("登录已结束");X.timer=setTimeout(()=>{this.cancelAttempt(X,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let W of X.early)X.notification("account/login/completed",W);return X.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:H}}catch(z){return await this.finish(X,D6(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};取消请求失败:${D6(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=D6(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,`登录进程关闭失败:${D6(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 D6($){return $ instanceof Error?$:Error(String($))}var m1;var OZ=N(()=>{C$();g0();h();m1=new MX});function AX($){let Z=new Map,J=$.map((G)=>{let B=G.fingerprint?Z.get(G.fingerprint):void 0;if(G.fingerprint&&!B)Z.set(G.fingerprint,G.account.name);return{...G,...B?{duplicateOf:B}:{}}}),Y=J.filter((G)=>!G.duplicateOf),V=(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]:[]),X=V&&H.every((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((B)=>B.percent!==null))?H.filter((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((B)=>B.percent<100)).length:null,z=V&&H.every((G)=>G.resetCredits!=null)?H.reduce((G,B)=>G+B.resetCredits,0):null,W=["fiveHour","weekly"].map((G)=>{let B=H.map((j)=>j[G]).filter((j)=>j!==null),_=V&&B.every((j)=>j.percent!==null&&j.percent>=0&&j.percent<=100);return{kind:G,count:B.length,remaining:_?B.reduce((j,q)=>j+(100-q.percent)/100,0):null}}).filter((G)=>G.count||!V);return{entries:J,complete:V,available:X,resetCredits:z,windows:W}}var OX=N(()=>{g0();C$()});class g2{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=TP){let Y=await J.sendCard($,V$(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new g2(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=x4($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=x4($);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,R.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:E4($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var TP;var RX=N(()=>{Z0();k$();k0();A2();TP={sendCard:u,convertMessageToCard:$$,recordCardCreated:u0,replaceElementChecked:U0,patchSettingsChecked:P0,dispose:w0}});var NZ={};N$(NZ,{settleCodexAccountCards:()=>RZ,runCodexNamedHi:()=>xP,runCodexAccountCommand:()=>SP});import{createHash as EP}from"node:crypto";function L9($,Z){let J=$ instanceof Error?$.message:String($),Y=!/失败|未完全退出/.test(J)&&/登录已取消|服务退出/.test(J),Q=/过期|等待超过|expired/i.test(J),V=J.split(/[\n;]/)[0];return{phase:Y?"cancelled":Q?"expired":"error",name:Z,message:V.length>80?V.slice(0,77)+"…":V,...J!==V||V.length>80?{details:J}:{}}}async function NX($,Z){if(!await u($.chatId,V$(L9(Z))))throw Error("Codex 错误卡片发送失败")}async function xP($,Z){let J=await g2.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Y=k.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(L9(Y,Z))}}async function RZ(){let Z=(await Promise.allSettled([...p1.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function SP($,Z,J,Y,Q){if(Z==="reset"){await CP($,J,Q);return}let V={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let z=m1.pending(V);if(!J&&z.length!==1)throw Error(z.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?k.find(J).id:z[0];await m1.cancel(W,V),await p1.get(W)}catch(z){await NX($,z)}return}let H=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,X=await g2.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:H,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let _=k.find(J);if(p1.has(_.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:j}=k.remove(_.id);F2(_.id),await X.finish({phase:"deleted",name:_.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:j?`已清除 ${j} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let _=J?Number(J):1,j=$.currentProvider()==="codex"?$.currentModelLabel():H0("codex-sub")?.defaultModel;if(!j)throw Error("Codex 模型 MISS,无法计算调度顺序");let q=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,P=await P3.choose({model:j,effort:q}),D=AX(P.candidates.flatMap((T)=>T.usage?[{account:T.account,usage:T.usage,fingerprint:T.identity.startsWith("record:")?null:T.identity}]:[]));await X.finish({phase:"accounts",total:D,currentId:$.codexAccountId(),...k.preferred($.sessionName)?{selectedId:k.selected($.sessionName)}:{},page:_,scheduling:{candidates:P.candidates,ultra:q==="ultra"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");k.selectAuto($.sessionName),await X.finish({phase:"selected",name:"自动选择",current:k.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await X.finish({phase:"current",current:k.get($.codexAccountId()).name,selected:k.preferred($.sessionName)===null?"自动 · 最高分优先":k.get(k.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let _=k.find(J),j=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,P=k.get($.codexAccountId()).name;if($.currentProvider()==="codex")T1($.sessionName,"codex",j,q,"codex-sub");if(k.select($.sessionName,_.id),$.currentProvider()==="codex")$.selectedModel=j,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await X.finish({phase:"selected",name:_.name,current:P,selected:_.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Y)throw Error("无法确认登录发起者");let z=k.ensure(J);if(r9(z.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(p1.has(z.id))throw Error("登录结果正在更新,请稍等");let W=await m1.start(z.id,V);try{await X.update({phase:"waiting",flow:"login",name:z.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${z.name}`:""}`})}catch(_){throw await m1.cancel(z.id,V),_}let G=(async()=>{let _;try{_=await W.done}catch(q){await X.finish(L9(q,z.name));return}await X.update({phase:"checking",flow:"login",name:z.name,message:"授权完成,正在读取模型…"});let j;try{await D2();let q=H0("codex-sub",z.id);if(!q)throw Error("Codex 订阅来源尚未初始化");if(await q.refreshModels(),q.modelCatalogState?.status!=="ready")throw Error(q.modelCatalogState?.error??"模型目录未就绪")}catch(q){j=q instanceof Error?q.message:String(q)}await X.finish({phase:j?"warning":"success",flow:"login",name:z.name,email:_.email,plan:_.planType,...j?{title:"已登录 · 目录 MISS",details:j}:{},hint:`已加入自动选择 · 优先使用:codex-account ${z.id==="default"?"default":z.name}`})})();p1.set(z.id,G);let B=()=>{if(p1.get(z.id)===G)p1.delete(z.id)};G.then(B,(_)=>{K(`codex-login: terminal card write failed: ${_}`),B()})}catch(z){K(`codex-${Z}: ${z}`),await X.finish(L9(z,H))}}async function CP($,Z,J){let Y;try{if(!J?.trim())throw Error("缺少消息 ID,未使用重置卡;请在群内发送 codex-reset [备注]");if(!Z&&(!$.proc?.isAlive()||$.proc.provider!=="codex"||$.proc.codexAccountSelectionMode?.()===null||$.proc.turnRetry?.reason==="quota"&&$.proc.turnRetry.phase==="waiting"))throw Error("当前没有正在使用的 Codex 账号;请用 codex-reset 备注,或 codex-reset default 指定默认账号");Y=Z?k.find(Z):k.get(o0($.proc))}catch(W){K(`codex-reset: ${W}`),await NX($,W);return}let Q=await g2.open($.chatId,{phase:"checking",name:Y.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let W=EP("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await bQ(Y.id,W)}catch(W){K(`codex-reset: ${W}`),await Q.finish(L9(W,Y.name));return}let H=bP[V.outcome],z=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
218
+ `);await Q.finish({...H,name:Y.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var p1,bP;var F6=N(()=>{Z0();g0();OZ();Y0();OX();U7();RX();A2();h();C$();p1=new Map;bP={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});function b0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function TZ($,Z){let J=$.agent==="claude"?M8.filter((Q)=>Q!=="default"):$.agent==="codex"?[...p8]:["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 U6($,Z){let J=$.modelSelection,Y=new Set(b0(Z.hidden_models)),Q=[...new Set([...b0(Z.custom_models),...J?[]:b0(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},H=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.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 X=$.models,z=(J?V.availableModels:X).map((G)=>({...G,origin:G.origin??"upstream"}));for(let G of Q){if(z.some((B)=>B.model.toLowerCase()===G.toLowerCase()))continue;z.push({model:G,display:G,origin:"custom",...TZ($,Z)})}V.availableModels=z;let W=J?X.map((G)=>z.find((B)=>B.model===G.model)??{...G,origin:"upstream"}):z;$.models=[...W.filter((G)=>G.origin==="custom"||!Y.has(G.model)),...z.filter((G)=>G.origin==="custom"&&!W.some((B)=>B.model===G.model))],V.modelIds=$.models.map((G)=>G.model)},$}var m2=N(()=>{D0();U1()});import{homedir as kP}from"node:os";function xX($,Z=EX){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Q),J(V)},(V)=>{clearTimeout(Q),Y(V)})})}function TX($){return typeof $==="string"&&yP.includes($)?$:null}async function SX(){let{ClaudeAgentProcess:$}=await Promise.resolve().then(() => (F4(),RQ)),Z=new $({workDir:kP(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1}});Z.on("error",(J)=>K(`Claude model catalog MISS: ${J.message}`));try{let J=await xX(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 bX($="default"){let Z=new O1({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 xX(Z.request("model/list",{}));if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let Q=Y.data,V=[];for(let H of Q){if(!H||H.hidden||!H.id)continue;let X=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((W)=>TX(W?.reasoningEffort)).filter((W)=>W!==null);if(!X.length)continue;let z=TX(H.defaultReasoningEffort)??X[0];V.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:X,defaultEffort:z})}return V}finally{await Z.close()}}async function CX($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,V=await J0(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(EX)});if(!V.ok)throw Error(`HTTP ${V.status}`);let H=await V.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 W=String(z.display_name||z.id);return{model:W,display:W,efforts:p2,defaultEffort:"max"}})}var EX=1e4,yP,p2;var q9=N(()=>{a0();C$();h();yP=["none","minimal","low","medium","high","xhigh","max","ultra"];p2=["max","xhigh","high","medium","low"]});import{existsSync as wP}from"node:fs";import{join as vP}from"node:path";function kX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function fP($){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(kX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(kX($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function yX($){return $===c||wP(vP(k.home($),"auth.json"))}var wX=N(()=>{C0();Y0();C$();q9();h();g0();m2();E0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let H=yX(V),X=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,W={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,k.revision(V)]),enabled:H,models:[],modelCatalogState:{status:H?"idle":"disabled",updatedAt:Date.now()},defaultModel:X??"",async refreshModels(){if(W.enabled=yX(V),!W.enabled){W.models=[],W.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}W.modelCatalogState={status:"loading",updatedAt:null};try{if(W.models=await bX(V),z)for(let G of W.models)G.defaultEffort=z;if(!X)W.defaultModel=W.models[0]?.model??"";W.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(K(`codex-sub ${V} refreshModels MISS: ${G?.message??G}`),W.models=[],G?.code==="CODEX_AUTH_MISSING")W.enabled=!1;W.modelCatalogState={status:W.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let B=j$(G);return Object.assign(B,v.codex.env),k.env(V,B)},resolveSpawnModel(G){return G},async readUsage(){return fP(await R1(V))}};return W},Y=J(c);Y.forAccount=(V)=>{if(V===c)return Y;let H=k.revision(V),X=Z.get(V);if(X?.revision===H)return X.source;let z=U6(J(V),$);return Z.set(V,{revision:H,source:z}),z};let Q=Y.refreshModels.bind(Y);return Y.refreshModels=async()=>{await Promise.all([Q(),...k.list().filter((V)=>V.id!==c).map((V)=>Y.forAccount(V.id).refreshModels())])},Y}})});function IP($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function M6($,Z,J){try{let Y=await J0(IP($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(hP)});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 K(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return K(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var hP=15000;var EZ=N(()=>{a0();h()});function vX($,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 fX($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function mP($){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 pP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),V=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&V)Z[Q]=V}return Z}function xZ($){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(vX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(vX($.weekly,"weekly","周额度"));if($.monthly)Z.push(gP($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var SZ=N(()=>{Y0();z9();q9();D4();EZ();h();E0({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)&&h1(J),V=$.model?.trim()||void 0,H=pP($.slots),X={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:V??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await CX(J,Y),G=[...new Set([...fX($.models),...fX($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:p2,defaultEffort:"max",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=mP(X.models.map((B)=>B.model));for(let B of X.models){let _=K2("glm",B.model);B.context1m=_!=null&&_>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){K(`glm refreshModels MISS: ${z?.message??z}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...j$(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 Q3("glm",z)},async verifyModel(z){return M6(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return xZ(await X9(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
219
219
  \`\`\`
220
220
  glm-setup <base_url> <token>
221
- \`\`\``,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(!g1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var CX=T(()=>{Q0();q9();E0({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 RX(),!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 kX($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function IP($){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 gP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),V=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&V)Z[Q]=V}return Z}function mP($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function pP($,Z){let J=new URL($).origin,Y=await Y0(`${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:c2,defaultEffort:"high"}))}async function xZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await Y0(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(cP)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof H?.currency==="string"?H.currency:"",z=H?.total_balance;if(!X||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:X}}}catch(Y){return K(`deepseek readUsage MISS: ${Y?.message??Y}`),{kind:"balance",state:"network",windows:[],reason:Y?.message??String(Y)}}}var hP="https://api.deepseek.com/anthropic",cP=1e4;var SZ=T(()=>{a0();Q0();q9();F4();TZ();I();E0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||hP,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,V=$.model?.trim()||void 0,H=gP($.slots),X={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await pP(J,Y),G=[...new Set([...kX($.models),...kX($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:c2,defaultEffort:"high",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=IP(X.models.map((B)=>B.model));for(let B of X.models){let _=_2("deepseek",B.model);B.context1m=_!=null&&_>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){K(`deepseek refreshModels MISS: ${z?.message??z}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...j$(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 Q3("deepseek",z)},async verifyModel(z){return M6(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return xZ(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
221
+ \`\`\``,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(!h1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var hX=N(()=>{Y0();q9();E0({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 SX(),!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 IX($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function uP($){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 lP($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),V=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&V)Z[Q]=V}return Z}function dP($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function iP($,Z){let J=new URL($).origin,Y=await J0(`${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:p2,defaultEffort:"high"}))}async function bZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await J0(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(nP)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof H?.currency==="string"?H.currency:"",z=H?.total_balance;if(!X||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:X}}}catch(Y){return K(`deepseek readUsage MISS: ${Y?.message??Y}`),{kind:"balance",state:"network",windows:[],reason:Y?.message??String(Y)}}}var cP="https://api.deepseek.com/anthropic",nP=1e4;var CZ=N(()=>{a0();Y0();q9();D4();EZ();h();E0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||cP,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,V=$.model?.trim()||void 0,H=lP($.slots),X={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await iP(J,Y),G=[...new Set([...IX($.models),...IX($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:p2,defaultEffort:"high",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=uP(X.models.map((B)=>B.model));for(let B of X.models){let _=K2("deepseek",B.model);B.context1m=_!=null&&_>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){K(`deepseek refreshModels MISS: ${z?.message??z}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...j$(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 Q3("deepseek",z)},async verifyModel(z){return M6(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return bZ(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
222
222
  \`\`\`
223
223
  deepseek-setup <api_key>
224
224
  \`\`\`
225
- 默认官方 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(!mP(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function l1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var bZ;var yX=T(()=>{bZ=[{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 H1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function kZ($){return $ instanceof Error?$.message:String($)}function wX($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function u2($){return $.replace(/\[1m\]$/,"")}function U6($){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 fX($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await Y0(`${U6($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(lP)});if(!Y.ok){let Q=await Y.text(),V="";if(Q.trim().startsWith("{"))try{let H=JSON.parse(Q);if(H1(H)&&H1(H.error)&&typeof H.error.message==="string")V=H.error.message}catch{}throw new yZ(Y.status,V.replaceAll(Z,"[redacted]"))}return Y.json()}async function dP($,Z){let J=await fX($,Z,"models/user");if(!H1(J)||!Array.isArray(J.data))throw Error("OpenRouter models: data 数组缺失");let Y=[],Q=new Set;for(let V of J.data){if(!H1(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!H1(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(l1(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Q.has(V.id))continue;let H=H1(V.reasoning)?V.reasoning:void 0,X=H?.supported_efforts,z=X===null||X===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(X)?[...new Set(X.filter((_)=>_!=="default"&&N0(_)))]:["default"],W=bZ.find((_)=>_.model===V.id),G=W?z.includes(W.effort)?W.effort:null:z[0]==="default"?"default":N0(H?.default_effort)&&z.includes(H.default_effort)?H.default_effort:null,B=_2("openrouter",V.id);Y.push({model:V.id,display:V.name,efforts:z,defaultEffort:G,context1m:B!==void 0&&B>=1e6||void 0}),Q.add(V.id)}if(!Y.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Y}function vX($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function iP($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await fX($,Z,"credits");if(!H1(J)||!H1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!vX(Y)||!vX(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=kZ(J);return K(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof yZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var uP="https://openrouter.ai/api",lP=1e4,CZ,yZ;var hX=T(()=>{a0();D0();Q0();F4();I();yX();CZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};yZ=class yZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};E0({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()||uP,V=$.model?.trim()||"",H=$.models===void 0?bZ.map((z)=>z.model):wX($.models),X={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Y,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:H,availableModels:[]},validateCustomModelId(z){if(l1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let W=X.modelSelection.availableModels.find((G)=>u2(G.model)===u2(z));if(!W||W.unavailableReason||!W.efforts.length)return"model-unavailable";return W.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(X.models=[],X.modelSelection.availableModels=[],!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await dP(Q,Y),W=z.find((B)=>B.model===u2(V));if(V&&!W)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!N0($.effort)||!W.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);W.defaultEffort=$.effort}let G=H.map((B)=>{let _=z.find((j)=>j.model===u2(B));if(!_)return{model:B,display:B,efforts:[],defaultEffort:null,unavailableReason:l1(B)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:B}});X.models=G,X.modelSelection.availableModels=z,X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let W=kZ(z);K(`openrouter refreshModels MISS: ${W}`),X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W}}},spawnEnv(z,W){if(!Y)throw Error("OpenRouter API key missing");let G=W||V;if(!G)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(l1(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let B=j$(z);B.ANTHROPIC_BASE_URL=U6(Q),B.ANTHROPIC_AUTH_TOKEN=Y,B.ANTHROPIC_API_KEY="",B.CLAUDE_CODE_NO_MODEL_FALLBACK="1",B.ANTHROPIC_MODEL=G,B.ANTHROPIC_SMALL_FAST_MODEL=G,B.CLAUDE_CODE_SUBAGENT_MODEL=G,B.ANTHROPIC_DEFAULT_FABLE_MODEL=G;for(let _ of Object.values(CZ))B[_]=G;for(let _ of wX($.slots)){let j=_.indexOf("="),q=_.slice(0,j).trim(),P=_.slice(j+1).trim();if(j<1||!Object.hasOwn(CZ,q)||!P)throw Error(`OpenRouter slots 无效: ${_}`);if(l1(P)||!X.modelSelection.availableModels.some((D)=>!D.unavailableReason&&u2(D.model)===u2(P)))throw Error(`OpenRouter slot 模型不在账号目录中: ${P}`);if(X.modelEnvironmentRevision(P)!==X.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${P}`);B[CZ[q]]=P}return B},resolveSpawnModel(z){if(l1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return iP(Q,Y)}};return X},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:U6(Z[0])}:{}}}}catch(J){return{error:kZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=U6(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var IX=T(()=>{Q0();D0();W4();H0();SZ();p2();E0({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 V=U4(Q);if(!Z)throw Error("DeepSeek Harness API key is missing");if(V.DEEPSEEK_API_KEY=Z,V.DEEPSEEK_BASE_URL=J,V.LODESTAR_DSH_PROVIDER="deepseek-official",$.bin)V.LODESTAR_DSH_NODE=$.bin;return V},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 V2({cwd:$2,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...b0($.models),...b0($.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(B0)||!B0(H.defaultEffort)||!H.efforts.includes(H.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${H.model}`);let V=$.model?.trim()||Q.find((H)=>H.isDefault)?.model;if(!V||!Q.some((H)=>H.model===V))throw Error("DSH default model is not in its catalog");Y.models=Q.map(({model:H,display:X,efforts:z,defaultEffort:W,isCustom:G})=>{let B=$.effort?.trim();if(B&&(!B0(B)||!z.includes(B)))throw Error(`DSH model ${H} does not support configured effort ${B}`);return{model:H,display:X,efforts:z,defaultEffort:B?B:W,origin:G?"custom":"upstream"}}),Y.defaultModel=V,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 q2(Y).find((V)=>V.model===Q)?.model},readUsage(){return Z?xZ(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 wZ($){let Z=new URL($);if(!g1(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 nP($,Z){let J=await Y0(`${$}/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 gX=T(()=>{a0();C0();D0();Q0();W4();H0();z9();EZ();p2();E0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=v.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&g1(Y)?{api_key:J,base_url:wZ(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=wZ($.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",V,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([...V??[]].sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(X){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=U4(X);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,V)z.LODESTAR_DSH_MODELS=JSON.stringify(V);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(H.models=[],V=void 0,!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let X=await nP(Y,J),z=[...X];for(let G of[...b0($.models),...b0($.custom_models)])if(!z.some((B)=>B.model.toLowerCase()===G.toLowerCase()))z.push({model:G,display:G});if(V=z.map((G)=>G.model),!$.model?.trim()){let G=(B)=>Number(B.match(/\d+(?:\.\d+)?/)?.[0]??-1);H.defaultModel=[...X].sort((B,_)=>G(_.model)-G(B.model))[0].model}let W=await V2({cwd:$2,env:H.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");H.models=z.map((G)=>{let B=W.find((P)=>P.model===G.model),_=RZ(H,$),j=B?B.efforts.filter(B0):_.efforts,q=$.effort?.trim()||B?.defaultEffort||_.defaultEffort;return{...G,display:B?.display??G.display,efforts:j,defaultEffort:B0(q)&&j.includes(q)?q:null,origin:X.some((P)=>P.model===G.model)?"upstream":"custom"}}),H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){throw H.models=[],V=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:X instanceof Error?X.message:String(X)},X}},resolveSpawnModel(X){return q2(H).find((z)=>z.model===X&&!z.unavailableReason)?.model},async readUsage(){return J?NZ(await X9(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:wZ(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 pX={};T$(pX,{tokenSourceSpawnRevision:()=>mX,buildTokenSourcesFromConfig:()=>vZ});import{createHash as aP}from"node:crypto";function vZ(){L7();let $=YZ(),Z=D2().map((V)=>{let H=V.configSectionId?(v.token_sources??{})[V.configSectionId]??{}:{},X=V.detect?.fromSettingsEnv($)??null,z=D6(V.build(H,X),H);return z.spawnRevision=mX(V.kind,H,X),z}),J=Z.find((V)=>V.kind==="claude-native");if(J){let V=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!V,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let V of Z)_7(V);let Q=Z.find((V)=>V.enabled&&v.token_sources?.[V.id]?.default===!0)??Z.find((V)=>V.enabled);if(Q)j7(Q.id);return Z.length}function mX($,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 aP("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var fZ=T(()=>{C0();Q0();z9();p2();xX();EZ();CX();SZ();hX();IX();gX()});import{readFileSync as oP}from"node:fs";function rP($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function sP($,Z){let J=[`[token_source.${$}]`],Y=(Q,V)=>{if(V!==void 0)J.push(`${Q} = "${rP(V)}"`)};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(`
226
- `)}function tP($,Z){let J=oP(T0,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
227
- `),V=!1,H=p9().token_sources[$]??{},X=[];for(let B of Q){let _=B.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(_)V=_===Y;if(!V)X.push(B)}let z={...H},W={...Z};for(let B of Object.keys(W))if(W[B]!==void 0)z[B]=W[B];let G=z;while(X.length&&X[X.length-1]==="")X.pop();Q$(T0,X.join(`
225
+ 默认官方 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(!dP(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function c1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var kZ;var gX=N(()=>{kZ=[{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 H1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function wZ($){return $ instanceof Error?$.message:String($)}function mX($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function c2($){return $.replace(/\[1m\]$/,"")}function A6($){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 cX($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await J0(`${A6($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(oP)});if(!Y.ok){let Q=await Y.text(),V="";if(Q.trim().startsWith("{"))try{let H=JSON.parse(Q);if(H1(H)&&H1(H.error)&&typeof H.error.message==="string")V=H.error.message}catch{}throw new vZ(Y.status,V.replaceAll(Z,"[redacted]"))}return Y.json()}async function rP($,Z){let J=await cX($,Z,"models/user");if(!H1(J)||!Array.isArray(J.data))throw Error("OpenRouter models: data 数组缺失");let Y=[],Q=new Set;for(let V of J.data){if(!H1(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!H1(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(c1(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Q.has(V.id))continue;let H=H1(V.reasoning)?V.reasoning:void 0,X=H?.supported_efforts,z=X===null||X===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(X)?[...new Set(X.filter((_)=>_!=="default"&&T0(_)))]:["default"],W=kZ.find((_)=>_.model===V.id),G=W?z.includes(W.effort)?W.effort:null:z[0]==="default"?"default":T0(H?.default_effort)&&z.includes(H.default_effort)?H.default_effort:null,B=K2("openrouter",V.id);Y.push({model:V.id,display:V.name,efforts:z,defaultEffort:G,context1m:B!==void 0&&B>=1e6||void 0}),Q.add(V.id)}if(!Y.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Y}function pX($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function sP($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await cX($,Z,"credits");if(!H1(J)||!H1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!pX(Y)||!pX(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=wZ(J);return K(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof vZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var aP="https://openrouter.ai/api",oP=1e4,yZ,vZ;var uX=N(()=>{a0();D0();Y0();D4();h();gX();yZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};vZ=class vZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};E0({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()||aP,V=$.model?.trim()||"",H=$.models===void 0?kZ.map((z)=>z.model):mX($.models),X={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Y,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:H,availableModels:[]},validateCustomModelId(z){if(c1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let W=X.modelSelection.availableModels.find((G)=>c2(G.model)===c2(z));if(!W||W.unavailableReason||!W.efforts.length)return"model-unavailable";return W.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(X.models=[],X.modelSelection.availableModels=[],!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let z=await rP(Q,Y),W=z.find((B)=>B.model===c2(V));if(V&&!W)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!T0($.effort)||!W.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);W.defaultEffort=$.effort}let G=H.map((B)=>{let _=z.find((j)=>j.model===c2(B));if(!_)return{model:B,display:B,efforts:[],defaultEffort:null,unavailableReason:c1(B)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:B}});X.models=G,X.modelSelection.availableModels=z,X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let W=wZ(z);K(`openrouter refreshModels MISS: ${W}`),X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W}}},spawnEnv(z,W){if(!Y)throw Error("OpenRouter API key missing");let G=W||V;if(!G)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(c1(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let B=j$(z);B.ANTHROPIC_BASE_URL=A6(Q),B.ANTHROPIC_AUTH_TOKEN=Y,B.ANTHROPIC_API_KEY="",B.CLAUDE_CODE_NO_MODEL_FALLBACK="1",B.ANTHROPIC_MODEL=G,B.ANTHROPIC_SMALL_FAST_MODEL=G,B.CLAUDE_CODE_SUBAGENT_MODEL=G,B.ANTHROPIC_DEFAULT_FABLE_MODEL=G;for(let _ of Object.values(yZ))B[_]=G;for(let _ of mX($.slots)){let j=_.indexOf("="),q=_.slice(0,j).trim(),P=_.slice(j+1).trim();if(j<1||!Object.hasOwn(yZ,q)||!P)throw Error(`OpenRouter slots 无效: ${_}`);if(c1(P)||!X.modelSelection.availableModels.some((D)=>!D.unavailableReason&&c2(D.model)===c2(P)))throw Error(`OpenRouter slot 模型不在账号目录中: ${P}`);if(X.modelEnvironmentRevision(P)!==X.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${P}`);B[yZ[q]]=P}return B},resolveSpawnModel(z){if(c1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return sP(Q,Y)}};return X},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:A6(Z[0])}:{}}}}catch(J){return{error:wZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=A6(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var lX=N(()=>{Y0();D0();z4();V0();CZ();m2();E0({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 V=U4(Q);if(!Z)throw Error("DeepSeek Harness API key is missing");if(V.DEEPSEEK_API_KEY=Z,V.DEEPSEEK_BASE_URL=J,V.LODESTAR_DSH_PROVIDER="deepseek-official",$.bin)V.LODESTAR_DSH_NODE=$.bin;return V},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 Y2({cwd:t1,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...b0($.models),...b0($.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(B0)||!B0(H.defaultEffort)||!H.efforts.includes(H.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${H.model}`);let V=$.model?.trim()||Q.find((H)=>H.isDefault)?.model;if(!V||!Q.some((H)=>H.model===V))throw Error("DSH default model is not in its catalog");Y.models=Q.map(({model:H,display:X,efforts:z,defaultEffort:W,isCustom:G})=>{let B=$.effort?.trim();if(B&&(!B0(B)||!z.includes(B)))throw Error(`DSH model ${H} does not support configured effort ${B}`);return{model:H,display:X,efforts:z,defaultEffort:B?B:W,origin:G?"custom":"upstream"}}),Y.defaultModel=V,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 j2(Y).find((V)=>V.model===Q)?.model},readUsage(){return Z?bZ(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(!h1(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 tP($,Z){let J=await J0(`${$}/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 dX=N(()=>{a0();C0();D0();Y0();z4();V0();z9();SZ();m2();E0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=v.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&h1(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",V,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([...V??[]].sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(X){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=U4(X);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,V)z.LODESTAR_DSH_MODELS=JSON.stringify(V);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(H.models=[],V=void 0,!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let X=await tP(Y,J),z=[...X];for(let G of[...b0($.models),...b0($.custom_models)])if(!z.some((B)=>B.model.toLowerCase()===G.toLowerCase()))z.push({model:G,display:G});if(V=z.map((G)=>G.model),!$.model?.trim()){let G=(B)=>Number(B.match(/\d+(?:\.\d+)?/)?.[0]??-1);H.defaultModel=[...X].sort((B,_)=>G(_.model)-G(B.model))[0].model}let W=await Y2({cwd:t1,env:H.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");H.models=z.map((G)=>{let B=W.find((P)=>P.model===G.model),_=TZ(H,$),j=B?B.efforts.filter(B0):_.efforts,q=$.effort?.trim()||B?.defaultEffort||_.defaultEffort;return{...G,display:B?.display??G.display,efforts:j,defaultEffort:B0(q)&&j.includes(q)?q:null,origin:X.some((P)=>P.model===G.model)?"upstream":"custom"}}),H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){throw H.models=[],V=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:X instanceof Error?X.message:String(X)},X}},resolveSpawnModel(X){return j2(H).find((z)=>z.model===X&&!z.unavailableReason)?.model},async readUsage(){return J?xZ(await X9(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 nX={};N$(nX,{tokenSourceSpawnRevision:()=>iX,buildTokenSourcesFromConfig:()=>hZ});import{createHash as eP}from"node:crypto";function hZ(){q7();let $=VZ(),Z=q2().map((V)=>{let H=V.configSectionId?(v.token_sources??{})[V.configSectionId]??{}:{},X=V.detect?.fromSettingsEnv($)??null,z=U6(V.build(H,X),H);return z.spawnRevision=iX(V.kind,H,X),z}),J=Z.find((V)=>V.kind==="claude-native");if(J){let V=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!V,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let V of Z)j7(V);let Q=Z.find((V)=>V.enabled&&v.token_sources?.[V.id]?.default===!0)??Z.find((V)=>V.enabled);if(Q)L7(Q.id);return Z.length}function iX($,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 eP("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var IZ=N(()=>{C0();Y0();z9();m2();wX();SZ();hX();CZ();uX();lX();dX()});import{readFileSync as $D}from"node:fs";function ZD($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function JD($,Z){let J=[`[token_source.${$}]`],Y=(Q,V)=>{if(V!==void 0)J.push(`${Q} = "${ZD(V)}"`)};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(`
226
+ `)}function YD($,Z){let J=$D(N0,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
227
+ `),V=!1,H=p9().token_sources[$]??{},X=[];for(let B of Q){let _=B.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(_)V=_===Y;if(!V)X.push(B)}let z={...H},W={...Z};for(let B of Object.keys(W))if(W[B]!==void 0)z[B]=W[B];let G=z;while(X.length&&X[X.length-1]==="")X.pop();Q$(N0,X.join(`
228
228
  `)+`
229
229
 
230
- `+sP($,G)+`
231
- `)}function A6($){let Z=cX.then($);return cX=Z.then(()=>{},()=>{}),Z}async function O6($,Z){tP($,Z),EY(),vZ(),await O4()}function uX($,Z){return A6(()=>O6($,Z))}function lX($,Z,J,Y="default"){return A6(async()=>{let Q=X0($,Y);if(!Q?.enabled||!Q.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Q.modelSelection.modelIds.filter((_)=>Q.models.find((j)=>j.model===_)?.origin!=="custom");if(J==="add"){if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");let _=Q.modelSelection.availableModels.find((j)=>j.model===Z);if(_?.origin==="custom")throw Error("补录模型请使用删除操作");if(!_||Q.modelSelection.mode!=="catalog"&&(_.unavailableReason||!_.efforts.length))throw Error("模型不在允许添加的账号目录中");if(V.includes(Z))throw Error("模型已在可选列表中")}else if(!V.includes(Z))throw Error("模型已不在可选列表中");let H=J==="add"?[...V,Z]:V.filter((_)=>_!==Z),X=v.token_sources[$],z=Q.modelSelection.mode==="catalog",W=b0(X?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...W,Z])]:W.filter((_)=>_!==Z)).join(",")}:{models:H.join(",")};await O6($,G);let B=X0($,Y);if(B?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${B?.modelCatalogState?.error??"MISS"}`)})}function dX($,Z,J="default"){return A6(async()=>{let Y=Z.trim();if(!Y||Y.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Y))throw Error("模型 ID 无效,请只填写一个完整模型名");let Q=X0($,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=v.token_sources[$];await O6($,{custom_models:[...b0(H?.custom_models),Y].join(",")});let X=X0($,J);if(X?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${X?.modelCatalogState?.error??"MISS"}`)})}function iX($,Z,J="default"){return A6(async()=>{let Y=X0($,J),Q=Y?.modelSelection?.availableModels.find((W)=>W.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=v.token_sources[$]??{},H=(W)=>W?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),X={custom_models:b0(V.custom_models).filter((W)=>!H(W)).join(","),hidden_models:b0(V.hidden_models).filter((W)=>!H(W)).join(","),...V.models!==void 0?{models:b0(V.models).filter((W)=>!H(W)).join(",")}:{},...H(V.model)?{model:"",effort:""}:{},...V.slots?{slots:V.slots.split(",").filter((W)=>!H(W.slice(W.indexOf("=")+1))).join(",")}:{}};await O6($,X);let z=X0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var cX;var hZ=T(()=>{H0();C0();fZ();Q0();f0();p2();cX=Promise.resolve()});var IZ={};T$(IZ,{runTokenSourceSetup:()=>$D,onTokenSourceEnable:()=>eP});async function eP($,Z){let J=q$(Z);if(!J){await E($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await E($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=D2().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,V$({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 $D($,Z,J){let Y=D2().find((V)=>V.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 uX(Y.configSectionId,Q.config);let V=q$(Y.configSectionId);if(V?.modelCatalogState?.status==="failed"){await E($.chatId,`❌ ${V.display} 配置已保存,但模型目录未就绪:${V.modelCatalogState.error??"MISS"}`);return}await E($.chatId,`✅ ${V?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(V){await E($.chatId,`❌ 启用失败: ${V?.message??V}`)}}var gZ=T(()=>{J0();Q0();hZ();R2()});async function nX($,Z,J="",Y){let Q=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Q){let{runCodexNamedHi:W}=await Promise.resolve().then(() => (P6(),OZ));return await W($,Q[1].trim()),!0}let V=Z.trim().match(/^codex-(login-cancel|login|accounts|account-delete|account|auto|reset)(?:[ \t]+([^\r\n]+))?$/i);if(V){let{runCodexAccountCommand:W}=await Promise.resolve().then(() => (P6(),OZ));return await W($,V[1].toLowerCase(),(V[2]??"").trim(),J,Y),!0}let H=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(H)return await $.runWorktreeCommand((H[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 X=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(X){let{runTokenSourceSetup:W}=await Promise.resolve().then(() => (gZ(),IZ));return await W($,X[1].trim().toLowerCase(),(X[2]??"").trim()),!0}let z=ZD.get(Z.trim().toLowerCase());if(!z)return!1;switch(z){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let G=!$.isRunning(),B=$.backendLabel(),_=G?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${B}`)):null,j=$.withModel(`\uD83D\uDE80 启动 ${B}`);if(!(G?await $.start({announce:!_,onStatus:(P)=>{j=P,$.setStatusCard(_,P)}}):!0))return await $.closeStatusCard(_,j.startsWith("❌")?j:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(_)await $.closeStatusCard(_,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:D}=await Promise.resolve().then(() => (R2(),fQ));if(!await u($.chatId,D({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(_)return await $.replaceStatusCardWithConsole(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(G)await $.closeStatusCard(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let G=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!G,onStatus:(B)=>$.setStatusCard(G,B)}),await $.closeStatusCard(G,"\uD83D\uDED1 已取消额度恢复")}catch(B){throw await $.closeStatusCard(G,`❌ ${O(B)}`),B}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let G=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(G)await $.closeStatusCard(G,"⚪ 无正在执行的 turn");else await E($.chatId,"⚪ 当前没有正在执行的 turn");return!0}K(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let W=new Set;for(let[G,B]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(B)S0(G,B);c0(G,"CrossMark"),W.add(G)}for(let G of $.pendingMidTurnMsgs)if(G.msgId&&!W.has(G.msgId))c0(G.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 G=$.isRunning(),B=$.backendLabel($.proc?.provider??$.currentProvider()),_=G?`\uD83D\uDED1 停止 ${B}`:"⚪ session 当前未运行",j=await $.openStatusCard("kill",_,G?"red":"grey"),q=null,P=G?`✅ ${B} 已终止`:`⚪ ${B} 未运行`;try{await $.stop("已终止",{announce:!j,onStatus:(D)=>{$.setStatusCard(j,D)}})}catch(D){q=D,P=$.isRunning()?`❌ ${B} 未确认终止: ${O(D)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${B} 停止收尾失败: ${O(D)}`}finally{try{await $.closeStatusCard(j,P)}catch(D){K(`session "${$.sessionName}": kill status card close failed: ${O(D)}`),await w($.chatId,`${P}
232
- ⚠️ kill 状态卡片终态写入失败: ${O(D)}`)}}if(q&&!j)await w($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let G=$.lastSessionId?U0($.lastSessionId):"",B=$.backendLabel($.proc?.provider??$.currentProvider()),_=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${B}`):G?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${G}`):$.withModel(`\uD83D\uDD01 启动 ${B}`),j=await $.openStatusCard("restart",_),q=_,P=await $.restart(!0,{announce:!j,onStatus:(N)=>{q=N,$.setStatusCard(j,N)}}),D=P?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(G?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(j,P?$.withModel(D):D)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let G=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(G)await $.closeStatusCard(G,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let G=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),B="\uD83E\uDDF9 清空并启动新会话",_=await $.restart(!1,{announce:!G,onStatus:(j)=>{B=j,$.setStatusCard(G,j)}});await $.closeStatusCard(G,_?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):B.startsWith("❌")?B:"❌ 清空失败")}return!0}}var ZD;var aX=T(()=>{J0();I();ZD=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 QD($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",W),$.off("error",G)},H=(_)=>{if(Z)return;Z=!0,V(),J(_)},X=(_)=>{if(Z)return;Z=!0,V(),Y(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Q&&_.threadId!==Q)return;H(_)},W=()=>X(Error(`${$.provider} process exited before context compaction completed`)),G=(_)=>X(_ instanceof Error?_:Error(String(_))),B=new Promise((_,j)=>{J=_,Y=j});return $.on("context_compacted",z),$.once("exit",W),$.once("error",G),{promise:B,cancel(){if(Z)return;Z=!0,V()}}}function VD($,Z){let J=[],Y=new Set,Q=(X,z)=>{let W=z.threadId??Z;if(W&&X.threadId&&X.threadId!==W)return!1;if(z.turnId)return X.turnId===z.turnId;return!0},V=(X)=>{for(let z=J.length-1;z>=0;z--){let W=J[z];if(W&&Q(W,X))return W}return null},H=(X)=>{if(Z&&X.threadId&&X.threadId!==Z)return;let z={usage:X.usage,contextWindow:X.contextWindow,threadId:X.threadId,turnId:X.turnId};J.push(z);for(let W of[...Y])if(Q(z,W.notice))W.finish(z)};return $.on("token_usage",H),{waitFor(X,z){let W=V(X);if(W)return Promise.resolve(W);return new Promise((G)=>{let B=null,_={notice:X,finish:(j)=>{if(B)clearTimeout(B);Y.delete(_),G(j)}};B=setTimeout(()=>_.finish(null),z),Y.add(_)})},cancel(){$.off("token_usage",H);for(let X of[...Y])X.finish(null)}}}function HD($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=y3($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=w3($.contextWindow);return` · \uD83E\uDDE0 ${MV(Z,J)} (${v3(Z,J)})`}async function oX($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let W=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(W)await $.closeStatusCard(W,"⚪ 后端未运行,compact 无效");else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let W=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(W)await $.closeStatusCard(W,"⚠️ 先 stop 当前 turn,再 compact");else await E($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let W=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(W)await $.closeStatusCard(W,"⏳ 上下文压缩已在进行中");else await E($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?U0(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),V=await $.openStatusCard("compact",Q,"orange"),H=async(W)=>{if(V)await $.closeStatusCard(V,W);else await E($.chatId,W)},X=QD(J),z=VD(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let W=await X.promise,G=await z.waitFor(W,YD),B=W.threadId?` thread=${U0(W.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${B}${HD(G)}`))}catch(W){if(X.cancel(),W instanceof D1)await H($.withModel(`ⓘ ${W.message}`));else await H(`❌ 上下文压缩失败: ${O(W)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var YD=1500;var rX=T(()=>{D0();J0()});import{randomUUID as zD}from"node:crypto";function WD($){let Z=$.currentTokenSource();return b$().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 pZ($,Z,J=Z.models){let Y=$.currentModelLabel(),Q=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((H)=>{let X=V&&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:X,efforts:H.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===H.defaultEffort,selected:X&&Q===z}))}})}async function sX($){await O4();let Z=zD(),J=WD($);$.modelPanels.set(Z,{models:[]});let Y=await u($.chatId,y5({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 cZ($,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 V=J.trim();if(!$.modelPanels.has(V))return{ok:!1,message:"模型面板已失效,请重新发送 model"};if(Q.modelCatalogState?.status==="failed")return{ok:!1,message:`模型目录 MISS:${Q.modelCatalogState.error??"刷新失败"}`};let H=pZ($,Q),X=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:H,sourceId:Y,messageId:X,mode:"select",editable:!!Q.modelSelection,sourceRevision:Q.spawnRevision}),R6($,V,Y,0)}async function R6($,Z,J,Y){let Q=$.modelPanels.get(Z);if(!Q?.catalog||Q.sourceId!==J)return{ok:!1,message:"模型面板已失效,请重新发送 model"};let V=Math.max(1,Math.ceil(Q.catalog.length/mZ));if(!Number.isInteger(Y)||Y<0||Y>=V)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*mZ,(Y+1)*mZ),Q.page=Y,Q.totalPages=V,{ok:!0,message:"",card:w5({sessionName:$.sessionName,panelId:Z,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:Q.models,sourceId:J,editable:Q.editable,allowCustom:!0,mode:Q.mode,...V>1?{pagination:{sourceId:J,page:Y,totalPages:V}}:{}})}}async function tX($,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 V=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:pZ($,Q,V),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),R6($,Z,J,0)}async function eX($,Z,J,Y,Q){let V=$.modelPanels.get(Z),H=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!H?.modelSelection||V.sourceRevision!==H.spawnRevision||V.mode!==(Q==="add"?"add":"select")||!V.models.some((X)=>X.model===Y))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Q==="delete"){let X=[...G$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Y.replace(/\[1m\]$/,""));if(X.length)return{ok:!1,message:`补录模型仍被会话 ${X.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Q==="delete")await iX(J,Y,$.codexAccountId());else await lX(J,Y,Q,$.codexAccountId());for(let z of G$.all)for(let[W,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||W!==Z))z.modelPanels.delete(W);return{...await cZ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(X){return{ok:!1,message:`模型列表更新失败:${O(X)}`}}}async function $z($,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 V=J.trim();if(!V)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:V,cardMessageId:Y},{ok:!0,message:"等待模型名",card:f5($.sessionName,Q.display,V)}}async function Zz($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),V=$.tokenSource(Y.sourceId),H=async(_)=>{if(!Y.cardMessageId)return!1;let j="",q=!1,P=!1;try{if(j=await $$(Y.cardMessageId),u0(j,1),q=await M0(j,R.modelPanel,_,{notifyCardFailure:!1}),!q)throw Error("model panel replace rejected");if(P=await P0(j,{config:{streaming_mode:!1}}),!P)throw Error("model panel streaming-off rejected")}catch(D){K(`model-custom: card update MISS (${D?.message??D})`)}finally{if(j){if(!P)try{P=await P0(j,{config:{streaming_mode:!1}})}catch(D){K(`model-custom: streaming-off retry MISS (${D?.message??D})`)}if(q&&P)try{await w0(j)}catch(D){K(`model-custom: card dispose MISS (${D?.message??D})`)}else K(`model-custom: retain card state after checked MISS mutation=${q} streamingOff=${P} card=${j.slice(0,12)}`)}}return q&&P},X=async(_,j)=>{if(await H(_))return!0;let P=`⚠️ 模型补录结果未能写回原卡。${j}
233
- 请重新发送 model 打开面板。`;if(!await w($.chatId,P))K(`model-custom: visible fallback send MISS (${j})`);return!1},z=(_)=>X(y2(!1,Q,_),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${_}。`);if(!V||!V.enabled)return await z("账号不可用"),!0;if(!Q)return await z("模型名为空"),!0;if(V.models.some((_)=>_.model.toLowerCase()===Q.toLowerCase()))return await X(y2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await dX(V.id,Q,$.codexAccountId())}catch(_){return K(`model-custom: config/refresh MISS (${O(_)})`),await z(`配置写入或模型刷新失败:${O(_)}`),!0}K(`model-custom: ${V.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let _ of G$.all)for(let[j,q]of _.modelPanels)if(q.sourceId===V.id&&(_!==$||j!==Y.panelId))_.modelPanels.delete(j);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await z(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let G=pZ($,W),B=G.find((_)=>_.model===Q);if(!B)return await z("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Y.panelId,{models:G,messageId:Y.cardMessageId}),B.unavailableReason||!B.efforts.length)return await X(y2(!0,Q,`**MISS**:${B.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Q} 已补录,能力尚未确认。`),!0;if(B.efforts.length===1){let _=await $.onModelEffortSelect(B.model,B.efforts[0].effort,Y.panelId,J,B.provider);return await X(_.ok?Q6({sessionName:$.sessionName,provider:B.provider,model:B.model,effort:B.efforts[0].effort,scope:Yz($,B.provider??"codex")}):y2(!0,Q,_.message),_.message),!0}return await X(Y6({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:B}),`✅ 模型 ${Q} 已补录成功。`),!0}async function Jz($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:J6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:J6($.sessionName)}}function GD($,Z){return B$(Z?.provider)?Z.provider:H2($)}function Yz($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${_$(Z)} 时使用。`}async function Qz($,Z,J="",Y="",Q=null){let V=Z.trim();if(!V)return await E($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=GD(V,Q),X=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===H);if(!X)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(X.unavailableReason)return{ok:!1,message:X.unavailableReason};if(X.enabled===!1)return{ok:!1,message:`${X.displayName} 未配置,请先点「启用」`};if(X.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(X.efforts.length===1)return uZ($,V,X.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:v5({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function uZ($,Z,J,Y="",Q="",V=""){let H=Z.trim(),X=J.trim();if(!H)return{ok:!1,message:"模型为空"};let z=Y.trim(),W=$.modelPanels.get(z),G=B$(V)?V:W?.models.find((M)=>M.model===H)?.provider??H2(H);if(G==="dsh"){if(!B0(X))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!N0(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!r0(X))return{ok:!1,message:"Codex reasoning effort 无效"};let B=X,_=W?.models.find((M)=>M.model===H&&(M.provider??"codex")===G);if(!_||!_.efforts.some((M)=>M.effort===B))return{ok:!1,message:`${_$(G)} · ${H}/${B} 不在选项中`};let j=$.tokenSource(_.sourceId);if(j?.modelCatalogState){if(!j.enabled||j.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${j.modelCatalogState.error??j.modelCatalogState.status}`};if(!j.models.some((M)=>M.model===H&&M.efforts.includes(B)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let q=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,P=!$.processSourceMatches(j,H)||!!j?.modelEnvironmentRevision&&j.modelEnvironmentRevision($.currentModelLabel()??"")!==j.modelEnvironmentRevision(H);if($.currentProvider()===G&&!q&&$.currentModelLabel()===H&&$.currentEffortLabel()===B)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${_$(G)} · ${H} / ${B}`,card:Z6({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${_$(G)}`};let U=$.currentModelLabel()!==H||q,A=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(P&&$.proc?.isAlive()&&A)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&U&&A)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!q&&!P){let S=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(H)??H:H;await kY($.proc.setModelSettings(S,B),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,B,_.sourceId);let M=Yz($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${_$(G)} · ${H} / ${B}`,card:Z6({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:M})}}catch(M){let S=`模型切换失败: ${O(M)}`;return K(`session "${$.sessionName}": set model settings failed: ${O(M)}`),await E($.chatId,`❌ ${S}`),{ok:!1,message:S}}}var mZ=20;var Vz=T(()=>{D0();lZ();Q0();hZ();M1();D0();J$();y$();J0();I()});import{createHash as BD}from"node:crypto";function _D($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function d1($="default"){return jD(b$().map((Z)=>Z.forAccount?.($)??Z))}function jD($){let Z=[],J=[];for(let Y of $)LD(Y,Z,J);return{catalogGeneration:BD("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function LD($,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(qD($,Q,Y))}function qD($,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:_D($.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:Hz($.defaultModel)===Hz(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function Hz($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var T6=T(()=>{Q0()});import{randomUUID as PD}from"node:crypto";async function Xz($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}Gz(),await F2();let J=`agents_${PD()}`;if(P9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,Wz(J)))await w($.chatId,"❌ agents 面板发送失败")}function zz($,Z,J){let Y=MD($,J),Q=Number(Z);if(!Number.isInteger(Q))return UD("无效页码");let V=FD(Y.codexAccountId);return Y.page=Math.max(0,Math.min(V-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:Wz($)}}function Wz($){let Z=P9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=d1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/N6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*N6;return o5({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+N6),failures:J.sourceFailures})}function FD($){return Math.max(1,Math.ceil(d1($).identities.length/N6))}function MD($,Z){Gz();let J=P9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function UD($){return{ok:!1,message:$,card:Q1({title:"agents",message:$,ok:!1})}}function Gz(){let $=Date.now()-DD;for(let[Z,J]of P9)if(J.createdAt<$)P9.delete(Z)}var N6=8,DD=1800000,P9;var Kz=T(()=>{J$();J0();T6();Q0();P9=new Map});var nZ={};T$(nZ,{withTasklistLifecycleLock:()=>b6,tasklistNameForProject:()=>S6,reconcileTasklistDeletions:()=>TD,isTasklistAlreadyDeletedError:()=>Bz,getTasklistBinding:()=>I$,enableTasklist:()=>dZ,deleteTasklistRemoteIdempotently:()=>_z,deleteTasklist:()=>iZ});import{existsSync as OD,readFileSync as RD}from"node:fs";function S6($){return`${$}[lodestar]`}function I$($){let Z=h$.get($);return Z?l2(Z):null}async function b6($,Z){let J=E6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),V=J.catch(()=>{}).then(()=>Q);E6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Y(),E6.get($)===V)E6.delete($)}}function Bz($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function _z($,Z=b7){try{return await Z($),"deleted"}catch(J){if(Bz(J))return"already_deleted";throw J}}async function dZ($,Z){return await b6($,async()=>{let J=I$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=S6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await x7(Z),V=await S7(Y,Q),H={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Q,createdAt:V.createdAt};return x6($,H),l2(H)})}async function iZ($,Z){return await b6($,async()=>{let J=I$($);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},x6($,J);return await jz($,Z)})}async function jz($,Z){let J=I$($);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,x6($,J);try{if(await _z(Z)==="already_deleted")K(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(h$);return Q.delete($),Lz(Q),h$.delete($),l2(J)}catch(Y){let Q=I$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),x6($,Q);throw Y}}async function TD(){let $=[...h$.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await b6(J.projectName,()=>jz(J.projectName,J.guid)),K(`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 ND(){if(!OD(R9))return;try{let $=JSON.parse(RD(R9,"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:ED(Y.deleting)};h$.set(Z,Q)}K(`tasklist: loaded ${h$.size} project bindings`)}catch($){K(`tasklist: load map failed: ${$}`)}}function ED($){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 x6($,Z){let J=new Map(h$);J.set($,l2(Z)),Lz(J),h$.set($,l2(Z))}function Lz($=h$){let Z={};for(let[J,Y]of $)Z[J]=l2(Y);s(R9,Z)}function l2($){return JSON.parse(JSON.stringify($))}var h$,E6;var aZ=T(()=>{H0();J0();I();f0();h$=new Map,E6=new Map;ND()});function X1($,Z,J=!1){let Y=$.worktreeProjectName();return n5({projectName:Y,tasklistName:S6(Y),binding:I$(Y),notice:Z,confirmDelete:J})}async function qz($){if(!await u($.chatId,X1($)))await w($.chatId,"❌ task 面板发送失败")}async function Pz($){let Z=$.worktreeProjectName();try{let J=I$(Z),Y=await dZ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:X1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${O(J)}`;return K(`session "${$.sessionName}": tasklist enable failed: ${O(J)}`),{ok:!1,message:Y,card:X1($,{type:"error",content:`❌ ${Y}`})}}}function Dz($,Z){let J=$.worktreeProjectName(),Y=I$(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:X1($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:X1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:X1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function Fz($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let V=`已删除 ${(await iZ(J,Y)).name}`;return{ok:!0,message:V,card:X1($,{type:"success",content:`✅ ${V}`})}}catch(Q){let V=`删除失败: ${O(Q)}`;return K(`session "${$.sessionName}": tasklist delete failed: ${O(Q)}`),{ok:!1,message:V,card:X1($,{type:"error",content:`❌ ${V}`})}}}var Mz=T(()=>{J$();J0();I();aZ()});var oZ,rZ,Uz,Az,Oz;var Rz=T(()=>{oZ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。","- 飞书单个出站文件不能超过 30 MB(30 × 1024 × 1024 字节)。交付前检查大小;超限先压缩或分卷,确保每个文件都不超过上限,再发送。"],rZ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],Uz=[...oZ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...rZ].join(`
234
- `),Az=[...oZ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...rZ].join(`
235
- `),Oz=[...oZ,"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。",...rZ].join(`
236
- `)});import{execFileSync as SD}from"node:child_process";import{existsSync as i1,readdirSync as bD,readFileSync as CD,realpathSync as sZ,statSync as kD}from"node:fs";import{dirname as yD,join as Nz,resolve as k6}from"node:path";async function y6($,Z){let J=sZ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=C6.get(Y)??Promise.resolve(),V,H=new Promise((z)=>{V=z}),X=Q.catch(()=>{}).then(()=>H);C6.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(V(),C6.get(Y)===X)C6.delete(Y)}}function n1($){let Z=$.trim();if(!wD.test(Z))return null;return Z}function Ez($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function i2($,Z){return`${$}[${Z}]`}function xz($){return`${d2}${$}`}function n2($,Z,J){return Nz(yD($),i2(Z,J))}function Sz($,Z,J){let Y=vD($,Z,J);if(!Y)return null;let Q=CD(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function bz($,Z){eZ($);let J=R0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${d2}`]).split(`
237
- `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(d2)),Y=$J($),Q=[];for(let V of J){let H=V.slice(d2.length);if(!n1(H))continue;let X=i2(Z,H),z=n2($,Z,H),W=Y.get(V)??null,G=!!W&&i1(W),B=wz($,V,G),_={slug:H,chatName:X,branch:V,state:B,expectedPath:z,worktreePath:G?W:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(W&&i1(W))try{let q=R0(W,["status","--porcelain=v1","--branch"]).split(`
238
- `).filter(Boolean);_.statusLine=q[0]?.startsWith("## ")?q[0].slice(3):null,_.dirtyCount=q.filter((P)=>!P.startsWith("## ")).length}catch(j){_.error=ZJ(j)}Q.push(_)}return Q.sort((V,H)=>V.slug.localeCompare(H.slug))}function Cz($,Z,J){let Y=n1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);eZ($);let Q=xz(Y),V=i2(Z,Y),H=n2($,Z,Y),X=gD($,Q),z=$J($).get(Q)??null,W=X&&!z&&wz($,Q,!1)==="merged"?R0($,["rev-parse","HEAD"]).trim():null;if(z){if(k6(z)!==k6(H))throw Error(`branch ${Q} is already mounted at ${z}`);return yz(H,Q),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(i1(H)){if(!kD(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!X)throw Error(`${H} already exists while branch ${Q} does not`)}if(X){if(R0($,["worktree","add",H,Q]),W)R0(H,["rebase",W]);return{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return R0($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function kz($,Z,J){let Y=tZ($,Z,J);if(!i1(Y.worktreePath))return Y;return R0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function tZ($,Z,J){let Y=n1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);eZ($);let Q=xz(Y),V=i2(Z,Y),H=n2($,Z,Y),z=$J($).get(Q)??null??H;if(!i1(z))return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1};yz(z,Q);let W=R0(z,["status","--porcelain=v1"]).split(`
230
+ `+JD($,G)+`
231
+ `)}function O6($){let Z=aX.then($);return aX=Z.then(()=>{},()=>{}),Z}async function R6($,Z){YD($,Z),SY(),hZ(),await A4()}function oX($,Z){return O6(()=>R6($,Z))}function rX($,Z,J,Y="default"){return O6(async()=>{let Q=H0($,Y);if(!Q?.enabled||!Q.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Q.modelSelection.modelIds.filter((_)=>Q.models.find((j)=>j.model===_)?.origin!=="custom");if(J==="add"){if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");let _=Q.modelSelection.availableModels.find((j)=>j.model===Z);if(_?.origin==="custom")throw Error("补录模型请使用删除操作");if(!_||Q.modelSelection.mode!=="catalog"&&(_.unavailableReason||!_.efforts.length))throw Error("模型不在允许添加的账号目录中");if(V.includes(Z))throw Error("模型已在可选列表中")}else if(!V.includes(Z))throw Error("模型已不在可选列表中");let H=J==="add"?[...V,Z]:V.filter((_)=>_!==Z),X=v.token_sources[$],z=Q.modelSelection.mode==="catalog",W=b0(X?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...W,Z])]:W.filter((_)=>_!==Z)).join(",")}:{models:H.join(",")};await R6($,G);let B=H0($,Y);if(B?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${B?.modelCatalogState?.error??"MISS"}`)})}function sX($,Z,J="default"){return O6(async()=>{let Y=Z.trim();if(!Y||Y.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Y))throw Error("模型 ID 无效,请只填写一个完整模型名");let Q=H0($,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=v.token_sources[$];await R6($,{custom_models:[...b0(H?.custom_models),Y].join(",")});let X=H0($,J);if(X?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${X?.modelCatalogState?.error??"MISS"}`)})}function tX($,Z,J="default"){return O6(async()=>{let Y=H0($,J),Q=Y?.modelSelection?.availableModels.find((W)=>W.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=v.token_sources[$]??{},H=(W)=>W?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),X={custom_models:b0(V.custom_models).filter((W)=>!H(W)).join(","),hidden_models:b0(V.hidden_models).filter((W)=>!H(W)).join(","),...V.models!==void 0?{models:b0(V.models).filter((W)=>!H(W)).join(",")}:{},...H(V.model)?{model:"",effort:""}:{},...V.slots?{slots:V.slots.split(",").filter((W)=>!H(W.slice(W.indexOf("=")+1))).join(",")}:{}};await R6($,X);let z=H0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var aX;var gZ=N(()=>{V0();C0();IZ();Y0();f0();m2();aX=Promise.resolve()});var mZ={};N$(mZ,{runTokenSourceSetup:()=>VD,onTokenSourceEnable:()=>QD});async function QD($,Z){let J=q$(Z);if(!J){await x($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await x($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=q2().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup)await x($.chatId,Y.setup.hint(J.display));else if(J.kind==="codex-subscription"){if(!await u($.chatId,V$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-native")await x($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function VD($,Z,J){let Y=q2().find((V)=>V.setup?.commandSuffix===Z);if(!Y?.setup||!Y.configSectionId){await x($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Q=Y.setup.parseArgs(J);if("error"in Q){await x($.chatId,Q.error);return}try{await oX(Y.configSectionId,Q.config);let V=q$(Y.configSectionId);if(V?.modelCatalogState?.status==="failed"){await x($.chatId,`❌ ${V.display} 配置已保存,但模型目录未就绪:${V.modelCatalogState.error??"MISS"}`);return}await x($.chatId,`✅ ${V?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(V){await x($.chatId,`❌ 启用失败: ${V?.message??V}`)}}var pZ=N(()=>{Z0();Y0();gZ();A2()});async function eX($,Z,J="",Y){let Q=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Q){let{runCodexNamedHi:W}=await Promise.resolve().then(() => (F6(),NZ));return await W($,Q[1].trim()),!0}let V=Z.trim().match(/^codex-(login-cancel|login|accounts|account-delete|account|auto|reset)(?:[ \t]+([^\r\n]+))?$/i);if(V){let{runCodexAccountCommand:W}=await Promise.resolve().then(() => (F6(),NZ));return await W($,V[1].toLowerCase(),(V[2]??"").trim(),J,Y),!0}let H=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(H)return await $.runWorktreeCommand((H[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 X=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(X){let{runTokenSourceSetup:W}=await Promise.resolve().then(() => (pZ(),mZ));return await W($,X[1].trim().toLowerCase(),(X[2]??"").trim()),!0}let z=HD.get(Z.trim().toLowerCase());if(!z)return!1;switch(z){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let G=!$.isRunning(),B=$.backendLabel(),_=G?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${B}`)):null,j=$.withModel(`\uD83D\uDE80 启动 ${B}`);if(!(G?await $.start({announce:!_,onStatus:(P)=>{j=P,$.setStatusCard(_,P)}}):!0))return await $.closeStatusCard(_,j.startsWith("❌")?j:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(_)await $.closeStatusCard(_,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:D}=await Promise.resolve().then(() => (A2(),IQ));if(!await u($.chatId,D({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(_)return await $.replaceStatusCardWithConsole(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(G)await $.closeStatusCard(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let G=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!G,onStatus:(B)=>$.setStatusCard(G,B)}),await $.closeStatusCard(G,"\uD83D\uDED1 已取消额度恢复")}catch(B){throw await $.closeStatusCard(G,`❌ ${O(B)}`),B}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let G=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(G)await $.closeStatusCard(G,"⚪ 无正在执行的 turn");else await x($.chatId,"⚪ 当前没有正在执行的 turn");return!0}K(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let W=new Set;for(let[G,B]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(B)S0(G,B);c0(G,"CrossMark"),W.add(G)}for(let G of $.pendingMidTurnMsgs)if(G.msgId&&!W.has(G.msgId))c0(G.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 G=$.isRunning(),B=$.backendLabel($.proc?.provider??$.currentProvider()),_=G?`\uD83D\uDED1 停止 ${B}`:"⚪ session 当前未运行",j=await $.openStatusCard("kill",_,G?"red":"grey"),q=null,P=G?`✅ ${B} 已终止`:`⚪ ${B} 未运行`;try{await $.stop("已终止",{announce:!j,onStatus:(D)=>{$.setStatusCard(j,D)}})}catch(D){q=D,P=$.isRunning()?`❌ ${B} 未确认终止: ${O(D)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${B} 停止收尾失败: ${O(D)}`}finally{try{await $.closeStatusCard(j,P)}catch(D){K(`session "${$.sessionName}": kill status card close failed: ${O(D)}`),await w($.chatId,`${P}
232
+ ⚠️ kill 状态卡片终态写入失败: ${O(D)}`)}}if(q&&!j)await w($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let G=$.lastSessionId?M0($.lastSessionId):"",B=$.backendLabel($.proc?.provider??$.currentProvider()),_=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${B}`):G?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${G}`):$.withModel(`\uD83D\uDD01 启动 ${B}`),j=await $.openStatusCard("restart",_),q=_,P=await $.restart(!0,{announce:!j,onStatus:(T)=>{q=T,$.setStatusCard(j,T)}}),D=P?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(G?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(j,P?$.withModel(D):D)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let G=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(G)await $.closeStatusCard(G,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await x($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let G=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),B="\uD83E\uDDF9 清空并启动新会话",_=await $.restart(!1,{announce:!G,onStatus:(j)=>{B=j,$.setStatusCard(G,j)}});await $.closeStatusCard(G,_?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):B.startsWith("❌")?B:"❌ 清空失败")}return!0}}var HD;var $z=N(()=>{Z0();h();HD=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 WD($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",W),$.off("error",G)},H=(_)=>{if(Z)return;Z=!0,V(),J(_)},X=(_)=>{if(Z)return;Z=!0,V(),Y(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Q&&_.threadId!==Q)return;H(_)},W=()=>X(Error(`${$.provider} process exited before context compaction completed`)),G=(_)=>X(_ instanceof Error?_:Error(String(_))),B=new Promise((_,j)=>{J=_,Y=j});return $.on("context_compacted",z),$.once("exit",W),$.once("error",G),{promise:B,cancel(){if(Z)return;Z=!0,V()}}}function GD($,Z){let J=[],Y=new Set,Q=(X,z)=>{let W=z.threadId??Z;if(W&&X.threadId&&X.threadId!==W)return!1;if(z.turnId)return X.turnId===z.turnId;return!0},V=(X)=>{for(let z=J.length-1;z>=0;z--){let W=J[z];if(W&&Q(W,X))return W}return null},H=(X)=>{if(Z&&X.threadId&&X.threadId!==Z)return;let z={usage:X.usage,contextWindow:X.contextWindow,threadId:X.threadId,turnId:X.turnId};J.push(z);for(let W of[...Y])if(Q(z,W.notice))W.finish(z)};return $.on("token_usage",H),{waitFor(X,z){let W=V(X);if(W)return Promise.resolve(W);return new Promise((G)=>{let B=null,_={notice:X,finish:(j)=>{if(B)clearTimeout(B);Y.delete(_),G(j)}};B=setTimeout(()=>_.finish(null),z),Y.add(_)})},cancel(){$.off("token_usage",H);for(let X of[...Y])X.finish(null)}}}function KD($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=v3($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=f3($.contextWindow);return` · \uD83E\uDDE0 ${NV(Z,J)} (${h3(Z,J)})`}async function Zz($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let W=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(W)await $.closeStatusCard(W,"⚪ 后端未运行,compact 无效");else await x($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let W=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(W)await $.closeStatusCard(W,"⚠️ 先 stop 当前 turn,再 compact");else await x($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let W=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(W)await $.closeStatusCard(W,"⏳ 上下文压缩已在进行中");else await x($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?M0(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),V=await $.openStatusCard("compact",Q,"orange"),H=async(W)=>{if(V)await $.closeStatusCard(V,W);else await x($.chatId,W)},X=WD(J),z=GD(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let W=await X.promise,G=await z.waitFor(W,zD),B=W.threadId?` thread=${M0(W.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${B}${KD(G)}`))}catch(W){if(X.cancel(),W instanceof D1)await H($.withModel(`ⓘ ${W.message}`));else await H(`❌ 上下文压缩失败: ${O(W)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var zD=1500;var Jz=N(()=>{D0();Z0()});import{randomUUID as _D}from"node:crypto";function jD($){let Z=$.currentTokenSource();return b$().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 uZ($,Z,J=Z.models){let Y=$.currentModelLabel(),Q=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((H)=>{let X=V&&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:X,efforts:H.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===H.defaultEffort,selected:X&&Q===z}))}})}async function Yz($){await A4();let Z=_D(),J=jD($);$.modelPanels.set(Z,{models:[]});let Y=await u($.chatId,v5({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 lZ($,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 V=J.trim();if(!$.modelPanels.has(V))return{ok:!1,message:"模型面板已失效,请重新发送 model"};if(Q.modelCatalogState?.status==="failed")return{ok:!1,message:`模型目录 MISS:${Q.modelCatalogState.error??"刷新失败"}`};let H=uZ($,Q),X=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:H,sourceId:Y,messageId:X,mode:"select",editable:!!Q.modelSelection,sourceRevision:Q.spawnRevision}),N6($,V,Y,0)}async function N6($,Z,J,Y){let Q=$.modelPanels.get(Z);if(!Q?.catalog||Q.sourceId!==J)return{ok:!1,message:"模型面板已失效,请重新发送 model"};let V=Math.max(1,Math.ceil(Q.catalog.length/cZ));if(!Number.isInteger(Y)||Y<0||Y>=V)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*cZ,(Y+1)*cZ),Q.page=Y,Q.totalPages=V,{ok:!0,message:"",card:f5({sessionName:$.sessionName,panelId:Z,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:Q.models,sourceId:J,editable:Q.editable,allowCustom:!0,mode:Q.mode,...V>1?{pagination:{sourceId:J,page:Y,totalPages:V}}:{}})}}async function Qz($,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 V=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:uZ($,Q,V),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),N6($,Z,J,0)}async function Vz($,Z,J,Y,Q){let V=$.modelPanels.get(Z),H=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!H?.modelSelection||V.sourceRevision!==H.spawnRevision||V.mode!==(Q==="add"?"add":"select")||!V.models.some((X)=>X.model===Y))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Q==="delete"){let X=[...G$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Y.replace(/\[1m\]$/,""));if(X.length)return{ok:!1,message:`补录模型仍被会话 ${X.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Q==="delete")await tX(J,Y,$.codexAccountId());else await rX(J,Y,Q,$.codexAccountId());for(let z of G$.all)for(let[W,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||W!==Z))z.modelPanels.delete(W);return{...await lZ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(X){return{ok:!1,message:`模型列表更新失败:${O(X)}`}}}async function Hz($,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 V=J.trim();if(!V)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:V,cardMessageId:Y},{ok:!0,message:"等待模型名",card:I5($.sessionName,Q.display,V)}}async function Xz($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),V=$.tokenSource(Y.sourceId),H=async(_)=>{if(!Y.cardMessageId)return!1;let j="",q=!1,P=!1;try{if(j=await $$(Y.cardMessageId),u0(j,1),q=await U0(j,R.modelPanel,_,{notifyCardFailure:!1}),!q)throw Error("model panel replace rejected");if(P=await P0(j,{config:{streaming_mode:!1}}),!P)throw Error("model panel streaming-off rejected")}catch(D){K(`model-custom: card update MISS (${D?.message??D})`)}finally{if(j){if(!P)try{P=await P0(j,{config:{streaming_mode:!1}})}catch(D){K(`model-custom: streaming-off retry MISS (${D?.message??D})`)}if(q&&P)try{await w0(j)}catch(D){K(`model-custom: card dispose MISS (${D?.message??D})`)}else K(`model-custom: retain card state after checked MISS mutation=${q} streamingOff=${P} card=${j.slice(0,12)}`)}}return q&&P},X=async(_,j)=>{if(await H(_))return!0;let P=`⚠️ 模型补录结果未能写回原卡。${j}
233
+ 请重新发送 model 打开面板。`;if(!await w($.chatId,P))K(`model-custom: visible fallback send MISS (${j})`);return!1},z=(_)=>X(k2(!1,Q,_),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${_}。`);if(!V||!V.enabled)return await z("账号不可用"),!0;if(!Q)return await z("模型名为空"),!0;if(V.models.some((_)=>_.model.toLowerCase()===Q.toLowerCase()))return await X(k2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await sX(V.id,Q,$.codexAccountId())}catch(_){return K(`model-custom: config/refresh MISS (${O(_)})`),await z(`配置写入或模型刷新失败:${O(_)}`),!0}K(`model-custom: ${V.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let _ of G$.all)for(let[j,q]of _.modelPanels)if(q.sourceId===V.id&&(_!==$||j!==Y.panelId))_.modelPanels.delete(j);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await z(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let G=uZ($,W),B=G.find((_)=>_.model===Q);if(!B)return await z("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Y.panelId,{models:G,messageId:Y.cardMessageId}),B.unavailableReason||!B.efforts.length)return await X(k2(!0,Q,`**MISS**:${B.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Q} 已补录,能力尚未确认。`),!0;if(B.efforts.length===1){let _=await $.onModelEffortSelect(B.model,B.efforts[0].effort,Y.panelId,J,B.provider);return await X(_.ok?H6({sessionName:$.sessionName,provider:B.provider,model:B.model,effort:B.efforts[0].effort,scope:Wz($,B.provider??"codex")}):k2(!0,Q,_.message),_.message),!0}return await X(V6({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:B}),`✅ 模型 ${Q} 已补录成功。`),!0}async function zz($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:Q6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:Q6($.sessionName)}}function LD($,Z){return B$(Z?.provider)?Z.provider:Q2($)}function Wz($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${_$(Z)} 时使用。`}async function Gz($,Z,J="",Y="",Q=null){let V=Z.trim();if(!V)return await x($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=LD(V,Q),X=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===H);if(!X)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(X.unavailableReason)return{ok:!1,message:X.unavailableReason};if(X.enabled===!1)return{ok:!1,message:`${X.displayName} 未配置,请先点「启用」`};if(X.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(X.efforts.length===1)return dZ($,V,X.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:h5({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function dZ($,Z,J,Y="",Q="",V=""){let H=Z.trim(),X=J.trim();if(!H)return{ok:!1,message:"模型为空"};let z=Y.trim(),W=$.modelPanels.get(z),G=B$(V)?V:W?.models.find((U)=>U.model===H)?.provider??Q2(H);if(G==="dsh"){if(!B0(X))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!T0(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!r0(X))return{ok:!1,message:"Codex reasoning effort 无效"};let B=X,_=W?.models.find((U)=>U.model===H&&(U.provider??"codex")===G);if(!_||!_.efforts.some((U)=>U.effort===B))return{ok:!1,message:`${_$(G)} · ${H}/${B} 不在选项中`};let j=$.tokenSource(_.sourceId);if(j?.modelCatalogState){if(!j.enabled||j.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${j.modelCatalogState.error??j.modelCatalogState.status}`};if(!j.models.some((U)=>U.model===H&&U.efforts.includes(B)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let q=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,P=!$.processSourceMatches(j,H)||!!j?.modelEnvironmentRevision&&j.modelEnvironmentRevision($.currentModelLabel()??"")!==j.modelEnvironmentRevision(H);if($.currentProvider()===G&&!q&&$.currentModelLabel()===H&&$.currentEffortLabel()===B)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${_$(G)} · ${H} / ${B}`,card:Y6({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${_$(G)}`};let M=$.currentModelLabel()!==H||q,A=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(P&&$.proc?.isAlive()&&A)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&M&&A)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!q&&!P){let S=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(H)??H:H;await wY($.proc.setModelSettings(S,B),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,B,_.sourceId);let U=Wz($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${_$(G)} · ${H} / ${B}`,card:Y6({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:U})}}catch(U){let S=`模型切换失败: ${O(U)}`;return K(`session "${$.sessionName}": set model settings failed: ${O(U)}`),await x($.chatId,`❌ ${S}`),{ok:!1,message:S}}}var cZ=20;var Kz=N(()=>{D0();iZ();Y0();gZ();U1();D0();J$();k$();Z0();h()});import{createHash as PD}from"node:crypto";function DD($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function u1($="default"){return FD(b$().map((Z)=>Z.forAccount?.($)??Z))}function FD($){let Z=[],J=[];for(let Y of $)UD(Y,Z,J);return{catalogGeneration:PD("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function UD($,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(MD($,Q,Y))}function MD($,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:DD($.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:Bz($.defaultModel)===Bz(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function Bz($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var T6=N(()=>{Y0()});import{randomUUID as AD}from"node:crypto";async function _z($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}qz(),await P2();let J=`agents_${AD()}`;if(P9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,Lz(J)))await w($.chatId,"❌ agents 面板发送失败")}function jz($,Z,J){let Y=ND($,J),Q=Number(Z);if(!Number.isInteger(Q))return TD("无效页码");let V=RD(Y.codexAccountId);return Y.page=Math.max(0,Math.min(V-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:Lz($)}}function Lz($){let Z=P9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=u1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/E6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*E6;return s5({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+E6),failures:J.sourceFailures})}function RD($){return Math.max(1,Math.ceil(u1($).identities.length/E6))}function ND($,Z){qz();let J=P9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function TD($){return{ok:!1,message:$,card:Q1({title:"agents",message:$,ok:!1})}}function qz(){let $=Date.now()-OD;for(let[Z,J]of P9)if(J.createdAt<$)P9.delete(Z)}var E6=8,OD=1800000,P9;var Pz=N(()=>{J$();Z0();T6();Y0();P9=new Map});var oZ={};N$(oZ,{withTasklistLifecycleLock:()=>C6,tasklistNameForProject:()=>b6,reconcileTasklistDeletions:()=>bD,isTasklistAlreadyDeletedError:()=>Dz,getTasklistBinding:()=>h$,enableTasklist:()=>nZ,deleteTasklistRemoteIdempotently:()=>Fz,deleteTasklist:()=>aZ});import{existsSync as xD,readFileSync as SD}from"node:fs";function b6($){return`${$}[lodestar]`}function h$($){let Z=f$.get($);return Z?u2(Z):null}async function C6($,Z){let J=x6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),V=J.catch(()=>{}).then(()=>Q);x6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Y(),x6.get($)===V)x6.delete($)}}function Dz($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function Fz($,Z=y7){try{return await Z($),"deleted"}catch(J){if(Dz(J))return"already_deleted";throw J}}async function nZ($,Z){return await C6($,async()=>{let J=h$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=b6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await C7(Z),V=await k7(Y,Q),H={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Q,createdAt:V.createdAt};return S6($,H),u2(H)})}async function aZ($,Z){return await C6($,async()=>{let J=h$($);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},S6($,J);return await Uz($,Z)})}async function Uz($,Z){let J=h$($);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,S6($,J);try{if(await Fz(Z)==="already_deleted")K(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(f$);return Q.delete($),Mz(Q),f$.delete($),u2(J)}catch(Y){let Q=h$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),S6($,Q);throw Y}}async function bD(){let $=[...f$.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await C6(J.projectName,()=>Uz(J.projectName,J.guid)),K(`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 CD(){if(!xD(R9))return;try{let $=JSON.parse(SD(R9,"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:kD(Y.deleting)};f$.set(Z,Q)}K(`tasklist: loaded ${f$.size} project bindings`)}catch($){K(`tasklist: load map failed: ${$}`)}}function kD($){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 S6($,Z){let J=new Map(f$);J.set($,u2(Z)),Mz(J),f$.set($,u2(Z))}function Mz($=f$){let Z={};for(let[J,Y]of $)Z[J]=u2(Y);s(R9,Z)}function u2($){return JSON.parse(JSON.stringify($))}var f$,x6;var rZ=N(()=>{V0();Z0();h();f0();f$=new Map,x6=new Map;CD()});function X1($,Z,J=!1){let Y=$.worktreeProjectName();return o5({projectName:Y,tasklistName:b6(Y),binding:h$(Y),notice:Z,confirmDelete:J})}async function Az($){if(!await u($.chatId,X1($)))await w($.chatId,"❌ task 面板发送失败")}async function Oz($){let Z=$.worktreeProjectName();try{let J=h$(Z),Y=await nZ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:X1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${O(J)}`;return K(`session "${$.sessionName}": tasklist enable failed: ${O(J)}`),{ok:!1,message:Y,card:X1($,{type:"error",content:`❌ ${Y}`})}}}function Rz($,Z){let J=$.worktreeProjectName(),Y=h$(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:X1($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:X1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:X1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function Nz($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let V=`已删除 ${(await aZ(J,Y)).name}`;return{ok:!0,message:V,card:X1($,{type:"success",content:`✅ ${V}`})}}catch(Q){let V=`删除失败: ${O(Q)}`;return K(`session "${$.sessionName}": tasklist delete failed: ${O(Q)}`),{ok:!1,message:V,card:X1($,{type:"error",content:`❌ ${V}`})}}}var Tz=N(()=>{J$();Z0();h();rZ()});var sZ,tZ,Ez,xz,Sz;var bz=N(()=>{sZ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。","- 飞书单个出站文件不能超过 30 MB(30 × 1024 × 1024 字节)。交付前检查大小;超限先压缩或分卷,确保每个文件都不超过上限,再发送。"],tZ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],Ez=[...sZ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...tZ].join(`
234
+ `),xz=[...sZ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...tZ].join(`
235
+ `),Sz=[...sZ,"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。",...tZ].join(`
236
+ `)});import{execFileSync as wD}from"node:child_process";import{existsSync as l1,readdirSync as vD,readFileSync as fD,realpathSync as eZ,statSync as hD}from"node:fs";import{dirname as ID,join as kz,resolve as y6}from"node:path";async function w6($,Z){let J=eZ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=k6.get(Y)??Promise.resolve(),V,H=new Promise((z)=>{V=z}),X=Q.catch(()=>{}).then(()=>H);k6.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(V(),k6.get(Y)===X)k6.delete(Y)}}function d1($){let Z=$.trim();if(!gD.test(Z))return null;return Z}function yz($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function d2($,Z){return`${$}[${Z}]`}function wz($){return`${l2}${$}`}function i2($,Z,J){return kz(ID($),d2(Z,J))}function vz($,Z,J){let Y=mD($,Z,J);if(!Y)return null;let Q=fD(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function fz($,Z){ZJ($);let J=R0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${l2}`]).split(`
237
+ `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(l2)),Y=JJ($),Q=[];for(let V of J){let H=V.slice(l2.length);if(!d1(H))continue;let X=d2(Z,H),z=i2($,Z,H),W=Y.get(V)??null,G=!!W&&l1(W),B=mz($,V,G),_={slug:H,chatName:X,branch:V,state:B,expectedPath:z,worktreePath:G?W:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(W&&l1(W))try{let q=R0(W,["status","--porcelain=v1","--branch"]).split(`
238
+ `).filter(Boolean);_.statusLine=q[0]?.startsWith("## ")?q[0].slice(3):null,_.dirtyCount=q.filter((P)=>!P.startsWith("## ")).length}catch(j){_.error=YJ(j)}Q.push(_)}return Q.sort((V,H)=>V.slug.localeCompare(H.slug))}function hz($,Z,J){let Y=d1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);ZJ($);let Q=wz(Y),V=d2(Z,Y),H=i2($,Z,Y),X=lD($,Q),z=JJ($).get(Q)??null,W=X&&!z&&mz($,Q,!1)==="merged"?R0($,["rev-parse","HEAD"]).trim():null;if(z){if(y6(z)!==y6(H))throw Error(`branch ${Q} is already mounted at ${z}`);return gz(H,Q),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(l1(H)){if(!hD(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!X)throw Error(`${H} already exists while branch ${Q} does not`)}if(X){if(R0($,["worktree","add",H,Q]),W)R0(H,["rebase",W]);return{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return R0($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function Iz($,Z,J){let Y=$J($,Z,J);if(!l1(Y.worktreePath))return Y;return R0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function $J($,Z,J){let Y=d1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);ZJ($);let Q=wz(Y),V=d2(Z,Y),H=i2($,Z,Y),z=JJ($).get(Q)??null??H;if(!l1(z))return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1};gz(z,Q);let W=R0(z,["status","--porcelain=v1"]).split(`
239
239
  `).filter(Boolean);if(W.length>0){let G=W.slice(0,8).join(`
240
240
  `);throw Error(`worktree has uncommitted changes:
241
- ${G}`)}return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1}}function eZ($){if(!i1($))throw Error(`project directory does not exist: ${$}`);let Z=R0($,["rev-parse","--show-toplevel"]).trim();if(sZ(Z)!==sZ($))throw Error(`${$} is not the git repository root (${Z})`)}function yz($,Z){let J=R0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function vD($,Z,J){let Y=fD($);if(!Y?.startsWith(d2))return null;let Q=Y.slice(d2.length);if(!n1(Q))throw Error(`invalid worktree branch "${Y}"`);let V=n2(Z,J,Q);if(k6($)!==k6(V))return null;let H=ID($,hD(Q));return H?{path:H,slug:Q}:null}function fD($){if(!i1($))return null;try{return R0($,["branch","--show-current"]).trim()||null}catch(Z){if(mD(Z))return null;throw Z}}function hD($){return $.split("-",1)[0]??$}function ID($,Z){let J=`agents.${Z}.md`,Y=bD($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?Nz($,Y[0]):null}function gD($,Z){try{return R0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function wz($,Z,J){let Y=R0($,["rev-parse",Z]).trim(),Q=R0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(Tz($,Z,"HEAD"))return"merged";if(Tz($,"HEAD",Z))return"active";return"stale"}function Tz($,Z,J){try{return R0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function $J($){let Z=new Map,J=R0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
242
- `)){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 R0($,Z){try{return SD("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(ZJ(J))}}function ZJ($){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 mD($){return/not a git repository/i.test(ZJ($))}var d2="work/",wD,C6;var vz=T(()=>{wD=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,C6=new Map});function z1($){return Ez(F$($.sessionName)??$.sessionName)}function a2($){return N3(z1($))}function hz($){let Z=F$($.sessionName)??$.sessionName,J=z1($),Y=N3(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return n2(Y,J,Q)}function Iz($,Z=$.currentProvider()){let J=Z==="dsh"?Oz:Z==="claude"?Az:Uz,Y=D9($);return Y?`${J}
243
- ${Y}`:J}function gz($,Z){return D9($)??""}function JJ($){return D9($)?"已载入wt特殊约定":null}function mz($,Z){let J=JJ($);return J?`${Z}
244
- ${J}`:Z}function D9($){let Z=z1($),J=Sz($.workDir,a2($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
245
- `)}async function pz($,Z,J){if(!Z){await YJ($);return}let Y=n1(Z);if(!Y){await E($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await E($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=z1($),V=a2($);try{await y6(V,async()=>{let H;try{H=Cz(V,Q,Y)}catch(X){await E($.chatId,`❌ wt 失败: ${O(X)}`);return}try{let X=await t7(H.chatName,J),z=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await u($.chatId,Q9({slug:Y,branch:H.branch,status:z})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await u(X.chatId,Q9({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await w(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await E($.chatId,`❌ wt 已建,拉群失败: ${O(X)}`)}})}catch(H){await E($.chatId,`❌ wt 失败: ${O(H)}`)}}async function cz($,Z){let J=z1($),Y=a2($);return await y6(Y,async()=>{return await cD(J,Y,Z)})}async function cD($,Z,J){let Y=bz(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,V=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await x3();return I5({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:V.map((X)=>{let z=H.get(X.chatName)??[],W=L0.get(X.chatName),G=W&&z.includes(W)?W:z.length===1?z[0]:null;return{slug:X.slug,chatName:X.chatName,branch:X.branch,state:X.state,path:X.worktreePath??X.expectedPath,mounted:X.mounted,dirtyCount:X.dirtyCount,statusLine:X.statusLine,error:X.error,chatId:G,duplicateChatCount:z.length}})})}async function YJ($){try{let Z=await cz($);if(!await u($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await E($.chatId,`❌ wt 列表失败: ${O(Z)}`)}}async function fz($,Z,J,Y){try{return{ok:Z,message:J,card:await cz($,{type:Y,content:J})}}catch(Q){let V=`列表刷新失败: ${O(Q)}`;return K(`session "${$.sessionName}": wt action panel refresh failed: ${O(Q)}`),{ok:!1,message:`${J}
246
- ${V}`,card:Q9({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function uz($,Z){let J=n1(Z);if(!J)return fz($,!1,"❌ 名称无效","error");let Y=z1($),Q=a2($),V;try{V=await y6(Q,async()=>{let H=i2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};tZ(Q,Y,J);let X=await $5(H),z=kz(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",z.branch].join(`
247
- `),type:"success"}})}catch(H){V={ok:!1,message:`❌ 解散 ${J} 失败: ${O(H)}`,type:"error"}}return fz($,V.ok,V.message,V.type)}var lz=T(()=>{Rz();J$();J0();I();vz()});import{closeSync as lD,openSync as dD,readSync as iD,readdirSync as nD,statSync as aD}from"node:fs";import{randomUUID as VJ}from"node:crypto";import{join as oD}from"node:path";function v6($){return F$($.sessionName)??$.sessionName}function iz($){let Z=d7($,QJ);return QJ.add(Z),Z}function nz($){QJ.delete($)}function o2($){let Z=dz.get($);if(!Z)Z=new Map,dz.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let V=Q.status==="consumed"?tD:sD,H=Q.consumedAt??Q.createdAt;if(J-H>V)Z.delete(Y)}return Z}function $F($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function az($,Z,J,Y){let Q={id:VJ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:v6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return o2($).set(Q.id,Q),Q}function HJ($,Z,J,Y,Q){let V=o2($).get(J);if(!V||V.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||V.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(V.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(V.provider!==$.selectedProvider||V.workDir!==$.workDir||V.sourceSessionId!==$.lastSessionId||!$F(V.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=V.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return V.status="processing",{panel:V,choice:H}}function w6($){$.status="consumed",$.consumedAt=Date.now()}function ZF($){return{kind:"fork",source:$.source,through:$}}function JF($){return f4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function YF($){let Z=h4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return _0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function QF($){let Z=X3($),J;try{J=nD(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 V=Q.slice(0,-6);if(Q2("claude",V))continue;let H=oD(Z,Q),X;try{X=aD(H).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:V,cwd:$,preview:HF(H),ts:X})}return Y.sort((Q,V)=>V.ts-Q.ts)}function VF($){let Z=$.slice().sort((Q,V)=>V.ts-Q.ts),J=Date.now()-rD,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(eD,Math.max(10,Y)))}function HF($){let Z="",J=null;try{J=dD($,"r");let Q=Buffer.alloc(65536),V=iD(J,Q,0,65536,0);Z=Q.subarray(0,V).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)lD(J)}let Y="";for(let Q of Z.split(`
248
- `)){let V=Q.trim();if(!V)continue;let H;try{H=JSON.parse(V)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let X=H.content.trim();if(X)return X.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let X=XF(H.message);if(X)Y=X}}return Y.slice(0,80)}function XF($){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 oz($,Z,J){if(!J){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=JF($),Q=YF($),V=new Map,H=[];for(let G=0;G<Y.length;G++){let B=Y[G];if(G===0&&Q===null)continue;let _=VJ(),j=G===0?Q:ZF(Y[G-1].checkpoint);V.set(_,{kind:Z,launch:j,branchBase:Q,seedAnchors:Y.slice(0,G),writes:Y.slice(G).flatMap((q)=>q.writes)}),H.push({choiceId:_,preview:B.preview,ts:B.ts})}H.reverse();let X=az($,Z,J,V),z=m5({projectName:v6($),panelId:X.id,mode:Z,entries:H}),W;try{W=await u($.chatId,z)}catch(G){throw o2($).delete(X.id),G}if(!W)o2($).delete(X.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function rz($,Z){return oz($,"fork",Z)}function sz($,Z){return oz($,"back",Z)}async function tz($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():QF($.workDir)}catch(z){await w($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=VF(J).map((z)=>{let W=VJ();return Y.set(W,{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:W,preview:z.preview,ts:z.ts}}),V=az($,"resume",Z,Y),H=p5({projectName:v6($),panelId:V.id,entries:Q}),X;try{X=await u($.chatId,H)}catch(z){throw o2($).delete(V.id),z}if(!X)o2($).delete(V.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function ez($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await E($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=iz(v6($));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{nz(J)}if(!Y.ok){await E($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await E($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function $W($){if(!F$($.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 ZW($,Z,J,Y){let Q=HJ($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let X=iz(V.baseName);K(`session-temp: fork ${$.sessionName} → ${X} (${H.launch.kind})`),await E($.chatId,`\uD83D\uDD31 正在分叉到 ${X}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:X,userOpenId:Y,workDir:V.workDir,routing:V.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{nz(X)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${X};原会话和磁盘文件未回滚`}}catch(X){return{ok:!1,message:`分叉失败: ${X instanceof Error?X.message:X}`}}finally{w6(V)}}async function JW($,Z,J,Y){let Q=HJ($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let X="";try{if(!await u($.chatId,c5({projectName:V.baseName,entries:H.writes})))X=";文件变更记录卡发送失败"}catch(G){X=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(K(`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:`回退失败;原会话绑定未改,请检查日志后重试${X}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${X}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${U0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{w6(V)}}async function YW($,Z,J,Y){let Q=HJ($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;if(H.kind!=="resume")throw w6(V),Error("resume panel contained a non-resume choice");let X=H.launch.source.sessionId,z=$.lastSessionId,W=(B,_)=>({projectName:V.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:X,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:z,newSessionId:B,bindingState:_}),G=(B,_,j,q=null)=>({ok:B,message:_,resumePresentation:W(q,j)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(K(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${X}`),!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 _=$.lastSessionId;if(!_)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===X||z&&_===z)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return G(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(B){return G(!1,`历史分支创建失败: ${B instanceof Error?B.message:B}`,"unknown")}finally{w6(V)}}var rD=86400000,sD=1800000,tD=3600000,eD=40,dz,QJ;var QW=T(()=>{J0();J$();I();M4();X4();F1();dz=new WeakMap,QJ=new Set});import{existsSync as VW}from"node:fs";import{randomBytes as WF,timingSafeEqual as GF}from"node:crypto";import{isAbsolute as KF}from"node:path";function zJ($,Z=new Set){if($ instanceof G2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=zJ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return zJ($.cause,Z);return null}function BF($){return $.itemId||$.turnId||"__latest__"}function HW($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function _F($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function jF($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function a1(){return v.runtime?.live_elapsed??"bucket"}function WW($,Z){return`${$} (${a$(Date.now()-Z,a1()).label})`}var XW="Thinking...",LF="Writing...",qF="Working...",XJ=1e4,f6=720000,PF=50,DF=256,h6=1e4,zW=250,G$;var lZ=T(()=>{X4();W4();D0();M1();J7();D0();C0();A7();Q0();g0();R2();M4();y$();J$();J0();I();H0();b5();C$();z9();QZ();IH();sH();BX();j6();LX();aX();rX();Vz();Kz();Mz();lz();QW();F1();G$=class G${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;G$.all.add(this);let Y=a7($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=q$(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)K(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=s$($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)K(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=I4($);if(V)if(this.selectedProvider!=="claude")t0($,[],null,null),K(`session "${$}": cleared pending Claude fork after provider changed`);else{_0(V.launch,"claude",this.workDir);let H=this.lastSessionId===V.previousSessionId,X=this.lastSessionRef,z=!H&&X?.provider==="claude"&&X.cwd===this.workDir&&X.sessionId!==V.launch.source.sessionId&&X.sessionId!==V.previousSessionId;if(!H&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,K(`session "${$}": restored ${z?"materialized":"pending"} Claude fork source=${V.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0,...this.proc?.isAlive()&&this.proc.provider==="codex"&&this.proc.codexAccountSelectionMode?.()!==null&&!(this.proc.turnRetry?.reason==="quota"&&this.proc.turnRetry.phase==="waiting")?{codexAccountName:k.get(o0(this.proc)).name}:{}}}get workDir(){return hz(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 K3(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?o0(this.proc):this.codexStartAccountOverride??k.selected(this.sessionName)}tokenSource($){let Z=q$($);return Z?.forAccount?X0($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...this.codexAccountId()===c?{}:{codexAccountId:this.codexAccountId()},...k.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)k.get($.codexAccountId);let Z=q$($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)t0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=s$(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,x1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??c;if($.codexAccountAutomatic)k.selectAuto(this.sessionName);else if(k.selected(this.sessionName)!==J)k.select(this.sessionName,J)}dshEffortForSpawn(){if(B0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&L$($,this.selectedModel??$.defaultModel);if(!Z||!B0(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 V2({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!Q2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!c4(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?(X)=>Z.spawnEnv(X):void 0,Y=new K2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,V=null;try{Q=await Y.listConversations()}catch(X){V=X}let H=null;try{await Y.kill(2000)}catch(X){H=X}if(V&&H)throw AggregateError([V,H],`Codex history query and cleanup failed: ${O(V)}; ${O(H)}`);if(V)throw V;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=z3(this.workDir,$.sessionId);if(!VW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${U0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!c4(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 K2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(X)=>Y.spawnEnv(X):void 0}),V=null;try{Z=await Q.readConversationRef($.sessionId)}catch(X){V=X,Z=$}let H=null;try{await Q.kill(2000)}catch(X){H=X}if(V&&H)throw AggregateError([V,H],`Codex legacy resume lookup and cleanup failed: read=${O(V)}; cleanup=${O(H)}`);if(V)throw V;if(H)throw H}return _0({kind:"resume",source:Z},this.selectedProvider,this.workDir),v4(this.sessionName,Z),Z}hasRunningPeerSession($){return[...G$.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 r0(this.selectedEffort)?this.selectedEffort:L4}return L4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&N0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=L$($,this.selectedModel??$.defaultModel);if(!N0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return l$}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??L$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?l$:L4)}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"?l$:L4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return $0($,R.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:R.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return G5($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return _$($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(_0($.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=WF(32).toString("base64url");let Z={LODESTAR_AGENT_URL:D3(v.notify.bind,v.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"});_0(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 V=Y?.enabled||Q?Y:void 0,H=E4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:V?.id??null,...this.selectedProvider==="codex"?{codexAccountId:k.selected(this.sessionName)}:{},...Q?{codexAccountPreference:this.codexStartAccountOverride??k.preferred(this.sessionName)}:{},model:V?this.selectedModel??V.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="dsh"?this.dshEffortForSpawn():this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:N2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},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!==$)t0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let V=q$(this.selectedTokenSourceId);if(V)this.selectedModel=Z||null,this.selectedEffort=J??L$(V,Z||V.defaultModel)?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=s$(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,n7(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()===P2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===P2($,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;K(`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(X){Q=X}Y=await this.settleProcResumableState(J);let V=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!V?[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;K(`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 V=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(V.length===1)throw V[0];if(V.length>1)throw AggregateError(V,`idle process stop failed: ${V.map(O).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,V=!1,H=()=>{if(V)return;this.replaceFooterContent($,J(WW(Q,Y)))},X=null,z=()=>{if(V)return;let{nextDelayMs:W}=a$(Date.now()-Y,a1());X=setTimeout(()=>{H(),z()},Math.max(1,Math.ceil(W)))};return H(),z(),{setStatus(W){Q=W,H()},stop(){if(V=!0,X)clearTimeout(X)},elapsedSec(){return(Date.now()-Y)/1000}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=C5({sessionName:this.sessionName,title:$,status:WW(Z,Y),template:J}),V=await u(this.chatId,Q);if(!V)return K(`session "${this.sessionName}": status card send failed title=${$}`),await w(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await $$(V)}catch(X){return K(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return u0(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>J9($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=J9($.title,`${Z} (${G0(J)})`);await U$($.cardId);let Q=await M0($.cardId,R.footer,this.footerElement(Y));A0($.cardId);let V=await P0($.cardId,v$({durationSec:J,suffix:Z}));if(Q&&V)await w0($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${V?"ok":"MISS"}`;K(`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((V)=>{Y=V}),await J;let Q=++this.lifecycleSequence;K(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),K(`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}),V={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=V,this.openingTurn=!0,V}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&&GF(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",K(`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(V){Z=`Codex 会话落盘确认失败: ${O(V)}`}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,t0(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(k.get($),this.selectedProvider!=="codex"){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Y=X0("codex-sub",$)?.defaultModel||null;t0(this.sessionName,[],null,null),x1(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=s$(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")x1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&o0(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${k.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"&&!c4(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,V$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!VW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await E(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{H5(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&&k.preferred(this.sessionName)===null)await M2();Q=this.spawnAgent()}catch(G){let B=`${this.backendLabel()} 启动失败: ${O(G)}`;if(K(`session "${this.sessionName}": ${B}`),J?.(`❌ ${B}`),Z)await E(this.chatId,`❌ ${B}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let V=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,zW):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let X,z=null;try{Q.sendInitialize(),X=Q.initializationPromise?.()}catch(G){X=void 0,z=G}let W=z?{state:"error",error:z}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(X),()=>{K(`session "${this.sessionName}": codex init still pending after ${XJ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(W.state==="error"||W.state==="exit"){let G=W.error?O(W.error):W.state;K(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let _=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${V} 启动失败: ${G}${_}`;if(J?.(j),Z)await E(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="timeout"){K(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${f6/1000}s)`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${f6/1000} 秒内初始化事务未完成${B}`;if(J?.(_),Z)await E(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let G=`${V} 启动期间已退出`;if(K(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await E(this.chatId,`❌ ${G}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,V$({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(`
249
- `))}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=(X,z)=>{if(Y)return;Y=!0,clearTimeout(V),clearTimeout(H),J({state:X,error:z})},V=setTimeout(()=>{if(Y)return;try{Z?.()}catch(X){Q("error",X)}},XJ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${f6/1000}s`))},f6);$.then(()=>Q("init"),(X)=>Q("error",X)),this.proc?.quotaWaitPromise?.().then(()=>Q("waiting_quota"),(X)=>Q("error",X))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(W,G)=>{if(Y)return;Y=!0,clearTimeout(V),$.off("init",H),$.off("error",X),$.off("exit",z),J({state:W,error:G})},V=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),X=(W)=>Q("error",W),z=(W)=>Q("exit",W);$.once("init",H),$.once("error",X),$.once("exit",z)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)S0($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;K(`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)S0(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,V=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),K(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((D)=>{K(`session "${this.sessionName}": stop current main-card close failed: ${O(D)}`)});let X=this.waitForTurnCloses().catch((D)=>K(`session "${this.sessionName}": stop main-card close failed: ${O(D)}`));this.beginProcStop(Q),this.status="stopped";let z=[];try{this.opts.onLifecycleChange?.()}catch(D){z.push(D),K(`session "${this.sessionName}": stop intent lifecycle write failed: ${O(D)}`)}let W=Q.conversationMaterializationBarrier?.();if(W){try{await W}catch(D){H=`Codex 会话落盘确认失败: ${O(D)}`}V=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(D){G=D}let B=Q.conversationMaterializationFailure?.();if(B&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${O(B)}`;V=this.persistResumableSessionId(!1,Q,!1);let j=(await Promise.allSettled([this.resetBackgroundTasks(),X])).filter((D)=>D.status==="rejected").map((D)=>D.reason);for(let D of j)K(`session "${this.sessionName}": stop terminal cleanup failed: ${O(D)}`);let q=this.finishProcStop(Q,G);try{this.opts.onLifecycleChange?.()}catch(D){z.push(D),K(`session "${this.sessionName}": stop final lifecycle write failed: ${O(D)}`)}let P=[...G?[G]:[],...!q&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...j,...z,...V?[Error(V)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(P.length===1)throw P[0];if(P.length>1)throw AggregateError(P,`stop failed: ${P.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,V=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,t$(this.sessionName,null),this.pendingConversationMaterialization=null;let X=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!X&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(x){let f=this.invalidateMissingCodexResume(z.sessionId,x,J),m=f?`❌ 旧会话不可恢复: ${O(x)};${f}`:`❌ 旧会话 cwd 校验失败: ${O(x)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Q?.(m),Y)await E(this.chatId,m);return!1}let W=z?.sessionId??null,G=X&&X.kind!=="fresh"?X.source.sessionId:W,B=G?U0(G):"",_=null,j=(x=this.proc)=>{if(!$||X||x?.provider!=="codex"||x.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,x,!1),z=this.lastSessionRef,W=z?.sessionId??null,G=W,B=G?U0(G):""},q=null;if(!Q&&Y&&$&&W){let x=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${B}`);if(q=await this.openStatusCard("restart",x),q)Q=(f)=>this.setStatusCard(q,f)}let P=Y&&!q,D=async(x)=>{if(q)await this.closeStatusCard(q,x)},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((x)=>{K(`session "${this.sessionName}": restart current main-card close failed: ${O(x)}`)});let U=this.waitForTurnCloses().catch((x)=>K(`session "${this.sessionName}": restart main-card close failed: ${O(x)}`)),A=null,M=null;if(this.proc){let x=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(x.provider)}`),M=x,this.beginProcStop(x);let f=x.conversationMaterializationBarrier?.();if(f)try{await f}catch(l){_=`Codex 会话落盘确认失败: ${O(l)}`}if(j(x),$&&!X&&_&&!N&&x.isAlive()){if(this.stoppingProc===x)this.stoppingProc=null;this.status=V;let l=`❌ ${this.backendLabel(x.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(K(`session "${this.sessionName}": abort restart before kill: ${_}`),Q?.(l),P)await E(this.chatId,l);return await D(l),!1}try{await x.kill()}catch(l){A=l}let m=x.conversationMaterializationFailure?.();if(m&&x.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${O(m)}`;j(x)}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(),U])).filter((x)=>x.status==="rejected").map((x)=>x.reason);for(let x of C)K(`session "${this.sessionName}": restart terminal cleanup failed: ${O(x)}`);let p=M?this.finishProcStop(M,A):!0,y=[...A?[`kill=${O(A)}`]:[],...!p&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...C.map((x)=>`cleanup=${O(x)}`),..._?[`resume=${_}`]:[]];if(y.length>0&&H)try{t$(this.sessionName,H),this.pendingConversationMaterialization=H}catch(x){y.push(`pendingRestore=${O(x)}`)}if(y.length>0){let x=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${y.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(x),P)await E(this.chatId,x);return await D(x),!1}let h=X?.kind==="resume"||X?.kind==="fork";if($&&z||h){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${B}`));let x;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&k.preferred(this.sessionName)===null)await M2();x=this.spawnAgent(z??void 0)}catch(o){let K0=`❌ ${this.backendLabel()} 恢复失败: ${O(o)}`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${O(o)}`),Q?.(K0),P)await E(this.chatId,K0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(K0),!1}this.attachProc(x);let f=this.backendLabel(),m=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(x,zW):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${f} 恢复启动`:`⏳ 等待 ${f} init 确认`);let l,F=null;try{x.sendInitialize(),l=x.initializationPromise?.()}catch(o){l=void 0,F=o}let b=F?{state:"error",error:F}:this.selectedProvider==="claude"?await m:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{K(`session "${this.sessionName}": codex resume init still pending after ${XJ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${f} init 确认 thread=${B}`))});if(b.state==="error"||b.state==="exit"||b.state==="timeout"){let o=b.state==="error"?this.invalidateMissingCodexResume(G,b.error,J):null,K0=[b.error?O(b.error):b.state,o].filter(Boolean).join(";");K(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${K0}`);let A9=await this.stopOwnedProc(x,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,t1=b.state==="timeout"?`❌ ${f} 恢复超时${A9}`:`❌ ${f} 恢复失败: ${K0}${A9}`;if(Q?.(t1),P)await E(this.chatId,t1);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(t1),!1}if(this.proc!==x||!x.isAlive()){let o=`❌ ${f} 恢复期间已退出`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(o),P)await E(this.chatId,o);return this.detachProc(x),this.status="stopped",this.opts.onLifecycleChange?.(),await D(o),!1}let d=this.withModel(this.withWorktreeInstructionNotice(b.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&b.state==="ready"?`✅ 已准备恢复上一会话 thread=${B}`:`✅ 已恢复上一会话 thread=${B}`));if(Q?.(d),P)await E(this.chatId,d);if(this.status=b.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),b.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await D(d)}catch(o){K(`session "${this.sessionName}": restart succeeded but status-card close failed: ${O(o)}`),await w(this.chatId,`⚠️ ${d}
250
- 状态卡收尾失败: ${O(o)}`)}return!0}else{if($&&!X){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),P)await E(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{_0($,this.selectedProvider,this.workDir);let J=I4(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)t$(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)t$(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{t$(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Q,V],`fork start and pending-intent restore failed: ${O(Q)}; ${O(V)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{_0($,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,V=this.lastSessionId,H=this.lastSessionRef,X=f4(this.sessionName).slice(),z=h4(this.sessionName),W=I4(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},B=!1,_=()=>{if(B)this.lastSessionId=null,this.lastSessionRef=null,E2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=H,H)v4(this.sessionName,H);else E2(this.sessionName,this.selectedProvider);t0(this.sessionName,X,z,W),this.pendingConversationMaterialization=W,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},j=!1;if(Y?.pendingLaunch)t0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,j=!0;this.pendingConversationLaunch=$;let q=(P)=>{B=H?.provider==="codex"&&H.sessionId===P};try{let P;try{P=$.kind==="fresh"?await this.restartUnlocked(!1,J,q):await this.restartUnlocked(!0,J,q)}catch(D){let N=null,U=this.proc&&this.proc!==Q?this.proc:null;if(U)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(C){N=C}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(A)try{_()}catch(C){M=C}let S=[D,...N?[N]:[],...M?[M]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback launch and cleanup failed: ${S.map(O).join("; ")}`)}if(!P)return _(),!1;if(Y)try{if(!j)t0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(D){let N=null,U=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(C){N=C}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(A)try{_()}catch(C){M=C}let S=[D,...N?[N]:[],...M?[M]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback branch commit failed: ${S.map(O).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){G$.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 K(`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 K(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),K(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return l7(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${O(Z)}`;return K(`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)K(`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(...d5(J.name,J.input));return Z}worktreeProjectName(){return z1(this)}worktreeProjectDir(){return a2(this)}spawnDeveloperInstructions(){return Iz(this)}delegatedAgentDeveloperInstructions($){return gz(this,$)}worktreeInstructionLoadedNotice(){return JJ(this)}withWorktreeInstructionNotice($){return mz(this,$)}worktreeExtraInstruction(){return D9(this)}runWorktreeCommand($,Z){return pz(this,$,Z)}showWorktrees(){return YJ(this)}showTasklistPanel(){return qz(this)}showAgentIdentityPanel($=""){return Xz(this,$)}onAgentIdentityPage($,Z,J){return zz($,Z,J)}onTasklistEnable(){return Pz(this)}onTasklistDeletePrompt($){return Dz(this,$)}onTasklistDeleteConfirm($){return Fz(this,$)}runCompactCommand(){return oX(this)}showModelPanel(){return sX(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>Qz(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>uZ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return cZ(this,$,Z)}onModelPage($,Z,J){return R6(this,$,Z,J)}onModelAddOpen($,Z){return tX(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>eX(this,$,Z,J,Y))}onModelPanelCancel($=""){return Jz(this,$)}onModelCustomPrompt($,Z,J=""){return $z(this,$,Z,J)}consumeModelCustomMessage($,Z){return Zz(this,$,Z)}onWorktreeDisband($){return uz(this,$)}showForkList($=""){return rz(this,$)}showBackList($=""){return sz(this,$)}showResumeList($=""){return tz(this,$)}runBtwCommand($){return ez(this,$)}runByeCommand(){return $W(this)}onForkSelect($,Z,J=""){return ZW(this,$,Z,J)}onBackSelect($,Z,J=""){return JW(this,$,Z,J)}onResumeSelect($,Z,J=""){return YW(this,$,Z,J)}runCommand($,Z="",J){return nX(this,$,Z,J)}async buildConsoleOpts($,Z){let J=await YH(),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:[...G$.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return k5(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:K3(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 CH();else Z.usage=await R1(this.codexAccountId());if(!await M0($,R.consoleUsage,Y9(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(V){Y=!1,K(`session "${this.sessionName}": ${Z} mutation failed: ${O(V)}`)}let Q=!1;try{Q=await P0($,{config:{streaming_mode:!1}})}catch(V){K(`session "${this.sessionName}": ${Z} streaming-off failed: ${O(V)}`)}if(!Y||!Q)return K(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await w0($)}catch(V){return K(`session "${this.sessionName}": ${Z} dispose failed: ${O(V)}`),!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 U$($.cardId);let Q=await M0($.cardId,R.footer,t3(Y,R.footer)),V=await e$($.cardId,s3(Y),{type:"insert_after",targetElementId:R.footer}),H=await e$($.cardId,e3(Y.sysinfo),{type:"insert_after",targetElementId:R.consoleProjects}),X=await e$($.cardId,Y9(Y),{type:"insert_after",targetElementId:R.consoleHost});if(!Q||!V||!H||!X){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}A0($.cardId),await P0($.cardId,v$({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 $$(Z),u0(J,4)}catch(Y){K(`session "${this.sessionName}": console card conversion failed: ${O(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>K(`session "${this.sessionName}": console async update rejected: ${O(J)}`))}interrupt(){if(!this.proc)return;K(`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 V=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!V||this.currentTurn!==V)return;let H=this.startFooterTimer(V.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),X=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{X=G,H.setStatus(G)}});if(H.stop(),await U$(V.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(X.startsWith("❌")?X:"❌ 启动失败",{forcePush:!0});return}let W=this.proc;if(!W?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(V),this.sendClaimedUserText(W,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 V=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let X=(Z.length?Z.map((W)=>`[file: ${W}]`).join(" ")+`
251
- `:"")+$,z=(W)=>{this.pendingReactionIds.set(W,""),(async()=>{let G=await c0(W,"OneSecond");if(!G)return;if(this.pendingReactionIds.has(W))this.pendingReactionIds.set(W,G);else if(this.currentBatchReactionIds.has(W))this.currentBatchReactionIds.set(W,G);else S0(W,G)})().catch((G)=>{K(`session "${this.sessionName}": reaction tracking failed: ${O(G)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}await this.startColdUserTurn($,X,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}if(!this.openingTurn&&this.initCount>=1){let W=this.proc,G=this.procEpoch,B=this.beginTurnOpen(W,G);try{this.pendingTurnInputs.push($);let _=await this.openTurnCard(B,J,"user_message");if(!_||this.currentTurn!==_)return;if(this.proc!==W||this.procEpoch!==G||!W.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(W.provider)} 已退出`);return}this.sendClaimedUserText(W,X),this.status="working"}finally{this.releaseTurnOpen(B)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,X),V&&Y)z(Y)}hasPendingAsk(){return VX(this)}refreshPendingAsks(){_6(this)}askBlockReason($){return g2(this,$)}onMultiMessageInbound($,Z,J,Y){return hH(this,$,Z,J,Y)}clearMultiMsgBuffer($){HZ(this,$)}onAskMessageAnswer($,Z,J){return HX(this,$,Z,J)}onAskAnswer($,Z,J,Y){return XX(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return PZ(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return _X(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=s$(this.sessionName,"codex");if(E2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)K(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=zJ(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=s$(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{E2(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${O(H)}`;return K(`session "${this.sessionName}": ${X} thread=${$}`),X}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${U0($)}`;return K(`session "${this.sessionName}": ${V} fullThread=${$}`),V}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 X=Error("Claude pending fork did not provide a materialized session id");if(K(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}let V={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let X=Error(`Claude fork did not materialize an independent session id (${Q})`);if(K(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}try{v4(this.sessionName,V)}catch(X){let z=`会话恢复点持久化失败: ${O(X)}`,W=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;if(K(`session "${this.sessionName}": ${z}`),$)throw X;if(W&&J)w(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let X=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(X&&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 K(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return t$(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${O(J)}`;return K(`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(o8(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(!U1(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{K(`session "${this.sessionName}": background settle failed: ${O(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{K(`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=$7(Z,Date.now(),a1()),Y=await u(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))K(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await $$(Y)}catch(V){K(`session "${this.sessionName}": background card id_convert failed: ${V}`);return}if(u0(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((V)=>V.id)),this.backgroundDetailAdding.clear(),K(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!U1(this.backgroundTasks)){this.settleBackgroundCard().catch((V)=>{K(`session "${this.sessionName}": background settle-after-open failed: ${O(V)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!U1(this.backgroundTasks))return;let Z=a1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(s0(Q))continue;let V=a$(J-Q.startedAt,Z).nextDelayMs;if(V<Y)Y=V}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=a1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),e$($.cardId,B2(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else K(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else $0($.cardId,q4.panel(Y.id),B2(Y,Z,J));k1($.cardId,Z3(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!s0($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>s0(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){K(`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 U$($.cardId),await M$($.messageId,J3(Z)),A0($.cardId),!await P0($.cardId,v$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await w0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!s0(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),K(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&U1(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 U$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(s0).map((V)=>V.id)),Y=J.size;if(Y>0)await M$($.messageId,J3(Z));else await M$($.messageId,Z7());if(A0($.cardId),!await P0($.cardId,v$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await w0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((V)=>!J.has(V.id)||!s0(V)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),K(`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){K(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${O(H)}`);return}let V=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${V.slice(0,78)}`,K(`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(K(`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,K(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else K(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,K(`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)=>{K(`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,V=!1,H=(X,z)=>{$.on(X,(W)=>{if(!Y()){if(!Q)Q=!0,K(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(X)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(X!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,K(`session "${this.sessionName}": ignore ${$.provider} event=${String(X)} while process stop is pending`);return}z(W)})};H("error",(X)=>{K(`session "${this.sessionName}": ${$.provider} process error: ${X}`)}),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++,K(`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)K(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let X=this.pendingUserMessageCount>0,z=!X&&this.bgResumePending;if(!X&&!z)return;let W=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(j){K(`session "${this.sessionName}": init turn-open ownership conflict: ${O(j)}`);return}if(this.bgResumePending=!1,X)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let B=X?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let j of B){let q=this.currentBatchReactionIds.get(j);if(this.currentBatchReactionIds.delete(j),q)S0(j,q)}};(async()=>{try{let j=await this.openTurnCard(G,W,X?"user_message":"bg_task_resume");if(!Y()){if(K(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),j&&this.currentTurn===j)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!j||this.currentTurn!==j){if(!this.ownsTurnOpen(G)){_();return}if(G.sawResult&&G.terminalSuffix)w(this.chatId,G.terminalSuffix);if(X)K(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,K(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else K(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,K(`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((j)=>{K(`session "${this.sessionName}": init turn-open handler failed: ${O(j)}`)})}),H("scheduled_turn_input",({text:X,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,X,z)}),H("conversation_materialized",({session_id:X,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==X){K(`session "${this.sessionName}": ignore mismatched Codex materialization session=${X} current=${$.sessionId??"MISS"} source=${z}`);return}K(`session "${this.sessionName}": Codex resume point materialized thread=${X} source=${z}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:X,source:z,error:W})=>{if($.provider!=="codex"||$.sessionId!==X)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${O(W)}`,B=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,K(`session "${this.sessionName}": ${G} thread=${X} source=${z}`),B)w(this.chatId,`⚠️ ${G}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("codex_account_changed",({accountId:X,diagnostics:z})=>{if(K(`session "${this.sessionName}": Codex account=${X}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)u(this.chatId,V$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
252
- `),hint:"详情:codex-accounts"})).catch((W)=>{K(`session "${this.sessionName}": 账号诊断卡失败: ${O(W)}`)})}),H("turn_started",({retry:X})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)K(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),X){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:X})=>{if(this.persistResumableSessionId(),X)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(X)=>{this.handleTurnPlanUpdated(X)}),H("plan_delta",(X)=>{this.handlePlanDelta(X)}),H("context_compacted",(X)=>{this.handleContextCompacted(X)}),H("rate_limits_updated",(X)=>{if($.provider==="codex")bQ(X,o0($))}),H("thread_goal_updated",(X)=>{this.handleThreadGoalUpdated(X)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:X,parentToolUseId:z})=>{if(z)return;this.appendAssistant(X)}),H("assistant_block_stop",({parentToolUseId:X})=>{if(X)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:X,name:z,input:W,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(s8({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}if(GX(this,X,z,W),!G)this.onMainThreadAdvance();if(!G&&(z==="Task"||z==="Agent"))this.lastMainTaskToolUseId=X}),H("tool_result",({tool_use_id:X,content:z,is_error:W,parentToolUseId:G,input:B})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(e8({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}KX(this,X,z,W,B)}),H("can_use_tool",(X)=>{jX(this,X)}),H("hook_callback",(X)=>{this.proc?.sendHookResponse(X.request_id,{})}),H("result",(X)=>{let z=this.persistResumableSessionId(),W=z?null:this.consumePendingConversationMaterialization(),G=[z,W].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",S=this.proc?.lastResult.is_error===!0;K(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${S} — ignored`),this.status="idle";return}let B=X?.is_error!==!0?this.recordTurnAnchor(X?.checkpoint):null;if(X?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,j=this.proc?.lastResult.is_error===!0,q=this.proc?.lastResult.subtype??"success",P=typeof X?.error==="string"&&X.error.trim()?X.error.trim():q,D,N=!1,U=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),A=[G,B].filter(Boolean).join(";")||null;if(A)D=`⚠️ ${A}`,N=!0;else if(_)D=j?`⚠️ ${U} ${P},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)D=`⚠️ ${U} ${P}`,N=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=D,this.openingTurnOwner.terminalForcePush=N;if(A&&!this.currentTurn&&!this.openingTurn)w(this.chatId,`⚠️ ${A}`);if(K(`session "${this.sessionName}": SDK result subtype=${q} isError=${j} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${N}`),this.closeTurnCard(D,{forcePush:N,hasFreshResult:!0}).catch((M)=>{K(`session "${this.sessionName}": result card close failed: ${O(M)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((M)=>{K(`session "${this.sessionName}": mid-turn drain failed: ${O(M)}`)})}),H("bg_task_started",(X)=>{let z=X.tool_use_id??this.lastMainTaskToolUseId??void 0;K(`session "${this.sessionName}": bg_task_started task=${X.task_id} type=${X.task_type??"-"} subagent=${X.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(X.description??"").slice(0,40)}`),this.applyBgStore(i8(this.bgStore(),{...X,tool_use_id:z})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(X)=>{this.applyBgStore(n8(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(a8(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(X)=>{if(K(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore(r8(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(t8(this.bgStore(),X.thread_id,X.item_id,X.tool,X.phase,X.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:X,signal:z,expected:W})=>{if(K(`session "${this.sessionName}": ${$.provider} exited code=${X} signal=${z} expected=${W}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let q=$.conversationMaterializationFailure?.(),P=this.persistResumableSessionId(!1,$,!1),D=[q&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${O(q)}`:null,P].filter(Boolean).join(";");if(D)w(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${D}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}K(`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((q)=>{K(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${O(q)}`)});let G=this.backendLabel($.provider),B=`code=${X??"null"}, signal=${z??"null"}`,_=W?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${B})`;if(this.currentTurn)this.closeTurnCard(_).catch((q)=>{K(`session "${this.sessionName}": process-exit current main-card close failed: ${O(q)}`)});let j=this.waitForTurnCloses().catch((q)=>{K(`session "${this.sessionName}": process-exit main-card close failed: ${O(q)}`)});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 q=await Promise.allSettled([j,this.resetBackgroundTasks()]);for(let P of q)if(P.status==="rejected")K(`session "${this.sessionName}": process-exit terminal cleanup failed: ${O(P.reason)}`);if(!W)await E(this.chatId,`⚠️ ${G} 异常退出 (${B})。回复任意消息将重新启动。`)}).catch((q)=>{K(`session "${this.sessionName}": process-exit cleanup rejected: ${O(q)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?S8(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=b8(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 y3(Z)}contextLimitForDisplay($=this.proc){return w3($?.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){K(`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 W=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,W),this.pendingReactionIds.delete(z.msgId)}let Q=Y.map((z)=>z.wireText).join(`
253
-
254
- `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,X=await this.openTurnCard(J,H,"user_message");if(!X||this.currentTurn!==X){for(let z of Y){if(!z.msgId)continue;let W=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),W)S0(z.msgId,W)}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 W=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),W)S0(z.msgId,W)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(z){K(`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 M0($,R.footer,this.footerElement(Z)):!0;A0($);let Q=await P0($,v$({suffix:Z}));if(Y&&Q){await w0($);return}let V=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;K(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${V}`),await w(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${V})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{K(`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&&U1(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(q){K(`session "${this.sessionName}": background migrate failed (non-blocking): ${q}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,V=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=V[0]?.slice(0,80)??this.lastTurnUserPreview,K(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${V.length}`);let H=this.runtimeModelSelection(),X=this.withModel(Y.initialFooter??"Waiting...(0s)",H),z=I3({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort??"MISS",kind:J,userInputs:V,initialFooter:X,directStart:Y.directStart}),W=await u(this.chatId,z);if(!W){if(!this.ownsTurnOpen($))return null;if(K(`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 $$(W)}catch(q){if(K(`session "${this.sessionName}": id_convert failed: ${q}`),J==="user_message"&&this.ownsTurnOpen($))await w(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let B=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return u0(G,B),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:G,...H,messageId:W,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(u0(G,B,(q,P)=>{this.onCardWriteFailure(_,G,q,P)}),this.currentTurn=_,Y.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let q=$.pendingCompactions.splice(0);K(`session "${this.sessionName}": replay ${q.length} context compaction event(s) buffered during card open`);for(let P of q)this.handleContextCompacted(P)}let j=this.takeOrphanAssistantText();if(j)this.appendAssistant(j),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((q)=>{K(`session "${this.sessionName}": background rebuild failed: ${O(q)}`)})}return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&l4($.cardId)<PF)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){K(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){K(`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(!u4(J,Y)){let H=Y?.operation??"unknown operation",X=Y?.elementId?` element=${Y.elementId}`:"";K(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${X} 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}${X})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let V=Y?.capacityFingerprint;if(V){let H=Q.cardCapacityFailures.get(V);if(H!==void 0){if(K(`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(V,!0),w(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(V,!1)}K(`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},V=(H,X)=>{if(!Q.value)Q.value={code:H,failure:X}};$.rotating=(async()=>{try{K(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${l4(Z)}`);let H=I3({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),X=await u(this.chatId,H);if(!X){if(K(`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 $$(X)}catch(P){if(K(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${P}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await w(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}u0(z,2,(P,D)=>{if($.rotating){V(P,D);return}this.onCardWriteFailure($,z,P,D)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=z,$.cardRotationFailed=!1,$.messageId=X,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,B=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&B){let P=R.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=P,$.currentAssistantText=B,$.segmentTexts.set(P,B)}if(B)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)F0($.cardId,I1(this.taskBoard),{type:"insert_before",targetElementId:R.footer});if($.planLiveInserted)F0($.cardId,n4($.planSteps,$.planExplanation,R.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?R.taskBoardLive:R.footer});for(let P of $.contextCompactionPending.values()){if(P.cardId!==Z)continue;P.cardId=z,P.created=!1,P.createFailure=void 0;let D=R.contextCompact(P.i);P.createPromise=S2(z,i4(P.i,P.notice,D),{type:"insert_before",targetElementId:O0($)}).then((N)=>{if(P.cardId===z)P.created=N.landed,P.createFailure=N.failure;return N.landed})}for(let[P,D]of _){if(G&&B&&P===G)continue;if(!x2(Z,P))continue;let N=$.assistantSegmentCount++,U=R.assistant(N);$.segmentTexts.set(U,D),await this.addCompletedAssistantSegment($,U,D)}MZ(this,Z,z,J,Y,$),await U$(Z),MZ(this,Z,z,J,Y,$);let j=new Set([R.taskBoardLive,R.planLive,...[...$.contextCompactionPending.values()].map((P)=>R.contextCompact(P.i))]);if(G)j.add(G);for(let P of J.values())if(P.output==null)j.add(R.tool(P.i));if(_V(Z).some((P)=>!j.has(P)))$.cardCapacityFailures.clear();await U$(z);try{await FZ($,Z);let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await U$(Z);let D=$.mathRendered?.get(Z);for(let[M,S]of _){if(G&&B&&M===G)continue;if(x2(Z,M))continue;if(D?.has(M))continue;await $0(Z,M,this.completedAssistantElement(M,S))}let N=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",U=await M0(Z,R.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${N}`)),{notifyCardFailure:!1});A0(Z);let A=await P0(Z,v$({suffix:"\uD83D\uDCE8 转下一张"}));if(U&&A)await w0(Z);else K(`session "${this.sessionName}": rotate old-card terminal MISS footer=${U} settings=${A}`),await w(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${U?"ok":"MISS"}, settings=${A?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(P){K(`session "${this.sessionName}": mid-turn rotate close-old failed: ${P}`)}K(`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=R.planUpdate($.planUpdateCount++);F0(Z,_5($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:O0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=R.goalUpdate(Z.goalUpdateCount++);F0(Z.cardId,j5($,J),{type:"insert_before",targetElementId:O0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=R.goalUpdate($.goalUpdateCount++);F0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
255
-
256
- 已清除`},{type:"insert_before",targetElementId:O0($)})}handleContextCompacted($){let Z=HW($);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;K(`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<h6){K(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((U)=>U.startsWith("turn:")),V=Y??Q,H=V?this.contextCompactionReceipts.get(V):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let U=this.contextCompactionReceipts.get(Q);if(!U?.hasItemAlias&&U?.completed&&Date.now()-U.completedAt<h6||!U?.hasItemAlias&&U?.completionKey&&J?.contextCompactionCompleting.has(U.completionKey))V=Q,H=U,U.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,U)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),K(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");K(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(V&&H?.completed){K(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${V}`);return}let X=this.contextCompactionOwnerId(J);if(V&&H&&H.ownerId!==X){this.rememberContextCompactionReceipt(Z,null,!0),K(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){K(`session "${this.sessionName}": context compaction alias already writing receipt=${V}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){K(`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<h6){K(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let U=BF($);if(J.contextCompactionPending.has(U)||J.contextCompactionCompleted.has(U)){K(`session "${this.sessionName}": duplicate context compaction start ignored key=${U}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,X,!1);let A=J.contextCompactCount++,M=J.cardId,S=R.contextCompact(A),C={i:A,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};C.createPromise=S2(M,i4(A,$,S),{type:"insert_before",targetElementId:O0(J)}).then((p)=>{if(C.cardId===M)C.created=p.landed,C.createFailure=p.failure;return p.landed}),J.contextCompactionPending.set(U,C),K(`session "${this.sessionName}": context compaction start #${A+1} key=${U}`),k1(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){K(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<h6){K(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){K(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let W=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:_F(J),G=W?J.contextCompactionPending.get(W):void 0,B=W??z??"__anonymous__";if(J.contextCompactionCompleting.has(B)){K(`session "${this.sessionName}": context compaction completion already writing key=${B}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=jF(G?.notice,$),j=J.contextCompactionEndOnly.get(B),q=G?.i??j??J.contextCompactCount++;if(!G&&j===void 0)J.contextCompactionEndOnly.set(B,q);J.contextCompactionCompleting.add(B);let P=[...new Set([...HW(G?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,X,!1,B);let D=R.contextCompact(q),N=i4(q,_,D);K(`session "${this.sessionName}": context compaction completion write #${q+1} key=${B}`),(async()=>{let U=!1;if(!G)while(!0){let A=J.cardId;if(U=await e$(A,N,{type:"insert_before",targetElementId:O0(J)}),U)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==A)continue;break}else while(!0){let A=G.cardId;if(await G.createPromise,G.cardId!==A)continue;if(G.created)U=await M0(A,D,N);else{if(BV(G.createFailure?.code,G.createFailure))jV(A,D),U=await M0(A,D,N,{notifyCardFailure:!1});if(!U)U=await e$(A,N,{type:"insert_before",targetElementId:O0(J)})}if(G.cardId!==A)continue;if(U){G.created=!0;break}let M=J.rotating;if(M){await M;continue}if(G.cardId!==A)continue;break}if(J.contextCompactionCompleting.delete(B),!U){K(`session "${this.sessionName}": context compaction completion write MISS #${q+1} key=${B}`);return}if(W&&J.contextCompactionPending.get(W)===G)J.contextCompactionPending.delete(W);if(J.contextCompactionEndOnly.delete(B),B!=="__anonymous__")J.contextCompactionCompleted.add(B);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=B==="__anonymous__",P.length>0){let A=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===B).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...P,...A])],null,!0)}K(`session "${this.sessionName}": context compaction completed #${q+1} key=${B}`)})().catch((U)=>{J.contextCompactionCompleting.delete(B),K(`session "${this.sessionName}": context compaction completion transaction failed: ${O(U)}`)}),k1(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((V)=>V.startsWith("item:"))};for(let V of $)this.contextCompactionReceipts.delete(V),this.contextCompactionReceipts.set(V,Q);while(this.contextCompactionReceipts.size>DF){let V;for(let H of this.contextCompactionReceipts.values()){if(H.completed){V=H;break}V??=H}if(!V)break;for(let[H,X]of this.contextCompactionReceipts)if(X===V)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){K(`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))K(`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?R.taskBoardLive:R.footer;Z.planLiveInserted=!0,F0(Z.cardId,n4(Z.planSteps,Z.planExplanation,R.planLive),{type:"insert_before",targetElementId:J})}else $0(Z.cardId,R.planLive,n4(Z.planSteps,Z.planExplanation,R.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){K(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)K(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){K(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")K(`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&&h3(Z)===h3(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 V=Z.assistantSegmentCount++,H=R.assistant(V);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);k1(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
257
-
258
- `).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;K(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),E(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
259
-
260
- ${J}`)}completedAssistantElement($,Z){if(GZ(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 rH(Y);if(!await M0(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){K(`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),K(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=O0($),V=(async()=>{if(!await e$(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return K(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(GZ(J)){let X=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((z)=>K(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(X),X.finally(()=>$.mathRenderInflight?.get(Y)?.delete(X))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(V),V.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(V)),V}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
261
-
262
- ${J}`;if(!await E(this.chatId,Y))K(`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 kH($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return e($)}sendOutboundPath($,Z){let J=W6($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!KF(J)){K(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),K(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),p4(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:V}=a$(Date.now()-$.footerStatusStartedAt,a1()),H=Z===XW?this.proc?.lastThinkingTokens:null,X=typeof H==="number"?` · 约 ${H} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${X} (${V})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:V}=a$(Date.now()-$.footerStatusStartedAt,a1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(V)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,XW)}startWritingFooter($){this.startFooterStatus($,LF)}startWorkingFooter($){this.startFooterStatus($,qF)}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 V=await Y.readUsage();if(V.state==="ok"&&V.kind!=="balance"){let H=V.windows.find((z)=>z.kind==="fiveHour"),X=V.windows.find((z)=>z.kind==="weekly");if(H||X)return this.fmtDualWindowSuffix(H??null,X??null)}return` | ${$6(V)}`}if($==="codex"){let V=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,H=V?await q3(()=>V.readRateLimits(),o0(V)):null,X=V?H:Q;return X?.state==="ok"?this.fmtDualWindowSuffix(X.fiveHour??null,X.weekly??null):" | 额度 MISS"}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(V)=>{if(!V)return null;if(V.percent==null)return"MISS";let H=V.resetsAt&&V.resetsAt.getTime()>Date.now()?A2(V.resetsAt):"",X=`${Math.round(V.percent)}%`;return H?`${H}·${X}`:X},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)S0(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"?X0(Y.tokenSourceId??this.selectedTokenSourceId,o0(Y)):this.currentTokenSource(),codexUsage:CQ(o0(Y)),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let V=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(V),V.then(()=>{this.turnCloseInflight.delete(V)},()=>{this.turnCloseInflight.delete(V)}),V}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;await FZ(Y),this.stopFooterStatus(Y);let Q=(Date.now()-Y.startedAt)/1000,V=Y.cardId,H=Y.segmentTexts;await U$(V);let X=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:A,currentAssistantText:M}=Y;if(!await this.addCompletedAssistantSegment(Y,A,M))X.set(A,M);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let z=Y.assistantWriteInflight?.get(V);if(z?.size)await Promise.allSettled([...z]);let W=Y.mathRenderInflight?.get(V);if(W?.size)await Promise.allSettled([...W]);let G=Y.mathRendered?.get(V);for(let[A,M]of H){if(x2(V,A)){X.set(A,M);continue}if(G?.has(A))continue;await $0(V,A,this.completedAssistantElement(A,M))}if(Y.cardRotationFailed)for(let[A,M]of H)X.set(A,M);let B=Z?Z:"✅",_=[`${B} ⏱ ${G0(Q)}`];if(J.hasFreshResult){let{contextTokens:A,contextLimit:M}=$,S=Y.provider==="claude",C=K5(A,M,S?0:void 0);if(C)_.push(`\uD83E\uDDE0 ${C}`);let p=$.lastTurnDelta?.costUsd??0;if(p>0)_.push(`\uD83D\uDCB0 $${p.toFixed(3)}`)}if(Y.contextCompactCount>0)_.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)_.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let j=this.modelLine(Y);if(j)_.push(j);let q=_.join(" | "),P=J.hasFreshResult?B5($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",D=P?`${q}
263
- ${P}`:q,N=await M0(V,R.footer,this.footerElement(D));A0(V);let U=await P0(V,v$({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(N&&U)await w0(V);else{let A=`footer=${N?"ok":"MISS"}, settings=${U?"ok":"MISS"}`;K(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${A}`),await w(this.chatId,`⚠️ 对话卡片终态写入失败 (${A})。本轮已结束: ${B}`)}for(let A of X.values())await this.sendAssistantTextFallback(A,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)S1(Y.messageId,[Y.userOpenId])}}});function Y$($){return{card:{type:"raw",data:$}}}import{randomUUID as FF}from"node:crypto";function WJ($){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:k.get(o0($.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:b$().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 GW($,Z,J,Y,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let V=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(V.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof V.message_id!=="string"||!V.message_id.startsWith("om_"))throw Error("message_id required");if(!Q||V.message_id!==Q)throw Error("stale or mismatched model panel");if(!J||J.message_id!==V.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(!V.value||typeof V.value!=="object"||Array.isArray(V.value))throw Error("action value required");let H={};for(let[X,z]of Object.entries(V.value)){if(!UF.has(X))throw Error(`unsupported model action field: ${X}`);if(X==="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 ${X}`);H[X]=z.trim()}}if(!MF.has(String(H.kind)))throw Error("only model panel actions are supported");for(let X of["panel_id","source_id"])if(!H[X])throw Error(`${X} 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&&!B$(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${FF()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:V.message_id},action:{tag:"button",value:H}}}var MF,UF;var KW=T(()=>{D0();Q0();g0();MF=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"]),UF=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as AF}from"node:http";import{randomUUID as OF}from"node:crypto";function LW($){if($.allowReply&&$.buttons?.length)throw Error(jW);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Q=new Date,V=`${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:u8($.text??"")||"_(空消息)_"}),$.resolution){let z=$.resolution,W=z.kind==="text"?"已回复":`已选择:${z.text}`,G;if(z.status==="processing")G=`<font color='blue'>⏳ ${W} · 推送中…</font>`;else if(z.status==="failed")G=`<font color='red'>⚠️ ${z.kind==="text"?W:`已选:${z.text}`} · 回调失败:${e(z.detail??"未知")} · ${V}</font>`;else if(z.status==="delivered")G=`<font color='green'>✅ ${W} · 反馈已送达 · ${V}</font>`;else if(z.status==="unknown")G=`<font color='red'>⚠️ ${W} · ${z.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${V}</font>`;else G=`<font color='green'>✅ ${W} · ${V}</font>`;if(H.push({tag:"markdown",content:G}),z.status==="delivered"&&z.reply)H.push({tag:"markdown",content:e(z.reply)})}let X=Y&&(!$.resolution||$.resolution.status==="failed");if(X&&$.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 · ${V}</font>`}),X&&$.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 W1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${e($.title)}`}];if(Z.response)V.push({tag:"markdown",content:e(Z.response.text)});if(Y==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
264
- 你的下一条文字优先用于这条通知,完成后再回答 Agent 的提问。点击其他通知的「回复」会放弃本次回复;群控制命令仍然优先。`}),V.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")V.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let H=J?.detail??Z.error;if(H)V.push({tag:"markdown",content:`<font color='red'>${e(H)}</font>`});if(Y==="failed")V.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Y==="unknown")V.push({tag:"markdown",content:"无法确认是否已送达,请联系通知发起方核实;已禁止自动重试。"});if(J?.reply)V.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:V}}}function EF($){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(),V=String(Y.text??"").trim();if(!NF.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!V)return{error:`button "${Q}" missing text`};if(V.length>BW)return{error:`button "${Q}" text > ${BW} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=TF.has(H)?H:"default";J.push({id:Q,text:V,type:X})}return{buttons:J}}function xF($){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 qW($){try{let Z=AF((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:_W(J,Y)):_W(J,Y)).catch((H)=>{if(K(`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)=>{K(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{K(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){K(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function _W($,Z,J=V0){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(l,F)=>{Z.statusCode=l,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(F)},V=(l,F)=>{Z.statusCode=l,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(F))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
241
+ ${G}`)}return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1}}function ZJ($){if(!l1($))throw Error(`project directory does not exist: ${$}`);let Z=R0($,["rev-parse","--show-toplevel"]).trim();if(eZ(Z)!==eZ($))throw Error(`${$} is not the git repository root (${Z})`)}function gz($,Z){let J=R0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function mD($,Z,J){let Y=pD($);if(!Y?.startsWith(l2))return null;let Q=Y.slice(l2.length);if(!d1(Q))throw Error(`invalid worktree branch "${Y}"`);let V=i2(Z,J,Q);if(y6($)!==y6(V))return null;let H=uD($,cD(Q));return H?{path:H,slug:Q}:null}function pD($){if(!l1($))return null;try{return R0($,["branch","--show-current"]).trim()||null}catch(Z){if(dD(Z))return null;throw Z}}function cD($){return $.split("-",1)[0]??$}function uD($,Z){let J=`agents.${Z}.md`,Y=vD($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?kz($,Y[0]):null}function lD($,Z){try{return R0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function mz($,Z,J){let Y=R0($,["rev-parse",Z]).trim(),Q=R0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(Cz($,Z,"HEAD"))return"merged";if(Cz($,"HEAD",Z))return"active";return"stale"}function Cz($,Z,J){try{return R0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function JJ($){let Z=new Map,J=R0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
242
+ `)){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 R0($,Z){try{return wD("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(YJ(J))}}function YJ($){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 dD($){return/not a git repository/i.test(YJ($))}var l2="work/",gD,k6;var pz=N(()=>{gD=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,k6=new Map});function z1($){return yz(F$($.sessionName)??$.sessionName)}function n2($){return T3(z1($))}function uz($){let Z=F$($.sessionName)??$.sessionName,J=z1($),Y=T3(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return i2(Y,J,Q)}function lz($,Z=$.currentProvider()){let J=Z==="dsh"?Sz:Z==="claude"?xz:Ez,Y=D9($);return Y?`${J}
243
+ ${Y}`:J}function dz($,Z){return D9($)??""}function QJ($){return D9($)?"已载入wt特殊约定":null}function iz($,Z){let J=QJ($);return J?`${Z}
244
+ ${J}`:Z}function D9($){let Z=z1($),J=vz($.workDir,n2($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
245
+ `)}async function nz($,Z,J){if(!Z){await VJ($);return}let Y=d1(Z);if(!Y){await x($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await x($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=z1($),V=n2($);try{await w6(V,async()=>{let H;try{H=hz(V,Q,Y)}catch(X){await x($.chatId,`❌ wt 失败: ${O(X)}`);return}try{let X=await Z5(H.chatName,J),z=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await u($.chatId,Q9({slug:Y,branch:H.branch,status:z})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await u(X.chatId,Q9({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await w(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await x($.chatId,`❌ wt 已建,拉群失败: ${O(X)}`)}})}catch(H){await x($.chatId,`❌ wt 失败: ${O(H)}`)}}async function az($,Z){let J=z1($),Y=n2($);return await w6(Y,async()=>{return await nD(J,Y,Z)})}async function nD($,Z,J){let Y=fz(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,V=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await x3();return m5({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:V.map((X)=>{let z=H.get(X.chatName)??[],W=L0.get(X.chatName),G=W&&z.includes(W)?W:z.length===1?z[0]:null;return{slug:X.slug,chatName:X.chatName,branch:X.branch,state:X.state,path:X.worktreePath??X.expectedPath,mounted:X.mounted,dirtyCount:X.dirtyCount,statusLine:X.statusLine,error:X.error,chatId:G,duplicateChatCount:z.length}})})}async function VJ($){try{let Z=await az($);if(!await u($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await x($.chatId,`❌ wt 列表失败: ${O(Z)}`)}}async function cz($,Z,J,Y){try{return{ok:Z,message:J,card:await az($,{type:Y,content:J})}}catch(Q){let V=`列表刷新失败: ${O(Q)}`;return K(`session "${$.sessionName}": wt action panel refresh failed: ${O(Q)}`),{ok:!1,message:`${J}
246
+ ${V}`,card:Q9({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function oz($,Z){let J=d1(Z);if(!J)return cz($,!1,"❌ 名称无效","error");let Y=z1($),Q=n2($),V;try{V=await w6(Q,async()=>{let H=d2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};$J(Q,Y,J);let X=await Y5(H),z=Iz(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",z.branch].join(`
247
+ `),type:"success"}})}catch(H){V={ok:!1,message:`❌ 解散 ${J} 失败: ${O(H)}`,type:"error"}}return cz($,V.ok,V.message,V.type)}var rz=N(()=>{bz();J$();Z0();h();pz()});import{closeSync as oD,openSync as rD,readSync as sD,readdirSync as tD,statSync as eD}from"node:fs";import{randomUUID as XJ}from"node:crypto";import{join as $F}from"node:path";function f6($){return F$($.sessionName)??$.sessionName}function tz($){let Z=a7($,HJ);return HJ.add(Z),Z}function ez($){HJ.delete($)}function a2($){let Z=sz.get($);if(!Z)Z=new Map,sz.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let V=Q.status==="consumed"?YF:JF,H=Q.consumedAt??Q.createdAt;if(J-H>V)Z.delete(Y)}return Z}function VF($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function $W($,Z,J,Y){let Q={id:XJ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:f6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return a2($).set(Q.id,Q),Q}function zJ($,Z,J,Y,Q){let V=a2($).get(J);if(!V||V.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||V.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(V.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(V.provider!==$.selectedProvider||V.workDir!==$.workDir||V.sourceSessionId!==$.lastSessionId||!VF(V.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=V.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return V.status="processing",{panel:V,choice:H}}function v6($){$.status="consumed",$.consumedAt=Date.now()}function HF($){return{kind:"fork",source:$.source,through:$}}function XF($){return f4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function zF($){let Z=h4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return _0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function WF($){let Z=X3($),J;try{J=tD(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 V=Q.slice(0,-6);if(J2("claude",V))continue;let H=$F(Z,Q),X;try{X=eD(H).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:V,cwd:$,preview:KF(H),ts:X})}return Y.sort((Q,V)=>V.ts-Q.ts)}function GF($){let Z=$.slice().sort((Q,V)=>V.ts-Q.ts),J=Date.now()-ZF,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(QF,Math.max(10,Y)))}function KF($){let Z="",J=null;try{J=rD($,"r");let Q=Buffer.alloc(65536),V=sD(J,Q,0,65536,0);Z=Q.subarray(0,V).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)oD(J)}let Y="";for(let Q of Z.split(`
248
+ `)){let V=Q.trim();if(!V)continue;let H;try{H=JSON.parse(V)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let X=H.content.trim();if(X)return X.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let X=BF(H.message);if(X)Y=X}}return Y.slice(0,80)}function BF($){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 ZW($,Z,J){if(!J){await x($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=XF($),Q=zF($),V=new Map,H=[];for(let G=0;G<Y.length;G++){let B=Y[G];if(G===0&&Q===null)continue;let _=XJ(),j=G===0?Q:HF(Y[G-1].checkpoint);V.set(_,{kind:Z,launch:j,branchBase:Q,seedAnchors:Y.slice(0,G),writes:Y.slice(G).flatMap((q)=>q.writes)}),H.push({choiceId:_,preview:B.preview,ts:B.ts})}H.reverse();let X=$W($,Z,J,V),z=c5({projectName:f6($),panelId:X.id,mode:Z,entries:H}),W;try{W=await u($.chatId,z)}catch(G){throw a2($).delete(X.id),G}if(!W)a2($).delete(X.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function JW($,Z){return ZW($,"fork",Z)}function YW($,Z){return ZW($,"back",Z)}async function QW($,Z){if(!Z){await x($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():WF($.workDir)}catch(z){await w($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=GF(J).map((z)=>{let W=XJ();return Y.set(W,{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:W,preview:z.preview,ts:z.ts}}),V=$W($,"resume",Z,Y),H=u5({projectName:f6($),panelId:V.id,entries:Q}),X;try{X=await u($.chatId,H)}catch(z){throw a2($).delete(V.id),z}if(!X)a2($).delete(V.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function VW($,Z){if(!Z){await x($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await x($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=tz(f6($));await x($.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{ez(J)}if(!Y.ok){await x($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await x($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function HW($){if(!F$($.sessionName)){await x($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await x($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await x($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await x($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function XW($,Z,J,Y){let Q=zJ($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let X=tz(V.baseName);K(`session-temp: fork ${$.sessionName} → ${X} (${H.launch.kind})`),await x($.chatId,`\uD83D\uDD31 正在分叉到 ${X}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:X,userOpenId:Y,workDir:V.workDir,routing:V.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{ez(X)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${X};原会话和磁盘文件未回滚`}}catch(X){return{ok:!1,message:`分叉失败: ${X instanceof Error?X.message:X}`}}finally{v6(V)}}async function zW($,Z,J,Y){let Q=zJ($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let X="";try{if(!await u($.chatId,l5({projectName:V.baseName,entries:H.writes})))X=";文件变更记录卡发送失败"}catch(G){X=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(K(`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:`回退失败;原会话绑定未改,请检查日志后重试${X}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${X}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${M0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{v6(V)}}async function WW($,Z,J,Y){let Q=zJ($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:H}=Q;if(H.kind!=="resume")throw v6(V),Error("resume panel contained a non-resume choice");let X=H.launch.source.sessionId,z=$.lastSessionId,W=(B,_)=>({projectName:V.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:X,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:z,newSessionId:B,bindingState:_}),G=(B,_,j,q=null)=>({ok:B,message:_,resumePresentation:W(q,j)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(K(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${X}`),!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 _=$.lastSessionId;if(!_)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===X||z&&_===z)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return G(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(B){return G(!1,`历史分支创建失败: ${B instanceof Error?B.message:B}`,"unknown")}finally{v6(V)}}var ZF=86400000,JF=1800000,YF=3600000,QF=40,sz,HJ;var GW=N(()=>{Z0();J$();h();F4();H4();F1();sz=new WeakMap,HJ=new Set});import{existsSync as KW}from"node:fs";import{randomBytes as jF,timingSafeEqual as LF}from"node:crypto";import{isAbsolute as qF}from"node:path";function GJ($,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=GJ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return GJ($.cause,Z);return null}function PF($){return $.itemId||$.turnId||"__latest__"}function BW($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function DF($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function FF($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function i1(){return v.runtime?.live_elapsed??"bucket"}function LW($,Z){return`${$} (${n$(Date.now()-Z,i1()).label})`}var _W="Thinking...",UF="Writing...",MF="Working...",WJ=1e4,h6=720000,AF=50,OF=256,I6=1e4,jW=250,G$;var iZ=N(()=>{H4();z4();D0();U1();Y7();D0();C0();O7();Y0();g0();A2();F4();k$();J$();Z0();h();V0();k5();C$();z9();HZ();uH();JX();PX();q6();UX();$z();Jz();Kz();Pz();Tz();rz();GW();F1();G$=class G${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;G$.all.add(this);let Y=s7($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=q$(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)K(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=s$($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)K(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=I4($);if(V)if(this.selectedProvider!=="claude")t0($,[],null,null),K(`session "${$}": cleared pending Claude fork after provider changed`);else{_0(V.launch,"claude",this.workDir);let H=this.lastSessionId===V.previousSessionId,X=this.lastSessionRef,z=!H&&X?.provider==="claude"&&X.cwd===this.workDir&&X.sessionId!==V.launch.source.sessionId&&X.sessionId!==V.previousSessionId;if(!H&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,K(`session "${$}": restored ${z?"materialized":"pending"} Claude fork source=${V.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0,...this.proc?.isAlive()&&this.proc.provider==="codex"&&this.proc.codexAccountSelectionMode?.()!==null&&!(this.proc.turnRetry?.reason==="quota"&&this.proc.turnRetry.phase==="waiting")?{codexAccountName:k.get(o0(this.proc)).name}:{}}}get workDir(){return uz(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 K3(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?o0(this.proc):this.codexStartAccountOverride??k.selected(this.sessionName)}tokenSource($){let Z=q$($);return Z?.forAccount?H0($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...this.codexAccountId()===c?{}:{codexAccountId:this.codexAccountId()},...k.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)k.get($.codexAccountId);let Z=q$($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)t0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=s$(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,T1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??c;if($.codexAccountAutomatic)k.selectAuto(this.sessionName);else if(k.selected(this.sessionName)!==J)k.select(this.sessionName,J)}dshEffortForSpawn(){if(B0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&L$($,this.selectedModel??$.defaultModel);if(!Z||!B0(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 Y2({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!J2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!c4(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?(X)=>Z.spawnEnv(X):void 0,Y=new W2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,V=null;try{Q=await Y.listConversations()}catch(X){V=X}let H=null;try{await Y.kill(2000)}catch(X){H=X}if(V&&H)throw AggregateError([V,H],`Codex history query and cleanup failed: ${O(V)}; ${O(H)}`);if(V)throw V;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=z3(this.workDir,$.sessionId);if(!KW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${M0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!c4(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?(X)=>Y.spawnEnv(X):void 0}),V=null;try{Z=await Q.readConversationRef($.sessionId)}catch(X){V=X,Z=$}let H=null;try{await Q.kill(2000)}catch(X){H=X}if(V&&H)throw AggregateError([V,H],`Codex legacy resume lookup and cleanup failed: read=${O(V)}; cleanup=${O(H)}`);if(V)throw V;if(H)throw H}return _0({kind:"resume",source:Z},this.selectedProvider,this.workDir),v4(this.sessionName,Z),Z}hasRunningPeerSession($){return[...G$.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 r0(this.selectedEffort)?this.selectedEffort:j4}return j4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&T0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=L$($,this.selectedModel??$.defaultModel);if(!T0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return u$}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??L$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?u$:j4)}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"?u$:j4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return $0($,R.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:R.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return B5($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return _$($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(_0($.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=jF(32).toString("base64url");let Z={LODESTAR_AGENT_URL:D3(v.notify.bind,v.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"});_0(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 V=Y?.enabled||Q?Y:void 0,H=T4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:V?.id??null,...this.selectedProvider==="codex"?{codexAccountId:k.selected(this.sessionName)}:{},...Q?{codexAccountPreference:this.codexStartAccountOverride??k.preferred(this.sessionName)}:{},model:V?this.selectedModel??V.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="dsh"?this.dshEffortForSpawn():this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:N2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},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!==$)t0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let V=q$(this.selectedTokenSourceId);if(V)this.selectedModel=Z||null,this.selectedEffort=J??L$(V,Z||V.defaultModel)?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=s$(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,r7(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()===L2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===L2($,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;K(`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(X){Q=X}Y=await this.settleProcResumableState(J);let V=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!V?[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;K(`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 V=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(V.length===1)throw V[0];if(V.length>1)throw AggregateError(V,`idle process stop failed: ${V.map(O).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,V=!1,H=()=>{if(V)return;this.replaceFooterContent($,J(LW(Q,Y)))},X=null,z=()=>{if(V)return;let{nextDelayMs:W}=n$(Date.now()-Y,i1());X=setTimeout(()=>{H(),z()},Math.max(1,Math.ceil(W)))};return H(),z(),{setStatus(W){Q=W,H()},stop(){if(V=!0,X)clearTimeout(X)},elapsedSec(){return(Date.now()-Y)/1000}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=y5({sessionName:this.sessionName,title:$,status:LW(Z,Y),template:J}),V=await u(this.chatId,Q);if(!V)return K(`session "${this.sessionName}": status card send failed title=${$}`),await w(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await $$(V)}catch(X){return K(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return u0(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>J9($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=J9($.title,`${Z} (${G0(J)})`);await M$($.cardId);let Q=await U0($.cardId,R.footer,this.footerElement(Y));A0($.cardId);let V=await P0($.cardId,w$({durationSec:J,suffix:Z}));if(Q&&V)await w0($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${V?"ok":"MISS"}`;K(`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((V)=>{Y=V}),await J;let Q=++this.lifecycleSequence;K(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),K(`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}),V={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=V,this.openingTurn=!0,V}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&&LF(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",K(`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(V){Z=`Codex 会话落盘确认失败: ${O(V)}`}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,t0(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(k.get($),this.selectedProvider!=="codex"){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Y=H0("codex-sub",$)?.defaultModel||null;t0(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=s$(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"&&o0(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${k.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 x(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"&&!c4(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,V$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!KW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await x(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{z5(this.workDir)}catch(G){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${G}`),Z)await x(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&&k.preferred(this.sessionName)===null)await D2();Q=this.spawnAgent()}catch(G){let B=`${this.backendLabel()} 启动失败: ${O(G)}`;if(K(`session "${this.sessionName}": ${B}`),J?.(`❌ ${B}`),Z)await x(this.chatId,`❌ ${B}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let V=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,jW):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let X,z=null;try{Q.sendInitialize(),X=Q.initializationPromise?.()}catch(G){X=void 0,z=G}let W=z?{state:"error",error:z}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(X),()=>{K(`session "${this.sessionName}": codex init still pending after ${WJ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(W.state==="error"||W.state==="exit"){let G=W.error?O(W.error):W.state;K(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let _=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${V} 启动失败: ${G}${_}`;if(J?.(j),Z)await x(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="timeout"){K(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${h6/1000}s)`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${h6/1000} 秒内初始化事务未完成${B}`;if(J?.(_),Z)await x(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let G=`${V} 启动期间已退出`;if(K(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await x(this.chatId,`❌ ${G}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,V$({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let G=this.modelLine();await x(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),G].filter(Boolean).join(`
249
+ `))}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=(X,z)=>{if(Y)return;Y=!0,clearTimeout(V),clearTimeout(H),J({state:X,error:z})},V=setTimeout(()=>{if(Y)return;try{Z?.()}catch(X){Q("error",X)}},WJ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${h6/1000}s`))},h6);$.then(()=>Q("init"),(X)=>Q("error",X)),this.proc?.quotaWaitPromise?.().then(()=>Q("waiting_quota"),(X)=>Q("error",X))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(W,G)=>{if(Y)return;Y=!0,clearTimeout(V),$.off("init",H),$.off("error",X),$.off("exit",z),J({state:W,error:G})},V=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),X=(W)=>Q("error",W),z=(W)=>Q("exit",W);$.once("init",H),$.once("error",X),$.once("exit",z)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)S0($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;K(`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)S0(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 x(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Q=this.proc,V=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),K(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((D)=>{K(`session "${this.sessionName}": stop current main-card close failed: ${O(D)}`)});let X=this.waitForTurnCloses().catch((D)=>K(`session "${this.sessionName}": stop main-card close failed: ${O(D)}`));this.beginProcStop(Q),this.status="stopped";let z=[];try{this.opts.onLifecycleChange?.()}catch(D){z.push(D),K(`session "${this.sessionName}": stop intent lifecycle write failed: ${O(D)}`)}let W=Q.conversationMaterializationBarrier?.();if(W){try{await W}catch(D){H=`Codex 会话落盘确认失败: ${O(D)}`}V=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(D){G=D}let B=Q.conversationMaterializationFailure?.();if(B&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${O(B)}`;V=this.persistResumableSessionId(!1,Q,!1);let j=(await Promise.allSettled([this.resetBackgroundTasks(),X])).filter((D)=>D.status==="rejected").map((D)=>D.reason);for(let D of j)K(`session "${this.sessionName}": stop terminal cleanup failed: ${O(D)}`);let q=this.finishProcStop(Q,G);try{this.opts.onLifecycleChange?.()}catch(D){z.push(D),K(`session "${this.sessionName}": stop final lifecycle write failed: ${O(D)}`)}let P=[...G?[G]:[],...!q&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...j,...z,...V?[Error(V)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(P.length===1)throw P[0];if(P.length>1)throw AggregateError(P,`stop failed: ${P.map(O).join("; ")}`);if(Y?.(`✅ ${$}`),J)await x(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 x(this.chatId,"❌ daemon 重启后没有可用的恢复点。请发送 rs 选择历史会话,或 hi 明确启动新会话。"),!1;return await this.restartUnlocked(!0)})}async restartUnlocked($=!1,Z={},J){let Y=Z.announce??!0,Q=Z.onStatus,V=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,t$(this.sessionName,null),this.pendingConversationMaterialization=null;let X=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!X&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(E){let f=this.invalidateMissingCodexResume(z.sessionId,E,J),m=f?`❌ 旧会话不可恢复: ${O(E)};${f}`:`❌ 旧会话 cwd 校验失败: ${O(E)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Q?.(m),Y)await x(this.chatId,m);return!1}let W=z?.sessionId??null,G=X&&X.kind!=="fresh"?X.source.sessionId:W,B=G?M0(G):"",_=null,j=(E=this.proc)=>{if(!$||X||E?.provider!=="codex"||E.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,E,!1),z=this.lastSessionRef,W=z?.sessionId??null,G=W,B=G?M0(G):""},q=null;if(!Q&&Y&&$&&W){let E=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${B}`);if(q=await this.openStatusCard("restart",E),q)Q=(f)=>this.setStatusCard(q,f)}let P=Y&&!q,D=async(E)=>{if(q)await this.closeStatusCard(q,E)},T=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)=>{K(`session "${this.sessionName}": restart current main-card close failed: ${O(E)}`)});let M=this.waitForTurnCloses().catch((E)=>K(`session "${this.sessionName}": restart main-card close failed: ${O(E)}`)),A=null,U=null;if(this.proc){let E=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(E.provider)}`),U=E,this.beginProcStop(E);let f=E.conversationMaterializationBarrier?.();if(f)try{await f}catch(l){_=`Codex 会话落盘确认失败: ${O(l)}`}if(j(E),$&&!X&&_&&!T&&E.isAlive()){if(this.stoppingProc===E)this.stoppingProc=null;this.status=V;let l=`❌ ${this.backendLabel(E.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(K(`session "${this.sessionName}": abort restart before kill: ${_}`),Q?.(l),P)await x(this.chatId,l);return await D(l),!1}try{await E.kill()}catch(l){A=l}let m=E.conversationMaterializationFailure?.();if(m&&E.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${O(m)}`;j(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(),M])).filter((E)=>E.status==="rejected").map((E)=>E.reason);for(let E of C)K(`session "${this.sessionName}": restart terminal cleanup failed: ${O(E)}`);let p=U?this.finishProcStop(U,A):!0,y=[...A?[`kill=${O(A)}`]:[],...!p&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...C.map((E)=>`cleanup=${O(E)}`),..._?[`resume=${_}`]:[]];if(y.length>0&&H)try{t$(this.sessionName,H),this.pendingConversationMaterialization=H}catch(E){y.push(`pendingRestore=${O(E)}`)}if(y.length>0){let E=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${y.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(E),P)await x(this.chatId,E);return await D(E),!1}let I=X?.kind==="resume"||X?.kind==="fork";if($&&z||I){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${B}`));let E;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&k.preferred(this.sessionName)===null)await D2();E=this.spawnAgent(z??void 0)}catch(o){let K0=`❌ ${this.backendLabel()} 恢复失败: ${O(o)}`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${O(o)}`),Q?.(K0),P)await x(this.chatId,K0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(K0),!1}this.attachProc(E);let f=this.backendLabel(),m=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(E,jW):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${f} 恢复启动`:`⏳ 等待 ${f} init 确认`);let l,F=null;try{E.sendInitialize(),l=E.initializationPromise?.()}catch(o){l=void 0,F=o}let b=F?{state:"error",error:F}:this.selectedProvider==="claude"?await m:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{K(`session "${this.sessionName}": codex resume init still pending after ${WJ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${f} init 确认 thread=${B}`))});if(b.state==="error"||b.state==="exit"||b.state==="timeout"){let o=b.state==="error"?this.invalidateMissingCodexResume(G,b.error,J):null,K0=[b.error?O(b.error):b.state,o].filter(Boolean).join(";");K(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${K0}`);let A9=await this.stopOwnedProc(E,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,r1=b.state==="timeout"?`❌ ${f} 恢复超时${A9}`:`❌ ${f} 恢复失败: ${K0}${A9}`;if(Q?.(r1),P)await x(this.chatId,r1);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(r1),!1}if(this.proc!==E||!E.isAlive()){let o=`❌ ${f} 恢复期间已退出`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(o),P)await x(this.chatId,o);return this.detachProc(E),this.status="stopped",this.opts.onLifecycleChange?.(),await D(o),!1}let d=this.withModel(this.withWorktreeInstructionNotice(b.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&b.state==="ready"?`✅ 已准备恢复上一会话 thread=${B}`:`✅ 已恢复上一会话 thread=${B}`));if(Q?.(d),P)await x(this.chatId,d);if(this.status=b.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),b.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await D(d)}catch(o){K(`session "${this.sessionName}": restart succeeded but status-card close failed: ${O(o)}`),await w(this.chatId,`⚠️ ${d}
250
+ 状态卡收尾失败: ${O(o)}`)}return!0}else{if($&&!X){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),P)await x(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{_0($,this.selectedProvider,this.workDir);let J=I4(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)t$(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)t$(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{t$(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Q,V],`fork start and pending-intent restore failed: ${O(Q)}; ${O(V)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{_0($,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,V=this.lastSessionId,H=this.lastSessionRef,X=f4(this.sessionName).slice(),z=h4(this.sessionName),W=I4(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},B=!1,_=()=>{if(B)this.lastSessionId=null,this.lastSessionRef=null,T2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=H,H)v4(this.sessionName,H);else T2(this.sessionName,this.selectedProvider);t0(this.sessionName,X,z,W),this.pendingConversationMaterialization=W,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},j=!1;if(Y?.pendingLaunch)t0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,j=!0;this.pendingConversationLaunch=$;let q=(P)=>{B=H?.provider==="codex"&&H.sessionId===P};try{let P;try{P=$.kind==="fresh"?await this.restartUnlocked(!1,J,q):await this.restartUnlocked(!0,J,q)}catch(D){let T=null,M=this.proc&&this.proc!==Q?this.proc:null;if(M)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(C){T=C}let A=!M||this.proc!==M&&!M.isAlive();if(!A&&!T)T=Error("replacement process stop was not confirmed");let U=null;if(A)try{_()}catch(C){U=C}let S=[D,...T?[T]:[],...U?[U]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback launch and cleanup failed: ${S.map(O).join("; ")}`)}if(!P)return _(),!1;if(Y)try{if(!j)t0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(D){let T=null,M=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(C){T=C}let A=!M||this.proc!==M&&!M.isAlive();if(!A&&!T)T=Error("replacement process stop was not confirmed");let U=null;if(A)try{_()}catch(C){U=C}let S=[D,...T?[T]:[],...U?[U]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback branch commit failed: ${S.map(O).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){G$.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 K(`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 K(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),K(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return n7(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${O(Z)}`;return K(`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)K(`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(...n5(J.name,J.input));return Z}worktreeProjectName(){return z1(this)}worktreeProjectDir(){return n2(this)}spawnDeveloperInstructions(){return lz(this)}delegatedAgentDeveloperInstructions($){return dz(this,$)}worktreeInstructionLoadedNotice(){return QJ(this)}withWorktreeInstructionNotice($){return iz(this,$)}worktreeExtraInstruction(){return D9(this)}runWorktreeCommand($,Z){return nz(this,$,Z)}showWorktrees(){return VJ(this)}showTasklistPanel(){return Az(this)}showAgentIdentityPanel($=""){return _z(this,$)}onAgentIdentityPage($,Z,J){return jz($,Z,J)}onTasklistEnable(){return Oz(this)}onTasklistDeletePrompt($){return Rz(this,$)}onTasklistDeleteConfirm($){return Nz(this,$)}runCompactCommand(){return Zz(this)}showModelPanel(){return Yz(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>Gz(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>dZ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return lZ(this,$,Z)}onModelPage($,Z,J){return N6(this,$,Z,J)}onModelAddOpen($,Z){return Qz(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>Vz(this,$,Z,J,Y))}onModelPanelCancel($=""){return zz(this,$)}onModelCustomPrompt($,Z,J=""){return Hz(this,$,Z,J)}consumeModelCustomMessage($,Z){return Xz(this,$,Z)}onWorktreeDisband($){return oz(this,$)}showForkList($=""){return JW(this,$)}showBackList($=""){return YW(this,$)}showResumeList($=""){return QW(this,$)}runBtwCommand($){return VW(this,$)}runByeCommand(){return HW(this)}onForkSelect($,Z,J=""){return XW(this,$,Z,J)}onBackSelect($,Z,J=""){return zW(this,$,Z,J)}onResumeSelect($,Z,J=""){return WW(this,$,Z,J)}runCommand($,Z="",J){return eX(this,$,Z,J)}async buildConsoleOpts($,Z){let J=await zH(),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:[...G$.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return w5(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:K3(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 fH();else Z.usage=await R1(this.codexAccountId());if(!await U0($,R.consoleUsage,Y9(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(V){Y=!1,K(`session "${this.sessionName}": ${Z} mutation failed: ${O(V)}`)}let Q=!1;try{Q=await P0($,{config:{streaming_mode:!1}})}catch(V){K(`session "${this.sessionName}": ${Z} streaming-off failed: ${O(V)}`)}if(!Y||!Q)return K(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await w0($)}catch(V){return K(`session "${this.sessionName}": ${Z} dispose failed: ${O(V)}`),!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 M$($.cardId);let Q=await U0($.cardId,R.footer,$6(Y,R.footer)),V=await e$($.cardId,e3(Y),{type:"insert_after",targetElementId:R.footer}),H=await e$($.cardId,Z6(Y.sysinfo),{type:"insert_after",targetElementId:R.consoleProjects}),X=await e$($.cardId,Y9(Y),{type:"insert_after",targetElementId:R.consoleHost});if(!Q||!V||!H||!X){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}A0($.cardId),await P0($.cardId,w$({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 $$(Z),u0(J,4)}catch(Y){K(`session "${this.sessionName}": console card conversion failed: ${O(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>K(`session "${this.sessionName}": console async update rejected: ${O(J)}`))}interrupt(){if(!this.proc)return;K(`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 V=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!V||this.currentTurn!==V)return;let H=this.startFooterTimer(V.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),X=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{X=G,H.setStatus(G)}});if(H.stop(),await M$(V.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(X.startsWith("❌")?X:"❌ 启动失败",{forcePush:!0});return}let W=this.proc;if(!W?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(V),this.sendClaimedUserText(W,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 x(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await x(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 V=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let X=(Z.length?Z.map((W)=>`[file: ${W}]`).join(" ")+`
251
+ `:"")+$,z=(W)=>{this.pendingReactionIds.set(W,""),(async()=>{let G=await c0(W,"OneSecond");if(!G)return;if(this.pendingReactionIds.has(W))this.pendingReactionIds.set(W,G);else if(this.currentBatchReactionIds.has(W))this.currentBatchReactionIds.set(W,G);else S0(W,G)})().catch((G)=>{K(`session "${this.sessionName}": reaction tracking failed: ${O(G)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}await this.startColdUserTurn($,X,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}if(!this.openingTurn&&this.initCount>=1){let W=this.proc,G=this.procEpoch,B=this.beginTurnOpen(W,G);try{this.pendingTurnInputs.push($);let _=await this.openTurnCard(B,J,"user_message");if(!_||this.currentTurn!==_)return;if(this.proc!==W||this.procEpoch!==G||!W.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(W.provider)} 已退出`);return}this.sendClaimedUserText(W,X),this.status="working"}finally{this.releaseTurnOpen(B)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)z(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,X),V&&Y)z(Y)}hasPendingAsk(){return GX(this)}refreshPendingAsks(){L6(this)}askBlockReason($){return I2(this,$)}onMultiMessageInbound($,Z,J,Y){return cH(this,$,Z,J,Y)}clearMultiMsgBuffer($){zZ(this,$)}onAskMessageAnswer($,Z,J){return KX(this,$,Z,J)}onAskAnswer($,Z,J,Y){return BX(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return FZ(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return DX(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=s$(this.sessionName,"codex");if(T2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)K(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=GJ(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=s$(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{T2(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${O(H)}`;return K(`session "${this.sessionName}": ${X} thread=${$}`),X}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${M0($)}`;return K(`session "${this.sessionName}": ${V} fullThread=${$}`),V}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 X=Error("Claude pending fork did not provide a materialized session id");if(K(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}let V={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let X=Error(`Claude fork did not materialize an independent session id (${Q})`);if(K(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}try{v4(this.sessionName,V)}catch(X){let z=`会话恢复点持久化失败: ${O(X)}`,W=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;if(K(`session "${this.sessionName}": ${z}`),$)throw X;if(W&&J)w(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let X=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(X&&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 K(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return t$(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${O(J)}`;return K(`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(r8(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(!M1(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{K(`session "${this.sessionName}": background settle failed: ${O(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{K(`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=Z7(Z,Date.now(),i1()),Y=await u(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))K(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await $$(Y)}catch(V){K(`session "${this.sessionName}": background card id_convert failed: ${V}`);return}if(u0(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((V)=>V.id)),this.backgroundDetailAdding.clear(),K(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!M1(this.backgroundTasks)){this.settleBackgroundCard().catch((V)=>{K(`session "${this.sessionName}": background settle-after-open failed: ${O(V)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!M1(this.backgroundTasks))return;let Z=i1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(s0(Q))continue;let V=n$(J-Q.startedAt,Z).nextDelayMs;if(V<Y)Y=V}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=i1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),e$($.cardId,G2(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else K(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else $0($.cardId,L4.panel(Y.id),G2(Y,Z,J));b1($.cardId,Z3(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!s0($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>s0(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){K(`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 M$($.cardId),await U$($.messageId,J3(Z)),A0($.cardId),!await P0($.cardId,w$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await w0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!s0(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),K(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&M1(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 M$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(s0).map((V)=>V.id)),Y=J.size;if(Y>0)await U$($.messageId,J3(Z));else await U$($.messageId,J7());if(A0($.cardId),!await P0($.cardId,w$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await w0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((V)=>!J.has(V.id)||!s0(V)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),K(`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){K(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${O(H)}`);return}let V=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${V.slice(0,78)}`,K(`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(K(`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,K(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else K(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,K(`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)=>{K(`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,V=!1,H=(X,z)=>{$.on(X,(W)=>{if(!Y()){if(!Q)Q=!0,K(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(X)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(X!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,K(`session "${this.sessionName}": ignore ${$.provider} event=${String(X)} while process stop is pending`);return}z(W)})};H("error",(X)=>{K(`session "${this.sessionName}": ${$.provider} process error: ${X}`)}),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++,K(`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)K(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let X=this.pendingUserMessageCount>0,z=!X&&this.bgResumePending;if(!X&&!z)return;let W=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(j){K(`session "${this.sessionName}": init turn-open ownership conflict: ${O(j)}`);return}if(this.bgResumePending=!1,X)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let B=X?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let j of B){let q=this.currentBatchReactionIds.get(j);if(this.currentBatchReactionIds.delete(j),q)S0(j,q)}};(async()=>{try{let j=await this.openTurnCard(G,W,X?"user_message":"bg_task_resume");if(!Y()){if(K(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),j&&this.currentTurn===j)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!j||this.currentTurn!==j){if(!this.ownsTurnOpen(G)){_();return}if(G.sawResult&&G.terminalSuffix)w(this.chatId,G.terminalSuffix);if(X)K(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,K(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else K(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,K(`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((j)=>{K(`session "${this.sessionName}": init turn-open handler failed: ${O(j)}`)})}),H("scheduled_turn_input",({text:X,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,X,z)}),H("conversation_materialized",({session_id:X,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==X){K(`session "${this.sessionName}": ignore mismatched Codex materialization session=${X} current=${$.sessionId??"MISS"} source=${z}`);return}K(`session "${this.sessionName}": Codex resume point materialized thread=${X} source=${z}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:X,source:z,error:W})=>{if($.provider!=="codex"||$.sessionId!==X)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${O(W)}`,B=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,K(`session "${this.sessionName}": ${G} thread=${X} source=${z}`),B)w(this.chatId,`⚠️ ${G}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("codex_account_changed",({accountId:X,diagnostics:z})=>{if(K(`session "${this.sessionName}": Codex account=${X}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)u(this.chatId,V$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
252
+ `),hint:"详情:codex-accounts"})).catch((W)=>{K(`session "${this.sessionName}": 账号诊断卡失败: ${O(W)}`)})}),H("turn_started",({retry:X})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)K(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),X){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:X})=>{if(this.persistResumableSessionId(),X)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(X)=>{this.handleTurnPlanUpdated(X)}),H("plan_delta",(X)=>{this.handlePlanDelta(X)}),H("context_compacted",(X)=>{this.handleContextCompacted(X)}),H("rate_limits_updated",(X)=>{if($.provider==="codex")kQ(X,o0($))}),H("thread_goal_updated",(X)=>{this.handleThreadGoalUpdated(X)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:X,parentToolUseId:z})=>{if(z)return;this.appendAssistant(X)}),H("assistant_block_stop",({parentToolUseId:X})=>{if(X)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:X,name:z,input:W,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(t8({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}if(LX(this,X,z,W),!G)this.onMainThreadAdvance();if(!G&&(z==="Task"||z==="Agent"))this.lastMainTaskToolUseId=X}),H("tool_result",({tool_use_id:X,content:z,is_error:W,parentToolUseId:G,input:B})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore($7({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}qX(this,X,z,W,B)}),H("can_use_tool",(X)=>{FX(this,X)}),H("hook_callback",(X)=>{this.proc?.sendHookResponse(X.request_id,{})}),H("result",(X)=>{let z=this.persistResumableSessionId(),W=z?null:this.consumePendingConversationMaterialization(),G=[z,W].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 U=this.proc?.lastResult.subtype??"unknown",S=this.proc?.lastResult.is_error===!0;K(`session "${this.sessionName}": SDK result after user stop subtype=${U} isError=${S} — ignored`),this.status="idle";return}let B=X?.is_error!==!0?this.recordTurnAnchor(X?.checkpoint):null;if(X?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,j=this.proc?.lastResult.is_error===!0,q=this.proc?.lastResult.subtype??"success",P=typeof X?.error==="string"&&X.error.trim()?X.error.trim():q,D,T=!1,M=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),A=[G,B].filter(Boolean).join(";")||null;if(A)D=`⚠️ ${A}`,T=!0;else if(_)D=j?`⚠️ ${M} ${P},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)D=`⚠️ ${M} ${P}`,T=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=D,this.openingTurnOwner.terminalForcePush=T;if(A&&!this.currentTurn&&!this.openingTurn)w(this.chatId,`⚠️ ${A}`);if(K(`session "${this.sessionName}": SDK result subtype=${q} isError=${j} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${T}`),this.closeTurnCard(D,{forcePush:T,hasFreshResult:!0}).catch((U)=>{K(`session "${this.sessionName}": result card close failed: ${O(U)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((U)=>{K(`session "${this.sessionName}": mid-turn drain failed: ${O(U)}`)})}),H("bg_task_started",(X)=>{let z=X.tool_use_id??this.lastMainTaskToolUseId??void 0;K(`session "${this.sessionName}": bg_task_started task=${X.task_id} type=${X.task_type??"-"} subagent=${X.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(X.description??"").slice(0,40)}`),this.applyBgStore(n8(this.bgStore(),{...X,tool_use_id:z})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(X)=>{this.applyBgStore(a8(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(o8(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(X)=>{if(K(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore(s8(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(e8(this.bgStore(),X.thread_id,X.item_id,X.tool,X.phase,X.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:X,signal:z,expected:W})=>{if(K(`session "${this.sessionName}": ${$.provider} exited code=${X} signal=${z} expected=${W}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let q=$.conversationMaterializationFailure?.(),P=this.persistResumableSessionId(!1,$,!1),D=[q&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${O(q)}`:null,P].filter(Boolean).join(";");if(D)w(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${D}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}K(`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((q)=>{K(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${O(q)}`)});let G=this.backendLabel($.provider),B=`code=${X??"null"}, signal=${z??"null"}`,_=W?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${B})`;if(this.currentTurn)this.closeTurnCard(_).catch((q)=>{K(`session "${this.sessionName}": process-exit current main-card close failed: ${O(q)}`)});let j=this.waitForTurnCloses().catch((q)=>{K(`session "${this.sessionName}": process-exit main-card close failed: ${O(q)}`)});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 q=await Promise.allSettled([j,this.resetBackgroundTasks()]);for(let P of q)if(P.status==="rejected")K(`session "${this.sessionName}": process-exit terminal cleanup failed: ${O(P.reason)}`);if(!W)await x(this.chatId,`⚠️ ${G} 异常退出 (${B})。回复任意消息将重新启动。`)}).catch((q)=>{K(`session "${this.sessionName}": process-exit cleanup rejected: ${O(q)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?b8(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=C8(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 v3(Z)}contextLimitForDisplay($=this.proc){return f3($?.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){K(`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 W=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,W),this.pendingReactionIds.delete(z.msgId)}let Q=Y.map((z)=>z.wireText).join(`
253
+
254
+ `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,X=await this.openTurnCard(J,H,"user_message");if(!X||this.currentTurn!==X){for(let z of Y){if(!z.msgId)continue;let W=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),W)S0(z.msgId,W)}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 W=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),W)S0(z.msgId,W)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(z){K(`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 U0($,R.footer,this.footerElement(Z)):!0;A0($);let Q=await P0($,w$({suffix:Z}));if(Y&&Q){await w0($);return}let V=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;K(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${V}`),await w(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${V})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{K(`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&&M1(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(q){K(`session "${this.sessionName}": background migrate failed (non-blocking): ${q}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,V=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=V[0]?.slice(0,80)??this.lastTurnUserPreview,K(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${V.length}`);let H=this.runtimeModelSelection(),X=this.withModel(Y.initialFooter??"Waiting...(0s)",H),z=m3({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort??"MISS",kind:J,userInputs:V,initialFooter:X,directStart:Y.directStart}),W=await u(this.chatId,z);if(!W){if(!this.ownsTurnOpen($))return null;if(K(`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 $$(W)}catch(q){if(K(`session "${this.sessionName}": id_convert failed: ${q}`),J==="user_message"&&this.ownsTurnOpen($))await w(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let B=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return u0(G,B),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:G,...H,messageId:W,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(u0(G,B,(q,P)=>{this.onCardWriteFailure(_,G,q,P)}),this.currentTurn=_,Y.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let q=$.pendingCompactions.splice(0);K(`session "${this.sessionName}": replay ${q.length} context compaction event(s) buffered during card open`);for(let P of q)this.handleContextCompacted(P)}let j=this.takeOrphanAssistantText();if(j)this.appendAssistant(j),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((q)=>{K(`session "${this.sessionName}": background rebuild failed: ${O(q)}`)})}return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&l4($.cardId)<AF)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){K(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){K(`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(!u4(J,Y)){let H=Y?.operation??"unknown operation",X=Y?.elementId?` element=${Y.elementId}`:"";K(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${X} 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}${X})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let V=Y?.capacityFingerprint;if(V){let H=Q.cardCapacityFailures.get(V);if(H!==void 0){if(K(`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(V,!0),w(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(V,!1)}K(`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},V=(H,X)=>{if(!Q.value)Q.value={code:H,failure:X}};$.rotating=(async()=>{try{K(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${l4(Z)}`);let H=m3({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),X=await u(this.chatId,H);if(!X){if(K(`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 $$(X)}catch(P){if(K(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${P}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await w(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}u0(z,2,(P,D)=>{if($.rotating){V(P,D);return}this.onCardWriteFailure($,z,P,D)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=z,$.cardRotationFailed=!1,$.messageId=X,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,B=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&B){let P=R.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=P,$.currentAssistantText=B,$.segmentTexts.set(P,B)}if(B)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)F0($.cardId,f1(this.taskBoard),{type:"insert_before",targetElementId:R.footer});if($.planLiveInserted)F0($.cardId,n4($.planSteps,$.planExplanation,R.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?R.taskBoardLive:R.footer});for(let P of $.contextCompactionPending.values()){if(P.cardId!==Z)continue;P.cardId=z,P.created=!1,P.createFailure=void 0;let D=R.contextCompact(P.i);P.createPromise=x2(z,i4(P.i,P.notice,D),{type:"insert_before",targetElementId:O0($)}).then((T)=>{if(P.cardId===z)P.created=T.landed,P.createFailure=T.failure;return T.landed})}for(let[P,D]of _){if(G&&B&&P===G)continue;if(!E2(Z,P))continue;let T=$.assistantSegmentCount++,M=R.assistant(T);$.segmentTexts.set(M,D),await this.addCompletedAssistantSegment($,M,D)}AZ(this,Z,z,J,Y,$),await M$(Z),AZ(this,Z,z,J,Y,$);let j=new Set([R.taskBoardLive,R.planLive,...[...$.contextCompactionPending.values()].map((P)=>R.contextCompact(P.i))]);if(G)j.add(G);for(let P of J.values())if(P.output==null)j.add(R.tool(P.i));if(DV(Z).some((P)=>!j.has(P)))$.cardCapacityFailures.clear();await M$(z);try{await MZ($,Z);let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await M$(Z);let D=$.mathRendered?.get(Z);for(let[U,S]of _){if(G&&B&&U===G)continue;if(E2(Z,U))continue;if(D?.has(U))continue;await $0(Z,U,this.completedAssistantElement(U,S))}let T=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",M=await U0(Z,R.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${T}`)),{notifyCardFailure:!1});A0(Z);let A=await P0(Z,w$({suffix:"\uD83D\uDCE8 转下一张"}));if(M&&A)await w0(Z);else K(`session "${this.sessionName}": rotate old-card terminal MISS footer=${M} settings=${A}`),await w(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${M?"ok":"MISS"}, settings=${A?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(P){K(`session "${this.sessionName}": mid-turn rotate close-old failed: ${P}`)}K(`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=R.planUpdate($.planUpdateCount++);F0(Z,L5($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:O0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=R.goalUpdate(Z.goalUpdateCount++);F0(Z.cardId,q5($,J),{type:"insert_before",targetElementId:O0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=R.goalUpdate($.goalUpdateCount++);F0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
255
+
256
+ 已清除`},{type:"insert_before",targetElementId:O0($)})}handleContextCompacted($){let Z=BW($);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;K(`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<I6){K(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((M)=>M.startsWith("turn:")),V=Y??Q,H=V?this.contextCompactionReceipts.get(V):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let M=this.contextCompactionReceipts.get(Q);if(!M?.hasItemAlias&&M?.completed&&Date.now()-M.completedAt<I6||!M?.hasItemAlias&&M?.completionKey&&J?.contextCompactionCompleting.has(M.completionKey))V=Q,H=M,M.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,M)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),K(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");K(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(V&&H?.completed){K(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${V}`);return}let X=this.contextCompactionOwnerId(J);if(V&&H&&H.ownerId!==X){this.rememberContextCompactionReceipt(Z,null,!0),K(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){K(`session "${this.sessionName}": context compaction alias already writing receipt=${V}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){K(`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<I6){K(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let M=PF($);if(J.contextCompactionPending.has(M)||J.contextCompactionCompleted.has(M)){K(`session "${this.sessionName}": duplicate context compaction start ignored key=${M}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,X,!1);let A=J.contextCompactCount++,U=J.cardId,S=R.contextCompact(A),C={i:A,cardId:U,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};C.createPromise=x2(U,i4(A,$,S),{type:"insert_before",targetElementId:O0(J)}).then((p)=>{if(C.cardId===U)C.created=p.landed,C.createFailure=p.failure;return p.landed}),J.contextCompactionPending.set(M,C),K(`session "${this.sessionName}": context compaction start #${A+1} key=${M}`),b1(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){K(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<I6){K(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){K(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let W=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:DF(J),G=W?J.contextCompactionPending.get(W):void 0,B=W??z??"__anonymous__";if(J.contextCompactionCompleting.has(B)){K(`session "${this.sessionName}": context compaction completion already writing key=${B}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=FF(G?.notice,$),j=J.contextCompactionEndOnly.get(B),q=G?.i??j??J.contextCompactCount++;if(!G&&j===void 0)J.contextCompactionEndOnly.set(B,q);J.contextCompactionCompleting.add(B);let P=[...new Set([...BW(G?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,X,!1,B);let D=R.contextCompact(q),T=i4(q,_,D);K(`session "${this.sessionName}": context compaction completion write #${q+1} key=${B}`),(async()=>{let M=!1;if(!G)while(!0){let A=J.cardId;if(M=await e$(A,T,{type:"insert_before",targetElementId:O0(J)}),M)break;let U=J.rotating;if(U){await U;continue}if(J.cardId!==A)continue;break}else while(!0){let A=G.cardId;if(await G.createPromise,G.cardId!==A)continue;if(G.created)M=await U0(A,D,T);else{if(PV(G.createFailure?.code,G.createFailure))FV(A,D),M=await U0(A,D,T,{notifyCardFailure:!1});if(!M)M=await e$(A,T,{type:"insert_before",targetElementId:O0(J)})}if(G.cardId!==A)continue;if(M){G.created=!0;break}let U=J.rotating;if(U){await U;continue}if(G.cardId!==A)continue;break}if(J.contextCompactionCompleting.delete(B),!M){K(`session "${this.sessionName}": context compaction completion write MISS #${q+1} key=${B}`);return}if(W&&J.contextCompactionPending.get(W)===G)J.contextCompactionPending.delete(W);if(J.contextCompactionEndOnly.delete(B),B!=="__anonymous__")J.contextCompactionCompleted.add(B);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=B==="__anonymous__",P.length>0){let A=[...this.contextCompactionReceipts.entries()].filter(([,U])=>U.completionKey===B).map(([U])=>U);this.rememberContextCompactionReceipt([...new Set([...P,...A])],null,!0)}K(`session "${this.sessionName}": context compaction completed #${q+1} key=${B}`)})().catch((M)=>{J.contextCompactionCompleting.delete(B),K(`session "${this.sessionName}": context compaction completion transaction failed: ${O(M)}`)}),b1(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((V)=>V.startsWith("item:"))};for(let V of $)this.contextCompactionReceipts.delete(V),this.contextCompactionReceipts.set(V,Q);while(this.contextCompactionReceipts.size>OF){let V;for(let H of this.contextCompactionReceipts.values()){if(H.completed){V=H;break}V??=H}if(!V)break;for(let[H,X]of this.contextCompactionReceipts)if(X===V)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){K(`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))K(`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?R.taskBoardLive:R.footer;Z.planLiveInserted=!0,F0(Z.cardId,n4(Z.planSteps,Z.planExplanation,R.planLive),{type:"insert_before",targetElementId:J})}else $0(Z.cardId,R.planLive,n4(Z.planSteps,Z.planExplanation,R.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){K(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)K(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){K(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")K(`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&&g3(Z)===g3(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 V=Z.assistantSegmentCount++,H=R.assistant(V);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);b1(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
257
+
258
+ `).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;K(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),x(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
259
+
260
+ ${J}`)}completedAssistantElement($,Z){if(BZ(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 ZX(Y);if(!await U0(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){K(`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),K(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=O0($),V=(async()=>{if(!await e$(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return K(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(BZ(J)){let X=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((z)=>K(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(X),X.finally(()=>$.mathRenderInflight?.get(Y)?.delete(X))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(V),V.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(V)),V}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
261
+
262
+ ${J}`;if(!await x(this.chatId,Y))K(`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 hH($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return e($)}sendOutboundPath($,Z){let J=K6($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!qF(J)){K(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),K(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),p4(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:V}=n$(Date.now()-$.footerStatusStartedAt,i1()),H=Z===_W?this.proc?.lastThinkingTokens:null,X=typeof H==="number"?` · 约 ${H} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${X} (${V})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:V}=n$(Date.now()-$.footerStatusStartedAt,i1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(V)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,_W)}startWritingFooter($){this.startFooterStatus($,UF)}startWorkingFooter($){this.startFooterStatus($,MF)}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 V=await Y.readUsage();if(V.state==="ok"&&V.kind!=="balance"){let H=V.windows.find((z)=>z.kind==="fiveHour"),X=V.windows.find((z)=>z.kind==="weekly");if(H||X)return this.fmtDualWindowSuffix(H??null,X??null)}return` | ${J6(V)}`}if($==="codex"){let V=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,H=V?await q3(()=>V.readRateLimits(),o0(V)):null,X=V?H:Q;return X?.state==="ok"?this.fmtDualWindowSuffix(X.fiveHour??null,X.weekly??null):" | 额度 MISS"}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(V)=>{if(!V)return null;if(V.percent==null)return"MISS";let H=V.resetsAt&&V.resetsAt.getTime()>Date.now()?U2(V.resetsAt):"",X=`${Math.round(V.percent)}%`;return H?`${H}·${X}`:X},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)S0(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"?H0(Y.tokenSourceId??this.selectedTokenSourceId,o0(Y)):this.currentTokenSource(),codexUsage:yQ(o0(Y)),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let V=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(V),V.then(()=>{this.turnCloseInflight.delete(V)},()=>{this.turnCloseInflight.delete(V)}),V}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;await MZ(Y),this.stopFooterStatus(Y);let Q=(Date.now()-Y.startedAt)/1000,V=Y.cardId,H=Y.segmentTexts;await M$(V);let X=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:A,currentAssistantText:U}=Y;if(!await this.addCompletedAssistantSegment(Y,A,U))X.set(A,U);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let z=Y.assistantWriteInflight?.get(V);if(z?.size)await Promise.allSettled([...z]);let W=Y.mathRenderInflight?.get(V);if(W?.size)await Promise.allSettled([...W]);let G=Y.mathRendered?.get(V);for(let[A,U]of H){if(E2(V,A)){X.set(A,U);continue}if(G?.has(A))continue;await $0(V,A,this.completedAssistantElement(A,U))}if(Y.cardRotationFailed)for(let[A,U]of H)X.set(A,U);let B=Z?Z:"✅",_=[`${B} ⏱ ${G0(Q)}`];if(J.hasFreshResult){let{contextTokens:A,contextLimit:U}=$,S=Y.provider==="claude",C=_5(A,U,S?0:void 0);if(C)_.push(`\uD83E\uDDE0 ${C}`);let p=$.lastTurnDelta?.costUsd??0;if(p>0)_.push(`\uD83D\uDCB0 $${p.toFixed(3)}`)}if(Y.contextCompactCount>0)_.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)_.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let j=this.modelLine(Y);if(j)_.push(j);let q=_.join(" | "),P=J.hasFreshResult?j5($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",D=P?`${q}
263
+ ${P}`:q,T=await U0(V,R.footer,this.footerElement(D));A0(V);let M=await P0(V,w$({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(T&&M)await w0(V);else{let A=`footer=${T?"ok":"MISS"}, settings=${M?"ok":"MISS"}`;K(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${A}`),await w(this.chatId,`⚠️ 对话卡片终态写入失败 (${A})。本轮已结束: ${B}`)}for(let A of X.values())await this.sendAssistantTextFallback(A,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)E1(Y.messageId,[Y.userOpenId])}}});function Y$($){return{card:{type:"raw",data:$}}}import{randomUUID as RF}from"node:crypto";function KJ($){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:k.get(o0($.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:b$().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 qW($,Z,J,Y,Q){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let V=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(V.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof V.message_id!=="string"||!V.message_id.startsWith("om_"))throw Error("message_id required");if(!Q||V.message_id!==Q)throw Error("stale or mismatched model panel");if(!J||J.message_id!==V.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(!V.value||typeof V.value!=="object"||Array.isArray(V.value))throw Error("action value required");let H={};for(let[X,z]of Object.entries(V.value)){if(!TF.has(X))throw Error(`unsupported model action field: ${X}`);if(X==="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 ${X}`);H[X]=z.trim()}}if(!NF.has(String(H.kind)))throw Error("only model panel actions are supported");for(let X of["panel_id","source_id"])if(!H[X])throw Error(`${X} 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&&!B$(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${RF()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:V.message_id},action:{tag:"button",value:H}}}var NF,TF;var PW=N(()=>{D0();Y0();g0();NF=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"]),TF=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as EF}from"node:http";import{randomUUID as xF}from"node:crypto";function MW($){if($.allowReply&&$.buttons?.length)throw Error(UW);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Q=new Date,V=`${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:l8($.text??"")||"_(空消息)_"}),$.resolution){let z=$.resolution,W=z.kind==="text"?"已回复":`已选择:${z.text}`,G;if(z.status==="processing")G=`<font color='blue'>⏳ ${W} · 推送中…</font>`;else if(z.status==="failed")G=`<font color='red'>⚠️ ${z.kind==="text"?W:`已选:${z.text}`} · 回调失败:${e(z.detail??"未知")} · ${V}</font>`;else if(z.status==="delivered")G=`<font color='green'>✅ ${W} · 反馈已送达 · ${V}</font>`;else if(z.status==="unknown")G=`<font color='red'>⚠️ ${W} · ${z.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${V}</font>`;else G=`<font color='green'>✅ ${W} · ${V}</font>`;if(H.push({tag:"markdown",content:G}),z.status==="delivered"&&z.reply)H.push({tag:"markdown",content:e(z.reply)})}let X=Y&&(!$.resolution||$.resolution.status==="failed");if(X&&$.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 · ${V}</font>`}),X&&$.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 W1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${e($.title)}`}];if(Z.response)V.push({tag:"markdown",content:e(Z.response.text)});if(Y==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
264
+ 你的下一条文字优先用于这条通知,完成后再回答 Agent 的提问。点击其他通知的「回复」会放弃本次回复;群控制命令仍然优先。`}),V.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")V.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let H=J?.detail??Z.error;if(H)V.push({tag:"markdown",content:`<font color='red'>${e(H)}</font>`});if(Y==="failed")V.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Y==="unknown")V.push({tag:"markdown",content:"无法确认是否已送达,请联系通知发起方核实;已禁止自动重试。"});if(J?.reply)V.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:V}}}function kF($){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(),V=String(Y.text??"").trim();if(!CF.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!V)return{error:`button "${Q}" missing text`};if(V.length>DW)return{error:`button "${Q}" text > ${DW} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=bF.has(H)?H:"default";J.push({id:Q,text:V,type:X})}return{buttons:J}}function yF($){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 AW($){try{let Z=EF((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:FW(J,Y)):FW(J,Y)).catch((H)=>{if(K(`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)=>{K(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{K(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){K(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function FW($,Z,J=Q0){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(l,F)=>{Z.statusCode=l,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(F)},V=(l,F)=>{Z.statusCode=l,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(F))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
265
265
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
266
266
  `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
267
267
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
268
268
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
269
269
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
270
270
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
271
- `);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 F=f$(l);if(!F)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,QX(F))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let l of $)H+=l.toString();let X={};try{X=JSON.parse(H)}catch{return Q(400,"bad json")}if(!X||typeof X!=="object"||Array.isArray(X))return Q(400,"body must be an object");if(X.allow_reply!==void 0&&typeof X.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let z=X.allow_reply===!0,W=String(X.project??"").trim(),G=String(X.text??""),B=String(X.title??"").trim(),_=String(X.level??"info").toLowerCase();if(!W)return Q(400,'missing "project"');if(!G)return Q(400,'missing "text"');let{buttons:j,error:q}=EF(X.buttons);if(q)return Q(400,q);let{url:P,error:D}=xF(X.callback);if(D)return Q(400,D);let N=!!(j&&j.length);if(N&&z)return Q(400,jW);let U=N||z,A=P??"",M=RF.has(_)?_:"info",S=B||W,C=J.sanitizeSessionName(W),p=J.chatIdForSession(C);if(!p)return K(`notify: project "${W}" (sanitized "${C}") has no chat binding → 404`),Q(404,`project "${W}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let y=Array.isArray(X.images)?X.images:[],h=[];for(let l of y){let F=String(l??"").trim();if(!F)continue;let b=await J.uploadImageKey(F);h.push({key:b??"",src:F})}let x=U?`nf_${OF()}`:"",f=LW({title:S,text:G,level:M,images:h,buttons:j,allowReply:z,notifyId:x}),m=await J.sendCard(p,f);if(!m)return K(`notify: sendCard failed → 502 (project="${W}" chat=${p.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(U&&x){let l={notifyId:x,callbackUrl:A,chatId:p,messageId:m,project:W,title:S,text:G,level:M,imageKeys:h,buttons:j,allowReply:z,createdAt:Date.now()};JX(l)}K(`notify: → ${W} (${p.slice(0,8)}…) level=${M} bytes=${G.length} images=${h.length} buttons=${j?.length??0} allowReply=${z} push=${U&&!!A?1:0} msg=${m}`),V(200,{ok:!0,chat_id:p,message_id:m,...x?{notify_id:x}:{}})}function o1($,Z){return LW({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var RF,TF,NF,BW=64,jW='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var I6=T(()=>{I();J0();k0();_9();RF=new Set(["info","warn","error"]),TF=new Set(["default","primary","danger"]),NF=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as GJ,readFileSync as KJ,rmSync as SF}from"node:fs";import{homedir as g6}from"node:os";import{join as R$}from"node:path";function m6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[R$(g6(),".codex","skills"),R$(g6(),".claude","skills")];for(let Y of J){let Q=R$(Y,$.name,"SKILL.md");try{let V=GJ(Q)?KJ(Q,"utf8"):null;if(V===$.body)continue;Q$(Q,$.body),K(`skill: ${V===null?"installed":"updated"} ${Q}`)}catch(V){K(`skill: sync failed (${Q}): ${V}`)}}if(!Z)bF($,j1)}function bF($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=R$(Z,".claude-plugin","plugin.json"),Y=R$(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)+`
272
- `;for(let[V,H]of[[J,Q],[Y,$.body]])try{let X=GJ(V)?KJ(V,"utf8"):null;if(X===H)continue;Q$(V,H),K(`skill: ${X===null?"installed":"updated"} ${V}`)}catch(X){K(`skill: Claude plugin sync failed (${V}): ${X}`)}}function PW($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[R$(g6(),".codex","skills"),R$(g6(),".claude","skills")]).map((Q)=>R$(Q,$));if(!Z)Y.push(R$(j1,"skills",$));for(let Q of Y){let V=R$(Q,"SKILL.md");if(!GJ(V))continue;try{let H=KJ(V,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){K(`skill: obsolete path preserved because ownership is unclear ${V}`);continue}SF(Q,{recursive:!0,force:!1}),K(`skill: removed obsolete ${Q}`)}catch(H){K(`skill: obsolete removal failed (${Q}): ${H}`)}}}var BJ=T(()=>{I();f0();H0()});function CF($){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`---
273
- name: ${DW}
271
+ `);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 F=v$(l);if(!F)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,WX(F))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let l of $)H+=l.toString();let X={};try{X=JSON.parse(H)}catch{return Q(400,"bad json")}if(!X||typeof X!=="object"||Array.isArray(X))return Q(400,"body must be an object");if(X.allow_reply!==void 0&&typeof X.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let z=X.allow_reply===!0,W=String(X.project??"").trim(),G=String(X.text??""),B=String(X.title??"").trim(),_=String(X.level??"info").toLowerCase();if(!W)return Q(400,'missing "project"');if(!G)return Q(400,'missing "text"');let{buttons:j,error:q}=kF(X.buttons);if(q)return Q(400,q);let{url:P,error:D}=yF(X.callback);if(D)return Q(400,D);let T=!!(j&&j.length);if(T&&z)return Q(400,UW);let M=T||z,A=P??"",U=SF.has(_)?_:"info",S=B||W,C=J.sanitizeSessionName(W),p=J.chatIdForSession(C);if(!p)return K(`notify: project "${W}" (sanitized "${C}") has no chat binding → 404`),Q(404,`project "${W}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let y=Array.isArray(X.images)?X.images:[],I=[];for(let l of y){let F=String(l??"").trim();if(!F)continue;let b=await J.uploadImageKey(F);I.push({key:b??"",src:F})}let E=M?`nf_${xF()}`:"",f=MW({title:S,text:G,level:U,images:I,buttons:j,allowReply:z,notifyId:E}),m=await J.sendCard(p,f);if(!m)return K(`notify: sendCard failed → 502 (project="${W}" chat=${p.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(M&&E){let l={notifyId:E,callbackUrl:A,chatId:p,messageId:m,project:W,title:S,text:G,level:U,imageKeys:I,buttons:j,allowReply:z,createdAt:Date.now()};XX(l)}K(`notify: → ${W} (${p.slice(0,8)}…) level=${U} bytes=${G.length} images=${I.length} buttons=${j?.length??0} allowReply=${z} push=${M&&!!A?1:0} msg=${m}`),V(200,{ok:!0,chat_id:p,message_id:m,...E?{notify_id:E}:{}})}function n1($,Z){return MW({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var SF,bF,CF,DW=64,UW='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var g6=N(()=>{h();Z0();k0();_9();SF=new Set(["info","warn","error"]),bF=new Set(["default","primary","danger"]),CF=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as BJ,readFileSync as _J,rmSync as wF}from"node:fs";import{homedir as m6}from"node:os";import{join as R$}from"node:path";function p6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[R$(m6(),".codex","skills"),R$(m6(),".claude","skills")];for(let Y of J){let Q=R$(Y,$.name,"SKILL.md");try{let V=BJ(Q)?_J(Q,"utf8"):null;if(V===$.body)continue;Q$(Q,$.body),K(`skill: ${V===null?"installed":"updated"} ${Q}`)}catch(V){K(`skill: sync failed (${Q}): ${V}`)}}if(!Z)vF($,j1)}function vF($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=R$(Z,".claude-plugin","plugin.json"),Y=R$(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)+`
272
+ `;for(let[V,H]of[[J,Q],[Y,$.body]])try{let X=BJ(V)?_J(V,"utf8"):null;if(X===H)continue;Q$(V,H),K(`skill: ${X===null?"installed":"updated"} ${V}`)}catch(X){K(`skill: Claude plugin sync failed (${V}): ${X}`)}}function OW($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[R$(m6(),".codex","skills"),R$(m6(),".claude","skills")]).map((Q)=>R$(Q,$));if(!Z)Y.push(R$(j1,"skills",$));for(let Q of Y){let V=R$(Q,"SKILL.md");if(!BJ(V))continue;try{let H=_J(V,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){K(`skill: obsolete path preserved because ownership is unclear ${V}`);continue}wF(Q,{recursive:!0,force:!1}),K(`skill: removed obsolete ${Q}`)}catch(H){K(`skill: obsolete removal failed (${Q}): ${H}`)}}}var jJ=N(()=>{h();f0();V0()});function fF($){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`---
273
+ name: ${RW}
274
274
  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.")}
275
275
  ---
276
276
 
@@ -527,13 +527,13 @@ is the script's acknowledgement, distinct from the user's response.
527
527
  Hand-edits will be overwritten — set
528
528
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
529
529
  to maintain the file yourself.
530
- `}function FW(){m6({name:DW,body:CF(v.notify.port)})}var DW="feishu-notify";var MW=T(()=>{C0();BJ()});import{randomUUID as kF}from"node:crypto";function UW($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,H,X)=>{if(!V)return"通知已过期或已移除";if(!X)return"无法识别回复人,操作未执行";if(H&&H!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(f2(V.notifyId))return"通知正在处理中";return null},Y=async(V,H)=>{if($.log(`notify-reply: ${H}`),!await $.sendText(V,`❌ ${H}`))throw Error(`通知回复错误提示发送失败: ${H}`)},Q=async(V,H,X,z)=>{try{await $.updateCard(H,X)}catch(W){await Y(V.chatId,`${z},卡片更新失败:${Z(W)}`)}};return{async recover(V){let H=V.replyState;if(!H||!V.unknownAt)return;let X={kind:"text",status:"unknown",text:H.response?.text??"",operatorOpenId:H.openId,detail:V.unknownReason};await Q(V,H.promptMessageId,W1(V,H,X),"回复送达状态未知"),await Q(V,V.messageId,o1(V,X),"回复送达状态未知")},async open(V,H,X){let z=f$(V),W=J(z,H,X);if(W||!z)return{ok:!1,message:W};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=BZ(z.chatId);if(G.some((B)=>B.replyState?.status==="sending"||f2(B.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};W9(V);try{for(let j of G){let q={...j.replyState,status:"cancelled",cancelReason:"switched"};I2(j.notifyId,q),await Q(j,q.promptMessageId,W1(j,q),"已放弃上一条回复并切换通知")}let B={id:kF(),openId:X,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,W1(z,B));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};B.promptMessageId=_;try{I2(V,B)}catch(j){let q=`等待输入状态保存失败,未开始接收回复:${Z(j)}`;return await Q(z,_,W1(z,B,{status:"failed",detail:q}),q),{ok:!1,message:q,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{G9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,H,X,z){let W=f$(V),G=J(W,X,z);if(G||!W)return{ok:!1,message:G};let B=W.replyState;if(!B||B.id!==H||B.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(B.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...B,status:"cancelled"};return I2(V,_),$.onWaitingChanged(W.chatId),await Q(W,B.promptMessageId,W1(W,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:H,openId:X,messageId:z,text:W,createTime:G}=V;if(!X||!z||!W.trim())return!1;if(YX(H,z))return!0;let B=K9(H,X);if(!B?.replyState)return!1;let _=B.replyState;if(G>0&&G<_.openedAt)return!1;if(_.status!=="waiting"||f2(B.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:W,message_id:z,prompt_message_id:_.promptMessageId},q={..._,status:"sending",response:j};W9(B.notifyId);try{try{I2(B.notifyId,q)}catch(U){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(U)}`),!0}let P;try{if(await $.updateCard(_.promptMessageId,W1(B,q)),B.callbackUrl)P=await $.dispatch(B,j,X);else B9(B.notifyId,void 0,X),P={ok:!0,detail:"已记录"}}catch(U){P={ok:!1,detail:Z(U)}}let D;if(P.ok){let U=B.callbackUrl?K6(B.notifyId,void 0,X):{state:"complete"};D={kind:"text",text:W,operatorOpenId:X,status:U.state==="unknown"?"unknown":B.callbackUrl?"delivered":"done",...U.state==="unknown"?{detail:U.detail}:{reply:P.reply}}}else{D={kind:"text",text:W,operatorOpenId:X,status:"failed",detail:P.detail};try{I2(B.notifyId,{...q,status:"failed",error:P.detail})}catch(U){let A=`${P.detail};失败状态保存失败:${Z(U)}`;try{_Z(B.notifyId,void 0,X,A)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}D={...D,status:"unknown",detail:A}}}let N=D.status==="delivered"?"回复已送达":D.status==="done"?"回复已记录":D.status==="unknown"?`回复送达状态未知:${D.detail}`:`回复未送达:${D.detail}`;return await Q(B,_.promptMessageId,W1(B,q,D),N),await Q(B,B.messageId,o1(B,D),N),$.log(`notify-reply: notify_id=${B.notifyId} status=${D.status}`),!0}finally{G9(B.notifyId),$.onWaitingChanged(B.chatId)}}}}var AW=T(()=>{_9();I6()});class _J{deps;tails=new Map;byRun=new Map;constructor($){this.deps=$}add($){return D$($.chatId,async()=>{let Z=this.tails.get($.chatId);if(Z){if(await this.deps.getChatTailMessageId($.chatId)===Z.messageId&&this.deps.getElementCount(Z.cardId)<yF){let Y=await this.deps.addElementResult(Z.cardId,V9($));if(Y.landed){this.attach(Z,$),await this.settings(Z);return}if(!OW(Y))throw RW("agent card append",Y)}await this.seal(Z)}await this.create($)})}update($,Z=!1){return D$($.chatId,async()=>{let J=this.byRun.get($.runId);if(!J)return;if(J.settled.has($.runId)){if(Z)await this.settings(J);return}let Y=[],Q=await this.deps.replaceElementResult(J.cardId,H9($.runId),V9($));if(!Q.landed){if(!OW(Q)||J.runs.size===1)throw RW("agent task row update",Q);let V=J;await this.seal(V);let H=this.tails.get($.chatId);if(H)await this.seal(H);J=await this.create($),V.runs.delete($.runId),V.settled.delete($.runId);try{if(!await this.deps.deleteElementChecked(V.cardId,H9($.runId)))throw Error("agent moved task row deletion MISS; the previous card may still show its earlier state")}catch(X){Y.push(String(X))}try{await this.settings(V)}catch(X){Y.push(String(X))}}if(Z)J.settled.add($.runId);try{await this.settings(J)}catch(V){Y.push(String(V))}if(Y.length)throw Error(Y.join("; "))})}closeChat($){return D$($,async()=>{let Z=this.tails.get($);if(Z)await this.seal(Z)})}attach($,Z){$.runs.set(Z.runId,Z),this.byRun.set(Z.runId,$),Z.cardMessageId=$.messageId}async create($){let Z=await this.deps.sendCard($.chatId,r5($));if(!Z)throw Error("agent card creation failed");let J=await this.deps.convertMessageToCard(Z);this.deps.recordCardCreated(J,1);let Y={cardId:J,messageId:Z,chatId:$.chatId,runs:new Map,settled:new Set,sealed:!1};return this.attach(Y,$),this.tails.set($.chatId,Y),Y}async seal($){if($.sealed=!0,this.tails.get($.chatId)===$)this.tails.delete($.chatId);await this.settings($)}async settings($){this.deps.cancelSummary($.cardId);let Z=$.settled.size===$.runs.size,J={config:{streaming_mode:!Z,summary:{content:s5([...$.runs.values()])}}},Y=JSON.stringify(J);if(Y!==$.settingsJson){if(!await this.deps.patchSettingsChecked($.cardId,J))throw Error("agent card settings update MISS");$.settingsJson=Y}if(Z&&$.sealed){await this.deps.dispose($.cardId);for(let Q of $.runs.keys())if(this.byRun.get(Q)===$)this.byRun.delete(Q)}}}function OW($){return u4($.failure?.code,$.failure)}function RW($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"})`:""}`)}var yF=50;var TW=T(()=>{J$();y$();E7()});function NW($){let Z=jJ($,"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((z)=>z.trim()).filter(Boolean))],Q=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=r2(Q);if(Q!==void 0&&!V)throw Error("agent session_id must be a non-empty string");if(Z.session_id!==void 0&&Z.sessionId!==void 0&&Z.session_id!==Z.sessionId)throw Error("conflicting agent session_id and sessionId");if(V&&Y.length>1)throw Error("agent session continuation accepts at most one identity_id");if(!V&&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 H=SW(Z.prompt,'agent run requires "prompt"'),X=r2(Z.effort);return{identityIds:Y,description:s2(Z.description),prompt:H,...X?{effort:X}:{},...V?{sessionId:V}:{}}}function EW($){let Z=jJ($,"agent follow-up request"),J=SW(Z.prompt,'agent follow-up requires "prompt"'),Y=r2(Z.identity_id??Z.identityId),Q=r2(Z.effort);return{description:s2(Z.description),prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function s2($){if(typeof $!=="string"||!$.trim())throw Error('agent run requires "description" (CLI: --description)');let Z=$.trim();if(/[\r\n\u2028\u2029]/.test(Z))throw Error("agent description must be a single line");if([...Z].length>60)throw Error("agent description exceeds 60 characters");return Z}function xW($){let Z=jJ($,"agent answer request"),J=r2(Z.identity_id??Z.identityId),Y=r2(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[V,H]of Object.entries(Z.answers)){if(!V.trim())throw Error("agent answer contains an empty question key");Q[V]=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 jJ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function SW($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function r2($){return(typeof $==="string"?$.trim():"")||void 0}function wF(){return["---",`name: ${bW}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar and continue the same work across multiple turns. 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."," Every run and follow-up also requires `--description`: a short, user-facing"," single-line task summary (at most 60 characters). The card shows this line"," with status; the full prompt, progress and results stay collapsed.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon schedules them within concurrency limits."," OpenRouter allows at most 2 delegated tasks at once across projects and models"," in the same daemon; additional tasks queue. This is a local limit, not an API quota."," Wait for queued tasks instead of submitting duplicates. If rate-limited, report"," the error and do not immediately retry the whole batch.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","6. When the same work needs another step, review the returned content and"," continue with `run --session <session-id>` plus the new input. Use as many"," turns as the authorized task needs; assess completion against the overall"," task and its verification requirements, not just one run ending.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Complete one work item across multiple turns","","A single work item can span multiple turns in the same native Agent session.","Use this for staged implementation, revisions based on feedback, or further","verification of previous results. The main Agent reads each result and sends","the next step; the delegated Agent still must not delegate further.","","Keep the returned `Session:` id (JSON: `workers[].session_id`) together with","the worker output. For turn 2 and later, send that id and only the new input:","","```bash","# desc: 用历史会话 ID 继续下一轮","lodestar-agent run --session '<session-id>' --description '继续下一步任务' --stdin <<'EOF'","<new input for the next turn>","EOF","```","","This resumes the provider-native conversation and inherits its identity and","last effort. An optional `--identity` must match the original worker;","`--effort` explicitly changes the effort for this turn. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","The session must belong to this Lodestar Session and workspace, with its","delegated run history still available. Saved history supports continuation","after a daemon restart. Unknown sessions, unavailable identities and native","resume failures are errors. Wait for the current run to finish before resuming;","concurrent turns on the same native session are rejected.","","Use `--json` with `run`, `follow-up` or `status` for structured results:","`workers[].session_id` is the conversation id and `workers[].output` is the","returned content. `--prompt <text>` supplies inline input instead of stdin.","A parallel run returns one session id per worker; continue each separately.","","For example, after turn 1 implements the requested change using the run form","above, continue the same work with feedback and then verification:","","```bash","# desc: 第二轮根据上一轮结果和反馈继续修改","lodestar-agent run --session '<session-id>' --description '根据反馈修改' --prompt 'Revise the previous implementation using this feedback: <specific feedback>.' --json","```","","Read turn 2's result before choosing turn 3's input, using the same session id:","","```bash","# desc: 第三轮验证同一项工作的最终结果","lodestar-agent run --session '<session-id>' --description '验证最终结果' --prompt 'Verify the revised implementation against the original requirements and report the results and any remaining issues.' --json","```","","These turns retain the earlier conversation; send only the new requirements,","feedback or next step. Omitting `--session` starts a fresh conversation.","An empty, unknown or out-of-scope session id is rejected before execution;","native resume failures are reported and never converted into a fresh session.","","If you kept the `run_id`, the existing follow-up form also resumes its worker:","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --description '完成指定任务' --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(`
531
- `)}function kW(){PW("lodestar-consult"),m6({name:bW,body:wF()})}var bW="lodestar-agent",CW;var LJ=T(()=>{BJ();CW=["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(`
532
- `)});function yW($){let Z=X0($.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}=E4({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,CW].filter(Boolean).join(`
530
+ `}function NW(){p6({name:RW,body:fF(v.notify.port)})}var RW="feishu-notify";var TW=N(()=>{C0();jJ()});import{randomUUID as hF}from"node:crypto";function EW($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,H,X)=>{if(!V)return"通知已过期或已移除";if(!X)return"无法识别回复人,操作未执行";if(H&&H!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(v2(V.notifyId))return"通知正在处理中";return null},Y=async(V,H)=>{if($.log(`notify-reply: ${H}`),!await $.sendText(V,`❌ ${H}`))throw Error(`通知回复错误提示发送失败: ${H}`)},Q=async(V,H,X,z)=>{try{await $.updateCard(H,X)}catch(W){await Y(V.chatId,`${z},卡片更新失败:${Z(W)}`)}};return{async recover(V){let H=V.replyState;if(!H||!V.unknownAt)return;let X={kind:"text",status:"unknown",text:H.response?.text??"",operatorOpenId:H.openId,detail:V.unknownReason};await Q(V,H.promptMessageId,W1(V,H,X),"回复送达状态未知"),await Q(V,V.messageId,n1(V,X),"回复送达状态未知")},async open(V,H,X){let z=v$(V),W=J(z,H,X);if(W||!z)return{ok:!1,message:W};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=jZ(z.chatId);if(G.some((B)=>B.replyState?.status==="sending"||v2(B.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};W9(V);try{for(let j of G){let q={...j.replyState,status:"cancelled",cancelReason:"switched"};h2(j.notifyId,q),await Q(j,q.promptMessageId,W1(j,q),"已放弃上一条回复并切换通知")}let B={id:hF(),openId:X,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,W1(z,B));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};B.promptMessageId=_;try{h2(V,B)}catch(j){let q=`等待输入状态保存失败,未开始接收回复:${Z(j)}`;return await Q(z,_,W1(z,B,{status:"failed",detail:q}),q),{ok:!1,message:q,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{G9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,H,X,z){let W=v$(V),G=J(W,X,z);if(G||!W)return{ok:!1,message:G};let B=W.replyState;if(!B||B.id!==H||B.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(B.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...B,status:"cancelled"};return h2(V,_),$.onWaitingChanged(W.chatId),await Q(W,B.promptMessageId,W1(W,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:H,openId:X,messageId:z,text:W,createTime:G}=V;if(!X||!z||!W.trim())return!1;if(zX(H,z))return!0;let B=K9(H,X);if(!B?.replyState)return!1;let _=B.replyState;if(G>0&&G<_.openedAt)return!1;if(_.status!=="waiting"||v2(B.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:W,message_id:z,prompt_message_id:_.promptMessageId},q={..._,status:"sending",response:j};W9(B.notifyId);try{try{h2(B.notifyId,q)}catch(M){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(M)}`),!0}let P;try{if(await $.updateCard(_.promptMessageId,W1(B,q)),B.callbackUrl)P=await $.dispatch(B,j,X);else B9(B.notifyId,void 0,X),P={ok:!0,detail:"已记录"}}catch(M){P={ok:!1,detail:Z(M)}}let D;if(P.ok){let M=B.callbackUrl?_6(B.notifyId,void 0,X):{state:"complete"};D={kind:"text",text:W,operatorOpenId:X,status:M.state==="unknown"?"unknown":B.callbackUrl?"delivered":"done",...M.state==="unknown"?{detail:M.detail}:{reply:P.reply}}}else{D={kind:"text",text:W,operatorOpenId:X,status:"failed",detail:P.detail};try{h2(B.notifyId,{...q,status:"failed",error:P.detail})}catch(M){let A=`${P.detail};失败状态保存失败:${Z(M)}`;try{LZ(B.notifyId,void 0,X,A)}catch(U){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(U)}`)}D={...D,status:"unknown",detail:A}}}let T=D.status==="delivered"?"回复已送达":D.status==="done"?"回复已记录":D.status==="unknown"?`回复送达状态未知:${D.detail}`:`回复未送达:${D.detail}`;return await Q(B,_.promptMessageId,W1(B,q,D),T),await Q(B,B.messageId,n1(B,D),T),$.log(`notify-reply: notify_id=${B.notifyId} status=${D.status}`),!0}finally{G9(B.notifyId),$.onWaitingChanged(B.chatId)}}}}var xW=N(()=>{_9();g6()});class LJ{deps;tails=new Map;byRun=new Map;constructor($){this.deps=$}add($){return D$($.chatId,async()=>{let Z=this.tails.get($.chatId);if(Z){if(await this.deps.getChatTailMessageId($.chatId)===Z.messageId&&this.deps.getElementCount(Z.cardId)<IF){let Y=await this.deps.addElementResult(Z.cardId,V9($));if(Y.landed){this.attach(Z,$),await this.settings(Z);return}if(!SW(Y))throw bW("agent card append",Y)}await this.seal(Z)}await this.create($)})}update($,Z=!1){return D$($.chatId,async()=>{let J=this.byRun.get($.runId);if(!J)return;if(J.settled.has($.runId)){if(Z)await this.settings(J);return}let Y=[],Q=await this.deps.replaceElementResult(J.cardId,H9($.runId),V9($));if(!Q.landed){if(!SW(Q)||J.runs.size===1)throw bW("agent task row update",Q);let V=J;await this.seal(V);let H=this.tails.get($.chatId);if(H)await this.seal(H);J=await this.create($),V.runs.delete($.runId),V.settled.delete($.runId);try{if(!await this.deps.deleteElementChecked(V.cardId,H9($.runId)))throw Error("agent moved task row deletion MISS; the previous card may still show its earlier state")}catch(X){Y.push(String(X))}try{await this.settings(V)}catch(X){Y.push(String(X))}}if(Z)J.settled.add($.runId);try{await this.settings(J)}catch(V){Y.push(String(V))}if(Y.length)throw Error(Y.join("; "))})}closeChat($){return D$($,async()=>{let Z=this.tails.get($);if(Z)await this.seal(Z)})}attach($,Z){$.runs.set(Z.runId,Z),this.byRun.set(Z.runId,$),Z.cardMessageId=$.messageId}async create($){let Z=await this.deps.sendCard($.chatId,t5($));if(!Z)throw Error("agent card creation failed");let J=await this.deps.convertMessageToCard(Z);this.deps.recordCardCreated(J,1);let Y={cardId:J,messageId:Z,chatId:$.chatId,runs:new Map,settled:new Set,sealed:!1};return this.attach(Y,$),this.tails.set($.chatId,Y),Y}async seal($){if($.sealed=!0,this.tails.get($.chatId)===$)this.tails.delete($.chatId);await this.settings($)}async settings($){this.deps.cancelSummary($.cardId);let Z=$.settled.size===$.runs.size,J={config:{streaming_mode:!Z,summary:{content:e5([...$.runs.values()])}}},Y=JSON.stringify(J);if(Y!==$.settingsJson){if(!await this.deps.patchSettingsChecked($.cardId,J))throw Error("agent card settings update MISS");$.settingsJson=Y}if(Z&&$.sealed){await this.deps.dispose($.cardId);for(let Q of $.runs.keys())if(this.byRun.get(Q)===$)this.byRun.delete(Q)}}}function SW($){return u4($.failure?.code,$.failure)}function bW($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"})`:""}`)}var IF=50;var CW=N(()=>{J$();k$();b7()});function kW($){let Z=qJ($,"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((z)=>z.trim()).filter(Boolean))],Q=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=o2(Q);if(Q!==void 0&&!V)throw Error("agent session_id must be a non-empty string");if(Z.session_id!==void 0&&Z.sessionId!==void 0&&Z.session_id!==Z.sessionId)throw Error("conflicting agent session_id and sessionId");if(V&&Y.length>1)throw Error("agent session continuation accepts at most one identity_id");if(!V&&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 H=vW(Z.prompt,'agent run requires "prompt"'),X=o2(Z.effort);return{identityIds:Y,description:r2(Z.description),prompt:H,...X?{effort:X}:{},...V?{sessionId:V}:{}}}function yW($){let Z=qJ($,"agent follow-up request"),J=vW(Z.prompt,'agent follow-up requires "prompt"'),Y=o2(Z.identity_id??Z.identityId),Q=o2(Z.effort);return{description:r2(Z.description),prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function r2($){if(typeof $!=="string"||!$.trim())throw Error('agent run requires "description" (CLI: --description)');let Z=$.trim();if(/[\r\n\u2028\u2029]/.test(Z))throw Error("agent description must be a single line");if([...Z].length>60)throw Error("agent description exceeds 60 characters");return Z}function wW($){let Z=qJ($,"agent answer request"),J=o2(Z.identity_id??Z.identityId),Y=o2(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[V,H]of Object.entries(Z.answers)){if(!V.trim())throw Error("agent answer contains an empty question key");Q[V]=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 qJ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function vW($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function o2($){return(typeof $==="string"?$.trim():"")||void 0}function gF(){return["---",`name: ${fW}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar and continue the same work across multiple turns. 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."," Every run and follow-up also requires `--description`: a short, user-facing"," single-line task summary (at most 60 characters). The card shows this line"," with status; the full prompt, progress and results stay collapsed.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon schedules them within concurrency limits."," OpenRouter allows at most 2 delegated tasks at once across projects and models"," in the same daemon; additional tasks queue. This is a local limit, not an API quota."," Wait for queued tasks instead of submitting duplicates. If rate-limited, report"," the error and do not immediately retry the whole batch.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","6. When the same work needs another step, review the returned content and"," continue with `run --session <session-id>` plus the new input. Use as many"," turns as the authorized task needs; assess completion against the overall"," task and its verification requirements, not just one run ending.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Complete one work item across multiple turns","","A single work item can span multiple turns in the same native Agent session.","Use this for staged implementation, revisions based on feedback, or further","verification of previous results. The main Agent reads each result and sends","the next step; the delegated Agent still must not delegate further.","","Keep the returned `Session:` id (JSON: `workers[].session_id`) together with","the worker output. For turn 2 and later, send that id and only the new input:","","```bash","# desc: 用历史会话 ID 继续下一轮","lodestar-agent run --session '<session-id>' --description '继续下一步任务' --stdin <<'EOF'","<new input for the next turn>","EOF","```","","This resumes the provider-native conversation and inherits its identity and","last effort. An optional `--identity` must match the original worker;","`--effort` explicitly changes the effort for this turn. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","The session must belong to this Lodestar Session and workspace, with its","delegated run history still available. Saved history supports continuation","after a daemon restart. Unknown sessions, unavailable identities and native","resume failures are errors. Wait for the current run to finish before resuming;","concurrent turns on the same native session are rejected.","","Use `--json` with `run`, `follow-up` or `status` for structured results:","`workers[].session_id` is the conversation id and `workers[].output` is the","returned content. `--prompt <text>` supplies inline input instead of stdin.","A parallel run returns one session id per worker; continue each separately.","","For example, after turn 1 implements the requested change using the run form","above, continue the same work with feedback and then verification:","","```bash","# desc: 第二轮根据上一轮结果和反馈继续修改","lodestar-agent run --session '<session-id>' --description '根据反馈修改' --prompt 'Revise the previous implementation using this feedback: <specific feedback>.' --json","```","","Read turn 2's result before choosing turn 3's input, using the same session id:","","```bash","# desc: 第三轮验证同一项工作的最终结果","lodestar-agent run --session '<session-id>' --description '验证最终结果' --prompt 'Verify the revised implementation against the original requirements and report the results and any remaining issues.' --json","```","","These turns retain the earlier conversation; send only the new requirements,","feedback or next step. Omitting `--session` starts a fresh conversation.","An empty, unknown or out-of-scope session id is rejected before execution;","native resume failures are reported and never converted into a fresh session.","","If you kept the `run_id`, the existing follow-up form also resumes its worker:","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --description '完成指定任务' --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(`
531
+ `)}function IW(){OW("lodestar-consult"),p6({name:fW,body:gF()})}var fW="lodestar-agent",hW;var PJ=N(()=>{jJ();hW=["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(`
532
+ `)});function gW($){let Z=H0($.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}=T4({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,hW].filter(Boolean).join(`
533
533
 
534
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return vF(Y,$.prompt,$.callbacks)}function vF($,Z,J={},Y=BY){let Q=[],V=null,H=!1,X=null,z=null,W=[],G,B,_=Date.now(),j=new Promise((F,b)=>{G=F,B=b}),q=(F)=>{if(!F)return null;try{return Y($.provider,F),J.onSession?.(F),null}catch(b){return b instanceof Error?b:Error(String(b))}},P=()=>{if($.off("assistant_text",N),$.off("tool_use",A),$.off("tool_result",M),$.off("subagent_step",S),$.off("can_use_tool",C),$.off("hook_callback",p),$.off("init",y),!$.isAlive())$.off("error",h);$.off("turn_retry",f),$.off("codex_account_changed",x),$.off("result",m),$.off("exit",l)},D=(F,b)=>{if(X)return X;return H=!0,W.length=0,X=Promise.resolve().then(async()=>{let d=q($.sessionId);try{await $.kill(3000)}catch(B1){z=B1 instanceof Error?B1:Error(String(B1))}P();let o=[F,d,z].filter((B1)=>!!B1),K0=o.length>1?AggregateError(o,o.map((B1)=>B1.message).join("; ")):o[0];if(K0){B(new F9(K0,Q.join("").trim(),$.sessionId));return}let J4=$.sessionId;if(!J4){B(new F9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let A9=Q.join("").trim(),t1=IF(b?.checkpoint,$);G({output:A9,outputTruncated:!1,sessionId:J4,...t1?{checkpointId:t1}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),X},N=(F)=>{if(H||F?.parentToolUseId||typeof F?.text!=="string")return;Q.push(F.text)},U=(F)=>{if(H)return;try{J.onProgress?.(F)}catch(b){D(b instanceof Error?b:Error(String(b)))}},A=(F)=>U({at:new Date().toISOString(),phase:"started",tool:String(F?.name??"tool"),detail:""}),M=(F)=>U({at:new Date().toISOString(),phase:"completed",tool:F?.is_error?"tool error":"tool result",detail:""}),S=(F)=>U({at:new Date().toISOString(),phase:F?.phase??"info",tool:String(F?.tool??"subagent"),detail:""}),C=(F)=>{if(H)return;if(F.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(F.request_id,"allow",{updatedInput:F.input??{}})}catch(d){D(d instanceof Error?d:Error(String(d)))}return}let b;try{b=fF(F)}catch(d){D(d instanceof Error?d:Error(String(d)));return}if(W.some((d)=>d.request.requestId===b.requestId))return;W.push({request:b,originalInput:F.input??{}});try{if(W.length===1)J.onNeedsInput?.(b)}catch(d){D(d instanceof Error?d:Error(String(d)))}},p=(F)=>{if(H)return;try{$.sendHookResponse(String(F.request_id),{})}catch(b){D(b instanceof Error?b:Error(String(b)))}},y=(F)=>{let b=q(F?.session_id??$.sessionId);if(b)D(b)},h=(F)=>{V=F instanceof Error?F:Error(String(F))},x=(F)=>{if(H)return;try{J.onCodexAccount?.(F.accountId)}catch(b){D(b instanceof Error?b:Error(String(b)))}if(F.diagnostics.length)U({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:F.diagnostics.join(";")})},f=(F)=>{U({at:new Date().toISOString(),phase:"info",tool:F.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:F.phase==="waiting"?`${F.message} · ${F.delayMs/1000}s 后重试 #${F.attempt}`:`正在重试 #${F.attempt}`})},m=(F)=>{let b=F?.is_error?Error(String(F.error??F.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(b,F)},l=(F)=>{if(H)return;let b=`code=${F?.code??"null"} signal=${F?.signal??"null"}`;D(V??Error(`delegated agent exited before result (${b})`))};$.on("assistant_text",N),$.on("tool_use",A),$.on("tool_result",M),$.on("subagent_step",S),$.on("can_use_tool",C),$.on("hook_callback",p),$.on("init",y),$.on("error",h),$.on("turn_retry",f),$.on("codex_account_changed",x),$.on("result",m),$.on("exit",l);try{$.sendInitialize(),$.sendUserText(Z)}catch(F){D(F instanceof Error?F:Error(String(F)))}return{done:j,isAlive:()=>$.isAlive(),pendingInput:()=>W[0]?.request??null,answer(F,b){let d=W[0];if(!d)throw Error("delegated agent is not waiting for input");if(d.request.requestId!==F)throw Error(`delegated agent input request mismatch: expected ${d.request.requestId}`);if($.sendPermissionResponse(F,"allow",{updatedInput:{...d.originalInput,answers:b}}),W.shift(),W[0])J.onNeedsInput?.(W[0].request)},async cancel(F="delegated agent cancelled"){let b=H;if(await D(Error(F)),await j.catch(()=>{}),b){if($.isAlive())await $.kill(3000);z=null,P()}if(z)throw z}}}function fF($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,V)=>hF(Q,V));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 hF($,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),V=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let X=H&&typeof H==="object"?H:{};return{label:String(X.label??X.value??""),...X.description?{description:String(X.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:V}}function IF($,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 F9;var wW=T(()=>{A7();X4();Q0();LJ();F9=class F9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as gF,randomBytes as mF,randomUUID as pF}from"node:crypto";import{existsSync as cF,readdirSync as uF,readFileSync as lW}from"node:fs";import{join as p6}from"node:path";class DJ{deps;presentation;runs=new Map;capabilities=new Map;activeTurns=0;activeTurnsBySource=new Map;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;startingNativeSessions=new Set;constructor($=lF){this.deps=$;this.presentation=new _J($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(fW);if(s2(Z.description),Z.sessionId!==void 0){if(!Z.sessionId.trim())throw Error("agent session_id must be a non-empty string");if(Z.identityIds.length>1)throw Error("agent session continuation accepts at most one identity_id");let{run:Y,worker:Q}=this.requireSessionRun($,Z.sessionId,Z.identityIds[0]);return this.followUp($,Y.snapshot.runId,{identityId:Q.identityId,description:Z.description,prompt:Z.prompt,effort:Z.effort})}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(fW);s2(J.description);let Y=this.requireMutableDescendant($,Z);if(!t2(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=pW(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 V=J.effort??Q.effort,H=this.reserveCapacity($,1),X;try{return X=this.reserveNativeSession(Q),await this.createRun($.session,{identityIds:[Q.identityId],description:J.description,prompt:J.prompt,effort:V},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Q})}finally{X?.(),H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=pW(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 V=Y.handles.get(Q.identityId);if(!V)throw Error("waiting agent process is no longer alive; start a follow-up run");V.answer(J.requestId,J.answers);let H=V.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),U9(Y.snapshot)}getRun($,Z){return U9(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((V)=>V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Q=await Promise.allSettled(Y.map((V)=>this.cancelTree(V,J)));PJ(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[X,z]=H.split("\x00");this.bumpCancellationEpoch(X,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()]),V=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));PJ([...Y,...V]);for(let H of new Set([...this.runs.values()].map((X)=>X.snapshot.chatId)))await this.presentation.closeChat(H)}async createRun($,Z,J){this.pruneRuns(J.parentRunId);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(),V=this.deps.getCatalog(Q),H=Z.identityIds.map((_)=>{let j=V.identities.find((P)=>P.id===_);if(!j)throw Error(`agent identity not found: ${_}`);if(j.status!=="ready")throw Error(`${j.displayName}: ${j.reason??j.status}`);let q=J.resumeWorker;if(q&&(j.id!==q.identityId||j.provider!==q.provider||j.tokenSourceId!==q.tokenSourceId||j.model!==q.model))throw Error("agent session identity changed; cannot resume with a different provider, source or model");return j}),X=H.map((_)=>dF(_,iF(_,Z.effort),J.resumeWorker?.sessionId)),z=`agent_${pF()}`,W={runId:z,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,description:s2(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:X,createdAt:new Date().toISOString()},G={snapshot:W,session:$,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};try{await this.presentation.add(W)}catch(_){if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);let j=`Agent 卡片初始化失败,Agent 未启动: ${v0(_)}`;for(let q of X)q.status="failed",q.error=j;throw await this.finalizeRun(G,"failed",j),await this.deps.sendTextRaw($.chatId,`❌ ${j}`),_}if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){G.cancelled=!0;let _="任务已在启动前取消";for(let j of G.snapshot.workers)j.status="cancelled",j.error=_,j.finishedAt=new Date().toISOString();return this.persist(G),await Promise.all(G.snapshot.workers.map((j)=>this.updateWorkerCard(G,j))),await this.finalizeRun(G,"cancelled",_),U9(G.snapshot)}this.persist(G);for(let _ of H){let j=J.resumeWorker?.sessionId;this.executeWorker(G,_,Z.prompt,j).catch((q)=>{K(`agent: run=${z} worker=${_.id} crashed: ${v0(q)}`)})}return U9(W)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(Z,(H)=>{Q.queuedReason=H,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=mF(32).toString("base64url"),this.capabilities.set(V,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,V),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:oF(N2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},hostEnv:{LODESTAR_AGENT_URL:D3(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:V,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 X=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=X.output,Q.outputTruncated=X.outputTruncated,Q.sessionId=X.sessionId,Q.checkpointId=X.checkpointId,Q.durationMs=X.durationMs,Q.usage=X.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof F9){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=v0(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(V)this.capabilities.delete(V);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||M9(Z.status))return;if(Z.steps.push(J),Z.steps.length>IW)Z.steps.splice(0,Z.steps.length-IW);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: ${v0(Y)}`,K(`agent: terminal finalization failed run=${$.snapshot.runId}: ${v0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${v0(Y)}`).catch((Q)=>K(`agent: terminal failure delivery failed: ${v0(Q)}`))})}async cancelTree($,Z){let J=!t2($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let V of[...$.progressTimers.keys()])this.clearProgressTimer($,V);for(let V of $.capabilityByIdentity.values())this.capabilities.delete(V);$.capabilityByIdentity.clear()}while(!0){let V=[...$.children].map((X)=>this.runs.get(X)).filter((X)=>!!X&&this.treeHasActiveRun(X));if(V.length===0)break;let H=await Promise.allSettled(V.map((X)=>this.cancelTree(X,Z)));if(Y.push(...H),H.some((X)=>X.status==="rejected"))break}if(!J){PJ(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([V,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${V}: Agent process is still alive after cancellation`);$.handles.delete(V),this.releaseWorkerSlot($,V)}))),Y.some((V)=>V.status==="rejected")){let V=dW(Y);throw $.snapshot.status="failed",$.snapshot.error=V.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${V.message}`).catch((H)=>K(`agent: cancellation failure notice failed: ${v0(H)}`)),V}let Q=[];for(let V of $.snapshot.workers)if(!M9(V.status))V.status="cancelled",V.error=Z,V.finishedAt=new Date().toISOString(),delete V.pendingInput,Q.push(V);await Promise.all(Q.map((V)=>this.updateWorkerCard($,V))),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{await this.presentation.update($.snapshot,!0)}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${v0(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)=>K(`agent: warning delivery failed run=${$.snapshot.runId}: ${v0(Y)}`))}async updateWorkerCard($,Z){if($.finalized)return;let J=$.snapshot.cardMessageId;try{await this.presentation.update($.snapshot)}catch(Y){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${v0(Y)}`)}finally{if($.snapshot.cardMessageId!==J)this.persist($)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,K(`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=gF("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=U9($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(p6(_1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;iW(Z),this.deps.writeTextArtifact(p6(_1,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}requireSessionRun($,Z,J){let Y=[...this.runs.values()].flatMap((H)=>{if(!this.canAccess($,H)||H.snapshot.workDir!==$.session.workDir)return[];return H.snapshot.workers.filter((X)=>X.sessionId===Z&&(!J||X.identityId===J)).map((X)=>({run:H,worker:X}))});if(!Y.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Y.map(({worker:H})=>H.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Q=new Set(Y.map(({run:H})=>H.snapshot.parentRunId)),V=Y.filter(({run:H})=>!Q.has(H.snapshot.runId)).sort((H,X)=>Date.parse(X.run.snapshot.createdAt)-Date.parse(H.run.snapshot.createdAt))[0];if(!V)throw Error(`agent session history has no latest run: ${Z}`);return V}reserveNativeSession($){let Z=JSON.stringify([$.provider,$.sessionId]),J=[...this.runs.values()].some((Y)=>Y.snapshot.workers.some((Q)=>{if(Q.provider!==$.provider||Q.sessionId!==$.sessionId)return!1;let V=Y.handles.get(Q.identityId);return!M9(Q.status)||!!V&&V.isAlive?.()!==!1}));if(this.startingNativeSessions.has(Z)||J)throw Error("agent session is already running or starting; wait for the current turn to finish");return this.startingNativeSessions.add(Z),()=>{this.startingNativeSessions.delete(Z)}}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(!t2($.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((X)=>this.sessionKey(X.snapshot.sessionName,X.snapshot.chatId)===J&&(!t2(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=gW)throw Error(`Session has reached ${gW} active Agent runs`);if([...this.runs.values()].reduce((X,z)=>X+z.snapshot.workers.filter((W)=>!M9(W.status)||z.handles.get(W.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>mW)throw Error(`global Agent worker limit ${mW} 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),uW(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)}tryAcquireSlot($){let Z=vW.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=qJ||Z!==void 0&&J>=Z)return!1;return this.activeTurns++,this.activeTurnsBySource.set($,J+1),!0}acquireSlot($,Z){if(this.tryAcquireSlot($.tokenSourceId))return Promise.resolve();let J=vW.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${qJ} 个 Agent)`),new Promise((Y)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Y}))}releaseSlot($){this.activeTurns--,uW(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<qJ;){let J=this.slotWaiters[Z];if(!this.tryAcquireSlot(J.tokenSourceId)){Z++;continue}this.slotWaiters.splice(Z,1),J.resolve()}}releaseWorkerSlot($,Z){let J=$.slotOwners.get(Z);if(J===void 0)return;$.slotOwners.delete(Z),this.releaseSlot(J)}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!t2($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!M9(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,handles:new Map,slotOwners:new Map,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<=hW)return;let Z=[...this.runs.values()].filter((J)=>J.snapshot.runId!==$&&t2(J.snapshot.status)&&J.handles.size===0&&J.slotOwners.size===0&&J.children.size===0).sort((J,Y)=>Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt)-Date.parse(Y.snapshot.finishedAt??Y.snapshot.createdAt));for(let J of Z){if(this.runs.size<=hW)break;if(this.runs.delete(J.snapshot.runId),J.snapshot.parentRunId)this.runs.get(J.snapshot.parentRunId)?.children.delete(J.snapshot.runId)}}}function dF($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function iF($,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 pW($,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 t2($){return $==="completed"||$==="failed"||$==="cancelled"}function M9($){return $==="completed"||$==="failed"||$==="cancelled"}function U9($){return JSON.parse(JSON.stringify($))}function nF(){if(!cF(_1))return[];let $=[];for(let Z of uF(_1).filter((J)=>J.endsWith(".json")).sort()){let J=p6(_1,Z),Y;try{Y=JSON.parse(lW(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${v0(Q)}`)}if(!aF(Y))throw Error(`agent run artifact is invalid: ${J}`);rF(Y,J),$.push(Y)}return $}function aF($){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"&&(Z.description===void 0||typeof Z.description==="string")&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function dW($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(v0).join("; ")}`)}function PJ($){if($.some((Z)=>Z.status==="rejected"))throw dW($)}function v0($){return $ instanceof Error?$.message:String($)}function oF($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function rF($,Z){if($.promptArtifact)$.prompt=cW($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=cW(J.outputArtifact,`output for ${Z}`)}function cW($,Z){iW($);try{return lW(p6(_1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${v0(J)}`)}}function iW($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function uW($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var qJ=8,vW,fW="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",hW=512,IW=50,gW=64,mW=128,lF;var nW=T(()=>{y$();TW();J0();C0();T6();wW();H0();f0();I();vW=new Map([["openrouter",2]]),lF={getCatalog:d1,startWorker:yW,sendCard:u,getChatTailMessageId:Y5,sendTextRaw:w,convertMessageToCard:$$,recordCardCreated:u0,getElementCount:l4,addElementResult:S2,replaceElementResult:qV,deleteElementChecked:PV,cancelSummary:A0,patchSettingsChecked:P0,dispose:w0,writeArtifact:s,writeTextArtifact:Q$,loadArtifacts:nF}});async function rW($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(G,B)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(B)),!0},V=eF($.headers.authorization);if(!V)return Q(401,{error:"missing bearer capability"});let H=sF(Y,V);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await F2(),Q(200,$M(d1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,NW(await FJ($)));return Q(202,c6(G))}catch(G){return Q(409,{error:oW(G)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let z=tF(X[1]);if(!z)return Q(400,{error:"invalid agent run id encoding"});let W=X[2];try{if(!W&&$.method==="GET")return Q(200,c6(Y.service.getRun(H,z)));if(!W&&$.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(W==="follow-up"&&$.method==="POST"){let G=await Y.service.followUp(H,z,EW(await FJ($)));return Q(202,c6(G))}if(W==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,z,xW(await FJ($)));return Q(200,c6(G))}}catch(G){return Q(409,{error:oW(G)})}return Q(405,{error:"unsupported agent endpoint"})}function sF($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function tF($){try{return decodeURIComponent($)}catch{return null}}function eF($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function FJ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>aW)throw Error(`request body exceeds ${aW} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function $M($){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 c6($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,description:$.description,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 oW($){return $ instanceof Error?$.message:String($)}var aW=4194304;var sW=T(()=>{T6();Q0()});import{chmodSync as ZM,existsSync as MJ,readFileSync as $G,realpathSync as JM,unlinkSync as YM}from"node:fs";import{homedir as QM}from"node:os";import{basename as VM,dirname as HM,join as G1,resolve as XM}from"node:path";function zM($={}){let Z=JM(XM($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??MJ,Q=HM(Z),V=G1(Q,"src","agent-cli.ts"),H=G1(Q,"lodestar-agent.js"),X=G1(Q,"dist","lodestar-agent.js"),W=/^bun(?:\.exe)?$/i.test(VM(J))?[V,H,X]:[H,X],G=W.find(Y);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${W.join(", ")}`);return{runtime:J,entry:G}}function ZG($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??GM(Z,$.homeDir??QM(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??zM(),V=G1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${eW(Q.runtime)}" "${eW(Q.entry)}" %*\r
534
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return mF(Y,$.prompt,$.callbacks)}function mF($,Z,J={},Y=jY){let Q=[],V=null,H=!1,X=null,z=null,W=[],G,B,_=Date.now(),j=new Promise((F,b)=>{G=F,B=b}),q=(F)=>{if(!F)return null;try{return Y($.provider,F),J.onSession?.(F),null}catch(b){return b instanceof Error?b:Error(String(b))}},P=()=>{if($.off("assistant_text",T),$.off("tool_use",A),$.off("tool_result",U),$.off("subagent_step",S),$.off("can_use_tool",C),$.off("hook_callback",p),$.off("init",y),!$.isAlive())$.off("error",I);$.off("turn_retry",f),$.off("codex_account_changed",E),$.off("result",m),$.off("exit",l)},D=(F,b)=>{if(X)return X;return H=!0,W.length=0,X=Promise.resolve().then(async()=>{let d=q($.sessionId);try{await $.kill(3000)}catch(B1){z=B1 instanceof Error?B1:Error(String(B1))}P();let o=[F,d,z].filter((B1)=>!!B1),K0=o.length>1?AggregateError(o,o.map((B1)=>B1.message).join("; ")):o[0];if(K0){B(new F9(K0,Q.join("").trim(),$.sessionId));return}let Z4=$.sessionId;if(!Z4){B(new F9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let A9=Q.join("").trim(),r1=uF(b?.checkpoint,$);G({output:A9,outputTruncated:!1,sessionId:Z4,...r1?{checkpointId:r1}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),X},T=(F)=>{if(H||F?.parentToolUseId||typeof F?.text!=="string")return;Q.push(F.text)},M=(F)=>{if(H)return;try{J.onProgress?.(F)}catch(b){D(b instanceof Error?b:Error(String(b)))}},A=(F)=>M({at:new Date().toISOString(),phase:"started",tool:String(F?.name??"tool"),detail:""}),U=(F)=>M({at:new Date().toISOString(),phase:"completed",tool:F?.is_error?"tool error":"tool result",detail:""}),S=(F)=>M({at:new Date().toISOString(),phase:F?.phase??"info",tool:String(F?.tool??"subagent"),detail:""}),C=(F)=>{if(H)return;if(F.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(F.request_id,"allow",{updatedInput:F.input??{}})}catch(d){D(d instanceof Error?d:Error(String(d)))}return}let b;try{b=pF(F)}catch(d){D(d instanceof Error?d:Error(String(d)));return}if(W.some((d)=>d.request.requestId===b.requestId))return;W.push({request:b,originalInput:F.input??{}});try{if(W.length===1)J.onNeedsInput?.(b)}catch(d){D(d instanceof Error?d:Error(String(d)))}},p=(F)=>{if(H)return;try{$.sendHookResponse(String(F.request_id),{})}catch(b){D(b instanceof Error?b:Error(String(b)))}},y=(F)=>{let b=q(F?.session_id??$.sessionId);if(b)D(b)},I=(F)=>{V=F instanceof Error?F:Error(String(F))},E=(F)=>{if(H)return;try{J.onCodexAccount?.(F.accountId)}catch(b){D(b instanceof Error?b:Error(String(b)))}if(F.diagnostics.length)M({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:F.diagnostics.join(";")})},f=(F)=>{M({at:new Date().toISOString(),phase:"info",tool:F.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:F.phase==="waiting"?`${F.message} · ${F.delayMs/1000}s 后重试 #${F.attempt}`:`正在重试 #${F.attempt}`})},m=(F)=>{let b=F?.is_error?Error(String(F.error??F.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(b,F)},l=(F)=>{if(H)return;let b=`code=${F?.code??"null"} signal=${F?.signal??"null"}`;D(V??Error(`delegated agent exited before result (${b})`))};$.on("assistant_text",T),$.on("tool_use",A),$.on("tool_result",U),$.on("subagent_step",S),$.on("can_use_tool",C),$.on("hook_callback",p),$.on("init",y),$.on("error",I),$.on("turn_retry",f),$.on("codex_account_changed",E),$.on("result",m),$.on("exit",l);try{$.sendInitialize(),$.sendUserText(Z)}catch(F){D(F instanceof Error?F:Error(String(F)))}return{done:j,isAlive:()=>$.isAlive(),pendingInput:()=>W[0]?.request??null,answer(F,b){let d=W[0];if(!d)throw Error("delegated agent is not waiting for input");if(d.request.requestId!==F)throw Error(`delegated agent input request mismatch: expected ${d.request.requestId}`);if($.sendPermissionResponse(F,"allow",{updatedInput:{...d.originalInput,answers:b}}),W.shift(),W[0])J.onNeedsInput?.(W[0].request)},async cancel(F="delegated agent cancelled"){let b=H;if(await D(Error(F)),await j.catch(()=>{}),b){if($.isAlive())await $.kill(3000);z=null,P()}if(z)throw z}}}function pF($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,V)=>cF(Q,V));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 cF($,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),V=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let X=H&&typeof H==="object"?H:{};return{label:String(X.label??X.value??""),...X.description?{description:String(X.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:V}}function uF($,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 F9;var mW=N(()=>{O7();H4();Y0();PJ();F9=class F9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as lF,randomBytes as dF,randomUUID as iF}from"node:crypto";import{existsSync as nF,readdirSync as aF,readFileSync as rW}from"node:fs";import{join as c6}from"node:path";class UJ{deps;presentation;runs=new Map;capabilities=new Map;activeTurns=0;activeTurnsBySource=new Map;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;startingNativeSessions=new Set;constructor($=oF){this.deps=$;this.presentation=new LJ($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(cW);if(r2(Z.description),Z.sessionId!==void 0){if(!Z.sessionId.trim())throw Error("agent session_id must be a non-empty string");if(Z.identityIds.length>1)throw Error("agent session continuation accepts at most one identity_id");let{run:Y,worker:Q}=this.requireSessionRun($,Z.sessionId,Z.identityIds[0]);return this.followUp($,Y.snapshot.runId,{identityId:Q.identityId,description:Z.description,prompt:Z.prompt,effort:Z.effort})}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(cW);r2(J.description);let Y=this.requireMutableDescendant($,Z);if(!s2(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=nW(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 V=J.effort??Q.effort,H=this.reserveCapacity($,1),X;try{return X=this.reserveNativeSession(Q),await this.createRun($.session,{identityIds:[Q.identityId],description:J.description,prompt:J.prompt,effort:V},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Q})}finally{X?.(),H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=nW(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 V=Y.handles.get(Q.identityId);if(!V)throw Error("waiting agent process is no longer alive; start a follow-up run");V.answer(J.requestId,J.answers);let H=V.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),M9(Y.snapshot)}getRun($,Z){return M9(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((V)=>V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Q=await Promise.allSettled(Y.map((V)=>this.cancelTree(V,J)));FJ(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[X,z]=H.split("\x00");this.bumpCancellationEpoch(X,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()]),V=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));FJ([...Y,...V]);for(let H of new Set([...this.runs.values()].map((X)=>X.snapshot.chatId)))await this.presentation.closeChat(H)}async createRun($,Z,J){this.pruneRuns(J.parentRunId);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(),V=this.deps.getCatalog(Q),H=Z.identityIds.map((_)=>{let j=V.identities.find((P)=>P.id===_);if(!j)throw Error(`agent identity not found: ${_}`);if(j.status!=="ready")throw Error(`${j.displayName}: ${j.reason??j.status}`);let q=J.resumeWorker;if(q&&(j.id!==q.identityId||j.provider!==q.provider||j.tokenSourceId!==q.tokenSourceId||j.model!==q.model))throw Error("agent session identity changed; cannot resume with a different provider, source or model");return j}),X=H.map((_)=>rF(_,sF(_,Z.effort),J.resumeWorker?.sessionId)),z=`agent_${iF()}`,W={runId:z,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,description:r2(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:X,createdAt:new Date().toISOString()},G={snapshot:W,session:$,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};try{await this.presentation.add(W)}catch(_){if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);let j=`Agent 卡片初始化失败,Agent 未启动: ${v0(_)}`;for(let q of X)q.status="failed",q.error=j;throw await this.finalizeRun(G,"failed",j),await this.deps.sendTextRaw($.chatId,`❌ ${j}`),_}if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){G.cancelled=!0;let _="任务已在启动前取消";for(let j of G.snapshot.workers)j.status="cancelled",j.error=_,j.finishedAt=new Date().toISOString();return this.persist(G),await Promise.all(G.snapshot.workers.map((j)=>this.updateWorkerCard(G,j))),await this.finalizeRun(G,"cancelled",_),M9(G.snapshot)}this.persist(G);for(let _ of H){let j=J.resumeWorker?.sessionId;this.executeWorker(G,_,Z.prompt,j).catch((q)=>{K(`agent: run=${z} worker=${_.id} crashed: ${v0(q)}`)})}return M9(W)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(Z,(H)=>{Q.queuedReason=H,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=dF(32).toString("base64url"),this.capabilities.set(V,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,V),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:$U(N2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},hostEnv:{LODESTAR_AGENT_URL:D3(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:V,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 X=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=X.output,Q.outputTruncated=X.outputTruncated,Q.sessionId=X.sessionId,Q.checkpointId=X.checkpointId,Q.durationMs=X.durationMs,Q.usage=X.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof F9){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=v0(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(V)this.capabilities.delete(V);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||U9(Z.status))return;if(Z.steps.push(J),Z.steps.length>lW)Z.steps.splice(0,Z.steps.length-lW);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: ${v0(Y)}`,K(`agent: terminal finalization failed run=${$.snapshot.runId}: ${v0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${v0(Y)}`).catch((Q)=>K(`agent: terminal failure delivery failed: ${v0(Q)}`))})}async cancelTree($,Z){let J=!s2($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let V of[...$.progressTimers.keys()])this.clearProgressTimer($,V);for(let V of $.capabilityByIdentity.values())this.capabilities.delete(V);$.capabilityByIdentity.clear()}while(!0){let V=[...$.children].map((X)=>this.runs.get(X)).filter((X)=>!!X&&this.treeHasActiveRun(X));if(V.length===0)break;let H=await Promise.allSettled(V.map((X)=>this.cancelTree(X,Z)));if(Y.push(...H),H.some((X)=>X.status==="rejected"))break}if(!J){FJ(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([V,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${V}: Agent process is still alive after cancellation`);$.handles.delete(V),this.releaseWorkerSlot($,V)}))),Y.some((V)=>V.status==="rejected")){let V=sW(Y);throw $.snapshot.status="failed",$.snapshot.error=V.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${V.message}`).catch((H)=>K(`agent: cancellation failure notice failed: ${v0(H)}`)),V}let Q=[];for(let V of $.snapshot.workers)if(!U9(V.status))V.status="cancelled",V.error=Z,V.finishedAt=new Date().toISOString(),delete V.pendingInput,Q.push(V);await Promise.all(Q.map((V)=>this.updateWorkerCard($,V))),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{await this.presentation.update($.snapshot,!0)}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${v0(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)=>K(`agent: warning delivery failed run=${$.snapshot.runId}: ${v0(Y)}`))}async updateWorkerCard($,Z){if($.finalized)return;let J=$.snapshot.cardMessageId;try{await this.presentation.update($.snapshot)}catch(Y){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${v0(Y)}`)}finally{if($.snapshot.cardMessageId!==J)this.persist($)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,K(`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=lF("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=M9($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(c6(_1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;tW(Z),this.deps.writeTextArtifact(c6(_1,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}requireSessionRun($,Z,J){let Y=[...this.runs.values()].flatMap((H)=>{if(!this.canAccess($,H)||H.snapshot.workDir!==$.session.workDir)return[];return H.snapshot.workers.filter((X)=>X.sessionId===Z&&(!J||X.identityId===J)).map((X)=>({run:H,worker:X}))});if(!Y.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Y.map(({worker:H})=>H.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Q=new Set(Y.map(({run:H})=>H.snapshot.parentRunId)),V=Y.filter(({run:H})=>!Q.has(H.snapshot.runId)).sort((H,X)=>Date.parse(X.run.snapshot.createdAt)-Date.parse(H.run.snapshot.createdAt))[0];if(!V)throw Error(`agent session history has no latest run: ${Z}`);return V}reserveNativeSession($){let Z=JSON.stringify([$.provider,$.sessionId]),J=[...this.runs.values()].some((Y)=>Y.snapshot.workers.some((Q)=>{if(Q.provider!==$.provider||Q.sessionId!==$.sessionId)return!1;let V=Y.handles.get(Q.identityId);return!U9(Q.status)||!!V&&V.isAlive?.()!==!1}));if(this.startingNativeSessions.has(Z)||J)throw Error("agent session is already running or starting; wait for the current turn to finish");return this.startingNativeSessions.add(Z),()=>{this.startingNativeSessions.delete(Z)}}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(!s2($.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((X)=>this.sessionKey(X.snapshot.sessionName,X.snapshot.chatId)===J&&(!s2(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=dW)throw Error(`Session has reached ${dW} active Agent runs`);if([...this.runs.values()].reduce((X,z)=>X+z.snapshot.workers.filter((W)=>!U9(W.status)||z.handles.get(W.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>iW)throw Error(`global Agent worker limit ${iW} 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),oW(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)}tryAcquireSlot($){let Z=pW.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=DJ||Z!==void 0&&J>=Z)return!1;return this.activeTurns++,this.activeTurnsBySource.set($,J+1),!0}acquireSlot($,Z){if(this.tryAcquireSlot($.tokenSourceId))return Promise.resolve();let J=pW.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${DJ} 个 Agent)`),new Promise((Y)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Y}))}releaseSlot($){this.activeTurns--,oW(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<DJ;){let J=this.slotWaiters[Z];if(!this.tryAcquireSlot(J.tokenSourceId)){Z++;continue}this.slotWaiters.splice(Z,1),J.resolve()}}releaseWorkerSlot($,Z){let J=$.slotOwners.get(Z);if(J===void 0)return;$.slotOwners.delete(Z),this.releaseSlot(J)}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!s2($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!U9(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,handles:new Map,slotOwners:new Map,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<=uW)return;let Z=[...this.runs.values()].filter((J)=>J.snapshot.runId!==$&&s2(J.snapshot.status)&&J.handles.size===0&&J.slotOwners.size===0&&J.children.size===0).sort((J,Y)=>Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt)-Date.parse(Y.snapshot.finishedAt??Y.snapshot.createdAt));for(let J of Z){if(this.runs.size<=uW)break;if(this.runs.delete(J.snapshot.runId),J.snapshot.parentRunId)this.runs.get(J.snapshot.parentRunId)?.children.delete(J.snapshot.runId)}}}function rF($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function sF($,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 nW($,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 s2($){return $==="completed"||$==="failed"||$==="cancelled"}function U9($){return $==="completed"||$==="failed"||$==="cancelled"}function M9($){return JSON.parse(JSON.stringify($))}function tF(){if(!nF(_1))return[];let $=[];for(let Z of aF(_1).filter((J)=>J.endsWith(".json")).sort()){let J=c6(_1,Z),Y;try{Y=JSON.parse(rW(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${v0(Q)}`)}if(!eF(Y))throw Error(`agent run artifact is invalid: ${J}`);ZU(Y,J),$.push(Y)}return $}function eF($){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"&&(Z.description===void 0||typeof Z.description==="string")&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function sW($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(v0).join("; ")}`)}function FJ($){if($.some((Z)=>Z.status==="rejected"))throw sW($)}function v0($){return $ instanceof Error?$.message:String($)}function $U($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function ZU($,Z){if($.promptArtifact)$.prompt=aW($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=aW(J.outputArtifact,`output for ${Z}`)}function aW($,Z){tW($);try{return rW(c6(_1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${v0(J)}`)}}function tW($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function oW($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var DJ=8,pW,cW="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",uW=512,lW=50,dW=64,iW=128,oF;var eW=N(()=>{k$();CW();Z0();C0();T6();mW();V0();f0();h();pW=new Map([["openrouter",2]]),oF={getCatalog:u1,startWorker:gW,sendCard:u,getChatTailMessageId:H5,sendTextRaw:w,convertMessageToCard:$$,recordCardCreated:u0,getElementCount:l4,addElementResult:x2,replaceElementResult:MV,deleteElementChecked:AV,cancelSummary:A0,patchSettingsChecked:P0,dispose:w0,writeArtifact:s,writeTextArtifact:Q$,loadArtifacts:tF}});async function JG($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(G,B)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(B)),!0},V=QU($.headers.authorization);if(!V)return Q(401,{error:"missing bearer capability"});let H=JU(Y,V);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await P2(),Q(200,VU(u1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,kW(await MJ($)));return Q(202,u6(G))}catch(G){return Q(409,{error:ZG(G)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let z=YU(X[1]);if(!z)return Q(400,{error:"invalid agent run id encoding"});let W=X[2];try{if(!W&&$.method==="GET")return Q(200,u6(Y.service.getRun(H,z)));if(!W&&$.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(W==="follow-up"&&$.method==="POST"){let G=await Y.service.followUp(H,z,yW(await MJ($)));return Q(202,u6(G))}if(W==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,z,wW(await MJ($)));return Q(200,u6(G))}}catch(G){return Q(409,{error:ZG(G)})}return Q(405,{error:"unsupported agent endpoint"})}function JU($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function YU($){try{return decodeURIComponent($)}catch{return null}}function QU($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function MJ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>$G)throw Error(`request body exceeds ${$G} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function VU($){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 u6($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,description:$.description,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 ZG($){return $ instanceof Error?$.message:String($)}var $G=4194304;var YG=N(()=>{T6();Y0()});import{chmodSync as HU,existsSync as AJ,readFileSync as HG,realpathSync as XU,unlinkSync as zU}from"node:fs";import{homedir as WU}from"node:os";import{basename as GU,dirname as KU,join as G1,resolve as BU}from"node:path";function _U($={}){let Z=XU(BU($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??AJ,Q=KU(Z),V=G1(Q,"src","agent-cli.ts"),H=G1(Q,"lodestar-agent.js"),X=G1(Q,"dist","lodestar-agent.js"),W=/^bun(?:\.exe)?$/i.test(GU(J))?[V,H,X]:[H,X],G=W.find(Y);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${W.join(", ")}`);return{runtime:J,entry:G}}function XG($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??LU(Z,$.homeDir??WU(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??_U(),V=G1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${VG(Q.runtime)}" "${VG(Q.entry)}" %*\r
535
535
  `:`#!/bin/sh
536
- exec ${tW(Q.runtime)} ${tW(Q.entry)} "$@"
537
- `,X=MJ(V)?$G(V,"utf8"):null;if(X!==H)sJ(V,H),K(`command: ${X===null?"installed":"updated"} ${V}`);else ZM(V,448);return KM(J,Y,Z),WM(Y,Z),V}function WM($,Z){let J=G1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!MJ(J))return;try{let Y=$G(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){K(`command: obsolete path preserved because ownership is unclear ${J}`);return}YM(J),K(`command: removed obsolete ${J}`)}catch(Y){K(`command: obsolete removal failed (${J}): ${Y}`)}}function GM($,Z,J){if($==="win32")return G1(J??G1(Z,"AppData","Local"),"Lodestar","bin");return G1(Z,".local","bin")}function KM($,Z,J){let Y=J==="win32"?Object.keys($).find((X)=>X.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",V=$[Y]??"",H=(X)=>J==="win32"?X.toLowerCase():X;if(V.split(Q).some((X)=>H(X)===H(Z)))return;$[Y]=V?`${Z}${Q}${V}`:Z}function tW($){return`'${$.replaceAll("'",`'"'"'`)}'`}function eW($){return $.replaceAll('"','""')}var JG=T(()=>{I();f0()});function YG($,Z,J){return $>0&&Z-$>J}async function QG($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function VG($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function UJ($){return typeof $==="string"&&$.length>0?$:void 0}function HG($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=UJ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=UJ(J.file_key);if(!Y)return null;let Q=UJ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function XG($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function zG($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class AJ{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 g$($){return $ instanceof Error?$.message:String($)}function WG($,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 GG($){let Z=(Q,V)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==V)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${V}"`);if(!H)H=$.createSession(V,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let V;try{if(_0(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(V=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!V.created)return{ok:!1,chatId:V.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(X){let z=g$(X);return $.log(`temp-session: create "${Q.chatName}" failed: ${z}`),{ok:!1,error:z}}let H=async()=>{let X=null;try{if($.registerTempSessionLease(Q.chatName,V.chatId),X=Z(V.chatId,Q.chatName),X.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(X.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${X.workDir}`);if(X.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await X.startForked(Q.launch,{announce:!1}):await X.start({announce:!1})))throw Error(`${X.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let W=g$(z);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${W}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(B){let _=g$(B);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${W};既有群保留,未执行删除`};let G;try{let B=await $.disbandChatForSessionExact(Q.chatName,V.chatId);G=WG(Q.chatName,V.chatId,B)}catch(B){let _=g$(B);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(G),X?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(B){let _=g$(B);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,error:`${W};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${W};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,H):await H()}catch(X){let z=g$(X);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Q,V)=>{let H=$.chatIdForSession(Q);if(!V||H!==V){let W=`临时群 chat_id 已变化: expected=${V||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,V)){let W=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}let X=$.registry.get(H);try{if(X)await X.stop("bye 解散",{announce:!1})}catch(W){let G=g$(W);return $.log(`temp-session: stop before disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let z;try{let W=await $.disbandChatForSessionExact(Q,H);z=WG(Q,H,W)}catch(W){let G=g$(W);return $.log(`temp-session: disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(z),X?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(W){let G=g$(W);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var KG=T(()=>{F1()});var wM={};import*as $4 from"@larksuiteoapi/node-sdk";import{chmodSync as BM,existsSync as RJ,mkdirSync as _M,readFileSync as jM,unlinkSync as l6,writeFileSync as LM}from"node:fs";import{dirname as qM}from"node:path";function Z4($,Z){if(K1=Math.max(K1,Z),u6)return u6;i0=!0,jG?.(),u$.close();try{LG?.()}catch(J){K1=1,K(`shutdown WebSocket close failed: ${J}`)}try{s1.persist()}catch(J){K(`shutdown alive marker write failed: ${J}`),K1=1}return u6=(async()=>{K(`${$}: staged shutdown begin sessions=${c$.size}`);try{let J=(async()=>{await zG(()=>[...u$.pending(),...PG]),s1.freezeForShutdown();let H=await Promise.allSettled([TJ.shutdown(`daemon ${$}`),c1.shutdown()]),X=await Promise.allSettled([AZ()]),z=await Promise.allSettled([...c$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[...H,...X,...z]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),_G)}),V=await Promise.race([J.then((H)=>{for(let X of H)if(X.status==="rejected")K1=1,K(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(V==="deadline")K1=1,K(`${$}: shutdown deadline ${_G}ms reached; forcing exit`);else K(`${$}: all sessions stopped`)}catch(J){K(`${$}: staged shutdown failed: ${J}`),K1=1}finally{qG(),process.exit(K1)}})(),u6}function NJ($){return XG(PG,$)}function DG($,Z="ws"){if(i0)return K(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=DM.accept($);if(!Y.accepted)return K(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{K(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function FM(){s1.persist()}function FG($,Z){return EJ.sessionFor($,Z)}async function MM($){return await EJ.createTempSession($)}async function UM($,Z){return await EJ.disbandTempSession($,Z)}function AM($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let V=Array.isArray($?.content)?$.content:[];for(let H of V){if(!Array.isArray(H))continue;let X=[];for(let W of H){if(!W||typeof W!=="object")continue;switch(W.tag){case"text":{let G=String(W.text??""),B=Array.isArray(W.style)?W.style:[];if(B.includes("bold"))G=`**${G}**`;if(B.includes("italic"))G=`*${G}*`;if(B.includes("lineThrough")||B.includes("strikethrough"))G=`~~${G}~~`;X.push(G);break}case"a":{let G=String(W.href??""),B=String(W.text??G);X.push(`[${B}](${G})`);break}case"at":{let G=String(W.user_name??W.user_id??"");X.push(`@${G}`);break}case"code_inline":X.push(`\`${String(W.text??"")}\``);break;case"hr":X.push("---");break;case"img":if(W.image_key)Z.push(String(W.image_key));break;case"media":if(W.file_key)J.push({key:String(W.file_key),name:W.file_name});break;case"emotion":break;default:if(typeof W.text==="string")X.push(W.text)}}let z=X.join("");if(z.trim())Y.push(z)}return{markdown:Y.join(`
536
+ exec ${QG(Q.runtime)} ${QG(Q.entry)} "$@"
537
+ `,X=AJ(V)?HG(V,"utf8"):null;if(X!==H)eJ(V,H),K(`command: ${X===null?"installed":"updated"} ${V}`);else HU(V,448);return qU(J,Y,Z),jU(Y,Z),V}function jU($,Z){let J=G1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!AJ(J))return;try{let Y=HG(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){K(`command: obsolete path preserved because ownership is unclear ${J}`);return}zU(J),K(`command: removed obsolete ${J}`)}catch(Y){K(`command: obsolete removal failed (${J}): ${Y}`)}}function LU($,Z,J){if($==="win32")return G1(J??G1(Z,"AppData","Local"),"Lodestar","bin");return G1(Z,".local","bin")}function qU($,Z,J){let Y=J==="win32"?Object.keys($).find((X)=>X.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",V=$[Y]??"",H=(X)=>J==="win32"?X.toLowerCase():X;if(V.split(Q).some((X)=>H(X)===H(Z)))return;$[Y]=V?`${Z}${Q}${V}`:Z}function QG($){return`'${$.replaceAll("'",`'"'"'`)}'`}function VG($){return $.replaceAll('"','""')}var zG=N(()=>{h();f0()});function WG($,Z,J){return $>0&&Z-$>J}async function GG($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function KG($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function OJ($){return typeof $==="string"&&$.length>0?$:void 0}function BG($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=OJ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=OJ(J.file_key);if(!Y)return null;let Q=OJ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function _G($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function jG($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class RJ{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 I$($){return $ instanceof Error?$.message:String($)}function LG($,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 qG($){let Z=(Q,V)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==V)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${V}"`);if(!H)H=$.createSession(V,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let V;try{if(_0(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(V=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!V.created)return{ok:!1,chatId:V.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(X){let z=I$(X);return $.log(`temp-session: create "${Q.chatName}" failed: ${z}`),{ok:!1,error:z}}let H=async()=>{let X=null;try{if($.registerTempSessionLease(Q.chatName,V.chatId),X=Z(V.chatId,Q.chatName),X.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(X.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${X.workDir}`);if(X.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await X.startForked(Q.launch,{announce:!1}):await X.start({announce:!1})))throw Error(`${X.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let W=I$(z);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${W}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(B){let _=I$(B);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${W};既有群保留,未执行删除`};let G;try{let B=await $.disbandChatForSessionExact(Q.chatName,V.chatId);G=LG(Q.chatName,V.chatId,B)}catch(B){let _=I$(B);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(G),X?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(B){let _=I$(B);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,error:`${W};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${W};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,H):await H()}catch(X){let z=I$(X);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Q,V)=>{let H=$.chatIdForSession(Q);if(!V||H!==V){let W=`临时群 chat_id 已变化: expected=${V||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,V)){let W=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}let X=$.registry.get(H);try{if(X)await X.stop("bye 解散",{announce:!1})}catch(W){let G=I$(W);return $.log(`temp-session: stop before disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let z;try{let W=await $.disbandChatForSessionExact(Q,H);z=LG(Q,H,W)}catch(W){let G=I$(W);return $.log(`temp-session: disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(z),X?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(W){let G=I$(W);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var PG=N(()=>{F1()});var gU={};import*as e2 from"@larksuiteoapi/node-sdk";import{chmodSync as PU,existsSync as TJ,mkdirSync as DU,readFileSync as FU,unlinkSync as d6,writeFileSync as UU}from"node:fs";import{dirname as MU}from"node:path";function $4($,Z){if(K1=Math.max(K1,Z),l6)return l6;i0=!0,UG?.(),c$.close();try{MG?.()}catch(J){K1=1,K(`shutdown WebSocket close failed: ${J}`)}try{o1.persist()}catch(J){K(`shutdown alive marker write failed: ${J}`),K1=1}return l6=(async()=>{K(`${$}: staged shutdown begin sessions=${p$.size}`);try{let J=(async()=>{await jG(()=>[...c$.pending(),...OG]),o1.freezeForShutdown();let H=await Promise.allSettled([EJ.shutdown(`daemon ${$}`),m1.shutdown()]),X=await Promise.allSettled([RZ()]),z=await Promise.allSettled([...p$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[...H,...X,...z]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),FG)}),V=await Promise.race([J.then((H)=>{for(let X of H)if(X.status==="rejected")K1=1,K(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(V==="deadline")K1=1,K(`${$}: shutdown deadline ${FG}ms reached; forcing exit`);else K(`${$}: all sessions stopped`)}catch(J){K(`${$}: staged shutdown failed: ${J}`),K1=1}finally{AG(),process.exit(K1)}})(),l6}function xJ($){return _G(OG,$)}function RG($,Z="ws"){if(i0)return K(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=OU.accept($);if(!Y.accepted)return K(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{K(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function RU(){o1.persist()}function NG($,Z){return SJ.sessionFor($,Z)}async function NU($){return await SJ.createTempSession($)}async function TU($,Z){return await SJ.disbandTempSession($,Z)}function EU($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let V=Array.isArray($?.content)?$.content:[];for(let H of V){if(!Array.isArray(H))continue;let X=[];for(let W of H){if(!W||typeof W!=="object")continue;switch(W.tag){case"text":{let G=String(W.text??""),B=Array.isArray(W.style)?W.style:[];if(B.includes("bold"))G=`**${G}**`;if(B.includes("italic"))G=`*${G}*`;if(B.includes("lineThrough")||B.includes("strikethrough"))G=`~~${G}~~`;X.push(G);break}case"a":{let G=String(W.href??""),B=String(W.text??G);X.push(`[${B}](${G})`);break}case"at":{let G=String(W.user_name??W.user_id??"");X.push(`@${G}`);break}case"code_inline":X.push(`\`${String(W.text??"")}\``);break;case"hr":X.push("---");break;case"img":if(W.image_key)Z.push(String(W.image_key));break;case"media":if(W.file_key)J.push({key:String(W.file_key),name:W.file_name});break;case"emotion":break;default:if(typeof W.text==="string")X.push(W.text)}}let z=X.join("");if(z.trim())Y.push(z)}return{markdown:Y.join(`
538
538
 
539
- `),imageKeys:Z,fileKeys:J}}async function RM($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",V=J.message_id;if(V&&e2.has(V))return;if(V){if(e2.add(V),e2.size>200){let A=[...e2];e2.clear();for(let M of A.slice(-100))e2.add(M)}}let H=Number(J.create_time??0);if(YG(H,Z,OM)){if(K(`drop stale message ${V} ageAtReceipt=${Math.round((Z-H)/1000)}s`),V)c0(V,"CrossMark");return}let X=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let W=J.message_type==="text"?z.text??"":"";if(typeof W==="string"&&W.startsWith("[DEBUG]")){try{LM(N9,JSON.stringify({chat_id:X,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),K(`debug: seeded inject context chat=${X.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(M){K(`debug: seed context failed: ${M}`)}let A=W.slice(7);z.text=A,J.content=JSON.stringify(z)}let G=q0.get(X);if(!G)await g4(),G=q0.get(X);if(!G)G=await J5(X)??void 0;if(!G){K(`unknown chat ${X}, dropping message`),await E(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let B=X5(G);T2(B,X);let _=FG(X,B),j={};try{j=JSON.parse(J.content??"{}")}catch{}let q=J.message_type,P="",D=!1,N=[];if(q==="text")P=(j.text??"").trim();else if(q==="post"){let A=AM(j);D=A.imageKeys.length>0||A.fileKeys.length>0,P=A.markdown.trim();for(let M of A.imageKeys){let S=await m4(J.message_id,M,"image");if(S)N.push(S)}for(let M of A.fileKeys){let S=await m4(J.message_id,M.key,"file",M.name);if(S)N.push(S)}}if(q==="text"&&P){if(await _.runCommand(P,Q,V))return}if((q==="text"||q==="post")&&P&&!D&&await QG({reply:()=>d6.consume({chatId:X,openId:Q,messageId:V??"",text:P,createTime:H,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(P,Q,V??"")}))return;if(q==="text"&&P&&await _.consumeModelCustomMessage(P,Q))return;let U=HG(q,j);if(U){let A=await m4(J.message_id,U.key,U.type,U.name);if(!A){await E(X,VG(q));return}if(N.push(A),!P&&U.displayText)P=U.displayText}if(!P&&N.length===0){K(`drop empty message ${V} type=${q}`);return}if(await _.onMultiMessageInbound(P,N,Q,V??""))return;await _.onUserMessage(P||"(empty)",N,Q,V??"")}function i6($){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 TM($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function z0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function p$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function m$($){return z0($.card?Y$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function r1($,Z){if(!$){K(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await w($,Z))K(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function NM($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=i6(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=TM(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&V)try{await M$(V,H);return}catch(j){K(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await r1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await r1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,W=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Y}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",B=Z?.__businessOk===!1||z?.type==="error"&&!G;if(!B&&new Set(["permission","ask","token_source_enable"]).has(J))return;await r1(Q,`${B?"❌":"✅"} ${Y}: ${W}`)}async function EM($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await r1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${i6(J)}失败: ${Y}`)}function MG($){return xM.accept($)}async function SM($){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??""),X=f$(H);if(X)$.__cardActionChatId=X.chatId;if(J.kind==="notify_callback")return await bM(J,Y,Q);let z=J.kind==="notify_reply"?await d6.open(H,Y,Q):await d6.cancel(H,String(J.reply_id??""),Y,Q),W=z0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return X?p$(X,W):W}let V=c$.get(Y);if(!V)return z0({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 X=await V.onPermissionDecision(J.request_id,H,Q);return z0({toast:{type:X.ok?H==="deny"?"error":"success":"error",content:X.message}},X.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${H+1})`),z0(Y$(Q1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let z=X instanceof Error?X.message:String(X);return z0(Y$(Q1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let H=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return m$(H)}case"model_page":{let H=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return m$(H)}case"model_list_open":{let H=String(J.panel_id??""),X=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return m$(await(J.mode==="add"?V.onModelAddOpen(H,X):V.onProviderSelect(X,H)))}case"model_add":case"model_remove":case"model_custom_remove":return m$(await V.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 V.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return m$(H)}case"model_custom_prompt":{let H=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return m$(H)}case"model_panel_cancel":{let H=await V.onModelPanelCancel(String(J.panel_id??""));return m$(H)}case"model_effort_select":{let H=await V.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return m$(H)}case"ask":{let H=V.askBlockReason(String(J.tool_use_id??""));if(H)return z0({toast:{type:"error",content:H}},!1);if(J.custom){let W=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,W,Q);return z0({toast:{type:G?"success":"error",content:G?"已回答":W.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let X=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return z0({toast:{type:X?"success":"error",content:X?"已回答":"问题已失效或选项无效"}},X)}case"worktree_disband":{let H=await V.onWorktreeDisband(String(J.slug??""));return z0(Y$(H.card),H.ok)}case"temp_fork_select":{let H=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z0(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Y$(Q1({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await V.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z0(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Y$(Q1({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await V.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return z0({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return z0(Y$(u5({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await V.onTasklistEnable();return z0(Y$(H.card),H.ok)}case"tasklist_delete_prompt":{let H=V.onTasklistDeletePrompt(String(J.guid??""));return z0(Y$(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await V.onTasklistDeleteConfirm(String(J.guid??""));return z0(Y$(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (gZ(),IZ));return await H(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return m$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function bM($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=f$(Y);if(!V)return K(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(V.unknownAt)return p$(V,z0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return p$(V,{toast:{type:"info",content:"已处理过"}});if(f2(Y))return p$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return p$(V,z0({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let H=V.buttons.find((W)=>W.id===Q);if(!H)return K(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),p$(V,z0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{B9(V.notifyId,H.id,J)}catch(W){return p$(V,z0({toast:{type:"error",content:`保存反馈结果失败: ${W instanceof Error?W.message:W}`}},!1))}return K(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),p$(V,{...Y$(o1(V,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}W9(V.notifyId);let X=NJ(CM(V,H,J));X.catch((W)=>{K(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${W instanceof Error?W.message:W}`)});let z=X.then((W)=>W==="retry"?"retry":"complete").catch(()=>"retry");return p$(V,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:z})}async function CM($,Z,J){try{let Y=o1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await M$($.messageId,Y)}catch(X){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${X instanceof Error?X.message:X}`)}let Q=await jZ($,Z,J),V=Q.ok?"complete":"retry",H;if(Q.ok){let X=K6($.notifyId,Z.id,J);if(X.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{V="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:X.detail},K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${X.detail}`);try{await r1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${X.detail}`)}catch(z){K(`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 X=o1($,H);await M$($.messageId,X)}catch(X){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${X instanceof Error?X.message:X}`);try{await r1($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${X instanceof Error?X.message:X}`)}catch(z){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),V}finally{G9($.notifyId)}}function OJ($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function kM(){if(process.platform==="win32"){K("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){K("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(RJ(L1))l6(L1)}catch{}try{Bun.serve({unix:L1,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(i0)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(!RJ(N9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(jM(N9,"utf8"))}catch(G){return new Response(`ctx read failed: ${G}`,{status:500})}let V=J?Z.searchParams.get("chat_id"):Y.chat_id;if(V!==void 0&&V!==Q.chat_id||Z.pathname!=="/"&&!V)return new Response("explicit debug chat_id must match the seeded context",{status:409});if(J){let G=c$.get(Q.chat_id);return G?Response.json(WJ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=c$.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 B=typeof Y.value?.panel_id==="string"?Y.value.panel_id.trim():"",_=G.modelPanels.get(B);if(!_?.messageId||_.messageId!==Y.message_id)throw Error("stale or mismatched model panel");let j=await Z0.im.v1.message.get({path:{message_id:Y.message_id}});if(j.code!==0)throw Error(`message.get failed: ${j.code} ${j.msg}`);let q=GW(Y,Q,j.data?.items?.[0],v.feishu.app_id,_.messageId);K(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let P=MG(q);return await u$.enqueue(Q.chat_id,async()=>{}),Response.json({admission:P,state:WJ(G)})}catch(B){return new Response(B instanceof Error?B.message:String(B),{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 X=`【自动化测试】:${H}`,z=await E(Q.chat_id,X);if(!z)return new Response("sendText failed — see daemon log",{status:502});let W={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(K(`debug: inject text=${JSON.stringify(H).slice(0,80)} msg_id=${z}`),!DG(W,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Y.wait_for_handling===!0)await u$.enqueue(Q.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{BM(L1,384)}catch{}K(`debug: inject socket listening at ${L1}`)}catch($){K(`debug: socket bind failed: ${$}`)}}async function yM(){K(`lodestar-daemon: pid ${process.pid} starting`),s1.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (fZ(),pX));if(i0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Q0(),NQ));if(i0)return;if(await Z(),i0)return;if(h7(),m7(),p7(),u7(),i7(),await g4(),i0)return;setInterval(()=>{g4()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (aZ(),nZ));if(i0)return;try{await J()}catch(F){K(`tasklist deletion reconcile failed: ${F instanceof Error?F.message:F}`)}if(i0)return;let Y,Q=Date.now(),V=0,H=!1,X=null,z=1500,W=90000,G=600000,B=3,_=null,j=0,q="",P=!1,D=(F)=>{K(`[ws] rebuild requested before WS init — ${F}`)},N=(F,b=0,d=!1)=>{if(i0)return;let o=Date.now()+b;if(_){if(P||=d,o>=j){K(`[ws] rebuild already scheduled — ${F}`);return}clearTimeout(_)}j=o,q=F,P=d,_=setTimeout(()=>{let K0=q,J4=P;_=null,j=0,q="",P=!1,D(K0,J4)},b)},U={error:(F)=>K(`[ws-sdk error] ${OJ(F)}`),warn:(F)=>{let b=OJ(F);if(K(`[ws-sdk warn] ${b}`),b.includes("no pong/inbound"))N("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(F)=>K(`[ws-sdk] ${OJ(F)}`),debug:(F)=>{},trace:(F)=>{}},A=new $4.EventDispatcher({}),M=()=>{if(Q=Date.now(),V=0,X)clearTimeout(X),X=null};A.register({"im.message.receive_v1":async(F)=>{if(M(),!DG(F))throw Error("daemon shutdown in progress")}}),A.register({"card.action.trigger":async(F)=>{return M(),MG(F)}});let S=()=>new $4.WSClient({appId:v.feishu.app_id,appSecret:v.feishu.app_secret,loggerLevel:$4.LoggerLevel.info,logger:U,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>K("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>p(),onError:(F)=>D(`SDK onError: ${F?.message??F}`)});D=(F,b=!1)=>{if(i0)return;if(H){K(`[ws] rebuild skipped (already rebuilding) — ${F}`);return}if(_)clearTimeout(_),_=null,j=0;H=!0,V++,K(`[ws] rebuild #${V} (fresh WSClient) — ${F}`);let d=Y;try{d?.close({force:!0})}catch(o){K(`[ws] rebuild: old close failed: ${o}`)}if(Y=S(),Y.start({eventDispatcher:A}).catch((o)=>{K(`[ws] rebuild start failed: ${o}`),N(`fresh client start failed: ${o}`,z,b)}),H=!1,b)C()};let C=()=>{if(X)clearTimeout(X);let F=Date.now();X=setTimeout(()=>{if(X=null,Q>=F){V=0;return}if(V>=B){K(`[ws] STILL deaf after ${B} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),V=0;return}D(`verify: no event ${Math.round((Date.now()-F)/1000)}s after rebuild`,!0)},W)},p=()=>{let F=Date.now()-Q<G;K("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${F})`),V=0,N("post-reconnect precaution",z,F)};Y=S();let y=15000,h=2,x=0,f=setInterval(()=>{if(i0)return;let{state:F}=Y.getConnectionStatus();if(F==="connected"){x=0;return}if(F==="failed"||F==="idle"){x=0,D(`watchdog: state=${F}`);return}if(x++,K(`[ws] watchdog: state=${F} (${x}/${h})`),x>=h)x=0,D(`watchdog: stuck in '${F}' ~${Math.round(y*h/1000)}s`)},y);LG=()=>{if(clearInterval(f),_)clearTimeout(_);if(X)clearTimeout(X);Y.close({force:!0})};let m=ZX();qW({bind:v.notify.bind,port:v.notify.port,extraHandler:(F,b,d)=>rW(F,b,d,{service:TJ,authorizeSession:(o)=>{for(let K0 of c$.values())if(K0.acceptsAgentCapability(o))return K0;return null}})}),ZG(),FW(),kW();let l=s1.enqueue();jG=VY(K,{enabled:v.runtime.agent_auto_update}),Y.start({eventDispatcher:A}).catch((F)=>{K(`[ws] initial start failed: ${F}`),N(`initial start failed: ${F}`,z,!1)}),K(`lodestar-daemon: WS start requested, watching ${q0.size} groups`),kM();for(let F of m)NJ(u$.enqueue(F.chatId,()=>d6.recover(F))).catch((b)=>K(`notify-reply recovery failed: ${b instanceof Error?b.message:b}`));await l}var BG=!1,i0=!1,u6=null,K1=0,jG,LG,_G=15000,qG=()=>{if(BG)return;BG=!0;try{s1.persist()}catch($){K(`alive marker write failed: ${$}`)}try{l6(n0)}catch{}try{l6(L1)}catch{}},c$,TJ,u$,s1,PM,PG,DM,EJ,OM=30000,e2,d6,xM;var UG=T(()=>{lZ();J0();J$();KW();_9();I6();I6();MW();AW();nW();UZ();P6();sW();LJ();JG();C0();I();Y2();H0();J8();N7();KG();{let $=E9(n0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(RJ(n0))try{l6(n0)}catch{}}_M(qM(n0),{recursive:!0});hJ(n0);process.on("exit",qG);process.on("SIGTERM",()=>{Z4("SIGTERM",0)});process.on("SIGINT",()=>{Z4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{Z4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{K(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),Z4("unhandledRejection",1)});process.on("uncaughtException",($)=>{K(`uncaughtException: ${$.stack??$.message}`),Z4("uncaughtException",1)});c$=new Map,TJ=new DJ,u$=new C4,s1=new AJ({readMarker:s7,writeMarker:r7,sessions:()=>c$.values(),chatIdForSession:E3,sessionFor:FG,actor:u$,isShuttingDown:()=>i0,log:K}),PM=new T7(30000),PG=new Set,DM=hQ({actor:u$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>RM($,Z)});EJ=GG({registry:c$,createSession:($,Z)=>{let J=new G$($,Z,{onLifecycleChange:FM,onCreateTempSession:MM,onDisbandTempSession:UM,onCancelAgentRuns:(Y,Q,V)=>TJ.cancelSessionRuns(Y,Q,V)});return s1.transferPending(J),J},ensureChatForSession:e7,disbandChatForSessionExact:Z5,chatIdForSession:E3,clearSessionConversationState:o7,registerTempSessionLease:I7,hasTempSessionLease:g7,replaceTurnAnchors:t0,runExclusive:($,Z)=>u$.enqueue($,Z),log:K});e2=new Set,d6=UW({sendCard:u,updateCard:M$,sendText:E,dispatch:jZ,onWaitingChanged:($)=>c$.get($)?.refreshPendingAsks(),log:K});xM=IQ({actor:u$,deduper:PM,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=f$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:SM,present:NM,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await EM($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await r1(String($?.context?.open_chat_id??""),`⚠️ ${i6(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:($)=>{NJ($)},onBackgroundError:($)=>{K(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${i6(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}})}});yM().catch(($)=>{K(`boot fatal: ${$}`),Z4("boot fatal",1)})});H0();J8();import{existsSync as AG,unlinkSync as vM}from"node:fs";var K$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function fM(){if(!AG(T0)){if(process.stdin.isTTY){console.log(),console.log(`${K$.bold}${K$.yellow}Lodestar: 未找到配置, 启动安装向导...${K$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (WY(),zY));await Z();return}console.error(`${K$.red}Lodestar: 未找到配置 ${T0}${K$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${K$.green}lodestar-setup${K$.reset} 完成首次配置 (或直接运行 ${K$.green}lodestar-daemon${K$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=E9(n0);if($.state==="exit")console.error(`${K$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${K$.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(` • 误判 / 已经死了: 手删 ${n0} 后再跑`),process.exit(1);if(AG(n0))try{vM(n0)}catch{}await Promise.resolve().then(() => (UG(),wM))}fM().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
539
+ `),imageKeys:Z,fileKeys:J}}async function SU($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",V=J.message_id;if(V&&t2.has(V))return;if(V){if(t2.add(V),t2.size>200){let A=[...t2];t2.clear();for(let U of A.slice(-100))t2.add(U)}}let H=Number(J.create_time??0);if(WG(H,Z,xU)){if(K(`drop stale message ${V} ageAtReceipt=${Math.round((Z-H)/1000)}s`),V)c0(V,"CrossMark");return}let X=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let W=J.message_type==="text"?z.text??"":"";if(typeof W==="string"&&W.startsWith("[DEBUG]")){try{UU(T9,JSON.stringify({chat_id:X,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),K(`debug: seeded inject context chat=${X.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(U){K(`debug: seed context failed: ${U}`)}let A=W.slice(7);z.text=A,J.content=JSON.stringify(z)}let G=q0.get(X);if(!G)await g4(),G=q0.get(X);if(!G)G=await V5(X)??void 0;if(!G){K(`unknown chat ${X}, dropping message`),await x(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let B=W5(G);R2(B,X);let _=NG(X,B),j={};try{j=JSON.parse(J.content??"{}")}catch{}let q=J.message_type,P="",D=!1,T=[];if(q==="text")P=(j.text??"").trim();else if(q==="post"){let A=EU(j);D=A.imageKeys.length>0||A.fileKeys.length>0,P=A.markdown.trim();for(let U of A.imageKeys){let S=await m4(J.message_id,U,"image");if(S)T.push(S)}for(let U of A.fileKeys){let S=await m4(J.message_id,U.key,"file",U.name);if(S)T.push(S)}}if(q==="text"&&P){if(await _.runCommand(P,Q,V))return}if((q==="text"||q==="post")&&P&&!D&&await GG({reply:()=>i6.consume({chatId:X,openId:Q,messageId:V??"",text:P,createTime:H,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(P,Q,V??"")}))return;if(q==="text"&&P&&await _.consumeModelCustomMessage(P,Q))return;let M=BG(q,j);if(M){let A=await m4(J.message_id,M.key,M.type,M.name);if(!A){await x(X,KG(q));return}if(T.push(A),!P&&M.displayText)P=M.displayText}if(!P&&T.length===0){K(`drop empty message ${V} type=${q}`);return}if(await _.onMultiMessageInbound(P,T,Q,V??""))return;await _.onUserMessage(P||"(empty)",T,Q,V??"")}function n6($){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 bU($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function z0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function m$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function g$($){return z0($.card?Y$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function a1($,Z){if(!$){K(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await w($,Z))K(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function CU($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=n6(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=bU(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&V)try{await U$(V,H);return}catch(j){K(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await a1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await a1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,W=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Y}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",B=Z?.__businessOk===!1||z?.type==="error"&&!G;if(!B&&new Set(["permission","ask","token_source_enable"]).has(J))return;await a1(Q,`${B?"❌":"✅"} ${Y}: ${W}`)}async function kU($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await a1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${n6(J)}失败: ${Y}`)}function TG($){return yU.accept($)}async function wU($){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??""),X=v$(H);if(X)$.__cardActionChatId=X.chatId;if(J.kind==="notify_callback")return await vU(J,Y,Q);let z=J.kind==="notify_reply"?await i6.open(H,Y,Q):await i6.cancel(H,String(J.reply_id??""),Y,Q),W=z0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return X?m$(X,W):W}let V=p$.get(Y);if(!V)return z0({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 X=await V.onPermissionDecision(J.request_id,H,Q);return z0({toast:{type:X.ok?H==="deny"?"error":"success":"error",content:X.message}},X.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${H+1})`),z0(Y$(Q1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let z=X instanceof Error?X.message:String(X);return z0(Y$(Q1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let H=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return g$(H)}case"model_page":{let H=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return g$(H)}case"model_list_open":{let H=String(J.panel_id??""),X=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return g$(await(J.mode==="add"?V.onModelAddOpen(H,X):V.onProviderSelect(X,H)))}case"model_add":case"model_remove":case"model_custom_remove":return g$(await V.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 V.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return g$(H)}case"model_custom_prompt":{let H=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return g$(H)}case"model_panel_cancel":{let H=await V.onModelPanelCancel(String(J.panel_id??""));return g$(H)}case"model_effort_select":{let H=await V.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return g$(H)}case"ask":{let H=V.askBlockReason(String(J.tool_use_id??""));if(H)return z0({toast:{type:"error",content:H}},!1);if(J.custom){let W=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,W,Q);return z0({toast:{type:G?"success":"error",content:G?"已回答":W.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let X=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return z0({toast:{type:X?"success":"error",content:X?"已回答":"问题已失效或选项无效"}},X)}case"worktree_disband":{let H=await V.onWorktreeDisband(String(J.slug??""));return z0(Y$(H.card),H.ok)}case"temp_fork_select":{let H=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z0(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Y$(Q1({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await V.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return z0(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:Y$(Q1({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await V.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return z0({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return z0(Y$(d5({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await V.onTasklistEnable();return z0(Y$(H.card),H.ok)}case"tasklist_delete_prompt":{let H=V.onTasklistDeletePrompt(String(J.guid??""));return z0(Y$(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await V.onTasklistDeleteConfirm(String(J.guid??""));return z0(Y$(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (pZ(),mZ));return await H(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return g$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function vU($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=v$(Y);if(!V)return K(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(V.unknownAt)return m$(V,z0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return m$(V,{toast:{type:"info",content:"已处理过"}});if(v2(Y))return m$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return m$(V,z0({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let H=V.buttons.find((W)=>W.id===Q);if(!H)return K(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),m$(V,z0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{B9(V.notifyId,H.id,J)}catch(W){return m$(V,z0({toast:{type:"error",content:`保存反馈结果失败: ${W instanceof Error?W.message:W}`}},!1))}return K(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),m$(V,{...Y$(n1(V,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}W9(V.notifyId);let X=xJ(fU(V,H,J));X.catch((W)=>{K(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${W instanceof Error?W.message:W}`)});let z=X.then((W)=>W==="retry"?"retry":"complete").catch(()=>"retry");return m$(V,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:z})}async function fU($,Z,J){try{let Y=n1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await U$($.messageId,Y)}catch(X){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${X instanceof Error?X.message:X}`)}let Q=await qZ($,Z,J),V=Q.ok?"complete":"retry",H;if(Q.ok){let X=_6($.notifyId,Z.id,J);if(X.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{V="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:X.detail},K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${X.detail}`);try{await a1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${X.detail}`)}catch(z){K(`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 X=n1($,H);await U$($.messageId,X)}catch(X){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${X instanceof Error?X.message:X}`);try{await a1($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${X instanceof Error?X.message:X}`)}catch(z){K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return K(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),V}finally{G9($.notifyId)}}function NJ($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function hU(){if(process.platform==="win32"){K("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){K("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(TJ(L1))d6(L1)}catch{}try{Bun.serve({unix:L1,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(i0)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(!TJ(T9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(FU(T9,"utf8"))}catch(G){return new Response(`ctx read failed: ${G}`,{status:500})}let V=J?Z.searchParams.get("chat_id"):Y.chat_id;if(V!==void 0&&V!==Q.chat_id||Z.pathname!=="/"&&!V)return new Response("explicit debug chat_id must match the seeded context",{status:409});if(J){let G=p$.get(Q.chat_id);return G?Response.json(KJ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=p$.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 B=typeof Y.value?.panel_id==="string"?Y.value.panel_id.trim():"",_=G.modelPanels.get(B);if(!_?.messageId||_.messageId!==Y.message_id)throw Error("stale or mismatched model panel");let j=await X0.im.v1.message.get({path:{message_id:Y.message_id}});if(j.code!==0)throw Error(`message.get failed: ${j.code} ${j.msg}`);let q=qW(Y,Q,j.data?.items?.[0],v.feishu.app_id,_.messageId);K(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let P=TG(q);return await c$.enqueue(Q.chat_id,async()=>{}),Response.json({admission:P,state:KJ(G)})}catch(B){return new Response(B instanceof Error?B.message:String(B),{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 X=`【自动化测试】:${H}`,z=await x(Q.chat_id,X);if(!z)return new Response("sendText failed — see daemon log",{status:502});let W={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(K(`debug: inject text=${JSON.stringify(H).slice(0,80)} msg_id=${z}`),!RG(W,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Y.wait_for_handling===!0)await c$.enqueue(Q.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{PU(L1,384)}catch{}K(`debug: inject socket listening at ${L1}`)}catch($){K(`debug: socket bind failed: ${$}`)}}async function IU(){K(`lodestar-daemon: pid ${process.pid} starting`),o1.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (IZ(),nX));if(i0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Y0(),xQ));if(i0)return;if(await Z(),i0)return;if(m7(),u7(),l7(),i7(),o7(),await g4(),i0)return;setInterval(()=>{g4()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (rZ(),oZ));if(i0)return;try{await J()}catch(F){K(`tasklist deletion reconcile failed: ${F instanceof Error?F.message:F}`)}if(i0)return;let Y,Q=Date.now(),V=0,H=!1,X=null,z=1500,W=90000,G=600000,B=3,_=null,j=0,q="",P=!1,D=(F)=>{K(`[ws] rebuild requested before WS init — ${F}`)},T=(F,b=0,d=!1)=>{if(i0)return;let o=Date.now()+b;if(_){if(P||=d,o>=j){K(`[ws] rebuild already scheduled — ${F}`);return}clearTimeout(_)}j=o,q=F,P=d,_=setTimeout(()=>{let K0=q,Z4=P;_=null,j=0,q="",P=!1,D(K0,Z4)},b)},M={error:(F)=>K(`[ws-sdk error] ${NJ(F)}`),warn:(F)=>{let b=NJ(F);if(K(`[ws-sdk warn] ${b}`),b.includes("no pong/inbound"))T("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(F)=>K(`[ws-sdk] ${NJ(F)}`),debug:(F)=>{},trace:(F)=>{}},A=new e2.EventDispatcher({}),U=()=>{if(Q=Date.now(),V=0,X)clearTimeout(X),X=null};A.register({"im.message.receive_v1":async(F)=>{if(U(),!RG(F))throw Error("daemon shutdown in progress")}}),A.register({"card.action.trigger":async(F)=>{return U(),TG(F)}});let S=()=>new e2.WSClient({appId:v.feishu.app_id,appSecret:v.feishu.app_secret,loggerLevel:e2.LoggerLevel.info,logger:M,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>K("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>p(),onError:(F)=>D(`SDK onError: ${F?.message??F}`)});D=(F,b=!1)=>{if(i0)return;if(H){K(`[ws] rebuild skipped (already rebuilding) — ${F}`);return}if(_)clearTimeout(_),_=null,j=0;H=!0,V++,K(`[ws] rebuild #${V} (fresh WSClient) — ${F}`);let d=Y;try{d?.close({force:!0})}catch(o){K(`[ws] rebuild: old close failed: ${o}`)}if(Y=S(),Y.start({eventDispatcher:A}).catch((o)=>{K(`[ws] rebuild start failed: ${o}`),T(`fresh client start failed: ${o}`,z,b)}),H=!1,b)C()};let C=()=>{if(X)clearTimeout(X);let F=Date.now();X=setTimeout(()=>{if(X=null,Q>=F){V=0;return}if(V>=B){K(`[ws] STILL deaf after ${B} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),V=0;return}D(`verify: no event ${Math.round((Date.now()-F)/1000)}s after rebuild`,!0)},W)},p=()=>{let F=Date.now()-Q<G;K("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${F})`),V=0,T("post-reconnect precaution",z,F)};Y=S();let y=15000,I=2,E=0,f=setInterval(()=>{if(i0)return;let{state:F}=Y.getConnectionStatus();if(F==="connected"){E=0;return}if(F==="failed"||F==="idle"){E=0,D(`watchdog: state=${F}`);return}if(E++,K(`[ws] watchdog: state=${F} (${E}/${I})`),E>=I)E=0,D(`watchdog: stuck in '${F}' ~${Math.round(y*I/1000)}s`)},y);MG=()=>{if(clearInterval(f),_)clearTimeout(_);if(X)clearTimeout(X);Y.close({force:!0})};let m=HX();AW({bind:v.notify.bind,port:v.notify.port,extraHandler:(F,b,d)=>JG(F,b,d,{service:EJ,authorizeSession:(o)=>{for(let K0 of p$.values())if(K0.acceptsAgentCapability(o))return K0;return null}})}),XG(),NW(),IW();let l=o1.enqueue();UG=XY(K,{enabled:v.runtime.agent_auto_update}),Y.start({eventDispatcher:A}).catch((F)=>{K(`[ws] initial start failed: ${F}`),T(`initial start failed: ${F}`,z,!1)}),K(`lodestar-daemon: WS start requested, watching ${q0.size} groups`),hU();for(let F of m)xJ(c$.enqueue(F.chatId,()=>i6.recover(F))).catch((b)=>K(`notify-reply recovery failed: ${b instanceof Error?b.message:b}`));await l}var DG=!1,i0=!1,l6=null,K1=0,UG,MG,FG=15000,AG=()=>{if(DG)return;DG=!0;try{o1.persist()}catch($){K(`alive marker write failed: ${$}`)}try{d6(n0)}catch{}try{d6(L1)}catch{}},p$,EJ,c$,o1,AU,OG,OU,SJ,xU=30000,t2,i6,yU;var EG=N(()=>{iZ();Z0();J$();PW();_9();g6();g6();TW();xW();eW();OZ();F6();YG();PJ();zG();C0();h();Z2();V0();Y8();S7();PG();{let $=E9(n0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(TJ(n0))try{d6(n0)}catch{}}DU(MU(n0),{recursive:!0});gJ(n0);process.on("exit",AG);process.on("SIGTERM",()=>{$4("SIGTERM",0)});process.on("SIGINT",()=>{$4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{$4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{K(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),$4("unhandledRejection",1)});process.on("uncaughtException",($)=>{K(`uncaughtException: ${$.stack??$.message}`),$4("uncaughtException",1)});p$=new Map,EJ=new UJ,c$=new C4,o1=new RJ({readMarker:$5,writeMarker:e7,sessions:()=>p$.values(),chatIdForSession:E3,sessionFor:NG,actor:c$,isShuttingDown:()=>i0,log:K}),AU=new x7(30000),OG=new Set,OU=cQ({actor:c$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>SU($,Z)});SJ=qG({registry:p$,createSession:($,Z)=>{let J=new G$($,Z,{onLifecycleChange:RU,onCreateTempSession:NU,onDisbandTempSession:TU,onCancelAgentRuns:(Y,Q,V)=>EJ.cancelSessionRuns(Y,Q,V)});return o1.transferPending(J),J},ensureChatForSession:J5,disbandChatForSessionExact:Q5,chatIdForSession:E3,clearSessionConversationState:t7,registerTempSessionLease:p7,hasTempSessionLease:c7,replaceTurnAnchors:t0,runExclusive:($,Z)=>c$.enqueue($,Z),log:K});t2=new Set,i6=EW({sendCard:u,updateCard:U$,sendText:x,dispatch:qZ,onWaitingChanged:($)=>p$.get($)?.refreshPendingAsks(),log:K});yU=uQ({actor:c$,deduper:AU,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=v$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:wU,present:CU,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await kU($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await a1(String($?.context?.open_chat_id??""),`⚠️ ${n6(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:($)=>{xJ($)},onBackgroundError:($)=>{K(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${n6(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}})}});IU().catch(($)=>{K(`boot fatal: ${$}`),$4("boot fatal",1)})});V0();Y8();import{existsSync as xG,unlinkSync as mU}from"node:fs";var K$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function pU(){if(!xG(N0)){if(process.stdin.isTTY){console.log(),console.log(`${K$.bold}${K$.yellow}Lodestar: 未找到配置, 启动安装向导...${K$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (KY(),GY));await Z();return}console.error(`${K$.red}Lodestar: 未找到配置 ${N0}${K$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${K$.green}lodestar-setup${K$.reset} 完成首次配置 (或直接运行 ${K$.green}lodestar-daemon${K$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=E9(n0);if($.state==="exit")console.error(`${K$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${K$.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(` • 误判 / 已经死了: 手删 ${n0} 后再跑`),process.exit(1);if(xG(n0))try{mU(n0)}catch{}await Promise.resolve().then(() => (EG(),gU))}pU().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});